@code-partner/codepipe 0.9.2-dev.215.g644f2a1 → 0.9.2-dev.216.ge6e181d

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,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- var Kk=Object.defineProperty;var v=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ir=(t,e)=>{for(var r in e)Kk(t,r,{get:e[r],enumerable:!0})};var Ue,ct,Es=v(()=>{"use strict";Ue="0.9.2-dev.215.g644f2a1",ct="https://hub.dev.codepipe.dev"});function Ao(t){return typeof t!="number"||!Number.isFinite(t)?!1:t>=Hk&&t<=lt}var lt,Hk,kl=v(()=>{"use strict";Es();lt=4,Hk=4});var wl=v(()=>{"use strict";Es()});function Po(t=4){return`# CodePipe Context Repo format version.
2
+ var Kk=Object.defineProperty;var v=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ir=(t,e)=>{for(var r in e)Kk(t,r,{get:e[r],enumerable:!0})};var Ue,ct,Es=v(()=>{"use strict";Ue="0.9.2-dev.216.ge6e181d",ct="https://hub.dev.codepipe.dev"});function Ao(t){return typeof t!="number"||!Number.isFinite(t)?!1:t>=Hk&&t<=lt}var lt,Hk,kl=v(()=>{"use strict";Es();lt=4,Hk=4});var wl=v(()=>{"use strict";Es()});function Po(t=4){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 $l(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 vl(t,e=bl){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 xl(t,e=bl){return e.filter(r=>r.version>t)}var ut,Nn,bl,Sl=v(()=>{"use strict";ut=".codepipe-context.yaml",Nn=".devpipe-context.yaml",bl=[{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",ut]},{version:2,summary:"Rename the format-version stamp .devpipe-context.yaml \u2192 .codepipe-context.yaml (drop the devpipe-brand leftover)",addedPaths:[ut]},{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"]}]});function _o(t){return`model/facts/identity/${t}.yaml`}function Pr(t){return`model/facts/events/${t}.yaml`}function Tl(t){return`model/facts/annotations/${t}.md`}function El(t){return`model/derived/correlates/${t}.yaml`}function Rl(t){return`model/derived/touched/${t}.yaml`}function Wk(t){return t===""?"root":t.replace(/\//g,"-")}function Il(t,e){return`model/derived/structure/${t}/${Wk(e)}.yaml`}function As(t){return typeof t=="string"&&Yk.test(t)}function Q(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(!qk.includes(n))return null;let o=t.slice(e+1,r),i=t.slice(r+1);return o===""&&!Vk.includes(n)||i===""?null:{level:n,repo:o,path:i}}function ve(t){return`task::${t}`}function pe(t,e,r){return`${t}:${e}:${r}`}function jo(t){let e=[];return dt(t)?(No(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(!dt(r)){e.push(`edges[${n}]: not an object`);return}Cl.includes(r.kind)||e.push(`edges[${n}].kind: unknown "${String(r.kind)}"`),Q(r.from)||e.push(`edges[${n}].from: malformed nodeKey`),Q(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 zk(t){return{...t,edges:Cr(t.edges,e=>`${e.kind} ${e.from} ${e.to}`)}}function _r(t){return Nr(zk(t))}function dt(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function No(t){return typeof t=="number"&&Number.isInteger(t)&&t>0}function ze(t){return typeof t=="string"&&t.length>0}function Ct(t){let e=[];if(!dt(t))return{ok:!1,errors:["shard: not an object"]};No(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),ze(t.repo)||e.push("repo: missing or empty"),ze(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(!dt(o)){e.push(`nodes[${i}]: not an object`);return}let s=Q(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&&!As(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(!dt(o)){e.push(`edges[${i}]: not an object`);return}Cl.includes(o.kind)||e.push(`edges[${i}].kind: unknown "${String(o.kind)}"`),(!ze(o.to)||!Q(o.to))&&e.push(`edges[${i}].to: malformed nodeKey`),(!ze(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 Oo(t){let e=[];if(!dt(t))return{ok:!1,errors:["identity: not an object"]};if(No(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),ze(t.repo)||e.push("repo: missing or empty"),t.builtFromCommit!==void 0&&!ze(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(!dt(n)){e.push(`entities[${o}]: not an object`);return}As(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)})`),Q(n.currentKey)||e.push(`entities[${o}].currentKey: malformed nodeKey`),n.status!=="active"&&n.status!=="orphaned"&&e.push(`entities[${o}].status: expected active|orphaned`),ze(n.firstSeen)||e.push(`entities[${o}].firstSeen: missing`),ze(n.lastSeen)||e.push(`entities[${o}].lastSeen: missing`),n.aliases!==void 0&&(Array.isArray(n.aliases)?n.aliases.forEach((i,s)=>{(!dt(i)||!Q(i.key)||!ze(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 At(t){let e=[];return dt(t)?(No(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),ze(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=>!ze(r)))&&e.push("commits: not an array of non-empty strings"),Array.isArray(t.files)?t.files.forEach((r,n)=>{if(!dt(r)||!Q(r.key)){e.push(`files[${n}].key: malformed nodeKey`);return}r.entityId!==void 0&&!As(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 Cr(t,e){return[...t].sort((r,n)=>e(r)<e(n)?-1:e(r)>e(n)?1:0)}function Jk(t){return{...t,nodes:Cr(t.nodes,e=>e.key),edges:Cr(t.edges,e=>`${e.kind}\0${e.from}\0${e.to}`)}}function Xk(t){return{...t,entities:Cr(t.entities,e=>e.entityId).map(e=>e.aliases?{...e,aliases:Cr(e.aliases,r=>`${r.key}\0${r.until}`)}:e)}}function Qk(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:Cr(t.files,r=>r.key),...e?{links:e}:{}}}function On(t){return Zk.test(t)?t:JSON.stringify(t)}function Nl(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 Ol(t){return t===null||["boolean","number","string"].includes(typeof t)}function Rs(t){return Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[r])=>e<r?-1:e>r?1:0)}function Dl(t,e,r){if(Array.isArray(t)){for(let n of t)if(Ol(n))r.push(`${e}- ${Nl(n)}`);else{if(Array.isArray(n))throw new Error("model yaml: nested arrays are not part of the model schema");{let o=Rs(n);if(o.length===0){r.push(`${e}- {}`);continue}o.forEach(([i,s],a)=>{let c=a===0?`${e}- `:`${e} `;Is(i,s,c,`${e} `,r)})}}return}for(let[n,o]of Rs(t))Is(n,o,e,e,r)}function Is(t,e,r,n,o){if(Ol(e))o.push(`${r}${On(t)}: ${Nl(e)}`);else if(Array.isArray(e))e.length===0?o.push(`${r}${On(t)}: []`):(o.push(`${r}${On(t)}:`),Dl(e,`${n} `,o));else{let i=Rs(e);if(i.length===0)o.push(`${r}${On(t)}: {}`);else{o.push(`${r}${On(t)}:`);for(let[s,a]of i)Is(s,a,`${n} `,`${n} `,o)}}}function Nr(t){let e=[];return Dl(t,"",e),e.join(`
6
6
  `)+`
7
- `}function Ll(t){return Nr(Jk(t))}function Ml(t){return Nr(Xk(t))}function Dn(t){return Nr(Qk(t))}var Cs,Ar,qk,Cl,Yk,Vk,Je,Al,Pl,_l,Ps,jl,jr,Zk,_s=v(()=>{"use strict";Cs="model/derived/INDEX.yaml",Ar="model/derived/relates.yaml";qk=["system","container","component","code","task","adr"],Cl=["contains","touched_by","correlates","relates","references","depends_on"],Yk=/^e_[0-9a-f]{8}$/;Vk=["system","task","adr"];Je={windowCommits:1e3,commitFileCap:30,supportMin:5,jaccardMinPct:25,halfLifeDays:270,topK:8};Al=2,Pl=5,_l=50,Ps=2e3,jl={touched_by:.8,references:.7,relates:.6,correlates:.4,contains:.3,depends_on:.5},jr={budgetTokens:4e3,activationCutoff:.05,topKPerNode:8,nodeCap:200};Zk=/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/});var Ul=v(()=>{"use strict"});var ew,yI,Bl=v(()=>{"use strict";ew=[{id:"intake",label:"Intake",phases:["INTAKE"]},{id:"analysis",label:"Analysis",phases:["ANALYZING","ESTIMATING"]},{id:"ready",label:"Ready",phases:["READY"]},{id:"implementation",label:"Implementation",phases:["IMPLEMENTING","BUILD"]},{id:"delivery",label:"Delivery",phases:["READY_TO_APPLY","APPLYING","AWAITING_CLUSTER"]}],yI=ew.flatMap(t=>t.phases)});function rr(){return{inputTokens:0,outputTokens:0,cacheReadInputTokens:0,cacheCreationInputTokens:0,totalCostUsd:0,model:"",numTurns:0,durationMs:0}}var Fl,js=v(()=>{"use strict";Fl=["estimate","analyze","implement","resolve-conflict","rework","draft","build","code-review","index","backfill","analysis","chat"]});function Gl(t,e){return e.toLowerCase().includes(t.toLowerCase())}function Wl(t){let e=t.filter(o=>o&&typeof o.id=="string"&&o.id.trim().length>0);if(e.length===0||rw.every(o=>e.some(i=>Gl(o,i.id))))return null;let n=[...e].sort((o,i)=>{let s=o.createdAt??"",a=i.createdAt??"";return s!==a?s<a?1:-1:o.id<i.id?1:-1});for(let o of tw){let i=n.find(s=>Gl(o,s.id));if(i)return i.id}return n[0].id}var pt,Kl,Xe,Ln,Hl,Ns,Os,tw,rw,Ds=v(()=>{"use strict";pt="claude",Kl=[pt],Xe="opus",Ln="sonnet",Hl="haiku",Ns=[Xe,Ln,Hl],Os={analyze:Xe,implement:Xe,"resolve-conflict":Xe,rework:Xe,estimate:Ln,build:Ln,"code-review":Xe,draft:Ln,index:Xe,backfill:Xe,analysis:Xe,chat:Xe},tw=[Xe,Ln,Hl],rw=Array.from(new Set(Object.values(Os)))});function Pt(t){return nw.has(t)?!0:ow.some(e=>t.startsWith(e))}function Do(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`${e} must be a mapping`);return t}function nr(t,e){if(t!=null){if(typeof t!="string")throw new Error(`${e} must be a string`);return t}}function Ls(t,e){if(t!=null){if(typeof t!="number"||!Number.isFinite(t))throw new Error(`${e} must be a number`);return t}}function Jl(t,e){let r=Do(e,"action definition"),n=t.replace(/\.(yml|yaml)$/i,""),o=nr(r.id,"id")??n;if(!ql.test(o))throw new Error(`id must match ${ql} (got "${o}")`);if(o!==n)throw new Error(`id "${o}" must match the file name ("${n}")`);let i=nr(r.title,"title")?.trim()||o,s;if(r.env!==void 0&&r.env!==null){let p=Do(r.env,"env");s={};for(let[d,f]of Object.entries(p)){if(!Be.test(d))throw new Error(`env name "${d}" must match ${Be}`);if(typeof f!="string"&&typeof f!="number"&&typeof f!="boolean")throw new Error(`env.${d} must be a scalar`);s[d]=String(f)}}let a,c=r.params;if(c!=null){if(!Array.isArray(c))throw new Error("params must be a list");if(c.length>Yl)throw new Error(`too many params (max ${Yl})`);let p=new Set;a=c.map((d,f)=>iw(d,f,p))}let l=r.steps;if(!Array.isArray(l)||l.length===0)throw new Error("steps must be a non-empty list");if(l.length>Vl)throw new Error(`too many steps (max ${Vl})`);let u=l.map((p,d)=>{let f=Do(p,`steps[${d}]`),m=nr(f.run,`steps[${d}].run`);if(!m||m.trim().length===0)throw new Error(`steps[${d}].run is required`);let h=nr(f.name,`steps[${d}].name`),g=Ls(f.timeout_sec,`steps[${d}].timeout_sec`);if(g!==void 0&&(!Number.isInteger(g)||g<=0))throw new Error(`steps[${d}].timeout_sec must be a positive integer`);return{run:m,...h?{name:h}:{},...g!==void 0?{timeout_sec:g}:{}}});return{id:o,title:i,...s?{env:s}:{},...a?{params:a}:{},steps:u}}function iw(t,e,r){let n=Do(t,`params[${e}]`),o=nr(n.name,`params[${e}].name`);if(!o||!Be.test(o))throw new Error(`params[${e}].name must match ${Be}`);if(r.has(o))throw new Error(`duplicate param "${o}"`);r.add(o);let i=n.type;if(i!=="string"&&i!=="enum"&&i!=="number"&&i!=="boolean")throw new Error(`params[${e}].type must be string | enum | number | boolean`);let s;if(i==="enum"){let f=n.enum;if(!Array.isArray(f)||f.length===0||!f.every(m=>typeof m=="string"))throw new Error(`params[${e}].enum must be a non-empty string list`);s=f}let a=nr(n.label,`params[${e}].label`),c=nr(n.help,`params[${e}].help`),l=n.required===!0,u=Ls(n.min,`params[${e}].min`),p=Ls(n.max,`params[${e}].max`),d=n.default;if(d!=null&&typeof d!="string"&&typeof d!="number"&&typeof d!="boolean")throw new Error(`params[${e}].default must be a scalar`);return{name:o,type:i,...a?{label:a}:{},...c?{help:c}:{},...l?{required:!0}:{},...s?{enum:s}:{},...u!==void 0?{min:u}:{},...p!==void 0?{max:p}:{},...d!=null?{default:d}:{}}}function Xl(t,e){let r=t.params??[],n=new Map(r.map(i=>[i.name,i]));for(let i of Object.keys(e))if(!n.has(i))return{ok:!1,error:`unknown param: ${i}`};let o={};for(let i of r){let s=e[i.name];if(s==null||typeof s=="string"&&s.trim()==="")if(i.default!==void 0)s=i.default;else{if(i.required)return{ok:!1,error:`${i.name} is required`};continue}switch(i.type){case"string":{if(typeof s!="string")return{ok:!1,error:`${i.name} must be a string`};o[i.name]=s;break}case"enum":{if(typeof s!="string"||!(i.enum??[]).includes(s))return{ok:!1,error:`${i.name} must be one of: ${(i.enum??[]).join(", ")}`};o[i.name]=s;break}case"number":{let a=typeof s=="number"?s:typeof s=="string"?Number(s):NaN;if(!Number.isFinite(a))return{ok:!1,error:`${i.name} must be a number`};if(i.min!==void 0&&a<i.min)return{ok:!1,error:`${i.name} must be \u2265 ${i.min}`};if(i.max!==void 0&&a>i.max)return{ok:!1,error:`${i.name} must be \u2264 ${i.max}`};o[i.name]=a;break}case"boolean":{let a=typeof s=="boolean"?s:s==="true"?!0:s==="false"?!1:null;if(a===null)return{ok:!1,error:`${i.name} must be a boolean`};o[i.name]=a;break}}}return{ok:!0,values:o}}var Be,nw,ow,zl,ql,Yl,Vl,Ms=v(()=>{"use strict";Be=/^[A-Z][A-Z0-9_]*$/,nw=new Set(["GH_TOKEN","GITHUB_TOKEN","GITLAB_TOKEN"]),ow=["BITBUCKET_","YOUTRACK_","CLAUDE_","INPUT_"];zl=600,ql=/^[a-z0-9-]+$/,Yl=32,Vl=64});var or,Ql,Mn,Us=v(()=>{"use strict";or="auto",Ql=["primary","context","tasks","docs","code_comments","chat"],Mn=["English","Russian","German","Spanish","French","Portuguese","Italian","Chinese","Japanese","Korean"]});function ru(t=cw){let e=[];for(let r of t)e.push(...r.fields),r.groups&&e.push(...ru(r.groups));return e}function lw(t,e){let r=JSON.stringify(e);return ru().find(n=>n.file===t&&JSON.stringify(n.path)===r)}function nu(t){let e=lw(t.file,t.path);if(!e)return{ok:!1,error:`unknown setting path: ${t.file}:${t.path.join(".")}`};let r=t.value,n=e.type==="model"||e.type==="enum"||e.type==="string";if(r===null||n&&typeof r=="string"&&r.trim().length===0)return e.nullable?{ok:!0,field:e,value:null}:{ok:!1,error:`${e.id} cannot be cleared`};switch(e.type){case"model":case"string":{if(typeof r!="string")return{ok:!1,error:`${e.id} must be a string`};let i=r.trim();return e.type==="string"&&e.mustContain&&!i.includes(e.mustContain)?{ok:!1,error:`${e.id} must contain "${e.mustContain}"`}:e.maxLength!==void 0&&i.length>e.maxLength?{ok:!1,error:`${e.id} must be \u2264 ${e.maxLength} chars`}:{ok:!0,field:e,value:i}}case"enum":{if(typeof r!="string")return{ok:!1,error:`${e.id} must be a string`};let i=r.trim();return e.suggestions?.includes(i)?{ok:!0,field:e,value:i}:{ok:!1,error:`${e.id} must be one of: ${(e.suggestions??[]).join(", ")}`}}case"number":return typeof r!="number"||!Number.isFinite(r)||!Number.isInteger(r)?{ok:!1,error:`${e.id} must be an integer`}:e.min!==void 0&&r<e.min?{ok:!1,error:`${e.id} must be \u2265 ${e.min}`}:e.max!==void 0&&r>e.max?{ok:!1,error:`${e.id} must be \u2264 ${e.max}`}:{ok:!0,field:e,value:r};case"boolean":return typeof r!="boolean"?{ok:!1,error:`${e.id} must be a boolean`}:{ok:!0,field:e,value:r};case"string_list":{if(!Array.isArray(r))return{ok:!1,error:`${e.id} must be a list`};let i=r.map(s=>typeof s=="string"?s.trim():"").filter(s=>s.length>0);return i.length===0?e.nullable?{ok:!0,field:e,value:null}:{ok:!1,error:`${e.id} must be a non-empty list`}:{ok:!0,field:e,value:i}}case"string_map":{if(typeof r!="object"||r===null||Array.isArray(r))return{ok:!1,error:`${e.id} must be a name\u2192value map`};let i=Object.entries(r);if(i.length===0)return e.nullable?{ok:!0,field:e,value:null}:{ok:!1,error:`${e.id} must be a non-empty map`};if(i.length>Zl)return{ok:!1,error:`${e.id} must have \u2264 ${Zl} entries`};let s={};for(let[a,c]of i){if(!Be.test(a))return{ok:!1,error:`${e.id}: name "${a}" must match ${Be}`};if(Pt(a))return{ok:!1,error:`${e.id}: name "${a}" is reserved`};if(typeof c!="string")return{ok:!1,error:`${e.id}: value of "${a}" must be a string`};if(c.length>eu)return{ok:!1,error:`${e.id}: value of "${a}" must be \u2264 ${eu} chars`};s[a]=c}return{ok:!0,field:e,value:s}}}}var sw,aw,Zl,eu,tu,cw,ou=v(()=>{"use strict";Ms();js();Ds();_s();Us();sw={primary:"Primary language",context:"Context documents",tasks:"Tracker issues",docs:"Repo documentation",code_comments:"Code comments",chat:"Agent chat"},aw={primary:"The project's main language (agent status notes ride it). Empty \u21D2 auto.",context:"Knowledge, ADRs and task artifacts in the Context Repo. Empty \u21D2 auto.",tasks:"Issue titles/bodies the agent drafts. Empty \u21D2 auto.",docs:"Documentation changes in the project repos. Empty \u21D2 auto.",code_comments:"New code comments the agent writes. Empty \u21D2 auto.",chat:"The interactive task-drafting chat. Empty/auto \u21D2 mirror the user's messages."},Zl=64,eu=2e3,tu=2e3,cw=[{id:"branch",label:"Branch",help:"Task-branch naming.",fields:[{id:"branch.pattern",file:"project.yaml",path:["branch","pattern"],type:"string",label:"Task-branch pattern",nullable:!0,mustContain:"<TASK_ID>",help:"Template for the per-task branch name. Must contain the <TASK_ID> placeholder. Empty \u21D2 default codepipe/<TASK_ID>."}]},{id:"llm",label:"LLM",fields:[{id:"llm.provider",file:"regimen.yaml",path:["llm","provider"],type:"enum",label:"Provider",nullable:!1,suggestions:[...Kl],help:"LLM backend for this project. Currently only claude is available."}],groups:[{id:"llm.models",label:"Models by role",help:"Model per pipeline stage. Empty \u21D2 the role's recommended default applies.",fields:[{id:"llm.models.default",file:"regimen.yaml",path:["llm","models","default"],type:"model",label:"default (catch-all)",nullable:!0,suggestions:[...Ns],help:"Overrides the recommended defaults for every role not listed below."},...Fl.map(t=>({id:`llm.models.${t}`,file:"regimen.yaml",path:["llm","models",t],type:"model",label:t,nullable:!0,suggestions:[...Ns],help:`recommended: ${Os[t]}`}))]}]},{id:"apply.style",label:"Commits & PRs",help:"Instructions for the AI agent on how to write commit messages and PR descriptions. Empty \u21D2 built-in templates.",fields:[{id:"apply.commit_style",file:"project.yaml",path:["apply","commit_style"],type:"string",label:"Commit message style",nullable:!0,multiline:!0,maxLength:tu,help:'e.g. "English, imperative mood, first line \u2264 72 chars, start with the issue key". Empty \u21D2 "<KEY>: <task title>".'},{id:"apply.pr_style",file:"project.yaml",path:["apply","pr_style"],type:"string",label:"PR description style",nullable:!0,multiline:!0,maxLength:tu,help:`e.g. "implementation details, bullet list of what was done, in the tracker's language". Empty \u21D2 the default PR body.`}]},{id:"variables",label:"Variables",help:"Non-secret env vars for custom actions (RUN tab). Secrets go via the sealed Secrets form on the Tokens section instead.",fields:[{id:"variables",file:"project.yaml",path:["variables"],type:"string_map",label:"Variables",nullable:!0,help:"NAME=value pairs, one per line. Names are env-style (A-Z, 0-9, _); reserved credential names are refused."}]},{id:"gates",label:"Gates",help:"Approval gate before the pipeline starts (on by default; orthogonal to automation).",fields:[{id:"gates.require_approval",file:"regimen.yaml",path:["gates","require_approval"],type:"boolean",label:"Require approval before start",nullable:!1,help:"When on (default), a task taken from Develop waits in the QUEUE for a single Confirm before the pipeline starts \u2014 the Confirm pulls in dependency closure and topologically orders the queue. Off \u21D2 conveyor: the task starts the pipeline immediately."}]},{id:"automation",label:"Automation",help:"How far the pipeline advances the G1\u2013G4 gates without a manual Run/Approve. Independent of the approval gate above.",fields:[{id:"automation.level",file:"regimen.yaml",path:["automation","level"],type:"enum",label:"Automation level",nullable:!1,suggestions:["assisted","full"],help:"assisted \u21D2 manual Run/Approve at each of G1\u2013G4; full \u21D2 gates auto-pass."}]},{id:"language",label:"Language",help:"Languages the agent writes in, per area. Empty \u21D2 auto: mirror the language of the user's material.",fields:Ql.map(t=>({id:`language.${t}`,file:"project.yaml",path:["language",t],type:"string",label:sw[t],nullable:!0,maxLength:40,suggestions:t==="chat"?[or,...Mn]:[...Mn],help:aw[t]}))},{id:"context.model",label:"Project map",help:"Parameters of the project map (built from git history by the CLI). Empty fields keep the defaults.",fields:[{id:"context.model.enabled",file:"regimen.yaml",path:["context","model","enabled"],type:"boolean",label:"Enable in the pipeline",nullable:!1,help:"When on, agents are asked to record intent annotations and (once available) receive an assembled context pack. Off \u21D2 the pipeline ignores the map entirely."},{id:"context.index.hub",file:"regimen.yaml",path:["context","index","hub"],type:"enum",label:"Search index on the server",nullable:!0,suggestions:["off","metadata"],help:"off (default): search runs on your machine, nothing is uploaded. metadata: paths, labels and task texts (never code) are mirrored to the server so search and structure stay available while your machine is offline. Switching back to off deletes the mirrored rows."},{id:"context.model.issue_key_pattern",file:"regimen.yaml",path:["context","model","issue_key_pattern"],type:"string",label:"Issue-key pattern (regex)",nullable:!0,maxLength:200,help:"Regex that finds tracker issue keys in commit subjects when mining task events from history. Empty \u21D2 derived from the tracker project key (e.g. DEV-\\d+)."},{id:"context.model.cochange.window_commits",file:"regimen.yaml",path:["context","model","cochange","window_commits"],type:"number",label:"History window (commits)",nullable:!0,min:50,max:5e4,help:`How many commits back from the build commit are mined. Default ${Je.windowCommits}.`},{id:"context.model.cochange.commit_file_cap",file:"regimen.yaml",path:["context","model","cochange","commit_file_cap"],type:"number",label:"Commit size cap (files)",nullable:!0,min:2,max:500,help:`Commits touching more files are ignored as noise. Default ${Je.commitFileCap}.`},{id:"context.model.cochange.support_min",file:"regimen.yaml",path:["context","model","cochange","support_min"],type:"number",label:"Minimum co-occurrences",nullable:!0,min:1,max:100,help:`A pair of files must change together at least this many times. Default ${Je.supportMin}.`},{id:"context.model.cochange.jaccard_min_pct",file:"regimen.yaml",path:["context","model","cochange","jaccard_min_pct"],type:"number",label:"Minimum Jaccard (%)",nullable:!0,min:0,max:100,help:`Overlap threshold: |A\u2229B| / |A\u222AB| of the files' commit sets, in percent. Default ${Je.jaccardMinPct}.`},{id:"context.model.cochange.half_life_days",file:"regimen.yaml",path:["context","model","cochange","half_life_days"],type:"number",label:"Time-decay half-life (days)",nullable:!0,min:1,max:3650,help:`A commit this old counts half as much. Default ${Je.halfLifeDays} (~9 months).`},{id:"context.model.cochange.top_k",file:"regimen.yaml",path:["context","model","cochange","top_k"],type:"number",label:"Edges per file (top-k)",nullable:!0,min:1,max:64,help:`Only the k strongest co-change edges of a file survive \u2014 bounds graph density whatever the thresholds. Default ${Je.topK}.`}]},{id:"implementation",label:"Implementation",help:"How a dependency cluster is serialized into branches and PRs.",fields:[{id:"implementation.mode",file:"regimen.yaml",path:["implementation","mode"],type:"enum",label:"Implementation mode",nullable:!0,suggestions:["cluster-pr","sequential","parallel"],help:"cluster-pr (the standard mode) \u2014 one shared branch and a single PR per dependency cluster; a lone task is a cluster of one. sequential / parallel are DEPRECATED and will be removed \u2014 migrate to cluster-pr. Clearing removes the key from regimen.yaml but keeps the mode already stored for the project (it is not reset to the default)."}]}]});var iu=v(()=>{"use strict"});var su=v(()=>{"use strict"});var au=v(()=>{"use strict"});function cu(t){return`codepipe-host-${t}`}var lu=v(()=>{"use strict"});function uu(t){return!(!t||t.length>250||!/^[A-Za-z0-9._/-]+$/.test(t)||/^[-/.]/.test(t)||/[/.]$/.test(t)||t.endsWith(".lock")||t.includes("..")||t.includes("//")||t.includes("/."))}function $t(t){return`${t}${uw}`}var ir,uw,du=v(()=>{"use strict";ir=/^[a-z][a-z0-9-]{1,30}$/,uw="-codepipe-ctx"});var pu=v(()=>{"use strict"});var fu=v(()=>{"use strict"});function Or(t){for(let e of dw){let r=t.match(e.pattern);if(r)return{name:e.name,args:(r[1]??"").trim()}}return null}var dw,mu=v(()=>{"use strict";dw=[{name:"rework",pattern:/^@(?:codepipe|devpipe)\s+rework:\s*(.+)$/im,description:"Send the task back to ANALYZING with a new instruction.",hasArg:!0},{name:"approve",pattern:/^@(?:codepipe|devpipe)\s+approve\s*$/im,description:"Merge every PR for this task (TRACKING only)."},{name:"reject",pattern:/^@(?:codepipe|devpipe)\s+reject(?::\s*(.+))?\s*$/im,description:"Abandon this task: close any open PR(s) and move it to DONE (reason rejected_and_closed). Valid from any non-terminal phase; from early phases it just skips the task.",hasArg:!0},{name:"merge",pattern:/^@(?:codepipe|devpipe)\s+merge\s*$/im,description:"Merge the task branch into the default branch without a PR (direct apply path, apply.pull_request=false; TRACKING only)."},{name:"rebase",pattern:/^@(?:codepipe|devpipe)\s+rebase\s*$/im,description:"Re-apply the patch on top of the latest base branch and force-push. Use after a PR merge conflict or APPLYING failure."},{name:"update",pattern:/^@(?:codepipe|devpipe)\s+update(?::\s*(.+))?\s*$/im,description:"Update a conflicting PR: resolve conflicts against the current base branch (TRACKING only). Optional `: <instruction>` is forwarded to the agent.",hasArg:!0},{name:"apply",pattern:/^@(?:codepipe|devpipe)\s+apply:\s*(local|auto)\s*$/im,description:"Override apply mode for this task: local (you apply by hand) or auto.",hasArg:!0}]});var gu=v(()=>{"use strict"});var hu=v(()=>{"use strict"});var yu=v(()=>{"use strict"});function ku(t){return t.toUpperCase().replace(/[^A-Z0-9]/g,"").replace(/^[^A-Z]+/,"").slice(0,10)}function bu(t){let e=t.split(/[^A-Za-z0-9]+/).filter(Boolean),r=ku(e.length>=2?e.map(o=>o[0]).join(""):(e[0]??"").slice(0,4));if(Dr.test(r))return r;let n=ku(t);return Dr.test(n)?n:Bs}function $u(t,e){let r=new Set([...e].map(n=>n.toUpperCase()));if(!r.has(t.toUpperCase()))return t;for(let n=1;n<1e4;n++){let o=String(n),i=t.slice(0,10-o.length)+o;if(!r.has(i.toUpperCase()))return i}return t}function Bn(t){return`tasks/${t}/issue.yaml`}var wu,Mo,Bs,Dr,Fs,OI,Uo,Un,vu=v(()=>{"use strict";wu=["bug","feature","epic"],Mo="feature",Bs="TASK",Dr=/^[A-Z][A-Z0-9]{1,9}$/;Fs={backlog:"Backlog",source:["To Do"],inProgress:"In Progress",review:"Review",done:["Done"],rejected:["Rejected"],statusColumns:["Backlog","To Do","In Progress","Review","Done","Rejected"]},OI=Fs.backlog,Uo="tracker/config.yaml",Un="tracker/counter"});var xu=v(()=>{"use strict"});function Lr(t){let e=t.match(/^git@([^:/]+):/);if(e)return e[1]??null;let r=t.match(/^ssh:\/\/(?:[^@/]+@)?([^/:]+)/);if(r)return r[1]??null;let n=t.match(/^https?:\/\/(?:[^@/]+@)?([^/:]+)/);return n?n[1]??null:null}function Bo(t){switch(t){case Fn.gitlab:return"oauth2";case Fn.bitbucket:return"x-token-auth";default:return"x-access-token"}}var Fn,sr,Su=v(()=>{"use strict";Fn={github:"github.com",gitlab:"gitlab.com",bitbucket:"bitbucket.org"};sr="x-bitbucket-api-token-auth"});var Tu=v(()=>{"use strict"});var Eu=v(()=>{"use strict";xu();Su();Tu()});var Ru,G=v(()=>{"use strict";kl();wl();Sl();_s();Ul();Bl();js();Ds();ou();Us();Ms();iu();su();au();lu();du();pu();fu();mu();gu();hu();yu();vu();Eu();Ru=20});function V(t){return process.env[`CODEPIPE_${t}`]??process.env[`DEVPIPE_${t}`]}var _e=v(()=>{"use strict"});import{existsSync as Iu,renameSync as pw}from"node:fs";function ar(t,e,r=n=>console.error(n)){if(Iu(e)||!Iu(t))return!1;try{return pw(t,e),r(`migrated ${t} \u2192 ${e} (DevPipe \u2192 CodePipe)`),!0}catch(n){return r(`failed to migrate ${t} \u2192 ${e}: ${n instanceof Error?n.message:String(n)} \u2014 continuing with the legacy path untouched`),!1}}var Fo=v(()=>{"use strict"});import{existsSync as Go,readFileSync as Cu,readdirSync as fw,writeFileSync as mw}from"node:fs";import{dirname as gw,join as _t}from"node:path";import{parse as hw}from"yaml";function yw(t=process.cwd()){let e=t;for(;;){if(Go(_t(e,ft,"project.yaml")))return e;if(Go(_t(e,Gs,"project.yaml")))return ar(_t(e,Gs),_t(e,ft))&&ww(e),e;let r=gw(e);if(r===e)return null;e=r}}function kw(t){let e=_t(t,ft);return Go(e)?e:_t(t,Gs)}function ww(t){let e=_t(t,".gitignore");if(!Go(e))return;let r=Cu(e,"utf-8"),n=r.split(/\r?\n/).map(o=>{let i=o.trim();return i===".devpipe"||i===".devpipe/"||i==="/.devpipe"||i==="/.devpipe/"?o.replace(".devpipe",".codepipe"):o}).join(`
7
+ `}function Ll(t){return Nr(Jk(t))}function Ml(t){return Nr(Xk(t))}function Dn(t){return Nr(Qk(t))}var Cs,Ar,qk,Cl,Yk,Vk,Je,Al,Pl,_l,Ps,jl,jr,Zk,_s=v(()=>{"use strict";Cs="model/derived/INDEX.yaml",Ar="model/derived/relates.yaml";qk=["system","container","component","code","task","adr"],Cl=["contains","touched_by","correlates","relates","references","depends_on"],Yk=/^e_[0-9a-f]{8}$/;Vk=["system","task","adr"];Je={windowCommits:1e3,commitFileCap:30,supportMin:5,jaccardMinPct:25,halfLifeDays:270,topK:8};Al=2,Pl=5,_l=50,Ps=2e3,jl={touched_by:.8,references:.7,relates:.6,correlates:.4,contains:.3,depends_on:.5},jr={budgetTokens:4e3,activationCutoff:.05,topKPerNode:8,nodeCap:200};Zk=/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/});var Ul=v(()=>{"use strict"});var ew,yI,Bl=v(()=>{"use strict";ew=[{id:"intake",label:"Intake",phases:["INTAKE"]},{id:"analysis",label:"Analysis",phases:["ANALYZING","ESTIMATING"]},{id:"ready",label:"Ready",phases:["READY"]},{id:"implementation",label:"Implementation",phases:["IMPLEMENTING","BUILD"]},{id:"delivery",label:"Delivery",phases:["READY_TO_APPLY","APPLYING","AWAITING_CLUSTER"]}],yI=ew.flatMap(t=>t.phases)});function rr(){return{inputTokens:0,outputTokens:0,cacheReadInputTokens:0,cacheCreationInputTokens:0,totalCostUsd:0,model:"",numTurns:0,durationMs:0}}var Fl,js=v(()=>{"use strict";Fl=["estimate","analyze","implement","resolve-conflict","rework","draft","build","code-review","index","backfill","analysis","chat"]});function Gl(t,e){return e.toLowerCase().includes(t.toLowerCase())}function Wl(t){let e=t.filter(o=>o&&typeof o.id=="string"&&o.id.trim().length>0);if(e.length===0||rw.every(o=>e.some(i=>Gl(o,i.id))))return null;let n=[...e].sort((o,i)=>{let s=o.createdAt??"",a=i.createdAt??"";return s!==a?s<a?1:-1:o.id<i.id?1:-1});for(let o of tw){let i=n.find(s=>Gl(o,s.id));if(i)return i.id}return n[0].id}var pt,Kl,Xe,Ln,Hl,Ns,Os,tw,rw,Ds=v(()=>{"use strict";pt="claude",Kl=[pt],Xe="opus",Ln="sonnet",Hl="haiku",Ns=[Xe,Ln,Hl],Os={analyze:Xe,implement:Xe,"resolve-conflict":Xe,rework:Xe,estimate:Ln,build:Ln,"code-review":Xe,draft:Ln,index:Xe,backfill:Xe,analysis:Xe,chat:Xe},tw=[Xe,Ln,Hl],rw=Array.from(new Set(Object.values(Os)))});function Pt(t){return nw.has(t)?!0:ow.some(e=>t.startsWith(e))}function Do(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`${e} must be a mapping`);return t}function nr(t,e){if(t!=null){if(typeof t!="string")throw new Error(`${e} must be a string`);return t}}function Ls(t,e){if(t!=null){if(typeof t!="number"||!Number.isFinite(t))throw new Error(`${e} must be a number`);return t}}function Jl(t,e){let r=Do(e,"action definition"),n=t.replace(/\.(yml|yaml)$/i,""),o=nr(r.id,"id")??n;if(!ql.test(o))throw new Error(`id must match ${ql} (got "${o}")`);if(o!==n)throw new Error(`id "${o}" must match the file name ("${n}")`);let i=nr(r.title,"title")?.trim()||o,s;if(r.env!==void 0&&r.env!==null){let p=Do(r.env,"env");s={};for(let[d,f]of Object.entries(p)){if(!Be.test(d))throw new Error(`env name "${d}" must match ${Be}`);if(typeof f!="string"&&typeof f!="number"&&typeof f!="boolean")throw new Error(`env.${d} must be a scalar`);s[d]=String(f)}}let a,c=r.params;if(c!=null){if(!Array.isArray(c))throw new Error("params must be a list");if(c.length>Yl)throw new Error(`too many params (max ${Yl})`);let p=new Set;a=c.map((d,f)=>iw(d,f,p))}let l=r.steps;if(!Array.isArray(l)||l.length===0)throw new Error("steps must be a non-empty list");if(l.length>Vl)throw new Error(`too many steps (max ${Vl})`);let u=l.map((p,d)=>{let f=Do(p,`steps[${d}]`),m=nr(f.run,`steps[${d}].run`);if(!m||m.trim().length===0)throw new Error(`steps[${d}].run is required`);let h=nr(f.name,`steps[${d}].name`),g=Ls(f.timeout_sec,`steps[${d}].timeout_sec`);if(g!==void 0&&(!Number.isInteger(g)||g<=0))throw new Error(`steps[${d}].timeout_sec must be a positive integer`);return{run:m,...h?{name:h}:{},...g!==void 0?{timeout_sec:g}:{}}});return{id:o,title:i,...s?{env:s}:{},...a?{params:a}:{},steps:u}}function iw(t,e,r){let n=Do(t,`params[${e}]`),o=nr(n.name,`params[${e}].name`);if(!o||!Be.test(o))throw new Error(`params[${e}].name must match ${Be}`);if(r.has(o))throw new Error(`duplicate param "${o}"`);r.add(o);let i=n.type;if(i!=="string"&&i!=="enum"&&i!=="number"&&i!=="boolean")throw new Error(`params[${e}].type must be string | enum | number | boolean`);let s;if(i==="enum"){let f=n.enum;if(!Array.isArray(f)||f.length===0||!f.every(m=>typeof m=="string"))throw new Error(`params[${e}].enum must be a non-empty string list`);s=f}let a=nr(n.label,`params[${e}].label`),c=nr(n.help,`params[${e}].help`),l=n.required===!0,u=Ls(n.min,`params[${e}].min`),p=Ls(n.max,`params[${e}].max`),d=n.default;if(d!=null&&typeof d!="string"&&typeof d!="number"&&typeof d!="boolean")throw new Error(`params[${e}].default must be a scalar`);return{name:o,type:i,...a?{label:a}:{},...c?{help:c}:{},...l?{required:!0}:{},...s?{enum:s}:{},...u!==void 0?{min:u}:{},...p!==void 0?{max:p}:{},...d!=null?{default:d}:{}}}function Xl(t,e){let r=t.params??[],n=new Map(r.map(i=>[i.name,i]));for(let i of Object.keys(e))if(!n.has(i))return{ok:!1,error:`unknown param: ${i}`};let o={};for(let i of r){let s=e[i.name];if(s==null||typeof s=="string"&&s.trim()==="")if(i.default!==void 0)s=i.default;else{if(i.required)return{ok:!1,error:`${i.name} is required`};continue}switch(i.type){case"string":{if(typeof s!="string")return{ok:!1,error:`${i.name} must be a string`};o[i.name]=s;break}case"enum":{if(typeof s!="string"||!(i.enum??[]).includes(s))return{ok:!1,error:`${i.name} must be one of: ${(i.enum??[]).join(", ")}`};o[i.name]=s;break}case"number":{let a=typeof s=="number"?s:typeof s=="string"?Number(s):NaN;if(!Number.isFinite(a))return{ok:!1,error:`${i.name} must be a number`};if(i.min!==void 0&&a<i.min)return{ok:!1,error:`${i.name} must be \u2265 ${i.min}`};if(i.max!==void 0&&a>i.max)return{ok:!1,error:`${i.name} must be \u2264 ${i.max}`};o[i.name]=a;break}case"boolean":{let a=typeof s=="boolean"?s:s==="true"?!0:s==="false"?!1:null;if(a===null)return{ok:!1,error:`${i.name} must be a boolean`};o[i.name]=a;break}}}return{ok:!0,values:o}}var Be,nw,ow,zl,ql,Yl,Vl,Ms=v(()=>{"use strict";Be=/^[A-Z][A-Z0-9_]*$/,nw=new Set(["GH_TOKEN","GITHUB_TOKEN","GITLAB_TOKEN"]),ow=["BITBUCKET_","YOUTRACK_","CLAUDE_","INPUT_"];zl=600,ql=/^[a-z0-9-]+$/,Yl=32,Vl=64});var or,Ql,Mn,Us=v(()=>{"use strict";or="auto",Ql=["primary","context","tasks","docs","code_comments","chat"],Mn=["English","Russian","German","Spanish","French","Portuguese","Italian","Chinese","Japanese","Korean"]});function ru(t=cw){let e=[];for(let r of t)e.push(...r.fields),r.groups&&e.push(...ru(r.groups));return e}function lw(t,e){let r=JSON.stringify(e);return ru().find(n=>n.file===t&&JSON.stringify(n.path)===r)}function nu(t){let e=lw(t.file,t.path);if(!e)return{ok:!1,error:`unknown setting path: ${t.file}:${t.path.join(".")}`};let r=t.value,n=e.type==="model"||e.type==="enum"||e.type==="string";if(r===null||n&&typeof r=="string"&&r.trim().length===0)return e.nullable?{ok:!0,field:e,value:null}:{ok:!1,error:`${e.id} cannot be cleared`};switch(e.type){case"model":case"string":{if(typeof r!="string")return{ok:!1,error:`${e.id} must be a string`};let i=r.trim();return e.type==="string"&&e.mustContain&&!i.includes(e.mustContain)?{ok:!1,error:`${e.id} must contain "${e.mustContain}"`}:e.maxLength!==void 0&&i.length>e.maxLength?{ok:!1,error:`${e.id} must be \u2264 ${e.maxLength} chars`}:{ok:!0,field:e,value:i}}case"enum":{if(typeof r!="string")return{ok:!1,error:`${e.id} must be a string`};let i=r.trim();return e.suggestions?.includes(i)?{ok:!0,field:e,value:i}:{ok:!1,error:`${e.id} must be one of: ${(e.suggestions??[]).join(", ")}`}}case"number":return typeof r!="number"||!Number.isFinite(r)||!Number.isInteger(r)?{ok:!1,error:`${e.id} must be an integer`}:e.min!==void 0&&r<e.min?{ok:!1,error:`${e.id} must be \u2265 ${e.min}`}:e.max!==void 0&&r>e.max?{ok:!1,error:`${e.id} must be \u2264 ${e.max}`}:{ok:!0,field:e,value:r};case"boolean":return typeof r!="boolean"?{ok:!1,error:`${e.id} must be a boolean`}:{ok:!0,field:e,value:r};case"string_list":{if(!Array.isArray(r))return{ok:!1,error:`${e.id} must be a list`};let i=r.map(s=>typeof s=="string"?s.trim():"").filter(s=>s.length>0);return i.length===0?e.nullable?{ok:!0,field:e,value:null}:{ok:!1,error:`${e.id} must be a non-empty list`}:{ok:!0,field:e,value:i}}case"string_map":{if(typeof r!="object"||r===null||Array.isArray(r))return{ok:!1,error:`${e.id} must be a name\u2192value map`};let i=Object.entries(r);if(i.length===0)return e.nullable?{ok:!0,field:e,value:null}:{ok:!1,error:`${e.id} must be a non-empty map`};if(i.length>Zl)return{ok:!1,error:`${e.id} must have \u2264 ${Zl} entries`};let s={};for(let[a,c]of i){if(!Be.test(a))return{ok:!1,error:`${e.id}: name "${a}" must match ${Be}`};if(Pt(a))return{ok:!1,error:`${e.id}: name "${a}" is reserved`};if(typeof c!="string")return{ok:!1,error:`${e.id}: value of "${a}" must be a string`};if(c.length>eu)return{ok:!1,error:`${e.id}: value of "${a}" must be \u2264 ${eu} chars`};s[a]=c}return{ok:!0,field:e,value:s}}}}var sw,aw,Zl,eu,tu,cw,ou=v(()=>{"use strict";Ms();js();Ds();_s();Us();sw={primary:"Primary language",context:"Context documents",tasks:"Tracker issues",docs:"Repo documentation",code_comments:"Code comments",chat:"Agent chat"},aw={primary:"The project's main language (agent status notes ride it). Empty \u21D2 auto.",context:"Knowledge, ADRs and task artifacts in the Context Repo. Empty \u21D2 auto.",tasks:"Issue titles/bodies the agent drafts. Empty \u21D2 auto.",docs:"Documentation changes in the project repos. Empty \u21D2 auto.",code_comments:"New code comments the agent writes. Empty \u21D2 auto.",chat:"The interactive task-drafting chat. Empty/auto \u21D2 mirror the user's messages."},Zl=64,eu=2e3,tu=2e3,cw=[{id:"branch",label:"Branch",help:"Task-branch naming.",fields:[{id:"branch.pattern",file:"project.yaml",path:["branch","pattern"],type:"string",label:"Task-branch pattern",nullable:!0,mustContain:"<TASK_ID>",help:"Template for the per-task branch name. Must contain the <TASK_ID> placeholder. Empty \u21D2 default codepipe/<TASK_ID>."}]},{id:"llm",label:"LLM",fields:[{id:"llm.provider",file:"regimen.yaml",path:["llm","provider"],type:"enum",label:"Provider",nullable:!1,suggestions:[...Kl],help:"LLM backend for this project. Currently only claude is available."}],groups:[{id:"llm.models",label:"Models by role",help:"Model per pipeline stage. Empty \u21D2 the role's recommended default applies.",fields:[{id:"llm.models.default",file:"regimen.yaml",path:["llm","models","default"],type:"model",label:"default (catch-all)",nullable:!0,suggestions:[...Ns],help:"Overrides the recommended defaults for every role not listed below."},...Fl.map(t=>({id:`llm.models.${t}`,file:"regimen.yaml",path:["llm","models",t],type:"model",label:t,nullable:!0,suggestions:[...Ns],help:`recommended: ${Os[t]}`}))]}]},{id:"apply.style",label:"Commits & PRs",help:"Instructions for the AI agent on how to write commit messages and PR descriptions. Empty \u21D2 built-in templates.",fields:[{id:"apply.commit_style",file:"project.yaml",path:["apply","commit_style"],type:"string",label:"Commit message style",nullable:!0,multiline:!0,maxLength:tu,help:'e.g. "English, imperative mood, first line \u2264 72 chars, start with the issue key". Empty \u21D2 "<KEY>: <task title>".'},{id:"apply.pr_style",file:"project.yaml",path:["apply","pr_style"],type:"string",label:"PR description style",nullable:!0,multiline:!0,maxLength:tu,help:`e.g. "implementation details, bullet list of what was done, in the tracker's language". Empty \u21D2 the default PR body.`}]},{id:"variables",label:"Variables",help:"Non-secret env vars for custom actions (RUN tab). Secrets go via the sealed Secrets form on the Tokens section instead.",fields:[{id:"variables",file:"project.yaml",path:["variables"],type:"string_map",label:"Variables",nullable:!0,help:"NAME=value pairs, one per line. Names are env-style (A-Z, 0-9, _); reserved credential names are refused."}]},{id:"gates",label:"Gates",help:"Approval gate before the pipeline starts (on by default; orthogonal to automation).",fields:[{id:"gates.require_approval",file:"regimen.yaml",path:["gates","require_approval"],type:"boolean",label:"Require approval before start",nullable:!1,help:"When on (default), a task taken from Develop waits in the QUEUE for a single Confirm before the pipeline starts \u2014 the Confirm pulls in dependency closure and topologically orders the queue. Off \u21D2 conveyor: the task starts the pipeline immediately."}]},{id:"automation",label:"Automation",help:"How far the pipeline advances the G1\u2013G4 gates without a manual Run/Approve. Independent of the approval gate above.",fields:[{id:"automation.level",file:"regimen.yaml",path:["automation","level"],type:"enum",label:"Automation level",nullable:!1,suggestions:["assisted","full"],help:"assisted \u21D2 manual Run/Approve at each of G1\u2013G4; full \u21D2 gates auto-pass."}]},{id:"language",label:"Language",help:"Languages the agent writes in, per area. Empty \u21D2 auto: mirror the language of the user's material.",fields:Ql.map(t=>({id:`language.${t}`,file:"project.yaml",path:["language",t],type:"string",label:sw[t],nullable:!0,maxLength:40,suggestions:t==="chat"?[or,...Mn]:[...Mn],help:aw[t]}))},{id:"context.model",label:"Project map",help:"Parameters of the project map (built from git history by the CLI). Empty fields keep the defaults.",fields:[{id:"context.model.enabled",file:"regimen.yaml",path:["context","model","enabled"],type:"boolean",label:"Enable in the pipeline",nullable:!1,help:"When on, agents are asked to record intent annotations and (once available) receive an assembled context pack. Off \u21D2 the pipeline ignores the map entirely."},{id:"context.index.hub",file:"regimen.yaml",path:["context","index","hub"],type:"enum",label:"Search index on the server",nullable:!0,suggestions:["off","metadata"],help:"off (default): search runs on your machine, nothing is uploaded. metadata: paths, labels and task texts (never code) are mirrored to the server so search and structure stay available while your machine is offline. Switching back to off deletes the mirrored rows."},{id:"context.model.issue_key_pattern",file:"regimen.yaml",path:["context","model","issue_key_pattern"],type:"string",label:"Issue-key pattern (regex)",nullable:!0,maxLength:200,help:"Regex that finds tracker issue keys in commit subjects when mining task events from history. Empty \u21D2 derived from the tracker project key (e.g. DEV-\\d+)."},{id:"context.model.cochange.window_commits",file:"regimen.yaml",path:["context","model","cochange","window_commits"],type:"number",label:"History window (commits)",nullable:!0,min:50,max:5e4,help:`How many commits back from the build commit are mined. Default ${Je.windowCommits}.`},{id:"context.model.cochange.commit_file_cap",file:"regimen.yaml",path:["context","model","cochange","commit_file_cap"],type:"number",label:"Commit size cap (files)",nullable:!0,min:2,max:500,help:`Commits touching more files are ignored as noise. Default ${Je.commitFileCap}.`},{id:"context.model.cochange.support_min",file:"regimen.yaml",path:["context","model","cochange","support_min"],type:"number",label:"Minimum co-occurrences",nullable:!0,min:1,max:100,help:`A pair of files must change together at least this many times. Default ${Je.supportMin}.`},{id:"context.model.cochange.jaccard_min_pct",file:"regimen.yaml",path:["context","model","cochange","jaccard_min_pct"],type:"number",label:"Minimum Jaccard (%)",nullable:!0,min:0,max:100,help:`Overlap threshold: |A\u2229B| / |A\u222AB| of the files' commit sets, in percent. Default ${Je.jaccardMinPct}.`},{id:"context.model.cochange.half_life_days",file:"regimen.yaml",path:["context","model","cochange","half_life_days"],type:"number",label:"Time-decay half-life (days)",nullable:!0,min:1,max:3650,help:`A commit this old counts half as much. Default ${Je.halfLifeDays} (~9 months).`},{id:"context.model.cochange.top_k",file:"regimen.yaml",path:["context","model","cochange","top_k"],type:"number",label:"Edges per file (top-k)",nullable:!0,min:1,max:64,help:`Only the k strongest co-change edges of a file survive \u2014 bounds graph density whatever the thresholds. Default ${Je.topK}.`}]},{id:"context.job_logs",label:"Job transcripts",help:"Whether the raw agent transcript of each job is kept in the Context Repo.",fields:[{id:"context.job_logs.enabled",file:"regimen.yaml",path:["context","job_logs","enabled"],type:"boolean",label:"Keep transcripts in the Context Repo",nullable:!1,help:"Off (default): the transcript is discarded after the run \u2014 nothing lands in the Context Repo. On: each job's raw transcript is committed as tasks/<KEY>/logs/job-<id>.jsonl for post-mortem debugging."}]},{id:"implementation",label:"Implementation",help:"How a dependency cluster is serialized into branches and PRs.",fields:[{id:"implementation.mode",file:"regimen.yaml",path:["implementation","mode"],type:"enum",label:"Implementation mode",nullable:!0,suggestions:["cluster-pr","sequential","parallel"],help:"cluster-pr (the standard mode) \u2014 one shared branch and a single PR per dependency cluster; a lone task is a cluster of one. sequential / parallel are DEPRECATED and will be removed \u2014 migrate to cluster-pr. Clearing removes the key from regimen.yaml but keeps the mode already stored for the project (it is not reset to the default)."}]}]});var iu=v(()=>{"use strict"});var su=v(()=>{"use strict"});var au=v(()=>{"use strict"});function cu(t){return`codepipe-host-${t}`}var lu=v(()=>{"use strict"});function uu(t){return!(!t||t.length>250||!/^[A-Za-z0-9._/-]+$/.test(t)||/^[-/.]/.test(t)||/[/.]$/.test(t)||t.endsWith(".lock")||t.includes("..")||t.includes("//")||t.includes("/."))}function $t(t){return`${t}${uw}`}var ir,uw,du=v(()=>{"use strict";ir=/^[a-z][a-z0-9-]{1,30}$/,uw="-codepipe-ctx"});var pu=v(()=>{"use strict"});var fu=v(()=>{"use strict"});function Or(t){for(let e of dw){let r=t.match(e.pattern);if(r)return{name:e.name,args:(r[1]??"").trim()}}return null}var dw,mu=v(()=>{"use strict";dw=[{name:"rework",pattern:/^@(?:codepipe|devpipe)\s+rework:\s*(.+)$/im,description:"Send the task back to ANALYZING with a new instruction.",hasArg:!0},{name:"approve",pattern:/^@(?:codepipe|devpipe)\s+approve\s*$/im,description:"Merge every PR for this task (TRACKING only)."},{name:"reject",pattern:/^@(?:codepipe|devpipe)\s+reject(?::\s*(.+))?\s*$/im,description:"Abandon this task: close any open PR(s) and move it to DONE (reason rejected_and_closed). Valid from any non-terminal phase; from early phases it just skips the task.",hasArg:!0},{name:"merge",pattern:/^@(?:codepipe|devpipe)\s+merge\s*$/im,description:"Merge the task branch into the default branch without a PR (direct apply path, apply.pull_request=false; TRACKING only)."},{name:"rebase",pattern:/^@(?:codepipe|devpipe)\s+rebase\s*$/im,description:"Re-apply the patch on top of the latest base branch and force-push. Use after a PR merge conflict or APPLYING failure."},{name:"update",pattern:/^@(?:codepipe|devpipe)\s+update(?::\s*(.+))?\s*$/im,description:"Update a conflicting PR: resolve conflicts against the current base branch (TRACKING only). Optional `: <instruction>` is forwarded to the agent.",hasArg:!0},{name:"apply",pattern:/^@(?:codepipe|devpipe)\s+apply:\s*(local|auto)\s*$/im,description:"Override apply mode for this task: local (you apply by hand) or auto.",hasArg:!0}]});var gu=v(()=>{"use strict"});var hu=v(()=>{"use strict"});var yu=v(()=>{"use strict"});function ku(t){return t.toUpperCase().replace(/[^A-Z0-9]/g,"").replace(/^[^A-Z]+/,"").slice(0,10)}function bu(t){let e=t.split(/[^A-Za-z0-9]+/).filter(Boolean),r=ku(e.length>=2?e.map(o=>o[0]).join(""):(e[0]??"").slice(0,4));if(Dr.test(r))return r;let n=ku(t);return Dr.test(n)?n:Bs}function $u(t,e){let r=new Set([...e].map(n=>n.toUpperCase()));if(!r.has(t.toUpperCase()))return t;for(let n=1;n<1e4;n++){let o=String(n),i=t.slice(0,10-o.length)+o;if(!r.has(i.toUpperCase()))return i}return t}function Bn(t){return`tasks/${t}/issue.yaml`}var wu,Mo,Bs,Dr,Fs,OI,Uo,Un,vu=v(()=>{"use strict";wu=["bug","feature","epic"],Mo="feature",Bs="TASK",Dr=/^[A-Z][A-Z0-9]{1,9}$/;Fs={backlog:"Backlog",source:["To Do"],inProgress:"In Progress",review:"Review",done:["Done"],rejected:["Rejected"],statusColumns:["Backlog","To Do","In Progress","Review","Done","Rejected"]},OI=Fs.backlog,Uo="tracker/config.yaml",Un="tracker/counter"});var xu=v(()=>{"use strict"});function Lr(t){let e=t.match(/^git@([^:/]+):/);if(e)return e[1]??null;let r=t.match(/^ssh:\/\/(?:[^@/]+@)?([^/:]+)/);if(r)return r[1]??null;let n=t.match(/^https?:\/\/(?:[^@/]+@)?([^/:]+)/);return n?n[1]??null:null}function Bo(t){switch(t){case Fn.gitlab:return"oauth2";case Fn.bitbucket:return"x-token-auth";default:return"x-access-token"}}var Fn,sr,Su=v(()=>{"use strict";Fn={github:"github.com",gitlab:"gitlab.com",bitbucket:"bitbucket.org"};sr="x-bitbucket-api-token-auth"});var Tu=v(()=>{"use strict"});var Eu=v(()=>{"use strict";xu();Su();Tu()});var Ru,G=v(()=>{"use strict";kl();wl();Sl();_s();Ul();Bl();js();Ds();ou();Us();Ms();iu();su();au();lu();du();pu();fu();mu();gu();hu();yu();vu();Eu();Ru=20});function V(t){return process.env[`CODEPIPE_${t}`]??process.env[`DEVPIPE_${t}`]}var _e=v(()=>{"use strict"});import{existsSync as Iu,renameSync as pw}from"node:fs";function ar(t,e,r=n=>console.error(n)){if(Iu(e)||!Iu(t))return!1;try{return pw(t,e),r(`migrated ${t} \u2192 ${e} (DevPipe \u2192 CodePipe)`),!0}catch(n){return r(`failed to migrate ${t} \u2192 ${e}: ${n instanceof Error?n.message:String(n)} \u2014 continuing with the legacy path untouched`),!1}}var Fo=v(()=>{"use strict"});import{existsSync as Go,readFileSync as Cu,readdirSync as fw,writeFileSync as mw}from"node:fs";import{dirname as gw,join as _t}from"node:path";import{parse as hw}from"yaml";function yw(t=process.cwd()){let e=t;for(;;){if(Go(_t(e,ft,"project.yaml")))return e;if(Go(_t(e,Gs,"project.yaml")))return ar(_t(e,Gs),_t(e,ft))&&ww(e),e;let r=gw(e);if(r===e)return null;e=r}}function kw(t){let e=_t(t,ft);return Go(e)?e:_t(t,Gs)}function ww(t){let e=_t(t,".gitignore");if(!Go(e))return;let r=Cu(e,"utf-8"),n=r.split(/\r?\n/).map(o=>{let i=o.trim();return i===".devpipe"||i===".devpipe/"||i==="/.devpipe"||i==="/.devpipe/"?o.replace(".devpipe",".codepipe"):o}).join(`
8
8
  `);n!==r&&mw(e,n)}function Se(t=process.cwd()){let e=yw(t);if(!e)return null;let r=kw(e),n=bw(Cu(_t(r,"project.yaml"),"utf-8"));return{root:e,contextDir:r,spec:n}}function Au(t,e,r){return fw(t).filter(o=>o!==".DS_Store").length===0?!0:e?r.some(o=>o.host===e.host&&o.owner===e.owner&&o.repoName===e.repoName):!1}function Ko(t,e=process.cwd()){try{let r=Se(e);return r&&r.spec.projectId===t?r:null}catch{return null}}function bw(t){let e=hw(t);if(!e||typeof e!="object")throw new Error("project.yaml is empty or malformed");let r=String(e.id??""),n=String(e.name??r),o=Array.isArray(e.repos)?e.repos:[],i=[];for(let s of o){if(!s||typeof s!="object")continue;let a=s,c=String(a.repo??a.repoName??""),l=String(a.name??c);if(!l||!c)continue;let u=a.host,p=u==="bitbucket"?"bitbucket":u==="gitlab"?"gitlab":"github";i.push({name:l,host:p,owner:String(a.owner??""),repoName:c,defaultBranch:String(a.default_branch??a.defaultBranch??"main"),mountAs:String(a.mount_as??a.mountAs??l)})}return{projectId:r,name:n,repos:i}}function Pu(t){return t.host==="github"?`git@github.com:${t.owner}/${t.repoName}.git`:t.host==="gitlab"?`git@gitlab.com:${t.owner}/${t.repoName}.git`:`git@bitbucket.org:${t.owner}/${t.repoName}.git`}var ft,Gs,mt=v(()=>{"use strict";Fo();ft=".codepipe",Gs=".devpipe"});import{homedir as _u}from"node:os";import{mkdirSync as $w,readFileSync as vw,writeFileSync as xw,existsSync as Ks}from"node:fs";import{dirname as Nu,join as Ho,resolve as Sw}from"node:path";import{fileURLToPath as Tw}from"node:url";function Ou(t){let e=Ho(ju,".env");if(Ks(e)&&process.loadEnvFile(e),t){let r=Ho(ju,"profiles",t,".env");Ks(r)&&process.loadEnvFile(r)}}function Mr(t){let e=V("CONFIG");return e||(t?Ho(_u(),".codepipe","profiles",t,"config.json"):Ho(_u(),".codepipe","config.json"))}function Qe(t){let e=Mr(t);if(!Ks(e))return null;let r=vw(e,"utf-8");return JSON.parse(r)}function vt(t,e){let r=Mr(e);$w(Nu(r),{recursive:!0}),xw(r,JSON.stringify(t,null,2)+`
9
9
  `,{mode:384})}function Wo(t){if(t)return{cfg:Fe(t),profile:t};let e;try{e=Se()?.spec.projectId||void 0}catch{}if(e){let r=Qe(e);if(r)return console.log(`[profile] ${e} \u2014 resolved from this folder's workspace`),{cfg:r,profile:e};console.error(`this folder is the workspace of project '${e}', but that CLI profile is not initialised on this machine \u2014 run \`codepipe init\` here (or pass --profile).`),process.exit(1)}return{cfg:Fe(void 0),profile:void 0}}function Fe(t){let e=Qe(t);if(!e){let r=t?`codepipe init --profile ${t} --hub <url> --token <token> --project ${t}`:"codepipe init --hub <url> --token <token> --project <id>";console.error(t?`CLI profile '${t}' is not initialised. run \`${r}\` first.`:`CLI is not initialised. run \`${r}\` first.`),process.exit(1)}return e.projectId||(console.error(`config at ${Mr(t)} is missing 'projectId'. re-run init with --force.`),process.exit(1)),e}var ju,Le=v(()=>{"use strict";_e();mt();ju=Sw(Nu(Tw(import.meta.url)),"..")});import{homedir as Uu}from"node:os";import{existsSync as Bu,mkdirSync as Fu,readFileSync as Gu,writeFileSync as Ku}from"node:fs";import{dirname as Hu,join as Wu}from"node:path";function qu(t,e,r){let n=W(t);if(!n)throw new Error("no secrets file for this project on the CLI");n.secrets={...n.secrets??{},[e]:r},oe(n)}function Yu(t,e){let r=W(t);return!r?.secrets||!(e in r.secrets)?!1:(delete r.secrets[e],oe(r),!0)}function Vu(t){return Object.keys(W(t)?.secrets??{}).sort()}function qo(t,e,r){let n=W(t);if(!n)return"mismatch";let o=n.sandboxPins??{},i=o[e];return i&&i===r?"ok":i&&i!==r?"mismatch":(o[e]=r,n.sandboxPins=o,oe(n),"pinned")}function zu(t,e){let r=W(t);return r?.sandboxPins?.[e]?(delete r.sandboxPins[e],oe(r),!0):!1}function gt(t){return Wu(Uu(),".codepipe","secrets",`${t}.json`)}function W(t){let e=gt(t);return Bu(e)?JSON.parse(Gu(e,"utf-8")):null}function oe(t){let e=gt(t.projectId);Fu(Hu(e),{recursive:!0}),Ku(e,JSON.stringify(t,null,2)+`
10
10
  `,{mode:384})}function Yo(){return Wu(Uu(),".codepipe","shared.json")}function Hs(){let t=Yo();return Bu(t)?JSON.parse(Gu(t,"utf-8")):null}function Ju(t){let e=Yo();Fu(Hu(e),{recursive:!0}),Ku(e,JSON.stringify(t,null,2)+`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-partner/codepipe",
3
- "version": "0.9.2-dev.215.g644f2a1",
3
+ "version": "0.9.2-dev.216.ge6e181d",
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",