@code-partner/codepipe 0.14.1-dev.298.gb3e4ee82 → 0.14.1-dev.301.g31b1f362
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +9 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var Fv=Object.defineProperty;var x=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ne=(t,e)=>{for(var r in e)Fv(t,r,{get:e[r],enumerable:!0})};var et,bt,$a=x(()=>{"use strict";et="0.14.1-dev.
|
|
2
|
+
var Fv=Object.defineProperty;var x=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ne=(t,e)=>{for(var r in e)Fv(t,r,{get:e[r],enumerable:!0})};var et,bt,$a=x(()=>{"use strict";et="0.14.1-dev.301.g31b1f362",bt="https://hub.dev.codepipe.dev"});function ho(t){return typeof t!="number"||!Number.isFinite(t)?!1:t>=Rd&&t<=kt}var kt,Rd,Td=x(()=>{"use strict";$a();kt=4,Rd=4});var Id=x(()=>{"use strict";$a()});function go(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 Sa(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 Ea(t,e=xa){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 Ra(t,e=xa){return e.filter(r=>r.version>t)}var Cd,vt,un,xa,Pd=x(()=>{"use strict";Cd=6,vt=".codepipe-context.yaml",un=".devpipe-context.yaml",xa=[{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",vt]},{version:2,summary:"Rename the format-version stamp .devpipe-context.yaml \u2192 .codepipe-context.yaml (drop the devpipe-brand leftover)",addedPaths:[vt]},{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 wo(t){return`model/facts/identity/${t}.yaml`}function Cr(t){return`model/facts/events/${t}.yaml`}function Ca(t){return`model/facts/annotations/${t}.md`}function Pa(t){return`model/derived/correlates/${t}.yaml`}function Aa(t){return`model/derived/touched/${t}.yaml`}function Ad(t){return t===""?"root":t.replace(/\//g,"-")}function _a(t,e){return`model/derived/structure/${t}/${Ad(e)}.yaml`}function vi(t){return typeof t=="string"&&jd.test(t)}function ne(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(!_d.includes(n))return null;let o=t.slice(e+1,r),i=t.slice(r+1);return o===""&&!qv.includes(n)||i===""?null:{level:n,repo:o,path:i}}function Ee(t){return`task::${t}`}function ye(t,e,r){return`${t}:${e}:${r}`}function bo(t){let e=[];return Pt(t)?(xi(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(!Pt(r)){e.push(`edges[${n}]: not an object`);return}ja.includes(r.kind)||e.push(`edges[${n}].kind: unknown "${String(r.kind)}"`),ne(r.from)||e.push(`edges[${n}].from: malformed nodeKey`),ne(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 Nd(t){return{...t,edges:dn(t.edges,e=>`${e.kind} ${e.from} ${e.to}`)}}function Pr(t){return _r(Nd(t))}function Pt(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function xi(t){return typeof t=="number"&&Number.isInteger(t)&&t>0}function $t(t){return typeof t=="string"&&t.length>0}function Vv(t){return t.modelFormatVersion!==2}function Gt(t){let e=[];if(!Pt(t))return{ok:!1,errors:["shard: not an object"]};xi(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),$t(t.repo)||e.push("repo: missing or empty"),$t(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(!Pt(o)){e.push(`nodes[${i}]: not an object`);return}let s=ne(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&&!vi(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(!Pt(o)){e.push(`edges[${i}]: not an object`);return}ja.includes(o.kind)||e.push(`edges[${i}].kind: unknown "${String(o.kind)}"`),(!$t(o.to)||!ne(o.to))&&e.push(`edges[${i}].to: malformed nodeKey`),(!$t(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 ko(t){let e=[];if(!Pt(t))return{ok:!1,errors:["identity: not an object"]};if(xi(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),$t(t.repo)||e.push("repo: missing or empty"),t.builtFromCommit!==void 0&&!$t(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(!Pt(n)){e.push(`entities[${o}]: not an object`);return}vi(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)})`),ne(n.currentKey)||e.push(`entities[${o}].currentKey: malformed nodeKey`),n.status!=="active"&&n.status!=="orphaned"&&e.push(`entities[${o}].status: expected active|orphaned`),$t(n.firstSeen)||e.push(`entities[${o}].firstSeen: missing`),$t(n.lastSeen)||e.push(`entities[${o}].lastSeen: missing`),n.aliases!==void 0&&(Array.isArray(n.aliases)?n.aliases.forEach((i,s)=>{(!Pt(i)||!ne(i.key)||!$t(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 Kt(t){let e=[];return Pt(t)?(xi(t.modelFormatVersion)||e.push("modelFormatVersion: missing or not a positive integer"),$t(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=>!$t(r)))&&e.push("commits: not an array of non-empty strings"),Array.isArray(t.files)?t.files.forEach((r,n)=>{if(!Pt(r)||!ne(r.key)){e.push(`files[${n}].key: malformed nodeKey`);return}r.entityId!==void 0&&!vi(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 dn(t,e){return[...t].sort((r,n)=>e(r)<e(n)?-1:e(r)>e(n)?1:0)}function Od(t){return{...t,nodes:dn(t.nodes,e=>e.key),edges:dn(t.edges,e=>`${e.kind}\0${e.from}\0${e.to}`)}}function Ld(t){return{...t,entities:dn(t.entities,e=>e.entityId).map(e=>e.aliases?{...e,aliases:dn(e.aliases,r=>`${r.key}\0${r.until}`)}:e)}}function Md(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:dn(t.files,r=>r.key),...e?{links:e}:{}}}function yo(t){return zv.test(t)?t:JSON.stringify(t)}function Dd(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 Ud(t){return t===null||["boolean","number","string"].includes(typeof t)}function Ta(t){return Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[r])=>e<r?-1:e>r?1:0)}function Bd(t,e,r){if(Array.isArray(t)){for(let n of t)if(Ud(n))r.push(`${e}- ${Dd(n)}`);else{if(Array.isArray(n))throw new Error("model yaml: nested arrays are not part of the model schema");{let o=Ta(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 Ta(t))Ia(n,o,e,e,r)}function Ia(t,e,r,n,o){if(Ud(e))o.push(`${r}${yo(t)}: ${Dd(e)}`);else if(Array.isArray(e))e.length===0?o.push(`${r}${yo(t)}: []`):(o.push(`${r}${yo(t)}:`),Bd(e,`${n} `,o));else{let i=Ta(e);if(i.length===0)o.push(`${r}${yo(t)}: {}`);else{o.push(`${r}${yo(t)}:`);for(let[s,a]of i)Ia(s,a,`${n} `,`${n} `,o)}}}function _r(t){let e=[];return Bd(t,"",e),e.join(`
|
|
6
6
|
`)+`
|
|
7
|
-
`}function Da(t){return _r(Od(t))}function Ua(t){return _r(Ld(t))}function pn(t){return _r(Md(t))}var Fe,Gv,Kv,Hv,Wv,ki,Ir,_d,ja,jd,qv,lt,Na,Oa,La,$i,Yv,Ma,Ar,zv,Ba=x(()=>{"use strict";Fe=2,Gv="model",Kv="model/README.md",Hv="model/facts",Wv="model/derived",ki="model/derived/INDEX.yaml",Ir="model/derived/relates.yaml";_d=["system","container","component","code","task","adr"],ja=["contains","touched_by","correlates","relates","references","depends_on"],jd=/^e_[0-9a-f]{8}$/;qv=["system","task","adr"];lt={windowCommits:1e3,commitFileCap:30,supportMin:5,jaccardMinPct:25,halfLifeDays:270,topK:8};Na=2,Oa=5,La=50,$i=2e3,Yv=5e4,Ma={touched_by:.8,references:.7,relates:.6,correlates:.4,contains:.3,depends_on:.5},Ar={budgetTokens:4e3,activationCutoff:.05,topKPerNode:8,nodeCap:200};zv=/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/});function Xv(t){return t==="DONE"}function Jv(t){return t==="AWAITING_EXTERNAL_FIX"?!1:Fa.indexOf(t)>=Fa.indexOf("IMPLEMENTING")}var Fa,Fd=x(()=>{"use strict";Fa=["BACKLOG","QUEUED","INTAKE","AWAITING_APPROVAL","ANALYZING","ESTIMATING","AWAITING_ANSWER","REVIEW","READY","IMPLEMENTING","BUILD","CODE_REVIEW","TESTING","AWAITING_EXTERNAL_FIX","READY_TO_APPLY","APPLYING","AWAITING_CLUSTER","TRACKING","NEEDS_MANUAL","DONE"]});function Qv(t){for(let e of Ga)if(e.phases.includes(t))return e.id;return null}function e$(t){for(let e of Gd)if(e.phases.includes(t))return e.id;return null}var Ga,Zv,Gd,Kd=x(()=>{"use strict";Ga=[{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"]}],Zv=Ga.flatMap(t=>t.phases),Gd=[{id:"review",label:"Review / tracking",phases:["CODE_REVIEW","TESTING","TRACKING"]},{id:"attention",label:"Need your attention",phases:["NEEDS_MANUAL","AWAITING_APPROVAL","AWAITING_EXTERNAL_FIX","AWAITING_ANSWER","REVIEW"]},{id:"backlog",label:"Backlog / queue",phases:["BACKLOG","QUEUED"]}]});function Ha(t){return Wd.includes(t)}function t$(t){return Hd.includes(t)?"planning":"implementation"}function ut(){return{inputTokens:0,outputTokens:0,cacheReadInputTokens:0,cacheCreationInputTokens:0,totalCostUsd:0,model:"",numTurns:0,durationMs:0}}var Ka,Hd,Wd,r$,Wa=x(()=>{"use strict";Ka=["estimate","analyze","implement","resolve-conflict","rework","draft","build","code-review","index","backfill","analysis","chat","config","observer","council","testing"],Hd=["draft","analysis","chat","config","observer","council"],Wd=["chat","config"];r$=1});function n$(t){return typeof t=="string"&&Jd.includes(t.trim())?t.trim():null}function qd(t,e){return e.toLowerCase().includes(t.toLowerCase())}function Ya(t){let e=t.filter(o=>o&&typeof o.id=="string"&&o.id.trim().length>0);if(e.length===0||tp.every(o=>e.some(i=>qd(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 ep){let i=n.find(s=>qd(o,s.id));if(i)return i.id}return n[0].id}function fn(){return{default:null,roles:{}}}function o$(t,e,r=Zd){let n=t?.roles?.[e];if(typeof n=="string"&&n.trim().length>0)return n.trim();if(t?.default&&t.default.trim().length>0)return t.default.trim();let o=Qd[r]?.[e];return o||(vo[e]??Xd)}function i$(t){let e=t?.provider;return typeof e=="string"&&e.trim().length>0?e.trim():tt}function s$(t){let e=fn();if(!t||typeof t!="object")return e;let r=t.llm;if(!r||typeof r!="object")return e;let n=r.provider;typeof n=="string"&&n.trim().length>0&&(e.provider=n.trim());let o=r.models;if(!o||typeof o!="object")return e;for(let[i,s]of Object.entries(o))typeof s!="string"||s.trim().length===0||(i==="default"?e.default=s.trim():e.roles[i]=s.trim());return e}function mn(){return{default:null,roles:{}}}function a$(t,e){let r=t?.roles?.[e];return typeof r=="string"&&r.trim().length>0?r.trim():t?.default&&t.default.trim().length>0?t.default.trim():$o[e]}function c$(t){let e=mn();if(!t||typeof t!="object")return e;let r=t.llm;if(!r||typeof r!="object")return e;let n=r.effort;if(!n||typeof n!="object")return e;for(let[o,i]of Object.entries(n))typeof i!="string"||i.trim().length===0||(o==="default"?e.default=i.trim():e.roles[o]=i.trim());return e}function l$(t){return t.default===null&&Object.keys(t.roles).length===0?null:JSON.stringify(t)}function u$(t){if(!t)return mn();try{let e=JSON.parse(t);if(!e||typeof e!="object")return mn();let r=e,n=mn();typeof r.default=="string"&&(n.default=r.default);let o=r.roles;if(o&&typeof o=="object")for(let[i,s]of Object.entries(o))typeof s=="string"&&(n.roles[i]=s);return n}catch{return mn()}}function d$(t){let e=typeof t.provider=="string"&&t.provider.trim().length>0&&t.provider.trim()!==tt;if(t.default===null&&Object.keys(t.roles).length===0&&!e)return null;let{provider:r,...n}=t;return JSON.stringify(e?{provider:r.trim(),...n}:n)}function p$(t){if(!t)return fn();try{let e=JSON.parse(t);if(!e||typeof e!="object")return fn();let r=e,n=fn();typeof r.provider=="string"&&r.provider.trim().length>0&&(n.provider=r.provider.trim()),typeof r.default=="string"&&(n.default=r.default);let o=r.roles;if(o&&typeof o=="object")for(let[i,s]of Object.entries(o))typeof s=="string"&&(n.roles[i]=s);return n}catch{return fn()}}var tt,qa,Ie,Ht,hn,Si,Yd,Vd,zd,Ei,vo,Xd,Jd,Zd,Qd,ep,tp,rp,Ri,$o,Va=x(()=>{"use strict";Wa();tt="claude",qa=[tt],Ie="opus",Ht="sonnet",hn="haiku",Si=[Ie,Ht,hn],Yd="build-discovery",Vd="code-review-verify",zd=[Yd,Vd],Ei=[...Ka,...zd],vo={analyze:Ie,implement:Ie,"resolve-conflict":Ie,rework:Ie,estimate:Ht,build:hn,"build-discovery":Ie,"code-review":Ie,"code-review-verify":Ht,draft:Ht,index:Ie,backfill:Ie,analysis:Ie,chat:Ie,config:Ie,observer:Ie,council:Ie,testing:Ie},Xd=Ie,Jd=["express","balanced","full"],Zd="full",Qd={express:{"code-review":Ht,"code-review-verify":hn},balanced:{implement:Ht,"code-review":Ht,"code-review-verify":hn},full:{}};ep=[Ie,Ht,hn],tp=Array.from(new Set(Object.values(vo)));rp=["low","medium","high","xhigh"],Ri=rp,$o={build:"low",estimate:"low",draft:"medium",index:"medium","code-review-verify":"medium"}});function Wt(t){return f$.has(t)?!0:m$.some(e=>t.startsWith(e))}function Ti(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`${e} must be a mapping`);return t}function jr(t,e){if(t!=null){if(typeof t!="string")throw new Error(`${e} must be a string`);return t}}function Xa(t,e){if(t!=null){if(typeof t!="number"||!Number.isFinite(t))throw new Error(`${e} must be a number`);return t}}function Za(t,e){let r=Ti(e,"action definition"),n=t.replace(/\.(yml|yaml)$/i,""),o=jr(r.id,"id")??n;if(!za.test(o))throw new Error(`id must match ${za} (got "${o}")`);if(o!==n)throw new Error(`id "${o}" must match the file name ("${n}")`);let i=jr(r.title,"title")?.trim()||o,s;if(r.env!==void 0&&r.env!==null){let p=Ti(r.env,"env");s={};for(let[d,f]of Object.entries(p)){if(!rt.test(d))throw new Error(`env name "${d}" must match ${rt}`);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>np)throw new Error(`too many params (max ${np})`);let p=new Set;a=c.map((d,f)=>h$(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>op)throw new Error(`too many steps (max ${op})`);let u=l.map((p,d)=>{let f=Ti(p,`steps[${d}]`),m=jr(f.run,`steps[${d}].run`);if(!m||m.trim().length===0)throw new Error(`steps[${d}].run is required`);let g=jr(f.name,`steps[${d}].name`),b=Xa(f.timeout_sec,`steps[${d}].timeout_sec`);if(b!==void 0&&(!Number.isInteger(b)||b<=0))throw new Error(`steps[${d}].timeout_sec must be a positive integer`);return{run:m,...g?{name:g}:{},...b!==void 0?{timeout_sec:b}:{}}});return{id:o,title:i,...s?{env:s}:{},...a?{params:a}:{},steps:u}}function h$(t,e,r){let n=Ti(t,`params[${e}]`),o=jr(n.name,`params[${e}].name`);if(!o||!rt.test(o))throw new Error(`params[${e}].name must match ${rt}`);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=jr(n.label,`params[${e}].label`),c=jr(n.help,`params[${e}].help`),l=n.required===!0,u=Xa(n.min,`params[${e}].min`),p=Xa(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 Qa(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 rt,f$,m$,Ja,za,np,op,ec=x(()=>{"use strict";rt=/^[A-Z][A-Z0-9_]*$/,f$=new Set(["GH_TOKEN","GITHUB_TOKEN","GITLAB_TOKEN"]),m$=["BITBUCKET_","YOUTRACK_","CLAUDE_","INPUT_"];Ja=600,za=/^[a-z0-9-]+$/,np=32,op=64});function ip(){return{primary:we,context:we,tasks:we,docs:we,code_comments:we,chat:we,code_review:we,commits:we}}function sp(t){return!t||t.trim().length===0||t.trim().toLowerCase()===we}function g$(t){if(typeof t!="string")return we;let e=t.trim().replace(/\s+/g," ");return e.length===0||e.length>40||e.toLowerCase()===we?we:e}function y$(t){let e=ip();if(!t||typeof t!="object")return e;let r=t.language;if(!r||typeof r!="object"||Array.isArray(r))return e;let n=r;for(let o of xo)e[o]=g$(n[o]);return e}function w$(t){return xo.every(e=>sp(t[e]))}var we,xo,gn,So,tc=x(()=>{"use strict";we="auto",xo=["primary","context","tasks","docs","code_comments","chat","code_review","commits"],gn=["English","Russian","German","Spanish","French","Portuguese","Italian","Chinese","Japanese","Korean"],So=40});function ic(t=ap){let e=[];for(let r of t)e.push(...r.fields),r.groups&&e.push(...ic(r.groups));return e}function cp(t,e){let r=JSON.stringify(e);return ic().find(n=>n.file===t&&JSON.stringify(n.path)===r)}function sc(t){let e=cp(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)?{ok:!1,error:`${e.id} must be a number`}:!e.float&&!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>rc)return{ok:!1,error:`${e.id} must have \u2264 ${rc} entries`};let s={};for(let[a,c]of i){if(!rt.test(a))return{ok:!1,error:`${e.id}: name "${a}" must match ${rt}`};if(Wt(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>nc)return{ok:!1,error:`${e.id}: value of "${a}" must be \u2264 ${nc} chars`};s[a]=c}return{ok:!0,field:e,value:s}}}}var b$,k$,rc,nc,oc,ap,lp=x(()=>{"use strict";ec();Va();Ba();tc();b$={primary:"Primary language",context:"Context documents",tasks:"Tracker issues",docs:"Repo documentation",code_comments:"Code comments",chat:"Agent chat",code_review:"Code review comments",commits:"Commits & branches"},k$={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.",code_review:"Review findings and PR comments. Empty \u21D2 follows the tracker-issues language.",commits:"Commit/PR subject & branch slug. Empty \u21D2 follows the tracker-issues language."},rc=64,nc=2e3,oc=2e3,ap=[{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:[...qa],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:[...Si],help:"Overrides the recommended defaults for every role not listed below."},...Ei.map(t=>({id:`llm.models.${t}`,file:"regimen.yaml",path:["llm","models",t],type:"model",label:t,nullable:!0,suggestions:[...Si],help:`recommended: ${vo[t]} (the workflow preset may set a cheaper default \u2014 an explicit value here overrides both)`}))]},{id:"llm.effort",label:"Reasoning effort by role",help:"Reasoning effort per pipeline stage (Claude Code --effort). Empty \u21D2 the mechanical roles run lowered (build/estimate: low; draft/index/code-review-verify: medium) and every other role keeps the backend default.",fields:[{id:"llm.effort.default",file:"regimen.yaml",path:["llm","effort","default"],type:"enum",label:"default (catch-all)",nullable:!0,suggestions:[...Ri],help:"Overrides the recommended lowerings for every role not listed below."},...Ei.map(t=>({id:`llm.effort.${t}`,file:"regimen.yaml",path:["llm","effort",t],type:"enum",label:t,nullable:!0,suggestions:[...Ri],help:$o[t]?`recommended: ${$o[t]}`:"recommended: backend default"}))]}]},{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:oc,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:oc,help:`e.g. "implementation details, bullet list of what was done, in the tracker's language". Empty \u21D2 the default PR body.`}]},{id:"apply.delivery",label:"Delivery & merge",help:"How a finished change reaches the repository: with or without a pull request, and who merges it.",fields:[{id:"apply.pull_request",file:"project.yaml",path:["apply","pull_request"],type:"boolean",label:"Open a pull request",nullable:!1,help:"On (default): the task branch is pushed and a pull request is opened \u2014 the change is reviewable in the git host and keeps a history of review comments. Off: no PR at all; the branch is merged into the default branch directly, and the agent's review remarks live only in the dashboard and the Context Repo."},{id:"apply.done",file:"project.yaml",path:["apply","done"],type:"enum",label:"Task is done when",nullable:!1,suggestions:["merge","branch"],help:"merge (default): the task is finished only once its change lands in the default branch. branch: the task ends at the pushed branch (plus the PR, if enabled) and nothing is merged for you."},{id:"apply.auto_merge",file:"project.yaml",path:["apply","auto_merge"],type:"enum",label:"Auto-merge pull requests",nullable:!1,suggestions:["off","on_ci_green"],help:"Applies to the pull-request path only. off (default): the merge waits for you (Approve on the task card). on_ci_green: as soon as the PR is open, conflict-free and its CI is green, CodePipe merges it \u2014 changes reach the default branch with no further review from you. Requires full automation; branch protection on the host still applies (a refused merge parks the task). Without pull requests, full automation merges the branch itself and this switch does not apply."}]},{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:"testing",label:"Testing",help:"An optional phase after code review: writes the test plan you run in the morning and reports what it could verify.",fields:[{id:"testing.enabled",file:"regimen.yaml",path:["testing","enabled"],type:"boolean",nullable:!1,label:"Run the testing phase",help:"Off by default. When on, a task passing code review goes through a test pass before the PR: it derives TESTPLAN.md from the plan's requirements and reports per requirement what it could verify. A requirement it finds broken sends the change back for a fix (bounded below)."},{id:"testing.max_iterations",file:"regimen.yaml",path:["testing","max_iterations"],type:"number",nullable:!0,min:1,max:10,label:"Fix rounds before stopping",help:"How many times a failed test pass may send the change back before the task waits for you. Empty \u21D2 2."}]},{id:"code_review",label:"Code review",help:"One review mechanism for the pipeline's own changes and for developers' branches (the review column); they differ only in where the findings go.",fields:[{id:"code_review.verify_pass",file:"regimen.yaml",path:["code_review","verify_pass"],type:"boolean",nullable:!1,label:"Verifier pass (precision)",help:"On by default. A second, narrow agent checks every finding against the code (real? re-grade) before it costs a rework round or reaches a developer; the findings threshold below keeps small rounds cheap."},{id:"code_review.verify_min_findings",file:"regimen.yaml",path:["code_review","verify_min_findings"],type:"number",nullable:!0,min:1,label:"Verifier threshold (findings)",help:"The verifier runs only when a round carries at least this many actionable findings \u2014 1-2 are cheap to absorb, noise scales with volume. Empty = 3; 1 = verify every round."},{id:"code_review.max_blocking",file:"regimen.yaml",path:["code_review","max_blocking"],type:"number",nullable:!0,label:"Blocking budget (internal)",help:"Max blocker findings that keep their power in the pipeline's own review; the rest are demoted to major, weakest confidence first. Empty = 5."},{id:"code_review.external.max_blocking",file:"regimen.yaml",path:["code_review","external","max_blocking"],type:"number",nullable:!0,label:"Blocking budget (external)",help:"The same budget for a developer's branch review \u2014 tighter by default because a human reads these. Empty = 3."}]},{id:"skills",label:"Skills",help:"Reusable procedures the agent can invoke instead of improvising. Only their names and one-line descriptions sit in the prompt; the steps load when a skill is used.",fields:[{id:"skills.from_bundled",file:"regimen.yaml",path:["skills","from_bundled"],type:"boolean",nullable:!1,label:"Use the skills shipped with CodePipe",help:"On by default. General procedures maintained with the product."},{id:"skills.from_context_repo",file:"regimen.yaml",path:["skills","from_context_repo"],type:"boolean",nullable:!1,label:"Use this project's skills",help:"On by default. Skills the team writes in the context repository under `skills/<name>/SKILL.md`. These override a bundled skill of the same name."},{id:"skills.from_project_repo",file:"regimen.yaml",path:["skills","from_project_repo"],type:"boolean",nullable:!1,label:"Use the code repository's skills",help:"On by default. `.claude/skills/` inside the project repositories \u2014 the skills your developers already use locally. These win over both other sources."}]},{id:"quality",label:"Quality block",help:"Skip the whole quality block (build + code review) when a change touches only safe paths.",fields:[{id:"quality.skip_paths",file:"regimen.yaml",path:["quality","skip_paths"],type:"string_list",nullable:!0,label:"Skip paths (gitignore-style)",help:"When every changed file across all repos matches these globs, build and code review are skipped and the change goes straight to apply. One file outside the list runs both as usual. Use ! to re-include (e.g. !schema/**/*.md). Empty = never skip."}]},{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), the observer's intake plan waits for your APPROVE & START before the batch runs. Off \u21D2 conveyor: the batch starts automatically on the observer's plan. Either way every task passes the observer intake first."},{id:"observer.debounce_seconds",file:"regimen.yaml",path:["observer","debounce_seconds"],type:"number",label:"Intake window (seconds)",nullable:!0,min:5,max:3600,help:"How long the queue collects newly staged tasks before the observer reviews them as one batch. Empty \u21D2 60."},{id:"observer.fast_path",file:"regimen.yaml",path:["observer","fast_path"],type:"boolean",label:"Fast path for trivial tasks",nullable:!1,help:"On by default. A single small task with no links skips the observer's LLM pass and is routed by rules (noted in its journal as routed without review)."}]},{id:"council",label:"Council",help:"Several roles examine the same subject in parallel, each in its own process; a final session weighs their written opinions. Costs several agent runs per use \u2014 off by default, enable per phase.",fields:[{id:"council.questions",file:"regimen.yaml",path:["council","questions"],type:"boolean",nullable:!1,label:"Council on blocking questions",help:"Off (default): an agent's blocking question is answered by a single session, which keeps full automation moving cheaply. On: the council's roles each write an independent opinion first, and the answering session weighs them."},{id:"council.code_review",file:"regimen.yaml",path:["council","code_review"],type:"boolean",nullable:!1,label:"Council on code review",help:"Off (default): one reviewer session judges the change alone. On: the project's critic roles each review the change in their own parallel process first, and the reviewer session weighs their written findings into the verdict. Applies to the internal and the external review; the verifier pass always runs solo."},{id:"council.max_parallel",file:"regimen.yaml",path:["council","max_parallel"],type:"number",nullable:!0,min:1,max:5,label:"Max parallel roles",help:"How many role processes run at once (the rest wait their turn). Empty \u21D2 3; hard ceiling 5."}]},{id:"workflow",label:"Workflow",help:"How much pipeline a task gets. A preset is a set of defaults \u2014 any explicit setting below always wins over it.",fields:[{id:"workflow.preset",file:"regimen.yaml",path:["workflow","preset"],type:"enum",nullable:!1,suggestions:["express","balanced","full"],label:"Preset",help:"express \u2014 no analysis phase, no review: one implementation session on the capable model (cheapest, for small clear tasks). balanced \u2014 every phase, cheaper models for implementation and review. full \u2014 the classic pipeline on the capable model."},{id:"analysis.enabled",file:"regimen.yaml",path:["analysis","enabled"],type:"boolean",nullable:!1,label:"Analysis phase",help:"Whether a task starts with a dedicated analysis pass (plan + open questions) before implementation. Off \u21D2 the implementer works straight from the task text and the context pack; an explicit value here overrides the preset."}]},{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:xo.map(t=>({id:`language.${t}`,file:"project.yaml",path:["language",t],type:"string",label:b$[t],nullable:!0,maxLength:40,suggestions:t==="chat"?[we,...gn]:[...gn],help:k$[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:"On by default. Agents are asked to record intent annotations and receive an assembled context pack built from the project map. Off \u21D2 the pipeline ignores the map entirely and behaves exactly as if the feature were absent."},{id:"context.model.pack.idf_penalty",file:"regimen.yaml",path:["context","model","pack","idf_penalty"],type:"boolean",label:"Demote ubiquitous files in the pack",nullable:!1,help:"On by default. Files that reached the pack only through STATISTICAL co-change (not direct task evidence) are ranked down in proportion to how many past tasks touched them, so the budget goes to task-specific paths. Off restores pure activation order."},{id:"context.model.prompt.pack",file:"regimen.yaml",path:["context","model","prompt","pack"],type:"boolean",nullable:!1,label:"Give agents the context pack",help:"On by default. The assembled pack costs up to ~4000 tokens on every task of the analyze / estimate / implement / rework roles. Turning it off keeps the map building and stops the spend \u2014 the way to see what the pack is actually worth on this project."},{id:"context.model.prompt.annotations",file:"regimen.yaml",path:["context","model","prompt","annotations"],type:"boolean",nullable:!1,label:"Ask agents for intent annotations",help:"On by default. Adds the annotations block to the implement and rework prompts \u2014 the layer that records WHY the code is shaped this way. Cheap, and worth accumulating even while the pack is off."},{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 ${lt.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 ${lt.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 ${lt.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 ${lt.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 ${lt.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 ${lt.topK}.`}]},{id:"rate_limit",label:"Rate limit",help:"Automatic project pause as the LLM usage window fills up.",fields:[{id:"rate_limit.auto_pause.enabled",file:"project.yaml",path:["rate_limit","auto_pause","enabled"],type:"boolean",nullable:!1,label:"Pause the project near the limit",help:"On (default): when window utilization reaches the threshold, the project is paused (same pause as the manual one) and you get an email \u2014 the remaining window stays available for your own work. Off: agents keep working until the provider actually runs out."},{id:"rate_limit.auto_pause.threshold",file:"project.yaml",path:["rate_limit","auto_pause","threshold"],type:"number",float:!0,nullable:!0,min:.05,max:1,label:"Pause threshold (share of the window)",help:"Fraction of the usage window at which the pause fires; the rest (1 \u2212 threshold) is your manual-work reserve. Empty \u21D2 0.75."}]},{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."}]}]});var up=x(()=>{"use strict"});function dp(t){if(t==null)return[];if(!Array.isArray(t))return null;let e=[];for(let r of t){if(typeof r!="string"||r.trim().length===0)return null;e.push(r.trim())}return e}function cc(t){let{name:e,body:r,origin:n}=t;if(!ac.test(e))return{ok:!1,error:`role name must match ${ac} (got "${e}")`};if(r.trim().length===0)return{ok:!1,error:"role body is empty \u2014 the body IS the role's prompt"};let o=t.frontmatter;if(o==null||typeof o!="object"||Array.isArray(o))return{ok:!1,error:"missing or malformed frontmatter block"};let i=o,s=i.description;if(typeof s!="string"||s.trim().length===0)return{ok:!1,error:"description is required (one line: what this role looks for)"};if(s.length>300)return{ok:!1,error:"description must be \u2264 300 characters"};let a=dp(i.refs);if(a===null)return{ok:!1,error:"refs must be a list of non-empty paths"};if(a.length>10)return{ok:!1,error:"refs must list at most 10 files \u2014 a role is a narrow view"};for(let f of a)if(f.startsWith("/")||f.includes(".."))return{ok:!1,error:`ref "${f}" must be a path inside the Context Repo`};let c=dp(i.scenarios);if(c===null)return{ok:!1,error:"scenarios must be a list"};let l=[];for(let f of c){if(!Ii.includes(f))return{ok:!1,error:`unknown scenario "${f}" \u2014 one of: ${Ii.join(", ")}`};l.includes(f)||l.push(f)}if(l.length===0)return{ok:!1,error:`scenarios must name at least one of: ${Ii.join(", ")}`};let u=i.model;if(u!==void 0&&(typeof u!="string"||u.trim().length===0))return{ok:!1,error:"model must be a non-empty string when set"};let p=i.provider;if(p!==void 0&&(typeof p!="string"||p.trim().length===0))return{ok:!1,error:"provider must be a non-empty string when set"};let d=i.enabled;return d!==void 0&&typeof d!="boolean"?{ok:!1,error:"enabled must be true or false"}:{ok:!0,role:{name:e,description:s.trim(),...typeof u=="string"?{model:u.trim()}:{},...typeof p=="string"?{provider:p.trim()}:{},refs:a,scenarios:l,enabled:d!==!1,body:r.trim(),origin:n}}}function lc(t,e){let r=new Map;for(let n of t)r.set(n.name,n);for(let n of e)r.set(n.name,n);return[...r.values()].sort((n,o)=>n.name<o.name?-1:n.name>o.name?1:0)}function uc(t,e){return t.filter(r=>r.enabled&&r.scenarios.includes(e))}var Ii,ac,Kj,Hj,pp=x(()=>{"use strict";Ii=["plan_review","code_review","council"],ac=/^[a-z][a-z0-9-]{1,39}$/,Kj=10,Hj=300});function dc(t){return fp.includes(t)}function pc(t){return`prompts/${t}.md`}var fp,mp=x(()=>{"use strict";fp=["analysis","analyze","backfill","build","chat","code-review","code-review-external","code-review-fix","code-review-verify","config","council","draft","estimate","implement","implement-direct","index","observer","resolve-conflict","review-comment","rework","testing"]});function mc(t){if(!fc.test(t.name))return{ok:!1,error:`skill directory name must match ${fc}`};if(t.body.trim().length===0)return{ok:!1,error:"SKILL.md has no body \u2014 the body IS the procedure"};let e=t.frontmatter;if(!e||typeof e!="object"||Array.isArray(e))return{ok:!1,error:"SKILL.md has no frontmatter block"};let r=e.description;return typeof r!="string"||r.trim().length===0?{ok:!1,error:"description is required \u2014 it is what decides when the skill fires"}:r.length>300?{ok:!1,error:"description must be \u2264 300 characters"}:{ok:!0,skill:{name:t.name,description:r.trim()}}}function hc(t,e,r){let n=new Map;for(let o of[...t,...e,...r])n.set(o.name,o);return[...n.values()].sort((o,i)=>o.name<i.name?-1:o.name>i.name?1:0)}function gp(t){let e=t.trim(),r=e.lastIndexOf("@"),n=r===-1?e:e.slice(0,r),o=r===-1?"":e.slice(r+1).trim();if(!v$.test(n))return{ok:!1,error:`"${t}": expected <owner>/<repo>[@<40-hex sha>]`};let i=hp.find(s=>s.repo.toLowerCase()===n.toLowerCase());return o&&!$$.test(o)?{ok:!1,error:`"${t}": pin to a full 40-character commit sha \u2014 a branch or tag can change under you`}:!i&&!o?{ok:!1,error:`"${t}": a third-party marketplace must be pinned to a commit (<owner>/<repo>@<sha>). Its skills run beside your code with the agent's token.`}:{ok:!0,source:{repo:n,sha:o,name:i?.name??n.replace("/","-").toLowerCase(),official:!!i}}}function x$(t){let e=[],r=[],n=new Set;for(let o of t){if(!o.trim())continue;let i=gp(o);if(!i.ok){r.push(i.error);continue}n.has(i.source.name)||(n.add(i.source.name),e.push(i.source))}return{sources:e,errors:r}}function E$(t,e){let r=new Set(e.map(i=>i.name)),n={},o=[];for(let i of t){let s=i.trim();if(s){if(!S$.test(s)||!r.has(s.slice(s.indexOf("@")+1))){o.push(s);continue}n[s]=!0}}return{enabled:n,unknown:o}}var fc,Yj,hp,v$,$$,S$,yp=x(()=>{"use strict";fc=/^[a-z][a-z0-9-]{1,39}$/,Yj=300;hp=[{repo:"anthropics/skills",name:"anthropic-agent-skills"},{repo:"anthropics/claude-plugins-official",name:"claude-plugins-official"}],v$=/^[A-Za-z0-9][\w.-]*\/[A-Za-z0-9][\w.-]*$/,$$=/^[0-9a-f]{40}$/;S$=/^[A-Za-z0-9][\w.-]*@[A-Za-z0-9][\w.-]*$/});function wp(t,e){if(t==null)return[];if(!Array.isArray(t)||t.length>e)return null;let r=[];for(let n of t){if(typeof n!="string"||n.trim().length===0)return null;r.push(n.trim())}return r}function R$(t,e){if(!t||typeof t!="object"||Array.isArray(t))return{ok:!1,error:"queue plan must be a JSON object"};let r=new Set(e),n=t,o=wp(n.order,e.length);if(o===null)return{ok:!1,error:"order must be a list of task keys"};for(let m of o)if(!r.has(m))return{ok:!1,error:`order names ${m}, which is not in this batch`};if(new Set(o).size!==o.length)return{ok:!1,error:"order repeats a task key"};let i=e.filter(m=>!o.includes(m));if(o.length>0&&i.length>0)return{ok:!1,error:`order omits ${i.join(", ")}`};let s=n.tasks,a=[];if(s!=null){if(!Array.isArray(s))return{ok:!1,error:"tasks must be a list"};for(let m of s){if(!m||typeof m!="object")return{ok:!1,error:"each task entry must be an object"};let g=m,b=typeof g.taskKey=="string"?g.taskKey.trim():"";if(!r.has(b))return{ok:!1,error:`tasks names ${b||"(empty)"}, which is not in this batch`};let w=wp(g.after,e.length);if(w===null)return{ok:!1,error:`${b}: after must be a list of task keys`};for(let y of w){if(!r.has(y))return{ok:!1,error:`${b}: after names ${y}, not in this batch`};if(y===b)return{ok:!1,error:`${b}: cannot come after itself`}}let v=typeof g.decisions=="string"?g.decisions.trim():"";a.push({taskKey:b,decisions:v.slice(0,4e3),after:w})}}let c=[],l=n.conflicts;if(Array.isArray(l))for(let m of l){if(!m||typeof m!="object")continue;let g=m,b=typeof g.taskKey=="string"?g.taskKey.trim():"",w=typeof g.adr=="string"?g.adr.trim():"",v=typeof g.detail=="string"?g.detail.trim():"";!r.has(b)||!v||c.push({taskKey:b,adr:w,detail:v.slice(0,4e3)})}let u=[],p=n.related;if(Array.isArray(p))for(let m of p){if(!m||typeof m!="object")continue;let g=m,b=typeof g.taskKey=="string"?g.taskKey.trim():"",w=typeof g.detail=="string"?g.detail.trim():"";!b||!w||u.push({taskKey:b,detail:w.slice(0,4e3)})}let d=typeof n.summary=="string"?n.summary.trim().slice(0,4e3):"",f=n.deferBehind===!0;return{ok:!0,plan:{order:o,tasks:a,conflicts:c,related:u,summary:d,deferBehind:f}}}var zj,Xj,bp=x(()=>{"use strict";zj=4e3,Xj=4e3});function T$(t,e){if(!t||typeof t!="object"||Array.isArray(t))return{ok:!1,error:"council verdict must be a JSON object"};let r=t,n=r.unresolved===!0,o=typeof r.fork=="string"?r.fork.trim().slice(0,4e3):"";if(n)return o?{ok:!0,verdict:{answers:[],unresolved:!0,fork:o}}:{ok:!1,error:"an unresolved verdict must describe the fork"};let i=r.answers;if(!Array.isArray(i))return{ok:!1,error:"answers must be a list"};if(i.length!==e.length)return{ok:!1,error:`expected ${e.length} answer(s), got ${i.length}`};let s=[];for(let[a,c]of i.entries()){if(!c||typeof c!="object")return{ok:!1,error:`answer ${a+1} must be an object`};let l=c,u=typeof l.answer=="string"?l.answer.trim():"";if(!u)return{ok:!1,error:`answer ${a+1} is empty`};s.push({question:typeof l.question=="string"?l.question.trim():e[a],answer:u.slice(0,4e3),rationale:typeof l.rationale=="string"?l.rationale.trim().slice(0,4e3):""})}return{ok:!0,verdict:{answers:s,unresolved:!1,fork:""}}}var Zj,kp=x(()=>{"use strict";Zj=4e3});function P$(t){let e=t.replace(/^#+\s*/,"").trim();for(let r of I$)if(r.re.test(e))return{kind:r.kind,letter:r.letter};return null}function gc(t){let e=[],r=new Map,n="",o=null,i=null;for(let a of t.split(`
|
|
7
|
+
`}function Da(t){return _r(Od(t))}function Ua(t){return _r(Ld(t))}function pn(t){return _r(Md(t))}var Fe,Gv,Kv,Hv,Wv,ki,Ir,_d,ja,jd,qv,lt,Na,Oa,La,$i,Yv,Ma,Ar,zv,Ba=x(()=>{"use strict";Fe=2,Gv="model",Kv="model/README.md",Hv="model/facts",Wv="model/derived",ki="model/derived/INDEX.yaml",Ir="model/derived/relates.yaml";_d=["system","container","component","code","task","adr"],ja=["contains","touched_by","correlates","relates","references","depends_on"],jd=/^e_[0-9a-f]{8}$/;qv=["system","task","adr"];lt={windowCommits:1e3,commitFileCap:30,supportMin:5,jaccardMinPct:25,halfLifeDays:270,topK:8};Na=2,Oa=5,La=50,$i=2e3,Yv=5e4,Ma={touched_by:.8,references:.7,relates:.6,correlates:.4,contains:.3,depends_on:.5},Ar={budgetTokens:4e3,activationCutoff:.05,topKPerNode:8,nodeCap:200};zv=/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/});function Xv(t){return t==="DONE"}function Jv(t){return t==="AWAITING_EXTERNAL_FIX"?!1:Fa.indexOf(t)>=Fa.indexOf("IMPLEMENTING")}var Fa,Fd=x(()=>{"use strict";Fa=["BACKLOG","QUEUED","INTAKE","AWAITING_APPROVAL","ANALYZING","ESTIMATING","AWAITING_ANSWER","REVIEW","READY","IMPLEMENTING","BUILD","CODE_REVIEW","TESTING","AWAITING_EXTERNAL_FIX","READY_TO_APPLY","APPLYING","AWAITING_CLUSTER","TRACKING","NEEDS_MANUAL","DONE"]});function Qv(t){for(let e of Ga)if(e.phases.includes(t))return e.id;return null}function e$(t){for(let e of Gd)if(e.phases.includes(t))return e.id;return null}var Ga,Zv,Gd,Kd=x(()=>{"use strict";Ga=[{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"]}],Zv=Ga.flatMap(t=>t.phases),Gd=[{id:"review",label:"Review / tracking",phases:["CODE_REVIEW","TESTING","TRACKING"]},{id:"attention",label:"Need your attention",phases:["NEEDS_MANUAL","AWAITING_APPROVAL","AWAITING_EXTERNAL_FIX","AWAITING_ANSWER","REVIEW"]},{id:"backlog",label:"Backlog / queue",phases:["BACKLOG","QUEUED"]}]});function Ha(t){return Wd.includes(t)}function t$(t){return Hd.includes(t)?"planning":"implementation"}function ut(){return{inputTokens:0,outputTokens:0,cacheReadInputTokens:0,cacheCreationInputTokens:0,totalCostUsd:0,model:"",numTurns:0,durationMs:0}}var Ka,Hd,Wd,r$,Wa=x(()=>{"use strict";Ka=["estimate","analyze","implement","resolve-conflict","rework","draft","build","code-review","index","backfill","analysis","chat","config","observer","council","testing"],Hd=["draft","analysis","chat","config","observer","council"],Wd=["chat","config"];r$=1});function n$(t){return typeof t=="string"&&Jd.includes(t.trim())?t.trim():null}function qd(t,e){return e.toLowerCase().includes(t.toLowerCase())}function Ya(t){let e=t.filter(o=>o&&typeof o.id=="string"&&o.id.trim().length>0);if(e.length===0||tp.every(o=>e.some(i=>qd(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 ep){let i=n.find(s=>qd(o,s.id));if(i)return i.id}return n[0].id}function fn(){return{default:null,roles:{}}}function o$(t,e,r=Zd){let n=t?.roles?.[e];if(typeof n=="string"&&n.trim().length>0)return n.trim();if(t?.default&&t.default.trim().length>0)return t.default.trim();let o=Qd[r]?.[e];return o||(vo[e]??Xd)}function i$(t){let e=t?.provider;return typeof e=="string"&&e.trim().length>0?e.trim():tt}function s$(t){let e=fn();if(!t||typeof t!="object")return e;let r=t.llm;if(!r||typeof r!="object")return e;let n=r.provider;typeof n=="string"&&n.trim().length>0&&(e.provider=n.trim());let o=r.models;if(!o||typeof o!="object")return e;for(let[i,s]of Object.entries(o))typeof s!="string"||s.trim().length===0||(i==="default"?e.default=s.trim():e.roles[i]=s.trim());return e}function mn(){return{default:null,roles:{}}}function a$(t,e){let r=t?.roles?.[e];return typeof r=="string"&&r.trim().length>0?r.trim():t?.default&&t.default.trim().length>0?t.default.trim():$o[e]}function c$(t){let e=mn();if(!t||typeof t!="object")return e;let r=t.llm;if(!r||typeof r!="object")return e;let n=r.effort;if(!n||typeof n!="object")return e;for(let[o,i]of Object.entries(n))typeof i!="string"||i.trim().length===0||(o==="default"?e.default=i.trim():e.roles[o]=i.trim());return e}function l$(t){return t.default===null&&Object.keys(t.roles).length===0?null:JSON.stringify(t)}function u$(t){if(!t)return mn();try{let e=JSON.parse(t);if(!e||typeof e!="object")return mn();let r=e,n=mn();typeof r.default=="string"&&(n.default=r.default);let o=r.roles;if(o&&typeof o=="object")for(let[i,s]of Object.entries(o))typeof s=="string"&&(n.roles[i]=s);return n}catch{return mn()}}function d$(t){let e=typeof t.provider=="string"&&t.provider.trim().length>0&&t.provider.trim()!==tt;if(t.default===null&&Object.keys(t.roles).length===0&&!e)return null;let{provider:r,...n}=t;return JSON.stringify(e?{provider:r.trim(),...n}:n)}function p$(t){if(!t)return fn();try{let e=JSON.parse(t);if(!e||typeof e!="object")return fn();let r=e,n=fn();typeof r.provider=="string"&&r.provider.trim().length>0&&(n.provider=r.provider.trim()),typeof r.default=="string"&&(n.default=r.default);let o=r.roles;if(o&&typeof o=="object")for(let[i,s]of Object.entries(o))typeof s=="string"&&(n.roles[i]=s);return n}catch{return fn()}}var tt,qa,Ie,Ht,hn,Si,Yd,Vd,zd,Ei,vo,Xd,Jd,Zd,Qd,ep,tp,rp,Ri,$o,Va=x(()=>{"use strict";Wa();tt="claude",qa=[tt],Ie="opus",Ht="sonnet",hn="haiku",Si=[Ie,Ht,hn],Yd="build-discovery",Vd="code-review-verify",zd=[Yd,Vd],Ei=[...Ka,...zd],vo={analyze:Ie,implement:Ie,"resolve-conflict":Ie,rework:Ie,estimate:Ht,build:hn,"build-discovery":Ie,"code-review":Ie,"code-review-verify":Ht,draft:Ht,index:Ie,backfill:Ie,analysis:Ie,chat:Ie,config:Ie,observer:Ie,council:Ie,testing:Ie},Xd=Ie,Jd=["express","balanced","full"],Zd="full",Qd={express:{"code-review":Ht,"code-review-verify":hn},balanced:{implement:Ht,"code-review":Ht,"code-review-verify":hn},full:{}};ep=[Ie,Ht,hn],tp=Array.from(new Set(Object.values(vo)));rp=["low","medium","high","xhigh"],Ri=rp,$o={build:"low",estimate:"low",draft:"medium",index:"medium","code-review-verify":"medium"}});function Wt(t){return f$.has(t)?!0:m$.some(e=>t.startsWith(e))}function Ti(t,e){if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`${e} must be a mapping`);return t}function jr(t,e){if(t!=null){if(typeof t!="string")throw new Error(`${e} must be a string`);return t}}function Xa(t,e){if(t!=null){if(typeof t!="number"||!Number.isFinite(t))throw new Error(`${e} must be a number`);return t}}function Za(t,e){let r=Ti(e,"action definition"),n=t.replace(/\.(yml|yaml)$/i,""),o=jr(r.id,"id")??n;if(!za.test(o))throw new Error(`id must match ${za} (got "${o}")`);if(o!==n)throw new Error(`id "${o}" must match the file name ("${n}")`);let i=jr(r.title,"title")?.trim()||o,s;if(r.env!==void 0&&r.env!==null){let p=Ti(r.env,"env");s={};for(let[d,f]of Object.entries(p)){if(!rt.test(d))throw new Error(`env name "${d}" must match ${rt}`);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>np)throw new Error(`too many params (max ${np})`);let p=new Set;a=c.map((d,f)=>h$(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>op)throw new Error(`too many steps (max ${op})`);let u=l.map((p,d)=>{let f=Ti(p,`steps[${d}]`),m=jr(f.run,`steps[${d}].run`);if(!m||m.trim().length===0)throw new Error(`steps[${d}].run is required`);let g=jr(f.name,`steps[${d}].name`),b=Xa(f.timeout_sec,`steps[${d}].timeout_sec`);if(b!==void 0&&(!Number.isInteger(b)||b<=0))throw new Error(`steps[${d}].timeout_sec must be a positive integer`);return{run:m,...g?{name:g}:{},...b!==void 0?{timeout_sec:b}:{}}});return{id:o,title:i,...s?{env:s}:{},...a?{params:a}:{},steps:u}}function h$(t,e,r){let n=Ti(t,`params[${e}]`),o=jr(n.name,`params[${e}].name`);if(!o||!rt.test(o))throw new Error(`params[${e}].name must match ${rt}`);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=jr(n.label,`params[${e}].label`),c=jr(n.help,`params[${e}].help`),l=n.required===!0,u=Xa(n.min,`params[${e}].min`),p=Xa(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 Qa(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 rt,f$,m$,Ja,za,np,op,ec=x(()=>{"use strict";rt=/^[A-Z][A-Z0-9_]*$/,f$=new Set(["GH_TOKEN","GITHUB_TOKEN","GITLAB_TOKEN"]),m$=["BITBUCKET_","YOUTRACK_","CLAUDE_","INPUT_"];Ja=600,za=/^[a-z0-9-]+$/,np=32,op=64});function ip(){return{primary:we,context:we,tasks:we,docs:we,code_comments:we,chat:we,code_review:we,commits:we}}function sp(t){return!t||t.trim().length===0||t.trim().toLowerCase()===we}function g$(t){if(typeof t!="string")return we;let e=t.trim().replace(/\s+/g," ");return e.length===0||e.length>40||e.toLowerCase()===we?we:e}function y$(t){let e=ip();if(!t||typeof t!="object")return e;let r=t.language;if(!r||typeof r!="object"||Array.isArray(r))return e;let n=r;for(let o of xo)e[o]=g$(n[o]);return e}function w$(t){return xo.every(e=>sp(t[e]))}var we,xo,gn,So,tc=x(()=>{"use strict";we="auto",xo=["primary","context","tasks","docs","code_comments","chat","code_review","commits"],gn=["English","Russian","German","Spanish","French","Portuguese","Italian","Chinese","Japanese","Korean"],So=40});function ic(t=ap){let e=[];for(let r of t)e.push(...r.fields),r.groups&&e.push(...ic(r.groups));return e}function cp(t,e){let r=JSON.stringify(e);return ic().find(n=>n.file===t&&JSON.stringify(n.path)===r)}function sc(t){let e=cp(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)?{ok:!1,error:`${e.id} must be a number`}:!e.float&&!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>rc)return{ok:!1,error:`${e.id} must have \u2264 ${rc} entries`};let s={};for(let[a,c]of i){if(!rt.test(a))return{ok:!1,error:`${e.id}: name "${a}" must match ${rt}`};if(Wt(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>nc)return{ok:!1,error:`${e.id}: value of "${a}" must be \u2264 ${nc} chars`};s[a]=c}return{ok:!0,field:e,value:s}}}}var b$,k$,rc,nc,oc,ap,lp=x(()=>{"use strict";ec();Va();Ba();tc();b$={primary:"Primary language",context:"Context documents",tasks:"Tracker issues",docs:"Repo documentation",code_comments:"Code comments",chat:"Agent chat",code_review:"Code review comments",commits:"Commits & branches"},k$={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.",code_review:"Review findings and PR comments. Empty \u21D2 follows the tracker-issues language.",commits:"Commit/PR subject & branch slug. Empty \u21D2 follows the tracker-issues language."},rc=64,nc=2e3,oc=2e3,ap=[{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:[...qa],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:[...Si],help:"Overrides the recommended defaults for every role not listed below."},...Ei.map(t=>({id:`llm.models.${t}`,file:"regimen.yaml",path:["llm","models",t],type:"model",label:t,nullable:!0,suggestions:[...Si],help:`recommended: ${vo[t]} (the workflow preset may set a cheaper default \u2014 an explicit value here overrides both)`}))]},{id:"llm.effort",label:"Reasoning effort by role",help:"Reasoning effort per pipeline stage (Claude Code --effort). Empty \u21D2 the mechanical roles run lowered (build/estimate: low; draft/index/code-review-verify: medium) and every other role keeps the backend default.",fields:[{id:"llm.effort.default",file:"regimen.yaml",path:["llm","effort","default"],type:"enum",label:"default (catch-all)",nullable:!0,suggestions:[...Ri],help:"Overrides the recommended lowerings for every role not listed below."},...Ei.map(t=>({id:`llm.effort.${t}`,file:"regimen.yaml",path:["llm","effort",t],type:"enum",label:t,nullable:!0,suggestions:[...Ri],help:$o[t]?`recommended: ${$o[t]}`:"recommended: backend default"}))]}]},{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:oc,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:oc,help:`e.g. "implementation details, bullet list of what was done, in the tracker's language". Empty \u21D2 the default PR body.`}]},{id:"apply.delivery",label:"Delivery & merge",help:"How a finished change reaches the repository: with or without a pull request, and who merges it.",fields:[{id:"apply.pull_request",file:"project.yaml",path:["apply","pull_request"],type:"boolean",label:"Open a pull request",nullable:!1,help:"On (default): the task branch is pushed and a pull request is opened \u2014 the change is reviewable in the git host and keeps a history of review comments. Off: no PR at all; the branch is merged into the default branch directly, and the agent's review remarks live only in the dashboard and the Context Repo."},{id:"apply.done",file:"project.yaml",path:["apply","done"],type:"enum",label:"Task is done when",nullable:!1,suggestions:["merge","branch"],help:"merge (default): the task is finished only once its change lands in the default branch. branch: the task ends at the pushed branch (plus the PR, if enabled) and nothing is merged for you."},{id:"apply.auto_merge",file:"project.yaml",path:["apply","auto_merge"],type:"enum",label:"Auto-merge pull requests",nullable:!1,suggestions:["off","on_ci_green"],help:"Applies to the pull-request path only. off (default): the merge waits for you (Approve on the task card). on_ci_green: as soon as the PR is open, conflict-free and its CI is green, CodePipe merges it \u2014 changes reach the default branch with no further review from you. Requires full automation; branch protection on the host still applies (a refused merge parks the task). Without pull requests, full automation merges the branch itself and this switch does not apply."}]},{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:"testing",label:"Testing",help:"An optional phase after code review: writes the test plan you run in the morning and reports what it could verify.",fields:[{id:"testing.enabled",file:"regimen.yaml",path:["testing","enabled"],type:"boolean",nullable:!1,label:"Run the testing phase",help:"Off by default. When on, a task passing code review goes through a test pass before the PR: it derives TESTPLAN.md from the plan's requirements and reports per requirement what it could verify. A requirement it finds broken sends the change back for a fix (bounded below)."},{id:"testing.max_iterations",file:"regimen.yaml",path:["testing","max_iterations"],type:"number",nullable:!0,min:1,max:10,label:"Fix rounds before stopping",help:"How many times a failed test pass may send the change back before the task waits for you. Empty \u21D2 2."}]},{id:"code_review",label:"Code review",help:"One review mechanism for the pipeline's own changes and for developers' branches (the review column); they differ only in where the findings go.",fields:[{id:"code_review.verify_pass",file:"regimen.yaml",path:["code_review","verify_pass"],type:"boolean",nullable:!1,label:"Verifier pass (precision)",help:"On by default. A second, narrow agent checks every finding against the code (real? re-grade) before it costs a rework round or reaches a developer; the findings threshold below keeps small rounds cheap."},{id:"code_review.verify_min_findings",file:"regimen.yaml",path:["code_review","verify_min_findings"],type:"number",nullable:!0,min:1,label:"Verifier threshold (findings)",help:"The verifier runs only when a round carries at least this many actionable findings \u2014 1-2 are cheap to absorb, noise scales with volume. Empty = 3; 1 = verify every round."},{id:"code_review.max_blocking",file:"regimen.yaml",path:["code_review","max_blocking"],type:"number",nullable:!0,label:"Blocking budget (internal)",help:"Max blocker findings that keep their power in the pipeline's own review; the rest are demoted to major, weakest confidence first. Empty = 5."},{id:"code_review.external.max_blocking",file:"regimen.yaml",path:["code_review","external","max_blocking"],type:"number",nullable:!0,label:"Blocking budget (external)",help:"The same budget for a developer's branch review \u2014 tighter by default because a human reads these. Empty = 3."}]},{id:"skills",label:"Skills",help:"Reusable procedures the agent can invoke instead of improvising. Only their names and one-line descriptions sit in the prompt; the steps load when a skill is used.",fields:[{id:"skills.from_bundled",file:"regimen.yaml",path:["skills","from_bundled"],type:"boolean",nullable:!1,label:"Use the skills shipped with CodePipe",help:"On by default. General procedures maintained with the product."},{id:"skills.from_context_repo",file:"regimen.yaml",path:["skills","from_context_repo"],type:"boolean",nullable:!1,label:"Use this project's skills",help:"On by default. Skills the team writes in the context repository under `skills/<name>/SKILL.md`. These override a bundled skill of the same name."},{id:"skills.from_project_repo",file:"regimen.yaml",path:["skills","from_project_repo"],type:"boolean",nullable:!1,label:"Use the code repository's skills",help:"On by default. `.claude/skills/` inside the project repositories \u2014 the skills your developers already use locally. These win over both other sources."}]},{id:"quality",label:"Quality block",help:"Skip the whole quality block (build + code review) when a change touches only safe paths.",fields:[{id:"quality.skip_paths",file:"regimen.yaml",path:["quality","skip_paths"],type:"string_list",nullable:!0,label:"Skip paths (gitignore-style)",help:"When every changed file across all repos matches these globs, build and code review are skipped and the change goes straight to apply. One file outside the list runs both as usual. Use ! to re-include (e.g. !schema/**/*.md). Empty = never skip."}]},{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), the observer's intake plan waits for your APPROVE & START before the batch runs. Off \u21D2 conveyor: the batch starts automatically on the observer's plan. Either way every task passes the observer intake first."},{id:"observer.debounce_seconds",file:"regimen.yaml",path:["observer","debounce_seconds"],type:"number",label:"Intake window (seconds)",nullable:!0,min:5,max:3600,help:"How long the queue collects newly staged tasks before the observer reviews them as one batch. Empty \u21D2 60."},{id:"observer.fast_path",file:"regimen.yaml",path:["observer","fast_path"],type:"boolean",label:"Fast path for trivial tasks",nullable:!1,help:"On by default. A single small task with no links skips the observer's LLM pass and is routed by rules (noted in its journal as routed without review)."}]},{id:"council",label:"Council",help:"Several roles examine the same subject in parallel, each in its own process; a final session weighs their written opinions. Costs several agent runs per use \u2014 off by default, enable per phase.",fields:[{id:"council.questions",file:"regimen.yaml",path:["council","questions"],type:"boolean",nullable:!1,label:"Council on blocking questions",help:"Off (default): an agent's blocking question is answered by a single session, which keeps full automation moving cheaply. On: the council's roles each write an independent opinion first, and the answering session weighs them."},{id:"council.code_review",file:"regimen.yaml",path:["council","code_review"],type:"boolean",nullable:!1,label:"Council on code review",help:"Off (default): one reviewer session judges the change alone. On: the project's critic roles each review the change in their own parallel process first, and the reviewer session weighs their written findings into the verdict. Applies to the internal and the external review; the verifier pass always runs solo."},{id:"council.max_parallel",file:"regimen.yaml",path:["council","max_parallel"],type:"number",nullable:!0,min:1,max:5,label:"Max parallel roles",help:"How many role processes run at once (the rest wait their turn). Empty \u21D2 3; hard ceiling 5."}]},{id:"workflow",label:"Workflow",help:"How much pipeline a task gets. A preset is a set of defaults \u2014 any explicit setting below always wins over it.",fields:[{id:"workflow.preset",file:"regimen.yaml",path:["workflow","preset"],type:"enum",nullable:!1,suggestions:["express","balanced","full"],label:"Preset",help:"express \u2014 no analysis phase, no review: one implementation session on the capable model (cheapest, for small clear tasks). balanced \u2014 every phase, cheaper models for implementation and review. full \u2014 the classic pipeline on the capable model."},{id:"workflow.observer_routing",file:"regimen.yaml",path:["workflow","observer_routing"],type:"boolean",nullable:!1,label:"Observer routes presets",help:"Off (default): every task runs the project's preset. On: the intake observer may assign a preset per task (a small clear task goes express, a risky one goes full), within the allowed list below; your explicit pick on a queued task always wins. A task that gets stuck on express escalates to the full pipeline automatically."},{id:"workflow.allowed_presets",file:"regimen.yaml",path:["workflow","allowed_presets"],type:"string_list",nullable:!0,label:"Presets the observer may use",help:"Limits observer routing, e.g. only balanced and full (no express). Empty \u21D2 all three."},{id:"analysis.enabled",file:"regimen.yaml",path:["analysis","enabled"],type:"boolean",nullable:!1,label:"Analysis phase",help:"Whether a task starts with a dedicated analysis pass (plan + open questions) before implementation. Off \u21D2 the implementer works straight from the task text and the context pack; an explicit value here overrides the preset."}]},{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:xo.map(t=>({id:`language.${t}`,file:"project.yaml",path:["language",t],type:"string",label:b$[t],nullable:!0,maxLength:40,suggestions:t==="chat"?[we,...gn]:[...gn],help:k$[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:"On by default. Agents are asked to record intent annotations and receive an assembled context pack built from the project map. Off \u21D2 the pipeline ignores the map entirely and behaves exactly as if the feature were absent."},{id:"context.model.pack.idf_penalty",file:"regimen.yaml",path:["context","model","pack","idf_penalty"],type:"boolean",label:"Demote ubiquitous files in the pack",nullable:!1,help:"On by default. Files that reached the pack only through STATISTICAL co-change (not direct task evidence) are ranked down in proportion to how many past tasks touched them, so the budget goes to task-specific paths. Off restores pure activation order."},{id:"context.model.prompt.pack",file:"regimen.yaml",path:["context","model","prompt","pack"],type:"boolean",nullable:!1,label:"Give agents the context pack",help:"On by default. The assembled pack costs up to ~4000 tokens on every task of the analyze / estimate / implement / rework roles. Turning it off keeps the map building and stops the spend \u2014 the way to see what the pack is actually worth on this project."},{id:"context.model.prompt.annotations",file:"regimen.yaml",path:["context","model","prompt","annotations"],type:"boolean",nullable:!1,label:"Ask agents for intent annotations",help:"On by default. Adds the annotations block to the implement and rework prompts \u2014 the layer that records WHY the code is shaped this way. Cheap, and worth accumulating even while the pack is off."},{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 ${lt.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 ${lt.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 ${lt.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 ${lt.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 ${lt.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 ${lt.topK}.`}]},{id:"rate_limit",label:"Rate limit",help:"Automatic project pause as the LLM usage window fills up.",fields:[{id:"rate_limit.auto_pause.enabled",file:"project.yaml",path:["rate_limit","auto_pause","enabled"],type:"boolean",nullable:!1,label:"Pause the project near the limit",help:"On (default): when window utilization reaches the threshold, the project is paused (same pause as the manual one) and you get an email \u2014 the remaining window stays available for your own work. Off: agents keep working until the provider actually runs out."},{id:"rate_limit.auto_pause.threshold",file:"project.yaml",path:["rate_limit","auto_pause","threshold"],type:"number",float:!0,nullable:!0,min:.05,max:1,label:"Pause threshold (share of the window)",help:"Fraction of the usage window at which the pause fires; the rest (1 \u2212 threshold) is your manual-work reserve. Empty \u21D2 0.75."}]},{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."}]}]});var up=x(()=>{"use strict"});function dp(t){if(t==null)return[];if(!Array.isArray(t))return null;let e=[];for(let r of t){if(typeof r!="string"||r.trim().length===0)return null;e.push(r.trim())}return e}function cc(t){let{name:e,body:r,origin:n}=t;if(!ac.test(e))return{ok:!1,error:`role name must match ${ac} (got "${e}")`};if(r.trim().length===0)return{ok:!1,error:"role body is empty \u2014 the body IS the role's prompt"};let o=t.frontmatter;if(o==null||typeof o!="object"||Array.isArray(o))return{ok:!1,error:"missing or malformed frontmatter block"};let i=o,s=i.description;if(typeof s!="string"||s.trim().length===0)return{ok:!1,error:"description is required (one line: what this role looks for)"};if(s.length>300)return{ok:!1,error:"description must be \u2264 300 characters"};let a=dp(i.refs);if(a===null)return{ok:!1,error:"refs must be a list of non-empty paths"};if(a.length>10)return{ok:!1,error:"refs must list at most 10 files \u2014 a role is a narrow view"};for(let f of a)if(f.startsWith("/")||f.includes(".."))return{ok:!1,error:`ref "${f}" must be a path inside the Context Repo`};let c=dp(i.scenarios);if(c===null)return{ok:!1,error:"scenarios must be a list"};let l=[];for(let f of c){if(!Ii.includes(f))return{ok:!1,error:`unknown scenario "${f}" \u2014 one of: ${Ii.join(", ")}`};l.includes(f)||l.push(f)}if(l.length===0)return{ok:!1,error:`scenarios must name at least one of: ${Ii.join(", ")}`};let u=i.model;if(u!==void 0&&(typeof u!="string"||u.trim().length===0))return{ok:!1,error:"model must be a non-empty string when set"};let p=i.provider;if(p!==void 0&&(typeof p!="string"||p.trim().length===0))return{ok:!1,error:"provider must be a non-empty string when set"};let d=i.enabled;return d!==void 0&&typeof d!="boolean"?{ok:!1,error:"enabled must be true or false"}:{ok:!0,role:{name:e,description:s.trim(),...typeof u=="string"?{model:u.trim()}:{},...typeof p=="string"?{provider:p.trim()}:{},refs:a,scenarios:l,enabled:d!==!1,body:r.trim(),origin:n}}}function lc(t,e){let r=new Map;for(let n of t)r.set(n.name,n);for(let n of e)r.set(n.name,n);return[...r.values()].sort((n,o)=>n.name<o.name?-1:n.name>o.name?1:0)}function uc(t,e){return t.filter(r=>r.enabled&&r.scenarios.includes(e))}var Ii,ac,Kj,Hj,pp=x(()=>{"use strict";Ii=["plan_review","code_review","council"],ac=/^[a-z][a-z0-9-]{1,39}$/,Kj=10,Hj=300});function dc(t){return fp.includes(t)}function pc(t){return`prompts/${t}.md`}var fp,mp=x(()=>{"use strict";fp=["analysis","analyze","backfill","build","chat","code-review","code-review-external","code-review-fix","code-review-verify","config","council","draft","estimate","implement","implement-direct","index","observer","resolve-conflict","review-comment","rework","testing"]});function mc(t){if(!fc.test(t.name))return{ok:!1,error:`skill directory name must match ${fc}`};if(t.body.trim().length===0)return{ok:!1,error:"SKILL.md has no body \u2014 the body IS the procedure"};let e=t.frontmatter;if(!e||typeof e!="object"||Array.isArray(e))return{ok:!1,error:"SKILL.md has no frontmatter block"};let r=e.description;return typeof r!="string"||r.trim().length===0?{ok:!1,error:"description is required \u2014 it is what decides when the skill fires"}:r.length>300?{ok:!1,error:"description must be \u2264 300 characters"}:{ok:!0,skill:{name:t.name,description:r.trim()}}}function hc(t,e,r){let n=new Map;for(let o of[...t,...e,...r])n.set(o.name,o);return[...n.values()].sort((o,i)=>o.name<i.name?-1:o.name>i.name?1:0)}function gp(t){let e=t.trim(),r=e.lastIndexOf("@"),n=r===-1?e:e.slice(0,r),o=r===-1?"":e.slice(r+1).trim();if(!v$.test(n))return{ok:!1,error:`"${t}": expected <owner>/<repo>[@<40-hex sha>]`};let i=hp.find(s=>s.repo.toLowerCase()===n.toLowerCase());return o&&!$$.test(o)?{ok:!1,error:`"${t}": pin to a full 40-character commit sha \u2014 a branch or tag can change under you`}:!i&&!o?{ok:!1,error:`"${t}": a third-party marketplace must be pinned to a commit (<owner>/<repo>@<sha>). Its skills run beside your code with the agent's token.`}:{ok:!0,source:{repo:n,sha:o,name:i?.name??n.replace("/","-").toLowerCase(),official:!!i}}}function x$(t){let e=[],r=[],n=new Set;for(let o of t){if(!o.trim())continue;let i=gp(o);if(!i.ok){r.push(i.error);continue}n.has(i.source.name)||(n.add(i.source.name),e.push(i.source))}return{sources:e,errors:r}}function E$(t,e){let r=new Set(e.map(i=>i.name)),n={},o=[];for(let i of t){let s=i.trim();if(s){if(!S$.test(s)||!r.has(s.slice(s.indexOf("@")+1))){o.push(s);continue}n[s]=!0}}return{enabled:n,unknown:o}}var fc,Yj,hp,v$,$$,S$,yp=x(()=>{"use strict";fc=/^[a-z][a-z0-9-]{1,39}$/,Yj=300;hp=[{repo:"anthropics/skills",name:"anthropic-agent-skills"},{repo:"anthropics/claude-plugins-official",name:"claude-plugins-official"}],v$=/^[A-Za-z0-9][\w.-]*\/[A-Za-z0-9][\w.-]*$/,$$=/^[0-9a-f]{40}$/;S$=/^[A-Za-z0-9][\w.-]*@[A-Za-z0-9][\w.-]*$/});function wp(t,e){if(t==null)return[];if(!Array.isArray(t)||t.length>e)return null;let r=[];for(let n of t){if(typeof n!="string"||n.trim().length===0)return null;r.push(n.trim())}return r}function R$(t,e){if(!t||typeof t!="object"||Array.isArray(t))return{ok:!1,error:"queue plan must be a JSON object"};let r=new Set(e),n=t,o=wp(n.order,e.length);if(o===null)return{ok:!1,error:"order must be a list of task keys"};for(let m of o)if(!r.has(m))return{ok:!1,error:`order names ${m}, which is not in this batch`};if(new Set(o).size!==o.length)return{ok:!1,error:"order repeats a task key"};let i=e.filter(m=>!o.includes(m));if(o.length>0&&i.length>0)return{ok:!1,error:`order omits ${i.join(", ")}`};let s=n.tasks,a=[];if(s!=null){if(!Array.isArray(s))return{ok:!1,error:"tasks must be a list"};for(let m of s){if(!m||typeof m!="object")return{ok:!1,error:"each task entry must be an object"};let g=m,b=typeof g.taskKey=="string"?g.taskKey.trim():"";if(!r.has(b))return{ok:!1,error:`tasks names ${b||"(empty)"}, which is not in this batch`};let w=wp(g.after,e.length);if(w===null)return{ok:!1,error:`${b}: after must be a list of task keys`};for(let C of w){if(!r.has(C))return{ok:!1,error:`${b}: after names ${C}, not in this batch`};if(C===b)return{ok:!1,error:`${b}: cannot come after itself`}}let v=typeof g.decisions=="string"?g.decisions.trim():"",y,k=g.workflow;if(k&&typeof k=="object"){let C=k,E=typeof C.preset=="string"?C.preset.trim():"";if(E==="express"||E==="balanced"||E==="full"){let $=typeof C.reason=="string"?C.reason.trim().slice(0,4e3):"";y={preset:E,reason:$}}}a.push({taskKey:b,decisions:v.slice(0,4e3),after:w,...y?{workflow:y}:{}})}}let c=[],l=n.conflicts;if(Array.isArray(l))for(let m of l){if(!m||typeof m!="object")continue;let g=m,b=typeof g.taskKey=="string"?g.taskKey.trim():"",w=typeof g.adr=="string"?g.adr.trim():"",v=typeof g.detail=="string"?g.detail.trim():"";!r.has(b)||!v||c.push({taskKey:b,adr:w,detail:v.slice(0,4e3)})}let u=[],p=n.related;if(Array.isArray(p))for(let m of p){if(!m||typeof m!="object")continue;let g=m,b=typeof g.taskKey=="string"?g.taskKey.trim():"",w=typeof g.detail=="string"?g.detail.trim():"";!b||!w||u.push({taskKey:b,detail:w.slice(0,4e3)})}let d=typeof n.summary=="string"?n.summary.trim().slice(0,4e3):"",f=n.deferBehind===!0;return{ok:!0,plan:{order:o,tasks:a,conflicts:c,related:u,summary:d,deferBehind:f}}}var zj,Xj,bp=x(()=>{"use strict";zj=4e3,Xj=4e3});function T$(t,e){if(!t||typeof t!="object"||Array.isArray(t))return{ok:!1,error:"council verdict must be a JSON object"};let r=t,n=r.unresolved===!0,o=typeof r.fork=="string"?r.fork.trim().slice(0,4e3):"";if(n)return o?{ok:!0,verdict:{answers:[],unresolved:!0,fork:o}}:{ok:!1,error:"an unresolved verdict must describe the fork"};let i=r.answers;if(!Array.isArray(i))return{ok:!1,error:"answers must be a list"};if(i.length!==e.length)return{ok:!1,error:`expected ${e.length} answer(s), got ${i.length}`};let s=[];for(let[a,c]of i.entries()){if(!c||typeof c!="object")return{ok:!1,error:`answer ${a+1} must be an object`};let l=c,u=typeof l.answer=="string"?l.answer.trim():"";if(!u)return{ok:!1,error:`answer ${a+1} is empty`};s.push({question:typeof l.question=="string"?l.question.trim():e[a],answer:u.slice(0,4e3),rationale:typeof l.rationale=="string"?l.rationale.trim().slice(0,4e3):""})}return{ok:!0,verdict:{answers:s,unresolved:!1,fork:""}}}var Zj,kp=x(()=>{"use strict";Zj=4e3});function P$(t){let e=t.replace(/^#+\s*/,"").trim();for(let r of I$)if(r.re.test(e))return{kind:r.kind,letter:r.letter};return null}function gc(t){let e=[],r=new Map,n="",o=null,i=null;for(let a of t.split(`
|
|
8
8
|
`)){let c=/^#{1,6}\s+(.*)$/.exec(a);if(c){n=c[1].trim(),o=P$(n),i=null;continue}let l=C$.exec(a);if(l&&o){let u=l[1];r.set(u,(r.get(u)??0)+1),i={id:u,kind:o.kind,text:l[2].trim(),section:n},e.push(i);continue}if(i&&a.trim()&&!/^#{1,6}\s/.test(a)&&!/^\s*[-*]\s/.test(a)){i.text=`${i.text}
|
|
9
9
|
${a.trim()}`.trim();continue}a.trim()||(i=null)}let s=[...r.entries()].filter(([,a])=>a>1).map(([a])=>a);return{items:e,structured:e.length>=2&&s.length===0,duplicateIds:s}}function A$(t){let e={decision:"D",change:"C",assumption:"A",out_of_scope:"O",test:"T",procedure:"P"};return t.items.filter(r=>!r.id.startsWith(e[r.kind]))}function _$(t,e){let r=new Map(t.items.map(s=>[s.id,s])),n=e.filter(s=>!s.approved),o=e.filter(s=>s.approved).map(s=>s.id);if(n.length===0)return"";let i=["Rejected plan items:",""];for(let s of n){let a=r.get(s.id),c=a?`${s.id} \u2014 ${a.text.split(`
|
|
10
10
|
`)[0]}`:s.id;i.push(`- **${c}**`),s.remark?.trim()&&i.push(` ${s.remark.trim()}`)}return o.length>0&&i.push("",`Approved and settled: ${o.join(", ")}. Do not revisit these unless a`,"rejected item forces it \u2014 and say so explicitly if it does."),i.join(`
|
|
@@ -647,6 +647,13 @@ workflow:
|
|
|
647
647
|
# balanced \u2014 every phase, cheaper models for implementation and review.
|
|
648
648
|
# full \u2014 the classic pipeline on the capable model everywhere.
|
|
649
649
|
preset: balanced
|
|
650
|
+
# Let the intake observer route EACH task to a preset by its content (a
|
|
651
|
+
# small clear task goes express, a risky one goes full); your explicit pick
|
|
652
|
+
# on a queued task always wins, and an express task that gets stuck
|
|
653
|
+
# escalates to the full pipeline automatically. Off by default.
|
|
654
|
+
observer_routing: false
|
|
655
|
+
# Limit what the observer may pick. Absent = all three presets.
|
|
656
|
+
# allowed_presets: [balanced, full]
|
|
650
657
|
|
|
651
658
|
# The dedicated analysis pass (plan + open questions) before implementation.
|
|
652
659
|
# Absent = the preset decides (express: off). An explicit value overrides the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-partner/codepipe",
|
|
3
|
-
"version": "0.14.1-dev.
|
|
3
|
+
"version": "0.14.1-dev.301.g31b1f362",
|
|
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",
|