@code-partner/codepipe 0.4.1-dev.131.ge050bff → 0.5.0

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 +1 -1
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var xf=Object.defineProperty;var R=(t,e)=>()=>(t&&(e=t(t=0)),e);var Sf=(t,e)=>{for(var r in e)xf(t,r,{get:e[r],enumerable:!0})};var xe,Ge,Wo=R(()=>{"use strict";xe="0.4.1-dev.131.ge050bff",Ge="https://hub.dev.codepipe.dev"});function Tn(t){return typeof t!="number"||!Number.isFinite(t)?!1:t>=Rf&&t<=Fe}var Fe,Rf,js=R(()=>{"use strict";Wo();Fe=4,Rf=4});var As=R(()=>{"use strict";Wo()});function In(t=3){return`# CodePipe Context Repo format version.
2
+ var xf=Object.defineProperty;var R=(t,e)=>()=>(t&&(e=t(t=0)),e);var Sf=(t,e)=>{for(var r in e)xf(t,r,{get:e[r],enumerable:!0})};var xe,Ge,Wo=R(()=>{"use strict";xe="0.5.0",Ge="https://hub.codepipe.dev"});function Tn(t){return typeof t!="number"||!Number.isFinite(t)?!1:t>=Rf&&t<=Fe}var Fe,Rf,js=R(()=>{"use strict";Wo();Fe=4,Rf=4});var As=R(()=>{"use strict";Wo()});function In(t=3){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 Ns(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 Os(t,e=_s){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 Ds(t,e=_s){return e.filter(r=>r.version>t)}var He,Ur,_s,Us=R(()=>{"use strict";He=".codepipe-context.yaml",Ur=".devpipe-context.yaml",_s=[{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",He]},{version:2,summary:"Rename the format-version stamp .devpipe-context.yaml \u2192 .codepipe-context.yaml (drop the devpipe-brand leftover)",addedPaths:[He]},{version:3,summary:"Custom project actions (the RUN tab): actions/ scaffold with the format README",addedPaths:["actions/README.md"]}]});var Ls=R(()=>{"use strict"});var Tf,Zb,Bs=R(()=>{"use strict";Tf=[{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"]}],Zb=Tf.flatMap(t=>t.phases)});function Et(){return{inputTokens:0,outputTokens:0,cacheReadInputTokens:0,cacheCreationInputTokens:0,totalCostUsd:0,model:"",numTurns:0,durationMs:0}}var Ms,Yo=R(()=>{"use strict";Ms=["estimate","analyze","implement","resolve-conflict","rework","draft","build","code-review","index","backfill","analysis","chat"]});var Ke,Cn,If,qo,Gs,Vo=R(()=>{"use strict";Ke="opus",Cn="sonnet",If="haiku",qo=[Ke,Cn,If],Gs={analyze:Ke,implement:Ke,"resolve-conflict":Ke,rework:Ke,estimate:Cn,build:Cn,"code-review":Ke,draft:Cn,index:Ke,backfill:Ke,analysis:Ke,chat:Ke}});function pt(t){return Cf.has(t)?!0:Pf.some(e=>t.startsWith(e))}function Pn(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`${e} must be a mapping`);return t}function jt(t,e){if(t!=null){if(typeof t!="string")throw new Error(`${e} must be a string`);return t}}function Jo(t,e){if(t!=null){if(typeof t!="number"||!Number.isFinite(t))throw new Error(`${e} must be a number`);return t}}function Ys(t,e){let r=Pn(e,"action definition"),n=t.replace(/\.(yml|yaml)$/i,""),o=jt(r.id,"id")??n;if(!Fs.test(o))throw new Error(`id must match ${Fs} (got "${o}")`);if(o!==n)throw new Error(`id "${o}" must match the file name ("${n}")`);let i=jt(r.title,"title")?.trim()||o,s;if(r.env!==void 0&&r.env!==null){let d=Pn(r.env,"env");s={};for(let[u,m]of Object.entries(d)){if(!Se.test(u))throw new Error(`env name "${u}" must match ${Se}`);if(typeof m!="string"&&typeof m!="number"&&typeof m!="boolean")throw new Error(`env.${u} must be a scalar`);s[u]=String(m)}}let a,c=r.params;if(c!=null){if(!Array.isArray(c))throw new Error("params must be a list");if(c.length>Hs)throw new Error(`too many params (max ${Hs})`);let d=new Set;a=c.map((u,m)=>Ef(u,m,d))}let l=r.steps;if(!Array.isArray(l)||l.length===0)throw new Error("steps must be a non-empty list");if(l.length>Ks)throw new Error(`too many steps (max ${Ks})`);let p=l.map((d,u)=>{let m=Pn(d,`steps[${u}]`),f=jt(m.run,`steps[${u}].run`);if(!f||f.trim().length===0)throw new Error(`steps[${u}].run is required`);let y=jt(m.name,`steps[${u}].name`),w=Jo(m.timeout_sec,`steps[${u}].timeout_sec`);if(w!==void 0&&(!Number.isInteger(w)||w<=0))throw new Error(`steps[${u}].timeout_sec must be a positive integer`);return{run:f,...y?{name:y}:{},...w!==void 0?{timeout_sec:w}:{}}});return{id:o,title:i,...s?{env:s}:{},...a?{params:a}:{},steps:p}}function Ef(t,e,r){let n=Pn(t,`params[${e}]`),o=jt(n.name,`params[${e}].name`);if(!o||!Se.test(o))throw new Error(`params[${e}].name must match ${Se}`);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 m=n.enum;if(!Array.isArray(m)||m.length===0||!m.every(f=>typeof f=="string"))throw new Error(`params[${e}].enum must be a non-empty string list`);s=m}let a=jt(n.label,`params[${e}].label`),c=jt(n.help,`params[${e}].help`),l=n.required===!0,p=Jo(n.min,`params[${e}].min`),d=Jo(n.max,`params[${e}].max`),u=n.default;if(u!=null&&typeof u!="string"&&typeof u!="number"&&typeof u!="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}:{},...p!==void 0?{min:p}:{},...d!==void 0?{max:d}:{},...u!=null?{default:u}:{}}}function qs(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 Se,Cf,Pf,Ws,Fs,Hs,Ks,zo=R(()=>{"use strict";Se=/^[A-Z][A-Z0-9_]*$/,Cf=new Set(["GH_TOKEN","GITHUB_TOKEN","GITLAB_TOKEN"]),Pf=["BITBUCKET_","YOUTRACK_","CLAUDE_","INPUT_"];Ws=600,Fs=/^[a-z0-9-]+$/,Hs=32,Ks=64});function Xs(t=jf){let e=[];for(let r of t)e.push(...r.fields),r.groups&&e.push(...Xs(r.groups));return e}function Af(t,e){let r=JSON.stringify(e);return Xs().find(n=>n.file===t&&JSON.stringify(n.path)===r)}function Qs(t){let e=Af(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>Vs)return{ok:!1,error:`${e.id} must have \u2264 ${Vs} entries`};let s={};for(let[a,c]of i){if(!Se.test(a))return{ok:!1,error:`${e.id}: name "${a}" must match ${Se}`};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>Js)return{ok:!1,error:`${e.id}: value of "${a}" must be \u2264 ${Js} chars`};s[a]=c}return{ok:!0,field:e,value:s}}}}var Vs,Js,zs,jf,Zs=R(()=>{"use strict";zo();Yo();Vo();Vs=64,Js=2e3,zs=2e3,jf=[{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:[],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:[...qo],help:"Overrides the recommended defaults for every role not listed below."},...Ms.map(t=>({id:`llm.models.${t}`,file:"regimen.yaml",path:["llm","models",t],type:"model",label:t,nullable:!0,suggestions:[...qo],help:`recommended: ${Gs[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:zs,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:zs,help:'e.g. "Russian, implementation details, bullet list of what was done". 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 (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, a task taken from Develop waits in AWAITING_APPROVAL for a manual Approve before analysis starts. Off \u21D2 intake auto-starts the pipeline."}]},{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."}]}]});var ea=R(()=>{"use strict"});var ta=R(()=>{"use strict"});var ra=R(()=>{"use strict"});var na=R(()=>{"use strict"});function oa(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 et(t){return`${t}${_f}`}var At,_f,ia=R(()=>{"use strict";At=/^[a-z][a-z0-9-]{1,30}$/,_f="-codepipe-ctx"});var sa=R(()=>{"use strict"});var aa=R(()=>{"use strict"});function qt(t){for(let e of Nf){let r=t.match(e.pattern);if(r)return{name:e.name,args:(r[1]??"").trim()}}return null}var Nf,ca=R(()=>{"use strict";Nf=[{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 la=R(()=>{"use strict"});var ua=R(()=>{"use strict"});var pa=R(()=>{"use strict"});function da(t){return t.toUpperCase().replace(/[^A-Z0-9]/g,"").replace(/^[^A-Z]+/,"").slice(0,10)}function ma(t){let e=t.split(/[^A-Za-z0-9]+/).filter(Boolean),r=da(e.length>=2?e.map(o=>o[0]).join(""):(e[0]??"").slice(0,4));if(Vt.test(r))return r;let n=da(t);return Vt.test(n)?n:Xo}function ga(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 Br(t){return`tasks/${t}/issue.yaml`}var fa,En,Xo,Vt,Qo,f$,jn,Lr,ha=R(()=>{"use strict";fa=["bug","feature","epic"],En="feature",Xo="TASK",Vt=/^[A-Z][A-Z0-9]{1,9}$/;Qo={backlog:"Backlog",source:["To Do"],inProgress:"In Progress",review:"Review",done:["Done"],rejected:["Rejected"],statusColumns:["Backlog","To Do","In Progress","Review","Done","Rejected"]},f$=Qo.backlog,jn="tracker/config.yaml",Lr="tracker/counter"});var ya=R(()=>{"use strict"});function Jt(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 An(t){switch(t){case Mr.gitlab:return"oauth2";case Mr.bitbucket:return"x-token-auth";default:return"x-access-token"}}var Mr,_t,wa=R(()=>{"use strict";Mr={github:"github.com",gitlab:"gitlab.com",bitbucket:"bitbucket.org"};_t="x-bitbucket-api-token-auth"});var ka=R(()=>{"use strict"});var ba=R(()=>{"use strict";ya();wa();ka()});var $a,q=R(()=>{"use strict";js();As();Us();Ls();Bs();Yo();Vo();Zs();zo();ea();ta();ra();na();ia();sa();aa();ca();la();ua();pa();ha();ba();$a=20});function K(t){return process.env[`CODEPIPE_${t}`]??process.env[`DEVPIPE_${t}`]}var Ne=R(()=>{"use strict"});import{existsSync as va,renameSync as Of}from"node:fs";function Nt(t,e,r=n=>console.error(n)){if(va(e)||!va(t))return!1;try{return Of(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 _n=R(()=>{"use strict"});import{existsSync as Nn,readFileSync as xa,readdirSync as Df,writeFileSync as Uf}from"node:fs";import{dirname as Lf,join as dt}from"node:path";import{parse as Bf}from"yaml";function Mf(t=process.cwd()){let e=t;for(;;){if(Nn(dt(e,We,"project.yaml")))return e;if(Nn(dt(e,Zo,"project.yaml")))return Nt(dt(e,Zo),dt(e,We))&&Ff(e),e;let r=Lf(e);if(r===e)return null;e=r}}function Gf(t){let e=dt(t,We);return Nn(e)?e:dt(t,Zo)}function Ff(t){let e=dt(t,".gitignore");if(!Nn(e))return;let r=xa(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(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-partner/codepipe",
3
- "version": "0.4.1-dev.131.ge050bff",
3
+ "version": "0.5.0",
4
4
  "description": "CodePipe turns tasks into reviewed pull requests: an AI agent analyzes, implements, and opens a PR under your control.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -29,8 +29,8 @@
29
29
  "@types/ws": "^8.5.13",
30
30
  "esbuild": "^0.21.5",
31
31
  "vitest": "2.1.9",
32
- "@codepipe/sandbox": "0.1.0",
33
- "@codepipe/shared": "0.0.0"
32
+ "@codepipe/shared": "0.0.0",
33
+ "@codepipe/sandbox": "0.1.0"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "tsc -p tsconfig.json && chmod +x dist/index.js",