@code-partner/codepipe 0.13.1-dev.278.gbdb59f5 → 0.13.1-dev.279.g10ce2c9

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 +2 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var $b=Object.defineProperty;var x=(t,e)=>()=>(t&&(e=t(t=0)),e);var Fe=(t,e)=>{for(var r in e)$b(t,r,{get:e[r],enumerable:!0})};var Ve,ht,Qs=x(()=>{"use strict";Ve="0.13.1-dev.278.gbdb59f5",ht="https://hub.dev.codepipe.dev"});function Jn(t){return typeof t!="number"||!Number.isFinite(t)?!1:t>=Iu&&t<=gt}var gt,Iu,Cu=x(()=>{"use strict";Qs();gt=4,Iu=4});var Pu=x(()=>{"use strict";Qs()});function Zn(t=6){return`# CodePipe Context Repo format version.
2
+ var $b=Object.defineProperty;var x=(t,e)=>()=>(t&&(e=t(t=0)),e);var Fe=(t,e)=>{for(var r in e)$b(t,r,{get:e[r],enumerable:!0})};var Ve,ht,Qs=x(()=>{"use strict";Ve="0.13.1-dev.279.g10ce2c9",ht="https://hub.dev.codepipe.dev"});function Jn(t){return typeof t!="number"||!Number.isFinite(t)?!1:t>=Iu&&t<=gt}var gt,Iu,Cu=x(()=>{"use strict";Qs();gt=4,Iu=4});var Pu=x(()=>{"use strict";Qs()});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 ta(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 ra(t,e=ea){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 na(t,e=ea){return e.filter(r=>r.version>t)}var Au,yt,qr,ea,_u=x(()=>{"use strict";Au=6,yt=".codepipe-context.yaml",qr=".devpipe-context.yaml",ea=[{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",yt]},{version:2,summary:"Rename the format-version stamp .devpipe-context.yaml \u2192 .codepipe-context.yaml (drop the devpipe-brand leftover)",addedPaths:[yt]},{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 eo(t){return`model/facts/identity/${t}.yaml`}function kr(t){return`model/facts/events/${t}.yaml`}function sa(t){return`model/facts/annotations/${t}.md`}function aa(t){return`model/derived/correlates/${t}.yaml`}function ca(t){return`model/derived/touched/${t}.yaml`}function ju(t){return t===""?"root":t.replace(/\//g,"-")}function la(t,e){return`model/derived/structure/${t}/${ju(e)}.yaml`}function ti(t){return typeof t=="string"&&Ou.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(!Nu.includes(n))return null;let o=t.slice(e+1,r),i=t.slice(r+1);return o===""&&!Tb.includes(n)||i===""?null:{level:n,repo:o,path:i}}function Ee(t){return`task::${t}`}function we(t,e,r){return`${t}:${e}:${r}`}function to(t){let e=[];return xt(t)?(ni(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(!xt(r)){e.push(`edges[${n}]: not an object`);return}ua.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 Lu(t){return{...t,edges:Yr(t.edges,e=>`${e.kind} ${e.from} ${e.to}`)}}function br(t){return vr(Lu(t))}function xt(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function ni(t){return typeof t=="number"&&Number.isInteger(t)&&t>0}function wt(t){return typeof t=="string"&&t.length>0}function Ib(t){return t.modelFormatVersion!==2}function Ot(t){let e=[];if(!xt(t))return{ok:!1,errors:["shard: not an object"]};ni(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),wt(t.repo)||e.push("repo: missing or empty"),wt(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(!xt(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&&!ti(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(!xt(o)){e.push(`edges[${i}]: not an object`);return}ua.includes(o.kind)||e.push(`edges[${i}].kind: unknown "${String(o.kind)}"`),(!wt(o.to)||!re(o.to))&&e.push(`edges[${i}].to: malformed nodeKey`),(!wt(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 ro(t){let e=[];if(!xt(t))return{ok:!1,errors:["identity: not an object"]};if(ni(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),wt(t.repo)||e.push("repo: missing or empty"),t.builtFromCommit!==void 0&&!wt(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(!xt(n)){e.push(`entities[${o}]: not an object`);return}ti(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`),wt(n.firstSeen)||e.push(`entities[${o}].firstSeen: missing`),wt(n.lastSeen)||e.push(`entities[${o}].lastSeen: missing`),n.aliases!==void 0&&(Array.isArray(n.aliases)?n.aliases.forEach((i,s)=>{(!xt(i)||!re(i.key)||!wt(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 Lt(t){let e=[];return xt(t)?(ni(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),wt(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=>!wt(r)))&&e.push("commits: not an array of non-empty strings"),Array.isArray(t.files)?t.files.forEach((r,n)=>{if(!xt(r)||!re(r.key)){e.push(`files[${n}].key: malformed nodeKey`);return}r.entityId!==void 0&&!ti(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 Yr(t,e){return[...t].sort((r,n)=>e(r)<e(n)?-1:e(r)>e(n)?1:0)}function Mu(t){return{...t,nodes:Yr(t.nodes,e=>e.key),edges:Yr(t.edges,e=>`${e.kind}\0${e.from}\0${e.to}`)}}function Du(t){return{...t,entities:Yr(t.entities,e=>e.entityId).map(e=>e.aliases?{...e,aliases:Yr(e.aliases,r=>`${r.key}\0${r.until}`)}:e)}}function Uu(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:Yr(t.files,r=>r.key),...e?{links:e}:{}}}function Qn(t){return Cb.test(t)?t:JSON.stringify(t)}function Bu(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 Fu(t){return t===null||["boolean","number","string"].includes(typeof t)}function oa(t){return Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[r])=>e<r?-1:e>r?1:0)}function Gu(t,e,r){if(Array.isArray(t)){for(let n of t)if(Fu(n))r.push(`${e}- ${Bu(n)}`);else{if(Array.isArray(n))throw new Error("model yaml: nested arrays are not part of the model schema");{let o=oa(n);if(o.length===0){r.push(`${e}- {}`);continue}o.forEach(([i,s],a)=>{let c=a===0?`${e}- `:`${e} `;ia(i,s,c,`${e} `,r)})}}return}for(let[n,o]of oa(t))ia(n,o,e,e,r)}function ia(t,e,r,n,o){if(Fu(e))o.push(`${r}${Qn(t)}: ${Bu(e)}`);else if(Array.isArray(e))e.length===0?o.push(`${r}${Qn(t)}: []`):(o.push(`${r}${Qn(t)}:`),Gu(e,`${n} `,o));else{let i=oa(e);if(i.length===0)o.push(`${r}${Qn(t)}: {}`);else{o.push(`${r}${Qn(t)}:`);for(let[s,a]of i)ia(s,a,`${n} `,`${n} `,o)}}}function vr(t){let e=[];return Gu(t,"",e),e.join(`
@@ -949,7 +949,7 @@ starting codepipe up \u2014 the CLI daemon and an agent worker, with their logs
949
949
  - **Status:** superseded by ADR-${r}`):n}function Jv(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(`
950
950
  `)+`
951
951
  `}async function mf(t,e,r,n=new Date().toISOString().slice(0,10),o="task"){try{await Wv(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=Te(t,i(k));if(!Ac(h)){a.push(k);continue}s.push({slug:k,content:pf(h,"utf-8")})}let c=ff(t,"adr"),l=new Map;if(Ac(c))for(let k of Hv(c)){let h=qv.exec(k);!h||k===Yv||l.set(k,{num:parseInt(h[1]??"",10),slug:h[2]??"",content:pf(ff(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}=Vv(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=Xv(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)Ac(Te(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:zv(w.content)}));p.set("INDEX.md",Jv(k))}for(let[k,h]of p.entries())f.push({path:`adr/${k}`,content:h});let y=d.length>0?`adr(${e}): promote ${s.map(k=>k.slug).join(", ")}`:`adr(${e}): drop stale staged ${m.join(", ")}`;return await Ce(t,f,y),{promoted:d,skipped:m,missing:a}}lt();Ci();Ft();B();import{existsSync as yf,readFileSync as sx}from"node:fs";import{join as wf}from"node:path";function ax(t){for(let e of[yt,qr]){let r=wf(t,e);if(yf(r))try{return ta(sx(r,"utf-8"))}catch{return 0}}return 0}function cx(t,e,r,n=6){let o=e<n,i=o?ra(e).filter(s=>!r(s)):[];return{type:"context_status",projectId:t,templateVersion:e,currentVersion:n,outdated:o,missingPaths:i}}function Pi(t,e){return cx(e,ax(t),r=>yf(wf(t,r)))}B();Jt();import{existsSync as Cf,mkdirSync as Lx,mkdtempSync as Mx,rmSync as Pf,writeFileSync as Af}from"node:fs";import{tmpdir as Dx}from"node:os";import{dirname as Ux,join as _i}from"node:path";import{simpleGit as Oc}from"simple-git";Ar();function Bx(t){return`codepipe/context-migration-v${t}`}function Fx(t){let e=na(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 \`${yt}\` stamp (renamed from \`${qr}\``,"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(`
952
- `)}async function _f(t,e,r,n){let o=Oc(t);await o.pull(void 0,void 0,["--rebase"]).catch(()=>{});let i=Pi(t,e);if(!i.outdated)return i;let s=Bx(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 Gx(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=Ir(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:Fx(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 Gx(t,e,r,n,o,i,s){let a=Oc(t),c=Mx(_i(Dx(),"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(hn(l,u).map(y=>[y.path,y.content])),d=0;for(let y of n.missingPaths){if(y===yt)continue;let k=p.get(y);if(k==null){s.warn(`[ctx] migration: no template for ${y} \u2014 skipped`);continue}let h=_i(c,y);Cf(h)||(Lx(Ux(h),{recursive:!0}),Af(h,k),d++)}Af(_i(c,yt),Zn(n.currentVersion)),d++;let m=_i(c,qr);Cf(m)&&(Pf(m,{force:!0}),d++);let f=Oc(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(()=>{}),Pf(c,{recursive:!0,force:!0}),await a.raw(["branch","-D",o]).catch(()=>{})}}import{existsSync as Kx,readFileSync as Hx,writeFileSync as Wx}from"node:fs";import{homedir as qx}from"node:os";import{join as jf}from"node:path";import{parseDocument as Yx}from"yaml";function zx(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 Vx(t,e){let r=Yx(t);return r.set("repos",e.map(zx)),r.toString()}function Xx(t,e){let r=[jf(qx(),".codepipe","profiles",t,"context-config","project.yaml")];return e&&r.push(jf(e,"project.yaml")),r}function $o(t,e,r){let n=[],o=[];for(let i of Xx(t,r))if(Kx(i))try{let s=Hx(i,"utf-8"),a=Vx(s,e);a!==s&&(Wx(i,a),n.push(i))}catch(s){o.push({path:i,error:s instanceof Error?s.message:String(s)})}return{updated:n,errors:o}}vo();dt();me();function aS(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 Yf(t,e,r,n){let o=aS(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=fi(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=Gt(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}dt();me();Jt();Cr();ln();Li();function Jf(t){let e=Y(t);if(!e)return null;if(!e.sealKey){let r=Oi();e.sealKey={publicKey:r.publicKey,privateKey:r.privateKey},ue(e)}return{publicKey:e.sealKey.publicKey,privateKey:e.sealKey.privateKey,fingerprint:He(e.sealKey.publicKey)}}async function Zf(t,e,r,n){let o;try{o=JSON.parse(yn(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=Y(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 zt(o.token);return i.github={token:o.token},wn(i,()=>{process.env.GH_TOKEN=o.token,zf(o.token)}),{ok:!0,detail:`authenticated as ${s}`}}case"gitlab":{if(!o.token)return{ok:!1,detail:"payload has no token"};let s=await Xt(o.token);return i.gitlab={token:o.token},wn(i,()=>{process.env.GITLAB_TOKEN=o.token,Vf(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 Vt(o.email,o.apiToken);return i.bitbucket={email:o.email,apiToken:o.apiToken},wn(i,()=>{process.env.BITBUCKET_EMAIL=o.email,process.env.BITBUCKET_API_TOKEN=o.apiToken,Xf(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 Qt({baseUrl:s,token:o.token});return i.youtrack={url:s,token:o.token},wn(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 Bt(o.token);return s==="invalid"?{ok:!1,detail:"Claude token rejected (401) \u2014 previous token kept"}:(i.claude={oauthToken:o.token},wn(i,()=>{}),{ok:!0,...s==="inconclusive"?{detail:"saved (live check inconclusive)"}:{}})}case"contextWrite":return o.token?(i.contextWrite={token:o.token},wn(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 wn(t,e){ue(t),e()}B();B();import{spawn as cS}from"node:child_process";var lS=124,Qf=16*1024,em=4e3;function uS(t,e,r,n,o,i){let s={...t},a=(c,l)=>{Mt(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 tm(t){let{def:e,onEvent:r}=t,n=uS(t.baseEnv??process.env,t.variables,t.secrets,e.env,t.credEnv,t.input),o="",i=a=>{o+=a+`
952
+ `)}async function _f(t,e,r,n){let o=Oc(t);await o.pull(void 0,void 0,["--rebase"]).catch(()=>{});let i=Pi(t,e);if(!i.outdated)return i;let s=Bx(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 Gx(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=Ir(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:Fx(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 Gx(t,e,r,n,o,i,s){let a=Oc(t),c=Mx(_i(Dx(),"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(hn(l,u).map(y=>[y.path,y.content])),d=0;for(let y of n.missingPaths){if(y===yt)continue;let k=p.get(y);if(k==null){s.warn(`[ctx] migration: no template for ${y} \u2014 skipped`);continue}let h=_i(c,y);Cf(h)||(Lx(Ux(h),{recursive:!0}),Af(h,k),d++)}Af(_i(c,yt),Zn(n.currentVersion)),d++;let m=_i(c,qr);Cf(m)&&(Pf(m,{force:!0}),d++);let f=Oc(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(()=>{}),Pf(c,{recursive:!0,force:!0}),await a.raw(["branch","-D",o]).catch(()=>{})}}import{existsSync as Kx,readFileSync as Hx,writeFileSync as Wx}from"node:fs";import{homedir as qx}from"node:os";import{join as jf}from"node:path";import{parseDocument as Yx}from"yaml";function zx(t,e){let r={name:t.name,host:t.host,owner:t.owner,repo:t.repoName,mount_as:t.mountAs??t.name};return t.defaultBranch&&(r.default_branch=t.defaultBranch),e!==void 0&&(r.mirror=e),r}function Vx(t,e){let r=Yx(t),n=new Map,o=r.toJS();for(let i of o?.repos??[]){if(!i||typeof i!="object")continue;let s=typeof i.name=="string"?i.name:String(i.repo??"");s&&i.mirror!==void 0&&i.mirror!==null&&n.set(s,i.mirror)}return r.set("repos",e.map(i=>zx(i,n.get(i.name)))),r.toString()}function Xx(t,e){let r=[jf(qx(),".codepipe","profiles",t,"context-config","project.yaml")];return e&&r.push(jf(e,"project.yaml")),r}function $o(t,e,r){let n=[],o=[];for(let i of Xx(t,r))if(Kx(i))try{let s=Hx(i,"utf-8"),a=Vx(s,e);a!==s&&(Wx(i,a),n.push(i))}catch(s){o.push({path:i,error:s instanceof Error?s.message:String(s)})}return{updated:n,errors:o}}vo();dt();me();function aS(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 Yf(t,e,r,n){let o=aS(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=fi(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=Gt(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}dt();me();Jt();Cr();ln();Li();function Jf(t){let e=Y(t);if(!e)return null;if(!e.sealKey){let r=Oi();e.sealKey={publicKey:r.publicKey,privateKey:r.privateKey},ue(e)}return{publicKey:e.sealKey.publicKey,privateKey:e.sealKey.privateKey,fingerprint:He(e.sealKey.publicKey)}}async function Zf(t,e,r,n){let o;try{o=JSON.parse(yn(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=Y(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 zt(o.token);return i.github={token:o.token},wn(i,()=>{process.env.GH_TOKEN=o.token,zf(o.token)}),{ok:!0,detail:`authenticated as ${s}`}}case"gitlab":{if(!o.token)return{ok:!1,detail:"payload has no token"};let s=await Xt(o.token);return i.gitlab={token:o.token},wn(i,()=>{process.env.GITLAB_TOKEN=o.token,Vf(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 Vt(o.email,o.apiToken);return i.bitbucket={email:o.email,apiToken:o.apiToken},wn(i,()=>{process.env.BITBUCKET_EMAIL=o.email,process.env.BITBUCKET_API_TOKEN=o.apiToken,Xf(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 Qt({baseUrl:s,token:o.token});return i.youtrack={url:s,token:o.token},wn(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 Bt(o.token);return s==="invalid"?{ok:!1,detail:"Claude token rejected (401) \u2014 previous token kept"}:(i.claude={oauthToken:o.token},wn(i,()=>{}),{ok:!0,...s==="inconclusive"?{detail:"saved (live check inconclusive)"}:{}})}case"contextWrite":return o.token?(i.contextWrite={token:o.token},wn(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 wn(t,e){ue(t),e()}B();B();import{spawn as cS}from"node:child_process";var lS=124,Qf=16*1024,em=4e3;function uS(t,e,r,n,o,i){let s={...t},a=(c,l)=>{Mt(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 tm(t){let{def:e,onEvent:r}=t,n=uS(t.baseEnv??process.env,t.variables,t.secrets,e.env,t.credEnv,t.input),o="",i=a=>{o+=a+`
953
953
  `,o.length>Qf&&(o=o.slice(o.length-Qf))},s=(a,c)=>{let l=c.length>em?c.slice(0,em)+"\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 dS(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 dS(t,e,r,n,o){return new Promise(i=>{let s=cS("bash",["-lc",t],{cwd:r,env:n,stdio:["ignore","pipe","pipe"]}),a=!1,c=(e??Ia)*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:y=>{f+=y.toString("utf-8");let k;for(;(k=f.indexOf(`
954
954
  `))!==-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?lS:m??(f?1:0))})})}lt();lt();import{existsSync as pS,readFileSync as fS,statSync as rm}from"node:fs";var nm=2*1024*1024;function mS(t){return Buffer.from(t.toString("utf-8"),"utf-8").equals(t)}function om(t,e){let r=Te(t,e);if(e.split("/").some(i=>i===".git"))throw new Error(`not a context file: ${e}`);if(!pS(r)||!rm(r).isFile())throw new Error(`file not found: ${e}`);let{size:n}=rm(r);if(n>nm)throw new Error(`file too large: ${e} is ${n} bytes (limit ${nm})`);let o=fS(r);return mS(o)?{content:o.toString("utf-8"),encoding:"utf8",sizeBytes:o.length}:{content:o.toString("base64"),encoding:"base64",sizeBytes:o.length}}me();B();import{existsSync as hS,readFileSync as gS,writeFileSync as yS}from"node:fs";import{join as wS}from"node:path";import{parseDocument as kS}from"yaml";async function im(t,e){if(e.length===0)return{files:[]};let r=new Map;for(let o of e){let i=Ma(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=wS(t,o);if(!hS(s))throw new Error(`${o} not found in context repo (${t})`);let a=kS(gS(s,"utf-8"));for(let c of i)c.value===null?a.deleteIn(c.path):a.setIn(c.path,c.value);yS(s,a.toString()),n.push(o)}return{files:n}}Gc();import{existsSync as Kc,readFileSync as Hc,writeFileSync as bS}from"node:fs";import{join as Di}from"node:path";import{parseDocument as Wc}from"yaml";async function fm(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=Di(t,"project.yaml");if(!Kc(i))throw new Error(`project.yaml not found in context repo (${t})`);let s=Wc(Hc(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=Di(t,"regimen.yaml");if(!Kc(i))throw new Error(`regimen.yaml not found in context repo (${t})`);let s=Wc(Hc(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)bS(Di(t,i.path),i.content);return{files:r.map(i=>i.path)}}function Ui(t){if(!t)return"Stage";try{let e=Di(t,"project.yaml");if(!Kc(e))return"Stage";let n=Wc(Hc(e,"utf-8")).getIn(["youtrack","stage_field"]);return typeof n=="string"&&n.trim().length>0?n.trim():"Stage"}catch{return"Stage"}}Jt();ji();vo();B();lt();import{existsSync as KS,readFileSync as HS}from"node:fs";import{join as oh}from"node:path";import{simpleGit as il}from"simple-git";B();import{existsSync as mm,readFileSync as hm,readdirSync as $S}from"node:fs";import{join as qc}from"node:path";import{simpleGit as vS}from"simple-git";function xS(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(`
955
955
  `)){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 SS(t,e){let r=qc(t,`tasks/${e}/annotations`);if(!mm(r))return[];let n=[];for(let o of $S(r).sort())if(o.endsWith(".md")){try{let i=xS(o,hm(qc(r,o),"utf-8"));i&&n.push(i)}catch{}if(n.length>=pa)break}return n}var ES=12;async function gm(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=vS(o),p=[];for(let d of SS(e,r)){if(d.repo!==n)continue;let m=we("code",n,d.path);if(!a.has(m))continue;let f=l.get(m);if(!f)continue;let y=(await u.raw(["rev-parse",`${i}:${d.path}`]).catch(()=>"")).trim().slice(0,ES),k=sa(f),h=qc(e,k),w=p.find(R=>R.path===k),$=w?.content??(mm(h)?hm(h,"utf-8"):null),S=`<!-- ${r}${y?`:${y}`:""} -->`;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.13.1-dev.278.gbdb59f5",
3
+ "version": "0.13.1-dev.279.g10ce2c9",
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",