@code-partner/codepipe 0.11.1-dev.221.g686928f → 0.11.1-dev.223.g7553648
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +6 -6
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var mb=Object.defineProperty;var $=(t,e)=>()=>(t&&(e=t(t=0)),e);var Be=(t,e)=>{for(var r in e)mb(t,r,{get:e[r],enumerable:!0})};var Fe,it,Ki=$(()=>{"use strict";Fe="0.11.1-dev.
|
|
2
|
+
var mb=Object.defineProperty;var $=(t,e)=>()=>(t&&(e=t(t=0)),e);var Be=(t,e)=>{for(var r in e)mb(t,r,{get:e[r],enumerable:!0})};var Fe,it,Ki=$(()=>{"use strict";Fe="0.11.1-dev.223.g7553648",it="https://hub.dev.codepipe.dev"});function Vn(t){return typeof t!="number"||!Number.isFinite(t)?!1:t>=Ru&&t<=at}var at,Ru,Tu=$(()=>{"use strict";Ki();at=4,Ru=4});var Iu=$(()=>{"use strict";Ki()});function zn(t=6){return`# CodePipe Context Repo format version.
|
|
3
3
|
# Bumped by the scaffold / the format-migration PR \u2014 do not edit by hand.
|
|
4
4
|
template_version: ${t}
|
|
5
5
|
`}function Hi(t){if(!t)return 0;let e=/^\s*template_version:\s*(\d+)\s*$/m.exec(t),r=e?parseInt(e[1]??"",10):NaN;return Number.isFinite(r)&&r>=0?r:0}function Wi(t,e=Gi){let r=[];for(let n of e)if(!(n.version<=t))for(let o of n.addedPaths)r.includes(o)||r.push(o);return r}function qi(t,e=Gi){return e.filter(r=>r.version>t)}var Cu,ct,Gr,Gi,Au=$(()=>{"use strict";Cu=6,ct=".codepipe-context.yaml",Gr=".devpipe-context.yaml",Gi=[{version:1,summary:"ADR section: adr/ scaffold (README, template, derived INDEX) + the format-version stamp itself",addedPaths:["adr/README.md","adr/0000-template.md","adr/INDEX.md",ct]},{version:2,summary:"Rename the format-version stamp .devpipe-context.yaml \u2192 .codepipe-context.yaml (drop the devpipe-brand leftover)",addedPaths:[ct]},{version:3,summary:"Custom project actions (the RUN tab): actions/ scaffold with the format README",addedPaths:["actions/README.md"]},{version:4,summary:"Project map: model/ scaffold with the format README (facts/ vs derived/ layout)",addedPaths:["model/README.md"]},{version:5,summary:"Roles: roles/ scaffold with the format README (override a bundled critic by name, or add your own)",addedPaths:["roles/README.md"]},{version:6,summary:"Skills: skills/ scaffold with the format README (procedures the agent invokes instead of improvising)",addedPaths:["skills/README.md"]}]});function Jn(t){return`model/facts/identity/${t}.yaml`}function dr(t){return`model/facts/events/${t}.yaml`}function zi(t){return`model/facts/annotations/${t}.md`}function Xi(t){return`model/derived/correlates/${t}.yaml`}function Ji(t){return`model/derived/touched/${t}.yaml`}function Pu(t){return t===""?"root":t.replace(/\//g,"-")}function Zi(t,e){return`model/derived/structure/${t}/${Pu(e)}.yaml`}function Xo(t){return typeof t=="string"&&ju.test(t)}function re(t){if(typeof t!="string")return null;let e=t.indexOf(":");if(e<=0)return null;let r=t.indexOf(":",e+1);if(r<0)return null;let n=t.slice(0,e);if(!_u.includes(n))return null;let o=t.slice(e+1,r),s=t.slice(r+1);return o===""&&!wb.includes(n)||s===""?null:{level:n,repo:o,path:s}}function ke(t){return`task::${t}`}function me(t,e,r){return`${t}:${e}:${r}`}function Zn(t){let e=[];return kt(t)?(Zo(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),typeof t.repo!="string"&&e.push("repo: missing (empty string = cross-repo)"),typeof t.builtFromCommit!="string"&&e.push("builtFromCommit: missing"),Array.isArray(t.edges)?t.edges.forEach((r,n)=>{if(!kt(r)){e.push(`edges[${n}]: not an object`);return}Qi.includes(r.kind)||e.push(`edges[${n}].kind: unknown "${String(r.kind)}"`),re(r.from)||e.push(`edges[${n}].from: malformed nodeKey`),re(r.to)||e.push(`edges[${n}].to: malformed nodeKey`),r.weight!==void 0&&!(typeof r.weight=="number"&&Number.isFinite(r.weight))&&e.push(`edges[${n}].weight: not a finite number`)}):e.push("edges: not an array"),e.length?{ok:!1,errors:e}:{ok:!0,value:t}):{ok:!1,errors:["edge sheet: not an object"]}}function Nu(t){return{...t,edges:Hr(t.edges,e=>`${e.kind} ${e.from} ${e.to}`)}}function pr(t){return mr(Nu(t))}function kt(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Zo(t){return typeof t=="number"&&Number.isInteger(t)&&t>0}function lt(t){return typeof t=="string"&&t.length>0}function $b(t){return t.modelFormatVersion!==2}function Ct(t){let e=[];if(!kt(t))return{ok:!1,errors:["shard: not an object"]};Zo(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),lt(t.repo)||e.push("repo: missing or empty"),lt(t.builtFromCommit)||e.push("builtFromCommit: missing or empty");let r=typeof t.repo=="string"?t.repo:"",n=new Set;return Array.isArray(t.nodes)?t.nodes.forEach((o,s)=>{if(!kt(o)){e.push(`nodes[${s}]: not an object`);return}let i=re(o.key);if(!i){e.push(`nodes[${s}].key: malformed nodeKey (${JSON.stringify(o.key??null)})`);return}o.level!==i.level&&e.push(`nodes[${s}]: level "${String(o.level)}" does not match key prefix "${i.level}"`),r&&i.repo!==r&&e.push(`nodes[${s}].key: repo "${i.repo}" mixed into shard of repo "${r}"`);let a=o.key;n.has(a)&&e.push(`nodes[${s}].key: duplicate "${a}"`),n.add(a),o.entityId!==void 0&&!Xo(o.entityId)&&e.push(`nodes[${s}].entityId: malformed (${JSON.stringify(o.entityId)})`)}):e.push("nodes: not an array"),Array.isArray(t.edges)?t.edges.forEach((o,s)=>{if(!kt(o)){e.push(`edges[${s}]: not an object`);return}Qi.includes(o.kind)||e.push(`edges[${s}].kind: unknown "${String(o.kind)}"`),(!lt(o.to)||!re(o.to))&&e.push(`edges[${s}].to: malformed nodeKey`),(!lt(o.from)||!n.has(o.from))&&e.push(`edges[${s}].from: "${String(o.from)}" is not a node of this shard`),o.weight!==void 0&&!(typeof o.weight=="number"&&Number.isFinite(o.weight))&&e.push(`edges[${s}].weight: not a finite number`)}):e.push("edges: not an array"),e.length?{ok:!1,errors:e}:{ok:!0,value:t}}function Qn(t){let e=[];if(!kt(t))return{ok:!1,errors:["identity: not an object"]};if(Zo(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),lt(t.repo)||e.push("repo: missing or empty"),t.builtFromCommit!==void 0&&!lt(t.builtFromCommit)&&e.push("builtFromCommit: not a non-empty string"),!Array.isArray(t.entities))e.push("entities: not an array");else{let r=new Set;t.entities.forEach((n,o)=>{if(!kt(n)){e.push(`entities[${o}]: not an object`);return}Xo(n.entityId)?r.has(n.entityId)?e.push(`entities[${o}].entityId: duplicate "${n.entityId}"`):r.add(n.entityId):e.push(`entities[${o}].entityId: malformed (${JSON.stringify(n.entityId??null)})`),re(n.currentKey)||e.push(`entities[${o}].currentKey: malformed nodeKey`),n.status!=="active"&&n.status!=="orphaned"&&e.push(`entities[${o}].status: expected active|orphaned`),lt(n.firstSeen)||e.push(`entities[${o}].firstSeen: missing`),lt(n.lastSeen)||e.push(`entities[${o}].lastSeen: missing`),n.aliases!==void 0&&(Array.isArray(n.aliases)?n.aliases.forEach((s,i)=>{(!kt(s)||!re(s.key)||!lt(s.until))&&e.push(`entities[${o}].aliases[${i}]: malformed`)}):e.push(`entities[${o}].aliases: not an array`))})}return e.length?{ok:!1,errors:e}:{ok:!0,value:t}}function At(t){let e=[];return kt(t)?(Zo(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),lt(t.taskKey)||e.push("taskKey: missing or empty"),t.origin!=="bootstrap"&&t.origin!=="pipeline"&&e.push("origin: expected bootstrap|pipeline"),t.date!==void 0&&!(typeof t.date=="string"&&/^\d{4}-\d{2}-\d{2}$/.test(t.date))&&e.push("date: expected YYYY-MM-DD"),(!Array.isArray(t.commits)||t.commits.some(r=>!lt(r)))&&e.push("commits: not an array of non-empty strings"),Array.isArray(t.files)?t.files.forEach((r,n)=>{if(!kt(r)||!re(r.key)){e.push(`files[${n}].key: malformed nodeKey`);return}r.entityId!==void 0&&!Xo(r.entityId)&&e.push(`files[${n}].entityId: malformed`),r.churn!==void 0&&!(typeof r.churn=="number"&&r.churn>=0)&&e.push(`files[${n}].churn: not a non-negative number`)}):e.push("files: not an array"),e.length?{ok:!1,errors:e}:{ok:!0,value:t}):{ok:!1,errors:["event: not an object"]}}function Hr(t,e){return[...t].sort((r,n)=>e(r)<e(n)?-1:e(r)>e(n)?1:0)}function Ou(t){return{...t,nodes:Hr(t.nodes,e=>e.key),edges:Hr(t.edges,e=>`${e.kind}\0${e.from}\0${e.to}`)}}function Lu(t){return{...t,entities:Hr(t.entities,e=>e.entityId).map(e=>e.aliases?{...e,aliases:Hr(e.aliases,r=>`${r.key}\0${r.until}`)}:e)}}function Du(t){let e=t.links?{...t.links,...t.links.adr?{adr:[...t.links.adr].sort()}:{},...t.links.tasks?{tasks:[...t.links.tasks].sort()}:{}}:void 0;return{...t,commits:[...t.commits].sort(),files:Hr(t.files,r=>r.key),...e?{links:e}:{}}}function Xn(t){return vb.test(t)?t:JSON.stringify(t)}function Mu(t){if(t===null)return"null";if(typeof t=="boolean")return t?"true":"false";if(typeof t=="number"){if(!Number.isFinite(t))throw new Error(`model yaml: non-finite number ${t}`);return JSON.stringify(t)}if(typeof t=="string")return JSON.stringify(t);throw new Error(`model yaml: unsupported scalar ${typeof t}`)}function Uu(t){return t===null||["boolean","number","string"].includes(typeof t)}function Yi(t){return Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[r])=>e<r?-1:e>r?1:0)}function Bu(t,e,r){if(Array.isArray(t)){for(let n of t)if(Uu(n))r.push(`${e}- ${Mu(n)}`);else{if(Array.isArray(n))throw new Error("model yaml: nested arrays are not part of the model schema");{let o=Yi(n);if(o.length===0){r.push(`${e}- {}`);continue}o.forEach(([s,i],a)=>{let c=a===0?`${e}- `:`${e} `;Vi(s,i,c,`${e} `,r)})}}return}for(let[n,o]of Yi(t))Vi(n,o,e,e,r)}function Vi(t,e,r,n,o){if(Uu(e))o.push(`${r}${Xn(t)}: ${Mu(e)}`);else if(Array.isArray(e))e.length===0?o.push(`${r}${Xn(t)}: []`):(o.push(`${r}${Xn(t)}:`),Bu(e,`${n} `,o));else{let s=Yi(e);if(s.length===0)o.push(`${r}${Xn(t)}: {}`);else{o.push(`${r}${Xn(t)}:`);for(let[i,a]of s)Vi(i,a,`${n} `,`${n} `,o)}}}function mr(t){let e=[];return Bu(t,"",e),e.join(`
|
|
@@ -21,7 +21,7 @@ ${o.trim()}`.trim())}let n={};for(let o of e)n[o.id]=o;return{items:e,byId:n}}fu
|
|
|
21
21
|
${up(h,8e3)}`)}}return u.length===0?void 0:up(u.join(`
|
|
22
22
|
|
|
23
23
|
`),16e3)}catch{return}}async mergePR(e,r,n,o){let s=await fetch(`https://api.github.com/repos/${e.owner}/${e.repoName}/pulls/${r}/merge`,{method:"PUT",headers:{Authorization:`Bearer ${this.token}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28","Content-Type":"application/json","User-Agent":"codepipe-cli"},body:JSON.stringify({merge_method:n})});if(!s.ok)throw new Error(`github merge PR #${r}: ${s.status} ${await s.text()}`);let i=await s.json().catch(()=>null);if(o){let a=await fetch(`https://api.github.com/repos/${e.owner}/${e.repoName}/pulls/${r}`,{headers:{Authorization:`Bearer ${this.token}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28","User-Agent":"codepipe-cli"}});if(a.ok){let l=(await a.json()).head?.ref;l&&await fetch(`https://api.github.com/repos/${e.owner}/${e.repoName}/git/refs/heads/${l}`,{method:"DELETE",headers:{Authorization:`Bearer ${this.token}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28","User-Agent":"codepipe-cli"}}).catch(()=>{})}}return i?.sha?{mergedSha:i.sha}:{}}async addPRComment(e,r,n){let o=await fetch(`https://api.github.com/repos/${e.owner}/${e.repoName}/issues/${r}/comments`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28","Content-Type":"application/json","User-Agent":"codepipe-cli"},body:JSON.stringify({body:n})});if(!o.ok)throw new Error(`github comment PR #${r}: ${o.status} ${await o.text()}`)}async closePR(e,r,n){n&&n.length>0&&await this.addPRComment(e,r,n);let o=await fetch(`https://api.github.com/repos/${e.owner}/${e.repoName}/pulls/${r}`,{method:"PATCH",headers:{Authorization:`Bearer ${this.token}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28","Content-Type":"application/json","User-Agent":"codepipe-cli"},body:JSON.stringify({state:"closed"})});if(!o.ok)throw new Error(`github close PR #${r}: ${o.status} ${await o.text()}`)}},Qa=class{constructor(e){this.token=e}name="gitlab";pid(e){return encodeURIComponent(`${e.owner}/${e.repoName}`)}headers(e=!1){let r={"PRIVATE-TOKEN":this.token,"User-Agent":"codepipe-cli"};return e&&(r["Content-Type"]="application/json"),r}async createPullRequest(e,r){let n=await fetch(`https://gitlab.com/api/v4/projects/${this.pid(e)}/merge_requests`,{method:"POST",headers:this.headers(!0),body:JSON.stringify({source_branch:r.branchName,target_branch:r.baseBranch,title:r.title,description:r.body})});if(!n.ok)throw new Error(`gitlab mr create: ${n.status} ${await n.text()}`);let o=await n.json();return{url:o.web_url??"",number:o.iid}}async findOpenPrByBranch(e,r){let n=await fetch(`https://gitlab.com/api/v4/projects/${this.pid(e)}/merge_requests?state=opened&source_branch=${encodeURIComponent(r)}`,{headers:this.headers()});if(!n.ok)return null;let s=(await n.json())[0];return s?{url:s.web_url??"",number:s.iid}:null}async getPullRequest(e,r){let n=`https://gitlab.com/api/v4/projects/${this.pid(e)}/merge_requests/${r}`,o=await fetch(n,{method:"GET",headers:this.headers()});if(o.status===404)throw new wr(`GitLab MR not found: ${e.owner}/${e.repoName}!${r}`);if(o.status>=400)throw new Error(`gitlab GET merge_requests/${r} \u2192 ${o.status} ${await o.text()}`);let s=await o.json();if(s.state==="merged")return{state:"merged",merged:!0,ci:"none",mergeable:"unknown"};if(s.state==="closed"||s.state==="locked")return{state:"closed",merged:!1,ci:"none",mergeable:"unknown"};let i=q$(s.head_pipeline?.status??s.pipeline?.status),a=s.merge_status==="cannot_be_merged"||s.has_conflicts===!0?"conflict":s.merge_status==="can_be_merged"&&s.blocking_discussions_resolved!==!1?"mergeable":"unknown";return{state:"open",merged:!1,ci:i,mergeable:a}}async mergePR(e,r,n,o){let s=`https://gitlab.com/api/v4/projects/${this.pid(e)}/merge_requests/${r}`,i,a=await fetch(s,{headers:this.headers()});if(a.ok){let u=await a.json().catch(()=>null);i=u?.sha??u?.diff_refs?.head_sha}let c=await fetch(`${s}/merge`,{method:"PUT",headers:this.headers(!0),body:JSON.stringify({squash:n==="squash",should_remove_source_branch:o,...i?{sha:i}:{}})});if(!c.ok)throw new Error(`gitlab merge MR !${r}: ${c.status} ${await c.text()}`);let l=await c.json().catch(()=>null);return l?.merge_commit_sha?{mergedSha:l.merge_commit_sha}:{}}async addPRComment(e,r,n){let o=await fetch(`https://gitlab.com/api/v4/projects/${this.pid(e)}/merge_requests/${r}/notes`,{method:"POST",headers:this.headers(!0),body:JSON.stringify({body:n})});if(!o.ok)throw new Error(`gitlab comment MR !${r}: ${o.status} ${await o.text()}`)}async closePR(e,r,n){n&&n.length>0&&await this.addPRComment(e,r,n);let o=await fetch(`https://gitlab.com/api/v4/projects/${this.pid(e)}/merge_requests/${r}`,{method:"PUT",headers:this.headers(!0),body:JSON.stringify({state_event:"close"})});if(!o.ok)throw new Error(`gitlab close MR !${r}: ${o.status} ${await o.text()}`)}};ec=class{name="mock";async createPullRequest(e,r){let n=Math.floor(Math.random()*9e3)+1e3;return{url:`https://example.com/${e.owner}/${e.repoName}/pull-requests/${n}`,number:n}}async getPullRequest(e,r){return{state:"open",merged:!1,ci:"none",mergeable:"unknown"}}async mergePR(e,r,n,o){throw new Error(Xa(e,r,"merge"))}async closePR(e,r,n){throw new Error(Xa(e,r,"close"))}async addPRComment(e,r,n){throw new Error(Xa(e,r,"comment"))}}});import{X509Certificate as hp}from"node:crypto";import{readFileSync as Y$}from"node:fs";import Yt from"node:tls";function V$(t){return t.match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g)??[]}function kp(t=yp){if(fp)return;fp=!0;let e=J("EXTRA_CA_FILE");if(!(!e||!gp))try{let r=V$(Y$(e,"utf8"));if(r.length===0){t(`[tls] CODEPIPE_EXTRA_CA_FILE ${e} has no PEM certificates \u2014 ignored`);return}Yt.setDefaultCACertificates([...Yt.getCACertificates(),...r]),t(`[tls] trusting ${r.length} extra CA cert(s) from ${e}`)}catch(r){t(`[tls] failed to load CODEPIPE_EXTRA_CA_FILE ${e}: ${r instanceof Error?r.message:String(r)}`)}}function wp(t){let e=t&&typeof t=="object"&&"cause"in t?t.cause?.code:void 0;return e==="UNABLE_TO_VERIFY_LEAF_SIGNATURE"||e==="UNABLE_TO_GET_ISSUER_CERT_LOCALLY"||e==="UNABLE_TO_GET_ISSUER_CERT"}function z$(t){let e=t.infoAccess;if(!e)return null;for(let r of e.split(`
|
|
24
|
-
`)){let n=r.match(/CA Issuers - URI:\s*(https?:\/\/\S+)/i);if(n?.[1])return n[1].trim()}return null}function X$(t,e,r){return new Promise((n,o)=>{let s=Yt.connect({host:t,port:e,servername:t,rejectUnauthorized:!1},()=>{let i=s.getPeerCertificate(!0),a=new Set;for(;i?.issuerCertificate&&i.issuerCertificate!==i&&i.fingerprint256&&!a.has(i.fingerprint256);)a.add(i.fingerprint256),i=i.issuerCertificate;let c=i?.raw?new hp(i.raw):null;s.end(),n(c)});s.on("error",o),s.setTimeout(r,()=>{s.destroy(),o(new Error("tls connect timeout"))})})}function tc(t,e,r){return new Promise(n=>{let o=Yt.connect({host:t,port:e,servername:t,rejectUnauthorized:!0},()=>{o.end(),n(!0)});o.on("error",()=>n(!1)),o.setTimeout(r,()=>{o.destroy(),n(!1)})})}async function J$(t){try{let e=await fetch(t);return e.ok?new hp(Buffer.from(await e.arrayBuffer())):null}catch{return null}}function bp(t,e=443,r=yp){let n=`${t}:${e}`,o=mp.get(n);if(o)return o;let s=Z$(t,e,r).catch(i=>(r(`[tls] chain repair for ${t} failed: ${i instanceof Error?i.message:String(i)}`),!1));return mp.set(n,s),s}async function Z$(t,e,r){if(!gp)return!1;let n=8e3;if(await tc(t,e,n))return!0;let o=await X$(t,e,n),s=Yt.getCACertificates(),i=[];for(let a=0;a<4&&o&&o.subject!==o.issuer;a++){let c=z$(o);if(!c)break;let l=await J$(c);if(!l)break;if(i.push(l.toString()),Yt.setDefaultCACertificates([...s,...i]),await tc(t,e,n))return r(`[tls] completed certificate chain for ${t} via AIA (+${i.length} intermediate cert(s))`),!0;if(l.subject===l.issuer)break;o=l}return tc(t,e,n)}var gp,fp,mp,yp,$p=$(()=>{"use strict";Le();gp=typeof Yt.getCACertificates=="function"&&typeof Yt.setDefaultCACertificates=="function",fp=!1,mp=new Map,yp=t=>console.warn(t)});function Ep(){let t=process.env.YOUTRACK_URL,e=process.env.YOUTRACK_TOKEN;return!t||!e?null:{baseUrl:t.replace(/\/$/,""),token:e}}async function et(t,e,r){kp();let n={Authorization:`Bearer ${t.token}`,Accept:"application/json"};r?.body&&(n["Content-Type"]="application/json");let o=t.baseUrl+e,s={...r,headers:{...n,...r?.headers??{}}};try{return await fetch(o,s)}catch(i){if(wp(i)&&await bp(new URL(t.baseUrl).host))return await fetch(o,s);throw i}}function Q$(t,e){return!!(t===429||t>=500||t===418&&/read-only|invalid_state/i.test(e))}function ev(){let t=Number(process.env.YOUTRACK_WRITE_RETRIES);return{attempts:Number.isFinite(t)&&t>=1?Math.floor(t):6,baseMs:1e3,capMs:15e3}}async function rc(t,e,r,n){let{attempts:o,baseMs:s,capMs:i}=ev(),a=null;for(let c=1;c<=o;c++){let l=null;try{l=await et(t,r,n)}catch(u){a=new Error(`${e}: ${u instanceof Error?u.message:String(u)}`)}if(l){if(l.ok)return l;let u=await l.text();if(c<o&&Q$(l.status,u)){await vp(Math.min(i,s*2**(c-1)));continue}throw new Error(`${e}: ${l.status} ${u}`)}if(c<o){await vp(Math.min(i,s*2**(c-1)));continue}throw a??new Error(`${e}: request failed`)}throw a??new Error(`${e}: request failed`)}async function Vt(t){let e;try{e=await et(t,"/api/users/me?fields=login,fullName")}catch(n){throw new Error(`cannot reach ${t.baseUrl} (${n instanceof Error?n.message:String(n)})`)}if(e.status===401)throw new Error("token rejected (401 \u2014 check the YouTrack PAT)");if(!e.ok)throw new Error(`YouTrack \u2192 ${e.status} ${e.statusText}`);let r=await e.json();return r.login??r.fullName??"ok"}async function Rp(t){try{let e=await et(t,"/api/users/me?fields=login");return e.ok?(await e.json()).login??void 0:void 0}catch{return}}async function tv(t,e,r,n){let o=`${e.split("-")[0]}:${n}:${r}`,s=xp.get(o);if(s)return s;let i=await et(t,`/api/issues/${encodeURIComponent(e)}?fields=customFields(name,projectCustomField(bundle(values(name,id))))`);if(!i.ok)throw new Error(`yt resolveStateId ${e}: ${i.status} ${await i.text()}`);let c=(await i.json()).customFields.find(u=>u.name===n);if(!c)throw new Error(`yt: issue ${e} has no ${n} custom field`);let l=c.projectCustomField.bundle.values.find(u=>u.name===r);if(!l)throw new Error(`yt: state "${r}" not found in ${n} bundle for ${e}`);return xp.set(o,l.id),l.id}async function Tp(t,e,r,n=co){let o=await tv(t,e,r,n);await rc(t,`yt updateState ${e}`,`/api/issues/${encodeURIComponent(e)}?fields=idReadable`,{method:"POST",body:JSON.stringify({customFields:[{name:n,$type:"StateIssueCustomField",value:{id:o,$type:"StateBundleElement"}}]})})}async function Ip(t,e,r){return await(await rc(t,`yt addComment ${e}`,`/api/issues/${encodeURIComponent(e)}/comments?fields=id`,{method:"POST",body:JSON.stringify({text:r})})).json()}async function Cp(t,e,r){let n={};r.summary!==void 0&&(n.summary=r.summary),r.description!==void 0&&(n.description=r.description),await rc(t,`yt updateIssue ${e}`,`/api/issues/${encodeURIComponent(e)}?fields=idReadable`,{method:"POST",body:JSON.stringify(n)})}async function Ap(t,e){let r=Sp.get(e);if(r)return r;let n=await et(t,"/api/admin/projects?fields=id,shortName&$top=200");if(!n.ok)throw new Error(`yt resolveProjectId: ${n.status} ${await n.text()}`);let s=(await n.json()).find(i=>i.shortName===e);if(!s)throw new Error(`yt: project "${e}" not found in /api/admin/projects`);return Sp.set(e,s.id),s.id}async function Pp(t,e,r,n,o,s=co){let i=await Ap(t,e),a=await et(t,"/api/issues?fields=id,idReadable",{method:"POST",body:JSON.stringify({project:{id:i},summary:r,description:n,customFields:[{name:s,$type:"StateIssueCustomField",value:{name:o,$type:"StateBundleElement"}}]})});if(!a.ok)throw new Error(`yt createIssue: ${a.status} ${await a.text()}`);let c=await a.json();return{id:c.id,key:c.idReadable}}async function _p(t,e,r,n){let o=r==="subtask_of"?`subtask of ${n}`:`depends on ${n}`,s=await et(t,"/api/commands",{method:"POST",body:JSON.stringify({query:o,issues:[{idReadable:e}]})});if(!s.ok)throw new Error(`yt applyIssueLink (${o} on ${e}): ${s.status} ${await s.text()}`)}function Op(t){if(!t||t.length===0)return;let e=[];for(let r of t)!r.url||!r.name||e.push({id:r.id,name:r.name,url:r.url,...r.mimeType?{mimeType:r.mimeType}:{},...typeof r.size=="number"?{size:r.size}:{}});return e.length>0?e:void 0}async function Lp(t,e){let r=e.startsWith("http")?e:t.baseUrl+e,n=await fetch(r,{headers:{Authorization:`Bearer ${t.token}`}});if(!n.ok)throw new Error(`yt downloadAttachment ${e}: ${n.status}`);return Buffer.from(await n.arrayBuffer())}async function Dp(t,e){let r=e.stageField??co,n=[`project: ${e.projectKey}`];if(e.columns&&e.columns.length>0){let c=e.columns.map(l=>`{${l}}`).join(", ");n.push(`${r}: ${c}`)}if(e.updatedSince){let c=new Date(e.updatedSince).toISOString().slice(0,10);n.push(`updated: ${c} .. *`)}e.assignee?n.push(`Assignee: {${e.assignee}}`):e.requireAnyAssignee&&n.push("has: Assignee");let o=n.join(" "),s=`/api/issues?query=${encodeURIComponent(o)}&fields=${Np}&$top=200`,i=await et(t,s);if(!i.ok)throw new Error(`yt listIssues: ${i.status} ${await i.text()}`);return(await i.json()).map(c=>Bp(c,r))}async function Mp(t,e,r=co){let n=`/api/issues/${encodeURIComponent(e)}?fields=${Np}`,o=await et(t,n);if(o.status===404)return null;if(!o.ok)throw new Error(`yt getIssue ${e}: ${o.status} ${await o.text()}`);return Bp(await o.json(),r)}async function Up(t,e,r){let n=`/api/issues/${encodeURIComponent(e)}/comments?fields=${nv}&$top=500`,o=await et(t,n);if(!o.ok)throw new Error(`yt listComments ${e}: ${o.status} ${await o.text()}`);return(await o.json()).filter(i=>i.created>r).map(i=>{let a={id:i.id,issueId:e,author:i.author?.login??"unknown",body:i.text??"",createdAt:new Date(i.created).toISOString()},c=Op(i.attachments);return c&&(a.attachments=c),a})}function ov(t){if(!t||t.length===0)return;let e=[];for(let r of t){if(r.direction!=="INWARD")continue;let n=r.linkType?.name==="Depend"?"depends_on":r.linkType?.name==="Subtask"?"subtask":null;if(n)for(let o of r.issues??[])o.idReadable&&e.push({type:n,targetKey:o.idReadable})}return e.length>0?e:void 0}function Bp(t,e=co){let r=t.customFields??[],n=r.find(l=>l.name===e),o=r.find(l=>l.name==="Assignee"),s=r.find(l=>l.name==="Type"),i={id:t.id,key:t.idReadable,title:t.summary,status:n?.value?.name??"Unknown",updatedAt:t.updated?new Date(t.updated).toISOString():new Date().toISOString()};t.description&&(i.description=t.description),o?.value?.login&&(i.assignee=o.value.login),s?.value?.name&&(i.issueType=s.value.name),t.tags&&t.tags.length>0&&(i.tags=t.tags.map(l=>l.name));let a=Op(t.attachments);a&&(i.attachments=a);let c=ov(t.links);return c&&(i.links=c),i}async function Fp(t,e){let r=await sv(t,e);return r.length>0?r:iv(t,e)}async function sv(t,e){let r=await Ap(t,e),n=await et(t,`/api/admin/projects/${encodeURIComponent(r)}/customFields?fields=$type,field(name),bundle(values(name,archived))&$top=100`);if(!n.ok)return[];let o=await n.json(),s=[];for(let i of o)i.$type==="StateProjectCustomField"&&i.field?.name&&s.push({name:i.field.name,values:Kp(i.bundle)});return s}async function iv(t,e){let r=`project: ${e}`,n=await et(t,`/api/issues?query=${encodeURIComponent(r)}&fields=customFields(name,$type,projectCustomField(bundle(values(name,archived))))&$top=1`);if(!n.ok)throw new Error(`yt fetchProjectStateFields ${e}: ${n.status} ${await n.text()}`);let o=await n.json(),s=[];for(let i of o[0]?.customFields??[])i.$type==="StateIssueCustomField"&&i.name&&s.push({name:i.name,values:Kp(i.projectCustomField?.bundle)});return s}function Kp(t){return(t?.values??[]).filter(e=>!!e.name&&e.archived!==!0).map(e=>e.name)}var vp,co,xp,Sp,jp,rv,Np,nv,br=$(()=>{"use strict";$p();vp=t=>new Promise(e=>setTimeout(e,t));co="Stage",xp=new Map;Sp=new Map;jp="attachments(id,name,url,size,mimeType)",rv="links(direction,linkType(name),issues(idReadable))",Np=`id,idReadable,summary,description,updated,customFields(name,value(name,login)),tags(name),${jp},${rv}`,nv=`id,text,created,author(login),${jp}`});function pt(t){let e=t instanceof Error?t.message:String(t);return e.length>120?e.slice(0,117)+"\u2026":e}function tn(t){return t instanceof Qe}async function Gp(t,e){let r=q(t),n=[],o=[],s=()=>Date.now();if(e?.trackerProvider==="internal")n.push({name:"tracker",ok:!0,detail:"built-in tracker"});else if(r?.youtrack?.url&&r.youtrack.token)try{let c=await Vt({baseUrl:r.youtrack.url,token:r.youtrack.token});n.push({name:"youtrack",ok:!0}),o.push({kind:"youtrack",present:!0,ok:!0,identity:c,checkedAt:s()})}catch(c){n.push({name:"youtrack",ok:!1,detail:pt(c)}),o.push({kind:"youtrack",present:!0,ok:!1,detail:pt(c),checkedAt:s()})}else n.push({name:"youtrack",ok:!1,detail:"no YouTrack token"}),o.push({kind:"youtrack",present:!1,checkedAt:s()});let i=!1;if(r?.github?.token){i=!0;try{let c=await Gt(r.github.token);n.push({name:"github",ok:!0}),o.push({kind:"github",present:!0,ok:!0,identity:c,checkedAt:s()})}catch(c){tn(c)?(n.push({name:"github",ok:!0}),o.push({kind:"github",present:!0,detail:"check inconclusive",checkedAt:s()})):(n.push({name:"github",ok:!1,detail:pt(c)}),o.push({kind:"github",present:!0,ok:!1,detail:pt(c),checkedAt:s()}))}}else o.push({kind:"github",present:!1,checkedAt:s()});if(r?.bitbucket?.email&&r.bitbucket.apiToken){i=!0;try{let c=await Ht(r.bitbucket.email,r.bitbucket.apiToken);n.push({name:"bitbucket",ok:!0}),o.push({kind:"bitbucket",present:!0,ok:!0,identity:c,checkedAt:s()})}catch(c){tn(c)?(n.push({name:"bitbucket",ok:!0}),o.push({kind:"bitbucket",present:!0,detail:"check inconclusive",checkedAt:s()})):(n.push({name:"bitbucket",ok:!1,detail:pt(c)}),o.push({kind:"bitbucket",present:!0,ok:!1,detail:pt(c),checkedAt:s()}))}}else o.push({kind:"bitbucket",present:!1,checkedAt:s()});if(r?.gitlab?.token){i=!0;try{let c=await Wt(r.gitlab.token);n.push({name:"gitlab",ok:!0}),o.push({kind:"gitlab",present:!0,ok:!0,identity:c,checkedAt:s()})}catch(c){tn(c)?(n.push({name:"gitlab",ok:!0}),o.push({kind:"gitlab",present:!0,detail:"check inconclusive",checkedAt:s()})):(n.push({name:"gitlab",ok:!1,detail:pt(c)}),o.push({kind:"gitlab",present:!0,ok:!1,detail:pt(c),checkedAt:s()}))}}else o.push({kind:"gitlab",present:!1,checkedAt:s()});if(i||n.push({name:"git",ok:!1,detail:"no GitHub/Bitbucket/GitLab credentials"}),r?.github?.token){let c=r.github.token;for(let u of e?.repos??[])if(u.host==="github")try{await ms(c,u.owner,u.repoName),n.push({name:`repo:${u.name}`,ok:!0})}catch(p){tn(p)?n.push({name:`repo:${u.name}`,ok:!0,detail:"check inconclusive"}):n.push({name:`repo:${u.name}`,ok:!1,detail:pt(p)})}let l=e?.contextRepo;if(l?.host==="github")try{await ms(c,l.owner,l.name),n.push({name:"context-repo",ok:!0})}catch(u){tn(u)?n.push({name:"context-repo",ok:!0,detail:"check inconclusive"}):n.push({name:"context-repo",ok:!1,detail:pt(u)})}}if(r?.contextWrite?.token){let c=e?.contextRepo;if(c?.host==="github")try{await ms(r.contextWrite.token,c.owner,c.name),o.push({kind:"contextWrite",present:!0,ok:!0,checkedAt:s()})}catch(l){tn(l)?o.push({kind:"contextWrite",present:!0,detail:"check inconclusive",checkedAt:s()}):o.push({kind:"contextWrite",present:!0,ok:!1,detail:pt(l),checkedAt:s()})}else o.push({kind:"contextWrite",present:!0,detail:"not live-checked",checkedAt:s()})}else o.push({kind:"contextWrite",present:!1,checkedAt:s()});let a=Zr(t);if(!a)n.push({name:"claude",ok:!1,detail:"no Claude token (run `codepipe login`)"}),o.push({kind:"claude",present:!1,checkedAt:s()});else if(process.env.CLI_READINESS_CLAUDE_LIVE==="0")n.push({name:"claude",ok:!0}),o.push({kind:"claude",present:!0,detail:"not live-checked",checkedAt:s()});else{let c=await zt(a);if(c==="invalid"){let l="Claude token rejected (401) \u2014 refresh via `claude setup-token`";n.push({name:"claude",ok:!1,detail:l}),o.push({kind:"claude",present:!0,ok:!1,detail:l,checkedAt:s()})}else n.push({name:"claude",ok:!0}),o.push({kind:"claude",present:!0,...c==="valid"?{ok:!0}:{detail:"check inconclusive"},checkedAt:s()})}return{ready:n.every(c=>c.ok),checks:n,creds:o,checkedAt:Date.now()}}async function zt(t){let e=new AbortController,r=setTimeout(()=>e.abort(),5e3);try{let n=await fetch("https://api.anthropic.com/v1/models?limit=1",{headers:{Authorization:`Bearer ${t}`,"anthropic-version":"2023-06-01","anthropic-beta":"oauth-2025-04-20"},signal:e.signal});return n.status===200?"valid":n.status===401?"invalid":"inconclusive"}catch{return"inconclusive"}finally{clearTimeout(r)}}async function Hp(t){let e=new AbortController,r=setTimeout(()=>e.abort(),5e3);try{let n=await fetch("https://api.anthropic.com/v1/models?limit=1000",{headers:{Authorization:`Bearer ${t}`,"anthropic-version":"2023-06-01","anthropic-beta":"oauth-2025-04-20"},signal:e.signal});if(n.status!==200)return null;let s=(await n.json())?.data;if(!Array.isArray(s))return null;let i=[];for(let a of s){let c=a?.id;if(typeof c!="string"||c.trim().length===0)continue;let l=a?.created_at;i.push({id:c,...typeof l=="string"?{createdAt:l}:{}})}return i}catch{return null}finally{clearTimeout(r)}}var rn=$(()=>{"use strict";pe();qt();br()});import av from"node:http";import nc from"node:crypto";function gs(){let t=oc(nc.randomBytes(32)),e=oc(nc.createHash("sha256").update(t).digest()),r=oc(nc.randomBytes(32));return{verifier:t,challenge:e,state:r}}function ic(t){let e=new URL(cv);return e.search=new URLSearchParams({response_type:"code",client_id:Wp,redirect_uri:t.redirectUri,scope:uv,state:t.state,code_challenge:t.challenge,code_challenge_method:"S256"}).toString(),e.toString()}function pv(t,e){let r=t.get("error");if(r)throw new Error(`oauth-error: ${r}`);if(t.get("state")!==e)throw new Error("state-mismatch");let n=t.get("code");if(!n)throw new Error("no-code");return n}function qp(t,e){let[r,n]=t.trim().split("#");if(!r)throw new Error("no-code");if(n!==void 0&&n!==e)throw new Error("state-mismatch");return r}function fv(t){let e=t,r=e?.access_token;if(!r||typeof r!="string")throw new Error(`no access_token in response: ${JSON.stringify(t)}`);return{oauthToken:r,...typeof e.refresh_token=="string"?{refreshToken:e.refresh_token}:{},...typeof e.expires_in=="number"?{expiresIn:e.expires_in}:{}}}async function ac(t){let e=await fetch(lv,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({grant_type:"authorization_code",code:t.code,state:t.state,redirect_uri:t.redirectUri,client_id:Wp,code_verifier:t.verifier})});if(!e.ok)throw new Error(`token endpoint ${e.status}: ${await e.text()}`);return fv(await e.json())}async function cc(t){let e=t.timeoutMs??dv,r=av.createServer();await new Promise(l=>r.listen(0,"127.0.0.1",l));let o=`http://localhost:${r.address().port}/callback`,s=ic({redirectUri:o,challenge:t.challenge,state:t.state}),i,a=new Promise((l,u)=>{i=setTimeout(()=>u(new Error("no-callback")),e),r.on("request",(p,d)=>{let m=new URL(p.url??"/",o);if(m.pathname!=="/callback"){d.statusCode=404,d.end();return}clearTimeout(i),d.setHeader("content-type","text/html"),d.end("<h3>Authorized \u2014 you can close this tab.</h3>");try{l(pv(m.searchParams,t.state))}catch(f){u(f)}})});a.catch(()=>{});let c;return{authUrl:s,redirectUri:o,waitForToken(){return c||(c=a.then(l=>ac({code:l,verifier:t.verifier,state:t.state,redirectUri:o})),c.catch(()=>{})),c},close(){clearTimeout(i),r.close()}}}async function Yp(t){let e=await cc(t);try{return t.openUrl(e.authUrl),t.log("Opening your browser to authorize Claude\u2026"),t.log(`If it didn't open, visit:
|
|
24
|
+
`)){let n=r.match(/CA Issuers - URI:\s*(https?:\/\/\S+)/i);if(n?.[1])return n[1].trim()}return null}function X$(t,e,r){return new Promise((n,o)=>{let s=Yt.connect({host:t,port:e,servername:t,rejectUnauthorized:!1},()=>{let i=s.getPeerCertificate(!0),a=new Set;for(;i?.issuerCertificate&&i.issuerCertificate!==i&&i.fingerprint256&&!a.has(i.fingerprint256);)a.add(i.fingerprint256),i=i.issuerCertificate;let c=i?.raw?new hp(i.raw):null;s.end(),n(c)});s.on("error",o),s.setTimeout(r,()=>{s.destroy(),o(new Error("tls connect timeout"))})})}function tc(t,e,r){return new Promise(n=>{let o=Yt.connect({host:t,port:e,servername:t,rejectUnauthorized:!0},()=>{o.end(),n(!0)});o.on("error",()=>n(!1)),o.setTimeout(r,()=>{o.destroy(),n(!1)})})}async function J$(t){try{let e=await fetch(t);return e.ok?new hp(Buffer.from(await e.arrayBuffer())):null}catch{return null}}function bp(t,e=443,r=yp){let n=`${t}:${e}`,o=mp.get(n);if(o)return o;let s=Z$(t,e,r).catch(i=>(r(`[tls] chain repair for ${t} failed: ${i instanceof Error?i.message:String(i)}`),!1));return mp.set(n,s),s}async function Z$(t,e,r){if(!gp)return!1;let n=8e3;if(await tc(t,e,n))return!0;let o=await X$(t,e,n),s=Yt.getCACertificates(),i=[];for(let a=0;a<4&&o&&o.subject!==o.issuer;a++){let c=z$(o);if(!c)break;let l=await J$(c);if(!l)break;if(i.push(l.toString()),Yt.setDefaultCACertificates([...s,...i]),await tc(t,e,n))return r(`[tls] completed certificate chain for ${t} via AIA (+${i.length} intermediate cert(s))`),!0;if(l.subject===l.issuer)break;o=l}return tc(t,e,n)}var gp,fp,mp,yp,$p=$(()=>{"use strict";Le();gp=typeof Yt.getCACertificates=="function"&&typeof Yt.setDefaultCACertificates=="function",fp=!1,mp=new Map,yp=t=>console.warn(t)});function Ep(){let t=process.env.YOUTRACK_URL,e=process.env.YOUTRACK_TOKEN;return!t||!e?null:{baseUrl:t.replace(/\/$/,""),token:e}}async function et(t,e,r){kp();let n={Authorization:`Bearer ${t.token}`,Accept:"application/json"};r?.body&&(n["Content-Type"]="application/json");let o=t.baseUrl+e,s={...r,headers:{...n,...r?.headers??{}}};try{return await fetch(o,s)}catch(i){if(wp(i)&&await bp(new URL(t.baseUrl).host))return await fetch(o,s);throw i}}function Q$(t,e){return!!(t===429||t>=500||t===418&&/read-only|invalid_state/i.test(e))}function ev(){let t=Number(process.env.YOUTRACK_WRITE_RETRIES);return{attempts:Number.isFinite(t)&&t>=1?Math.floor(t):6,baseMs:1e3,capMs:15e3}}async function rc(t,e,r,n){let{attempts:o,baseMs:s,capMs:i}=ev(),a=null;for(let c=1;c<=o;c++){let l=null;try{l=await et(t,r,n)}catch(u){a=new Error(`${e}: ${u instanceof Error?u.message:String(u)}`)}if(l){if(l.ok)return l;let u=await l.text();if(c<o&&Q$(l.status,u)){await vp(Math.min(i,s*2**(c-1)));continue}throw new Error(`${e}: ${l.status} ${u}`)}if(c<o){await vp(Math.min(i,s*2**(c-1)));continue}throw a??new Error(`${e}: request failed`)}throw a??new Error(`${e}: request failed`)}async function Vt(t){let e;try{e=await et(t,"/api/users/me?fields=login,fullName")}catch(n){throw new Error(`cannot reach ${t.baseUrl} (${n instanceof Error?n.message:String(n)})`)}if(e.status===401)throw new Error("token rejected (401 \u2014 check the YouTrack PAT)");if(!e.ok)throw new Error(`YouTrack \u2192 ${e.status} ${e.statusText}`);let r=await e.json();return r.login??r.fullName??"ok"}async function Rp(t){try{let e=await et(t,"/api/users/me?fields=login");return e.ok?(await e.json()).login??void 0:void 0}catch{return}}async function tv(t,e,r,n){let o=`${e.split("-")[0]}:${n}:${r}`,s=xp.get(o);if(s)return s;let i=await et(t,`/api/issues/${encodeURIComponent(e)}?fields=customFields(name,projectCustomField(bundle(values(name,id))))`);if(!i.ok)throw new Error(`yt resolveStateId ${e}: ${i.status} ${await i.text()}`);let c=(await i.json()).customFields.find(u=>u.name===n);if(!c)throw new Error(`yt: issue ${e} has no ${n} custom field`);let l=c.projectCustomField.bundle.values.find(u=>u.name===r);if(!l)throw new Error(`yt: state "${r}" not found in ${n} bundle for ${e}`);return xp.set(o,l.id),l.id}async function Tp(t,e,r,n=co){let o=await tv(t,e,r,n);await rc(t,`yt updateState ${e}`,`/api/issues/${encodeURIComponent(e)}?fields=idReadable`,{method:"POST",body:JSON.stringify({customFields:[{name:n,$type:"StateIssueCustomField",value:{id:o,$type:"StateBundleElement"}}]})})}async function Ip(t,e,r){return await(await rc(t,`yt addComment ${e}`,`/api/issues/${encodeURIComponent(e)}/comments?fields=id`,{method:"POST",body:JSON.stringify({text:r})})).json()}async function Cp(t,e,r){let n={};r.summary!==void 0&&(n.summary=r.summary),r.description!==void 0&&(n.description=r.description),await rc(t,`yt updateIssue ${e}`,`/api/issues/${encodeURIComponent(e)}?fields=idReadable`,{method:"POST",body:JSON.stringify(n)})}async function Ap(t,e){let r=Sp.get(e);if(r)return r;let n=await et(t,"/api/admin/projects?fields=id,shortName&$top=200");if(!n.ok)throw new Error(`yt resolveProjectId: ${n.status} ${await n.text()}`);let s=(await n.json()).find(i=>i.shortName===e);if(!s)throw new Error(`yt: project "${e}" not found in /api/admin/projects`);return Sp.set(e,s.id),s.id}async function Pp(t,e,r,n,o,s=co){let i=await Ap(t,e),a=await et(t,"/api/issues?fields=id,idReadable",{method:"POST",body:JSON.stringify({project:{id:i},summary:r,description:n,customFields:[{name:s,$type:"StateIssueCustomField",value:{name:o,$type:"StateBundleElement"}}]})});if(!a.ok)throw new Error(`yt createIssue: ${a.status} ${await a.text()}`);let c=await a.json();return{id:c.id,key:c.idReadable}}async function _p(t,e,r,n){let o=r==="subtask_of"?`subtask of ${n}`:`depends on ${n}`,s=await et(t,"/api/commands",{method:"POST",body:JSON.stringify({query:o,issues:[{idReadable:e}]})});if(!s.ok)throw new Error(`yt applyIssueLink (${o} on ${e}): ${s.status} ${await s.text()}`)}function Op(t){if(!t||t.length===0)return;let e=[];for(let r of t)!r.url||!r.name||e.push({id:r.id,name:r.name,url:r.url,...r.mimeType?{mimeType:r.mimeType}:{},...typeof r.size=="number"?{size:r.size}:{}});return e.length>0?e:void 0}async function Lp(t,e){let r=e.startsWith("http")?e:t.baseUrl+e,n=await fetch(r,{headers:{Authorization:`Bearer ${t.token}`}});if(!n.ok)throw new Error(`yt downloadAttachment ${e}: ${n.status}`);return Buffer.from(await n.arrayBuffer())}async function Dp(t,e){let r=e.stageField??co,n=[`project: ${e.projectKey}`];if(e.columns&&e.columns.length>0){let c=e.columns.map(l=>`{${l}}`).join(", ");n.push(`${r}: ${c}`)}if(e.updatedSince){let c=new Date(e.updatedSince).toISOString().slice(0,10);n.push(`updated: ${c} .. *`)}e.assignee?n.push(`Assignee: {${e.assignee}}`):e.requireAnyAssignee&&n.push("has: Assignee");let o=n.join(" "),s=`/api/issues?query=${encodeURIComponent(o)}&fields=${Np}&$top=200`,i=await et(t,s);if(!i.ok)throw new Error(`yt listIssues: ${i.status} ${await i.text()}`);let a=await i.json();if(e.columns&&e.columns.length>0&&a.length>0&&!a.some(l=>(l.customFields??[]).some(u=>u.name===r))){let l=[...new Set((a[0]?.customFields??[]).map(u=>u.name).filter(u=>!!u))];throw new Error(`youtrack.stage_field "${r}" does not exist in project ${e.projectKey} \u2014 YouTrack ignored the status filter and would have returned unrelated issues. `+(l.length>0?`Fields on the issues: ${l.join(", ")}.`:"The issues carry no custom fields at all."))}return a.map(c=>Bp(c,r))}async function Mp(t,e,r=co){let n=`/api/issues/${encodeURIComponent(e)}?fields=${Np}`,o=await et(t,n);if(o.status===404)return null;if(!o.ok)throw new Error(`yt getIssue ${e}: ${o.status} ${await o.text()}`);return Bp(await o.json(),r)}async function Up(t,e,r){let n=`/api/issues/${encodeURIComponent(e)}/comments?fields=${nv}&$top=500`,o=await et(t,n);if(!o.ok)throw new Error(`yt listComments ${e}: ${o.status} ${await o.text()}`);return(await o.json()).filter(i=>i.created>r).map(i=>{let a={id:i.id,issueId:e,author:i.author?.login??"unknown",body:i.text??"",createdAt:new Date(i.created).toISOString()},c=Op(i.attachments);return c&&(a.attachments=c),a})}function ov(t){if(!t||t.length===0)return;let e=[];for(let r of t){if(r.direction!=="INWARD")continue;let n=r.linkType?.name==="Depend"?"depends_on":r.linkType?.name==="Subtask"?"subtask":null;if(n)for(let o of r.issues??[])o.idReadable&&e.push({type:n,targetKey:o.idReadable})}return e.length>0?e:void 0}function Bp(t,e=co){let r=t.customFields??[],n=r.find(l=>l.name===e),o=r.find(l=>l.name==="Assignee"),s=r.find(l=>l.name==="Type"),i={id:t.id,key:t.idReadable,title:t.summary,status:n?.value?.name??"Unknown",updatedAt:t.updated?new Date(t.updated).toISOString():new Date().toISOString()};t.description&&(i.description=t.description),o?.value?.login&&(i.assignee=o.value.login),s?.value?.name&&(i.issueType=s.value.name),t.tags&&t.tags.length>0&&(i.tags=t.tags.map(l=>l.name));let a=Op(t.attachments);a&&(i.attachments=a);let c=ov(t.links);return c&&(i.links=c),i}async function Fp(t,e){let r=await sv(t,e);return r.length>0?r:iv(t,e)}async function sv(t,e){let r=await Ap(t,e),n=await et(t,`/api/admin/projects/${encodeURIComponent(r)}/customFields?fields=$type,field(name),bundle(values(name,archived))&$top=100`);if(!n.ok)return[];let o=await n.json(),s=[];for(let i of o)i.$type==="StateProjectCustomField"&&i.field?.name&&s.push({name:i.field.name,values:Kp(i.bundle)});return s}async function iv(t,e){let r=`project: ${e}`,n=await et(t,`/api/issues?query=${encodeURIComponent(r)}&fields=customFields(name,$type,projectCustomField(bundle(values(name,archived))))&$top=1`);if(!n.ok)throw new Error(`yt fetchProjectStateFields ${e}: ${n.status} ${await n.text()}`);let o=await n.json(),s=[];for(let i of o[0]?.customFields??[])i.$type==="StateIssueCustomField"&&i.name&&s.push({name:i.name,values:Kp(i.projectCustomField?.bundle)});return s}function Kp(t){return(t?.values??[]).filter(e=>!!e.name&&e.archived!==!0).map(e=>e.name)}var vp,co,xp,Sp,jp,rv,Np,nv,br=$(()=>{"use strict";$p();vp=t=>new Promise(e=>setTimeout(e,t));co="Stage",xp=new Map;Sp=new Map;jp="attachments(id,name,url,size,mimeType)",rv="links(direction,linkType(name),issues(idReadable))",Np=`id,idReadable,summary,description,updated,customFields(name,value(name,login)),tags(name),${jp},${rv}`,nv=`id,text,created,author(login),${jp}`});function pt(t){let e=t instanceof Error?t.message:String(t);return e.length>120?e.slice(0,117)+"\u2026":e}function tn(t){return t instanceof Qe}async function Gp(t,e){let r=q(t),n=[],o=[],s=()=>Date.now();if(e?.trackerProvider==="internal")n.push({name:"tracker",ok:!0,detail:"built-in tracker"});else if(r?.youtrack?.url&&r.youtrack.token)try{let c=await Vt({baseUrl:r.youtrack.url,token:r.youtrack.token});n.push({name:"youtrack",ok:!0}),o.push({kind:"youtrack",present:!0,ok:!0,identity:c,checkedAt:s()})}catch(c){n.push({name:"youtrack",ok:!1,detail:pt(c)}),o.push({kind:"youtrack",present:!0,ok:!1,detail:pt(c),checkedAt:s()})}else n.push({name:"youtrack",ok:!1,detail:"no YouTrack token"}),o.push({kind:"youtrack",present:!1,checkedAt:s()});let i=!1;if(r?.github?.token){i=!0;try{let c=await Gt(r.github.token);n.push({name:"github",ok:!0}),o.push({kind:"github",present:!0,ok:!0,identity:c,checkedAt:s()})}catch(c){tn(c)?(n.push({name:"github",ok:!0}),o.push({kind:"github",present:!0,detail:"check inconclusive",checkedAt:s()})):(n.push({name:"github",ok:!1,detail:pt(c)}),o.push({kind:"github",present:!0,ok:!1,detail:pt(c),checkedAt:s()}))}}else o.push({kind:"github",present:!1,checkedAt:s()});if(r?.bitbucket?.email&&r.bitbucket.apiToken){i=!0;try{let c=await Ht(r.bitbucket.email,r.bitbucket.apiToken);n.push({name:"bitbucket",ok:!0}),o.push({kind:"bitbucket",present:!0,ok:!0,identity:c,checkedAt:s()})}catch(c){tn(c)?(n.push({name:"bitbucket",ok:!0}),o.push({kind:"bitbucket",present:!0,detail:"check inconclusive",checkedAt:s()})):(n.push({name:"bitbucket",ok:!1,detail:pt(c)}),o.push({kind:"bitbucket",present:!0,ok:!1,detail:pt(c),checkedAt:s()}))}}else o.push({kind:"bitbucket",present:!1,checkedAt:s()});if(r?.gitlab?.token){i=!0;try{let c=await Wt(r.gitlab.token);n.push({name:"gitlab",ok:!0}),o.push({kind:"gitlab",present:!0,ok:!0,identity:c,checkedAt:s()})}catch(c){tn(c)?(n.push({name:"gitlab",ok:!0}),o.push({kind:"gitlab",present:!0,detail:"check inconclusive",checkedAt:s()})):(n.push({name:"gitlab",ok:!1,detail:pt(c)}),o.push({kind:"gitlab",present:!0,ok:!1,detail:pt(c),checkedAt:s()}))}}else o.push({kind:"gitlab",present:!1,checkedAt:s()});if(i||n.push({name:"git",ok:!1,detail:"no GitHub/Bitbucket/GitLab credentials"}),r?.github?.token){let c=r.github.token;for(let u of e?.repos??[])if(u.host==="github")try{await ms(c,u.owner,u.repoName),n.push({name:`repo:${u.name}`,ok:!0})}catch(p){tn(p)?n.push({name:`repo:${u.name}`,ok:!0,detail:"check inconclusive"}):n.push({name:`repo:${u.name}`,ok:!1,detail:pt(p)})}let l=e?.contextRepo;if(l?.host==="github")try{await ms(c,l.owner,l.name),n.push({name:"context-repo",ok:!0})}catch(u){tn(u)?n.push({name:"context-repo",ok:!0,detail:"check inconclusive"}):n.push({name:"context-repo",ok:!1,detail:pt(u)})}}if(r?.contextWrite?.token){let c=e?.contextRepo;if(c?.host==="github")try{await ms(r.contextWrite.token,c.owner,c.name),o.push({kind:"contextWrite",present:!0,ok:!0,checkedAt:s()})}catch(l){tn(l)?o.push({kind:"contextWrite",present:!0,detail:"check inconclusive",checkedAt:s()}):o.push({kind:"contextWrite",present:!0,ok:!1,detail:pt(l),checkedAt:s()})}else o.push({kind:"contextWrite",present:!0,detail:"not live-checked",checkedAt:s()})}else o.push({kind:"contextWrite",present:!1,checkedAt:s()});let a=Zr(t);if(!a)n.push({name:"claude",ok:!1,detail:"no Claude token (run `codepipe login`)"}),o.push({kind:"claude",present:!1,checkedAt:s()});else if(process.env.CLI_READINESS_CLAUDE_LIVE==="0")n.push({name:"claude",ok:!0}),o.push({kind:"claude",present:!0,detail:"not live-checked",checkedAt:s()});else{let c=await zt(a);if(c==="invalid"){let l="Claude token rejected (401) \u2014 refresh via `claude setup-token`";n.push({name:"claude",ok:!1,detail:l}),o.push({kind:"claude",present:!0,ok:!1,detail:l,checkedAt:s()})}else n.push({name:"claude",ok:!0}),o.push({kind:"claude",present:!0,...c==="valid"?{ok:!0}:{detail:"check inconclusive"},checkedAt:s()})}return{ready:n.every(c=>c.ok),checks:n,creds:o,checkedAt:Date.now()}}async function zt(t){let e=new AbortController,r=setTimeout(()=>e.abort(),5e3);try{let n=await fetch("https://api.anthropic.com/v1/models?limit=1",{headers:{Authorization:`Bearer ${t}`,"anthropic-version":"2023-06-01","anthropic-beta":"oauth-2025-04-20"},signal:e.signal});return n.status===200?"valid":n.status===401?"invalid":"inconclusive"}catch{return"inconclusive"}finally{clearTimeout(r)}}async function Hp(t){let e=new AbortController,r=setTimeout(()=>e.abort(),5e3);try{let n=await fetch("https://api.anthropic.com/v1/models?limit=1000",{headers:{Authorization:`Bearer ${t}`,"anthropic-version":"2023-06-01","anthropic-beta":"oauth-2025-04-20"},signal:e.signal});if(n.status!==200)return null;let s=(await n.json())?.data;if(!Array.isArray(s))return null;let i=[];for(let a of s){let c=a?.id;if(typeof c!="string"||c.trim().length===0)continue;let l=a?.created_at;i.push({id:c,...typeof l=="string"?{createdAt:l}:{}})}return i}catch{return null}finally{clearTimeout(r)}}var rn=$(()=>{"use strict";pe();qt();br()});import av from"node:http";import nc from"node:crypto";function gs(){let t=oc(nc.randomBytes(32)),e=oc(nc.createHash("sha256").update(t).digest()),r=oc(nc.randomBytes(32));return{verifier:t,challenge:e,state:r}}function ic(t){let e=new URL(cv);return e.search=new URLSearchParams({response_type:"code",client_id:Wp,redirect_uri:t.redirectUri,scope:uv,state:t.state,code_challenge:t.challenge,code_challenge_method:"S256"}).toString(),e.toString()}function pv(t,e){let r=t.get("error");if(r)throw new Error(`oauth-error: ${r}`);if(t.get("state")!==e)throw new Error("state-mismatch");let n=t.get("code");if(!n)throw new Error("no-code");return n}function qp(t,e){let[r,n]=t.trim().split("#");if(!r)throw new Error("no-code");if(n!==void 0&&n!==e)throw new Error("state-mismatch");return r}function fv(t){let e=t,r=e?.access_token;if(!r||typeof r!="string")throw new Error(`no access_token in response: ${JSON.stringify(t)}`);return{oauthToken:r,...typeof e.refresh_token=="string"?{refreshToken:e.refresh_token}:{},...typeof e.expires_in=="number"?{expiresIn:e.expires_in}:{}}}async function ac(t){let e=await fetch(lv,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({grant_type:"authorization_code",code:t.code,state:t.state,redirect_uri:t.redirectUri,client_id:Wp,code_verifier:t.verifier})});if(!e.ok)throw new Error(`token endpoint ${e.status}: ${await e.text()}`);return fv(await e.json())}async function cc(t){let e=t.timeoutMs??dv,r=av.createServer();await new Promise(l=>r.listen(0,"127.0.0.1",l));let o=`http://localhost:${r.address().port}/callback`,s=ic({redirectUri:o,challenge:t.challenge,state:t.state}),i,a=new Promise((l,u)=>{i=setTimeout(()=>u(new Error("no-callback")),e),r.on("request",(p,d)=>{let m=new URL(p.url??"/",o);if(m.pathname!=="/callback"){d.statusCode=404,d.end();return}clearTimeout(i),d.setHeader("content-type","text/html"),d.end("<h3>Authorized \u2014 you can close this tab.</h3>");try{l(pv(m.searchParams,t.state))}catch(f){u(f)}})});a.catch(()=>{});let c;return{authUrl:s,redirectUri:o,waitForToken(){return c||(c=a.then(l=>ac({code:l,verifier:t.verifier,state:t.state,redirectUri:o})),c.catch(()=>{})),c},close(){clearTimeout(i),r.close()}}}async function Yp(t){let e=await cc(t);try{return t.openUrl(e.authUrl),t.log("Opening your browser to authorize Claude\u2026"),t.log(`If it didn't open, visit:
|
|
25
25
|
${e.authUrl}`),t.log(`Waiting for the redirect on ${e.redirectUri} \u2026`),await e.waitForToken()}finally{e.close()}}var Wp,cv,lv,sc,uv,dv,oc,lc=$(()=>{"use strict";Wp="9d1c250a-e61b-44d9-88ed-5944d1962f5e",cv="https://platform.claude.com/oauth/authorize",lv="https://platform.claude.com/v1/oauth/token",sc="https://platform.claude.com/oauth/code/callback",uv="org:create_api_key user:profile user:inference",dv=12e4,oc=t=>Buffer.from(t).toString("base64url")});async function Vp(t,e,r,n,o){let s=c=>{e.readyState===e.OPEN&&e.send(JSON.stringify(c))},i=c=>s({type:"agent_login_url",requestId:r.requestId,projectId:t.projectId,error:c});if(J("ORIGIN")==="farm"||J("CLAUDE_AUTOLOGIN")==="0"){i("autologin_disabled");return}let a;try{a=await cc(gs())}catch(c){i(`listener failed: ${c instanceof Error?c.message:String(c)}`);return}s({type:"agent_login_url",requestId:r.requestId,projectId:t.projectId,authUrl:a.authUrl}),n.info(`[agent-auth] authorize Claude in a browser on THIS machine: ${a.authUrl}`),n.info(`[agent-auth] waiting for the redirect on ${a.redirectUri} \u2026`);try{let c=await a.waitForToken(),l=await zt(c.oauthToken);if(l==="invalid"){s({type:"agent_login_result",projectId:t.projectId,ok:!1,detail:"token rejected (401) \u2014 previous token kept"}),n.warn("[agent-auth] new Claude token rejected (401) \u2014 previous token kept");return}let u=q(t.projectId);if(!u){s({type:"agent_login_result",projectId:t.projectId,ok:!1,detail:"no secrets file for this project on the CLI"}),n.warn("[agent-auth] no secrets file for this project \u2014 token not saved");return}u.claude={oauthToken:c.oauthToken},ie(u),n.info(`[agent-auth] Claude token replaced (${c.oauthToken.slice(0,12)}\u2026, ${c.oauthToken.length} chars)`),s({type:"agent_login_result",projectId:t.projectId,ok:!0,...l==="inconclusive"?{detail:"saved (live check inconclusive)"}:{}}),o()}catch(c){let l=c instanceof Error?c.message:String(c);s({type:"agent_login_result",projectId:t.projectId,ok:!1,detail:l}),n.warn(`[agent-auth] browser authorization failed: ${l}`)}finally{a.close()}}var zp=$(()=>{"use strict";Le();rn();pe();lc()});function Xp(t,e){let r=t.find(n=>n.kind==="claude");return r?.present===!0&&r.ok===!1?J("ORIGIN")==="farm"||J("CLAUDE_AUTOLOGIN")==="0"||e?"none":"open":r?.ok===!0?"rearm":"none"}function Jp(t,e){return`${t.replace(/\/$/,"")}/?project=${encodeURIComponent(e)}`}var Zp=$(()=>{"use strict";Le()});import{spawn as mv}from"node:child_process";function $r(t){let[e,r]=process.platform==="darwin"?["open",[t]]:process.platform==="win32"?["cmd",["/c","start","",t]]:["xdg-open",[t]];try{let n=mv(e,r,{detached:!0,stdio:"ignore"});n.on("error",()=>{}),n.unref()}catch{}}var ys=$(()=>{"use strict"});import{setTimeout as hv}from"node:timers/promises";import gv from"ws";function ks(t,e){let r=t.replace(/^http/,"ws")+`/cli/connect?token=${encodeURIComponent(e)}`;return new gv(r)}async function Xt(t,e,r){return ft(t,e,"/projects",r)}async function Qp(t,e){let r=await fetch(`${t}/farms`,{headers:{Authorization:`Bearer ${e}`}});if(!r.ok)throw new H(r.status,null,`GET /farms HTTP ${r.status}`);return await r.json()}async function ws(t,e,r,n){return ft(t,e,`/farms/${encodeURIComponent(r)}/provision`,n)}async function ef(t,e,r,n){return ft(t,e,`/runners/${encodeURIComponent(r)}/gh-runners`,n)}async function tf(t,e,r,n){return ft(t,e,`/runners/${encodeURIComponent(r)}/gh-runners/teardown`,n)}async function rf(t,e){let r=await fetch(`${t}/sandbox/me`,{headers:{Authorization:`Bearer ${e}`}});if(r.ok)return"ok";if(r.status===401)return"unknown";if(r.status===404)return"unsupported";throw new H(r.status,null,`GET /sandbox/me HTTP ${r.status}`)}async function bs(t,e){let r=await fetch(`${t}/sandbox/reg-token/cli`,{method:"POST",headers:{Authorization:`Bearer ${e}`}});if(!r.ok)throw new H(r.status,null,`POST /sandbox/reg-token/cli HTTP ${r.status}`);return await r.json()}async function uc(t,e){let r=await fetch(`${t}/projects/cli`,{headers:{Authorization:`Bearer ${e}`}});if(!r.ok)throw new H(r.status,null,`GET /projects/cli HTTP ${r.status}`);return(await r.json()).projects}async function nf(t,e,r={}){let n=r.attempts??3,o;for(let s=0;s<n;s++)try{let i=await uc(t,e),a=new Set;for(let c of i)c.id!==r.excludeProjectId&&c.trackerProvider==="internal"&&c.youtrackProjectKey&&a.add(c.youtrackProjectKey.toUpperCase());return a}catch(i){o=i,s<n-1&&await hv(r.delayMs??1500)}throw o}async function of(t,e){let r=await fetch(`${t}/cli/bootstrap-request`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e})});if(r.status===403){let n;try{n=(await r.json()).error}catch{}if(n==="registration_required")throw new lo(e)}if(!r.ok)throw new H(r.status,null,`bootstrap-request HTTP ${r.status}`);return await r.json()}async function sf(t,e){let r=await fetch(`${t}/cli/bootstrap-poll?request=${encodeURIComponent(e)}`);if(!r.ok)throw new H(r.status,null,`bootstrap-poll HTTP ${r.status}`);return await r.json()}async function af(t,e,r){let n=await fetch(`${t}/projects/${encodeURIComponent(r)}/cli-tasks`,{headers:{Authorization:`Bearer ${e}`}});if(!n.ok)throw new H(n.status,null,`GET cli-tasks HTTP ${n.status}`);return await n.json()}async function cf(t,e,r,n){let o=await fetch(`${t}/projects/${encodeURIComponent(r)}/cli-tasks/${encodeURIComponent(n)}`,{headers:{Authorization:`Bearer ${e}`}});if(!o.ok)throw new H(o.status,null,`GET cli-task HTTP ${o.status}`);return await o.json()}async function dc(t,e,r,n){return ft(t,e,`/projects/${encodeURIComponent(r)}/tasks/${encodeURIComponent(n)}/apply-claim`,{})}async function lf(t,e,r,n,o){return ft(t,e,`/projects/${encodeURIComponent(r)}/tasks/${encodeURIComponent(n)}/applied`,{prs:o})}async function uf(t,e,r,n,o){return ft(t,e,`/projects/${encodeURIComponent(r)}/tasks/${encodeURIComponent(n)}/abort`,{reason:o})}async function df(t,e,r,n,o){return ft(t,e,`/projects/${encodeURIComponent(r)}/tasks/${encodeURIComponent(n)}/command`,{command:o})}async function uo(t,e,r,n){return ft(t,e,`/projects/${encodeURIComponent(r)}/index`,n)}async function pc(t,e,r,n){await ft(t,e,`/projects/${encodeURIComponent(r)}/init-status`,n)}async function pf(t,e,r,n){return ft(t,e,`/projects/${encodeURIComponent(r)}/repos`,n)}async function ff(t,e,r,n){let o=await fetch(`${t}/projects/${encodeURIComponent(r)}/repos/${encodeURIComponent(n)}`,{method:"DELETE",headers:{Authorization:`Bearer ${e}`}}),s=await o.text(),i=s?JSON.parse(s):null;if(!o.ok){let a=i&&typeof i=="object"&&"error"in i?String(i.error):`HTTP ${o.status}`;throw new H(o.status,i,a)}return i}async function oe(t,e,r){let n=await fetch(`${t}/projects/${encodeURIComponent(r)}/cli-summary`,{headers:{Authorization:`Bearer ${e}`}});if(!n.ok)throw new H(n.status,null,`GET /projects/${r}/cli-summary HTTP ${n.status}`);return await n.json()}async function ft(t,e,r,n){let o=await fetch(`${t}${r}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(n)}),s=await o.text(),i=s?JSON.parse(s):null;if(!o.ok){let a=i&&typeof i=="object"&&"error"in i?String(i.error):`HTTP ${o.status}`;throw new H(o.status,i,a)}return i}var H,lo,Ae=$(()=>{"use strict";H=class extends Error{constructor(r,n,o){super(o);this.status=r;this.payload=n;this.name="HubHttpError"}};lo=class extends Error{constructor(r){super("registration_required");this.email=r;this.name="RegistrationRequiredError"}}});function hf(t){mf=t}function vr(t,e="info"){mf(t,e)}var mf,$s=$(()=>{"use strict";mf=t=>console.log(t)});import{homedir as yv,tmpdir as kv}from"node:os";import{existsSync as wv,mkdirSync as bv,mkdtempSync as $v,rmSync as vv}from"node:fs";import{join as po}from"node:path";import{simpleGit as vs}from"simple-git";function Ie(t,e,r){let n=r??po(yv(),".codepipe","repos");return po(n,t,e)}async function Nt(t,e,r={}){let n=Ie(t,e.name,r.baseDir),o=r.cloneUrlOverride??mo(e);if(!wv(po(n,".git"))){bv(n,{recursive:!0});let a=vs();vr(`[git] clone ${o} \u2192 ${n}`);try{await a.clone(o,n)}catch(c){let l=c instanceof Error?c.message:String(c);throw new Error(`git clone failed: ${o}
|
|
26
26
|
${l.trim()}`)}}let s=vs(n);try{await s.fetch()}catch(a){let c=a instanceof Error?a.message:String(a);throw new Error(`git fetch failed in ${n}
|
|
27
27
|
${c.trim()}`)}let i=e.defaultBranch??"main";return await s.checkout(["-B",i,`origin/${i}`]).catch(()=>{}),s}async function xr(t,e){try{return await t.raw(["cat-file","-e",`${e}^{commit}`]),!0}catch{return!1}}async function Sr(t,e){let{contextRepoCloneUrl:r,deliveryRef:n,deliverySha:o,baseSha:s,commitMessage:i}=e;await t.raw(["fetch",r,`+refs/heads/${n}:refs/codepipe-delivery`]);let a=(await t.revparse(["refs/codepipe-delivery"])).trim();o&&a!==o&&vr(`[git] delivery ${n} resolved ${a.slice(0,10)} (expected ${o.slice(0,10)})`);let c=(await t.raw(["rev-parse","refs/codepipe-delivery^{tree}"])).trim();if(await xr(t,s)||await t.fetch(["origin",s]).catch(()=>{}),!await xr(t,s))throw new Error(`apply_delivery: base commit ${s.slice(0,10)} unavailable \u2014 cannot re-parent the delivery`);let l=(await t.raw([...xs,"commit-tree",c,"-p",s,"-m",i])).trim();return await t.raw(["update-ref","-d","refs/codepipe-delivery"]).catch(()=>{}),l}async function fo(t,e,r){let n=`refs/codepipe/deliveries/${e}`;if(await xr(t,n))return(await t.revparse([n])).trim();let o=`refs/devpipe/deliveries/${e}`;if(await xr(t,o)){let i=(await t.revparse([o])).trim();return await t.raw(["update-ref",n,i]).catch(()=>{}),i}let s=await r();return await t.raw(["update-ref",n,s]).catch(()=>{}),s}async function gf(t,e,r){let{contextRepoCloneUrl:n,deliveryRef:o,deliverySha:s,baseSha:i,branchName:a,baseRef:c,commitMessage:l,defaultBranch:u,force:p}=r,d=await fo(t,s,()=>Sr(t,{contextRepoCloneUrl:n,deliveryRef:o,deliverySha:s,baseSha:i,commitMessage:l}));p&&await t.raw(["branch","-D",a]).catch(()=>{});let m=`origin/${c}`;if(await xr(t,m)||(m=`origin/${u??c}`),(await t.revparse([m])).trim()===i)await t.raw(["branch","-f",a,d]),await t.checkout(a);else{await t.checkout(["-B",a,m]);try{await t.raw([...xs,"cherry-pick",d])}catch(w){await t.raw(["cherry-pick","--abort"]).catch(()=>{});let y=w instanceof Error?w.message:String(w);throw new Error(`apply_delivery: cherry-pick of ${s.slice(0,10)} onto ${c} hit conflicts
|
|
@@ -501,9 +501,9 @@ ${Object.entries(e).map(([n,o])=>` ${n}: ${o}`).join(`
|
|
|
501
501
|
# they sync, but do not enter the QUEUE until moved there (Add to queue) or
|
|
502
502
|
# dragged into a source_columns stage. Optional: remove to disable BACKLOG.
|
|
503
503
|
backlog_column: Backlog
|
|
504
|
-
# Optional: backlog role scope.
|
|
505
|
-
#
|
|
506
|
-
#
|
|
504
|
+
# Optional: backlog role scope. personal (default, or key missing) \u2014 only
|
|
505
|
+
# tasks assigned to the assignee below. shared \u2014 any unaccepted tracker task
|
|
506
|
+
# in backlog_column, for a board that IS the team's shared queue.
|
|
507
507
|
# backlog_scope: shared
|
|
508
508
|
# Optional: YT stages meaning the task is completed. A task in one of these
|
|
509
509
|
# stages is synced to DONE and leaves the board (must not overlap the stages
|
|
@@ -739,7 +739,7 @@ Append-only. Keyed by entityId \u2014 never by path; entries survive renames.
|
|
|
739
739
|
`)+`
|
|
740
740
|
`;return await Se(this.contextDir,[{path:`tasks/${e}/comments.jsonl`,content:c}],`tracker(${e}): comment`),{id:s.id}}async createIssue(e){let r=new Date().toISOString(),n=await rm(this.contextDir,this.config.prefix,o=>this.renderNewIssueFiles(o,e,r),o=>`tracker(${o}): create issue`);return{id:n,key:n}}async editIssue(e,r){await this.mutateRecord(e,n=>({...n,...r.title!==void 0?{title:r.title}:{}}),r.body)}async applyLink(e,r,n){let o=r==="subtask_of"?"subtask":"depends_on";await this.mutateRecord(e,s=>{let i=s.links.filter(a=>!(a.type===o&&a.targetKey===n));return i.push({type:o,targetKey:n}),{...s,links:i}})}async fetchStateFields(e){return[{name:"Status",values:os.statusColumns}]}async mutateRecord(e,r,n){let o=ko(this.contextDir,e);if(!o)throw new Error(`internal tracker: unknown issue ${e}`);let s={...r(o),updated:new Date().toISOString()},i=wo(this.contextDir,s,{withDescription:!0});n!==void 0&&(n.trim().length>0?i.description=n:delete i.description);let a=[{path:zr(e),content:Pc(s)},...zs(this.contextDir,this.projectId,[{issue:i,comments:[],attachments:[]}])];await Se(this.contextDir,a,`tracker(${e}): update`)}renderNewIssueFiles(e,r,n){let o={key:e,title:r.title,type:oo,status:r.targetStatus,links:[],created:n,updated:n},s=wo(this.contextDir,o);return r.body.trim().length>0&&(s.description=r.body),[{path:zr(e),content:Pc(o)},...zs(this.contextDir,this.projectId,[{issue:s,comments:[],attachments:[]}])]}}});import{existsSync as jh,readFileSync as Nh}from"node:fs";import{join as Oh}from"node:path";import{parseDocument as Lh}from"yaml";function il(t){if(!t)return"youtrack";try{let e=Oh(t,"project.yaml");return jh(e)&&Lh(Nh(e,"utf-8")).getIn(["adapters","tracker"])==="internal"?"internal":"youtrack"}catch{return"youtrack"}}function St(t){let e=il(t.contextDir);if(e==="internal"){let n=t.contextDir;if(!n)return{ok:!1,kind:e,error:"internal tracker: no Context Repo clone on this CLI"};let o=Qf(n);if(!o)return{ok:!1,kind:e,error:"internal tracker: tracker/config.yaml missing or has an invalid prefix"};let s=JS(n);return s?{ok:!0,kind:e,provider:new Co(n,s,o)}:{ok:!1,kind:e,error:"internal tracker: project.yaml has no id"}}let r=Ep();return r?{ok:!0,kind:e,provider:new Io(r,t.contextDir??void 0)}:{ok:!1,kind:e,error:"YOUTRACK_URL/YOUTRACK_TOKEN not set in CLI env"}}function JS(t){try{let e=Oh(t,"project.yaml");if(!jh(e))return null;let r=Lh(Nh(e,"utf-8")).getIn(["id"]);return typeof r=="string"&&r.trim().length>0?r.trim():null}catch{return null}}var Zs=$(()=>{"use strict";br();nl();sl();js();nl();sl()});async function hn(t,e){let n=(Qs.get(t)??Promise.resolve()).catch(()=>{}).then(e);Qs.set(t,n);try{return await n}finally{Qs.get(t)===n&&Qs.delete(t)}}async function Dh(t){let{action:e,repo:r}=t,n="repoName"in e?e.repoName:"-",o="taskId"in e?e.taskId:"draftId"in e?e.draftId:e.projectId;vr(`[exec] ${e.type} task=${o} repo=${n}`);try{switch(e.type){case"apply_delivery":{if(!r)return V("no repo spec");let s=e.taskId.split(":",2)[0]??"?";return hn(`${s}/${r.name}`,async()=>{let i=await Nt(s,r,{baseDir:t.baseDir,cloneUrlOverride:t.cloneUrlOverride}),a=Ie(s,r.name,t.baseDir),{commit:c,pushed:l}=await gf(i,a,{contextRepoCloneUrl:e.contextRepoCloneUrl,deliveryRef:e.deliveryRef,deliverySha:e.deliverySha,baseSha:e.baseSha,branchName:e.branchName,baseRef:e.baseRef,commitMessage:e.commitMessage,defaultBranch:r.defaultBranch,force:e.force,push:e.push});if(t.contextDir){let u=e.taskId.split(":")[1]??"";u&&await el({contextDir:t.contextDir,repoDir:a,repoName:r.name,taskKey:u,commitSha:c}).catch(p=>{vr(`[model] task event for ${u} failed: ${p instanceof Error?p.message:String(p)}`)})}return ue({branch:e.branchName,base:e.baseRef,baseSha:e.baseSha,commit:c,pushed:l,...e.force?{force:!0}:{},...typeof e.existingPrNumber=="number"?{reusedPrNumber:e.existingPrNumber}:{}})})}case"push_branch":{if(!r)return V("no repo spec");let s=e.taskId.split(":",2)[0]??"?";return hn(`${s}/${r.name}`,async()=>{let i=await Nt(s,r,{baseDir:t.baseDir,cloneUrlOverride:t.cloneUrlOverride}),a=Ie(s,r.name,t.baseDir);return await yf(i,a,{branchName:e.branchName,force:e.force}),ue({branch:e.branchName,pushed:!0,...e.force?{force:!0}:{}})})}case"early_branch":{if(!r)return V("no repo spec");let s=e.taskId.split(":",2)[0]??"?";return hn(`${s}/${r.name}`,async()=>{let i=await Nt(s,r,{baseDir:t.baseDir,cloneUrlOverride:t.cloneUrlOverride}),a=Ie(s,r.name,t.baseDir),{commit:c,pushed:l}=await kf(i,a,{contextRepoCloneUrl:e.contextRepoCloneUrl,deliveryRef:e.deliveryRef,deliverySha:e.deliverySha,baseSha:e.baseSha,branchName:e.branchName,commitMessage:e.commitMessage,push:e.push});return ue({branch:e.branchName,commit:c,pushed:l})})}case"create_pr":{if(!r)return V("no repo spec");let s=dt(r),i=await s.createPullRequest(r,e);if(t.contextDir){let a=e.taskId.split(":")[1]??"",c=e.taskId.split(":",2)[0]??"?";a&&await tl({contextDir:t.contextDir,repoDir:Ie(c,r.name,t.baseDir),branchName:e.branchName,baseBranch:e.baseBranch,fallbackTaskKey:a,prUrl:i.url}).catch(l=>{vr(`[model] pr link for ${a} failed: ${l instanceof Error?l.message:String(l)}`)})}return ue({url:i.url,number:i.number,host:s.name})}case"merge_pr":{if(!r)return V("no repo spec");let s=dt(r),i=await s.mergePR(r,e.prNumber,e.mergeMethod,e.deleteBranch);return ue({prNumber:e.prNumber,host:s.name,...i.mergedSha?{mergedSha:i.mergedSha}:{}})}case"close_pr":{if(!r)return V("no repo spec");let s=dt(r);return await s.closePR(r,e.prNumber,e.comment),ue({prNumber:e.prNumber,host:s.name})}case"rewrite_cluster_branch":{if(!r)return V("no repo spec");let s=e.taskId.split(":",2)[0]??"?";return hn(`${s}/${r.name}`,async()=>{let i=await Nt(s,r,{baseDir:t.baseDir,cloneUrlOverride:t.cloneUrlOverride}),a=Ie(s,r.name,t.baseDir),{commit:c,dropped:l}=await bf(i,a,{branchName:e.branchName,dropTaskKeys:e.dropTaskKeys,defaultBranch:r.defaultBranch});return ue({branch:e.branchName,commit:c,dropped:l,pushed:l>0})})}case"merge_branch":{if(!r)return V("no repo spec");let s=e.taskId.split(":",2)[0]??"?";return hn(`${s}/${r.name}`,async()=>{let i=await Nt(s,r,{baseDir:t.baseDir,cloneUrlOverride:t.cloneUrlOverride}),a=Ie(s,r.name,t.baseDir),{mergedSha:c}=await $f(i,a,{branchName:e.branchName,baseBranch:e.baseBranch,mergeMethod:e.mergeMethod,deleteBranch:e.deleteBranch});return ue({branch:e.branchName,base:e.baseBranch,mergedSha:c})})}case"resolve_review_branch":{if(!r)return V("no repo spec");let s=t.cloneUrlOverride??mo(r),a=(await vf(s)).filter(u=>xf(u,e.issueKey)),c=dt(r),l=null;if(c.findOpenPrByBranch)for(let u of a){let p=await c.findOpenPrByBranch(r,u).catch(()=>null);if(p){l={number:p.number,url:p.url};break}}return ue({branches:a,...l?{pr:l}:{}})}case"add_pr_comment":{if(!r)return V("no repo spec");let s=dt(r);return await s.addPRComment(r,e.prNumber,e.body),ue({prNumber:e.prNumber,host:s.name})}case"tracker_status":{let s=St({contextDir:t.contextDir});return s.ok?t.trackerIssueId?(await s.provider.updateStatus(t.trackerIssueId,e.newStatus),ue({issueId:t.trackerIssueId,newStatus:e.newStatus})):V("no tracker_issue_id provided"):V(s.error)}case"tracker_comment":{let s=St({contextDir:t.contextDir});if(!s.ok)return V(s.error);if(!t.trackerIssueId)return V("no tracker_issue_id provided");let i=await s.provider.addComment(t.trackerIssueId,e.body,e.author);return ue({issueId:t.trackerIssueId,commentId:i.id})}case"create_tracker_issue":{let s=St({contextDir:t.contextDir});if(!s.ok)return V(s.error);if(!e.projectKey)return V("no projectKey in create_tracker_issue action");let{id:i,key:a}=await s.provider.createIssue({projectKey:e.projectKey,title:e.title,body:e.body,targetStatus:e.targetStatus});return ue({issueKey:a,issueId:i})}case"apply_tracker_links":{let s=St({contextDir:t.contextDir});if(!s.ok)return V(s.error);let i=0;for(let a of e.links)try{await s.provider.applyLink(a.sourceIssueKey,a.rel,a.targetIssueKey),i++}catch(c){return V(`${c instanceof Error?c.message:String(c)} (applied ${i}/${e.links.length})`)}return ue({applied:i})}case"set_project_setting":{if(!t.contextDir)return V("no context repo clone on this CLI");let s=await Pm(t.contextDir,e.edits);return ue({files:s.files})}case"set_prompt_override":{if(!t.contextDir)return V("no context repo clone on this CLI");if(!Pa(e.role))return V(`unknown prompt operation: ${e.role}`);let s=_a(e.role);return await Se(t.contextDir,[e.content===null?{path:s,content:"",deleted:!0}:{path:s,content:e.content}],e.commitMessage),t.requestConfigReport?.(),ue({path:s,reset:e.content===null})}case"tracker_edit":{let s=St({contextDir:t.contextDir});if(!s.ok)return V(s.error);if(!t.contextDir)return V("no context repo clone on this CLI");await s.provider.editIssue(e.issueKey,{...e.title!==void 0?{title:e.title}:{},...e.body!==void 0?{body:e.body}:{}});let i=await s.provider.getIssue(e.issueKey);return i&&await Xs(t.contextDir,e.projectId,[{issue:i,comments:[],attachments:[]}]),ue({issueKey:e.issueKey})}case"set_youtrack_config":{if(!t.contextDir)return V("no context repo clone on this CLI");let s=await Lm(t.contextDir,e);return ue({files:s.files})}case"set_repo_default_branch":{if(!t.contextDir)return V("no context repo clone on this CLI");let s=await Nm(t.contextDir,e);return ue({repoName:s.repoName,defaultBranch:s.defaultBranch})}case"sync_config":return t.requestConfigReport?(t.requestConfigReport(),ue({reported:!0})):V("no context repo clone on this CLI");case"refresh_context_status":{if(!t.refreshContextStatus)return V("no context repo clone on this CLI");let s=await t.refreshContextStatus();return ue({outdated:s.outdated,templateVersion:s.templateVersion})}case"run_action":{if(!t.contextDir)return V("no project workspace on this CLI");if(!r)return V("no repo spec");if(!t.onRunActivity)return V("no run-activity stream on this CLI");let s=t.onRunActivity,{defs:i,errors:a}=Rs(t.contextDir),c=i.find(m=>m.id===e.actionId);if(!c){let m=a.find(f=>f.file===`actions/${e.actionId}.yml`);return V(m?`action "${e.actionId}" failed to parse: ${m.error}`:`unknown action "${e.actionId}"`)}let l=wa(c,e.input);if(!l.ok)return V(l.error);let u=Nf(t.contextDir),p=q(e.projectId),d={};return p?.github?.token&&(d.GH_TOKEN=p.github.token),p?.gitlab?.token&&(d.GITLAB_TOKEN=p.gitlab.token),p?.bitbucket&&(d.BITBUCKET_EMAIL=p.bitbucket.email,d.BITBUCKET_API_TOKEN=p.bitbucket.apiToken),p?.youtrack&&(d.YOUTRACK_URL=p.youtrack.url,d.YOUTRACK_TOKEN=p.youtrack.token),hn(`${e.projectId}/${r.name}`,async()=>{await Nt(e.projectId,r,{baseDir:t.baseDir,cloneUrlOverride:t.cloneUrlOverride});let m=Ie(e.projectId,r.name,t.baseDir),f=await Em({cwd:m,def:c,input:l.values,variables:u,secrets:p?.secrets??{},credEnv:d,onEvent:g=>s(e.runId,g)});return ue({runId:e.runId,status:f.status,exitCode:f.exitCode,...f.failedStep?{failedStep:f.failedStep}:{}})})}case"read_context_file":{if(!t.contextDir)return V("no context repo clone on this CLI");let s=Cm(t.contextDir,e.path);return ue({path:e.path,...s})}case"search_model":{if(!t.contextDir)return V("no context repo clone on this CLI");let{searchModelIndex:s}=await Promise.resolve().then(()=>(To(),Ro)),i=await s(t.contextDir,e.q,e.limit);return ue({hits:i})}case"model_drift":return V("model_drift requires a local workspace (handled by the daemon)");case"model_bootstrap":return V("model_bootstrap requires a local workspace (handled by the daemon)");case"local_apply":return V("local_apply requires a local workspace (handled by the daemon)");default:return V(`unsupported action type: ${e.type}`)}}catch(s){return V(s instanceof Error?s.message:String(s))}}function ue(t){return{status:"done",result:t}}function V(t){return{status:"failed",error:t}}var Qs,Mh=$(()=>{"use strict";F();kc();Rm();tt();Am();pe();_m();Om();Uc();qt();$s();Er();rl();Zs();Js();Qs=new Map});import{existsSync as ZS,mkdtempSync as QS,rmSync as eE}from"node:fs";import{tmpdir as tE}from"node:os";import{join as al}from"node:path";import{simpleGit as Uh}from"simple-git";async function Bh(t,e,r){let n=[];for(let a of e){let c=t.repos.find(u=>u.name===a.repoName);if(!c)return{ok:!1,error:`repo "${a.repoName}" not in project.yaml \u2014 run /sync`};let l=al(t.root,c.mountAs);if(!ZS(al(l,".git")))return{ok:!1,error:`${c.mountAs}/ not cloned \u2014 run /sync first`};n.push({payload:a,dir:l,mountAs:c.mountAs,defaultBranch:c.defaultBranch})}let o=[];for(let a of n){let c=Uh(a.dir),l=a.payload;try{await c.fetch()}catch(m){return{ok:!1,error:`fetch failed in ${a.mountAs}: ${Ao(m)}`}}let u=`origin/${l.baseRef}`;await sE(c,u)||(u=`origin/${a.defaultBranch}`);let p;try{p=(await c.revparse([u])).trim()}catch(m){return{ok:!1,error:`base ${u} unavailable in ${a.mountAs}: ${Ao(m)}`}}let d;try{d=await fo(c,l.deliverySha,()=>Sr(c,{contextRepoCloneUrl:l.contextRepoCloneUrl,deliveryRef:l.deliveryRef,deliverySha:l.deliverySha,baseSha:l.baseSha,commitMessage:l.commitMessage}))}catch(m){return{ok:!1,error:`fetch delivery failed in ${a.mountAs}: ${Ao(m)}`}}o.push({repoName:l.repoName,mountAs:a.mountAs,git:c,branch:l.branchName,startPoint:p,deliveryCommit:d})}let s=[],i=[];for(let a of o){let c=await iE(a.git,`refs/heads/${a.branch}`);try{let u=(await a.git.revparse([`${a.deliveryCommit}^`])).trim()===a.startPoint?a.deliveryCommit:await nE(a);await a.git.raw(["branch","-f",a.branch,u]),s.push({git:a.git,mountAs:a.mountAs,branch:a.branch,priorSha:c}),i.push({repoName:a.repoName,branch:a.branch,commit:u}),r.info(`[local-apply] ${a.mountAs}: branch ${a.branch} \u2192 ${u.slice(0,10)} (no checkout)`)}catch(l){return await oE(s,r),{ok:!1,error:`apply failed in ${a.mountAs}: ${Ao(l)} (rolled back all repos)`}}}return{ok:!0,repos:i}}async function nE(t){let e=QS(al(tE(),"codepipe-local-apply-"));try{await t.git.raw(["worktree","add","--detach",e,t.startPoint]);let r=Uh(e);try{await r.raw([...rE,"cherry-pick",t.deliveryCommit])}catch(n){throw await r.raw(["cherry-pick","--abort"]).catch(()=>{}),n}return(await r.revparse(["HEAD"])).trim()}finally{await t.git.raw(["worktree","remove","--force",e]).catch(()=>{}),eE(e,{recursive:!0,force:!0}),await t.git.raw(["worktree","prune"]).catch(()=>{})}}async function oE(t,e){for(let r of t)try{r.priorSha?await r.git.raw(["branch","-f",r.branch,r.priorSha]):await r.git.raw(["branch","-D",r.branch])}catch(n){e.warn(`[local-apply] rollback of ${r.mountAs}#${r.branch} failed: ${Ao(n)} \u2014 check manually`)}}async function sE(t,e){try{return await t.raw(["cat-file","-e",`${e}^{commit}`]),!0}catch{return!1}}async function iE(t,e){try{return(await t.raw(["rev-parse","--verify","--quiet",e])).trim()||null}catch{return null}}function Ao(t){return t instanceof Error?t.message.trim():String(t)}var rE,Fh=$(()=>{"use strict";Er();rE=["-c","user.name=CodePipe","-c","user.email=codepipe@codepartner.ee"]});import{homedir as aE}from"node:os";import{existsSync as cE,mkdirSync as lE,readFileSync as uE,writeFileSync as dE}from"node:fs";import{dirname as pE,join as fE}from"node:path";function cl(){return J("FARM_PINS")??fE(aE(),".codepipe","farm-pins.json")}function Kh(){let t=cl();if(!cE(t))return{};try{return JSON.parse(uE(t,"utf-8"))}catch{return{}}}function mE(t){let e=cl();lE(pE(e),{recursive:!0}),dE(e,JSON.stringify(t,null,2)+`
|
|
741
741
|
`,{mode:384})}function hE(t){return Kh()[t]}function ei(t,e){let r=Kh();r[t]=e,mE(r)}function ti(t,e){let r=De(e),n=hE(t);if(n&&n!==r)throw new Error(`farm ${t} key fingerprint changed (pinned ${n}, now ${r}) \u2014 refusing to seal. If the farm was re-registered intentionally, remove its entry from ${cl()}.`);return r}var ll=$(()=>{"use strict";Le();rt()});import{existsSync as Gh,readFileSync as Hh}from"node:fs";import{join as Wh}from"node:path";async function qh(t,e,r,n){let o=s=>({type:"move_to_farm_result",requestId:e.requestId,projectId:t.projectId,ok:!1,error:s});try{if(e.projectId!==t.projectId)return o(`project mismatch: this daemon serves ${t.projectId}, not ${e.projectId}`);let s=De(e.farmPublicKey);if(s!==e.fingerprint)return o("farm key fingerprint does not match the confirmed one \u2014 refusing to seal (possible relay tampering)");ti(e.farmId,e.farmPublicKey);let i=q(t.projectId);if(!i)return o("no secrets stored for this project on this CLI \u2014 cannot build the farm bundle");let a=await oe(t.hubUrl,t.cliToken,t.projectId),c;if(r){let d=Wh(r,"project.yaml"),m=Wh(r,"regimen.yaml");Gh(d)&&Gh(m)?c={projectYaml:Hh(d,"utf-8"),regimenYaml:Hh(m,"utf-8")}:n.warn("[farm-move] local project.yaml/regimen.yaml not found \u2014 the farm will seed defaults")}let l={projectId:t.projectId,config:{hubUrl:t.hubUrl,cliToken:t.cliToken,projectId:t.projectId},secrets:{...i.github?{github:i.github}:{},...i.bitbucket?{bitbucket:i.bitbucket}:{},...i.gitlab?{gitlab:i.gitlab}:{},...i.youtrack?{youtrack:i.youtrack}:{},...i.claude?{claude:i.claude}:{},...i.contextWrite?{contextWrite:i.contextWrite}:{},...i.contextSsh?{contextSsh:i.contextSsh}:{}},...a.contextRepo?{contextRepo:a.contextRepo}:{},...c?{projectConfig:c}:{}},u=Lt(e.farmPublicKey,JSON.stringify(l));ei(e.farmId,s),n.info(`[farm-move] bundle sealed for farm ${e.farmName} (${s}) \u2014 handing off`);let p=await ws(t.hubUrl,t.cliToken,e.farmId,{projectId:t.projectId,sealedBundle:u});return p.ok?{type:"move_to_farm_result",requestId:e.requestId,projectId:t.projectId,ok:!0,...p.daemonStatus?{daemonStatus:p.daemonStatus}:{}}:o(p.error??"farm provisioning failed")}catch(s){return o(s instanceof Error?s.message:String(s))}}var Yh=$(()=>{"use strict";rt();ll();Ae();pe()});import{homedir as gE}from"node:os";import{existsSync as yE,mkdirSync as kE,readFileSync as wE,writeFileSync as bE}from"node:fs";import{dirname as $E,join as vE}from"node:path";function ul(){return J("RUNNER_PINS")??vE(gE(),".codepipe","runner-pins.json")}function Vh(){let t=ul();if(!yE(t))return{};try{return JSON.parse(wE(t,"utf-8"))}catch{return{}}}function xE(t){let e=ul();kE($E(e),{recursive:!0}),bE(e,JSON.stringify(t,null,2)+`
|
|
742
|
-
`,{mode:384})}function SE(t){return Vh()[t]}function dl(t,e){let r=Vh();r[t]=e,xE(r)}function zh(t,e){let r=De(e),n=SE(t);if(n&&n!==r)throw new Error(`runner host ${t} key fingerprint changed (pinned ${n}, now ${r}) \u2014 refusing to seal. If the runner host was re-registered intentionally, remove its entry from ${ul()}.`);return r}var Xh=$(()=>{"use strict";Le();rt()});async function Jh(t,e,r,n){let o=await fetch(`https://api.github.com/repos/${e}/${r}/actions/runners/${n}`,{method:"POST",headers:Zh(t)});if(!o.ok)throw new Error(`github ${n} for ${e}/${r}: HTTP ${o.status}`);let s=await o.json();if(!s.token)throw new Error(`github ${n} for ${e}/${r}: no token in response`);return s.token}async function eg(t,e,r){if(e.projectId!==t.projectId)throw new Error(`project mismatch: this daemon serves ${t.projectId}, not ${e.projectId}`);if(De(e.runnerPublicKey)!==e.fingerprint)throw new Error("runner host key fingerprint does not match the confirmed one \u2014 refusing to seal (possible relay tampering)");zh(e.runnerId,e.runnerPublicKey);let s=q(t.projectId)?.github?.token;if(!s)throw new Error("no GitHub token stored for this project on this CLI");let a=((await r.fetchProject(t.hubUrl,t.cliToken,t.projectId)).repos??[]).find(c=>c.host==="github"&&c.owner===e.owner&&c.repoName===e.repo);if(!a)throw new Error(`${e.owner}/${e.repo} is not a GitHub repository of this project`);return{githubToken:s,repo:a}}async function tg(t,e,r,n=Qh){let o=s=>({type:"gh_runner_setup_result",requestId:e.requestId,projectId:t.projectId,ok:!1,error:s});try{let{githubToken:s,repo:i}=await eg(t,e,n);if(!await n.api.repoHasAdmin(s,i.owner,i.repoName))return o(`the GitHub token lacks admin access on ${i.owner}/${i.repoName} \u2014 replace it (project page \u2192 Tokens \u2192 Replace) with a token that has admin rights on this repository`);let a={projectId:t.projectId,runners:[{owner:i.owner,repo:i.repoName,regToken:await n.api.mintRegistrationToken(s,i.owner,i.repoName)}],labels:[Ma(e.runnerId)]},c=Lt(e.runnerPublicKey,JSON.stringify(a));dl(e.runnerId,e.fingerprint),r.info(`[ghr] registration token for ${i.owner}/${i.repoName} sealed for runner host ${e.runnerName} \u2014 handing off`);let l=await n.provisionOnRunner(t.hubUrl,t.cliToken,e.runnerId,{projectId:t.projectId,sealedBundle:c});return{type:"gh_runner_setup_result",requestId:e.requestId,projectId:t.projectId,ok:l.ok,...l.runners?{runners:l.runners}:{},...l.error?{error:l.error}:{}}}catch(s){return o(s instanceof Error?s.message:String(s))}}async function rg(t,e,r,n=Qh){let o=s=>({type:"gh_runner_teardown_result",requestId:e.requestId,projectId:t.projectId,ok:!1,error:s});try{let{githubToken:s,repo:i}=await eg(t,e,n),a={owner:i.owner,repo:i.repoName};try{a.removeToken=await n.api.mintRemoveToken(s,i.owner,i.repoName)}catch(p){r.warn(`[ghr] remove-token for ${i.owner}/${i.repoName} failed (${p instanceof Error?p.message:p}) \u2014 the runner host will force-remove`)}let c={projectId:t.projectId,runners:[a]},l=Lt(e.runnerPublicKey,JSON.stringify(c));dl(e.runnerId,e.fingerprint),r.info(`[ghr] removal bundle for ${i.owner}/${i.repoName} sealed for runner host ${e.runnerName} \u2014 handing off`);let u=await n.teardownOnRunner(t.hubUrl,t.cliToken,e.runnerId,{projectId:t.projectId,sealedBundle:l,owner:i.owner,repo:i.repoName});return{type:"gh_runner_teardown_result",requestId:e.requestId,projectId:t.projectId,ok:u.ok,...u.error?{error:u.error}:{}}}catch(s){return o(s instanceof Error?s.message:String(s))}}var Zh,EE,Qh,ng=$(()=>{"use strict";F();rt();Xh();Ae();pe();Zh=t=>({Authorization:`Bearer ${t}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28","User-Agent":"codepipe-cli"});EE={async repoHasAdmin(t,e,r){let n=await fetch(`https://api.github.com/repos/${e}/${r}`,{headers:Zh(t)});if(!n.ok)throw new Error(`github GET /repos/${e}/${r}: HTTP ${n.status}`);return(await n.json()).permissions?.admin===!0},mintRegistrationToken:(t,e,r)=>Jh(t,e,r,"registration-token"),mintRemoveToken:(t,e,r)=>Jh(t,e,r,"remove-token")},Qh={api:EE,fetchProject:oe,provisionOnRunner:ef,teardownOnRunner:tf}});function RE(t){return Ge.test(t)?Pt(t)?`secret name "${t}" is reserved`:null:`secret name must match ${Ge}`}function sg(t,e,r,n){let o=RE(e);if(o)return{ok:!1,detail:o};let s;try{let i=JSON.parse(ln(n,r).toString("utf-8"));if(typeof i.value!="string"||i.value.length===0)return{ok:!1,detail:"payload has no value"};s=i.value}catch(i){return{ok:!1,detail:`cannot open the sealed secret (${i instanceof Error?i.message:String(i)}) \u2014 wrong channel key?`}}if(s.length>og)return{ok:!1,detail:`secret value too large (max ${og} chars)`};try{return Zd(t,e,s),{ok:!0}}catch(i){return{ok:!1,detail:i instanceof Error?i.message:String(i)}}}function ig(t,e){try{return Qd(t,e)?{ok:!0}:{ok:!0,detail:"no such secret (already absent)"}}catch(r){return{ok:!1,detail:r instanceof Error?r.message:String(r)}}}var og,ag=$(()=>{"use strict";F();rt();pe();og=16*1024});function TE(t){return t.length===0?null:t.some(e=>e.state==="closed"&&!e.merged)?"needs_manual":t.every(e=>e.merged)?"done":null}var ri,cg=$(()=>{"use strict";qt();ri=class{constructor(e,r,n){this.intervalMs=e;this.send=r;this.log=n}targets=new Map;lastSig=new Map;timer=null;running=!1;setTargets(e){this.targets.clear(),this.lastSig.clear();for(let r of e)this.targets.set(r.taskId,r);this.log.info(`[track] targets updated: ${this.targets.size} task(s)`)}start(){if(this.timer)return;this.log.info(`[track] poller started (interval=${this.intervalMs}ms)`);let e=()=>{this.tick().catch(r=>this.log.warn(`[track] tick crashed: ${r instanceof Error?r.message:String(r)}`))};e(),this.timer=setInterval(e,this.intervalMs)}stop(){this.timer&&(clearInterval(this.timer),this.timer=null,this.log.info("[track] poller stopped"))}async tickOnce(){await this.tick()}async tick(){if(!this.running){this.running=!0;try{for(let[e,r]of this.targets)await this.processTask(e,r)}finally{this.running=!1}}}async processTask(e,r){let n=[];for(let i of r.prs){let a=dt(i.repoSpec);try{let c=await a.getPullRequest(i.repoSpec,i.number);n.push({number:i.number,url:i.url,state:c.state,merged:c.merged,ci:c.ci,mergeable:c.mergeable})}catch(c){if(c instanceof wr){this.log.warn(`[track] task=${e} pr=${i.url} not found \u2014 skipping tick for this task`);return}this.log.warn(`[track] task=${e} pr=${i.url} fetch failed: ${c instanceof Error?c.message:String(c)}`);return}}let o=n.map(i=>`${i.number}:${i.state}:${i.merged?1:0}:${i.ci}:${i.mergeable}`).join("|");if(this.lastSig.get(e)===o)return;for(let i=0;i<n.length;i++){let a=n[i];if(a.ci!=="failed")continue;let c=dt(r.prs[i].repoSpec);if(c.getCiFailureLog)try{let l=await c.getCiFailureLog(r.prs[i].repoSpec,a.number);l&&(a.ciFailureLog=l)}catch(l){this.log.warn(`[track] task=${e} pr=${a.url} ci-log fetch failed: ${l instanceof Error?l.message:String(l)}`)}}this.send({type:"pr_state_observed",taskId:e,prs:n}),this.lastSig.set(e,o);let s=TE(n);this.log.info(`[track] task=${e} snapshot signalled${s?` \u2192 ${s}`:""} (${n.length} PR(s))`)}}});function lg(t){let{description:e,...r}=t;return r}function IE(t){let{body:e,...r}=t;return r}function CE(t){let r=(t.split(/[\\/]/).pop()??t).replace(/[^A-Za-z0-9._-]/g,"_").replace(/^\.+/,"");return r.length>0?r.slice(0,120):"attachment"}async function ug(t,e,r,n){try{return await t.getIssue(e,r)}catch(o){return n.warn(`[yt-sync] getIssue ${e} failed: ${o instanceof Error?o.message:String(o)}`),null}}async function dg(t,e,r,n){try{return await t.listComments(e,r)}catch(o){return n.warn(`[yt-sync] listComments ${e} failed: ${o instanceof Error?o.message:String(o)}`),null}}var ni,pg=$(()=>{"use strict";F();Js();Zs();ni=class t{constructor(e,r,n,o={contextDir:null}){this.intervalMs=e;this.send=r;this.log=n;this.options=o}request=null;timer=null;running=!1;warnedMissingCfg=!1;shippedAttachments=new Set;abandonedTicks=0;static MAX_ABANDONED_TICKS=3;setRequest(e){let r=this.request?.projectId;this.request=e,this.log.info(`[yt-sync] request updated: project=${e.projectKey} columns=[${e.sourceColumns.join(",")}] sinceMs=${e.sinceMs} offBoard=${e.offBoardIssueIds.length}`),this.timer||this.start(),r&&r!==e.projectId&&this.log.info(`[yt-sync] project switch ${r} \u2192 ${e.projectId}`)}start(){if(this.timer)return;this.log.info(`[yt-sync] poller started (interval=${this.intervalMs}ms)`);let e=()=>{this.tick().catch(r=>this.log.warn(`[yt-sync] tick crashed: ${r instanceof Error?r.message:String(r)}`))};e(),this.timer=setInterval(e,this.intervalMs)}stop(){this.timer&&(clearInterval(this.timer),this.timer=null,this.log.info("[yt-sync] poller stopped"))}async tickOnce(){await this.tick()}async forceSync(){if(!this.request){this.log.info("[yt-sync] force requested but no sync_request yet \u2014 ignored");return}this.log.info("[yt-sync] force sync requested (manual)"),await this.tick()}async tick(){if(this.running||!this.request)return;let r=(this.options.resolveProvider??(()=>St({contextDir:this.options.contextDir})))();if(!r.ok){this.warnedMissingCfg||(this.warnedMissingCfg=!0,this.log.warn(`[yt-sync] tracker provider unavailable (${r.error}) \u2014 poller idle.`));return}this.warnedMissingCfg=!1,this.running=!0;try{await this.pollOnce(this.request,r.provider)}finally{this.running=!1}}async pollOnce(e,r){let n=Date.now(),o;try{let x=e.stageField?{stageField:e.stageField}:{},S=e.requireAssignee&&e.assignee?{assignee:e.assignee}:e.requireAssignee&&!e.assignee?{requireAnyAssignee:!0}:{},R=(e.backlogScope??"shared")==="shared"&&!!e.requireAssignee&&!!e.backlogColumn;if(r.kind==="internal")o=await r.listIssues({projectKey:e.projectKey});else if(R){let b=[...new Set([...e.sourceColumns,...e.rejectColumns??[],...e.doneColumns??[],...e.reviewColumns??[]])],[I,D]=await Promise.all([b.length>0?r.listIssues({projectKey:e.projectKey,columns:b,...x,...S}):Promise.resolve([]),r.listIssues({projectKey:e.projectKey,columns:[e.backlogColumn],...x})]),K=new Map;for(let ee of[...I,...D])K.set(ee.id,ee);o=[...K.values()]}else{let b=[...new Set([...e.sourceColumns,...e.rejectColumns??[],...e.doneColumns??[],...e.reviewColumns??[],...e.backlogColumn?[e.backlogColumn]:[]])];o=await r.listIssues({projectKey:e.projectKey,columns:b,...x,...S})}}catch(x){this.log.warn(`[yt-sync] listIssues failed: ${x instanceof Error?x.message:String(x)}`);return}let s=new Map,i=new Set,a=new Set(e.doneColumns??[]);for(let x of o){if(i.add(x.id),a.has(x.status))continue;let S=await dg(r,x.id,e.sinceMs,this.log);S&&s.set(x.id,S)}let c=[];for(let x of e.offBoardIssueIds){if(i.has(x))continue;let S=await dg(r,x,e.sinceMs,this.log);if(S&&S.length>0&&s.set(x,S),e.requireAssignee||S&&S.length>0){let T=await ug(r,x,e.stageField,this.log);if(T)c.push(T);else if(S&&S.length>0){this.abandonTick("off-board issue fetch failed with new comments");return}}}let l=o.filter(x=>!a.has(x.status)),{attachmentsByIssue:u,attachmentKeys:p}=await this.collectAttachments(l,s,r);if(!this.options.contextDir){this.abandonTick("no Context Repo clone (headless / clone failed) \u2014 cannot deliver task content");return}let d=[...l,...c].map(x=>({issue:x,comments:s.get(x.id)??[],attachments:u.get(x.id)??[]}));d.push(...await Ph(this.options.contextDir,d,x=>ug(r,x,e.stageField,this.log)));try{await Xs(this.options.contextDir,e.projectId,d),this.abandonedTicks=0;for(let x of p)this.shippedAttachments.add(x)}catch(x){let S=x instanceof Error?x.message:String(x);this.abandonTick(`context task sync failed: ${S}`);return}let m=this.options.isSelfComment??(()=>!1),f=[],g=[];for(let[x,S]of s){let T=S.filter(b=>!m(b.id));if(T.length===0)continue;f.push({issueId:x,comments:T.map(IE)});let R=T.flatMap(b=>{let I=gr(b.body);return I?[{commentId:b.id,author:b.author,name:I.name,args:I.args,createdAt:b.createdAt}]:[]});R.length>0&&g.push({issueId:x,commands:R})}let h={type:"youtrack_observation",projectId:e.projectId,issues:o.map(lg),commentsBatch:f,...g.length>0?{commandsBatch:g}:{},...e.requireAssignee&&c.length>0?{offBoardIssues:c.map(lg)}:{},observedAtMs:n};this.send(h);let w=f.reduce((x,S)=>x+S.comments.length,0),y=g.reduce((x,S)=>x+S.commands.length,0);this.log.info(`[yt-sync] observation sent: issues=${o.length} comments=${w} commands=${y} (sinceMs=${e.sinceMs})`)}abandonTick(e){this.abandonedTicks++,this.abandonedTicks<=t.MAX_ABANDONED_TICKS?this.log.warn(`[yt-sync] ${e} \u2014 tick abandoned (${this.abandonedTicks}/${t.MAX_ABANDONED_TICKS}), will retry`):this.log.warn(`[yt-sync] ERROR: ${e} \u2014 still failing after ${this.abandonedTicks} ticks; the project is STALLED until the Context Repo clone is restored`)}async collectAttachments(e,r,n){let o=new Map,s=[];for(let i of e){let a=[...i.attachments??[]];for(let u of r.get(i.id)??[])a.push(...u.attachments??[]);if(a.length===0)continue;let c=[],l=new Set;for(let u of a){let p=`${i.id}:${u.id}`;if(this.shippedAttachments.has(p))continue;let d;try{d=await n.downloadAttachment(u.url)}catch(f){this.log.warn(`[yt-sync] attachment ${u.name} (${i.id}) download failed: ${f instanceof Error?f.message:String(f)}`);continue}let m=CE(u.name);l.has(m)&&(m=`${u.id}-${m}`),l.add(m),c.push({name:m,contentBase64:d.toString("base64")}),s.push(p)}c.length>0&&o.set(i.id,c)}return{attachmentsByIssue:o,attachmentKeys:s}}}});import{existsSync as fg,readFileSync as AE,readdirSync as PE}from"node:fs";import{join as mg}from"node:path";import{simpleGit as _E}from"simple-git";import{parse as jE}from"yaml";function pl(t){let e=new Map,r=mg(t,zo);if(!fg(r))return e;let n;try{n=jE(AE(r,"utf-8"))}catch{return e}let o=n?.repos;if(!o||typeof o!="object")return e;for(let[s,i]of Object.entries(o)){if(!i||typeof i!="object")continue;let a=i,c=a.counts??{};typeof a.builtFromCommit=="string"&&e.set(s,{builtFromCommit:a.builtFromCommit,counts:{component:typeof c.component=="number"?c.component:0,code:typeof c.code=="number"?c.code:0,correlates:typeof c.correlates=="number"?c.correlates:0}})}return e}function NE(t){let e={};for(let[r,n]of t)e[r]={builtFromCommit:n.builtFromCommit,counts:n.counts};return mr({modelFormatVersion:2,repos:e})}function hg(t,e){let r=mg(t,e);if(!fg(r))return[];let n=[];for(let o of PE(r,{withFileTypes:!0})){let s=`${e}/${o.name}`;o.isDirectory()?n.push(...hg(t,s)):n.push(s)}return n}async function oi(t,e,r={}){let n=[],o=0;for(let d of e){n.push(...d.files);let m=`model/derived/structure/${d.repo}`;for(let f of hg(t,m))d.emittedShardPaths.has(f)||(n.push({path:f,content:"",deleted:!0}),o++)}let s=pl(t);for(let d of e)s.set(d.repo,{builtFromCommit:d.headCommit,counts:d.counts});n.push({path:zo,content:NE(s)});let i=Gs(t),a=$h(i,r.halfLifeDays??Je.halfLifeDays);n.push({path:ur,content:Hs(a)});for(let d of e){let m=[];for(let f of i)for(let g of f.files)re(g.key)?.repo===d.repo&&m.push({kind:"touched_by",from:ke(f.taskKey),to:g.key,...g.churn!==void 0?{weight:g.churn}:{}});n.push({path:Ji(d.repo),content:pr({modelFormatVersion:2,repo:d.repo,builtFromCommit:d.headCommit,edges:m})})}let c=_E(t),l=(await c.revparse(["HEAD"]).catch(()=>"")).trim(),u=`model: build ${e.map(d=>`${d.repo}@${d.headCommit.slice(0,10)}`).join(", ")}`;await Se(t,n,u);let p=(await c.revparse(["HEAD"]).catch(()=>"")).trim();if(p!==l){let{rebuildSearchIndex:d}=await Promise.resolve().then(()=>(To(),Ro));await d(t).catch(()=>{})}return{committed:p!==l,filesWritten:n.filter(d=>!d.deleted).length,filesDeleted:o}}var gg=$(()=>{"use strict";F();Jc();tt()});var ii={};Be(ii,{bootstrapDaemonModel:()=>LE,bootstrapModelForTargets:()=>wl,bootstrapWorkspaceModel:()=>$g,modelBootstrapCommand:()=>kl,modelBuildCommand:()=>yl,rebuildWorkspaceModelIfStale:()=>DE});import{existsSync as hl}from"node:fs";import{join as gn}from"node:path";import{cancel as OE,intro as yg,log as fl,outro as ml}from"@clack/prompts";import{simpleGit as gl}from"simple-git";function si(t){OE(t),process.exit(1)}function kg(t,e,r){let n=t.spec.repos.filter(s=>!e||s.name===e);if(n.length===0)throw new Error(e?`repo "${e}" is not part of this project (see project.yaml)`:"the project has no repos configured");let o=[];for(let s of n){let i=s.mountAs==="."?t.root:gn(t.root,s.mountAs);if(!hl(gn(i,".git"))){r(`${s.name}: no local clone at ${i} \u2014 skipped (run \`codepipe clone\` first)`);continue}o.push({name:s.name,dir:i,defaultBranch:s.defaultBranch||"main"})}if(o.length===0)throw new Error("nothing to do \u2014 no repo clones found");return o}async function wg(t){let e=gl(t.dir),r=`origin/${t.defaultBranch}`;return await e.raw(["rev-parse","--verify",r]).then(()=>!0).catch(()=>!1)?r:"HEAD"}async function bg(t,e,r,n){let o=[];for(let s of e)try{let i=await Vc({repo:s.name,repoDir:s.dir,contextDir:t,settings:r,ref:await wg(s)});o.push(i),n(`${s.name}: ${i.counts.code} files, ${i.counts.component} components, ${i.counts.correlates} co-change edges @ ${i.headCommit.slice(0,10)}`)}catch(i){throw new Error(`${s.name}: ${i instanceof Error?i.message:String(i)}`)}return o}async function yl(t){yg("codepipe model build");let e=Te();e||si("not inside a project workspace \u2014 run from a folder with .codepipe/ (see `codepipe init`)");try{let r=pn(e.contextDir),n=kg(e,t.repo,i=>fl.warn(i)),o=await bg(e.contextDir,n,r,i=>fl.info(i)),s=await oi(e.contextDir,o,{halfLifeDays:r.cochange.halfLifeDays});s.committed?ml(`model updated: ${s.filesWritten} files written, ${s.filesDeleted} stale removed`):ml("model already up to date (no changes)")}catch(r){si(r instanceof Error?r.message:String(r))}}async function kl(t){yg("codepipe model bootstrap");let e=Te();e||si("not inside a project workspace \u2014 run from a folder with .codepipe/ (see `codepipe init`)");try{await $g(e,t.repo,{onLog:r=>fl.info(r)})}catch(r){si(r instanceof Error?r.message:String(r))}ml("bootstrap complete")}async function $g(t,e,r){let n=kg(t,e,r.onLog);return wl(t.contextDir,n,r)}async function wl(t,e,r){let n=pn(t),o=await bg(t,e,n,r.onLog),s=Wm(t),i=Hm(n.issueKeyPattern,s),a=Pr([...n.ignore,...dn]),c=[];for(let p of o){let d=e.find(f=>f.name===p.repo),m=await Ym({repo:p.repo,repoDir:d.dir,headCommit:p.headCommit,windowCommits:n.cochange.windowCommits,issueKeyRe:i,pathToCurrent:Bs(p.identityTable),entityByKey:p.entityByKey,ignored:a,trackerProjectKey:s});c.push(m),r.onLog(`${p.repo}: ${m.size} task events mined from history`)}let{files:l,skippedPipeline:u}=Vm(t,c);return u>0&&r.onLog(`${u} events already recorded by the live pipeline \u2014 left untouched`),l.length>0&&await Se(t,l,`model: bootstrap ${l.length} task events from history`),await oi(t,o,{halfLifeDays:n.cochange.halfLifeDays}),{events:l.length}}async function LE(t,e,r,n){if(r.length===0)throw new Error("the project has no repos configured");let o=[];for(let i of r){let a=i.mountAs??i.name,c=a==="."?e.root:gn(e.root,a),l=i.defaultBranch||"main";c!==e.contextDir&&hl(gn(c,".git"))?(await gl(c).fetch(["origin",l]).catch(()=>{}),o.push({name:i.name,dir:c,defaultBranch:l})):(n(`${i.name}: materializing clone in the daemon layout`),await Nt(t,i),o.push({name:i.name,dir:Ie(t,i.name),defaultBranch:l}))}let s=await wl(e.contextDir,o,{onLog:n});return{repos:o.length,events:s.events}}async function DE(t,e={}){let r=e.onLog??(()=>{}),n=pn(t.contextDir);if(!n.enabled)return{rebuilt:[],skipped:[]};let o=[],s=[],i=pl(t.contextDir),a=[];for(let c of t.repos){let l=c.mountAs==="."?t.root:gn(t.root,c.mountAs);if(!hl(gn(l,".git")))continue;let u=gl(l),p=c.defaultBranch||"main";e.fetch&&await u.fetch(["origin",p]).catch(()=>{});let d=await wg({name:c.name,dir:l,defaultBranch:p}),m=(await u.revparse([d]).catch(()=>"")).trim();if(m){if(i.get(c.name)?.builtFromCommit===m){s.push(c.name);continue}try{a.push(await Vc({repo:c.name,repoDir:l,contextDir:t.contextDir,settings:n,ref:m})),o.push(c.name)}catch(f){r(`[model] rebuild of ${c.name} failed: ${f instanceof Error?f.message:String(f)}`)}}}return a.length>0&&(await oi(t.contextDir,a,{halfLifeDays:n.cochange.halfLifeDays}),r(`[model] release-path rebuild: ${o.join(", ")} (skipped up-to-date: ${s.join(", ")||"\u2014"})`)),{rebuilt:o,skipped:s}}var Po=$(()=>{"use strict";tt();gg();zc();qc();Fs();Eo();Er();bt()});var xg={};Be(xg,{computeDriftReport:()=>KE,supersededAdrIds:()=>vg});import{existsSync as bl,readFileSync as $l,readdirSync as vl}from"node:fs";import{join as yn}from"node:path";import{parse as ME}from"yaml";import{simpleGit as UE}from"simple-git";function FE(t,e){let r=yn(t,`model/derived/structure/${e}`),n=[],o="";if(!bl(r))return{nodes:n,builtFromCommit:o};for(let s of vl(r).sort()){if(!s.endsWith(".yaml"))continue;let i;try{let a=Ct(ME($l(yn(r,s),"utf-8")));if(!a.ok)continue;i=a.value}catch{continue}o=i.builtFromCommit;for(let a of i.nodes){let c=re(a.key);!c||c.level!=="code"&&c.level!=="component"||n.push({key:a.key,path:c.path,level:c.level,contentHash:a.contentHash,entityId:a.entityId})}}return{nodes:n,builtFromCommit:o}}function vg(t){let e=new Set,r=yn(t,"adr");if(!bl(r))return e;for(let n of vl(r).sort()){let o=/^(\d{4})-/.exec(n)?.[1];if(!(!o||!n.endsWith(".md")))try{let s=$l(yn(r,n),"utf-8").slice(0,600).toLowerCase();/status[^\n]*superseded/.test(s)&&e.add(`ADR-${o}`)}catch{}}return e}async function KE(t,e,r){let{nodes:n,builtFromCommit:o}=FE(e,r),s=(await UE(t).revparse(["HEAD"])).trim(),i=await So(t,s),a=new Map(i.map(y=>[y.path,y.blobHash])),c=[],l=[],u=new Set,p=[];for(let y of n){if(y.level==="component"){p.push(y);continue}u.add(y.path);let x=a.get(y.path);x?y.contentHash&&x.slice(0,BE)!==y.contentHash&&c.push(y.key):l.push(y.key)}let d=0,m=new Map,f=new Set;for(let y of i){let x=y.path.lastIndexOf("/"),S=x<0?"":y.path.slice(0,x);m.has(S)||m.set(S,new Set),m.get(S).add(y.path),u.has(y.path)||d++;let T=S;for(;T!==""&&!f.has(T);)f.add(T),T=T.includes("/")?T.slice(0,T.lastIndexOf("/")):""}let g=new Map;for(let y of u){let x=y.lastIndexOf("/"),S=x<0?"":y.slice(0,x);g.has(S)||g.set(S,new Set),g.get(S).add(y)}for(let y of p){if(!f.has(y.path)){l.push(y.key);continue}let x=g.get(y.path)??new Set,S=m.get(y.path)??new Set;(x.size!==S.size||[...x].some(R=>!S.has(R)))&&c.push(y.key)}let h=[],w=vg(e);if(w.size>0){let y=yn(e,"model/facts/annotations"),x=new Map(n.filter(S=>S.entityId).map(S=>[S.entityId,S.key]));if(bl(y))for(let S of vl(y).sort()){if(!S.endsWith(".md"))continue;let T=S.replace(/\.md$/,""),R=x.get(T);if(R)try{($l(yn(y,S),"utf-8").match(/\bADR-(\d{3,4})\b/g)??[]).map(D=>`ADR-${D.slice(4).padStart(4,"0")}`).some(D=>w.has(D))&&h.push(R)}catch{}}}return{repo:r,builtFromCommit:o,headCommit:s,stale:[...new Set(c)].sort(),orphaned:[...new Set(l)].sort(),superseded:[...new Set(h)].sort(),newFiles:d}}var BE,Sg=$(()=>{"use strict";F();Eo();BE=12});import{existsSync as Rg,rmSync as GE}from"node:fs";import{join as _r}from"node:path";import{simpleGit as HE}from"simple-git";import"ws";function ai(t,e={}){let r=e.log??{info:h=>console.log(h),warn:h=>console.warn(h)};r.info(`codepipe-cli v${Fe} (protocol ${at})`);let n=h=>e.onEvent?.(h),o=e.workspace;o?.contextDir&&Mf(o.contextDir,r);let s=Eg("CLI_TRACKING_POLL_INTERVAL_SEC"),i=Eg("CLI_YOUTRACK_POLL_INTERVAL_SEC"),a=(()=>{let h=parseInt(process.env.CLI_READINESS_INTERVAL_SEC??"600",10);return Number.isFinite(h)&&h>0?h*1e3:6e5})(),c=!1,l=!1,u=!1,p=new Set,d=!1,m=new Set,f=g();function g(){let h=ks(t.hubUrl,t.cliToken),w=null,y=new ri(s,_=>{h.readyState===h.OPEN&&h.send(JSON.stringify(_))},r),x=new ni(i,_=>{h.readyState===h.OPEN&&h.send(JSON.stringify(_))},r,{contextDir:o?.contextDir??null,isSelfComment:_=>m.has(_)}),S=null,T=async()=>{try{let _={trackerProvider:il(o?.contextDir??null)};try{let L=await oe(t.hubUrl,t.cliToken,t.projectId);_={..._,repos:L.repos,contextRepo:L.contextRepo}}catch(L){r.warn(`[readiness] could not fetch project summary for push checks: ${L instanceof Error?L.message:String(L)}`)}let B=await Gp(t.projectId,_);if(h.readyState!==h.OPEN)return;let O={type:"cli_readiness",projectId:t.projectId,ready:B.ready,checks:B.checks,creds:B.creds,secretNames:ep(t.projectId),checkedAt:B.checkedAt};if(h.send(JSON.stringify(O)),B.ready)r.info("[readiness] ready");else{let L=B.checks.filter(E=>!E.ok).map(E=>`${E.name}(${E.detail??""})`);r.warn(`[readiness] NOT ready \u2014 ${L.join(", ")}`)}let X=Xp(B.creds,u);if(X==="open"){u=!0;let L=Jp(t.hubUrl,t.projectId);r.info(`[agent-auth] Claude token invalid (401) \u2014 opening the dashboard to re-authorize: ${L}`),$r(L)}else X==="rearm"&&(u=!1)}catch(_){r.warn(`[readiness] check failed: ${_ instanceof Error?_.message:String(_)}`)}},R=()=>{T(),S=setInterval(()=>void T(),a),typeof S.unref=="function"&&S.unref()},b=()=>{S&&(clearInterval(S),S=null)},I=150,D=new Map,K=_=>{let B=D.get(_);if(!B||(B.timer&&clearTimeout(B.timer),D.delete(_),B.events.length===0||h.readyState!==h.OPEN))return;let O={type:"run_activity",projectId:t.projectId,runId:_,events:B.events};h.send(JSON.stringify(O))},ee=(_,B)=>{let O=D.get(_);if(O||(O={events:[],timer:null},D.set(_,O)),O.events.push(B),B.kind==="result"){K(_);return}O.timer||(O.timer=setTimeout(()=>K(_),I),O.timer.unref?.())},C=o?.contextDir?new Ts(o.contextDir,t.projectId,_=>{h.readyState===h.OPEN&&h.send(JSON.stringify(_))},r):null,k=async()=>{let _=o?.contextDir;if(!_)throw new Error("no context repo clone on this CLI");let B;try{B=(await oe(t.hubUrl,t.cliToken,t.projectId)).contextRepo}catch{}let O=await cm(_,t.projectId,B,r);return h.readyState===h.OPEN&&h.send(JSON.stringify(O)),O},U=null,P=async()=>{let _=o?.contextDir;if(_)try{let{readContextIndexHub:B,collectSearchRows:O}=await Promise.resolve().then(()=>(To(),Ro));if(B(_)!=="metadata")return;let X=O(_);h.readyState===h.OPEN&&(h.send(JSON.stringify({type:"model_index",projectId:t.projectId,rows:X})),r.info(`[model] tier-2 index snapshot pushed (${X.length} rows)`))}catch(B){r.warn(`[model] tier-2 index push failed (non-fatal): ${B instanceof Error?B.message:String(B)}`)}},G=()=>{U&&clearTimeout(U),U=setTimeout(()=>void P(),5e3)},Y=null,se=async _=>{if(o?.contextDir)try{let{rebuildWorkspaceModelIfStale:B}=await Promise.resolve().then(()=>(Po(),ii));(await B({root:o.root,contextDir:o.contextDir,repos:o.repos},{fetch:_,onLog:X=>r.info(X)})).rebuilt.length>0&&G()}catch(B){r.warn(`[model] release-path rebuild failed (non-fatal): ${B instanceof Error?B.message:String(B)}`)}},qe=_=>{Y&&clearTimeout(Y),Y=setTimeout(()=>void se(_),6e4)},Ye=setInterval(()=>void se(!0),6*36e5);return h.on("open",()=>{r.info("[ws] connected"),n({kind:"connected"});let _=cp(t.projectId),B=J("ORIGIN")==="farm"?"farm":"local",O=J("FARM_ID"),X=t.accountEmail??_.email,L;try{let v=bm(t.projectId);v&&(L=v.publicKey,r.info(`[cred-channel] key fingerprint: ${v.fingerprint}`))}catch(v){r.warn(`[cred-channel] key setup failed (token replacement via dashboard unavailable): ${v instanceof Error?v.message:String(v)}`)}let E={type:"register",projectId:t.projectId,platformVersion:Fe,protocolVersion:at,accountId:_.accountId,accountLabel:_.label,origin:B,inFlightActionIds:[...p],...X?{accountEmail:X}:{},...B==="farm"&&O?{farmId:O}:{},...L?{sealPublicKey:L}:{}};h.send(JSON.stringify(E))}),h.on("message",async _=>{let B=_.toString("utf-8");if(B==="pong"||B==="ping")return;let O;try{O=JSON.parse(B)}catch{return}if(!O||typeof O!="object")return;let X=O.type;if(X==="registered"){let E=O;if(E.ok){if(r.info(`[ws] registered for project ${E.projectId}`),n({kind:"registered",projectId:E.projectId??t.projectId}),y.start(),C?.start(),R(),Sl(t,o,r),o?.contextDir){try{let v=_s(o.contextDir,t.projectId);h.readyState===h.OPEN&&h.send(JSON.stringify(v)),v.outdated&&(r.warn(`[ctx] context format outdated: v${v.templateVersion} \u2192 v${v.currentVersion}`+(v.missingPaths.length>0?` (missing: ${v.missingPaths.join(", ")})`:"")),l||(l=!0,k().catch(()=>{})))}catch(v){r.warn(`[ctx] context-format detect failed (non-fatal): ${v instanceof Error?v.message:String(v)}`)}P(),qe(!0)}}else r.warn(`[ws] register rejected: ${E.reason??"unknown"}`),n({kind:"register_rejected",reason:E.reason??"unknown"}),c=!0,h.close();return}if(X==="hello"){let E=O;w=Vn(E.protocolVersion);let v=w?"compatible":"INCOMPATIBLE";r.info(`[ws] hub v${E.platformVersion} (protocol ${E.protocolVersion}) \u2014 ${v}`),w||(r.warn(`[ws] HUB protocol incompatible with this CLI (v${Fe}, protocol ${at}) \u2014 WriteActions will be refused until versions align.`),r.warn(`[ws] update the CLI: ${xl}`),n({kind:"incompatible",hubVersion:typeof E.platformVersion=="string"?E.platformVersion:null,hubProtocol:typeof E.protocolVersion=="number"?E.protocolVersion:null,updateCommand:xl}));return}if(X==="tracking_targets"){y.setTargets(O.targets);return}if(X==="youtrack_sync_request"){x.setRequest(O);return}if(X==="youtrack_force_sync"){x.forceSync();return}if(X==="sync_local"){await YE(O,o,h,r);return}if(X==="provision_repo"){let E=O;r.info(`[repo] provision_repo: ${E.repo.name} (${E.repo.host}:${E.repo.owner}/${E.repo.repoName})`),await WE(t,o,E.repo,r),await Sl(t,o,r);return}if(X==="remove_repo"){let E=O;r.info(`[repo] remove_repo: ${E.repoName}${E.purge?" (purge)":""}`),await Sl(t,o,r),E.purge&&qE(t,o,E.repoName,r);return}if(X==="context_write"){await VE(O,o,h,r);return}if(X==="adr_promote"){await zE(O,o,h,r);return}if(X==="cred_update"){let E=O,v=q(t.projectId),N=v?.sealKey?await $m(t.projectId,E.kind,E.sealed,v.sealKey.privateKey):{ok:!1,detail:"no cred-channel key on this CLI (restart the daemon)"},z={type:"cred_update_result",updateId:E.updateId,projectId:t.projectId,ok:N.ok,...N.detail?{detail:N.detail}:{}};h.readyState===h.OPEN&&h.send(JSON.stringify(z)),N.ok?(r.info(`[cred] ${E.kind} replaced${N.detail?` \u2014 ${N.detail}`:""}`),T()):r.warn(`[cred] ${E.kind} replacement rejected: ${N.detail??"unknown"}`);return}if(X==="readiness_check"){r.info("[readiness] on-demand check requested"),T();return}if(X==="agent_login_start"){Vp(t,h,O,r,T);return}if(X==="move_to_farm"){let E=O;r.info(`[farm-move] request to move ${t.projectId} onto farm ${E.farmName} (${E.farmId})`);let v=await qh(t,E,o?.contextDir,r);h.readyState===h.OPEN&&h.send(JSON.stringify(v)),v.ok?r.info(`[farm-move] done \u2014 farm daemon ${v.daemonStatus??"started"}; expecting takeover`):r.warn(`[farm-move] failed: ${v.error??"unknown error"}`);return}if(X==="gh_runner_setup"){let E=O;r.info(`[ghr] runner setup for ${t.projectId} on runner host ${E.runnerName} (${E.runnerId})`);let v=await tg(t,E,r);h.readyState===h.OPEN&&h.send(JSON.stringify(v)),v.ok?r.info(`[ghr] runners connected on ${E.runnerName}`):r.warn(`[ghr] setup failed: ${v.error??"see per-repo statuses"}`);return}if(X==="gh_runner_teardown"){let E=O;r.info(`[ghr] runner teardown for ${t.projectId} on runner host ${E.runnerName} (${E.runnerId})`);let v=await rg(t,E,r);h.readyState===h.OPEN&&h.send(JSON.stringify(v)),v.ok?r.info(`[ghr] runners disconnected from ${E.runnerName}`):r.warn(`[ghr] teardown failed: ${v.error??"unknown error"}`);return}if(X==="tracker_fields_request"){let E=O,v={type:"tracker_fields_result",requestId:E.requestId,projectId:t.projectId,ok:!1},N=St({contextDir:o?.contextDir??null});if(!N.ok)v.error=N.error;else try{v.fields=await N.provider.fetchStateFields(E.projectKey),v.ok=!0}catch(z){v.error=z instanceof Error?z.message:String(z)}h.readyState===h.OPEN&&h.send(JSON.stringify(v)),v.ok||r.warn(`[yt-fields] listing failed: ${v.error??"unknown"}`);return}if(X==="project_secret_update"||X==="project_secret_delete"){let E=O,v;if(E.type==="project_secret_update"){let z=q(t.projectId);v=z?.sealKey?sg(t.projectId,E.name,E.sealed,z.sealKey.privateKey):{ok:!1,detail:"no cred-channel key on this CLI (restart the daemon)"}}else v=ig(t.projectId,E.name);let N={type:"project_secret_update_result",updateId:E.updateId,projectId:t.projectId,ok:v.ok,...v.detail?{detail:v.detail}:{}};h.readyState===h.OPEN&&h.send(JSON.stringify(N)),v.ok?(r.info(`[secret] ${E.name} ${E.type==="project_secret_update"?"saved":"deleted"}`+(v.detail?` \u2014 ${v.detail}`:"")),T()):r.warn(`[secret] ${E.name} rejected: ${v.detail??"unknown"}`);return}if(X==="auto_apply_local"){let E=O;if(!o?.contextDir){r.warn(`[apply] auto_apply_local for ${E.claim.taskKey} \u2014 no workspace (headless), skipped; task stays in READY_TO_APPLY`);return}let v=await Tf({hubUrl:t.hubUrl,cliToken:t.cliToken,projectId:t.projectId,root:o.root,contextDir:o.contextDir,repos:o.repos},E.claim,r).catch(N=>({ok:!1,message:N instanceof Error?N.message:String(N)}));v.ok?r.info(`[apply] ${E.claim.taskKey}: ${v.message}`):r.warn(`[apply] ${E.claim.taskKey}: ${v.message} \u2014 task stays in READY_TO_APPLY`),n({kind:"local_applied",taskKey:E.claim.taskKey,ok:v.ok,...v.ok?{branches:v.branches??[]}:{error:v.message}});return}if(X==="sandbox_keys"){let E=q(t.projectId);if(!E){r.warn(`[cred] sandbox_keys received but no secrets for ${t.projectId} \u2014 cannot seal`);return}let v=Zr(t.projectId),N=hm(O,E,v,r);for(let z of N)h.readyState===h.OPEN&&h.send(JSON.stringify(z));return}if(X!=="dispatch_action")return;let L=O;if(w===!1){let E=`refused: HUB protocol incompatible with CLI v${Fe} (protocol ${at})`;h.send(JSON.stringify({type:"action_result",actionId:L.actionId,status:"failed",error:E})),r.warn(`[exec] ${L.actionId} (${L.action.type}) \u2192 REFUSED: ${E}`),r.warn(`[exec] update the CLI to clear this: ${xl}`),n({kind:"action",actionId:L.actionId,actionType:L.action.type,ok:!1,error:E});return}if(L.action.type==="model_drift"){p.add(L.actionId);try{let E,v=o?.repos.find(N=>N.name===L.action.repoName);if(!o?.contextDir||!v)E={status:"failed",error:"no local workspace/repo clone on this CLI"};else try{let{computeDriftReport:N}=await Promise.resolve().then(()=>(Sg(),xg)),z=v.mountAs==="."?o.root:_r(o.root,v.mountAs);E={status:"done",result:{report:await N(z,o.contextDir,v.name)}}}catch(N){E={status:"failed",error:N instanceof Error?N.message:String(N)}}h.send(JSON.stringify({type:"action_result",actionId:L.actionId,...E}))}finally{p.delete(L.actionId)}return}if(L.action.type==="model_bootstrap"){p.add(L.actionId);try{let E;if(!o?.contextDir)E={status:"failed",error:"no Context Repo clone on this CLI"};else if(d)E={status:"failed",error:"model bootstrap is already running"};else{d=!0;try{let v=await oe(t.hubUrl,t.cliToken,t.projectId),{bootstrapDaemonModel:N}=await Promise.resolve().then(()=>(Po(),ii)),z=await N(t.projectId,{root:o.root,contextDir:o.contextDir},v.repos,ve=>r.info(`[model] ${ve}`));r.info(`[model] bootstrap done: ${z.repos} repos, ${z.events} task events`),G(),E={status:"done",result:{repos:z.repos,events:z.events}}}catch(v){E={status:"failed",error:v instanceof Error?v.message:String(v)},r.warn(`[model] bootstrap failed: ${E.error}`)}finally{d=!1}}h.readyState===h.OPEN&&h.send(JSON.stringify({type:"action_result",actionId:L.actionId,...E}))}finally{p.delete(L.actionId)}return}if(L.action.type==="local_apply"){p.add(L.actionId);try{let E;if(!o)E={status:"failed",error:"no local workspace on this CLI"};else{let N=await Bh(o,L.action.repos,r);if(E=N.ok?{status:"done",result:{repos:N.repos}}:{status:"failed",error:N.error},N.ok&&o.contextDir){let z=L.action.taskId.split(":")[1]??"";for(let ve of z?N.repos:[]){let ot=o.repos.find(ne=>ne.name===ve.repoName);if(!ot)continue;let{recordPipelineEvent:W}=await Promise.resolve().then(()=>(rl(),Ah));await W({contextDir:o.contextDir,repoDir:_r(o.root,ot.mountAs),repoName:ve.repoName,taskKey:z,commitSha:ve.commit}).catch(ne=>r.warn(`[model] task event for ${z} failed: ${ne instanceof Error?ne.message:String(ne)}`))}G()}}h.send(JSON.stringify({type:"action_result",actionId:L.actionId,...E}));let v=E.status!=="failed";v?r.info(`[exec] ${L.actionId} (local_apply) \u2192 done`):r.warn(`[exec] ${L.actionId} (local_apply) \u2192 FAILED: ${E.status==="failed"?E.error:"?"}`),n({kind:"action",actionId:L.actionId,actionType:"local_apply",ok:v,...E.status==="failed"?{error:E.error}:{}})}finally{p.delete(L.actionId)}return}p.add(L.actionId);try{let E=await Dh({action:L.action,repo:L.repo,trackerIssueId:L.trackerIssueId,contextDir:o?.contextDir,requestConfigReport:C?()=>C.reportNow():void 0,refreshContextStatus:o?.contextDir?k:void 0,onRunActivity:ee}).catch(z=>({status:"failed",error:z instanceof Error?z.message:String(z)}));L.action.type==="tracker_comment"&&E.status==="done"&&"result"in E&&typeof E.result?.commentId=="string"&&m.add(E.result.commentId),h.send(JSON.stringify({type:"action_result",actionId:L.actionId,...E}));let v=E.status!=="failed",N=!v&&"error"in E?E.error:void 0;v?r.info(`[exec] ${L.actionId} (${L.action.type}) \u2192 done`):r.warn(`[exec] ${L.actionId} (${L.action.type}) \u2192 FAILED: ${N??"?"}`),n({kind:"action",actionId:L.actionId,actionType:L.action.type,ok:v,...N?{error:N}:{}}),v&&["apply_delivery","context_write","create_pr"].includes(L.action.type)&&G(),v&&["merge_pr","merge_branch"].includes(L.action.type)&&qe(!0)}finally{p.delete(L.actionId)}}),h.on("close",(_,B)=>{let O=B?.toString("utf-8")??"";if(r.info(`[ws] closed code=${_}${O?` reason=${O}`:""}`),y.stop(),x.stop(),C?.stop(),b(),clearInterval(Ye),Y&&clearTimeout(Y),U&&clearTimeout(U),O==="replaced"){c=!0,r.warn(`[ws] project ${t.projectId} was taken over by another CLI (HUB closed us as "replaced") \u2014 standing down, not reconnecting. Run exactly ONE CLI per project.`),n({kind:"replaced"});return}n({kind:"disconnected",code:_}),!c&&setTimeout(()=>{f=g()},2e3)}),h.on("error",_=>r.warn(`[ws] error: ${_.message}`)),h}return{stop(){c=!0,f.close()}}}async function Sl(t,e,r){try{let n=await oe(t.hubUrl,t.cliToken,t.projectId),{updated:o,errors:s}=bo(t.projectId,n.repos,e?.contextDir);for(let i of o)r.info(`[repo] restaged repo set in ${i}`);for(let i of s)r.warn(`[repo] could not restage ${i.path}: ${i.error}`)}catch(n){r.warn(`[repo] repo-set reconcile skipped: ${n instanceof Error?n.message:String(n)}`)}}async function WE(t,e,r,n){let o=r.mountAs??r.name;if(o==="."){n.info(`[repo] ${r.name} mounts in place (mount_as: .) \u2014 nothing to clone`);return}let s=e?_r(e.root,o):Ie(t.projectId,r.name);if(Rg(_r(s,".git"))){n.info(`[repo] ${r.name} already present at ${s}`);return}try{await HE().clone(mo(r),s),n.info(`[repo] cloned ${r.name} \u2192 ${s}`)}catch(i){n.warn(`[repo] clone of ${r.name} failed (will retry lazily): ${i instanceof Error?i.message.trim():String(i)}`)}}function qE(t,e,r,n){let o=e?.repos.find(i=>i.name===r)?.mountAs??r,s=e?_r(e.root,o):Ie(t.projectId,r);if(e&&s===e.root){n.warn(`[repo] ${r} maps to the workspace root \u2014 skipping purge`);return}if(!Rg(_r(s,".git"))){n.info(`[repo] no local clone to purge for ${r} (${s})`);return}try{GE(s,{recursive:!0,force:!0}),n.info(`[repo] purged local clone ${s}`)}catch(i){n.warn(`[repo] purge of ${s} failed: ${i instanceof Error?i.message:String(i)}`)}}async function YE(t,e,r,n){if(!e){n.info(`[sync] sync_local for ${t.taskId} \u2014 no workspace (headless), skipped`);return}for(let o of t.repos){let s=e.repos.find(l=>l.name===o.repoName),i=_r(e.root,s?.mountAs??o.repoName),a=s?.defaultBranch??o.defaultBranch,c=await Cf(i,a).catch(l=>({status:"warn",reason:l instanceof Error?l.message:String(l)}));c.status==="updated"?n.info(`[sync] ${o.repoName}: fast-forwarded ${a} \u2192 origin`):c.status==="skipped"?n.info(`[sync] ${o.repoName}: not cloned in workspace \u2014 skipped`):(n.warn(`[sync] ${o.repoName}: ${c.reason??"sync skipped"}`),r.readyState===r.OPEN&&r.send(JSON.stringify({type:"local_sync_warning",taskId:t.taskId,repoName:o.repoName,reason:c.reason??"sync skipped"})))}}async function VE(t,e,r,n){let o=(s,i)=>{if(r.readyState!==r.OPEN)return;let a={type:"context_write_result",id:t.id,status:s};i&&(a.error=i),r.send(JSON.stringify(a))};if(!e?.contextDir){n.warn(`[ctx] context_write ${t.id} \u2014 no .codepipe clone (headless), reporting failed`),o("failed","no context repo clone on this CLI");return}try{await Se(e.contextDir,t.files,t.message),n.info(`[ctx] context_write ${t.id}: committed ${t.files.length} file(s)`),o("done")}catch(s){let i=s instanceof Error?s.message:String(s);n.warn(`[ctx] context_write ${t.id} failed: ${i}`),o("failed",i)}}async function zE(t,e,r,n){let o=(s,i)=>{if(r.readyState!==r.OPEN)return;let a={type:"context_write_result",id:t.id,status:s};i&&(a.error=i),r.send(JSON.stringify(a))};if(!e?.contextDir){n.warn(`[adr] adr_promote ${t.id} \u2014 no .codepipe clone (headless), reporting failed`),o("failed","no context repo clone on this CLI");return}try{let s=t.source??"task",i=await Wf(e.contextDir,t.taskKey,t.slugs,void 0,s);if(n.info(`[adr] adr_promote ${t.id}: promoted ${i.promoted.length}, skipped ${i.skipped.length}`+(i.promoted.length>0?` (${i.promoted.join(", ")})`:"")),i.missing.length>0){let a=l=>s==="staging"?`adr/DRAFT-${l}.md`:`tasks/${t.taskKey}/adr/DRAFT-${l}.md`,c=`draft file(s) missing in clone: ${i.missing.map(a).join(", ")}`;n.warn(`[adr] adr_promote ${t.id}: ${c}`),o("failed",c);return}o("done")}catch(s){let i=s instanceof Error?s.message:String(s);n.warn(`[adr] adr_promote ${t.id} failed: ${i}`),o("failed",i)}}function Eg(t){let e=parseInt(process.env[t]??"60",10);return Number.isFinite(e)&&e>0?e*1e3:6e4}var xl,El=$(()=>{"use strict";Le();F();lp();zp();Zp();ys();gc();Af();Lf();qf();tt();Ot();Ic();lm();jc();Er();gm();vm();Mh();Fh();Yh();ng();Ae();ag();rn();pe();cg();pg();Zs();xl="npm i -g @code-partner/codepipe@latest"});import{execFileSync as XE}from"node:child_process";import{mkdtempSync as JE,mkdirSync as ZE,readFileSync as Tg,rmSync as QE,writeFileSync as eR}from"node:fs";import{tmpdir as tR}from"node:os";import{dirname as rR,join as Ig}from"node:path";function Cg(t="codepipe-context"){let e=JE(Ig(tR(),"codepipe-ssh-")),r=Ig(e,"id_ed25519");try{return XE("ssh-keygen",["-t","ed25519","-N","","-C",t,"-f",r,"-q"],{stdio:"ignore"}),{privateKey:Tg(r,"utf-8"),publicKey:Tg(`${r}.pub`,"utf-8").trim()}}finally{QE(e,{recursive:!0,force:!0})}}async function Ag(t,e,r,n="codepipe-context"){let o=await fetch(`https://api.github.com/repos/${t.owner}/${t.name}/keys`,{method:"POST",headers:{Authorization:`Bearer ${e}`,Accept:"application/vnd.github+json","Content-Type":"application/json"},body:JSON.stringify({title:n,key:r,read_only:!1})});if(o.ok)return;let s=await o.text();if(!(o.status===422&&/already in use/i.test(s)))throw new Error(`add deploy key failed: ${o.status} ${s}`)}function Pg(t){if(/^git@[^:]+:.+/.test(t))return t;let e=t.match(/^ssh:\/\/git@([^/]+)\/(.+)$/);if(e)return`git@${e[1]}:${e[2]}`;let r=t.match(/^https:\/\/(?:[^@/]+@)?([^/]+)\/(.+)$/);return r?`git@${r[1]}:${r[2]}`:t}function _g(t,e){ZE(rR(t),{recursive:!0});let r=e.endsWith(`
|
|
742
|
+
`,{mode:384})}function SE(t){return Vh()[t]}function dl(t,e){let r=Vh();r[t]=e,xE(r)}function zh(t,e){let r=De(e),n=SE(t);if(n&&n!==r)throw new Error(`runner host ${t} key fingerprint changed (pinned ${n}, now ${r}) \u2014 refusing to seal. If the runner host was re-registered intentionally, remove its entry from ${ul()}.`);return r}var Xh=$(()=>{"use strict";Le();rt()});async function Jh(t,e,r,n){let o=await fetch(`https://api.github.com/repos/${e}/${r}/actions/runners/${n}`,{method:"POST",headers:Zh(t)});if(!o.ok)throw new Error(`github ${n} for ${e}/${r}: HTTP ${o.status}`);let s=await o.json();if(!s.token)throw new Error(`github ${n} for ${e}/${r}: no token in response`);return s.token}async function eg(t,e,r){if(e.projectId!==t.projectId)throw new Error(`project mismatch: this daemon serves ${t.projectId}, not ${e.projectId}`);if(De(e.runnerPublicKey)!==e.fingerprint)throw new Error("runner host key fingerprint does not match the confirmed one \u2014 refusing to seal (possible relay tampering)");zh(e.runnerId,e.runnerPublicKey);let s=q(t.projectId)?.github?.token;if(!s)throw new Error("no GitHub token stored for this project on this CLI");let a=((await r.fetchProject(t.hubUrl,t.cliToken,t.projectId)).repos??[]).find(c=>c.host==="github"&&c.owner===e.owner&&c.repoName===e.repo);if(!a)throw new Error(`${e.owner}/${e.repo} is not a GitHub repository of this project`);return{githubToken:s,repo:a}}async function tg(t,e,r,n=Qh){let o=s=>({type:"gh_runner_setup_result",requestId:e.requestId,projectId:t.projectId,ok:!1,error:s});try{let{githubToken:s,repo:i}=await eg(t,e,n);if(!await n.api.repoHasAdmin(s,i.owner,i.repoName))return o(`the GitHub token lacks admin access on ${i.owner}/${i.repoName} \u2014 replace it (project page \u2192 Tokens \u2192 Replace) with a token that has admin rights on this repository`);let a={projectId:t.projectId,runners:[{owner:i.owner,repo:i.repoName,regToken:await n.api.mintRegistrationToken(s,i.owner,i.repoName)}],labels:[Ma(e.runnerId)]},c=Lt(e.runnerPublicKey,JSON.stringify(a));dl(e.runnerId,e.fingerprint),r.info(`[ghr] registration token for ${i.owner}/${i.repoName} sealed for runner host ${e.runnerName} \u2014 handing off`);let l=await n.provisionOnRunner(t.hubUrl,t.cliToken,e.runnerId,{projectId:t.projectId,sealedBundle:c});return{type:"gh_runner_setup_result",requestId:e.requestId,projectId:t.projectId,ok:l.ok,...l.runners?{runners:l.runners}:{},...l.error?{error:l.error}:{}}}catch(s){return o(s instanceof Error?s.message:String(s))}}async function rg(t,e,r,n=Qh){let o=s=>({type:"gh_runner_teardown_result",requestId:e.requestId,projectId:t.projectId,ok:!1,error:s});try{let{githubToken:s,repo:i}=await eg(t,e,n),a={owner:i.owner,repo:i.repoName};try{a.removeToken=await n.api.mintRemoveToken(s,i.owner,i.repoName)}catch(p){r.warn(`[ghr] remove-token for ${i.owner}/${i.repoName} failed (${p instanceof Error?p.message:p}) \u2014 the runner host will force-remove`)}let c={projectId:t.projectId,runners:[a]},l=Lt(e.runnerPublicKey,JSON.stringify(c));dl(e.runnerId,e.fingerprint),r.info(`[ghr] removal bundle for ${i.owner}/${i.repoName} sealed for runner host ${e.runnerName} \u2014 handing off`);let u=await n.teardownOnRunner(t.hubUrl,t.cliToken,e.runnerId,{projectId:t.projectId,sealedBundle:l,owner:i.owner,repo:i.repoName});return{type:"gh_runner_teardown_result",requestId:e.requestId,projectId:t.projectId,ok:u.ok,...u.error?{error:u.error}:{}}}catch(s){return o(s instanceof Error?s.message:String(s))}}var Zh,EE,Qh,ng=$(()=>{"use strict";F();rt();Xh();Ae();pe();Zh=t=>({Authorization:`Bearer ${t}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28","User-Agent":"codepipe-cli"});EE={async repoHasAdmin(t,e,r){let n=await fetch(`https://api.github.com/repos/${e}/${r}`,{headers:Zh(t)});if(!n.ok)throw new Error(`github GET /repos/${e}/${r}: HTTP ${n.status}`);return(await n.json()).permissions?.admin===!0},mintRegistrationToken:(t,e,r)=>Jh(t,e,r,"registration-token"),mintRemoveToken:(t,e,r)=>Jh(t,e,r,"remove-token")},Qh={api:EE,fetchProject:oe,provisionOnRunner:ef,teardownOnRunner:tf}});function RE(t){return Ge.test(t)?Pt(t)?`secret name "${t}" is reserved`:null:`secret name must match ${Ge}`}function sg(t,e,r,n){let o=RE(e);if(o)return{ok:!1,detail:o};let s;try{let i=JSON.parse(ln(n,r).toString("utf-8"));if(typeof i.value!="string"||i.value.length===0)return{ok:!1,detail:"payload has no value"};s=i.value}catch(i){return{ok:!1,detail:`cannot open the sealed secret (${i instanceof Error?i.message:String(i)}) \u2014 wrong channel key?`}}if(s.length>og)return{ok:!1,detail:`secret value too large (max ${og} chars)`};try{return Zd(t,e,s),{ok:!0}}catch(i){return{ok:!1,detail:i instanceof Error?i.message:String(i)}}}function ig(t,e){try{return Qd(t,e)?{ok:!0}:{ok:!0,detail:"no such secret (already absent)"}}catch(r){return{ok:!1,detail:r instanceof Error?r.message:String(r)}}}var og,ag=$(()=>{"use strict";F();rt();pe();og=16*1024});function TE(t){return t.length===0?null:t.some(e=>e.state==="closed"&&!e.merged)?"needs_manual":t.every(e=>e.merged)?"done":null}var ri,cg=$(()=>{"use strict";qt();ri=class{constructor(e,r,n){this.intervalMs=e;this.send=r;this.log=n}targets=new Map;lastSig=new Map;timer=null;running=!1;setTargets(e){this.targets.clear(),this.lastSig.clear();for(let r of e)this.targets.set(r.taskId,r);this.log.info(`[track] targets updated: ${this.targets.size} task(s)`)}start(){if(this.timer)return;this.log.info(`[track] poller started (interval=${this.intervalMs}ms)`);let e=()=>{this.tick().catch(r=>this.log.warn(`[track] tick crashed: ${r instanceof Error?r.message:String(r)}`))};e(),this.timer=setInterval(e,this.intervalMs)}stop(){this.timer&&(clearInterval(this.timer),this.timer=null,this.log.info("[track] poller stopped"))}async tickOnce(){await this.tick()}async tick(){if(!this.running){this.running=!0;try{for(let[e,r]of this.targets)await this.processTask(e,r)}finally{this.running=!1}}}async processTask(e,r){let n=[];for(let i of r.prs){let a=dt(i.repoSpec);try{let c=await a.getPullRequest(i.repoSpec,i.number);n.push({number:i.number,url:i.url,state:c.state,merged:c.merged,ci:c.ci,mergeable:c.mergeable})}catch(c){if(c instanceof wr){this.log.warn(`[track] task=${e} pr=${i.url} not found \u2014 skipping tick for this task`);return}this.log.warn(`[track] task=${e} pr=${i.url} fetch failed: ${c instanceof Error?c.message:String(c)}`);return}}let o=n.map(i=>`${i.number}:${i.state}:${i.merged?1:0}:${i.ci}:${i.mergeable}`).join("|");if(this.lastSig.get(e)===o)return;for(let i=0;i<n.length;i++){let a=n[i];if(a.ci!=="failed")continue;let c=dt(r.prs[i].repoSpec);if(c.getCiFailureLog)try{let l=await c.getCiFailureLog(r.prs[i].repoSpec,a.number);l&&(a.ciFailureLog=l)}catch(l){this.log.warn(`[track] task=${e} pr=${a.url} ci-log fetch failed: ${l instanceof Error?l.message:String(l)}`)}}this.send({type:"pr_state_observed",taskId:e,prs:n}),this.lastSig.set(e,o);let s=TE(n);this.log.info(`[track] task=${e} snapshot signalled${s?` \u2192 ${s}`:""} (${n.length} PR(s))`)}}});function lg(t){let{description:e,...r}=t;return r}function IE(t){let{body:e,...r}=t;return r}function CE(t){let r=(t.split(/[\\/]/).pop()??t).replace(/[^A-Za-z0-9._-]/g,"_").replace(/^\.+/,"");return r.length>0?r.slice(0,120):"attachment"}async function ug(t,e,r,n){try{return await t.getIssue(e,r)}catch(o){return n.warn(`[yt-sync] getIssue ${e} failed: ${o instanceof Error?o.message:String(o)}`),null}}async function dg(t,e,r,n){try{return await t.listComments(e,r)}catch(o){return n.warn(`[yt-sync] listComments ${e} failed: ${o instanceof Error?o.message:String(o)}`),null}}var ni,pg=$(()=>{"use strict";F();Js();Zs();ni=class t{constructor(e,r,n,o={contextDir:null}){this.intervalMs=e;this.send=r;this.log=n;this.options=o}request=null;timer=null;running=!1;warnedMissingCfg=!1;shippedAttachments=new Set;abandonedTicks=0;static MAX_ABANDONED_TICKS=3;setRequest(e){let r=this.request?.projectId;this.request=e,this.log.info(`[yt-sync] request updated: project=${e.projectKey} columns=[${e.sourceColumns.join(",")}] sinceMs=${e.sinceMs} offBoard=${e.offBoardIssueIds.length}`),this.timer||this.start(),r&&r!==e.projectId&&this.log.info(`[yt-sync] project switch ${r} \u2192 ${e.projectId}`)}start(){if(this.timer)return;this.log.info(`[yt-sync] poller started (interval=${this.intervalMs}ms)`);let e=()=>{this.tick().catch(r=>this.log.warn(`[yt-sync] tick crashed: ${r instanceof Error?r.message:String(r)}`))};e(),this.timer=setInterval(e,this.intervalMs)}stop(){this.timer&&(clearInterval(this.timer),this.timer=null,this.log.info("[yt-sync] poller stopped"))}async tickOnce(){await this.tick()}async forceSync(){if(!this.request){this.log.info("[yt-sync] force requested but no sync_request yet \u2014 ignored");return}this.log.info("[yt-sync] force sync requested (manual)"),await this.tick()}async tick(){if(this.running||!this.request)return;let r=(this.options.resolveProvider??(()=>St({contextDir:this.options.contextDir})))();if(!r.ok){this.warnedMissingCfg||(this.warnedMissingCfg=!0,this.log.warn(`[yt-sync] tracker provider unavailable (${r.error}) \u2014 poller idle.`));return}this.warnedMissingCfg=!1,this.running=!0;try{await this.pollOnce(this.request,r.provider)}finally{this.running=!1}}async pollOnce(e,r){let n=Date.now(),o;try{let x=e.stageField?{stageField:e.stageField}:{},S=e.requireAssignee&&e.assignee?{assignee:e.assignee}:e.requireAssignee&&!e.assignee?{requireAnyAssignee:!0}:{},R=(e.backlogScope??"personal")==="shared"&&!!e.requireAssignee&&!!e.backlogColumn;if(r.kind==="internal")o=await r.listIssues({projectKey:e.projectKey});else if(R){let b=[...new Set([...e.sourceColumns,...e.rejectColumns??[],...e.doneColumns??[],...e.reviewColumns??[]])],[I,D]=await Promise.all([b.length>0?r.listIssues({projectKey:e.projectKey,columns:b,...x,...S}):Promise.resolve([]),r.listIssues({projectKey:e.projectKey,columns:[e.backlogColumn],...x})]),K=new Map;for(let ee of[...I,...D])K.set(ee.id,ee);o=[...K.values()]}else{let b=[...new Set([...e.sourceColumns,...e.rejectColumns??[],...e.doneColumns??[],...e.reviewColumns??[],...e.backlogColumn?[e.backlogColumn]:[]])];o=await r.listIssues({projectKey:e.projectKey,columns:b,...x,...S})}}catch(x){let S=x instanceof Error?x.message:String(x);S.includes("stage_field")?this.log.warn(`[yt-sync] CONFIGURATION ERROR \u2014 ${S}`):this.log.warn(`[yt-sync] listIssues failed: ${S}`);return}let s=new Map,i=new Set,a=new Set(e.doneColumns??[]);for(let x of o){if(i.add(x.id),a.has(x.status))continue;let S=await dg(r,x.id,e.sinceMs,this.log);S&&s.set(x.id,S)}let c=[];for(let x of e.offBoardIssueIds){if(i.has(x))continue;let S=await dg(r,x,e.sinceMs,this.log);if(S&&S.length>0&&s.set(x,S),e.requireAssignee||S&&S.length>0){let T=await ug(r,x,e.stageField,this.log);if(T)c.push(T);else if(S&&S.length>0){this.abandonTick("off-board issue fetch failed with new comments");return}}}let l=o.filter(x=>!a.has(x.status)),{attachmentsByIssue:u,attachmentKeys:p}=await this.collectAttachments(l,s,r);if(!this.options.contextDir){this.abandonTick("no Context Repo clone (headless / clone failed) \u2014 cannot deliver task content");return}let d=[...l,...c].map(x=>({issue:x,comments:s.get(x.id)??[],attachments:u.get(x.id)??[]}));d.push(...await Ph(this.options.contextDir,d,x=>ug(r,x,e.stageField,this.log)));try{await Xs(this.options.contextDir,e.projectId,d),this.abandonedTicks=0;for(let x of p)this.shippedAttachments.add(x)}catch(x){let S=x instanceof Error?x.message:String(x);this.abandonTick(`context task sync failed: ${S}`);return}let m=this.options.isSelfComment??(()=>!1),f=[],g=[];for(let[x,S]of s){let T=S.filter(b=>!m(b.id));if(T.length===0)continue;f.push({issueId:x,comments:T.map(IE)});let R=T.flatMap(b=>{let I=gr(b.body);return I?[{commentId:b.id,author:b.author,name:I.name,args:I.args,createdAt:b.createdAt}]:[]});R.length>0&&g.push({issueId:x,commands:R})}let h={type:"youtrack_observation",projectId:e.projectId,issues:o.map(lg),commentsBatch:f,...g.length>0?{commandsBatch:g}:{},...e.requireAssignee&&c.length>0?{offBoardIssues:c.map(lg)}:{},observedAtMs:n};this.send(h);let w=f.reduce((x,S)=>x+S.comments.length,0),y=g.reduce((x,S)=>x+S.commands.length,0);this.log.info(`[yt-sync] observation sent: issues=${o.length} comments=${w} commands=${y} (sinceMs=${e.sinceMs})`)}abandonTick(e){this.abandonedTicks++,this.abandonedTicks<=t.MAX_ABANDONED_TICKS?this.log.warn(`[yt-sync] ${e} \u2014 tick abandoned (${this.abandonedTicks}/${t.MAX_ABANDONED_TICKS}), will retry`):this.log.warn(`[yt-sync] ERROR: ${e} \u2014 still failing after ${this.abandonedTicks} ticks; the project is STALLED until the Context Repo clone is restored`)}async collectAttachments(e,r,n){let o=new Map,s=[];for(let i of e){let a=[...i.attachments??[]];for(let u of r.get(i.id)??[])a.push(...u.attachments??[]);if(a.length===0)continue;let c=[],l=new Set;for(let u of a){let p=`${i.id}:${u.id}`;if(this.shippedAttachments.has(p))continue;let d;try{d=await n.downloadAttachment(u.url)}catch(f){this.log.warn(`[yt-sync] attachment ${u.name} (${i.id}) download failed: ${f instanceof Error?f.message:String(f)}`);continue}let m=CE(u.name);l.has(m)&&(m=`${u.id}-${m}`),l.add(m),c.push({name:m,contentBase64:d.toString("base64")}),s.push(p)}c.length>0&&o.set(i.id,c)}return{attachmentsByIssue:o,attachmentKeys:s}}}});import{existsSync as fg,readFileSync as AE,readdirSync as PE}from"node:fs";import{join as mg}from"node:path";import{simpleGit as _E}from"simple-git";import{parse as jE}from"yaml";function pl(t){let e=new Map,r=mg(t,zo);if(!fg(r))return e;let n;try{n=jE(AE(r,"utf-8"))}catch{return e}let o=n?.repos;if(!o||typeof o!="object")return e;for(let[s,i]of Object.entries(o)){if(!i||typeof i!="object")continue;let a=i,c=a.counts??{};typeof a.builtFromCommit=="string"&&e.set(s,{builtFromCommit:a.builtFromCommit,counts:{component:typeof c.component=="number"?c.component:0,code:typeof c.code=="number"?c.code:0,correlates:typeof c.correlates=="number"?c.correlates:0}})}return e}function NE(t){let e={};for(let[r,n]of t)e[r]={builtFromCommit:n.builtFromCommit,counts:n.counts};return mr({modelFormatVersion:2,repos:e})}function hg(t,e){let r=mg(t,e);if(!fg(r))return[];let n=[];for(let o of PE(r,{withFileTypes:!0})){let s=`${e}/${o.name}`;o.isDirectory()?n.push(...hg(t,s)):n.push(s)}return n}async function oi(t,e,r={}){let n=[],o=0;for(let d of e){n.push(...d.files);let m=`model/derived/structure/${d.repo}`;for(let f of hg(t,m))d.emittedShardPaths.has(f)||(n.push({path:f,content:"",deleted:!0}),o++)}let s=pl(t);for(let d of e)s.set(d.repo,{builtFromCommit:d.headCommit,counts:d.counts});n.push({path:zo,content:NE(s)});let i=Gs(t),a=$h(i,r.halfLifeDays??Je.halfLifeDays);n.push({path:ur,content:Hs(a)});for(let d of e){let m=[];for(let f of i)for(let g of f.files)re(g.key)?.repo===d.repo&&m.push({kind:"touched_by",from:ke(f.taskKey),to:g.key,...g.churn!==void 0?{weight:g.churn}:{}});n.push({path:Ji(d.repo),content:pr({modelFormatVersion:2,repo:d.repo,builtFromCommit:d.headCommit,edges:m})})}let c=_E(t),l=(await c.revparse(["HEAD"]).catch(()=>"")).trim(),u=`model: build ${e.map(d=>`${d.repo}@${d.headCommit.slice(0,10)}`).join(", ")}`;await Se(t,n,u);let p=(await c.revparse(["HEAD"]).catch(()=>"")).trim();if(p!==l){let{rebuildSearchIndex:d}=await Promise.resolve().then(()=>(To(),Ro));await d(t).catch(()=>{})}return{committed:p!==l,filesWritten:n.filter(d=>!d.deleted).length,filesDeleted:o}}var gg=$(()=>{"use strict";F();Jc();tt()});var ii={};Be(ii,{bootstrapDaemonModel:()=>LE,bootstrapModelForTargets:()=>wl,bootstrapWorkspaceModel:()=>$g,modelBootstrapCommand:()=>kl,modelBuildCommand:()=>yl,rebuildWorkspaceModelIfStale:()=>DE});import{existsSync as hl}from"node:fs";import{join as gn}from"node:path";import{cancel as OE,intro as yg,log as fl,outro as ml}from"@clack/prompts";import{simpleGit as gl}from"simple-git";function si(t){OE(t),process.exit(1)}function kg(t,e,r){let n=t.spec.repos.filter(s=>!e||s.name===e);if(n.length===0)throw new Error(e?`repo "${e}" is not part of this project (see project.yaml)`:"the project has no repos configured");let o=[];for(let s of n){let i=s.mountAs==="."?t.root:gn(t.root,s.mountAs);if(!hl(gn(i,".git"))){r(`${s.name}: no local clone at ${i} \u2014 skipped (run \`codepipe clone\` first)`);continue}o.push({name:s.name,dir:i,defaultBranch:s.defaultBranch||"main"})}if(o.length===0)throw new Error("nothing to do \u2014 no repo clones found");return o}async function wg(t){let e=gl(t.dir),r=`origin/${t.defaultBranch}`;return await e.raw(["rev-parse","--verify",r]).then(()=>!0).catch(()=>!1)?r:"HEAD"}async function bg(t,e,r,n){let o=[];for(let s of e)try{let i=await Vc({repo:s.name,repoDir:s.dir,contextDir:t,settings:r,ref:await wg(s)});o.push(i),n(`${s.name}: ${i.counts.code} files, ${i.counts.component} components, ${i.counts.correlates} co-change edges @ ${i.headCommit.slice(0,10)}`)}catch(i){throw new Error(`${s.name}: ${i instanceof Error?i.message:String(i)}`)}return o}async function yl(t){yg("codepipe model build");let e=Te();e||si("not inside a project workspace \u2014 run from a folder with .codepipe/ (see `codepipe init`)");try{let r=pn(e.contextDir),n=kg(e,t.repo,i=>fl.warn(i)),o=await bg(e.contextDir,n,r,i=>fl.info(i)),s=await oi(e.contextDir,o,{halfLifeDays:r.cochange.halfLifeDays});s.committed?ml(`model updated: ${s.filesWritten} files written, ${s.filesDeleted} stale removed`):ml("model already up to date (no changes)")}catch(r){si(r instanceof Error?r.message:String(r))}}async function kl(t){yg("codepipe model bootstrap");let e=Te();e||si("not inside a project workspace \u2014 run from a folder with .codepipe/ (see `codepipe init`)");try{await $g(e,t.repo,{onLog:r=>fl.info(r)})}catch(r){si(r instanceof Error?r.message:String(r))}ml("bootstrap complete")}async function $g(t,e,r){let n=kg(t,e,r.onLog);return wl(t.contextDir,n,r)}async function wl(t,e,r){let n=pn(t),o=await bg(t,e,n,r.onLog),s=Wm(t),i=Hm(n.issueKeyPattern,s),a=Pr([...n.ignore,...dn]),c=[];for(let p of o){let d=e.find(f=>f.name===p.repo),m=await Ym({repo:p.repo,repoDir:d.dir,headCommit:p.headCommit,windowCommits:n.cochange.windowCommits,issueKeyRe:i,pathToCurrent:Bs(p.identityTable),entityByKey:p.entityByKey,ignored:a,trackerProjectKey:s});c.push(m),r.onLog(`${p.repo}: ${m.size} task events mined from history`)}let{files:l,skippedPipeline:u}=Vm(t,c);return u>0&&r.onLog(`${u} events already recorded by the live pipeline \u2014 left untouched`),l.length>0&&await Se(t,l,`model: bootstrap ${l.length} task events from history`),await oi(t,o,{halfLifeDays:n.cochange.halfLifeDays}),{events:l.length}}async function LE(t,e,r,n){if(r.length===0)throw new Error("the project has no repos configured");let o=[];for(let i of r){let a=i.mountAs??i.name,c=a==="."?e.root:gn(e.root,a),l=i.defaultBranch||"main";c!==e.contextDir&&hl(gn(c,".git"))?(await gl(c).fetch(["origin",l]).catch(()=>{}),o.push({name:i.name,dir:c,defaultBranch:l})):(n(`${i.name}: materializing clone in the daemon layout`),await Nt(t,i),o.push({name:i.name,dir:Ie(t,i.name),defaultBranch:l}))}let s=await wl(e.contextDir,o,{onLog:n});return{repos:o.length,events:s.events}}async function DE(t,e={}){let r=e.onLog??(()=>{}),n=pn(t.contextDir);if(!n.enabled)return{rebuilt:[],skipped:[]};let o=[],s=[],i=pl(t.contextDir),a=[];for(let c of t.repos){let l=c.mountAs==="."?t.root:gn(t.root,c.mountAs);if(!hl(gn(l,".git")))continue;let u=gl(l),p=c.defaultBranch||"main";e.fetch&&await u.fetch(["origin",p]).catch(()=>{});let d=await wg({name:c.name,dir:l,defaultBranch:p}),m=(await u.revparse([d]).catch(()=>"")).trim();if(m){if(i.get(c.name)?.builtFromCommit===m){s.push(c.name);continue}try{a.push(await Vc({repo:c.name,repoDir:l,contextDir:t.contextDir,settings:n,ref:m})),o.push(c.name)}catch(f){r(`[model] rebuild of ${c.name} failed: ${f instanceof Error?f.message:String(f)}`)}}}return a.length>0&&(await oi(t.contextDir,a,{halfLifeDays:n.cochange.halfLifeDays}),r(`[model] release-path rebuild: ${o.join(", ")} (skipped up-to-date: ${s.join(", ")||"\u2014"})`)),{rebuilt:o,skipped:s}}var Po=$(()=>{"use strict";tt();gg();zc();qc();Fs();Eo();Er();bt()});var xg={};Be(xg,{computeDriftReport:()=>KE,supersededAdrIds:()=>vg});import{existsSync as bl,readFileSync as $l,readdirSync as vl}from"node:fs";import{join as yn}from"node:path";import{parse as ME}from"yaml";import{simpleGit as UE}from"simple-git";function FE(t,e){let r=yn(t,`model/derived/structure/${e}`),n=[],o="";if(!bl(r))return{nodes:n,builtFromCommit:o};for(let s of vl(r).sort()){if(!s.endsWith(".yaml"))continue;let i;try{let a=Ct(ME($l(yn(r,s),"utf-8")));if(!a.ok)continue;i=a.value}catch{continue}o=i.builtFromCommit;for(let a of i.nodes){let c=re(a.key);!c||c.level!=="code"&&c.level!=="component"||n.push({key:a.key,path:c.path,level:c.level,contentHash:a.contentHash,entityId:a.entityId})}}return{nodes:n,builtFromCommit:o}}function vg(t){let e=new Set,r=yn(t,"adr");if(!bl(r))return e;for(let n of vl(r).sort()){let o=/^(\d{4})-/.exec(n)?.[1];if(!(!o||!n.endsWith(".md")))try{let s=$l(yn(r,n),"utf-8").slice(0,600).toLowerCase();/status[^\n]*superseded/.test(s)&&e.add(`ADR-${o}`)}catch{}}return e}async function KE(t,e,r){let{nodes:n,builtFromCommit:o}=FE(e,r),s=(await UE(t).revparse(["HEAD"])).trim(),i=await So(t,s),a=new Map(i.map(y=>[y.path,y.blobHash])),c=[],l=[],u=new Set,p=[];for(let y of n){if(y.level==="component"){p.push(y);continue}u.add(y.path);let x=a.get(y.path);x?y.contentHash&&x.slice(0,BE)!==y.contentHash&&c.push(y.key):l.push(y.key)}let d=0,m=new Map,f=new Set;for(let y of i){let x=y.path.lastIndexOf("/"),S=x<0?"":y.path.slice(0,x);m.has(S)||m.set(S,new Set),m.get(S).add(y.path),u.has(y.path)||d++;let T=S;for(;T!==""&&!f.has(T);)f.add(T),T=T.includes("/")?T.slice(0,T.lastIndexOf("/")):""}let g=new Map;for(let y of u){let x=y.lastIndexOf("/"),S=x<0?"":y.slice(0,x);g.has(S)||g.set(S,new Set),g.get(S).add(y)}for(let y of p){if(!f.has(y.path)){l.push(y.key);continue}let x=g.get(y.path)??new Set,S=m.get(y.path)??new Set;(x.size!==S.size||[...x].some(R=>!S.has(R)))&&c.push(y.key)}let h=[],w=vg(e);if(w.size>0){let y=yn(e,"model/facts/annotations"),x=new Map(n.filter(S=>S.entityId).map(S=>[S.entityId,S.key]));if(bl(y))for(let S of vl(y).sort()){if(!S.endsWith(".md"))continue;let T=S.replace(/\.md$/,""),R=x.get(T);if(R)try{($l(yn(y,S),"utf-8").match(/\bADR-(\d{3,4})\b/g)??[]).map(D=>`ADR-${D.slice(4).padStart(4,"0")}`).some(D=>w.has(D))&&h.push(R)}catch{}}}return{repo:r,builtFromCommit:o,headCommit:s,stale:[...new Set(c)].sort(),orphaned:[...new Set(l)].sort(),superseded:[...new Set(h)].sort(),newFiles:d}}var BE,Sg=$(()=>{"use strict";F();Eo();BE=12});import{existsSync as Rg,rmSync as GE}from"node:fs";import{join as _r}from"node:path";import{simpleGit as HE}from"simple-git";import"ws";function ai(t,e={}){let r=e.log??{info:h=>console.log(h),warn:h=>console.warn(h)};r.info(`codepipe-cli v${Fe} (protocol ${at})`);let n=h=>e.onEvent?.(h),o=e.workspace;o?.contextDir&&Mf(o.contextDir,r);let s=Eg("CLI_TRACKING_POLL_INTERVAL_SEC"),i=Eg("CLI_YOUTRACK_POLL_INTERVAL_SEC"),a=(()=>{let h=parseInt(process.env.CLI_READINESS_INTERVAL_SEC??"600",10);return Number.isFinite(h)&&h>0?h*1e3:6e5})(),c=!1,l=!1,u=!1,p=new Set,d=!1,m=new Set,f=g();function g(){let h=ks(t.hubUrl,t.cliToken),w=null,y=new ri(s,_=>{h.readyState===h.OPEN&&h.send(JSON.stringify(_))},r),x=new ni(i,_=>{h.readyState===h.OPEN&&h.send(JSON.stringify(_))},r,{contextDir:o?.contextDir??null,isSelfComment:_=>m.has(_)}),S=null,T=async()=>{try{let _={trackerProvider:il(o?.contextDir??null)};try{let L=await oe(t.hubUrl,t.cliToken,t.projectId);_={..._,repos:L.repos,contextRepo:L.contextRepo}}catch(L){r.warn(`[readiness] could not fetch project summary for push checks: ${L instanceof Error?L.message:String(L)}`)}let B=await Gp(t.projectId,_);if(h.readyState!==h.OPEN)return;let O={type:"cli_readiness",projectId:t.projectId,ready:B.ready,checks:B.checks,creds:B.creds,secretNames:ep(t.projectId),checkedAt:B.checkedAt};if(h.send(JSON.stringify(O)),B.ready)r.info("[readiness] ready");else{let L=B.checks.filter(E=>!E.ok).map(E=>`${E.name}(${E.detail??""})`);r.warn(`[readiness] NOT ready \u2014 ${L.join(", ")}`)}let X=Xp(B.creds,u);if(X==="open"){u=!0;let L=Jp(t.hubUrl,t.projectId);r.info(`[agent-auth] Claude token invalid (401) \u2014 opening the dashboard to re-authorize: ${L}`),$r(L)}else X==="rearm"&&(u=!1)}catch(_){r.warn(`[readiness] check failed: ${_ instanceof Error?_.message:String(_)}`)}},R=()=>{T(),S=setInterval(()=>void T(),a),typeof S.unref=="function"&&S.unref()},b=()=>{S&&(clearInterval(S),S=null)},I=150,D=new Map,K=_=>{let B=D.get(_);if(!B||(B.timer&&clearTimeout(B.timer),D.delete(_),B.events.length===0||h.readyState!==h.OPEN))return;let O={type:"run_activity",projectId:t.projectId,runId:_,events:B.events};h.send(JSON.stringify(O))},ee=(_,B)=>{let O=D.get(_);if(O||(O={events:[],timer:null},D.set(_,O)),O.events.push(B),B.kind==="result"){K(_);return}O.timer||(O.timer=setTimeout(()=>K(_),I),O.timer.unref?.())},C=o?.contextDir?new Ts(o.contextDir,t.projectId,_=>{h.readyState===h.OPEN&&h.send(JSON.stringify(_))},r):null,k=async()=>{let _=o?.contextDir;if(!_)throw new Error("no context repo clone on this CLI");let B;try{B=(await oe(t.hubUrl,t.cliToken,t.projectId)).contextRepo}catch{}let O=await cm(_,t.projectId,B,r);return h.readyState===h.OPEN&&h.send(JSON.stringify(O)),O},U=null,P=async()=>{let _=o?.contextDir;if(_)try{let{readContextIndexHub:B,collectSearchRows:O}=await Promise.resolve().then(()=>(To(),Ro));if(B(_)!=="metadata")return;let X=O(_);h.readyState===h.OPEN&&(h.send(JSON.stringify({type:"model_index",projectId:t.projectId,rows:X})),r.info(`[model] tier-2 index snapshot pushed (${X.length} rows)`))}catch(B){r.warn(`[model] tier-2 index push failed (non-fatal): ${B instanceof Error?B.message:String(B)}`)}},G=()=>{U&&clearTimeout(U),U=setTimeout(()=>void P(),5e3)},Y=null,se=async _=>{if(o?.contextDir)try{let{rebuildWorkspaceModelIfStale:B}=await Promise.resolve().then(()=>(Po(),ii));(await B({root:o.root,contextDir:o.contextDir,repos:o.repos},{fetch:_,onLog:X=>r.info(X)})).rebuilt.length>0&&G()}catch(B){r.warn(`[model] release-path rebuild failed (non-fatal): ${B instanceof Error?B.message:String(B)}`)}},qe=_=>{Y&&clearTimeout(Y),Y=setTimeout(()=>void se(_),6e4)},Ye=setInterval(()=>void se(!0),6*36e5);return h.on("open",()=>{r.info("[ws] connected"),n({kind:"connected"});let _=cp(t.projectId),B=J("ORIGIN")==="farm"?"farm":"local",O=J("FARM_ID"),X=t.accountEmail??_.email,L;try{let v=bm(t.projectId);v&&(L=v.publicKey,r.info(`[cred-channel] key fingerprint: ${v.fingerprint}`))}catch(v){r.warn(`[cred-channel] key setup failed (token replacement via dashboard unavailable): ${v instanceof Error?v.message:String(v)}`)}let E={type:"register",projectId:t.projectId,platformVersion:Fe,protocolVersion:at,accountId:_.accountId,accountLabel:_.label,origin:B,inFlightActionIds:[...p],...X?{accountEmail:X}:{},...B==="farm"&&O?{farmId:O}:{},...L?{sealPublicKey:L}:{}};h.send(JSON.stringify(E))}),h.on("message",async _=>{let B=_.toString("utf-8");if(B==="pong"||B==="ping")return;let O;try{O=JSON.parse(B)}catch{return}if(!O||typeof O!="object")return;let X=O.type;if(X==="registered"){let E=O;if(E.ok){if(r.info(`[ws] registered for project ${E.projectId}`),n({kind:"registered",projectId:E.projectId??t.projectId}),y.start(),C?.start(),R(),Sl(t,o,r),o?.contextDir){try{let v=_s(o.contextDir,t.projectId);h.readyState===h.OPEN&&h.send(JSON.stringify(v)),v.outdated&&(r.warn(`[ctx] context format outdated: v${v.templateVersion} \u2192 v${v.currentVersion}`+(v.missingPaths.length>0?` (missing: ${v.missingPaths.join(", ")})`:"")),l||(l=!0,k().catch(()=>{})))}catch(v){r.warn(`[ctx] context-format detect failed (non-fatal): ${v instanceof Error?v.message:String(v)}`)}P(),qe(!0)}}else r.warn(`[ws] register rejected: ${E.reason??"unknown"}`),n({kind:"register_rejected",reason:E.reason??"unknown"}),c=!0,h.close();return}if(X==="hello"){let E=O;w=Vn(E.protocolVersion);let v=w?"compatible":"INCOMPATIBLE";r.info(`[ws] hub v${E.platformVersion} (protocol ${E.protocolVersion}) \u2014 ${v}`),w||(r.warn(`[ws] HUB protocol incompatible with this CLI (v${Fe}, protocol ${at}) \u2014 WriteActions will be refused until versions align.`),r.warn(`[ws] update the CLI: ${xl}`),n({kind:"incompatible",hubVersion:typeof E.platformVersion=="string"?E.platformVersion:null,hubProtocol:typeof E.protocolVersion=="number"?E.protocolVersion:null,updateCommand:xl}));return}if(X==="tracking_targets"){y.setTargets(O.targets);return}if(X==="youtrack_sync_request"){x.setRequest(O);return}if(X==="youtrack_force_sync"){x.forceSync();return}if(X==="sync_local"){await YE(O,o,h,r);return}if(X==="provision_repo"){let E=O;r.info(`[repo] provision_repo: ${E.repo.name} (${E.repo.host}:${E.repo.owner}/${E.repo.repoName})`),await WE(t,o,E.repo,r),await Sl(t,o,r);return}if(X==="remove_repo"){let E=O;r.info(`[repo] remove_repo: ${E.repoName}${E.purge?" (purge)":""}`),await Sl(t,o,r),E.purge&&qE(t,o,E.repoName,r);return}if(X==="context_write"){await VE(O,o,h,r);return}if(X==="adr_promote"){await zE(O,o,h,r);return}if(X==="cred_update"){let E=O,v=q(t.projectId),N=v?.sealKey?await $m(t.projectId,E.kind,E.sealed,v.sealKey.privateKey):{ok:!1,detail:"no cred-channel key on this CLI (restart the daemon)"},z={type:"cred_update_result",updateId:E.updateId,projectId:t.projectId,ok:N.ok,...N.detail?{detail:N.detail}:{}};h.readyState===h.OPEN&&h.send(JSON.stringify(z)),N.ok?(r.info(`[cred] ${E.kind} replaced${N.detail?` \u2014 ${N.detail}`:""}`),T()):r.warn(`[cred] ${E.kind} replacement rejected: ${N.detail??"unknown"}`);return}if(X==="readiness_check"){r.info("[readiness] on-demand check requested"),T();return}if(X==="agent_login_start"){Vp(t,h,O,r,T);return}if(X==="move_to_farm"){let E=O;r.info(`[farm-move] request to move ${t.projectId} onto farm ${E.farmName} (${E.farmId})`);let v=await qh(t,E,o?.contextDir,r);h.readyState===h.OPEN&&h.send(JSON.stringify(v)),v.ok?r.info(`[farm-move] done \u2014 farm daemon ${v.daemonStatus??"started"}; expecting takeover`):r.warn(`[farm-move] failed: ${v.error??"unknown error"}`);return}if(X==="gh_runner_setup"){let E=O;r.info(`[ghr] runner setup for ${t.projectId} on runner host ${E.runnerName} (${E.runnerId})`);let v=await tg(t,E,r);h.readyState===h.OPEN&&h.send(JSON.stringify(v)),v.ok?r.info(`[ghr] runners connected on ${E.runnerName}`):r.warn(`[ghr] setup failed: ${v.error??"see per-repo statuses"}`);return}if(X==="gh_runner_teardown"){let E=O;r.info(`[ghr] runner teardown for ${t.projectId} on runner host ${E.runnerName} (${E.runnerId})`);let v=await rg(t,E,r);h.readyState===h.OPEN&&h.send(JSON.stringify(v)),v.ok?r.info(`[ghr] runners disconnected from ${E.runnerName}`):r.warn(`[ghr] teardown failed: ${v.error??"unknown error"}`);return}if(X==="tracker_fields_request"){let E=O,v={type:"tracker_fields_result",requestId:E.requestId,projectId:t.projectId,ok:!1},N=St({contextDir:o?.contextDir??null});if(!N.ok)v.error=N.error;else try{v.fields=await N.provider.fetchStateFields(E.projectKey),v.ok=!0}catch(z){v.error=z instanceof Error?z.message:String(z)}h.readyState===h.OPEN&&h.send(JSON.stringify(v)),v.ok||r.warn(`[yt-fields] listing failed: ${v.error??"unknown"}`);return}if(X==="project_secret_update"||X==="project_secret_delete"){let E=O,v;if(E.type==="project_secret_update"){let z=q(t.projectId);v=z?.sealKey?sg(t.projectId,E.name,E.sealed,z.sealKey.privateKey):{ok:!1,detail:"no cred-channel key on this CLI (restart the daemon)"}}else v=ig(t.projectId,E.name);let N={type:"project_secret_update_result",updateId:E.updateId,projectId:t.projectId,ok:v.ok,...v.detail?{detail:v.detail}:{}};h.readyState===h.OPEN&&h.send(JSON.stringify(N)),v.ok?(r.info(`[secret] ${E.name} ${E.type==="project_secret_update"?"saved":"deleted"}`+(v.detail?` \u2014 ${v.detail}`:"")),T()):r.warn(`[secret] ${E.name} rejected: ${v.detail??"unknown"}`);return}if(X==="auto_apply_local"){let E=O;if(!o?.contextDir){r.warn(`[apply] auto_apply_local for ${E.claim.taskKey} \u2014 no workspace (headless), skipped; task stays in READY_TO_APPLY`);return}let v=await Tf({hubUrl:t.hubUrl,cliToken:t.cliToken,projectId:t.projectId,root:o.root,contextDir:o.contextDir,repos:o.repos},E.claim,r).catch(N=>({ok:!1,message:N instanceof Error?N.message:String(N)}));v.ok?r.info(`[apply] ${E.claim.taskKey}: ${v.message}`):r.warn(`[apply] ${E.claim.taskKey}: ${v.message} \u2014 task stays in READY_TO_APPLY`),n({kind:"local_applied",taskKey:E.claim.taskKey,ok:v.ok,...v.ok?{branches:v.branches??[]}:{error:v.message}});return}if(X==="sandbox_keys"){let E=q(t.projectId);if(!E){r.warn(`[cred] sandbox_keys received but no secrets for ${t.projectId} \u2014 cannot seal`);return}let v=Zr(t.projectId),N=hm(O,E,v,r);for(let z of N)h.readyState===h.OPEN&&h.send(JSON.stringify(z));return}if(X!=="dispatch_action")return;let L=O;if(w===!1){let E=`refused: HUB protocol incompatible with CLI v${Fe} (protocol ${at})`;h.send(JSON.stringify({type:"action_result",actionId:L.actionId,status:"failed",error:E})),r.warn(`[exec] ${L.actionId} (${L.action.type}) \u2192 REFUSED: ${E}`),r.warn(`[exec] update the CLI to clear this: ${xl}`),n({kind:"action",actionId:L.actionId,actionType:L.action.type,ok:!1,error:E});return}if(L.action.type==="model_drift"){p.add(L.actionId);try{let E,v=o?.repos.find(N=>N.name===L.action.repoName);if(!o?.contextDir||!v)E={status:"failed",error:"no local workspace/repo clone on this CLI"};else try{let{computeDriftReport:N}=await Promise.resolve().then(()=>(Sg(),xg)),z=v.mountAs==="."?o.root:_r(o.root,v.mountAs);E={status:"done",result:{report:await N(z,o.contextDir,v.name)}}}catch(N){E={status:"failed",error:N instanceof Error?N.message:String(N)}}h.send(JSON.stringify({type:"action_result",actionId:L.actionId,...E}))}finally{p.delete(L.actionId)}return}if(L.action.type==="model_bootstrap"){p.add(L.actionId);try{let E;if(!o?.contextDir)E={status:"failed",error:"no Context Repo clone on this CLI"};else if(d)E={status:"failed",error:"model bootstrap is already running"};else{d=!0;try{let v=await oe(t.hubUrl,t.cliToken,t.projectId),{bootstrapDaemonModel:N}=await Promise.resolve().then(()=>(Po(),ii)),z=await N(t.projectId,{root:o.root,contextDir:o.contextDir},v.repos,ve=>r.info(`[model] ${ve}`));r.info(`[model] bootstrap done: ${z.repos} repos, ${z.events} task events`),G(),E={status:"done",result:{repos:z.repos,events:z.events}}}catch(v){E={status:"failed",error:v instanceof Error?v.message:String(v)},r.warn(`[model] bootstrap failed: ${E.error}`)}finally{d=!1}}h.readyState===h.OPEN&&h.send(JSON.stringify({type:"action_result",actionId:L.actionId,...E}))}finally{p.delete(L.actionId)}return}if(L.action.type==="local_apply"){p.add(L.actionId);try{let E;if(!o)E={status:"failed",error:"no local workspace on this CLI"};else{let N=await Bh(o,L.action.repos,r);if(E=N.ok?{status:"done",result:{repos:N.repos}}:{status:"failed",error:N.error},N.ok&&o.contextDir){let z=L.action.taskId.split(":")[1]??"";for(let ve of z?N.repos:[]){let ot=o.repos.find(ne=>ne.name===ve.repoName);if(!ot)continue;let{recordPipelineEvent:W}=await Promise.resolve().then(()=>(rl(),Ah));await W({contextDir:o.contextDir,repoDir:_r(o.root,ot.mountAs),repoName:ve.repoName,taskKey:z,commitSha:ve.commit}).catch(ne=>r.warn(`[model] task event for ${z} failed: ${ne instanceof Error?ne.message:String(ne)}`))}G()}}h.send(JSON.stringify({type:"action_result",actionId:L.actionId,...E}));let v=E.status!=="failed";v?r.info(`[exec] ${L.actionId} (local_apply) \u2192 done`):r.warn(`[exec] ${L.actionId} (local_apply) \u2192 FAILED: ${E.status==="failed"?E.error:"?"}`),n({kind:"action",actionId:L.actionId,actionType:"local_apply",ok:v,...E.status==="failed"?{error:E.error}:{}})}finally{p.delete(L.actionId)}return}p.add(L.actionId);try{let E=await Dh({action:L.action,repo:L.repo,trackerIssueId:L.trackerIssueId,contextDir:o?.contextDir,requestConfigReport:C?()=>C.reportNow():void 0,refreshContextStatus:o?.contextDir?k:void 0,onRunActivity:ee}).catch(z=>({status:"failed",error:z instanceof Error?z.message:String(z)}));L.action.type==="tracker_comment"&&E.status==="done"&&"result"in E&&typeof E.result?.commentId=="string"&&m.add(E.result.commentId),h.send(JSON.stringify({type:"action_result",actionId:L.actionId,...E}));let v=E.status!=="failed",N=!v&&"error"in E?E.error:void 0;v?r.info(`[exec] ${L.actionId} (${L.action.type}) \u2192 done`):r.warn(`[exec] ${L.actionId} (${L.action.type}) \u2192 FAILED: ${N??"?"}`),n({kind:"action",actionId:L.actionId,actionType:L.action.type,ok:v,...N?{error:N}:{}}),v&&["apply_delivery","context_write","create_pr"].includes(L.action.type)&&G(),v&&["merge_pr","merge_branch"].includes(L.action.type)&&qe(!0)}finally{p.delete(L.actionId)}}),h.on("close",(_,B)=>{let O=B?.toString("utf-8")??"";if(r.info(`[ws] closed code=${_}${O?` reason=${O}`:""}`),y.stop(),x.stop(),C?.stop(),b(),clearInterval(Ye),Y&&clearTimeout(Y),U&&clearTimeout(U),O==="replaced"){c=!0,r.warn(`[ws] project ${t.projectId} was taken over by another CLI (HUB closed us as "replaced") \u2014 standing down, not reconnecting. Run exactly ONE CLI per project.`),n({kind:"replaced"});return}n({kind:"disconnected",code:_}),!c&&setTimeout(()=>{f=g()},2e3)}),h.on("error",_=>r.warn(`[ws] error: ${_.message}`)),h}return{stop(){c=!0,f.close()}}}async function Sl(t,e,r){try{let n=await oe(t.hubUrl,t.cliToken,t.projectId),{updated:o,errors:s}=bo(t.projectId,n.repos,e?.contextDir);for(let i of o)r.info(`[repo] restaged repo set in ${i}`);for(let i of s)r.warn(`[repo] could not restage ${i.path}: ${i.error}`)}catch(n){r.warn(`[repo] repo-set reconcile skipped: ${n instanceof Error?n.message:String(n)}`)}}async function WE(t,e,r,n){let o=r.mountAs??r.name;if(o==="."){n.info(`[repo] ${r.name} mounts in place (mount_as: .) \u2014 nothing to clone`);return}let s=e?_r(e.root,o):Ie(t.projectId,r.name);if(Rg(_r(s,".git"))){n.info(`[repo] ${r.name} already present at ${s}`);return}try{await HE().clone(mo(r),s),n.info(`[repo] cloned ${r.name} \u2192 ${s}`)}catch(i){n.warn(`[repo] clone of ${r.name} failed (will retry lazily): ${i instanceof Error?i.message.trim():String(i)}`)}}function qE(t,e,r,n){let o=e?.repos.find(i=>i.name===r)?.mountAs??r,s=e?_r(e.root,o):Ie(t.projectId,r);if(e&&s===e.root){n.warn(`[repo] ${r} maps to the workspace root \u2014 skipping purge`);return}if(!Rg(_r(s,".git"))){n.info(`[repo] no local clone to purge for ${r} (${s})`);return}try{GE(s,{recursive:!0,force:!0}),n.info(`[repo] purged local clone ${s}`)}catch(i){n.warn(`[repo] purge of ${s} failed: ${i instanceof Error?i.message:String(i)}`)}}async function YE(t,e,r,n){if(!e){n.info(`[sync] sync_local for ${t.taskId} \u2014 no workspace (headless), skipped`);return}for(let o of t.repos){let s=e.repos.find(l=>l.name===o.repoName),i=_r(e.root,s?.mountAs??o.repoName),a=s?.defaultBranch??o.defaultBranch,c=await Cf(i,a).catch(l=>({status:"warn",reason:l instanceof Error?l.message:String(l)}));c.status==="updated"?n.info(`[sync] ${o.repoName}: fast-forwarded ${a} \u2192 origin`):c.status==="skipped"?n.info(`[sync] ${o.repoName}: not cloned in workspace \u2014 skipped`):(n.warn(`[sync] ${o.repoName}: ${c.reason??"sync skipped"}`),r.readyState===r.OPEN&&r.send(JSON.stringify({type:"local_sync_warning",taskId:t.taskId,repoName:o.repoName,reason:c.reason??"sync skipped"})))}}async function VE(t,e,r,n){let o=(s,i)=>{if(r.readyState!==r.OPEN)return;let a={type:"context_write_result",id:t.id,status:s};i&&(a.error=i),r.send(JSON.stringify(a))};if(!e?.contextDir){n.warn(`[ctx] context_write ${t.id} \u2014 no .codepipe clone (headless), reporting failed`),o("failed","no context repo clone on this CLI");return}try{await Se(e.contextDir,t.files,t.message),n.info(`[ctx] context_write ${t.id}: committed ${t.files.length} file(s)`),o("done")}catch(s){let i=s instanceof Error?s.message:String(s);n.warn(`[ctx] context_write ${t.id} failed: ${i}`),o("failed",i)}}async function zE(t,e,r,n){let o=(s,i)=>{if(r.readyState!==r.OPEN)return;let a={type:"context_write_result",id:t.id,status:s};i&&(a.error=i),r.send(JSON.stringify(a))};if(!e?.contextDir){n.warn(`[adr] adr_promote ${t.id} \u2014 no .codepipe clone (headless), reporting failed`),o("failed","no context repo clone on this CLI");return}try{let s=t.source??"task",i=await Wf(e.contextDir,t.taskKey,t.slugs,void 0,s);if(n.info(`[adr] adr_promote ${t.id}: promoted ${i.promoted.length}, skipped ${i.skipped.length}`+(i.promoted.length>0?` (${i.promoted.join(", ")})`:"")),i.missing.length>0){let a=l=>s==="staging"?`adr/DRAFT-${l}.md`:`tasks/${t.taskKey}/adr/DRAFT-${l}.md`,c=`draft file(s) missing in clone: ${i.missing.map(a).join(", ")}`;n.warn(`[adr] adr_promote ${t.id}: ${c}`),o("failed",c);return}o("done")}catch(s){let i=s instanceof Error?s.message:String(s);n.warn(`[adr] adr_promote ${t.id} failed: ${i}`),o("failed",i)}}function Eg(t){let e=parseInt(process.env[t]??"60",10);return Number.isFinite(e)&&e>0?e*1e3:6e4}var xl,El=$(()=>{"use strict";Le();F();lp();zp();Zp();ys();gc();Af();Lf();qf();tt();Ot();Ic();lm();jc();Er();gm();vm();Mh();Fh();Yh();ng();Ae();ag();rn();pe();cg();pg();Zs();xl="npm i -g @code-partner/codepipe@latest"});import{execFileSync as XE}from"node:child_process";import{mkdtempSync as JE,mkdirSync as ZE,readFileSync as Tg,rmSync as QE,writeFileSync as eR}from"node:fs";import{tmpdir as tR}from"node:os";import{dirname as rR,join as Ig}from"node:path";function Cg(t="codepipe-context"){let e=JE(Ig(tR(),"codepipe-ssh-")),r=Ig(e,"id_ed25519");try{return XE("ssh-keygen",["-t","ed25519","-N","","-C",t,"-f",r,"-q"],{stdio:"ignore"}),{privateKey:Tg(r,"utf-8"),publicKey:Tg(`${r}.pub`,"utf-8").trim()}}finally{QE(e,{recursive:!0,force:!0})}}async function Ag(t,e,r,n="codepipe-context"){let o=await fetch(`https://api.github.com/repos/${t.owner}/${t.name}/keys`,{method:"POST",headers:{Authorization:`Bearer ${e}`,Accept:"application/vnd.github+json","Content-Type":"application/json"},body:JSON.stringify({title:n,key:r,read_only:!1})});if(o.ok)return;let s=await o.text();if(!(o.status===422&&/already in use/i.test(s)))throw new Error(`add deploy key failed: ${o.status} ${s}`)}function Pg(t){if(/^git@[^:]+:.+/.test(t))return t;let e=t.match(/^ssh:\/\/git@([^/]+)\/(.+)$/);if(e)return`git@${e[1]}:${e[2]}`;let r=t.match(/^https:\/\/(?:[^@/]+@)?([^/]+)\/(.+)$/);return r?`git@${r[1]}:${r[2]}`:t}function _g(t,e){ZE(rR(t),{recursive:!0});let r=e.endsWith(`
|
|
743
743
|
`)?e:e+`
|
|
744
744
|
`;return eR(t,r,{mode:384}),`ssh -i "${t}" -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new`}var Rl=$(()=>{"use strict"});import{existsSync as jg,mkdirSync as Ng}from"node:fs";import{dirname as Og}from"node:path";import{simpleGit as kn}from"simple-git";function nR(t,e,r="x-access-token"){let n=`${encodeURIComponent(r)}:${encodeURIComponent(e)}`,o=t.match(/^git@([^:]+):(.+)$/);if(o)return`https://${n}@${o[1]}/${o[2]}`;let s=t.match(/^ssh:\/\/git@([^/]+)\/(.+)$/);if(s)return`https://${n}@${s[1]}/${s[2]}`;let i=t.match(/^https:\/\/(?:[^@/]+@)?(.+)$/);return i?`https://${n}@${i[1]}`:t}function oR(t,e){return e?.contextWrite?.token?{user:io(t),secret:e.contextWrite.token}:t===Xr.gitlab?e?.gitlab?.token?{user:"oauth2",secret:e.gitlab.token}:null:t===Xr.bitbucket?e?.bitbucket?.apiToken?{user:Kt,secret:e.bitbucket.apiToken}:null:e?.github?.token?{user:"x-access-token",secret:e.github.token}:null}async function Lg(t,e){let r=e.sleep??(s=>new Promise(i=>setTimeout(i,s))),n=e.initialDelayMs??5e3,o=e.maxDelayMs??6e4;for(;;)try{return await t()}catch(s){if(!(s instanceof ci))throw s;e.log.warn(`[ctx] ${s.message} \u2014 retrying in ${Math.round(n/1e3)}s (the HUB may be deploying)`),await r(n),n=Math.min(n*2,o)}}async function li(t){let{cfg:e,secrets:r,contextDir:n,log:o}=t,s;try{s=await oe(e.hubUrl,e.cliToken,e.projectId)}catch(c){throw new ci(c)}let i=s.contextRepo;if(!i)return o.warn("[ctx] project has no Context Repo on HUB \u2014 daemon stays headless (no config report)"),null;let a=oR(kr(i.cloneUrl),r);if(a){let c=await sR({ctx:i,contextDir:n,cred:a,log:o});if(c)return c;o.warn("[ctx] token clone/update failed")}if(r?.contextSsh?.privateKey){let c=await iR({ctx:i,contextDir:n,privateKey:r.contextSsh.privateKey,log:o});if(c)return c;o.warn("[ctx] SSH deploy-key clone failed")}return o.warn("[ctx] no usable context-host/contextWrite token or SSH deploy key \u2014 can't clone the Context Repo on the farm; config_observation + artifact commits disabled."),null}async function sR(t){let{ctx:e,contextDir:r,cred:n,log:o}=t,s=nR(e.cloneUrl,n.secret,n.user),i=e.branch,a=encodeURIComponent(n.secret),c=l=>l.split(n.secret).join("***").split(a).join("***");try{if(jg(`${r}/.git`)){let l=kn(r);await l.remote(["set-url","origin",s]),await l.fetch("origin",i),await l.checkout(i);let u=$c(r);await l.reset(["--hard",`origin/${i}`]),vc(r,u),o.info(`[ctx] updated Context Repo clone \u2192 ${r}@${i}`)}else Ng(Og(r),{recursive:!0}),await kn().clone(s,r,["--branch",i]),o.info(`[ctx] cloned Context Repo ${e.owner}/${e.name}@${i} \u2192 ${r}`);await Dg(r)}catch(l){return o.warn(`[ctx] Context Repo clone/update failed: ${c(l instanceof Error?l.message:String(l))}`),null}return{root:r,contextDir:r,repos:[]}}async function iR(t){let{ctx:e,contextDir:r,privateKey:n,log:o}=t,s=`${r}.deploy-key`,i=_g(s,n),a=Pg(e.cloneUrl),c=e.branch;try{if(jg(`${r}/.git`)){let l=kn(r);await l.addConfig("core.sshCommand",i,!1,"local"),await l.remote(["set-url","origin",a]),await l.fetch("origin",c),await l.checkout(c);let u=$c(r);await l.reset(["--hard",`origin/${c}`]),vc(r,u),o.info(`[ctx] updated Context Repo clone (ssh) \u2192 ${r}@${c}`)}else Ng(Og(r),{recursive:!0}),await kn().env({...process.env,GIT_SSH_COMMAND:i}).clone(a,r,["--branch",c]),await kn(r).addConfig("core.sshCommand",i,!1,"local"),o.info(`[ctx] cloned Context Repo (ssh) ${e.owner}/${e.name}@${c} \u2192 ${r}`);return await Dg(r),{root:r,contextDir:r,repos:[]}}catch(l){return o.warn(`[ctx] Context Repo ssh clone/update failed: ${l instanceof Error?l.message:String(l)}`),null}}async function Dg(t){let e=kn(t);await e.raw(["config","user.email"]).then(n=>n.trim()).catch(()=>"")||(await e.addConfig("user.email","farm@codepipe.local",!1,"local"),await e.addConfig("user.name","CodePipe Farm CLI",!1,"local"))}var ci,Tl=$(()=>{"use strict";F();Ae();Ot();Rl();ci=class extends Error{constructor(e){super(`could not fetch project summary: ${e instanceof Error?e.message:String(e)}`),this.name="HubSummaryUnreachableError"}}});import{spawnSync as aR}from"node:child_process";function cR(){try{return aR("podman",["--version"],{stdio:"ignore",timeout:5e3}).status===0}catch{return!1}}function Ug(t={}){let e=process.platform==="darwin"?"darwin":process.platform==="win32"?"windows":"linux",r=process.arch==="arm64"?"arm64":"x64";return{os:e,arch:r,containers:cR(),node:process.versions.node,browser:!1,projects:t.projects??[],llm:t.llm??null}}var Bg=$(()=>{"use strict"});import{homedir as lR}from"node:os";import{mkdirSync as uR,readFileSync as dR,writeFileSync as pR,existsSync as Fg}from"node:fs";import{dirname as fR,join as Cl}from"node:path";function mR(){let t=process.env.SANDBOX_PLANNING_LANE;return t===void 0?!0:!/^(0|false|no|off)$/i.test(t.trim())}function ht(t){let e=J("SANDBOX_CONFIG");if(e)return e;let r=Cl(lR(),".codepipe","worker");return t?Cl(r,"profiles",t,"config.json"):Cl(r,"config.json")}function Kg(t,e,r){return t?`sandbox-${t}`:r?`sandbox-${e}`:"sandbox"}function je(t){let e=ht(t),r=null;return Fg(e)&&(r=JSON.parse(dR(e,"utf-8"))),r?(r.planningLane=mR(),r):null}function Gg(t,e){let r=ht(e);uR(fR(r),{recursive:!0}),pR(r,JSON.stringify(t,null,2)+`
|
|
745
745
|
`,{mode:384})}var ui=$(()=>{"use strict";Le();Fg(".env")&&process.loadEnvFile(".env")});import hR from"ws";var wn,Al=$(()=>{"use strict";wn=class{hubUrl;token;constructor(e,r){this.hubUrl=e,this.token=r}async register(e){let r=await fetch(`${this.hubUrl}/sandbox/register`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok)throw new Error(`register failed: ${r.status} ${await r.text()}`);return await r.json()}async claim(e,r){if(!this.token)throw new Error("no sandbox token");let n={method:"POST",headers:{Authorization:`Bearer ${this.token}`}};e&&(n.signal=e);let o=r?`${this.hubUrl}/jobs/claim?lane=${encodeURIComponent(r)}`:`${this.hubUrl}/jobs/claim`;return fetch(o,n)}async submitResult(e){if(!this.token)throw new Error("no sandbox token");let r=await fetch(`${this.hubUrl}/jobs/result`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify(e)});if(!r.ok)throw new Error(`submitResult failed: ${r.status} ${await r.text()}`)}async heartbeat(e,r){if(!this.token)throw new Error("no sandbox token");let n={method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify({jobId:e})};r&&(n.signal=r);let o=await fetch(`${this.hubUrl}/jobs/heartbeat`,n);if(o.status===410)return"claim_lost";if(!o.ok)throw new Error(`heartbeat failed: ${o.status} ${await o.text()}`);return"ok"}async releaseJob(e,r,n){if(!this.token)throw new Error("no sandbox token");let o={method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify({jobId:e,reason:r})};n&&(o.signal=n);let s=await fetch(`${this.hubUrl}/jobs/release`,o);if(!s.ok&&s.status!==409&&s.status!==404)throw new Error(`release failed: ${s.status} ${await s.text()}`)}openControlSocket(){if(!this.token)throw new Error("no sandbox token");let e=this.hubUrl.replace(/^http/,"ws")+`/sandbox/connect?token=${encodeURIComponent(this.token)}`;return new hR(e)}}});import{hostname as gR}from"node:os";async function jr(t){let e=je(t.profile);e&&!t.force&&(console.error(`sandbox already registered as ${e.sandboxId} (${e.name}) at ${e.hubUrl}.`),console.error(`pass --force to overwrite ${ht(t.profile)}.`),process.exit(1));let r=t.name??gR(),n=Ug({projects:t.projects??[],llm:t.llm??null}),o=new wn(t.hub.replace(/\/$/,"")),s=Os(),i=De(s.publicKey),{sandboxId:a,token:c}=await o.register({name:r,registrationToken:t.token,capabilities:n,publicKey:s.publicKey});Gg({hubUrl:t.hub.replace(/\/$/,""),sandboxId:a,token:c,name:r,llm:t.llm??null,sealPublicKey:s.publicKey,sealPrivateKey:s.privateKey},t.profile),console.log(`registered as ${a} (${r}) at ${t.hub}`),console.log(`config saved to ${ht(t.profile)}`),console.log(""),console.log(" cred-channel key fingerprint (confirm this on the CLI \u2014 pin-on-register):"),console.log(` ${i}`),console.log("")}var Hg=$(()=>{"use strict";rt();Bg();ui();Al()});function Wg(t){return t?`Write ALL user-visible text \u2014 full replies and the brief status notes you emit between tool calls alike \u2014 in ${t}, regardless of the language the user writes in (the project pinned ${t} for the chat).`:"Write ALL user-visible text \u2014 full replies and the brief status notes you emit between tool calls alike \u2014 in the language of the user's most recent chat message. When the user switches language mid-conversation, switch with them. Judge the language by the human prose only: ignore code snippets, file paths and identifiers. If a message is too short to tell (a bare keyword, pure code), keep the language of the conversation so far."}function di(t){return t?`Write ALL user-facing prose \u2014 brief status notes between tool calls, questions, summaries and the bodies of Markdown artifacts you produce for humans \u2014 in ${t} (the project's configured language), unless your prompt pins a different language for a specific output. In-repo content (code, code comments, commit messages) follows the project's existing conventions and any explicit instructions in your prompt.`:"Write ALL user-facing prose \u2014 brief status notes between tool calls, questions, summaries and the bodies of Markdown artifacts you produce for humans \u2014 in the language of the task description and user input embedded in your prompt, NOT the language the surrounding instructions are written in. Judge that language by the human prose only, ignoring code snippets, file paths and identifiers. In-repo content (code, code comments, commit messages) follows the project's existing conventions instead."}function qg(t){return t?`[Session note: the instructions from the start of this conversation remain in force. Reply in ${t} \u2014 including the brief status notes between tool calls.]`:"[Session note: the instructions from the start of this conversation remain in force. Reply in the language of the user's message above \u2014 including the brief status notes between tool calls. Judge the language by the human prose, ignoring code snippets and identifiers.]"}function bn(t){let e=t?.responseLanguage;if(typeof e!="string")return;let r=e.trim();return r.length>0&&r.toLowerCase()!=="auto"?r:void 0}var pi=$(()=>{"use strict"});import{spawn as yR}from"node:child_process";function Pl(t,e){return t.length>e?t.slice(0,e)+"\u2026":t}function wR(t,e){if(!(typeof t!="string"||!t))return t.startsWith(e)?t.slice(e.length).replace(/^\/+/,"")||t.split("/").pop()||void 0:t.startsWith("/")?t.split("/").pop()||void 0:t}function bR(t){return typeof t=="string"?t.trim():Array.isArray(t)?t.map(e=>e&&typeof e=="object"?String(e.text??""):"").join(" ").trim():""}function Nr(t){return typeof t=="number"&&Number.isFinite(t)?t:0}function _l(t,e){let r=[{type:"text",text:t}];return e&&r.push({type:"text",text:e}),JSON.stringify({type:"user",message:{role:"user",content:r}})+`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-partner/codepipe",
|
|
3
|
-
"version": "0.11.1-dev.
|
|
3
|
+
"version": "0.11.1-dev.223.g7553648",
|
|
4
4
|
"description": "CodePipe turns tasks into reviewed pull requests: an AI agent analyzes, implements, and opens a PR under your control.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"@types/ws": "^8.5.13",
|
|
30
30
|
"esbuild": "^0.21.5",
|
|
31
31
|
"vitest": "2.1.9",
|
|
32
|
-
"@codepipe/
|
|
33
|
-
"@codepipe/
|
|
32
|
+
"@codepipe/shared": "0.0.0",
|
|
33
|
+
"@codepipe/sandbox": "0.1.0"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsc -p tsconfig.json && chmod +x dist/index.js",
|