@code-partner/codepipe 0.12.1-dev.249.gc370d3a → 0.12.1-dev.250.g9a27fd7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +4 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var tb=Object.defineProperty;var x=(t,e)=>()=>(t&&(e=t(t=0)),e);var ze=(t,e)=>{for(var r in e)tb(t,r,{get:e[r],enumerable:!0})};var Ve,mt,Ws=x(()=>{"use strict";Ve="0.12.1-dev.249.gc370d3a",mt="https://hub.dev.codepipe.dev"});function zn(t){return typeof t!="number"||!Number.isFinite(t)?!1:t>=ku&&t<=ht}var ht,ku,bu=x(()=>{"use strict";Ws();ht=4,ku=4});var $u=x(()=>{"use strict";Ws()});function Vn(t=6){return`# CodePipe Context Repo format version.
2
+ var tb=Object.defineProperty;var x=(t,e)=>()=>(t&&(e=t(t=0)),e);var ze=(t,e)=>{for(var r in e)tb(t,r,{get:e[r],enumerable:!0})};var Ve,mt,Ws=x(()=>{"use strict";Ve="0.12.1-dev.250.g9a27fd7",mt="https://hub.dev.codepipe.dev"});function zn(t){return typeof t!="number"||!Number.isFinite(t)?!1:t>=ku&&t<=ht}var ht,ku,bu=x(()=>{"use strict";Ws();ht=4,ku=4});var $u=x(()=>{"use strict";Ws()});function Vn(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 Ys(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 zs(t,e=qs){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 Vs(t,e=qs){return e.filter(r=>r.version>t)}var vu,gt,Gr,qs,xu=x(()=>{"use strict";vu=6,gt=".codepipe-context.yaml",Gr=".devpipe-context.yaml",qs=[{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",gt]},{version:2,summary:"Rename the format-version stamp .devpipe-context.yaml \u2192 .codepipe-context.yaml (drop the devpipe-brand leftover)",addedPaths:[gt]},{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 hr(t){return`model/facts/events/${t}.yaml`}function Zs(t){return`model/facts/annotations/${t}.md`}function Qs(t){return`model/derived/correlates/${t}.yaml`}function ea(t){return`model/derived/touched/${t}.yaml`}function Su(t){return t===""?"root":t.replace(/\//g,"-")}function ta(t,e){return`model/derived/structure/${t}/${Su(e)}.yaml`}function Jo(t){return typeof t=="string"&&Tu.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(!Eu.includes(n))return null;let o=t.slice(e+1,r),i=t.slice(r+1);return o===""&&!sb.includes(n)||i===""?null:{level:n,repo:o,path:i}}function ve(t){return`task::${t}`}function ye(t,e,r){return`${t}:${e}:${r}`}function Zn(t){let e=[];return vt(t)?(Qo(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(!vt(r)){e.push(`edges[${n}]: not an object`);return}ra.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 Iu(t){return{...t,edges:Kr(t.edges,e=>`${e.kind} ${e.from} ${e.to}`)}}function gr(t){return wr(Iu(t))}function vt(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Qo(t){return typeof t=="number"&&Number.isInteger(t)&&t>0}function yt(t){return typeof t=="string"&&t.length>0}function cb(t){return t.modelFormatVersion!==2}function jt(t){let e=[];if(!vt(t))return{ok:!1,errors:["shard: not an object"]};Qo(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),yt(t.repo)||e.push("repo: missing or empty"),yt(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,i)=>{if(!vt(o)){e.push(`nodes[${i}]: not an object`);return}let s=re(o.key);if(!s){e.push(`nodes[${i}].key: malformed nodeKey (${JSON.stringify(o.key??null)})`);return}o.level!==s.level&&e.push(`nodes[${i}]: level "${String(o.level)}" does not match key prefix "${s.level}"`),r&&s.repo!==r&&e.push(`nodes[${i}].key: repo "${s.repo}" mixed into shard of repo "${r}"`);let a=o.key;n.has(a)&&e.push(`nodes[${i}].key: duplicate "${a}"`),n.add(a),o.entityId!==void 0&&!Jo(o.entityId)&&e.push(`nodes[${i}].entityId: malformed (${JSON.stringify(o.entityId)})`)}):e.push("nodes: not an array"),Array.isArray(t.edges)?t.edges.forEach((o,i)=>{if(!vt(o)){e.push(`edges[${i}]: not an object`);return}ra.includes(o.kind)||e.push(`edges[${i}].kind: unknown "${String(o.kind)}"`),(!yt(o.to)||!re(o.to))&&e.push(`edges[${i}].to: malformed nodeKey`),(!yt(o.from)||!n.has(o.from))&&e.push(`edges[${i}].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[${i}].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(!vt(t))return{ok:!1,errors:["identity: not an object"]};if(Qo(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),yt(t.repo)||e.push("repo: missing or empty"),t.builtFromCommit!==void 0&&!yt(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(!vt(n)){e.push(`entities[${o}]: not an object`);return}Jo(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`),yt(n.firstSeen)||e.push(`entities[${o}].firstSeen: missing`),yt(n.lastSeen)||e.push(`entities[${o}].lastSeen: missing`),n.aliases!==void 0&&(Array.isArray(n.aliases)?n.aliases.forEach((i,s)=>{(!vt(i)||!re(i.key)||!yt(i.until))&&e.push(`entities[${o}].aliases[${s}]: malformed`)}):e.push(`entities[${o}].aliases: not an array`))})}return e.length?{ok:!1,errors:e}:{ok:!0,value:t}}function Nt(t){let e=[];return vt(t)?(Qo(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),yt(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=>!yt(r)))&&e.push("commits: not an array of non-empty strings"),Array.isArray(t.files)?t.files.forEach((r,n)=>{if(!vt(r)||!re(r.key)){e.push(`files[${n}].key: malformed nodeKey`);return}r.entityId!==void 0&&!Jo(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 Kr(t,e){return[...t].sort((r,n)=>e(r)<e(n)?-1:e(r)>e(n)?1:0)}function Ru(t){return{...t,nodes:Kr(t.nodes,e=>e.key),edges:Kr(t.edges,e=>`${e.kind}\0${e.from}\0${e.to}`)}}function Cu(t){return{...t,entities:Kr(t.entities,e=>e.entityId).map(e=>e.aliases?{...e,aliases:Kr(e.aliases,r=>`${r.key}\0${r.until}`)}:e)}}function Pu(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:Kr(t.files,r=>r.key),...e?{links:e}:{}}}function Xn(t){return lb.test(t)?t:JSON.stringify(t)}function Au(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 _u(t){return t===null||["boolean","number","string"].includes(typeof t)}function Xs(t){return Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[r])=>e<r?-1:e>r?1:0)}function ju(t,e,r){if(Array.isArray(t)){for(let n of t)if(_u(n))r.push(`${e}- ${Au(n)}`);else{if(Array.isArray(n))throw new Error("model yaml: nested arrays are not part of the model schema");{let o=Xs(n);if(o.length===0){r.push(`${e}- {}`);continue}o.forEach(([i,s],a)=>{let c=a===0?`${e}- `:`${e} `;Js(i,s,c,`${e} `,r)})}}return}for(let[n,o]of Xs(t))Js(n,o,e,e,r)}function Js(t,e,r,n,o){if(_u(e))o.push(`${r}${Xn(t)}: ${Au(e)}`);else if(Array.isArray(e))e.length===0?o.push(`${r}${Xn(t)}: []`):(o.push(`${r}${Xn(t)}:`),ju(e,`${n} `,o));else{let i=Xs(e);if(i.length===0)o.push(`${r}${Xn(t)}: {}`);else{o.push(`${r}${Xn(t)}:`);for(let[s,a]of i)Js(s,a,`${n} `,`${n} `,o)}}}function wr(t){let e=[];return ju(t,"",e),e.join(`
@@ -806,7 +806,7 @@ Produced by the interactive chat (mock runner).
806
806
  `)+`
807
807
  `,{mode:384}),Fg(o,`[credential]
808
808
  helper = store --file=${n}
809
- `+e.join(""),{mode:384}),{env:{...process.env,GIT_CONFIG_GLOBAL:o,GIT_CONFIG_SYSTEM:"/dev/null",GIT_CONFIG_NOSYSTEM:"1",GIT_TERMINAL_PROMPT:"0"},cleanup:()=>{try{AT(r,{recursive:!0,force:!0})}catch{}}}}function Pl(t){let e=[],r=[];return t.mirrorWrite?.token&&(e.push(`https://x-access-token:${t.mirrorWrite.token}@github.com`),e.push(`https://oauth2:${t.mirrorWrite.token}@gitlab.com`),e.push(`https://${Lt}:${encodeURIComponent(t.mirrorWrite.token)}@bitbucket.org`),r.push(Gg,Hg,Kg)),t.github?.token&&(e.push(`https://x-access-token:${t.github.token}@github.com`),r.push(Gg)),t.bitbucket?.apiToken&&(e.push(`https://${Lt}:${encodeURIComponent(t.bitbucket.apiToken)}@bitbucket.org`),r.push(Kg)),t.gitlab?.token&&(e.push(`https://oauth2:${t.gitlab.token}@gitlab.com`),r.push(Hg)),Wg(e,r)}function qg(t,e){if(t.contextWrite?.token){let r=vr(e)??"github.com",n=ao(r);return Wg([`https://${n}:${t.contextWrite.token}@${r}`],[fs(r)])}return Pl(t)}var Gg,Kg,Hg,Yg=x(()=>{"use strict";F();Gg=fs("github.com"),Kg=fs("bitbucket.org"),Hg=fs("gitlab.com")});import{spawn as Vg}from"node:child_process";import{existsSync as ms,mkdirSync as Lo,readFileSync as jT,rmSync as Al,symlinkSync as NT}from"node:fs";import{homedir as OT}from"node:os";import{dirname as In,join as ar}from"node:path";function Xg(t){let e=ar(OT(),".codepipe-sandbox","repos");return t?ar(e,t):e}function Jg(t,e){let n=(Tn.get(t)??Promise.resolve()).then(e,e),o=n.then(()=>{Tn.get(t)===o&&Tn.delete(t)},()=>{Tn.get(t)===o&&Tn.delete(t)});return Tn.set(t,o),n}function zg(t){let e=t instanceof Error?t.message:String(t);return/couldn't find remote ref/i.test(e)||/Remote branch .* not found/i.test(e)||/unknown revision/i.test(e)}function LT(t){let e=t instanceof Error?t.message:String(t);return/invalid index-pack output/i.test(e)||/index-pack failed/i.test(e)||/fetch-pack/i.test(e)||/objects[\/\\]pack/i.test(e)||/(loose object .* is corrupt|corrupt loose object|object file .* is empty)/i.test(e)||/did not send all necessary objects/i.test(e)||/(bad object|bad tree object|unable to read (tree|sha1))/i.test(e)||/not a git repository/i.test(e)||/unable to read .*(pack|object)/i.test(e)}async function Zg(t,e,r,n,o){let i=async c=>{await ue(t,["fetch","--depth=1","origin",`+refs/heads/${c}:refs/remotes/origin/${c}`],o),await ue(t,["reset","--hard",`origin/${c}`],o),await ue(t,["clean","-fdx"],o)},s=async()=>{try{return await i(r),r}catch(c){if(!n||n===r||!zg(c))throw c;return console.log(`[git] ref ${r} gone upstream \u2014 falling back to ${n}`),await i(n),n}},a=async()=>{ms(t)&&Al(t,{recursive:!0,force:!0}),Lo(In(t),{recursive:!0});try{return await ue(void 0,["clone","--depth=1","--single-branch","--branch",r,e,t],o),r}catch(c){if(!n||n===r||!zg(c))throw c;return console.log(`[git] branch ${r} not found on clone \u2014 falling back to ${n}`),ms(t)&&Al(t,{recursive:!0,force:!0}),Lo(In(t),{recursive:!0}),await ue(void 0,["clone","--depth=1","--single-branch","--branch",n,e,t],o),n}};if(ms(ar(t,".git")))try{return await s()}catch(c){if(!LT(c))throw c;let l=c instanceof Error?c.message:String(c);console.warn(`[git] cache at ${t} looks corrupt (${l}) \u2014 discarding and re-cloning`)}return a()}async function Qg(t){await ue(t.workspacePath,["reset","--hard",t.baseSha]),await ue(t.workspacePath,["clean","-fdx"])}async function ey(t,e){let r=t.workspacePath;await ue(r,["add","-A"]);let n=(await Ne(r,["write-tree"])).trim(),o=(await Ne(r,["rev-parse",`${t.baseSha}^{tree}`])).trim();if(n===o)return null;let i={...process.env,GIT_AUTHOR_NAME:Rn,GIT_AUTHOR_EMAIL:Cn,GIT_COMMITTER_NAME:Rn,GIT_COMMITTER_EMAIL:Cn};return(await Ne(r,["commit-tree",n,"-m",e],i)).trim()}async function ty(t,e,r,n,o){try{await ue(t.workspacePath,["push","--force",n,`${e}:refs/heads/${r}`],o)}catch(i){let s=i instanceof Error?i.message:String(i);throw vr(n)==="github.com"&&/without `?workflow`? scope|workflow.*scope/i.test(s)?new Error("delivery push rejected: the Context-Repo push token needs the `workflow` scope (the delivery includes .github/workflows/*). Set secrets.contextWrite.token to a fine-grained PAT on the Context Repo with Contents: write + Workflows: write (or add `workflow` to the project token).\n"+s):i}}async function ry(t,e){return Ne(t.workspacePath,["diff","--binary",t.baseSha,e])}async function ny(t,e,r,n,o){await ue(t.workspacePath,["fetch",n,`+refs/heads/${e}:refs/codepipe-build-delivery`],o),await ue(t.workspacePath,["checkout","--force",r])}async function oy(t,e,r,n,o,i){let s=t.workspacePath;await ue(s,["fetch",o,`+refs/heads/${e}:refs/codepipe-build-delivery`],i);let a=(await Ne(s,["rev-parse","refs/codepipe-build-delivery"])).trim();a!==r&&console.warn(`[git] delivery ${e} resolved ${a.slice(0,10)} (expected ${r.slice(0,10)})`);let c=f=>Ne(s,["rev-parse","-q","--verify",`${f}^{commit}`]).then(()=>!0).catch(()=>!1);if(!await c(n)&&((await Ne(s,["rev-parse","--is-shallow-repository"])).trim()==="true"&&await ue(s,["fetch","--unshallow","origin",`+refs/heads/${t.ref}:refs/remotes/origin/${t.ref}`],i).catch(g=>{console.warn(`[git] moved-base apply: --unshallow ${t.ref} failed: ${String(g)}`)}),await c(n)||await ue(s,["fetch","origin",n],i).catch(()=>{}),!await c(n)))throw new Error(`moved-base apply: delivery base ${n.slice(0,10)} is unreachable \u2014 cannot re-apply the previous iteration onto the fresh ${t.ref}`);let l={...i??process.env,GIT_AUTHOR_NAME:Rn,GIT_AUTHOR_EMAIL:Cn,GIT_COMMITTER_NAME:Rn,GIT_COMMITTER_EMAIL:Cn},u=(await Ne(s,["rev-parse","refs/codepipe-build-delivery^{tree}"])).trim(),p=(await Ne(s,["commit-tree",u,"-p",n,"-m","delivery"],l)).trim();await ue(s,["cherry-pick","--quit"],l).catch(()=>{});let d=null;try{await ue(s,["cherry-pick","--no-commit",p],l)}catch(f){d=f instanceof Error?f.message:String(f)}let m=(await Ne(s,["diff","--name-only","--diff-filter=U"])).split(`
809
+ `+e.join(""),{mode:384}),{env:{...process.env,GIT_CONFIG_GLOBAL:o,GIT_CONFIG_SYSTEM:"/dev/null",GIT_CONFIG_NOSYSTEM:"1",GIT_TERMINAL_PROMPT:"0"},cleanup:()=>{try{AT(r,{recursive:!0,force:!0})}catch{}}}}function Pl(t){let e=[],r=[];if(t.mirrorWrite?.token){let n=t.mirrorWrite.host;(!n||n==="github")&&(e.push(`https://x-access-token:${t.mirrorWrite.token}@github.com`),r.push(Gg)),(!n||n==="gitlab")&&(e.push(`https://oauth2:${t.mirrorWrite.token}@gitlab.com`),r.push(Hg)),(!n||n==="bitbucket")&&(e.push(`https://${Lt}:${encodeURIComponent(t.mirrorWrite.token)}@bitbucket.org`),r.push(Kg))}return t.github?.token&&(e.push(`https://x-access-token:${t.github.token}@github.com`),r.push(Gg)),t.bitbucket?.apiToken&&(e.push(`https://${Lt}:${encodeURIComponent(t.bitbucket.apiToken)}@bitbucket.org`),r.push(Kg)),t.gitlab?.token&&(e.push(`https://oauth2:${t.gitlab.token}@gitlab.com`),r.push(Hg)),Wg(e,r)}function qg(t,e){if(t.contextWrite?.token){let r=vr(e)??"github.com",n=ao(r);return Wg([`https://${n}:${t.contextWrite.token}@${r}`],[fs(r)])}return Pl(t)}var Gg,Kg,Hg,Yg=x(()=>{"use strict";F();Gg=fs("github.com"),Kg=fs("bitbucket.org"),Hg=fs("gitlab.com")});import{spawn as Vg}from"node:child_process";import{existsSync as ms,mkdirSync as Lo,readFileSync as jT,rmSync as Al,symlinkSync as NT}from"node:fs";import{homedir as OT}from"node:os";import{dirname as In,join as ar}from"node:path";function Xg(t){let e=ar(OT(),".codepipe-sandbox","repos");return t?ar(e,t):e}function Jg(t,e){let n=(Tn.get(t)??Promise.resolve()).then(e,e),o=n.then(()=>{Tn.get(t)===o&&Tn.delete(t)},()=>{Tn.get(t)===o&&Tn.delete(t)});return Tn.set(t,o),n}function zg(t){let e=t instanceof Error?t.message:String(t);return/couldn't find remote ref/i.test(e)||/Remote branch .* not found/i.test(e)||/unknown revision/i.test(e)}function LT(t){let e=t instanceof Error?t.message:String(t);return/invalid index-pack output/i.test(e)||/index-pack failed/i.test(e)||/fetch-pack/i.test(e)||/objects[\/\\]pack/i.test(e)||/(loose object .* is corrupt|corrupt loose object|object file .* is empty)/i.test(e)||/did not send all necessary objects/i.test(e)||/(bad object|bad tree object|unable to read (tree|sha1))/i.test(e)||/not a git repository/i.test(e)||/unable to read .*(pack|object)/i.test(e)}async function Zg(t,e,r,n,o){let i=async c=>{await ue(t,["fetch","--depth=1","origin",`+refs/heads/${c}:refs/remotes/origin/${c}`],o),await ue(t,["reset","--hard",`origin/${c}`],o),await ue(t,["clean","-fdx"],o)},s=async()=>{try{return await i(r),r}catch(c){if(!n||n===r||!zg(c))throw c;return console.log(`[git] ref ${r} gone upstream \u2014 falling back to ${n}`),await i(n),n}},a=async()=>{ms(t)&&Al(t,{recursive:!0,force:!0}),Lo(In(t),{recursive:!0});try{return await ue(void 0,["clone","--depth=1","--single-branch","--branch",r,e,t],o),r}catch(c){if(!n||n===r||!zg(c))throw c;return console.log(`[git] branch ${r} not found on clone \u2014 falling back to ${n}`),ms(t)&&Al(t,{recursive:!0,force:!0}),Lo(In(t),{recursive:!0}),await ue(void 0,["clone","--depth=1","--single-branch","--branch",n,e,t],o),n}};if(ms(ar(t,".git")))try{return await s()}catch(c){if(!LT(c))throw c;let l=c instanceof Error?c.message:String(c);console.warn(`[git] cache at ${t} looks corrupt (${l}) \u2014 discarding and re-cloning`)}return a()}async function Qg(t){await ue(t.workspacePath,["reset","--hard",t.baseSha]),await ue(t.workspacePath,["clean","-fdx"])}async function ey(t,e){let r=t.workspacePath;await ue(r,["add","-A"]);let n=(await Ne(r,["write-tree"])).trim(),o=(await Ne(r,["rev-parse",`${t.baseSha}^{tree}`])).trim();if(n===o)return null;let i={...process.env,GIT_AUTHOR_NAME:Rn,GIT_AUTHOR_EMAIL:Cn,GIT_COMMITTER_NAME:Rn,GIT_COMMITTER_EMAIL:Cn};return(await Ne(r,["commit-tree",n,"-m",e],i)).trim()}async function ty(t,e,r,n,o){try{await ue(t.workspacePath,["push","--force",n,`${e}:refs/heads/${r}`],o)}catch(i){let s=i instanceof Error?i.message:String(i);throw vr(n)==="github.com"&&/without `?workflow`? scope|workflow.*scope/i.test(s)?new Error("delivery push rejected: the Context-Repo push token needs the `workflow` scope (the delivery includes .github/workflows/*). Set secrets.contextWrite.token to a fine-grained PAT on the Context Repo with Contents: write + Workflows: write (or add `workflow` to the project token).\n"+s):i}}async function ry(t,e){return Ne(t.workspacePath,["diff","--binary",t.baseSha,e])}async function ny(t,e,r,n,o){await ue(t.workspacePath,["fetch",n,`+refs/heads/${e}:refs/codepipe-build-delivery`],o),await ue(t.workspacePath,["checkout","--force",r])}async function oy(t,e,r,n,o,i){let s=t.workspacePath;await ue(s,["fetch",o,`+refs/heads/${e}:refs/codepipe-build-delivery`],i);let a=(await Ne(s,["rev-parse","refs/codepipe-build-delivery"])).trim();a!==r&&console.warn(`[git] delivery ${e} resolved ${a.slice(0,10)} (expected ${r.slice(0,10)})`);let c=f=>Ne(s,["rev-parse","-q","--verify",`${f}^{commit}`]).then(()=>!0).catch(()=>!1);if(!await c(n)&&((await Ne(s,["rev-parse","--is-shallow-repository"])).trim()==="true"&&await ue(s,["fetch","--unshallow","origin",`+refs/heads/${t.ref}:refs/remotes/origin/${t.ref}`],i).catch(g=>{console.warn(`[git] moved-base apply: --unshallow ${t.ref} failed: ${String(g)}`)}),await c(n)||await ue(s,["fetch","origin",n],i).catch(()=>{}),!await c(n)))throw new Error(`moved-base apply: delivery base ${n.slice(0,10)} is unreachable \u2014 cannot re-apply the previous iteration onto the fresh ${t.ref}`);let l={...i??process.env,GIT_AUTHOR_NAME:Rn,GIT_AUTHOR_EMAIL:Cn,GIT_COMMITTER_NAME:Rn,GIT_COMMITTER_EMAIL:Cn},u=(await Ne(s,["rev-parse","refs/codepipe-build-delivery^{tree}"])).trim(),p=(await Ne(s,["commit-tree",u,"-p",n,"-m","delivery"],l)).trim();await ue(s,["cherry-pick","--quit"],l).catch(()=>{});let d=null;try{await ue(s,["cherry-pick","--no-commit",p],l)}catch(f){d=f instanceof Error?f.message:String(f)}let m=(await Ne(s,["diff","--name-only","--diff-filter=U"])).split(`
810
810
  `).map(f=>f.trim()).filter(f=>f.length>0);if(d&&m.length===0)throw await ue(s,["cherry-pick","--abort"],l).catch(()=>{}),new Error(`moved-base apply: cherry-pick of the previous delivery onto ${t.ref} failed: ${d}`);return m}async function _l(t,e,r){let n=t.workspacePath,o={...r??process.env,GIT_AUTHOR_NAME:Rn,GIT_AUTHOR_EMAIL:Cn,GIT_COMMITTER_NAME:Rn,GIT_COMMITTER_EMAIL:Cn};(await Ne(n,["rev-parse","--is-shallow-repository"])).trim()==="true"&&await ue(n,["fetch","--unshallow","origin",`+refs/heads/${t.ref}:refs/remotes/origin/${t.ref}`],r).catch(l=>{console.warn(`[git] resolve-conflict: --unshallow ${t.ref} failed: ${String(l)}`)}),await ue(n,["fetch","origin",`+refs/heads/${e}:refs/remotes/origin/${e}`],r);let s=null;try{await ue(n,["merge","--no-commit","--no-ff",`origin/${e}`],o)}catch(l){s=l instanceof Error?l.message:String(l)}let a=(await Ne(n,["diff","--name-only","--diff-filter=U"])).split(`
811
811
  `).map(l=>l.trim()).filter(l=>l.length>0),c=await Ne(n,["rev-parse","-q","--verify","MERGE_HEAD"]).then(()=>!0).catch(()=>!1);if(s&&!c&&a.length===0)throw new Error(`resolve-conflict: merge of ${e} into ${t.ref} failed: ${s}`);return a}function ue(t,e,r){return new Promise((n,o)=>{let i=Vg("git",e,{cwd:t,stdio:["ignore","pipe","pipe"],env:r??{...process.env}}),s=[];i.stderr.setEncoding("utf-8"),i.stderr.on("data",a=>s.push(a)),i.on("error",o),i.on("close",a=>{if(a===0)return n();o(new Error(`git ${e[0]} failed (exit ${a}):
812
812
  ${s.join("").trim()||"(no stderr)"}`))})})}function Ne(t,e,r){return new Promise((n,o)=>{let i=Vg("git",e,{cwd:t,stdio:["ignore","pipe","pipe"],env:r??{...process.env}}),s=[],a=[];i.stdout.setEncoding("utf-8"),i.stderr.setEncoding("utf-8"),i.stdout.on("data",c=>s.push(c)),i.stderr.on("data",c=>a.push(c)),i.on("error",o),i.on("close",c=>{if(c===0)return n(s.join(""));o(new Error(`git ${e[0]} failed (exit ${c}):
@@ -897,7 +897,7 @@ Re-register it: codepipe up --reregister (or delete that file and run codepipe
897
897
  `))w.length>0&&k.write(`${f} ${w}
898
898
  `)};m.stdout?.on("data",g(process.stdout)),m.stderr?.on("data",g(process.stderr))},i=(m,f)=>{let g=zw(process.execPath,[n,...f],{stdio:["ignore","pipe","pipe"],env:process.env});return o(g,m),g};console.log(`[up] starting CLI daemon + embedded worker (project=${e.projectId})`);let s=i("[cli]",[...r?["--profile",r]:[],"daemon"]),a=Cs({entry:n,profile:r,onLine:m=>process.stdout.write(`[worker] ${m}
899
899
  `)}),c=[{name:"daemon",child:s},{name:"worker",child:a}],l=!1,u=m=>{if(!l){l=!0,console.log(`
900
- [up] ${m} \u2014 stopping both roles`);for(let{child:f}of c)f.exitCode===null&&f.kill(m);setTimeout(()=>{for(let{name:f,child:g}of c)g.exitCode===null&&(console.warn(`[up] ${f} did not stop \u2014 SIGKILL`),g.kill("SIGKILL"))},8e3).unref()}};process.on("SIGINT",()=>u("SIGINT")),process.on("SIGTERM",()=>u("SIGTERM"));let p=c.map(({name:m,child:f})=>new Promise(g=>{f.on("exit",(k,h)=>g({name:m,code:k??(h?1:0)}))})),d=await Promise.race(p);l||(console.log(`[up] ${d.name} exited (code ${d.code}) \u2014 stopping the other role`),u("SIGTERM")),await Promise.all(p),process.exit(d.code)}var As=x(()=>{"use strict";ut();_n();Ge();Ut();vl();Ir();je();fe();it();Ko()});import{existsSync as Nr,mkdirSync as Qw,readFileSync as _s,readdirSync as wC,writeFileSync as ek}from"node:fs";import{join as Ye,resolve as tk}from"node:path";import{setTimeout as zl}from"node:timers/promises";import{cancel as rk,confirm as Ho,intro as nk,isCancel as Jl,log as C,multiselect as kC,outro as Vl,password as Wo,select as dt,spinner as Zl,text as ke}from"@clack/prompts";import{simpleGit as On}from"simple-git";function he(t){rk(t),process.exit(1)}function we(t){return Jl(t)&&he("aborted"),t}function ce(t){return Jl(t)&&he("aborted"),typeof t=="string"?t:""}async function ok(t={}){nk("codepipe init \u2014 register a project locally or on a farm");let e=process.cwd();Cw();let r=Rw(e),n,o=!1;r&&Object.keys(r.answers).length>0?we(await Ho({message:"You have not completed the initialization, do you want to continue?",initialValue:!0}))?(C.message("continuing with the saved answers \u2014 only the missing ones are asked"),n=new Nn(e,r),o=!0):(Wl(e),n=new Nn(e)):n=new Nn(e);let i=t.force===!0?null:await Yl(e),s=await n.ask("target",async()=>we(await dt({message:"where should this project run?",options:[{value:"local",label:"local \u2014 a CLI daemon on this machine, in this folder"},{value:"farm",label:"farm \u2014 a CLI daemon on a remote farm host"}],initialValue:"local"}))),a=null;s==="local"&&(a=i??(t.force===!0?null:await $C(e,n)),a?C.message(`this folder is a git checkout of ${a.parsed.owner}/${a.parsed.repoName} \u2014 registering this repo in place (.codepipe/ will live inside it)`):o&&n.get("contextRepo")!==void 0||sk(e,t.force===!0));let c=await n.ask("hubUrl",async()=>ce(await ke({message:"HUB URL",placeholder:mt,initialValue:V("HUB_URL")??mt,validate:P=>P.trim().startsWith("http")?void 0:"must start with http(s)://"})).trim().replace(/\/$/,"")),l=await n.ask("email",()=>Ln()),{cliToken:u,accountEmail:p}=await n.ask("bootstrap",()=>Mn(c,l)),d=null;s==="farm"&&(d=await bC(c,u));let m=a?SC(a.parsed.repoName):"",f=await n.ask("projectId",async()=>ce(await ke({message:"project id (slug)",placeholder:m||"acme",...m?{initialValue:m}:{},validate:P=>Wt.test(P.trim())?void 0:"must match /^[a-z][a-z0-9-]{1,30}$/"})).trim()),g=await n.ask("projectName",async()=>ce(await ke({message:"project name (human-readable)",placeholder:a?.parsed.repoName??"Acme",...a?{initialValue:a.parsed.repoName}:{},validate:P=>P.trim().length>0?void 0:"required"})).trim()),k=await n.ask("language",()=>NC()),h=await n.ask("automationLevel",async()=>we(await dt({message:"automation level",options:[{value:"assisted",label:"assisted \u2014 every gate via manual Run on the dashboard"},{value:"full",label:"full \u2014 gates auto-approve, runs end-to-end"}],initialValue:"assisted"}))),$=(s==="farm"?"no":await n.ask("mirrorChoice",async()=>we(await dt({message:"how much access should CodePipe have to your repositories?",options:[{value:"no",label:"read and write \u2014 branches and pull requests go into your repositories"},{value:"yes",label:"read only \u2014 CodePipe mirrors them and works in the mirrors",hint:"a mirror is a full copy of the history, in the account you choose next"}],initialValue:"no"}))))==="yes";$&&C.message("read-only token tip: if you want CodePipe to review pull requests people open in your repositories, the token also needs PR-comment permission (GitHub: Pull requests write; Bitbucket: pullrequest:write). Code stays read-only either way.");let S=await n.ask("trackerProvider",async()=>we(await dt({message:"task tracker",options:[{value:"internal",label:"built-in \u2014 CodePipe tracks tasks itself (no external tracker needed)"},{value:"youtrack",label:"YouTrack \u2014 connect an existing YouTrack project"}],initialValue:"internal"}))),T=S==="internal",v=null,b,I=!0;if(T){let P,N=Zl();N.start("checking task-key prefixes on your account\u2026");try{P=await ch(c,u,{excludeProjectId:f}),N.stop("prefixes checked")}catch{N.stop("could not reach the HUB",1),he("Could not verify the task-key prefix against your account \u2014 the HUB is unreachable right now. Prefix uniqueness is required, so init can't continue. Check your connection and re-run `codepipe init` later.")}let de=qa(Wa(g),P);b=await n.ask("trackerPrefix",async()=>ce(await ke({message:"task key prefix (tasks become <PREFIX>-1, <PREFIX>-2, \u2026)",placeholder:de,initialValue:de,validate:Te=>{let ft=Te.trim();if(!$r.test(ft))return"uppercase letters/digits, 2\u201310 chars, starting with a letter (e.g. TASK)";if(P.has(ft.toUpperCase()))return"this prefix is already used by another project on your account \u2014 pick another"}})).trim())}else v=await n.ask("youtrack",()=>hk()),b=await n.ask("youtrackProjectKey",async()=>ce(await ke({message:"YouTrack project key",placeholder:"DEV",validate:P=>P.trim().length>0?void 0:"required"})).trim()),I=await n.ask("youtrackWrites",async()=>we(await Ho({message:"Allow CodePipe to write to YouTrack? (status changes, PR comments, dashboard mirror)",initialValue:!0})));let _=n.get("tokens")??{},G=()=>n.set("tokens",_),z=await n.ask("repos",()=>RC(_,l,a,{onCred:G,initial:n.get("reposPartial")??[],onProgress:P=>n.set("reposPartial",P)}));n.delete("reposPartial");let A=null,y="",U="";if($){let P=we(await n.ask("mirrorHost",async()=>we(await dt({message:"where should the mirrors live? (your Context Repo will default there too)",options:["github","gitlab","bitbucket"].map(pe=>({value:pe,label:pe===z[0]?.host?`${pe} (same as your repositories)`:pe})),initialValue:z[0]?.host??"github"}))));y=ce(await n.ask("mirrorToken",async()=>we(await Wo({message:`token that may CREATE and PUSH repositories on ${P}`})))).trim(),P==="bitbucket"&&(U=ce(await n.ask("mirrorEmail",async()=>we(await ke({message:"Atlassian account email for that token",..._.bitbucket?.email?{placeholder:_.bitbucket.email,defaultValue:_.bitbucket.email}:{}})))).trim());let N=await Kw(P,y,U||void 0),de=P==="bitbucket"?"workspace slug":"username or organization (not an email)",ft=ce(await n.ask("mirrorOwnerLogin",async()=>we(await ke({message:`account for the mirrors \u2014 ${P} ${de}`,...N?{placeholder:N,defaultValue:N}:{},validate:pe=>{let ne=(pe??"").trim();if(!ne&&!N)return"required";if(ne.includes("@"))return`that looks like an email \u2014 a ${P} ${de} is expected`;if(/\s/.test(ne))return"no spaces"}})))).trim()||N||"";if(!ft||ft.includes("@")){rk("mirrors need a host account to live in (a username/organization, not an email)");return}A={host:P,owner:ft}}let j=await CC(await n.ask("contextRepo",()=>pk(f,z,_,l,A??void 0)),f,z,_,l,G,P=>n.set("contextRepo",P),A??void 0),{spec:H,mode:J}=j,oe;T||(C.message("Only YouTrack tasks assigned to you enter this pipeline (to lift the filter later, set require_assignee: false in .codepipe/project.yaml)."),oe=await n.ask("assigneeLogin",async()=>ce(await ke({message:"your YouTrack login (the assignee value)",...v?.login?{initialValue:v.login}:{},validate:P=>P.trim().length>0?void 0:"required"})).trim()));let At=await n.ask("llmProvider",async()=>{for(;;){if(we(await dt({message:"LLM provider",options:[{value:"claude",label:"Claude",hint:"recommended"},{value:"codex",label:"Codex",hint:"coming soon"}],initialValue:"claude"}))==="claude")return"claude";C.warn("Codex support is coming soon \u2014 pick Claude for now.")}}),pt=At==="claude"?await n.ask("claudeToken",()=>ww(yw("claude"),{farm:s==="farm"})):"",Ue;if(pt){let P=await Op(pt);if(P){let N=ga(P);N&&(Ue=N,C.warn(`Claude subscription is missing some recommended models \u2014 regimen.yaml will use ${N} for all roles. Adjust later in the dashboard (Project Settings \u2192 llm.models) or .codepipe/regimen.yaml.`))}}let L={projectId:f,name:g,automationLevel:h,repos:z,trackerProvider:S,youtrackProjectKey:b,language:k};C.step(`${J==="attach"?"attaching to":"provisioning"} Context Repo ${H.owner}/${H.name} (${H.host})\u2026`);let B;try{B=await jn(L,H,{...fk(_),youtrackWrites:I,...v?{trackerUrl:v.url}:{},mode:J,log:{info:P=>C.message(P),warn:P=>C.warn(P)}})}catch(P){he(`Context Repo provisioning failed: ${P instanceof Error?P.message:String(P)}`)}L.contextRepo=B,C.success(`Context Repo ready: ${B.owner}/${B.name}@${B.branch}`),C.step(`registering project on ${c}\u2026`);let M;try{M=await nr(c,u,L)}catch(P){if(P instanceof K&&P.status===409){C.warn(`project ${f} already exists on HUB \u2014 reusing it`);try{M=await se(c,u,f)}catch(N){throw N instanceof K&&he(`HUB \u2192 ${N.status} ${N.message}`),N}}else if(P instanceof K&&P.status===401)n.delete("cliToken"),he("HUB rejected the sign-in token (401) \u2014 re-run `codepipe init` to sign in again");else if(P instanceof K)he(`HUB \u2192 ${P.status} ${P.message}`);else throw P}let Y=M.contextRepo??B;C.success(`project ${M.projectId} ready (${M.provisioningStatus})`);let W=v?{url:v.url,token:v.token}:void 0;if(s==="farm"){let P=d,N={..._,...pt?{claude:{oauthToken:pt}}:{},...W?{youtrack:W}:{}},de=_.github?.token;if(Y.host==="github"&&de)try{let ne=eg(`devpipe-${f}`);await tg(Y,de,ne.publicKey,`devpipe-${f}`),N.contextSsh={privateKey:ne.privateKey},C.success("Context Repo SSH deploy key registered (no contextWrite PAT needed on the farm)")}catch(ne){C.warn(`could not set up Context Repo SSH deploy key (${ne instanceof Error?ne.message:String(ne)}); the farm will fall back to the token path.`)}let Te={projectId:f,config:{hubUrl:c,cliToken:u,projectId:f},secrets:N,contextRepo:Y,projectConfig:Tt(L,I,v?.url,oe||void 0,At,Ue)},ft=Bt(P.farm.publicKey,JSON.stringify(Te));C.step(`handing project ${f} to farm ${P.farm.name}\u2026`);let pe;try{pe=await Zi(c,u,P.farm.farmId,{projectId:f,sealedBundle:ft})}catch(ne){throw ne instanceof K&&he(ne.status===409?`farm ${P.farm.name} is offline \u2014 start it and re-run.`:ne.status===504?`farm ${P.farm.name} did not respond in time.`:`HUB \u2192 ${ne.status} ${ne.message}`),ne}pe.ok||he(`farm rejected provisioning: ${pe.error??"unknown error"}`),await Xl(c,u,f,Y,de,M.repos,null,_),n.clear(),Vl(`done. project ${f} is now hosted on farm ${P.farm.name} (daemon ${pe.daemonStatus}). Watch the setup progress on the dashboard \u2014 the project card shows each step until the project is ready.`);return}mk(_),await lk(e,Y.cloneUrl,Y.branch),dk(e);try{cn(Ye(e,ot),e,{info:P=>C.message(P),warn:P=>C.warn(P)})}catch(P){C.warn(`skills materialize failed \u2014 ${P instanceof Error?P.message:String(P)}`)}a&&await TC(e);{let P=Ye(e,ot);an(P);let N=Tt(L,I,v?.url,oe||void 0,At,Ue),de=fo(P,N);de.length>0&&C.success(`local project config \u2192 .codepipe/{${de.join(", ")}}`),Qt(f,N,{info:Te=>C.message(Te),warn:Te=>C.warn(Te)})}await uk(e,M.repos);let E=!1;if($&&A&&(E=await IC(e,Ye(e,ot),M.repos,{host:A.host,owner:A.owner,token:y,...U?{email:U}:{}}),E)){let P=Ye(e,ot);Qt(f,{projectYaml:_s(Ye(P,"project.yaml"),"utf-8"),regimenYaml:_s(Ye(P,"regimen.yaml"),"utf-8")},{info:N=>C.message(N),warn:N=>C.warn(N)})}let R={hubUrl:c,cliToken:u,projectId:f,..._,...pt?{claude:{oauthToken:pt}}:{},...W?{youtrack:W}:{},...E?{mirrorWrite:{token:y,...U?{email:U}:{}}}:{}};ae(R),Mt({hubUrl:c,cliToken:u,projectId:f,accountEmail:p},f),C.success(`secrets \u2192 ${St(f)}`),await Xl(c,u,f,Y,_.github?.token??process.env.GH_TOKEN??process.env.GITHUB_TOKEN,M.repos,e,_),n.clear();let Q=`${c}/?project=${encodeURIComponent(f)}`;Tr(Q),Vl(`done. your project on the dashboard (sign in there to work with it):
900
+ [up] ${m} \u2014 stopping both roles`);for(let{child:f}of c)f.exitCode===null&&f.kill(m);setTimeout(()=>{for(let{name:f,child:g}of c)g.exitCode===null&&(console.warn(`[up] ${f} did not stop \u2014 SIGKILL`),g.kill("SIGKILL"))},8e3).unref()}};process.on("SIGINT",()=>u("SIGINT")),process.on("SIGTERM",()=>u("SIGTERM"));let p=c.map(({name:m,child:f})=>new Promise(g=>{f.on("exit",(k,h)=>g({name:m,code:k??(h?1:0)}))})),d=await Promise.race(p);l||(console.log(`[up] ${d.name} exited (code ${d.code}) \u2014 stopping the other role`),u("SIGTERM")),await Promise.all(p),process.exit(d.code)}var As=x(()=>{"use strict";ut();_n();Ge();Ut();vl();Ir();je();fe();it();Ko()});import{existsSync as Nr,mkdirSync as Qw,readFileSync as _s,readdirSync as wC,writeFileSync as ek}from"node:fs";import{join as Ye,resolve as tk}from"node:path";import{setTimeout as zl}from"node:timers/promises";import{cancel as rk,confirm as Ho,intro as nk,isCancel as Jl,log as C,multiselect as kC,outro as Vl,password as Wo,select as dt,spinner as Zl,text as ke}from"@clack/prompts";import{simpleGit as On}from"simple-git";function he(t){rk(t),process.exit(1)}function we(t){return Jl(t)&&he("aborted"),t}function ce(t){return Jl(t)&&he("aborted"),typeof t=="string"?t:""}async function ok(t={}){nk("codepipe init \u2014 register a project locally or on a farm");let e=process.cwd();Cw();let r=Rw(e),n,o=!1;r&&Object.keys(r.answers).length>0?we(await Ho({message:"You have not completed the initialization, do you want to continue?",initialValue:!0}))?(C.message("continuing with the saved answers \u2014 only the missing ones are asked"),n=new Nn(e,r),o=!0):(Wl(e),n=new Nn(e)):n=new Nn(e);let i=t.force===!0?null:await Yl(e),s=await n.ask("target",async()=>we(await dt({message:"where should this project run?",options:[{value:"local",label:"local \u2014 a CLI daemon on this machine, in this folder"},{value:"farm",label:"farm \u2014 a CLI daemon on a remote farm host"}],initialValue:"local"}))),a=null;s==="local"&&(a=i??(t.force===!0?null:await $C(e,n)),a?C.message(`this folder is a git checkout of ${a.parsed.owner}/${a.parsed.repoName} \u2014 registering this repo in place (.codepipe/ will live inside it)`):o&&n.get("contextRepo")!==void 0||sk(e,t.force===!0));let c=await n.ask("hubUrl",async()=>ce(await ke({message:"HUB URL",placeholder:mt,initialValue:V("HUB_URL")??mt,validate:P=>P.trim().startsWith("http")?void 0:"must start with http(s)://"})).trim().replace(/\/$/,"")),l=await n.ask("email",()=>Ln()),{cliToken:u,accountEmail:p}=await n.ask("bootstrap",()=>Mn(c,l)),d=null;s==="farm"&&(d=await bC(c,u));let m=a?SC(a.parsed.repoName):"",f=await n.ask("projectId",async()=>ce(await ke({message:"project id (slug)",placeholder:m||"acme",...m?{initialValue:m}:{},validate:P=>Wt.test(P.trim())?void 0:"must match /^[a-z][a-z0-9-]{1,30}$/"})).trim()),g=await n.ask("projectName",async()=>ce(await ke({message:"project name (human-readable)",placeholder:a?.parsed.repoName??"Acme",...a?{initialValue:a.parsed.repoName}:{},validate:P=>P.trim().length>0?void 0:"required"})).trim()),k=await n.ask("language",()=>NC()),h=await n.ask("automationLevel",async()=>we(await dt({message:"automation level",options:[{value:"assisted",label:"assisted \u2014 every gate via manual Run on the dashboard"},{value:"full",label:"full \u2014 gates auto-approve, runs end-to-end"}],initialValue:"assisted"}))),$=(s==="farm"?"no":await n.ask("mirrorChoice",async()=>we(await dt({message:"how much access should CodePipe have to your repositories?",options:[{value:"no",label:"read and write \u2014 branches and pull requests go into your repositories"},{value:"yes",label:"read only \u2014 CodePipe mirrors them and works in the mirrors",hint:"a mirror is a full copy of the history, in the account you choose next"}],initialValue:"no"}))))==="yes";$&&C.message("read-only token tip: if you want CodePipe to review pull requests people open in your repositories, the token also needs PR-comment permission (GitHub: Pull requests write; Bitbucket: pullrequest:write). Code stays read-only either way.");let S=await n.ask("trackerProvider",async()=>we(await dt({message:"task tracker",options:[{value:"internal",label:"built-in \u2014 CodePipe tracks tasks itself (no external tracker needed)"},{value:"youtrack",label:"YouTrack \u2014 connect an existing YouTrack project"}],initialValue:"internal"}))),T=S==="internal",v=null,b,I=!0;if(T){let P,N=Zl();N.start("checking task-key prefixes on your account\u2026");try{P=await ch(c,u,{excludeProjectId:f}),N.stop("prefixes checked")}catch{N.stop("could not reach the HUB",1),he("Could not verify the task-key prefix against your account \u2014 the HUB is unreachable right now. Prefix uniqueness is required, so init can't continue. Check your connection and re-run `codepipe init` later.")}let de=qa(Wa(g),P);b=await n.ask("trackerPrefix",async()=>ce(await ke({message:"task key prefix (tasks become <PREFIX>-1, <PREFIX>-2, \u2026)",placeholder:de,initialValue:de,validate:Te=>{let ft=Te.trim();if(!$r.test(ft))return"uppercase letters/digits, 2\u201310 chars, starting with a letter (e.g. TASK)";if(P.has(ft.toUpperCase()))return"this prefix is already used by another project on your account \u2014 pick another"}})).trim())}else v=await n.ask("youtrack",()=>hk()),b=await n.ask("youtrackProjectKey",async()=>ce(await ke({message:"YouTrack project key",placeholder:"DEV",validate:P=>P.trim().length>0?void 0:"required"})).trim()),I=await n.ask("youtrackWrites",async()=>we(await Ho({message:"Allow CodePipe to write to YouTrack? (status changes, PR comments, dashboard mirror)",initialValue:!0})));let _=n.get("tokens")??{},G=()=>n.set("tokens",_),z=await n.ask("repos",()=>RC(_,l,a,{onCred:G,initial:n.get("reposPartial")??[],onProgress:P=>n.set("reposPartial",P)}));n.delete("reposPartial");let A=null,y="",U="";if($){let P=we(await n.ask("mirrorHost",async()=>we(await dt({message:"where should the mirrors live? (your Context Repo will default there too)",options:["github","gitlab","bitbucket"].map(pe=>({value:pe,label:pe===z[0]?.host?`${pe} (same as your repositories)`:pe})),initialValue:z[0]?.host??"github"}))));y=ce(await n.ask("mirrorToken",async()=>we(await Wo({message:`token that may CREATE and PUSH repositories on ${P}`})))).trim(),P==="bitbucket"&&(U=ce(await n.ask("mirrorEmail",async()=>we(await ke({message:"Atlassian account email for that token",..._.bitbucket?.email?{placeholder:_.bitbucket.email,defaultValue:_.bitbucket.email}:{}})))).trim());let N=await Kw(P,y,U||void 0),de=P==="bitbucket"?"workspace slug":"username or organization (not an email)",ft=ce(await n.ask("mirrorOwnerLogin",async()=>we(await ke({message:`account for the mirrors \u2014 ${P} ${de}`,...N?{placeholder:N,defaultValue:N}:{},validate:pe=>{let ne=(pe??"").trim();if(!ne&&!N)return"required";if(ne.includes("@"))return`that looks like an email \u2014 a ${P} ${de} is expected`;if(/\s/.test(ne))return"no spaces"}})))).trim()||N||"";if(!ft||ft.includes("@")){rk("mirrors need a host account to live in (a username/organization, not an email)");return}A={host:P,owner:ft}}let j=await CC(await n.ask("contextRepo",()=>pk(f,z,_,l,A??void 0)),f,z,_,l,G,P=>n.set("contextRepo",P),A??void 0),{spec:H,mode:J}=j,oe;T||(C.message("Only YouTrack tasks assigned to you enter this pipeline (to lift the filter later, set require_assignee: false in .codepipe/project.yaml)."),oe=await n.ask("assigneeLogin",async()=>ce(await ke({message:"your YouTrack login (the assignee value)",...v?.login?{initialValue:v.login}:{},validate:P=>P.trim().length>0?void 0:"required"})).trim()));let At=await n.ask("llmProvider",async()=>{for(;;){if(we(await dt({message:"LLM provider",options:[{value:"claude",label:"Claude",hint:"recommended"},{value:"codex",label:"Codex",hint:"coming soon"}],initialValue:"claude"}))==="claude")return"claude";C.warn("Codex support is coming soon \u2014 pick Claude for now.")}}),pt=At==="claude"?await n.ask("claudeToken",()=>ww(yw("claude"),{farm:s==="farm"})):"",Ue;if(pt){let P=await Op(pt);if(P){let N=ga(P);N&&(Ue=N,C.warn(`Claude subscription is missing some recommended models \u2014 regimen.yaml will use ${N} for all roles. Adjust later in the dashboard (Project Settings \u2192 llm.models) or .codepipe/regimen.yaml.`))}}let L={projectId:f,name:g,automationLevel:h,repos:z,trackerProvider:S,youtrackProjectKey:b,language:k};C.step(`${J==="attach"?"attaching to":"provisioning"} Context Repo ${H.owner}/${H.name} (${H.host})\u2026`);let B;try{B=await jn(L,H,{...fk(_),youtrackWrites:I,...v?{trackerUrl:v.url}:{},mode:J,log:{info:P=>C.message(P),warn:P=>C.warn(P)}})}catch(P){he(`Context Repo provisioning failed: ${P instanceof Error?P.message:String(P)}`)}L.contextRepo=B,C.success(`Context Repo ready: ${B.owner}/${B.name}@${B.branch}`),C.step(`registering project on ${c}\u2026`);let M;try{M=await nr(c,u,L)}catch(P){if(P instanceof K&&P.status===409){C.warn(`project ${f} already exists on HUB \u2014 reusing it`);try{M=await se(c,u,f)}catch(N){throw N instanceof K&&he(`HUB \u2192 ${N.status} ${N.message}`),N}}else if(P instanceof K&&P.status===401)n.delete("cliToken"),he("HUB rejected the sign-in token (401) \u2014 re-run `codepipe init` to sign in again");else if(P instanceof K)he(`HUB \u2192 ${P.status} ${P.message}`);else throw P}let Y=M.contextRepo??B;C.success(`project ${M.projectId} ready (${M.provisioningStatus})`);let W=v?{url:v.url,token:v.token}:void 0;if(s==="farm"){let P=d,N={..._,...pt?{claude:{oauthToken:pt}}:{},...W?{youtrack:W}:{}},de=_.github?.token;if(Y.host==="github"&&de)try{let ne=eg(`devpipe-${f}`);await tg(Y,de,ne.publicKey,`devpipe-${f}`),N.contextSsh={privateKey:ne.privateKey},C.success("Context Repo SSH deploy key registered (no contextWrite PAT needed on the farm)")}catch(ne){C.warn(`could not set up Context Repo SSH deploy key (${ne instanceof Error?ne.message:String(ne)}); the farm will fall back to the token path.`)}let Te={projectId:f,config:{hubUrl:c,cliToken:u,projectId:f},secrets:N,contextRepo:Y,projectConfig:Tt(L,I,v?.url,oe||void 0,At,Ue)},ft=Bt(P.farm.publicKey,JSON.stringify(Te));C.step(`handing project ${f} to farm ${P.farm.name}\u2026`);let pe;try{pe=await Zi(c,u,P.farm.farmId,{projectId:f,sealedBundle:ft})}catch(ne){throw ne instanceof K&&he(ne.status===409?`farm ${P.farm.name} is offline \u2014 start it and re-run.`:ne.status===504?`farm ${P.farm.name} did not respond in time.`:`HUB \u2192 ${ne.status} ${ne.message}`),ne}pe.ok||he(`farm rejected provisioning: ${pe.error??"unknown error"}`),await Xl(c,u,f,Y,de,M.repos,null,_),n.clear(),Vl(`done. project ${f} is now hosted on farm ${P.farm.name} (daemon ${pe.daemonStatus}). Watch the setup progress on the dashboard \u2014 the project card shows each step until the project is ready.`);return}mk(_),await lk(e,Y.cloneUrl,Y.branch),dk(e);try{cn(Ye(e,ot),e,{info:P=>C.message(P),warn:P=>C.warn(P)})}catch(P){C.warn(`skills materialize failed \u2014 ${P instanceof Error?P.message:String(P)}`)}a&&await TC(e);{let P=Ye(e,ot);an(P);let N=Tt(L,I,v?.url,oe||void 0,At,Ue),de=fo(P,N);de.length>0&&C.success(`local project config \u2192 .codepipe/{${de.join(", ")}}`),Qt(f,N,{info:Te=>C.message(Te),warn:Te=>C.warn(Te)})}await uk(e,M.repos);let E=!1;if($&&A&&(E=await IC(e,Ye(e,ot),M.repos,{host:A.host,owner:A.owner,token:y,...U?{email:U}:{}}),E)){let P=Ye(e,ot);Qt(f,{projectYaml:_s(Ye(P,"project.yaml"),"utf-8"),regimenYaml:_s(Ye(P,"regimen.yaml"),"utf-8")},{info:N=>C.message(N),warn:N=>C.warn(N)})}let R={hubUrl:c,cliToken:u,projectId:f,..._,...pt?{claude:{oauthToken:pt}}:{},...W?{youtrack:W}:{},...E?{mirrorWrite:{token:y,host:A.host,...U?{email:U}:{}}}:{}};ae(R),Mt({hubUrl:c,cliToken:u,projectId:f,accountEmail:p},f),C.success(`secrets \u2192 ${St(f)}`),await Xl(c,u,f,Y,_.github?.token??process.env.GH_TOKEN??process.env.GITHUB_TOKEN,M.repos,e,_),n.clear();let Q=`${c}/?project=${encodeURIComponent(f)}`;Tr(Q),Vl(`done. your project on the dashboard (sign in there to work with it):
901
901
  ${Q}
902
902
  starting codepipe up \u2014 the CLI daemon and an agent worker, with their logs on screen. Ctrl+C to stop (restart anytime with \`codepipe up\` from this folder).`);let{upCommand:ie}=await Promise.resolve().then(()=>(As(),Jw));await ie({profile:void 0})}async function Xl(t,e,r,n,o,i=[],s=null,a={}){let c=await _w(n,o),l=!1;if(!c)try{l=await Ow(i,{localRoot:s,tokens:a})}catch{l=!1}let u=Aw({indexExists:c,localClones:s!==null,reposNonEmpty:l}),p=await kC({message:u.message,options:u.options,initialValues:u.initialValues,required:!1});if(Jl(p))return;let d=new Set(p);if(d.has("map")&&s!==null)try{let m=Ae(s);if(!m)throw new Error("workspace not found");let{bootstrapWorkspaceModel:f}=await Promise.resolve().then(()=>(_o(),is)),g=await f(m,void 0,{onLog:k=>C.message(k)});C.success(`project map ready: ${g.events} task events mined from history`)}catch(m){C.warn(`could not build the project map: ${m instanceof Error?m.message:String(m)}. Registration is not affected \u2014 run \`codepipe model bootstrap\` later.`)}if(d.has("backfill"))try{let{jobId:m}=await Ao(t,e,r,{reindex:!1,backfill:!0});C.success(`retrospective architecture analysis queued (job ${m}); decision drafts will appear on the project card for review once a SANDBOX picks up the job.`)}catch(m){C.warn(`could not start the retrospective analysis: ${m instanceof Error?m.message:String(m)}. Registration is not affected.`)}if(d.has("index"))try{let{jobId:m}=await Ao(t,e,r,{reindex:u.reindex});C.success(`indexing queued (job ${m}); knowledge/INDEX.md will appear in the Context Repo once the project daemon is running and a SANDBOX picks up the job.`)}catch(m){C.warn(`could not start indexing: ${m instanceof Error?m.message:String(m)}. You can retry later \u2014 registration is not affected.`)}}async function bC(t,e){let r;try{r=await oh(t,e)}catch(c){throw c instanceof K&&he(`could not list farms: HUB \u2192 ${c.status} ${c.message}`),c}let n=r.filter(c=>c.publicKey);n.length===0&&he("no farm is available to this account. Farms are assigned by the operator \u2014 ask them to assign one to you (or, if you run your own farm host: `codepipe-farm register --hub <url> --token <token>` and `codepipe-farm start`, then have the operator assign it).");let o=we(await dt({message:"target farm",options:n.map(c=>({value:c.farmId,label:`${c.name}${c.online?"":" (offline)"} \u2014 ${c.keyFingerprint??"no fingerprint"}`}))})),i=n.find(c=>c.farmId===o),s;try{s=Xi(i.farmId,i.publicKey)}catch(c){he(c instanceof Error?c.message:String(c))}return we(await Ho({message:`confirm farm ${i.name} cred-channel fingerprint:
903
903
  ${s}
@@ -941,7 +941,7 @@ starting codepipe up \u2014 the CLI daemon and an agent worker, with their logs
941
941
  - **Status:** superseded by ADR-${r}`):n}function Pv(t){let e=["# ADR index","","<!-- REGENERATED from adr/NNNN-*.md headers on every promote \u2014 do not edit. -->",""];if(t.length===0)e.push("(no accepted ADRs yet)");else for(let r of[...t].sort((n,o)=>n.num-o.num)){let n=String(r.num).padStart(4,"0"),o=[r.header.status||"accepted",r.header.date].filter(Boolean).join(", ");e.push(`- [ADR-${n} \u2014 ${r.header.title||r.file}](${r.file}) \u2014 ${o}`)}return e.join(`
942
942
  `)+`
943
943
  `}async function rf(t,e,r,n=new Date().toISOString().slice(0,10),o="task"){try{await Sv(t).pull(void 0,void 0,["--rebase"])}catch{}let i=k=>o==="staging"?`adr/DRAFT-${k}.md`:`tasks/${e}/adr/DRAFT-${k}.md`,s=[],a=[];for(let k of r){let h=Se(t,i(k));if(!xc(h)){a.push(k);continue}s.push({slug:k,content:ef(h,"utf-8")})}let c=tf(t,"adr"),l=new Map;if(xc(c))for(let k of xv(c)){let h=Ev.exec(k);!h||k===Tv||l.set(k,{num:parseInt(h[1]??"",10),slug:h[2]??"",content:ef(tf(c,k),"utf-8")})}let u=Math.max(0,...[...l.values()].map(k=>k.num))+1,p=new Map,d=[],m=[];for(let k of s){if([...l.entries()].find(([,v])=>v.slug===k.slug&&v.content.includes(e))){m.push(k.slug);continue}let w=u++,$=`${String(w).padStart(4,"0")}-${k.slug}.md`,{content:S,supersedes:T}=Rv(k.content,w,k.slug,e,n);if(p.set($,S),l.set($,{num:w,slug:k.slug,content:S}),d.push(`adr/${$}`),T!==null){let v=[...l.keys()].find(b=>b.startsWith(`${String(T).padStart(4,"0")}-`));if(v&&v!==$){let b=Cv(p.get(v)??l.get(v).content,w);p.set(v,b),l.set(v,{...l.get(v),content:b})}}}let f=[];if(o==="staging")for(let k of s)xc(Se(t,`adr/DRAFT-${k.slug}.md`))&&f.push({path:`adr/DRAFT-${k.slug}.md`,content:"",deleted:!0});if(d.length===0&&f.length===0)return{promoted:d,skipped:m,missing:a};if(d.length>0){let k=[...l.entries()].map(([h,w])=>({num:w.num,file:h,header:Iv(w.content)}));p.set("INDEX.md",Pv(k))}for(let[k,h]of p.entries())f.push({path:`adr/${k}`,content:h});let g=d.length>0?`adr(${e}): promote ${s.map(k=>k.slug).join(", ")}`:`adr(${e}): drop stale staged ${m.join(", ")}`;return await Re(t,f,g),{promoted:d,skipped:m,missing:a}}lt();Si();Ut();F();import{existsSync as sf,readFileSync as Uv}from"node:fs";import{join as af}from"node:path";function Bv(t){for(let e of[gt,Gr]){let r=af(t,e);if(sf(r))try{return Ys(Uv(r,"utf-8"))}catch{return 0}}return 0}function Fv(t,e,r,n=6){let o=e<n,i=o?zs(e).filter(s=>!r(s)):[];return{type:"context_status",projectId:t,templateVersion:e,currentVersion:n,outdated:o,missingPaths:i}}function Ei(t,e){return Fv(e,Bv(t),r=>sf(af(t,r)))}F();Vt();import{existsSync as wf,mkdirSync as hx,mkdtempSync as gx,rmSync as kf,writeFileSync as bf}from"node:fs";import{tmpdir as yx}from"node:os";import{dirname as wx,join as Ii}from"node:path";import{simpleGit as Ic}from"simple-git";Ir();function kx(t){return`codepipe/context-migration-v${t}`}function bx(t){let e=Vs(t.templateVersion),r=[`CodePipe context format migration: **v${t.templateVersion} \u2192 v${t.currentVersion}**.`,"","Additive only \u2014 this PR creates files your context is missing and updates",`the \`${gt}\` stamp (renamed from \`${Gr}\``,"when the legacy file is present). Hand-edited files are never touched.","","## Format changes",""];for(let n of e){r.push(`- **v${n.version}** \u2014 ${n.summary}`);for(let o of n.addedPaths)r.push(` - \`${o}\``)}return r.push("","Merge to apply. CodePipe re-checks the stamp on the next daemon start and","clears the \u201Ccontext outdated\u201D badge.","","_Opened automatically by the CodePipe CLI._"),r.join(`
944
- `)}async function $f(t,e,r,n){let o=Ic(t);await o.pull(void 0,void 0,["--rebase"]).catch(()=>{});let i=Ei(t,e);if(!i.outdated)return i;let s=kx(i.currentVersion),a=r?.branch??(await o.revparse(["--abbrev-ref","HEAD"]).catch(()=>"main")).trim();try{await o.fetch().catch(()=>{}),(await o.raw(["ls-remote","--heads","origin",s]).catch(()=>"")).trim().length===0?await $x(t,e,r,i,s,a,n):n.info(`[ctx] migration branch ${s} already on origin \u2014 reusing`)}catch(l){return n.warn(`[ctx] context migration branch failed (will retry next start): ${l instanceof Error?l.message:String(l)}`),i}if(!r)return i;let c={name:r.name,host:r.host,owner:r.owner,repoName:r.name};try{let l=Sr(c),u=await l.findOpenPrByBranch?.(c,s)??null;if(u)return n.info(`[ctx] migration PR already open: ${u.url}`),{...i,migrationPrUrl:u.url};let p=await l.createPullRequest(c,{type:"create_pr",taskId:`context-migration::${e}`,repoName:r.name,branchName:s,baseBranch:a,title:`CodePipe: context format v${i.templateVersion} \u2192 v${i.currentVersion}`,body:bx(i)});return n.info(`[ctx] migration PR opened: ${p.url}`),{...i,migrationPrUrl:p.url}}catch(l){return n.warn(`[ctx] migration PR create/find failed (branch pushed, badge without link): ${l instanceof Error?l.message:String(l)}`),i}}async function $x(t,e,r,n,o,i,s){let a=Ic(t),c=gx(Ii(yx(),"codepipe-ctx-migration-"));try{await a.raw(["worktree","add","--force","-B",o,c,`origin/${i}`]);let l={projectId:e,name:e,automationLevel:"assisted",repos:[]},u={host:r?.host??"github",owner:r?.owner??e,name:r?.name??`${e}-codepipe-ctx`},p=new Map(un(l,u).map(g=>[g.path,g.content])),d=0;for(let g of n.missingPaths){if(g===gt)continue;let k=p.get(g);if(k==null){s.warn(`[ctx] migration: no template for ${g} \u2014 skipped`);continue}let h=Ii(c,g);wf(h)||(hx(wx(h),{recursive:!0}),bf(h,k),d++)}bf(Ii(c,gt),Vn(n.currentVersion)),d++;let m=Ii(c,Gr);wf(m)&&(kf(m,{force:!0}),d++);let f=Ic(c);await f.add(["-A","--",".",":(exclude)project.yaml",":(exclude)regimen.yaml"]),await f.commit(`chore(context): migrate format v${n.templateVersion} -> v${n.currentVersion}`),await f.push(["-u","origin",o]),s.info(`[ctx] migration branch ${o} pushed (${d} file(s))`)}finally{await a.raw(["worktree","remove","--force",c]).catch(()=>{}),kf(c,{recursive:!0,force:!0}),await a.raw(["branch","-D",o]).catch(()=>{})}}import{existsSync as vx,readFileSync as xx,writeFileSync as Sx}from"node:fs";import{homedir as Ex}from"node:os";import{join as vf}from"node:path";import{parseDocument as Tx}from"yaml";function Ix(t){let e={name:t.name,host:t.host,owner:t.owner,repo:t.repoName,mount_as:t.mountAs??t.name};return t.defaultBranch&&(e.default_branch=t.defaultBranch),e}function Rx(t,e){let r=Tx(t);return r.set("repos",e.map(Ix)),r.toString()}function Cx(t,e){let r=[vf(Ex(),".codepipe","profiles",t,"context-config","project.yaml")];return e&&r.push(vf(e,"project.yaml")),r}function wo(t,e,r){let n=[],o=[];for(let i of Cx(t,r))if(vx(i))try{let s=xx(i,"utf-8"),a=Rx(s,e);a!==s&&(Sx(i,a),n.push(i))}catch(s){o.push({path:i,error:s instanceof Error?s.message:String(s)})}return{updated:n,errors:o}}ko();ut();fe();function Bx(t,e){let r={};t.github?.token&&(r.github={token:t.github.token}),t.bitbucket?.apiToken&&(r.bitbucket={apiToken:t.bitbucket.apiToken}),t.gitlab?.token&&(r.gitlab={token:t.gitlab.token});let n=e??t.claude?.oauthToken;return n&&(r.claudeOauthToken=n),t.contextWrite?.token&&(r.contextWrite={token:t.contextWrite.token}),t.mirrorWrite?.token&&(r.mirrorWrite={token:t.mirrorWrite.token}),r}function Lf(t,e,r,n){let o=Bx(e,r);t.sandboxes.length>0&&!o.claudeOauthToken&&n.warn("[cred] no Claude OAuth token set \u2014 agent jobs will fail in the SANDBOX. Set one with `codepipe login` (per project) or `make farm-config` (shared farm token)."),t.sandboxes.length>0&&!o.contextWrite&&(o.github||o.gitlab||o.bitbucket)&&n.warn("[cred] no dedicated contextWrite token \u2014 SANDBOX pushes deliveries with the project token of the context repo's host (broader scope than necessary). Set secrets.contextWrite.token (a token scoped to the Context Repo only) to tighten. NOTE (GitHub): the push token MUST have the `workflow` scope, else delivery pushes that carry `.github/workflows/*` are rejected.");let i=JSON.stringify(o),s=[];for(let a of t.sandboxes){let c=ci(t.projectId,a.sandboxId,a.fingerprint);if(c==="mismatch"){n.warn(`[cred] SANDBOX ${a.name} (${a.sandboxId}) key fingerprint CHANGED \u2014 refusing to seal creds. Expected the pinned key; got ${a.fingerprint}. If this is intentional, clear the pin in the secrets file and re-run.`);continue}c==="pinned"&&n.info(`[cred] pinned SANDBOX ${a.name} (${a.sandboxId}) fingerprint ${a.fingerprint}`);let l;try{l=Bt(a.publicKey,i)}catch(u){n.warn(`[cred] failed to seal bundle for ${a.sandboxId}: ${u instanceof Error?u.message:String(u)}`);continue}s.push({type:"sandbox_bundle",projectId:t.projectId,sandboxId:a.sandboxId,sealed:l})}return s}ut();fe();Vt();Er();nn();Ai();function Bf(t){let e=q(t);if(!e)return null;if(!e.sealKey){let r=Pi();e.sealKey={publicKey:r.publicKey,privateKey:r.privateKey},ae(e)}return{publicKey:e.sealKey.publicKey,privateKey:e.sealKey.privateKey,fingerprint:Ke(e.sealKey.publicKey)}}async function Ff(t,e,r,n){let o;try{o=JSON.parse(pn(n,r).toString("utf-8"))}catch(s){return{ok:!1,detail:`cannot open the sealed credential (${s instanceof Error?s.message:String(s)}) \u2014 wrong channel key?`}}let i=q(t);if(!i)return{ok:!1,detail:"no secrets file for this project on the CLI"};try{switch(e){case"github":{if(!o.token)return{ok:!1,detail:"payload has no token"};let s=await qt(o.token);return i.github={token:o.token},fn(i,()=>{process.env.GH_TOKEN=o.token,Mf(o.token)}),{ok:!0,detail:`authenticated as ${s}`}}case"gitlab":{if(!o.token)return{ok:!1,detail:"payload has no token"};let s=await zt(o.token);return i.gitlab={token:o.token},fn(i,()=>{process.env.GITLAB_TOKEN=o.token,Df(o.token)}),{ok:!0,detail:`authenticated as ${s}`}}case"bitbucket":{if(!o.email||!o.apiToken)return{ok:!1,detail:"payload needs email + apiToken"};let s=await Yt(o.email,o.apiToken);return i.bitbucket={email:o.email,apiToken:o.apiToken},fn(i,()=>{process.env.BITBUCKET_EMAIL=o.email,process.env.BITBUCKET_API_TOKEN=o.apiToken,Uf(o.apiToken)}),{ok:!0,detail:`authenticated as ${s}`}}case"youtrack":{if(!o.token)return{ok:!1,detail:"payload has no token"};let s=o.url?.trim().replace(/\/$/,"")||i.youtrack?.url;if(!s)return{ok:!1,detail:"no YouTrack URL (send one with the token)"};let a=await Jt({baseUrl:s,token:o.token});return i.youtrack={url:s,token:o.token},fn(i,()=>{process.env.YOUTRACK_URL=s,process.env.YOUTRACK_TOKEN=o.token}),{ok:!0,detail:`authenticated as ${a}`}}case"claude":{if(!o.token)return{ok:!1,detail:"payload has no token"};let s=await Dt(o.token);return s==="invalid"?{ok:!1,detail:"Claude token rejected (401) \u2014 previous token kept"}:(i.claude={oauthToken:o.token},fn(i,()=>{}),{ok:!0,...s==="inconclusive"?{detail:"saved (live check inconclusive)"}:{}})}case"contextWrite":return o.token?(i.contextWrite={token:o.token},fn(i,()=>{}),{ok:!0,detail:"saved (verified on the next readiness pass)"}):{ok:!1,detail:"payload has no token"};default:return{ok:!1,detail:`unknown credential kind '${e}'`}}}catch(s){return{ok:!1,detail:`${s instanceof Error?s.message:String(s)} \u2014 previous credential kept`}}}function fn(t,e){ae(t),e()}F();F();import{spawn as Fx}from"node:child_process";var Gx=124,Gf=16*1024,Kf=4e3;function Kx(t,e,r,n,o,i){let s={...t},a=(c,l)=>{Ot(c)||(s[c]=l)};for(let[c,l]of Object.entries(e))a(c,l);for(let[c,l]of Object.entries(r))a(c,l);for(let[c,l]of Object.entries(n??{}))a(c,l);for(let[c,l]of Object.entries(o))s[c]=l;for(let[c,l]of Object.entries(i))s[`INPUT_${c}`]=String(l);return s}async function Hf(t){let{def:e,onEvent:r}=t,n=Kx(t.baseEnv??process.env,t.variables,t.secrets,e.env,t.credEnv,t.input),o="",i=a=>{o+=a+`
944
+ `)}async function $f(t,e,r,n){let o=Ic(t);await o.pull(void 0,void 0,["--rebase"]).catch(()=>{});let i=Ei(t,e);if(!i.outdated)return i;let s=kx(i.currentVersion),a=r?.branch??(await o.revparse(["--abbrev-ref","HEAD"]).catch(()=>"main")).trim();try{await o.fetch().catch(()=>{}),(await o.raw(["ls-remote","--heads","origin",s]).catch(()=>"")).trim().length===0?await $x(t,e,r,i,s,a,n):n.info(`[ctx] migration branch ${s} already on origin \u2014 reusing`)}catch(l){return n.warn(`[ctx] context migration branch failed (will retry next start): ${l instanceof Error?l.message:String(l)}`),i}if(!r)return i;let c={name:r.name,host:r.host,owner:r.owner,repoName:r.name};try{let l=Sr(c),u=await l.findOpenPrByBranch?.(c,s)??null;if(u)return n.info(`[ctx] migration PR already open: ${u.url}`),{...i,migrationPrUrl:u.url};let p=await l.createPullRequest(c,{type:"create_pr",taskId:`context-migration::${e}`,repoName:r.name,branchName:s,baseBranch:a,title:`CodePipe: context format v${i.templateVersion} \u2192 v${i.currentVersion}`,body:bx(i)});return n.info(`[ctx] migration PR opened: ${p.url}`),{...i,migrationPrUrl:p.url}}catch(l){return n.warn(`[ctx] migration PR create/find failed (branch pushed, badge without link): ${l instanceof Error?l.message:String(l)}`),i}}async function $x(t,e,r,n,o,i,s){let a=Ic(t),c=gx(Ii(yx(),"codepipe-ctx-migration-"));try{await a.raw(["worktree","add","--force","-B",o,c,`origin/${i}`]);let l={projectId:e,name:e,automationLevel:"assisted",repos:[]},u={host:r?.host??"github",owner:r?.owner??e,name:r?.name??`${e}-codepipe-ctx`},p=new Map(un(l,u).map(g=>[g.path,g.content])),d=0;for(let g of n.missingPaths){if(g===gt)continue;let k=p.get(g);if(k==null){s.warn(`[ctx] migration: no template for ${g} \u2014 skipped`);continue}let h=Ii(c,g);wf(h)||(hx(wx(h),{recursive:!0}),bf(h,k),d++)}bf(Ii(c,gt),Vn(n.currentVersion)),d++;let m=Ii(c,Gr);wf(m)&&(kf(m,{force:!0}),d++);let f=Ic(c);await f.add(["-A","--",".",":(exclude)project.yaml",":(exclude)regimen.yaml"]),await f.commit(`chore(context): migrate format v${n.templateVersion} -> v${n.currentVersion}`),await f.push(["-u","origin",o]),s.info(`[ctx] migration branch ${o} pushed (${d} file(s))`)}finally{await a.raw(["worktree","remove","--force",c]).catch(()=>{}),kf(c,{recursive:!0,force:!0}),await a.raw(["branch","-D",o]).catch(()=>{})}}import{existsSync as vx,readFileSync as xx,writeFileSync as Sx}from"node:fs";import{homedir as Ex}from"node:os";import{join as vf}from"node:path";import{parseDocument as Tx}from"yaml";function Ix(t){let e={name:t.name,host:t.host,owner:t.owner,repo:t.repoName,mount_as:t.mountAs??t.name};return t.defaultBranch&&(e.default_branch=t.defaultBranch),e}function Rx(t,e){let r=Tx(t);return r.set("repos",e.map(Ix)),r.toString()}function Cx(t,e){let r=[vf(Ex(),".codepipe","profiles",t,"context-config","project.yaml")];return e&&r.push(vf(e,"project.yaml")),r}function wo(t,e,r){let n=[],o=[];for(let i of Cx(t,r))if(vx(i))try{let s=xx(i,"utf-8"),a=Rx(s,e);a!==s&&(Sx(i,a),n.push(i))}catch(s){o.push({path:i,error:s instanceof Error?s.message:String(s)})}return{updated:n,errors:o}}ko();ut();fe();function Bx(t,e){let r={};t.github?.token&&(r.github={token:t.github.token}),t.bitbucket?.apiToken&&(r.bitbucket={apiToken:t.bitbucket.apiToken}),t.gitlab?.token&&(r.gitlab={token:t.gitlab.token});let n=e??t.claude?.oauthToken;return n&&(r.claudeOauthToken=n),t.contextWrite?.token&&(r.contextWrite={token:t.contextWrite.token}),t.mirrorWrite?.token&&(r.mirrorWrite={token:t.mirrorWrite.token,...t.mirrorWrite.host?{host:t.mirrorWrite.host}:{}}),r}function Lf(t,e,r,n){let o=Bx(e,r);t.sandboxes.length>0&&!o.claudeOauthToken&&n.warn("[cred] no Claude OAuth token set \u2014 agent jobs will fail in the SANDBOX. Set one with `codepipe login` (per project) or `make farm-config` (shared farm token)."),t.sandboxes.length>0&&!o.contextWrite&&(o.github||o.gitlab||o.bitbucket)&&n.warn("[cred] no dedicated contextWrite token \u2014 SANDBOX pushes deliveries with the project token of the context repo's host (broader scope than necessary). Set secrets.contextWrite.token (a token scoped to the Context Repo only) to tighten. NOTE (GitHub): the push token MUST have the `workflow` scope, else delivery pushes that carry `.github/workflows/*` are rejected.");let i=JSON.stringify(o),s=[];for(let a of t.sandboxes){let c=ci(t.projectId,a.sandboxId,a.fingerprint);if(c==="mismatch"){n.warn(`[cred] SANDBOX ${a.name} (${a.sandboxId}) key fingerprint CHANGED \u2014 refusing to seal creds. Expected the pinned key; got ${a.fingerprint}. If this is intentional, clear the pin in the secrets file and re-run.`);continue}c==="pinned"&&n.info(`[cred] pinned SANDBOX ${a.name} (${a.sandboxId}) fingerprint ${a.fingerprint}`);let l;try{l=Bt(a.publicKey,i)}catch(u){n.warn(`[cred] failed to seal bundle for ${a.sandboxId}: ${u instanceof Error?u.message:String(u)}`);continue}s.push({type:"sandbox_bundle",projectId:t.projectId,sandboxId:a.sandboxId,sealed:l})}return s}ut();fe();Vt();Er();nn();Ai();function Bf(t){let e=q(t);if(!e)return null;if(!e.sealKey){let r=Pi();e.sealKey={publicKey:r.publicKey,privateKey:r.privateKey},ae(e)}return{publicKey:e.sealKey.publicKey,privateKey:e.sealKey.privateKey,fingerprint:Ke(e.sealKey.publicKey)}}async function Ff(t,e,r,n){let o;try{o=JSON.parse(pn(n,r).toString("utf-8"))}catch(s){return{ok:!1,detail:`cannot open the sealed credential (${s instanceof Error?s.message:String(s)}) \u2014 wrong channel key?`}}let i=q(t);if(!i)return{ok:!1,detail:"no secrets file for this project on the CLI"};try{switch(e){case"github":{if(!o.token)return{ok:!1,detail:"payload has no token"};let s=await qt(o.token);return i.github={token:o.token},fn(i,()=>{process.env.GH_TOKEN=o.token,Mf(o.token)}),{ok:!0,detail:`authenticated as ${s}`}}case"gitlab":{if(!o.token)return{ok:!1,detail:"payload has no token"};let s=await zt(o.token);return i.gitlab={token:o.token},fn(i,()=>{process.env.GITLAB_TOKEN=o.token,Df(o.token)}),{ok:!0,detail:`authenticated as ${s}`}}case"bitbucket":{if(!o.email||!o.apiToken)return{ok:!1,detail:"payload needs email + apiToken"};let s=await Yt(o.email,o.apiToken);return i.bitbucket={email:o.email,apiToken:o.apiToken},fn(i,()=>{process.env.BITBUCKET_EMAIL=o.email,process.env.BITBUCKET_API_TOKEN=o.apiToken,Uf(o.apiToken)}),{ok:!0,detail:`authenticated as ${s}`}}case"youtrack":{if(!o.token)return{ok:!1,detail:"payload has no token"};let s=o.url?.trim().replace(/\/$/,"")||i.youtrack?.url;if(!s)return{ok:!1,detail:"no YouTrack URL (send one with the token)"};let a=await Jt({baseUrl:s,token:o.token});return i.youtrack={url:s,token:o.token},fn(i,()=>{process.env.YOUTRACK_URL=s,process.env.YOUTRACK_TOKEN=o.token}),{ok:!0,detail:`authenticated as ${a}`}}case"claude":{if(!o.token)return{ok:!1,detail:"payload has no token"};let s=await Dt(o.token);return s==="invalid"?{ok:!1,detail:"Claude token rejected (401) \u2014 previous token kept"}:(i.claude={oauthToken:o.token},fn(i,()=>{}),{ok:!0,...s==="inconclusive"?{detail:"saved (live check inconclusive)"}:{}})}case"contextWrite":return o.token?(i.contextWrite={token:o.token},fn(i,()=>{}),{ok:!0,detail:"saved (verified on the next readiness pass)"}):{ok:!1,detail:"payload has no token"};default:return{ok:!1,detail:`unknown credential kind '${e}'`}}}catch(s){return{ok:!1,detail:`${s instanceof Error?s.message:String(s)} \u2014 previous credential kept`}}}function fn(t,e){ae(t),e()}F();F();import{spawn as Fx}from"node:child_process";var Gx=124,Gf=16*1024,Kf=4e3;function Kx(t,e,r,n,o,i){let s={...t},a=(c,l)=>{Ot(c)||(s[c]=l)};for(let[c,l]of Object.entries(e))a(c,l);for(let[c,l]of Object.entries(r))a(c,l);for(let[c,l]of Object.entries(n??{}))a(c,l);for(let[c,l]of Object.entries(o))s[c]=l;for(let[c,l]of Object.entries(i))s[`INPUT_${c}`]=String(l);return s}async function Hf(t){let{def:e,onEvent:r}=t,n=Kx(t.baseEnv??process.env,t.variables,t.secrets,e.env,t.credEnv,t.input),o="",i=a=>{o+=a+`
945
945
  `,o.length>Gf&&(o=o.slice(o.length-Gf))},s=(a,c)=>{let l=c.length>Kf?c.slice(0,Kf)+"\u2026":c;i(l),r({ts:Date.now(),kind:"log",stream:a,text:l})};r({ts:Date.now(),kind:"start",status:"running"});for(let[a,c]of e.steps.entries()){let l=c.name??`step ${a+1}`;r({ts:Date.now(),kind:"step",stepName:l});let u=await Hx(c.run,c.timeout_sec,t.cwd,n,s);if(u!==0)return i(`[${l}] exited with code ${u}`),r({ts:Date.now(),kind:"result",status:"failed",exitCode:u,failedStep:l}),{status:"failed",exitCode:u,failedStep:l,logTail:o}}return r({ts:Date.now(),kind:"result",status:"succeeded",exitCode:0}),{status:"succeeded",exitCode:0,logTail:o}}function Hx(t,e,r,n,o){return new Promise(i=>{let s=Fx("bash",["-lc",t],{cwd:r,env:n,stdio:["ignore","pipe","pipe"]}),a=!1,c=(e??ba)*1e3,l=setTimeout(()=>{a=!0,o("stderr",`step timed out after ${c/1e3}s \u2014 killing`),s.kill("SIGTERM"),setTimeout(()=>s.kill("SIGKILL"),5e3).unref()},c);l.unref?.();let u=m=>{let f="";return{data:g=>{f+=g.toString("utf-8");let k;for(;(k=f.indexOf(`
946
946
  `))!==-1;)o(m,f.slice(0,k).replace(/\r$/,"")),f=f.slice(k+1)},flush:()=>{f.length>0&&o(m,f.replace(/\r$/,"")),f=""}}},p=u("stdout"),d=u("stderr");s.stdout?.on("data",p.data),s.stderr?.on("data",d.data),s.on("error",m=>{clearTimeout(l),o("stderr",`spawn failed: ${m.message}`),i(127)}),s.on("close",(m,f)=>{clearTimeout(l),p.flush(),d.flush(),i(a?Gx:m??(f?1:0))})})}lt();lt();import{existsSync as Wx,readFileSync as qx,statSync as Wf}from"node:fs";var qf=2*1024*1024;function Yx(t){return Buffer.from(t.toString("utf-8"),"utf-8").equals(t)}function Yf(t,e){let r=Se(t,e);if(e.split("/").some(i=>i===".git"))throw new Error(`not a context file: ${e}`);if(!Wx(r)||!Wf(r).isFile())throw new Error(`file not found: ${e}`);let{size:n}=Wf(r);if(n>qf)throw new Error(`file too large: ${e} is ${n} bytes (limit ${qf})`);let o=qx(r);return Yx(o)?{content:o.toString("utf-8"),encoding:"utf8",sizeBytes:o.length}:{content:o.toString("base64"),encoding:"base64",sizeBytes:o.length}}fe();F();import{existsSync as zx,readFileSync as Vx,writeFileSync as Xx}from"node:fs";import{join as Jx}from"node:path";import{parseDocument as Zx}from"yaml";async function zf(t,e){if(e.length===0)return{files:[]};let r=new Map;for(let o of e){let i=Ca(o);if(!i.ok)throw new Error(i.error);let s=r.get(o.file)??[];s.push({path:i.field.path,value:i.value}),r.set(o.file,s)}let n=[];for(let[o,i]of r){let s=Jx(t,o);if(!zx(s))throw new Error(`${o} not found in context repo (${t})`);let a=Zx(Vx(s,"utf-8"));for(let c of i)c.value===null?a.deleteIn(c.path):a.setIn(c.path,c.value);Xx(s,a.toString()),n.push(o)}return{files:n}}Nc();import{existsSync as Oc,readFileSync as Lc,writeFileSync as Qx}from"node:fs";import{join as ji}from"node:path";import{parseDocument as Mc}from"yaml";async function rm(t,e){let r=[];if(e.stageField!==void 0||e.sourceColumns!==void 0||e.rejectColumns!==void 0||e.doneColumns!==void 0||e.reviewColumns!==void 0||e.statusColumns!==void 0||e.backlogColumn!==void 0||e.assignee!==void 0||e.requireAssignee!==void 0||e.backlogScope!==void 0){let i=ji(t,"project.yaml");if(!Oc(i))throw new Error(`project.yaml not found in context repo (${t})`);let s=Mc(Lc(i,"utf-8"));if(e.stageField!==void 0){let a=typeof e.stageField=="string"?e.stageField.trim():"";a&&a!=="Stage"?s.setIn(["youtrack","stage_field"],a):s.deleteIn(["youtrack","stage_field"])}if(e.rejectColumns!==void 0){let a=e.rejectColumns.map(c=>typeof c=="string"?c.trim():"").filter(c=>c.length>0);a.length>0?s.setIn(["youtrack","reject_columns"],a):s.deleteIn(["youtrack","reject_columns"])}if(e.doneColumns!==void 0){let a=e.doneColumns.map(c=>typeof c=="string"?c.trim():"").filter(c=>c.length>0);a.length>0?s.setIn(["youtrack","done_columns"],a):s.deleteIn(["youtrack","done_columns"])}if(e.reviewColumns!==void 0){let a=e.reviewColumns.map(c=>typeof c=="string"?c.trim():"").filter(c=>c.length>0);a.length>0?s.setIn(["youtrack","review_columns"],a):s.deleteIn(["youtrack","review_columns"])}if(e.statusColumns!==void 0){let a=e.statusColumns.map(c=>typeof c=="string"?c.trim():"").filter(c=>c.length>0);a.length>0?s.setIn(["youtrack","status_columns"],a):s.deleteIn(["youtrack","status_columns"])}if(e.sourceColumns!==void 0){let a=e.sourceColumns.map(c=>typeof c=="string"?c.trim():"").filter(c=>c.length>0);if(a.length===0)throw new Error("source_columns must be a non-empty list of non-empty strings");s.setIn(["youtrack","source_columns"],a)}if(e.backlogColumn!==void 0){let a=typeof e.backlogColumn=="string"?e.backlogColumn.trim():"";a?s.setIn(["youtrack","backlog_column"],a):s.deleteIn(["youtrack","backlog_column"])}if(e.assignee!==void 0){let a=typeof e.assignee=="string"?e.assignee.trim():"";a?s.setIn(["youtrack","assignee"],a):s.deleteIn(["youtrack","assignee"])}e.requireAssignee!==void 0&&s.setIn(["youtrack","require_assignee"],e.requireAssignee===!0),e.backlogScope!==void 0&&(e.backlogScope==="personal"?s.setIn(["youtrack","backlog_scope"],"personal"):e.backlogScope==="shared"?s.setIn(["youtrack","backlog_scope"],"shared"):s.deleteIn(["youtrack","backlog_scope"])),r.push({path:"project.yaml",content:s.toString()})}if(e.reviewStatus!==void 0||e.writes!==void 0){let i=ji(t,"regimen.yaml");if(!Oc(i))throw new Error(`regimen.yaml not found in context repo (${t})`);let s=Mc(Lc(i,"utf-8"));if(e.reviewStatus!==void 0){let a=e.reviewStatus.trim();a&&s.setIn(["youtrack","review_status"],a)}if(e.writes!==void 0){let a=e.writes;s.setIn(["youtrack","writes","enabled"],a.enabled===!0),s.setIn(["youtrack","writes","status_changes"],a.statusChanges===!0),s.setIn(["youtrack","writes","pr_comment"],a.prComment===!0),s.setIn(["youtrack","writes","dashboard_mirror"],a.dashboardMirror===!0)}r.push({path:"regimen.yaml",content:s.toString()})}if(r.length===0)return{files:[]};for(let i of r)Qx(ji(t,i.path),i.content);return{files:r.map(i=>i.path)}}function Ni(t){if(!t)return"Stage";try{let e=ji(t,"project.yaml");if(!Oc(e))return"Stage";let n=Mc(Lc(e,"utf-8")).getIn(["youtrack","stage_field"]);return typeof n=="string"&&n.trim().length>0?n.trim():"Stage"}catch{return"Stage"}}Vt();Ri();ko();F();lt();import{existsSync as vS,readFileSync as xS}from"node:fs";import{join as Ym}from"node:path";import{simpleGit as Jc}from"simple-git";F();import{existsSync as nm,readFileSync as om,readdirSync as eS}from"node:fs";import{join as Dc}from"node:path";import{simpleGit as tS}from"simple-git";function rS(t,e){let r=/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(e);if(!r)return null;let n="",o="";for(let s of r[1].split(`
947
947
  `)){let a=/^(\w+):\s*(.+)$/.exec(s.trim());a&&(a[1]==="repo"&&(n=a[2].trim()),a[1]==="path"&&(o=a[2].trim().replace(/^\.\//,"")))}let i=r[2].trim();return!n||!o||!i||o.includes("..")||o.startsWith("/")?null:{repo:n,path:o,body:i,source:t}}function nS(t,e){let r=Dc(t,`tasks/${e}/annotations`);if(!nm(r))return[];let n=[];for(let o of eS(r).sort())if(o.endsWith(".md")){try{let i=rS(o,om(Dc(r,o),"utf-8"));i&&n.push(i)}catch{}if(n.length>=oa)break}return n}var oS=12;async function im(t){let{contextDir:e,taskKey:r,repoName:n,repoDir:o,commitSha:i,date:s,touchedKeys:a,identity:c}=t;if(!c)return[];let l=new Map(c.entities.filter(d=>d.status==="active").map(d=>[d.currentKey,d.entityId])),u=tS(o),p=[];for(let d of nS(e,r)){if(d.repo!==n)continue;let m=ye("code",n,d.path);if(!a.has(m))continue;let f=l.get(m);if(!f)continue;let g=(await u.raw(["rev-parse",`${i}:${d.path}`]).catch(()=>"")).trim().slice(0,oS),k=Zs(f),h=Dc(e,k),w=p.find(I=>I.path===k),$=w?.content??(nm(h)?om(h,"utf-8"):null),S=`<!-- ${r}${g?`:${g}`:""} -->`;if($?.includes(S))continue;let T=$??`---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-partner/codepipe",
3
- "version": "0.12.1-dev.249.gc370d3a",
3
+ "version": "0.12.1-dev.250.g9a27fd7",
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",