@mthanh/vespercli 2.1.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +22 -2
  2. package/assets/CATALOG.md +14 -0
  3. package/assets/claude/.claude-plugin/marketplace.json +21 -15
  4. package/assets/claude/.claude-plugin/plugin.json +1 -1
  5. package/assets/claude/agents/workspace-learner.md +1 -1
  6. package/assets/claude/orchestration.md.tpl +1 -1
  7. package/assets/claude/packs/backend/.claude-plugin/plugin.json +1 -1
  8. package/assets/claude/packs/docs/.claude-plugin/plugin.json +1 -1
  9. package/assets/claude/packs/frontend/.claude-plugin/plugin.json +1 -1
  10. package/assets/claude/packs/graphify/.claude-plugin/plugin.json +10 -0
  11. package/assets/claude/packs/graphify/skills/agent-fundamentals/SKILL.md +89 -0
  12. package/assets/claude/packs/graphify/skills/agent-fundamentals/references/codebase-query.md +95 -0
  13. package/assets/claude/packs/graphify/skills/agent-fundamentals/references/terminal-discipline.md +94 -0
  14. package/assets/claude/packs/graphify/skills/agent-fundamentals/references/tool-usage-patterns.md +67 -0
  15. package/assets/claude/packs/graphify/skills/graphify-research/SKILL.md +101 -0
  16. package/assets/claude/packs/integrations/.claude-plugin/plugin.json +1 -1
  17. package/assets/claude/packs/playwright/.claude-plugin/plugin.json +1 -1
  18. package/assets/claude/packs/polyglot/.claude-plugin/plugin.json +1 -1
  19. package/assets/claude/packs/styles/.claude-plugin/plugin.json +1 -1
  20. package/assets/claude/vesper-orchestrator.md +1 -1
  21. package/assets/copilot/agents/workspace-learner.agent.md +1 -1
  22. package/assets/copilot/packs/graphify/skills/graphify-research/SKILL.md +101 -0
  23. package/assets/manifest.json +3 -0
  24. package/dist/cli.min.js +122 -107
  25. package/package.json +1 -1
  26. package/scripts/packs-layout.test.js +23 -2
  27. package/src/mcp/vesper-indexing/dist/indexer/chunker.js +83 -2
  28. package/src/mcp/vesper-indexing/dist/indexer/chunker.js.map +1 -1
  29. package/src/mcp/vesper-indexing/package-lock.json +2 -2
  30. package/src/mcp/vesper-indexing/package.json +1 -1
package/dist/cli.min.js CHANGED
@@ -1,98 +1,111 @@
1
- var im=Object.defineProperty;var ee=(e,t)=>()=>(e&&(t=e(e=0)),t);var yn=(e,t)=>{for(var r in t)im(e,r,{get:t[r],enumerable:!0})};var hl={};yn(hl,{HOOK_GUARD_END:()=>Tr,HOOK_GUARD_START:()=>kt,classifyForeignHook:()=>Pr,findTopLevelExit:()=>fl,hookInterpreter:()=>pl,isBinaryHook:()=>Ni,removeHookRegion:()=>nr});function Ni(e){let t=Buffer.isBuffer(e)?e:Buffer.from(e??[]);if(t.subarray(0,8192).includes(0))return!0;let r=t.subarray(0,4).toString("hex");return r==="7f454c46"||["feedface","feedfacf","cefaedfe","cffaedfe","cafebabe"].includes(r)?!0:t.length>=2&&t[0]===77&&t[1]===90}function pl(e){if(!e.startsWith("#!"))return"sh";let t=e.slice(2).trim().split(/\s+/).filter(Boolean),r=o=>(o??"").split("/").pop(),n=0,s=r(t[n]);if(s==="env"){for(n+=1;n<t.length;){let o=t[n];if(o.startsWith("-S")&&o.length>2){t[n]=o.slice(2);break}if(o==="-u"||o==="-C"||o==="--unset"||o==="--chdir"){n+=2;continue}if(o.startsWith("-")||/^[A-Za-z_][A-Za-z0-9_]*=/.test(o)){n+=1;continue}break}s=r(t[n])}if(s==="busybox"){let o=r(t[n+1]);return o==="sh"||o==="ash"?o:"busybox"}return s||"sh"}function Pr(e,{whole:t}={}){let r=c=>Buffer.isBuffer(c)?c:Buffer.from(String(c??""),"utf-8"),n=r(e);if(Ni(r(t??n))||Ni(n))return{ok:!1,reason:"foreign-hook-language",interpreter:"binary"};let s=n.toString("utf-8"),o=s.split(`
2
- `,1)[0].replace(/\r$/,""),i=pl(o);if(!am.test(i))return{ok:!1,reason:"foreign-hook-language",interpreter:i};let a=fl(s);return a?{ok:!1,reason:"foreign-hook-exits",interpreter:i,line:a}:{ok:!0,interpreter:i}}function nr(e){let t=e.indexOf(kt);if(t===-1)return null;let r=e.indexOf(Tr,t);if(r===-1)return null;let n=t,s=r+Tr.length;return n>0&&e[n-1]===`
1
+ var eg=Object.defineProperty;var Z=(e,t)=>()=>(e&&(t=e(e=0)),t);var jn=(e,t)=>{for(var r in t)eg(e,r,{get:t[r],enumerable:!0})};var Jl={};jn(Jl,{HOOK_GUARD_END:()=>Yt,HOOK_GUARD_START:()=>ot,classifyForeignHook:()=>Ur,findTopLevelExit:()=>Yl,hookInterpreter:()=>zl,isBinaryHook:()=>ia,removeHookRegion:()=>vr});function ia(e){let t=Buffer.isBuffer(e)?e:Buffer.from(e??[]);if(t.subarray(0,8192).includes(0))return!0;let r=t.subarray(0,4).toString("hex");return r==="7f454c46"||["feedface","feedfacf","cefaedfe","cffaedfe","cafebabe"].includes(r)?!0:t.length>=2&&t[0]===77&&t[1]===90}function zl(e){if(!e.startsWith("#!"))return"sh";let t=e.slice(2).trim().split(/\s+/).filter(Boolean),r=o=>(o??"").split("/").pop(),n=0,s=r(t[n]);if(s==="env"){for(n+=1;n<t.length;){let o=t[n];if(o.startsWith("-S")&&o.length>2){t[n]=o.slice(2);break}if(o==="-u"||o==="-C"||o==="--unset"||o==="--chdir"){n+=2;continue}if(o.startsWith("-")||/^[A-Za-z_][A-Za-z0-9_]*=/.test(o)){n+=1;continue}break}s=r(t[n])}if(s==="busybox"){let o=r(t[n+1]);return o==="sh"||o==="ash"?o:"busybox"}return s||"sh"}function Ur(e,{whole:t}={}){let r=c=>Buffer.isBuffer(c)?c:Buffer.from(String(c??""),"utf-8"),n=r(e);if(ia(r(t??n))||ia(n))return{ok:!1,reason:"foreign-hook-language",interpreter:"binary"};let s=n.toString("utf-8"),o=s.split(`
2
+ `,1)[0].replace(/\r$/,""),i=zl(o);if(!tg.test(i))return{ok:!1,reason:"foreign-hook-language",interpreter:i};let a=Yl(s);return a?{ok:!1,reason:"foreign-hook-exits",interpreter:i,line:a}:{ok:!0,interpreter:i}}function vr(e){let t=e.indexOf(ot);if(t===-1)return null;let r=e.indexOf(Yt,t);if(r===-1)return null;let n=t,s=r+Yt.length;return n>0&&e[n-1]===`
3
3
  `&&(n-=1),e[s]===`
4
- `&&(s+=1),e.slice(0,n)+e.slice(s)}function pm(e){let t=[],r=[],n=0,s=1,o="",i=1,a=!1,c=e.length,l=()=>{(o!==""||a)&&t.push({t:"word",v:o,line:i,quoted:a}),o="",a=!1},d=f=>{o===""&&!a&&(i=s),o+=f},p=(f,g,y)=>{let k=0;for(;f<c;f+=1){let v=e[f];if(v==="\\"){f+=1;continue}if(v===`
5
- `&&(s+=1),v==="'"&&g==="("){let S=e.indexOf("'",f+1);if(S===-1)return-1;s+=dl(e,f,S),f=S;continue}if(v==='"'){let S=h(f+1);if(S===-1)return-1;f=S;continue}if(v==="`"){let S=m(f+1);if(S===-1)return-1;f=S;continue}if(v===g)k+=1;else if(v===y&&(k-=1,k===0))return f}return-1},h=f=>{for(;f<c;f+=1){let g=e[f];if(g==="\\"){f+=1;continue}if(g===`
6
- `&&(s+=1),g==='"')return f;if(g==="$"&&(e[f+1]==="("||e[f+1]==="{")){let y=p(f+1,e[f+1],e[f+1]==="("?")":"}");if(y===-1)return-1;f=y;continue}if(g==="`"){let y=m(f+1);if(y===-1)return-1;f=y}}return-1},m=f=>{for(;f<c;f+=1){let g=e[f];if(g==="\\"){f+=1;continue}if(g===`
7
- `&&(s+=1),g==="`")return f}return-1};for(;n<c;){let f=e[n];if(f==="\\"){if(e[n+1]===`
8
- `){n+=2,s+=1;continue}d(e.slice(n,n+2)),n+=2;continue}if(f==="'"){let g=e.indexOf("'",n+1);if(g===-1)return null;o===""&&!a&&(i=s),s+=dl(e,n,g),o+=e.slice(n+1,g),a=!0,n=g+1;continue}if(f==='"'){let g=s,y=h(n+1);if(y===-1)return null;o===""&&!a&&(i=g),o+=e.slice(n+1,y),a=!0,n=y+1;continue}if(f==="`"){let g=m(n+1);if(g===-1)return null;d(e.slice(n,g+1)),n=g+1;continue}if(f==="$"&&(e[n+1]==="("||e[n+1]==="{")){let g=s,y=p(n+1,e[n+1],e[n+1]==="("?")":"}");if(y===-1)return null;o===""&&!a&&(i=g),o+=e.slice(n,y+1),n=y+1;continue}if(f==="#"&&o===""&&!a){let g=e.indexOf(`
9
- `,n);n=g===-1?c:g;continue}if(f===`
4
+ `&&(s+=1),e.slice(0,n)+e.slice(s)}function ig(e){let t=[],r=[],n=0,s=1,o="",i=1,a=!1,c=e.length,l=()=>{(o!==""||a)&&t.push({t:"word",v:o,line:i,quoted:a}),o="",a=!1},d=h=>{o===""&&!a&&(i=s),o+=h},p=(h,g,y)=>{let k=0;for(;h<c;h+=1){let v=e[h];if(v==="\\"){h+=1;continue}if(v===`
5
+ `&&(s+=1),v==="'"&&g==="("){let S=e.indexOf("'",h+1);if(S===-1)return-1;s+=Bl(e,h,S),h=S;continue}if(v==='"'){let S=f(h+1);if(S===-1)return-1;h=S;continue}if(v==="`"){let S=m(h+1);if(S===-1)return-1;h=S;continue}if(v===g)k+=1;else if(v===y&&(k-=1,k===0))return h}return-1},f=h=>{for(;h<c;h+=1){let g=e[h];if(g==="\\"){h+=1;continue}if(g===`
6
+ `&&(s+=1),g==='"')return h;if(g==="$"&&(e[h+1]==="("||e[h+1]==="{")){let y=p(h+1,e[h+1],e[h+1]==="("?")":"}");if(y===-1)return-1;h=y;continue}if(g==="`"){let y=m(h+1);if(y===-1)return-1;h=y}}return-1},m=h=>{for(;h<c;h+=1){let g=e[h];if(g==="\\"){h+=1;continue}if(g===`
7
+ `&&(s+=1),g==="`")return h}return-1};for(;n<c;){let h=e[n];if(h==="\\"){if(e[n+1]===`
8
+ `){n+=2,s+=1;continue}d(e.slice(n,n+2)),n+=2;continue}if(h==="'"){let g=e.indexOf("'",n+1);if(g===-1)return null;o===""&&!a&&(i=s),s+=Bl(e,n,g),o+=e.slice(n+1,g),a=!0,n=g+1;continue}if(h==='"'){let g=s,y=f(n+1);if(y===-1)return null;o===""&&!a&&(i=g),o+=e.slice(n+1,y),a=!0,n=y+1;continue}if(h==="`"){let g=m(n+1);if(g===-1)return null;d(e.slice(n,g+1)),n=g+1;continue}if(h==="$"&&(e[n+1]==="("||e[n+1]==="{")){let g=s,y=p(n+1,e[n+1],e[n+1]==="("?")":"}");if(y===-1)return null;o===""&&!a&&(i=g),o+=e.slice(n,y+1),n=y+1;continue}if(h==="#"&&o===""&&!a){let g=e.indexOf(`
9
+ `,n);n=g===-1?c:g;continue}if(h===`
10
10
  `){for(l(),t.push({t:"op",v:`
11
11
  `,line:s}),s+=1,n+=1;r.length>0;){let{delim:g,strip:y}=r.shift(),k=!1;for(;n<c;){let v=e.indexOf(`
12
- `,n),S=e.slice(n,v===-1?c:v),A=y?S.replace(/^\t+/,""):S;if(n=v===-1?c:v+1,s+=1,A===g){k=!0;break}}if(!k)return null}continue}if(f===" "||f===" "||f==="\r"){l(),n+=1;continue}if(f===";"){if(l(),e[n+1]===";"){t.push({t:"op",v:";;",line:s}),n+=e[n+2]==="&"?3:2;continue}if(e[n+1]==="&"){t.push({t:"op",v:";;",line:s}),n+=2;continue}t.push({t:"op",v:";",line:s}),n+=1;continue}if(f==="&"){if(o!==""&&/[<>]$/.test(o)){d("&"),n+=1;continue}if(e[n+1]===">"){d("&"),n+=1;continue}if(l(),e[n+1]==="&"){t.push({t:"op",v:"&&",line:s}),n+=2;continue}t.push({t:"op",v:"&",line:s}),n+=1;continue}if(f==="|"){if(o!==""&&/[>]$/.test(o)){d("|"),n+=1;continue}if(l(),e[n+1]==="|"){t.push({t:"op",v:"||",line:s}),n+=2;continue}t.push({t:"op",v:"|",line:s}),n+=1;continue}if(f==="("||f===")"){if(f==="("&&o!==""&&/[<>]$/.test(o)){let g=p(n,"(",")");if(g===-1)return null;o+=e.slice(n,g+1),n=g+1;continue}l(),t.push({t:"op",v:f,line:s}),n+=1;continue}if(f==="<"&&e[n+1]==="<"&&e[n+2]!=="<"){l();let g=n+2,y=e[g]==="-";for(y&&(g+=1);e[g]===" "||e[g]===" ";)g+=1;let k="";for(;g<c&&!/[\s;&|<>()]/.test(e[g]);){if(e[g]==="'"||e[g]==='"'){let v=e[g],S=e.indexOf(v,g+1);if(S===-1)return null;k+=e.slice(g+1,S),g=S+1;continue}if(e[g]==="\\"){k+=e[g+1]??"",g+=2;continue}k+=e[g],g+=1}if(k==="")return null;r.push({delim:k,strip:y}),t.push({t:"word",v:`<<${k}`,line:s,heredoc:!0}),n=g;continue}d(f),n+=1}return l(),r.length>0?null:t}function dl(e,t,r){let n=0;for(let s=t;s<r;s+=1)e[s]===`
13
- `&&(n+=1);return n}function fl(e){let t=pm(e);if(!t)return"(unparsable)";let r=e.split(`
14
- `),n=m=>(r[m-1]??"").trim(),s=[],o=!0,i="start",a=!1,c=0,l=!1,d=!1,p=()=>s.every(m=>m.kind==="group"&&m.uncond),h=()=>["start",";","nl","&"].includes(i);for(let m=0;m<t.length;m+=1){let f=t[m],g=s[s.length-1];if(f.t==="op"){let v=f.v;if(v==="("){if(g?.kind==="case")continue;if(!o&&t[m+1]?.t==="op"&&t[m+1].v===")"){m+=1,a=!0,o=!0;continue}s.push({kind:"sub",close:")",uncond:h()}),o=!0,i="kw";continue}if(v===")"){if(g?.kind==="case"){l=!1,o=!0,i="kw";continue}if(!g||g.kind!=="sub")return"(unparsable)";s.pop(),o=!1;continue}if(v===";;"){if(g?.kind!=="case")return"(unparsable)";l=!0,o=!0,i=";";continue}if(o=!0,i=v===`
12
+ `,n),S=e.slice(n,v===-1?c:v),C=y?S.replace(/^\t+/,""):S;if(n=v===-1?c:v+1,s+=1,C===g){k=!0;break}}if(!k)return null}continue}if(h===" "||h===" "||h==="\r"){l(),n+=1;continue}if(h===";"){if(l(),e[n+1]===";"){t.push({t:"op",v:";;",line:s}),n+=e[n+2]==="&"?3:2;continue}if(e[n+1]==="&"){t.push({t:"op",v:";;",line:s}),n+=2;continue}t.push({t:"op",v:";",line:s}),n+=1;continue}if(h==="&"){if(o!==""&&/[<>]$/.test(o)){d("&"),n+=1;continue}if(e[n+1]===">"){d("&"),n+=1;continue}if(l(),e[n+1]==="&"){t.push({t:"op",v:"&&",line:s}),n+=2;continue}t.push({t:"op",v:"&",line:s}),n+=1;continue}if(h==="|"){if(o!==""&&/[>]$/.test(o)){d("|"),n+=1;continue}if(l(),e[n+1]==="|"){t.push({t:"op",v:"||",line:s}),n+=2;continue}t.push({t:"op",v:"|",line:s}),n+=1;continue}if(h==="("||h===")"){if(h==="("&&o!==""&&/[<>]$/.test(o)){let g=p(n,"(",")");if(g===-1)return null;o+=e.slice(n,g+1),n=g+1;continue}l(),t.push({t:"op",v:h,line:s}),n+=1;continue}if(h==="<"&&e[n+1]==="<"&&e[n+2]!=="<"){l();let g=n+2,y=e[g]==="-";for(y&&(g+=1);e[g]===" "||e[g]===" ";)g+=1;let k="";for(;g<c&&!/[\s;&|<>()]/.test(e[g]);){if(e[g]==="'"||e[g]==='"'){let v=e[g],S=e.indexOf(v,g+1);if(S===-1)return null;k+=e.slice(g+1,S),g=S+1;continue}if(e[g]==="\\"){k+=e[g+1]??"",g+=2;continue}k+=e[g],g+=1}if(k==="")return null;r.push({delim:k,strip:y}),t.push({t:"word",v:`<<${k}`,line:s,heredoc:!0}),n=g;continue}d(h),n+=1}return l(),r.length>0?null:t}function Bl(e,t,r){let n=0;for(let s=t;s<r;s+=1)e[s]===`
13
+ `&&(n+=1);return n}function Yl(e){let t=ig(e);if(!t)return"(unparsable)";let r=e.split(`
14
+ `),n=m=>(r[m-1]??"").trim(),s=[],o=!0,i="start",a=!1,c=0,l=!1,d=!1,p=()=>s.every(m=>m.kind==="group"&&m.uncond),f=()=>["start",";","nl","&"].includes(i);for(let m=0;m<t.length;m+=1){let h=t[m],g=s[s.length-1];if(h.t==="op"){let v=h.v;if(v==="("){if(g?.kind==="case")continue;if(!o&&t[m+1]?.t==="op"&&t[m+1].v===")"){m+=1,a=!0,o=!0;continue}s.push({kind:"sub",close:")",uncond:f()}),o=!0,i="kw";continue}if(v===")"){if(g?.kind==="case"){l=!1,o=!0,i="kw";continue}if(!g||g.kind!=="sub")return"(unparsable)";s.pop(),o=!1;continue}if(v===";;"){if(g?.kind!=="case")return"(unparsable)";l=!0,o=!0,i=";";continue}if(o=!0,i=v===`
15
15
  `?i==="&&"||i==="||"||i==="|"?i:"nl":v,g?.kind==="case"&&l&&v===`
16
- `)continue;continue}let y=f.quoted?null:f.v;if(d){y==="in"&&(d=!1,l=!0,o=!0,i="kw");continue}if(g?.kind==="case"&&l){if(y==="esac"){s.pop(),o=!1,l=!1;continue}continue}if(c===1){c=0,a=!0,o=!0;continue}if(!o){y==="{"&&a&&(s.push({kind:"func",close:"}",uncond:!1}),a=!1,o=!0,i="kw");continue}if(y==="{"){s.push({kind:a?"func":"group",close:"}",uncond:!a&&h()&&p()}),a=!1,o=!0,i="start";continue}if(a=!1,y==="}"){if(!g||g.kind!=="group"&&g.kind!=="func")return"(unparsable)";s.pop(),o=!1;continue}if(y!==null&&ul.has(y)){s.push({kind:y==="if"?"if":y==="case"?"case":"loop",close:ul.get(y)}),y==="case"?(d=!0,o=!1):(o=y==="if"||y==="while"||y==="until",i="kw");continue}if(y!==null&&um.has(y)){if(!g||g.close!==y)return"(unparsable)";s.pop(),o=!1;continue}if(y!==null&&dm.has(y)){i="kw";continue}if(y==="function"){c=1,o=!1;continue}if(y!==null&&/^[A-Za-z_][A-Za-z0-9_]*=/.test(y))continue;let k=f.v;if(!f.quoted&&p()&&h()){if(k==="exit")return n(f.line);if(k==="exec"){let v=!0,S=!1;for(let A=m+1;A<t.length;A+=1){let N=t[A];if(N.t==="op")break;if(S){S=!1;continue}if(!N.heredoc){if(!N.quoted&&cm.test(N.v)){lm.test(N.v)&&(S=!0);continue}v=!1;break}}if(!v)return n(f.line)}}o=!1}return s.length>0||d||a||c?"(unparsable)":null}var kt,Tr,am,cm,lm,ul,um,dm,wn=ee(()=>{kt="# <!-- vesper:hook:start -->",Tr="# <!-- vesper:hook:end -->",am=/^(sh|bash|dash|zsh|ksh|mksh|ash)(\d[\d.]*)?$/,cm=/^[0-9]*(>>|<>|<&|>&|>\||&>>|&>|<|>)/,lm=/^[0-9]*(>>|<>|<&|>&|>\||&>>|&>|<|>)$/;ul=new Map([["if","fi"],["case","esac"],["for","done"],["while","done"],["until","done"],["select","done"]]),um=new Set(["fi","esac","done"]),dm=new Set(["then","do","else","elif","!","time"])});import de from"picocolors";function fm(e){console.log(`${de.green("\u2713")} ${e}`)}function hm(e){console.log(`${de.red("\u2717")} ${e}`)}function Li(e){console.log(`${de.yellow("!")} ${e}`)}function mm(e){console.log(`${de.cyan("\u2192")} ${e}`)}function gm(e){console.log(de.dim(e))}function ym(e){return de.cyan(e)}function wm(e){return de.bold(e)}function vm(e){console.log(),console.log(de.bold(de.underline(e)))}function km(e,t=!1){let r=t?de.green("\u25CF"):de.dim("\u25CB");console.log(` ${r} ${e}`)}function Sm(){console.log(),console.log(de.bold(de.magenta("\u{1F3AF} Ready to use Vesper!"))),console.log(de.cyan(' In VS Code Chat, select "Vesper" from the agent dropdown')),console.log(de.cyan(" and start requesting!")),console.log()}function Em(e){let t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],r=0,n=null,s=e,o=()=>{let i=de.cyan(t[r]);process.stdout.write(`\r${i} ${s}`),r=(r+1)%t.length};return{start(){process.stdout.write(`
17
- `),n=setInterval(o,80),o()},update(i){s=i},stop(){n&&(clearInterval(n),n=null,process.stdout.write("\r"+" ".repeat(s.length+4)+"\r"))},succeed(i){this.stop(),console.log(`${de.green("\u2713")} ${i||s}`)},fail(i){this.stop(),console.log(`${de.red("\u2717")} ${i||s}`)}}}var u,Te=ee(()=>{u={success:fm,error:hm,warn:Li,info:mm,dim:gm,formatPath:ym,formatName:wm,header:vm,listItem:km,vesperTip:Sm,createSpinner:Em}});import{fileURLToPath as bm}from"node:url";import{dirname as Mi,join as vn,resolve as xm}from"node:path";import{readdir as _m}from"node:fs/promises";import{existsSync as Am,readFileSync as Cm}from"node:fs";function Tm(e){let t=e;for(;t!==Mi(t);){if(Am(vn(t,"package.json")))return t;t=Mi(t)}return xm(e,"..","..","..")}function Ps(){try{return JSON.parse(Cm(vn(kn,"package.json"),"utf-8")).version??null}catch{return null}}function Di(e){if(!e||typeof e!="string")throw new Error("Asset name is required");if(e.includes("..")||e.includes("/")||e.includes("\\"))throw new Error(`Invalid asset name: ${e}`)}async function Is(e){let t=ze[e];if(!t)throw new Error(`Unknown asset type: ${e}`);try{let r=await _m(vn(St,t.dir),{withFileTypes:!0});if(e==="skills")return r.filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>s.name).sort();let n=/\.(agent|prompt|instructions)\.md$|\.md$/;return r.filter(s=>s.isFile()&&s.name.endsWith(".md")).map(s=>s.name.replace(n,"")).sort()}catch{return[]}}var $m,Om,kn,O,St,ze,Ee=ee(()=>{$m=bm(import.meta.url),Om=Mi($m);kn=Tm(Om),O=vn(kn,"assets");St=vn(O,"copilot");ze={agents:{dir:"agents",extension:".agent.md",isFolder:!1},prompts:{dir:"prompts",extension:".prompt.md",isFolder:!1},instructions:{dir:"instructions",extension:".instructions.md",isFolder:!1},skills:{dir:"skills",extension:"",isFolder:!0}}});var Fi={};yn(Fi,{DEFAULT_GIT_TIMEOUT_MS:()=>Pm,default:()=>Im,runGit:()=>G,runGitCapture:()=>Et});async function G(e,{cwd:t,timeout:r=3e4,env:n,detached:s=!1}={}){if(s){let c=await Et(e,{cwd:t,timeout:r,env:n,detached:!0});return c.ok?c.stdout.trim():null}let{execFile:o}=await import("node:child_process"),{promisify:i}=await import("node:util"),a=i(o);try{let{stdout:c}=await a("git",e,{cwd:t,timeout:r,maxBuffer:16777216,...n?{env:n}:{}});return c.trim()}catch{return null}}async function Et(e,{cwd:t,timeout:r=3e4,env:n,detached:s=!1}={}){let{spawn:o}=await import("node:child_process"),i=s&&process.platform!=="win32";return new Promise(a=>{let c;try{c=o("git",e,{cwd:t,env:n??process.env,detached:i,stdio:["ignore","pipe","pipe"]})}catch(g){a({ok:!1,stdout:"",stderr:String(g?.message??g),timedOut:!1});return}let l="",d="",p=!1,h=!1;c.stdout.on("data",g=>{l+=g}),c.stderr.on("data",g=>{d+=g});let m=r?setTimeout(()=>{p=!0;try{i?process.kill(-c.pid,"SIGKILL"):c.kill("SIGKILL")}catch{}},r):null,f=g=>{if(!h){if(h=!0,m&&clearTimeout(m),i)try{process.kill(-c.pid,"SIGKILL")}catch{}a({ok:g,stdout:l,stderr:d,timedOut:p})}};c.on("error",g=>{d+=String(g?.message??g),f(!1)}),c.on("close",g=>f(g===0&&!p))})}var Pm,Im,ct=ee(()=>{Pm=3e4;Im=G});import{access as jm,constants as Rm,readFile as vl,readdir as Nm}from"node:fs/promises";import{execFile as Lm}from"node:child_process";import{join as Vi}from"node:path";import Mm from"strip-json-comments";async function kl(e){try{return await jm(e,Rm.F_OK),!0}catch{return!1}}function Sl(e,t){let r=e?.visible;if(r===null||r instanceof Set)return r;throw new TypeError(`${t}: \`visible\` is required \u2014 a Set of git-visible paths, or null for no repository`)}async function Gi(e,t){let r=Sl(t,"findCodeWorkspaceFile");try{let s=(await Nm(e,{withFileTypes:!0})).find(o=>o.isFile()&&o.name.endsWith(".code-workspace")&&(!r||r.has(o.name)));return s?Vi(e,s.name):null}catch{return null}}function Sn(e){let t=typeof e=="string"?Dm.exec(e):null;return t?t[1]:null}function Pe(e){return`.vesper/instructions/${e}.instructions.md`}function sr({path:e,parse:t,test:r,describe:n,vscodeSettings:s=!1}){if(typeof e!="string"||!e)throw new Error("keyFingerprintEntry: `path` must be a non-empty string");if(!Object.hasOwn(xl,t))throw new Error(`keyFingerprintEntry: \`parse\` for "${e}" must be 'json', 'jsonc' or 'text'`);if(typeof r!="function")throw new Error(`keyFingerprintEntry: \`test\` for "${e}" must be a function`);if(typeof n!="string"||!n)throw new Error(`keyFingerprintEntry: \`describe\` for "${e}" must be a non-empty string`);if(s&&t!=="jsonc")throw new Error(`keyFingerprintEntry: a \`vscodeSettings\` entry ("${e}") must parse as 'jsonc'`);let o={path:e,parse:t,test:r,describe:n,...s?{vscodeSettings:!0}:{}};return Object.defineProperty(o,Hi,{value:!0,enumerable:!1}),Object.freeze(o)}function Rr(e){return!!e&&typeof e=="object"&&e[Hi]===!0&&typeof e.test=="function"}function _l(e){if(typeof e!="string"&&!(e&&typeof e=="object"&&e[Hi]===!0))throw new TypeError(`fingerprint entry must be a bare path string or an object built by fingerprintEntry() \u2014 received ${e===null?"null":typeof e}. Never hand-roll join(root, entry) or String(entry) over a fingerprint set; route through fingerprintPath/fingerprintMatchesEntry.`)}function lt(e){return _l(e),typeof e=="string"?e:e.path}async function Vt(e,t,r){let n=Sl(r,"fingerprintMatchesEntry"),s=lt(t),o=Vi(e,s);if(typeof t=="string")return(!n||n.has(s))&&kl(o);let i=Rr(t)&&t.vscodeSettings?await Gi(e,{visible:n}):null;if(i)o=i;else if(n&&!n.has(s))return!1;let a;try{a=await vl(o,"utf-8")}catch{return!1}return Ui(t,a,{fromWorkspaceFile:!!i})}function Ui(e,t,{fromWorkspaceFile:r=!1}={}){if(Rr(e)){let n;try{n=xl[e.parse](t),r&&(n=n?.settings||{})}catch{return!1}try{return e.test(n)===!0}catch{return!1}}return e.anyOf.some(n=>t.includes(n))}function Wi(e,t){return new Promise(r=>{Lm("git",t,{cwd:e,maxBuffer:16777216,timeout:5e3,env:Gm(process.env)},(s,o)=>{r(s?null:String(o))}).stdin?.end()})}function Gm(e){let t={...e,...Fm};return!t.GIT_SSH_COMMAND&&!t.GIT_SSH&&(t.GIT_SSH_COMMAND=Vm),t}async function Hm(e,t){return Wi(e,["show",`HEAD:./${t}`])}async function Um(e){let t=await Wi(e,["ls-tree","-z","HEAD"]);if(!t)return null;for(let r of t.split("\0")){let n=r.indexOf(" ");if(n===-1)continue;let[,s]=r.slice(0,n).split(" "),o=r.slice(n+1);if(s==="blob"&&!o.includes("/")&&o.endsWith(".code-workspace"))return o}return null}async function Wm(e,t){let r=lt(t);if(typeof t=="string"){let a=await Wi(e,["cat-file","-e",`HEAD:./${r}`])!==null;return{matched:a,path:a?r:null}}let n=Rr(t)&&t.vscodeSettings?await Um(e):null,s=n||r,o=await Hm(e,s);if(o===null)return{matched:!1,path:null};let i=Ui(t,o,{fromWorkspaceFile:!!n});return{matched:i,path:i?s:null}}async function Ki(e,t,r){let n=Vi(e,r);if(typeof t=="string")return kl(n);lt(t);let s;try{s=await vl(n,"utf-8")}catch{return!1}let o=Rr(t)&&!!t.vscodeSettings&&r.endsWith(".code-workspace");return Ui(t,s,{fromWorkspaceFile:o})}async function Al(e,{fingerprints:t=Ut()}={}){let r={};for(let s of Object.keys(t)){let o=[];for(let i of t[s]||[]){let a=await Wm(e,i);a.matched&&o.push({entry:i,path:a.path})}o.length&&(r[s]=o)}let n=Object.keys(r);return n.length===0?{host:null,matched:[]}:n.length>1?{host:"both",matched:[]}:{host:n[0],matched:r[n[0]]}}function Bi(e){return _l(e),typeof e!="string"?!0:e.toLowerCase().includes("vesper")}function Km(e){if(!e||typeof e!="object")return!1;for(let r of["extraKnownMarketplaces","enabledPlugins"])if(e[r]&&typeof e[r]!="object")return!1;return!!e.enabledPlugins&&ut in e.enabledPlugins||e.agent===L}function Cl(e){return!e||typeof e!="object"||Array.isArray(e)?!1:e.default_agent===L}function Bm(e){return!e||typeof e!="object"?!1:bl.some(t=>{let r=e[t];return!!r&&Object.keys(r).includes(El)})}function zm(e){return Array.isArray(e?.tasks)&&e.tasks.some(t=>t?.label===Rs&&typeof t.command=="string"&&Jm.test(t.command))}function Ym(e){let t=new Set([En,bn,xn]),r=e?.hooks?.SessionStart;return Array.isArray(r)?r.some(n=>Array.isArray(n?.hooks)&&n.hooks.some(s=>typeof s?.command=="string"&&t.has(s.command.trim()))):!1}function qm(e){if(typeof e!="string")return!1;let t=/<!-- vesper:start -->([\s\S]*?)<!-- vesper:end -->/.exec(e);return!!t&&/^@\.claude\/vesper\/[a-z-]+\.md\s*$/m.test(t[1])}function zi(e){let t=Ns.exec(String(e).replace(/\\/g,"/"));if(!t)return!1;let r=t[1].replace(/\/+$/,"");return Xm.some(n=>n.endsWith("/")?r.startsWith(n):r===n||r.startsWith(`${n}/`))}function $l(e){return!e||typeof e!="object"?!1:bl.some(t=>{let r=e[t];return!!r&&typeof r=="object"&&Object.keys(r).some(zi)})}function Ut(){return{...Ol,...Tl}}function Qm(){return{...Pl,...Il}}async function _n(e,t){let r=[];for(let n of Qm()[t]||[])await Rl(e,n)&&r.push(lt(n));return r.sort()}async function Ls(e,t){return(await _n(e,t)).length>0}async function jl(e,{vscodeSettings:t}={}){let r={claude:!1,copilot:!1},n=[];for(let o of["claude","copilot"])for(let i of wl.primaryByHost[o])await Vt(e,i,{visible:null})&&(r[o]=!0,n.push(lt(i)));!r.copilot&&t&&$l(t)&&(r.copilot=!0,n.push("<workspace settings>"));let s=[];for(let o of wl.residue)await Vt(e,o,{visible:null})&&s.push(lt(o));return{primary:r.claude||r.copilot,residue:s,hosts:r,matched:[...new Set(n)].sort()}}async function ir(e,t,{fingerprints:r=Ut()}={}){for(let n of r[t]||[])if(await Rl(e,n))return!0;return!1}async function Rl(e,t){return Vt(e,t,{visible:null})}var L,ut,Dm,bt,Gt,js,Rs,or,Ft,Ir,jr,El,bl,Ht,En,bn,xn,Hi,xl,Fm,Vm,Jm,Ns,Xm,Ol,Tl,Pl,Il,ml,gl,yl,wl,ye=ee(()=>{L="vesper-orchestrator",ut="vesper@vesper-marketplace",Dm=/^vesper-([a-z0-9][a-z0-9-]*)@vesper-marketplace$/;bt=`.vesper/agents/${L}.agent.md`;Gt=".vscode/settings.json",js=".vscode/tasks.json",Rs="Vesper: worktree bootstrap",or=".claude/settings.json",Ft="opencode.json",Ir=`.opencode/agents/${L}.md`,jr=".opencode/plugins/vesper.js",El="${workspaceFolder}/.vesper/agents",bl=Object.freeze(["chat.agentFilesLocations","chat.instructionsFilesLocations","chat.promptFilesLocations","chat.agentSkillsLocations"]),Ht=Object.freeze(["reinit","compact-knowledge","revalidate-knowledge","revalidate-team"]),En=`node -e "['orchestrator','orchestration','context'].forEach(n=>{try{process.stdout.write(require('fs').readFileSync('.claude/vesper/'+n+'.md','utf8')+'\\n\\n')}catch(e){}})"`,bn=`node -e "const fs=require('fs');['orchestrator','orchestration','context'].forEach(n=>{try{process.stdout.write(fs.readFileSync('.claude/vesper/'+n+'.md','utf8')+'\\n\\n')}catch(e){}});try{fs.readdirSync('.claude/rules').filter(f=>f.endsWith('.md')).sort().forEach(f=>{try{process.stdout.write(fs.readFileSync('.claude/rules/'+f,'utf8')+'\\n\\n')}catch(e){}})}catch(e){}"`,xn="command -v vespercli >/dev/null 2>&1 && vespercli worktree bootstrap --quiet || true",Hi=Symbol.for("vesper.fingerprintEntry"),xl=Object.freeze({json:e=>JSON.parse(e),jsonc:e=>JSON.parse(Mm(e,{trailingCommas:!0})),text:e=>e});Fm=Object.freeze({GIT_NO_LAZY_FETCH:"1",GIT_OPTIONAL_LOCKS:"0",GIT_TERMINAL_PROMPT:"0",GCM_INTERACTIVE:"never",SSH_ASKPASS_REQUIRE:"never",LC_ALL:"C"}),Vm="ssh -o BatchMode=yes -o ConnectTimeout=10";Jm=/(^|[\s;&|(])vespercli\s+guard\s+--running-host(\s+|=)copilot(?![\w-])/;Ns=/node_modules\/(?:@[^/]+\/)?(?:vesper-cli|vespercli)\/(.+)$/,Xm=Object.freeze(["assets/core/","assets/skills","assets/agents/","assets/prompts/","assets/instructions/"]);Ol=Object.freeze({claude:Object.freeze([sr({path:or,parse:"json",test:Km,describe:`"enabledPlugins[${ut}]" or "agent": "${L}"`}),sr({path:Ft,parse:"json",test:Cl,describe:`"default_agent": "${L}" in ${Ft}`})])}),Tl=Object.freeze({copilot:Object.freeze([sr({path:js,parse:"jsonc",test:zm,describe:`task "${Rs}"`}),sr({path:Gt,parse:"jsonc",test:Bm,describe:`"${El}" in a chat.*FilesLocations setting (of the root *.code-workspace file when one exists)`,vscodeSettings:!0})])});Pl=Object.freeze({claude:Object.freeze([".claude/rules/vesper-orchestrator.md",`.claude/agents/${L}.md`,...Ht.map(e=>`.claude/skills/${e}/SKILL.md`),Ir,jr])}),Il=Object.freeze({copilot:Object.freeze([bt,Pe(L)])});ml=sr({path:or,parse:"json",test:Ym,describe:"an exact 1.x SessionStart command"}),gl=sr({path:"CLAUDE.md",parse:"text",test:qm,describe:"the 1.x guard block importing .claude/vesper/*.md"}),yl=sr({path:Gt,parse:"jsonc",test:$l,describe:"a 1.x package location (assets/core, assets/skills, assets/<type>/<name>)"}),wl=Object.freeze({primary:Object.freeze([ml,gl,yl]),primaryByHost:Object.freeze({claude:Object.freeze([ml,gl]),copilot:Object.freeze([yl])}),residue:Object.freeze([".claude/vesper/orchestrator.md"])})});var Xi={};yn(Xi,{AUTH_FAILURE_RE:()=>Yi,BATCH_SSH:()=>Ll,CONFIG_VARS_KEPT:()=>Nl,NON_INTERACTIVE:()=>An,NO_PROMPT_PROGRAM:()=>Ji,READ_ONLY_GIT_ENV:()=>xt,REPO_LOCATION_VARS:()=>Ds,authFailureLine:()=>qi,nonInteractiveGitEnv:()=>Cn,repoLocationVars:()=>Fs,stripRepoLocationEnv:()=>ar});import{execFileSync as Zm}from"node:child_process";function Fs(){if(Ms)return Ms;let e=[];try{let r={...process.env,LC_ALL:"C"};for(let n of Ds)delete r[n];e=Zm("git",["rev-parse","--local-env-vars"],{encoding:"utf-8",timeout:5e3,env:r,stdio:["ignore","pipe","ignore"]}).split(`
18
- `).map(n=>n.trim()).filter(n=>/^GIT_[A-Z0-9_]+$/.test(n))}catch{e=[]}let t=e.filter(r=>!Nl.includes(r)&&!eg.includes(r)&&!Ds.includes(r));return Ms=Object.freeze([...Ds,...t]),Ms}function ar(e=process.env){let t={...e};for(let r of Fs())delete t[r];return t}function Cn(e=process.env,{sshCommandConfigured:t=!1}={}){let r={...e,...An};!r.GIT_SSH_COMMAND&&!r.GIT_SSH&&!t&&(r.GIT_SSH_COMMAND=Ll),r.GIT_ASKPASS=Ji,r.SSH_ASKPASS=Ji;let n=Number.parseInt(r.GIT_CONFIG_COUNT??"0",10),s=Number.isFinite(n)&&n>=0?n:0;return r[`GIT_CONFIG_KEY_${s}`]="core.askPass",r[`GIT_CONFIG_VALUE_${s}`]="",r.GIT_CONFIG_COUNT=String(s+1),r}function qi(e){return`${e} skipped: authentication needs interaction, which background runs never do (most likely an SSH key passphrase or a credential prompt). Load the key into ssh-agent (\`ssh-add\`), or run \`vespercli init\` in a terminal to sync attended.`}var Ds,Nl,eg,Ms,An,Ll,Ji,xt,Yi,dt=ee(()=>{Ds=Object.freeze(["GIT_ALTERNATE_OBJECT_DIRECTORIES","GIT_OBJECT_DIRECTORY","GIT_DIR","GIT_WORK_TREE","GIT_IMPLICIT_WORK_TREE","GIT_GRAFT_FILE","GIT_INDEX_FILE","GIT_NO_REPLACE_OBJECTS","GIT_REPLACE_REF_BASE","GIT_PREFIX","GIT_SHALLOW_FILE","GIT_COMMON_DIR"]),Nl=Object.freeze(["GIT_CONFIG","GIT_CONFIG_PARAMETERS","GIT_CONFIG_COUNT"]),eg=Object.freeze(["GIT_INTERNAL_SUPER_PREFIX"]),Ms=null;An=Object.freeze({GIT_TERMINAL_PROMPT:"0",GCM_INTERACTIVE:"never",SSH_ASKPASS_REQUIRE:"never",LC_ALL:"C"}),Ll="ssh -o BatchMode=yes -o ConnectTimeout=10";Ji=process.platform==="win32"?"false":"/bin/false",xt=Object.freeze({GIT_NO_LAZY_FETCH:"1",GIT_OPTIONAL_LOCKS:"0",...An}),Yi=/Permission denied \(publickey|Host key verification failed|could not read (Username|Password)|terminal prompts disabled|Authentication failed|passphrase|sign_and_send_pubkey|BatchMode/i});var pa={};yn(pa,{ADDITIONAL_READ_ACCESS_PATHS_SETTING:()=>ne,AGENT_MAX_REQUESTS_SETTING:()=>Ws,CHAT_AGENT_ENABLED_SETTING:()=>zs,COPILOT_PACKS_DIR:()=>Hs,CORE_INSTRUCTIONS_DIR:()=>Pn,CUSTOM_AGENT_IN_SUBAGENT_SETTING:()=>Bs,EXTENDED_INSTRUCTIONS_DIR:()=>Gs,GIT_PLUMBING_TIMEOUT_MS:()=>ra,GUARD_TRIGGER_MARKERS:()=>Nn,INCLUDE_REFERENCED_INSTRUCTIONS_SETTING:()=>Ks,INIT_DEFAULTS:()=>Ie,LOCAL_STATE:()=>na,MCP_AUTO_START_SETTING:()=>qs,MCP_DISCOVERY_ENABLED_SETTING:()=>Ys,MCP_SERVERS:()=>we,MCP_TOOLS_AUTO_APPROVAL:()=>Wl,MCP_TOOLS_BY_AGENT:()=>Zs,MCP_TOOLS_CORE:()=>je,NEVER_WRITE_USER_PATHS:()=>oa,OMIT_BASE_AGENT_INSTRUCTIONS_SETTING:()=>Js,PERMITTED_USER_PATHS:()=>ia,SAFE_AUTO_APPROVAL_COMMANDS:()=>Tn,SIBLING_GIT_ARGS:()=>Ur,TERMINAL_AUTO_APPROVAL_SETTING:()=>_t,TERMINAL_ENABLE_AUTO_APPROVAL_SETTING:()=>Us,TOOLS_AUTO_APPROVE_SETTING:()=>Mr,TOOLS_ELIGIBLE_FOR_AUTO_APPROVAL_SETTING:()=>V,VESPER_BOOTSTRAP_TASK_LABEL:()=>Xs,VESPER_GIT_PATHS:()=>ig,VESPER_LOCAL_PATHS:()=>On,VESPER_MANAGED_GIT_HOOKS:()=>rt,VESPER_MANAGED_MCP_SERVERS:()=>fe,VESPER_MANAGED_SETTINGS:()=>Ct,VSCODE_SETTINGS_MAP:()=>Ge,WORKSPACE_TYPES:()=>pe,addAgentToolsToAutoApproval:()=>eu,addMcpServer:()=>Kr,addReadAccessPath:()=>ao,addToSettings:()=>Vr,allPackAssetEntries:()=>Yl,buildGuardCommand:()=>Dr,classifyForeignHook:()=>Pr,configureChatSettings:()=>io,configureMcpServer:()=>ur,configureMcpToolsAutoApproval:()=>go,configureTerminalAutoApproval:()=>oo,configureVesperMergeDriver:()=>Un,default:()=>yg,deriveHost:()=>In,ensureCopilotFolderOpenTask:()=>Mn,ensureCoreSettings:()=>uo,ensureFolderOpenTask:()=>Qs,ensureVesperGitattributes:()=>Hn,ensureVesperGitignore:()=>jn,findNestedVesperrc:()=>Dn,findTrackedLocalPaths:()=>Rn,findWorkspaceFile:()=>aa,getAutoApprovalCommands:()=>ql,getConfiguredMcpServers:()=>ru,getCoreAssetEntries:()=>no,getExtendedInstructionEntry:()=>ro,getInstalledTargets:()=>he,getMcpConfigPath:()=>Je,getPackAssetEntries:()=>Hr,getReadAccessPaths:()=>lo,getSettingsPath:()=>Kl,getTrackedPaths:()=>ht,getTrackingPath:()=>Fr,getTrackingPathAsync:()=>ft,getVesperIndexingPath:()=>Ue,getWorkspaceConfig:()=>z,getWorkspaceFolders:()=>ca,gitHookResultLines:()=>Vn,gitHooksEnsured:()=>ua,gitHooksSkipMessage:()=>Zl,installVesperGitHook:()=>Ql,installVesperGitHooks:()=>Gn,isHookTrackedByGit:()=>Lr,isInsideRepository:()=>Kt,isMcpServerConfigured:()=>mo,isUserLevelViolation:()=>lr,listCopilotPackNames:()=>so,listExtendedInstructions:()=>to,listMcpServers:()=>tu,listWorktrees:()=>fo,migrateVesperrcToWorkspaceLevel:()=>eo,parseJsonc:()=>$t,parseWorktreeList:()=>po,pruneLegacySettingsEntries:()=>Gr,readMcpConfig:()=>Ye,readTracking:()=>x,readVSCodeSettings:()=>J,realOrNearestAncestor:()=>At,removeFolderOpenTask:()=>Ln,removeFromSettings:()=>Fn,removeHookRegion:()=>nr,removeLegacyTracking:()=>zl,removeMcpServer:()=>yo,removePathsFromSettings:()=>la,removeReadAccessPath:()=>co,repositoryRoots:()=>Xl,resetVesperConfig:()=>Bl,resolveGitHooksDir:()=>Wr,resolveHookWriteTarget:()=>ho,sweepResetLocalState:()=>sa,writeHookAtomic:()=>cr,writeTracking:()=>I,writeVSCodeSettings:()=>oe});import{readFile as He,readdir as tg,rename as rg}from"node:fs/promises";import{existsSync as Nr,readdirSync as ng}from"node:fs";import{join as M,dirname as pt}from"node:path";import*as sg from"node:path";import{homedir as ta}from"node:os";import og from"strip-json-comments";function Wt(e){let t=ta();return e.startsWith(t)?"~"+e.slice(t.length).replace(/\\/g,"/"):e.replace(/\\/g,"/")}function Ul(e){return e==="vesper-cli"||e.startsWith("vesper-cli ")||e.endsWith("/vesper-cli")}async function sa(e){let{rm:t,readdir:r,lstat:n}=await import("node:fs/promises"),s=[],o=async i=>{let a=M(e,i.replace(/\/+$/,"")),c;try{c=await n(a)}catch{return}if(c.isSymbolicLink())return;await t(a,{force:!0,recursive:!0});let l=!1;try{await n(a)}catch{l=!0}l&&s.push(i)};for(let{path:i}of na.filter(a=>a.resetRemoves)){let a=i.endsWith("/")?null:pt(i);if(i.includes("*")){let c=i.split("/").pop(),l=new RegExp(`^${c.split("*").map(p=>p.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join("[^/]*")}$`),d=[];try{d=await r(M(e,a))}catch{d=[]}for(let p of d)l.test(p)&&await o(`${a}/${p}`)}else await o(i)}return s}function lr(e){if(typeof e!="string"||e.length===0)return!1;let t=ta(),r=e.startsWith("~")?M(t,e.slice(1)):e;r=r.replace(/\\/g,"/");let n=t.replace(/\\/g,"/");if(r!==n&&!r.startsWith(`${n}/`))return!1;let s=r.slice(n.length).replace(/^\/+/,""),o=i=>s===i||s.startsWith(`${i}/`);return ia.some(o)?!1:!!oa.some(o)}function In(e){return e&&(e.host==="claude"||e.host==="copilot")?e.host:e&&e.claude?"claude":e&&Array.isArray(e.paths)&&e.paths.length>0?"copilot":null}async function jn(e){let t=M(e,".gitignore"),r=[Ml,...On,Dl].join(`
19
- `),n=new RegExp(`${Ml}[\\s\\S]*?${Dl}`),s="";try{s=await He(t,"utf-8")}catch(i){if(i.code!=="ENOENT")throw i;return await C(t,`${r}
20
- `,"utf-8"),{created:!0,updated:!1}}if(n.test(s)){let i=s.replace(n,r);return i!==s?(await C(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=s.endsWith(`
16
+ `)continue;continue}let y=h.quoted?null:h.v;if(d){y==="in"&&(d=!1,l=!0,o=!0,i="kw");continue}if(g?.kind==="case"&&l){if(y==="esac"){s.pop(),o=!1,l=!1;continue}continue}if(c===1){c=0,a=!0,o=!0;continue}if(!o){y==="{"&&a&&(s.push({kind:"func",close:"}",uncond:!1}),a=!1,o=!0,i="kw");continue}if(y==="{"){s.push({kind:a?"func":"group",close:"}",uncond:!a&&f()&&p()}),a=!1,o=!0,i="start";continue}if(a=!1,y==="}"){if(!g||g.kind!=="group"&&g.kind!=="func")return"(unparsable)";s.pop(),o=!1;continue}if(y!==null&&Kl.has(y)){s.push({kind:y==="if"?"if":y==="case"?"case":"loop",close:Kl.get(y)}),y==="case"?(d=!0,o=!1):(o=y==="if"||y==="while"||y==="until",i="kw");continue}if(y!==null&&sg.has(y)){if(!g||g.close!==y)return"(unparsable)";s.pop(),o=!1;continue}if(y!==null&&og.has(y)){i="kw";continue}if(y==="function"){c=1,o=!1;continue}if(y!==null&&/^[A-Za-z_][A-Za-z0-9_]*=/.test(y))continue;let k=h.v;if(!h.quoted&&p()&&f()){if(k==="exit")return n(h.line);if(k==="exec"){let v=!0,S=!1;for(let C=m+1;C<t.length;C+=1){let N=t[C];if(N.t==="op")break;if(S){S=!1;continue}if(!N.heredoc){if(!N.quoted&&rg.test(N.v)){ng.test(N.v)&&(S=!0);continue}v=!1;break}}if(!v)return n(h.line)}}o=!1}return s.length>0||d||a||c?"(unparsable)":null}var ot,Yt,tg,rg,ng,Kl,sg,og,Wr=Z(()=>{ot="# <!-- vesper:hook:start -->",Yt="# <!-- vesper:hook:end -->",tg=/^(sh|bash|dash|zsh|ksh|mksh|ash)(\d[\d.]*)?$/,rg=/^[0-9]*(>>|<>|<&|>&|>\||&>>|&>|<|>)/,ng=/^[0-9]*(>>|<>|<&|>&|>\||&>>|&>|<|>)$/;Kl=new Map([["if","fi"],["case","esac"],["for","done"],["while","done"],["until","done"],["select","done"]]),sg=new Set(["fi","esac","done"]),og=new Set(["then","do","else","elif","!","time"])});import pe from"picocolors";function ag(e){console.log(`${pe.green("\u2713")} ${e}`)}function cg(e){console.log(`${pe.red("\u2717")} ${e}`)}function aa(e){console.log(`${pe.yellow("!")} ${e}`)}function lg(e){console.log(`${pe.cyan("\u2192")} ${e}`)}function ug(e){console.log(pe.dim(e))}function dg(e){return pe.cyan(e)}function pg(e){return pe.bold(e)}function fg(e){console.log(),console.log(pe.bold(pe.underline(e)))}function hg(e,t=!1){let r=t?pe.green("\u25CF"):pe.dim("\u25CB");console.log(` ${r} ${e}`)}function mg(){console.log(),console.log(pe.bold(pe.magenta("\u{1F3AF} Ready to use Vesper!"))),console.log(pe.cyan(' In VS Code Chat, select "Vesper" from the agent dropdown')),console.log(pe.cyan(" and start requesting!")),console.log()}function gg(e){let t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],r=0,n=null,s=e,o=()=>{let i=pe.cyan(t[r]);process.stdout.write(`\r${i} ${s}`),r=(r+1)%t.length};return{start(){process.stdout.write(`
17
+ `),n=setInterval(o,80),o()},update(i){s=i},stop(){n&&(clearInterval(n),n=null,process.stdout.write("\r"+" ".repeat(s.length+4)+"\r"))},succeed(i){this.stop(),console.log(`${pe.green("\u2713")} ${i||s}`)},fail(i){this.stop(),console.log(`${pe.red("\u2717")} ${i||s}`)}}}var u,Pe=Z(()=>{u={success:ag,error:cg,warn:aa,info:lg,dim:ug,formatPath:dg,formatName:pg,header:fg,listItem:hg,vesperTip:mg,createSpinner:gg}});import{fileURLToPath as yg}from"node:url";import{dirname as ca,join as Rn,resolve as wg}from"node:path";import{readdir as vg}from"node:fs/promises";import{existsSync as kg,readFileSync as Sg}from"node:fs";function xg(e){let t=e;for(;t!==ca(t);){if(kg(Rn(t,"package.json")))return t;t=ca(t)}return wg(e,"..","..","..")}function Qs(){try{return JSON.parse(Sg(Rn(Nn,"package.json"),"utf-8")).version??null}catch{return null}}function la(e){if(!e||typeof e!="string")throw new Error("Asset name is required");if(e.includes("..")||e.includes("/")||e.includes("\\"))throw new Error(`Invalid asset name: ${e}`)}async function Zs(e){let t=Xe[e];if(!t)throw new Error(`Unknown asset type: ${e}`);try{let r=await vg(Rn(Ot,t.dir),{withFileTypes:!0});if(e==="skills")return r.filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>s.name).sort();let n=/\.(agent|prompt|instructions)\.md$|\.md$/;return r.filter(s=>s.isFile()&&s.name.endsWith(".md")).map(s=>s.name.replace(n,"")).sort()}catch{return[]}}var Eg,bg,Nn,O,Ot,Xe,Ee=Z(()=>{Eg=yg(import.meta.url),bg=ca(Eg);Nn=xg(bg),O=Rn(Nn,"assets");Ot=Rn(O,"copilot");Xe={agents:{dir:"agents",extension:".agent.md",isFolder:!1},prompts:{dir:"prompts",extension:".prompt.md",isFolder:!1},instructions:{dir:"instructions",extension:".instructions.md",isFolder:!1},skills:{dir:"skills",extension:"",isFolder:!0}}});var ua={};jn(ua,{DEFAULT_GIT_TIMEOUT_MS:()=>Ag,default:()=>_g,runGit:()=>D,runGitCapture:()=>Tt});async function D(e,{cwd:t,timeout:r=3e4,env:n,detached:s=!1}={}){if(s){let c=await Tt(e,{cwd:t,timeout:r,env:n,detached:!0});return c.ok?c.stdout.trim():null}let{execFile:o}=await import("node:child_process"),{promisify:i}=await import("node:util"),a=i(o);try{let{stdout:c}=await a("git",e,{cwd:t,timeout:r,maxBuffer:16777216,...n?{env:n}:{}});return c.trim()}catch{return null}}async function Tt(e,{cwd:t,timeout:r=3e4,env:n,detached:s=!1}={}){let{spawn:o}=await import("node:child_process"),i=s&&process.platform!=="win32";return new Promise(a=>{let c;try{c=o("git",e,{cwd:t,env:n??process.env,detached:i,stdio:["ignore","pipe","pipe"]})}catch(g){a({ok:!1,stdout:"",stderr:String(g?.message??g),timedOut:!1});return}let l="",d="",p=!1,f=!1;c.stdout.on("data",g=>{l+=g}),c.stderr.on("data",g=>{d+=g});let m=r?setTimeout(()=>{p=!0;try{i?process.kill(-c.pid,"SIGKILL"):c.kill("SIGKILL")}catch{}},r):null,h=g=>{if(!f){if(f=!0,m&&clearTimeout(m),i)try{process.kill(-c.pid,"SIGKILL")}catch{}a({ok:g,stdout:l,stderr:d,timedOut:p})}};c.on("error",g=>{d+=String(g?.message??g),h(!1)}),c.on("close",g=>h(g===0&&!p))})}var Ag,_g,it=Z(()=>{Ag=3e4;_g=D});import{access as Cg,constants as $g,readFile as eu,readdir as Og}from"node:fs/promises";import{execFile as Tg}from"node:child_process";import{join as da}from"node:path";import Pg from"strip-json-comments";async function tu(e){try{return await Cg(e,$g.F_OK),!0}catch{return!1}}function ru(e,t){let r=e?.visible;if(r===null||r instanceof Set)return r;throw new TypeError(`${t}: \`visible\` is required \u2014 a Set of git-visible paths, or null for no repository`)}async function pa(e,t){let r=ru(t,"findCodeWorkspaceFile");try{let s=(await Og(e,{withFileTypes:!0})).find(o=>o.isFile()&&o.name.endsWith(".code-workspace")&&(!r||r.has(o.name)));return s?da(e,s.name):null}catch{return null}}function Sr(e){let t=typeof e=="string"?Ig.exec(e):null;return t?t[1]:null}function Ie(e){return`.vesper/instructions/${e}.instructions.md`}function kr({path:e,parse:t,test:r,describe:n,vscodeSettings:s=!1}){if(typeof e!="string"||!e)throw new Error("keyFingerprintEntry: `path` must be a non-empty string");if(!Object.hasOwn(ou,t))throw new Error(`keyFingerprintEntry: \`parse\` for "${e}" must be 'json', 'jsonc' or 'text'`);if(typeof r!="function")throw new Error(`keyFingerprintEntry: \`test\` for "${e}" must be a function`);if(typeof n!="string"||!n)throw new Error(`keyFingerprintEntry: \`describe\` for "${e}" must be a non-empty string`);if(s&&t!=="jsonc")throw new Error(`keyFingerprintEntry: a \`vscodeSettings\` entry ("${e}") must parse as 'jsonc'`);let o={path:e,parse:t,test:r,describe:n,...s?{vscodeSettings:!0}:{}};return Object.defineProperty(o,fa,{value:!0,enumerable:!1}),Object.freeze(o)}function zr(e){return!!e&&typeof e=="object"&&e[fa]===!0&&typeof e.test=="function"}function iu(e){if(typeof e!="string"&&!(e&&typeof e=="object"&&e[fa]===!0))throw new TypeError(`fingerprint entry must be a bare path string or an object built by fingerprintEntry() \u2014 received ${e===null?"null":typeof e}. Never hand-roll join(root, entry) or String(entry) over a fingerprint set; route through fingerprintPath/fingerprintMatchesEntry.`)}function gt(e){return iu(e),typeof e=="string"?e:e.path}async function qt(e,t,r){let n=ru(r,"fingerprintMatchesEntry"),s=gt(t),o=da(e,s);if(typeof t=="string")return(!n||n.has(s))&&tu(o);let i=zr(t)&&t.vscodeSettings?await pa(e,{visible:n}):null;if(i)o=i;else if(n&&!n.has(s))return!1;let a;try{a=await eu(o,"utf-8")}catch{return!1}return ha(t,a,{fromWorkspaceFile:!!i})}function ha(e,t,{fromWorkspaceFile:r=!1}={}){if(zr(e)){let n;try{n=ou[e.parse](t),r&&(n=n?.settings||{})}catch{return!1}try{return e.test(n)===!0}catch{return!1}}return e.anyOf.some(n=>t.includes(n))}function ma(e,t){return new Promise(r=>{Tg("git",t,{cwd:e,maxBuffer:16777216,timeout:5e3,env:Ng(process.env)},(s,o)=>{r(s?null:String(o))}).stdin?.end()})}function Ng(e){let t={...e,...jg};return!t.GIT_SSH_COMMAND&&!t.GIT_SSH&&(t.GIT_SSH_COMMAND=Rg),t}async function Lg(e,t){return ma(e,["show",`HEAD:./${t}`])}async function Mg(e){let t=await ma(e,["ls-tree","-z","HEAD"]);if(!t)return null;for(let r of t.split("\0")){let n=r.indexOf(" ");if(n===-1)continue;let[,s]=r.slice(0,n).split(" "),o=r.slice(n+1);if(s==="blob"&&!o.includes("/")&&o.endsWith(".code-workspace"))return o}return null}async function Gg(e,t){let r=gt(t);if(typeof t=="string"){let a=await ma(e,["cat-file","-e",`HEAD:./${r}`])!==null;return{matched:a,path:a?r:null}}let n=zr(t)&&t.vscodeSettings?await Mg(e):null,s=n||r,o=await Lg(e,s);if(o===null)return{matched:!1,path:null};let i=ha(t,o,{fromWorkspaceFile:!!n});return{matched:i,path:i?s:null}}async function ga(e,t,r){let n=da(e,r);if(typeof t=="string")return tu(n);gt(t);let s;try{s=await eu(n,"utf-8")}catch{return!1}let o=zr(t)&&!!t.vscodeSettings&&r.endsWith(".code-workspace");return ha(t,s,{fromWorkspaceFile:o})}async function au(e,{fingerprints:t=Zt()}={}){let r={};for(let s of Object.keys(t)){let o=[];for(let i of t[s]||[]){let a=await Gg(e,i);a.matched&&o.push({entry:i,path:a.path})}o.length&&(r[s]=o)}let n=Object.keys(r);return n.length===0?{host:null,matched:[]}:n.length>1?{host:"both",matched:[]}:{host:n[0],matched:r[n[0]]}}function ya(e){return iu(e),typeof e!="string"?!0:e.toLowerCase().includes("vesper")}function Fg(e){if(!e||typeof e!="object")return!1;for(let r of["extraKnownMarketplaces","enabledPlugins"])if(e[r]&&typeof e[r]!="object")return!1;return!!e.enabledPlugins&&yt in e.enabledPlugins||e.agent===L}function cu(e){return!e||typeof e!="object"||Array.isArray(e)?!1:e.default_agent===L}function Dg(e){return!e||typeof e!="object"?!1:su.some(t=>{let r=e[t];return!!r&&Object.keys(r).includes(nu)})}function Vg(e){return Array.isArray(e?.tasks)&&e.tasks.some(t=>t?.label===to&&typeof t.command=="string"&&Hg.test(t.command))}function Ug(e){let t=new Set([Ln,Mn,Gn]),r=e?.hooks?.SessionStart;return Array.isArray(r)?r.some(n=>Array.isArray(n?.hooks)&&n.hooks.some(s=>typeof s?.command=="string"&&t.has(s.command.trim()))):!1}function Wg(e){if(typeof e!="string")return!1;let t=/<!-- vesper:start -->([\s\S]*?)<!-- vesper:end -->/.exec(e);return!!t&&/^@\.claude\/vesper\/[a-z-]+\.md\s*$/m.test(t[1])}function wa(e){let t=ro.exec(String(e).replace(/\\/g,"/"));if(!t)return!1;let r=t[1].replace(/\/+$/,"");return Kg.some(n=>n.endsWith("/")?r.startsWith(n):r===n||r.startsWith(`${n}/`))}function lu(e){return!e||typeof e!="object"?!1:su.some(t=>{let r=e[t];return!!r&&typeof r=="object"&&Object.keys(r).some(wa)})}function Zt(){return{...uu,...du}}function Bg(){return{...pu,...fu}}async function Fn(e,t){let r=[];for(let n of Bg()[t]||[])await mu(e,n)&&r.push(gt(n));return r.sort()}async function no(e,t){return(await Fn(e,t)).length>0}async function hu(e,{vscodeSettings:t}={}){let r={claude:!1,copilot:!1},n=[];for(let o of["claude","copilot"])for(let i of Zl.primaryByHost[o])await qt(e,i,{visible:null})&&(r[o]=!0,n.push(gt(i)));!r.copilot&&t&&lu(t)&&(r.copilot=!0,n.push("<workspace settings>"));let s=[];for(let o of Zl.residue)await qt(e,o,{visible:null})&&s.push(gt(o));return{primary:r.claude||r.copilot,residue:s,hosts:r,matched:[...new Set(n)].sort()}}async function Er(e,t,{fingerprints:r=Zt()}={}){for(let n of r[t]||[])if(await mu(e,n))return!0;return!1}async function mu(e,t){return qt(e,t,{visible:null})}var L,yt,Ig,Pt,Xt,eo,to,It,Jt,Kr,Br,nu,su,Qt,Ln,Mn,Gn,fa,ou,jg,Rg,Hg,ro,Kg,uu,du,pu,fu,ql,Xl,Ql,Zl,fe=Z(()=>{L="vesper-orchestrator",yt="vesper@vesper-marketplace",Ig=/^vesper-([a-z0-9][a-z0-9-]*)@vesper-marketplace$/;Pt=`.vesper/agents/${L}.agent.md`;Xt=".vscode/settings.json",eo=".vscode/tasks.json",to="Vesper: worktree bootstrap",It=".claude/settings.json",Jt="opencode.json",Kr=`.opencode/agents/${L}.md`,Br=".opencode/plugins/vesper.js",nu="${workspaceFolder}/.vesper/agents",su=Object.freeze(["chat.agentFilesLocations","chat.instructionsFilesLocations","chat.promptFilesLocations","chat.agentSkillsLocations"]),Qt=Object.freeze(["reinit","compact-knowledge","revalidate-knowledge","revalidate-team"]),Ln=`node -e "['orchestrator','orchestration','context'].forEach(n=>{try{process.stdout.write(require('fs').readFileSync('.claude/vesper/'+n+'.md','utf8')+'\\n\\n')}catch(e){}})"`,Mn=`node -e "const fs=require('fs');['orchestrator','orchestration','context'].forEach(n=>{try{process.stdout.write(fs.readFileSync('.claude/vesper/'+n+'.md','utf8')+'\\n\\n')}catch(e){}});try{fs.readdirSync('.claude/rules').filter(f=>f.endsWith('.md')).sort().forEach(f=>{try{process.stdout.write(fs.readFileSync('.claude/rules/'+f,'utf8')+'\\n\\n')}catch(e){}})}catch(e){}"`,Gn="command -v vespercli >/dev/null 2>&1 && vespercli worktree bootstrap --quiet || true",fa=Symbol.for("vesper.fingerprintEntry"),ou=Object.freeze({json:e=>JSON.parse(e),jsonc:e=>JSON.parse(Pg(e,{trailingCommas:!0})),text:e=>e});jg=Object.freeze({GIT_NO_LAZY_FETCH:"1",GIT_OPTIONAL_LOCKS:"0",GIT_TERMINAL_PROMPT:"0",GCM_INTERACTIVE:"never",SSH_ASKPASS_REQUIRE:"never",LC_ALL:"C"}),Rg="ssh -o BatchMode=yes -o ConnectTimeout=10";Hg=/(^|[\s;&|(])vespercli\s+guard\s+--running-host(\s+|=)copilot(?![\w-])/;ro=/node_modules\/(?:@[^/]+\/)?(?:vesper-cli|vespercli)\/(.+)$/,Kg=Object.freeze(["assets/core/","assets/skills","assets/agents/","assets/prompts/","assets/instructions/"]);uu=Object.freeze({claude:Object.freeze([kr({path:It,parse:"json",test:Fg,describe:`"enabledPlugins[${yt}]" or "agent": "${L}"`}),kr({path:Jt,parse:"json",test:cu,describe:`"default_agent": "${L}" in ${Jt}`})])}),du=Object.freeze({copilot:Object.freeze([kr({path:eo,parse:"jsonc",test:Vg,describe:`task "${to}"`}),kr({path:Xt,parse:"jsonc",test:Dg,describe:`"${nu}" in a chat.*FilesLocations setting (of the root *.code-workspace file when one exists)`,vscodeSettings:!0})])});pu=Object.freeze({claude:Object.freeze([".claude/rules/vesper-orchestrator.md",`.claude/agents/${L}.md`,...Qt.map(e=>`.claude/skills/${e}/SKILL.md`),Kr,Br])}),fu=Object.freeze({copilot:Object.freeze([Pt,Ie(L)])});ql=kr({path:It,parse:"json",test:Ug,describe:"an exact 1.x SessionStart command"}),Xl=kr({path:"CLAUDE.md",parse:"text",test:Wg,describe:"the 1.x guard block importing .claude/vesper/*.md"}),Ql=kr({path:Xt,parse:"jsonc",test:lu,describe:"a 1.x package location (assets/core, assets/skills, assets/<type>/<name>)"}),Zl=Object.freeze({primary:Object.freeze([ql,Xl,Ql]),primaryByHost:Object.freeze({claude:Object.freeze([ql,Xl]),copilot:Object.freeze([Ql])}),residue:Object.freeze([".claude/vesper/orchestrator.md"])})});var Ea={};jn(Ea,{AUTH_FAILURE_RE:()=>ka,BATCH_SSH:()=>yu,CONFIG_VARS_KEPT:()=>gu,NON_INTERACTIVE:()=>Dn,NO_PROMPT_PROGRAM:()=>va,READ_ONLY_GIT_ENV:()=>jt,REPO_LOCATION_VARS:()=>oo,authFailureLine:()=>Sa,nonInteractiveGitEnv:()=>Vn,repoLocationVars:()=>io,stripRepoLocationEnv:()=>br});import{execFileSync as zg}from"node:child_process";function io(){if(so)return so;let e=[];try{let r={...process.env,LC_ALL:"C"};for(let n of oo)delete r[n];e=zg("git",["rev-parse","--local-env-vars"],{encoding:"utf-8",timeout:5e3,env:r,stdio:["ignore","pipe","ignore"]}).split(`
18
+ `).map(n=>n.trim()).filter(n=>/^GIT_[A-Z0-9_]+$/.test(n))}catch{e=[]}let t=e.filter(r=>!gu.includes(r)&&!Yg.includes(r)&&!oo.includes(r));return so=Object.freeze([...oo,...t]),so}function br(e=process.env){let t={...e};for(let r of io())delete t[r];return t}function Vn(e=process.env,{sshCommandConfigured:t=!1}={}){let r={...e,...Dn};!r.GIT_SSH_COMMAND&&!r.GIT_SSH&&!t&&(r.GIT_SSH_COMMAND=yu),r.GIT_ASKPASS=va,r.SSH_ASKPASS=va;let n=Number.parseInt(r.GIT_CONFIG_COUNT??"0",10),s=Number.isFinite(n)&&n>=0?n:0;return r[`GIT_CONFIG_KEY_${s}`]="core.askPass",r[`GIT_CONFIG_VALUE_${s}`]="",r.GIT_CONFIG_COUNT=String(s+1),r}function Sa(e){return`${e} skipped: authentication needs interaction, which background runs never do (most likely an SSH key passphrase or a credential prompt). Load the key into ssh-agent (\`ssh-add\`), or run \`vespercli init\` in a terminal to sync attended.`}var oo,gu,Yg,so,Dn,yu,va,jt,ka,wt=Z(()=>{oo=Object.freeze(["GIT_ALTERNATE_OBJECT_DIRECTORIES","GIT_OBJECT_DIRECTORY","GIT_DIR","GIT_WORK_TREE","GIT_IMPLICIT_WORK_TREE","GIT_GRAFT_FILE","GIT_INDEX_FILE","GIT_NO_REPLACE_OBJECTS","GIT_REPLACE_REF_BASE","GIT_PREFIX","GIT_SHALLOW_FILE","GIT_COMMON_DIR"]),gu=Object.freeze(["GIT_CONFIG","GIT_CONFIG_PARAMETERS","GIT_CONFIG_COUNT"]),Yg=Object.freeze(["GIT_INTERNAL_SUPER_PREFIX"]),so=null;Dn=Object.freeze({GIT_TERMINAL_PROMPT:"0",GCM_INTERACTIVE:"never",SSH_ASKPASS_REQUIRE:"never",LC_ALL:"C"}),yu="ssh -o BatchMode=yes -o ConnectTimeout=10";va=process.platform==="win32"?"false":"/bin/false",jt=Object.freeze({GIT_NO_LAZY_FETCH:"1",GIT_OPTIONAL_LOCKS:"0",...Dn}),ka=/Permission denied \(publickey|Host key verification failed|could not read (Username|Password)|terminal prompts disabled|Authentication failed|passphrase|sign_and_send_pubkey|BatchMode/i});var Ma={};jn(Ma,{ADDITIONAL_READ_ACCESS_PATHS_SETTING:()=>oe,AGENT_MAX_REQUESTS_SETTING:()=>po,CHAT_AGENT_ENABLED_SETTING:()=>mo,COPILOT_PACKS_DIR:()=>lo,CORE_INSTRUCTIONS_DIR:()=>Kn,CUSTOM_AGENT_IN_SUBAGENT_SETTING:()=>ho,EXTENDED_INSTRUCTIONS_DIR:()=>co,GIT_PLUMBING_TIMEOUT_MS:()=>Ca,GUARD_TRIGGER_MARKERS:()=>Jn,INCLUDE_REFERENCED_INSTRUCTIONS_SETTING:()=>fo,INIT_DEFAULTS:()=>je,LOCAL_STATE:()=>$a,MCP_AUTO_START_SETTING:()=>wo,MCP_DISCOVERY_ENABLED_SETTING:()=>yo,MCP_SERVERS:()=>we,MCP_TOOLS_AUTO_APPROVAL:()=>Au,MCP_TOOLS_BY_AGENT:()=>So,MCP_TOOLS_CORE:()=>Re,NEVER_WRITE_USER_PATHS:()=>Ta,OMIT_BASE_AGENT_INSTRUCTIONS_SETTING:()=>go,PERMITTED_USER_PATHS:()=>Pa,SAFE_AUTO_APPROVAL_COMMANDS:()=>Wn,SIBLING_GIT_ARGS:()=>en,TERMINAL_AUTO_APPROVAL_SETTING:()=>Rt,TERMINAL_ENABLE_AUTO_APPROVAL_SETTING:()=>uo,TOOLS_AUTO_APPROVE_SETTING:()=>Jr,TOOLS_ELIGIBLE_FOR_AUTO_APPROVAL_SETTING:()=>V,VESPER_BOOTSTRAP_TASK_LABEL:()=>vo,VESPER_GIT_PATHS:()=>ey,VESPER_LOCAL_PATHS:()=>Un,VESPER_MANAGED_GIT_HOOKS:()=>ct,VESPER_MANAGED_MCP_SERVERS:()=>me,VESPER_MANAGED_SETTINGS:()=>Nt,VSCODE_SETTINGS_MAP:()=>We,WORKSPACE_TYPES:()=>he,addAgentToolsToAutoApproval:()=>Nu,addMcpServer:()=>sr,addReadAccessPath:()=>Oo,addToSettings:()=>Qr,allPackAssetEntries:()=>Tu,buildGuardCommand:()=>qr,classifyForeignHook:()=>Ur,configureChatSettings:()=>$o,configureMcpServer:()=>Ar,configureMcpToolsAutoApproval:()=>Lo,configureTerminalAutoApproval:()=>Co,configureVesperMergeDriver:()=>ns,default:()=>dy,deriveHost:()=>Bn,ensureCopilotFolderOpenTask:()=>Xn,ensureCoreSettings:()=>Io,ensureFolderOpenTask:()=>ko,ensureVesperGitattributes:()=>rs,ensureVesperGitignore:()=>zn,findNestedVesperrc:()=>Qn,findTrackedLocalPaths:()=>Yn,findWorkspaceFile:()=>Ia,getAutoApprovalCommands:()=>Pu,getConfiguredMcpServers:()=>Mo,getCoreAssetEntries:()=>Ao,getExtendedInstructionEntry:()=>xo,getInstalledTargets:()=>ge,getMcpConfigPath:()=>Qe,getPackAssetEntries:()=>rr,getReadAccessPaths:()=>Po,getSettingsPath:()=>_u,getTrackedPaths:()=>bt,getTrackingPath:()=>Xr,getTrackingPathAsync:()=>Et,getVesperIndexingPath:()=>Be,getWorkspaceConfig:()=>q,getWorkspaceFolders:()=>ja,gitHookResultLines:()=>es,gitHooksEnsured:()=>Na,gitHooksSkipMessage:()=>Ru,installVesperGitHook:()=>ju,installVesperGitHooks:()=>ts,isHookTrackedByGit:()=>tr,isInsideRepository:()=>kt,isMcpServerConfigured:()=>No,isUserLevelViolation:()=>xr,listCopilotPackNames:()=>_o,listExtendedInstructions:()=>bo,listMcpServers:()=>Lu,listWorktrees:()=>Ro,migrateVesperrcToWorkspaceLevel:()=>Eo,parseJsonc:()=>Lt,parseWorktreeList:()=>jo,pruneLegacySettingsEntries:()=>Zr,readMcpConfig:()=>Ze,readTracking:()=>x,readVSCodeSettings:()=>K,realOrNearestAncestor:()=>at,removeFolderOpenTask:()=>qn,removeFromSettings:()=>Zn,removeHookRegion:()=>vr,removeLegacyTracking:()=>$u,removeMcpServer:()=>rn,removePathsFromSettings:()=>Ra,removeReadAccessPath:()=>To,repositoryRoots:()=>Iu,resetVesperConfig:()=>Cu,resolveGitHooksDir:()=>nr,resolveHookWriteTarget:()=>tn,sweepResetLocalState:()=>Oa,writeHookAtomic:()=>vt,writeTracking:()=>T,writeVSCodeSettings:()=>ce});import{readFile as Ke,readdir as Jg,rename as qg}from"node:fs/promises";import{existsSync as Yr,readdirSync as Xg}from"node:fs";import{join as M,dirname as St}from"node:path";import*as Qg from"node:path";import{homedir as _a}from"node:os";import Zg from"strip-json-comments";function er(e){let t=_a();return e.startsWith(t)?"~"+e.slice(t.length).replace(/\\/g,"/"):e.replace(/\\/g,"/")}function xu(e){return e==="vesper-cli"||e.startsWith("vesper-cli ")||e.endsWith("/vesper-cli")}async function Oa(e){let{rm:t,readdir:r,lstat:n}=await import("node:fs/promises"),s=[],o=async i=>{let a=M(e,i.replace(/\/+$/,"")),c;try{c=await n(a)}catch{return}if(c.isSymbolicLink())return;await t(a,{force:!0,recursive:!0});let l=!1;try{await n(a)}catch{l=!0}l&&s.push(i)};for(let{path:i}of $a.filter(a=>a.resetRemoves)){let a=i.endsWith("/")?null:St(i);if(i.includes("*")){let c=i.split("/").pop(),l=new RegExp(`^${c.split("*").map(p=>p.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join("[^/]*")}$`),d=[];try{d=await r(M(e,a))}catch{d=[]}for(let p of d)l.test(p)&&await o(`${a}/${p}`)}else await o(i)}return s}function xr(e){if(typeof e!="string"||e.length===0)return!1;let t=_a(),r=e.startsWith("~")?M(t,e.slice(1)):e;r=r.replace(/\\/g,"/");let n=t.replace(/\\/g,"/");if(r!==n&&!r.startsWith(`${n}/`))return!1;let s=r.slice(n.length).replace(/^\/+/,""),o=i=>s===i||s.startsWith(`${i}/`);return Pa.some(o)?!1:!!Ta.some(o)}function Bn(e){return e&&(e.host==="claude"||e.host==="copilot")?e.host:e&&e.claude?"claude":e&&Array.isArray(e.paths)&&e.paths.length>0?"copilot":null}async function zn(e){let t=M(e,".gitignore"),r=[wu,...Un,vu].join(`
19
+ `),n=new RegExp(`${wu}[\\s\\S]*?${vu}`),s="";try{s=await Ke(t,"utf-8")}catch(i){if(i.code!=="ENOENT")throw i;return await A(t,`${r}
20
+ `,"utf-8"),{created:!0,updated:!1}}if(n.test(s)){let i=s.replace(n,r);return i!==s?(await A(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=s.endsWith(`
21
21
  `)?`
22
22
  `:`
23
23
 
24
- `;return await C(t,`${s}${o}${r}
25
- `,"utf-8"),{created:!1,updated:!0}}function ag(e,t){let r=e.endsWith("/"),n=r?e.slice(0,-1):e;return new RegExp(`^${n.split("*").map(o=>o.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join("[^/]*")}${r?"/":"$"}`).test(t)}async function Rn(e){let{execFile:t}=await import("node:child_process"),{promisify:r}=await import("node:util"),n=r(t),s=async l=>{try{let{stdout:d}=await n("git",l,{cwd:e,timeout:ra,maxBuffer:16777216});return d}catch{return null}},o=await s(["rev-parse","--is-inside-work-tree"]);if(o===null||o.trim()!=="true")return[];let i=On.map(l=>l.endsWith("/")?`${l}*`:l),a=await s(["ls-files","-z","--",...i]);if(!a)return[];let c=l=>{let d=On.findIndex(p=>ag(p,l));return d===-1?On.length:d};return[...new Set(a.split("\0").filter(Boolean))].sort((l,d)=>c(l)-c(d)||(l<d?-1:l>d?1:0))}function Dr(e){return`vespercli guard --running-host ${e}`}async function Qs(e,t,{createOnly:r=!1}={}){let n=M(e,".vscode","tasks.json"),s={label:t.label,type:"shell",command:t.command,presentation:t.presentation||{reveal:"silent",panel:"shared"},problemMatcher:[],runOptions:{runOn:"folderOpen"}},o={version:"2.0.0",tasks:[]},i=!1;try{let c=await He(n,"utf-8");o=$t(c),Array.isArray(o.tasks)||(o.tasks=[]),i=!0}catch(c){if(c.code!=="ENOENT")throw c}let a=o.tasks.findIndex(c=>c?.label===t.label);if(a===-1)o.tasks.push(s);else if(JSON.stringify(o.tasks[a])!==JSON.stringify(s)){if(r)return{created:!1,updated:!1,kept:!0};o.tasks[a]=s}else return{created:!1,updated:!1};return await T(pt(n),{recursive:!0}),await C(n,JSON.stringify(o,null," "),"utf-8"),{created:!i,updated:i}}async function Ln(e,t,{removeFileIfEmpty:r=!1}={}){let n=M(e,".vscode","tasks.json"),s;try{s=$t(await He(n,"utf-8"))}catch{return{removed:!1,fileRemoved:!1}}if(!Array.isArray(s?.tasks))return{removed:!1,fileRemoved:!1};let o=s.tasks.filter(a=>a?.label!==t);if(o.length===s.tasks.length)return{removed:!1,fileRemoved:!1};if(s.tasks=o,o.length===0&&Object.keys(s).every(a=>a==="version"||a==="tasks")&&r){let{rm:a}=await import("node:fs/promises");return await a(n,{force:!0}),{removed:!0,fileRemoved:!0}}return await C(n,JSON.stringify(s,null," "),"utf-8"),{removed:!0,fileRemoved:!1}}async function Mn(e,{createOnly:t=!1}={}){return Qs(e,{label:Xs,command:Dr("copilot"),presentation:{reveal:"silent",panel:"shared"}},{createOnly:t})}async function aa(e){return Gi(e,{visible:null})}async function z(e){let t=await aa(e);return t?{type:pe.WORKSPACE_FILE,settingsPath:t,workspaceFile:t}:{type:pe.FOLDER,settingsPath:M(e,".vscode","settings.json"),workspaceFile:null}}function Kl(e){return M(e,".vscode","settings.json")}function Fr(e,t=null){return t?.workspaceFile?M(pt(t.workspaceFile),".vesperrc"):M(e,".vesperrc")}async function ft(e){let t=await z(e);return Fr(e,t)}function $t(e){let t=og(e,{trailingCommas:!0});return JSON.parse(t)}async function J(e){let t=await z(e);try{let r=await He(t.settingsPath,"utf-8"),n=$t(r);return t.type===pe.WORKSPACE_FILE?n.settings||{}:n}catch(r){if(r.code==="ENOENT")return{};if(r instanceof SyntaxError){if(t.type===pe.WORKSPACE_FILE)throw new Error(`Failed to parse workspace file: ${t.settingsPath}. ${r.message}`);return{}}throw r}}async function oe(e,t){let r=await z(e);if(r.type===pe.WORKSPACE_FILE){let n;try{let s=await He(r.settingsPath,"utf-8");n=$t(s)}catch(s){if(s.code==="ENOENT")n={folders:[],settings:{}};else throw new Error(`Failed to read workspace file: ${r.settingsPath}. ${s.message}`)}n.settings=t,await C(r.settingsPath,JSON.stringify(n,null," "),"utf-8")}else{let n=pt(r.settingsPath);await T(n,{recursive:!0}),await C(r.settingsPath,JSON.stringify(t,null," "),"utf-8")}}function cg(e){return M(e,".vesper","tracking.json")}function Qi(){return{schemaVersion:2,manifest:[]}}async function Zi(e){let t;try{t=await He(e,"utf-8")}catch(r){return r&&r.code==="ENOENT"?{}:{corrupt:!0}}try{return{parsed:JSON.parse(t)}}catch{return{corrupt:!0,raw:t}}}async function ea(e,t){let r=`${e}.corrupt-${Date.now()}`,n=!1;try{await rg(e,r),n=!0}catch{if(typeof t=="string")try{await C(r,t,"utf-8"),n=!0}catch{}}Fl.has(e)||(Fl.add(e),Li(n?`Unreadable Vesper config at ${e} \u2014 backed up to ${r} and continuing with a fresh default. Restore it from the backup if this was unexpected.`:`Unreadable Vesper config at ${e} that could not be backed up \u2014 continuing with a fresh default. Inspect the file manually before re-running if this was unexpected.`))}async function x(e){let t=await z(e),r=Fr(e,t),n=cg(e),s=M(e,".vesperrc"),o=await Zi(r);if(o.parsed!==void 0)return o.parsed;if(o.corrupt)return await ea(r,o.raw),Qi();if(r!==s){let a=await Zi(s);if(a.parsed!==void 0)return a.parsed;if(a.corrupt)return await ea(s,a.raw),Qi()}let i=await Zi(n);return i.parsed!==void 0?i.parsed:(i.corrupt&&await ea(n,i.raw),Qi())}async function Bl(e){return await Fn(e)}async function zl(e){return await Bl(e)}async function ca(e){try{let t=await He(e,"utf-8"),n=$t(t).folders||[],s=pt(e);return n.map(o=>{let i=o.path||o;return i.startsWith("/")||i.startsWith("~")?i.replace(/^~/,ta()):M(s,i)})}catch{return[]}}async function Dn(e){let t=await z(e);if(t.type!==pe.WORKSPACE_FILE)return{found:!1,paths:[]};let r=pt(t.workspaceFile),n=M(r,".vesperrc"),s=await ca(t.workspaceFile),o=[];for(let i of s){let a=M(i,".vesperrc");if(a!==n)try{let c=await He(a,"utf-8"),l=JSON.parse(c);o.push({folderPath:i,vesperrcPath:a,tracking:l})}catch{}}return{found:o.length>0,paths:o}}async function eo(e,t,r){let n=await z(e),s=Fr(e,n),o={...r,workspaceType:pe.WORKSPACE_FILE,settingsPath:n.settingsPath,migratedFrom:t,migratedAt:new Date().toISOString()};await C(s,JSON.stringify(o,null,2),"utf-8");try{let{unlink:i}=await import("node:fs/promises");await i(t)}catch{}return{success:!0,newPath:s}}async function I(e,t){let r=await z(e),n=Fr(e,r);try{let s=JSON.parse(await He(n,"utf-8"));if(Vl(s)===Vl(t))return}catch{}await dr(n,JSON.stringify(t,null,2))}function Vl(e){let t=r=>{if(Array.isArray(r))return r.map(t);if(r&&typeof r=="object"){let n={};for(let s of Object.keys(r).sort())s==="updatedAt"||r[s]===void 0||(n[s]=t(r[s]));return n}return r};return JSON.stringify(t(e))}async function Vr(e,t){let r=await z(e),n=await J(e),s=await x(e);Array.isArray(s.paths)||(s.paths=[]);let o=[],i=[];for(let{path:a,settingKey:c}of t){if(n[c]||(n[c]={}),n[c][a]){i.push(a),s.paths.includes(a)||s.paths.push(a);continue}n[c][a]=!0,o.push(a),s.paths.includes(a)||s.paths.push(a)}return o.length>0&&await oe(e,n),s.paths.length>0&&(s.addedAt=s.addedAt||new Date().toISOString(),s.updatedAt=new Date().toISOString(),s.workspaceType=r.type,s.settingsPath=r.settingsPath,await I(e,s)),{added:o,skipped:i,workspaceType:r.type}}async function Fn(e){let t=await J(e),r=await x(e),n={paths:[],settings:[],mcpServers:[],agentTools:[]},s=/vespercli|vesper-cli/,o=[...new Set([...Jl(r),...no().map(h=>h.path),...Yl().map(h=>h.path)])];for(let h of Object.values(Ge))if(t[h]){for(let m of Object.keys(t[h])){let f=o.includes(m),g=s.test(m);(f||g)&&(delete t[h][m],n.paths.includes(m)||n.paths.push(m))}Object.keys(t[h]).length===0&&delete t[h]}let i=[...new Set([...r.readAccessPaths||[],O])];if(i.length>0){let h=t[ne]||[],m=h.filter(f=>!i.includes(f));m.length!==h.length&&(m.length>0?t[ne]=m:delete t[ne],n.settings.push(ne))}let a=ug();for(let h of Ct){if(t[h]===void 0)continue;let m=t[h];if(lg.has(h)&&m&&typeof m=="object"&&!Array.isArray(m)){let f=!1;for(let g of Object.keys(m))(a.has(g)||Ul(g))&&(delete m[g],f=!0);Object.keys(m).length===0?(delete t[h],n.settings.push(h)):f&&n.settings.push(h);continue}delete t[h],n.settings.push(h)}let c=r.mcp?.agentTools||{};for(let[h,m]of Object.entries(c))n.agentTools.push({agent:h,tools:m});(n.paths.length>0||n.settings.length>0)&&await oe(e,t);let l=await Ye(e),d=r.mcp?.servers||[],p=[...new Set([...fe,...d])];if(l.servers){for(let h of p)l.servers[h]&&(delete l.servers[h],n.mcpServers.push(h));if(n.mcpServers.length>0){let h=Je(e),m=pt(h);await T(m,{recursive:!0}),await C(h,JSON.stringify(l,null," "),"utf-8")}}return r.paths=[],r.readAccessPaths=[],r.addedAt=null,r.workspaceType=null,r.settingsPath=null,r.mcp=null,await I(e,r),{removed:n}}function ug(){return new Set([...Tn,...je,...Object.values(Zs).flat()])}async function Gr(e,{trackedPaths:t=[],trackedReadAccess:r=[]}={}){let n={removed:[],rehomed:[],readAccessRemoved:[],commandKeysRemoved:[]},s;try{s=await J(e)}catch{return n}let o=new Set(t),i=/\/assets\/(?:core\/|skills(?:\/|$)|agents\/|prompts\/|instructions\/)/,a=!1;for(let d of Object.values(Ge)){let p=s[d];if(!(!p||typeof p!="object"||Array.isArray(p))){for(let h of Object.keys(p)){let m=h.replace(/\\/g,"/");if(zi(m)||o.has(h)&&i.test(m)){delete p[h],n.removed.push(h),a=!0;continue}let f=Ns.exec(m);if(f&&f[1].startsWith("assets/copilot/")){let g=Wt(M(kn,f[1]));if(g!==h){let y=p[h];delete p[h],p[g]=p[g]===!0?!0:y,n.rehomed.push(h),a=!0}}}Object.keys(p).length===0&&(delete s[d],a=!0)}}let c=s[ne];if(Array.isArray(c)){let d=new Set([O,Wt(O)]),p=new Set(r.filter(m=>typeof m=="string"&&/\/assets\/?$/.test(m.replace(/\\/g,"/")))),h=c.filter(m=>{if(typeof m!="string"||d.has(m))return!0;let f=Ns.exec(m.replace(/\\/g,"/")),g=!!f&&/^assets\/?$/.test(f[1])||p.has(m);return g&&n.readAccessRemoved.push(m),!g});h.length!==c.length&&(h.length?s[ne]=h:delete s[ne],a=!0)}let l=s[_t];if(l&&typeof l=="object"&&!Array.isArray(l))for(let d of Object.keys(l))Ul(d)&&(delete l[d],n.commandKeysRemoved.push(d),a=!0);if(a&&await oe(e,s),n.removed.length||n.rehomed.length||n.readAccessRemoved.length){let d=await x(e),p=!1,h=new Set([...n.removed,...n.rehomed]);Array.isArray(d.paths)&&d.paths.some(f=>h.has(f))&&(d.paths=d.paths.filter(f=>!h.has(f)),p=!0);let m=new Set(n.readAccessRemoved);Array.isArray(d.readAccessPaths)&&d.readAccessPaths.some(f=>m.has(f))&&(d.readAccessPaths=d.readAccessPaths.filter(f=>!m.has(f)),p=!0),p&&await I(e,d)}return n}function Jl(e){let r=(Array.isArray(e?.manifest)?e.manifest:[]).find(n=>n&&n.path===".vscode/settings.json"&&n.category==="settings");return r&&Array.isArray(r.owns?.entries)&&r.owns.entries.length?[...r.owns.entries]:Array.isArray(e?.paths)?[...e.paths]:[]}async function he(e){let t=await x(e);if(Number(t.schemaVersion)>=2)return[];let r=[];return Array.isArray(t.paths)&&t.paths.length>0&&r.push("copilot"),t.claude&&r.push("claude"),r}async function to(){try{return(await tg(Gs,{withFileTypes:!0})).filter(t=>t.isDirectory()&&!t.name.startsWith(".")).map(t=>t.name).sort()}catch{return[]}}function ro(e){Di(e);let t=M(Gs,e);if(!Nr(M(t,`${e}.instructions.md`)))throw new Error(`Unknown instruction "${e}" \u2014 not in ${Gs}`);return{path:Wt(t),settingKey:Ge.instructions,type:"instructions",name:e}}function no(){let e=[];for(let s of pg){let o=ze[s],i=Ge[s];i&&o&&e.push({path:Wt(M(dg,o.dir)),settingKey:i,type:s})}Ge.instructions&&Nr(Pn)&&e.push({path:Wt(Pn),settingKey:Ge.instructions,type:"instructions"});let t=Ge.agents;t&&e.push({path:"${workspaceFolder}/.vesper/agents",settingKey:t,type:"agents"});let r=Ge.instructions;r&&e.push({path:"${workspaceFolder}/.vesper/instructions",settingKey:r,type:"instructions"});let n=Ge.skills;return n&&e.push({path:"${workspaceFolder}/.vesper/skills",settingKey:n,type:"skills"}),e}function so(){try{return ng(Hs,{withFileTypes:!0}).filter(e=>e.isDirectory()&&!e.name.startsWith(".")).map(e=>e.name).sort()}catch{return[]}}function Hr(e){Di(e);let t=M(Hs,e);if(!Nr(t))throw new Error(`Unknown pack "${e}" \u2014 not in ${Hs}`);let r=[];for(let n of["agents","skills"]){let s=M(t,n);Nr(s)&&r.push({path:Wt(s),settingKey:Ge[n],type:n,pack:e})}return r}function Yl(){return so().flatMap(e=>Hr(e))}async function la(e,t){let r=await J(e),n=await x(e),s=new Set(t),o=[];for(let i of Object.values(Ge)){let a=r[i];if(!(!a||typeof a!="object")){for(let c of Object.keys(a))s.has(c)&&(delete a[c],o.includes(c)||o.push(c));Object.keys(a).length===0&&delete r[i]}}return o.length>0&&await oe(e,r),Array.isArray(n.paths)&&n.paths.some(i=>s.has(i))&&(n.paths=n.paths.filter(i=>!s.has(i)),n.updatedAt=new Date().toISOString(),await I(e,n)),{removed:o}}async function oo(e,t=!0){let r=await z(e),n=await J(e);if(n[Us]=t,t){n[_t]||(n[_t]={});for(let s of Tn)n[_t][s]=!0}return await oe(e,n),{configured:t?Tn.length:0,workspaceType:r.type}}async function io(e,t={}){let{maxRequests:r=Ie.maxRequests,omitBaseAgentInstructions:n=Ie.omitBaseAgentInstructions}=t,s=await J(e);s[Ws]=r,s[Ks]=!0,s[Bs]=!0,s[zs]=!0,s[Js]=n,s[Ys]=!0,s[qs]="newAndOutdated",s[ne]||(s[ne]=[]),await oe(e,s)}async function ql(e){let r=(await J(e))[_t]||{};return Object.entries(r).filter(([,n])=>n===!0).map(([n])=>n)}async function ao(e,t){let r=await J(e),n=r[ne]||[];n.includes(t)||(n.push(t),r[ne]=n,await oe(e,r));let s=await x(e);return s.readAccessPaths||(s.readAccessPaths=[]),s.readAccessPaths.includes(t)||(s.readAccessPaths.push(t),s.updatedAt=new Date().toISOString(),await I(e,s)),n}async function co(e,t){let r=await J(e),n=r[ne]||[],s=n.indexOf(t);s!==-1&&(n.splice(s,1),r[ne]=n,await oe(e,r));let o=await x(e);if(o.readAccessPaths){let i=o.readAccessPaths.indexOf(t);i!==-1&&(o.readAccessPaths.splice(i,1),o.updatedAt=new Date().toISOString(),await I(e,o))}return n}async function lo(e){return(await J(e))[ne]||[]}async function ht(e){let t=await x(e);return Jl(t)}async function uo(e){let t=await z(e),r=await J(e),n=await x(e);Array.isArray(n.paths)||(n.paths=[]);let s=no(),o=[],i=[];for(let{path:l,settingKey:d}of s)r[d]||(r[d]={}),r[d][l]===!0?i.push(l):(r[d][l]=!0,o.push(l)),n.paths.includes(l)||n.paths.push(l);let a=O,c=r[ne]||[];return c.includes(a)||(c.push(a),r[ne]=c,o.push(a)),n.readAccessPaths||(n.readAccessPaths=[]),n.readAccessPaths.includes(a)||n.readAccessPaths.push(a),o.length>0&&await oe(e,r),n.addedAt=n.addedAt||new Date().toISOString(),n.updatedAt=new Date().toISOString(),n.workspaceType=t.type,n.settingsPath=t.settingsPath,await I(e,n),{added:o,existed:i,workspaceType:t.type}}async function fg(e,{cwd:t,env:r,gitArgs:n=[],timeout:s=ra}={}){let{execFile:o}=await import("node:child_process");return new Promise(i=>{try{o("git",[...n,...e],{cwd:t,timeout:s,maxBuffer:16777216,encoding:"utf-8",...r?{env:r}:{}},(c,l)=>{i(c?null:l)}).stdin?.end()}catch{i(null)}})}function po(e){if(!e)return[];let t=e.includes("\0")?"\0":`
26
- `,r=[],n=null;for(let s of e.split(t)){if(s===""){n&&r.push(n),n=null;continue}n??={};let o=s.indexOf(" "),i=o===-1?s:s.slice(0,o),a=o===-1?null:s.slice(o+1);i==="worktree"?n.worktree=a:i==="HEAD"?n.head=a:i==="branch"?n.branch=a:i==="bare"?n.bare=!0:i==="detached"?n.detached=!0:i==="locked"?n.locked=a??!0:i==="prunable"&&(n.prunable=a??!0)}return n&&r.push(n),r}async function hg(){if(Vs)return Vs;let e=await G(["version"]),t=/(\d+)\.(\d+)/.exec(e||"");return Vs=t?[Number(t[1]),Number(t[2])]:[0,0],Vs}async function fo(e,{env:t,gitArgs:r=[],gitVersion:n}={}){let[s,o]=n??await hg(),i=s>2||s===2&&o>=36,a=await fg(["worktree","list","--porcelain",...i?["-z"]:[]],{cwd:e,env:t,gitArgs:r});return a===null?null:{out:a,nul:i}}async function $n(e){let{realpath:t}=await import("node:fs/promises"),{resolve:r}=await import("node:path");try{return await t(e)}catch{return r(e)}}async function At(e){let{realpath:t}=await import("node:fs/promises"),{resolve:r,join:n,dirname:s,basename:o}=await import("node:path"),i=r(e),a=[];for(;;)try{let c=await t(i);return a.length?n(c,...a.reverse()):c}catch{let c=s(i);if(c===i)return r(e);a.push(o(i)),i=c}}async function Xl(e,{top:t,common:r},{git:n=G,env:s,gitArgs:o=[]}={}){let i=new Set([await $n(t),await $n(r)]);await n(["rev-parse","--is-bare-repository"],{cwd:e})==="true"||i.add(await $n(pt(r)));let c=await fo(e,{env:s,gitArgs:o});for(let l of po(c?.out??null))l.worktree&&!l.bare&&i.add(await $n(l.worktree));return[...i]}function Kt(e,t){let{sep:r}=sg;return(t||[]).some(n=>e===n||e.startsWith(`${n}${r}`))}async function Wr(e,{runGit:t=G,env:r,gitArgs:n=[]}={}){let s=(E,b={})=>t([...n,...E],{...b,...r?{env:r}:{}}),{isAbsolute:o,resolve:i}=await import("node:path"),{realpath:a,stat:c}=await import("node:fs/promises");if(await s(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{dir:null,reason:"not-a-repo"};let l=await s(["rev-parse","--show-toplevel"],{cwd:e}),d=await s(["rev-parse","--git-common-dir"],{cwd:e});if(!l||!d)return{dir:null,reason:"not-a-repo"};let p=o(d)?d:i(e,d),h=await Xl(e,{top:l,common:p},{git:s,env:r,gitArgs:n}),m={top:l,common:p,roots:h},f=await s(["config","--type=path","--show-scope","--get","core.hooksPath"],{cwd:e});if(f===null){let E=await s(["config","--get","core.hooksPath"],{cwd:e});if(E)return{dir:null,disabled:!0,reason:"unverifiable",configured:E};let b=M(p,"hooks"),F=await At(b);if(!Kt(F,h))return{dir:null,disabled:!0,reason:"outside-repository",configured:b,defaultDir:!0};if(Nr(b))try{if(!(await c(F)).isDirectory())return{dir:null,disabled:!0,reason:"not-a-directory",configured:b,defaultDir:!0}}catch{}return{dir:b,default:!0,...m}}let g=f.indexOf(" "),y=g===-1?"":f.slice(0,g),k=g===-1?f:f.slice(g+1);if(!["local","worktree"].includes(y))return{dir:null,disabled:!0,reason:"machine-wide",scope:y,configured:k};let v=o(k)?k:i(l,k);if(mg(v))return{dir:null,disabled:!0,reason:"husky-v9",scope:y,configured:k};let S=null;try{S=await a(v)}catch{S=null}let A=!1;if(S!==null)try{A=(await c(S)).isDirectory()}catch{A=!1}if(S!==null&&!A)return{dir:null,disabled:!0,reason:"not-a-directory",scope:y,configured:k};let N=S??i(v);return Kt(N,h)?A?{dir:v,scope:y,configured:k,...m}:{dir:null,disabled:!0,reason:"not-a-directory",scope:y,configured:k}:{dir:null,disabled:!0,reason:"outside-repository",scope:y,configured:k}}function mg(e){let t=e.replace(/\\/g,"/").replace(/\/+$/,"").split("/");return t.at(-1)==="_"&&t.at(-2)===".husky"&&Nr(M(e,"h"))}async function ho(e){let{lstat:t,realpath:r}=await import("node:fs/promises"),n;try{n=await t(e)}catch(s){if(s.code==="ENOENT")return{path:e};throw s}if(!n.isSymbolicLink())return{path:e};try{return{path:await r(e)}}catch{return{path:null,reason:"dangling-symlink"}}}async function cr(e,t){let{basename:r}=await import("node:path");await dr(e,t,{mode:493,tempName:n=>M(pt(n),`.${r(n)}.vesper-${process.pid}.tmp`),sweepPattern:/^\..+\.vesper-\d+\.tmp$/})}async function Lr(e,t,{dir:r=!1}={}){let{relative:n}=await import("node:path"),s=await $n(t.common??"");if(Kt(e,[s]))return!1;let o=(t.roots||[]).filter(l=>l!==s&&Kt(e,[l])).sort((l,d)=>d.length-l.length),{stripRepoLocationEnv:i,READ_ONLY_GIT_ENV:a}=await Promise.resolve().then(()=>(dt(),Xi)),c={...i(process.env),...a};for(let l of o){let d=n(l,e);if(d===""||d.startsWith(".."))continue;let p=r?["ls-files","-z","--",d]:["ls-files","--error-unmatch","--",d],h=await G([...Ur,...p],{cwd:l,env:c,timeout:1e4});return r?!!h:h!==null}return!1}async function Ql(e,t,{resolved:r,dirTracked:n}={}){let s=r??await Wr(e);if(!s.dir){let{reason:N,disabled:E,scope:b,configured:F,defaultDir:Q}=s;return{installed:!1,updated:!1,hooksDir:null,reason:N,...E?{disabled:E}:{},...b?{scope:b}:{},...F!==void 0?{configured:F}:{},...Q?{defaultDir:Q}:{}}}let o=s.dir,i=(N,E={})=>({installed:!1,updated:!1,hooksDir:o,hook:t,reason:N,...E}),a=M(O,"hooks",t),c=await He(a,"utf-8"),l=c.match(new RegExp(`${kt}[\\s\\S]*?${Tr}`));if(!l)throw new Error(`Hook source ${a} is missing its vesper:hook guard markers`);let d=Buffer.from(l[0],"utf-8").toString("latin1"),p=new RegExp(`${kt}[\\s\\S]*?${Tr}`);if(n??(!s.default&&await Lr(await At(o),s,{dir:!0})))return{installed:!1,updated:!1,hooksDir:null,reason:"tracked-by-git",configured:o};let m=M(o,t),f=await ho(m);if(!f.path)return i(f.reason,{configured:m});let g=await At(f.path);if(!Kt(g,s.roots))return i("outside-repository",{configured:f.path});if(lr(f.path))return i("write-refused",{configured:f.path});if(await Lr(g,s))return i("tracked-by-git",{configured:g});s.default&&await T(o,{recursive:!0});let y=null;try{y=await He(f.path)}catch(N){if(N.code!=="ENOENT")throw N}if(y===null)return await cr(f.path,c),{installed:!0,updated:!1,hooksDir:o};let k=y.toString("latin1"),v=k.indexOf(kt);if(v!==-1&&p.test(k)){let N=Pr(y.subarray(0,v),{whole:y});if(!N.ok){let b=nr(k);return b!==null&&b!==k&&await cr(f.path,Buffer.from(b,"latin1")),{installed:!1,updated:!0,hooksDir:o,hook:t,reason:"foreign-hook-repaired",interpreter:N.interpreter}}let E=k.replace(p,()=>d);return E!==k?(await cr(f.path,Buffer.from(E,"latin1")),{installed:!1,updated:!0,hooksDir:o}):{installed:!1,updated:!1,hooksDir:o}}let S=Pr(y);if(!S.ok){let{reason:N,interpreter:E,line:b}=S;return i(N,{interpreter:E,...b!==void 0?{line:b}:{}})}let A=k.endsWith(`
24
+ `;return await A(t,`${s}${o}${r}
25
+ `,"utf-8"),{created:!1,updated:!0}}function ty(e,t){let r=e.endsWith("/"),n=r?e.slice(0,-1):e;return new RegExp(`^${n.split("*").map(o=>o.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join("[^/]*")}${r?"/":"$"}`).test(t)}async function Yn(e){let{execFile:t}=await import("node:child_process"),{promisify:r}=await import("node:util"),n=r(t),s=async l=>{try{let{stdout:d}=await n("git",l,{cwd:e,timeout:Ca,maxBuffer:16777216});return d}catch{return null}},o=await s(["rev-parse","--is-inside-work-tree"]);if(o===null||o.trim()!=="true")return[];let i=Un.map(l=>l.endsWith("/")?`${l}*`:l),a=await s(["ls-files","-z","--",...i]);if(!a)return[];let c=l=>{let d=Un.findIndex(p=>ty(p,l));return d===-1?Un.length:d};return[...new Set(a.split("\0").filter(Boolean))].sort((l,d)=>c(l)-c(d)||(l<d?-1:l>d?1:0))}function qr(e){return`vespercli guard --running-host ${e}`}async function ko(e,t,{createOnly:r=!1}={}){let n=M(e,".vscode","tasks.json"),s={label:t.label,type:"shell",command:t.command,presentation:t.presentation||{reveal:"silent",panel:"shared"},problemMatcher:[],runOptions:{runOn:"folderOpen"}},o={version:"2.0.0",tasks:[]},i=!1;try{let c=await Ke(n,"utf-8");o=Lt(c),Array.isArray(o.tasks)||(o.tasks=[]),i=!0}catch(c){if(c.code!=="ENOENT")throw c}let a=o.tasks.findIndex(c=>c?.label===t.label);if(a===-1)o.tasks.push(s);else if(JSON.stringify(o.tasks[a])!==JSON.stringify(s)){if(r)return{created:!1,updated:!1,kept:!0};o.tasks[a]=s}else return{created:!1,updated:!1};return await P(St(n),{recursive:!0}),await A(n,JSON.stringify(o,null," "),"utf-8"),{created:!i,updated:i}}async function qn(e,t,{removeFileIfEmpty:r=!1}={}){let n=M(e,".vscode","tasks.json"),s;try{s=Lt(await Ke(n,"utf-8"))}catch{return{removed:!1,fileRemoved:!1}}if(!Array.isArray(s?.tasks))return{removed:!1,fileRemoved:!1};let o=s.tasks.filter(a=>a?.label!==t);if(o.length===s.tasks.length)return{removed:!1,fileRemoved:!1};if(s.tasks=o,o.length===0&&Object.keys(s).every(a=>a==="version"||a==="tasks")&&r){let{rm:a}=await import("node:fs/promises");return await a(n,{force:!0}),{removed:!0,fileRemoved:!0}}return await A(n,JSON.stringify(s,null," "),"utf-8"),{removed:!0,fileRemoved:!1}}async function Xn(e,{createOnly:t=!1}={}){return ko(e,{label:vo,command:qr("copilot"),presentation:{reveal:"silent",panel:"shared"}},{createOnly:t})}async function Ia(e){return pa(e,{visible:null})}async function q(e){let t=await Ia(e);return t?{type:he.WORKSPACE_FILE,settingsPath:t,workspaceFile:t}:{type:he.FOLDER,settingsPath:M(e,".vscode","settings.json"),workspaceFile:null}}function _u(e){return M(e,".vscode","settings.json")}function Xr(e,t=null){return t?.workspaceFile?M(St(t.workspaceFile),".vesperrc"):M(e,".vesperrc")}async function Et(e){let t=await q(e);return Xr(e,t)}function Lt(e){let t=Zg(e,{trailingCommas:!0});return JSON.parse(t)}async function K(e){let t=await q(e);try{let r=await Ke(t.settingsPath,"utf-8"),n=Lt(r);return t.type===he.WORKSPACE_FILE?n.settings||{}:n}catch(r){if(r.code==="ENOENT")return{};if(r instanceof SyntaxError){if(t.type===he.WORKSPACE_FILE)throw new Error(`Failed to parse workspace file: ${t.settingsPath}. ${r.message}`);return{}}throw r}}async function ce(e,t){let r=await q(e);if(r.type===he.WORKSPACE_FILE){let n;try{let s=await Ke(r.settingsPath,"utf-8");n=Lt(s)}catch(s){if(s.code==="ENOENT")n={folders:[],settings:{}};else throw new Error(`Failed to read workspace file: ${r.settingsPath}. ${s.message}`)}n.settings=t,await A(r.settingsPath,JSON.stringify(n,null," "),"utf-8")}else{let n=St(r.settingsPath);await P(n,{recursive:!0}),await A(r.settingsPath,JSON.stringify(t,null," "),"utf-8")}}function ry(e){return M(e,".vesper","tracking.json")}function ba(){return{schemaVersion:2,manifest:[]}}async function xa(e){let t;try{t=await Ke(e,"utf-8")}catch(r){return r&&r.code==="ENOENT"?{}:{corrupt:!0}}try{return{parsed:JSON.parse(t)}}catch{return{corrupt:!0,raw:t}}}async function Aa(e,t){let r=`${e}.corrupt-${Date.now()}`,n=!1;try{await qg(e,r),n=!0}catch{if(typeof t=="string")try{await A(r,t,"utf-8"),n=!0}catch{}}ku.has(e)||(ku.add(e),aa(n?`Unreadable Vesper config at ${e} \u2014 backed up to ${r} and continuing with a fresh default. Restore it from the backup if this was unexpected.`:`Unreadable Vesper config at ${e} that could not be backed up \u2014 continuing with a fresh default. Inspect the file manually before re-running if this was unexpected.`))}async function x(e){let t=await q(e),r=Xr(e,t),n=ry(e),s=M(e,".vesperrc"),o=await xa(r);if(o.parsed!==void 0)return o.parsed;if(o.corrupt)return await Aa(r,o.raw),ba();if(r!==s){let a=await xa(s);if(a.parsed!==void 0)return a.parsed;if(a.corrupt)return await Aa(s,a.raw),ba()}let i=await xa(n);return i.parsed!==void 0?i.parsed:(i.corrupt&&await Aa(n,i.raw),ba())}async function Cu(e){return await Zn(e)}async function $u(e){return await Cu(e)}async function ja(e){try{let t=await Ke(e,"utf-8"),n=Lt(t).folders||[],s=St(e);return n.map(o=>{let i=o.path||o;return i.startsWith("/")||i.startsWith("~")?i.replace(/^~/,_a()):M(s,i)})}catch{return[]}}async function Qn(e){let t=await q(e);if(t.type!==he.WORKSPACE_FILE)return{found:!1,paths:[]};let r=St(t.workspaceFile),n=M(r,".vesperrc"),s=await ja(t.workspaceFile),o=[];for(let i of s){let a=M(i,".vesperrc");if(a!==n)try{let c=await Ke(a,"utf-8"),l=JSON.parse(c);o.push({folderPath:i,vesperrcPath:a,tracking:l})}catch{}}return{found:o.length>0,paths:o}}async function Eo(e,t,r){let n=await q(e),s=Xr(e,n),o={...r,workspaceType:he.WORKSPACE_FILE,settingsPath:n.settingsPath,migratedFrom:t,migratedAt:new Date().toISOString()};await A(s,JSON.stringify(o,null,2),"utf-8");try{let{unlink:i}=await import("node:fs/promises");await i(t)}catch{}return{success:!0,newPath:s}}async function T(e,t){let r=await q(e),n=Xr(e,r);try{let s=JSON.parse(await Ke(n,"utf-8"));if(Su(s)===Su(t))return}catch{}await _r(n,JSON.stringify(t,null,2))}function Su(e){let t=r=>{if(Array.isArray(r))return r.map(t);if(r&&typeof r=="object"){let n={};for(let s of Object.keys(r).sort())s==="updatedAt"||r[s]===void 0||(n[s]=t(r[s]));return n}return r};return JSON.stringify(t(e))}async function Qr(e,t){let r=await q(e),n=await K(e),s=await x(e);Array.isArray(s.paths)||(s.paths=[]);let o=[],i=[];for(let{path:a,settingKey:c}of t){if(n[c]||(n[c]={}),n[c][a]){i.push(a),s.paths.includes(a)||s.paths.push(a);continue}n[c][a]=!0,o.push(a),s.paths.includes(a)||s.paths.push(a)}return o.length>0&&await ce(e,n),s.paths.length>0&&(s.addedAt=s.addedAt||new Date().toISOString(),s.updatedAt=new Date().toISOString(),s.workspaceType=r.type,s.settingsPath=r.settingsPath,await T(e,s)),{added:o,skipped:i,workspaceType:r.type}}async function Zn(e){let t=await K(e),r=await x(e),n={paths:[],settings:[],mcpServers:[],agentTools:[]},s=/vespercli|vesper-cli/,o=[...new Set([...Ou(r),...Ao().map(f=>f.path),...Tu().map(f=>f.path)])];for(let f of Object.values(We))if(t[f]){for(let m of Object.keys(t[f])){let h=o.includes(m),g=s.test(m);(h||g)&&(delete t[f][m],n.paths.includes(m)||n.paths.push(m))}Object.keys(t[f]).length===0&&delete t[f]}let i=[...new Set([...r.readAccessPaths||[],O])];if(i.length>0){let f=t[oe]||[],m=f.filter(h=>!i.includes(h));m.length!==f.length&&(m.length>0?t[oe]=m:delete t[oe],n.settings.push(oe))}let a=sy();for(let f of Nt){if(t[f]===void 0)continue;let m=t[f];if(ny.has(f)&&m&&typeof m=="object"&&!Array.isArray(m)){let h=!1;for(let g of Object.keys(m))(a.has(g)||xu(g))&&(delete m[g],h=!0);Object.keys(m).length===0?(delete t[f],n.settings.push(f)):h&&n.settings.push(f);continue}delete t[f],n.settings.push(f)}let c=r.mcp?.agentTools||{};for(let[f,m]of Object.entries(c))n.agentTools.push({agent:f,tools:m});(n.paths.length>0||n.settings.length>0)&&await ce(e,t);let l=await Ze(e),d=r.mcp?.servers||[],p=[...new Set([...me,...d])];if(l.servers){for(let f of p)l.servers[f]&&(delete l.servers[f],n.mcpServers.push(f));if(n.mcpServers.length>0){let f=Qe(e),m=St(f);await P(m,{recursive:!0}),await A(f,JSON.stringify(l,null," "),"utf-8")}}return r.paths=[],r.readAccessPaths=[],r.addedAt=null,r.workspaceType=null,r.settingsPath=null,r.mcp=null,await T(e,r),{removed:n}}function sy(){return new Set([...Wn,...Re,...Object.values(So).flat()])}async function Zr(e,{trackedPaths:t=[],trackedReadAccess:r=[]}={}){let n={removed:[],rehomed:[],readAccessRemoved:[],commandKeysRemoved:[]},s;try{s=await K(e)}catch{return n}let o=new Set(t),i=/\/assets\/(?:core\/|skills(?:\/|$)|agents\/|prompts\/|instructions\/)/,a=!1;for(let d of Object.values(We)){let p=s[d];if(!(!p||typeof p!="object"||Array.isArray(p))){for(let f of Object.keys(p)){let m=f.replace(/\\/g,"/");if(wa(m)||o.has(f)&&i.test(m)){delete p[f],n.removed.push(f),a=!0;continue}let h=ro.exec(m);if(h&&h[1].startsWith("assets/copilot/")){let g=er(M(Nn,h[1]));if(g!==f){let y=p[f];delete p[f],p[g]=p[g]===!0?!0:y,n.rehomed.push(f),a=!0}}}Object.keys(p).length===0&&(delete s[d],a=!0)}}let c=s[oe];if(Array.isArray(c)){let d=new Set([O,er(O)]),p=new Set(r.filter(m=>typeof m=="string"&&/\/assets\/?$/.test(m.replace(/\\/g,"/")))),f=c.filter(m=>{if(typeof m!="string"||d.has(m))return!0;let h=ro.exec(m.replace(/\\/g,"/")),g=!!h&&/^assets\/?$/.test(h[1])||p.has(m);return g&&n.readAccessRemoved.push(m),!g});f.length!==c.length&&(f.length?s[oe]=f:delete s[oe],a=!0)}let l=s[Rt];if(l&&typeof l=="object"&&!Array.isArray(l))for(let d of Object.keys(l))xu(d)&&(delete l[d],n.commandKeysRemoved.push(d),a=!0);if(a&&await ce(e,s),n.removed.length||n.rehomed.length||n.readAccessRemoved.length){let d=await x(e),p=!1,f=new Set([...n.removed,...n.rehomed]);Array.isArray(d.paths)&&d.paths.some(h=>f.has(h))&&(d.paths=d.paths.filter(h=>!f.has(h)),p=!0);let m=new Set(n.readAccessRemoved);Array.isArray(d.readAccessPaths)&&d.readAccessPaths.some(h=>m.has(h))&&(d.readAccessPaths=d.readAccessPaths.filter(h=>!m.has(h)),p=!0),p&&await T(e,d)}return n}function Ou(e){let r=(Array.isArray(e?.manifest)?e.manifest:[]).find(n=>n&&n.path===".vscode/settings.json"&&n.category==="settings");return r&&Array.isArray(r.owns?.entries)&&r.owns.entries.length?[...r.owns.entries]:Array.isArray(e?.paths)?[...e.paths]:[]}async function ge(e){let t=await x(e);if(Number(t.schemaVersion)>=2)return[];let r=[];return Array.isArray(t.paths)&&t.paths.length>0&&r.push("copilot"),t.claude&&r.push("claude"),r}async function bo(){try{return(await Jg(co,{withFileTypes:!0})).filter(t=>t.isDirectory()&&!t.name.startsWith(".")).map(t=>t.name).sort()}catch{return[]}}function xo(e){la(e);let t=M(co,e);if(!Yr(M(t,`${e}.instructions.md`)))throw new Error(`Unknown instruction "${e}" \u2014 not in ${co}`);return{path:er(t),settingKey:We.instructions,type:"instructions",name:e}}function Ao(){let e=[];for(let s of iy){let o=Xe[s],i=We[s];i&&o&&e.push({path:er(M(oy,o.dir)),settingKey:i,type:s})}We.instructions&&Yr(Kn)&&e.push({path:er(Kn),settingKey:We.instructions,type:"instructions"});let t=We.agents;t&&e.push({path:"${workspaceFolder}/.vesper/agents",settingKey:t,type:"agents"});let r=We.instructions;r&&e.push({path:"${workspaceFolder}/.vesper/instructions",settingKey:r,type:"instructions"});let n=We.skills;return n&&e.push({path:"${workspaceFolder}/.vesper/skills",settingKey:n,type:"skills"}),e}function _o(){try{return Xg(lo,{withFileTypes:!0}).filter(e=>e.isDirectory()&&!e.name.startsWith(".")).map(e=>e.name).sort()}catch{return[]}}function rr(e){la(e);let t=M(lo,e);if(!Yr(t))throw new Error(`Unknown pack "${e}" \u2014 not in ${lo}`);let r=[];for(let n of["agents","skills"]){let s=M(t,n);Yr(s)&&r.push({path:er(s),settingKey:We[n],type:n,pack:e})}return r}function Tu(){return _o().flatMap(e=>rr(e))}async function Ra(e,t){let r=await K(e),n=await x(e),s=new Set(t),o=[];for(let i of Object.values(We)){let a=r[i];if(!(!a||typeof a!="object")){for(let c of Object.keys(a))s.has(c)&&(delete a[c],o.includes(c)||o.push(c));Object.keys(a).length===0&&delete r[i]}}return o.length>0&&await ce(e,r),Array.isArray(n.paths)&&n.paths.some(i=>s.has(i))&&(n.paths=n.paths.filter(i=>!s.has(i)),n.updatedAt=new Date().toISOString(),await T(e,n)),{removed:o}}async function Co(e,t=!0){let r=await q(e),n=await K(e);if(n[uo]=t,t){n[Rt]||(n[Rt]={});for(let s of Wn)n[Rt][s]=!0}return await ce(e,n),{configured:t?Wn.length:0,workspaceType:r.type}}async function $o(e,t={}){let{maxRequests:r=je.maxRequests,omitBaseAgentInstructions:n=je.omitBaseAgentInstructions}=t,s=await K(e);s[po]=r,s[fo]=!0,s[ho]=!0,s[mo]=!0,s[go]=n,s[yo]=!0,s[wo]="newAndOutdated",s[oe]||(s[oe]=[]),await ce(e,s)}async function Pu(e){let r=(await K(e))[Rt]||{};return Object.entries(r).filter(([,n])=>n===!0).map(([n])=>n)}async function Oo(e,t){let r=await K(e),n=r[oe]||[];n.includes(t)||(n.push(t),r[oe]=n,await ce(e,r));let s=await x(e);return s.readAccessPaths||(s.readAccessPaths=[]),s.readAccessPaths.includes(t)||(s.readAccessPaths.push(t),s.updatedAt=new Date().toISOString(),await T(e,s)),n}async function To(e,t){let r=await K(e),n=r[oe]||[],s=n.indexOf(t);s!==-1&&(n.splice(s,1),r[oe]=n,await ce(e,r));let o=await x(e);if(o.readAccessPaths){let i=o.readAccessPaths.indexOf(t);i!==-1&&(o.readAccessPaths.splice(i,1),o.updatedAt=new Date().toISOString(),await T(e,o))}return n}async function Po(e){return(await K(e))[oe]||[]}async function bt(e){let t=await x(e);return Ou(t)}async function Io(e){let t=await q(e),r=await K(e),n=await x(e);Array.isArray(n.paths)||(n.paths=[]);let s=Ao(),o=[],i=[];for(let{path:l,settingKey:d}of s)r[d]||(r[d]={}),r[d][l]===!0?i.push(l):(r[d][l]=!0,o.push(l)),n.paths.includes(l)||n.paths.push(l);let a=O,c=r[oe]||[];return c.includes(a)||(c.push(a),r[oe]=c,o.push(a)),n.readAccessPaths||(n.readAccessPaths=[]),n.readAccessPaths.includes(a)||n.readAccessPaths.push(a),o.length>0&&await ce(e,r),n.addedAt=n.addedAt||new Date().toISOString(),n.updatedAt=new Date().toISOString(),n.workspaceType=t.type,n.settingsPath=t.settingsPath,await T(e,n),{added:o,existed:i,workspaceType:t.type}}async function ay(e,{cwd:t,env:r,gitArgs:n=[],timeout:s=Ca}={}){let{execFile:o}=await import("node:child_process");return new Promise(i=>{try{o("git",[...n,...e],{cwd:t,timeout:s,maxBuffer:16777216,encoding:"utf-8",...r?{env:r}:{}},(c,l)=>{i(c?null:l)}).stdin?.end()}catch{i(null)}})}function jo(e){if(!e)return[];let t=e.includes("\0")?"\0":`
26
+ `,r=[],n=null;for(let s of e.split(t)){if(s===""){n&&r.push(n),n=null;continue}n??={};let o=s.indexOf(" "),i=o===-1?s:s.slice(0,o),a=o===-1?null:s.slice(o+1);i==="worktree"?n.worktree=a:i==="HEAD"?n.head=a:i==="branch"?n.branch=a:i==="bare"?n.bare=!0:i==="detached"?n.detached=!0:i==="locked"?n.locked=a??!0:i==="prunable"&&(n.prunable=a??!0)}return n&&r.push(n),r}async function cy(){if(ao)return ao;let e=await D(["version"]),t=/(\d+)\.(\d+)/.exec(e||"");return ao=t?[Number(t[1]),Number(t[2])]:[0,0],ao}async function Ro(e,{env:t,gitArgs:r=[],gitVersion:n}={}){let[s,o]=n??await cy(),i=s>2||s===2&&o>=36,a=await ay(["worktree","list","--porcelain",...i?["-z"]:[]],{cwd:e,env:t,gitArgs:r});return a===null?null:{out:a,nul:i}}async function Hn(e){let{realpath:t}=await import("node:fs/promises"),{resolve:r}=await import("node:path");try{return await t(e)}catch{return r(e)}}async function at(e){let{realpath:t}=await import("node:fs/promises"),{resolve:r,join:n,dirname:s,basename:o}=await import("node:path"),i=r(e),a=[];for(;;)try{let c=await t(i);return a.length?n(c,...a.reverse()):c}catch{let c=s(i);if(c===i)return r(e);a.push(o(i)),i=c}}async function Iu(e,{top:t,common:r},{git:n=D,env:s,gitArgs:o=[]}={}){let i=new Set([await Hn(t),await Hn(r)]);await n(["rev-parse","--is-bare-repository"],{cwd:e})==="true"||i.add(await Hn(St(r)));let c=await Ro(e,{env:s,gitArgs:o});for(let l of jo(c?.out??null))l.worktree&&!l.bare&&i.add(await Hn(l.worktree));return[...i]}function kt(e,t){let{sep:r}=Qg;return(t||[]).some(n=>e===n||e.startsWith(`${n}${r}`))}async function nr(e,{runGit:t=D,env:r,gitArgs:n=[]}={}){let s=(E,b={})=>t([...n,...E],{...b,...r?{env:r}:{}}),{isAbsolute:o,resolve:i}=await import("node:path"),{realpath:a,stat:c}=await import("node:fs/promises");if(await s(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{dir:null,reason:"not-a-repo"};let l=await s(["rev-parse","--show-toplevel"],{cwd:e}),d=await s(["rev-parse","--git-common-dir"],{cwd:e});if(!l||!d)return{dir:null,reason:"not-a-repo"};let p=o(d)?d:i(e,d),f=await Iu(e,{top:l,common:p},{git:s,env:r,gitArgs:n}),m={top:l,common:p,roots:f},h=await s(["config","--type=path","--show-scope","--get","core.hooksPath"],{cwd:e});if(h===null){let E=await s(["config","--get","core.hooksPath"],{cwd:e});if(E)return{dir:null,disabled:!0,reason:"unverifiable",configured:E};let b=M(p,"hooks"),F=await at(b);if(!kt(F,f))return{dir:null,disabled:!0,reason:"outside-repository",configured:b,defaultDir:!0};if(Yr(b))try{if(!(await c(F)).isDirectory())return{dir:null,disabled:!0,reason:"not-a-directory",configured:b,defaultDir:!0}}catch{}return{dir:b,default:!0,...m}}let g=h.indexOf(" "),y=g===-1?"":h.slice(0,g),k=g===-1?h:h.slice(g+1);if(!["local","worktree"].includes(y))return{dir:null,disabled:!0,reason:"machine-wide",scope:y,configured:k};let v=o(k)?k:i(l,k);if(ly(v))return{dir:null,disabled:!0,reason:"husky-v9",scope:y,configured:k};let S=null;try{S=await a(v)}catch{S=null}let C=!1;if(S!==null)try{C=(await c(S)).isDirectory()}catch{C=!1}if(S!==null&&!C)return{dir:null,disabled:!0,reason:"not-a-directory",scope:y,configured:k};let N=S??i(v);return kt(N,f)?C?{dir:v,scope:y,configured:k,...m}:{dir:null,disabled:!0,reason:"not-a-directory",scope:y,configured:k}:{dir:null,disabled:!0,reason:"outside-repository",scope:y,configured:k}}function ly(e){let t=e.replace(/\\/g,"/").replace(/\/+$/,"").split("/");return t.at(-1)==="_"&&t.at(-2)===".husky"&&Yr(M(e,"h"))}async function tn(e){let{lstat:t,realpath:r}=await import("node:fs/promises"),n;try{n=await t(e)}catch(s){if(s.code==="ENOENT")return{path:e};throw s}if(!n.isSymbolicLink())return{path:e};try{return{path:await r(e)}}catch{return{path:null,reason:"dangling-symlink"}}}async function vt(e,t){let{basename:r}=await import("node:path");await _r(e,t,{mode:493,tempName:n=>M(St(n),`.${r(n)}.vesper-${process.pid}.tmp`),sweepPattern:/^\..+\.vesper-\d+\.tmp$/})}async function tr(e,t,{dir:r=!1}={}){let{relative:n}=await import("node:path"),s=await Hn(t.common??"");if(kt(e,[s]))return!1;let o=(t.roots||[]).filter(l=>l!==s&&kt(e,[l])).sort((l,d)=>d.length-l.length),{stripRepoLocationEnv:i,READ_ONLY_GIT_ENV:a}=await Promise.resolve().then(()=>(wt(),Ea)),c={...i(process.env),...a};for(let l of o){let d=n(l,e);if(d===""||d.startsWith(".."))continue;let p=r?["ls-files","-z","--",d]:["ls-files","--error-unmatch","--",d],f=await D([...en,...p],{cwd:l,env:c,timeout:1e4});return r?!!f:f!==null}return!1}async function ju(e,t,{resolved:r,dirTracked:n}={}){let s=r??await nr(e);if(!s.dir){let{reason:N,disabled:E,scope:b,configured:F,defaultDir:X}=s;return{installed:!1,updated:!1,hooksDir:null,reason:N,...E?{disabled:E}:{},...b?{scope:b}:{},...F!==void 0?{configured:F}:{},...X?{defaultDir:X}:{}}}let o=s.dir,i=(N,E={})=>({installed:!1,updated:!1,hooksDir:o,hook:t,reason:N,...E}),a=M(O,"hooks",t),c=await Ke(a,"utf-8"),l=c.match(new RegExp(`${ot}[\\s\\S]*?${Yt}`));if(!l)throw new Error(`Hook source ${a} is missing its vesper:hook guard markers`);let d=Buffer.from(l[0],"utf-8").toString("latin1"),p=new RegExp(`${ot}[\\s\\S]*?${Yt}`);if(n??(!s.default&&await tr(await at(o),s,{dir:!0})))return{installed:!1,updated:!1,hooksDir:null,reason:"tracked-by-git",configured:o};let m=M(o,t),h=await tn(m);if(!h.path)return i(h.reason,{configured:m});let g=await at(h.path);if(!kt(g,s.roots))return i("outside-repository",{configured:h.path});if(xr(h.path))return i("write-refused",{configured:h.path});if(await tr(g,s))return i("tracked-by-git",{configured:g});s.default&&await P(o,{recursive:!0});let y=null;try{y=await Ke(h.path)}catch(N){if(N.code!=="ENOENT")throw N}if(y===null)return await vt(h.path,c),{installed:!0,updated:!1,hooksDir:o};let k=y.toString("latin1"),v=k.indexOf(ot);if(v!==-1&&p.test(k)){let N=Ur(y.subarray(0,v),{whole:y});if(!N.ok){let b=vr(k);return b!==null&&b!==k&&await vt(h.path,Buffer.from(b,"latin1")),{installed:!1,updated:!0,hooksDir:o,hook:t,reason:"foreign-hook-repaired",interpreter:N.interpreter}}let E=k.replace(p,()=>d);return E!==k?(await vt(h.path,Buffer.from(E,"latin1")),{installed:!1,updated:!0,hooksDir:o}):{installed:!1,updated:!1,hooksDir:o}}let S=Ur(y);if(!S.ok){let{reason:N,interpreter:E,line:b}=S;return i(N,{interpreter:E,...b!==void 0?{line:b}:{}})}let C=k.endsWith(`
27
27
  `)?`
28
28
  `:`
29
29
 
30
- `;return await cr(f.path,Buffer.from(`${k}${A}${d}
31
- `,"latin1")),{installed:!1,updated:!0,hooksDir:o}}function Zl(e){if(!e||!e.reason||e.reason==="not-a-repo")return null;let t=e.configured??"",r=e.hook??"hook",n=r==="pre-commit"?`copy the block from ${M(O,"hooks","pre-commit")} into it yourself.`:"Add a call to `vespercli guard` to it yourself.",s=`${n[0].toUpperCase()}${n.slice(1)}`;switch(e.reason){case"not-a-directory":return e.defaultDir?`Git hooks not installed: git's hooks directory "${t}" is not a directory.`:`Git hooks not installed: core.hooksPath is "${t}", which is not a directory (hooks disabled for this repository).`;case"machine-wide":return`Git hooks not installed: core.hooksPath is set machine-wide (${e.scope}) \u2014 Vesper does not write shared hooks.`;case"outside-repository":return e.hooksDir?`Git hook ${r} not written: it resolves outside this repository (${t}) \u2014 Vesper does not write shared hooks.`:e.defaultDir?`Git hooks not installed: git's hooks directory "${t}" resolves outside this repository (a symlink) \u2014 Vesper does not write shared hooks.`:`Git hooks not installed: core.hooksPath points outside this repository ("${t}") \u2014 Vesper does not write shared hooks.`;case"unverifiable":return`Git hooks not installed: this git cannot report where core.hooksPath ("${t}") is set \u2014 Vesper does not write hooks it cannot scope.`;case"husky-v9":return"Git hooks not installed: husky v9 manages .husky/_ \u2014 to keep Vesper's bootstrap on checkout, add `vespercli guard` to .husky/post-checkout.";case"dangling-symlink":return`Git hook ${r} left untouched: ${t||r} is a symlink whose target does not exist.`;case"write-refused":return`Git hook ${r} not written: its real location (${t||r}) is a user-level path Vesper never writes.`;case"opted-out":return"Git hooks not installed: disabled for this repository (git config vesper.hooks false).";case"tracked-by-git":return`Git hooks not installed: ${t} is committed to this repository (team-managed hooks) \u2014 Vesper does not edit tracked hooks; add \`vespercli guard\` to its post-checkout yourself.`;case"foreign-hook-language":return e.interpreter==="binary"?`Git hook ${r} is a compiled executable \u2014 Vesper did not modify it (appending would break it). ${s}`:`Git hook ${r} is a ${e.interpreter} script \u2014 Vesper did not modify it. ${s}`;case"foreign-hook-exits":return r==="pre-commit"?`Git hook ${r} ends its run early (\`${e.line}\`) \u2014 Vesper did not modify it, because its block would never run. To keep it, ${n}`:`Git hook ${r} ends its run early (\`${e.line}\`) \u2014 Vesper did not modify it, because its block would never run. Add \`vespercli guard >/dev/null 2>&1 || true\` before that line yourself.`;case"foreign-hook-repaired":return`Git hook ${r} is a ${e.interpreter} ${e.interpreter==="binary"?"executable":"script"}: Vesper's block, added by an earlier version, was removed from it (it broke the hook). ${r==="pre-commit"?`To keep it, ${n}`:"Add `vespercli guard` yourself."}`;default:return`Git hooks not installed (${e.reason}).`}}function Vn(e){let t=[];for(let r of rt){let n=e?.[r];if(!n)continue;let s=Zl({...n,hook:n.hook??r});s&&!t.includes(s)&&t.push(s)}return t}function ua(e){return rt.every(t=>e?.[t]&&!e[t].reason)}async function Gn(e){let t={};if(await G(["config","--type=bool","--get","vesper.hooks"],{cwd:e})==="false"){for(let s of rt)t[s]={installed:!1,updated:!1,hooksDir:null,reason:"opted-out"};return t}let r=await Wr(e),n=!!r.dir&&!r.default&&await Lr(await At(r.dir),r,{dir:!0});for(let s of rt)t[s]=await Ql(e,s,{resolved:r,dirTracked:n});return t}async function Hn(e){if(await G(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{created:!1,updated:!1,skipped:"not-a-repo"};let t=M(e,".gitattributes"),r=[Gl,...gg,Hl].join(`
32
- `),n=new RegExp(`${Gl}[\\s\\S]*?${Hl}`),s="";try{s=await He(t,"utf-8")}catch(i){if(i.code!=="ENOENT")throw i;return await C(t,`${r}
33
- `,"utf-8"),{created:!0,updated:!1}}if(n.test(s)){let i=s.replace(n,r);return i!==s?(await C(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=s.endsWith(`
30
+ `;return await vt(h.path,Buffer.from(`${k}${C}${d}
31
+ `,"latin1")),{installed:!1,updated:!0,hooksDir:o}}function Ru(e){if(!e||!e.reason||e.reason==="not-a-repo")return null;let t=e.configured??"",r=e.hook??"hook",n=r==="pre-commit"?`copy the block from ${M(O,"hooks","pre-commit")} into it yourself.`:"Add a call to `vespercli guard` to it yourself.",s=`${n[0].toUpperCase()}${n.slice(1)}`;switch(e.reason){case"not-a-directory":return e.defaultDir?`Git hooks not installed: git's hooks directory "${t}" is not a directory.`:`Git hooks not installed: core.hooksPath is "${t}", which is not a directory (hooks disabled for this repository).`;case"machine-wide":return`Git hooks not installed: core.hooksPath is set machine-wide (${e.scope}) \u2014 Vesper does not write shared hooks.`;case"outside-repository":return e.hooksDir?`Git hook ${r} not written: it resolves outside this repository (${t}) \u2014 Vesper does not write shared hooks.`:e.defaultDir?`Git hooks not installed: git's hooks directory "${t}" resolves outside this repository (a symlink) \u2014 Vesper does not write shared hooks.`:`Git hooks not installed: core.hooksPath points outside this repository ("${t}") \u2014 Vesper does not write shared hooks.`;case"unverifiable":return`Git hooks not installed: this git cannot report where core.hooksPath ("${t}") is set \u2014 Vesper does not write hooks it cannot scope.`;case"husky-v9":return"Git hooks not installed: husky v9 manages .husky/_ \u2014 to keep Vesper's bootstrap on checkout, add `vespercli guard` to .husky/post-checkout.";case"dangling-symlink":return`Git hook ${r} left untouched: ${t||r} is a symlink whose target does not exist.`;case"write-refused":return`Git hook ${r} not written: its real location (${t||r}) is a user-level path Vesper never writes.`;case"opted-out":return"Git hooks not installed: disabled for this repository (git config vesper.hooks false).";case"tracked-by-git":return`Git hooks not installed: ${t} is committed to this repository (team-managed hooks) \u2014 Vesper does not edit tracked hooks; add \`vespercli guard\` to its post-checkout yourself.`;case"foreign-hook-language":return e.interpreter==="binary"?`Git hook ${r} is a compiled executable \u2014 Vesper did not modify it (appending would break it). ${s}`:`Git hook ${r} is a ${e.interpreter} script \u2014 Vesper did not modify it. ${s}`;case"foreign-hook-exits":return r==="pre-commit"?`Git hook ${r} ends its run early (\`${e.line}\`) \u2014 Vesper did not modify it, because its block would never run. To keep it, ${n}`:`Git hook ${r} ends its run early (\`${e.line}\`) \u2014 Vesper did not modify it, because its block would never run. Add \`vespercli guard >/dev/null 2>&1 || true\` before that line yourself.`;case"foreign-hook-repaired":return`Git hook ${r} is a ${e.interpreter} ${e.interpreter==="binary"?"executable":"script"}: Vesper's block, added by an earlier version, was removed from it (it broke the hook). ${r==="pre-commit"?`To keep it, ${n}`:"Add `vespercli guard` yourself."}`;default:return`Git hooks not installed (${e.reason}).`}}function es(e){let t=[];for(let r of ct){let n=e?.[r];if(!n)continue;let s=Ru({...n,hook:n.hook??r});s&&!t.includes(s)&&t.push(s)}return t}function Na(e){return ct.every(t=>e?.[t]&&!e[t].reason)}async function ts(e){let t={};if(await D(["config","--type=bool","--get","vesper.hooks"],{cwd:e})==="false"){for(let s of ct)t[s]={installed:!1,updated:!1,hooksDir:null,reason:"opted-out"};return t}let r=await nr(e),n=!!r.dir&&!r.default&&await tr(await at(r.dir),r,{dir:!0});for(let s of ct)t[s]=await ju(e,s,{resolved:r,dirTracked:n});return t}async function rs(e){if(await D(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{created:!1,updated:!1,skipped:"not-a-repo"};let t=M(e,".gitattributes"),r=[Eu,...uy,bu].join(`
32
+ `),n=new RegExp(`${Eu}[\\s\\S]*?${bu}`),s="";try{s=await Ke(t,"utf-8")}catch(i){if(i.code!=="ENOENT")throw i;return await A(t,`${r}
33
+ `,"utf-8"),{created:!0,updated:!1}}if(n.test(s)){let i=s.replace(n,r);return i!==s?(await A(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=s.endsWith(`
34
34
  `)?`
35
35
  `:`
36
36
 
37
- `;return await C(t,`${s}${o}${r}
38
- `,"utf-8"),{created:!1,updated:!0}}async function Un(e){if(await G(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{configured:!1};let n=`node "${M(O,"hooks","merge-memory-jsonl.js")}" %O %A %B`;return await G(["config","merge.vesper-memory.name","Vesper memory.jsonl entity-aware merge"],{cwd:e}),{configured:await G(["config","merge.vesper-memory.driver",n],{cwd:e})!==null}}function Je(e){return M(e,".vscode","mcp.json")}function Ue(){return M(kn,"src","mcp","vesper-indexing","dist","index.js")}async function Ye(e){let t=Je(e);try{let r=await He(t,"utf-8");return $t(r)}catch(r){if(r.code==="ENOENT")return{servers:{}};if(r instanceof SyntaxError)return{servers:{}};throw r}}async function da(e,t){let r=Je(e),n=pt(r);await T(n,{recursive:!0}),await C(r,JSON.stringify(t,null," "),"utf-8")}async function ur(e,t=!0,{record:r=!0}={}){let n=await Ye(e),s=Wt(Ue()),o=[];if(n.servers||(n.servers={}),t?(n.servers["vesper-indexing"]={type:"stdio",command:"node",args:[s],env:{VESPER_INDEX_ROOT:"${workspaceFolder}"}},o.push("vesper-indexing"),n.servers["sequential-thinking"]={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},o.push("sequential-thinking"),n.servers.memory={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:"${workspaceFolder}/.vesper/memory.jsonl"}},o.push("memory")):(delete n.servers["vesper-indexing"],delete n.servers["sequential-thinking"],delete n.servers.memory),await da(e,n),r&&t&&o.length>0){let i=await x(e);i.mcp=i.mcp||{},i.mcp.servers=[...new Set([...Array.isArray(i.mcp.servers)?i.mcp.servers:[],...o])],i.mcp.updatedAt=new Date().toISOString(),await I(e,i)}return{configured:t,mcpPath:Je(e),servers:o}}async function mo(e){return!!(await Ye(e)).servers?.["vesper-indexing"]}async function go(e){let t=await z(e),r=await J(e);r[Mr]=!1,r[V]||(r[V]={});for(let n of je)r[V][n]=!0;return await oe(e,r),{configured:je.length,workspaceType:t.type}}async function eu(e,t){let r=Zs[t];if(!r||r.length===0)return{added:[],agentName:t};let n=await J(e),s=await z(e),o=await x(e,s);n[V]||(n[V]={});let i=[];for(let a of r)n[V][a]||(n[V][a]=!0,i.push(a));return i.length>0&&(await oe(e,n),o.mcp=o.mcp||{},o.mcp.agentTools=o.mcp.agentTools||{},o.mcp.agentTools[t]=r,o.mcp.updatedAt=new Date().toISOString(),await I(e,o)),{added:i,agentName:t}}async function Kr(e,t){let r=we[t];if(!r)return{added:!1,serverName:t,tools:[],error:`Unknown MCP server: ${t}`};let n=await Ye(e),s=await J(e),o=await z(e),i=await x(e,o);if(n.servers||(n.servers={}),n.servers[t])return{added:!1,serverName:t,tools:[],error:"Already configured"};let a=JSON.parse(JSON.stringify(r.config));if(t==="vesper-indexing"){let l=Wt(Ue());a.args&&(a.args=a.args.map(d=>d==="${VESPER_INDEXING_PATH}"?l:d))}n.servers[t]=a,await da(e,n),s[V]||(s[V]={});let c=[];for(let l of r.tools||[])s[V][l]||(s[V][l]=!0,c.push(l));return s[Mr]=!1,await oe(e,s),i.mcp=i.mcp||{},i.mcp.servers=i.mcp.servers||[],i.mcp.servers.includes(t)||i.mcp.servers.push(t),i.mcp.updatedAt=new Date().toISOString(),await I(e,i),{added:!0,serverName:t,tools:c}}async function yo(e,t){let r=we[t],n=await Ye(e),s=await J(e),o=await z(e),i=await x(e,o),a=!1;n.servers&&n.servers[t]&&(delete n.servers[t],await da(e,n),a=!0);let c=[];if(r&&s[V]){for(let l of r.tools||[])s[V][l]&&(delete s[V][l],c.push(l));c.length>0&&await oe(e,s)}return i.mcp?.servers&&(i.mcp.servers=i.mcp.servers.filter(l=>l!==t),i.mcp.updatedAt=new Date().toISOString(),await I(e,i)),{removed:a,serverName:t,tools:c}}function tu(){return Object.entries(we).map(([e,t])=>({name:e,description:t.description,tools:t.tools?.length||0}))}async function ru(e){let t=await Ye(e);return Object.keys(t.servers||{})}var ra,Ge,_t,Us,Mr,V,Ws,Ks,Bs,zs,Js,Ys,qs,ne,Ie,Ct,fe,na,On,oa,ia,ig,Ml,Dl,Xs,Nn,Tn,je,Zs,we,Wl,pe,Fl,lg,dg,pg,Pn,Gs,Hs,Ur,Vs,rt,Gl,Hl,gg,yg,H=ee(()=>{wn();U();Te();Ee();ct();ye();wn();ra=1e4;Ge={agents:"chat.agentFilesLocations",instructions:"chat.instructionsFilesLocations",prompts:"chat.promptFilesLocations",skills:"chat.agentSkillsLocations"},_t="chat.tools.terminal.autoApprove",Us="chat.tools.terminal.enableAutoApprove",Mr="chat.tools.autoApprove",V="chat.tools.eligibleForAutoApproval",Ws="chat.agent.maxRequests",Ks="chat.includeReferencedInstructions",Bs="chat.customAgentInSubagent.enabled",zs="chat.agent.enabled",Js="github.copilot.chat.omitBaseAgentInstructions",Ys="chat.mcp.discovery.enabled",qs="chat.mcp.autoStart",ne="github.copilot.chat.additionalReadAccessPaths",Ie={maxRequests:300,terminalEnableAutoApprove:!0,omitBaseAgentInstructions:!0,enableMcpServer:!0},Ct=[Ws,Ks,Bs,zs,Js,Ys,qs,Us,_t,Mr,V],fe=["vesper-indexing","sequential-thinking","memory"],na=Object.freeze([Object.freeze({path:".vesperrc"}),Object.freeze({path:".vesperrc.*.tmp"}),Object.freeze({path:".vesperrc.corrupt-*"}),Object.freeze({path:".mcp.json"}),Object.freeze({path:".vscode/mcp.json"}),Object.freeze({path:".vesper/index.db"}),Object.freeze({path:".vesper/index.db-wal"}),Object.freeze({path:".vesper/index.db-shm"}),Object.freeze({path:".vesper/indexing-status.json"}),Object.freeze({path:".claude/settings.local.json"}),Object.freeze({path:".vesper/.host-switch-journal.json"}),Object.freeze({path:".vesper/.host-switch-journal.json.*.tmp"}),Object.freeze({path:".vesper/.migration-backup/"})]),On=na.map(e=>e.path);oa=[".claude/skills",".claude/rules",".claude/agents",".claude/commands",".claude/CLAUDE.md",".claude/settings.json",".copilot/agents",".copilot/skills",".copilot/instructions"],ia=[".claude/plugins",".vesperrc"];ig=[".claude/vesper/context",".claude/agents",".claude/commands",".claude/skills",".claude/rules",".vesper/skills",".vesper/instructions",".vesper/agents",".vesper/context",".vesper/.tracking",".vesper/memory.jsonl",".vesper/gates.json","CLAUDE.md","opencode.json",".opencode"],Ml="# <!-- vesper:gitignore:start -->",Dl="# <!-- vesper:gitignore:end -->";Xs="Vesper: worktree bootstrap",Nn=Object.freeze({taskLabel:"Vesper: host guard",hookCommandMarker:"vespercli guard --running-host"});Tn=["react-scripts","**/node_modules/.bin/react-scripts","next","**/node_modules/.bin/next","vite","**/node_modules/.bin/vite","webpack","**/node_modules/.bin/webpack","turbo","**/node_modules/.bin/turbo","tsc","**/node_modules/.bin/tsc","tsup","**/node_modules/.bin/tsup","esbuild","**/node_modules/.bin/esbuild","rollup","**/node_modules/.bin/rollup","parcel","**/node_modules/.bin/parcel","jest","**/node_modules/.bin/jest","vitest","**/node_modules/.bin/vitest","npx vitest","pnpm vitest","pnpm vitest run","pnpm exec vitest","pnpm dlx vitest","mocha","**/node_modules/.bin/mocha","playwright","**/node_modules/.bin/playwright","npx playwright open","npx playwright test","npx playwright show-report","npx playwright codegen","open playwright","open playwright-report/index.html",'ps aux | grep "playwright test" | grep -v grep | wc -l',"cypress","**/node_modules/.bin/cypress","pytest","npx","pnpm dlx","pnpm exec","yarn dlx","npm test","npm run","npm start","npm run test","npm run build","npm run dev","npm run lint","pnpm test","pnpm run","pnpm start","pnpm tsc","yarn test","yarn run","yarn start","eslint","**/node_modules/.bin/eslint","pnpm eslint","prettier","**/node_modules/.bin/prettier","biome","**/node_modules/.bin/biome","stylelint","**/node_modules/.bin/stylelint","mkdir","touch","cat","ls","head","tail","wc","grep","find","tree","file","stat","realpath","basename","dirname","awk","sed","cut","sort","uniq","tr","xargs","column","paste","join","comm","diff","cmp","git status","git log","git diff","git branch","git show","git remote","git tag","git rev-parse","git describe","git ls-files","git ls-tree","git blame","git shortlog","pushd","popd","dirs","echo","pwd","which","type","env","printenv","date","hostname","whoami","uname","lsof","pkill","node --version","npm --version","pnpm --version","yarn --version","python --version","python3 --version","curl -I *","curl --head *","curl -sI *","curl -s http://localhost:*","curl -s http://127.0.0.1:*","curl -sf http://localhost:*","curl -sf http://127.0.0.1:*","curl --fail http://localhost:*","curl --fail http://127.0.0.1:*","tsx","**/node_modules/.bin/tsx","npx tsx","/^(\\w+=\\S+\\s+)+(npx|node|tsx|npm|pnpm|yarn)\\b/","vespercli","vespercli init","vespercli add","vespercli list","vespercli ls","vespercli reset","vespercli catalog","**/node_modules/.bin/vespercli","mcp: vesper-indexing: vesper_search","mcp: vesper-indexing: vesper_symbols","mcp: vesper-indexing: vesper_status","mcp: vesper-indexing: vesper_reindex","python3 << 'PYEOF'",'python3 << "PYEOF"',"python3 << 'EOF'",'python3 << "EOF"',"python3 << 'END'","python << 'PYEOF'",'python << "PYEOF"',"python << 'EOF'","cat << 'EOF'",'cat << "EOF"',"cat << 'END'","bash << 'EOF'","sh << 'EOF'","cat << 'RESEARCH_EOF'",'cat << "RESEARCH_EOF"',"RESEARCH_EOF","tee","node -e","python3 -c","python -c"],je=["vesper_search","vesper_symbols","vesper_status","vesper_reindex","resolve-library-id","get-library-docs","query-docs","sequentialthinking","create_entities","create_relations","add_observations","delete_entities","delete_observations","delete_relations","read_graph","search_nodes","open_nodes"],Zs={"clickup-agent":["clickup_add_tag_to_task","clickup_add_time_entry","clickup_attach_task_file","clickup_create_document","clickup_create_document_page","clickup_create_folder","clickup_create_list","clickup_create_list_in_folder","clickup_create_task","clickup_create_task_comment","clickup_find_member_by_name","clickup_get_chat_channels","clickup_get_current_time_entry","clickup_get_document_pages","clickup_get_folder","clickup_get_list","clickup_get_task","clickup_get_task_comments","clickup_get_task_time_entries","clickup_get_workspace_hierarchy","clickup_get_workspace_members","clickup_list_document_pages","clickup_remove_tag_from_task","clickup_resolve_assignees","clickup_search","clickup_send_chat_message","clickup_start_time_tracking","clickup_stop_time_tracking","clickup_update_document_page","clickup_update_folder","clickup_update_list","clickup_update_task"]},we={"vesper-indexing":{description:"Fast code search with semantic indexing",config:{type:"stdio",command:"node",args:["${VESPER_INDEXING_PATH}"],env:{VESPER_INDEX_ROOT:"${workspaceFolder}"}},tools:["vesper_search","vesper_symbols","vesper_status","vesper_reindex"]},context7:{description:"Documentation lookup for libraries",config:{type:"stdio",command:"npx",args:["-y","@upstash/context7-mcp"]},tools:["resolve-library-id","get-library-docs","query-docs"]},"sequential-thinking":{description:"Step-by-step reasoning for complex problems",config:{type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},tools:["sequentialthinking"]},clickup:{description:"ClickUp project management integration",config:{type:"stdio",command:"npx",args:["-y","@anthropics/mcp-clickup"],env:{CLICKUP_API_KEY:"${env:CLICKUP_API_KEY}",CLICKUP_TEAM_ID:"${env:CLICKUP_TEAM_ID}"}},tools:["clickup_add_tag_to_task","clickup_add_time_entry","clickup_attach_task_file","clickup_create_document","clickup_create_document_page","clickup_create_folder","clickup_create_list","clickup_create_list_in_folder","clickup_create_task","clickup_create_task_comment","clickup_find_member_by_name","clickup_get_chat_channels","clickup_get_current_time_entry","clickup_get_document_pages","clickup_get_folder","clickup_get_list","clickup_get_task","clickup_get_task_comments","clickup_get_task_time_entries","clickup_get_workspace_hierarchy","clickup_get_workspace_members","clickup_list_document_pages","clickup_remove_tag_from_task","clickup_resolve_assignees","clickup_search","clickup_send_chat_message","clickup_start_time_tracking","clickup_stop_time_tracking","clickup_update_document_page","clickup_update_folder","clickup_update_list","clickup_update_task"]},memory:{description:"Persistent knowledge graph memory for AI agents",config:{type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:"${workspaceFolder}/.vesper/memory.jsonl"}},tools:["create_entities","create_relations","add_observations","delete_entities","delete_observations","delete_relations","read_graph","search_nodes","open_nodes"]}},Wl=je,pe={FOLDER:"folder",WORKSPACE_FILE:"workspace"};Fl=new Set;lg=new Set([_t,Mr,V]);dg=St,pg=["agents","prompts","skills"],Pn=M(O,"copilot","instructions"),Gs=M(O,"copilot","instructions-extended");Hs=M(St,"packs");Ur=Object.freeze(["-c","core.fsmonitor=false","-c","core.untrackedCache=false"]),Vs=null;rt=["pre-commit","post-checkout"];Gl="# <!-- vesper:gitattributes:start -->",Hl="# <!-- vesper:gitattributes:end -->",gg=[".vesper/memory.jsonl merge=vesper-memory",".claude/vesper/context/recent-decisions.md merge=union",".vesper/context/recent-decisions.md merge=union"];yg={VSCODE_SETTINGS_MAP:Ge,WORKSPACE_TYPES:pe,TERMINAL_AUTO_APPROVAL_SETTING:_t,TERMINAL_ENABLE_AUTO_APPROVAL_SETTING:Us,TOOLS_AUTO_APPROVE_SETTING:Mr,TOOLS_ELIGIBLE_FOR_AUTO_APPROVAL_SETTING:V,AGENT_MAX_REQUESTS_SETTING:Ws,INCLUDE_REFERENCED_INSTRUCTIONS_SETTING:Ks,CUSTOM_AGENT_IN_SUBAGENT_SETTING:Bs,CHAT_AGENT_ENABLED_SETTING:zs,OMIT_BASE_AGENT_INSTRUCTIONS_SETTING:Js,MCP_DISCOVERY_ENABLED_SETTING:Ys,MCP_AUTO_START_SETTING:qs,ADDITIONAL_READ_ACCESS_PATHS_SETTING:ne,SAFE_AUTO_APPROVAL_COMMANDS:Tn,MCP_TOOLS_CORE:je,MCP_TOOLS_BY_AGENT:Zs,MCP_SERVERS:we,MCP_TOOLS_AUTO_APPROVAL:Wl,INIT_DEFAULTS:Ie,VESPER_MANAGED_SETTINGS:Ct,VESPER_MANAGED_MCP_SERVERS:fe,findWorkspaceFile:aa,getWorkspaceConfig:z,getSettingsPath:Kl,getTrackingPath:Fr,getTrackingPathAsync:ft,readVSCodeSettings:J,writeVSCodeSettings:oe,readTracking:x,writeTracking:I,removeLegacyTracking:zl,addToSettings:Vr,removeFromSettings:Fn,getCoreAssetEntries:no,pruneLegacySettingsEntries:Gr,listExtendedInstructions:to,getExtendedInstructionEntry:ro,getTrackedPaths:ht,configureTerminalAutoApproval:oo,configureChatSettings:io,getAutoApprovalCommands:ql,addReadAccessPath:ao,removeReadAccessPath:co,getReadAccessPaths:lo,getMcpConfigPath:Je,getVesperIndexingPath:Ue,readMcpConfig:Ye,configureMcpServer:ur,isMcpServerConfigured:mo,configureMcpToolsAutoApproval:go,addAgentToolsToAutoApproval:eu,addMcpServer:Kr,removeMcpServer:yo,listMcpServers:tu,getConfiguredMcpServers:ru,getWorkspaceFolders:ca,findNestedVesperrc:Dn,migrateVesperrcToWorkspaceLevel:eo,ensureCoreSettings:uo}});import{access as wg,constants as vg,stat as Nb,lstat as kg,readdir as Sg,readFile as Eg,readlink as bg,rename as xg,writeFile as _g,mkdir as Ag,cp as Cg,appendFile as nu}from"node:fs/promises";import{createHash as $g}from"node:crypto";import{isAbsolute as Og,join as Tg,relative as Pg,resolve as wo,sep as Ig}from"node:path";function ha(e){fa=e?{root:wo(e.root),log:e.log,exclude:e.exclude||(()=>!1)}:null}async function su(e,t,r){let n=await kg(e);if(n.isSymbolicLink())r.push([t,`link:${await bg(e)}`]);else if(n.isDirectory())for(let s of await Sg(e))await su(Tg(e,s),`${t}/${s}`,r);else n.isFile()&&r.push([t,$g("sha256").update(await Eg(e)).digest("hex")])}function ou(e,t){let r=wo(t),n=Pg(e.root,r);if(!n||n.startsWith("..")||Og(n))return null;let s=n.split(Ig).join("/");return e.exclude(s)?null:s}async function ma(e){let t=fa;if(t)try{let r=ou(t,e);r&&await nu(t.log,`${JSON.stringify([r,Wn])}
39
- `,"utf-8")}catch{}}async function ga(e){let t=fa;if(t)try{let r=wo(e),n=ou(t,e);if(!n)return;let s=[];await su(r,n,s);let o=s.filter(([i])=>!t.exclude(i)).map(i=>`${JSON.stringify(i)}
40
- `).join("");o&&await nu(t.log,o,"utf-8")}catch{}}async function w(e){try{return await wg(e,vg.F_OK),!0}catch{return!1}}function ya(e){let t=wo(e);if(lr(t)||lr(e))throw new Error(`Refusing to write a user-level path (Vesper is project-scoped, D7): ${e}. Only the project workspace and the permitted plugin cache (~/.claude/plugins) may be written.`)}async function C(e,t,r){ya(e),await ma(e);let n=await _g(e,t,r);return await ga(e),n}async function T(e,t){return ya(e),Ag(e,t)}async function Kn(e,t,r){ya(t),await ma(t);let n=await Cg(e,t,r);return await ga(t),n}async function jg(e,t){await ma(t);let r=await xg(e,t);return await ga(t),r}async function dr(e,t,{mode:r,encoding:n="utf-8",tempName:s,sweepPattern:o,sweep:i=!0}={}){let{dirname:a,basename:c,join:l}=await import("node:path"),d=await import("node:fs/promises"),p=a(e);if(i){let m=c(e).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),f=o??new RegExp(`^${m}\\.\\d+\\.tmp$`),g=[];try{g=await d.readdir(p)}catch{g=[]}for(let y of g){if(!f.test(y))continue;let k=l(p,y);try{Date.now()-(await d.stat(k)).mtimeMs>Rg&&await d.unlink(k)}catch{}}}let h=s?s(e):`${e}.${process.pid}.tmp`;try{await C(h,t,r===void 0?n:{encoding:n,mode:r}),r!==void 0&&await d.chmod(h,r).catch(()=>{}),await jg(h,e)}catch(m){throw await d.unlink(h).catch(()=>{}),m}}var fa,Wn,Rg,U=ee(()=>{H();fa=null;Wn="intent";Rg=5*60*1e3});import{existsSync as iu,readdirSync as Ng}from"node:fs";import{readdir as au,readFile as cu}from"node:fs/promises";import{join as Bt}from"node:path";function uu(e=O){try{return Ng(Bt(e,"claude","packs"),{withFileTypes:!0}).filter(t=>t.isDirectory()&&!t.name.startsWith(".")).map(t=>t.name).sort()}catch{return[]}}function fr(e,t=O){if(typeof e!="string"||!e||/[\\/]|\.\./.test(e))return null;for(let r of uu(t)){let n=Bt(t,"claude","packs",r,"skills",e);if(iu(Bt(n,wa)))return{pack:r,dir:n}}return null}async function vo(e){let t={},r=async n=>{let s=await au(Bt(e,n),{withFileTypes:!0});for(let o of s.sort((i,a)=>i.name.localeCompare(a.name))){let i=n?`${n}/${o.name}`:o.name;o.isDirectory()?await r(i):o.isFile()&&i!==wa&&(t[i]=await cu(Bt(e,i)))}};return await r(""),t}async function du(e=O){let t=[];for(let r of uu(e)){let n=[];try{n=(await au(Bt(e,"claude","packs",r,"skills"),{withFileTypes:!0})).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>s.name).sort()}catch{n=[]}for(let s of n){let o=Bt(e,"claude","packs",r,"skills",s),i=Bt(o,wa);if(!iu(i))continue;let a=null;try{let c=JSON.parse(await cu(i,"utf-8"));a=c&&typeof c=="object"&&!Array.isArray(c)?c:null}catch{a=null}t.push({pack:r,skill:s,dir:o,record:a})}}return t}var wa,pr,lu,hr=ee(()=>{Ee();wa="UPSTREAM.json",pr=Object.freeze(["gitlab-ci-skill","github-actions-to-gitlab-ci","i-have-adhd","ponytail"]),lu="styles"});import{lstat as hu,readdir as mu,readFile as ko,rm as gu,rmdir as pu}from"node:fs/promises";import{basename as yu,join as We,relative as Lg,sep as Mg}from"node:path";import{existsSync as va}from"node:fs";import{createHash as wu}from"node:crypto";async function nt(e){let t=[],r=[],n=[],s=async o=>{let i=await mu(o,{withFileTypes:!0});for(let a of i){let c=We(o,a.name),l=Lg(e,c).split(Mg).join("/");a.isSymbolicLink()?r.push(l):a.isDirectory()?(await s(c),n.push(l)):a.isFile()?t.push(l):r.push(l)}};return await s(e),t.sort(),r.sort(),n.sort((o,i)=>i.split("/").length-o.split("/").length||i.localeCompare(o)),{files:t,others:r,dirs:n}}function Dg(e){return`sha256:${wu("sha256").update(e).digest("hex")}`}function st(e){let t=e.toString("utf-8").replace(/\r\n/g,`
41
- `);return`sha256:${wu("sha256").update(t,"utf8").digest("hex")}`}function fu(e){if(!e.includes(13))return e;let t=Buffer.allocUnsafe(e.length),r=0;for(let n=0;n<e.length;n+=1)e[n]===13&&e[n+1]===10||(t[r]=e[n],r+=1);return t.subarray(0,r)}function me(e,t){let r=Buffer.isBuffer(e)?e:Buffer.from(String(e),"utf-8"),n=Buffer.isBuffer(t)?t:Buffer.from(String(t),"utf-8");return fu(r).equals(fu(n))}async function Fg({sourceDir:e,sourceFiles:t,sourceHashes:r,sourceLfHashes:n}={}){let s=new Map,o=(i,a)=>{let c=s.get(i);s.set(i,c?async l=>await c(l)||a(l):a)};if(r)for(let[i,a]of Object.entries(r))typeof a=="string"&&a&&o(i,async c=>Dg(c)===a);if(t)for(let[i,a]of Object.entries(t)){let c=Buffer.isBuffer(a)?a:Buffer.from(a,"utf-8");o(i,async l=>me(l,c))}if(e&&va(e)){let{files:i}=await nt(e);for(let a of i)o(a,async c=>me(c,await ko(We(e,a))))}if(n)for(let[i,a]of Object.entries(n)){let c=new Set((Array.isArray(a)?a:[a]).filter(l=>typeof l=="string"&&l));c.size&&o(i,async l=>c.has(st(l)))}return s}async function Ot(e,{sourceDir:t,sourceFiles:r,sourceHashes:n,sourceLfHashes:s,sourceMatch:o,anchor:i="SKILL.md"}={}){let a;try{a=await hu(e)}catch{return{status:"absent",proven:[],kept:[],dirs:[]}}if(!a.isDirectory())return{status:"not-directory",proven:[],kept:[yu(e)],dirs:[]};let c=await Fg({sourceDir:t,sourceFiles:r,sourceHashes:n,sourceLfHashes:s}),{files:l,others:d,dirs:p}=await nt(e),h=[],m=[...d];for(let f of l){let y=c.get(f)||(o?async k=>!!await o(f,k):null);if(!y){m.push(f);continue}try{await y(await ko(We(e,f)))?h.push(f):m.push(f)}catch{m.push(f)}}return m.sort(),i&&(c.has(i)||o&&l.includes(i))&&!h.includes(i)?{status:"anchor-unproven",proven:[],kept:[...l,...d].sort(),dirs:p}:{status:"classified",proven:h,kept:m,dirs:p}}async function Bn(e,t={}){let r=await Ot(e,t);if(r.status==="absent")return{status:"absent",removed:[],kept:[]};if(r.status!=="classified")return{status:"kept",removed:[],kept:r.kept};for(let o of r.proven)await gu(We(e,o),{force:!0});for(let o of r.dirs)try{await pu(We(e,o))}catch{}let n=!1;try{await pu(e),n=!0}catch{}let s="kept";return n?s="removed":r.proven.length>0&&(s="partial"),{status:s,removed:r.proven,kept:r.kept}}async function Vg(e){let t=yu(String(e?.path||""));if(!t||t==="."||t==="..")return null;if(e.category==="vendored-body"){let r=e.placedFiles??e.syncedFiles,n=r&&typeof r=="object"&&Object.keys(r).length?{...r}:null,s=fr(t);return s?{sourceFiles:await vo(s.dir),...n?{sourceHashes:n}:{}}:n?{sourceHashes:n}:null}if(e.category==="catalog-skill"||e.category==="added-asset"){let r;for(let s of["claude-committed","claude"]){let o=We(O,s,"skills",t);if(va(o)){r=o;break}}if(!r){let s=[];try{s=(await mu(We(O,"claude","packs"),{withFileTypes:!0})).filter(o=>o.isDirectory()&&!o.name.startsWith(".")).map(o=>o.name).sort()}catch{s=[]}for(let o of s){let i=We(O,"claude","packs",o,"skills",t);if(va(i)){r=i;break}}}let n=e.fileHashes&&typeof e.fileHashes=="object"&&Object.keys(e.fileHashes).length?{...e.fileHashes}:null;if(r||n)return{...r?{sourceDir:r}:{},...n?{sourceLfHashes:n}:{}}}return null}async function Gg(e){let t=String(e?.path||""),r=[];t===".claude/rules/vesper-orchestrator.md"&&r.push(We(O,"claude","vesper-orchestrator.md"));let n=/^\.claude\/agents\/([^/]+\.md)$/.exec(t);n&&r.push(We(O,"claude-committed","agents",n[1]),We(O,"claude","agents",n[1])),n=/^\.claude\/commands\/([^/]+\.md)$/.exec(t),n&&r.push(We(O,"claude","commands",n[1])),t===".opencode/plugins/vesper.js"&&r.push(We(O,"opencode","vesper-plugin.js"));let s=[];for(let o of r)try{s.push(await ko(o))}catch{}return s}async function zn(e,t,{expected:r=[]}={}){let n;try{n=await ko(e)}catch{return!1}return typeof t?.hash=="string"&&t.hash&&st(n)===t.hash?!0:[...r.map(o=>Buffer.isBuffer(o)?o:Buffer.from(String(o),"utf-8")),...await Gg(t)].some(o=>me(n,o))}async function ie(e,t,{expected:r=[],purgeProjectAuthored:n=!1}={}){let s;try{s=await hu(e)}catch{return"absent"}if(s.isFile())return!(n===!0&&t?.category==="per-project-authored")&&!await zn(e,t,{expected:r})?"kept":(await gu(e,{force:!0}),"removed");if(!s.isDirectory())return"kept";let o=await Vg(t);return o?(await Bn(e,o)).status:"kept"}var qe=ee(()=>{Ee();hr()});import{access as Hg,constants as Ug,readFile as ku,readdir as Wg}from"node:fs/promises";import{execFile as Kg}from"node:child_process";import{join as So}from"node:path";async function Bg(e){try{return await Hg(e,Ug.F_OK),!0}catch{return!1}}async function Tt(e){try{let t=JSON.parse(await ku(So(e,zt),"utf-8"));if(t&&typeof t=="object"&&t.snapshot&&Jn.includes(t.from))return t}catch{}return null}async function ka(e){return await Bg(So(e,zt))?await Tt(e)===null:!1}async function zg(e){let t;try{t=[await ft(e),So(e,".vesperrc")]}catch{t=[So(e,".vesperrc")]}let r=new Set;for(let n of t)if(!r.has(n)){r.add(n);try{return JSON.parse(await ku(n,"utf-8"))}catch(s){if(s&&s.code==="ENOENT")continue;return null}}return null}function Su(e,t,{env:r,gitArgs:n=[]}={}){return new Promise(s=>{let o;try{o=Kg("git",[...n,...t],{cwd:e,timeout:5e3,maxBuffer:16*1024*1024,encoding:"utf-8",env:{...r??process.env,...xt}},(i,a,c)=>{let l=i&&typeof i.code=="string"?i:null;s({ok:!i,stdout:String(a??""),stderr:String(c??""),spawnError:l})}),o.stdin?.end()}catch(i){s({ok:!1,stdout:"",stderr:"",spawnError:i})}})}async function Jg(e,t={}){let r=await Su(e,["rev-parse","--is-inside-work-tree"],t);return r.ok&&r.stdout.trim()==="true"?{state:"repo"}:/dubious ownership/i.test(r.stderr)?{state:"error",gitError:"dubious-ownership"}:/not a git repository/i.test(r.stderr)?{state:"no-repo"}:r.spawnError?.code==="ENOENT"?{state:"no-repo"}:{state:"error",gitError:"unknown"}}async function Yg(e,t){if(!t?.host)return!1;try{let{host:r,matched:n}=await Al(e);if(r!==t.host||n.length===0)return!1;for(let{entry:s,path:o}of n)if(!await Ki(e,s,o))return!1;return!0}catch{return!1}}async function qg(e){try{return(await Wg(e,{withFileTypes:!0})).filter(t=>t.isFile()&&t.name.endsWith(".code-workspace")).map(t=>t.name).sort()}catch{return[]}}function Xg(e){let t=[];for(let r of Jn)for(let n of e[r]||[])t.push(lt(n));return[...new Set(t)]}async function vu(e,t,r,n){let s=[],o=null;for(let i of Jn){let a=!1,c=[...t[i]||[]].sort((l,d)=>+!!d?.vscodeSettings-+!!l?.vscodeSettings);for(let l of c){let d=lt(l),p=Rr(l)&&l.vscodeSettings?[...n,d]:[d];for(let h of p)if(!r.has(h)&&await Ki(e,l,h)){a=!0,o??=h;break}if(a)break}a&&s.push(i)}return s.length===0?{ignoredEvidence:null,ignoredFile:null}:{ignoredEvidence:s.length>1?"both":s[0],ignoredFile:o}}async function W(e,{requireCommitted:t=!1,withCommitted:r=!1,env:n,gitArgs:s}={}){let o={env:n,gitArgs:s},i=await mr(e),a={host:null,source:null,ambiguous:!1,committed:!1,ignoredEvidence:null,ignoredFile:null,candidate:null,visible:null,gitError:null};try{let c=await Jg(e,o);if(c.state==="error")return{...a,gitError:c.gitError};let l=Ut(),d=await qg(e),p=null;if(c.state==="repo"){let f=[...new Set([...Xg(l),...d])],g=await Su(e,["--literal-pathspecs","ls-files","-z","--cached","--others","--exclude-standard","--",...f],o);if(!g.ok)return{...a,gitError:"unknown"};p=new Set(g.stdout.split("\0").filter(Boolean))}a.visible=p;let h=[];for(let f of Jn)for(let g of l[f]||[])if(await Vt(e,g,{visible:p})){h.push(f);break}if(h.length>1)return{...a,ambiguous:!0};let m=h[0]??null;if(m){if(t||r){let f=await Yg(e,{host:m});return a.committed=f,t&&!f?(p&&Object.assign(a,await vu(e,l,p,d)),{...a,candidate:m}):{...a,host:m,source:f?"committed":"working-tree"}}return{...a,host:m,source:"working-tree"}}return c.state!=="repo"?a:(Object.assign(a,await vu(e,l,p,d)),!t&&a.ignoredEvidence&&a.ignoredEvidence!=="both"&&a.ignoredEvidence===i?{...a,host:i,source:"local"}:a)}catch{return a}}async function mr(e){try{let t=await zg(e);return t&&Jn.includes(t.host)?t.host:null}catch{return null}}var Jn,zt,be=ee(()=>{ye();H();dt();Jn=Object.freeze(["claude","copilot"]),zt=".vesper/.host-switch-journal.json"});import{createHash as Qg}from"node:crypto";import{readFile as bu,readdir as xu}from"node:fs/promises";import{join as Br,isAbsolute as Zg}from"node:path";function qn(e){let t=String(e).replace(/\r\n/g,`
42
- `);return`sha256:${Qg("sha256").update(t,"utf8").digest("hex")}`}async function ge(e){try{return qn(await bu(e,"utf-8"))}catch{return null}}function D({path:e,host:t,category:r,hash:n=null}){if(ey.has(r)&&!n)throw new Error(`wholeFileEntry: category "${r}" is content-hash verified but was given a null/empty hash for "${e}". Provide a hash (from hashFile) or use an existence-checked category \u2014 a content-hash entry without a hash is never verified.`);return{path:e,host:t,category:r,hash:n}}function Y({path:e,host:t,category:r,owns:n}){return{path:e,host:t,category:r,owns:n||{}}}async function zr(e){return(await W(e)).host}async function _u(e,t){if(!K.includes(t))throw new Error(`Invalid host "${t}". Vesper 2.0 provisions exactly one of: ${K.join(", ")}.`);let r=await x(e);return r.schemaVersion=ve,r.host=t,await I(e,r),t}async function bo(e,t){return(await x(e))[t]}async function ty(e,t,r){let n=await x(e);return n[t]=r,await I(e,n),r}async function Cu(e){return await bo(e,Ea)===ba}function $u(e){return ty(e,Ea,ba)}async function Ou(e,t){let r=await x(e);if(r[Ea]===ba)return[];let n=q(r),s=[],o=n.filter(i=>{let a=i.host===t&&i.category!=="added-asset"&&Pt[i.category]?.ownership==="whole-file";return a&&s.push(i.path),!a});return s.length===0?[]:(r.manifest=o,await I(e,r),s)}function Yn(e){return e&&typeof e.path=="string"&&typeof e.host=="string"&&typeof e.category=="string"}async function ae(e){let t=await x(e);return q(t)}function q(e){let t=e?.manifest;return Array.isArray(t)?t.filter(Yn):[]}function mt(e){return[...e].sort((t,r)=>String(t.path).localeCompare(String(r.path))||String(t.host).localeCompare(String(r.host)))}function xa(e,t){let r=[...e];for(let n of t){if(!Yn(n))continue;let s=r.findIndex(o=>o.path===n.path&&o.host===n.host);s===-1?r.push(n):r[s]=n}return r}async function B(e,t){let r=await x(e);return r.schemaVersion=ve,r.manifest=mt(xa(q(r),t||[])),await I(e,r),r.manifest}function ry(e){return typeof e=="string"&&e.length>0&&!e.includes("..")&&!e.startsWith("/")}function _o(e,{host:t,keep:r,purgeProjectAuthored:n=!1}={}){return!e||typeof e.path!="string"||e.host==="shared"||Re.has(e.category)&&!n||t&&e.host!==t||Pt[e.category]?.ownership!=="whole-file"||r&&r.has(e.path)?!1:ry(e.path)}async function Yr(e,t,{prune:r=!0,categories:n}={}){let s=await ae(e),o=(t||[]).filter(Yn),i=new Set(n||o.map(f=>f.category)),a=new Set(o.map(f=>f.host)),c=f=>i.has(f.category)&&(a.size===0||a.has(f.host)),l=new Set(o.map(f=>f.path)),d=[],p=[];if(r)for(let f of s){if(!c(f)||!_o(f,{keep:l}))continue;let g=Br(e,f.path);if(await w(g)){let y=await ie(g,f);(y==="kept"||y==="partial")&&p.push(f.path),y!=="kept"&&d.push(f.path)}}let h=s.filter(f=>!c(f)),m=await x(e);return m.schemaVersion=ve,m.manifest=mt(xa(h,o)),await I(e,m),{pruned:d,kept:p,manifest:m.manifest}}async function Tu(e,t,{host:r,purgeProjectAuthored:n=!1}={}){let s=new Set(t||[]),o=await ae(e),i=[],a=[],c=[],l=p=>p.category==="per-project-authored"&&o.some(h=>h&&h.path===p.path&&h.host!==p.host&&h.category==="per-project-authored");for(let p of o){if(_o(p,{host:r,keep:s,purgeProjectAuthored:n})){let h=Br(e,p.path);if(l(p)){i.push(p.path);continue}if(await w(h)){let m=await ie(h,p,{purgeProjectAuthored:n});(m==="kept"||m==="partial")&&a.push(p.path)}i.push(p.path);continue}c.push(p)}let d=await x(e);return d.manifest=mt(c),await I(e,d),{pruned:i,kept:a,manifest:d.manifest}}async function Pu(e){let t=await ae(e),r={missing:[],modified:[],clean:[],userLevelViolations:[]};for(let n of t){let s=Zg(n.path)?n.path:Br(e,n.path);lr(s)&&r.userLevelViolations.push(n);let o=Pt[n.category]||{doctor:"existence"},i=await w(s);if(o.doctor==="content-hash"){if(!i){r.missing.push(n);continue}let a=await ge(s);n.hash&&a&&a!==n.hash?r.modified.push(n):r.clean.push(n);continue}if(o.doctor==="server-drift"){if(!i){r.missing.push(n);continue}let a=n.owns?.keys||[],c=await Sa(s),l=a.every(d=>c.includes(d));a.length&&!l?r.modified.push(n):r.clean.push(n);continue}i?r.clean.push(n):r.missing.push(n)}return r}async function Sa(e){try{let t=JSON.parse(await bu(e,"utf-8"));return Object.keys(t.mcpServers||t.servers||{})}catch{return[]}}async function Eu(e){try{return(await xu(e,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(".md")).map(r=>r.name)}catch{return[]}}async function ny(e){try{return(await xu(e,{withFileTypes:!0})).filter(r=>r.isDirectory()).map(r=>r.name)}catch{return[]}}async function _a(e,t,{settingsEntries:r,hooksDir:n,hookNames:s,provisionedSkillNames:o,provisionedInstructionNames:i}={}){let a=[],c=d=>Br(e,d),l=async(d,p)=>{a.push(D({path:d,host:t,category:p,hash:await ge(c(d))}))};if(t==="claude"){for(let p of await Eu(c(".claude/agents")))await l(`.claude/agents/${p}`,"catalog-agent");for(let p of await Eu(c(".claude/commands")))await l(`.claude/commands/${p}`,"catalog-command");let d=new Set(o||[]);for(let p of await ny(c(".claude/skills")))d.has(p)&&a.push(D({path:`.claude/skills/${p}`,host:t,category:"catalog-skill",hash:null}));await w(c(".claude/vesper/orchestrator.md"))&&await l(".claude/vesper/orchestrator.md","playbook");for(let p of[".claude/vesper/orchestration.md",".claude/vesper/context.md"])await w(c(p))&&a.push(D({path:p,host:t,category:"per-project-authored",hash:null}));await w(c("CLAUDE.md"))&&a.push(Y({path:"CLAUDE.md",host:t,category:"pointer",owns:{region:"vesper"}})),await w(c(".mcp.json"))&&a.push(Y({path:".mcp.json",host:t,category:"mcp-config",owns:{keys:await Sa(c(".mcp.json"))}})),await w(c(".claude/settings.json"))&&a.push(Y({path:".claude/settings.json",host:t,category:"settings",owns:{keys:["permissions.allow","hooks.SessionStart","hooks.SubagentStart"]}}))}if(t==="copilot"&&(await w(c(".vscode/settings.json"))&&a.push(Y({path:".vscode/settings.json",host:t,category:"settings",owns:{keys:[...Ct],entries:r?[...r]:[]}})),await w(c(".vscode/mcp.json"))&&a.push(Y({path:".vscode/mcp.json",host:t,category:"mcp-config",owns:{keys:await Sa(c(".vscode/mcp.json"))}})),await w(c(".vscode/tasks.json"))&&a.push(Y({path:".vscode/tasks.json",host:t,category:"bootstrap-task",owns:{keys:["Vesper: worktree bootstrap"]}}))),await w(c(".gitignore"))&&a.push(Y({path:".gitignore",host:"shared",category:"gitignore",owns:{region:"vesper:gitignore"}})),n)for(let d of Array.isArray(s)?s:["pre-commit","post-checkout"]){let p=Br(n,d);await w(p)&&a.push(Y({path:p,host:"shared",category:"hook",owns:{region:"vesper:hook"}}))}return a}function Aa(e){return(e||[]).filter(t=>t&&t.host==="shared")}function sy(e){let t=!1;for(let r of Xn)r in e&&(delete e[r],t=!0);return t}async function Iu(e){!await w(Br(e,".vesperrc"))||(await x(e)).schemaVersion!==ve||await qr(e)}async function qr(e,{frameworkVersion:t,legacyEntries:r=[],host:n}={}){let s=await x(e);if(s.schemaVersion===ve){let f=!1;if("host"in s&&!K.includes(s.host)&&(delete s.host,f=!0),!Array.isArray(s.manifest))s.manifest=[],f=!0;else{let g=s.manifest.filter(Yn);g.length!==s.manifest.length&&(s.manifest=g,f=!0)}return sy(s)&&(f=!0),f&&await I(e,s),s}let o=(K.includes(n)?n:null)||In(s)||(await W(e)).host,i=o==="both"?null:o,a=s.claude?.namePrefix??s.namePrefix,c=s.claude?.pluginPath??s.pluginPath,l=Array.isArray(s.paths)?[...s.paths]:[],d=await _a(e,i,{settingsEntries:l}),p=mt(xa(Aa(d),(r||[]).filter(Yn))),h={schemaVersion:ve,host:i||void 0,frameworkVersion:t??s.frameworkVersion,manifest:p};a!==void 0&&(h.namePrefix=a),c!==void 0&&(h.pluginPath=c),s.vendored!==void 0&&(h.vendored=s.vendored),s.mcp!==void 0&&(h.mcp=s.mcp),s.readAccessPaths!==void 0&&(h.readAccessPaths=s.readAccessPaths);let m=new Set([...Xn,"schemaVersion","host","frameworkVersion","manifest","namePrefix","pluginPath","vendored","mcp","readAccessPaths"]);for(let[f,g]of Object.entries(s))m.has(f)||(h[f]=g);return await I(e,h),h}async function gr(e,t){let r=await x(e);return!!(q(r).some(s=>s.host===t&&!Re.has(s.category))||t==="claude"&&r.claude||t==="copilot"&&Array.isArray(r.paths)&&r.paths.length>0)}async function gt(e){let t=await x(e),n=q(t).find(s=>s.path===".vscode/settings.json"&&s.category==="settings");return n&&Array.isArray(n.owns?.entries)&&n.owns.entries.length?[...n.owns.entries]:Array.isArray(t.paths)?[...t.paths]:[]}var ve,K,Xe,Eo,Pt,ey,xo,Jr,Au,Ea,ba,Re,Xn,te=ee(()=>{H();U();qe();be();ye();ve=2,K=["claude","copilot"],Xe="This workspace carries both Copilot and Claude targets from a pre-2.0 install. Vesper 2.0 uses a single host per workspace \u2014 run `vespercli init --host <claude|copilot>` to choose one, or pass an explicit `--target claude|copilot`.",Eo="This workspace carries both Copilot and Claude targets from a pre-2.0 install. Vesper 2.0 uses a single host per workspace \u2014 run `vespercli init --host <claude|copilot>` to choose one, or `vespercli reset --host <claude|copilot>` to remove one host's artifacts.",Pt={"catalog-agent":{ownership:"whole-file",doctor:"content-hash"},"catalog-command":{ownership:"whole-file",doctor:"content-hash"},"catalog-skill":{ownership:"whole-file",doctor:"existence"},playbook:{ownership:"whole-file",doctor:"content-hash"},"pack-rule":{ownership:"whole-file",doctor:"existence"},"vendored-body":{ownership:"whole-file",doctor:"existence"},"vendored-activation":{ownership:"whole-file",doctor:"content-hash"},"per-project-authored":{ownership:"whole-file",doctor:"existence"},"mcp-config":{ownership:"key",doctor:"server-drift"},settings:{ownership:"key",doctor:"key-presence"},pointer:{ownership:"region",doctor:"region-presence"},hook:{ownership:"region",doctor:"region-presence"},gitignore:{ownership:"region",doctor:"region-presence"},"bootstrap-task":{ownership:"key",doctor:"key-presence"},"guard-trigger":{ownership:"key",doctor:"key-presence"},"added-asset":{ownership:"whole-file",doctor:"existence"},"opencode-agent":{ownership:"whole-file",doctor:"existence"},"opencode-overlay":{ownership:"whole-file",doctor:"existence"},"opencode-config":{ownership:"key",doctor:"key-presence"}},ey=new Set(Object.entries(Pt).filter(([,e])=>e.doctor==="content-hash").map(([e])=>e));xo=e=>bo(e,"frameworkVersion"),Jr=async e=>await bo(e,"namePrefix")??"",Au=e=>bo(e,"pluginPath"),Ea="manifestProvenance",ba="granular";Re=new Set(["per-project-authored"]);Xn=Object.freeze(["paths","claude","addedAt","workspaceType","settingsPath","updatedAt","catalogVersion","targets"])});import{readdir as Ca}from"node:fs/promises";import{join as Qn}from"node:path";function Nu(e){let t=[],r=null;return{text:String(e||"").split(`
43
- `).filter(s=>{if(!/^\s*\|/.test(s))return r=null,!0;let o=Mu(s);if(Du(o))return!0;if(r===null)return r=o.map((i,a)=>/agent/i.test(i)?a:-1).filter(i=>i>=0),!0;for(let i of r){let a=Lu.exec(o[i]||"")?.[2],c=a?Xr(a).name:null;if(c&&Object.hasOwn(Ao,c))return t.push({role:(o[0]||"").trim(),agent:c,replacement:Ao[c]}),!1}return!0}).join(`
44
- `),removed:t}}function Ne(e){return`${It}-${e}`}async function ju(e){try{return(await Ca(e)).filter(t=>t.endsWith(".md")).map(t=>t.slice(0,-3))}catch{return[]}}async function Ru(e){try{return(await Ca(e,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name)}catch{return[]}}async function yt(e=O){let t={agents:new Set,skills:new Set,agentPlugin:new Map,skillPlugin:new Map,agentPack:new Map,skillPack:new Map},r=(s,o,i,a)=>{t[s].add(o);let c=s==="agents"?t.agentPlugin:t.skillPlugin,l=s==="agents"?t.agentPack:t.skillPack;c.has(o)||(c.set(o,i),l.set(o,a))};for(let s of await ju(Qn(e,"claude","agents")))r("agents",s,It,"core");for(let s of await Ru(Qn(e,"claude","skills")))r("skills",s,It,"core");let n=[];try{n=(await Ca(Qn(e,"claude","packs"),{withFileTypes:!0})).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>s.name).sort()}catch{n=[]}for(let s of n){let o=Ne(s);for(let i of await ju(Qn(e,"claude","packs",s,"agents")))r("agents",i,o,s);for(let i of await Ru(Qn(e,"claude","packs",s,"skills")))r("skills",i,o,s)}return t}function Mu(e){return e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|")}function Du(e){return e.every(t=>/^:?-{2,}:?$/.test(t.trim()))}function Fu(e,t,r){let n=null;return e.split(`
45
- `).map(s=>{if(!/^\s*\|/.test(s))return n=null,s;let o=Mu(s);if(Du(o))return s;if(n===null)return n=o.map((c,l)=>t.test(c)?l:-1).filter(c=>c>=0),s;let i=!1;for(let c of n){if(o[c]===void 0)continue;let l=r(o[c]);l!==null&&l!==o[c]&&(o[c]=l,i=!0)}return i?`${/^\s*/.exec(s)[0]}|${o.join("|")}|`:s}).join(`
46
- `)}function $a(e,t){return Fu(e,/agent/i,r=>{let n=Lu.exec(r);if(!n)return null;let s=t(n[2]);return!s||s===n[2]?null:n[1]+s+r.slice(n[0].length)})}function Xr(e){let t=e.lastIndexOf(":");return t===-1?{plugin:null,name:e}:{plugin:e.slice(0,t),name:e.slice(t+1)}}function Vu(e,t){let r=new Set;return $a(e,n=>(!n.includes(":")&&t.has(n)&&r.add(n),null)),[...r].sort()}function Co(e,t,{skip:r=new Set}={}){let n=t instanceof Set?t:t.agents,s=a=>t instanceof Set?It:t.agentPlugin?.get(a)??It,o=new Set;return{text:$a(e,a=>{let{plugin:c,name:l}=Xr(a);if(!n.has(l)||r.has(l))return null;let d=s(l);return c===d||c!==null&&!(c===It||c.startsWith(`${It}-`))?null:(o.add(l),`${d}:${l}`)}),qualified:[...o].sort()}}function Gu(e){return String(e||"").replace(/<!--[\s\S]*?-->/g,"")}function Hu(e){let t=new Set;return $a(Gu(e),r=>(t.add(Xr(r).name),null)),[...t].sort()}function Uu(e){let t=new Set;return Fu(Gu(e),/skill/i,r=>{for(let n of r.split(",")){let s=n.trim().replace(/^`|`$/g,"").trim();if(!s||s==="\u2014"||s==="-"||s==="\u2013")continue;let o=/^\/?(?:[a-z0-9-]+:)?([a-z0-9][a-z0-9-]*)$/i.exec(s);o&&t.add(o[1].toLowerCase())}return null}),[...t].sort()}var Ao,It,Lu,Qr=ee(()=>{Ee();Ao=Object.freeze({"history-logger":"vespercli log (the run ledger)"});It="vesper";Lu=/^(\s*`?)([a-z0-9:-]+)/});import{readFile as Wu}from"node:fs/promises";import{join as Zn,dirname as oy}from"node:path";function Ku(){return Object.keys(Oa).sort()}function yr(e){return Object.prototype.hasOwnProperty.call(Oa,e)}function ts(e,t){return Oa[e]?.[t]??null}function Ta(e,t){if(e!=="styles"||!ts(e,t))return null;let n=["# Vesper styles (always on)","","This project enables the `vesper-styles` pack. Apply the `i-have-adhd` output style and the",`\`ponytail\` decision ladder on every reply: ${t==="claude"?"load `/vesper-styles:i-have-adhd` and `/vesper-styles:ponytail` at session start":"read the `i-have-adhd` and `ponytail` skills under the pack's injected `skills/` location at session start"}, and keep both in effect for the`,`whole session (until the user says "normal mode"). Safety, correctness and the harness's own`,"instructions always outrank either style.","","Written by Vesper (`vespercli packs enable styles`); `vespercli packs disable styles` removes it.",""].join(`
37
+ `;return await A(t,`${s}${o}${r}
38
+ `,"utf-8"),{created:!1,updated:!0}}async function ns(e){if(await D(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{configured:!1};let n=`node "${M(O,"hooks","merge-memory-jsonl.js")}" %O %A %B`;return await D(["config","merge.vesper-memory.name","Vesper memory.jsonl entity-aware merge"],{cwd:e}),{configured:await D(["config","merge.vesper-memory.driver",n],{cwd:e})!==null}}function Qe(e){return M(e,".vscode","mcp.json")}function Be(){return M(Nn,"src","mcp","vesper-indexing","dist","index.js")}async function Ze(e){let t=Qe(e);try{let r=await Ke(t,"utf-8");return Lt(r)}catch(r){if(r.code==="ENOENT")return{servers:{}};if(r instanceof SyntaxError)return{servers:{}};throw r}}async function La(e,t){let r=Qe(e),n=St(r);await P(n,{recursive:!0}),await A(r,JSON.stringify(t,null," "),"utf-8")}async function Ar(e,t=!0,{record:r=!0}={}){let n=await Ze(e),s=er(Be()),o=[];if(n.servers||(n.servers={}),t?(n.servers["vesper-indexing"]={type:"stdio",command:"node",args:[s],env:{VESPER_INDEX_ROOT:"${workspaceFolder}"}},o.push("vesper-indexing"),n.servers["sequential-thinking"]={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},o.push("sequential-thinking"),n.servers.memory={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:"${workspaceFolder}/.vesper/memory.jsonl"}},o.push("memory")):(delete n.servers["vesper-indexing"],delete n.servers["sequential-thinking"],delete n.servers.memory),await La(e,n),r&&t&&o.length>0){let i=await x(e);i.mcp=i.mcp||{},i.mcp.servers=[...new Set([...Array.isArray(i.mcp.servers)?i.mcp.servers:[],...o])],i.mcp.updatedAt=new Date().toISOString(),await T(e,i)}return{configured:t,mcpPath:Qe(e),servers:o}}async function No(e){return!!(await Ze(e)).servers?.["vesper-indexing"]}async function Lo(e){let t=await q(e),r=await K(e);r[Jr]=!1,r[V]||(r[V]={});for(let n of Re)r[V][n]=!0;return await ce(e,r),{configured:Re.length,workspaceType:t.type}}async function Nu(e,t){let r=So[t];if(!r||r.length===0)return{added:[],agentName:t};let n=await K(e),s=await q(e),o=await x(e,s);n[V]||(n[V]={});let i=[];for(let a of r)n[V][a]||(n[V][a]=!0,i.push(a));return i.length>0&&(await ce(e,n),o.mcp=o.mcp||{},o.mcp.agentTools=o.mcp.agentTools||{},o.mcp.agentTools[t]=r,o.mcp.updatedAt=new Date().toISOString(),await T(e,o)),{added:i,agentName:t}}async function sr(e,t){let r=we[t];if(!r)return{added:!1,serverName:t,tools:[],error:`Unknown MCP server: ${t}`};let n=await Ze(e),s=await K(e),o=await q(e),i=await x(e,o);if(n.servers||(n.servers={}),n.servers[t])return{added:!1,serverName:t,tools:[],error:"Already configured"};let a=JSON.parse(JSON.stringify(r.config));if(t==="vesper-indexing"){let l=er(Be());a.args&&(a.args=a.args.map(d=>d==="${VESPER_INDEXING_PATH}"?l:d))}n.servers[t]=a,await La(e,n),s[V]||(s[V]={});let c=[];for(let l of r.tools||[])s[V][l]||(s[V][l]=!0,c.push(l));return s[Jr]=!1,await ce(e,s),i.mcp=i.mcp||{},i.mcp.servers=i.mcp.servers||[],i.mcp.servers.includes(t)||i.mcp.servers.push(t),i.mcp.updatedAt=new Date().toISOString(),await T(e,i),{added:!0,serverName:t,tools:c}}async function rn(e,t){let r=we[t],n=await Ze(e),s=await K(e),o=await q(e),i=await x(e,o),a=!1;n.servers&&n.servers[t]&&(delete n.servers[t],await La(e,n),a=!0);let c=[];if(r&&s[V]){for(let l of r.tools||[])s[V][l]&&(delete s[V][l],c.push(l));c.length>0&&await ce(e,s)}return i.mcp?.servers&&(i.mcp.servers=i.mcp.servers.filter(l=>l!==t),i.mcp.updatedAt=new Date().toISOString(),await T(e,i)),{removed:a,serverName:t,tools:c}}function Lu(){return Object.entries(we).map(([e,t])=>({name:e,description:t.description,tools:t.tools?.length||0}))}async function Mo(e){let t=await Ze(e);return Object.keys(t.servers||{})}var Ca,We,Rt,uo,Jr,V,po,fo,ho,mo,go,yo,wo,oe,je,Nt,me,$a,Un,Ta,Pa,ey,wu,vu,vo,Jn,Wn,Re,So,we,Au,he,ku,ny,oy,iy,Kn,co,lo,en,ao,ct,Eu,bu,uy,dy,H=Z(()=>{Wr();U();Pe();Ee();it();fe();Wr();Ca=1e4;We={agents:"chat.agentFilesLocations",instructions:"chat.instructionsFilesLocations",prompts:"chat.promptFilesLocations",skills:"chat.agentSkillsLocations"},Rt="chat.tools.terminal.autoApprove",uo="chat.tools.terminal.enableAutoApprove",Jr="chat.tools.autoApprove",V="chat.tools.eligibleForAutoApproval",po="chat.agent.maxRequests",fo="chat.includeReferencedInstructions",ho="chat.customAgentInSubagent.enabled",mo="chat.agent.enabled",go="github.copilot.chat.omitBaseAgentInstructions",yo="chat.mcp.discovery.enabled",wo="chat.mcp.autoStart",oe="github.copilot.chat.additionalReadAccessPaths",je={maxRequests:300,terminalEnableAutoApprove:!0,omitBaseAgentInstructions:!0,enableMcpServer:!0},Nt=[po,fo,ho,mo,go,yo,wo,uo,Rt,Jr,V],me=["vesper-indexing","sequential-thinking","memory"],$a=Object.freeze([Object.freeze({path:".vesperrc"}),Object.freeze({path:".vesperrc.*.tmp"}),Object.freeze({path:".vesperrc.corrupt-*"}),Object.freeze({path:".mcp.json"}),Object.freeze({path:".vscode/mcp.json"}),Object.freeze({path:".vesper/index.db"}),Object.freeze({path:".vesper/index.db-wal"}),Object.freeze({path:".vesper/index.db-shm"}),Object.freeze({path:".vesper/indexing-status.json"}),Object.freeze({path:".claude/settings.local.json"}),Object.freeze({path:".vesper/.host-switch-journal.json"}),Object.freeze({path:".vesper/.host-switch-journal.json.*.tmp"}),Object.freeze({path:".vesper/.migration-backup/"})]),Un=$a.map(e=>e.path);Ta=[".claude/skills",".claude/rules",".claude/agents",".claude/commands",".claude/CLAUDE.md",".claude/settings.json",".copilot/agents",".copilot/skills",".copilot/instructions"],Pa=[".claude/plugins",".vesperrc"];ey=[".claude/vesper/context",".claude/agents",".claude/commands",".claude/skills",".claude/rules",".vesper/skills",".vesper/instructions",".vesper/agents",".vesper/context",".vesper/.tracking",".vesper/memory.jsonl",".vesper/gates.json","CLAUDE.md","opencode.json",".opencode"],wu="# <!-- vesper:gitignore:start -->",vu="# <!-- vesper:gitignore:end -->";vo="Vesper: worktree bootstrap",Jn=Object.freeze({taskLabel:"Vesper: host guard",hookCommandMarker:"vespercli guard --running-host"});Wn=["react-scripts","**/node_modules/.bin/react-scripts","next","**/node_modules/.bin/next","vite","**/node_modules/.bin/vite","webpack","**/node_modules/.bin/webpack","turbo","**/node_modules/.bin/turbo","tsc","**/node_modules/.bin/tsc","tsup","**/node_modules/.bin/tsup","esbuild","**/node_modules/.bin/esbuild","rollup","**/node_modules/.bin/rollup","parcel","**/node_modules/.bin/parcel","jest","**/node_modules/.bin/jest","vitest","**/node_modules/.bin/vitest","npx vitest","pnpm vitest","pnpm vitest run","pnpm exec vitest","pnpm dlx vitest","mocha","**/node_modules/.bin/mocha","playwright","**/node_modules/.bin/playwright","npx playwright open","npx playwright test","npx playwright show-report","npx playwright codegen","open playwright","open playwright-report/index.html",'ps aux | grep "playwright test" | grep -v grep | wc -l',"cypress","**/node_modules/.bin/cypress","pytest","npx","pnpm dlx","pnpm exec","yarn dlx","npm test","npm run","npm start","npm run test","npm run build","npm run dev","npm run lint","pnpm test","pnpm run","pnpm start","pnpm tsc","yarn test","yarn run","yarn start","eslint","**/node_modules/.bin/eslint","pnpm eslint","prettier","**/node_modules/.bin/prettier","biome","**/node_modules/.bin/biome","stylelint","**/node_modules/.bin/stylelint","mkdir","touch","cat","ls","head","tail","wc","grep","find","tree","file","stat","realpath","basename","dirname","awk","sed","cut","sort","uniq","tr","xargs","column","paste","join","comm","diff","cmp","git status","git log","git diff","git branch","git show","git remote","git tag","git rev-parse","git describe","git ls-files","git ls-tree","git blame","git shortlog","pushd","popd","dirs","echo","pwd","which","type","env","printenv","date","hostname","whoami","uname","lsof","pkill","node --version","npm --version","pnpm --version","yarn --version","python --version","python3 --version","curl -I *","curl --head *","curl -sI *","curl -s http://localhost:*","curl -s http://127.0.0.1:*","curl -sf http://localhost:*","curl -sf http://127.0.0.1:*","curl --fail http://localhost:*","curl --fail http://127.0.0.1:*","tsx","**/node_modules/.bin/tsx","npx tsx","/^(\\w+=\\S+\\s+)+(npx|node|tsx|npm|pnpm|yarn)\\b/","vespercli","vespercli init","vespercli add","vespercli list","vespercli ls","vespercli reset","vespercli catalog","**/node_modules/.bin/vespercli","mcp: vesper-indexing: vesper_search","mcp: vesper-indexing: vesper_symbols","mcp: vesper-indexing: vesper_status","mcp: vesper-indexing: vesper_reindex","python3 << 'PYEOF'",'python3 << "PYEOF"',"python3 << 'EOF'",'python3 << "EOF"',"python3 << 'END'","python << 'PYEOF'",'python << "PYEOF"',"python << 'EOF'","cat << 'EOF'",'cat << "EOF"',"cat << 'END'","bash << 'EOF'","sh << 'EOF'","cat << 'RESEARCH_EOF'",'cat << "RESEARCH_EOF"',"RESEARCH_EOF","tee","node -e","python3 -c","python -c"],Re=["vesper_search","vesper_symbols","vesper_status","vesper_reindex","resolve-library-id","get-library-docs","query-docs","sequentialthinking","create_entities","create_relations","add_observations","delete_entities","delete_observations","delete_relations","read_graph","search_nodes","open_nodes"],So={"clickup-agent":["clickup_add_tag_to_task","clickup_add_time_entry","clickup_attach_task_file","clickup_create_document","clickup_create_document_page","clickup_create_folder","clickup_create_list","clickup_create_list_in_folder","clickup_create_task","clickup_create_task_comment","clickup_find_member_by_name","clickup_get_chat_channels","clickup_get_current_time_entry","clickup_get_document_pages","clickup_get_folder","clickup_get_list","clickup_get_task","clickup_get_task_comments","clickup_get_task_time_entries","clickup_get_workspace_hierarchy","clickup_get_workspace_members","clickup_list_document_pages","clickup_remove_tag_from_task","clickup_resolve_assignees","clickup_search","clickup_send_chat_message","clickup_start_time_tracking","clickup_stop_time_tracking","clickup_update_document_page","clickup_update_folder","clickup_update_list","clickup_update_task"]},we={"vesper-indexing":{description:"Fast code search with semantic indexing",config:{type:"stdio",command:"node",args:["${VESPER_INDEXING_PATH}"],env:{VESPER_INDEX_ROOT:"${workspaceFolder}"}},tools:["vesper_search","vesper_symbols","vesper_status","vesper_reindex"]},context7:{description:"Documentation lookup for libraries",config:{type:"stdio",command:"npx",args:["-y","@upstash/context7-mcp"]},tools:["resolve-library-id","get-library-docs","query-docs"]},"sequential-thinking":{description:"Step-by-step reasoning for complex problems",config:{type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},tools:["sequentialthinking"]},clickup:{description:"ClickUp project management integration",config:{type:"stdio",command:"npx",args:["-y","@anthropics/mcp-clickup"],env:{CLICKUP_API_KEY:"${env:CLICKUP_API_KEY}",CLICKUP_TEAM_ID:"${env:CLICKUP_TEAM_ID}"}},tools:["clickup_add_tag_to_task","clickup_add_time_entry","clickup_attach_task_file","clickup_create_document","clickup_create_document_page","clickup_create_folder","clickup_create_list","clickup_create_list_in_folder","clickup_create_task","clickup_create_task_comment","clickup_find_member_by_name","clickup_get_chat_channels","clickup_get_current_time_entry","clickup_get_document_pages","clickup_get_folder","clickup_get_list","clickup_get_task","clickup_get_task_comments","clickup_get_task_time_entries","clickup_get_workspace_hierarchy","clickup_get_workspace_members","clickup_list_document_pages","clickup_remove_tag_from_task","clickup_resolve_assignees","clickup_search","clickup_send_chat_message","clickup_start_time_tracking","clickup_stop_time_tracking","clickup_update_document_page","clickup_update_folder","clickup_update_list","clickup_update_task"]},memory:{description:"Persistent knowledge graph memory for AI agents",config:{type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:"${workspaceFolder}/.vesper/memory.jsonl"}},tools:["create_entities","create_relations","add_observations","delete_entities","delete_observations","delete_relations","read_graph","search_nodes","open_nodes"]},graphify:{description:"Code knowledge graph (graphify, opt-in pack) \u2014 impact, path and architecture queries",config:{type:"stdio",command:"vespercli",args:["mcp","serve","graphify"]},tools:["query_graph","get_node","get_neighbors","shortest_path","get_pr_impact"]}},Au=Re,he={FOLDER:"folder",WORKSPACE_FILE:"workspace"};ku=new Set;ny=new Set([Rt,Jr,V]);oy=Ot,iy=["agents","prompts","skills"],Kn=M(O,"copilot","instructions"),co=M(O,"copilot","instructions-extended");lo=M(Ot,"packs");en=Object.freeze(["-c","core.fsmonitor=false","-c","core.untrackedCache=false"]),ao=null;ct=["pre-commit","post-checkout"];Eu="# <!-- vesper:gitattributes:start -->",bu="# <!-- vesper:gitattributes:end -->",uy=[".vesper/memory.jsonl merge=vesper-memory",".claude/vesper/context/recent-decisions.md merge=union",".vesper/context/recent-decisions.md merge=union"];dy={VSCODE_SETTINGS_MAP:We,WORKSPACE_TYPES:he,TERMINAL_AUTO_APPROVAL_SETTING:Rt,TERMINAL_ENABLE_AUTO_APPROVAL_SETTING:uo,TOOLS_AUTO_APPROVE_SETTING:Jr,TOOLS_ELIGIBLE_FOR_AUTO_APPROVAL_SETTING:V,AGENT_MAX_REQUESTS_SETTING:po,INCLUDE_REFERENCED_INSTRUCTIONS_SETTING:fo,CUSTOM_AGENT_IN_SUBAGENT_SETTING:ho,CHAT_AGENT_ENABLED_SETTING:mo,OMIT_BASE_AGENT_INSTRUCTIONS_SETTING:go,MCP_DISCOVERY_ENABLED_SETTING:yo,MCP_AUTO_START_SETTING:wo,ADDITIONAL_READ_ACCESS_PATHS_SETTING:oe,SAFE_AUTO_APPROVAL_COMMANDS:Wn,MCP_TOOLS_CORE:Re,MCP_TOOLS_BY_AGENT:So,MCP_SERVERS:we,MCP_TOOLS_AUTO_APPROVAL:Au,INIT_DEFAULTS:je,VESPER_MANAGED_SETTINGS:Nt,VESPER_MANAGED_MCP_SERVERS:me,findWorkspaceFile:Ia,getWorkspaceConfig:q,getSettingsPath:_u,getTrackingPath:Xr,getTrackingPathAsync:Et,readVSCodeSettings:K,writeVSCodeSettings:ce,readTracking:x,writeTracking:T,removeLegacyTracking:$u,addToSettings:Qr,removeFromSettings:Zn,getCoreAssetEntries:Ao,pruneLegacySettingsEntries:Zr,listExtendedInstructions:bo,getExtendedInstructionEntry:xo,getTrackedPaths:bt,configureTerminalAutoApproval:Co,configureChatSettings:$o,getAutoApprovalCommands:Pu,addReadAccessPath:Oo,removeReadAccessPath:To,getReadAccessPaths:Po,getMcpConfigPath:Qe,getVesperIndexingPath:Be,readMcpConfig:Ze,configureMcpServer:Ar,isMcpServerConfigured:No,configureMcpToolsAutoApproval:Lo,addAgentToolsToAutoApproval:Nu,addMcpServer:sr,removeMcpServer:rn,listMcpServers:Lu,getConfiguredMcpServers:Mo,getWorkspaceFolders:ja,findNestedVesperrc:Qn,migrateVesperrcToWorkspaceLevel:Eo,ensureCoreSettings:Io}});import{access as py,constants as fy,stat as Jx,lstat as hy,readdir as my,readFile as gy,readlink as yy,rename as wy,writeFile as vy,mkdir as ky,cp as Sy,appendFile as Mu}from"node:fs/promises";import{createHash as Ey}from"node:crypto";import{isAbsolute as by,join as xy,relative as Ay,resolve as Go,sep as _y}from"node:path";function Fa(e){Ga=e?{root:Go(e.root),log:e.log,exclude:e.exclude||(()=>!1)}:null}async function Gu(e,t,r){let n=await hy(e);if(n.isSymbolicLink())r.push([t,`link:${await yy(e)}`]);else if(n.isDirectory())for(let s of await my(e))await Gu(xy(e,s),`${t}/${s}`,r);else n.isFile()&&r.push([t,Ey("sha256").update(await gy(e)).digest("hex")])}function Fu(e,t){let r=Go(t),n=Ay(e.root,r);if(!n||n.startsWith("..")||by(n))return null;let s=n.split(_y).join("/");return e.exclude(s)?null:s}async function Da(e){let t=Ga;if(t)try{let r=Fu(t,e);r&&await Mu(t.log,`${JSON.stringify([r,ss])}
39
+ `,"utf-8")}catch{}}async function Va(e){let t=Ga;if(t)try{let r=Go(e),n=Fu(t,e);if(!n)return;let s=[];await Gu(r,n,s);let o=s.filter(([i])=>!t.exclude(i)).map(i=>`${JSON.stringify(i)}
40
+ `).join("");o&&await Mu(t.log,o,"utf-8")}catch{}}async function w(e){try{return await py(e,fy.F_OK),!0}catch{return!1}}function Ha(e){let t=Go(e);if(xr(t)||xr(e))throw new Error(`Refusing to write a user-level path (Vesper is project-scoped, D7): ${e}. Only the project workspace and the permitted plugin cache (~/.claude/plugins) may be written.`)}async function A(e,t,r){Ha(e),await Da(e);let n=await vy(e,t,r);return await Va(e),n}async function P(e,t){return Ha(e),ky(e,t)}async function os(e,t,r){Ha(t),await Da(t);let n=await Sy(e,t,r);return await Va(t),n}async function Cy(e,t){await Da(t);let r=await wy(e,t);return await Va(t),r}async function _r(e,t,{mode:r,encoding:n="utf-8",tempName:s,sweepPattern:o,sweep:i=!0}={}){let{dirname:a,basename:c,join:l}=await import("node:path"),d=await import("node:fs/promises"),p=a(e);if(i){let m=c(e).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),h=o??new RegExp(`^${m}\\.\\d+\\.tmp$`),g=[];try{g=await d.readdir(p)}catch{g=[]}for(let y of g){if(!h.test(y))continue;let k=l(p,y);try{Date.now()-(await d.stat(k)).mtimeMs>$y&&await d.unlink(k)}catch{}}}let f=s?s(e):`${e}.${process.pid}.tmp`;try{await A(f,t,r===void 0?n:{encoding:n,mode:r}),r!==void 0&&await d.chmod(f,r).catch(()=>{}),await Cy(f,e)}catch(m){throw await d.unlink(f).catch(()=>{}),m}}var Ga,ss,$y,U=Z(()=>{H();Ga=null;ss="intent";$y=5*60*1e3});import{existsSync as Du,readdirSync as Oy}from"node:fs";import{readdir as Vu,readFile as Hu}from"node:fs/promises";import{join as or}from"node:path";function Wu(e=O){try{return Oy(or(e,"claude","packs"),{withFileTypes:!0}).filter(t=>t.isDirectory()&&!t.name.startsWith(".")).map(t=>t.name).sort()}catch{return[]}}function $r(e,t=O){if(typeof e!="string"||!e||/[\\/]|\.\./.test(e))return null;for(let r of Wu(t)){let n=or(t,"claude","packs",r,"skills",e);if(Du(or(n,Ua)))return{pack:r,dir:n}}return null}async function Fo(e){let t={},r=async n=>{let s=await Vu(or(e,n),{withFileTypes:!0});for(let o of s.sort((i,a)=>i.name.localeCompare(a.name))){let i=n?`${n}/${o.name}`:o.name;o.isDirectory()?await r(i):o.isFile()&&i!==Ua&&(t[i]=await Hu(or(e,i)))}};return await r(""),t}async function Ku(e=O){let t=[];for(let r of Wu(e)){let n=[];try{n=(await Vu(or(e,"claude","packs",r,"skills"),{withFileTypes:!0})).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>s.name).sort()}catch{n=[]}for(let s of n){let o=or(e,"claude","packs",r,"skills",s),i=or(o,Ua);if(!Du(i))continue;let a=null;try{let c=JSON.parse(await Hu(i,"utf-8"));a=c&&typeof c=="object"&&!Array.isArray(c)?c:null}catch{a=null}t.push({pack:r,skill:s,dir:o,record:a})}}return t}var Ua,Cr,Uu,Or=Z(()=>{Ee();Ua="UPSTREAM.json",Cr=Object.freeze(["gitlab-ci-skill","github-actions-to-gitlab-ci","i-have-adhd","ponytail"]),Uu="styles"});import{lstat as Yu,readdir as Ju,readFile as Do,rm as qu,rmdir as Bu}from"node:fs/promises";import{basename as Xu,join as ze,relative as Ty,sep as Py}from"node:path";import{existsSync as Wa}from"node:fs";import{createHash as Qu}from"node:crypto";async function lt(e){let t=[],r=[],n=[],s=async o=>{let i=await Ju(o,{withFileTypes:!0});for(let a of i){let c=ze(o,a.name),l=Ty(e,c).split(Py).join("/");a.isSymbolicLink()?r.push(l):a.isDirectory()?(await s(c),n.push(l)):a.isFile()?t.push(l):r.push(l)}};return await s(e),t.sort(),r.sort(),n.sort((o,i)=>i.split("/").length-o.split("/").length||i.localeCompare(o)),{files:t,others:r,dirs:n}}function Iy(e){return`sha256:${Qu("sha256").update(e).digest("hex")}`}function ut(e){let t=e.toString("utf-8").replace(/\r\n/g,`
41
+ `);return`sha256:${Qu("sha256").update(t,"utf8").digest("hex")}`}function zu(e){if(!e.includes(13))return e;let t=Buffer.allocUnsafe(e.length),r=0;for(let n=0;n<e.length;n+=1)e[n]===13&&e[n+1]===10||(t[r]=e[n],r+=1);return t.subarray(0,r)}function ee(e,t){let r=Buffer.isBuffer(e)?e:Buffer.from(String(e),"utf-8"),n=Buffer.isBuffer(t)?t:Buffer.from(String(t),"utf-8");return zu(r).equals(zu(n))}async function jy({sourceDir:e,sourceFiles:t,sourceHashes:r,sourceLfHashes:n}={}){let s=new Map,o=(i,a)=>{let c=s.get(i);s.set(i,c?async l=>await c(l)||a(l):a)};if(r)for(let[i,a]of Object.entries(r))typeof a=="string"&&a&&o(i,async c=>Iy(c)===a);if(t)for(let[i,a]of Object.entries(t)){let c=Buffer.isBuffer(a)?a:Buffer.from(a,"utf-8");o(i,async l=>ee(l,c))}if(e&&Wa(e)){let{files:i}=await lt(e);for(let a of i)o(a,async c=>ee(c,await Do(ze(e,a))))}if(n)for(let[i,a]of Object.entries(n)){let c=new Set((Array.isArray(a)?a:[a]).filter(l=>typeof l=="string"&&l));c.size&&o(i,async l=>c.has(ut(l)))}return s}async function Mt(e,{sourceDir:t,sourceFiles:r,sourceHashes:n,sourceLfHashes:s,sourceMatch:o,anchor:i="SKILL.md"}={}){let a;try{a=await Yu(e)}catch{return{status:"absent",proven:[],kept:[],dirs:[]}}if(!a.isDirectory())return{status:"not-directory",proven:[],kept:[Xu(e)],dirs:[]};let c=await jy({sourceDir:t,sourceFiles:r,sourceHashes:n,sourceLfHashes:s}),{files:l,others:d,dirs:p}=await lt(e),f=[],m=[...d];for(let h of l){let y=c.get(h)||(o?async k=>!!await o(h,k):null);if(!y){m.push(h);continue}try{await y(await Do(ze(e,h)))?f.push(h):m.push(h)}catch{m.push(h)}}return m.sort(),i&&(c.has(i)||o&&l.includes(i))&&!f.includes(i)?{status:"anchor-unproven",proven:[],kept:[...l,...d].sort(),dirs:p}:{status:"classified",proven:f,kept:m,dirs:p}}async function is(e,t={}){let r=await Mt(e,t);if(r.status==="absent")return{status:"absent",removed:[],kept:[]};if(r.status!=="classified")return{status:"kept",removed:[],kept:r.kept};for(let o of r.proven)await qu(ze(e,o),{force:!0});for(let o of r.dirs)try{await Bu(ze(e,o))}catch{}let n=!1;try{await Bu(e),n=!0}catch{}let s="kept";return n?s="removed":r.proven.length>0&&(s="partial"),{status:s,removed:r.proven,kept:r.kept}}async function Ry(e){let t=Xu(String(e?.path||""));if(!t||t==="."||t==="..")return null;if(e.category==="vendored-body"){let r=e.placedFiles??e.syncedFiles,n=r&&typeof r=="object"&&Object.keys(r).length?{...r}:null,s=$r(t);return s?{sourceFiles:await Fo(s.dir),...n?{sourceHashes:n}:{}}:n?{sourceHashes:n}:null}if(e.category==="catalog-skill"||e.category==="added-asset"){let r;for(let s of["claude-committed","claude"]){let o=ze(O,s,"skills",t);if(Wa(o)){r=o;break}}if(!r){let s=[];try{s=(await Ju(ze(O,"claude","packs"),{withFileTypes:!0})).filter(o=>o.isDirectory()&&!o.name.startsWith(".")).map(o=>o.name).sort()}catch{s=[]}for(let o of s){let i=ze(O,"claude","packs",o,"skills",t);if(Wa(i)){r=i;break}}}let n=e.fileHashes&&typeof e.fileHashes=="object"&&Object.keys(e.fileHashes).length?{...e.fileHashes}:null;if(r||n)return{...r?{sourceDir:r}:{},...n?{sourceLfHashes:n}:{}}}return null}async function Ny(e){let t=String(e?.path||""),r=[];t===".claude/rules/vesper-orchestrator.md"&&r.push(ze(O,"claude","vesper-orchestrator.md"));let n=/^\.claude\/agents\/([^/]+\.md)$/.exec(t);n&&r.push(ze(O,"claude-committed","agents",n[1]),ze(O,"claude","agents",n[1])),n=/^\.claude\/commands\/([^/]+\.md)$/.exec(t),n&&r.push(ze(O,"claude","commands",n[1])),t===".opencode/plugins/vesper.js"&&r.push(ze(O,"opencode","vesper-plugin.js"));let s=[];for(let o of r)try{s.push(await Do(o))}catch{}return s}async function as(e,t,{expected:r=[]}={}){let n;try{n=await Do(e)}catch{return!1}return typeof t?.hash=="string"&&t.hash&&ut(n)===t.hash?!0:[...r.map(o=>Buffer.isBuffer(o)?o:Buffer.from(String(o),"utf-8")),...await Ny(t)].some(o=>ee(n,o))}async function le(e,t,{expected:r=[],purgeProjectAuthored:n=!1}={}){let s;try{s=await Yu(e)}catch{return"absent"}if(s.isFile())return!(n===!0&&t?.category==="per-project-authored")&&!await as(e,t,{expected:r})?"kept":(await qu(e,{force:!0}),"removed");if(!s.isDirectory())return"kept";let o=await Ry(t);return o?(await is(e,o)).status:"kept"}var Ye=Z(()=>{Ee();Or()});import{access as Ly,constants as My,readFile as ed,readdir as Gy}from"node:fs/promises";import{execFile as Fy}from"node:child_process";import{join as Vo}from"node:path";async function Dy(e){try{return await Ly(e,My.F_OK),!0}catch{return!1}}async function Gt(e){try{let t=JSON.parse(await ed(Vo(e,ir),"utf-8"));if(t&&typeof t=="object"&&t.snapshot&&cs.includes(t.from))return t}catch{}return null}async function Ka(e){return await Dy(Vo(e,ir))?await Gt(e)===null:!1}async function Vy(e){let t;try{t=[await Et(e),Vo(e,".vesperrc")]}catch{t=[Vo(e,".vesperrc")]}let r=new Set;for(let n of t)if(!r.has(n)){r.add(n);try{return JSON.parse(await ed(n,"utf-8"))}catch(s){if(s&&s.code==="ENOENT")continue;return null}}return null}function td(e,t,{env:r,gitArgs:n=[]}={}){return new Promise(s=>{let o;try{o=Fy("git",[...n,...t],{cwd:e,timeout:5e3,maxBuffer:16*1024*1024,encoding:"utf-8",env:{...r??process.env,...jt}},(i,a,c)=>{let l=i&&typeof i.code=="string"?i:null;s({ok:!i,stdout:String(a??""),stderr:String(c??""),spawnError:l})}),o.stdin?.end()}catch(i){s({ok:!1,stdout:"",stderr:"",spawnError:i})}})}async function Hy(e,t={}){let r=await td(e,["rev-parse","--is-inside-work-tree"],t);return r.ok&&r.stdout.trim()==="true"?{state:"repo"}:/dubious ownership/i.test(r.stderr)?{state:"error",gitError:"dubious-ownership"}:/not a git repository/i.test(r.stderr)?{state:"no-repo"}:r.spawnError?.code==="ENOENT"?{state:"no-repo"}:{state:"error",gitError:"unknown"}}async function Uy(e,t){if(!t?.host)return!1;try{let{host:r,matched:n}=await au(e);if(r!==t.host||n.length===0)return!1;for(let{entry:s,path:o}of n)if(!await ga(e,s,o))return!1;return!0}catch{return!1}}async function Wy(e){try{return(await Gy(e,{withFileTypes:!0})).filter(t=>t.isFile()&&t.name.endsWith(".code-workspace")).map(t=>t.name).sort()}catch{return[]}}function Ky(e){let t=[];for(let r of cs)for(let n of e[r]||[])t.push(gt(n));return[...new Set(t)]}async function Zu(e,t,r,n){let s=[],o=null;for(let i of cs){let a=!1,c=[...t[i]||[]].sort((l,d)=>+!!d?.vscodeSettings-+!!l?.vscodeSettings);for(let l of c){let d=gt(l),p=zr(l)&&l.vscodeSettings?[...n,d]:[d];for(let f of p)if(!r.has(f)&&await ga(e,l,f)){a=!0,o??=f;break}if(a)break}a&&s.push(i)}return s.length===0?{ignoredEvidence:null,ignoredFile:null}:{ignoredEvidence:s.length>1?"both":s[0],ignoredFile:o}}async function B(e,{requireCommitted:t=!1,withCommitted:r=!1,env:n,gitArgs:s}={}){let o={env:n,gitArgs:s},i=await Tr(e),a={host:null,source:null,ambiguous:!1,committed:!1,ignoredEvidence:null,ignoredFile:null,candidate:null,visible:null,gitError:null};try{let c=await Hy(e,o);if(c.state==="error")return{...a,gitError:c.gitError};let l=Zt(),d=await Wy(e),p=null;if(c.state==="repo"){let h=[...new Set([...Ky(l),...d])],g=await td(e,["--literal-pathspecs","ls-files","-z","--cached","--others","--exclude-standard","--",...h],o);if(!g.ok)return{...a,gitError:"unknown"};p=new Set(g.stdout.split("\0").filter(Boolean))}a.visible=p;let f=[];for(let h of cs)for(let g of l[h]||[])if(await qt(e,g,{visible:p})){f.push(h);break}if(f.length>1)return{...a,ambiguous:!0};let m=f[0]??null;if(m){if(t||r){let h=await Uy(e,{host:m});return a.committed=h,t&&!h?(p&&Object.assign(a,await Zu(e,l,p,d)),{...a,candidate:m}):{...a,host:m,source:h?"committed":"working-tree"}}return{...a,host:m,source:"working-tree"}}return c.state!=="repo"?a:(Object.assign(a,await Zu(e,l,p,d)),!t&&a.ignoredEvidence&&a.ignoredEvidence!=="both"&&a.ignoredEvidence===i?{...a,host:i,source:"local"}:a)}catch{return a}}async function Tr(e){try{let t=await Vy(e);return t&&cs.includes(t.host)?t.host:null}catch{return null}}var cs,ir,be=Z(()=>{fe();H();wt();cs=Object.freeze(["claude","copilot"]),ir=".vesper/.host-switch-journal.json"});import{createHash as By}from"node:crypto";import{readFile as nd,readdir as sd}from"node:fs/promises";import{join as nn,isAbsolute as zy}from"node:path";function us(e){let t=String(e).replace(/\r\n/g,`
42
+ `);return`sha256:${By("sha256").update(t,"utf8").digest("hex")}`}async function ye(e){try{return us(await nd(e,"utf-8"))}catch{return null}}function G({path:e,host:t,category:r,hash:n=null}){if(Yy.has(r)&&!n)throw new Error(`wholeFileEntry: category "${r}" is content-hash verified but was given a null/empty hash for "${e}". Provide a hash (from hashFile) or use an existence-checked category \u2014 a content-hash entry without a hash is never verified.`);return{path:e,host:t,category:r,hash:n}}function Y({path:e,host:t,category:r,owns:n}){return{path:e,host:t,category:r,owns:n||{}}}async function sn(e){return(await B(e)).host}async function od(e,t){if(!z.includes(t))throw new Error(`Invalid host "${t}". Vesper 2.0 provisions exactly one of: ${z.join(", ")}.`);let r=await x(e);return r.schemaVersion=ve,r.host=t,await T(e,r),t}async function Uo(e,t){return(await x(e))[t]}async function Jy(e,t,r){let n=await x(e);return n[t]=r,await T(e,n),r}async function ad(e){return await Uo(e,za)===Ya}function cd(e){return Jy(e,za,Ya)}async function ld(e,t){let r=await x(e);if(r[za]===Ya)return[];let n=J(r),s=[],o=n.filter(i=>{let a=i.host===t&&i.category!=="added-asset"&&Ft[i.category]?.ownership==="whole-file";return a&&s.push(i.path),!a});return s.length===0?[]:(r.manifest=o,await T(e,r),s)}function ls(e){return e&&typeof e.path=="string"&&typeof e.host=="string"&&typeof e.category=="string"}async function ne(e){let t=await x(e);return J(t)}function J(e){let t=e?.manifest;return Array.isArray(t)?t.filter(ls):[]}function tt(e){return[...e].sort((t,r)=>String(t.path).localeCompare(String(r.path))||String(t.host).localeCompare(String(r.host)))}function Ja(e,t){let r=[...e];for(let n of t){if(!ls(n))continue;let s=r.findIndex(o=>o.path===n.path&&o.host===n.host);s===-1?r.push(n):r[s]=n}return r}async function W(e,t){let r=await x(e);return r.schemaVersion=ve,r.manifest=tt(Ja(J(r),t||[])),await T(e,r),r.manifest}function qy(e){return typeof e=="string"&&e.length>0&&!e.includes("..")&&!e.startsWith("/")}function Ko(e,{host:t,keep:r,purgeProjectAuthored:n=!1}={}){return!e||typeof e.path!="string"||e.host==="shared"||Ne.has(e.category)&&!n||t&&e.host!==t||Ft[e.category]?.ownership!=="whole-file"||r&&r.has(e.path)?!1:qy(e.path)}async function an(e,t,{prune:r=!0,categories:n}={}){let s=await ne(e),o=(t||[]).filter(ls),i=new Set(n||o.map(h=>h.category)),a=new Set(o.map(h=>h.host)),c=h=>i.has(h.category)&&(a.size===0||a.has(h.host)),l=new Set(o.map(h=>h.path)),d=[],p=[];if(r)for(let h of s){if(!c(h)||!Ko(h,{keep:l}))continue;let g=nn(e,h.path);if(await w(g)){let y=await le(g,h);(y==="kept"||y==="partial")&&p.push(h.path),y!=="kept"&&d.push(h.path)}}let f=s.filter(h=>!c(h)),m=await x(e);return m.schemaVersion=ve,m.manifest=tt(Ja(f,o)),await T(e,m),{pruned:d,kept:p,manifest:m.manifest}}async function ud(e,t,{host:r,purgeProjectAuthored:n=!1}={}){let s=new Set(t||[]),o=await ne(e),i=[],a=[],c=[],l=p=>p.category==="per-project-authored"&&o.some(f=>f&&f.path===p.path&&f.host!==p.host&&f.category==="per-project-authored");for(let p of o){if(Ko(p,{host:r,keep:s,purgeProjectAuthored:n})){let f=nn(e,p.path);if(l(p)){i.push(p.path);continue}if(await w(f)){let m=await le(f,p,{purgeProjectAuthored:n});(m==="kept"||m==="partial")&&a.push(p.path)}i.push(p.path);continue}c.push(p)}let d=await x(e);return d.manifest=tt(c),await T(e,d),{pruned:i,kept:a,manifest:d.manifest}}async function dd(e){let t=await ne(e),r={missing:[],modified:[],clean:[],userLevelViolations:[]};for(let n of t){let s=zy(n.path)?n.path:nn(e,n.path);xr(s)&&r.userLevelViolations.push(n);let o=Ft[n.category]||{doctor:"existence"},i=await w(s);if(o.doctor==="content-hash"){if(!i){r.missing.push(n);continue}let a=await ye(s);n.hash&&a&&a!==n.hash?r.modified.push(n):r.clean.push(n);continue}if(o.doctor==="server-drift"){if(!i){r.missing.push(n);continue}let a=n.owns?.keys||[],c=await Ba(s),l=a.every(d=>c.includes(d));a.length&&!l?r.modified.push(n):r.clean.push(n);continue}i?r.clean.push(n):r.missing.push(n)}return r}async function Ba(e){try{let t=JSON.parse(await nd(e,"utf-8"));return Object.keys(t.mcpServers||t.servers||{})}catch{return[]}}async function rd(e){try{return(await sd(e,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(".md")).map(r=>r.name)}catch{return[]}}async function Xy(e){try{return(await sd(e,{withFileTypes:!0})).filter(r=>r.isDirectory()).map(r=>r.name)}catch{return[]}}async function qa(e,t,{settingsEntries:r,hooksDir:n,hookNames:s,provisionedSkillNames:o,provisionedInstructionNames:i}={}){let a=[],c=d=>nn(e,d),l=async(d,p)=>{a.push(G({path:d,host:t,category:p,hash:await ye(c(d))}))};if(t==="claude"){for(let p of await rd(c(".claude/agents")))await l(`.claude/agents/${p}`,"catalog-agent");for(let p of await rd(c(".claude/commands")))await l(`.claude/commands/${p}`,"catalog-command");let d=new Set(o||[]);for(let p of await Xy(c(".claude/skills")))d.has(p)&&a.push(G({path:`.claude/skills/${p}`,host:t,category:"catalog-skill",hash:null}));await w(c(".claude/vesper/orchestrator.md"))&&await l(".claude/vesper/orchestrator.md","playbook");for(let p of[".claude/vesper/orchestration.md",".claude/vesper/context.md"])await w(c(p))&&a.push(G({path:p,host:t,category:"per-project-authored",hash:null}));await w(c("CLAUDE.md"))&&a.push(Y({path:"CLAUDE.md",host:t,category:"pointer",owns:{region:"vesper"}})),await w(c(".mcp.json"))&&a.push(Y({path:".mcp.json",host:t,category:"mcp-config",owns:{keys:await Ba(c(".mcp.json"))}})),await w(c(".claude/settings.json"))&&a.push(Y({path:".claude/settings.json",host:t,category:"settings",owns:{keys:["permissions.allow","hooks.SessionStart","hooks.SubagentStart"]}}))}if(t==="copilot"&&(await w(c(".vscode/settings.json"))&&a.push(Y({path:".vscode/settings.json",host:t,category:"settings",owns:{keys:[...Nt],entries:r?[...r]:[]}})),await w(c(".vscode/mcp.json"))&&a.push(Y({path:".vscode/mcp.json",host:t,category:"mcp-config",owns:{keys:await Ba(c(".vscode/mcp.json"))}})),await w(c(".vscode/tasks.json"))&&a.push(Y({path:".vscode/tasks.json",host:t,category:"bootstrap-task",owns:{keys:["Vesper: worktree bootstrap"]}}))),await w(c(".gitignore"))&&a.push(Y({path:".gitignore",host:"shared",category:"gitignore",owns:{region:"vesper:gitignore"}})),n)for(let d of Array.isArray(s)?s:["pre-commit","post-checkout"]){let p=nn(n,d);await w(p)&&a.push(Y({path:p,host:"shared",category:"hook",owns:{region:"vesper:hook"}}))}return a}function Xa(e){return(e||[]).filter(t=>t&&t.host==="shared")}function Qy(e){let t=!1;for(let r of ds)r in e&&(delete e[r],t=!0);return t}async function pd(e){!await w(nn(e,".vesperrc"))||(await x(e)).schemaVersion!==ve||await cn(e)}async function cn(e,{frameworkVersion:t,legacyEntries:r=[],host:n}={}){let s=await x(e);if(s.schemaVersion===ve){let h=!1;if("host"in s&&!z.includes(s.host)&&(delete s.host,h=!0),!Array.isArray(s.manifest))s.manifest=[],h=!0;else{let g=s.manifest.filter(ls);g.length!==s.manifest.length&&(s.manifest=g,h=!0)}return Qy(s)&&(h=!0),h&&await T(e,s),s}let o=(z.includes(n)?n:null)||Bn(s)||(await B(e)).host,i=o==="both"?null:o,a=s.claude?.namePrefix??s.namePrefix,c=s.claude?.pluginPath??s.pluginPath,l=Array.isArray(s.paths)?[...s.paths]:[],d=await qa(e,i,{settingsEntries:l}),p=tt(Ja(Xa(d),(r||[]).filter(ls))),f={schemaVersion:ve,host:i||void 0,frameworkVersion:t??s.frameworkVersion,manifest:p};a!==void 0&&(f.namePrefix=a),c!==void 0&&(f.pluginPath=c),s.vendored!==void 0&&(f.vendored=s.vendored),s.mcp!==void 0&&(f.mcp=s.mcp),s.readAccessPaths!==void 0&&(f.readAccessPaths=s.readAccessPaths);let m=new Set([...ds,"schemaVersion","host","frameworkVersion","manifest","namePrefix","pluginPath","vendored","mcp","readAccessPaths"]);for(let[h,g]of Object.entries(s))m.has(h)||(f[h]=g);return await T(e,f),f}async function Pr(e,t){let r=await x(e);return!!(J(r).some(s=>s.host===t&&!Ne.has(s.category))||t==="claude"&&r.claude||t==="copilot"&&Array.isArray(r.paths)&&r.paths.length>0)}async function xt(e){let t=await x(e),n=J(t).find(s=>s.path===".vscode/settings.json"&&s.category==="settings");return n&&Array.isArray(n.owns?.entries)&&n.owns.entries.length?[...n.owns.entries]:Array.isArray(t.paths)?[...t.paths]:[]}var ve,z,et,Ho,Ft,Yy,Wo,on,id,za,Ya,Ne,ds,te=Z(()=>{H();U();Ye();be();fe();ve=2,z=["claude","copilot"],et="This workspace carries both Copilot and Claude targets from a pre-2.0 install. Vesper 2.0 uses a single host per workspace \u2014 run `vespercli init --host <claude|copilot>` to choose one, or pass an explicit `--target claude|copilot`.",Ho="This workspace carries both Copilot and Claude targets from a pre-2.0 install. Vesper 2.0 uses a single host per workspace \u2014 run `vespercli init --host <claude|copilot>` to choose one, or `vespercli reset --host <claude|copilot>` to remove one host's artifacts.",Ft={"catalog-agent":{ownership:"whole-file",doctor:"content-hash"},"catalog-command":{ownership:"whole-file",doctor:"content-hash"},"catalog-skill":{ownership:"whole-file",doctor:"existence"},playbook:{ownership:"whole-file",doctor:"content-hash"},"pack-rule":{ownership:"whole-file",doctor:"existence"},"vendored-body":{ownership:"whole-file",doctor:"existence"},"vendored-activation":{ownership:"whole-file",doctor:"content-hash"},"per-project-authored":{ownership:"whole-file",doctor:"existence"},"mcp-config":{ownership:"key",doctor:"server-drift"},settings:{ownership:"key",doctor:"key-presence"},pointer:{ownership:"region",doctor:"region-presence"},hook:{ownership:"region",doctor:"region-presence"},gitignore:{ownership:"region",doctor:"region-presence"},"bootstrap-task":{ownership:"key",doctor:"key-presence"},"guard-trigger":{ownership:"key",doctor:"key-presence"},"added-asset":{ownership:"whole-file",doctor:"existence"},"opencode-agent":{ownership:"whole-file",doctor:"existence"},"opencode-overlay":{ownership:"whole-file",doctor:"existence"},"opencode-config":{ownership:"key",doctor:"key-presence"}},Yy=new Set(Object.entries(Ft).filter(([,e])=>e.doctor==="content-hash").map(([e])=>e));Wo=e=>Uo(e,"frameworkVersion"),on=async e=>await Uo(e,"namePrefix")??"",id=e=>Uo(e,"pluginPath"),za="manifestProvenance",Ya="granular";Ne=new Set(["per-project-authored"]);ds=Object.freeze(["paths","claude","addedAt","workspaceType","settingsPath","updatedAt","catalogVersion","targets"])});import{readdir as Qa}from"node:fs/promises";import{join as ps}from"node:path";function md(e){let t=[],r=null;return{text:String(e||"").split(`
43
+ `).filter(s=>{if(!/^\s*\|/.test(s))return r=null,!0;let o=yd(s);if(wd(o))return!0;if(r===null)return r=o.map((i,a)=>/agent/i.test(i)?a:-1).filter(i=>i>=0),!0;for(let i of r){let a=gd.exec(o[i]||"")?.[2],c=a?ln(a).name:null;if(c&&Object.hasOwn(Bo,c))return t.push({role:(o[0]||"").trim(),agent:c,replacement:Bo[c]}),!1}return!0}).join(`
44
+ `),removed:t}}function Le(e){return`${Dt}-${e}`}async function fd(e){try{return(await Qa(e)).filter(t=>t.endsWith(".md")).map(t=>t.slice(0,-3))}catch{return[]}}async function hd(e){try{return(await Qa(e,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name)}catch{return[]}}async function At(e=O){let t={agents:new Set,skills:new Set,agentPlugin:new Map,skillPlugin:new Map,agentPack:new Map,skillPack:new Map},r=(s,o,i,a)=>{t[s].add(o);let c=s==="agents"?t.agentPlugin:t.skillPlugin,l=s==="agents"?t.agentPack:t.skillPack;c.has(o)||(c.set(o,i),l.set(o,a))};for(let s of await fd(ps(e,"claude","agents")))r("agents",s,Dt,"core");for(let s of await hd(ps(e,"claude","skills")))r("skills",s,Dt,"core");let n=[];try{n=(await Qa(ps(e,"claude","packs"),{withFileTypes:!0})).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>s.name).sort()}catch{n=[]}for(let s of n){let o=Le(s);for(let i of await fd(ps(e,"claude","packs",s,"agents")))r("agents",i,o,s);for(let i of await hd(ps(e,"claude","packs",s,"skills")))r("skills",i,o,s)}return t}function yd(e){return e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|")}function wd(e){return e.every(t=>/^:?-{2,}:?$/.test(t.trim()))}function vd(e,t,r){let n=null;return e.split(`
45
+ `).map(s=>{if(!/^\s*\|/.test(s))return n=null,s;let o=yd(s);if(wd(o))return s;if(n===null)return n=o.map((c,l)=>t.test(c)?l:-1).filter(c=>c>=0),s;let i=!1;for(let c of n){if(o[c]===void 0)continue;let l=r(o[c]);l!==null&&l!==o[c]&&(o[c]=l,i=!0)}return i?`${/^\s*/.exec(s)[0]}|${o.join("|")}|`:s}).join(`
46
+ `)}function Za(e,t){return vd(e,/agent/i,r=>{let n=gd.exec(r);if(!n)return null;let s=t(n[2]);return!s||s===n[2]?null:n[1]+s+r.slice(n[0].length)})}function ln(e){let t=e.lastIndexOf(":");return t===-1?{plugin:null,name:e}:{plugin:e.slice(0,t),name:e.slice(t+1)}}function kd(e,t){let r=new Set;return Za(e,n=>(!n.includes(":")&&t.has(n)&&r.add(n),null)),[...r].sort()}function zo(e,t,{skip:r=new Set}={}){let n=t instanceof Set?t:t.agents,s=a=>t instanceof Set?Dt:t.agentPlugin?.get(a)??Dt,o=new Set;return{text:Za(e,a=>{let{plugin:c,name:l}=ln(a);if(!n.has(l)||r.has(l))return null;let d=s(l);return c===d||c!==null&&!(c===Dt||c.startsWith(`${Dt}-`))?null:(o.add(l),`${d}:${l}`)}),qualified:[...o].sort()}}function Sd(e){return String(e||"").replace(/<!--[\s\S]*?-->/g,"")}function Ed(e){let t=new Set;return Za(Sd(e),r=>(t.add(ln(r).name),null)),[...t].sort()}function bd(e){let t=new Set;return vd(Sd(e),/skill/i,r=>{for(let n of r.split(",")){let s=n.trim().replace(/^`|`$/g,"").trim();if(!s||s==="\u2014"||s==="-"||s==="\u2013")continue;let o=/^\/?(?:[a-z0-9-]+:)?([a-z0-9][a-z0-9-]*)$/i.exec(s);o&&t.add(o[1].toLowerCase())}return null}),[...t].sort()}var Bo,Dt,gd,un=Z(()=>{Ee();Bo=Object.freeze({"history-logger":"vespercli log (the run ledger)"});Dt="vesper";gd=/^(\s*`?)([a-z0-9:-]+)/});import{readFile as xd}from"node:fs/promises";import{join as fs,dirname as Zy}from"node:path";function Ad(){return Object.keys(ec).sort()}function Ir(e){return Object.prototype.hasOwnProperty.call(ec,e)}function ms(e,t){return ec[e]?.[t]??null}function tc(e,t){if(e!=="styles"||!ms(e,t))return null;let n=["# Vesper styles (always on)","","This project enables the `vesper-styles` pack. Apply the `i-have-adhd` output style and the",`\`ponytail\` decision ladder on every reply: ${t==="claude"?"load `/vesper-styles:i-have-adhd` and `/vesper-styles:ponytail` at session start":"read the `i-have-adhd` and `ponytail` skills under the pack's injected `skills/` location at session start"}, and keep both in effect for the`,`whole session (until the user says "normal mode"). Safety, correctness and the harness's own`,"instructions always outrank either style.","","Written by Vesper (`vespercli packs enable styles`); `vespercli packs disable styles` removes it.",""].join(`
47
47
  `);return t==="claude"?n:`---
48
48
  applyTo: '**'
49
49
  description: 'Vesper styles pack \u2014 apply the i-have-adhd output style and the ponytail decision ladder on every reply.'
50
50
  ---
51
51
 
52
- ${n}`}async function Bu(e,t,r){return(await ae(e)).find(n=>n.host===t&&n.path===r&&n.category===es)||null}async function iy(e,t,r){let n=await x(e),s=q(n),o=s.filter(i=>!(i.host===t&&i.path===r&&i.category===es));return o.length===s.length?!1:(n.manifest=mt(o),await I(e,n),!0)}async function zu(e,t,r){let n=ts(r,t);if(!n)return null;let s=Ta(r,t),o=Zn(e,n),i=async()=>B(e,[D({path:n,host:t,category:es,hash:qn(s)})]),a=null;try{a=await Wu(o)}catch{a=null}if(a===null)return await T(oy(o),{recursive:!0}),await C(o,s,"utf-8"),await i(),{path:n,status:"created"};if(me(a,s))return await i(),{path:n,status:"unchanged"};let c=await Bu(e,t,n);return c?.hash&&await ge(o)===c.hash?(await C(o,s,"utf-8"),await i(),{path:n,status:"updated"}):{path:n,status:"kept-edited"}}async function Pa(e,t,r){let n=ts(r,t);if(!n)return null;let o=await Bu(e,t,n)??{path:n,category:es,hash:null},i=await ie(Zn(e,n),o,{expected:[Ta(r,t)]});return await iy(e,t,n),{path:n,status:i==="partial"?"kept":i}}async function $o(e,t){let r={removed:[],kept:[]};for(let n of Ku()){let s=await Pa(e,t,n);s?.status==="removed"?r.removed.push(s.path):s?.status==="kept"&&r.kept.push(s.path)}return r}async function Ju(e,t){let r=[];for(let n of Ku()){let s=ts(n,t);if(!s||!await w(Zn(e,s)))continue;let o=null;try{o=await Wu(Zn(e,s))}catch{o=null}!o||!me(o,Ta(n,t))||r.push(D({path:s,host:t,category:es,hash:await ge(Zn(e,s))}))}return r}function Ia(e){return`Kept your edited ${e} \u2014 Vesper never overwrites or deletes a file that differs from what it wrote. Delete it by hand to take Vesper's version.`}var es,Oa,Zr=ee(()=>{U();H();te();qe();ye();es="pack-rule",Oa=Object.freeze({styles:Object.freeze({claude:".claude/rules/vesper-styles.md",copilot:Pe("vesper-styles")})})});import{readFile as Oo,readdir as ay}from"node:fs/promises";import{join as tn,dirname as qu,basename as cy}from"node:path";import{spawnSync as Xu}from"node:child_process";function my(e,t=[]){let r=typeof e?.packageManager=="string"?e.packageManager.trim().split("@")[0]:"";if(fy.includes(r))return r;let n=new Set(t);for(let[s,o]of hy)if(n.has(s))return o;return"npm"}function gy(e,t){switch(e){case"pnpm":return`pnpm ${t}`;case"yarn":return`yarn ${t}`;case"bun":return`bun run ${t}`;default:return t==="test"?"npm test":`npm run ${t}`}}function yy(e,t="npm"){let r=[];if(!e||typeof e!="object")return r;for(let n of py){let s=n.candidates.find(o=>typeof e[o]=="string"&&e[o].trim()!=="");s&&r.push({name:s,command:gy(t,s),detected:!0})}return r}function wy(e,t=[]){return{schemaVersion:Ra,checks:yy(e?.scripts,my(e,t)),diffSizeCap:{...Qu},protectedPaths:[]}}async function To(e){let t=tn(e,ce);if(await w(t))return{created:!1,path:ce,checks:[]};let r=null;try{r=JSON.parse(await Oo(tn(e,"package.json"),"utf-8"))}catch{r=null}let n=[];try{n=await ay(e)}catch{n=[]}let s=wy(r,n);return await T(qu(t),{recursive:!0}),await C(t,`${JSON.stringify(s,null,2)}
53
- `,"utf-8"),{created:!0,path:ce,checks:s.checks.map(o=>o.name)}}function vy(e){let t=[];if(!e||typeof e!="object"||Array.isArray(e))return["config is not an object"];e.schemaVersion!==Ra&&t.push(`schemaVersion must be ${Ra}`),Array.isArray(e.checks)?e.checks.forEach((n,s)=>{if(!n||typeof n!="object"){t.push(`checks[${s}] is not an object`);return}(typeof n.name!="string"||!n.name.trim())&&t.push(`checks[${s}].name must be a non-empty string`),(typeof n.command!="string"||!n.command.trim())&&t.push(`checks[${s}].command must be a non-empty string`)}):t.push("checks must be an array");let r=e.diffSizeCap;if(r!==void 0)if(!r||typeof r!="object")t.push("diffSizeCap must be an object");else for(let n of["files","lines"])r[n]!==void 0&&!(Number.isInteger(r[n])&&r[n]>=0)&&t.push(`diffSizeCap.${n} must be a non-negative integer`);return e.protectedPaths!==void 0&&(!Array.isArray(e.protectedPaths)||e.protectedPaths.some(n=>typeof n!="string"))&&t.push("protectedPaths must be an array of strings"),t}async function Zu(e){let t;try{t=await Oo(tn(e,ce),"utf-8")}catch{return{ok:!1,reason:"missing",errors:[`${ce} not found`]}}let r;try{r=JSON.parse(t)}catch(s){return{ok:!1,reason:"invalid",errors:[`${ce} is not valid JSON: ${s.message}`]}}let n=vy(r);return n.length?{ok:!1,reason:"invalid",errors:n}:{ok:!0,config:{...r,diffSizeCap:{...Qu,...r.diffSizeCap||{}},protectedPaths:r.protectedPaths||[]}}}function Yu(e){let t=String(e).trim().replace(/^`+|`+$/g,"").replace(/^\*\*|\*\*$/g,"");if(t=t.replace(/[:,;)\]}.]+$/g,""),t=t.replace(/^\.\//,""),!t||/\s/.test(t)||/^(https?:|www\.|--|-)/.test(t))return null;let r=t.endsWith("/"),n=r?t.slice(0,-1):t;return!ky.test(n)||!r&&!n.includes("/")&&!Sy.test(n)||/^\.+$/.test(n)?null:r?`${n}/`:n}function Ay(e){let t=new Set,r=String(e||"");for(let i of r.matchAll(/`([^`\n]+)`/g)){let a=Yu(i[1]);a&&t.add(a)}let n=r.split(/\r?\n/),s=!1,o=-1;for(let i of n){if(Ey.test(i)){s=!0,o=-1;continue}if(!s)continue;if(!i.trim()){o>=0&&(s=!1);continue}if(by.test(i)||xy.test(i)){s=!1;continue}let a=_y.exec(i);if(!a){o>=0&&(s=!1);continue}let c=i.length-i.trimStart().length;if(o<0)o=c;else if(c<o){s=!1;continue}let l=a[1].trim().split(/\s+/)[0],d=Yu(l);d&&t.add(d)}return[...t].sort()}function Cy(e){let t=cy(e);if(!/-plan\.md$/i.test(t))return[];let r=t.replace(/-plan\.md$/i,"-details.md"),n=qu(e);return[tn(n,"..","details",r),tn(n,r)]}async function ed(e){let t=[e];for(let s of Cy(e))if(await w(s)){t.push(s);break}let r=await Promise.all(t.map(s=>Oo(s,"utf-8"))),n=new Set;for(let s of r)for(let o of Ay(s))n.add(o);return{planned:[...n].sort(),sources:t}}function $y(e,t){for(let r of t)if(r===e||r.endsWith("/")&&e.startsWith(r))return!0;return!1}function Oy(e,t){let r=e.filter(n=>!n.startsWith(uy)).filter(n=>!$y(n,t)).sort();return{planned:[...t].sort(),unplanned:r,skipped:null}}function Ty(e){if(ja.has(e))return ja.get(e);let t=String(e).replace(/^\.\//,"").replace(/\/+$/,""),r="";for(let s=0;s<t.length;s+=1){let o=t[s];o==="*"?t[s+1]==="*"?t[s+2]==="/"?(r+="(?:.*/)?",s+=2):(r+=".*",s+=1):r+="[^/]*":o==="?"?r+="[^/]":r+=o.replace(/[.+^${}()|[\]\\]/g,"\\$&")}let n=new RegExp(`^${r}(?:/.*)?$`);return ja.set(e,n),n}function Py(e,t){return Ty(t).test(String(e).replace(/^\.\//,""))}function Iy(e,t){return t?.length?e.filter(r=>t.some(n=>Py(r,n))).sort():[]}function td({config:e,checks:t,diff:r,planned:n,diffSkipped:s=null}){let o=[],i=t.map(p=>({name:p.name,command:p.command,exitCode:p.exitCode,durationMs:p.durationMs,tail:p.tail||[]}));for(let p of i)p.exitCode!==0&&o.push(`${p.name} exit ${p.exitCode===null?"signal":p.exitCode}`);let a={files:e.diffSizeCap.files,lines:e.diffSizeCap.lines},c,l,d=[];if(r)n===null?c={planned:[],unplanned:[],skipped:"no --plan given"}:(c=Oy(r.changed,n),c.unplanned.length&&o.push(`unplanned files: ${c.unplanned.join(", ")}`)),l={files:r.changed.length,lines:r.lines,cap:a,skipped:null},l.files>a.files&&o.push(`size ${l.files} files > cap ${a.files}`),l.lines>a.lines&&o.push(`size ${l.lines} lines > cap ${a.lines}`),d=Iy(r.changed,e.protectedPaths),d.length&&o.push(`protected path touched: ${d.join(", ")}`);else{let p=s||"not a git repository";c={planned:n?[...n].sort():[],unplanned:[],skipped:p},l={files:null,lines:null,cap:a,skipped:p}}return{pass:o.length===0,reasons:o,checks:i,plan:c,size:l,protected:d}}function rd(e){let t=[];for(let r of e.checks)if(r.exitCode===0)t.push(`\u2713 ${r.name} (${(r.durationMs/1e3).toFixed(1)}s)`);else{t.push(`\u2717 ${r.name} (${r.exitCode===null?"killed by signal":`exit ${r.exitCode}`})`);for(let n of r.tail)t.push(` ${n}`)}return e.plan.skipped?t.push(`plan: skipped (${e.plan.skipped})`):e.plan.unplanned.length?t.push(`plan: unplanned: ${e.plan.unplanned.join(", ")}`):t.push("plan: ok"),e.size.skipped?t.push(`size: skipped (${e.size.skipped})`):t.push(`size: ${e.size.files} files / ${e.size.lines} lines (cap ${e.size.cap.files} / ${e.size.cap.lines})`),e.size.skipped?t.push(`protected: skipped (${e.size.skipped})`):e.protected.length?t.push(`protected: ${e.protected.join(", ")}`):t.push("protected: ok"),t.push(e.pass?"GATE PASS":`GATE FAIL: ${e.reasons.join("; ")}`),t.join(`
54
- `)}function jy(e,t=ly){let r=String(e||"").replace(/\r\n/g,`
52
+ ${n}`}async function _d(e,t,r){return(await ne(e)).find(n=>n.host===t&&n.path===r&&n.category===hs)||null}async function ew(e,t,r){let n=await x(e),s=J(n),o=s.filter(i=>!(i.host===t&&i.path===r&&i.category===hs));return o.length===s.length?!1:(n.manifest=tt(o),await T(e,n),!0)}async function Cd(e,t,r){let n=ms(r,t);if(!n)return null;let s=tc(r,t),o=fs(e,n),i=async()=>W(e,[G({path:n,host:t,category:hs,hash:us(s)})]),a=null;try{a=await xd(o)}catch{a=null}if(a===null)return await P(Zy(o),{recursive:!0}),await A(o,s,"utf-8"),await i(),{path:n,status:"created"};if(ee(a,s))return await i(),{path:n,status:"unchanged"};let c=await _d(e,t,n);return c?.hash&&await ye(o)===c.hash?(await A(o,s,"utf-8"),await i(),{path:n,status:"updated"}):{path:n,status:"kept-edited"}}async function rc(e,t,r){let n=ms(r,t);if(!n)return null;let o=await _d(e,t,n)??{path:n,category:hs,hash:null},i=await le(fs(e,n),o,{expected:[tc(r,t)]});return await ew(e,t,n),{path:n,status:i==="partial"?"kept":i}}async function Yo(e,t){let r={removed:[],kept:[]};for(let n of Ad()){let s=await rc(e,t,n);s?.status==="removed"?r.removed.push(s.path):s?.status==="kept"&&r.kept.push(s.path)}return r}async function $d(e,t){let r=[];for(let n of Ad()){let s=ms(n,t);if(!s||!await w(fs(e,s)))continue;let o=null;try{o=await xd(fs(e,s))}catch{o=null}!o||!ee(o,tc(n,t))||r.push(G({path:s,host:t,category:hs,hash:await ye(fs(e,s))}))}return r}function nc(e){return`Kept your edited ${e} \u2014 Vesper never overwrites or deletes a file that differs from what it wrote. Delete it by hand to take Vesper's version.`}var hs,ec,dn=Z(()=>{U();H();te();Ye();fe();hs="pack-rule",ec=Object.freeze({styles:Object.freeze({claude:".claude/rules/vesper-styles.md",copilot:Ie("vesper-styles")})})});import{accessSync as tw,constants as rw,statSync as Td,readFileSync as nw,existsSync as sw}from"node:fs";import{readFile as ws}from"node:fs/promises";import{spawn as Pd}from"node:child_process";import{join as ar,delimiter as ow}from"node:path";function Id(){return[Jo,...lw,qo].join(`
53
+ `)}function ic(){return[gs,"# Vesper graphify pack: refresh the code knowledge graph (graphify-out/graph.json) after an",`# attached branch checkout. No-op without the graphify tool on PATH (\`${Xo}\`),`,"# honours `git config vesper.hooks false`, never fails the checkout. Removed by","# `vespercli packs disable graphify`.",'if [ "$3" = "1" ] && [ "$(git config --type=bool --get vesper.hooks 2>/dev/null)" != "false" ] \\'," && command -v graphify >/dev/null 2>&1 && git symbolic-ref -q HEAD >/dev/null 2>&1; then",` ${Ge} >/dev/null 2>&1 || true`,"fi",ys].join(`
54
+ `)}function ac(e,t,r){let n=e.indexOf(t);if(n===-1)return null;let s=e.indexOf(r,n);return s===-1?null:{start:n,end:s+r.length}}function Qo(e,t,r){let n=ac(e,t,r);return n?e.slice(n.start,n.end):null}function cc(e,t,r){let n=ac(e,t,r);if(!n)return null;let{start:s,end:o}=n;return s>0&&e[s-1]===`
55
+ `&&(s-=1),e[o]===`
56
+ `&&(o+=1),e.slice(0,s)+e.slice(o)}async function jd(e,{path:t,host:r,category:n,region:s}){await W(e,[Y({path:t,host:r,category:n,owns:{region:s}})])}async function Rd(e,{host:t,category:r,region:n}){let s=await x(e),o=J(s),i=o.filter(a=>!(a.host===t&&a.category===r&&a.owns?.region===n));return i.length===o.length?!1:(s.manifest=tt(i),await T(e,s),!0)}async function uw(e,t){return(await ne(e)).find(r=>r.host===t&&r.category==="hook"&&r.owns?.region===pn)||null}async function fn(e,t){if(t==="claude")try{let n=JSON.parse(await ws(ar(e,It),"utf-8"))?.enabledPlugins;return!n||typeof n!="object"||Array.isArray(n)?!1:Object.entries(n).some(([s,o])=>o===!0&&Sr(s)===Me)}catch{return!1}if(t==="copilot"){let r=await K(e);return rr(Me).some(({path:n,settingKey:s})=>r[s]?.[n]===!0)}return!1}async function dw(e,t){let r=".gitignore",n=ar(e,r),s=Id(),o=()=>jd(e,{path:r,host:t,category:"gitignore",region:vs}),i=null;try{i=await ws(n,"utf-8")}catch(l){if(l.code!=="ENOENT")throw l}if(i===null)return await A(n,`${s}
57
+ `,"utf-8"),await o(),{path:r,status:"created"};let a=Qo(i,Jo,qo);if(a!==null)return await o(),ee(a,s)?{path:r,status:"unchanged"}:{path:r,status:"kept-edited"};let c=i.endsWith(`
58
+ `)?`
59
+ `:`
60
+
61
+ `;return await A(n,`${i}${c}${s}
62
+ `,"utf-8"),await o(),{path:r,status:"updated"}}async function pw(e,t){let r=".gitignore",n=ar(e,r);await Rd(e,{host:t,category:"gitignore",region:vs});let s=null;try{s=await ws(n,"utf-8")}catch{s=null}if(s===null)return{path:r,status:"absent"};let o=Qo(s,Jo,qo);if(o===null)return{path:r,status:"absent"};if(!ee(o,Id()))return{path:r,status:"kept"};let i=cc(s,Jo,qo);return await A(n,i,"utf-8"),{path:r,status:"removed"}}async function Nd(e){let t=await nr(e);if(!t.dir)return{path:null,reason:t.reason||"not-installable"};let r=ar(t.dir,cw),n=await tn(r);if(!n.path)return{path:null,reason:n.reason};let s=await at(n.path);return kt(s,t.roots)?await tr(s,t)?{path:null,reason:"tracked-by-git"}:{path:n.path}:{path:null,reason:"outside-repository"}}async function fw(e,t){let r=await Nd(e);if(!r.path)return{path:null,status:"skipped",reason:r.reason};let n=null;try{n=await ws(r.path)}catch{n=null}if(n===null)return{path:r.path,status:"skipped",reason:"hook-missing"};let s=n.toString("latin1"),o=ac(s,ot,Yt);if(!o)return{path:r.path,status:"skipped",reason:"vesper-block-missing"};let i=Buffer.from(ic(),"utf-8").toString("latin1"),a=()=>jd(e,{path:r.path,host:t,category:"hook",region:pn}),c=Qo(s,gs,ys);if(c!==null)return await a(),ee(Buffer.from(c,"latin1"),ic())?{path:r.path,status:"unchanged"}:{path:r.path,status:"kept-edited"};let l=o.end;s[l]===`
63
+ `&&(l+=1);let d=`${s.slice(0,l)}
64
+ ${i}
65
+ ${s.slice(l)}`;return await vt(r.path,Buffer.from(d,"latin1")),await a(),{path:r.path,status:"created"}}async function hw(e,t){let r=await uw(e,t);await Rd(e,{host:t,category:"hook",region:pn});let n=[];r?.path&&n.push(r.path);let s=await Nd(e);s.path&&!n.includes(s.path)&&n.push(s.path);for(let o of n){let i=null;try{i=await ws(o)}catch{continue}let a=i.toString("latin1"),c=Qo(a,gs,ys);if(c!==null){if(!ee(Buffer.from(c,"latin1"),ic()))return{path:o,status:"kept"};if(o===s.path)return await vt(o,Buffer.from(cc(a,gs,ys),"latin1")),{path:o,status:"removed"}}}return{path:n[0]??null,status:"absent"}}function Ld(e){return cc(e,gs,ys)}async function ks(e,t){return{gitignore:await dw(e,t),hook:await fw(e,t)}}async function hn(e,t){let r=await pw(e,t),n=await hw(e,t),s=[];return r.status==="kept"&&s.push(r.path),n.status==="kept"&&n.path&&s.push(n.path),{gitignore:r,hook:n,kept:s}}function Ss(e){return`Kept the edited graphify block in ${e} \u2014 Vesper never deletes a block that differs from what it wrote. Remove the \`${vs}\` / \`${pn}\` markers by hand to drop it.`}function Md({plan:e=mn(),onPath:t=!!dt()}={}){let r=`run \`${Ge}\` to build the graph (${xe} is committed and shared; the post-checkout hook keeps it fresh)`,n=Gd.map(o=>`\`${o.command}\``).join(" / ");return[t?`graphify found on PATH \u2014 ${r}.`:e.command?`graphify is an external tool: install it with \`${e.command}\` (routes: ${n}), then ${r}.`:`graphify is an external tool: ${e.hint} Then ${r}.`,"Code never leaves the machine; a code-only build costs 0 tokens. Doc/PDF extraction and community labels call an LLM (`--no-label` skips the labels)."]}function mn({env:e=process.env,which:t=r=>lc(r,e)}={}){for(let r of Gd){let n=r.needs.find(i=>t(i));if(!n)continue;let s=r.argv.map(i=>i.replace("${python}",n)),o=s.join(" ");return{tool:r.tool,command:o,argv:s,hint:`Install graphify with \`${o}\`, then run \`${Ge}\`.`}}return{tool:null,command:null,argv:null,hint:`No uv, pipx or python on PATH \u2014 install uv first (\`${iw}\`, or \`pip install uv\`), then \`${Xo}\`.`}}function Zo(e=mn()){return e.command??e.hint}function Fd(e,{spawn:t=Pd}={}){return e?.argv?.length?new Promise(r=>{let n;try{n=t(e.argv[0],e.argv.slice(1),{stdio:"inherit",shell:process.platform==="win32"})}catch(s){return r({ok:!1,code:null,error:s?.message||String(s)})}n.on("error",s=>r({ok:!1,code:null,error:s?.message||String(s)})),n.on("close",s=>r({ok:s===0,code:s}))}):Promise.resolve({ok:!1,code:null,error:"no install command for this machine"})}function Dd(e,{spawn:t=Pd,env:r=process.env}={}){let[n,...s]=Ge.split(" ");return new Promise(o=>{let i;try{i=t(n,s,{cwd:e,env:r,stdio:"inherit",shell:process.platform==="win32"})}catch(a){return o({ok:!1,code:null,error:a?.message||String(a)})}i.on("error",a=>o({ok:!1,code:null,error:a?.message||String(a)})),i.on("close",a=>o({ok:a===0,code:a}))})}function Vd(e){return sw(ar(e,xe))}function Hd(e,{env:t=process.env,which:r=n=>lc(n,t)}={}){try{let n=nw(ar(e,aw),"utf-8").split(/\r?\n/)[0].trim();if(n&&Td(n).isFile())return n}catch{}return r("python3")?"python3":r("python")?"python":"python3"}function dt(e=process.env){return lc("graphify",e)}function lc(e,t=process.env){let r=t.PATH??t.Path??"",n=process.platform==="win32"?(t.PATHEXT||".EXE;.CMD;.BAT;.COM").split(";"):[""];for(let s of r.split(ow).filter(Boolean))for(let o of n){let i=ar(s,`${e}${o}`);try{if(!Td(i).isFile())continue;return process.platform!=="win32"&&tw(i,rw.X_OK),i}catch{}}return null}async function Ud(e){let t=ar(e,xe);if(!await w(t))return{present:!1,commit:null,key:null};let r="";try{let{open:s}=await import("node:fs/promises"),o=await s(t,"r");try{let i=Buffer.alloc(65536),{bytesRead:a}=await o.read(i,0,i.length,0);r=i.subarray(0,a).toString("utf-8")}finally{await o.close()}}catch{return{present:!0,commit:null,key:null}}let n=mw(r);return{present:!0,commit:n?.commit??null,key:n?.key??null}}function oc(e,t){if(!e||typeof e!="object"||Array.isArray(e))return null;for(let[r,n]of Object.entries(e))if(/commit/i.test(r)){if(typeof n=="string"&&Od.test(n.trim()))return{key:t?`${t}.${r}`:r,commit:n.trim()};if(n&&typeof n=="object"&&!Array.isArray(n)){for(let[s,o]of Object.entries(n))if(typeof o=="string"&&Od.test(o.trim()))return{key:`${t?`${t}.`:""}${r}.${s}`,commit:o.trim()}}}return null}function mw(e){let t=null;try{t=JSON.parse(e)}catch{t=null}if(t&&typeof t=="object")return oc(t,"")||oc(t.graph,"graph")||oc(t.metadata,"metadata");let r=e.match(/"([A-Za-z0-9_.-]*commit[A-Za-z0-9_.-]*)"\s*:\s*"([0-9a-fA-F]{7,40})"/i);return r?{key:r[1],commit:r[2]}:null}var Me,Vt,xe,Xo,sc,iw,aw,Ge,cw,vs,pn,Jo,qo,gs,ys,lw,Gd,Od,pt=Z(()=>{U();H();te();Ye();fe();Wr();Me="graphify",Vt="graphify",xe="graphify-out/graph.json",Xo="uv tool install graphifyy",sc="graphifyy",iw="curl -LsSf https://astral.sh/uv/install.sh | sh",aw="graphify-out/.graphify_python",Ge="graphify update .",cw="post-checkout",vs="vesper:gitignore:graphify",pn="vesper:hook:graphify",Jo=`# <!-- ${vs}:start -->`,qo=`# <!-- ${vs}:end -->`,gs=`# <!-- ${pn}:start -->`,ys=`# <!-- ${pn}:end -->`,lw=Object.freeze(["graphify-out/*",`!${xe}`]);Gd=Object.freeze([Object.freeze({tool:"uv",needs:["uv"],argv:Object.freeze(["uv","tool","install",sc])}),Object.freeze({tool:"pipx",needs:["pipx"],argv:Object.freeze(["pipx","install",sc])}),Object.freeze({tool:"pip",needs:["python3","python"],argv:Object.freeze(["${python}","-m","pip","install","--user",sc])})].map(e=>({...e,command:e.argv.join(" ").replace("${python}","python3")})));Od=/^[0-9a-f]{7,40}$/i});import{readFile as ei,readdir as gw}from"node:fs/promises";import{join as yn,dirname as Kd,basename as yw}from"node:path";import{spawnSync as Bd}from"node:child_process";function xw(e,t=[]){let r=typeof e?.packageManager=="string"?e.packageManager.trim().split("@")[0]:"";if(Ew.includes(r))return r;let n=new Set(t);for(let[s,o]of bw)if(n.has(s))return o;return"npm"}function Aw(e,t){switch(e){case"pnpm":return`pnpm ${t}`;case"yarn":return`yarn ${t}`;case"bun":return`bun run ${t}`;default:return t==="test"?"npm test":`npm run ${t}`}}function _w(e,t="npm"){let r=[];if(!e||typeof e!="object")return r;for(let n of Sw){let s=n.candidates.find(o=>typeof e[o]=="string"&&e[o].trim()!=="");s&&r.push({name:s,command:Aw(t,s),detected:!0})}return r}function Cw(e,t=[]){return{schemaVersion:dc,checks:_w(e?.scripts,xw(e,t)),diffSizeCap:{...zd},protectedPaths:[]}}async function ti(e){let t=yn(e,ue);if(await w(t))return{created:!1,path:ue,checks:[]};let r=null;try{r=JSON.parse(await ei(yn(e,"package.json"),"utf-8"))}catch{r=null}let n=[];try{n=await gw(e)}catch{n=[]}let s=Cw(r,n);return await P(Kd(t),{recursive:!0}),await A(t,`${JSON.stringify(s,null,2)}
66
+ `,"utf-8"),{created:!0,path:ue,checks:s.checks.map(o=>o.name)}}function $w(e){let t=[];if(!e||typeof e!="object"||Array.isArray(e))return["config is not an object"];e.schemaVersion!==dc&&t.push(`schemaVersion must be ${dc}`),Array.isArray(e.checks)?e.checks.forEach((n,s)=>{if(!n||typeof n!="object"){t.push(`checks[${s}] is not an object`);return}(typeof n.name!="string"||!n.name.trim())&&t.push(`checks[${s}].name must be a non-empty string`),(typeof n.command!="string"||!n.command.trim())&&t.push(`checks[${s}].command must be a non-empty string`)}):t.push("checks must be an array");let r=e.diffSizeCap;if(r!==void 0)if(!r||typeof r!="object")t.push("diffSizeCap must be an object");else for(let n of["files","lines"])r[n]!==void 0&&!(Number.isInteger(r[n])&&r[n]>=0)&&t.push(`diffSizeCap.${n} must be a non-negative integer`);return e.protectedPaths!==void 0&&(!Array.isArray(e.protectedPaths)||e.protectedPaths.some(n=>typeof n!="string"))&&t.push("protectedPaths must be an array of strings"),t}async function Yd(e){let t;try{t=await ei(yn(e,ue),"utf-8")}catch{return{ok:!1,reason:"missing",errors:[`${ue} not found`]}}let r;try{r=JSON.parse(t)}catch(s){return{ok:!1,reason:"invalid",errors:[`${ue} is not valid JSON: ${s.message}`]}}let n=$w(r);return n.length?{ok:!1,reason:"invalid",errors:n}:{ok:!0,config:{...r,diffSizeCap:{...zd,...r.diffSizeCap||{}},protectedPaths:r.protectedPaths||[]}}}function Wd(e){let t=String(e).trim().replace(/^`+|`+$/g,"").replace(/^\*\*|\*\*$/g,"");if(t=t.replace(/[:,;)\]}.]+$/g,""),t=t.replace(/^\.\//,""),!t||/\s/.test(t)||/^(https?:|www\.|--|-)/.test(t))return null;let r=t.endsWith("/"),n=r?t.slice(0,-1):t;return!Ow.test(n)||!r&&!n.includes("/")&&!Tw.test(n)||/^\.+$/.test(n)?null:r?`${n}/`:n}function Nw(e){let t=new Set,r=String(e||"");for(let i of r.matchAll(/`([^`\n]+)`/g)){let a=Wd(i[1]);a&&t.add(a)}let n=r.split(/\r?\n/),s=!1,o=-1;for(let i of n){if(Pw.test(i)){s=!0,o=-1;continue}if(!s)continue;if(!i.trim()){o>=0&&(s=!1);continue}if(Iw.test(i)||jw.test(i)){s=!1;continue}let a=Rw.exec(i);if(!a){o>=0&&(s=!1);continue}let c=i.length-i.trimStart().length;if(o<0)o=c;else if(c<o){s=!1;continue}let l=a[1].trim().split(/\s+/)[0],d=Wd(l);d&&t.add(d)}return[...t].sort()}function Lw(e){let t=yw(e);if(!/-plan\.md$/i.test(t))return[];let r=t.replace(/-plan\.md$/i,"-details.md"),n=Kd(e);return[yn(n,"..","details",r),yn(n,r)]}async function Jd(e){let t=[e];for(let s of Lw(e))if(await w(s)){t.push(s);break}let r=await Promise.all(t.map(s=>ei(s,"utf-8"))),n=new Set;for(let s of r)for(let o of Nw(s))n.add(o);return{planned:[...n].sort(),sources:t}}function Mw(e,t){for(let r of t)if(r===e||r.endsWith("/")&&e.startsWith(r))return!0;return!1}function Gw(e,t){let r=e.filter(n=>!n.startsWith(vw)).filter(n=>!Mw(n,t)).sort();return{planned:[...t].sort(),unplanned:r,skipped:null}}function Fw(e){if(uc.has(e))return uc.get(e);let t=String(e).replace(/^\.\//,"").replace(/\/+$/,""),r="";for(let s=0;s<t.length;s+=1){let o=t[s];o==="*"?t[s+1]==="*"?t[s+2]==="/"?(r+="(?:.*/)?",s+=2):(r+=".*",s+=1):r+="[^/]*":o==="?"?r+="[^/]":r+=o.replace(/[.+^${}()|[\]\\]/g,"\\$&")}let n=new RegExp(`^${r}(?:/.*)?$`);return uc.set(e,n),n}function Dw(e,t){return Fw(t).test(String(e).replace(/^\.\//,""))}function Vw(e,t){return t?.length?e.filter(r=>t.some(n=>Dw(r,n))).sort():[]}function qd({config:e,checks:t,diff:r,planned:n,diffSkipped:s=null}){let o=[],i=t.map(p=>({name:p.name,command:p.command,exitCode:p.exitCode,durationMs:p.durationMs,tail:p.tail||[]}));for(let p of i)p.exitCode!==0&&o.push(`${p.name} exit ${p.exitCode===null?"signal":p.exitCode}`);let a={files:e.diffSizeCap.files,lines:e.diffSizeCap.lines},c,l,d=[];if(r)n===null?c={planned:[],unplanned:[],skipped:"no --plan given"}:(c=Gw(r.changed,n),c.unplanned.length&&o.push(`unplanned files: ${c.unplanned.join(", ")}`)),l={files:r.changed.length,lines:r.lines,cap:a,skipped:null},l.files>a.files&&o.push(`size ${l.files} files > cap ${a.files}`),l.lines>a.lines&&o.push(`size ${l.lines} lines > cap ${a.lines}`),d=Vw(r.changed,e.protectedPaths),d.length&&o.push(`protected path touched: ${d.join(", ")}`);else{let p=s||"not a git repository";c={planned:n?[...n].sort():[],unplanned:[],skipped:p},l={files:null,lines:null,cap:a,skipped:p}}return{pass:o.length===0,reasons:o,checks:i,plan:c,size:l,protected:d}}function Xd(e){let t=[];for(let r of e.checks)if(r.exitCode===0)t.push(`\u2713 ${r.name} (${(r.durationMs/1e3).toFixed(1)}s)`);else{t.push(`\u2717 ${r.name} (${r.exitCode===null?"killed by signal":`exit ${r.exitCode}`})`);for(let n of r.tail)t.push(` ${n}`)}return e.plan.skipped?t.push(`plan: skipped (${e.plan.skipped})`):e.plan.unplanned.length?t.push(`plan: unplanned: ${e.plan.unplanned.join(", ")}`):t.push("plan: ok"),e.size.skipped?t.push(`size: skipped (${e.size.skipped})`):t.push(`size: ${e.size.files} files / ${e.size.lines} lines (cap ${e.size.cap.files} / ${e.size.cap.lines})`),e.size.skipped?t.push(`protected: skipped (${e.size.skipped})`):e.protected.length?t.push(`protected: ${e.protected.join(", ")}`):t.push("protected: ok"),t.push(e.pass?"GATE PASS":`GATE FAIL: ${e.reasons.join("; ")}`),t.join(`
67
+ `)}function Hw(e,t=ww){let r=String(e||"").replace(/\r\n/g,`
55
68
  `).split(`
56
- `);for(;r.length&&r[r.length-1]==="";)r.pop();for(;r.length&&r[0]==="";)r.shift();return r.slice(-t)}function nd(e,t){let r=Date.now(),n=Xu("sh",["-c",e.command],{cwd:t,env:process.env,encoding:"utf-8",stdio:["ignore","pipe","pipe"],maxBuffer:64*1024*1024}),s=Date.now()-r,o=`${n.stdout||""}${n.stderr||""}${n.error?`
57
- ${n.error.message}`:""}`,i=n.error&&n.status===null?127:n.status;return{name:e.name,command:e.command,exitCode:i,durationMs:s,tail:jy(o)}}function en(e,t){let r=Xu("git",t,{cwd:e,env:{...process.env,...xt},encoding:"utf-8",stdio:["ignore","pipe","ignore"],maxBuffer:67108864});return{status:r.error?-1:r.status,stdout:r.stdout||""}}async function Ry(e){try{let t=await Oo(e);if(t.includes(0))return 0;let r=0;for(let n of t)n===10&&(r+=1);return t.length&&t[t.length-1]!==10&&(r+=1),r}catch{return 0}}async function sd(e,t){let r=en(e,["rev-parse","--is-inside-work-tree"]);if(r.status!==0||r.stdout.trim()!=="true")return{skipped:"not a git repository"};let n=t;if(!n)n=en(e,["rev-parse","--verify","--quiet","HEAD"]).status===0?"HEAD":dy;else if(en(e,["rev-parse","--verify","--quiet",`${n}^{commit}`]).status!==0)return{skipped:`unknown --base ref "${t}"`};let s=en(e,["diff","--name-only","-z",n,"--"]);if(s.status!==0)return{skipped:`git diff against ${n} failed`};let o=en(e,["diff","--numstat","-z",n,"--"]),i=en(e,["ls-files","--others","--exclude-standard","-z"]),a=new Set(s.stdout.split("\0").filter(Boolean)),c=i.status===0?i.stdout.split("\0").filter(Boolean):[];for(let d of c)a.add(d);let l=0;for(let d of o.stdout.split("\0")){let p=/^(\d+|-)\t(\d+|-)\t?/.exec(d);p&&(p[1]!=="-"&&(l+=Number(p[1])),p[2]!=="-"&&(l+=Number(p[2])))}for(let d of c)l+=await Ry(tn(e,d));return{changed:[...a].sort(),lines:l}}var ce,Ra,Qu,ly,uy,wr,dy,py,fy,hy,ky,Sy,Ey,by,xy,_y,ja,rs=ee(()=>{U();dt();ce=".vesper/gates.json",Ra=1,Qu=Object.freeze({files:40,lines:1500}),ly=30,uy=".vesper/.tracking/",wr=Object.freeze({PASS:0,FAIL:1,NO_CONFIG:2}),dy="4b825dc642cb6eb9a060e54bf8d69288fbee4904",py=Object.freeze([{candidates:["test"]},{candidates:["lint"]},{candidates:["typecheck","tsc","type-check"]},{candidates:["build"]}]),fy=Object.freeze(["npm","pnpm","yarn","bun"]),hy=Object.freeze([["pnpm-lock.yaml","pnpm"],["yarn.lock","yarn"],["bun.lockb","bun"],["bun.lock","bun"],["package-lock.json","npm"]]);ky=/^(?:[\w.@-]+\/)*[\w.@-]+(?:\.[A-Za-z0-9]+)?$/,Sy=/\.[A-Za-z0-9]{1,10}$/;Ey=/^\s*(?:#{1,6}\s*|[-*]\s*\*\*)(?:files?(?:\s+operations?)?|file\s+list)\*{0,2}\s*:?\s*$/i,by=/^\s*#{1,6}\s/,xy=/^\s*[-*]\s*\*\*[^*]+\*\*\s*:?/,_y=/^\s*[-*+]\s+(.*)$/;ja=new Map});import{readFileSync as Ny}from"node:fs";import{join as Ly}from"node:path";function rn(){if(Po)return Po;let e={};try{e=JSON.parse(Ny(My,"utf-8"))}catch{e={}}return Po={files:Na(e.files),playbook:new Set(Array.isArray(e.playbook)?e.playbook.filter(t=>typeof t=="string"):[]),pluginFiles:Na(e.pluginFiles),pluginDescriptions:new Set(Array.isArray(e.pluginManifestDescriptions)?e.pluginManifestDescriptions.filter(t=>typeof t=="string"):[]),vendoredFiles:Na(e.vendoredFiles)},Po}function Dy(e,t){return t?e.replace(/^(name:\s*)([a-z0-9-]+)/m,(r,n,s)=>s.startsWith(t)?`${n}${s.slice(t.length)}`:r):e}function od(e,t,r,n,s){let o=t.toString("utf-8").replace(/\r\n/g,`
58
- `),i=new Set([""]);typeof s=="string"&&s&&i.add(s);for(let a of e.keys()){if(!a.startsWith(`${r}/`))continue;let c=a.slice(r.length+1);if(n.length>c.length&&n.endsWith(c)){let l=n.slice(0,n.length-c.length);/^[a-z0-9-]+$/.test(l)&&i.add(l)}}for(let a of i){if(a&&!n.startsWith(a))continue;let c=e.get(`${r}/${n.slice(a.length)}`);if(c){for(let l of new Set([o,Dy(o,a)]))if(c.has(st(Buffer.from(l,"utf-8"))))return!0}}return!1}function Io(e,t,{namePrefix:r}={}){let n=/^(agents|commands)\/([^/]+\.md)$/.exec(String(t||""));return n?od(rn().files,e,n[1],n[2],r):!1}function id(e){return rn().playbook.has(st(e))}function ad(e){if(!e||e.includes("/")||e.includes(".."))return null;let t=`skills/${e}/`,r={};for(let[n,s]of rn().files)n.startsWith(t)&&(r[n.slice(t.length)]=[...s]);return Object.keys(r).length?r:null}function jo(e,t,r){let{files:n}=rn();return n.has(`${e}/${t}`)?!0:!!r&&t.startsWith(r)&&n.has(`${e}/${t.slice(r.length)}`)}function cd(e,t,{pluginName:r="vesper"}={}){let n=String(t||""),{pluginFiles:s,pluginDescriptions:o}=rn();if(n===".claude-plugin/plugin.json"){let c;try{c=JSON.parse(e.toString("utf-8"))}catch{return!1}return!c||typeof c!="object"||Array.isArray(c)?!1:Object.keys(c).sort().join(",")==="description,name,version"&&c.name===r&&o.has(c.description)&&typeof c.version=="string"}let i=/^(agents|commands)\/([^/]+\.md)$/.exec(n);if(i)return od(s,e,i[1],i[2]);let a=s.get(n);return!!a&&a.has(st(e))}function La(e,t){let r=rn().vendoredFiles.get(String(t||""));return!!r&&r.has(st(e))}var My,Po,Na,ns=ee(()=>{Ee();qe();My=Ly(O,"legacy","claude-1x-digests.json"),Po=null,Na=e=>{let t=new Map;for(let[r,n]of Object.entries(e||{}))Array.isArray(n)&&t.set(r,new Set(n.filter(s=>typeof s=="string")));return t}});import{readFile as ld,readdir as Fy}from"node:fs/promises";import{join as vr}from"node:path";import{homedir as Vy}from"node:os";function ud(e=Ma,t=Vy()){return vr(t,".claude","skills",e)}async function Hy(e){for(let t of["agents","commands","skills"])if(!await w(vr(e,t)))return!1;for(let t of["agents","commands"]){let r;try{r=await Fy(vr(e,t),{withFileTypes:!0})}catch{continue}if(r.some(n=>n.isFile()&&n.name.startsWith("vesper-")))return!0}return!1}function dd({pluginName:e,workspaceRoot:t}){return async(r,n)=>{if(cd(n,r,{pluginName:e}))return!0;let s=/^skills\/([^/]+)\/(.+)$/.exec(r);if(!s||!Gy.includes(s[1]))return!1;let o=fr(s[1]),i=[...o?[o.dir]:[],...t?[vr(t,".claude","skills",s[1]),vr(t,".vesper","skills",s[1])]:[]];for(let a of i)try{if(me(n,await ld(vr(a,s[2]))))return!0}catch{}return!1}}async function ss({pluginName:e=Ma,staleDir:t,homeDir:r,workspaceRoot:n}={}){if(typeof e!="string"||e===""||/[\\/]|\.\./.test(e))return{reason:"not-ours",proven:[],kept:[]};let s=t??ud(e,r);if(!await w(s))return{reason:"absent",proven:[],kept:[]};let o="not-ours",i=null;try{let c=JSON.parse(await ld(vr(s,".claude-plugin","plugin.json"),"utf-8"));c&&c.name===e&&(o="match",typeof c.version=="string"&&/^1\.\d+\.\d+/.test(c.version)&&(i=c.version))}catch{}if(o==="not-ours"&&await Hy(s)&&(o="manifest-less-ours"),o==="not-ours")return{reason:o,path:s,proven:[],kept:[]};let a=await Ot(s,{sourceMatch:dd({pluginName:e,workspaceRoot:n}),anchor:null});return{reason:o,path:s,proven:a.proven,kept:a.kept,version:i}}async function pd({pluginName:e=Ma,staleDir:t,homeDir:r,workspaceRoot:n,backup:s}={}){let o=await ss({pluginName:e,staleDir:t,homeDir:r,workspaceRoot:n});if(o.reason==="absent"||o.reason==="not-ours")return{removed:!1,reason:o.reason,...o.path?{path:o.path}:{}};if(!o.proven.length)return{removed:!1,reason:"nothing-proven",path:o.path,kept:o.kept};if(typeof s!="function")return{removed:!1,reason:"no-backup",path:o.path,kept:o.kept};let i,a;try{i=await s(o.path),a=await Bn(o.path,{sourceMatch:dd({pluginName:e,workspaceRoot:n}),anchor:null})}catch(c){return{removed:!1,reason:"remove-failed",path:o.path,error:c&&c.message?c.message:String(c),...i?{backedUpTo:i}:{}}}return{removed:a.status==="removed",partial:a.status==="partial",reason:o.reason,path:o.path,removedFiles:a.removed,kept:a.kept,backedUpTo:i}}var Ma,Gy,Da=ee(()=>{U();qe();ns();hr();Ma="vesper",Gy=Object.freeze(["gitlab-ci-skill","github-actions-to-gitlab-ci"])});function By(e){return String(e).replace(/[^a-zA-Z0-9_-]/g,"_")}function zy(e,t=Ro){return`${t||Ro}:${e}`}function Jy(e){let t=String(e??"").trim();if(!(!t||t==="inherit")){if(t.includes("/"))return t;if(t.startsWith("claude-"))return`${Uy}${t}`}}function Yy(e){if(e==null)return null;let r=(Array.isArray(e)?e:String(e).split(",")).map(n=>String(n).trim()).filter(Boolean);return r.length?r:null}function qy(e){let t=Yy(e);if(t===null)return{permission:{},unmapped:[],restricted:!1};let r=new Set,n=new Set,s=[];for(let i of t){let a=/^mcp__(.+?)__(.+)$/.exec(i);if(a){n.add(`${By(a[1])}_*`);continue}let c=Wy[i];c?r.add(c):s.push(i)}let o={};for(let i of Ky)o[i]=r.has(i)?"allow":"deny";for(let i of r)i in o||(o[i]="allow");for(let i of[...n].sort())o[i]="allow";return{permission:o,unmapped:s,restricted:!0}}function Xy(e){let t=String(e??"").replace(/\r\n/g,`
59
- `),r=/^---\n([\s\S]*?)\n---(?:\n|$)/.exec(t);return r?{raw:r[1],body:t.slice(r[0].length)}:{raw:"",body:t}}function Fa(e){let t=String(e).trim();if(t.startsWith('"')&&t.endsWith('"')&&t.length>=2)try{return JSON.parse(t)}catch{return t.slice(1,-1)}return t.startsWith("'")&&t.endsWith("'")&&t.length>=2?t.slice(1,-1).replace(/''/g,"'"):t}function Qy(e){let t={},r=String(e??"").replace(/\r\n/g,`
69
+ `);for(;r.length&&r[r.length-1]==="";)r.pop();for(;r.length&&r[0]==="";)r.shift();return r.slice(-t)}function Qd(e,t){let r=Date.now(),n=Bd("sh",["-c",e.command],{cwd:t,env:process.env,encoding:"utf-8",stdio:["ignore","pipe","pipe"],maxBuffer:64*1024*1024}),s=Date.now()-r,o=`${n.stdout||""}${n.stderr||""}${n.error?`
70
+ ${n.error.message}`:""}`,i=n.error&&n.status===null?127:n.status;return{name:e.name,command:e.command,exitCode:i,durationMs:s,tail:Hw(o)}}function gn(e,t){let r=Bd("git",t,{cwd:e,env:{...process.env,...jt},encoding:"utf-8",stdio:["ignore","pipe","ignore"],maxBuffer:67108864});return{status:r.error?-1:r.status,stdout:r.stdout||""}}async function Uw(e){try{let t=await ei(e);if(t.includes(0))return 0;let r=0;for(let n of t)n===10&&(r+=1);return t.length&&t[t.length-1]!==10&&(r+=1),r}catch{return 0}}async function Zd(e,t){let r=gn(e,["rev-parse","--is-inside-work-tree"]);if(r.status!==0||r.stdout.trim()!=="true")return{skipped:"not a git repository"};let n=t;if(!n)n=gn(e,["rev-parse","--verify","--quiet","HEAD"]).status===0?"HEAD":kw;else if(gn(e,["rev-parse","--verify","--quiet",`${n}^{commit}`]).status!==0)return{skipped:`unknown --base ref "${t}"`};let s=gn(e,["diff","--name-only","-z",n,"--"]);if(s.status!==0)return{skipped:`git diff against ${n} failed`};let o=gn(e,["diff","--numstat","-z",n,"--"]),i=gn(e,["ls-files","--others","--exclude-standard","-z"]),a=new Set(s.stdout.split("\0").filter(Boolean)),c=i.status===0?i.stdout.split("\0").filter(Boolean):[];for(let d of c)a.add(d);let l=0;for(let d of o.stdout.split("\0")){let p=/^(\d+|-)\t(\d+|-)\t?/.exec(d);p&&(p[1]!=="-"&&(l+=Number(p[1])),p[2]!=="-"&&(l+=Number(p[2])))}for(let d of c)l+=await Uw(yn(e,d));return{changed:[...a].sort(),lines:l}}var ue,dc,zd,ww,vw,jr,kw,Sw,Ew,bw,Ow,Tw,Pw,Iw,jw,Rw,uc,Es=Z(()=>{U();wt();ue=".vesper/gates.json",dc=1,zd=Object.freeze({files:40,lines:1500}),ww=30,vw=".vesper/.tracking/",jr=Object.freeze({PASS:0,FAIL:1,NO_CONFIG:2}),kw="4b825dc642cb6eb9a060e54bf8d69288fbee4904",Sw=Object.freeze([{candidates:["test"]},{candidates:["lint"]},{candidates:["typecheck","tsc","type-check"]},{candidates:["build"]}]),Ew=Object.freeze(["npm","pnpm","yarn","bun"]),bw=Object.freeze([["pnpm-lock.yaml","pnpm"],["yarn.lock","yarn"],["bun.lockb","bun"],["bun.lock","bun"],["package-lock.json","npm"]]);Ow=/^(?:[\w.@-]+\/)*[\w.@-]+(?:\.[A-Za-z0-9]+)?$/,Tw=/\.[A-Za-z0-9]{1,10}$/;Pw=/^\s*(?:#{1,6}\s*|[-*]\s*\*\*)(?:files?(?:\s+operations?)?|file\s+list)\*{0,2}\s*:?\s*$/i,Iw=/^\s*#{1,6}\s/,jw=/^\s*[-*]\s*\*\*[^*]+\*\*\s*:?/,Rw=/^\s*[-*+]\s+(.*)$/;uc=new Map});import{readFileSync as Ww}from"node:fs";import{join as Kw}from"node:path";function wn(){if(ri)return ri;let e={};try{e=JSON.parse(Ww(Bw,"utf-8"))}catch{e={}}return ri={files:pc(e.files),playbook:new Set(Array.isArray(e.playbook)?e.playbook.filter(t=>typeof t=="string"):[]),pluginFiles:pc(e.pluginFiles),pluginDescriptions:new Set(Array.isArray(e.pluginManifestDescriptions)?e.pluginManifestDescriptions.filter(t=>typeof t=="string"):[]),vendoredFiles:pc(e.vendoredFiles)},ri}function zw(e,t){return t?e.replace(/^(name:\s*)([a-z0-9-]+)/m,(r,n,s)=>s.startsWith(t)?`${n}${s.slice(t.length)}`:r):e}function ep(e,t,r,n,s){let o=t.toString("utf-8").replace(/\r\n/g,`
71
+ `),i=new Set([""]);typeof s=="string"&&s&&i.add(s);for(let a of e.keys()){if(!a.startsWith(`${r}/`))continue;let c=a.slice(r.length+1);if(n.length>c.length&&n.endsWith(c)){let l=n.slice(0,n.length-c.length);/^[a-z0-9-]+$/.test(l)&&i.add(l)}}for(let a of i){if(a&&!n.startsWith(a))continue;let c=e.get(`${r}/${n.slice(a.length)}`);if(c){for(let l of new Set([o,zw(o,a)]))if(c.has(ut(Buffer.from(l,"utf-8"))))return!0}}return!1}function ni(e,t,{namePrefix:r}={}){let n=/^(agents|commands)\/([^/]+\.md)$/.exec(String(t||""));return n?ep(wn().files,e,n[1],n[2],r):!1}function tp(e){return wn().playbook.has(ut(e))}function rp(e){if(!e||e.includes("/")||e.includes(".."))return null;let t=`skills/${e}/`,r={};for(let[n,s]of wn().files)n.startsWith(t)&&(r[n.slice(t.length)]=[...s]);return Object.keys(r).length?r:null}function si(e,t,r){let{files:n}=wn();return n.has(`${e}/${t}`)?!0:!!r&&t.startsWith(r)&&n.has(`${e}/${t.slice(r.length)}`)}function np(e,t,{pluginName:r="vesper"}={}){let n=String(t||""),{pluginFiles:s,pluginDescriptions:o}=wn();if(n===".claude-plugin/plugin.json"){let c;try{c=JSON.parse(e.toString("utf-8"))}catch{return!1}return!c||typeof c!="object"||Array.isArray(c)?!1:Object.keys(c).sort().join(",")==="description,name,version"&&c.name===r&&o.has(c.description)&&typeof c.version=="string"}let i=/^(agents|commands)\/([^/]+\.md)$/.exec(n);if(i)return ep(s,e,i[1],i[2]);let a=s.get(n);return!!a&&a.has(ut(e))}function fc(e,t){let r=wn().vendoredFiles.get(String(t||""));return!!r&&r.has(ut(e))}var Bw,ri,pc,bs=Z(()=>{Ee();Ye();Bw=Kw(O,"legacy","claude-1x-digests.json"),ri=null,pc=e=>{let t=new Map;for(let[r,n]of Object.entries(e||{}))Array.isArray(n)&&t.set(r,new Set(n.filter(s=>typeof s=="string")));return t}});import{readFile as sp,readdir as Yw}from"node:fs/promises";import{join as Rr}from"node:path";import{homedir as Jw}from"node:os";function op(e=hc,t=Jw()){return Rr(t,".claude","skills",e)}async function Xw(e){for(let t of["agents","commands","skills"])if(!await w(Rr(e,t)))return!1;for(let t of["agents","commands"]){let r;try{r=await Yw(Rr(e,t),{withFileTypes:!0})}catch{continue}if(r.some(n=>n.isFile()&&n.name.startsWith("vesper-")))return!0}return!1}function ip({pluginName:e,workspaceRoot:t}){return async(r,n)=>{if(np(n,r,{pluginName:e}))return!0;let s=/^skills\/([^/]+)\/(.+)$/.exec(r);if(!s||!qw.includes(s[1]))return!1;let o=$r(s[1]),i=[...o?[o.dir]:[],...t?[Rr(t,".claude","skills",s[1]),Rr(t,".vesper","skills",s[1])]:[]];for(let a of i)try{if(ee(n,await sp(Rr(a,s[2]))))return!0}catch{}return!1}}async function xs({pluginName:e=hc,staleDir:t,homeDir:r,workspaceRoot:n}={}){if(typeof e!="string"||e===""||/[\\/]|\.\./.test(e))return{reason:"not-ours",proven:[],kept:[]};let s=t??op(e,r);if(!await w(s))return{reason:"absent",proven:[],kept:[]};let o="not-ours",i=null;try{let c=JSON.parse(await sp(Rr(s,".claude-plugin","plugin.json"),"utf-8"));c&&c.name===e&&(o="match",typeof c.version=="string"&&/^1\.\d+\.\d+/.test(c.version)&&(i=c.version))}catch{}if(o==="not-ours"&&await Xw(s)&&(o="manifest-less-ours"),o==="not-ours")return{reason:o,path:s,proven:[],kept:[]};let a=await Mt(s,{sourceMatch:ip({pluginName:e,workspaceRoot:n}),anchor:null});return{reason:o,path:s,proven:a.proven,kept:a.kept,version:i}}async function ap({pluginName:e=hc,staleDir:t,homeDir:r,workspaceRoot:n,backup:s}={}){let o=await xs({pluginName:e,staleDir:t,homeDir:r,workspaceRoot:n});if(o.reason==="absent"||o.reason==="not-ours")return{removed:!1,reason:o.reason,...o.path?{path:o.path}:{}};if(!o.proven.length)return{removed:!1,reason:"nothing-proven",path:o.path,kept:o.kept};if(typeof s!="function")return{removed:!1,reason:"no-backup",path:o.path,kept:o.kept};let i,a;try{i=await s(o.path),a=await is(o.path,{sourceMatch:ip({pluginName:e,workspaceRoot:n}),anchor:null})}catch(c){return{removed:!1,reason:"remove-failed",path:o.path,error:c&&c.message?c.message:String(c),...i?{backedUpTo:i}:{}}}return{removed:a.status==="removed",partial:a.status==="partial",reason:o.reason,path:o.path,removedFiles:a.removed,kept:a.kept,backedUpTo:i}}var hc,qw,mc=Z(()=>{U();Ye();bs();Or();hc="vesper",qw=Object.freeze(["gitlab-ci-skill","github-actions-to-gitlab-ci"])});function tv(e){return String(e).replace(/[^a-zA-Z0-9_-]/g,"_")}function rv(e,t=oi){return`${t||oi}:${e}`}function nv(e){let t=String(e??"").trim();if(!(!t||t==="inherit")){if(t.includes("/"))return t;if(t.startsWith("claude-"))return`${Qw}${t}`}}function sv(e){if(e==null)return null;let r=(Array.isArray(e)?e:String(e).split(",")).map(n=>String(n).trim()).filter(Boolean);return r.length?r:null}function ov(e){let t=sv(e);if(t===null)return{permission:{},unmapped:[],restricted:!1};let r=new Set,n=new Set,s=[];for(let i of t){let a=/^mcp__(.+?)__(.+)$/.exec(i);if(a){n.add(`${tv(a[1])}_*`);continue}let c=Zw[i];c?r.add(c):s.push(i)}let o={};for(let i of ev)o[i]=r.has(i)?"allow":"deny";for(let i of r)i in o||(o[i]="allow");for(let i of[...n].sort())o[i]="allow";return{permission:o,unmapped:s,restricted:!0}}function iv(e){let t=String(e??"").replace(/\r\n/g,`
72
+ `),r=/^---\n([\s\S]*?)\n---(?:\n|$)/.exec(t);return r?{raw:r[1],body:t.slice(r[0].length)}:{raw:"",body:t}}function gc(e){let t=String(e).trim();if(t.startsWith('"')&&t.endsWith('"')&&t.length>=2)try{return JSON.parse(t)}catch{return t.slice(1,-1)}return t.startsWith("'")&&t.endsWith("'")&&t.length>=2?t.slice(1,-1).replace(/''/g,"'"):t}function av(e){let t={},r=String(e??"").replace(/\r\n/g,`
60
73
  `).split(`
61
74
  `);for(let n=0;n<r.length;n++){let s=r[n];if(!s.trim()||/^\s*#/.test(s))continue;let o=/^([A-Za-z0-9_-]+):\s*(.*)$/.exec(s);if(!o)continue;let i=o[1],a=o[2].trim();if(/^[>|]-?$/.test(a)){let c=[];for(;n+1<r.length&&(/^\s+\S/.test(r[n+1])||r[n+1].trim()==="");)c.push(r[++n].trim());for(;c.length&&c[c.length-1]==="";)c.pop();t[i]=a.startsWith(">")?c.join(" ").replace(/\s+/g," "):c.join(`
62
- `);continue}if(a===""){let c=[];for(;n+1<r.length&&/^\s*-\s/.test(r[n+1]);)c.push(Fa(r[++n].replace(/^\s*-\s*/,"")));t[i]=c.length?c:"";continue}if(a.startsWith("[")&&a.endsWith("]")){t[i]=a.slice(1,-1).split(",").map(c=>Fa(c)).filter(c=>c!=="");continue}t[i]=Fa(a)}return t}function Va(e){let{raw:t,body:r}=Xy(e);return{frontmatter:Qy(t),body:r}}function Zy(e){return/^[A-Za-z_][A-Za-z0-9_-]*$/.test(e)?e:JSON.stringify(e)}function fd({description:e,mode:t,model:r,permission:n}){let s=["---",`description: ${JSON.stringify(e)}`,`mode: ${t}`];if(r&&s.push(`model: ${r}`),n&&Object.keys(n).length){s.push("permission:");for(let[o,i]of Object.entries(n))s.push(` ${Zy(o)}: ${i}`)}return s.push("---"),s.join(`
63
- `)}function hd({name:e,frontmatter:t={},body:r="",plugin:n=Ro}={}){if(!e||typeof e!="string")throw new Error("convertClaudeAgent: `name` is required");let s=t&&typeof t=="object"?t:{},o=String(s.description??"").replace(/\s+/g," ").trim()||`Vesper specialist: ${e}`,i=Jy(s.model),{permission:a,unmapped:c,restricted:l}=qy(s.tools),d=String(r??""),p={description:o,mode:"subagent"};i&&(p.model=i),l&&(p.permission=a),p.prompt=d;let h=`${fd({description:o,mode:"subagent",model:i,permission:l?a:void 0})}
64
- ${d}`;return{id:zy(e,n),name:e,plugin:n||Ro,markdown:h,config:p,unmapped:c}}function No({source:e,description:t}={}){let r=t;!r&&e&&(r=Va(e).frontmatter.description),r=String(r||tw).replace(/\s+/g," ").trim();let n=["# Vesper (Super Orchestrator) \u2014 OpenCode primary agent","","You are Vesper, the super-orchestrator for this project. Your complete operating playbook \u2014","the mandatory delegation law, the purpose router, every pipeline, the degraded-mode carve-out","and the host-mismatch warning \u2014 is the **always-on rules** `opencode.json` loads through","`instructions` into every session:","",...ew.map(([s,o])=>`- \`${s}\` \u2014 ${o}.`),"","This agent file is intentionally thin: it exists so `opencode.json` `default_agent:",'"vesper-orchestrator"` resolves a real primary agent. All behavior lives in the rules above \u2014',"follow them exactly. Do not restate or override them here.","","Specialists are delegated to by their namespaced names (`vesper:<name>` for the core catalog,","`vesper-<pack>:<name>` for an enabled pack), registered by the Vesper plugin","(`.opencode/plugins/vesper.js`) from the installed `@mthanh/vespercli` package \u2014 or, when",'`vesper.agentsMode` is `"files"`, from the generated `.opencode/agents/<id>.md` files. The',"committed maintenance skills resolve from `.claude/skills/` and are invoked unqualified","(`/reinit`, `/compact-knowledge`, `/revalidate-knowledge`, `/revalidate-team`).",""].join(`
65
- `);return`${fd({description:r,mode:"primary"})}
75
+ `);continue}if(a===""){let c=[];for(;n+1<r.length&&/^\s*-\s/.test(r[n+1]);)c.push(gc(r[++n].replace(/^\s*-\s*/,"")));t[i]=c.length?c:"";continue}if(a.startsWith("[")&&a.endsWith("]")){t[i]=a.slice(1,-1).split(",").map(c=>gc(c)).filter(c=>c!=="");continue}t[i]=gc(a)}return t}function yc(e){let{raw:t,body:r}=iv(e);return{frontmatter:av(t),body:r}}function cv(e){return/^[A-Za-z_][A-Za-z0-9_-]*$/.test(e)?e:JSON.stringify(e)}function cp({description:e,mode:t,model:r,permission:n}){let s=["---",`description: ${JSON.stringify(e)}`,`mode: ${t}`];if(r&&s.push(`model: ${r}`),n&&Object.keys(n).length){s.push("permission:");for(let[o,i]of Object.entries(n))s.push(` ${cv(o)}: ${i}`)}return s.push("---"),s.join(`
76
+ `)}function lp({name:e,frontmatter:t={},body:r="",plugin:n=oi}={}){if(!e||typeof e!="string")throw new Error("convertClaudeAgent: `name` is required");let s=t&&typeof t=="object"?t:{},o=String(s.description??"").replace(/\s+/g," ").trim()||`Vesper specialist: ${e}`,i=nv(s.model),{permission:a,unmapped:c,restricted:l}=ov(s.tools),d=String(r??""),p={description:o,mode:"subagent"};i&&(p.model=i),l&&(p.permission=a),p.prompt=d;let f=`${cp({description:o,mode:"subagent",model:i,permission:l?a:void 0})}
77
+ ${d}`;return{id:rv(e,n),name:e,plugin:n||oi,markdown:f,config:p,unmapped:c}}function ii({source:e,description:t}={}){let r=t;!r&&e&&(r=yc(e).frontmatter.description),r=String(r||uv).replace(/\s+/g," ").trim();let n=["# Vesper (Super Orchestrator) \u2014 OpenCode primary agent","","You are Vesper, the super-orchestrator for this project. Your complete operating playbook \u2014","the mandatory delegation law, the purpose router, every pipeline, the degraded-mode carve-out","and the host-mismatch warning \u2014 is the **always-on rules** `opencode.json` loads through","`instructions` into every session:","",...lv.map(([s,o])=>`- \`${s}\` \u2014 ${o}.`),"","This agent file is intentionally thin: it exists so `opencode.json` `default_agent:",'"vesper-orchestrator"` resolves a real primary agent. All behavior lives in the rules above \u2014',"follow them exactly. Do not restate or override them here.","","Specialists are delegated to by their namespaced names (`vesper:<name>` for the core catalog,","`vesper-<pack>:<name>` for an enabled pack), registered by the Vesper plugin","(`.opencode/plugins/vesper.js`) from the installed `@mthanh/vespercli` package \u2014 or, when",'`vesper.agentsMode` is `"files"`, from the generated `.opencode/agents/<id>.md` files. The',"committed maintenance skills resolve from `.claude/skills/` and are invoked unqualified","(`/reinit`, `/compact-knowledge`, `/revalidate-knowledge`, `/revalidate-team`).",""].join(`
78
+ `);return`${cp({description:r,mode:"primary"})}
66
79
 
67
- ${n}`}var Ro,kr,Uy,Wy,Ky,ew,tw,Lo=ee(()=>{Ro="vesper",kr=".opencode/agents",Uy="anthropic/",Wy=Object.freeze({Read:"read",Write:"edit",Edit:"edit",MultiEdit:"edit",NotebookEdit:"edit",Bash:"bash",Grep:"grep",Glob:"glob",LS:"list",WebFetch:"webfetch",WebSearch:"websearch",Task:"task",Agent:"task",TodoWrite:"todowrite",TodoRead:"todowrite",AskUserQuestion:"question",Skill:"skill"}),Ky=Object.freeze(["read","edit","glob","grep","bash","task","todowrite","webfetch","websearch","question"]);ew=Object.freeze([[".claude/rules/vesper-orchestrator.md","the orchestrator playbook (delegation law, purpose router, pipelines, degraded mode, host-mismatch warning)"],[".claude/rules/vesper-orchestration.md","the team roster + task-management config (the single authority for which `vesper:<name>` specialist fills which role)"],[".claude/rules/vesper-context.md","the slim project whitepaper (architecture, domain model, workflows, freshness)"]]),tw="Vesper super-orchestrator \u2014 the primary agent of a Vesper-managed project on OpenCode. Routes every request to the specialist team per the always-on orchestrator playbook and team roster in `.claude/rules/`."});import{readFileSync as rw}from"node:fs";import{readFile as md}from"node:fs/promises";import{join as Ga,dirname as nw}from"node:path";function yd(e){return`${Ne(e)}@${Ce}`}function sw(e){return Sn(e)!==null}function Mo(e=O){let t=null;try{t=JSON.parse(rw(Ga(e,"manifest.json"),"utf-8"))}catch{t=null}return{packs:Array.isArray(t?.packs)?[...t.packs]:[],agents:Array.isArray(t?.agents)?[...t.agents]:[],skills:Array.isArray(t?.skills)?[...t.skills]:[],assetPacks:{agents:{...t?.assetPacks?.agents||{}},skills:{...t?.assetPacks?.skills||{}}}}}function Qe(e=O){return[...Mo(e).packs].sort()}function wd(e,t=O){let r=Mo(t),n=s=>Object.keys(s).filter(o=>s[o]===e).sort();return{agents:n(r.assetPacks.agents),skills:n(r.assetPacks.skills)}}async function Ha(e){try{let t=JSON.parse(await md(Le(e),"utf-8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}async function Sr(e,t){let r=new Set(Qe()),n=new Set,s=new Set;if(t==="claude"){let i=(await Ha(e))?.enabledPlugins;if(i&&typeof i=="object"&&!Array.isArray(i))for(let[a,c]of Object.entries(i)){let l=Sn(a);!l||c!==!0||(r.has(l)?n:s).add(l)}}else if(t==="copilot"){let o=await J(e);for(let i of so())for(let{path:a,settingKey:c}of Hr(i))if(o[c]?.[a]===!0){n.add(i);break}}return{enabled:[...n].sort(),unknown:[...s].sort()}}async function jt(e,t){return(await Sr(e,t)).enabled}async function vd(e,t){let n=(await ae(e)).find(i=>i&&i.path===or&&i.host==="claude"&&i.category==="settings"),o={keys:Array.isArray(n?.owns?.keys)&&n.owns.keys.length?[...n.owns.keys]:[...ow]};t.length&&(o.entries=[...t].sort()),await B(e,[Y({path:or,host:"claude",category:"settings",owns:o})])}async function kd(e){let r=(await ae(e)).find(n=>n&&n.path===or&&n.host==="claude"&&n.category==="settings");return(Array.isArray(r?.owns?.entries)?r.owns.entries:[]).filter(sw).sort()}async function Sd(e,t){if(!await w(Ga(e,Gt)))return;await B(e,[Y({path:Gt,host:"copilot",category:"settings",owns:{keys:[...Ct],entries:[...t]}})]);let r=await x(e);if(Number(r.schemaVersion)===2&&Xn.some(n=>n in r)){for(let n of Xn)delete r[n];await I(e,r)}}function Ed(e){if(!Qe().includes(e))throw new Error(`Unknown pack "${e}". Available packs: ${Qe().join(", ")||"none"}.`)}async function Er(e,t,r){Ed(r);let n=await iw(e,t,r);if(yr(r)){let s=await zu(e,t,r);s&&(n.rule=s)}return n}async function iw(e,t,r){if(t==="claude"){let n=Le(e),s=await Ha(e);if(s===null&&await w(n))throw new Error(`${or} is malformed \u2014 fix it before enabling a pack (nothing was written).`);s=s||{},(!s.enabledPlugins||typeof s.enabledPlugins!="object"||Array.isArray(s.enabledPlugins))&&(s.enabledPlugins={});let o=yd(r),i=s.enabledPlugins[o]===!0;i||(s.enabledPlugins[o]=!0,await T(nw(n),{recursive:!0}),await C(n,JSON.stringify(s,null," "),"utf-8"));let a=new Set([...await kd(e),o]);return await vd(e,[...a]),await Do(e,await jt(e,"claude")),{pack:r,enabled:!i}}if(t==="copilot"){let n=Hr(r),{added:s}=await Vr(e,n),o=new Set([...await gt(e),...n.map(i=>i.path)]);return await Sd(e,[...o]),{pack:r,enabled:s.length>0}}throw new Error(`Unknown host "${t}"`)}async function bd(e,t,r){Ed(r);let n=await aw(e,t,r);if(yr(r)){let s=await Pa(e,t,r);s&&(n.rule=s)}return n}async function aw(e,t,r){if(t==="claude"){let n=Le(e),s=await Ha(e),o=yd(r),i=!1;s?.enabledPlugins&&typeof s.enabledPlugins=="object"&&o in s.enabledPlugins&&(delete s.enabledPlugins[o],Object.keys(s.enabledPlugins).length===0&&delete s.enabledPlugins,await C(n,JSON.stringify(s,null," "),"utf-8"),i=!0);let a=(await kd(e)).filter(c=>c!==o);return await vd(e,a),await Do(e,await jt(e,"claude")),{pack:r,disabled:i}}if(t==="copilot"){let n=Hr(r).map(i=>i.path),{removed:s}=await la(e,n),o=(await gt(e)).filter(i=>!n.includes(i));return await Sd(e,o),{pack:r,disabled:s.length>0}}throw new Error(`Unknown host "${t}"`)}async function Jt(e,t){let r=nn[t];if(!r)return null;try{return await md(Ga(e,r),"utf-8")}catch{return null}}async function Yt(e,t){let r=t||await yt(),n={},s=(a,c,l)=>{n[a]||(n[a]={agents:[],skills:[]}),n[a][c].includes(l)||n[a][c].push(l)},o=[],i=[];for(let a of Hu(e||"")){let c=r.agentPack.get(a);if(c===void 0){Object.hasOwn(Ao,a)||o.push(a);continue}c!=="core"&&s(c,"agents",a)}for(let a of Uu(e||"")){let c=r.skillPack.get(a);if(c===void 0){i.push(a);continue}c!=="core"&&s(c,"skills",a)}for(let a of Object.values(n))a.agents.sort(),a.skills.sort();return{needed:n,packs:Object.keys(n).sort(),unknownAgents:o,unknownSkills:i}}async function qt(e,t,{dryRun:r=!1}={}){let n=nn[t],s=await Jt(e,t),o=await Yt(s||""),i=await jt(e,t),a=[],c=[];for(let d of o.packs){if(i.includes(d)){c.push(d);continue}r||await Er(e,t,d),a.push(d)}let l=i.filter(d=>!o.packs.includes(d));return t==="claude"&&!r&&await Do(e,await jt(e,"claude")),{host:t,rosterPath:n,rosterFound:s!==null,needed:o.needed,packs:o.packs,enabled:a,already:c,unused:l,unknownAgents:o.unknownAgents,unknownSkills:o.unknownSkills}}async function xd(e){let r=(await yt()).agentPlugin.get(Xr(e).name);return r?`${r}:${Xr(e).name}`:null}var nn,gd,ow,Rt=ee(()=>{Ee();H();te();ye();xe();U();Qr();Zr();os();nn=Object.freeze({claude:".claude/rules/vesper-orchestration.md",copilot:".vesper/instructions/vesper-orchestration.instructions.md"}),gd="vespercli packs sync";ow=Object.freeze(["permissions.allow","hooks.SessionStart","agent","enabledPlugins"])});var $d={};yn($d,{OPENCODE_AGENTS_MODES:()=>Ua,OPENCODE_AGENT_CATEGORY:()=>is,OPENCODE_CONFIG_RELATIVE:()=>as,default:()=>uw,listCatalogAgentSources:()=>Ka,openCodeAgentRelative:()=>Ba,orchestratorAgentMarkdown:()=>Cd,readOpenCodeVesperSettings:()=>Wa,recordedOpenCodeAgentFiles:()=>Ad,renderOpenCodeAgentFiles:()=>Vo,renderOpenCodeAgents:()=>za});import{readdir as cw,readFile as Fo}from"node:fs/promises";import{join as Xt}from"node:path";async function Wa(e){let t={packs:null,agentsMode:"plugin"};try{let r=JSON.parse(await Fo(Xt(e,as),"utf-8")),n=r&&typeof r=="object"?r.vesper:null;n&&typeof n=="object"&&(Array.isArray(n.packs)&&(t.packs=n.packs.filter(s=>typeof s=="string")),Ua.includes(n.agentsMode)&&(t.agentsMode=n.agentsMode))}catch{}return t}async function _d(e){try{return(await cw(e)).filter(t=>t.endsWith(".md")).sort()}catch{return[]}}async function Ka(e=[],t=O){let r=[],n=Xt(t,"claude","agents");for(let o of await _d(n))r.push({name:o.slice(0,-3),plugin:It,pack:"core",path:Xt(n,o)});let s=new Set(Qe(t));for(let o of[...new Set(e)].sort()){if(!s.has(o))continue;let i=Xt(t,"claude","packs",o,"agents");for(let a of await _d(i))r.push({name:a.slice(0,-3),plugin:Ne(o),pack:o,path:Xt(i,a)})}return r}function Ba(e){return`${kr}/${e}.md`}async function za(e=[],t=O){let r=[];for(let n of await Ka(e,t)){let{frontmatter:s,body:o}=Va(await Fo(n.path,"utf-8")),i=hd({name:n.name,frontmatter:s,body:o,plugin:n.plugin});r.push({...i,pack:n.pack,path:Ba(i.id)})}return r}async function lw(e,t){if(Array.isArray(t))return[...new Set(t)].sort();let r=(await Wa(e)).packs;return r?[...new Set(r)].sort():jt(e,"claude")}async function Vo(e,{packs:t}={}){let r=await lw(e,t),n=await za(r),s=Xt(e,kr);n.length&&await T(s,{recursive:!0});let o=[],i=[],a=[];for(let d of n){let p=Xt(e,d.path),h=null;if(await w(p))try{h=await Fo(p,"utf-8")}catch{h=null}h===d.markdown?i.push(d.path):(await C(p,d.markdown,"utf-8"),o.push(d.path)),a.push(D({path:d.path,host:"claude",category:is,hash:qn(d.markdown)}))}let{pruned:c,kept:l}=await Yr(e,a,{categories:[is]});return{packs:r,written:o,unchanged:i,pruned:c,kept:l,agents:n.map(d=>d.id)}}async function Ad(e){return(await ae(e)).filter(r=>r.host==="claude"&&r.category===is).map(r=>r.path).sort()}async function Cd(e=O){let t;try{t=await Fo(Xt(e,"claude-committed","agents","vesper-orchestrator.md"),"utf-8")}catch{t=void 0}return No({source:t})}var is,as,Ua,uw,Ja=ee(()=>{Ee();U();te();Rt();Qr();Lo();is="opencode-agent",as="opencode.json",Ua=Object.freeze(["plugin","files"]);uw={OPENCODE_AGENT_CATEGORY:is,OPENCODE_CONFIG_RELATIVE:as,OPENCODE_AGENTS_MODES:Ua,readOpenCodeVesperSettings:Wa,listCatalogAgentSources:Ka,openCodeAgentRelative:Ba,renderOpenCodeAgents:za,renderOpenCodeAgentFiles:Vo,recordedOpenCodeAgentFiles:Ad,orchestratorAgentMarkdown:Cd}});import{readFile as us,rm as dw,rmdir as pw}from"node:fs/promises";import{join as Nt,dirname as Td}from"node:path";function ww(e){return{type:"local",command:["vespercli","mcp","serve",e],enabled:!0}}async function qa(){try{let e=No();if(typeof e=="string"&&e.trim())return e}catch{}return kw()}async function vw(){try{let e=(await us(Nt(O,"claude-committed","agents",`${L}.md`),"utf-8")).replace(/\r\n/g,`
68
- `),t=/^---\n[\s\S]*?\n---\n/.exec(e);return(t?e.slice(t[0].length):e).trim()}catch{return null}}async function kw(){return["---","description: Vesper super-orchestrator \u2014 routes every request to the specialist team per the always-on playbook and Team Roster in .claude/rules/ (Claude Code host, OpenCode overlay).","mode: primary","---","",await vw()||`# Vesper (Super Orchestrator)
80
+ ${n}`}var oi,Nr,Qw,Zw,ev,lv,uv,ai=Z(()=>{oi="vesper",Nr=".opencode/agents",Qw="anthropic/",Zw=Object.freeze({Read:"read",Write:"edit",Edit:"edit",MultiEdit:"edit",NotebookEdit:"edit",Bash:"bash",Grep:"grep",Glob:"glob",LS:"list",WebFetch:"webfetch",WebSearch:"websearch",Task:"task",Agent:"task",TodoWrite:"todowrite",TodoRead:"todowrite",AskUserQuestion:"question",Skill:"skill"}),ev=Object.freeze(["read","edit","glob","grep","bash","task","todowrite","webfetch","websearch","question"]);lv=Object.freeze([[".claude/rules/vesper-orchestrator.md","the orchestrator playbook (delegation law, purpose router, pipelines, degraded mode, host-mismatch warning)"],[".claude/rules/vesper-orchestration.md","the team roster + task-management config (the single authority for which `vesper:<name>` specialist fills which role)"],[".claude/rules/vesper-context.md","the slim project whitepaper (architecture, domain model, workflows, freshness)"]]),uv="Vesper super-orchestrator \u2014 the primary agent of a Vesper-managed project on OpenCode. Routes every request to the specialist team per the always-on orchestrator playbook and team roster in `.claude/rules/`."});import{readFileSync as dv}from"node:fs";import{readFile as up}from"node:fs/promises";import{join as wc,dirname as pv}from"node:path";function pp(e){return`${Le(e)}@${$e}`}function fv(e){return Sr(e)!==null}function ci(e=O){let t=null;try{t=JSON.parse(dv(wc(e,"manifest.json"),"utf-8"))}catch{t=null}return{packs:Array.isArray(t?.packs)?[...t.packs]:[],agents:Array.isArray(t?.agents)?[...t.agents]:[],skills:Array.isArray(t?.skills)?[...t.skills]:[],assetPacks:{agents:{...t?.assetPacks?.agents||{}},skills:{...t?.assetPacks?.skills||{}}}}}function rt(e=O){return[...ci(e).packs].sort()}function fp(e,t=O){let r=ci(t),n=s=>Object.keys(s).filter(o=>s[o]===e).sort();return{agents:n(r.assetPacks.agents),skills:n(r.assetPacks.skills)}}async function vc(e){try{let t=JSON.parse(await up(Fe(e),"utf-8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}async function Lr(e,t){let r=new Set(rt()),n=new Set,s=new Set;if(t==="claude"){let i=(await vc(e))?.enabledPlugins;if(i&&typeof i=="object"&&!Array.isArray(i))for(let[a,c]of Object.entries(i)){let l=Sr(a);!l||c!==!0||(r.has(l)?n:s).add(l)}}else if(t==="copilot"){let o=await K(e);for(let i of _o())for(let{path:a,settingKey:c}of rr(i))if(o[c]?.[a]===!0){n.add(i);break}}return{enabled:[...n].sort(),unknown:[...s].sort()}}async function Ht(e,t){return(await Lr(e,t)).enabled}async function hp(e,t){let n=(await ne(e)).find(i=>i&&i.path===It&&i.host==="claude"&&i.category==="settings"),o={keys:Array.isArray(n?.owns?.keys)&&n.owns.keys.length?[...n.owns.keys]:[...hv]};t.length&&(o.entries=[...t].sort()),await W(e,[Y({path:It,host:"claude",category:"settings",owns:o})])}async function mp(e){let r=(await ne(e)).find(n=>n&&n.path===It&&n.host==="claude"&&n.category==="settings");return(Array.isArray(r?.owns?.entries)?r.owns.entries:[]).filter(fv).sort()}async function gp(e,t){if(!await w(wc(e,Xt)))return;await W(e,[Y({path:Xt,host:"copilot",category:"settings",owns:{keys:[...Nt],entries:[...t]}})]);let r=await x(e);if(Number(r.schemaVersion)===2&&ds.some(n=>n in r)){for(let n of ds)delete r[n];await T(e,r)}}function yp(e){if(!rt().includes(e))throw new Error(`Unknown pack "${e}". Available packs: ${rt().join(", ")||"none"}.`)}async function cr(e,t,r){yp(r);let n=await mv(e,t,r);if(Ir(r)){let s=await Cd(e,t,r);s&&(n.rule=s)}return r===Me&&(n.graphify=await ks(e,t),n.graphify.mcp=t==="claude"?await kn(e,Vt):await sr(e,Vt)),n}async function mv(e,t,r){if(t==="claude"){let n=Fe(e),s=await vc(e);if(s===null&&await w(n))throw new Error(`${It} is malformed \u2014 fix it before enabling a pack (nothing was written).`);s=s||{},(!s.enabledPlugins||typeof s.enabledPlugins!="object"||Array.isArray(s.enabledPlugins))&&(s.enabledPlugins={});let o=pp(r),i=s.enabledPlugins[o]===!0;i||(s.enabledPlugins[o]=!0,await P(pv(n),{recursive:!0}),await A(n,JSON.stringify(s,null," "),"utf-8"));let a=new Set([...await mp(e),o]);return await hp(e,[...a]),await li(e,await Ht(e,"claude")),{pack:r,enabled:!i}}if(t==="copilot"){let n=rr(r),{added:s}=await Qr(e,n),o=new Set([...await xt(e),...n.map(i=>i.path)]);return await gp(e,[...o]),{pack:r,enabled:s.length>0}}throw new Error(`Unknown host "${t}"`)}async function wp(e,t,r){yp(r);let n=await gv(e,t,r);if(Ir(r)){let s=await rc(e,t,r);s&&(n.rule=s)}return r===Me&&(n.graphify=await hn(e,t),n.graphify.mcp=t==="claude"?await ui(e,Vt):await rn(e,Vt)),n}async function gv(e,t,r){if(t==="claude"){let n=Fe(e),s=await vc(e),o=pp(r),i=!1;s?.enabledPlugins&&typeof s.enabledPlugins=="object"&&o in s.enabledPlugins&&(delete s.enabledPlugins[o],Object.keys(s.enabledPlugins).length===0&&delete s.enabledPlugins,await A(n,JSON.stringify(s,null," "),"utf-8"),i=!0);let a=(await mp(e)).filter(c=>c!==o);return await hp(e,a),await li(e,await Ht(e,"claude")),{pack:r,disabled:i}}if(t==="copilot"){let n=rr(r).map(i=>i.path),{removed:s}=await Ra(e,n),o=(await xt(e)).filter(i=>!n.includes(i));return await gp(e,o),{pack:r,disabled:s.length>0}}throw new Error(`Unknown host "${t}"`)}async function lr(e,t){let r=vn[t];if(!r)return null;try{return await up(wc(e,r),"utf-8")}catch{return null}}async function ur(e,t){let r=t||await At(),n={},s=(a,c,l)=>{n[a]||(n[a]={agents:[],skills:[]}),n[a][c].includes(l)||n[a][c].push(l)},o=[],i=[];for(let a of Ed(e||"")){let c=r.agentPack.get(a);if(c===void 0){Object.hasOwn(Bo,a)||o.push(a);continue}c!=="core"&&s(c,"agents",a)}for(let a of bd(e||"")){let c=r.skillPack.get(a);if(c===void 0){i.push(a);continue}c!=="core"&&s(c,"skills",a)}for(let a of Object.values(n))a.agents.sort(),a.skills.sort();return{needed:n,packs:Object.keys(n).sort(),unknownAgents:o,unknownSkills:i}}async function dr(e,t,{dryRun:r=!1}={}){let n=vn[t],s=await lr(e,t),o=await ur(s||""),i=await Ht(e,t),a=[],c=[];for(let d of o.packs){if(i.includes(d)){c.push(d);continue}r||await cr(e,t,d),a.push(d)}let l=i.filter(d=>!o.packs.includes(d));return!r&&i.includes(Me)&&await ks(e,t),t==="claude"&&!r&&await li(e,await Ht(e,"claude")),{host:t,rosterPath:n,rosterFound:s!==null,needed:o.needed,packs:o.packs,enabled:a,already:c,unused:l,unknownAgents:o.unknownAgents,unknownSkills:o.unknownSkills}}async function vp(e){let r=(await At()).agentPlugin.get(ln(e).name);return r?`${r}:${ln(e).name}`:null}var I_,vn,dp,hv,Ut=Z(()=>{Ee();H();te();fe();Ae();U();un();dn();As();pt();I_=Object.freeze(["graphify","styles"]),vn=Object.freeze({claude:".claude/rules/vesper-orchestration.md",copilot:".vesper/instructions/vesper-orchestration.instructions.md"}),dp="vespercli packs sync";hv=Object.freeze(["permissions.allow","hooks.SessionStart","agent","enabledPlugins"])});var bp={};jn(bp,{OPENCODE_AGENTS_MODES:()=>kc,OPENCODE_AGENT_CATEGORY:()=>_s,OPENCODE_CONFIG_RELATIVE:()=>Cs,default:()=>vv,listCatalogAgentSources:()=>Ec,openCodeAgentRelative:()=>bc,orchestratorAgentMarkdown:()=>Ep,readOpenCodeVesperSettings:()=>Sc,recordedOpenCodeAgentFiles:()=>Sp,renderOpenCodeAgentFiles:()=>pi,renderOpenCodeAgents:()=>xc});import{readdir as yv,readFile as di}from"node:fs/promises";import{join as pr}from"node:path";async function Sc(e){let t={packs:null,agentsMode:"plugin"};try{let r=JSON.parse(await di(pr(e,Cs),"utf-8")),n=r&&typeof r=="object"?r.vesper:null;n&&typeof n=="object"&&(Array.isArray(n.packs)&&(t.packs=n.packs.filter(s=>typeof s=="string")),kc.includes(n.agentsMode)&&(t.agentsMode=n.agentsMode))}catch{}return t}async function kp(e){try{return(await yv(e)).filter(t=>t.endsWith(".md")).sort()}catch{return[]}}async function Ec(e=[],t=O){let r=[],n=pr(t,"claude","agents");for(let o of await kp(n))r.push({name:o.slice(0,-3),plugin:Dt,pack:"core",path:pr(n,o)});let s=new Set(rt(t));for(let o of[...new Set(e)].sort()){if(!s.has(o))continue;let i=pr(t,"claude","packs",o,"agents");for(let a of await kp(i))r.push({name:a.slice(0,-3),plugin:Le(o),pack:o,path:pr(i,a)})}return r}function bc(e){return`${Nr}/${e}.md`}async function xc(e=[],t=O){let r=[];for(let n of await Ec(e,t)){let{frontmatter:s,body:o}=yc(await di(n.path,"utf-8")),i=lp({name:n.name,frontmatter:s,body:o,plugin:n.plugin});r.push({...i,pack:n.pack,path:bc(i.id)})}return r}async function wv(e,t){if(Array.isArray(t))return[...new Set(t)].sort();let r=(await Sc(e)).packs;return r?[...new Set(r)].sort():Ht(e,"claude")}async function pi(e,{packs:t}={}){let r=await wv(e,t),n=await xc(r),s=pr(e,Nr);n.length&&await P(s,{recursive:!0});let o=[],i=[],a=[];for(let d of n){let p=pr(e,d.path),f=null;if(await w(p))try{f=await di(p,"utf-8")}catch{f=null}f===d.markdown?i.push(d.path):(await A(p,d.markdown,"utf-8"),o.push(d.path)),a.push(G({path:d.path,host:"claude",category:_s,hash:us(d.markdown)}))}let{pruned:c,kept:l}=await an(e,a,{categories:[_s]});return{packs:r,written:o,unchanged:i,pruned:c,kept:l,agents:n.map(d=>d.id)}}async function Sp(e){return(await ne(e)).filter(r=>r.host==="claude"&&r.category===_s).map(r=>r.path).sort()}async function Ep(e=O){let t;try{t=await di(pr(e,"claude-committed","agents","vesper-orchestrator.md"),"utf-8")}catch{t=void 0}return ii({source:t})}var _s,Cs,kc,vv,Ac=Z(()=>{Ee();U();te();Ut();un();ai();_s="opencode-agent",Cs="opencode.json",kc=Object.freeze(["plugin","files"]);vv={OPENCODE_AGENT_CATEGORY:_s,OPENCODE_CONFIG_RELATIVE:Cs,OPENCODE_AGENTS_MODES:kc,readOpenCodeVesperSettings:Sc,listCatalogAgentSources:Ec,openCodeAgentRelative:bc,renderOpenCodeAgents:xc,renderOpenCodeAgentFiles:pi,recordedOpenCodeAgentFiles:Sp,orchestratorAgentMarkdown:Ep}});import{readFile as Ts,rm as kv,rmdir as Sv}from"node:fs/promises";import{join as Wt,dirname as Ap}from"node:path";function Cv(e){return{type:"local",command:["vespercli","mcp","serve",e],enabled:!0}}async function Cc(){try{let e=ii();if(typeof e=="string"&&e.trim())return e}catch{}return Ov()}async function $v(){try{let e=(await Ts(Wt(O,"claude-committed","agents",`${L}.md`),"utf-8")).replace(/\r\n/g,`
81
+ `),t=/^---\n[\s\S]*?\n---\n/.exec(e);return(t?e.slice(t[0].length):e).trim()}catch{return null}}async function Ov(){return["---","description: Vesper super-orchestrator \u2014 routes every request to the specialist team per the always-on playbook and Team Roster in .claude/rules/ (Claude Code host, OpenCode overlay).","mode: primary","---","",await $v()||`# Vesper (Super Orchestrator)
69
82
 
70
- Follow the always-on rules in \`${Ya.join("`, `")}\` exactly.`,""].join(`
71
- `)}async function Xa(){return us(fw)}function Go(e){return Nt(e,Ft)}async function Ho(e){let t;try{t=await us(Go(e),"utf-8")}catch{return{present:!1,malformed:!1,config:null}}try{let r=JSON.parse(t);return!r||typeof r!="object"||Array.isArray(r)?{present:!0,malformed:!0,config:null}:{present:!0,malformed:!1,config:r}}catch{return{present:!0,malformed:!0,config:null}}}async function Uo(e,t){let r=Go(e);await T(Td(r),{recursive:!0}),await C(r,JSON.stringify(t,null," "),"utf-8")}async function Rd(e){let t=await x(e),r=Array.isArray(t.mcp?.servers)?t.mcp.servers.filter(n=>typeof n=="string"&&n):[];return[...new Set([...fe,...r])]}function Ld(e,t){let r=Wo(e.vesper)?e.vesper:{},n=ls(t===void 0?r.packs:t),s=mw.includes(r.agentsMode)?r.agentsMode:gw,o={...r,packs:n,agentsMode:s};return Nd(e.vesper,o)?!1:(e.vesper=o,!0)}function Md(e,t){let r=!1;Wo(e.mcp)||(e.mcp={},r=!0);for(let n of t){let s=ww(n);Nd(e.mcp[n],s)||(e.mcp[n]=s,r=!0)}return r}function Od(e,t,r){let n=!1;Array.isArray(e[t])||(e[t]=[],n=!0);for(let s of r)e[t].includes(s)||(e[t].push(s),n=!0);return n}function Sw(e,{servers:t,packs:r}){let n=!1;return e.default_agent!==L&&(e.default_agent=L,n=!0),Od(e,"instructions",Ya)&&(n=!0),Md(e,t)&&(n=!0),Od(e,"plugin",[jd])&&(n=!0),Ld(e,r)&&(n=!0),n}function Ew(e,{servers:t}){let r=!1;e.default_agent===L&&(delete e.default_agent,r=!0);let n=(s,o)=>{if(!Array.isArray(e[s]))return;let i=e[s].filter(a=>!o.includes(a));i.length!==e[s].length&&(i.length?e[s]=i:delete e[s],r=!0)};if(n("instructions",Ya),n("plugin",[jd]),Wo(e.mcp)){let s=!1;for(let o of t)o in e.mcp&&(delete e.mcp[o],s=!0);s&&(r=!0,Object.keys(e.mcp).length===0&&delete e.mcp)}return"vesper"in e&&(delete e.vesper,r=!0),r}async function Dd(e,t){await B(e,[Y({path:Ft,host:"claude",category:Pd,owns:{keys:[...hw],entries:ls(t)}})])}async function bw(e){return(await ae(e)).find(t=>t&&t.path===Ft&&t.host==="claude"&&t.category===Pd)||null}async function Fd(e,{record:t=!0}={}){let r=Go(e),{present:n,malformed:s,config:o}=await Ho(e);if(s)return{configured:!1,configPath:r,status:"skipped-malformed",servers:[]};let i=o||{$schema:yw},a=await Rd(e),c=Sw(i,{servers:a});return(c||!n)&&await Uo(e,i),t&&await Dd(e,a),{configured:!0,configPath:r,status:n?c?"updated":"unchanged":"created",servers:a}}async function Do(e,t){let{present:r,malformed:n,config:s}=await Ho(e);if(!r)return{mirrored:!1,reason:"absent"};if(n)return{mirrored:!1,reason:"malformed"};let o=Ld(s,t);o&&await Uo(e,s);let i=s.vesper.agentsMode,a=!1;if(i==="files"){let c=await Promise.resolve().then(()=>(Ja(),$d)).catch(()=>null);if(c&&typeof c.renderOpenCodeAgentFiles=="function")try{await c.renderOpenCodeAgentFiles(e,{packs:ls(t)}),a=!0}catch(l){u.dim(` OpenCode agent files not rendered (${l?.message||l}) \u2014 run \`vespercli opencode render-agents\`.`)}else u.dim(' OpenCode agentsMode "files": the agent-file renderer is not available in this build \u2014 run `vespercli opencode render-agents` once it ships.')}return{mirrored:!0,changed:o,agentsMode:i,rendered:a}}async function Qa(e){let{present:t,malformed:r,config:n}=await Ho(e);if(!t)return{synced:!1,reason:"absent"};if(r)return{synced:!1,reason:"malformed"};let s=await Rd(e),o=await bw(e),i=new Set([...Array.isArray(o?.owns?.entries)?o.owns.entries:[],...fe]),a=!1;if(Wo(n.mcp))for(let c of i)!s.includes(c)&&c in n.mcp&&(delete n.mcp[c],a=!0);return Md(n,s)&&(a=!0),a&&await Uo(e,n),await Dd(e,s),{synced:!0,changed:a,servers:s}}async function xw(e,t,r,n){let s=Nt(e,t),o=null;try{o=await us(s)}catch{o=null}if(o!==null&&me(o,r))return"unchanged";if(o!==null){let i=n.find(a=>a&&a.path===t&&a.host==="claude")||{path:t,category:cs,hash:null};if(!await zn(s,i))return"kept-edited"}return await T(Td(s),{recursive:!0}),await C(s,r),o===null?"created":"refreshed"}async function Vd(e){let t=await ae(e),r=[["agent",Ir,await qa()],["plugin",jr,await Xa()]],n={agent:"unchanged",plugin:"unchanged",keptEdited:[]},s=[];for(let[o,i,a]of r){let c=await xw(e,i,a,t);if(n[o]=c,c==="kept-edited"){n.keptEdited.push(i);continue}s.push(D({path:i,host:"claude",category:cs,hash:await ge(Nt(e,i))}))}return await Yr(e,s,{categories:[cs],prune:!1}),n}async function Gd(e){let t=[],r=[[Ir,await qa()],[jr,await Xa()]];for(let[n,s]of r){let o=null;try{o=await us(Nt(e,n))}catch{continue}me(o,s)&&t.push(D({path:n,host:"claude",category:cs,hash:await ge(Nt(e,n))}))}return t}async function Hd(e,{manifest:t=[],ownedServers:r=[]}={}){let n={kept:[],config:"absent"},{present:s,malformed:o,config:i}=await Ho(e);if(s&&o&&(n.config="malformed"),s&&!o){let c=t.find(m=>m&&m.path===Ft&&m.host==="claude")||null,l=await x(e),d=Array.isArray(l.mcp?.servers)?l.mcp.servers:[],p=ls([...fe,...Array.isArray(c?.owns?.entries)?c.owns.entries:[],...d,...r]);Ew(i,{servers:p})?Object.keys(i).every(m=>m==="$schema")?(await dw(Go(e),{force:!0}),n.config="removed"):(await Uo(e,i),n.config="stripped"):n.config="unchanged"}let a=[[Ir,[await qa()]],[jr,[await Xa()]]];for(let[c,l]of a){let d=Nt(e,c);if(!await w(d))continue;let p=t.find(m=>m&&m.path===c&&m.host==="claude")||{path:c,category:cs,hash:null},h=await ie(d,p,{expected:l});(h==="kept"||h==="partial")&&n.kept.push(c)}for(let c of[".opencode/agents",".opencode/plugins",".opencode"])try{await pw(Nt(e,c))}catch{}return n}var cs,Pd,fw,Id,Ya,jd,hw,mw,gw,yw,Nd,Wo,ls,os=ee(()=>{Ee();U();ye();H();te();qe();Te();Lo();cs="opencode-overlay",Pd="opencode-config",fw=Nt(O,"opencode","vesper-plugin.js"),Id=Object.freeze([Ft,Ir,jr]),Ya=Object.freeze([".claude/rules/vesper-orchestrator.md",".claude/rules/vesper-orchestration.md",".claude/rules/vesper-context.md"]),jd="./.opencode/plugins/vesper.js",hw=Object.freeze(["default_agent","instructions","mcp","plugin","vesper"]),mw=Object.freeze(["plugin","files"]),gw="plugin",yw="https://opencode.ai/config.json";Nd=(e,t)=>JSON.stringify(e)===JSON.stringify(t),Wo=e=>!!e&&typeof e=="object"&&!Array.isArray(e),ls=e=>[...new Set((e||[]).filter(t=>typeof t=="string"&&t))].sort()});import{readFile as se,readdir as Bd,rm as sn,rmdir as ec}from"node:fs/promises";import{join as j,dirname as fs,basename as _w}from"node:path";function br(e){return j(e,".claude")}function zd(e){return j(e,".claude","vesper")}function Jd(e){return j(e,"CLAUDE.md")}function De(e){return j(e,Yd)}function Le(e){return j(e,".claude","settings.json")}function Ow(e,t){return t?e.replace(/^(name:\s*)([a-z0-9-]+)/m,(r,n,s)=>s.startsWith(t)?r:`${n}${t}${s}`):e}async function Ko({workspaceRoot:e,namePrefix:t,version:r}={}){let n=br(e),s=[],o=`.claude/agents/${L}.md`,i=j(Qt,"agents",`${L}.md`);await T(j(n,"agents"),{recursive:!0}),await C(j(e,o),await se(i,"utf-8"),"utf-8"),s.push(D({path:o,host:"claude",category:"catalog-agent",hash:await ge(j(e,o))}));for(let d of Ht){let p=j(Qt,"skills",d),h=`.claude/skills/${d}`;await Kn(p,j(e,h),{recursive:!0}),s.push(D({path:h,host:"claude",category:"catalog-skill",hash:null}))}let{pruned:a,kept:c}=await Yr(e,s,{categories:["catalog-agent","catalog-command","catalog-skill"]});if(r!==void 0){let d=await x(e);d.schemaVersion=ve,d.frameworkVersion=r,await I(e,d)}let l={agents:1,skills:Ht.length,commands:0};return{pluginDir:n,counts:l,pruned:a.map(d=>d.replace(/^\.claude\//,"")),keptEdited:c.map(d=>d.replace(/^\.claude\//,""))}}async function ds(e,t){let r=s=>e==="skills"?j(s,"skills",t):j(s,e,`${t}.md`);if(await w(r(Me)))return{path:r(Me),pack:"core"};let n=[];try{n=(await Bd(j(Me,"packs"),{withFileTypes:!0})).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>s.name).sort()}catch{n=[]}for(let s of n){let o=j(Me,"packs",s);if(await w(r(o)))return{path:r(o),pack:s}}return null}async function Bo(e,t,{workspaceRoot:r,namePrefix:n=""}={}){let s=br(r),o=j(s,e);if(await T(o,{recursive:!0}),e==="skills"){let m=await ds("skills",t);if(!m)throw new Error(`Skill "${t}" not found in assets/claude/skills/ or any assets/claude/packs/<pack>/skills/`);let f=m.path,g=j(o,t),y=await Ot(g,{sourceDir:f});if(y.status!=="absent"&&!(y.status==="classified"&&y.kept.length===0))throw Ud(`.claude/skills/${t}`,`vesper:${t}`);return await Kn(f,g,{recursive:!0}),await B(r,[D({path:`.claude/skills/${t}`,host:"claude",category:"added-asset",hash:null})]),{installedAs:t}}let i=".md",a=await ds(e,t);if(!a)throw new Error(`${e.slice(0,-1)} "${t}" not found in assets/claude/${e}/ or any assets/claude/packs/<pack>/${e}/`);let c=a.path,l=await se(c,"utf-8"),d=Ow(l,n),p=n&&!t.startsWith(n)?`${n}${t}${i}`:`${t}${i}`,h=null;try{h=await se(j(o,p))}catch{h=null}if(h!==null&&!me(h,d))throw Ud(`.claude/${e}/${p}`,`vesper:${t}`);return await C(j(o,p),d,"utf-8"),await B(r,[D({path:`.claude/${e}/${p}`,host:"claude",category:"added-asset",hash:await ge(j(o,p))})]),{installedAs:_w(p,i)}}function Ud(e,t){let r=new Error(`${e} already exists and differs from Vesper's version (your edits, or a file of yours) \u2014 nothing was written or recorded. To keep yours: do nothing (it already takes precedence over \`${t}\`). To pin Vesper's version instead: move yours aside (e.g. \`mv ${e} ${e}.mine\`), then re-run the command.`);return r.name="AssetConflict",r.path=e,r}async function qd(e){let t=br(e),r={};for(let n of Aw){let s=j(t,n);if(!await w(s)){r[n]=[];continue}let o=await Bd(s,{withFileTypes:!0});r[n]=n==="skills"?o.filter(i=>i.isDirectory()).map(i=>i.name).sort():o.filter(i=>i.isFile()&&i.name.endsWith(".md")).map(i=>i.name.replace(/\.md$/,"")).sort()}return r}async function zo({pluginName:e=$w,staleDir:t,dryRun:r=!1,workspaceRoot:n,backup:s}={}){return r?{removed:!1,...await ss({pluginName:e,staleDir:t,workspaceRoot:n})}:pd({pluginName:e,staleDir:t,workspaceRoot:n,backup:s})}function Xd(e){let t="This is a machine-wide folder, removed as a side effect of running `vespercli init` in THIS project: every other pre-1.9 Vesper project on this machine loses its Vesper specialists until you run `vespercli init` in it (that migrates it to 2.0 \u2014 nothing else brings them back).",r=n=>n?.length?[`Kept ${n.length} file(s) there that no released Vesper build wrote (your edits or your own files): ${n.slice(0,10).join(", ")}${n.length>10?", \u2026":""}`]:[];return e.removed||e.partial?{level:e.partial?"warn":"success",lines:[`${e.removed?"Removed":"Removed the Vesper-written files of"} the pre-1.9 machine-wide Vesper Claude catalog at ${e.path}${e.backedUpTo?` (backed up first to ${e.backedUpTo})`:""}.`,...r(e.kept),t]}:e.reason==="no-backup"||e.reason==="nothing-proven"?{level:"warn",lines:[`Found the pre-1.9 machine-wide Vesper Claude catalog at ${e.path}, but ${e.reason==="no-backup"?"no backup could be made, so nothing was removed":"none of its files is byte-identical to a released Vesper build, so nothing was removed"}.`,"Review it yourself; `vespercli doctor` names it while Vesper-written files remain."]}:e.reason==="remove-failed"?{level:"warn",lines:[`Could not clean the stale machine-wide Vesper Claude catalog at ${e.path}${e.error?` (${e.error})`:""} \u2014 your install completed fine, this was only the cleanup step.`,"Re-run `vespercli init` to retry (it backs the folder up first and removes only files a released Vesper build wrote)."]}:null}function Tw(){return[tc,"This project is managed by **Vesper**. Its orchestrator playbook, team roster, and slim","project whitepaper are always-on rules loaded automatically every session:","`.claude/rules/vesper-orchestrator.md`, `.claude/rules/vesper-orchestration.md`,","`.claude/rules/vesper-context.md`. On-demand deep context lives in `.claude/vesper/context/`.","This block is a human breadcrumb only (no `@import`) \u2014 it is regenerated by `vespercli`; do not hand-edit.",rc].join(`
72
- `)}async function Pw(e){let t=Jd(e),r=Tw(),n=new RegExp(`${tc}[\\s\\S]*?${rc}`);if(!await w(t))return await T(fs(t),{recursive:!0}),await C(t,`${r}
73
- `,"utf-8"),{created:!0,updated:!1};let s=await se(t,"utf-8");if(n.test(s)){let i=s.replace(n,r);return i!==s?(await C(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=`${r}
83
+ Follow the always-on rules in \`${_c.join("`, `")}\` exactly.`,""].join(`
84
+ `)}async function $c(){return Ts(Ev)}function fi(e){return Wt(e,Jt)}async function hi(e){let t;try{t=await Ts(fi(e),"utf-8")}catch{return{present:!1,malformed:!1,config:null}}try{let r=JSON.parse(t);return!r||typeof r!="object"||Array.isArray(r)?{present:!0,malformed:!0,config:null}:{present:!0,malformed:!1,config:r}}catch{return{present:!0,malformed:!0,config:null}}}async function mi(e,t){let r=fi(e);await P(Ap(r),{recursive:!0}),await A(r,JSON.stringify(t,null," "),"utf-8")}async function Op(e){let t=await x(e),r=Array.isArray(t.mcp?.servers)?t.mcp.servers.filter(n=>typeof n=="string"&&n):[];return[...new Set([...me,...r])]}function Pp(e,t){let r=gi(e.vesper)?e.vesper:{},n=Os(t===void 0?r.packs:t),s=xv.includes(r.agentsMode)?r.agentsMode:Av,o={...r,packs:n,agentsMode:s};return Tp(e.vesper,o)?!1:(e.vesper=o,!0)}function Ip(e,t){let r=!1;gi(e.mcp)||(e.mcp={},r=!0);for(let n of t){let s=Cv(n);Tp(e.mcp[n],s)||(e.mcp[n]=s,r=!0)}return r}function xp(e,t,r){let n=!1;Array.isArray(e[t])||(e[t]=[],n=!0);for(let s of r)e[t].includes(s)||(e[t].push(s),n=!0);return n}function Tv(e,{servers:t,packs:r}){let n=!1;return e.default_agent!==L&&(e.default_agent=L,n=!0),xp(e,"instructions",_c)&&(n=!0),Ip(e,t)&&(n=!0),xp(e,"plugin",[$p])&&(n=!0),Pp(e,r)&&(n=!0),n}function Pv(e,{servers:t}){let r=!1;e.default_agent===L&&(delete e.default_agent,r=!0);let n=(s,o)=>{if(!Array.isArray(e[s]))return;let i=e[s].filter(a=>!o.includes(a));i.length!==e[s].length&&(i.length?e[s]=i:delete e[s],r=!0)};if(n("instructions",_c),n("plugin",[$p]),gi(e.mcp)){let s=!1;for(let o of t)o in e.mcp&&(delete e.mcp[o],s=!0);s&&(r=!0,Object.keys(e.mcp).length===0&&delete e.mcp)}return"vesper"in e&&(delete e.vesper,r=!0),r}async function jp(e,t){await W(e,[Y({path:Jt,host:"claude",category:_p,owns:{keys:[...bv],entries:Os(t)}})])}async function Iv(e){return(await ne(e)).find(t=>t&&t.path===Jt&&t.host==="claude"&&t.category===_p)||null}async function Rp(e,{record:t=!0}={}){let r=fi(e),{present:n,malformed:s,config:o}=await hi(e);if(s)return{configured:!1,configPath:r,status:"skipped-malformed",servers:[]};let i=o||{$schema:_v},a=await Op(e),c=Tv(i,{servers:a});return(c||!n)&&await mi(e,i),t&&await jp(e,a),{configured:!0,configPath:r,status:n?c?"updated":"unchanged":"created",servers:a}}async function li(e,t){let{present:r,malformed:n,config:s}=await hi(e);if(!r)return{mirrored:!1,reason:"absent"};if(n)return{mirrored:!1,reason:"malformed"};let o=Pp(s,t);o&&await mi(e,s);let i=s.vesper.agentsMode,a=!1;if(i==="files"){let c=await Promise.resolve().then(()=>(Ac(),bp)).catch(()=>null);if(c&&typeof c.renderOpenCodeAgentFiles=="function")try{await c.renderOpenCodeAgentFiles(e,{packs:Os(t)}),a=!0}catch(l){u.dim(` OpenCode agent files not rendered (${l?.message||l}) \u2014 run \`vespercli opencode render-agents\`.`)}else u.dim(' OpenCode agentsMode "files": the agent-file renderer is not available in this build \u2014 run `vespercli opencode render-agents` once it ships.')}return{mirrored:!0,changed:o,agentsMode:i,rendered:a}}async function Oc(e){let{present:t,malformed:r,config:n}=await hi(e);if(!t)return{synced:!1,reason:"absent"};if(r)return{synced:!1,reason:"malformed"};let s=await Op(e),o=await Iv(e),i=new Set([...Array.isArray(o?.owns?.entries)?o.owns.entries:[],...me]),a=!1;if(gi(n.mcp))for(let c of i)!s.includes(c)&&c in n.mcp&&(delete n.mcp[c],a=!0);return Ip(n,s)&&(a=!0),a&&await mi(e,n),await jp(e,s),{synced:!0,changed:a,servers:s}}async function jv(e,t,r,n){let s=Wt(e,t),o=null;try{o=await Ts(s)}catch{o=null}if(o!==null&&ee(o,r))return"unchanged";if(o!==null){let i=n.find(a=>a&&a.path===t&&a.host==="claude")||{path:t,category:$s,hash:null};if(!await as(s,i))return"kept-edited"}return await P(Ap(s),{recursive:!0}),await A(s,r),o===null?"created":"refreshed"}async function Np(e){let t=await ne(e),r=[["agent",Kr,await Cc()],["plugin",Br,await $c()]],n={agent:"unchanged",plugin:"unchanged",keptEdited:[]},s=[];for(let[o,i,a]of r){let c=await jv(e,i,a,t);if(n[o]=c,c==="kept-edited"){n.keptEdited.push(i);continue}s.push(G({path:i,host:"claude",category:$s,hash:await ye(Wt(e,i))}))}return await an(e,s,{categories:[$s],prune:!1}),n}async function Lp(e){let t=[],r=[[Kr,await Cc()],[Br,await $c()]];for(let[n,s]of r){let o=null;try{o=await Ts(Wt(e,n))}catch{continue}ee(o,s)&&t.push(G({path:n,host:"claude",category:$s,hash:await ye(Wt(e,n))}))}return t}async function Mp(e,{manifest:t=[],ownedServers:r=[]}={}){let n={kept:[],config:"absent"},{present:s,malformed:o,config:i}=await hi(e);if(s&&o&&(n.config="malformed"),s&&!o){let c=t.find(m=>m&&m.path===Jt&&m.host==="claude")||null,l=await x(e),d=Array.isArray(l.mcp?.servers)?l.mcp.servers:[],p=Os([...me,...Array.isArray(c?.owns?.entries)?c.owns.entries:[],...d,...r]);Pv(i,{servers:p})?Object.keys(i).every(m=>m==="$schema")?(await kv(fi(e),{force:!0}),n.config="removed"):(await mi(e,i),n.config="stripped"):n.config="unchanged"}let a=[[Kr,[await Cc()]],[Br,[await $c()]]];for(let[c,l]of a){let d=Wt(e,c);if(!await w(d))continue;let p=t.find(m=>m&&m.path===c&&m.host==="claude")||{path:c,category:$s,hash:null},f=await le(d,p,{expected:l});(f==="kept"||f==="partial")&&n.kept.push(c)}for(let c of[".opencode/agents",".opencode/plugins",".opencode"])try{await Sv(Wt(e,c))}catch{}return n}var $s,_p,Ev,Cp,_c,$p,bv,xv,Av,_v,Tp,gi,Os,As=Z(()=>{Ee();U();fe();H();te();Ye();Pe();ai();$s="opencode-overlay",_p="opencode-config",Ev=Wt(O,"opencode","vesper-plugin.js"),Cp=Object.freeze([Jt,Kr,Br]),_c=Object.freeze([".claude/rules/vesper-orchestrator.md",".claude/rules/vesper-orchestration.md",".claude/rules/vesper-context.md"]),$p="./.opencode/plugins/vesper.js",bv=Object.freeze(["default_agent","instructions","mcp","plugin","vesper"]),xv=Object.freeze(["plugin","files"]),Av="plugin",_v="https://opencode.ai/config.json";Tp=(e,t)=>JSON.stringify(e)===JSON.stringify(t),gi=e=>!!e&&typeof e=="object"&&!Array.isArray(e),Os=e=>[...new Set((e||[]).filter(t=>typeof t=="string"&&t))].sort()});import{readFile as ie,readdir as Vp,rm as Sn,rmdir as Pc}from"node:fs/promises";import{join as R,dirname as js,basename as Rv}from"node:path";function Mr(e){return R(e,".claude")}function Hp(e){return R(e,".claude","vesper")}function Up(e){return R(e,"CLAUDE.md")}function Ve(e){return R(e,Wp)}function Fe(e){return R(e,".claude","settings.json")}function Gv(e,t){return t?e.replace(/^(name:\s*)([a-z0-9-]+)/m,(r,n,s)=>s.startsWith(t)?r:`${n}${t}${s}`):e}async function yi({workspaceRoot:e,namePrefix:t,version:r}={}){let n=Mr(e),s=[],o=`.claude/agents/${L}.md`,i=R(fr,"agents",`${L}.md`);await P(R(n,"agents"),{recursive:!0}),await A(R(e,o),await ie(i,"utf-8"),"utf-8"),s.push(G({path:o,host:"claude",category:"catalog-agent",hash:await ye(R(e,o))}));for(let d of Qt){let p=R(fr,"skills",d),f=`.claude/skills/${d}`;await os(p,R(e,f),{recursive:!0}),s.push(G({path:f,host:"claude",category:"catalog-skill",hash:null}))}let{pruned:a,kept:c}=await an(e,s,{categories:["catalog-agent","catalog-command","catalog-skill"]});if(r!==void 0){let d=await x(e);d.schemaVersion=ve,d.frameworkVersion=r,await T(e,d)}let l={agents:1,skills:Qt.length,commands:0};return{pluginDir:n,counts:l,pruned:a.map(d=>d.replace(/^\.claude\//,"")),keptEdited:c.map(d=>d.replace(/^\.claude\//,""))}}async function Ps(e,t){let r=s=>e==="skills"?R(s,"skills",t):R(s,e,`${t}.md`);if(await w(r(De)))return{path:r(De),pack:"core"};let n=[];try{n=(await Vp(R(De,"packs"),{withFileTypes:!0})).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>s.name).sort()}catch{n=[]}for(let s of n){let o=R(De,"packs",s);if(await w(r(o)))return{path:r(o),pack:s}}return null}async function wi(e,t,{workspaceRoot:r,namePrefix:n=""}={}){let s=Mr(r),o=R(s,e);if(await P(o,{recursive:!0}),e==="skills"){let m=await Ps("skills",t);if(!m)throw new Error(`Skill "${t}" not found in assets/claude/skills/ or any assets/claude/packs/<pack>/skills/`);let h=m.path,g=R(o,t),y=await Mt(g,{sourceDir:h});if(y.status!=="absent"&&!(y.status==="classified"&&y.kept.length===0))throw Gp(`.claude/skills/${t}`,`vesper:${t}`);return await os(h,g,{recursive:!0}),await W(r,[G({path:`.claude/skills/${t}`,host:"claude",category:"added-asset",hash:null})]),{installedAs:t}}let i=".md",a=await Ps(e,t);if(!a)throw new Error(`${e.slice(0,-1)} "${t}" not found in assets/claude/${e}/ or any assets/claude/packs/<pack>/${e}/`);let c=a.path,l=await ie(c,"utf-8"),d=Gv(l,n),p=n&&!t.startsWith(n)?`${n}${t}${i}`:`${t}${i}`,f=null;try{f=await ie(R(o,p))}catch{f=null}if(f!==null&&!ee(f,d))throw Gp(`.claude/${e}/${p}`,`vesper:${t}`);return await A(R(o,p),d,"utf-8"),await W(r,[G({path:`.claude/${e}/${p}`,host:"claude",category:"added-asset",hash:await ye(R(o,p))})]),{installedAs:Rv(p,i)}}function Gp(e,t){let r=new Error(`${e} already exists and differs from Vesper's version (your edits, or a file of yours) \u2014 nothing was written or recorded. To keep yours: do nothing (it already takes precedence over \`${t}\`). To pin Vesper's version instead: move yours aside (e.g. \`mv ${e} ${e}.mine\`), then re-run the command.`);return r.name="AssetConflict",r.path=e,r}async function Kp(e){let t=Mr(e),r={};for(let n of Nv){let s=R(t,n);if(!await w(s)){r[n]=[];continue}let o=await Vp(s,{withFileTypes:!0});r[n]=n==="skills"?o.filter(i=>i.isDirectory()).map(i=>i.name).sort():o.filter(i=>i.isFile()&&i.name.endsWith(".md")).map(i=>i.name.replace(/\.md$/,"")).sort()}return r}async function vi({pluginName:e=Mv,staleDir:t,dryRun:r=!1,workspaceRoot:n,backup:s}={}){return r?{removed:!1,...await xs({pluginName:e,staleDir:t,workspaceRoot:n})}:ap({pluginName:e,staleDir:t,workspaceRoot:n,backup:s})}function Bp(e){let t="This is a machine-wide folder, removed as a side effect of running `vespercli init` in THIS project: every other pre-1.9 Vesper project on this machine loses its Vesper specialists until you run `vespercli init` in it (that migrates it to 2.0 \u2014 nothing else brings them back).",r=n=>n?.length?[`Kept ${n.length} file(s) there that no released Vesper build wrote (your edits or your own files): ${n.slice(0,10).join(", ")}${n.length>10?", \u2026":""}`]:[];return e.removed||e.partial?{level:e.partial?"warn":"success",lines:[`${e.removed?"Removed":"Removed the Vesper-written files of"} the pre-1.9 machine-wide Vesper Claude catalog at ${e.path}${e.backedUpTo?` (backed up first to ${e.backedUpTo})`:""}.`,...r(e.kept),t]}:e.reason==="no-backup"||e.reason==="nothing-proven"?{level:"warn",lines:[`Found the pre-1.9 machine-wide Vesper Claude catalog at ${e.path}, but ${e.reason==="no-backup"?"no backup could be made, so nothing was removed":"none of its files is byte-identical to a released Vesper build, so nothing was removed"}.`,"Review it yourself; `vespercli doctor` names it while Vesper-written files remain."]}:e.reason==="remove-failed"?{level:"warn",lines:[`Could not clean the stale machine-wide Vesper Claude catalog at ${e.path}${e.error?` (${e.error})`:""} \u2014 your install completed fine, this was only the cleanup step.`,"Re-run `vespercli init` to retry (it backs the folder up first and removes only files a released Vesper build wrote)."]}:null}function Fv(){return[Ic,"This project is managed by **Vesper**. Its orchestrator playbook, team roster, and slim","project whitepaper are always-on rules loaded automatically every session:","`.claude/rules/vesper-orchestrator.md`, `.claude/rules/vesper-orchestration.md`,","`.claude/rules/vesper-context.md`. On-demand deep context lives in `.claude/vesper/context/`.","This block is a human breadcrumb only (no `@import`) \u2014 it is regenerated by `vespercli`; do not hand-edit.",jc].join(`
85
+ `)}async function Dv(e){let t=Up(e),r=Fv(),n=new RegExp(`${Ic}[\\s\\S]*?${jc}`);if(!await w(t))return await P(js(t),{recursive:!0}),await A(t,`${r}
86
+ `,"utf-8"),{created:!0,updated:!1};let s=await ie(t,"utf-8");if(n.test(s)){let i=s.replace(n,r);return i!==s?(await A(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=`${r}
74
87
 
75
- ${s}`;return await C(t,o,"utf-8"),{created:!1,updated:!0}}function Iw(e){let t=new RegExp(`${tc}[\\s\\S]*?${rc}\\n*`);return e.replace(t,"")}function jw(e){return j(e,".claude","rules")}async function Jo(e){let t=jw(e);await T(t,{recursive:!0});let r={orchestrator:"refreshed",orchestration:"skipped",context:"skipped"},n=[],s=".claude/rules/vesper-orchestrator.md";await C(j(e,s),await se(j(Me,"vesper-orchestrator.md"),"utf-8"),"utf-8"),n.push(D({path:s,host:"claude",category:"playbook",hash:await ge(j(e,s))}));let o=async(l,d,p)=>{await w(j(e,l))||(await C(j(e,l),await se(j(Me,d),"utf-8"),"utf-8"),r[p]="created"),n.push(D({path:l,host:"claude",category:"per-project-authored",hash:null}))};if(await o(".claude/rules/vesper-orchestration.md","orchestration.md.tpl","orchestration"),r.orchestration==="skipped"){let l=j(e,".claude/rules/vesper-orchestration.md"),d=await se(l,"utf-8"),p=await yt(),h=new Set;for(let f of p.agents)await w(j(e,".claude","agents",`${f}.md`))&&h.add(f);let m=Co(d,p,{skip:h});m.qualified.length&&(await C(l,m.text,"utf-8"),r.orchestration=`namespaced ${m.qualified.length} specialist name(s) to their plugin (vesper:<name> / vesper-<pack>:<name>)`)}await o(".claude/rules/vesper-context.md","context.md.tpl","context");let i=await To(e);r.gates=i.created?`created (checks: ${i.checks.join(", ")||"none"})`:"skipped",n.push(D({path:ce,host:"claude",category:"per-project-authored",hash:null}));let a=await Pw(e);r.claudeMd=a.created?"created":a.updated?"updated":"unchanged",n.push(Y({path:"CLAUDE.md",host:"claude",category:"pointer",owns:{region:"vesper"}})),await B(e,n);let c=await Vd(e);return r.opencodeAgent=c.agent,r.opencodePlugin=c.plugin,r.opencodeKept=c.keptEdited,r}async function Yo(e){let t=De(e);try{let r=await se(t,"utf-8");return JSON.parse(r)}catch(r){return r.code==="ENOENT"?{mcpServers:{}}:{mcpServers:{}}}}async function qo(e,t){let r=De(e);await T(fs(r),{recursive:!0}),await C(r,JSON.stringify(t,null," "),"utf-8")}function Rw(e){return{"vesper-indexing":{command:"node",args:[Ue()],env:{VESPER_INDEX_ROOT:e}},"sequential-thinking":{command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},memory:{command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:j(e,".vesper","memory.jsonl")}}}}async function Zt(e,t=!0,{record:r=!0}={}){let n=await Yo(e);n.mcpServers||(n.mcpServers={});let s=Rw(e),o=Object.keys(s);if(t)for(let[i,a]of Object.entries(s))n.mcpServers[i]=a;else for(let i of o)delete n.mcpServers[i];return await qo(e,n),t&&r&&await B(e,[Y({path:Yd,host:"claude",category:"mcp-config",owns:{keys:o}})]),{configured:t,mcpPath:De(e),servers:t?o:[]}}function Za(e,t){return String(e).replace(/\$\{VESPER_INDEXING_PATH\}/g,Ue()).replace(/\$\{workspaceFolder\}/g,t).replace(/\$\{env:([^}]+)\}/g,"$${$1}")}function Nw(e,{workspaceRoot:t}){let{type:r,...n}=structuredClone(e);if(typeof n.command=="string"&&(n.command=Za(n.command,t)),Array.isArray(n.args)&&(n.args=n.args.map(s=>Za(s,t))),n.env&&typeof n.env=="object")for(let[s,o]of Object.entries(n.env))n.env[s]=Za(o,t);return n}async function Xo(e,t){if(fe.includes(t))return{added:!1,serverName:t,error:`${t} is a Vesper-managed core server \u2014 use "vespercli mcp enable --target claude" instead.`};let r=we[t];if(!r)return{added:!1,serverName:t,error:`Unknown MCP server: ${t}`};let n=await Yo(e);if(n.mcpServers||(n.mcpServers={}),n.mcpServers[t])return{added:!1,serverName:t,error:"Already configured"};n.mcpServers[t]=Nw(r.config,{workspaceRoot:e}),await qo(e,n);let s=await x(e);return s.mcp=s.mcp||{},s.mcp.servers=s.mcp.servers||[],s.mcp.servers.includes(t)||s.mcp.servers.push(t),s.mcp.updatedAt=new Date().toISOString(),await I(e,s),await Qa(e),{added:!0,serverName:t}}async function Qd(e,t){if(fe.includes(t))return{removed:!1,serverName:t,error:`${t} is a Vesper-managed core server \u2014 use "vespercli mcp disable --target claude" instead.`};let r=await Yo(e),n=!1;r.mcpServers&&r.mcpServers[t]&&(delete r.mcpServers[t],await qo(e,r),n=!0);let s=await x(e);return s.mcp?.servers&&(s.mcp.servers=s.mcp.servers.filter(o=>o!==t),s.mcp.updatedAt=new Date().toISOString(),await I(e,s)),await Qa(e),{removed:n,serverName:t}}async function Zd(e){let t=await Yo(e),r=Object.keys(t.mcpServers||{}),n=r.filter(s=>!we[s]);return{configured:r,custom:n}}function Lw(e){let t=e?.permissions?.allow;if(!Array.isArray(t))return!1;let r=new Set(ep),n=t.filter(s=>!r.has(s));return n.length===t.length?!1:(n.length?e.permissions.allow=n:delete e.permissions.allow,Object.keys(e.permissions).length===0&&delete e.permissions,!0)}function tp(e){(!e.permissions||typeof e.permissions!="object")&&(e.permissions={}),Array.isArray(e.permissions.allow)||(e.permissions.allow=[]);let t=0;for(let r of ep)e.permissions.allow.includes(r)||(e.permissions.allow.push(r),t+=1);return t}async function rp(e){let t=Le(e),r={},n=null;try{n=await se(t,"utf-8")}catch{n=null}if(n!==null){try{r=JSON.parse(n)}catch{return{configured:0,settingsPath:t,skipped:"malformed"}}if(!r||typeof r!="object"||Array.isArray(r))return{configured:0,settingsPath:t,skipped:"malformed"}}let s=tp(r);return(s>0||n===null)&&(await T(fs(t),{recursive:!0}),await C(t,JSON.stringify(r,null," "),"utf-8")),{configured:s,settingsPath:t}}async function np(e){let t=Le(e),r={};try{r=JSON.parse(await se(t,"utf-8"))}catch{r={}}let n=tp(r);(!r.enabledPlugins||typeof r.enabledPlugins!="object")&&(r.enabledPlugins={}),r.enabledPlugins[ut]=!0,r.agent=L,Dw(r),Vw(r),await T(fs(t),{recursive:!0}),await C(t,JSON.stringify(r,null," "),"utf-8");let s=(await ae(e)).find(a=>a&&a.path===".claude/settings.json"&&a.host==="claude"&&a.category==="settings"),o={keys:["permissions.allow","hooks.SessionStart","hooks.SubagentStart","agent","enabledPlugins"]};Array.isArray(s?.owns?.entries)&&s.owns.entries.length&&(o.entries=[...s.owns.entries]),await B(e,[Y({path:".claude/settings.json",host:"claude",category:"settings",owns:o})]),await Qo(e);let i=await Fd(e);return{configured:n,settingsPath:t,opencode:i}}function on(e){return j(e,".claude","settings.local.json")}function Mw(){return{source:{source:"directory",path:Me}}}function sp(e){return!!e&&typeof e=="object"&&!!e.source&&typeof e.source=="object"&&typeof e.source.source=="string"&&e.source.source.length>0}async function Qo(e,{record:t=!0}={}){let r=on(e),n={};try{n=JSON.parse(await se(r,"utf-8"))||{}}catch{n={}}return(!n.extraKnownMarketplaces||typeof n.extraKnownMarketplaces!="object")&&(n.extraKnownMarketplaces={}),n.extraKnownMarketplaces[Ce]=Mw(),await T(fs(r),{recursive:!0}),await C(r,JSON.stringify(n,null," "),"utf-8"),t&&await B(e,[Y({path:".claude/settings.local.json",host:"claude",category:"settings",owns:{keys:["extraKnownMarketplaces"]}})]),{localPath:r}}function Wd(e){let t=!1;if(e?.extraKnownMarketplaces&&Ce in e.extraKnownMarketplaces&&(delete e.extraKnownMarketplaces[Ce],Object.keys(e.extraKnownMarketplaces).length===0&&delete e.extraKnownMarketplaces,t=!0),e?.enabledPlugins&&ut in e.enabledPlugins&&(delete e.enabledPlugins[ut],Object.keys(e.enabledPlugins).length===0&&delete e.enabledPlugins,t=!0),e?.enabledPlugins&&typeof e.enabledPlugins=="object"){for(let r of Object.keys(e.enabledPlugins))Sn(r)!==null&&(delete e.enabledPlugins[r],t=!0);Object.keys(e.enabledPlugins).length===0&&delete e.enabledPlugins}return e?.agent===L&&(delete e.agent,t=!0),t}function nc(e,{command:t=op,markers:r=Object.values(ps)}={}){let n=JSON.stringify(e.hooks?.SessionStart??null);return Zo(e,{markers:r}),e.hooks||(e.hooks={}),Array.isArray(e.hooks.SessionStart)||(e.hooks.SessionStart=[]),e.hooks.SessionStart.push({hooks:[{type:"command",command:t}]}),JSON.stringify(e.hooks.SessionStart)!==n}function Dw(e){nc(e)}function Zo(e,{markers:t}={}){if(!Array.isArray(t)||t.length===0)throw new Error("removeVesperSessionStartHook: an explicit `markers` list is required (see VESPER_HOOK_MARKERS)");return ip(e,"SessionStart",t)}function ip(e,t,r){if(!Array.isArray(e?.hooks?.[t]))return!1;let n=new Set(r.flat().filter(a=>typeof a=="string"&&a.trim()).map(a=>a.trim())),s=a=>typeof a?.command=="string"&&n.has(a.command.trim()),o=!1,i=[];for(let a of e.hooks[t]){if(!a||!Array.isArray(a.hooks)){i.push(a);continue}let c=a.hooks.filter(l=>!s(l));if(c.length===a.hooks.length){i.push(a);continue}o=!0,c.length>0&&i.push({...a,hooks:c})}return e.hooks[t]=i,e.hooks[t].length===0&&delete e.hooks[t],e.hooks&&Object.keys(e.hooks).length===0&&delete e.hooks,o}function Vw(e){let t=JSON.stringify(e.hooks?.SubagentStart??null);return cp(e),e.hooks||(e.hooks={}),Array.isArray(e.hooks.SubagentStart)||(e.hooks.SubagentStart=[]),e.hooks.SubagentStart.push({hooks:[{type:"command",command:ap}]}),JSON.stringify(e.hooks.SubagentStart)!==t}function cp(e,{markers:t=Object.values(Fw)}={}){return ip(e,"SubagentStart",t)}async function lp(e,t={}){let r=await x(e);return r.schemaVersion=ve,r.host="claude",t.namePrefix!==void 0&&(r.namePrefix=t.namePrefix),t.pluginPath!==void 0&&(r.pluginPath=t.pluginPath),t.version!==void 0&&(r.frameworkVersion=t.version),r.updatedAt=new Date().toISOString(),await I(e,r),r}function sc(e){let t=String(e);for(let r of["adhd","ponytail"])t=t.replace(new RegExp(`\\n*<!-- vesper:${r}:start -->[\\s\\S]*?<!-- vesper:${r}:end -->\\n*`),`
76
- `);return t}async function Gw(e){let t=j(zd(e),"context"),r=j(e,".vesper","context"),n=await w(r),s={removed:[],kept:[]},o;try{o=await nt(t)}catch{return s}for(let i of o.files){let a=!n;if(n)try{a=me(await se(j(t,i)),await se(j(r,i)))}catch{a=!1}a?(await sn(j(t,i),{force:!0}),s.removed.push(i)):s.kept.push(i)}s.kept.push(...o.others);for(let i of o.dirs)try{await ec(j(t,i))}catch{}try{await ec(t)}catch{}return s}function Kd(e){let t=String(e).replace(/\r\n/g,`
77
- `),r=/^---\n[\s\S]*?\n---\n/.exec(t);return(r?t.slice(r[0].length):t).trim()}async function Hw(e){let t={removed:[],kept:[]};for(let r of["orchestration","context"]){let n=`.claude/vesper/${r}.md`,s;try{s=await se(j(e,n),"utf-8")}catch{continue}let o=null;try{o=await se(j(e,".vesper","instructions",`vesper-${r}.instructions.md`),"utf-8")}catch{o=null}let i=Kd(s);o===null||i!==""&&Kd(o).includes(i)?(await sn(j(e,n),{force:!0}),t.removed.push(n)):t.kept.push(n)}return t}async function an(e,{purgeProjectAuthored:t=!1}={}){let r=zd(e),n=".claude/vesper/orchestrator.md";await ie(j(e,n),{path:n,category:"playbook"});let s=[];t&&(s.push(...(await Hw(e)).kept),s.push(...(await Gw(e)).kept.map(y=>`.claude/vesper/context/${y}`)));try{await ec(r)}catch{}let o=await x(e),i=new Set,a=Array.isArray(o.manifest)?o.manifest:[],c=new Set(a.filter(y=>y&&y.host!=="claude"&&y.category==="per-project-authored").map(y=>y.path));for(let y of a)_o(y,{host:"claude",purgeProjectAuthored:t})&&(y.category==="per-project-authored"&&c.has(y.path)||i.add(y.path));for(let y of Array.isArray(o.claude?.catalogManifest)?o.claude.catalogManifest:[]){if(typeof y!="string"||y.includes(".."))continue;let[k,...v]=y.split("/");!Cw.includes(k)||v.length===0||i.add(`.claude/${y}`)}for(let y of i){let k=(o.manifest||[]).find(v=>v?.path===y)||{path:y,category:y.startsWith(".claude/skills/")?"catalog-skill":"catalog-agent"};await ie(j(e,y),k,{purgeProjectAuthored:t})}let{kept:l}=await $o(e,"claude"),d=await Hd(e,{manifest:a}),p=Jd(e);if(await w(p)){let y=await se(p,"utf-8"),k=sc(Iw(y));k.trim()?await C(p,k,"utf-8"):await sn(p,{force:!0})}await Zt(e,!1);let h=Array.isArray(o.mcp?.servers)?o.mcp.servers:[];if(h.length&&await w(De(e)))try{let y=JSON.parse(await se(De(e),"utf-8")),k=!1;for(let v of h)y?.mcpServers&&typeof y.mcpServers=="object"&&v in y.mcpServers&&(delete y.mcpServers[v],k=!0);k&&await qo(e,y)}catch{}try{let y=JSON.parse(await se(De(e),"utf-8"));y&&typeof y=="object"&&Object.keys(y).every(v=>v==="mcpServers")&&(!y.mcpServers||Object.keys(y.mcpServers).length===0)&&await sn(De(e),{force:!0})}catch{}let m=Le(e);if(await w(m))try{let y=JSON.parse(await se(m,"utf-8")),k=Zo(y,{markers:[ps.legacy,ps.bootstrap]}),v=cp(y),S=Wd(y),A=Lw(y);(k||v||S||A)&&(Object.keys(y).length===0?await sn(m,{force:!0}):await C(m,JSON.stringify(y,null," "),"utf-8"))}catch{}let f=on(e);if(await w(f))try{let y=JSON.parse(await se(f,"utf-8"));Wd(y)&&(Object.keys(y).length===0?await sn(f,{force:!0}):await C(f,JSON.stringify(y,null," "),"utf-8"))}catch{}let g=await x(e);return delete g.claude,g.host==="claude"&&delete g.host,delete g.namePrefix,delete g.pluginPath,Array.isArray(g.manifest)&&(g.manifest=g.manifest.filter(y=>!(y&&y.host==="claude")||!t&&Re.has(y.category))),await I(e,g),{kept:l,knowledgeKept:s,overlayKept:d.kept}}var Me,Qt,Ce,Aw,Cw,$w,Yd,tc,rc,ep,op,ps,ap,Fw,xe=ee(()=>{Ee();Qr();U();qe();Zr();rs();Da();H();te();ye();os();Me=j(O,"claude"),Qt=j(O,"claude-committed"),Ce="vesper-marketplace",Aw=["agents","skills"],Cw=["agents","commands","skills"],$w="vesper";Yd=".mcp.json";tc="<!-- vesper:start -->",rc="<!-- vesper:end -->";ep=Object.freeze(["mcp__vesper-indexing__vesper_search","mcp__vesper-indexing__vesper_symbols","mcp__vesper-indexing__vesper_status","mcp__vesper-indexing__vesper_reindex","mcp__sequential-thinking__sequentialthinking","mcp__memory__create_entities","mcp__memory__create_relations","mcp__memory__add_observations","mcp__memory__delete_entities","mcp__memory__delete_observations","mcp__memory__delete_relations","mcp__memory__read_graph","mcp__memory__search_nodes","mcp__memory__open_nodes"]);op=`command -v vespercli >/dev/null 2>&1 && ${Dr("claude")} || true`,ps=Object.freeze({legacy:Object.freeze([En,bn]),bootstrap:Object.freeze([xn]),guard:Object.freeze([op])});ap="command -v vespercli >/dev/null 2>&1 && vespercli log delegated --pipeline hook --note hook --stdin || true",Fw=Object.freeze({runLedger:Object.freeze([ap])})});import{Command as QE,Option as at}from"commander";import{readFileSync as ZE,existsSync as eb}from"node:fs";import{fileURLToPath as tb}from"node:url";import{dirname as al,join as nm}from"node:path";U();H();te();xe();import{resolve as yS,basename as rh,relative as wS,sep as vS,isAbsolute as kS}from"node:path";import{spawn as SS}from"node:child_process";import{confirm as tr,input as ES,number as bS,select as xS}from"@inquirer/prompts";U();qe();rs();H();te();ye();import{readFile as ws,rm as Mp,rmdir as Zv}from"node:fs/promises";import{join as Be}from"node:path";te();H();xe();be();import{readFile as ys,readdir as fv}from"node:fs/promises";import{join as Ae,isAbsolute as hv,relative as mv}from"node:path";import{readdir as Uw,readFile as up,rename as Ww,access as Kw,constants as Bw}from"node:fs/promises";import{join as er}from"node:path";import{execFile as zw}from"node:child_process";var oc=".vesper/.migration-backup";async function dp(e){try{return await Kw(e,Bw.F_OK),!0}catch{return!1}}function Jw(e){return new Promise(t=>{try{zw("git",["rev-parse","--verify","-q","HEAD"],{cwd:e,timeout:5e3,encoding:"utf-8",env:{...process.env,GIT_NO_LAZY_FETCH:"1",GIT_OPTIONAL_LOCKS:"0",GIT_TERMINAL_PROMPT:"0",GCM_INTERACTIVE:"never",SSH_ASKPASS_REQUIRE:"never",LC_ALL:"C"}},(n,s)=>t(n?null:String(s).trim()||null)).stdin?.end()}catch{t(null)}})}async function pp(e){try{return(await Uw(er(e,oc),{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name).sort()}catch{return[]}}async function ei(e,{head:t}={}){let r=await pp(e);if(r.length===0)return!1;let n=er(e,oc),s=t!==void 0?t:await Jw(e),o=r.at(-1);for(let i of[...r].reverse()){let a;try{a=await up(er(n,i,"rollback.json"),"utf-8")}catch{continue}let c;try{c=JSON.parse(a)}catch{if(i!==o)continue;return!await dp(er(n,i,"created.txt"))}if(!c||!Array.isArray(c.before)||s!==null&&c.head!==s)continue;return(typeof c.status=="string"?c.status:Array.isArray(c.created)?"finished":"started")==="started"}return!1}async function ic(e){let t=await pp(e);if(!t.length)return null;let r=er(e,oc,t.at(-1)),n;try{n=await up(er(r,"rollback.json"),"utf-8")}catch{return null}try{return JSON.parse(n),null}catch{}return await dp(er(r,"created.txt"))?null:er(r,"rollback.json")}async function fp(e,{now:t=new Date}={}){let r=await ic(e);if(!r)return null;let n=`${r}.torn-${t.toISOString().replace(/[:.]/g,"-")}`;return await Ww(r,n),{from:r,to:n}}U();H();te();xe();ye();qe();be();import{readFile as wp,rm as nv,rmdir as sv}from"node:fs/promises";import{join as dc}from"node:path";H();ye();Ee();Da();be();import{readFile as cc,readdir as gp}from"node:fs/promises";import{readdirSync as Yw}from"node:fs";import{join as _e,basename as qw}from"node:path";import{homedir as Xw}from"node:os";var Qw=Object.freeze(["agents","commands","skills"]),Zw=Object.freeze(["claude","paths","catalogVersion","targets"]),xr=".vesper/.migration-backup",Ze="This is a pre-2.0 (1.x) Vesper workspace. Run `vespercli init` to migrate it in place \u2014 nothing of yours is deleted, and anything Vesper removes is backed up first.";async function ni(e){let t=[...new Set([await ft(e),_e(e,".vesperrc"),_e(e,".vesper","tracking.json")])],r=null,n=null;for(let c of t){let l;try{l=await cc(c,"utf-8")}catch(d){if(d&&d.code==="ENOENT")continue;return ti({config:"corrupt",path:c})}try{r=JSON.parse(l),n=c}catch{return ti({config:"corrupt",path:c})}break}if(!r||typeof r!="object")return ti({config:"absent",path:null});let s=Number(r.schemaVersion)>=2?"v2":"v1",o=[];for(let c of Array.isArray(r.claude?.catalogManifest)?r.claude.catalogManifest:[]){if(typeof c!="string"||c.includes("..")||c.startsWith("/"))continue;let[l,...d]=c.split("/");!Qw.includes(l)||d.length===0||o.push(`.claude/${c}`)}let i=c=>Array.isArray(c)?c.filter(l=>typeof l=="string"):[],a=r.claude?.namePrefix??r.namePrefix;return ti({config:s,path:n,catalogManifest:o,namePrefix:typeof a=="string"?a:"",injectedPaths:i(r.paths),readAccessPaths:i(r.readAccessPaths),mcpServers:i(r.mcp?.servers),vendored:r.vendored&&typeof r.vendored=="object"?JSON.parse(JSON.stringify(r.vendored)):void 0,hosts:s==="v1"?{claude:!!r.claude,copilot:i(r.paths).length>0}:{claude:!1,copilot:!1},staleKeys:s==="v2"?Zw.filter(c=>c in r):[],recordedHost:s==="v2"?In({host:r.host}):null,version:s==="v1"&&[r.catalogVersion,r.claude?.catalogVersion,r.version].find(c=>typeof c=="string"&&/^1\.\d+\.\d+/.test(c))||null})}function ti(e){return Object.freeze({config:"absent",path:null,catalogManifest:[],namePrefix:"",injectedPaths:[],readAccessPaths:[],mcpServers:[],vendored:void 0,hosts:{claude:!1,copilot:!1},staleKeys:[],recordedHost:null,version:null,...e})}async function $e(e,{checkout:t}={}){let r=await ni(e),n;try{n=await J(e)}catch{n=void 0}let s=await jl(e,{vscodeSettings:n}),o={claude:s.hosts.claude||r.hosts.claude,copilot:s.hosts.copilot||r.hosts.copilot},i=[...s.matched];r.config==="v1"&&i.unshift(`${qw(r.path||".vesperrc")} (1.x record)`);let a=!1,c=!1,l=!1,d=null;try{let h=t??await W(e);d=h.source==="local"?null:h.host??h.candidate??null}catch{d=null}r.config==="corrupt"||(r.config==="v1"&&(r.hosts.claude||r.hosts.copilot||r.mcpServers.length>0||r.vendored!==void 0||s.primary)?a=!0:d?(s.primary||r.staleKeys.length)&&(l=!0,i.push(...r.staleKeys.map(h=>`.vesperrc key "${h}"`))):s.primary?a=!0:s.residue.length&&!d&&(c=!0,o.claude=!0,i.push(...s.residue)));let p=a||c?[]:[...s.residue];return{unmigrated:a,advisory:c,residue:l,needsMigration:a||c||l,corrupt:r.config==="corrupt",config:r.config,hosts:o,staleKeys:[...r.staleKeys],evidence:[...new Set(i)],leftovers:p,record:r}}var ev="<!-- vesper(?::[a-z0-9-]+)?:start -->[\\s\\S]*?<!-- vesper(?::[a-z0-9-]+)?:end -->",hp=e=>new RegExp(ev).test(e),tv=Object.freeze([En,bn,xn]);async function ac(e){try{return await gp(e,{withFileTypes:!0})}catch{return[]}}async function ri(e){try{return await cc(e)}catch{return null}}function mp(e){let t=new Set;for(let r of[_e(O,"claude",e),_e(O,"claude-committed",e)])try{for(let n of Yw(r))t.add(n.replace(/\.md$/,""))}catch{}return t}function rv(e){let t=/^---\r?\n([\s\S]*?)\r?\n---/.exec(e);if(!t)return null;let r=/^name:\s*['"]?([A-Za-z0-9_.-]+)['"]?\s*$/m.exec(t[1]);return r?r[1]:null}async function si({homeDir:e=Xw(),pluginName:t="vesper",workspaceRoot:r}={}){let n=[],s=(p,h,m,f,g={})=>n.push({path:_e(e,p),rel:p,kind:h,tier:m,marker:f,...g}),o=mp("agents"),i=mp("skills"),a=`.claude/skills/${t}`,c=await ss({pluginName:t,staleDir:_e(e,a),workspaceRoot:r});(c.reason==="match"||c.reason==="manifest-less-ours")&&c.proven.length&&s(a,"plugin",2,`${c.proven.length} file(s) byte-identical to a released Vesper 1.x build`,{proven:c.proven.length,kept:c.kept.length});for(let[p,h]of[[".claude/rules",m=>m.endsWith(".md")],[".copilot/instructions",()=>!0]])for(let m of await ac(_e(e,p))){if(!m.isFile()||!h(m.name))continue;let f=`${p}/${m.name}`,g=(await ri(_e(e,f)))?.toString("utf-8")??"";hp(g)?s(f,"file",3,"a Vesper guard block"):m.name.startsWith("vesper-")&&s(f,"file",3,"a vesper- file name")}for(let p of[".claude/agents",".copilot/agents"])for(let h of await ac(_e(e,p))){if(!h.isFile()||!h.name.endsWith(".md"))continue;let m=`${p}/${h.name}`,f=await ri(_e(e,m));if(!f)continue;let g=h.name.replace(/(\.agent)?\.md$/,"");(o.has(rv(f.toString("utf-8"))||g)||o.has(g)||h.name.startsWith("vesper-"))&&s(m,"file",3,"a Vesper agent name")}for(let p of[".claude/skills",".copilot/skills"])for(let h of await ac(_e(e,p)))h.isDirectory()&&(p===".claude/skills"&&h.name===t||(i.has(h.name)||h.name.startsWith("vesper-"))&&s(`${p}/${h.name}`,"dir",3,"a Vesper skill name"));let l=(await ri(_e(e,".claude","CLAUDE.md")))?.toString("utf-8");l&&hp(l)&&s(".claude/CLAUDE.md","region",3,"a Vesper guard block");let d=await ri(_e(e,".claude","settings.json"));if(d){let p=null;try{p=JSON.parse(d.toString("utf-8"))}catch{p=null}if(p&&typeof p=="object"){let h=[],m=p.hooks&&typeof p.hooks=="object"?p.hooks:{};for(let[f,g]of Object.entries(m))Array.isArray(g)&&g.some(y=>Array.isArray(y?.hooks)&&y.hooks.some(k=>typeof k?.command=="string"&&tv.includes(k.command.trim())))&&h.push(`hooks.${f}`);p.agent===L&&h.push("agent"),h.length&&s(".claude/settings.json","keys",3,`Vesper keys: ${h.join(", ")}`)}}return n.sort((p,h)=>p.rel.localeCompare(h.rel))}async function yp(e){let t=_e(e,xr),r=[];try{r=(await gp(t,{withFileTypes:!0})).filter(s=>s.isDirectory()).map(s=>s.name).sort()}catch{r=[]}let n=[];for(let s of r){let o;try{o=JSON.parse(await cc(_e(t,s,"kept.json"),"utf-8"))}catch{continue}if(Array.isArray(o))for(let i of o)i&&typeof i.rel=="string"&&typeof i.reason=="string"&&n.push({rel:i.rel,reason:i.reason,backup:_e(t,s)})}return n}ct();var oi="VESPER_HOST_MISMATCH",pc="VESPER_PLUGIN_ABSENT",Z="vespercli init",Ke=e=>`vespercli init --host ${e}`,ms="opencode";function vp(e){return e===ms?"claude":e}function kp(e){return K.includes(e)||e===ms}function ov(e,t,{runningLabel:r}={}){return t==="copilot"&&e==="claude"?`This workspace is provisioned for Claude Code, and VS Code just opened it. If you use GitHub Copilot here, run \`${Ke("copilot")}\` (it removes the Claude Code setup). If you use Claude Code inside VS Code, ignore this message \u2014 nothing was changed.`:r===ms&&t==="claude"?`This workspace is provisioned for "${e}" but is running under OpenCode, which uses the "claude" host. Fix: ${Ke("claude")}`:`This workspace is provisioned for "${e}" but is running under "${t}". Fix: ${Ke(t)}`}var hs=".vesper/instructions/vesper-host-guard.instructions.md",lc="guard-rule",iv=["---","applyTo: '**'",'description: "Vesper host guard \u2014 refuse work in this workspace while a host mismatch is active"',"---","","# Vesper host guard","","Before doing anything else in this workspace, check whether `.vesper/.host-guard/ACTIVE` exists.","",`If it does, treat this session as \`${oi}\`: this workspace was provisioned for a`,"different AI host than the one you are running in. Refuse all provisioning and orchestration","work, print the `fix:` command the file contains (`vespercli init --host <running host>` to","re-provision this workspace for the host you are running in, or `vespercli reset --host <x>`","to remove one host's Vesper files), and take no other action.","","If the file does not exist, this rule imposes nothing \u2014 proceed normally.","","This file is written by Vesper (`vespercli`) and is constant; the sentinel it names is","gitignored and written/cleared by `vespercli guard`.",""].join(`
78
- `);function fc(e){return e==="claude"?"copilot":"claude"}async function Sp(e){let t=Le(e),r={},n=!0;try{r=JSON.parse(await wp(t,"utf-8")),n=!1}catch{r={}}(!r||typeof r!="object"||Array.isArray(r))&&(r={});let s=nc(r);return(s||n)&&(await T(dc(e,".claude"),{recursive:!0}),await C(t,JSON.stringify(r,null," "),"utf-8")),{changed:s,created:n}}function av(){return{label:Nn.taskLabel,command:Dr("copilot"),presentation:{reveal:"always",panel:"shared"}}}async function cv(e,t,{unattended:r=!1}={}){return ln(t),t==="claude"?Sp(e):Mn(e,{createOnly:r})}async function Ep(e,t){if(ln(t),t==="claude"){let n=await Sp(e);return await B(e,[Y({path:".claude/settings.json",host:"shared",category:"guard-trigger",owns:{keys:["hooks.SessionStart"]}})]),n}let r=await Qs(e,av());return await B(e,[Y({path:".vscode/tasks.json",host:"shared",category:"guard-trigger",owns:{keys:[Nn.taskLabel]}})]),r}async function ii(e,t,{unattended:r=!1}={}){return ln(t),await cv(e,t,{unattended:r}),await Ep(e,fc(t)),{legacyGuardRule:await _r(e)}}async function uc(e,t){let r=await x(e),n=q(r),s=n.filter(o=>!t(o));return s.length===n.length?!1:(r.manifest=s,await I(e,r),!0)}async function gs(e,t){ln(t);let r=q(await x(e));if(t==="claude"){let i=Le(e);if(await w(i))try{let a=JSON.parse(await wp(i,"utf-8"));Zo(a,{markers:[ps.guard]})&&(Object.keys(a).length===0?await nv(i,{force:!0}):await C(i,JSON.stringify(a,null," "),"utf-8"))}catch{}await uc(e,a=>a.path===".claude/settings.json"&&a.category==="guard-trigger");return}let n=r.some(i=>i.path===".vscode/tasks.json"&&i.category==="guard-trigger"),s=r.some(i=>i.path===".vscode/tasks.json"&&i.host==="copilot"),{fileRemoved:o}=await Ln(e,Nn.taskLabel,{removeFileIfEmpty:n&&!s});if(o)try{await sv(dc(e,".vscode"))}catch{}await uc(e,i=>i.path===".vscode/tasks.json"&&i.category==="guard-trigger")}async function _r(e){let n=q(await x(e)).find(o=>o.path===hs&&o.category===lc)??{path:hs,category:lc,hash:null},s=await ie(dc(e,hs),n,{expected:[iv]});return await uc(e,o=>o.path===hs&&o.category===lc),s==="partial"?"kept":s}function cn(){return`Kept your edited ${hs} \u2014 Vesper no longer uses this file (a host mismatch now warns instead of refusing work) and never deletes a copy that differs from what it wrote. Delete it by hand.`}function lv(e){return e?.ignoredFile&&e.ignoredEvidence&&e.ignoredEvidence!=="both"?`This repository gitignores ${e.ignoredFile}, so a checkout cannot confirm the ${e.ignoredEvidence} provisioning it carries \u2014 bootstrap wrote nothing; session start still provisions this worktree. To bootstrap on checkouts too, commit ${e.ignoredFile} (remove it from .gitignore).`:e?.candidate?`This checkout's committed files carry no ${e.candidate} provisioning \u2014 bootstrap wrote nothing. Session start (or \`vespercli init\`) provisions it.`:"Not a vesperized workspace \u2014 nothing to bootstrap. Run `vespercli init` to set up."}function uv(e,t){return e?.gitError==="dubious-ownership"?`git refuses this repository (dubious ownership), so Vesper cannot read its checkout and provisions nothing here. Fix: git config --global --add safe.directory ${t}`:"git could not read this repository, so Vesper provisions nothing here; run `git status` to see why."}async function ai(e,{runningHost:t,runningLabel:r}={}){let n=t!==void 0,s={identity:n,network:n,runningHost:t,journal:null,fix:null,note:null,message:null},o=await Tt(e),i=await W(e,{requireCommitted:!n&&!o});if(o)return n&&t!==o.to?{...s,action:"refuse",reason:"switch-in-progress",host:o.to,checkout:i,journal:o,fix:Z,message:`An interrupted host switch (${o.from} \u2192 ${o.to}) is pending in this workspace. Fix: ${Z}`}:{...s,action:"none",reason:"switch-in-progress",host:null,checkout:i,journal:o,note:`An interrupted host switch (${o.from} \u2192 ${o.to}) is pending \u2014 run \`vespercli init\` to finish it.`};let a=async()=>{let l=null;try{l=await $e(e,{checkout:i})}catch{l=null}return l?.unmigrated?{...s,action:"none",reason:"legacy-unmigrated",host:null,checkout:i,note:`Bootstrap wrote nothing. ${Ze}`}:await ei(e)?{...s,action:"none",reason:"migration-in-progress",host:null,checkout:i,note:"A Vesper 1.x migration was interrupted in this workspace \u2014 run `vespercli init` to finish it. Nothing was provisioned."}:null},c=i.source==="local";if(c){let l=await a();if(l)return l}if(n&&i.host&&i.host!==t)return{...s,action:"refuse",reason:"host-mismatch",host:i.host,checkout:i,fix:Ke(t),message:ov(i.host,t,{runningLabel:r})};if(!c){let l=await a();if(l)return l}if(i.gitError)return{...s,action:"none",reason:i.gitError==="dubious-ownership"?"not-vesperized":"git-unreadable",host:null,checkout:i,note:uv(i,e)};if(i.ambiguous)return{...s,action:"none",reason:"host-ambiguous",host:null,checkout:i,note:n?Xe:null};if(!i.host){let l=!n&&i.candidate?"host-unconfirmed":"not-vesperized",d=n?await mr(e):null,p=d?`This worktree's local record names ${d}, but the checked-out commit carries no Vesper provisioning \u2014 nothing was provisioned. \`vespercli init --host ${t}\` provisions it.`:lv(i);return{...s,action:"none",reason:l,host:null,checkout:i,note:p}}return{...s,action:"bootstrap",reason:"healthy",host:i.host,checkout:i}}async function bp(e,t,{checkout:r}={}){if(ln(t),r?.source==="local"){for(let n of[dv(t),".vesperrc"])if(!await pv(e,n))return{healed:!1,reason:"local-tier"}}return await Ep(e,t),{healed:!0}}function dv(e){return ln(e),e==="claude"?".claude/settings.json":".vscode/tasks.json"}async function pv(e,t){return await G(["check-ignore","-q","--",t],{cwd:e,timeout:5e3})!==null}function ln(e){if(!K.includes(e))throw new Error(`host must be one of: ${K.join(", ")} (received "${e}")`)}ye();Ee();Qr();Rt();Zr();U();rs();os();ns();import{readFile as mc,readdir as gv}from"node:fs/promises";import{homedir as yv}from"node:os";var $=Object.freeze({ERROR:"error",WARN:"warn",INFO:"info"}),Oe=Object.freeze({OK:0,ERROR:1,HOST_MISMATCH:2}),xp=new Set(Object.values($)),Tp="host-mismatch",wv="check-failed",vv=new Set(["playbook","pointer","mcp-config","settings"]);var _p=Eo,kv=e=>`vespercli reset --host ${e}`;function R({code:e,severity:t,message:r,fix:n,category:s,path:o}){if(!xp.has(t))throw new Error(`makeFinding: unknown severity "${t}" for code "${e}". Valid severities: ${[...xp].join(", ")}. An unbucketed finding is invisible to both the rendered report and the exit code.`);let i={code:e,severity:t,message:r,fix:n||Z};return s!==void 0&&(i.category=s),o!==void 0&&(i.path=o),i}function hc(e,t){if(!t)return t;let r=mv(e,t);return r.startsWith("..")?t:r}async function Sv(e){let r=[await ft(e),Ae(e,".vesperrc"),Ae(e,".vesper","tracking.json")],n=new Set;for(let s of r){if(n.has(s))continue;n.add(s);let o;try{o=await ys(s,"utf-8")}catch(i){if(i&&i.code==="ENOENT")continue;return{corrupt:!0,corruptPath:s}}try{return{tracking:JSON.parse(o),trackingPath:s}}catch{return{corrupt:!0,corruptPath:s}}}return{absent:!0}}async function Ap(e,t){let r=!1;try{r=await w(e)}catch{r=!1}if(!r)return{path:e,exists:!1,servers:[]};try{let n=JSON.parse(await ys(e,"utf-8"));return{path:e,exists:!0,servers:Object.keys(n[t]||{})}}catch{return{path:e,exists:!0,servers:[]}}}async function Ev(e,t,{visible:r}={}){let n={};for(let s of Object.keys(t)){n[s]=[];for(let o of t[s])try{await Vt(e,o,{visible:r})&&n[s].push(o)}catch(i){if(!bv(i))throw i}}return n}function bv(e){return!!e&&typeof e.code=="string"&&["ENOENT","EACCES","EISDIR","ENOTDIR","EPERM","ELOOP","ENAMETOOLONG"].includes(e.code)}function xv(e){return Bi(e)}async function _v(e,t,{homeDir:r=yv(),checkout:n=null}={}){let s=await Sv(e);if(s.corrupt)return{workspaceRoot:e,runningHost:t,corrupt:!0,corruptPath:s.corruptPath};let o=s.tracking||null,i=n;i||(i=await W(e,{withCommitted:!0}));let a=i.host,c=null;try{c=await Tt(e)}catch{c=null}let l=null,d=!1;try{l=await ic(e)}catch{l=null}try{d=await ei(e)}catch{d=!1}let p=await Pu(e),h=[...p.missing,...p.modified,...p.clean],m=await xo(e),f=Ps(),g=[];try{g=await he(e)}catch{g=[]}let y=a?[a]:g,k={claude:await Ap(De(e),"mcpServers"),copilot:await Ap(Je(e),"servers")},v=Ut(),S=i.ambiguous?"both":i.host,A=await Ev(e,v,{visible:i.visible}),N={};for(let[Ve,Dt]of Object.entries(A))N[Ve]=Dt.some(xv);let E={};for(let Ve of K)E[Ve]=await _n(e,Ve);let b=null;try{b=await $e(e,{checkout:i})}catch{b=null}let F=[];try{F=(await si({homeDir:r,workspaceRoot:e})).filter(Ve=>Ve.kind==="plugin")}catch{F=[]}let Q=[];try{Q=await yp(e)}catch{Q=[]}let Fe=await mr(e),hn=!!Fe&&Fe!==a;{let Ve=i.source==="local"?null:a,Dt=et=>{if(!et)return!1;if(K.includes(et.host))return et.host===Ve;let Or=Av(et);return!Or||Or===Ve};p={...p,missing:p.missing.filter(Dt),modified:p.modified.filter(Dt),clean:p.clean.filter(Dt),userLevelViolations:p.userLevelViolations}}let wt=[...p.missing,...p.modified,...p.clean],Mt=!!a||h.length>0;return{workspaceRoot:e,runningHost:t,absent:!!s.absent,tracking:o,host:a,checkout:i,ledgerHostForReporting:Fe,verify:p,manifestEntries:wt,manifestAll:h,recordStale:hn,journal:c,migrationTorn:l,migrationActive:d,frameworkVersion:m,packageVersion:f,installedTargets:y,mcpConfigs:k,detectedHost:S,fingerprintMatches:A,fingerprintSpecific:N,residue:E,legacy:b,userResidue:F,keptItems:Q,initialised:Mt}}function Av(e){return e.category==="guard-rule"||e.category==="guard-trigger"&&e.path===".claude/settings.json"?"copilot":e.category==="guard-trigger"&&e.path===".vscode/tasks.json"?"claude":null}function Pp(e,t){return e.checkout?.host===t||!!e.fingerprintSpecific?.[t]}function Cv(e){let t=[],{verify:r}=e;for(let n of r.userLevelViolations)t.push(R({code:"user-level-violation",severity:$.ERROR,category:n.category,path:n.path,message:`Owned file "${n.path}" sits under a user-level scan path \u2014 it would silently activate in unrelated projects (isolation breach).`,fix:Z}));for(let n of r.modified)(Pt[n.category]||{}).doctor==="server-drift"?t.push(R({code:"mcp-core-missing",severity:$.ERROR,category:n.category,path:n.path,message:`A required Vesper-core MCP server is missing from "${n.path}".`,fix:Z})):t.push(R({code:"file-edited",severity:$.WARN,category:n.category,path:n.path,message:`"${n.path}" was edited since the last Vesper write in this worktree.`,fix:Z}));for(let n of r.missing){let s=vv.has(n.category);t.push(R({code:"owned-file-missing",severity:s?$.ERROR:$.WARN,category:n.category,path:n.path,message:s?`Load-bearing owned file "${n.path}" is missing \u2014 framework cannot operate.`:`Owned file "${n.path}" is missing \u2014 \`vespercli init\` will re-provision it.`,fix:Z}))}return t}async function ci(e,t={}){let r=new Set,n=t.installedTargets;if(!Array.isArray(n))try{let a=await zr(e);n=a?[a]:await he(e)}catch{n=[]}if(n.includes("claude"))if(t.mcpConfigs?.claude)for(let a of t.mcpConfigs.claude.servers)r.add(a);else try{let a=await $v(e);for(let c of Object.keys(a.mcpServers||{}))r.add(c)}catch{}if(n.includes("copilot"))if(t.mcpConfigs?.copilot)for(let a of t.mcpConfigs.copilot.servers)r.add(a);else try{let a=await Ye(e);for(let c of Object.keys(a.servers||{}))r.add(c)}catch{}let s=[];if("tracking"in t)s=Array.isArray(t.tracking?.mcp?.servers)?t.tracking.mcp.servers:[];else try{let a=await x(e);s=Array.isArray(a.mcp?.servers)?a.mcp.servers:[]}catch{s=[]}let o=new Set(s);return{drifted:[...r].filter(a=>!fe.includes(a)&&!o.has(a))}}async function $v(e){try{return JSON.parse(await ys(De(e),"utf-8"))}catch{return{mcpServers:{}}}}async function Ov(e){let{drifted:t}=await ci(e.workspaceRoot,{tracking:e.tracking,mcpConfigs:e.mcpConfigs,installedTargets:e.installedTargets});return t.map(r=>R({code:"mcp-drift",severity:$.WARN,category:"mcp-config",message:`MCP server "${r}" is present in the live MCP config but not tracked in .vesperrc mcp.servers.`,fix:Z}))}async function Tv(e){return!e.initialised||!e.host?[]:(e.manifestAll??e.manifestEntries).some(r=>r.category==="mcp-config")?[]:Pv(e)?[R({code:"mcp-config-unrecorded",severity:$.ERROR,category:"mcp-config",message:"A live MCP config exists but is not recorded in the owned-files manifest \u2014 Vesper cannot reconcile its managed servers.",fix:Z})]:[]}function Pv(e){return!!e.mcpConfigs?.[e.host]?.exists}function Iv(e){if(e.absent||!e.tracking)return[];let t=e.tracking;return(t.host===void 0||K.includes(t.host))&&Array.isArray(t.manifest)&&t.schemaVersion===ve?[]:[R({code:"tracking-shape-invalid",severity:$.WARN,path:".vesperrc",message:".vesperrc parses but its shape is invalid (host/manifest/schemaVersion) \u2014 `vespercli init` repairs it.",fix:Z})]}async function jv(e){let t=[];if(e.detectedHost==="both"){let r=K.every(n=>Pp(e,n));t.push(R({code:"host-ambiguous",severity:r?$.ERROR:$.WARN,message:r?_p:`${_p} (Reported as a warning: at least one host matched only generic, non-Vesper-specific files, so this is probably not a real dual provisioning.)`,fix:"vespercli init --host <claude|copilot>"}))}if(e.host){let r=e.host==="claude"?"copilot":"claude";await Rv(e,r)&&t.push(R({code:"host-residue",severity:$.WARN,message:`This workspace is host "${e.host}" but still carries "${r}" artifacts (a leftover from a host switch).`,fix:kv(r)}))}return t}async function Rv(e,t){if(e.checkout?.ignoredEvidence===t)return!0;let r=e.tracking||{};if(!(Number(r.schemaVersion)>=2)&&(t==="claude"&&r.claude||t==="copilot"&&Array.isArray(r.paths)&&r.paths.length>0))return!0;let n=[...e.residue?.[t]||[]];for(let a of e.manifestAll||[])a?.host!==t||a.owns||Re.has(a.category)||typeof a.path!="string"||a.path.includes("..")||hv(a.path)||await w(Ae(e.workspaceRoot,a.path))&&n.push(a.path);if(!n.length)return!1;if(e.checkout?.visible===null||e.checkout?.visible===void 0)return!e.checkout?.gitError;let{runGit:s}=await Promise.resolve().then(()=>(ct(),Fi)),{READ_ONLY_GIT_ENV:o}=await Promise.resolve().then(()=>(dt(),Xi)),i=await s(["--literal-pathspecs","ls-files","-z","--cached","--others","--exclude-standard","--",...n],{cwd:e.workspaceRoot,timeout:1e4,env:{...process.env,...o}});return!!i&&i.split("\0").some(Boolean)}function Nv(e){let t=[],r=e.checkout||{},n=e.ledgerHostForReporting??null;r.gitError==="dubious-ownership"?t.push(R({code:"git-dubious-ownership",severity:$.WARN,message:"git refuses this repository (dubious ownership), so Vesper cannot read its checkout and provisions nothing here.",fix:`git config --global --add safe.directory ${e.workspaceRoot}`})):r.gitError&&t.push(R({code:"git-unreadable",severity:$.INFO,message:"git could not read this repository, so Vesper provisions nothing here; run `git status` to see why.",fix:"git status"})),e.journal&&t.push(R({code:"host-switch-pending",severity:$.WARN,message:`An interrupted host switch (${e.journal.from} \u2192 ${e.journal.to}) is pending; automatic provisioning is suspended until \`vespercli init\` finishes it.`,fix:Z}));let s=!r.host&&!r.ambiguous&&!r.gitError;if(n&&(r.host&&r.host!==n||s&&!e.journal&&!e.legacy?.needsMigration)&&t.push(R({code:"host-record-stale",severity:$.INFO,path:".vesperrc",message:`This worktree's local record describes a ${n} provisioning, but the checked-out commit is ${r.host??"not provisioned"}. The record is not used to decide the host.`,fix:Ke(r.host??n)})),r.source==="local"&&r.host&&t.push(R({code:"host-local-only",severity:$.INFO,path:r.ignoredFile??void 0,message:`Vesper's activation here lives in gitignored ${r.ignoredFile}; it follows this worktree across branches, not the commit. Commit ${r.ignoredFile} for per-commit behaviour.`,fix:Ke(r.host)})),!r.host&&r.ignoredEvidence){let o=r.ignoredEvidence==="both"?"claude|copilot":r.ignoredEvidence;t.push(R({code:"host-local-unconfirmed",severity:$.WARN,path:r.ignoredFile??void 0,message:`Vesper keys for ${o} are only in gitignored ${r.ignoredFile}, and this worktree's record does not confirm them \u2014 nothing is provisioned from them. Commit ${r.ignoredFile}, or run \`vespercli init --host ${r.ignoredEvidence==="both"?"<claude|copilot>":o}\`.`,fix:r.ignoredEvidence==="both"?"vespercli init --host <claude|copilot>":Ke(o)}))}return t}function Lv(e){let t=[];for(let r of K){let n=e.residue?.[r]||[];n.length&&((e.fingerprintMatches?.[r]||[]).length>0||e.host!==r&&t.push(R({code:"host-leftover-files",severity:$.WARN,message:`Leftover ${r} files that hold your edits: ${n.join(", ")} \u2014 delete them, or run \`${Ke(r)}\` to provision ${r} again. They do not mark this workspace as ${r}.`,fix:Ke(r)})))}return t}function Cp(e){let t=K.filter(r=>e?.hosts?.[r]);return t.length===1?Ke(t[0]):"vespercli init --host claude (or --host copilot \u2014 Vesper 2.0 provisions exactly one host)"}function Mv(e){let t=[],r=e.legacy;r?.unmigrated?t.push(R({code:"legacy-workspace",severity:$.ERROR,message:`${Ze} Evidence: ${r.evidence.join(", ")||"1.x record"}.`,fix:Cp(r)})):(r?.advisory||r?.residue)&&t.push(R({code:"legacy-residue",severity:$.WARN,message:r.advisory?`Pre-2.0 Vesper leftovers and no 2.0 host (${r.evidence.join(", ")}) \u2014 \`vespercli init\` migrates them.`:`This 2.0 workspace still carries pre-2.0 Vesper state (${r.evidence.join(", ")}) \u2014 \`vespercli init\` finishes the migration.`,fix:r.residue&&e.host?Ke(e.host):Cp(r)})),r&&!r.unmigrated&&!r.advisory&&r.leftovers.length&&t.push(R({code:"legacy-leftover-files",severity:$.WARN,message:`Leftover 1.x files that hold your edits: ${r.leftovers.join(", ")} \u2014 Vesper 2.0 never reads them. Delete them once you have kept what you need.`,fix:`rm ${r.leftovers.join(" ")}`}));for(let n of e.userResidue||[])t.push(R({code:"user-level-residue",severity:$.ERROR,path:n.path,message:`The pre-1.9 machine-wide Vesper catalog is still here (${n.marker}${n.kept?`; ${n.kept} other file(s) there are yours and stay`:""}) \u2014 every project on this machine loads it. \`vespercli init\` backs the folder up and removes only the files a released Vesper build wrote.`,fix:Z}));return e.migrationTorn?t.push(R({code:"migration-record-unreadable",severity:$.WARN,path:hc(e.workspaceRoot,e.migrationTorn),message:`The newest migration record (${hc(e.workspaceRoot,e.migrationTorn)}) is unreadable, so automatic provisioning is suspended; \`vespercli init\` sets it aside and continues.`,fix:Z})):e.migrationActive&&!t.length&&t.push(R({code:"migration-in-progress",severity:$.WARN,message:"A Vesper 1.x migration was interrupted in this workspace; automatic provisioning is suspended until `vespercli init` finishes it.",fix:Z})),t}async function Dv(e){if(e.host!=="claude"||e.legacy?.needsMigration)return[];let t=await yt(),r=new Set((e.manifestEntries||[]).map(o=>o.path)),n=new Set;for(let o of e.keptItems||[])(o.reason==="edited-catalog"||o.reason==="edited-skill")&&n.add(o.rel);try{for(let o of await gv(Ae(e.workspaceRoot,".claude","agents"))){let i=`.claude/agents/${o}`;if(!o.endsWith(".md")||r.has(i)||!jo("agents",o,""))continue;let a=null;try{a=await mc(Ae(e.workspaceRoot,i))}catch{a=null}a&&!Io(a,`agents/${o}`)&&n.add(i)}}catch{}let s=[];for(let o of[...n].sort()){if(r.has(o)||!await w(Ae(e.workspaceRoot,o)))continue;let i=/^\.claude\/(agents|skills)\/([^/]+?)(\.md)?$/.exec(o);if(!i)continue;let[,a,c]=i;if(!(a==="agents"?t.agents:t.skills).has(c)||a==="skills"&&!await w(Ae(e.workspaceRoot,o,"SKILL.md")))continue;let l=a==="agents"?Ae(O,"claude","agents",`${c}.md`):Ae(O,"claude","skills",c);s.push(R({code:"kept-shadows-plugin",severity:$.WARN,path:o,message:`${o} is a 1.x copy kept because it holds your edits, and it shadows the plugin's \`vesper:${c}\` (Claude Code prefers the project-level one) \u2014 you keep getting the 1.x version.`,fix:`compare: ${a==="agents"?"diff":"diff -r"} "${Ae(e.workspaceRoot,o)}" "${l}"; then either keep yours (it wins) or delete it (${a==="agents"?"rm":"rm -r"} ${o}) to use vesper:${c}`}))}return s}async function Fv(e){if(e.host!=="claude")return[];let t;try{t=await mc(Ae(e.workspaceRoot,".claude","rules","vesper-orchestration.md"),"utf-8")}catch{return[]}let r=Vu(t,(await yt()).agents);return r.length?[R({code:"roster-unqualified-agents",severity:$.WARN,path:".claude/rules/vesper-orchestration.md",message:`The Team Roster names ${r.length} specialist(s) without the plugin namespace (${r.slice(0,6).join(", ")}${r.length>6?", \u2026":""}) \u2014 2.0 serves them as \`vesper:<name>\`, so delegation to them does not match until the roster is revalidated.`,fix:"run `/revalidate-team` once in Claude Code (it rewrites the roster with vesper:<name> names)"})]:[]}async function Vv(e){if(!e.host)return[];let t=await Jt(e.workspaceRoot,e.host);if(t===null)return[];let r=await Yt(t),{enabled:n}=await Sr(e.workspaceRoot,e.host),s=[];for(let o of r.packs){if(n.includes(o))continue;let i=[...r.needed[o].agents,...r.needed[o].skills];s.push(R({code:"pack-not-enabled",severity:$.WARN,path:nn[e.host],message:`The Team Roster names ${i.length} asset(s) of the "${o}" pack (${Ne(o)}: ${i.slice(0,6).join(", ")}${i.length>6?", \u2026":""}), but that pack is not enabled for ${e.host} in this workspace \u2014 delegation to them does not resolve until it is.`,fix:gd}))}for(let o of n)r.packs.includes(o)||yr(o)||s.push(R({code:"pack-unused",severity:$.INFO,path:e.host==="claude"?".claude/settings.json":".vscode/settings.json",message:`The "${o}" pack (${Ne(o)}) is enabled for ${e.host}, but the Team Roster names none of its assets.`,fix:`vespercli packs disable ${o} (or keep it \u2014 an unused pack costs only load time)`}));return s}async function Gv(e){if(!e.runningHost)return[];if(e.journal)return[];if(e.checkout?.source==="local"&&e.legacy?.unmigrated)return[];if(e.checkout?.source==="local"&&e.migrationActive)return[];let t=[],r=e.checkout?.host??null;if(!r)return t.push(R({code:"host-unresolved",severity:$.INFO,message:"Could not resolve the provisioned host from disk (no recorded host and no Vesper-specific fingerprint) \u2014 the host-identity check has nothing to compare against.",fix:Z})),t;if(r!==e.runningHost){let n=Pp(e,r);t.push(R({code:Tp,severity:n?$.ERROR:$.WARN,message:n?`This workspace is provisioned for host "${r}" but is running under "${e.runningHost}".`:`This workspace looks like host "${r}" but is running under "${e.runningHost}". Reported as a warning: the only evidence is generic, non-Vesper-specific files, so this may not be a Vesper workspace at all.`,fix:Ke(e.runningHost)}))}return t}async function Hv(e){if(e.host!=="claude")return[];let t;try{t=JSON.parse(await mc(on(e.workspaceRoot),"utf-8"))}catch{return[]}let r=t?.extraKnownMarketplaces?.[Ce];return r===void 0||sp(r)?[]:[R({code:"marketplace-entry-invalid",severity:$.WARN,path:".claude/settings.local.json",message:`The \`extraKnownMarketplaces.${Ce}\` entry is not in Claude Code's schema (\`source\` must be an object: {"source":"directory","path":\u2026}); Claude Code ignores it and the vesper plugin does not load.`,fix:"vespercli worktree bootstrap"})]}function Uv(e){if(!e.initialised)return[];let t=e.packageVersion;if(!t)return[];let r=e.frameworkVersion;return r?r!==t?[R({code:"framework-stale",severity:$.WARN,message:`Workspace provisioned with Vesper ${r}, running ${t}.`,fix:Z})]:[]:[R({code:"ledger-unstamped",severity:$.INFO,message:"This worktree's ledger (`.vesperrc`) carries no framework version yet \u2014 `init` has not run in this worktree (bootstrap does not stamp one).",fix:Z})]}async function Wv(e){return e.initialised?await w(Ae(e.workspaceRoot,ce))?[]:e.manifestAll?.some(t=>t?.path===ce)?[]:[R({code:"gates-missing",severity:$.INFO,path:ce,message:"No gate policy (`.vesper/gates.json`) \u2014 `vespercli gate` exits 2 here until `init` seeds one.",fix:Z})]:[]}async function Kv(e){if(e.host!=="claude")return[];let t=new Set((e.manifestAll||[]).map(n=>n?.path)),r=[];for(let n of Id)t.has(n)||await w(Ae(e.workspaceRoot,n))||r.push(n);return r.length?[R({code:"opencode-overlay-missing",severity:$.INFO,path:r[0],message:`OpenCode overlay incomplete \u2014 missing ${r.join(", ")}. \`vespercli init\` adds the missing file(s); nothing else changes (a 2.0.x Claude workspace gets the overlay this way).`,fix:Z})]:[]}async function Bv(e){if(e.host!=="claude")return[];let t=Ae(e.workspaceRoot,".claude","agents"),r=[];try{r=(await fv(t,{withFileTypes:!0})).filter(o=>o.isFile()&&o.name.endsWith(".md")).map(o=>o.name)}catch{return[]}let n=[];for(let s of r){let o=`.claude/agents/${s}`;try{let i=await ys(Ae(t,s),"utf-8"),a=zv(i);(!a||!$p(a.name)||!$p(a.description))&&n.push(R({code:"agent-frontmatter-incomplete",severity:$.WARN,category:"catalog-agent",path:o,message:`Committed agent "${o}" is missing a non-empty name/description in its frontmatter.`,fix:Z}))}catch{}}return n}function $p(e){return typeof e=="string"&&e.trim().length>0}function zv(e){let t=/^---\r?\n([\s\S]*?)\r?\n---/.exec(e);if(!t)return null;let r={};for(let n of t[1].split(/\r?\n/)){let s=/^([A-Za-z0-9_-]+):\s*(.*)$/.exec(n);if(!s)continue;let o=s[2].trim();(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),r[s[1]]=o}return r}async function Jv(e){let t=[],r=e.checkout||{};if(!r.host||r.source==="local"||r.gitError)return t;let{resolveGitHooksDir:n,gitHooksSkipMessage:s,VESPER_MANAGED_GIT_HOOKS:o,isHookTrackedByGit:i,realOrNearestAncestor:a,resolveHookWriteTarget:c}=await Promise.resolve().then(()=>(H(),pa)),{runGit:l}=await Promise.resolve().then(()=>(ct(),Fi)),{classifyForeignHook:d,HOOK_GUARD_START:p,HOOK_GUARD_END:h}=await Promise.resolve().then(()=>(wn(),hl));if(await l(["config","--type=bool","--get","vesper.hooks"],{cwd:e.workspaceRoot,timeout:5e3})==="false")return t.push(R({code:"git-hooks-opted-out",severity:$.INFO,message:"Vesper's git hooks are turned off for this repository (git config vesper.hooks false): no guard runs on checkout and no commit hygiene on commit.",fix:"git config --unset vesper.hooks && vespercli worktree bootstrap"})),t;let m=await n(e.workspaceRoot);if(!m.dir)return m.reason==="not-a-repo"||t.push(R({code:"git-hooks-not-installable",severity:$.INFO,message:s({...m,hook:"hook"})??`Git hooks not installable (${m.reason}).`,fix:"see the message"})),t;if(!m.default&&await i(await a(m.dir),m,{dir:!0}))return t.push(R({code:"git-hooks-not-installable",severity:$.INFO,message:s({reason:"tracked-by-git",configured:m.dir}),fix:"see the message"})),t;for(let f of o){let g=Ae(m.dir,f),y=await c(g),k=null;if(y.path)try{k=await ys(y.path)}catch{k=null}let v=k?k.toString("latin1"):"",S=v.indexOf(p);if(S!==-1){let N=v.indexOf(h,S),E=v.slice(S,N===-1?void 0:N);E.includes("vesper.hooks")?f==="pre-commit"&&!E.includes("VESPER_NO_SWEEP")&&t.push(R({code:"git-hook-outdated",severity:$.INFO,path:g,message:`Vesper's pre-commit git hook block (${g}) predates VESPER_NO_SWEEP: an agent's commit still sweeps every dirty knowledge path into it.`,fix:"vespercli worktree bootstrap"})):t.push(R({code:"git-hook-outdated",severity:$.INFO,path:g,message:`Vesper's ${f} git hook block (${g}) predates the run-time opt-out check: \`git config vesper.hooks false\` would not stop it.`,fix:"vespercli worktree bootstrap"}));continue}let A=null;if(!y.path)A={reason:y.reason,configured:g};else if(k&&await i(await a(y.path),m))A={reason:"tracked-by-git",configured:y.path};else if(k){let N=d(k);N.ok||(A={reason:N.reason,interpreter:N.interpreter,line:N.line})}if(A){t.push(R({code:"git-hook-not-modifiable",severity:$.INFO,path:g,message:s({...A,hook:f,hooksDir:m.dir})??`Git hook ${f} cannot carry Vesper's block (${A.reason}).`,fix:"see the message"}));continue}t.push(R({code:"git-hook-missing",severity:$.WARN,path:g,message:`Vesper's ${f} git hook block is missing (${g}): ${f==="post-checkout"?"a branch switch or a new worktree does not run the host guard":"commits do not carry the project-knowledge files"}.`,fix:"vespercli worktree bootstrap"}))}return t}var Ip=[{id:"manifest",title:"Owned-files manifest",run:e=>Cv(e)},{id:"mcp-drift",title:"MCP config drift",run:e=>Ov(e)},{id:"mcp-required",title:"MCP config recorded",run:e=>Tv(e)},{id:"tracking",title:"Tracking structure",run:e=>Iv(e)},{id:"host-conflict",title:"Host conflict",run:e=>jv(e)},{id:"host-authority",title:"Host authority (checkout vs worktree record)",run:e=>Nv(e)},{id:"host-leftover",title:"Leftover host files",run:e=>Lv(e)},{id:"legacy",title:"Pre-2.0 (1.x) residue",run:e=>Mv(e)},{id:"legacy-kept-shadows",title:"Kept 1.x copies shadowing plugin specialists",run:e=>Dv(e)},{id:"roster-namespaces",title:"Team Roster delegation names",run:e=>Fv(e)},{id:"packs",title:"Packs the Team Roster needs",run:e=>Vv(e)},{id:"git-hooks",title:"Vesper git hooks",run:e=>Jv(e)},{id:"host-mismatch",title:"Host identity",run:e=>Gv(e),failureSeverity:e=>e.runningHost?$.ERROR:$.WARN},{id:"framework-version",title:"Framework version",run:e=>Uv(e)},{id:"marketplace-entry",title:"Marketplace entry shape",run:e=>Hv(e)},{id:"agent-frontmatter",title:"Agent frontmatter",run:e=>Bv(e)},{id:"gates-config",title:"Gate policy",run:e=>Wv(e)},{id:"opencode-overlay",title:"OpenCode overlay",run:e=>Kv(e)}];function Op(e){let t=e.filter(o=>o.severity===$.ERROR),r=e.filter(o=>o.severity===$.WARN),n=e.filter(o=>o.severity===$.INFO),s=t.some(o=>o.code===Tp);return{findings:e,errors:t,warnings:r,infos:n,summary:{hasError:t.length>0,hostMismatch:s}}}async function un(e,{runningHost:t,homeDir:r,checkout:n}={}){let s=await _v(e,t,{homeDir:r,checkout:n});return s.corrupt?Op([R({code:"tracking-unparseable",severity:$.ERROR,path:hc(e,s.corruptPath),message:"Malformed .tracking structure (.vesperrc is present but unparseable) \u2014 framework cannot operate.",fix:Z})]):Op(await Yv(s,Ip))}async function Yv(e,t=Ip){let r=[];for(let n of t)try{let s=await n.run(e);Array.isArray(s)&&r.push(...s)}catch(s){let o=n.failureSeverity?n.failureSeverity(e):$.WARN;r.push(R({code:wv,severity:o,category:n.id,message:`Doctor check "${n.title}" (${n.id}) failed to run \u2014 its coverage is MISSING from this report, not clean: ${s?.message||s}`,fix:Z}))}return r}function li(e){return e.summary.hostMismatch?Oe.HOST_MISMATCH:e.summary.hasError?Oe.ERROR:Oe.OK}xe();H();function gc(e){return String(e??"").replace(/\r\n?/g,`
79
- `)}function ot(e){let t=gc(e),r=/^---\n([\s\S]*?)\n---(?:\n|$)/.exec(t);return r?{frontmatter:r[1],body:t.slice(r[0].length)}:{frontmatter:null,body:t}}function Ar(e,t){if(!e)return null;let r=gc(e).split(`
80
- `),n=r.findIndex(i=>new RegExp(`^${t}:`).test(i));if(n===-1)return null;let s=r[n].slice(t.length+1).trim();if(s&&![">","|",">-","|-"].includes(s))return/^'.*'$/.test(s)?s.slice(1,-1).replace(/''/g,"'"):/^".*"$/.test(s)?s.slice(1,-1).replace(/\\"/g,'"'):s;let o=[];for(let i=n+1;i<r.length;i++){if(!/^\s+\S/.test(r[i])){if(r[i].trim()==="")continue;break}o.push(r[i].trim())}return o.length?o.join(" "):null}function ui(e){return`'${String(e??"").replace(/[\u0000-\u001f]+/g," ").replace(/\s+/g," ").trim().replace(/'/g,"''")}'`}var Rp=Object.freeze(["vesper-orchestrator","vesper-orchestration","vesper-context"]);function qv(e){let t=e;for(let r of Rp){let n=r.replace(/^vesper-/,""),s=`.vesper/instructions/${r}.instructions.md`;t=t.replace(new RegExp(`\\.claude/rules/${r}\\.md`,"g"),s).replace(new RegExp(`\\.claude/vesper/${n}\\.md`,"g"),s)}return t.replace(/\.claude\/vesper\/\{orchestrator,orchestration,context\}\.md/g,".vesper/instructions/vesper-{orchestrator,orchestration,context}.instructions.md").replace(/\.claude\/rules\/vesper-\*\.md/g,".vesper/instructions/vesper-*.instructions.md").replace(/\.claude\/vesper\/\*\.md/g,".vesper/instructions/vesper-*.instructions.md").replace(/\.claude\/agents\/vesper-orchestrator\.md/g,".vesper/agents/vesper-orchestrator.agent.md")}function Xv(e){return qv(e).replace(/\.claude\/rules\/([A-Za-z0-9_{}*-]+)\.md/g,".vesper/instructions/$1.instructions.md").replace(/\.claude\/agents/g,".vesper/agents").replace(/\.claude\/commands/g,".vesper/prompts").replace(/\.claude\/skills/g,".vesper/skills").replace(/\.claude\/rules/g,".vesper/instructions").replace(/\.claude\/vesper\/context/g,".vesper/context").replace(/\.claude\/vesper/g,".vesper").replace(/(?<!\.vscode\/)\.mcp\.json/g,".vscode/mcp.json").replace(/\bAskUserQuestion\b/g,"vscode/askQuestions").replace(/\bTodoWrite\b/g,"manage_todo_list").replace(/`run_in_background:\s*true`/g,"`isBackground: true`").replace(/run_in_background:\s*true/g,"isBackground: true")}function Qv(e){let t=e;for(let r of Rp)t=t.replace(new RegExp(`\\.vesper/instructions/${r}\\.md`,"g"),`.vesper/instructions/${r}.instructions.md`);return t.replace(/\.vesper\/agents\/vesper-orchestrator\.md/g,".vesper/agents/vesper-orchestrator.agent.md")}var jp=Object.freeze(["start","end","gitignore","hook"]);function Np(e){return e.replace(/`\/?vesper-<pack>:<name>`/g,"`<name>`").replace(/\bvesper-<pack>:<name>\b/g,"<name>").replace(/`\/?vesper-[a-z][a-z0-9-]*:([a-z][a-z0-9-]*)`/g,"`$1`").replace(/\bvesper-[a-z][a-z0-9-]*:([a-z][a-z0-9-]*)\b/g,"$1").replace(/`vesper:<name>`/g,"`<name>`").replace(/`\/vesper:<name>`/g,"`/<name>`").replace(/`vesper:\*`/g,"`<name>`").replace(/`vesper:([a-z][a-z0-9-]*)`/g,(t,r)=>jp.includes(r)?t:`\`${r}\``).replace(/\bvesper:([a-z][a-z0-9-]*)\b/g,(t,r)=>jp.includes(r)?t:r)}function Lp(e){return Np(Qv(Xv(gc(e))))}var zA=Object.freeze({Read:"read/readFile",Bash:"execute/runInTerminal",Grep:"search/codebase",Glob:"search/fileSearch",TodoWrite:"todo",AskUserQuestion:"vscode/askQuestions",Agent:"agent/runSubagent"}),JA=Object.freeze(["read/readFile","search/codebase","search/fileSearch","edit/editFiles","edit/createFile","execute/runInTerminal","agent/runSubagent","todo","vscode/askQuestions","web","web/fetch"]),YA=Object.freeze({"claude-opus-4-8":"Claude Opus 4.8","claude-sonnet-5":"Claude Sonnet 4.6","claude-haiku-4-5-20251001":"Claude Haiku 4.5"});var qA=Object.freeze(["core","extended"]);var XA=Object.freeze(["copilot-apply-to","copilot-instructions-tier"]);var yc=Object.freeze([{key:"orchestrator",source:"vesper-orchestrator.md",name:"vesper-orchestrator",seedOnce:!1},{key:"orchestration",source:"orchestration.md.tpl",name:"vesper-orchestration",seedOnce:!0},{key:"context",source:"context.md.tpl",name:"vesper-context",seedOnce:!0}]),Vp=".vesper/context";function Gp(e){return Be(e,".vesper","agents")}function ek(e){return Be(e,".vesper","instructions")}function Hp(e){return Be(e,Vp)}var tk=".vscode/mcp.json",dC=Object.freeze([".github/",".claude/rules/",".claude/agents/",".claude/commands/",".claude/skills/"]);function di(e){return Lp(e)}function Up(e){return ui(e).slice(1,-1)}var Dp="VESPER_HOST_MISMATCH";function rk(){return["## \u{1F3AF} Who this playbook binds (read first)","","This file is attached to **every** chat and agent context in this workspace","(`applyTo: '**'`), but it is the operating playbook of exactly **one** persona.","Establish which one you are before reading further:","",`- **You are \`${L}\`** \u2014 the single pickable Vesper agent`,` (\`${bt}\`). Everything below binds you in full. The`," MANDATORY DELEGATION LAW, the Purpose Router and every Purpose Pipeline are yours.","- **You are anyone else** \u2014 a Vesper specialist you were delegated to"," (`code-reviewer`, `task-researcher`, `principal-software-engineer`, \u2026), a built-in"," mode (Agent / Ask / Edit), or a custom agent. Then the **MANDATORY DELEGATION LAW,"," the Purpose Router and the Purpose Pipelines below do NOT bind you.** You were"," delegated to precisely so that you would do the work directly: read, analyse, edit"," and run commands exactly as your own agent definition instructs. Never refuse a task"," by citing the delegation law, and never hand your task back to the orchestrator"," merely because this file is in your context.","","Sections that bind **every** agent regardless of persona: the workspace layout and","path conventions, the Tracking & History rules, and the Host-mismatch warning.","","---",""].join(`
81
- `)}function nk(e,t,r){let n=t.trim().split(/\s+/).map(s=>s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("\\s+");return e.replace(new RegExp(n,"g"),r)}var sk=Object.freeze([["installed once, globally, as the Vesper plugin","shipped inside the installed `@mthanh/vespercli` package and activated by the `chat.*FilesLocations` settings Vesper injects"],["Degraded mode (plugin unavailable)","Degraded mode (specialists unresolvable)"],["(and any session where the plugin's workspace-trust dialog was declined) the marketplace plugin does **not** load, so those specialists are **absent**","(most often because `vespercli init` was never run here, the injected `chat.agentFilesLocations` entry was pruned, or the VS Code window has not been reloaded since init) the specialist agent files do **not** resolve, so those specialists are **absent**"],["in cloud/remote ALL skills are plugin-carried and therefore absent alongside the specialists","when the specialists do not resolve, ALL package-carried skills are absent alongside them"],["skills are installed in the shared Vesper plugin and auto-discovered by name","skills ship inside the installed Vesper package and are auto-discovered by name"],["never to the plugin/global install location","never to the package install location"],["(`.vesper/`, `.vesper/`, project source)","(`.vesper/`, project source)"],["(it verified the enabled plugin's cache resolves for this project)","(it verified the specialist agent files resolve for this project)"],["when it can confirm the plugin is not resolved","when it can confirm the specialists are not resolvable"],["the plugin is actually present (e.g. a flaked desktop hook)","the specialists are actually present (e.g. a flaked guard)"]]),ok="**Namespaced delegation names",ik=`- **Plain delegation names (correctness invariant, not style):** this host has no plugin namespace \u2014 every specialist is an ordinary agent file discovered by its bare name. Delegate to them by their **plain** name (e.g. \`code-reviewer\`, \`task-researcher\`, \`principal-software-engineer\`). The Team Roster's "Agent Name" column carries these plain names verbatim \u2014 use them exactly as written. The one project-local agent is \`${L}\` (this persona). The four maintenance prompts are invoked unqualified (\`/reinit\`, \`/compact-knowledge\`, \`/revalidate-knowledge\`, \`/revalidate-team\`).`;function ak(e){return e.split(`
82
- `).map(t=>t.trimStart().startsWith("- ")&&t.includes(ok)?ik:t).join(`
83
- `)}function ck(e){let t=sk.reduce((r,[n,s])=>nk(r,n,s),e);return ak(t)}function lk(e){let r=e.indexOf("> **First-run workspace trust & plugin resolution:**");if(r===-1)return e;let n=e.indexOf(`
84
- `,r);n===-1&&(n=e.length);let s=`> **How the Vesper team resolves here:** on the Copilot host the specialist catalog is NOT a plugin and needs no workspace-trust dialog \u2014 the agents, skills, prompts and instructions are read straight from the installed \`@mthanh/vespercli\` package through the \`chat.*FilesLocations\` entries Vesper injects into \`.vscode/settings.json\`. Every package agent is a HIDDEN specialist (\`user-invocable: false\`); the only pickable Vesper agent is \`${L}\`, provisioned project-local at \`${bt}\`. If the specialists do not resolve, the settings injection is missing or VS Code has not been reloaded \u2014 reload the window, then run \`vespercli doctor\`. The **Degraded mode** section below governs how you operate while they are unavailable.`;return e.slice(0,r)+s+e.slice(n)}function Wp(e){let{body:t}=ot(e);if(!t.includes(Dp))throw new Error(`renderCopilotPlaybook: the canonical playbook no longer contains the ${Dp} marker. The host-mismatch warning keys off it \u2014 restore the "Host-mismatch warning" section in assets/claude/vesper-orchestrator.md.`);let r=ck(di(lk(t))),n=["---","applyTo: '**'",`description: 'Vesper orchestrator playbook \u2014 delegation law, purpose router, and pipelines. Binds the ${L} persona; see the scope block at the top.'`,"---",""].join(`
88
+ ${s}`;return await A(t,o,"utf-8"),{created:!1,updated:!0}}function Vv(e){let t=new RegExp(`${Ic}[\\s\\S]*?${jc}\\n*`);return e.replace(t,"")}function Hv(e){return R(e,".claude","rules")}async function ki(e){let t=Hv(e);await P(t,{recursive:!0});let r={orchestrator:"refreshed",orchestration:"skipped",context:"skipped"},n=[],s=".claude/rules/vesper-orchestrator.md";await A(R(e,s),await ie(R(De,"vesper-orchestrator.md"),"utf-8"),"utf-8"),n.push(G({path:s,host:"claude",category:"playbook",hash:await ye(R(e,s))}));let o=async(l,d,p)=>{await w(R(e,l))||(await A(R(e,l),await ie(R(De,d),"utf-8"),"utf-8"),r[p]="created"),n.push(G({path:l,host:"claude",category:"per-project-authored",hash:null}))};if(await o(".claude/rules/vesper-orchestration.md","orchestration.md.tpl","orchestration"),r.orchestration==="skipped"){let l=R(e,".claude/rules/vesper-orchestration.md"),d=await ie(l,"utf-8"),p=await At(),f=new Set;for(let h of p.agents)await w(R(e,".claude","agents",`${h}.md`))&&f.add(h);let m=zo(d,p,{skip:f});m.qualified.length&&(await A(l,m.text,"utf-8"),r.orchestration=`namespaced ${m.qualified.length} specialist name(s) to their plugin (vesper:<name> / vesper-<pack>:<name>)`)}await o(".claude/rules/vesper-context.md","context.md.tpl","context");let i=await ti(e);r.gates=i.created?`created (checks: ${i.checks.join(", ")||"none"})`:"skipped",n.push(G({path:ue,host:"claude",category:"per-project-authored",hash:null}));let a=await Dv(e);r.claudeMd=a.created?"created":a.updated?"updated":"unchanged",n.push(Y({path:"CLAUDE.md",host:"claude",category:"pointer",owns:{region:"vesper"}})),await W(e,n);let c=await Np(e);return r.opencodeAgent=c.agent,r.opencodePlugin=c.plugin,r.opencodeKept=c.keptEdited,r}async function Si(e){let t=Ve(e);try{let r=await ie(t,"utf-8");return JSON.parse(r)}catch(r){return r.code==="ENOENT"?{mcpServers:{}}:{mcpServers:{}}}}async function Ei(e,t){let r=Ve(e);await P(js(r),{recursive:!0}),await A(r,JSON.stringify(t,null," "),"utf-8")}function Uv(e){return{"vesper-indexing":{command:"node",args:[Be()],env:{VESPER_INDEX_ROOT:e}},"sequential-thinking":{command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},memory:{command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:R(e,".vesper","memory.jsonl")}}}}async function hr(e,t=!0,{record:r=!0}={}){let n=await Si(e);n.mcpServers||(n.mcpServers={});let s=Uv(e),o=Object.keys(s);if(t)for(let[i,a]of Object.entries(s))n.mcpServers[i]=a;else for(let i of o)delete n.mcpServers[i];return await Ei(e,n),t&&r&&await W(e,[Y({path:Wp,host:"claude",category:"mcp-config",owns:{keys:o}})]),{configured:t,mcpPath:Ve(e),servers:t?o:[]}}function Tc(e,t){return String(e).replace(/\$\{VESPER_INDEXING_PATH\}/g,Be()).replace(/\$\{workspaceFolder\}/g,t).replace(/\$\{env:([^}]+)\}/g,"$${$1}")}function Wv(e,{workspaceRoot:t}){let{type:r,...n}=structuredClone(e);if(typeof n.command=="string"&&(n.command=Tc(n.command,t)),Array.isArray(n.args)&&(n.args=n.args.map(s=>Tc(s,t))),n.env&&typeof n.env=="object")for(let[s,o]of Object.entries(n.env))n.env[s]=Tc(o,t);return n}async function kn(e,t){if(me.includes(t))return{added:!1,serverName:t,error:`${t} is a Vesper-managed core server \u2014 use "vespercli mcp enable --target claude" instead.`};let r=we[t];if(!r)return{added:!1,serverName:t,error:`Unknown MCP server: ${t}`};let n=await Si(e);if(n.mcpServers||(n.mcpServers={}),n.mcpServers[t])return{added:!1,serverName:t,error:"Already configured"};n.mcpServers[t]=Wv(r.config,{workspaceRoot:e}),await Ei(e,n);let s=await x(e);return s.mcp=s.mcp||{},s.mcp.servers=s.mcp.servers||[],s.mcp.servers.includes(t)||s.mcp.servers.push(t),s.mcp.updatedAt=new Date().toISOString(),await T(e,s),await Oc(e),{added:!0,serverName:t}}async function ui(e,t){if(me.includes(t))return{removed:!1,serverName:t,error:`${t} is a Vesper-managed core server \u2014 use "vespercli mcp disable --target claude" instead.`};let r=await Si(e),n=!1;r.mcpServers&&r.mcpServers[t]&&(delete r.mcpServers[t],await Ei(e,r),n=!0);let s=await x(e);return s.mcp?.servers&&(s.mcp.servers=s.mcp.servers.filter(o=>o!==t),s.mcp.updatedAt=new Date().toISOString(),await T(e,s)),await Oc(e),{removed:n,serverName:t}}async function Rc(e){let t=await Si(e),r=Object.keys(t.mcpServers||{}),n=r.filter(s=>!we[s]);return{configured:r,custom:n}}function Kv(e){let t=e?.permissions?.allow;if(!Array.isArray(t))return!1;let r=new Set(zp),n=t.filter(s=>!r.has(s));return n.length===t.length?!1:(n.length?e.permissions.allow=n:delete e.permissions.allow,Object.keys(e.permissions).length===0&&delete e.permissions,!0)}function Yp(e){(!e.permissions||typeof e.permissions!="object")&&(e.permissions={}),Array.isArray(e.permissions.allow)||(e.permissions.allow=[]);let t=0;for(let r of zp)e.permissions.allow.includes(r)||(e.permissions.allow.push(r),t+=1);return t}async function Jp(e){let t=Fe(e),r={},n=null;try{n=await ie(t,"utf-8")}catch{n=null}if(n!==null){try{r=JSON.parse(n)}catch{return{configured:0,settingsPath:t,skipped:"malformed"}}if(!r||typeof r!="object"||Array.isArray(r))return{configured:0,settingsPath:t,skipped:"malformed"}}let s=Yp(r);return(s>0||n===null)&&(await P(js(t),{recursive:!0}),await A(t,JSON.stringify(r,null," "),"utf-8")),{configured:s,settingsPath:t}}async function qp(e){let t=Fe(e),r={};try{r=JSON.parse(await ie(t,"utf-8"))}catch{r={}}let n=Yp(r);(!r.enabledPlugins||typeof r.enabledPlugins!="object")&&(r.enabledPlugins={}),r.enabledPlugins[yt]=!0,r.agent=L,zv(r),Jv(r),await P(js(t),{recursive:!0}),await A(t,JSON.stringify(r,null," "),"utf-8");let s=(await ne(e)).find(a=>a&&a.path===".claude/settings.json"&&a.host==="claude"&&a.category==="settings"),o={keys:["permissions.allow","hooks.SessionStart","hooks.SubagentStart","agent","enabledPlugins"]};Array.isArray(s?.owns?.entries)&&s.owns.entries.length&&(o.entries=[...s.owns.entries]),await W(e,[Y({path:".claude/settings.json",host:"claude",category:"settings",owns:o})]),await bi(e);let i=await Rp(e);return{configured:n,settingsPath:t,opencode:i}}function En(e){return R(e,".claude","settings.local.json")}function Bv(){return{source:{source:"directory",path:De}}}function Xp(e){return!!e&&typeof e=="object"&&!!e.source&&typeof e.source=="object"&&typeof e.source.source=="string"&&e.source.source.length>0}async function bi(e,{record:t=!0}={}){let r=En(e),n={};try{n=JSON.parse(await ie(r,"utf-8"))||{}}catch{n={}}return(!n.extraKnownMarketplaces||typeof n.extraKnownMarketplaces!="object")&&(n.extraKnownMarketplaces={}),n.extraKnownMarketplaces[$e]=Bv(),await P(js(r),{recursive:!0}),await A(r,JSON.stringify(n,null," "),"utf-8"),t&&await W(e,[Y({path:".claude/settings.local.json",host:"claude",category:"settings",owns:{keys:["extraKnownMarketplaces"]}})]),{localPath:r}}function Fp(e){let t=!1;if(e?.extraKnownMarketplaces&&$e in e.extraKnownMarketplaces&&(delete e.extraKnownMarketplaces[$e],Object.keys(e.extraKnownMarketplaces).length===0&&delete e.extraKnownMarketplaces,t=!0),e?.enabledPlugins&&yt in e.enabledPlugins&&(delete e.enabledPlugins[yt],Object.keys(e.enabledPlugins).length===0&&delete e.enabledPlugins,t=!0),e?.enabledPlugins&&typeof e.enabledPlugins=="object"){for(let r of Object.keys(e.enabledPlugins))Sr(r)!==null&&(delete e.enabledPlugins[r],t=!0);Object.keys(e.enabledPlugins).length===0&&delete e.enabledPlugins}return e?.agent===L&&(delete e.agent,t=!0),t}function Nc(e,{command:t=Qp,markers:r=Object.values(Is)}={}){let n=JSON.stringify(e.hooks?.SessionStart??null);return xi(e,{markers:r}),e.hooks||(e.hooks={}),Array.isArray(e.hooks.SessionStart)||(e.hooks.SessionStart=[]),e.hooks.SessionStart.push({hooks:[{type:"command",command:t}]}),JSON.stringify(e.hooks.SessionStart)!==n}function zv(e){Nc(e)}function xi(e,{markers:t}={}){if(!Array.isArray(t)||t.length===0)throw new Error("removeVesperSessionStartHook: an explicit `markers` list is required (see VESPER_HOOK_MARKERS)");return Zp(e,"SessionStart",t)}function Zp(e,t,r){if(!Array.isArray(e?.hooks?.[t]))return!1;let n=new Set(r.flat().filter(a=>typeof a=="string"&&a.trim()).map(a=>a.trim())),s=a=>typeof a?.command=="string"&&n.has(a.command.trim()),o=!1,i=[];for(let a of e.hooks[t]){if(!a||!Array.isArray(a.hooks)){i.push(a);continue}let c=a.hooks.filter(l=>!s(l));if(c.length===a.hooks.length){i.push(a);continue}o=!0,c.length>0&&i.push({...a,hooks:c})}return e.hooks[t]=i,e.hooks[t].length===0&&delete e.hooks[t],e.hooks&&Object.keys(e.hooks).length===0&&delete e.hooks,o}function Jv(e){let t=JSON.stringify(e.hooks?.SubagentStart??null);return tf(e),e.hooks||(e.hooks={}),Array.isArray(e.hooks.SubagentStart)||(e.hooks.SubagentStart=[]),e.hooks.SubagentStart.push({hooks:[{type:"command",command:ef}]}),JSON.stringify(e.hooks.SubagentStart)!==t}function tf(e,{markers:t=Object.values(Yv)}={}){return Zp(e,"SubagentStart",t)}async function rf(e,t={}){let r=await x(e);return r.schemaVersion=ve,r.host="claude",t.namePrefix!==void 0&&(r.namePrefix=t.namePrefix),t.pluginPath!==void 0&&(r.pluginPath=t.pluginPath),t.version!==void 0&&(r.frameworkVersion=t.version),r.updatedAt=new Date().toISOString(),await T(e,r),r}function Lc(e){let t=String(e);for(let r of["adhd","ponytail"])t=t.replace(new RegExp(`\\n*<!-- vesper:${r}:start -->[\\s\\S]*?<!-- vesper:${r}:end -->\\n*`),`
89
+ `);return t}async function qv(e){let t=R(Hp(e),"context"),r=R(e,".vesper","context"),n=await w(r),s={removed:[],kept:[]},o;try{o=await lt(t)}catch{return s}for(let i of o.files){let a=!n;if(n)try{a=ee(await ie(R(t,i)),await ie(R(r,i)))}catch{a=!1}a?(await Sn(R(t,i),{force:!0}),s.removed.push(i)):s.kept.push(i)}s.kept.push(...o.others);for(let i of o.dirs)try{await Pc(R(t,i))}catch{}try{await Pc(t)}catch{}return s}function Dp(e){let t=String(e).replace(/\r\n/g,`
90
+ `),r=/^---\n[\s\S]*?\n---\n/.exec(t);return(r?t.slice(r[0].length):t).trim()}async function Xv(e){let t={removed:[],kept:[]};for(let r of["orchestration","context"]){let n=`.claude/vesper/${r}.md`,s;try{s=await ie(R(e,n),"utf-8")}catch{continue}let o=null;try{o=await ie(R(e,".vesper","instructions",`vesper-${r}.instructions.md`),"utf-8")}catch{o=null}let i=Dp(s);o===null||i!==""&&Dp(o).includes(i)?(await Sn(R(e,n),{force:!0}),t.removed.push(n)):t.kept.push(n)}return t}async function bn(e,{purgeProjectAuthored:t=!1}={}){let r=Hp(e),n=".claude/vesper/orchestrator.md";await le(R(e,n),{path:n,category:"playbook"});let s=[];t&&(s.push(...(await Xv(e)).kept),s.push(...(await qv(e)).kept.map(y=>`.claude/vesper/context/${y}`)));try{await Pc(r)}catch{}let o=await x(e),i=new Set,a=Array.isArray(o.manifest)?o.manifest:[],c=new Set(a.filter(y=>y&&y.host!=="claude"&&y.category==="per-project-authored").map(y=>y.path));for(let y of a)Ko(y,{host:"claude",purgeProjectAuthored:t})&&(y.category==="per-project-authored"&&c.has(y.path)||i.add(y.path));for(let y of Array.isArray(o.claude?.catalogManifest)?o.claude.catalogManifest:[]){if(typeof y!="string"||y.includes(".."))continue;let[k,...v]=y.split("/");!Lv.includes(k)||v.length===0||i.add(`.claude/${y}`)}for(let y of i){let k=(o.manifest||[]).find(v=>v?.path===y)||{path:y,category:y.startsWith(".claude/skills/")?"catalog-skill":"catalog-agent"};await le(R(e,y),k,{purgeProjectAuthored:t})}let{kept:l}=await Yo(e,"claude");l.push(...(await hn(e,"claude")).kept);let d=await Mp(e,{manifest:a}),p=Up(e);if(await w(p)){let y=await ie(p,"utf-8"),k=Lc(Vv(y));k.trim()?await A(p,k,"utf-8"):await Sn(p,{force:!0})}await hr(e,!1);let f=Array.isArray(o.mcp?.servers)?o.mcp.servers:[];if(f.length&&await w(Ve(e)))try{let y=JSON.parse(await ie(Ve(e),"utf-8")),k=!1;for(let v of f)y?.mcpServers&&typeof y.mcpServers=="object"&&v in y.mcpServers&&(delete y.mcpServers[v],k=!0);k&&await Ei(e,y)}catch{}try{let y=JSON.parse(await ie(Ve(e),"utf-8"));y&&typeof y=="object"&&Object.keys(y).every(v=>v==="mcpServers")&&(!y.mcpServers||Object.keys(y.mcpServers).length===0)&&await Sn(Ve(e),{force:!0})}catch{}let m=Fe(e);if(await w(m))try{let y=JSON.parse(await ie(m,"utf-8")),k=xi(y,{markers:[Is.legacy,Is.bootstrap]}),v=tf(y),S=Fp(y),C=Kv(y);(k||v||S||C)&&(Object.keys(y).length===0?await Sn(m,{force:!0}):await A(m,JSON.stringify(y,null," "),"utf-8"))}catch{}let h=En(e);if(await w(h))try{let y=JSON.parse(await ie(h,"utf-8"));Fp(y)&&(Object.keys(y).length===0?await Sn(h,{force:!0}):await A(h,JSON.stringify(y,null," "),"utf-8"))}catch{}let g=await x(e);return delete g.claude,g.host==="claude"&&delete g.host,delete g.namePrefix,delete g.pluginPath,Array.isArray(g.manifest)&&(g.manifest=g.manifest.filter(y=>!(y&&y.host==="claude")||!t&&Ne.has(y.category))),await T(e,g),{kept:l,knowledgeKept:s,overlayKept:d.kept}}var De,fr,$e,Nv,Lv,Mv,Wp,Ic,jc,zp,Qp,Is,ef,Yv,Ae=Z(()=>{Ee();un();U();Ye();dn();pt();Es();mc();H();te();fe();As();De=R(O,"claude"),fr=R(O,"claude-committed"),$e="vesper-marketplace",Nv=["agents","skills"],Lv=["agents","commands","skills"],Mv="vesper";Wp=".mcp.json";Ic="<!-- vesper:start -->",jc="<!-- vesper:end -->";zp=Object.freeze(["mcp__vesper-indexing__vesper_search","mcp__vesper-indexing__vesper_symbols","mcp__vesper-indexing__vesper_status","mcp__vesper-indexing__vesper_reindex","mcp__sequential-thinking__sequentialthinking","mcp__memory__create_entities","mcp__memory__create_relations","mcp__memory__add_observations","mcp__memory__delete_entities","mcp__memory__delete_observations","mcp__memory__delete_relations","mcp__memory__read_graph","mcp__memory__search_nodes","mcp__memory__open_nodes"]);Qp=`command -v vespercli >/dev/null 2>&1 && ${qr("claude")} || true`,Is=Object.freeze({legacy:Object.freeze([Ln,Mn]),bootstrap:Object.freeze([Gn]),guard:Object.freeze([Qp])});ef="command -v vespercli >/dev/null 2>&1 && vespercli log delegated --pipeline hook --note hook --stdin || true",Yv=Object.freeze({runLedger:Object.freeze([ef])})});import{Command as px,Option as mt}from"commander";import{readFileSync as fx,existsSync as hx}from"node:fs";import{fileURLToPath as mx}from"node:url";import{dirname as Hl,join as Xm}from"node:path";U();H();te();Ae();import{resolve as OE,basename as Jh,relative as TE,sep as PE,isAbsolute as IE}from"node:path";import{spawn as jE}from"node:child_process";import{confirm as Kt,input as RE,number as NE,select as LE}from"@inquirer/prompts";U();Ye();Es();H();te();fe();import{readFile as Gs,rm as Pf,rmdir as lS}from"node:fs/promises";import{join as qe}from"node:path";te();H();Ae();be();import{readFile as Ms,readdir as Ek}from"node:fs/promises";import{join as Ce,isAbsolute as bk,relative as xk}from"node:path";import{readdir as Qv,readFile as nf,rename as Zv,access as ek,constants as tk}from"node:fs/promises";import{join as mr}from"node:path";import{execFile as rk}from"node:child_process";var Mc=".vesper/.migration-backup";async function sf(e){try{return await ek(e,tk.F_OK),!0}catch{return!1}}function nk(e){return new Promise(t=>{try{rk("git",["rev-parse","--verify","-q","HEAD"],{cwd:e,timeout:5e3,encoding:"utf-8",env:{...process.env,GIT_NO_LAZY_FETCH:"1",GIT_OPTIONAL_LOCKS:"0",GIT_TERMINAL_PROMPT:"0",GCM_INTERACTIVE:"never",SSH_ASKPASS_REQUIRE:"never",LC_ALL:"C"}},(n,s)=>t(n?null:String(s).trim()||null)).stdin?.end()}catch{t(null)}})}async function of(e){try{return(await Qv(mr(e,Mc),{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name).sort()}catch{return[]}}async function Ai(e,{head:t}={}){let r=await of(e);if(r.length===0)return!1;let n=mr(e,Mc),s=t!==void 0?t:await nk(e),o=r.at(-1);for(let i of[...r].reverse()){let a;try{a=await nf(mr(n,i,"rollback.json"),"utf-8")}catch{continue}let c;try{c=JSON.parse(a)}catch{if(i!==o)continue;return!await sf(mr(n,i,"created.txt"))}if(!c||!Array.isArray(c.before)||s!==null&&c.head!==s)continue;return(typeof c.status=="string"?c.status:Array.isArray(c.created)?"finished":"started")==="started"}return!1}async function Gc(e){let t=await of(e);if(!t.length)return null;let r=mr(e,Mc,t.at(-1)),n;try{n=await nf(mr(r,"rollback.json"),"utf-8")}catch{return null}try{return JSON.parse(n),null}catch{}return await sf(mr(r,"created.txt"))?null:mr(r,"rollback.json")}async function af(e,{now:t=new Date}={}){let r=await Gc(e);if(!r)return null;let n=`${r}.torn-${t.toISOString().replace(/[:.]/g,"-")}`;return await Zv(r,n),{from:r,to:n}}U();H();te();Ae();fe();Ye();be();import{readFile as pf,rm as pk,rmdir as fk}from"node:fs/promises";import{join as Uc}from"node:path";H();fe();Ee();mc();be();import{readFile as Dc,readdir as uf}from"node:fs/promises";import{readdirSync as sk}from"node:fs";import{join as _e,basename as ok}from"node:path";import{homedir as ik}from"node:os";var ak=Object.freeze(["agents","commands","skills"]),ck=Object.freeze(["claude","paths","catalogVersion","targets"]),Gr=".vesper/.migration-backup",nt="This is a pre-2.0 (1.x) Vesper workspace. Run `vespercli init` to migrate it in place \u2014 nothing of yours is deleted, and anything Vesper removes is backed up first.";async function $i(e){let t=[...new Set([await Et(e),_e(e,".vesperrc"),_e(e,".vesper","tracking.json")])],r=null,n=null;for(let c of t){let l;try{l=await Dc(c,"utf-8")}catch(d){if(d&&d.code==="ENOENT")continue;return _i({config:"corrupt",path:c})}try{r=JSON.parse(l),n=c}catch{return _i({config:"corrupt",path:c})}break}if(!r||typeof r!="object")return _i({config:"absent",path:null});let s=Number(r.schemaVersion)>=2?"v2":"v1",o=[];for(let c of Array.isArray(r.claude?.catalogManifest)?r.claude.catalogManifest:[]){if(typeof c!="string"||c.includes("..")||c.startsWith("/"))continue;let[l,...d]=c.split("/");!ak.includes(l)||d.length===0||o.push(`.claude/${c}`)}let i=c=>Array.isArray(c)?c.filter(l=>typeof l=="string"):[],a=r.claude?.namePrefix??r.namePrefix;return _i({config:s,path:n,catalogManifest:o,namePrefix:typeof a=="string"?a:"",injectedPaths:i(r.paths),readAccessPaths:i(r.readAccessPaths),mcpServers:i(r.mcp?.servers),vendored:r.vendored&&typeof r.vendored=="object"?JSON.parse(JSON.stringify(r.vendored)):void 0,hosts:s==="v1"?{claude:!!r.claude,copilot:i(r.paths).length>0}:{claude:!1,copilot:!1},staleKeys:s==="v2"?ck.filter(c=>c in r):[],recordedHost:s==="v2"?Bn({host:r.host}):null,version:s==="v1"&&[r.catalogVersion,r.claude?.catalogVersion,r.version].find(c=>typeof c=="string"&&/^1\.\d+\.\d+/.test(c))||null})}function _i(e){return Object.freeze({config:"absent",path:null,catalogManifest:[],namePrefix:"",injectedPaths:[],readAccessPaths:[],mcpServers:[],vendored:void 0,hosts:{claude:!1,copilot:!1},staleKeys:[],recordedHost:null,version:null,...e})}async function Oe(e,{checkout:t}={}){let r=await $i(e),n;try{n=await K(e)}catch{n=void 0}let s=await hu(e,{vscodeSettings:n}),o={claude:s.hosts.claude||r.hosts.claude,copilot:s.hosts.copilot||r.hosts.copilot},i=[...s.matched];r.config==="v1"&&i.unshift(`${ok(r.path||".vesperrc")} (1.x record)`);let a=!1,c=!1,l=!1,d=null;try{let f=t??await B(e);d=f.source==="local"?null:f.host??f.candidate??null}catch{d=null}r.config==="corrupt"||(r.config==="v1"&&(r.hosts.claude||r.hosts.copilot||r.mcpServers.length>0||r.vendored!==void 0||s.primary)?a=!0:d?(s.primary||r.staleKeys.length)&&(l=!0,i.push(...r.staleKeys.map(f=>`.vesperrc key "${f}"`))):s.primary?a=!0:s.residue.length&&!d&&(c=!0,o.claude=!0,i.push(...s.residue)));let p=a||c?[]:[...s.residue];return{unmigrated:a,advisory:c,residue:l,needsMigration:a||c||l,corrupt:r.config==="corrupt",config:r.config,hosts:o,staleKeys:[...r.staleKeys],evidence:[...new Set(i)],leftovers:p,record:r}}var lk="<!-- vesper(?::[a-z0-9-]+)?:start -->[\\s\\S]*?<!-- vesper(?::[a-z0-9-]+)?:end -->",cf=e=>new RegExp(lk).test(e),uk=Object.freeze([Ln,Mn,Gn]);async function Fc(e){try{return await uf(e,{withFileTypes:!0})}catch{return[]}}async function Ci(e){try{return await Dc(e)}catch{return null}}function lf(e){let t=new Set;for(let r of[_e(O,"claude",e),_e(O,"claude-committed",e)])try{for(let n of sk(r))t.add(n.replace(/\.md$/,""))}catch{}return t}function dk(e){let t=/^---\r?\n([\s\S]*?)\r?\n---/.exec(e);if(!t)return null;let r=/^name:\s*['"]?([A-Za-z0-9_.-]+)['"]?\s*$/m.exec(t[1]);return r?r[1]:null}async function Oi({homeDir:e=ik(),pluginName:t="vesper",workspaceRoot:r}={}){let n=[],s=(p,f,m,h,g={})=>n.push({path:_e(e,p),rel:p,kind:f,tier:m,marker:h,...g}),o=lf("agents"),i=lf("skills"),a=`.claude/skills/${t}`,c=await xs({pluginName:t,staleDir:_e(e,a),workspaceRoot:r});(c.reason==="match"||c.reason==="manifest-less-ours")&&c.proven.length&&s(a,"plugin",2,`${c.proven.length} file(s) byte-identical to a released Vesper 1.x build`,{proven:c.proven.length,kept:c.kept.length});for(let[p,f]of[[".claude/rules",m=>m.endsWith(".md")],[".copilot/instructions",()=>!0]])for(let m of await Fc(_e(e,p))){if(!m.isFile()||!f(m.name))continue;let h=`${p}/${m.name}`,g=(await Ci(_e(e,h)))?.toString("utf-8")??"";cf(g)?s(h,"file",3,"a Vesper guard block"):m.name.startsWith("vesper-")&&s(h,"file",3,"a vesper- file name")}for(let p of[".claude/agents",".copilot/agents"])for(let f of await Fc(_e(e,p))){if(!f.isFile()||!f.name.endsWith(".md"))continue;let m=`${p}/${f.name}`,h=await Ci(_e(e,m));if(!h)continue;let g=f.name.replace(/(\.agent)?\.md$/,"");(o.has(dk(h.toString("utf-8"))||g)||o.has(g)||f.name.startsWith("vesper-"))&&s(m,"file",3,"a Vesper agent name")}for(let p of[".claude/skills",".copilot/skills"])for(let f of await Fc(_e(e,p)))f.isDirectory()&&(p===".claude/skills"&&f.name===t||(i.has(f.name)||f.name.startsWith("vesper-"))&&s(`${p}/${f.name}`,"dir",3,"a Vesper skill name"));let l=(await Ci(_e(e,".claude","CLAUDE.md")))?.toString("utf-8");l&&cf(l)&&s(".claude/CLAUDE.md","region",3,"a Vesper guard block");let d=await Ci(_e(e,".claude","settings.json"));if(d){let p=null;try{p=JSON.parse(d.toString("utf-8"))}catch{p=null}if(p&&typeof p=="object"){let f=[],m=p.hooks&&typeof p.hooks=="object"?p.hooks:{};for(let[h,g]of Object.entries(m))Array.isArray(g)&&g.some(y=>Array.isArray(y?.hooks)&&y.hooks.some(k=>typeof k?.command=="string"&&uk.includes(k.command.trim())))&&f.push(`hooks.${h}`);p.agent===L&&f.push("agent"),f.length&&s(".claude/settings.json","keys",3,`Vesper keys: ${f.join(", ")}`)}}return n.sort((p,f)=>p.rel.localeCompare(f.rel))}async function df(e){let t=_e(e,Gr),r=[];try{r=(await uf(t,{withFileTypes:!0})).filter(s=>s.isDirectory()).map(s=>s.name).sort()}catch{r=[]}let n=[];for(let s of r){let o;try{o=JSON.parse(await Dc(_e(t,s,"kept.json"),"utf-8"))}catch{continue}if(Array.isArray(o))for(let i of o)i&&typeof i.rel=="string"&&typeof i.reason=="string"&&n.push({rel:i.rel,reason:i.reason,backup:_e(t,s)})}return n}it();var Ti="VESPER_HOST_MISMATCH",Wc="VESPER_PLUGIN_ABSENT",re="vespercli init",Je=e=>`vespercli init --host ${e}`,Ns="opencode";function ff(e){return e===Ns?"claude":e}function hf(e){return z.includes(e)||e===Ns}function hk(e,t,{runningLabel:r}={}){return t==="copilot"&&e==="claude"?`This workspace is provisioned for Claude Code, and VS Code just opened it. If you use GitHub Copilot here, run \`${Je("copilot")}\` (it removes the Claude Code setup). If you use Claude Code inside VS Code, ignore this message \u2014 nothing was changed.`:r===Ns&&t==="claude"?`This workspace is provisioned for "${e}" but is running under OpenCode, which uses the "claude" host. Fix: ${Je("claude")}`:`This workspace is provisioned for "${e}" but is running under "${t}". Fix: ${Je(t)}`}var Rs=".vesper/instructions/vesper-host-guard.instructions.md",Vc="guard-rule",mk=["---","applyTo: '**'",'description: "Vesper host guard \u2014 refuse work in this workspace while a host mismatch is active"',"---","","# Vesper host guard","","Before doing anything else in this workspace, check whether `.vesper/.host-guard/ACTIVE` exists.","",`If it does, treat this session as \`${Ti}\`: this workspace was provisioned for a`,"different AI host than the one you are running in. Refuse all provisioning and orchestration","work, print the `fix:` command the file contains (`vespercli init --host <running host>` to","re-provision this workspace for the host you are running in, or `vespercli reset --host <x>`","to remove one host's Vesper files), and take no other action.","","If the file does not exist, this rule imposes nothing \u2014 proceed normally.","","This file is written by Vesper (`vespercli`) and is constant; the sentinel it names is","gitignored and written/cleared by `vespercli guard`.",""].join(`
91
+ `);function Kc(e){return e==="claude"?"copilot":"claude"}async function mf(e){let t=Fe(e),r={},n=!0;try{r=JSON.parse(await pf(t,"utf-8")),n=!1}catch{r={}}(!r||typeof r!="object"||Array.isArray(r))&&(r={});let s=Nc(r);return(s||n)&&(await P(Uc(e,".claude"),{recursive:!0}),await A(t,JSON.stringify(r,null," "),"utf-8")),{changed:s,created:n}}function gk(){return{label:Jn.taskLabel,command:qr("copilot"),presentation:{reveal:"always",panel:"shared"}}}async function yk(e,t,{unattended:r=!1}={}){return An(t),t==="claude"?mf(e):Xn(e,{createOnly:r})}async function gf(e,t){if(An(t),t==="claude"){let n=await mf(e);return await W(e,[Y({path:".claude/settings.json",host:"shared",category:"guard-trigger",owns:{keys:["hooks.SessionStart"]}})]),n}let r=await ko(e,gk());return await W(e,[Y({path:".vscode/tasks.json",host:"shared",category:"guard-trigger",owns:{keys:[Jn.taskLabel]}})]),r}async function Pi(e,t,{unattended:r=!1}={}){return An(t),await yk(e,t,{unattended:r}),await gf(e,Kc(t)),{legacyGuardRule:await Fr(e)}}async function Hc(e,t){let r=await x(e),n=J(r),s=n.filter(o=>!t(o));return s.length===n.length?!1:(r.manifest=s,await T(e,r),!0)}async function Ls(e,t){An(t);let r=J(await x(e));if(t==="claude"){let i=Fe(e);if(await w(i))try{let a=JSON.parse(await pf(i,"utf-8"));xi(a,{markers:[Is.guard]})&&(Object.keys(a).length===0?await pk(i,{force:!0}):await A(i,JSON.stringify(a,null," "),"utf-8"))}catch{}await Hc(e,a=>a.path===".claude/settings.json"&&a.category==="guard-trigger");return}let n=r.some(i=>i.path===".vscode/tasks.json"&&i.category==="guard-trigger"),s=r.some(i=>i.path===".vscode/tasks.json"&&i.host==="copilot"),{fileRemoved:o}=await qn(e,Jn.taskLabel,{removeFileIfEmpty:n&&!s});if(o)try{await fk(Uc(e,".vscode"))}catch{}await Hc(e,i=>i.path===".vscode/tasks.json"&&i.category==="guard-trigger")}async function Fr(e){let n=J(await x(e)).find(o=>o.path===Rs&&o.category===Vc)??{path:Rs,category:Vc,hash:null},s=await le(Uc(e,Rs),n,{expected:[mk]});return await Hc(e,o=>o.path===Rs&&o.category===Vc),s==="partial"?"kept":s}function xn(){return`Kept your edited ${Rs} \u2014 Vesper no longer uses this file (a host mismatch now warns instead of refusing work) and never deletes a copy that differs from what it wrote. Delete it by hand.`}function wk(e){return e?.ignoredFile&&e.ignoredEvidence&&e.ignoredEvidence!=="both"?`This repository gitignores ${e.ignoredFile}, so a checkout cannot confirm the ${e.ignoredEvidence} provisioning it carries \u2014 bootstrap wrote nothing; session start still provisions this worktree. To bootstrap on checkouts too, commit ${e.ignoredFile} (remove it from .gitignore).`:e?.candidate?`This checkout's committed files carry no ${e.candidate} provisioning \u2014 bootstrap wrote nothing. Session start (or \`vespercli init\`) provisions it.`:"Not a vesperized workspace \u2014 nothing to bootstrap. Run `vespercli init` to set up."}function vk(e,t){return e?.gitError==="dubious-ownership"?`git refuses this repository (dubious ownership), so Vesper cannot read its checkout and provisions nothing here. Fix: git config --global --add safe.directory ${t}`:"git could not read this repository, so Vesper provisions nothing here; run `git status` to see why."}async function Ii(e,{runningHost:t,runningLabel:r}={}){let n=t!==void 0,s={identity:n,network:n,runningHost:t,journal:null,fix:null,note:null,message:null},o=await Gt(e),i=await B(e,{requireCommitted:!n&&!o});if(o)return n&&t!==o.to?{...s,action:"refuse",reason:"switch-in-progress",host:o.to,checkout:i,journal:o,fix:re,message:`An interrupted host switch (${o.from} \u2192 ${o.to}) is pending in this workspace. Fix: ${re}`}:{...s,action:"none",reason:"switch-in-progress",host:null,checkout:i,journal:o,note:`An interrupted host switch (${o.from} \u2192 ${o.to}) is pending \u2014 run \`vespercli init\` to finish it.`};let a=async()=>{let l=null;try{l=await Oe(e,{checkout:i})}catch{l=null}return l?.unmigrated?{...s,action:"none",reason:"legacy-unmigrated",host:null,checkout:i,note:`Bootstrap wrote nothing. ${nt}`}:await Ai(e)?{...s,action:"none",reason:"migration-in-progress",host:null,checkout:i,note:"A Vesper 1.x migration was interrupted in this workspace \u2014 run `vespercli init` to finish it. Nothing was provisioned."}:null},c=i.source==="local";if(c){let l=await a();if(l)return l}if(n&&i.host&&i.host!==t)return{...s,action:"refuse",reason:"host-mismatch",host:i.host,checkout:i,fix:Je(t),message:hk(i.host,t,{runningLabel:r})};if(!c){let l=await a();if(l)return l}if(i.gitError)return{...s,action:"none",reason:i.gitError==="dubious-ownership"?"not-vesperized":"git-unreadable",host:null,checkout:i,note:vk(i,e)};if(i.ambiguous)return{...s,action:"none",reason:"host-ambiguous",host:null,checkout:i,note:n?et:null};if(!i.host){let l=!n&&i.candidate?"host-unconfirmed":"not-vesperized",d=n?await Tr(e):null,p=d?`This worktree's local record names ${d}, but the checked-out commit carries no Vesper provisioning \u2014 nothing was provisioned. \`vespercli init --host ${t}\` provisions it.`:wk(i);return{...s,action:"none",reason:l,host:null,checkout:i,note:p}}return{...s,action:"bootstrap",reason:"healthy",host:i.host,checkout:i}}async function yf(e,t,{checkout:r}={}){if(An(t),r?.source==="local"){for(let n of[kk(t),".vesperrc"])if(!await Sk(e,n))return{healed:!1,reason:"local-tier"}}return await gf(e,t),{healed:!0}}function kk(e){return An(e),e==="claude"?".claude/settings.json":".vscode/tasks.json"}async function Sk(e,t){return await D(["check-ignore","-q","--",t],{cwd:e,timeout:5e3})!==null}function An(e){if(!z.includes(e))throw new Error(`host must be one of: ${z.join(", ")} (received "${e}")`)}fe();Ee();un();Ut();dn();pt();it();U();Es();As();bs();import{readFile as zc,readdir as Ak}from"node:fs/promises";import{homedir as _k}from"node:os";var $=Object.freeze({ERROR:"error",WARN:"warn",INFO:"info"}),Te=Object.freeze({OK:0,ERROR:1,HOST_MISMATCH:2}),wf=new Set(Object.values($)),xf="host-mismatch",Ck="check-failed",$k=new Set(["playbook","pointer","mcp-config","settings"]);var vf=Ho,Ok=e=>`vespercli reset --host ${e}`;function I({code:e,severity:t,message:r,fix:n,category:s,path:o}){if(!wf.has(t))throw new Error(`makeFinding: unknown severity "${t}" for code "${e}". Valid severities: ${[...wf].join(", ")}. An unbucketed finding is invisible to both the rendered report and the exit code.`);let i={code:e,severity:t,message:r,fix:n||re};return s!==void 0&&(i.category=s),o!==void 0&&(i.path=o),i}function Bc(e,t){if(!t)return t;let r=xk(e,t);return r.startsWith("..")?t:r}async function Tk(e){let r=[await Et(e),Ce(e,".vesperrc"),Ce(e,".vesper","tracking.json")],n=new Set;for(let s of r){if(n.has(s))continue;n.add(s);let o;try{o=await Ms(s,"utf-8")}catch(i){if(i&&i.code==="ENOENT")continue;return{corrupt:!0,corruptPath:s}}try{return{tracking:JSON.parse(o),trackingPath:s}}catch{return{corrupt:!0,corruptPath:s}}}return{absent:!0}}async function kf(e,t){let r=!1;try{r=await w(e)}catch{r=!1}if(!r)return{path:e,exists:!1,servers:[]};try{let n=JSON.parse(await Ms(e,"utf-8"));return{path:e,exists:!0,servers:Object.keys(n[t]||{})}}catch{return{path:e,exists:!0,servers:[]}}}async function Pk(e,t,{visible:r}={}){let n={};for(let s of Object.keys(t)){n[s]=[];for(let o of t[s])try{await qt(e,o,{visible:r})&&n[s].push(o)}catch(i){if(!Ik(i))throw i}}return n}function Ik(e){return!!e&&typeof e.code=="string"&&["ENOENT","EACCES","EISDIR","ENOTDIR","EPERM","ELOOP","ENAMETOOLONG"].includes(e.code)}function jk(e){return ya(e)}async function Rk(e,t,{homeDir:r=_k(),checkout:n=null}={}){let s=await Tk(e);if(s.corrupt)return{workspaceRoot:e,runningHost:t,corrupt:!0,corruptPath:s.corruptPath};let o=s.tracking||null,i=n;i||(i=await B(e,{withCommitted:!0}));let a=i.host,c=null;try{c=await Gt(e)}catch{c=null}let l=null,d=!1;try{l=await Gc(e)}catch{l=null}try{d=await Ai(e)}catch{d=!1}let p=await dd(e),f=[...p.missing,...p.modified,...p.clean],m=await Wo(e),h=Qs(),g=[];try{g=await ge(e)}catch{g=[]}let y=a?[a]:g,k={claude:await kf(Ve(e),"mcpServers"),copilot:await kf(Qe(e),"servers")},v=Zt(),S=i.ambiguous?"both":i.host,C=await Pk(e,v,{visible:i.visible}),N={};for(let[Ue,yr]of Object.entries(C))N[Ue]=yr.some(jk);let E={};for(let Ue of z)E[Ue]=await Fn(e,Ue);let b=null;try{b=await Oe(e,{checkout:i})}catch{b=null}let F=[];try{F=(await Oi({homeDir:r,workspaceRoot:e})).filter(Ue=>Ue.kind==="plugin")}catch{F=[]}let X=[];try{X=await df(e)}catch{X=[]}let He=await Tr(e),Tn=!!He&&He!==a;{let Ue=i.source==="local"?null:a,yr=wr=>{if(!wr)return!1;if(z.includes(wr.host))return wr.host===Ue;let Ct=Nk(wr);return!Ct||Ct===Ue};p={...p,missing:p.missing.filter(yr),modified:p.modified.filter(yr),clean:p.clean.filter(yr),userLevelViolations:p.userLevelViolations}}let _t=[...p.missing,...p.modified,...p.clean],zt=!!a||f.length>0;return{workspaceRoot:e,runningHost:t,absent:!!s.absent,tracking:o,host:a,checkout:i,ledgerHostForReporting:He,verify:p,manifestEntries:_t,manifestAll:f,recordStale:Tn,journal:c,migrationTorn:l,migrationActive:d,frameworkVersion:m,packageVersion:h,installedTargets:y,mcpConfigs:k,detectedHost:S,fingerprintMatches:C,fingerprintSpecific:N,residue:E,legacy:b,userResidue:F,keptItems:X,initialised:zt}}function Nk(e){return e.category==="guard-rule"||e.category==="guard-trigger"&&e.path===".claude/settings.json"?"copilot":e.category==="guard-trigger"&&e.path===".vscode/tasks.json"?"claude":null}function Af(e,t){return e.checkout?.host===t||!!e.fingerprintSpecific?.[t]}function Lk(e){let t=[],{verify:r}=e;for(let n of r.userLevelViolations)t.push(I({code:"user-level-violation",severity:$.ERROR,category:n.category,path:n.path,message:`Owned file "${n.path}" sits under a user-level scan path \u2014 it would silently activate in unrelated projects (isolation breach).`,fix:re}));for(let n of r.modified)(Ft[n.category]||{}).doctor==="server-drift"?t.push(I({code:"mcp-core-missing",severity:$.ERROR,category:n.category,path:n.path,message:`A required Vesper-core MCP server is missing from "${n.path}".`,fix:re})):t.push(I({code:"file-edited",severity:$.WARN,category:n.category,path:n.path,message:`"${n.path}" was edited since the last Vesper write in this worktree.`,fix:re}));for(let n of r.missing){let s=$k.has(n.category);t.push(I({code:"owned-file-missing",severity:s?$.ERROR:$.WARN,category:n.category,path:n.path,message:s?`Load-bearing owned file "${n.path}" is missing \u2014 framework cannot operate.`:`Owned file "${n.path}" is missing \u2014 \`vespercli init\` will re-provision it.`,fix:re}))}return t}async function ji(e,t={}){let r=new Set,n=t.installedTargets;if(!Array.isArray(n))try{let a=await sn(e);n=a?[a]:await ge(e)}catch{n=[]}if(n.includes("claude"))if(t.mcpConfigs?.claude)for(let a of t.mcpConfigs.claude.servers)r.add(a);else try{let a=await Mk(e);for(let c of Object.keys(a.mcpServers||{}))r.add(c)}catch{}if(n.includes("copilot"))if(t.mcpConfigs?.copilot)for(let a of t.mcpConfigs.copilot.servers)r.add(a);else try{let a=await Ze(e);for(let c of Object.keys(a.servers||{}))r.add(c)}catch{}let s=[];if("tracking"in t)s=Array.isArray(t.tracking?.mcp?.servers)?t.tracking.mcp.servers:[];else try{let a=await x(e);s=Array.isArray(a.mcp?.servers)?a.mcp.servers:[]}catch{s=[]}let o=new Set(s);return{drifted:[...r].filter(a=>!me.includes(a)&&!o.has(a))}}async function Mk(e){try{return JSON.parse(await Ms(Ve(e),"utf-8"))}catch{return{mcpServers:{}}}}async function Gk(e){let{drifted:t}=await ji(e.workspaceRoot,{tracking:e.tracking,mcpConfigs:e.mcpConfigs,installedTargets:e.installedTargets});return t.map(r=>I({code:"mcp-drift",severity:$.WARN,category:"mcp-config",message:`MCP server "${r}" is present in the live MCP config but not tracked in .vesperrc mcp.servers.`,fix:re}))}async function Fk(e){return!e.initialised||!e.host?[]:(e.manifestAll??e.manifestEntries).some(r=>r.category==="mcp-config")?[]:Dk(e)?[I({code:"mcp-config-unrecorded",severity:$.ERROR,category:"mcp-config",message:"A live MCP config exists but is not recorded in the owned-files manifest \u2014 Vesper cannot reconcile its managed servers.",fix:re})]:[]}function Dk(e){return!!e.mcpConfigs?.[e.host]?.exists}function Vk(e){if(e.absent||!e.tracking)return[];let t=e.tracking;return(t.host===void 0||z.includes(t.host))&&Array.isArray(t.manifest)&&t.schemaVersion===ve?[]:[I({code:"tracking-shape-invalid",severity:$.WARN,path:".vesperrc",message:".vesperrc parses but its shape is invalid (host/manifest/schemaVersion) \u2014 `vespercli init` repairs it.",fix:re})]}async function Hk(e){let t=[];if(e.detectedHost==="both"){let r=z.every(n=>Af(e,n));t.push(I({code:"host-ambiguous",severity:r?$.ERROR:$.WARN,message:r?vf:`${vf} (Reported as a warning: at least one host matched only generic, non-Vesper-specific files, so this is probably not a real dual provisioning.)`,fix:"vespercli init --host <claude|copilot>"}))}if(e.host){let r=e.host==="claude"?"copilot":"claude";await Uk(e,r)&&t.push(I({code:"host-residue",severity:$.WARN,message:`This workspace is host "${e.host}" but still carries "${r}" artifacts (a leftover from a host switch).`,fix:Ok(r)}))}return t}async function Uk(e,t){if(e.checkout?.ignoredEvidence===t)return!0;let r=e.tracking||{};if(!(Number(r.schemaVersion)>=2)&&(t==="claude"&&r.claude||t==="copilot"&&Array.isArray(r.paths)&&r.paths.length>0))return!0;let n=[...e.residue?.[t]||[]];for(let a of e.manifestAll||[])a?.host!==t||a.owns||Ne.has(a.category)||typeof a.path!="string"||a.path.includes("..")||bk(a.path)||await w(Ce(e.workspaceRoot,a.path))&&n.push(a.path);if(!n.length)return!1;if(e.checkout?.visible===null||e.checkout?.visible===void 0)return!e.checkout?.gitError;let{runGit:s}=await Promise.resolve().then(()=>(it(),ua)),{READ_ONLY_GIT_ENV:o}=await Promise.resolve().then(()=>(wt(),Ea)),i=await s(["--literal-pathspecs","ls-files","-z","--cached","--others","--exclude-standard","--",...n],{cwd:e.workspaceRoot,timeout:1e4,env:{...process.env,...o}});return!!i&&i.split("\0").some(Boolean)}function Wk(e){let t=[],r=e.checkout||{},n=e.ledgerHostForReporting??null;r.gitError==="dubious-ownership"?t.push(I({code:"git-dubious-ownership",severity:$.WARN,message:"git refuses this repository (dubious ownership), so Vesper cannot read its checkout and provisions nothing here.",fix:`git config --global --add safe.directory ${e.workspaceRoot}`})):r.gitError&&t.push(I({code:"git-unreadable",severity:$.INFO,message:"git could not read this repository, so Vesper provisions nothing here; run `git status` to see why.",fix:"git status"})),e.journal&&t.push(I({code:"host-switch-pending",severity:$.WARN,message:`An interrupted host switch (${e.journal.from} \u2192 ${e.journal.to}) is pending; automatic provisioning is suspended until \`vespercli init\` finishes it.`,fix:re}));let s=!r.host&&!r.ambiguous&&!r.gitError;if(n&&(r.host&&r.host!==n||s&&!e.journal&&!e.legacy?.needsMigration)&&t.push(I({code:"host-record-stale",severity:$.INFO,path:".vesperrc",message:`This worktree's local record describes a ${n} provisioning, but the checked-out commit is ${r.host??"not provisioned"}. The record is not used to decide the host.`,fix:Je(r.host??n)})),r.source==="local"&&r.host&&t.push(I({code:"host-local-only",severity:$.INFO,path:r.ignoredFile??void 0,message:`Vesper's activation here lives in gitignored ${r.ignoredFile}; it follows this worktree across branches, not the commit. Commit ${r.ignoredFile} for per-commit behaviour.`,fix:Je(r.host)})),!r.host&&r.ignoredEvidence){let o=r.ignoredEvidence==="both"?"claude|copilot":r.ignoredEvidence;t.push(I({code:"host-local-unconfirmed",severity:$.WARN,path:r.ignoredFile??void 0,message:`Vesper keys for ${o} are only in gitignored ${r.ignoredFile}, and this worktree's record does not confirm them \u2014 nothing is provisioned from them. Commit ${r.ignoredFile}, or run \`vespercli init --host ${r.ignoredEvidence==="both"?"<claude|copilot>":o}\`.`,fix:r.ignoredEvidence==="both"?"vespercli init --host <claude|copilot>":Je(o)}))}return t}function Kk(e){let t=[];for(let r of z){let n=e.residue?.[r]||[];n.length&&((e.fingerprintMatches?.[r]||[]).length>0||e.host!==r&&t.push(I({code:"host-leftover-files",severity:$.WARN,message:`Leftover ${r} files that hold your edits: ${n.join(", ")} \u2014 delete them, or run \`${Je(r)}\` to provision ${r} again. They do not mark this workspace as ${r}.`,fix:Je(r)})))}return t}function Sf(e){let t=z.filter(r=>e?.hosts?.[r]);return t.length===1?Je(t[0]):"vespercli init --host claude (or --host copilot \u2014 Vesper 2.0 provisions exactly one host)"}function Bk(e){let t=[],r=e.legacy;r?.unmigrated?t.push(I({code:"legacy-workspace",severity:$.ERROR,message:`${nt} Evidence: ${r.evidence.join(", ")||"1.x record"}.`,fix:Sf(r)})):(r?.advisory||r?.residue)&&t.push(I({code:"legacy-residue",severity:$.WARN,message:r.advisory?`Pre-2.0 Vesper leftovers and no 2.0 host (${r.evidence.join(", ")}) \u2014 \`vespercli init\` migrates them.`:`This 2.0 workspace still carries pre-2.0 Vesper state (${r.evidence.join(", ")}) \u2014 \`vespercli init\` finishes the migration.`,fix:r.residue&&e.host?Je(e.host):Sf(r)})),r&&!r.unmigrated&&!r.advisory&&r.leftovers.length&&t.push(I({code:"legacy-leftover-files",severity:$.WARN,message:`Leftover 1.x files that hold your edits: ${r.leftovers.join(", ")} \u2014 Vesper 2.0 never reads them. Delete them once you have kept what you need.`,fix:`rm ${r.leftovers.join(" ")}`}));for(let n of e.userResidue||[])t.push(I({code:"user-level-residue",severity:$.ERROR,path:n.path,message:`The pre-1.9 machine-wide Vesper catalog is still here (${n.marker}${n.kept?`; ${n.kept} other file(s) there are yours and stay`:""}) \u2014 every project on this machine loads it. \`vespercli init\` backs the folder up and removes only the files a released Vesper build wrote.`,fix:re}));return e.migrationTorn?t.push(I({code:"migration-record-unreadable",severity:$.WARN,path:Bc(e.workspaceRoot,e.migrationTorn),message:`The newest migration record (${Bc(e.workspaceRoot,e.migrationTorn)}) is unreadable, so automatic provisioning is suspended; \`vespercli init\` sets it aside and continues.`,fix:re})):e.migrationActive&&!t.length&&t.push(I({code:"migration-in-progress",severity:$.WARN,message:"A Vesper 1.x migration was interrupted in this workspace; automatic provisioning is suspended until `vespercli init` finishes it.",fix:re})),t}async function zk(e){if(e.host!=="claude"||e.legacy?.needsMigration)return[];let t=await At(),r=new Set((e.manifestEntries||[]).map(o=>o.path)),n=new Set;for(let o of e.keptItems||[])(o.reason==="edited-catalog"||o.reason==="edited-skill")&&n.add(o.rel);try{for(let o of await Ak(Ce(e.workspaceRoot,".claude","agents"))){let i=`.claude/agents/${o}`;if(!o.endsWith(".md")||r.has(i)||!si("agents",o,""))continue;let a=null;try{a=await zc(Ce(e.workspaceRoot,i))}catch{a=null}a&&!ni(a,`agents/${o}`)&&n.add(i)}}catch{}let s=[];for(let o of[...n].sort()){if(r.has(o)||!await w(Ce(e.workspaceRoot,o)))continue;let i=/^\.claude\/(agents|skills)\/([^/]+?)(\.md)?$/.exec(o);if(!i)continue;let[,a,c]=i;if(!(a==="agents"?t.agents:t.skills).has(c)||a==="skills"&&!await w(Ce(e.workspaceRoot,o,"SKILL.md")))continue;let l=a==="agents"?Ce(O,"claude","agents",`${c}.md`):Ce(O,"claude","skills",c);s.push(I({code:"kept-shadows-plugin",severity:$.WARN,path:o,message:`${o} is a 1.x copy kept because it holds your edits, and it shadows the plugin's \`vesper:${c}\` (Claude Code prefers the project-level one) \u2014 you keep getting the 1.x version.`,fix:`compare: ${a==="agents"?"diff":"diff -r"} "${Ce(e.workspaceRoot,o)}" "${l}"; then either keep yours (it wins) or delete it (${a==="agents"?"rm":"rm -r"} ${o}) to use vesper:${c}`}))}return s}async function Yk(e){if(e.host!=="claude")return[];let t;try{t=await zc(Ce(e.workspaceRoot,".claude","rules","vesper-orchestration.md"),"utf-8")}catch{return[]}let r=kd(t,(await At()).agents);return r.length?[I({code:"roster-unqualified-agents",severity:$.WARN,path:".claude/rules/vesper-orchestration.md",message:`The Team Roster names ${r.length} specialist(s) without the plugin namespace (${r.slice(0,6).join(", ")}${r.length>6?", \u2026":""}) \u2014 2.0 serves them as \`vesper:<name>\`, so delegation to them does not match until the roster is revalidated.`,fix:"run `/revalidate-team` once in Claude Code (it rewrites the roster with vesper:<name> names)"})]:[]}async function Jk(e){if(!e.host)return[];let t=await lr(e.workspaceRoot,e.host);if(t===null)return[];let r=await ur(t),{enabled:n}=await Lr(e.workspaceRoot,e.host),s=[];for(let o of r.packs){if(n.includes(o))continue;let i=[...r.needed[o].agents,...r.needed[o].skills];s.push(I({code:"pack-not-enabled",severity:$.WARN,path:vn[e.host],message:`The Team Roster names ${i.length} asset(s) of the "${o}" pack (${Le(o)}: ${i.slice(0,6).join(", ")}${i.length>6?", \u2026":""}), but that pack is not enabled for ${e.host} in this workspace \u2014 delegation to them does not resolve until it is.`,fix:dp}))}for(let o of n)r.packs.includes(o)||Ir(o)||o===Me||s.push(I({code:"pack-unused",severity:$.INFO,path:e.host==="claude"?".claude/settings.json":".vscode/settings.json",message:`The "${o}" pack (${Le(o)}) is enabled for ${e.host}, but the Team Roster names none of its assets.`,fix:`vespercli packs disable ${o} (or keep it \u2014 an unused pack costs only load time)`}));return s}async function qk(e){if(!e.runningHost)return[];if(e.journal)return[];if(e.checkout?.source==="local"&&e.legacy?.unmigrated)return[];if(e.checkout?.source==="local"&&e.migrationActive)return[];let t=[],r=e.checkout?.host??null;if(!r)return t.push(I({code:"host-unresolved",severity:$.INFO,message:"Could not resolve the provisioned host from disk (no recorded host and no Vesper-specific fingerprint) \u2014 the host-identity check has nothing to compare against.",fix:re})),t;if(r!==e.runningHost){let n=Af(e,r);t.push(I({code:xf,severity:n?$.ERROR:$.WARN,message:n?`This workspace is provisioned for host "${r}" but is running under "${e.runningHost}".`:`This workspace looks like host "${r}" but is running under "${e.runningHost}". Reported as a warning: the only evidence is generic, non-Vesper-specific files, so this may not be a Vesper workspace at all.`,fix:Je(e.runningHost)}))}return t}async function Xk(e){if(e.host!=="claude")return[];let t;try{t=JSON.parse(await zc(En(e.workspaceRoot),"utf-8"))}catch{return[]}let r=t?.extraKnownMarketplaces?.[$e];return r===void 0||Xp(r)?[]:[I({code:"marketplace-entry-invalid",severity:$.WARN,path:".claude/settings.local.json",message:`The \`extraKnownMarketplaces.${$e}\` entry is not in Claude Code's schema (\`source\` must be an object: {"source":"directory","path":\u2026}); Claude Code ignores it and the vesper plugin does not load.`,fix:"vespercli worktree bootstrap"})]}function Qk(e){if(!e.initialised)return[];let t=e.packageVersion;if(!t)return[];let r=e.frameworkVersion;return r?r!==t?[I({code:"framework-stale",severity:$.WARN,message:`Workspace provisioned with Vesper ${r}, running ${t}.`,fix:re})]:[]:[I({code:"ledger-unstamped",severity:$.INFO,message:"This worktree's ledger (`.vesperrc`) carries no framework version yet \u2014 `init` has not run in this worktree (bootstrap does not stamp one).",fix:re})]}async function Zk(e){return e.initialised?await w(Ce(e.workspaceRoot,ue))?[]:e.manifestAll?.some(t=>t?.path===ue)?[]:[I({code:"gates-missing",severity:$.INFO,path:ue,message:"No gate policy (`.vesper/gates.json`) \u2014 `vespercli gate` exits 2 here until `init` seeds one.",fix:re})]:[]}async function eS(e){if(e.host!=="claude")return[];let t=new Set((e.manifestAll||[]).map(n=>n?.path)),r=[];for(let n of Cp)t.has(n)||await w(Ce(e.workspaceRoot,n))||r.push(n);return r.length?[I({code:"opencode-overlay-missing",severity:$.INFO,path:r[0],message:`OpenCode overlay incomplete \u2014 missing ${r.join(", ")}. \`vespercli init\` adds the missing file(s); nothing else changes (a 2.0.x Claude workspace gets the overlay this way).`,fix:re})]:[]}async function tS(e){if(e.host!=="claude")return[];let t=Ce(e.workspaceRoot,".claude","agents"),r=[];try{r=(await Ek(t,{withFileTypes:!0})).filter(o=>o.isFile()&&o.name.endsWith(".md")).map(o=>o.name)}catch{return[]}let n=[];for(let s of r){let o=`.claude/agents/${s}`;try{let i=await Ms(Ce(t,s),"utf-8"),a=rS(i);(!a||!Ef(a.name)||!Ef(a.description))&&n.push(I({code:"agent-frontmatter-incomplete",severity:$.WARN,category:"catalog-agent",path:o,message:`Committed agent "${o}" is missing a non-empty name/description in its frontmatter.`,fix:re}))}catch{}}return n}function Ef(e){return typeof e=="string"&&e.trim().length>0}function rS(e){let t=/^---\r?\n([\s\S]*?)\r?\n---/.exec(e);if(!t)return null;let r={};for(let n of t[1].split(/\r?\n/)){let s=/^([A-Za-z0-9_-]+):\s*(.*)$/.exec(n);if(!s)continue;let o=s[2].trim();(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),r[s[1]]=o}return r}async function nS(e){let t=[],r=e.checkout||{};if(!r.host||r.source==="local"||r.gitError)return t;let{resolveGitHooksDir:n,gitHooksSkipMessage:s,VESPER_MANAGED_GIT_HOOKS:o,isHookTrackedByGit:i,realOrNearestAncestor:a,resolveHookWriteTarget:c}=await Promise.resolve().then(()=>(H(),Ma)),{runGit:l}=await Promise.resolve().then(()=>(it(),ua)),{classifyForeignHook:d,HOOK_GUARD_START:p,HOOK_GUARD_END:f}=await Promise.resolve().then(()=>(Wr(),Jl));if(await l(["config","--type=bool","--get","vesper.hooks"],{cwd:e.workspaceRoot,timeout:5e3})==="false")return t.push(I({code:"git-hooks-opted-out",severity:$.INFO,message:"Vesper's git hooks are turned off for this repository (git config vesper.hooks false): no guard runs on checkout and no commit hygiene on commit.",fix:"git config --unset vesper.hooks && vespercli worktree bootstrap"})),t;let m=await n(e.workspaceRoot);if(!m.dir)return m.reason==="not-a-repo"||t.push(I({code:"git-hooks-not-installable",severity:$.INFO,message:s({...m,hook:"hook"})??`Git hooks not installable (${m.reason}).`,fix:"see the message"})),t;if(!m.default&&await i(await a(m.dir),m,{dir:!0}))return t.push(I({code:"git-hooks-not-installable",severity:$.INFO,message:s({reason:"tracked-by-git",configured:m.dir}),fix:"see the message"})),t;for(let h of o){let g=Ce(m.dir,h),y=await c(g),k=null;if(y.path)try{k=await Ms(y.path)}catch{k=null}let v=k?k.toString("latin1"):"",S=v.indexOf(p);if(S!==-1){let N=v.indexOf(f,S),E=v.slice(S,N===-1?void 0:N);E.includes("vesper.hooks")?h==="pre-commit"&&!E.includes("VESPER_NO_SWEEP")&&t.push(I({code:"git-hook-outdated",severity:$.INFO,path:g,message:`Vesper's pre-commit git hook block (${g}) predates VESPER_NO_SWEEP: an agent's commit still sweeps every dirty knowledge path into it.`,fix:"vespercli worktree bootstrap"})):t.push(I({code:"git-hook-outdated",severity:$.INFO,path:g,message:`Vesper's ${h} git hook block (${g}) predates the run-time opt-out check: \`git config vesper.hooks false\` would not stop it.`,fix:"vespercli worktree bootstrap"}));continue}let C=null;if(!y.path)C={reason:y.reason,configured:g};else if(k&&await i(await a(y.path),m))C={reason:"tracked-by-git",configured:y.path};else if(k){let N=d(k);N.ok||(C={reason:N.reason,interpreter:N.interpreter,line:N.line})}if(C){t.push(I({code:"git-hook-not-modifiable",severity:$.INFO,path:g,message:s({...C,hook:h,hooksDir:m.dir})??`Git hook ${h} cannot carry Vesper's block (${C.reason}).`,fix:"see the message"}));continue}t.push(I({code:"git-hook-missing",severity:$.WARN,path:g,message:`Vesper's ${h} git hook block is missing (${g}): ${h==="post-checkout"?"a branch switch or a new worktree does not run the host guard":"commits do not carry the project-knowledge files"}.`,fix:"vespercli worktree bootstrap"}))}return t}async function sS(e){if(!e.host)return[];if(!await fn(e.workspaceRoot,e.host))return[];let t=[],r=e.host==="claude"?".claude/settings.json":".vscode/settings.json";dt()||t.push(I({code:"graphify-missing",severity:$.INFO,path:r,message:"The graphify pack is enabled but the `graphify` tool is not on PATH \u2014 the post-checkout refresh and `graphify update .` do nothing until it is installed (vesper-indexing remains the default codebase tool).",fix:Zo()}));let n=await Ud(e.workspaceRoot);if(!n.present)return t.push(I({code:"graphify-no-graph",severity:$.INFO,path:xe,message:`The graphify pack is enabled but ${xe} does not exist \u2014 the graphify MCP server has nothing to serve until the graph is built.`,fix:Ge})),t;if(!n.commit)return t;let s=await D(["rev-parse","HEAD"],{cwd:e.workspaceRoot});return s&&(s.startsWith(n.commit)||n.commit.startsWith(s)||t.push(I({code:"graphify-stale",severity:$.WARN,path:xe,message:`${xe} was built from commit ${n.commit.slice(0,12)} (\`${n.key}\`) but HEAD is ${s.slice(0,12)} \u2014 impact and path answers may miss recent changes.`,fix:Ge}))),t}var _f=[{id:"manifest",title:"Owned-files manifest",run:e=>Lk(e)},{id:"mcp-drift",title:"MCP config drift",run:e=>Gk(e)},{id:"mcp-required",title:"MCP config recorded",run:e=>Fk(e)},{id:"tracking",title:"Tracking structure",run:e=>Vk(e)},{id:"host-conflict",title:"Host conflict",run:e=>Hk(e)},{id:"host-authority",title:"Host authority (checkout vs worktree record)",run:e=>Wk(e)},{id:"host-leftover",title:"Leftover host files",run:e=>Kk(e)},{id:"legacy",title:"Pre-2.0 (1.x) residue",run:e=>Bk(e)},{id:"legacy-kept-shadows",title:"Kept 1.x copies shadowing plugin specialists",run:e=>zk(e)},{id:"roster-namespaces",title:"Team Roster delegation names",run:e=>Yk(e)},{id:"packs",title:"Packs the Team Roster needs",run:e=>Jk(e)},{id:"git-hooks",title:"Vesper git hooks",run:e=>nS(e)},{id:"graphify",title:"graphify pack (opt-in)",run:e=>sS(e)},{id:"host-mismatch",title:"Host identity",run:e=>qk(e),failureSeverity:e=>e.runningHost?$.ERROR:$.WARN},{id:"framework-version",title:"Framework version",run:e=>Qk(e)},{id:"marketplace-entry",title:"Marketplace entry shape",run:e=>Xk(e)},{id:"agent-frontmatter",title:"Agent frontmatter",run:e=>tS(e)},{id:"gates-config",title:"Gate policy",run:e=>Zk(e)},{id:"opencode-overlay",title:"OpenCode overlay",run:e=>eS(e)}];function bf(e){let t=e.filter(o=>o.severity===$.ERROR),r=e.filter(o=>o.severity===$.WARN),n=e.filter(o=>o.severity===$.INFO),s=t.some(o=>o.code===xf);return{findings:e,errors:t,warnings:r,infos:n,summary:{hasError:t.length>0,hostMismatch:s}}}async function _n(e,{runningHost:t,homeDir:r,checkout:n}={}){let s=await Rk(e,t,{homeDir:r,checkout:n});return s.corrupt?bf([I({code:"tracking-unparseable",severity:$.ERROR,path:Bc(e,s.corruptPath),message:"Malformed .tracking structure (.vesperrc is present but unparseable) \u2014 framework cannot operate.",fix:re})]):bf(await oS(s,_f))}async function oS(e,t=_f){let r=[];for(let n of t)try{let s=await n.run(e);Array.isArray(s)&&r.push(...s)}catch(s){let o=n.failureSeverity?n.failureSeverity(e):$.WARN;r.push(I({code:Ck,severity:o,category:n.id,message:`Doctor check "${n.title}" (${n.id}) failed to run \u2014 its coverage is MISSING from this report, not clean: ${s?.message||s}`,fix:re}))}return r}function Ri(e){return e.summary.hostMismatch?Te.HOST_MISMATCH:e.summary.hasError?Te.ERROR:Te.OK}Ae();H();function Yc(e){return String(e??"").replace(/\r\n?/g,`
92
+ `)}function ft(e){let t=Yc(e),r=/^---\n([\s\S]*?)\n---(?:\n|$)/.exec(t);return r?{frontmatter:r[1],body:t.slice(r[0].length)}:{frontmatter:null,body:t}}function Dr(e,t){if(!e)return null;let r=Yc(e).split(`
93
+ `),n=r.findIndex(i=>new RegExp(`^${t}:`).test(i));if(n===-1)return null;let s=r[n].slice(t.length+1).trim();if(s&&![">","|",">-","|-"].includes(s))return/^'.*'$/.test(s)?s.slice(1,-1).replace(/''/g,"'"):/^".*"$/.test(s)?s.slice(1,-1).replace(/\\"/g,'"'):s;let o=[];for(let i=n+1;i<r.length;i++){if(!/^\s+\S/.test(r[i])){if(r[i].trim()==="")continue;break}o.push(r[i].trim())}return o.length?o.join(" "):null}function Ni(e){return`'${String(e??"").replace(/[\u0000-\u001f]+/g," ").replace(/\s+/g," ").trim().replace(/'/g,"''")}'`}var $f=Object.freeze(["vesper-orchestrator","vesper-orchestration","vesper-context"]);function iS(e){let t=e;for(let r of $f){let n=r.replace(/^vesper-/,""),s=`.vesper/instructions/${r}.instructions.md`;t=t.replace(new RegExp(`\\.claude/rules/${r}\\.md`,"g"),s).replace(new RegExp(`\\.claude/vesper/${n}\\.md`,"g"),s)}return t.replace(/\.claude\/vesper\/\{orchestrator,orchestration,context\}\.md/g,".vesper/instructions/vesper-{orchestrator,orchestration,context}.instructions.md").replace(/\.claude\/rules\/vesper-\*\.md/g,".vesper/instructions/vesper-*.instructions.md").replace(/\.claude\/vesper\/\*\.md/g,".vesper/instructions/vesper-*.instructions.md").replace(/\.claude\/agents\/vesper-orchestrator\.md/g,".vesper/agents/vesper-orchestrator.agent.md")}function aS(e){return iS(e).replace(/\.claude\/rules\/([A-Za-z0-9_{}*-]+)\.md/g,".vesper/instructions/$1.instructions.md").replace(/\.claude\/agents/g,".vesper/agents").replace(/\.claude\/commands/g,".vesper/prompts").replace(/\.claude\/skills/g,".vesper/skills").replace(/\.claude\/rules/g,".vesper/instructions").replace(/\.claude\/vesper\/context/g,".vesper/context").replace(/\.claude\/vesper/g,".vesper").replace(/(?<!\.vscode\/)\.mcp\.json/g,".vscode/mcp.json").replace(/\bAskUserQuestion\b/g,"vscode/askQuestions").replace(/\bTodoWrite\b/g,"manage_todo_list").replace(/`run_in_background:\s*true`/g,"`isBackground: true`").replace(/run_in_background:\s*true/g,"isBackground: true")}function cS(e){let t=e;for(let r of $f)t=t.replace(new RegExp(`\\.vesper/instructions/${r}\\.md`,"g"),`.vesper/instructions/${r}.instructions.md`);return t.replace(/\.vesper\/agents\/vesper-orchestrator\.md/g,".vesper/agents/vesper-orchestrator.agent.md")}var Cf=Object.freeze(["start","end","gitignore","hook"]);function Of(e){return e.replace(/`\/?vesper-<pack>:<name>`/g,"`<name>`").replace(/\bvesper-<pack>:<name>\b/g,"<name>").replace(/`\/?vesper-[a-z][a-z0-9-]*:([a-z][a-z0-9-]*)`/g,"`$1`").replace(/\bvesper-[a-z][a-z0-9-]*:([a-z][a-z0-9-]*)\b/g,"$1").replace(/`vesper:<name>`/g,"`<name>`").replace(/`\/vesper:<name>`/g,"`/<name>`").replace(/`vesper:\*`/g,"`<name>`").replace(/`vesper:([a-z][a-z0-9-]*)`/g,(t,r)=>Cf.includes(r)?t:`\`${r}\``).replace(/\bvesper:([a-z][a-z0-9-]*)\b/g,(t,r)=>Cf.includes(r)?t:r)}function Tf(e){return Of(cS(aS(Yc(e))))}var b$=Object.freeze({Read:"read/readFile",Bash:"execute/runInTerminal",Grep:"search/codebase",Glob:"search/fileSearch",TodoWrite:"todo",AskUserQuestion:"vscode/askQuestions",Agent:"agent/runSubagent"}),x$=Object.freeze(["read/readFile","search/codebase","search/fileSearch","edit/editFiles","edit/createFile","execute/runInTerminal","agent/runSubagent","todo","vscode/askQuestions","web","web/fetch"]),A$=Object.freeze({"claude-opus-4-8":"Claude Opus 4.8","claude-sonnet-5":"Claude Sonnet 4.6","claude-haiku-4-5-20251001":"Claude Haiku 4.5"});var _$=Object.freeze(["core","extended"]);var C$=Object.freeze(["copilot-apply-to","copilot-instructions-tier"]);var Jc=Object.freeze([{key:"orchestrator",source:"vesper-orchestrator.md",name:"vesper-orchestrator",seedOnce:!1},{key:"orchestration",source:"orchestration.md.tpl",name:"vesper-orchestration",seedOnce:!0},{key:"context",source:"context.md.tpl",name:"vesper-context",seedOnce:!0}]),Rf=".vesper/context";function Nf(e){return qe(e,".vesper","agents")}function uS(e){return qe(e,".vesper","instructions")}function Lf(e){return qe(e,Rf)}var dS=".vscode/mcp.json",V$=Object.freeze([".github/",".claude/rules/",".claude/agents/",".claude/commands/",".claude/skills/"]);function Li(e){return Tf(e)}function Mf(e){return Ni(e).slice(1,-1)}var If="VESPER_HOST_MISMATCH";function pS(){return["## \u{1F3AF} Who this playbook binds (read first)","","This file is attached to **every** chat and agent context in this workspace","(`applyTo: '**'`), but it is the operating playbook of exactly **one** persona.","Establish which one you are before reading further:","",`- **You are \`${L}\`** \u2014 the single pickable Vesper agent`,` (\`${Pt}\`). Everything below binds you in full. The`," MANDATORY DELEGATION LAW, the Purpose Router and every Purpose Pipeline are yours.","- **You are anyone else** \u2014 a Vesper specialist you were delegated to"," (`code-reviewer`, `task-researcher`, `principal-software-engineer`, \u2026), a built-in"," mode (Agent / Ask / Edit), or a custom agent. Then the **MANDATORY DELEGATION LAW,"," the Purpose Router and the Purpose Pipelines below do NOT bind you.** You were"," delegated to precisely so that you would do the work directly: read, analyse, edit"," and run commands exactly as your own agent definition instructs. Never refuse a task"," by citing the delegation law, and never hand your task back to the orchestrator"," merely because this file is in your context.","","Sections that bind **every** agent regardless of persona: the workspace layout and","path conventions, the Tracking & History rules, and the Host-mismatch warning.","","---",""].join(`
94
+ `)}function fS(e,t,r){let n=t.trim().split(/\s+/).map(s=>s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("\\s+");return e.replace(new RegExp(n,"g"),r)}var hS=Object.freeze([["installed once, globally, as the Vesper plugin","shipped inside the installed `@mthanh/vespercli` package and activated by the `chat.*FilesLocations` settings Vesper injects"],["Degraded mode (plugin unavailable)","Degraded mode (specialists unresolvable)"],["(and any session where the plugin's workspace-trust dialog was declined) the marketplace plugin does **not** load, so those specialists are **absent**","(most often because `vespercli init` was never run here, the injected `chat.agentFilesLocations` entry was pruned, or the VS Code window has not been reloaded since init) the specialist agent files do **not** resolve, so those specialists are **absent**"],["in cloud/remote ALL skills are plugin-carried and therefore absent alongside the specialists","when the specialists do not resolve, ALL package-carried skills are absent alongside them"],["skills are installed in the shared Vesper plugin and auto-discovered by name","skills ship inside the installed Vesper package and are auto-discovered by name"],["never to the plugin/global install location","never to the package install location"],["(`.vesper/`, `.vesper/`, project source)","(`.vesper/`, project source)"],["(it verified the enabled plugin's cache resolves for this project)","(it verified the specialist agent files resolve for this project)"],["when it can confirm the plugin is not resolved","when it can confirm the specialists are not resolvable"],["the plugin is actually present (e.g. a flaked desktop hook)","the specialists are actually present (e.g. a flaked guard)"]]),mS="**Namespaced delegation names",gS=`- **Plain delegation names (correctness invariant, not style):** this host has no plugin namespace \u2014 every specialist is an ordinary agent file discovered by its bare name. Delegate to them by their **plain** name (e.g. \`code-reviewer\`, \`task-researcher\`, \`principal-software-engineer\`). The Team Roster's "Agent Name" column carries these plain names verbatim \u2014 use them exactly as written. The one project-local agent is \`${L}\` (this persona). The four maintenance prompts are invoked unqualified (\`/reinit\`, \`/compact-knowledge\`, \`/revalidate-knowledge\`, \`/revalidate-team\`).`;function yS(e){return e.split(`
95
+ `).map(t=>t.trimStart().startsWith("- ")&&t.includes(mS)?gS:t).join(`
96
+ `)}function wS(e){let t=hS.reduce((r,[n,s])=>fS(r,n,s),e);return yS(t)}function vS(e){let r=e.indexOf("> **First-run workspace trust & plugin resolution:**");if(r===-1)return e;let n=e.indexOf(`
97
+ `,r);n===-1&&(n=e.length);let s=`> **How the Vesper team resolves here:** on the Copilot host the specialist catalog is NOT a plugin and needs no workspace-trust dialog \u2014 the agents, skills, prompts and instructions are read straight from the installed \`@mthanh/vespercli\` package through the \`chat.*FilesLocations\` entries Vesper injects into \`.vscode/settings.json\`. Every package agent is a HIDDEN specialist (\`user-invocable: false\`); the only pickable Vesper agent is \`${L}\`, provisioned project-local at \`${Pt}\`. If the specialists do not resolve, the settings injection is missing or VS Code has not been reloaded \u2014 reload the window, then run \`vespercli doctor\`. The **Degraded mode** section below governs how you operate while they are unavailable.`;return e.slice(0,r)+s+e.slice(n)}function Gf(e){let{body:t}=ft(e);if(!t.includes(If))throw new Error(`renderCopilotPlaybook: the canonical playbook no longer contains the ${If} marker. The host-mismatch warning keys off it \u2014 restore the "Host-mismatch warning" section in assets/claude/vesper-orchestrator.md.`);let r=wS(Li(vS(t))),n=["---","applyTo: '**'",`description: 'Vesper orchestrator playbook \u2014 delegation law, purpose router, and pipelines. Binds the ${L} persona; see the scope block at the top.'`,"---",""].join(`
85
98
  `),[s,...o]=r.split(`
86
99
  `),i=o.join(`
87
100
  `).replace(/^\n+/,"");return`${n}${s}
88
101
 
89
- ${rk()}${i}`}function wc(e,t){let{frontmatter:r,body:n}=ot(e),s=Ar(r,"description")||t;return["---","applyTo: '**'",`description: '${Up(s)}'`,"---",""].join(`
90
- `)+di(n).replace(/^\n+/,"")}var uk=Object.freeze([{token:".claude/settings.json",why:"Copilot has no `.claude/settings.json`"},{token:"marketplace",why:"the Copilot catalog is not a plugin marketplace"},{token:"vesper:<name>",why:"Copilot delegation names are plain (DEC-5)"},{token:"/vesper:",why:"Copilot prompts are invoked unqualified"},{token:"Claude Code project",why:"this artifact provisions a VS Code / Copilot project"}]);function dk(e,t){let r=uk.filter(({token:n})=>e.includes(n));if(r.length!==0)throw new Error(`Copilot render of ${t} still contains Claude-host-only text: `+r.map(({token:n,why:s})=>`"${n}" (${s})`).join(", ")+". The source in assets/claude-committed/agents/ was likely reworded, so a paragraph anchor in PERSONA_PARAGRAPH_REWRITES no longer matches \u2014 update the anchor/replacement pair rather than deleting this assertion.")}var pk=Object.freeze([{anchor:"committed main-thread persona",replace:e=>e.replace("committed main-thread persona","project-local orchestrator persona")},{anchor:"This agent file is intentionally thin",replace:()=>"This agent file is intentionally thin: it exists so that `"+L+"` is the ONE selectable Vesper agent in the VS Code chat agent picker. Every packaged specialist is emitted `user-invocable: false` and is therefore hidden from the picker while remaining delegable. All behavior lives in the always-on instructions above \u2014 follow them exactly. Do not restate or override them here."},{anchor:"Specialists are delegated to by",replace:()=>"Specialists are delegated to by their PLAIN names (e.g. `code-reviewer`, `task-researcher`) \u2014 this host has no plugin namespace, so the Team Roster carries plain names and you use them verbatim. The maintenance prompts are invoked unqualified (`/reinit`, `/compact-knowledge`, `/revalidate-knowledge`, `/revalidate-team`)."}]);function fk(e){return e.split(`
102
+ ${pS()}${i}`}function qc(e,t){let{frontmatter:r,body:n}=ft(e),s=Dr(r,"description")||t;return["---","applyTo: '**'",`description: '${Mf(s)}'`,"---",""].join(`
103
+ `)+Li(n).replace(/^\n+/,"")}var kS=Object.freeze([{token:".claude/settings.json",why:"Copilot has no `.claude/settings.json`"},{token:"marketplace",why:"the Copilot catalog is not a plugin marketplace"},{token:"vesper:<name>",why:"Copilot delegation names are plain (DEC-5)"},{token:"/vesper:",why:"Copilot prompts are invoked unqualified"},{token:"Claude Code project",why:"this artifact provisions a VS Code / Copilot project"}]);function SS(e,t){let r=kS.filter(({token:n})=>e.includes(n));if(r.length!==0)throw new Error(`Copilot render of ${t} still contains Claude-host-only text: `+r.map(({token:n,why:s})=>`"${n}" (${s})`).join(", ")+". The source in assets/claude-committed/agents/ was likely reworded, so a paragraph anchor in PERSONA_PARAGRAPH_REWRITES no longer matches \u2014 update the anchor/replacement pair rather than deleting this assertion.")}var ES=Object.freeze([{anchor:"committed main-thread persona",replace:e=>e.replace("committed main-thread persona","project-local orchestrator persona")},{anchor:"This agent file is intentionally thin",replace:()=>"This agent file is intentionally thin: it exists so that `"+L+"` is the ONE selectable Vesper agent in the VS Code chat agent picker. Every packaged specialist is emitted `user-invocable: false` and is therefore hidden from the picker while remaining delegable. All behavior lives in the always-on instructions above \u2014 follow them exactly. Do not restate or override them here."},{anchor:"Specialists are delegated to by",replace:()=>"Specialists are delegated to by their PLAIN names (e.g. `code-reviewer`, `task-researcher`) \u2014 this host has no plugin namespace, so the Team Roster carries plain names and you use them verbatim. The maintenance prompts are invoked unqualified (`/reinit`, `/compact-knowledge`, `/revalidate-knowledge`, `/revalidate-team`)."}]);function bS(e){return e.split(`
91
104
 
92
- `).map(t=>{let r=pk.find(n=>t.includes(n.anchor));return r?r.replace(t):t}).join(`
105
+ `).map(t=>{let r=ES.find(n=>t.includes(n.anchor));return r?r.replace(t):t}).join(`
93
106
 
94
- `)}function hk(e){let t=e.indexOf("This is a COMMITTED project agent"),r=(t===-1?e:e.slice(0,t)).trim();return`${di(r).replace(/Claude Code project/g,"VS Code (GitHub Copilot) project")} The only user-selectable Vesper agent in this workspace; every packaged specialist is hidden and reached by delegation.`}function Kp(e){let{frontmatter:t,body:r}=ot(e),n=Ar(t,"description")||"Vesper super-orchestrator \u2014 routes every request to the specialist team.",o=["---",`description: '${Up(hk(n))}'`,`name: ${L}`,"user-invocable: true","model: 'Claude Opus 4.8'","tools: ['read/readFile', 'search/listDirectory', 'search/fileSearch', 'agent/runSubagent', 'todo', 'vscode/askQuestions', 'vesper-indexing/*', 'memory/*']","agents: '*'","---",""].join(`
95
- `)+fk(di(r)).replace(/^\n+/,"");return dk(o,"the pickable orchestrator agent"),o}async function Fp(e,t){if(await w(e)){try{if(await ws(e,"utf-8")===t)return"unchanged"}catch{}return await C(e,t,"utf-8"),"updated"}return await C(e,t,"utf-8"),"created"}async function pi(e,{version:t}={}){await T(Gp(e),{recursive:!0}),await T(ek(e),{recursive:!0}),await T(Hp(e),{recursive:!0});let r={},n=[],s=Be(Qt,"agents",`${L}.md`);r.orchestratorAgent=await Fp(Be(e,bt),Kp(await ws(s,"utf-8"))),n.push(D({path:bt,host:"copilot",category:"catalog-agent",hash:await ge(Be(e,bt))}));for(let i of yc){let a=Pe(i.name),c=Be(e,a),l=await ws(Be(Me,i.source),"utf-8");i.seedOnce?(r[i.key]="skipped",await w(c)||(await C(c,wc(l,`Vesper ${i.name}`),"utf-8"),r[i.key]="created"),n.push(D({path:a,host:"copilot",category:"per-project-authored",hash:null}))):(r[i.key]=await Fp(c,Wp(l)),n.push(D({path:a,host:"copilot",category:"playbook",hash:await ge(c)})))}r.contextTier="ensured",n.push(D({path:Vp,host:"copilot",category:"per-project-authored",hash:null}));let o=await To(e);if(r.gates=o.created?`created (checks: ${o.checks.join(", ")||"none"})`:"skipped",n.push(D({path:ce,host:"copilot",category:"per-project-authored",hash:null})),await B(e,n),t!==void 0){let i=await x(e);i.schemaVersion=ve,i.frameworkVersion=t,await I(e,i)}return r}async function vc(e,{settingsEntries:t=[]}={}){let r=[],n=s=>Be(e,s);return await w(n(Gt))&&r.push(Y({path:Gt,host:"copilot",category:"settings",owns:{keys:[...Ct],entries:[...t]}})),await w(n(js))&&r.push(Y({path:js,host:"copilot",category:"bootstrap-task",owns:{keys:[Rs]}})),r.length>0&&await B(e,r),r}function Bp(){return to()}async function fi(e,t){let r=ro(t),{added:n}=await Vr(e,[r]),s=new Set([...await gt(e),r.path]);return await vc(e,{settingsEntries:[...s]}),{name:t,path:r.path,added:n.includes(r.path)}}async function vs(e,t=!0,{record:r=!0}={}){let n=await ur(e,t,{record:r});return t&&r&&await B(e,[Y({path:tk,host:"copilot",category:"mcp-config",owns:{keys:[...fe]}})]),{...n,mcpPath:Je(e)}}async function zp(e,{purgeProjectAuthored:t=!1}={}){let r=[],n=[],s=new Map(q(await x(e)).filter(l=>l.host==="copilot").map(l=>[l.path,l])),o=await mk(),i=[bt,Pe(L)];for(let l of i){let d=await ie(Be(e,l),s.get(l)||{path:l},{expected:o[l]===void 0?[]:[o[l]]});d==="removed"?r.push(l):d==="kept"&&n.push(l)}let a=q(await x(e)).some(l=>l.host!=="copilot"&&l.path===ce&&l.category==="per-project-authored"),c=t?[...yc.filter(l=>l.seedOnce).map(l=>Pe(l.name)),...a?[]:[ce]]:[];for(let l of c){let d=Be(e,l);await w(d)&&(await Mp(d,{force:!0}),r.push(l))}try{await Zv(Gp(e))}catch{}return t&&await Mp(Hp(e),{recursive:!0,force:!0}),{removed:r,kept:n}}async function mk(){let e={};try{e[bt]=Kp(await ws(Be(Qt,"agents",`${L}.md`),"utf-8"))}catch{}let t=yc.find(r=>!r.seedOnce);try{e[Pe(t.name)]=Wp(await ws(Be(Me,t.source),"utf-8"))}catch{}return e}U();H();te();xe();import{resolve as pn,basename as Fk}from"node:path";import{confirm as Pc}from"@inquirer/prompts";be();U();H();te();xe();ye();import{resolve as Ek,join as ke}from"node:path";import{rm as ks,rmdir as bk,readFile as bc,readdir as xk}from"node:fs/promises";qe();Rt();Zr();os();U();H();te();qe();ns();ye();import{readFile as kc,rm as gk}from"node:fs/promises";import{join as hi}from"node:path";hr();xe();var qp=Object.freeze(["i-have-adhd","ponytail"]),Jp=Object.freeze(["vendored-body","vendored-activation"]);function yk(){return pr.flatMap(e=>[`.claude/skills/${e}`,`.vesper/skills/${e}`])}function Xp(){return[...qp.map(e=>`.claude/rules/${e}.md`),...pr.map(e=>Pe(e))]}function Sc(){return[...yk(),...Xp()].sort()}function Ec(e){if(!e||typeof e!="object")return!1;if(e.adhd?.installed===!0)return!0;let t=e.vendored;return!!t&&typeof t=="object"&&Object.values(t).some(r=>r&&r.installed===!0)}var Qp=`# ADHD-friendly output (always on)
107
+ `)}function xS(e){let t=e.indexOf("This is a COMMITTED project agent"),r=(t===-1?e:e.slice(0,t)).trim();return`${Li(r).replace(/Claude Code project/g,"VS Code (GitHub Copilot) project")} The only user-selectable Vesper agent in this workspace; every packaged specialist is hidden and reached by delegation.`}function Ff(e){let{frontmatter:t,body:r}=ft(e),n=Dr(t,"description")||"Vesper super-orchestrator \u2014 routes every request to the specialist team.",o=["---",`description: '${Mf(xS(n))}'`,`name: ${L}`,"user-invocable: true","model: 'Claude Opus 4.8'","tools: ['read/readFile', 'search/listDirectory', 'search/fileSearch', 'agent/runSubagent', 'todo', 'vscode/askQuestions', 'vesper-indexing/*', 'memory/*']","agents: '*'","---",""].join(`
108
+ `)+bS(Li(r)).replace(/^\n+/,"");return SS(o,"the pickable orchestrator agent"),o}async function jf(e,t){if(await w(e)){try{if(await Gs(e,"utf-8")===t)return"unchanged"}catch{}return await A(e,t,"utf-8"),"updated"}return await A(e,t,"utf-8"),"created"}async function Mi(e,{version:t}={}){await P(Nf(e),{recursive:!0}),await P(uS(e),{recursive:!0}),await P(Lf(e),{recursive:!0});let r={},n=[],s=qe(fr,"agents",`${L}.md`);r.orchestratorAgent=await jf(qe(e,Pt),Ff(await Gs(s,"utf-8"))),n.push(G({path:Pt,host:"copilot",category:"catalog-agent",hash:await ye(qe(e,Pt))}));for(let i of Jc){let a=Ie(i.name),c=qe(e,a),l=await Gs(qe(De,i.source),"utf-8");i.seedOnce?(r[i.key]="skipped",await w(c)||(await A(c,qc(l,`Vesper ${i.name}`),"utf-8"),r[i.key]="created"),n.push(G({path:a,host:"copilot",category:"per-project-authored",hash:null}))):(r[i.key]=await jf(c,Gf(l)),n.push(G({path:a,host:"copilot",category:"playbook",hash:await ye(c)})))}r.contextTier="ensured",n.push(G({path:Rf,host:"copilot",category:"per-project-authored",hash:null}));let o=await ti(e);if(r.gates=o.created?`created (checks: ${o.checks.join(", ")||"none"})`:"skipped",n.push(G({path:ue,host:"copilot",category:"per-project-authored",hash:null})),await W(e,n),t!==void 0){let i=await x(e);i.schemaVersion=ve,i.frameworkVersion=t,await T(e,i)}return r}async function Xc(e,{settingsEntries:t=[]}={}){let r=[],n=s=>qe(e,s);return await w(n(Xt))&&r.push(Y({path:Xt,host:"copilot",category:"settings",owns:{keys:[...Nt],entries:[...t]}})),await w(n(eo))&&r.push(Y({path:eo,host:"copilot",category:"bootstrap-task",owns:{keys:[to]}})),r.length>0&&await W(e,r),r}function Df(){return bo()}async function Gi(e,t){let r=xo(t),{added:n}=await Qr(e,[r]),s=new Set([...await xt(e),r.path]);return await Xc(e,{settingsEntries:[...s]}),{name:t,path:r.path,added:n.includes(r.path)}}async function Fs(e,t=!0,{record:r=!0}={}){let n=await Ar(e,t,{record:r});return t&&r&&await W(e,[Y({path:dS,host:"copilot",category:"mcp-config",owns:{keys:[...me]}})]),{...n,mcpPath:Qe(e)}}async function Vf(e,{purgeProjectAuthored:t=!1}={}){let r=[],n=[],s=new Map(J(await x(e)).filter(l=>l.host==="copilot").map(l=>[l.path,l])),o=await AS(),i=[Pt,Ie(L)];for(let l of i){let d=await le(qe(e,l),s.get(l)||{path:l},{expected:o[l]===void 0?[]:[o[l]]});d==="removed"?r.push(l):d==="kept"&&n.push(l)}let a=J(await x(e)).some(l=>l.host!=="copilot"&&l.path===ue&&l.category==="per-project-authored"),c=t?[...Jc.filter(l=>l.seedOnce).map(l=>Ie(l.name)),...a?[]:[ue]]:[];for(let l of c){let d=qe(e,l);await w(d)&&(await Pf(d,{force:!0}),r.push(l))}try{await lS(Nf(e))}catch{}return t&&await Pf(Lf(e),{recursive:!0,force:!0}),{removed:r,kept:n}}async function AS(){let e={};try{e[Pt]=Ff(await Gs(qe(fr,"agents",`${L}.md`),"utf-8"))}catch{}let t=Jc.find(r=>!r.seedOnce);try{e[Ie(t.name)]=Gf(await Gs(qe(De,t.source),"utf-8"))}catch{}return e}U();H();te();Ae();import{resolve as $n,basename as JS}from"node:path";import{confirm as ll}from"@inquirer/prompts";be();U();H();te();Ae();fe();import{resolve as IS,join as ke}from"node:path";import{rm as Ds,rmdir as jS,readFile as tl,readdir as RS}from"node:fs/promises";Ye();Ut();dn();pt();As();U();H();te();Ye();bs();fe();import{readFile as Qc,rm as _S}from"node:fs/promises";import{join as Fi}from"node:path";Or();Ae();var Wf=Object.freeze(["i-have-adhd","ponytail"]),Hf=Object.freeze(["vendored-body","vendored-activation"]);function CS(){return Cr.flatMap(e=>[`.claude/skills/${e}`,`.vesper/skills/${e}`])}function Kf(){return[...Wf.map(e=>`.claude/rules/${e}.md`),...Cr.map(e=>Ie(e))]}function Zc(){return[...CS(),...Kf()].sort()}function el(e){if(!e||typeof e!="object")return!1;if(e.adhd?.installed===!0)return!0;let t=e.vendored;return!!t&&typeof t=="object"&&Object.values(t).some(r=>r&&r.installed===!0)}var Bf=`# ADHD-friendly output (always on)
96
109
 
97
110
  Shape every response so a reader with ADHD can act on it: lead with the next
98
111
  concrete action (a command, path, or snippet \u2014 not preamble), keep it brief and
@@ -102,7 +115,7 @@ always win over brevity, and the harness/system prompt always outranks this rule
102
115
  Follow the full \`i-have-adhd\` skill for the specifics
103
116
  (\`.claude/skills/i-have-adhd/SKILL.md\`). It stays in effect for the whole
104
117
  session until the reader says "stop adhd mode" or "normal mode".
105
- `,Zp=`# Ponytail: the laziest solution that works (always on)
118
+ `,zf=`# Ponytail: the laziest solution that works (always on)
106
119
 
107
120
  Prefer the simplest, shortest, most minimal solution \u2014 but only after you
108
121
  understand the problem and trace the flow. Climb the ladder, stop at the first
@@ -120,9 +133,9 @@ for \u2014 build it in full, no re-arguing. Intensity: \`/ponytail lite|full|ult
120
133
  Follow the full \`ponytail\` skill for the specifics
121
134
  (\`.claude/skills/ponytail/SKILL.md\`). It stays in effect for the
122
135
  whole session until the user says "stop ponytail" or "normal mode".
123
- `,wk=Object.freeze({"i-have-adhd":"Install the third-party i-have-adhd output-style skill? (MIT, reviewed snapshot, added to this repo)",ponytail:"Install the third-party ponytail decision-ladder skill? (MIT, reviewed snapshot, rule-text only, added to this repo)"});function vk(e){let t=e==="i-have-adhd"?Qp:Zp;return`${["---","applyTo: '**'",`description: '${wk[e].replace(/'/g,"''")}'`,"---",""].join(`
136
+ `,$S=Object.freeze({"i-have-adhd":"Install the third-party i-have-adhd output-style skill? (MIT, reviewed snapshot, added to this repo)",ponytail:"Install the third-party ponytail decision-ladder skill? (MIT, reviewed snapshot, rule-text only, added to this repo)"});function OS(e){let t=e==="i-have-adhd"?Bf:zf;return`${["---","applyTo: '**'",`description: '${$S[e].replace(/'/g,"''")}'`,"---",""].join(`
124
137
  `)}
125
- ${t.split(`.claude/skills/${e}/`).join(`.vesper/skills/${e}/`)}`}function Yp(e,t){return`${["---","applyTo: '**'",`description: '${ui(t||`Vendored skill "${e}", a reviewed snapshot pinned to an upstream commit and installed by Vesper.`)}'`,"---",""].join(`
138
+ ${t.split(`.claude/skills/${e}/`).join(`.vesper/skills/${e}/`)}`}function Uf(e,t){return`${["---","applyTo: '**'",`description: '${Ni(t||`Vendored skill "${e}", a reviewed snapshot pinned to an upstream commit and installed by Vesper.`)}'`,"---",""].join(`
126
139
  `)}
127
140
  # ${e} (vendored skill)
128
141
 
@@ -134,22 +147,22 @@ anything the skill covers, rather than working from memory.
134
147
  Vesper places this skill but does not author it. A newer upstream arrives only with
135
148
  a Vesper release that re-vendors it (a reviewed change); a file you edit is kept and
136
149
  reported, never overwritten.
137
- `}async function kk(e){let t=fr(e);if(!t)return null;try{let{frontmatter:r}=ot(await kc(hi(t.dir,"SKILL.md"),"utf-8")),n=r?Ar(r,"description"):null;return n&&String(n).trim()||null}catch{return null}}async function Sk(e){if(e===".claude/rules/i-have-adhd.md")return[Qp];if(e===".claude/rules/ponytail.md")return[Zp];for(let t of pr)if(e===Pe(t))return qp.includes(t)?[vk(t)]:[Yp(t,await kk(t)),Yp(t,null)];return[]}async function ef(e,{backup:t}={}){let r={removed:[],kept:[],claudeMd:!1,stylesConsent:!1,rowsDropped:0},n=new Set,s=async f=>{typeof t!="function"||n.has(f)||(n.add(f),await t(f))},o=await x(e),i=q(o),a=f=>i.find(g=>g.path===f&&Jp.includes(g.category))||null;for(let f of pr){let g=fr(f),y=g?await vo(g.dir):{};for(let k of[`.claude/skills/${f}`,`.vesper/skills/${f}`]){let v=hi(e,k);if(!await w(v))continue;let S=a(k),A=S?.placedFiles??S?.syncedFiles,N=A&&typeof A=="object"&&Object.keys(A).length?{...A}:void 0,E={sourceFiles:y,...N?{sourceHashes:N}:{},sourceMatch:(Q,Fe)=>La(Fe,`${k}/${Q}`),anchor:"SKILL.md"},b=await Ot(v,E);if(b.status!=="classified"||b.proven.length===0){(b.status==="anchor-unproven"||b.status==="classified"&&b.kept.length)&&r.kept.push({path:k,files:b.kept});continue}await s(k);let F=await Bn(v,E);F.status==="removed"?r.removed.push(k):F.status!=="absent"&&r.kept.push({path:k,files:F.kept})}}for(let f of Xp()){let g=hi(e,f);if(!await w(g))continue;let y=null;try{y=await kc(g)}catch{y=null}if(y&&La(y,f)){await s(f),await gk(g,{force:!0}),r.removed.push(f);continue}let k=a(f)??{path:f,category:"vendored-activation",hash:null},v=await Sk(f);if(!await zn(g,k,{expected:v})){r.kept.push({path:f});continue}await s(f);let S=await ie(g,k,{expected:v});S==="removed"?r.removed.push(f):S!=="absent"&&r.kept.push({path:f})}let c=hi(e,"CLAUDE.md");if(await w(c)){let f=await kc(c,"utf-8"),g=sc(f);me(g,f)||(await C(c,g,"utf-8"),r.claudeMd=!0)}let l=await x(e),d=new Set(Sc()),p=q(l),h=p.filter(f=>!(d.has(f.path)&&Jp.includes(f.category)));return r.rowsDropped=p.length-h.length,r.stylesConsent=Ec(l),(r.rowsDropped>0||l.vendored!==void 0||l.adhd!==void 0)&&(l.manifest=mt(h),delete l.vendored,delete l.adhd,await I(e,l)),r}function tf(e){let t=[];e.removed.length&&t.push(`Retired the third-party copies an older Vesper placed here (they are pack content now, served from the package): ${e.removed.join(", ")}`),e.claudeMd&&t.push("Removed the retired `vesper:adhd` / `vesper:ponytail` import blocks from CLAUDE.md."),e.stylesConsent&&t.push("Your recorded opt-in to the third-party styles now enables the `styles` pack (`.claude/rules/vesper-styles.md` / `.vesper/instructions/vesper-styles.instructions.md` point at it); `vespercli packs disable styles` turns it off.");let r=e.kept.map(s=>s.files?.length?`${s.path} (${s.files.join(", ")})`:s.path),n=r.length?`Kept \u2014 they hold your edits or your own files, so Vesper could not prove them its own: ${r.join("; ")}. The third-party skills are pack content now (nothing under .claude/skills or .vesper/skills is needed); delete these copies yourself if you do not need them.`:null;return{info:t,warn:n}}var xc=class extends Error{constructor(t){super(t),this.name="HostCleanRefused",this.code="HOST_CLEAN_REFUSED"}};async function _c(e,t){if(t==="copilot"&&!await Cu(e)&&await _k(e)!==0)throw new xc(`This workspace's Copilot ownership manifest has no granular-provenance record, so it may have been written by an older Vesper whose manifest can claim user files. Run \`${Ak}\` to re-record it granularly, then retry.`)}async function _k(e){return q(await x(e)).filter(r=>r.host==="copilot"&&Pt[r.category]?.ownership==="whole-file").length}var Ak="vespercli init --host copilot";async function rf(e,{from:t,to:r,snapshot:n}){await T(ke(e,".vesper"),{recursive:!0});let s={from:t,to:r,snapshot:n,startedAt:new Date().toISOString()};await dr(ke(e,zt),JSON.stringify(s,null,2))}async function Ac(e){await ks(ke(e,zt),{force:!0});let t=zt.split("/").pop();try{for(let r of await xk(ke(e,".vesper")))r.startsWith(`${t}.`)&&r.endsWith(".tmp")&&await ks(ke(e,".vesper",r),{force:!0})}catch{}}async function Cc(e){let t=await x(e),r=q(t);return{manifest:r,mcpServers:Array.isArray(t.mcp?.servers)?[...t.mcp.servers]:[],mcp:t.mcp?JSON.parse(JSON.stringify(t.mcp)):void 0,settingsEntries:await gt(e),addedAssets:r.filter(n=>n.category==="added-asset").map(n=>n.path),namePrefix:typeof t.namePrefix=="string"?t.namePrefix:"",packs:[...new Set([...await jt(e,"claude"),...await jt(e,"copilot"),...Ec(t)?["styles"]:[]])].sort()}}async function Ck(e,t={}){let r=ke(e,".vscode"),n=async i=>{try{return $t(await bc(i,"utf-8"))}catch{return}},s=ke(r,"settings.json");if((await z(e)).type!==pe.WORKSPACE_FILE&&(t.paths?.length??0)+(t.settings?.length??0)>0){let i=await n(s);i&&typeof i=="object"&&Object.keys(i).length===0&&await ks(s,{force:!0})}if((t.mcpServers?.length??0)>0){let i=Je(e),a=await n(i);a&&typeof a=="object"&&Object.keys(a).every(l=>l==="servers")&&(!a.servers||Object.keys(a.servers).length===0)&&await ks(i,{force:!0})}try{await bk(r)}catch{}}async function Ss(e,{purgeProjectAuthored:t=!1}={}){let r=await x(e),n=await gr(e,"claude"),{removed:s}=await Fn(e);try{let i=await J(e);if(i[V]){let a=new Set(je),c=!1;for(let l of Object.keys(i[V]))a.has(l)||(delete i[V][l],c=!0);c&&await oe(e,i)}}catch{}await $o(e,"copilot"),await zp(e,{purgeProjectAuthored:t}),await Ln(e,Xs,{removeFileIfEmpty:!0}),await Ck(e,s);let o=Ek(e,".vesperrc");try{n?(r.paths=[],r.readAccessPaths=[],r.addedAt=null,r.workspaceType=null,r.settingsPath=null,r.host==="copilot"&&(r.host="claude"),Array.isArray(r.manifest)&&(r.manifest=r.manifest.filter(i=>!(i&&i.host==="copilot"))),await C(o,JSON.stringify(r,null,2),"utf-8")):await ks(o,{force:!0})}catch{}}async function mi(e,t,r){let n=new Set(q(await x(e)).map(o=>`${o.host}\0${o.path}`)),s=[];for(let o of t||[])!o||o.host!==r||Pt[o.category]?.ownership!=="whole-file"||Re.has(o.category)||n.has(`${o.host}\0${o.path}`)||await w(ke(e,o.path))&&s.push(o.path);return[...new Set(s)].sort()}async function dn(e,t,r,n){let o=(await _n(e,r)).filter(a=>!(t||[]).some(c=>a===c||a.startsWith(`${c}/`))),i=[...new Set([...t||[],...o])].sort();return i.length?(n.warn(`Left in place \u2014 they hold your own files or edits (or were written by a different Vesper version), so Vesper could not prove them its own and no longer tracks them: ${i.join(", ")}. Delete them yourself if you do not need them.`),await ir(e,r)?n.warn(`This workspace still carries ${r} provisioning markers and may still be detected as ${r}.`):n.warn(`These no longer mark this workspace as ${r}: a later \`vespercli worktree bootstrap\` will not re-provision ${r} because of them.`),i):[]}function $k(e,t,r){return r?t==="copilot"&&e.category==="guard-rule"?!0:e.category==="guard-trigger"?e.path===(t==="claude"?".claude/settings.json":".vscode/tasks.json"):!1:!1}async function gi(e,t,{keepPaths:r=[],purgeProjectAuthored:n=!1,fullTeardown:s=!1}={}){if(!K.includes(t))throw new Error(`cleanHost: host must be one of ${K.join(", ")} (received "${t}")`);let o=!!n;await _c(e,t),await $c(e,t);let i=await Cc(e),{pruned:a}=await Tu(e,r,{host:t,purgeProjectAuthored:o});t==="claude"?await an(e,{purgeProjectAuthored:o}):await Ss(e,{purgeProjectAuthored:o}),s&&(await gs(e,t),t==="copilot"&&await _r(e));let c=await x(e);c.schemaVersion=ve,c.manifest=q(c).filter(d=>d.host!==t||!o&&Re.has(d.category));for(let d of i.manifest)if(!c.manifest.some(h=>h.path===d.path&&h.host===d.host))if(d.host==="shared"){if($k(d,t,s))continue;c.manifest.push(d)}else d.host===t&&!o&&Re.has(d.category)&&await w(ke(e,d.path))&&c.manifest.push(d);c.manifest=mt(c.manifest),i.mcp!==void 0?c.mcp=i.mcp:delete c.mcp,await I(e,c);let l=await mi(e,i.manifest,t);return{...i,pruned:a,retained:l}}async function $c(e,t){if(t!=="claude")return[];if(!await ir(e,"claude")&&!await Ls(e,"claude"))return[];let r=new Set(q(await x(e)).filter(a=>a.host==="claude").map(a=>a.path)),n=async(a,c)=>{try{let[l,d]=await Promise.all([bc(ke(e,a)),bc(c)]);return me(l,d)}catch{return!1}},s=[],o=`.claude/agents/${L}.md`;!r.has(o)&&await n(o,ke(Qt,"agents",`${L}.md`))&&s.push(D({path:o,host:"claude",category:"catalog-agent",hash:await ge(ke(e,o))}));for(let a of Ht){let c=`.claude/skills/${a}`;!r.has(c)&&await n(`${c}/SKILL.md`,ke(Qt,"skills",a,"SKILL.md"))&&s.push(D({path:c,host:"claude",category:"catalog-skill",hash:null}))}let i=".claude/rules/vesper-orchestrator.md";!r.has(i)&&await n(i,ke(Me,"vesper-orchestrator.md"))&&s.push(D({path:i,host:"claude",category:"playbook",hash:await ge(ke(e,i))}));for(let a of[".claude/rules/vesper-orchestration.md",".claude/rules/vesper-context.md"])!r.has(a)&&await w(ke(e,a))&&s.push(D({path:a,host:"claude",category:"per-project-authored",hash:null}));for(let a of await Ju(e,"claude"))r.has(a.path)||s.push(a);for(let a of await Gd(e))r.has(a.path)||s.push(a);return s.length&&await B(e,s),s.map(a=>a.path)}function Ok(e){let t=/^\.claude\/agents\/([^/]+)\.md$/.exec(e);return t?{type:"agents",name:t[1]}:(t=/^\.claude\/commands\/([^/]+)\.md$/.exec(e),t?{type:"prompts",name:t[1]}:(t=/^\.claude\/skills\/([^/]+)$/.exec(e),t?{type:"skills",name:t[1]}:null))}function Tk(e){let t=String(e).replace(/\\/g,"/"),r=/\/assets\/copilot\/instructions-extended\/([^/]+)\/?$/.exec(t);return r?{type:"instructions",name:r[1]}:(r=/\/assets\/(?:copilot\/)?(agents|prompts)\/([^/]+)\/?$/.exec(t),r?{type:r[1],name:r[2].replace(/\.(agent|prompt)\.md$/,"")}:null)}async function nf(e,t,r){let n={mcpServers:{added:[],skipped:[]},assets:{added:[],kept:[],skipped:[]},packs:{added:[],kept:[],skipped:[]}};for(let l of r.packs||[])try{let{enabled:d}=await Er(e,t,l);(d?n.packs.added:n.packs.kept).push(l)}catch{n.packs.skipped.push(l)}for(let l of r.mcpServers||[])if(!fe.includes(l))try{((t==="claude"?await Xo(e,l):await Kr(e,l)).added?n.mcpServers.added:n.mcpServers.skipped).push(l)}catch{n.mcpServers.skipped.push(l)}let s=await Jr(e)||"",o=r.namePrefix??s,i=l=>o&&l.startsWith(o)?l.slice(o.length):l,a=[...(r.addedAssets||[]).map(Ok).filter(Boolean).map(l=>({...l,name:i(l.name),source:"claude-record"})),...(r.settingsEntries||[]).map(Tk).filter(Boolean).map(l=>({...l,source:"copilot-entry"}))],c=new Set;for(let{type:l,name:d,source:p}of a){let h=`${l}/${d}`;if(!c.has(h)){c.add(h);try{if(t==="copilot"){if(l==="instructions"){let{added:m}=await fi(e,d);(m?n.assets.added:n.assets.kept).push(h);continue}n.assets.kept.push(h)}else if(p==="copilot-entry")n.assets.kept.push(h);else{let m=l==="prompts"?"commands":l,f=Pk(m,d,s);if(await w(ke(e,f))){await B(e,[D({path:f,host:"claude",category:"added-asset",hash:null})]),n.assets.kept.push(h);continue}await Bo(m,d,{workspaceRoot:e,namePrefix:s}),n.assets.added.push(h)}}catch{n.assets.skipped.push(h)}}}return n}function Pk(e,t,r=""){if(e==="skills")return`.claude/skills/${t}`;let n=r&&!t.startsWith(r)?`${r}${t}`:t;return`.claude/${e}/${n}.md`}be();ye();Te();H();be();wn();dt();import{lstat as Ik,readFile as sf,realpath as jk,rm as of,stat as Rk}from"node:fs/promises";import{join as af,resolve as Nk}from"node:path";function Lk(e){return e.split(`
138
- `).every(t=>{let r=t.trim();return r===""||r.startsWith("#")||/^exit\s+0\s*;?$/.test(r)})}async function cf(e){try{return await jk(e)}catch{return Nk(e)}}async function Mk(e){try{return(await Rk(e)).isDirectory()}catch{return!1}}async function Dk(e,t,{gitVersion:r,resolveHooksDir:n=Wr}={}){let s={...ar(process.env),...xt},o=await fo(e,{env:s,gitArgs:Ur,gitVersion:r});if(o===null)return[{worktree:"(unknown)",host:null,why:"git worktree list failed"}];let i=await At(t.dir),a=await cf(t.top??e),c=[];for(let l of po(o.out)){if(l.bare||!l.worktree||await cf(l.worktree)===a)continue;if(l.prunable!==void 0){c.push({worktree:l.worktree,host:null,why:"prunable"});continue}if(l.locked!==void 0){c.push({worktree:l.worktree,host:null,why:"locked"});continue}if(!await Mk(l.worktree)){c.push({worktree:l.worktree,host:null,why:"missing"});continue}let p=await n(l.worktree,{env:s,gitArgs:Ur});if(!p.dir&&["machine-wide","not-a-directory","husky-v9"].includes(p.reason)||p.dir&&!p.default&&await At(p.dir)!==i)continue;if(!p.dir){c.push({worktree:l.worktree,host:null,why:`hooks path unknown (${p.reason})`});continue}let h;try{h=await W(l.worktree,{env:s,gitArgs:Ur})}catch{h={gitError:"unknown"}}if(h.gitError){c.push({worktree:l.worktree,host:null,why:`git error (${h.gitError})`});continue}(h.host||h.ambiguous)&&c.push({worktree:l.worktree,host:h.host??"both",why:"provisioned"})}return c}async function Oc(e,{gitVersion:t,resolveHooksDir:r}={}){let n=Object.fromEntries(rt.map(c=>[c,null])),s=await Wr(e);if(!s.dir)return{action:"none",hooks:n,reason:s.reason};let o=[];for(let c of rt){let l=af(s.dir,c);try{(await sf(l)).toString("latin1").includes(kt)&&o.push(l)}catch{}}if(!o.length)return{action:"none",hooks:n};let i=await W(e);if(i.host)return{action:"kept",hooks:n,paths:o,keptFor:[{worktree:e,host:i.host,why:"this checkout still carries Vesper provisioning"}]};let a=await Dk(e,s,{gitVersion:t,...r?{resolveHooksDir:r}:{}});if(a.length)return{action:"kept",hooks:n,paths:o,keptFor:a};for(let c of rt){let l=af(s.dir,c),d=await ho(l);if(!d.path)continue;let p=await At(d.path);if(!Kt(p,s.roots)||await Lr(p,s))continue;let h;try{h=await sf(d.path)}catch{continue}let m=h.toString("latin1");if(!m.includes(kt))continue;let f=nr(m);if(f!==null)if(Lk(f)){await of(d.path,{force:!0});try{(await Ik(l)).isSymbolicLink()&&l!==d.path&&await of(l,{force:!0})}catch{}n[c]="file"}else await cr(d.path,Buffer.from(f,"latin1")),n[c]="region"}return{action:Object.values(n).some(Boolean)?"removed":"none",hooks:n}}function Tc(e){if(e.action==="removed")return`Removed Vesper's git hooks (${Object.entries(e.hooks).filter(([,t])=>t).map(([t])=>t).join(", ")}).`;if(e.action==="kept"){let t=e.keptFor.map(a=>`${a.worktree} (${a.host??`unknown: ${a.why}`})`).join(", "),r=e.paths?.length?` in ${e.paths.join(", ")}`:"",n=e.keptFor.filter(a=>a.why==="missing"||a.why==="prunable").map(a=>a.worktree),s=e.keptFor.filter(a=>a.why==="locked").map(a=>a.worktree),o=[n.length?` ${n.join(", ")} ${n.length>1?"are":"is"} gone: \`git worktree prune\` drops ${n.length>1?"those entries":"that entry"}, then reset again.`:"",s.length?` ${s.join(", ")} ${s.length>1?"are":"is"} locked: if ${s.length>1?"they are":"it is"} gone, \`git worktree unlock <path>\` and \`git worktree prune\`, then reset again.`:""].join(""),i=e.keptFor.every(a=>a.worktree===e.keptFor[0].worktree&&a.why==="this checkout still carries Vesper provisioning")?"this checkout still carries Vesper provisioning":`worktrees sharing these hooks may still use Vesper \u2014 ${t}`;return`Kept Vesper's git-hook block${r}: ${i}.${o} To remove it everywhere, reset those worktrees too, or run \`git config vesper.hooks false\` (the block then does nothing) and delete it from those files.`}return null}var lf=".claude/rules/vesper-orchestrator.md";async function Ic(e,t,{purge:r=!1}={}){if(await gr(e,t)||await ir(e,t)||await Ls(e,t))return!0;if(r){if((await ae(e)).some(s=>s.host===t&&Re.has(s.category)))return!0;if(t==="copilot"){for(let s of[".vesper/instructions/vesper-orchestration.instructions.md",".vesper/instructions/vesper-context.instructions.md",".vesper/context"])if(await w(pn(e,s)))return!0}}return!1}async function yi(e){try{let t=await Oc(e),r=Tc(t);r&&(t.action==="kept"?u.warn:u.info)(r)}catch(t){u.warn(`Vesper's git-hook block was left in place (${t?.message??t}).`)}}async function df(e,t){await gs(e,t),await gs(e,fc(t)),await _r(e)==="kept"&&u.warn(cn());try{let r=await Oc(e),n=Tc(r);n&&(r.action==="kept"?u.warn:u.info)(n)}catch(r){u.warn(`Vesper's git-hook block was left in place (${r?.message??r}).`)}await sa(e)}async function Vk(e={}){let t=pn(e.path||process.cwd()),r=!!e.purgeKnowledge;if(!await Ic(t,"claude",{purge:r})){u.warn("Claude Code target is not initialized in this workspace."),await yi(t);return}if(!e.yes&&!await Pc({message:r?"Remove the Claude Code target INCLUDING the Team Roster and project whitepaper? (this deletes accumulated project knowledge)":"Remove the Claude Code target from this project? (the Team Roster and project whitepaper are KEPT \u2014 pass --purge-knowledge to remove them too)",default:!1})){u.info("Reset cancelled.");return}await $c(t,"claude");let n=await ae(t),s=await w(pn(t,lf)),{kept:o=[],knowledgeKept:i=[]}=await an(t,{purgeProjectAuthored:r})||{};await df(t,"claude");let a=await mi(t,n,"claude"),c=s&&!await w(pn(t,lf));console.log(),u.success("Claude Code target reset complete."),u.info(`Removed (manifest-scoped; only files Vesper could prove it wrote): recorded catalog entries, the pack pointer rules, ${c?"the orchestrator playbook, ":""}guard triggers, CLAUDE.md guard block, .mcp.json entry, the OpenCode overlay (opencode.json keys, .opencode/), .vesperrc.claude.`),o.length&&u.warn(`Kept \u2014 they hold your edits, so Vesper could not prove them its own: ${o.join(", ")}. Delete them yourself if you do not need them.`),u.info(r?"Removed (--purge-knowledge): the Team Roster, project whitepaper, on-demand context tier, and .vesper/gates.json.":"Kept: the Team Roster (.claude/rules/vesper-orchestration.md), project whitepaper (vesper-context.md), and on-demand context tier \u2014 they belong to this project."),r&&i.length&&u.warn(`Kept despite --purge-knowledge \u2014 their content exists nowhere else (no identical copy in the Copilot brain): ${i.join(", ")}.`),u.info("Left intact: agent-authored skills in .claude/skills/ (never Vesper-recorded)."),await dn(t,a,"claude",u)}async function Gk(e={}){let t=pn(e.path||process.cwd()),r=!!e.purgeKnowledge;if(!await Ic(t,"copilot",{purge:r})){u.warn("Vesper is not initialized in this workspace."),await yi(t);return}let n=await ht(t),s=Hk(n);if(!e.yes&&!await Pc({message:r?`Remove all Vesper assets (${s.join(", ")}) INCLUDING the Team Roster and project whitepaper?`:`Remove all Vesper assets (${s.join(", ")})? (the Team Roster and project whitepaper are KEPT \u2014 pass --purge-knowledge to remove them too)`,default:!1})){u.info("Reset cancelled.");return}let o=await x(t),i=await z(t),a=await gr(t,"claude"),c=await ae(t);await Ss(t,{purgeProjectAuthored:r}),await df(t,"copilot");let l=await mi(t,c,"copilot");a&&u.info("Claude Code target detected \u2014 kept its record in .vesperrc"),console.log(),u.success("Vesper reset complete."),o.workspaceType===pe.WORKSPACE_FILE||i.type===pe.WORKSPACE_FILE?u.info(`Cleaned: ${Fk(i.settingsPath)}`):u.info("Cleaned: .vscode/settings.json"),u.info(r?"Removed (--purge-knowledge): the Team Roster, project whitepaper, on-demand context tier, and .vesper/gates.json.":"Kept: the Team Roster and project whitepaper \u2014 they belong to this project."),u.info("Reload VS Code to apply changes"),await dn(t,l,"copilot",u)}function Hk(e){let t=new Set;for(let r of e)r.includes("/agents")&&t.add("Agents"),r.includes("/instructions")&&t.add("Instructions"),r.includes("/prompts")&&t.add("Prompts"),r.includes("/skills")&&t.add("Skills");return Array.from(t)}async function uf(e,t,r){return t==="claude"?Vk({...r,path:e}):Gk({...r,path:e})}async function Uk(e,t,r){let n=!!r.purgeKnowledge;if(!await Ic(e,t,{purge:n})){u.info(`No ${t} artifacts found to clean \u2014 nothing to do.`);return}if(!r.yes&&!await Pc({message:n?`Remove stray ${t} artifacts INCLUDING its Team Roster and project whitepaper? (the active host and all shared state are kept)`:`Remove stray ${t} artifacts from this workspace? (the active host and all shared state are kept)`,default:!1})){u.info("Reset cancelled.");return}let{retained:s}=await gi(e,t,{fullTeardown:!1,purgeProjectAuthored:n});console.log(),u.success(`Foreign ${t} residue removed.`),await dn(e,s,t,u),u.info(n?`Removed (--purge-knowledge): ${t}'s Team Roster, project whitepaper and on-demand context tier.`:`Kept: ${t}'s Team Roster + project whitepaper (pass --purge-knowledge to remove them).`),u.info("Kept: the active host, the cross-host guard trigger, and all shared state (.vesper/.tracking/, memory, history).")}async function pf(e={}){try{let t=pn(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=e.host;if(!r&&e.target){let i=String(e.target).toLowerCase();K.includes(i)||(u.error(`Unknown target: ${e.target}. Valid: ${K.join(", ")}.`),process.exit(1)),u.warn("`--target` is deprecated; use `--host` instead. Mapping to `--host "+i+"`."),r=i}let n=await he(t),o=await zr(t)??(n.length===1?n[0]:null);if(!r){if(n.length>1&&(u.error(Eo),process.exit(1)),!o){let i=await mr(t);if(i){u.warn(`Nothing is provisioned in this checkout; the local record names ${i} \u2014 \`vespercli reset --host ${i}\` removes that host's local files.`),await yi(t);return}u.warn("Vesper is not initialized in this workspace."),await yi(t);return}return await uf(t,o,e)}return o&&o!==r?await Uk(t,r,e):await uf(t,r,e)}catch(t){if(t.name==="ExitPromptError"){console.log(),u.info("Reset cancelled.");return}t.name==="HostCleanRefused"&&(u.error(t.message),process.exit(1)),u.error(`Reset failed: ${t.message}`),process.exit(1)}}be();ye();U();import{lstat as wi,readFile as Se,readdir as Si,readlink as Es,rmdir as gf}from"node:fs/promises";import{createHash as Wk}from"node:crypto";import{basename as yf,dirname as jc,isAbsolute as vi,join as _,relative as Rc,sep as bs}from"node:path";import{homedir as xs}from"node:os";te();be();qe();ns();hr();H();xe();ye();ct();Qr();var Kk=Object.freeze([".vesper/.tracking",".vesper/history.md",".vesper/history-archive",".vesper/memory.jsonl",".vesper/index.db",".vesper/index.db-wal",".vesper/index.db-shm",".vesper/indexing-status.json",xr]);function ki(e){return Kk.some(t=>e===t||e.startsWith(`${t}/`))}var wf=Object.freeze([".vesperrc",".vesper/tracking.json","CLAUDE.md",".claude/settings.json",".claude/settings.local.json",".mcp.json",".vscode/settings.json",".vscode/tasks.json",".vscode/mcp.json",".gitignore",".gitattributes"]),vf=Object.freeze([".claude",".vscode",".vesper",".github",".opencode"]);async function Bk(e,t){let r,n;try{[r,n]=await Promise.all([wi(e),wi(t)])}catch{return!1}if(r.isSymbolicLink()||n.isSymbolicLink())return r.isSymbolicLink()&&n.isSymbolicLink()&&await Es(e)===await Es(t);if(r.isFile()&&n.isFile())return(await Se(e)).equals(await Se(t));if(!r.isDirectory()||!n.isDirectory())return!1;let[s,o]=await Promise.all([nt(e),nt(t)]),i=(a,c)=>a.length===c.length&&a.every((l,d)=>l===c[d]);if(!i(s.files,o.files)||!i(s.others,o.others)||!i([...s.dirs].sort(),[...o.dirs].sort()))return!1;for(let a of s.files)if(!(await Se(_(e,a))).equals(await Se(_(t,a))))return!1;for(let a of s.others)try{if(await Es(_(e,a))!==await Es(_(t,a)))return!1}catch{return!1}return!0}async function ff(e){let t=_(e,xr);await T(t,{recursive:!0});let r=_(t,".gitignore"),n=null;try{n=await Se(r,"utf-8")}catch{n=null}n!==`*
139
- `&&await C(r,`*
140
- `,"utf-8")}async function kf(e,t,r,n){if(!["project","home","rewritten","outside"].includes(t))throw new Error(`backupPath: sourceRoot must be 'project', 'home', 'rewritten' or 'outside' (got "${t}")`);let s=String(r||"").split(bs).join("/");if(!s||vi(s)||s.split("/").includes(".."))throw new Error(`backupPath: unsafe relative path "${r}"`);let o=_(e,t,s);if(await w(o))throw new Error(`backupPath: refusing to overwrite an existing backup at ${o}`);if(await T(jc(o),{recursive:!0}),await Kn(n,o,{recursive:!0,errorOnExist:!0,force:!1,verbatimSymlinks:!0,preserveTimestamps:!0}),!await Bk(n,o))throw new Error(`backupPath: the backup of ${n} at ${o} is not byte-identical \u2014 nothing was removed`);return o}function Nc(e,{now:t=new Date,homeDir:r=xs()}={}){let n=t.toISOString().replace(/[:.]/g,"-"),s=_(e,xr,n),o=[],i=new Set,a=async(c,l,d)=>{await ff(e);let p=await kf(s,c,l,d);return o.push({sourceRoot:c,rel:l,original:d,backup:p}),p};return{dir:s,items:o,homeDir:r,project:c=>a("project",c,_(e,c)),home:c=>a("home",Rc(r,c).split(bs).join("/"),c),async nestedConfig(c){let l=Rc(e,c).split(bs).join("/");if(l&&!l.startsWith("..")&&!vi(l))return a("project",l,c);let d=_(s,Sf),p=[];try{p=JSON.parse(await Se(d,"utf-8"))}catch{p=[]}let h=`${p.length}/${yf(c)}`,m=await a("outside",h,c);return p.push({original:c,backup:_("outside",h).split(bs).join("/")}),await C(d,`${JSON.stringify(p,null,2)}
141
- `,"utf-8"),m},async snapshot(c){return i.has(c)||(i.add(c),!await w(_(e,c)))?null:a("rewritten",c,_(e,c))},async writeSidecar(c,l){return await ff(e),await T(s,{recursive:!0}),await C(_(s,c),l,"utf-8"),_(s,c)},restoreCommands(){let c=new Set(o.map(d=>d.sourceRoot)),l=[];return c.has("project")&&l.push(`cp -R "${_(s,"project")}/." "${e}/"`),c.has("home")&&l.push(`cp -R "${_(s,"home")}/." "${r}/"`),l}}}var Sf="outside.json";async function Ei(e){let t=_(e,xr),r=[];try{r=(await Si(t,{withFileTypes:!0})).filter(s=>s.isDirectory()).map(s=>s.name).sort()}catch{r=[]}let n=[];for(let s of r){let o=_(t,s),i=async h=>{try{return JSON.parse(await Se(_(o,h),"utf-8"))}catch{return null}},a=await i("kept.json"),c=await i("rollback.json"),l=await i(Sf),d=!!c&&Array.isArray(c.before),p=d?typeof c.status=="string"?c.status:Array.isArray(c.created)?"finished":"started":null;n.push({dir:o,name:s,project:await w(_(o,"project")),home:await w(_(o,"home")),rewritten:await w(_(o,"rewritten")),kept:Array.isArray(a)?a.filter(h=>h&&typeof h.rel=="string"):[],created:Array.isArray(c?.created)?c.created.filter(h=>typeof h=="string"):[],trackedPaths:Array.isArray(c?.trackedPaths)?c.trackedPaths.filter(h=>typeof h=="string"):[],head:typeof c?.head=="string"?c.head:null,before:Array.isArray(c?.before)?c.before.filter(h=>typeof h=="string"):null,previousVersion:typeof c?.previousVersion=="string"?c.previousVersion:null,migration:d,status:p,chainRoot:typeof c?.chainRoot=="string"?c.chainRoot:s,preCreated:Array.isArray(c?.preCreated)?c.preCreated.filter(h=>typeof h=="string"):[],outside:Array.isArray(l)?l.filter(h=>h&&typeof h.original=="string"&&typeof h.backup=="string"):[],createdChecked:await w(_(o,Mc))&&await w(_(o,Dc)),guidancePrinted:d?typeof c.guidancePrinted=="boolean"?c.guidancePrinted:p==="finished":!1})}return n}async function Ef(e,t=".md"){try{return(await Si(e,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(t)).map(r=>r.name).sort()}catch{return[]}}async function zk(e){try{return(await Si(e,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name).sort()}catch{return[]}}async function bf(e){try{return await Se(e)}catch{return null}}var Jk=Object.freeze({"edited-catalog":"a 1.x catalog file you edited (or a namesake you wrote) \u2014 it shadows its plugin twin `vesper:<name>` until you delete it","edited-skill":"a 1.x catalog skill holding your edits or your own files \u2014 only its untouched files are retired","edited-playbook":"the 1.x orchestrator playbook holds your edits (2.0 reads .claude/rules/vesper-orchestrator.md instead)","github-brain":"left in place: GitHub.com's Copilot coding agent and code review read it; its content was copied into the new brain","github-brain-kept":"left in place, untouched: GitHub.com's Copilot coding agent and code review read it (the new brain's whitepaper was taken from .claude/vesper/context.md instead)","github-brain-dest":"left in place, untouched: GitHub.com's Copilot coding agent and code review read it (the new brain already had its whitepaper)","github-own":"your own file (no Vesper content) \u2014 left untouched and nothing copied from it (GitHub Copilot reads it natively)","unmarked-knowledge":"no Vesper marker \u2014 not provably Vesper's; left in place","duplicate-knowledge":"not relocated: the same knowledge already moved into the new brain \u2014 review it and delete this copy yourself","plugin-folder":"kept in the old machine-wide plugin folder: no released Vesper build wrote these bytes",error:"left in place after an error"});async function xf(e,t){let r=new Set(t.catalogManifest),n={record:[],keep:[]},s=new Set([...Ht,...pr]);for(let[o,i]of[["agents","catalog-agent"],["commands","catalog-command"]])for(let a of await Ef(_(e,".claude",o))){if(o==="agents"&&a===`${L}.md`)continue;let c=`.claude/${o}/${a}`,l=await bf(_(e,c));if(!l)continue;let d=r.has(c)?1:2;Io(l,`${o}/${a}`,{namePrefix:t.namePrefix})?n.record.push({rel:c,kind:"file",tier:d,entry:D({path:c,host:"claude",category:i,hash:st(l)})}):(r.has(c)||jo(o,a,t.namePrefix))&&n.keep.push({rel:c,reason:"edited-catalog"})}for(let o of await zk(_(e,".claude","skills"))){if(s.has(o))continue;let i=`.claude/skills/${o}`,a=ad(o);if(!a&&!r.has(i))continue;let c=a?await Ot(_(e,i),{sourceLfHashes:a}):{status:"none",proven:[]};if(c.status==="classified"&&c.proven.length){let l={};for(let d of c.proven)l[d]=st(await Se(_(e,i,d)));n.record.push({rel:i,kind:"dir",tier:r.has(i)?1:2,entry:{...D({path:i,host:"claude",category:"catalog-skill",hash:null}),fileHashes:l},userFiles:c.kept}),c.kept.length&&n.keep.push({rel:i,reason:"edited-skill",files:c.kept})}else n.keep.push({rel:i,reason:"edited-skill"})}return n}async function hf(e){let{frontmatter:t}=ot(await Se(_(Me,e),"utf-8"));return t===null?"":`---
150
+ `}async function TS(e){let t=$r(e);if(!t)return null;try{let{frontmatter:r}=ft(await Qc(Fi(t.dir,"SKILL.md"),"utf-8")),n=r?Dr(r,"description"):null;return n&&String(n).trim()||null}catch{return null}}async function PS(e){if(e===".claude/rules/i-have-adhd.md")return[Bf];if(e===".claude/rules/ponytail.md")return[zf];for(let t of Cr)if(e===Ie(t))return Wf.includes(t)?[OS(t)]:[Uf(t,await TS(t)),Uf(t,null)];return[]}async function Yf(e,{backup:t}={}){let r={removed:[],kept:[],claudeMd:!1,stylesConsent:!1,rowsDropped:0},n=new Set,s=async h=>{typeof t!="function"||n.has(h)||(n.add(h),await t(h))},o=await x(e),i=J(o),a=h=>i.find(g=>g.path===h&&Hf.includes(g.category))||null;for(let h of Cr){let g=$r(h),y=g?await Fo(g.dir):{};for(let k of[`.claude/skills/${h}`,`.vesper/skills/${h}`]){let v=Fi(e,k);if(!await w(v))continue;let S=a(k),C=S?.placedFiles??S?.syncedFiles,N=C&&typeof C=="object"&&Object.keys(C).length?{...C}:void 0,E={sourceFiles:y,...N?{sourceHashes:N}:{},sourceMatch:(X,He)=>fc(He,`${k}/${X}`),anchor:"SKILL.md"},b=await Mt(v,E);if(b.status!=="classified"||b.proven.length===0){(b.status==="anchor-unproven"||b.status==="classified"&&b.kept.length)&&r.kept.push({path:k,files:b.kept});continue}await s(k);let F=await is(v,E);F.status==="removed"?r.removed.push(k):F.status!=="absent"&&r.kept.push({path:k,files:F.kept})}}for(let h of Kf()){let g=Fi(e,h);if(!await w(g))continue;let y=null;try{y=await Qc(g)}catch{y=null}if(y&&fc(y,h)){await s(h),await _S(g,{force:!0}),r.removed.push(h);continue}let k=a(h)??{path:h,category:"vendored-activation",hash:null},v=await PS(h);if(!await as(g,k,{expected:v})){r.kept.push({path:h});continue}await s(h);let S=await le(g,k,{expected:v});S==="removed"?r.removed.push(h):S!=="absent"&&r.kept.push({path:h})}let c=Fi(e,"CLAUDE.md");if(await w(c)){let h=await Qc(c,"utf-8"),g=Lc(h);ee(g,h)||(await A(c,g,"utf-8"),r.claudeMd=!0)}let l=await x(e),d=new Set(Zc()),p=J(l),f=p.filter(h=>!(d.has(h.path)&&Hf.includes(h.category)));return r.rowsDropped=p.length-f.length,r.stylesConsent=el(l),(r.rowsDropped>0||l.vendored!==void 0||l.adhd!==void 0)&&(l.manifest=tt(f),delete l.vendored,delete l.adhd,await T(e,l)),r}function Jf(e){let t=[];e.removed.length&&t.push(`Retired the third-party copies an older Vesper placed here (they are pack content now, served from the package): ${e.removed.join(", ")}`),e.claudeMd&&t.push("Removed the retired `vesper:adhd` / `vesper:ponytail` import blocks from CLAUDE.md."),e.stylesConsent&&t.push("Your recorded opt-in to the third-party styles now enables the `styles` pack (`.claude/rules/vesper-styles.md` / `.vesper/instructions/vesper-styles.instructions.md` point at it); `vespercli packs disable styles` turns it off.");let r=e.kept.map(s=>s.files?.length?`${s.path} (${s.files.join(", ")})`:s.path),n=r.length?`Kept \u2014 they hold your edits or your own files, so Vesper could not prove them its own: ${r.join("; ")}. The third-party skills are pack content now (nothing under .claude/skills or .vesper/skills is needed); delete these copies yourself if you do not need them.`:null;return{info:t,warn:n}}var rl=class extends Error{constructor(t){super(t),this.name="HostCleanRefused",this.code="HOST_CLEAN_REFUSED"}};async function nl(e,t){if(t==="copilot"&&!await ad(e)&&await NS(e)!==0)throw new rl(`This workspace's Copilot ownership manifest has no granular-provenance record, so it may have been written by an older Vesper whose manifest can claim user files. Run \`${LS}\` to re-record it granularly, then retry.`)}async function NS(e){return J(await x(e)).filter(r=>r.host==="copilot"&&Ft[r.category]?.ownership==="whole-file").length}var LS="vespercli init --host copilot";async function qf(e,{from:t,to:r,snapshot:n}){await P(ke(e,".vesper"),{recursive:!0});let s={from:t,to:r,snapshot:n,startedAt:new Date().toISOString()};await _r(ke(e,ir),JSON.stringify(s,null,2))}async function sl(e){await Ds(ke(e,ir),{force:!0});let t=ir.split("/").pop();try{for(let r of await RS(ke(e,".vesper")))r.startsWith(`${t}.`)&&r.endsWith(".tmp")&&await Ds(ke(e,".vesper",r),{force:!0})}catch{}}async function ol(e){let t=await x(e),r=J(t);return{manifest:r,mcpServers:Array.isArray(t.mcp?.servers)?[...t.mcp.servers]:[],mcp:t.mcp?JSON.parse(JSON.stringify(t.mcp)):void 0,settingsEntries:await xt(e),addedAssets:r.filter(n=>n.category==="added-asset").map(n=>n.path),namePrefix:typeof t.namePrefix=="string"?t.namePrefix:"",packs:[...new Set([...await Ht(e,"claude"),...await Ht(e,"copilot"),...el(t)?["styles"]:[]])].sort()}}async function MS(e,t={}){let r=ke(e,".vscode"),n=async i=>{try{return Lt(await tl(i,"utf-8"))}catch{return}},s=ke(r,"settings.json");if((await q(e)).type!==he.WORKSPACE_FILE&&(t.paths?.length??0)+(t.settings?.length??0)>0){let i=await n(s);i&&typeof i=="object"&&Object.keys(i).length===0&&await Ds(s,{force:!0})}if((t.mcpServers?.length??0)>0){let i=Qe(e),a=await n(i);a&&typeof a=="object"&&Object.keys(a).every(l=>l==="servers")&&(!a.servers||Object.keys(a.servers).length===0)&&await Ds(i,{force:!0})}try{await jS(r)}catch{}}async function Vs(e,{purgeProjectAuthored:t=!1}={}){let r=await x(e),n=await Pr(e,"claude"),{removed:s}=await Zn(e);try{let i=await K(e);if(i[V]){let a=new Set(Re),c=!1;for(let l of Object.keys(i[V]))a.has(l)||(delete i[V][l],c=!0);c&&await ce(e,i)}}catch{}await Yo(e,"copilot"),await hn(e,"copilot"),await Vf(e,{purgeProjectAuthored:t}),await qn(e,vo,{removeFileIfEmpty:!0}),await MS(e,s);let o=IS(e,".vesperrc");try{n?(r.paths=[],r.readAccessPaths=[],r.addedAt=null,r.workspaceType=null,r.settingsPath=null,r.host==="copilot"&&(r.host="claude"),Array.isArray(r.manifest)&&(r.manifest=r.manifest.filter(i=>!(i&&i.host==="copilot"))),await A(o,JSON.stringify(r,null,2),"utf-8")):await Ds(o,{force:!0})}catch{}}async function Di(e,t,r){let n=new Set(J(await x(e)).map(o=>`${o.host}\0${o.path}`)),s=[];for(let o of t||[])!o||o.host!==r||Ft[o.category]?.ownership!=="whole-file"||Ne.has(o.category)||n.has(`${o.host}\0${o.path}`)||await w(ke(e,o.path))&&s.push(o.path);return[...new Set(s)].sort()}async function Cn(e,t,r,n){let o=(await Fn(e,r)).filter(a=>!(t||[]).some(c=>a===c||a.startsWith(`${c}/`))),i=[...new Set([...t||[],...o])].sort();return i.length?(n.warn(`Left in place \u2014 they hold your own files or edits (or were written by a different Vesper version), so Vesper could not prove them its own and no longer tracks them: ${i.join(", ")}. Delete them yourself if you do not need them.`),await Er(e,r)?n.warn(`This workspace still carries ${r} provisioning markers and may still be detected as ${r}.`):n.warn(`These no longer mark this workspace as ${r}: a later \`vespercli worktree bootstrap\` will not re-provision ${r} because of them.`),i):[]}function GS(e,t,r){return r?t==="copilot"&&e.category==="guard-rule"?!0:e.category==="guard-trigger"?e.path===(t==="claude"?".claude/settings.json":".vscode/tasks.json"):!1:!1}async function Vi(e,t,{keepPaths:r=[],purgeProjectAuthored:n=!1,fullTeardown:s=!1}={}){if(!z.includes(t))throw new Error(`cleanHost: host must be one of ${z.join(", ")} (received "${t}")`);let o=!!n;await nl(e,t),await il(e,t);let i=await ol(e),{pruned:a}=await ud(e,r,{host:t,purgeProjectAuthored:o});t==="claude"?await bn(e,{purgeProjectAuthored:o}):await Vs(e,{purgeProjectAuthored:o}),s&&(await Ls(e,t),t==="copilot"&&await Fr(e));let c=await x(e);c.schemaVersion=ve,c.manifest=J(c).filter(d=>d.host!==t||!o&&Ne.has(d.category));for(let d of i.manifest)if(!c.manifest.some(f=>f.path===d.path&&f.host===d.host))if(d.host==="shared"){if(GS(d,t,s))continue;c.manifest.push(d)}else d.host===t&&!o&&Ne.has(d.category)&&await w(ke(e,d.path))&&c.manifest.push(d);c.manifest=tt(c.manifest),i.mcp!==void 0?c.mcp=i.mcp:delete c.mcp,await T(e,c);let l=await Di(e,i.manifest,t);return{...i,pruned:a,retained:l}}async function il(e,t){if(t!=="claude")return[];if(!await Er(e,"claude")&&!await no(e,"claude"))return[];let r=new Set(J(await x(e)).filter(a=>a.host==="claude").map(a=>a.path)),n=async(a,c)=>{try{let[l,d]=await Promise.all([tl(ke(e,a)),tl(c)]);return ee(l,d)}catch{return!1}},s=[],o=`.claude/agents/${L}.md`;!r.has(o)&&await n(o,ke(fr,"agents",`${L}.md`))&&s.push(G({path:o,host:"claude",category:"catalog-agent",hash:await ye(ke(e,o))}));for(let a of Qt){let c=`.claude/skills/${a}`;!r.has(c)&&await n(`${c}/SKILL.md`,ke(fr,"skills",a,"SKILL.md"))&&s.push(G({path:c,host:"claude",category:"catalog-skill",hash:null}))}let i=".claude/rules/vesper-orchestrator.md";!r.has(i)&&await n(i,ke(De,"vesper-orchestrator.md"))&&s.push(G({path:i,host:"claude",category:"playbook",hash:await ye(ke(e,i))}));for(let a of[".claude/rules/vesper-orchestration.md",".claude/rules/vesper-context.md"])!r.has(a)&&await w(ke(e,a))&&s.push(G({path:a,host:"claude",category:"per-project-authored",hash:null}));for(let a of await $d(e,"claude"))r.has(a.path)||s.push(a);for(let a of await Lp(e))r.has(a.path)||s.push(a);return s.length&&await W(e,s),s.map(a=>a.path)}function FS(e){let t=/^\.claude\/agents\/([^/]+)\.md$/.exec(e);return t?{type:"agents",name:t[1]}:(t=/^\.claude\/commands\/([^/]+)\.md$/.exec(e),t?{type:"prompts",name:t[1]}:(t=/^\.claude\/skills\/([^/]+)$/.exec(e),t?{type:"skills",name:t[1]}:null))}function DS(e){let t=String(e).replace(/\\/g,"/"),r=/\/assets\/copilot\/instructions-extended\/([^/]+)\/?$/.exec(t);return r?{type:"instructions",name:r[1]}:(r=/\/assets\/(?:copilot\/)?(agents|prompts)\/([^/]+)\/?$/.exec(t),r?{type:r[1],name:r[2].replace(/\.(agent|prompt)\.md$/,"")}:null)}async function Xf(e,t,r){let n={mcpServers:{added:[],skipped:[]},assets:{added:[],kept:[],skipped:[]},packs:{added:[],kept:[],skipped:[]}};for(let l of r.packs||[])try{let{enabled:d}=await cr(e,t,l);(d?n.packs.added:n.packs.kept).push(l)}catch{n.packs.skipped.push(l)}for(let l of r.mcpServers||[])if(!me.includes(l))try{((t==="claude"?await kn(e,l):await sr(e,l)).added?n.mcpServers.added:n.mcpServers.skipped).push(l)}catch{n.mcpServers.skipped.push(l)}let s=await on(e)||"",o=r.namePrefix??s,i=l=>o&&l.startsWith(o)?l.slice(o.length):l,a=[...(r.addedAssets||[]).map(FS).filter(Boolean).map(l=>({...l,name:i(l.name),source:"claude-record"})),...(r.settingsEntries||[]).map(DS).filter(Boolean).map(l=>({...l,source:"copilot-entry"}))],c=new Set;for(let{type:l,name:d,source:p}of a){let f=`${l}/${d}`;if(!c.has(f)){c.add(f);try{if(t==="copilot"){if(l==="instructions"){let{added:m}=await Gi(e,d);(m?n.assets.added:n.assets.kept).push(f);continue}n.assets.kept.push(f)}else if(p==="copilot-entry")n.assets.kept.push(f);else{let m=l==="prompts"?"commands":l,h=VS(m,d,s);if(await w(ke(e,h))){await W(e,[G({path:h,host:"claude",category:"added-asset",hash:null})]),n.assets.kept.push(f);continue}await wi(m,d,{workspaceRoot:e,namePrefix:s}),n.assets.added.push(f)}}catch{n.assets.skipped.push(f)}}}return n}function VS(e,t,r=""){if(e==="skills")return`.claude/skills/${t}`;let n=r&&!t.startsWith(r)?`${r}${t}`:t;return`.claude/${e}/${n}.md`}be();fe();Pe();H();be();Wr();pt();wt();import{lstat as HS,readFile as Qf,realpath as US,rm as Zf,stat as WS}from"node:fs/promises";import{join as eh,resolve as KS}from"node:path";function BS(e){return e.split(`
151
+ `).every(t=>{let r=t.trim();return r===""||r.startsWith("#")||/^exit\s+0\s*;?$/.test(r)})}async function th(e){try{return await US(e)}catch{return KS(e)}}async function zS(e){try{return(await WS(e)).isDirectory()}catch{return!1}}async function YS(e,t,{gitVersion:r,resolveHooksDir:n=nr}={}){let s={...br(process.env),...jt},o=await Ro(e,{env:s,gitArgs:en,gitVersion:r});if(o===null)return[{worktree:"(unknown)",host:null,why:"git worktree list failed"}];let i=await at(t.dir),a=await th(t.top??e),c=[];for(let l of jo(o.out)){if(l.bare||!l.worktree||await th(l.worktree)===a)continue;if(l.prunable!==void 0){c.push({worktree:l.worktree,host:null,why:"prunable"});continue}if(l.locked!==void 0){c.push({worktree:l.worktree,host:null,why:"locked"});continue}if(!await zS(l.worktree)){c.push({worktree:l.worktree,host:null,why:"missing"});continue}let p=await n(l.worktree,{env:s,gitArgs:en});if(!p.dir&&["machine-wide","not-a-directory","husky-v9"].includes(p.reason)||p.dir&&!p.default&&await at(p.dir)!==i)continue;if(!p.dir){c.push({worktree:l.worktree,host:null,why:`hooks path unknown (${p.reason})`});continue}let f;try{f=await B(l.worktree,{env:s,gitArgs:en})}catch{f={gitError:"unknown"}}if(f.gitError){c.push({worktree:l.worktree,host:null,why:`git error (${f.gitError})`});continue}(f.host||f.ambiguous)&&c.push({worktree:l.worktree,host:f.host??"both",why:"provisioned"})}return c}async function al(e,{gitVersion:t,resolveHooksDir:r}={}){let n=Object.fromEntries(ct.map(c=>[c,null])),s=await nr(e);if(!s.dir)return{action:"none",hooks:n,reason:s.reason};let o=[];for(let c of ct){let l=eh(s.dir,c);try{(await Qf(l)).toString("latin1").includes(ot)&&o.push(l)}catch{}}if(!o.length)return{action:"none",hooks:n};let i=await B(e);if(i.host)return{action:"kept",hooks:n,paths:o,keptFor:[{worktree:e,host:i.host,why:"this checkout still carries Vesper provisioning"}]};let a=await YS(e,s,{gitVersion:t,...r?{resolveHooksDir:r}:{}});if(a.length)return{action:"kept",hooks:n,paths:o,keptFor:a};for(let c of ct){let l=eh(s.dir,c),d=await tn(l);if(!d.path)continue;let p=await at(d.path);if(!kt(p,s.roots)||await tr(p,s))continue;let f;try{f=await Qf(d.path)}catch{continue}let m=f.toString("latin1");if(!m.includes(ot))continue;let h=vr(Ld(m)??m);if(h!==null)if(BS(h)){await Zf(d.path,{force:!0});try{(await HS(l)).isSymbolicLink()&&l!==d.path&&await Zf(l,{force:!0})}catch{}n[c]="file"}else await vt(d.path,Buffer.from(h,"latin1")),n[c]="region"}return{action:Object.values(n).some(Boolean)?"removed":"none",hooks:n}}function cl(e){if(e.action==="removed")return`Removed Vesper's git hooks (${Object.entries(e.hooks).filter(([,t])=>t).map(([t])=>t).join(", ")}).`;if(e.action==="kept"){let t=e.keptFor.map(a=>`${a.worktree} (${a.host??`unknown: ${a.why}`})`).join(", "),r=e.paths?.length?` in ${e.paths.join(", ")}`:"",n=e.keptFor.filter(a=>a.why==="missing"||a.why==="prunable").map(a=>a.worktree),s=e.keptFor.filter(a=>a.why==="locked").map(a=>a.worktree),o=[n.length?` ${n.join(", ")} ${n.length>1?"are":"is"} gone: \`git worktree prune\` drops ${n.length>1?"those entries":"that entry"}, then reset again.`:"",s.length?` ${s.join(", ")} ${s.length>1?"are":"is"} locked: if ${s.length>1?"they are":"it is"} gone, \`git worktree unlock <path>\` and \`git worktree prune\`, then reset again.`:""].join(""),i=e.keptFor.every(a=>a.worktree===e.keptFor[0].worktree&&a.why==="this checkout still carries Vesper provisioning")?"this checkout still carries Vesper provisioning":`worktrees sharing these hooks may still use Vesper \u2014 ${t}`;return`Kept Vesper's git-hook block${r}: ${i}.${o} To remove it everywhere, reset those worktrees too, or run \`git config vesper.hooks false\` (the block then does nothing) and delete it from those files.`}return null}var rh=".claude/rules/vesper-orchestrator.md";async function ul(e,t,{purge:r=!1}={}){if(await Pr(e,t)||await Er(e,t)||await no(e,t))return!0;if(r){if((await ne(e)).some(s=>s.host===t&&Ne.has(s.category)))return!0;if(t==="copilot"){for(let s of[".vesper/instructions/vesper-orchestration.instructions.md",".vesper/instructions/vesper-context.instructions.md",".vesper/context"])if(await w($n(e,s)))return!0}}return!1}async function Hi(e){try{let t=await al(e),r=cl(t);r&&(t.action==="kept"?u.warn:u.info)(r)}catch(t){u.warn(`Vesper's git-hook block was left in place (${t?.message??t}).`)}}async function sh(e,t){await Ls(e,t),await Ls(e,Kc(t)),await Fr(e)==="kept"&&u.warn(xn());try{let r=await al(e),n=cl(r);n&&(r.action==="kept"?u.warn:u.info)(n)}catch(r){u.warn(`Vesper's git-hook block was left in place (${r?.message??r}).`)}await Oa(e)}async function qS(e={}){let t=$n(e.path||process.cwd()),r=!!e.purgeKnowledge;if(!await ul(t,"claude",{purge:r})){u.warn("Claude Code target is not initialized in this workspace."),await Hi(t);return}if(!e.yes&&!await ll({message:r?"Remove the Claude Code target INCLUDING the Team Roster and project whitepaper? (this deletes accumulated project knowledge)":"Remove the Claude Code target from this project? (the Team Roster and project whitepaper are KEPT \u2014 pass --purge-knowledge to remove them too)",default:!1})){u.info("Reset cancelled.");return}await il(t,"claude");let n=await ne(t),s=await w($n(t,rh)),{kept:o=[],knowledgeKept:i=[]}=await bn(t,{purgeProjectAuthored:r})||{};await sh(t,"claude");let a=await Di(t,n,"claude"),c=s&&!await w($n(t,rh));console.log(),u.success("Claude Code target reset complete."),u.info(`Removed (manifest-scoped; only files Vesper could prove it wrote): recorded catalog entries, the pack pointer rules, ${c?"the orchestrator playbook, ":""}guard triggers, CLAUDE.md guard block, .mcp.json entry, the OpenCode overlay (opencode.json keys, .opencode/), .vesperrc.claude.`),o.length&&u.warn(`Kept \u2014 they hold your edits, so Vesper could not prove them its own: ${o.join(", ")}. Delete them yourself if you do not need them.`),u.info(r?"Removed (--purge-knowledge): the Team Roster, project whitepaper, on-demand context tier, and .vesper/gates.json.":"Kept: the Team Roster (.claude/rules/vesper-orchestration.md), project whitepaper (vesper-context.md), and on-demand context tier \u2014 they belong to this project."),r&&i.length&&u.warn(`Kept despite --purge-knowledge \u2014 their content exists nowhere else (no identical copy in the Copilot brain): ${i.join(", ")}.`),u.info("Left intact: agent-authored skills in .claude/skills/ (never Vesper-recorded)."),await Cn(t,a,"claude",u)}async function XS(e={}){let t=$n(e.path||process.cwd()),r=!!e.purgeKnowledge;if(!await ul(t,"copilot",{purge:r})){u.warn("Vesper is not initialized in this workspace."),await Hi(t);return}let n=await bt(t),s=QS(n);if(!e.yes&&!await ll({message:r?`Remove all Vesper assets (${s.join(", ")}) INCLUDING the Team Roster and project whitepaper?`:`Remove all Vesper assets (${s.join(", ")})? (the Team Roster and project whitepaper are KEPT \u2014 pass --purge-knowledge to remove them too)`,default:!1})){u.info("Reset cancelled.");return}let o=await x(t),i=await q(t),a=await Pr(t,"claude"),c=await ne(t);await Vs(t,{purgeProjectAuthored:r}),await sh(t,"copilot");let l=await Di(t,c,"copilot");a&&u.info("Claude Code target detected \u2014 kept its record in .vesperrc"),console.log(),u.success("Vesper reset complete."),o.workspaceType===he.WORKSPACE_FILE||i.type===he.WORKSPACE_FILE?u.info(`Cleaned: ${JS(i.settingsPath)}`):u.info("Cleaned: .vscode/settings.json"),u.info(r?"Removed (--purge-knowledge): the Team Roster, project whitepaper, on-demand context tier, and .vesper/gates.json.":"Kept: the Team Roster and project whitepaper \u2014 they belong to this project."),u.info("Reload VS Code to apply changes"),await Cn(t,l,"copilot",u)}function QS(e){let t=new Set;for(let r of e)r.includes("/agents")&&t.add("Agents"),r.includes("/instructions")&&t.add("Instructions"),r.includes("/prompts")&&t.add("Prompts"),r.includes("/skills")&&t.add("Skills");return Array.from(t)}async function nh(e,t,r){return t==="claude"?qS({...r,path:e}):XS({...r,path:e})}async function ZS(e,t,r){let n=!!r.purgeKnowledge;if(!await ul(e,t,{purge:n})){u.info(`No ${t} artifacts found to clean \u2014 nothing to do.`);return}if(!r.yes&&!await ll({message:n?`Remove stray ${t} artifacts INCLUDING its Team Roster and project whitepaper? (the active host and all shared state are kept)`:`Remove stray ${t} artifacts from this workspace? (the active host and all shared state are kept)`,default:!1})){u.info("Reset cancelled.");return}let{retained:s}=await Vi(e,t,{fullTeardown:!1,purgeProjectAuthored:n});console.log(),u.success(`Foreign ${t} residue removed.`),await Cn(e,s,t,u),u.info(n?`Removed (--purge-knowledge): ${t}'s Team Roster, project whitepaper and on-demand context tier.`:`Kept: ${t}'s Team Roster + project whitepaper (pass --purge-knowledge to remove them).`),u.info("Kept: the active host, the cross-host guard trigger, and all shared state (.vesper/.tracking/, memory, history).")}async function oh(e={}){try{let t=$n(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=e.host;if(!r&&e.target){let i=String(e.target).toLowerCase();z.includes(i)||(u.error(`Unknown target: ${e.target}. Valid: ${z.join(", ")}.`),process.exit(1)),u.warn("`--target` is deprecated; use `--host` instead. Mapping to `--host "+i+"`."),r=i}let n=await ge(t),o=await sn(t)??(n.length===1?n[0]:null);if(!r){if(n.length>1&&(u.error(Ho),process.exit(1)),!o){let i=await Tr(t);if(i){u.warn(`Nothing is provisioned in this checkout; the local record names ${i} \u2014 \`vespercli reset --host ${i}\` removes that host's local files.`),await Hi(t);return}u.warn("Vesper is not initialized in this workspace."),await Hi(t);return}return await nh(t,o,e)}return o&&o!==r?await ZS(t,r,e):await nh(t,r,e)}catch(t){if(t.name==="ExitPromptError"){console.log(),u.info("Reset cancelled.");return}t.name==="HostCleanRefused"&&(u.error(t.message),process.exit(1)),u.error(`Reset failed: ${t.message}`),process.exit(1)}}be();fe();U();import{lstat as Ui,readFile as Se,readdir as Bi,readlink as Hs,rmdir as lh}from"node:fs/promises";import{createHash as eE}from"node:crypto";import{basename as uh,dirname as dl,isAbsolute as Wi,join as _,relative as pl,sep as Us}from"node:path";import{homedir as Ws}from"node:os";te();be();Ye();bs();Or();H();Ae();fe();it();un();var tE=Object.freeze([".vesper/.tracking",".vesper/history.md",".vesper/history-archive",".vesper/memory.jsonl",".vesper/index.db",".vesper/index.db-wal",".vesper/index.db-shm",".vesper/indexing-status.json",Gr]);function Ki(e){return tE.some(t=>e===t||e.startsWith(`${t}/`))}var dh=Object.freeze([".vesperrc",".vesper/tracking.json","CLAUDE.md",".claude/settings.json",".claude/settings.local.json",".mcp.json",".vscode/settings.json",".vscode/tasks.json",".vscode/mcp.json",".gitignore",".gitattributes"]),ph=Object.freeze([".claude",".vscode",".vesper",".github",".opencode"]);async function rE(e,t){let r,n;try{[r,n]=await Promise.all([Ui(e),Ui(t)])}catch{return!1}if(r.isSymbolicLink()||n.isSymbolicLink())return r.isSymbolicLink()&&n.isSymbolicLink()&&await Hs(e)===await Hs(t);if(r.isFile()&&n.isFile())return(await Se(e)).equals(await Se(t));if(!r.isDirectory()||!n.isDirectory())return!1;let[s,o]=await Promise.all([lt(e),lt(t)]),i=(a,c)=>a.length===c.length&&a.every((l,d)=>l===c[d]);if(!i(s.files,o.files)||!i(s.others,o.others)||!i([...s.dirs].sort(),[...o.dirs].sort()))return!1;for(let a of s.files)if(!(await Se(_(e,a))).equals(await Se(_(t,a))))return!1;for(let a of s.others)try{if(await Hs(_(e,a))!==await Hs(_(t,a)))return!1}catch{return!1}return!0}async function ih(e){let t=_(e,Gr);await P(t,{recursive:!0});let r=_(t,".gitignore"),n=null;try{n=await Se(r,"utf-8")}catch{n=null}n!==`*
152
+ `&&await A(r,`*
153
+ `,"utf-8")}async function fh(e,t,r,n){if(!["project","home","rewritten","outside"].includes(t))throw new Error(`backupPath: sourceRoot must be 'project', 'home', 'rewritten' or 'outside' (got "${t}")`);let s=String(r||"").split(Us).join("/");if(!s||Wi(s)||s.split("/").includes(".."))throw new Error(`backupPath: unsafe relative path "${r}"`);let o=_(e,t,s);if(await w(o))throw new Error(`backupPath: refusing to overwrite an existing backup at ${o}`);if(await P(dl(o),{recursive:!0}),await os(n,o,{recursive:!0,errorOnExist:!0,force:!1,verbatimSymlinks:!0,preserveTimestamps:!0}),!await rE(n,o))throw new Error(`backupPath: the backup of ${n} at ${o} is not byte-identical \u2014 nothing was removed`);return o}function fl(e,{now:t=new Date,homeDir:r=Ws()}={}){let n=t.toISOString().replace(/[:.]/g,"-"),s=_(e,Gr,n),o=[],i=new Set,a=async(c,l,d)=>{await ih(e);let p=await fh(s,c,l,d);return o.push({sourceRoot:c,rel:l,original:d,backup:p}),p};return{dir:s,items:o,homeDir:r,project:c=>a("project",c,_(e,c)),home:c=>a("home",pl(r,c).split(Us).join("/"),c),async nestedConfig(c){let l=pl(e,c).split(Us).join("/");if(l&&!l.startsWith("..")&&!Wi(l))return a("project",l,c);let d=_(s,hh),p=[];try{p=JSON.parse(await Se(d,"utf-8"))}catch{p=[]}let f=`${p.length}/${uh(c)}`,m=await a("outside",f,c);return p.push({original:c,backup:_("outside",f).split(Us).join("/")}),await A(d,`${JSON.stringify(p,null,2)}
154
+ `,"utf-8"),m},async snapshot(c){return i.has(c)||(i.add(c),!await w(_(e,c)))?null:a("rewritten",c,_(e,c))},async writeSidecar(c,l){return await ih(e),await P(s,{recursive:!0}),await A(_(s,c),l,"utf-8"),_(s,c)},restoreCommands(){let c=new Set(o.map(d=>d.sourceRoot)),l=[];return c.has("project")&&l.push(`cp -R "${_(s,"project")}/." "${e}/"`),c.has("home")&&l.push(`cp -R "${_(s,"home")}/." "${r}/"`),l}}}var hh="outside.json";async function zi(e){let t=_(e,Gr),r=[];try{r=(await Bi(t,{withFileTypes:!0})).filter(s=>s.isDirectory()).map(s=>s.name).sort()}catch{r=[]}let n=[];for(let s of r){let o=_(t,s),i=async f=>{try{return JSON.parse(await Se(_(o,f),"utf-8"))}catch{return null}},a=await i("kept.json"),c=await i("rollback.json"),l=await i(hh),d=!!c&&Array.isArray(c.before),p=d?typeof c.status=="string"?c.status:Array.isArray(c.created)?"finished":"started":null;n.push({dir:o,name:s,project:await w(_(o,"project")),home:await w(_(o,"home")),rewritten:await w(_(o,"rewritten")),kept:Array.isArray(a)?a.filter(f=>f&&typeof f.rel=="string"):[],created:Array.isArray(c?.created)?c.created.filter(f=>typeof f=="string"):[],trackedPaths:Array.isArray(c?.trackedPaths)?c.trackedPaths.filter(f=>typeof f=="string"):[],head:typeof c?.head=="string"?c.head:null,before:Array.isArray(c?.before)?c.before.filter(f=>typeof f=="string"):null,previousVersion:typeof c?.previousVersion=="string"?c.previousVersion:null,migration:d,status:p,chainRoot:typeof c?.chainRoot=="string"?c.chainRoot:s,preCreated:Array.isArray(c?.preCreated)?c.preCreated.filter(f=>typeof f=="string"):[],outside:Array.isArray(l)?l.filter(f=>f&&typeof f.original=="string"&&typeof f.backup=="string"):[],createdChecked:await w(_(o,ml))&&await w(_(o,gl)),guidancePrinted:d?typeof c.guidancePrinted=="boolean"?c.guidancePrinted:p==="finished":!1})}return n}async function mh(e,t=".md"){try{return(await Bi(e,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(t)).map(r=>r.name).sort()}catch{return[]}}async function nE(e){try{return(await Bi(e,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name).sort()}catch{return[]}}async function gh(e){try{return await Se(e)}catch{return null}}var sE=Object.freeze({"edited-catalog":"a 1.x catalog file you edited (or a namesake you wrote) \u2014 it shadows its plugin twin `vesper:<name>` until you delete it","edited-skill":"a 1.x catalog skill holding your edits or your own files \u2014 only its untouched files are retired","edited-playbook":"the 1.x orchestrator playbook holds your edits (2.0 reads .claude/rules/vesper-orchestrator.md instead)","github-brain":"left in place: GitHub.com's Copilot coding agent and code review read it; its content was copied into the new brain","github-brain-kept":"left in place, untouched: GitHub.com's Copilot coding agent and code review read it (the new brain's whitepaper was taken from .claude/vesper/context.md instead)","github-brain-dest":"left in place, untouched: GitHub.com's Copilot coding agent and code review read it (the new brain already had its whitepaper)","github-own":"your own file (no Vesper content) \u2014 left untouched and nothing copied from it (GitHub Copilot reads it natively)","unmarked-knowledge":"no Vesper marker \u2014 not provably Vesper's; left in place","duplicate-knowledge":"not relocated: the same knowledge already moved into the new brain \u2014 review it and delete this copy yourself","plugin-folder":"kept in the old machine-wide plugin folder: no released Vesper build wrote these bytes",error:"left in place after an error"});async function yh(e,t){let r=new Set(t.catalogManifest),n={record:[],keep:[]},s=new Set([...Qt,...Cr]);for(let[o,i]of[["agents","catalog-agent"],["commands","catalog-command"]])for(let a of await mh(_(e,".claude",o))){if(o==="agents"&&a===`${L}.md`)continue;let c=`.claude/${o}/${a}`,l=await gh(_(e,c));if(!l)continue;let d=r.has(c)?1:2;ni(l,`${o}/${a}`,{namePrefix:t.namePrefix})?n.record.push({rel:c,kind:"file",tier:d,entry:G({path:c,host:"claude",category:i,hash:ut(l)})}):(r.has(c)||si(o,a,t.namePrefix))&&n.keep.push({rel:c,reason:"edited-catalog"})}for(let o of await nE(_(e,".claude","skills"))){if(s.has(o))continue;let i=`.claude/skills/${o}`,a=rp(o);if(!a&&!r.has(i))continue;let c=a?await Mt(_(e,i),{sourceLfHashes:a}):{status:"none",proven:[]};if(c.status==="classified"&&c.proven.length){let l={};for(let d of c.proven)l[d]=ut(await Se(_(e,i,d)));n.record.push({rel:i,kind:"dir",tier:r.has(i)?1:2,entry:{...G({path:i,host:"claude",category:"catalog-skill",hash:null}),fileHashes:l},userFiles:c.kept}),c.kept.length&&n.keep.push({rel:i,reason:"edited-skill",files:c.kept})}else n.keep.push({rel:i,reason:"edited-skill"})}return n}async function ah(e){let{frontmatter:t}=ft(await Se(_(De,e),"utf-8"));return t===null?"":`---
142
155
  ${t}
143
156
  ---
144
157
 
145
- `}function Yk(e){let{frontmatter:t}=ot(e);return/Vesper orchestration/.test(Ar(t,"description")||"")}function qk(e){let t=e.split(`
158
+ `}function oE(e){let{frontmatter:t}=ft(e);return/Vesper orchestration/.test(Dr(t,"description")||"")}function iE(e){let t=e.split(`
146
159
  `).slice(0,40).join(`
147
- `);return/^#\s*Vesper\b/m.test(t)||t.includes(".vesper/")||t.includes(".claude/vesper/context")}async function _f(e){return await Ef(e,".code-workspace")}async function Af(e,{record:t}={}){let r=t||await ni(e),n=await xf(e,r),s=new Set([...wf,...await _f(e),...n.record.map(o=>o.rel),".claude/vesper/orchestrator.md",".claude/vesper/orchestration.md",".claude/vesper/context.md",".github/instructions/orchestration.instructions.md"]);for(let o of Sc())s.add(o);return[...s].sort()}async function Lc(e){let t=await G(["rev-parse","--git-path","hooks"],{cwd:e});if(!t)return null;let n=(vi(t)?Rc(e,t):t).split(bs).join("/");return!n||n.startsWith("..")||vi(n)?null:n}async function Cf(e){return await G(["rev-parse","--is-inside-work-tree"],{cwd:e})==="true"}async function $f(e,{record:t}={}){if(!await Cf(e))return{inGit:!1,dirty:[],staged:[]};let r=await Af(e,{record:t}),n=new Set,s=new Set,o=i=>i?i.split(`
148
- `).map(a=>a.trim()).filter(Boolean):[];for(let[i,a]of[[["diff","--name-only","--",...r],null],[["diff","--name-only","--cached","--",...r],s],[["ls-files","--others","--exclude-standard","--",...r],null]])for(let c of o(await G(["-c","core.quotepath=off",...i],{cwd:e})))n.add(c),a&&a.add(c);return{inGit:!0,dirty:[...n].sort(),staged:[...s].sort()}}function Of(e,{interrupted:t=null}={}){let r=e.slice(0,15).join(", ")+(e.length>15?`, \u2026 (${e.length} in total)`:""),n=t?` An interrupted migration of this commit left its own changes too (${t}) \u2014 those alone would not stop a re-run, but these paths hold changes it did not write.`:"";return`Not migrating: this pre-2.0 (1.x) Vesper workspace has uncommitted changes in paths the migration removes or rewrites (${r}).${n} Commit or stash them first (\`git add -A && git commit\`, or \`git stash -u\`), then re-run \`vespercli init\` \u2014 a clean start is what makes \`git restore\` a genuine undo of the migration.`}async function Xk(e){let t=new Set,r=s=>ki(s)||/^\.vesper\/index\.db/.test(s),n=await Lc(e);for(let s of[...vf,...n?[n]:[]]){let o;try{o=await nt(_(e,s))}catch{continue}for(let i of[...o.files,...o.others]){let a=`${s}/${i}`;r(a)||t.add(a)}}try{for(let s of await Si(e,{withFileTypes:!0}))(s.isFile()||s.isSymbolicLink())&&t.add(s.name)}catch{}return t}var Tf="written.log",Pf="no-hooks",Mc="created.sha256",Dc="remove-created.sh",Qk=`#!/bin/sh
160
+ `);return/^#\s*Vesper\b/m.test(t)||t.includes(".vesper/")||t.includes(".claude/vesper/context")}async function wh(e){return await mh(e,".code-workspace")}async function vh(e,{record:t}={}){let r=t||await $i(e),n=await yh(e,r),s=new Set([...dh,...await wh(e),...n.record.map(o=>o.rel),".claude/vesper/orchestrator.md",".claude/vesper/orchestration.md",".claude/vesper/context.md",".github/instructions/orchestration.instructions.md"]);for(let o of Zc())s.add(o);return[...s].sort()}async function hl(e){let t=await D(["rev-parse","--git-path","hooks"],{cwd:e});if(!t)return null;let n=(Wi(t)?pl(e,t):t).split(Us).join("/");return!n||n.startsWith("..")||Wi(n)?null:n}async function kh(e){return await D(["rev-parse","--is-inside-work-tree"],{cwd:e})==="true"}async function Sh(e,{record:t}={}){if(!await kh(e))return{inGit:!1,dirty:[],staged:[]};let r=await vh(e,{record:t}),n=new Set,s=new Set,o=i=>i?i.split(`
161
+ `).map(a=>a.trim()).filter(Boolean):[];for(let[i,a]of[[["diff","--name-only","--",...r],null],[["diff","--name-only","--cached","--",...r],s],[["ls-files","--others","--exclude-standard","--",...r],null]])for(let c of o(await D(["-c","core.quotepath=off",...i],{cwd:e})))n.add(c),a&&a.add(c);return{inGit:!0,dirty:[...n].sort(),staged:[...s].sort()}}function Eh(e,{interrupted:t=null}={}){let r=e.slice(0,15).join(", ")+(e.length>15?`, \u2026 (${e.length} in total)`:""),n=t?` An interrupted migration of this commit left its own changes too (${t}) \u2014 those alone would not stop a re-run, but these paths hold changes it did not write.`:"";return`Not migrating: this pre-2.0 (1.x) Vesper workspace has uncommitted changes in paths the migration removes or rewrites (${r}).${n} Commit or stash them first (\`git add -A && git commit\`, or \`git stash -u\`), then re-run \`vespercli init\` \u2014 a clean start is what makes \`git restore\` a genuine undo of the migration.`}async function aE(e){let t=new Set,r=s=>Ki(s)||/^\.vesper\/index\.db/.test(s),n=await hl(e);for(let s of[...ph,...n?[n]:[]]){let o;try{o=await lt(_(e,s))}catch{continue}for(let i of[...o.files,...o.others]){let a=`${s}/${i}`;r(a)||t.add(a)}}try{for(let s of await Bi(e,{withFileTypes:!0}))(s.isFile()||s.isSymbolicLink())&&t.add(s.name)}catch{}return t}var bh="written.log",xh="no-hooks",ml="created.sha256",gl="remove-created.sh",cE=`#!/bin/sh
149
162
  # Written by vespercli (1.x migration rollback). Run from the workspace root.
150
163
  # Removes the files this migration created, ONLY while they still hold the bytes it wrote.
151
164
  # A file changed since is KEPT and listed below: review it and delete it yourself.
152
- list="$(dirname -- "$0")/${Mc}"
165
+ list="$(dirname -- "$0")/${ml}"
153
166
  kept=0
154
167
  tab="$(printf ' ')"
155
168
  while IFS="$tab" read -r want f; do
@@ -172,45 +185,46 @@ if [ "$kept" -gt 0 ]; then
172
185
  echo "$kept file(s) this migration created were changed since and were NOT removed - review them and delete them yourself." >&2
173
186
  fi
174
187
  exit 0
175
- `;async function Fc(e){let t="";try{t=await Se(_(e,Tf),"utf-8")}catch{return[]}let r=[];for(let n of t.split(`
176
- `))if(n)try{let s=JSON.parse(n);Array.isArray(s)&&typeof s[0]=="string"&&typeof s[1]=="string"&&r.push(s)}catch{}return r}async function Zk(e,t){let r=[];for(let[n,s]of await Fc(t)){if(r.push([n,s]),s!==Wn)continue;let o=null;try{o=await wi(_(e,n))}catch{o=null}if(!o?.isDirectory())continue;let i=null;try{i=await nt(_(e,n))}catch{i=null}for(let a of i?[...i.files,...i.others]:[])r.push([`${n}/${a}`,Wn])}return r}async function If(e){let t;try{t=await wi(e)}catch{return null}return t.isSymbolicLink()?`link:${await Es(e)}`:t.isFile()?Wk("sha256").update(await Se(e)).digest("hex"):null}async function Vc(e,t){let r=_(e,"rollback.json"),n;try{n=JSON.parse(await Se(r,"utf-8"))}catch{return}await dr(r,`${JSON.stringify({...n,...t},null,2)}
177
- `)}async function bi(e){return await G(["rev-parse","HEAD"],{cwd:e})||null}async function eS(e){let t=(await Ei(e)).filter(s=>s.migration);if(!t.length)return null;let r=t[t.length-1],n=t.filter(s=>s.chainRoot===r.chainRoot);return{root:n[0],latest:r,members:n,status:r.status,guidancePrinted:r.guidancePrinted}}async function jf(e){let t=await eS(e);return t&&(t.status==="started"||t.status==="finished"&&!t.guidancePrinted)?t:null}async function Rf(e){for(let t of e.members)await Vc(t.dir,{status:"abandoned",guidancePrinted:!0});return e.members.map(t=>t.dir)}async function Nf(e,t,{dirty:r,staged:n=[]}){let s=new Map;for(let c of t.members)for(let[l,d]of await Fc(c.dir))s.set(l,d);let o=new Set(t.root.trackedPaths),i=new Set(n),a=[];for(let c of r){if(i.has(c)){a.push(c);continue}let l=await If(_(e,c));l===null?o.has(c)||a.push(c):s.get(c)!==l&&a.push(c)}return a}async function Gc(e,t,{record:r,previousVersion:n=null,chain:s=null,preCreated:o=[]}={}){let i=await Cf(e),a=null,c=[];if(i){a=await bi(e);let d=await Af(e,{record:r}),p=a?await G(["-c","core.quotepath=off","ls-files","--",...d],{cwd:e}):null;c=p?p.split(`
178
- `).map(h=>h.trim()).filter(h=>h&&!ki(h)).sort():[]}let l={version:2,startedAt:new Date().toISOString(),head:a,trackedPaths:c,previousVersion:n||s?.root.previousVersion||null,before:[...await Xk(e)].sort(),chainRoot:s?s.root.chainRoot:yf(t.dir),preCreated:[...new Set(o)].filter(d=>typeof d=="string"&&d).sort(),status:"started",created:null,guidancePrinted:!1};return c.length&&await t.writeSidecar("tracked-paths.txt",`${c.join(`
188
+ `;async function yl(e){let t="";try{t=await Se(_(e,bh),"utf-8")}catch{return[]}let r=[];for(let n of t.split(`
189
+ `))if(n)try{let s=JSON.parse(n);Array.isArray(s)&&typeof s[0]=="string"&&typeof s[1]=="string"&&r.push(s)}catch{}return r}async function lE(e,t){let r=[];for(let[n,s]of await yl(t)){if(r.push([n,s]),s!==ss)continue;let o=null;try{o=await Ui(_(e,n))}catch{o=null}if(!o?.isDirectory())continue;let i=null;try{i=await lt(_(e,n))}catch{i=null}for(let a of i?[...i.files,...i.others]:[])r.push([`${n}/${a}`,ss])}return r}async function Ah(e){let t;try{t=await Ui(e)}catch{return null}return t.isSymbolicLink()?`link:${await Hs(e)}`:t.isFile()?eE("sha256").update(await Se(e)).digest("hex"):null}async function wl(e,t){let r=_(e,"rollback.json"),n;try{n=JSON.parse(await Se(r,"utf-8"))}catch{return}await _r(r,`${JSON.stringify({...n,...t},null,2)}
190
+ `)}async function Yi(e){return await D(["rev-parse","HEAD"],{cwd:e})||null}async function uE(e){let t=(await zi(e)).filter(s=>s.migration);if(!t.length)return null;let r=t[t.length-1],n=t.filter(s=>s.chainRoot===r.chainRoot);return{root:n[0],latest:r,members:n,status:r.status,guidancePrinted:r.guidancePrinted}}async function _h(e){let t=await uE(e);return t&&(t.status==="started"||t.status==="finished"&&!t.guidancePrinted)?t:null}async function Ch(e){for(let t of e.members)await wl(t.dir,{status:"abandoned",guidancePrinted:!0});return e.members.map(t=>t.dir)}async function $h(e,t,{dirty:r,staged:n=[]}){let s=new Map;for(let c of t.members)for(let[l,d]of await yl(c.dir))s.set(l,d);let o=new Set(t.root.trackedPaths),i=new Set(n),a=[];for(let c of r){if(i.has(c)){a.push(c);continue}let l=await Ah(_(e,c));l===null?o.has(c)||a.push(c):s.get(c)!==l&&a.push(c)}return a}async function vl(e,t,{record:r,previousVersion:n=null,chain:s=null,preCreated:o=[]}={}){let i=await kh(e),a=null,c=[];if(i){a=await Yi(e);let d=await vh(e,{record:r}),p=a?await D(["-c","core.quotepath=off","ls-files","--",...d],{cwd:e}):null;c=p?p.split(`
191
+ `).map(f=>f.trim()).filter(f=>f&&!Ki(f)).sort():[]}let l={version:2,startedAt:new Date().toISOString(),head:a,trackedPaths:c,previousVersion:n||s?.root.previousVersion||null,before:[...await aE(e)].sort(),chainRoot:s?s.root.chainRoot:uh(t.dir),preCreated:[...new Set(o)].filter(d=>typeof d=="string"&&d).sort(),status:"started",created:null,guidancePrinted:!1};return c.length&&await t.writeSidecar("tracked-paths.txt",`${c.join(`
179
192
  `)}
180
193
  `),await t.writeSidecar("rollback.json",`${JSON.stringify(l,null,2)}
181
- `),ha({root:e,log:_(t.dir,Tf),exclude:ki}),l}function Hc(){ha(null)}async function Uc(e,t){Hc();let r=await Ei(e),n=r.find(v=>v.dir===t);if(!n?.migration)return null;let s=r.filter(v=>v.migration&&v.chainRoot===n.chainRoot&&v.name<=n.name),[o]=s,i=await Lc(e),a=v=>!v.includes("/")||vf.some(S=>v.startsWith(`${S}/`))||i&&v.startsWith(`${i}/`),c=new Set(s.flatMap(v=>v.preCreated)),l=new Set(o.before.filter(v=>!c.has(v))),d=new Set(n.before.filter(v=>!c.has(v))),p=new Set,h=new Set,m=new Map;for(let v of s)for(let[S,A]of await Zk(e,v.dir))p.add(S),m.set(S,A),v!==n&&h.add(S);let f=[],g=[];for(let v of[...p].sort()){if(!a(v)||ki(v)||l.has(v)||d.has(v)&&!h.has(v))continue;let S=await If(_(e,v));if(S===null)continue;f.push(v);let A=m.get(v);g.push([A===Wn?S:A,v])}await C(_(n.dir,"created.txt"),f.length?`${f.join(`
194
+ `),Fa({root:e,log:_(t.dir,bh),exclude:Ki}),l}function kl(){Fa(null)}async function Sl(e,t){kl();let r=await zi(e),n=r.find(v=>v.dir===t);if(!n?.migration)return null;let s=r.filter(v=>v.migration&&v.chainRoot===n.chainRoot&&v.name<=n.name),[o]=s,i=await hl(e),a=v=>!v.includes("/")||ph.some(S=>v.startsWith(`${S}/`))||i&&v.startsWith(`${i}/`),c=new Set(s.flatMap(v=>v.preCreated)),l=new Set(o.before.filter(v=>!c.has(v))),d=new Set(n.before.filter(v=>!c.has(v))),p=new Set,f=new Set,m=new Map;for(let v of s)for(let[S,C]of await lE(e,v.dir))p.add(S),m.set(S,C),v!==n&&f.add(S);let h=[],g=[];for(let v of[...p].sort()){if(!a(v)||Ki(v)||l.has(v)||d.has(v)&&!f.has(v))continue;let S=await Ah(_(e,v));if(S===null)continue;h.push(v);let C=m.get(v);g.push([C===ss?S:C,v])}await A(_(n.dir,"created.txt"),h.length?`${h.join(`
182
195
  `)}
183
- `:"","utf-8"),await C(_(n.dir,Mc),g.map(([v,S])=>`${v} ${S}
184
- `).join(""),"utf-8"),await C(_(n.dir,Dc),Qk,"utf-8");let y=new Set;for(let v of s){if(v!==o){let S=null;try{S=await nt(_(v.dir,"rewritten"))}catch{S=null}for(let A of S?S.files:[])!l.has(A)||y.has(A)||await w(_(o.dir,"rewritten",A))||await kf(o.dir,"rewritten",A,_(v.dir,"rewritten",A))}for(let[S]of await Fc(v.dir))y.add(S)}await T(_(n.dir,Pf),{recursive:!0});let k=new Date().toISOString();for(let v of s)await Vc(v.dir,{status:"finished",finishedAt:k,...v.dir===n.dir?{created:f}:{}});return f}async function Lf(e,t){for(let r of await Ei(e))r.migration&&t.includes(r.dir)&&await Vc(r.dir,{guidancePrinted:!0})}async function mf(e,{homeDir:t=xs()}={}){let r=new Set;for(let n of[...e?.injectedPaths||[],...e?.readAccessPaths||[]]){let s=/^(.*?)\/assets(?:\/|$)/.exec(String(n).split("\\").join("/"));!s||s[1].includes("${")||r.add(s[1].startsWith("~/")?_(t,s[1].slice(2)):s[1])}for(let n of r)try{let s=JSON.parse(await Se(_(n,"package.json"),"utf-8"));if(["@mthanh/vespercli","vespercli"].includes(s?.name)&&/^1\.\d+\.\d+/.test(s?.version||""))return s.version}catch{}return null}async function Mf(e,t,r,{homeDir:n=xs()}={}){if(t?.version)return t.version;let s=await mf(t,{homeDir:n});if(s)return s;let o=[];try{let{readVSCodeSettings:a}=await Promise.resolve().then(()=>(H(),pa)),c=await a(e);for(let[l,d]of Object.entries(c||{}))!/^chat\..*Locations$/.test(l)||!d||o.push(...(Array.isArray(d)?d:Object.keys(d)).filter(p=>typeof p=="string"))}catch{o=[]}let i=await mf({injectedPaths:o},{homeDir:n});return i||t?.config==="v1"&&r||null}async function Df(e,{runDirs:t=[],homeDir:r=xs()}={}){let n=await Ei(e),s=new Set(t),o=n.filter(E=>E.migration&&s.has(E.dir)),i=[];if(o.length){let E=o[o.length-1];i=n.filter(b=>b.migration&&b.chainRoot===E.chainRoot&&b.name<=E.name);for(let b of i)s.add(b.dir)}let a=n.filter(E=>s.has(E.dir)&&(E.project||E.home||E.rewritten||E.migration||E.outside.length));if(!a.length)return[];let c=n.filter(E=>!s.has(E.dir)),l=c.filter(E=>E.migration&&E.status==="abandoned"),d=E=>`"${E}"`,p=[];p.push(`Migration backups (${a.length}) \u2014 in ${_(e,xr)}, gitignored; keep them until you are happy with 2.0${a.length>1?" (an interrupted run was completed: ALL its folders are listed, oldest first)":""}:`);for(let E of a)p.push(` ${E.dir}${E.home?" (holds home-directory files too)":""}${E.outside.length?" (holds files from outside the workspace too)":""}`);if(c.length&&p.push(` (${c.length} other folder(s) there belong to an earlier migration or cleanup \u2014 the commands below never use them)`),l.length){p.push(" Abandoned interrupted migration(s) \u2014 never resumed, kept in case they hold a file you need; remove them when you no longer do (rm -rf):");for(let E of l)p.push(` ${E.dir}`)}let h=E=>E.outside.map(b=>`cp -R -p ${d(_(E.dir,b.backup))} ${d(b.original)}`),m=[];for(let E of a)E.project&&m.push(`cp -R ${d(_(E.dir,"project"))}/. ${d(e)}/`),E.home&&m.push(`cp -R ${d(_(E.dir,"home"))}/. ${d(r)}/`),m.push(...h(E));if(m.length){p.push("Recover the files the migration REMOVED (copies them back; this alone is not a rollback):");for(let E of m)p.push(` ${E}`)}if(!i.length)return p;let f=i[0],g=i[i.length-1],y=g.created,k=i.map(E=>E.previousVersion).find(Boolean),v=f.head?await bi(e):null;f.head&&v&&v!==f.head&&p.push(`Note: HEAD is now ${v.slice(0,12)}, not ${f.head.slice(0,12)} (the commit this migration started from). The rollback below still restores the migrated paths to ${f.head.slice(0,12)}'s committed layout \u2014 changes committed since to those paths are undone in the working tree (they stay in git history).`),p.push(`Roll back THIS migration to 1.x completely (back to its starting commit ${f.head?f.head.slice(0,12):"(no git)"}; run from the workspace root, in this order):`);let S=1;if(f.head){let E=f.head.slice(0,12);p.push(` ${S++}. [ "$(git rev-parse HEAD)" = "${f.head}" ] || echo "Warning: HEAD is no longer ${E}, the commit this migration started from - the restore below returns the migrated paths to ${E}'s layout; review git status/diff afterwards." >&2 (a check only: it changes nothing)`)}if(y.length&&g.createdChecked?p.push(` ${S++}. sh ${d(_(g.dir,Dc))} (removes the ${y.length} file(s) this migration created, incl. its git hooks: ${y.slice(0,4).join(", ")}${y.length>4?", \u2026":""} \u2014 only while each still holds the bytes the migration wrote; a file changed since is kept and named)`):y.length&&p.push(` ${S++}. while IFS= read -r f; do rm -f -- "$f"; done < ${d(_(g.dir,"created.txt"))} (the ${y.length} file(s) this migration created, incl. its git hooks: ${y.slice(0,4).join(", ")}${y.length>4?", \u2026":""})`),f.rewritten&&p.push(` ${S++}. cp -R ${d(_(f.dir,"rewritten"))}/. ${d(e)}/ (every whole file init rewrote, incl. the gitignored .vesperrc / .mcp.json and the git hooks, as they were when this migration started)`),f.head&&f.trackedPaths.length){let E=_(f.dir,"tracked-paths.txt");p.push(` ${S++}. git -c core.hooksPath=${d(_(g.dir,Pf))} restore --source=${f.head} --staged --worktree --pathspec-from-file=${d(E)} (the committed layout; hooks disabled for this one command; the migration refused to start on uncommitted changes, so this is exact)`)}let A=[];for(let E of i)E.project&&A.push(`cp -R ${d(_(E.dir,"project"))}/. ${d(e)}/`),E.home&&A.push(`cp -R ${d(_(E.dir,"home"))}/. ${d(r)}/`),A.push(...h(E));A.length&&p.push(` ${S++}. ${A.join(" && ")} (the removed files)`);let N=k&&/^1\.9\./.test(k)?`; ${k} was never published to npm \u2014 install it from the repository's ${k} commit, or pin 1.8.0`:"";return p.push(` ${S++}. npm install -g @mthanh/vespercli@${k||"<your previous 1.x version>"} (LAST: pin the previous CLI \u2014 any 2.x CLI migrates again${N})`),p}async function Ff(e,t,{legacy:r,recordHost:n,frameworkVersion:s,homeDir:o=xs(),now:i=new Date,log:a,backup:c}={}){let l=await ni(e),d=a||{info(){},success(){},warn(){}},p=c||Nc(e,{now:i,homeDir:o}),h={record:l,backupDir:null,relocated:[],recorded:[],removed:[],moved:[],kept:[],homeLookalikes:[],settings:null},m=(b,F,Q={})=>h.kept.push({rel:b,reason:F,...Q}),f=async(b,F)=>{try{return await F()}catch(Q){m(b,"error",{detail:String(Q?.message||Q)});return}},g=await Lc(e),y=g?["pre-commit","post-checkout"].map(b=>`${g}/${b}`):[];for(let b of[...wf,...await _f(e),...y])await f(b,()=>p.snapshot(b));let k=l;if(l.config==="v2"&&l.recordedHost){let b=null;try{b=(await W(e)).host}catch{b=null}if(l.recordedHost!==b){let F=l.recordedHost;d.info(`This worktree's 2.0 record describes another branch (${F}); migrating this 1.x checkout from its files.`),k=Object.freeze({...l,catalogManifest:[],injectedPaths:[],readAccessPaths:[],mcpServers:[],vendored:void 0,hosts:{claude:!1,copilot:!1}}),await f(".vesperrc",async()=>{let Q=await x(e);Q.manifest=q(Q).filter(Fe=>Fe.host!==F||Re.has(Fe.category)),delete Q.host,await I(e,Q)})}}let v=await xf(e,k);await tS(e,t,{backup:p,result:h,safely:f,keep:m,catalog:v});let S=[];for(let b of v.record)await f(b.rel,async()=>(await p.project(b.rel),!0))&&(S.push(b.entry),h.recorded.push(b.rel));for(let b of v.keep)m(b.rel,b.reason,b.files?{files:b.files}:{});let A=".claude/vesper/orchestrator.md";await w(_(e,A))&&await f(A,async()=>{let b=await Se(_(e,A));if(!id(b)){m(A,"edited-playbook");return}await p.project(A),await ie(_(e,A),{path:A,category:"playbook",hash:st(b)})==="removed"&&h.removed.push(A)});try{await gf(_(e,".claude","vesper"))}catch{}t==="copilot"&&(h.settings=await f(".vscode/settings.json",()=>Gr(e,{trackedPaths:k.injectedPaths,trackedReadAccess:k.readAccessPaths})));let N=await si({homeDir:o}).catch(()=>[]);if(h.homeLookalikes=N.filter(b=>b.tier===3),(await x(e)).schemaVersion===ve){await qr(e,{frameworkVersion:s}),S.length&&await B(e,S);let b=await x(e);!b.host&&n&&(b.host=n,await I(e,b))}else await qr(e,{frameworkVersion:s,legacyEntries:S,host:n});return h.kept.length&&await f("kept.json",()=>Wc(p,h.kept)),h.backup=p,h.backupDir=p.items.length?p.dir:null,nS(h,d),h}async function Wc(e,t){e.keptRows??=[];for(let r of t)e.keptRows.push({rel:r.rel,reason:r.reason,...r.files?{files:r.files}:{},...r.detail?{detail:r.detail}:{}});return e.writeSidecar("kept.json",`${JSON.stringify(e.keptRows,null,2)}
185
- `)}async function tS(e,t,{backup:r,result:n,safely:s,keep:o,catalog:i}){let a=null,c=new Set;if(t==="claude"){a=await yt();let d=new Set((i?.record||[]).map(p=>p.rel));for(let p of a.agents){let h=`.claude/agents/${p}.md`;!d.has(h)&&await w(_(e,h))&&c.add(p)}}let l=[{key:"orchestration",claudeDest:".claude/rules/vesper-orchestration.md",copilotDest:Pe("vesper-orchestration"),tpl:"orchestration.md.tpl",sources:[{rel:".claude/vesper/orchestration.md",vesper:()=>!0,move:!0},{rel:".github/instructions/orchestration.instructions.md",vesper:Yk,move:!0,unmarked:"report"}]},{key:"context",claudeDest:".claude/rules/vesper-context.md",copilotDest:Pe("vesper-context"),tpl:"context.md.tpl",sources:[{rel:".claude/vesper/context.md",vesper:()=>!0,move:!0},{rel:".github/copilot-instructions.md",vesper:qk,move:!1,unmarked:"claude-only"}]}];for(let d of l){let p=t==="claude"?d.claudeDest:d.copilotDest,h=null;for(let m of d.sources){let f=_(e,m.rel),g=(await bf(f))?.toString("utf-8");if(g===void 0)continue;let y=m.vesper(g);if(!y&&m.unmarked==="report"){o(m.rel,"unmarked-knowledge");continue}if(!y&&m.unmarked==="claude-only"&&t!=="claude"){o(m.rel,"github-own");continue}if(h||await w(_(e,p))){let k="duplicate-knowledge";m.move||(k=y?h?"github-brain-kept":"github-brain-dest":"github-own"),o(m.rel,k);continue}await s(m.rel,async()=>{let{body:k}=ot(g),v=k.replace(/^\n+/,"");if(t==="claude"&&d.key==="orchestration"){let E=Nu(v);n.rosterRetired=E.removed;let b=Co(E.text,a,{skip:c});v=b.text,n.rosterQualified=b.qualified}let S=t==="claude"?`${await hf(d.tpl)}${v}`:wc(ot(g).frontmatter===null?`${await hf(d.tpl)}${k}`:g,`Vesper ${d.key}`),A=_(e,p);if(await T(jc(A),{recursive:!0}),await C(A,S,"utf-8"),await Se(A,"utf-8")!==S)throw new Error(`could not verify ${p}`);if(h=m.rel,!m.move||!y){n.relocated.push({from:m.rel,to:p,copied:!0}),o(m.rel,m.move?"unmarked-knowledge":"github-brain");return}n.relocated.push({from:m.rel,to:p}),await r.project(m.rel),await ie(f,{path:m.rel,category:"relocated-original"},{expected:[Buffer.from(g,"utf-8")]})==="removed"&&n.moved.push({from:m.rel,to:p})})}}for(let d of[".github/instructions",".github"])try{await gf(_(e,d))}catch{}if(t==="copilot"){let d=_(e,".claude","vesper","context"),p=[];try{p=(await nt(d)).files}catch{p=[]}for(let h of p){let m=_(e,".vesper","context",h);await w(m)||await s(`.claude/vesper/context/${h}`,async()=>{await T(jc(m),{recursive:!0}),await C(m,await Se(_(d,h))),n.relocated.push({from:`.claude/vesper/context/${h}`,to:`.vesper/context/${h}`,copied:!0})})}}}function rS(e,{max:t=5}={}){let r=new Map;for(let s of e)r.has(s.reason)||r.set(s.reason,[]),r.get(s.reason).push(s.rel);let n=[];for(let[s,o]of r){let i=o.slice(0,t).join(", ")+(o.length>t?`, \u2026 +${o.length-t} more`:"");n.push(`Kept ${o.length} \u2014 ${Jk[s]||s}: ${i}`)}return n}function nS(e,t){for(let{from:r,to:n,copied:s}of e.relocated)s&&t.info(`Copied ${r} \u2192 ${n}`);for(let{from:r,to:n}of e.moved)t.info(`Moved your ${r} \u2192 ${n} (your project knowledge; the original is backed up)`);if(e.relocated.some(r=>/vesper-orchestration\.md$/.test(r.to))){let r=e.rosterQualified?.length||0;for(let n of e.rosterRetired||[])t.info(`Removed retired roster row: ${n.role} (${n.agent}) \u2014 replaced by ${n.replacement}`);r?t.info(`Team roster relocated \u2014 ${r} specialist name(s) namespaced to \`vesper:<name>\` for the plugin.`):e.rosterQualified===void 0&&t.info("Team roster relocated \u2014 run `/revalidate-team` once: 2.0 delegates to the plugin's specialists by `vesper:<name>` (doctor reminds you until then).")}e.recorded.length&&t.info(`Retiring ${e.recorded.length} 1.x catalog item(s) byte-identical to a released 1.x build \u2014 the vesper plugin serves them now (backed up): ${e.recorded.slice(0,8).join(", ")}${e.recorded.length>8?", \u2026":""}`);for(let r of e.removed)t.info(`Removed ${r} (byte-identical to a released 1.x Vesper file; backed up)`);for(let r of e.settings?.removed||[])t.info(`Removed the 1.x settings location ${r} (2.0 injects each assets/copilot/<type> folder whole)`);for(let r of rS(e.kept))t.warn(r);if(e.homeLookalikes.length){let r=e.homeLookalikes.slice(0,5).map(n=>`~/${n.rel}`).join(", ")+(e.homeLookalikes.length>5?", \u2026":"");t.info(`FYI: ${e.homeLookalikes.length} Vesper-looking item(s) in your home directory (${r}). Vesper 1.x never wrote these locations, so they are yours \u2014 left untouched, and not mentioned again.`)}}U();import{join as Jc}from"node:path";U();ct();dt();import{rename as sS}from"node:fs/promises";import{dirname as oS,join as Vf}from"node:path";async function xi(e,t,r){let n=Vf(e,t),s=Vf(e,r);if(!await w(n))return{ok:!1,reason:"missing"};if(await w(s))return{ok:!1,reason:"exists"};await T(oS(s),{recursive:!0});let o={...process.env,...xt};return await G(["rev-parse","--is-inside-work-tree"],{cwd:e,env:o})==="true"&&(await Et(["--literal-pathspecs","ls-files","--error-unmatch","--",t],{cwd:e,env:o})).ok&&await G(["--literal-pathspecs","status","--porcelain","--",t],{cwd:e,env:o})===""&&(await Et(["--literal-pathspecs","mv","--",t,r],{cwd:e,env:{...process.env,...An}})).ok?{ok:!0,method:"git"}:(await sS(n,s),{ok:!0,method:"rename"})}U();import{readdir as iS,readFile as aS}from"node:fs/promises";import{join as _i}from"node:path";var Bc=".vesper/.tracking/runs",As=Object.freeze(["started","completed","note","delegated","returned"]),Gf=Object.freeze(["DONE","NEED_HELP","BLOCKED"]),cS="adhoc",Ai=5,fn=Object.freeze({OK:0,INVALID:2}),lS=Object.freeze(["ts","event","pipeline","step","agent","goal","author","status","note"]),uS=Object.freeze({started:["goal"],completed:["status"],note:[],delegated:["agent"],returned:["agent","status"]});function Hf(e){return String(e??"").toLowerCase().replace(/[^a-z0-9-]+/g,"-").replace(/-{2,}/g,"-").replace(/^-|-$/g,"")||cS}function zc(e=new Date){return e.toISOString().slice(0,10).replace(/-/g,"")}function dS(e,t=new Date){return`${zc(t)}-${Hf(e)}.jsonl`}function _s(e){return typeof e=="string"&&e.trim()!==""}function Uf(e={},{now:t=new Date}={}){let r=[],n=typeof e.event=="string"?e.event.trim():"";As.includes(n)||r.push(`event must be one of ${As.join("|")} (received "${n}")`),_s(e.pipeline)||r.push("--pipeline is required");for(let o of uS[n]||[])_s(e[o])||r.push(`--${o} is required for \`${n}\``);if(e.status!==void 0&&e.status!==null&&!Gf.includes(String(e.status))&&r.push(`--status must be one of ${Gf.join("|")} (received "${e.status}")`),r.length)return{ok:!1,errors:r};let s={ts:t.toISOString(),event:n};for(let o of lS.slice(2))s[o]=_s(e[o])?e[o].trim():null;return _s(e.session)&&(s.session=e.session.trim()),{ok:!0,row:s}}async function Wf(e,t,{slug:r,now:n=new Date}={}){let s=_i(e,Bc);await T(s,{recursive:!0});let o=dS(r,n),i=_i(s,o),a=`${JSON.stringify(t)}
186
- `;return await C(i,a,{encoding:"utf-8",flag:"a"}),{rel:`${Bc}/${o}`,abs:i,line:a}}function Kc(e){let t=/^\d{8}-(.+)\.jsonl$/.exec(e);return t?t[1]:null}async function Kf(e,{slug:t}={}){let r=_i(e,Bc);if(!await w(r))return{rows:[],files:[],malformed:0};let n=t?Hf(t):null,s=(await iS(r)).filter(c=>c.endsWith(".jsonl")&&Kc(c)!==null&&(!n||Kc(c)===n)).sort(),o=[],i=0,a=0;for(let c of s){let l=await aS(_i(r,c),"utf-8");for(let d of l.split(`
187
- `))if(d.trim()!=="")try{let p=JSON.parse(d);if(!p||typeof p!="object"||Array.isArray(p)){i+=1;continue}o.push({...p,slug:Kc(c),__order:a++})}catch{i+=1}}o.sort((c,l)=>{let d=typeof c.ts=="string"?c.ts:"",p=typeof l.ts=="string"?l.ts:"";return d<p?-1:d>p?1:c.__order-l.__order});for(let c of o)delete c.__order;return{rows:o,files:s,malformed:i}}function Bf(e,t=Ai){let r=Number.isFinite(t)?Math.max(0,Math.floor(t)):Ai;return r===0?[]:e.slice(-r)}function zf(e){let t=[String(e.ts??"-"),String(e.event??"-").padEnd(9),String(e.pipeline??"-")];e.slug&&t.push(`[${e.slug}]`);for(let r of["step","agent","status","author","session"])e[r]!==null&&e[r]!==void 0&&e[r]!==""&&t.push(`${r}=${e[r]}`);return e.goal&&t.push(`goal="${e.goal}"`),e.note&&t.push(`\u2014 ${e.note}`),t.join(" ")}function Jf(e){let t;try{t=JSON.parse(String(e??""))}catch{return null}if(!t||typeof t!="object"||Array.isArray(t))return null;let r=n=>_s(t[n])?t[n].trim():null;return{agent:r("agent_type"),agentId:r("agent_id"),session:r("session_id")}}var Ci=".vesper/history.md",Yf=".vesper/history-archive";function qf(e=new Date,t=0){return`history-${zc(e)}${t>0?`-${t}`:""}.md`}async function Xf(e,{now:t=new Date}={}){if(!await w(Jc(e,Ci)))return{archived:!1};let r=Jc(e,Yf);await T(r,{recursive:!0});let n=0,s=qf(t,n);for(;await w(Jc(r,s));)n+=1,s=qf(t,n);let o=`${Yf}/${s}`,i=await xi(e,Ci,o);if(!i.ok)throw new Error(`Could not archive ${Ci}: ${i.reason}`);return{archived:!0,from:Ci,to:o,method:i.method}}Rt();hr();U();be();te();H();import{resolve as fS}from"node:path";import le from"picocolors";Rt();Zr();ct();dt();hr();var $i=3e3;async function pS(e,{timeoutMs:t=$i,env:r}={}){let n=await Et(["ls-remote","--",e,"HEAD"],{timeout:t,env:Cn(ar(r??process.env)),detached:!0});if(!n.ok)return null;let s=n.stdout.split(`
188
- `).map(o=>o.trim()).find(o=>/^[0-9a-f]{40}\s+HEAD$/.test(o));return s?s.slice(0,40):null}async function Oi({assetsDir:e,timeoutMs:t=$i,env:r}={}){let n=[];for(let{pack:s,skill:o,record:i}of await du(e)){let a=typeof i?.upstream=="string"?i.upstream:null,c=typeof i?.sha=="string"?i.sha:null;if(!a||!c){n.push({skill:o,pack:s,upstream:a,pinned:c,remote:null,stale:null,status:"no-record"});continue}let l=await pS(a,{timeoutMs:t,env:r});if(!l){n.push({skill:o,pack:s,upstream:a,pinned:c,remote:null,stale:null,status:"unreachable"});continue}let d=l!==c;n.push({skill:o,pack:s,upstream:a,pinned:c,remote:l,stale:d,status:d?"stale":"current"})}return n}function Qf(e){return`\`${e.skill}\` has a newer upstream (${e.upstream} is at ${e.remote.slice(0,12)}, the package ships ${e.pinned.slice(0,12)}); the next Vesper release picks it up.`}Te();var Zf=["list","enable","disable","sync","upstream"];function hS(e,{log:t=console.log}={}){if(t(),t(le.bold("Third-party pack skills \u2014 upstream check")),t(le.dim("Pinned = the commit the shipped snapshot was taken at (UPSTREAM.json); remote = upstream HEAD now.")),t(),!e.length){t(le.dim(" (this package ships no third-party skills)")),t();return}let r=Math.max(...e.map(s=>s.skill.length));for(let s of e){let o=s.status==="stale"?le.yellow("newer upstream"):s.status==="current"?le.green("current"):s.status==="unreachable"?le.dim("unreachable"):le.red("no record"),i=s.pinned?s.pinned.slice(0,12):"\u2014",a=s.remote?s.remote.slice(0,12):"\u2014";t(` ${s.skill.padEnd(r)} ${s.pack.padEnd(12)} pinned ${i} remote ${a} ${o}`)}t();let n=e.filter(s=>s.status==="stale");n.length&&t(le.dim(`A newer upstream reaches projects with the next Vesper release (maintainers: npm run vendor:sync ${n.map(s=>s.skill).join(" ")}).`)),t()}function Cr(e,{log:t=u}={}){if(!e.rosterFound){t.info(`Packs: no Team Roster at ${e.rosterPath} yet \u2014 nothing to enable (run \`vespercli packs sync\` after the roster is written).`);return}e.enabled.length&&t.success(`Packs enabled for ${e.host}: ${e.enabled.map(Ne).join(", ")} (named by the Team Roster).`),e.already.length&&t.info(`Packs already enabled: ${e.already.map(Ne).join(", ")}.`),!e.enabled.length&&!e.already.length&&t.info("Packs: the Team Roster names core assets only \u2014 no pack needed."),e.unused.length&&t.info(`Packs enabled but unused by the Team Roster (kept; \`vespercli packs disable <pack>\` removes one): ${e.unused.join(", ")}.`),e.unknownAgents.length&&t.dim(` roster agents not in the catalog (project agents or typos): ${e.unknownAgents.join(", ")}`),e.unknownSkills.length&&t.dim(` roster skills not in the catalog (project skills or typos): ${e.unknownSkills.join(", ")}`)}async function mS(e,t){let r=await W(e);(await $e(e,{checkout:r})).unmigrated&&(u.error(Ze),process.exit(1));let n=r.host?[r.host]:await he(e);!t.target&&n.length>1&&(u.error(Xe),process.exit(1));let s=t.target||r.host||null;return{host:s,provisioned:!!r.host&&r.host===s}}function eh({host:e,provisioned:t},r){t||(e?u.error(`\`vespercli packs ${r}\` for ${e} needs a workspace provisioned for ${e} \u2014 nothing was written. Run \`vespercli init --host ${e}\` first.`):u.error(`\`vespercli packs ${r}\` needs a workspace provisioned for a host \u2014 nothing was written. Run \`vespercli init\` first.`),process.exit(1))}async function gS(e,{host:t}){let r=Qe(),{enabled:n,unknown:s}=t?await Sr(e,t):{enabled:[],unknown:[]},o=t?await Jt(e,t):null,i=o!==null?await Yt(o):null;if(console.log(),console.log(le.bold("Vesper packs")),console.log(le.dim(t?`Host: ${t}${o===null?` (no Team Roster at ${nn[t]})`:""}`:"Host: not provisioned (catalog only)")),console.log(le.dim("Core (vesper) is always enabled; a pack is enabled when the Team Roster names one of its assets (`vespercli packs sync`).")),console.log(),!r.length){console.log(le.dim(" (this package ships no packs)")),console.log();return}for(let a of r){let{agents:c,skills:l}=wd(a),d=n.includes(a)?le.green("enabled"):le.dim("disabled"),p=i?.needed[a],h=p?` \u2014 roster needs it: ${[...p.agents,...p.skills].join(", ")}`:i?le.dim(" \u2014 not named by the roster"):"";console.log(` ${le.bold(a)} (${Ne(a)}) ${d}${h}`),console.log(le.dim(` agents: ${c.join(", ")||"\u2014"}`)),console.log(le.dim(` skills: ${l.join(", ")||"\u2014"}`)),yr(a)&&console.log(le.dim(" opt-in: enabling writes an always-on pointer rule that applies these styles (`vespercli packs enable styles`)"))}if(s.length&&(console.log(),u.warn(`Enabled pack keys this package does not ship: ${s.join(", ")} (an older/newer Vesper wrote them; \`vespercli packs disable <pack>\` cannot remove an unknown pack \u2014 edit the settings by hand).`)),i){let a=i.packs.filter(c=>!n.includes(c));console.log(),a.length?u.warn(`The Team Roster needs ${a.join(", ")} but they are not enabled \u2014 run \`vespercli packs sync\`.`):u.success("Every pack the Team Roster needs is enabled.")}console.log()}async function th(e="list",t,r={}){try{let n=fS(r.path||process.cwd());await w(n)||(u.error(`Directory not found: ${u.formatPath(n)}`),process.exit(1));let s=e||"list";Zf.includes(s)||(u.error(`Unknown packs subcommand: ${s}. Subcommands: ${Zf.join(", ")}`),process.exit(1));let o=await mS(n,r);if(s==="list")return await gS(n,o);if(s==="upstream"){hS(await Oi());return}if(s==="sync"){eh(o,"sync");let c=await qt(n,o.host);Cr(c);return}if(t||(u.error(`\`vespercli packs ${s}\` needs a pack name. Packs: ${Qe().join(", ")||"none"}`),process.exit(1)),Qe().includes(t)||(u.error(`Unknown pack "${t}". Packs: ${Qe().join(", ")||"none"}`),process.exit(1)),eh(o,s),s==="enable"){let{enabled:c,rule:l}=await Er(n,o.host,t);c?u.success(`Enabled the ${t} pack (${Ne(t)}) for ${o.host}.${o.host==="copilot"?" Reload VS Code to apply.":""}`):u.info(`The ${t} pack is already enabled for ${o.host}.`),(l?.status==="created"||l?.status==="updated")&&u.info(` always-on pointer rule written: ${l.path}`),l?.status==="kept-edited"&&u.warn(Ia(l.path));return}let{disabled:i,rule:a}=await bd(n,o.host,t);if(a?.status==="removed"&&u.info(` always-on pointer rule removed: ${a.path}`),a?.status==="kept"&&u.warn(Ia(a.path)),i){u.success(`Disabled the ${t} pack (${Ne(t)}) for ${o.host}.`);let c=await Jt(n,o.host);c!==null&&(await Yt(c)).packs.includes(t)&&u.warn(`The Team Roster still names assets of the ${t} pack \u2014 \`vespercli doctor\` will report it; \`vespercli packs sync\` re-enables it.`)}else u.info(`The ${t} pack was not enabled for ${o.host}.`)}catch(n){u.error(`Packs failed: ${n.message}`),process.exit(1)}}Te();var Yc=["copilot","claude"];function _S(e,t){return Aa(e)}async function AS(e,t,{settingsEntries:r,hooksDir:n=null,hookNames:s,version:o}={}){await qr(e,{frameworkVersion:o}),await _u(e,t);let i=await _a(e,t,{settingsEntries:r,hooksDir:n,hookNames:s});await B(e,_S(i,t)),await $u(e)}function nh(e){return e==="claude"?"Claude Code + OpenCode":"GitHub Copilot"}async function sh(e,t,{thirdPartyBackup:r=null}={}){let n=await ef(e,{backup:r||void 0}),{info:s,warn:o}=tf(n);for(let i of s)u.info(i);if(o&&u.warn(o),n.stylesConsent)try{await Er(e,t,lu)}catch(i){u.warn(`Could not enable the styles pack (${i?.message??i}); run \`vespercli packs enable styles\` by hand.`)}}async function CS(e,t,{legacyHint:r,checkout:n}={}){let s=await he(t),o=n?n.host:await zr(t),i=o?[o]:s,a=()=>{u.error("Vesper 2.0 provisions exactly one host per workspace \u2014 pass a single `--host claude` or `--host copilot` (not `all` or a comma list)."),process.exit(1)},c=e.host;if(!c&&e.target&&(u.warn("`--target` is deprecated on `init`; use `--host` instead."),c=e.target),c){let f=String(c).toLowerCase();f==="all"&&a();let g=[...new Set(f.split(",").map(y=>y.trim()).filter(Boolean))];for(let y of g)Yc.includes(y)||(u.error(`Unknown host: ${y}. Valid hosts: copilot, claude`),process.exit(1));return g.length>1&&a(),{selected:g,installed:i}}let l=await Tt(t),d=l&&Yc.includes(l.to)?l.to:null,p=r?.needsMigration?Yc.filter(f=>r.hosts?.[f]):[],h=d??(p.length>1?null:o??p[0]??null);if(!process.stdin.isTTY){let f=s.length===1?s[0]:null;if(h&&(p.length===0||(o??f)===h))return{selected:[h],installed:i};u.error(p.length?`Non-interactive run on a pre-2.0 Vesper workspace (${p.join(" + ")}) without --host. Vesper 2.0 provisions exactly one host \u2014 re-run with --host claude or --host copilot to migrate.`:"Non-interactive run without --host, and this checkout carries no Vesper provisioning \u2014 specify the single platform, e.g. --host copilot or --host claude."),process.exit(1)}return{selected:[await xS({message:i.length?"Host for this workspace (Vesper provisions exactly one):":"Which AI host is this workspace for?",choices:[{name:"GitHub Copilot (VS Code)",value:"copilot"},{name:"Claude Code + OpenCode (Claude Code CLI / VS Code extension / JetBrains / desktop; OpenCode reads the same setup)",value:"claude"}],...h?{default:h}:{}})],installed:i}}function $S(e){if(!e)return;console.log();let t=e.level==="warn"?u.warn:u.success;for(let r of e.lines)t(r);console.log()}async function OS(e,t,{backup:r,workspaceRoot:n}={}){let s=await zo({staleDir:void 0,dryRun:!0,workspaceRoot:n});if(s.reason==="absent"||s.reason==="not-ours"||!s.proven?.length)return null;let o=t;if(t||(o=await tr({message:`Clean the pre-1.9 MACHINE-WIDE Vesper Claude catalog at ${s.path}? ${s.proven.length} file(s) there are byte-identical to a released Vesper build and are removed (backed up first); ${s.kept.length?`${s.kept.length} other file(s) (your edits or your own files) are kept. `:""}Every other pre-1.9 Vesper project on this machine loses its specialists until you run \`vespercli init\` in it.`,default:!0})),!o)return u.info("Left the stale machine-wide Vesper Claude catalog in place (`vespercli doctor` names it)."),null;let i=await zo({backup:r,workspaceRoot:n});return $S(Xd(i)),i}async function TS(e,t={},r=!1){let n="";console.log(),u.header("Installing Vesper for Claude Code"),console.log();let{pluginDir:s,counts:o,pruned:i,keptEdited:a=[]}=await Ko({workspaceRoot:e,namePrefix:n,version:t.version});u.success(`Committed fallback surface installed: ${s}`),u.info(` main-thread agent: ${o.agents} (vesper-orchestrator), maintenance skills: ${o.skills}`),u.info(" full specialist catalog served via the vesper marketplace plugin (see .claude/settings.json)"),i.length&&u.info(` pruned ${i.length} legacy project-committed asset(s): ${i.join(", ")}`),a.length&&u.warn(`Left in place \u2014 no longer shipped, but they hold your edits, so Vesper could not prove them its own and no longer tracks them: ${a.map(h=>`.claude/${h}`).join(", ")}. Delete them yourself if you do not need them.`);let c=await Jo(e);u.success("Project files ready:"),u.info(` .claude/rules/vesper-orchestrator.md (${c.orchestrator})`),u.info(` .claude/rules/vesper-orchestration.md (${c.orchestration})`),u.info(` .claude/rules/vesper-context.md (${c.context})`),u.info(` .vesper/gates.json (${c.gates})`),u.info(` CLAUDE.md pointer (${c.claudeMd})`);let l=await Zt(e,!0),d=await np(e);u.success(`MCP servers configured: .mcp.json (${l.servers.join(", ")})`);let p=d.opencode||{};u.success("OpenCode overlay ready (the same setup, read by OpenCode):"),u.info(` opencode.json (${p.status||"unchanged"}${p.status==="skipped-malformed"?" \u2014 the file does not parse as JSON; fix it and re-run":""})`),u.info(` .opencode/agents/vesper-orchestrator.md (${c.opencodeAgent})`),u.info(` .opencode/plugins/vesper.js (${c.opencodePlugin})`),c.opencodeKept?.length&&u.warn(`Left in place \u2014 they differ from what Vesper writes (your edits, or an older build's copy), so Vesper could not prove them its own and no longer tracks them: ${c.opencodeKept.join(", ")}. Delete them to get this version's copy on the next init.`),Cr(await qt(e,"claude")),await sh(e,"claude",t),await lp(e,{pluginPath:br(e),namePrefix:n,mcpConfigPath:De(e),settingsPath:Le(e),installedAt:new Date().toISOString()})}async function PS(e,t,r,n={}){console.log(),u.header("Configuring GitHub Copilot"),console.log(),await Gr(e);let s=await uo(e);await io(e,{maxRequests:r.maxRequests,omitBaseAgentInstructions:r.omitBaseAgentInstructions});let o=await oo(e,r.terminalEnableAutoApprove),i=!1;r.enableMcpServer&&(i=(await vs(e,!0)).configured,await go(e)),await Mn(e);let a=await pi(e,{version:n.version});return await vc(e,{settingsEntries:await gt(e)}),Cr(await qt(e,"copilot")),await sh(e,"copilot",n),u.success("Core assets ensured: agents, prompts, instructions, skills"),u.success("Project brain ready:"),u.info(` .vesper/agents/vesper-orchestrator.agent.md (${a.orchestratorAgent}) \u2014 the one pickable agent`),u.info(` .vesper/instructions/vesper-orchestrator.instructions.md (${a.orchestrator})`),u.info(` .vesper/instructions/vesper-orchestration.instructions.md (${a.orchestration})`),u.info(` .vesper/instructions/vesper-context.instructions.md (${a.context})`),u.info(` .vesper/context/ (${a.contextTier}) \u2014 on-demand tier`),u.info(` .vesper/gates.json (${a.gates})`),u.info(`Max agent requests: ${r.maxRequests}`),o.configured>0?u.info(`Terminal auto-approval: ${o.configured} safe commands configured`):r.terminalEnableAutoApprove===!1&&u.info("Terminal auto-approval: disabled"),i&&(u.info("MCP servers: vesper-indexing, sequential-thinking, memory (.vscode/mcp.json)"),u.info("MCP tools auto-approval: vesper-indexing + context7 + sequential-thinking + memory")),s.workspaceType===pe.WORKSPACE_FILE?u.info(`Settings added to: ${rh(t.settingsPath)}`):u.info("Settings added to: .vscode/settings.json"),u.info("Tracking file: .vesperrc"),u.info("Worktree bootstrap task: .vscode/tasks.json (runs on folder open)"),{mcpConfigured:i}}async function IS(e,t,r=null){let n=await Dn(e);if(!n.found)return{migrated:!1,from:null,preCreated:[],backedUp:!1};let{paths:s}=n;console.log(),u.warn(`Found .vesperrc in nested folder${s.length>1?"s":""}:`);for(let{folderPath:c}of s)u.info(` \u2192 ${c}`);console.log();let o=s[0],i=!0;t||(i=await tr({message:"Migrate .vesperrc to workspace level? (recommended for multi-root workspaces)",default:!0}));let a=[];if(i&&r)try{let c=await ft(e),l=wS(e,c).split(vS).join("/");l&&!l.startsWith("..")&&!kS(l)&&(await w(c)?await r.snapshot(l):(await r.snapshot(l),a=[l]));for(let{vesperrcPath:p}of s)await r.nestedConfig(p)}catch(c){return u.warn(`Not moving the nested .vesperrc: it could not be backed up first (${c?.message||c}). Nothing was changed.`),console.log(),{migrated:!1,from:null,preCreated:[],backedUp:!1}}if(i){let c=await eo(e,o.vesperrcPath,o.tracking);if(c.success){if(u.success("Migrated .vesperrc to workspace level"),u.info(` From: ${o.vesperrcPath}`),u.info(` To: ${c.newPath}`),s.length>1){let{unlink:l}=await import("node:fs/promises");for(let d=1;d<s.length;d++)try{await l(s[d].vesperrcPath),u.info(` Removed: ${s[d].vesperrcPath}`)}catch{}}return console.log(),{migrated:!0,from:o.folderPath,preCreated:a,backedUp:!!r}}}else u.info("Migration skipped. .vesperrc will remain in nested folder."),console.log();return{migrated:!1,from:null,preCreated:[],backedUp:!!r&&i}}async function jS(e,t){let r=e;return t||(r=await ES({message:"Workspace root directory:",default:r})),yS(r)}async function RS(e,t,r){let n=[];for(let s of t){let o=nh(s),i=r;if(r||(i=await tr({message:`${o} is installed but was unchecked. Remove it from this project?`,default:!1})),!i){u.info(`Kept ${o}.`);continue}s==="claude"?await an(e):await Ss(e),n.push(s),u.success(`Removed ${o} from this project.`)}return n}async function NS(e){if(e)return{maxRequests:Ie.maxRequests,terminalEnableAutoApprove:Ie.terminalEnableAutoApprove,omitBaseAgentInstructions:Ie.omitBaseAgentInstructions,enableMcpServer:Ie.enableMcpServer};console.log(),u.info("Configure VS Code Chat settings:");let t=await bS({message:"Max agent requests per session (chat.agent.maxRequests):",default:Ie.maxRequests,min:1,max:1e3}),r=await tr({message:"Controls whether terminal commands are automatically approved. Enable terminal auto-approval? (chat.tools.terminal.enableAutoApprove)",default:Ie.terminalEnableAutoApprove});r&&u.info("Terminal auto-approval enabled with safe command whitelist");let n=await tr({message:"Omit base agent instructions for custom agents? (github.copilot.chat.omitBaseAgentInstructions)",default:Ie.omitBaseAgentInstructions}),s=await tr({message:"Enable vesper-indexing MCP server for fast code search?",default:Ie.enableMcpServer});return{maxRequests:t||Ie.maxRequests,terminalEnableAutoApprove:r,omitBaseAgentInstructions:n,enableMcpServer:s}}async function Ti(e,t=!1){let r=Ue().replace("index.js","cli-index.js");if(!await w(r))return{success:!1,error:"MCP server not built"};t&&(console.log(),u.info("Starting workspace indexing..."));let n=t?null:u.createSpinner("Indexing workspace...");return n&&n.start(),new Promise(s=>{let o=SS(process.execPath,["--disable-warning=ExperimentalWarning",r,e],{stdio:["ignore","pipe","pipe"],env:{...process.env}}),i="",a=0;o.stderr.on("data",c=>{let l=c.toString().trim(),d=l.match(/Indexed (\d+) files/);if(d&&(a=parseInt(d[1],10),n&&n.update(`Indexing workspace... ${a} files`)),t&&l)for(let p of l.split(`
189
- `))p.trim()&&u.info(p.replace("[vesper-indexing] ",""))}),o.stdout.on("data",c=>{i+=c.toString()}),o.on("close",c=>{try{let l=JSON.parse(i.trim());l.success?n?n.succeed(`Workspace indexed: ${l.filesIndexed} files`):u.success(`Workspace indexed: ${l.filesIndexed} files`):n?n.fail(`Indexing failed: ${l.error}`):u.error(`Indexing failed: ${l.error}`),s(l)}catch{c===0?(n?n.succeed(`Workspace indexed: ${a} files`):u.success(`Workspace indexed: ${a} files`),s({success:!0,filesIndexed:a})):(n?n.fail("Indexing failed"):u.error("Indexing failed"),s({success:!1,error:"Unknown error"}))}}),o.on("error",c=>{n?n.fail(`Indexing failed: ${c.message}`):u.error(`Indexing failed: ${c.message}`),s({success:!1,error:c.message})})})}function LS({copilot:e,claude:t,indexingResult:r}){console.log(),u.success("Vesper is ready."),r?.success?u.info(`Code index built: ${r.filesIndexed} files.`):r?.error&&u.info("Code index will be built on first MCP server start."),console.log(),u.header("Next Steps"),console.log(),e&&(u.info("GitHub Copilot \u2014 reload VS Code to activate Vesper:"),u.info(' Cmd+Shift+P (macOS) / Ctrl+Shift+P (Windows/Linux) \u2192 "Developer: Reload Window"')),t&&(u.info("Claude Code \u2014 open a session in this workspace; the orchestrator"),u.info(" activates automatically via the always-on rules in .claude/rules/ plus the"),u.info(" default-agent key in .claude/settings.json (vesper-orchestrator)."),u.info(" Committed to the repo: the orchestrator agent, four maintenance skills, and"),u.info(" the three .claude/rules/vesper-*.md files. The full specialist catalog ships"),u.info(' as the "vesper" marketplace plugin \u2014 Claude Code shows a one-time'),u.info(" workspace-trust dialog to load it (decline it, or a cloud/headless session,"),u.info(" and Vesper runs in degraded mode on the committed fallback)."),u.info("OpenCode \u2014 open the same checkout: opencode.json makes vesper-orchestrator the"),u.info(" default agent, loads the three .claude/rules files as instructions, runs the MCP"),u.info(" servers through `vespercli mcp serve`, and .opencode/plugins/vesper.js registers"),u.info(" the specialists. Commit opencode.json and .opencode/ with the rest.")),console.log(),e&&u.vesperTip()}async function oh(e={}){try{await MS(e)}finally{Hc()}}async function MS(e){try{let t=e.yes||e.forceDefault,r=await jS(e.path||process.cwd(),t);await w(r)||(u.error(`Directory not found: ${u.formatPath(r)}`),process.exit(1));let n=await z(r),s=await W(r),o=await $e(r,{checkout:s}),i=n.type===pe.WORKSPACE_FILE?await Dn(r):{found:!1,paths:[]},a=i.found&&i.paths.some(P=>!(Number(P?.tracking?.schemaVersion)>=2)),c=await fp(r);c&&u.warn(`An interrupted migration's record (${c.from}) was unreadable and was set aside as ${rh(c.to)}; its backups are kept. If files look half-migrated, restore them from that folder.`);let l=await jf(r),d=await bi(r),p=null;if(o.needsMigration||a){let P=await $f(r,{record:o.record}),X=l?.status==="started"&&l.latest.head===d&&l.root.head===d?l:null;if(P.dirty.length){let tt=X?await Nf(r,X,P):P.dirty;tt.length&&(u.error(Of(tt,{interrupted:X?X.latest.dir:null})),process.exit(1)),u.warn(`Resuming an interrupted migration (its backups: ${X.latest.dir}) \u2014 every uncommitted change is its own write.`)}p=X}let h=Nc(r),m={migrated:!1,preCreated:[],backedUp:!1};n.type===pe.WORKSPACE_FILE&&(m=await IS(r,t,h),i.found&&(o=await $e(r,{checkout:s})));let{selected:f,installed:g}=await CS(e,r,{legacyHint:o,checkout:s}),y=f[0],k=y==="claude"?"copilot":"claude",v=o.needsMigration&&o.hosts[k]?k:null,S=null,A=s,N=async()=>!!y&&!!A.host&&A.host!==y&&(await gr(r,A.host)||await ir(r,A.host)),E=!!v||await N(),b=()=>v??A.host;await ka(r)&&(u.warn(`An unreadable host-switch journal (${zt}) was found and removed: an earlier switch was interrupted before its record was saved. Check your added assets and MCP servers (\`vespercli list\`, \`vespercli mcp list\`) and re-add any that are missing.`),await Ac(r));let F=await Tt(r),Q=F?F.snapshot:null;if(F&&u.warn(E?`Resuming an interrupted host switch (${F.from} \u2192 ${F.to}, started ${F.startedAt}): completing it now \u2014 ${b()}'s remaining Vesper artifacts are cleaned, and the assets and MCP servers preserved when it started are restored onto ${y}.`:`Resuming an interrupted host switch (${F.from} \u2192 ${F.to}, started ${F.startedAt}): its preserved assets and MCP servers will be restored onto ${y}.`),E){let P=b(),X=v?`the pre-2.0 (1.x) ${P} setup`:`${P}'s Vesper artifacts`;if(!t&&!process.stdin.isTTY&&(u.error(`This workspace is provisioned for "${P}"${v?" (pre-2.0)":""}; switching to "${y}" removes ${X}. Re-run with --yes to confirm (non-interactive), or interactively.`),process.exit(1)),!t&&!await tr({message:`Switch this workspace from ${P} to ${y}? This removes ${X}. Your .vesper/.tracking/ (run ledger included) and memory.jsonl are untouched, and the Team Roster + project whitepaper are preserved.`,default:!1})){u.info("Initialization cancelled.");return}}let Fe=null;if(o.needsMigration){if(l?.status==="started"&&l!==p){let tt=await Rf(l);u.warn(`An interrupted migration from another commit (${l.root.head?l.root.head.slice(0,12):"no git"}) cannot be resumed and was abandoned; its backups are kept \u2014 remove them when you no longer need them: ${tt.join(", ")}`)}let P=await zo({dryRun:!0,workspaceRoot:r});S=await Gc(r,h,{record:o.record,previousVersion:await Mf(r,o.record,P.version||null),chain:p,preCreated:m.preCreated});let X=v??y;Fe=await Ff(r,y,{legacy:o,recordHost:X,frameworkVersion:e.version,log:u,backup:h}),A={host:X,source:"migration"},E=!!v||E&&await N()}else l&&(u.warn(`Completing an interrupted 1.x migration (its backups: ${l.latest.dir}): its rollback record is finished and its backup and rollback guidance printed at the end of this run.`),l.latest.head===d?S=await Gc(r,h,{record:o.record,chain:l}):l.status==="started"&&await Uc(r,l.latest.dir));if(E){await _c(r,A.host),F||(Q=await Cc(r),await rf(r,{from:A.host,to:y,snapshot:Q}));let{retained:P}=await gi(r,A.host,{fullTeardown:!0});await dn(r,P,A.host,u)}let hn=E||Fe?[]:g.filter(P=>!f.includes(P));if(f.length===0&&hn.length===0){u.info("No platforms selected. Nothing to do.");return}if(!t&&g.length===0&&f.length>0&&!await tr({message:`Set up ${f.map(nh).join(" + ")} in ${r}?`,default:!0})){u.info("Initialization cancelled.");return}hn.length>0&&await RS(r,hn,t);let wt=f.includes("copilot"),Mt=f.includes("claude"),Ve=null;wt&&(Ve=await NS(t));let Dt={...e,thirdPartyBackup:Fe?P=>h.project(P):null};wt&&(await Ou(r,"copilot"),await PS(r,n,Ve,Dt)),Mt&&await TS(r,Dt,g.includes("claude"));let et=null;if((wt||Mt)&&(et=await OS(g.includes(y),t,{backup:async P=>h.home(P),workspaceRoot:r}),et?.kept?.length&&(et.removed||et.partial)))try{await Wc(h,et.kept.map(P=>({rel:`~/.claude/skills/vesper/${P}`,reason:"plugin-folder"})))}catch{}if(wt||Mt){let P=await Xf(r);P.archived&&u.success(`Archived .vesper/history.md \u2192 ${P.to} (${P.method==="git"?"git mv, staged":"moved"}). Vesper 2.0 keeps the run ledger under .vesper/.tracking/runs/ instead; the archive is read-only and reachable by /revalidate-knowledge.`)}let Or=null,mn=[];if(wt||Mt){await jn(r);let P=await Rn(r);if(P.length>0){let vt=P.map(om=>`'${om.replace(/'/g,"'\\''")}'`);u.warn(`Local-only file(s) are git-tracked despite .gitignore: ${vt.join(", ")}`),u.warn(`Untrack them yourself (Vesper won't touch your git index): git rm --cached -- ${vt.join(" ")}`)}let X=await Gn(r);mn=rt.filter(vt=>X[vt]&&!X[vt].reason),Or=mn.length&&X[mn[0]].hooksDir||null;for(let vt of Vn(X))vt.startsWith("Git hooks not installed")?u.info(vt):u.warn(vt);Or&&(u.success("Local-only Vesper files gitignored (.vesperrc, .mcp.json, .vesper/index.db)"),mn.includes("pre-commit")&&u.info("Commit-hygiene git hook installed (pre-commit): keeps team roster/context/tracking/memory in sync with every commit"));let tt=await Hn(r);await Un(r),tt.skipped||u.info("Merge strategy configured (.gitattributes): memory.jsonl merges entity-aware across worktrees, recent-decisions.md unions")}if(f.length===1){let P=f[0],X=P==="copilot"?await gt(r):void 0;await AS(r,P,{settingsEntries:X,hooksDir:Or,hookNames:mn,version:e.version}),Q&&(await nf(r,P,Q),await Ac(r));let{legacyGuardRule:tt}=await ii(r,P);tt==="kept"&&u.warn(cn())}if(Fe)try{let X=(await un(r)).findings.filter(tt=>tt.code.startsWith("legacy-"));X.length&&u.warn(`The migration left ${X.length} pre-2.0 item(s) \u2014 see \`vespercli doctor\`.`)}catch{}if(S)try{await Uc(r,h.dir)}catch(P){u.warn(`Could not finish the migration's rollback record (${P?.message||P}); the backups are under .vesper/.migration-backup/.`)}let sm=wt&&Ve?.enableMcpServer||Mt,ll=null;sm&&(ll=await Ti(r,!0));let gn=[];if((S||et?.backedUpTo||m.backedUp)&&gn.push(h.dir),l&&!o.needsMigration&&!S&&gn.push(l.latest.dir),gn.length)try{let P=await Df(r,{runDirs:gn});if(P.length){console.log();for(let X of P)u.info(X)}await Lf(r,gn)}catch(P){u.warn(`Could not print the migration backup guidance (${P?.message||P}); the backups are under .vesper/.migration-backup/.`)}LS({copilot:wt,claude:Mt,indexingResult:ll})}catch(t){if(t.name==="ExitPromptError"){console.log(),u.info("Initialization cancelled.");return}t.name==="HostCleanRefused"&&(u.error(t.message),process.exit(1)),u.error(`Initialization failed: ${t.message}`),process.exit(1)}}U();H();te();be();Ee();xe();Rt();import{resolve as DS,join as ih}from"node:path";import{checkbox as FS}from"@inquirer/prompts";Te();var ah=["agents","skills"];async function VS(e,t){let r=t?[t]:await he(e);return r.length===0&&(u.warn('Vesper is not initialized in this workspace. Run "vespercli init" first.'),process.exit(0)),r.length>1&&(u.error(Xe),process.exit(1)),r[0]}async function ch(e,t,r){r!==t&&(u.error(`\`vespercli add\` for ${t==="claude"?"Claude Code":"Copilot"} needs a workspace provisioned for ${t}${r?` (this one is provisioned for ${r})`:""} \u2014 nothing was written. Run \`vespercli init --host ${t}\` first.`),process.exit(1))}async function GS(e,t){return await ds(e,t)!==null}async function HS(e,t,r){if(!t.type||!t.name){u.info("Every Vesper specialist and skill is served by the vesper plugin as `vesper:<name>` \u2014 there is nothing to add."),u.info("To pin a project-level copy anyway: vespercli add <agents|skills> <name> --override");return}if(t.type==="prompts"&&(u.error("Vesper 2.0 ships its maintenance workflows as skills (served by the plugin); slash commands are no longer provisioned."),process.exit(1)),ah.includes(t.type)||(u.error(`Unknown asset type for Claude Code: ${t.type}. Types: ${ah.join(", ")}`),process.exit(1)),await GS(t.type,t.name)||(u.error(`${t.type}/${t.name} is not in the Vesper catalog.`),process.exit(1)),!t.override){let n=await ds(t.type,t.name),s=t.type==="agents"?await xd(t.name):`/${n.pack==="core"?"vesper":`vesper-${n.pack}`}:${t.name}`;u.info(`\`${t.name}\` is already available as \`${s}\` from the ${n.pack==="core"?"vesper plugin":`vesper-${n.pack} pack (enabled per project by \`vespercli packs sync\`)`} \u2014 nothing to add.`),u.info("A project-level copy would shadow the plugin's version. To pin one anyway (not recommended): add --override.");return}await ch(e,"claude",r);try{let n=await Bo(t.type,t.name,{workspaceRoot:e,namePrefix:await Jr(e)});u.success(`Pinned a project-level copy of ${t.type}/${t.name} as "${n.installedAs}" (recorded; \`vespercli reset --host claude\` removes it).`)}catch(n){u.error(n.message),process.exit(1)}}async function US(e,t,r){let n=await Bp(),s=new Set(await ht(e)),o=c=>[...s].some(l=>l.replace(/\\/g,"/").endsWith(`/instructions-extended/${c}`));if(t.type&&t.type!=="instructions"){ze[t.type]||(u.error(`Unknown asset type: ${t.type}. Types: ${Object.keys(ze).join(", ")}`),process.exit(1));let c=Mo(),l=[...new Set([...await Is(t.type),...c[t.type]||[]])];t.name&&!l.includes(t.name)&&(u.error(`${t.type}/${t.name} is not in the Vesper catalog.`),process.exit(1));let d=t.name?c.assetPacks[t.type]?.[t.name]??"core":"core",p=d==="core"?`${ih(St,ze[t.type].dir)} (the whole folder is injected)`:`${ih(St,"packs",d,ze[t.type].dir)} (the ${d} pack's folder, injected when the pack is enabled \u2014 \`vespercli packs sync\`)`;u.info(`Copilot reads every Vesper ${t.type.replace(/s$/,"")} from ${p}${t.name?` \u2014 \`${t.name}\` is already available`:""}. Nothing to add.`);return}let i=[];if(t.name)n.includes(t.name)||(u.error(`Unknown opt-in instruction: ${t.name}. Available: ${n.join(", ")||"none"}`),process.exit(1)),i=[t.name];else{let c=n.filter(l=>!o(l));if(c.length===0){u.info("Every opt-in instruction is already added.");return}if(!process.stdin.isTTY){u.info(`Opt-in instructions you can add: ${c.join(", ")} \u2014 run \`vespercli add instructions <name>\`.`);return}if(i=await FS({message:"Select opt-in instructions to add:",choices:c.map(l=>({name:l,value:l}))}),i.length===0){u.info("Nothing selected.");return}}await ch(e,"copilot",r);let a=[];for(let c of i)(await fi(e,c)).added&&a.push(c);a.length?u.success(`Added opt-in instruction(s): ${a.join(", ")} \u2014 reload VS Code to apply.`):u.info("All selected instructions were already added.")}async function lh(e={}){try{let t=DS(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await W(t);return(await $e(t,{checkout:r})).unmigrated&&(u.error(Ze),process.exit(1)),(e.target||await VS(t,r.host))==="claude"?await HS(t,e,r.host):await US(t,e,r.host)}catch(t){if(t.name==="ExitPromptError"){console.log(),u.info("Cancelled.");return}u.error(`Add failed: ${t.message}`),process.exit(1)}}U();Ee();H();import{resolve as dh,join as WS}from"node:path";import{readdir as ph}from"node:fs/promises";te();be();xe();Rt();Te();import re from"picocolors";async function uh(e={},t){let r=dh(e.path||process.cwd());if(console.log(),console.log(re.bold("Claude Code target")),t!=="claude"){console.log(),u.warn('Not initialized for Claude Code. Run "vespercli init --host claude" first.'),console.log();return}let n=await Au(r)||br(r);console.log(re.dim(`Project catalog: ${n}`));let s=await xo(r),o=Ps();s&&o&&s!==o&&u.warn(`Catalog drift: installed catalog is v${s}, but Vesper is v${o}. Run \`vespercli update\` to refresh the committed orchestrator, maintenance skills and playbook.`);let i=await qd(r);for(let[a,c]of Object.entries(i))console.log(),console.log(re.bold(a.charAt(0).toUpperCase()+a.slice(1))),c.length===0?console.log(re.dim(" (none installed)")):c.forEach(l=>console.log(` ${l}`));console.log(),console.log(re.dim("The full specialist catalog is served by the vesper plugin (vesper:<name>) and its packs (vesper-<pack>:<name>) \u2014 see `vespercli catalog`.")),await fh(r,"claude"),console.log(),console.log(re.bold("Project files")),console.log(" CLAUDE.md (pointer), .claude/rules/vesper-{orchestrator,orchestration,context}.md, .mcp.json, .claude/settings.json"),console.log()}async function fh(e,t){let r=Qe();if(console.log(),console.log(re.bold("Packs")),!r.length){console.log(re.dim(" (this package ships no packs)"));return}let{enabled:n,unknown:s}=await Sr(e,t),o=await Jt(e,t),i=o!==null?await Yt(o):null;for(let a of r){let c=n.includes(a)?re.green("(enabled)"):re.dim("(disabled)"),l=i?.packs.includes(a)?n.includes(a)?re.dim("\u2014 roster needs it"):re.yellow("\u2014 roster needs it: run `vespercli packs sync`"):"";console.log(` ${a} ${c} ${l}`.trimEnd())}s.length&&console.log(re.yellow(` enabled but not shipped by this package: ${s.join(", ")}`)),console.log(re.dim(" `vespercli packs` for contents; `vespercli packs sync` enables what the Team Roster names."))}async function KS(e,t){try{let r=await ph(WS(e,".vesper",t),{withFileTypes:!0});return t==="skills"?r.filter(n=>n.isDirectory()&&!n.name.startsWith(".")).map(n=>n.name).sort():r.filter(n=>n.isFile()&&n.name.endsWith(".md")).map(n=>n.name.replace(/\.(agent|instructions|prompt)\.md$|\.md$/,"")).sort()}catch{return[]}}async function BS(){try{return(await ph(Pn,{withFileTypes:!0})).filter(e=>e.isFile()&&e.name.endsWith(".md")).map(e=>e.name.replace(/\.instructions\.md$|\.md$/,"")).sort()}catch{return[]}}async function zS(e,t){let n=(await ht(e)).map(o=>/\/instructions-extended\/([^/]+)\/?$/.exec(String(o).replace(/\\/g,"/"))).filter(Boolean).map(o=>o[1]).sort(),s=t.type?[t.type]:Object.keys(ze);console.log(),console.log(re.bold("GitHub Copilot target")),console.log(re.dim(`Package catalog: ${St}`));for(let o of s){let i=o.charAt(0).toUpperCase()+o.slice(1),a=o==="instructions"?await BS():await Is(o),c=await KS(e,o),l=o==="instructions"?n:[];if(console.log(),console.log(re.bold(i)),!a.length&&!c.length&&!l.length){console.log(re.dim(" (none)"));continue}a.forEach(d=>console.log(` ${d} ${re.dim("(package)")}`)),l.forEach(d=>console.log(` ${d} ${re.dim("(opt-in)")}`)),c.forEach(d=>console.log(` ${d} ${re.dim("(project)")}`))}await fh(e,"copilot"),console.log()}async function hh(e={}){try{let t=dh(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await W(t),n=r.host,s=n?[n]:await he(t);if(e.target==="claude")return await uh({...e,path:t},n);if(!e.target){if((await $e(t,{checkout:r})).unmigrated&&(u.error(Ze),process.exit(1)),s.length===0){console.log(),u.warn('Vesper is not initialized. Run "vespercli init" first.'),console.log();return}if(s.length>1&&(u.error(Xe),process.exit(1)),s[0]==="claude")return await uh({...e,path:t},n)}e.type&&!ze[e.type]&&(u.error(`Unknown asset type: ${e.type}`),u.info(`Valid types: ${Object.keys(ze).join(", ")}`),process.exit(1)),await zS(t,e)}catch(t){u.error(`List failed: ${t.message}`),process.exit(1)}}Ee();import{readFileSync as JS,existsSync as YS}from"node:fs";import{join as qS}from"node:path";var qc=qS(O,"CATALOG.md");function XS(){return YS(qc)?JS(qc,"utf-8"):null}async function mh(){let e=XS();e===null&&(console.error(`Error loading catalog: ${qc} not found in the installed package.`),process.exit(1)),console.log(e)}U();H();te();be();xe();import{resolve as Eh,join as Ii,dirname as wh}from"node:path";import{stat as QS,readFile as bh}from"node:fs/promises";import{existsSync as ZS}from"node:fs";import{spawn as eE}from"node:child_process";import"@inquirer/prompts";H();var gh=Object.freeze(Object.keys(we)),lT=Object.freeze(["vesper-indexing","sequential-thinking","memory"]);function Xc(e,{workspaceRoot:t,env:r,indexingPath:n}){return String(e).replace(/\$\{VESPER_INDEXING_PATH\}/g,n).replace(/\$\{workspaceFolder\}/g,t).replace(/\$\{env:([^}]+)\}/g,(s,o)=>r[o]??"")}function yh(e,t,{env:r=process.env,indexingPath:n=Ue()}={}){let s=we[e];if(!s||!s.config)return null;let{type:o,...i}=structuredClone(s.config),a={workspaceRoot:String(t),env:r||{},indexingPath:n},c={command:Xc(i.command,a),args:(Array.isArray(i.args)?i.args:[]).map(l=>Xc(l,a)),env:{}};for(let[l,d]of Object.entries(i.env||{})){let p=Xc(d,a);p!==""&&(c.env[l]=p)}return c}Te();import it from"picocolors";async function vh(e,t){if(console.log(),u.header("vesper-indexing MCP Server (Claude Code target)"),console.log(),t!=="claude"){u.info("Claude Code target is not initialized. Run `vesper init --target claude` first.");return}let r=De(e),n=!1;if(await w(r))try{n=!!JSON.parse(await bh(r,"utf-8")).mcpServers?.["vesper-indexing"]}catch{n=!1}u.info(`Configured: ${n?"\u2713 yes":"\u2717 no"} (${r})`),u.info(`Server built: ${$h(await Ch())}`);let s=Zc(e);u.info(`Index exists: ${await w(s)?"\u2713 yes":"\u2717 no"} (shared with the Copilot target if both are installed)`);try{let{drifted:o}=await ci(e);o.length&&(console.log(),u.warn(`MCP config drift: ${o.join(", ")} present in the live MCP config but not tracked in .vesperrc mcp.servers.`),u.warn("Run `/reinit` (or re-run workspace-learner) to resync tracking and the generated docs."))}catch{}}var xh=new Set(["enable","disable","sync","add","remove"]),tE=xh,_h="Vesper regenerates them at every session start \u2014 `vespercli mcp disable` makes no lasting change.";function rE(e){return`\`vespercli mcp ${e}\` for Claude Code needs a workspace provisioned for Claude \u2014 nothing was written. Run \`vespercli init --host claude\` first.`}async function Qc(e,t=!0){if(await Zt(e,t),t){let r=await rp(e);r.skipped==="malformed"&&u.warn(`${r.settingsPath} is not valid JSON \u2014 MCP tool permissions were not added (the file was left as found).`)}t?u.success("Claude Code target: vesper-indexing enabled in .mcp.json"):(u.success("MCP servers removed from .mcp.json until the next session start"),u.info(_h))}function Zc(e){return Ii(e,".vesper","index.db")}function nE(e){return Ii(e,".vesper","indexing-status.json")}async function Ah(e){let t=nE(e);try{let r=await bh(t,"utf-8");return JSON.parse(r)}catch{return null}}async function Ch(){let e=Ue();if(!await w(e))return"missing";let t=wh(wh(e)),r=[Ii(t,"node_modules","@modelcontextprotocol","sdk","package.json"),Ii(t,"node_modules","zod","package.json")];for(let n of r)if(!await w(n))return"broken";return"ready"}function $h(e){switch(e){case"ready":return"\u2713 yes";case"broken":return"\u26A0 yes, but dependencies missing \u2014 run 'npm install' in src/mcp/vesper-indexing (or reinstall Vesper)";default:return"\u2717 no"}}async function sE(e){try{let t=await QS(e),r=t.size,n=`${r} bytes`;return r>1024*1024?n=`${(r/(1024*1024)).toFixed(2)} MB`:r>1024&&(n=`${(r/1024).toFixed(1)} KB`),{dbSize:n,lastModified:t.mtime.toISOString()}}catch{return null}}async function kh(e,t=!1){let r=await mo(e),n=await Ch(),s=Zc(e),o=await w(s),i=await Ah(e);if(console.log(),u.header("vesper-indexing MCP Server"),console.log(),u.info(`Configured: ${r?"\u2713 yes":"\u2717 no"}`),u.info(`Server built: ${$h(n)}`),u.info(`Index exists: ${o?"\u2713 yes":"\u2717 no"}`),i)if(console.log(),i.status==="indexing")if(t){await oE(e,i);return}else{let a=i.startedAt?Math.round((Date.now()-new Date(i.startedAt).getTime())/1e3):0;u.info(it.yellow("\u27F3 Indexing in progress...")),u.info(` Files processed: ${it.cyan(i.filesProcessed)}`),u.info(` Elapsed: ${it.dim(`${a}s`)}`),console.log(),u.info("Use --watch to follow indexing progress until completion")}else i.status==="error"&&(u.error(`Indexing error: ${i.error}`),u.info(` Files processed before error: ${i.filesProcessed}`));if(!r){console.log(),u.info("Run `vespercli init` to configure the MCP server");return}if(n==="missing"){console.log(),u.warn("MCP server not built. Run: cd src/mcp/vesper-indexing && npm install && npm run build");return}if(n==="broken"){console.log(),u.warn("MCP server dependencies are missing/corrupt. Run: cd src/mcp/vesper-indexing && npm install (or reinstall Vesper)");return}if(o&&!i){let a=await sE(s);a&&(console.log(),u.info(`Index size: ${a.dbSize}`),u.info(`Last modified: ${a.lastModified}`)),u.vesperTip()}else!o&&!i&&(console.log(),u.info("Index not yet created. It will be built when VS Code loads the MCP server."),console.log())}async function oE(e,t){let r=u.createSpinner(`Indexing... ${t.filesProcessed} files processed`);r.start();let n=500,s=30*60*1e3,o=Date.now();return new Promise(i=>{let a=async()=>{let c=await Ah(e);if(!c||c.status!=="indexing"){c?.status==="error"?r.fail(`Indexing failed: ${c.error}`):(r.succeed(`Indexing complete! ${c?.filesProcessed||"All"} files indexed`),u.info(`
190
- \u2192 Reload VS Code to update MCP tools with the new index`),u.vesperTip()),i();return}let l=c.startedAt?Math.round((Date.now()-new Date(c.startedAt).getTime())/1e3):0;if(r.update(`Indexing... ${c.filesProcessed} files processed (${l}s)`),Date.now()-o>s){r.fail("Indexing watch timed out (30 minutes)"),i();return}setTimeout(a,n)};setTimeout(a,n)})}async function Sh(e,t=!1){let r=Zc(e);if(!await w(r))u.info("No index exists. It will be built when VS Code loads the MCP server.");else if(t){let{unlink:s}=await import("node:fs/promises");await s(r),u.success("Index cleared. Reload VS Code to rebuild.")}else u.info("Incremental reindex happens automatically when files change."),u.info("Use --full to clear and rebuild the entire index.")}async function iE(e){let t=await ur(e,!0);t.configured&&(u.success("MCP server enabled"),u.info(`Config: ${t.mcpPath}`),u.info("Reload VS Code to start the server"))}async function aE(e){await ur(e,!1),u.success("MCP servers removed from .vscode/mcp.json until the next session start"),u.info(_h),u.info("Reload VS Code to apply changes")}async function Oh(e){let t=await ht(e),r=[];for(let n of t){let s=n.match(/agents\/([^/]+)\/?$/);s&&MCP_TOOLS_BY_AGENT[s[1]]&&r.push(s[1])}return r}async function cE(e){let t=await z(e),r=await x(e,t),n=await J(e,t),s=await Oh(e),o=n[V]||{},i=new Set(je),a=[],c=[],l=!1;n[V]||(n[V]={});for(let p of je)o[p]||(n[V][p]=!0,a.push(p),l=!0);for(let p of s){let h=MCP_TOOLS_BY_AGENT[p]||[];for(let m of h)o[m]||(n[V][m]=!0,a.push(m),l=!0)}let d=new Set;for(let p of s)for(let h of MCP_TOOLS_BY_AGENT[p]||[])d.add(h);for(let p of Object.keys(o)){if(i.has(p))continue;let h=!1;for(let[m,f]of Object.entries(MCP_TOOLS_BY_AGENT))if(f.includes(p)){h=!0;break}h&&!d.has(p)&&(delete n[V][p],c.push(p),l=!0)}if(r.mcp=r.mcp||{},r.mcp.syncedAt=new Date().toISOString(),r.mcp.approvedAgents=s,r.mcp.toolCount=Object.keys(n[V]).length,l&&await oe(e,n),await I(e,r),console.log(),u.header("MCP Tools Sync"),console.log(),a.length===0&&c.length===0)u.success("Already in sync");else{if(a.length>0){u.success(`Added ${a.length} tool(s)`);let p=a.filter(h=>i.has(h));p.length>0&&u.info(` Core: ${p.length} tools`);for(let h of s){let m=a.filter(f=>(MCP_TOOLS_BY_AGENT[h]||[]).includes(f));m.length>0&&u.info(` ${h}: ${m.length} tools`)}}c.length>0&&u.info(`Removed ${c.length} orphaned tool(s)`)}u.info(`
196
+ `:"","utf-8"),await A(_(n.dir,ml),g.map(([v,S])=>`${v} ${S}
197
+ `).join(""),"utf-8"),await A(_(n.dir,gl),cE,"utf-8");let y=new Set;for(let v of s){if(v!==o){let S=null;try{S=await lt(_(v.dir,"rewritten"))}catch{S=null}for(let C of S?S.files:[])!l.has(C)||y.has(C)||await w(_(o.dir,"rewritten",C))||await fh(o.dir,"rewritten",C,_(v.dir,"rewritten",C))}for(let[S]of await yl(v.dir))y.add(S)}await P(_(n.dir,xh),{recursive:!0});let k=new Date().toISOString();for(let v of s)await wl(v.dir,{status:"finished",finishedAt:k,...v.dir===n.dir?{created:h}:{}});return h}async function Oh(e,t){for(let r of await zi(e))r.migration&&t.includes(r.dir)&&await wl(r.dir,{guidancePrinted:!0})}async function ch(e,{homeDir:t=Ws()}={}){let r=new Set;for(let n of[...e?.injectedPaths||[],...e?.readAccessPaths||[]]){let s=/^(.*?)\/assets(?:\/|$)/.exec(String(n).split("\\").join("/"));!s||s[1].includes("${")||r.add(s[1].startsWith("~/")?_(t,s[1].slice(2)):s[1])}for(let n of r)try{let s=JSON.parse(await Se(_(n,"package.json"),"utf-8"));if(["@mthanh/vespercli","vespercli"].includes(s?.name)&&/^1\.\d+\.\d+/.test(s?.version||""))return s.version}catch{}return null}async function Th(e,t,r,{homeDir:n=Ws()}={}){if(t?.version)return t.version;let s=await ch(t,{homeDir:n});if(s)return s;let o=[];try{let{readVSCodeSettings:a}=await Promise.resolve().then(()=>(H(),Ma)),c=await a(e);for(let[l,d]of Object.entries(c||{}))!/^chat\..*Locations$/.test(l)||!d||o.push(...(Array.isArray(d)?d:Object.keys(d)).filter(p=>typeof p=="string"))}catch{o=[]}let i=await ch({injectedPaths:o},{homeDir:n});return i||t?.config==="v1"&&r||null}async function Ph(e,{runDirs:t=[],homeDir:r=Ws()}={}){let n=await zi(e),s=new Set(t),o=n.filter(E=>E.migration&&s.has(E.dir)),i=[];if(o.length){let E=o[o.length-1];i=n.filter(b=>b.migration&&b.chainRoot===E.chainRoot&&b.name<=E.name);for(let b of i)s.add(b.dir)}let a=n.filter(E=>s.has(E.dir)&&(E.project||E.home||E.rewritten||E.migration||E.outside.length));if(!a.length)return[];let c=n.filter(E=>!s.has(E.dir)),l=c.filter(E=>E.migration&&E.status==="abandoned"),d=E=>`"${E}"`,p=[];p.push(`Migration backups (${a.length}) \u2014 in ${_(e,Gr)}, gitignored; keep them until you are happy with 2.0${a.length>1?" (an interrupted run was completed: ALL its folders are listed, oldest first)":""}:`);for(let E of a)p.push(` ${E.dir}${E.home?" (holds home-directory files too)":""}${E.outside.length?" (holds files from outside the workspace too)":""}`);if(c.length&&p.push(` (${c.length} other folder(s) there belong to an earlier migration or cleanup \u2014 the commands below never use them)`),l.length){p.push(" Abandoned interrupted migration(s) \u2014 never resumed, kept in case they hold a file you need; remove them when you no longer do (rm -rf):");for(let E of l)p.push(` ${E.dir}`)}let f=E=>E.outside.map(b=>`cp -R -p ${d(_(E.dir,b.backup))} ${d(b.original)}`),m=[];for(let E of a)E.project&&m.push(`cp -R ${d(_(E.dir,"project"))}/. ${d(e)}/`),E.home&&m.push(`cp -R ${d(_(E.dir,"home"))}/. ${d(r)}/`),m.push(...f(E));if(m.length){p.push("Recover the files the migration REMOVED (copies them back; this alone is not a rollback):");for(let E of m)p.push(` ${E}`)}if(!i.length)return p;let h=i[0],g=i[i.length-1],y=g.created,k=i.map(E=>E.previousVersion).find(Boolean),v=h.head?await Yi(e):null;h.head&&v&&v!==h.head&&p.push(`Note: HEAD is now ${v.slice(0,12)}, not ${h.head.slice(0,12)} (the commit this migration started from). The rollback below still restores the migrated paths to ${h.head.slice(0,12)}'s committed layout \u2014 changes committed since to those paths are undone in the working tree (they stay in git history).`),p.push(`Roll back THIS migration to 1.x completely (back to its starting commit ${h.head?h.head.slice(0,12):"(no git)"}; run from the workspace root, in this order):`);let S=1;if(h.head){let E=h.head.slice(0,12);p.push(` ${S++}. [ "$(git rev-parse HEAD)" = "${h.head}" ] || echo "Warning: HEAD is no longer ${E}, the commit this migration started from - the restore below returns the migrated paths to ${E}'s layout; review git status/diff afterwards." >&2 (a check only: it changes nothing)`)}if(y.length&&g.createdChecked?p.push(` ${S++}. sh ${d(_(g.dir,gl))} (removes the ${y.length} file(s) this migration created, incl. its git hooks: ${y.slice(0,4).join(", ")}${y.length>4?", \u2026":""} \u2014 only while each still holds the bytes the migration wrote; a file changed since is kept and named)`):y.length&&p.push(` ${S++}. while IFS= read -r f; do rm -f -- "$f"; done < ${d(_(g.dir,"created.txt"))} (the ${y.length} file(s) this migration created, incl. its git hooks: ${y.slice(0,4).join(", ")}${y.length>4?", \u2026":""})`),h.rewritten&&p.push(` ${S++}. cp -R ${d(_(h.dir,"rewritten"))}/. ${d(e)}/ (every whole file init rewrote, incl. the gitignored .vesperrc / .mcp.json and the git hooks, as they were when this migration started)`),h.head&&h.trackedPaths.length){let E=_(h.dir,"tracked-paths.txt");p.push(` ${S++}. git -c core.hooksPath=${d(_(g.dir,xh))} restore --source=${h.head} --staged --worktree --pathspec-from-file=${d(E)} (the committed layout; hooks disabled for this one command; the migration refused to start on uncommitted changes, so this is exact)`)}let C=[];for(let E of i)E.project&&C.push(`cp -R ${d(_(E.dir,"project"))}/. ${d(e)}/`),E.home&&C.push(`cp -R ${d(_(E.dir,"home"))}/. ${d(r)}/`),C.push(...f(E));C.length&&p.push(` ${S++}. ${C.join(" && ")} (the removed files)`);let N=k&&/^1\.9\./.test(k)?`; ${k} was never published to npm \u2014 install it from the repository's ${k} commit, or pin 1.8.0`:"";return p.push(` ${S++}. npm install -g @mthanh/vespercli@${k||"<your previous 1.x version>"} (LAST: pin the previous CLI \u2014 any 2.x CLI migrates again${N})`),p}async function Ih(e,t,{legacy:r,recordHost:n,frameworkVersion:s,homeDir:o=Ws(),now:i=new Date,log:a,backup:c}={}){let l=await $i(e),d=a||{info(){},success(){},warn(){}},p=c||fl(e,{now:i,homeDir:o}),f={record:l,backupDir:null,relocated:[],recorded:[],removed:[],moved:[],kept:[],homeLookalikes:[],settings:null},m=(b,F,X={})=>f.kept.push({rel:b,reason:F,...X}),h=async(b,F)=>{try{return await F()}catch(X){m(b,"error",{detail:String(X?.message||X)});return}},g=await hl(e),y=g?["pre-commit","post-checkout"].map(b=>`${g}/${b}`):[];for(let b of[...dh,...await wh(e),...y])await h(b,()=>p.snapshot(b));let k=l;if(l.config==="v2"&&l.recordedHost){let b=null;try{b=(await B(e)).host}catch{b=null}if(l.recordedHost!==b){let F=l.recordedHost;d.info(`This worktree's 2.0 record describes another branch (${F}); migrating this 1.x checkout from its files.`),k=Object.freeze({...l,catalogManifest:[],injectedPaths:[],readAccessPaths:[],mcpServers:[],vendored:void 0,hosts:{claude:!1,copilot:!1}}),await h(".vesperrc",async()=>{let X=await x(e);X.manifest=J(X).filter(He=>He.host!==F||Ne.has(He.category)),delete X.host,await T(e,X)})}}let v=await yh(e,k);await dE(e,t,{backup:p,result:f,safely:h,keep:m,catalog:v});let S=[];for(let b of v.record)await h(b.rel,async()=>(await p.project(b.rel),!0))&&(S.push(b.entry),f.recorded.push(b.rel));for(let b of v.keep)m(b.rel,b.reason,b.files?{files:b.files}:{});let C=".claude/vesper/orchestrator.md";await w(_(e,C))&&await h(C,async()=>{let b=await Se(_(e,C));if(!tp(b)){m(C,"edited-playbook");return}await p.project(C),await le(_(e,C),{path:C,category:"playbook",hash:ut(b)})==="removed"&&f.removed.push(C)});try{await lh(_(e,".claude","vesper"))}catch{}t==="copilot"&&(f.settings=await h(".vscode/settings.json",()=>Zr(e,{trackedPaths:k.injectedPaths,trackedReadAccess:k.readAccessPaths})));let N=await Oi({homeDir:o}).catch(()=>[]);if(f.homeLookalikes=N.filter(b=>b.tier===3),(await x(e)).schemaVersion===ve){await cn(e,{frameworkVersion:s}),S.length&&await W(e,S);let b=await x(e);!b.host&&n&&(b.host=n,await T(e,b))}else await cn(e,{frameworkVersion:s,legacyEntries:S,host:n});return f.kept.length&&await h("kept.json",()=>El(p,f.kept)),f.backup=p,f.backupDir=p.items.length?p.dir:null,fE(f,d),f}async function El(e,t){e.keptRows??=[];for(let r of t)e.keptRows.push({rel:r.rel,reason:r.reason,...r.files?{files:r.files}:{},...r.detail?{detail:r.detail}:{}});return e.writeSidecar("kept.json",`${JSON.stringify(e.keptRows,null,2)}
198
+ `)}async function dE(e,t,{backup:r,result:n,safely:s,keep:o,catalog:i}){let a=null,c=new Set;if(t==="claude"){a=await At();let d=new Set((i?.record||[]).map(p=>p.rel));for(let p of a.agents){let f=`.claude/agents/${p}.md`;!d.has(f)&&await w(_(e,f))&&c.add(p)}}let l=[{key:"orchestration",claudeDest:".claude/rules/vesper-orchestration.md",copilotDest:Ie("vesper-orchestration"),tpl:"orchestration.md.tpl",sources:[{rel:".claude/vesper/orchestration.md",vesper:()=>!0,move:!0},{rel:".github/instructions/orchestration.instructions.md",vesper:oE,move:!0,unmarked:"report"}]},{key:"context",claudeDest:".claude/rules/vesper-context.md",copilotDest:Ie("vesper-context"),tpl:"context.md.tpl",sources:[{rel:".claude/vesper/context.md",vesper:()=>!0,move:!0},{rel:".github/copilot-instructions.md",vesper:iE,move:!1,unmarked:"claude-only"}]}];for(let d of l){let p=t==="claude"?d.claudeDest:d.copilotDest,f=null;for(let m of d.sources){let h=_(e,m.rel),g=(await gh(h))?.toString("utf-8");if(g===void 0)continue;let y=m.vesper(g);if(!y&&m.unmarked==="report"){o(m.rel,"unmarked-knowledge");continue}if(!y&&m.unmarked==="claude-only"&&t!=="claude"){o(m.rel,"github-own");continue}if(f||await w(_(e,p))){let k="duplicate-knowledge";m.move||(k=y?f?"github-brain-kept":"github-brain-dest":"github-own"),o(m.rel,k);continue}await s(m.rel,async()=>{let{body:k}=ft(g),v=k.replace(/^\n+/,"");if(t==="claude"&&d.key==="orchestration"){let E=md(v);n.rosterRetired=E.removed;let b=zo(E.text,a,{skip:c});v=b.text,n.rosterQualified=b.qualified}let S=t==="claude"?`${await ah(d.tpl)}${v}`:qc(ft(g).frontmatter===null?`${await ah(d.tpl)}${k}`:g,`Vesper ${d.key}`),C=_(e,p);if(await P(dl(C),{recursive:!0}),await A(C,S,"utf-8"),await Se(C,"utf-8")!==S)throw new Error(`could not verify ${p}`);if(f=m.rel,!m.move||!y){n.relocated.push({from:m.rel,to:p,copied:!0}),o(m.rel,m.move?"unmarked-knowledge":"github-brain");return}n.relocated.push({from:m.rel,to:p}),await r.project(m.rel),await le(h,{path:m.rel,category:"relocated-original"},{expected:[Buffer.from(g,"utf-8")]})==="removed"&&n.moved.push({from:m.rel,to:p})})}}for(let d of[".github/instructions",".github"])try{await lh(_(e,d))}catch{}if(t==="copilot"){let d=_(e,".claude","vesper","context"),p=[];try{p=(await lt(d)).files}catch{p=[]}for(let f of p){let m=_(e,".vesper","context",f);await w(m)||await s(`.claude/vesper/context/${f}`,async()=>{await P(dl(m),{recursive:!0}),await A(m,await Se(_(d,f))),n.relocated.push({from:`.claude/vesper/context/${f}`,to:`.vesper/context/${f}`,copied:!0})})}}}function pE(e,{max:t=5}={}){let r=new Map;for(let s of e)r.has(s.reason)||r.set(s.reason,[]),r.get(s.reason).push(s.rel);let n=[];for(let[s,o]of r){let i=o.slice(0,t).join(", ")+(o.length>t?`, \u2026 +${o.length-t} more`:"");n.push(`Kept ${o.length} \u2014 ${sE[s]||s}: ${i}`)}return n}function fE(e,t){for(let{from:r,to:n,copied:s}of e.relocated)s&&t.info(`Copied ${r} \u2192 ${n}`);for(let{from:r,to:n}of e.moved)t.info(`Moved your ${r} \u2192 ${n} (your project knowledge; the original is backed up)`);if(e.relocated.some(r=>/vesper-orchestration\.md$/.test(r.to))){let r=e.rosterQualified?.length||0;for(let n of e.rosterRetired||[])t.info(`Removed retired roster row: ${n.role} (${n.agent}) \u2014 replaced by ${n.replacement}`);r?t.info(`Team roster relocated \u2014 ${r} specialist name(s) namespaced to \`vesper:<name>\` for the plugin.`):e.rosterQualified===void 0&&t.info("Team roster relocated \u2014 run `/revalidate-team` once: 2.0 delegates to the plugin's specialists by `vesper:<name>` (doctor reminds you until then).")}e.recorded.length&&t.info(`Retiring ${e.recorded.length} 1.x catalog item(s) byte-identical to a released 1.x build \u2014 the vesper plugin serves them now (backed up): ${e.recorded.slice(0,8).join(", ")}${e.recorded.length>8?", \u2026":""}`);for(let r of e.removed)t.info(`Removed ${r} (byte-identical to a released 1.x Vesper file; backed up)`);for(let r of e.settings?.removed||[])t.info(`Removed the 1.x settings location ${r} (2.0 injects each assets/copilot/<type> folder whole)`);for(let r of pE(e.kept))t.warn(r);if(e.homeLookalikes.length){let r=e.homeLookalikes.slice(0,5).map(n=>`~/${n.rel}`).join(", ")+(e.homeLookalikes.length>5?", \u2026":"");t.info(`FYI: ${e.homeLookalikes.length} Vesper-looking item(s) in your home directory (${r}). Vesper 1.x never wrote these locations, so they are yours \u2014 left untouched, and not mentioned again.`)}}U();import{join as _l}from"node:path";U();it();wt();import{rename as hE}from"node:fs/promises";import{dirname as mE,join as jh}from"node:path";async function Ji(e,t,r){let n=jh(e,t),s=jh(e,r);if(!await w(n))return{ok:!1,reason:"missing"};if(await w(s))return{ok:!1,reason:"exists"};await P(mE(s),{recursive:!0});let o={...process.env,...jt};return await D(["rev-parse","--is-inside-work-tree"],{cwd:e,env:o})==="true"&&(await Tt(["--literal-pathspecs","ls-files","--error-unmatch","--",t],{cwd:e,env:o})).ok&&await D(["--literal-pathspecs","status","--porcelain","--",t],{cwd:e,env:o})===""&&(await Tt(["--literal-pathspecs","mv","--",t,r],{cwd:e,env:{...process.env,...Dn}})).ok?{ok:!0,method:"git"}:(await hE(n,s),{ok:!0,method:"rename"})}U();import{readdir as gE,readFile as yE}from"node:fs/promises";import{join as qi}from"node:path";var xl=".vesper/.tracking/runs",Bs=Object.freeze(["started","completed","note","delegated","returned"]),Rh=Object.freeze(["DONE","NEED_HELP","BLOCKED"]),wE="adhoc",Xi=5,On=Object.freeze({OK:0,INVALID:2}),vE=Object.freeze(["ts","event","pipeline","step","agent","goal","author","status","note"]),kE=Object.freeze({started:["goal"],completed:["status"],note:[],delegated:["agent"],returned:["agent","status"]});function Nh(e){return String(e??"").toLowerCase().replace(/[^a-z0-9-]+/g,"-").replace(/-{2,}/g,"-").replace(/^-|-$/g,"")||wE}function Al(e=new Date){return e.toISOString().slice(0,10).replace(/-/g,"")}function SE(e,t=new Date){return`${Al(t)}-${Nh(e)}.jsonl`}function Ks(e){return typeof e=="string"&&e.trim()!==""}function Lh(e={},{now:t=new Date}={}){let r=[],n=typeof e.event=="string"?e.event.trim():"";Bs.includes(n)||r.push(`event must be one of ${Bs.join("|")} (received "${n}")`),Ks(e.pipeline)||r.push("--pipeline is required");for(let o of kE[n]||[])Ks(e[o])||r.push(`--${o} is required for \`${n}\``);if(e.status!==void 0&&e.status!==null&&!Rh.includes(String(e.status))&&r.push(`--status must be one of ${Rh.join("|")} (received "${e.status}")`),r.length)return{ok:!1,errors:r};let s={ts:t.toISOString(),event:n};for(let o of vE.slice(2))s[o]=Ks(e[o])?e[o].trim():null;return Ks(e.session)&&(s.session=e.session.trim()),{ok:!0,row:s}}async function Mh(e,t,{slug:r,now:n=new Date}={}){let s=qi(e,xl);await P(s,{recursive:!0});let o=SE(r,n),i=qi(s,o),a=`${JSON.stringify(t)}
199
+ `;return await A(i,a,{encoding:"utf-8",flag:"a"}),{rel:`${xl}/${o}`,abs:i,line:a}}function bl(e){let t=/^\d{8}-(.+)\.jsonl$/.exec(e);return t?t[1]:null}async function Gh(e,{slug:t}={}){let r=qi(e,xl);if(!await w(r))return{rows:[],files:[],malformed:0};let n=t?Nh(t):null,s=(await gE(r)).filter(c=>c.endsWith(".jsonl")&&bl(c)!==null&&(!n||bl(c)===n)).sort(),o=[],i=0,a=0;for(let c of s){let l=await yE(qi(r,c),"utf-8");for(let d of l.split(`
200
+ `))if(d.trim()!=="")try{let p=JSON.parse(d);if(!p||typeof p!="object"||Array.isArray(p)){i+=1;continue}o.push({...p,slug:bl(c),__order:a++})}catch{i+=1}}o.sort((c,l)=>{let d=typeof c.ts=="string"?c.ts:"",p=typeof l.ts=="string"?l.ts:"";return d<p?-1:d>p?1:c.__order-l.__order});for(let c of o)delete c.__order;return{rows:o,files:s,malformed:i}}function Fh(e,t=Xi){let r=Number.isFinite(t)?Math.max(0,Math.floor(t)):Xi;return r===0?[]:e.slice(-r)}function Dh(e){let t=[String(e.ts??"-"),String(e.event??"-").padEnd(9),String(e.pipeline??"-")];e.slug&&t.push(`[${e.slug}]`);for(let r of["step","agent","status","author","session"])e[r]!==null&&e[r]!==void 0&&e[r]!==""&&t.push(`${r}=${e[r]}`);return e.goal&&t.push(`goal="${e.goal}"`),e.note&&t.push(`\u2014 ${e.note}`),t.join(" ")}function Vh(e){let t;try{t=JSON.parse(String(e??""))}catch{return null}if(!t||typeof t!="object"||Array.isArray(t))return null;let r=n=>Ks(t[n])?t[n].trim():null;return{agent:r("agent_type"),agentId:r("agent_id"),session:r("session_id")}}var Qi=".vesper/history.md",Hh=".vesper/history-archive";function Uh(e=new Date,t=0){return`history-${Al(e)}${t>0?`-${t}`:""}.md`}async function Wh(e,{now:t=new Date}={}){if(!await w(_l(e,Qi)))return{archived:!1};let r=_l(e,Hh);await P(r,{recursive:!0});let n=0,s=Uh(t,n);for(;await w(_l(r,s));)n+=1,s=Uh(t,n);let o=`${Hh}/${s}`,i=await Ji(e,Qi,o);if(!i.ok)throw new Error(`Could not archive ${Qi}: ${i.reason}`);return{archived:!0,from:Qi,to:o,method:i.method}}Ut();Or();U();be();te();H();import{resolve as bE}from"node:path";import ae from"picocolors";Ut();dn();pt();import{confirm as xE}from"@inquirer/prompts";it();wt();Or();var Zi=3e3;async function EE(e,{timeoutMs:t=Zi,env:r}={}){let n=await Tt(["ls-remote","--",e,"HEAD"],{timeout:t,env:Vn(br(r??process.env)),detached:!0});if(!n.ok)return null;let s=n.stdout.split(`
201
+ `).map(o=>o.trim()).find(o=>/^[0-9a-f]{40}\s+HEAD$/.test(o));return s?s.slice(0,40):null}async function ea({assetsDir:e,timeoutMs:t=Zi,env:r}={}){let n=[];for(let{pack:s,skill:o,record:i}of await Ku(e)){let a=typeof i?.upstream=="string"?i.upstream:null,c=typeof i?.sha=="string"?i.sha:null;if(!a||!c){n.push({skill:o,pack:s,upstream:a,pinned:c,remote:null,stale:null,status:"no-record"});continue}let l=await EE(a,{timeoutMs:t,env:r});if(!l){n.push({skill:o,pack:s,upstream:a,pinned:c,remote:null,stale:null,status:"unreachable"});continue}let d=l!==c;n.push({skill:o,pack:s,upstream:a,pinned:c,remote:l,stale:d,status:d?"stale":"current"})}return n}function Kh(e){return`\`${e.skill}\` has a newer upstream (${e.upstream} is at ${e.remote.slice(0,12)}, the package ships ${e.pinned.slice(0,12)}); the next Vesper release picks it up.`}Pe();var Bh=["list","enable","disable","sync","upstream"];function AE(e,{log:t=console.log}={}){if(t(),t(ae.bold("Third-party pack skills \u2014 upstream check")),t(ae.dim("Pinned = the commit the shipped snapshot was taken at (UPSTREAM.json); remote = upstream HEAD now.")),t(),!e.length){t(ae.dim(" (this package ships no third-party skills)")),t();return}let r=Math.max(...e.map(s=>s.skill.length));for(let s of e){let o=s.status==="stale"?ae.yellow("newer upstream"):s.status==="current"?ae.green("current"):s.status==="unreachable"?ae.dim("unreachable"):ae.red("no record"),i=s.pinned?s.pinned.slice(0,12):"\u2014",a=s.remote?s.remote.slice(0,12):"\u2014";t(` ${s.skill.padEnd(r)} ${s.pack.padEnd(12)} pinned ${i} remote ${a} ${o}`)}t();let n=e.filter(s=>s.status==="stale");n.length&&t(ae.dim(`A newer upstream reaches projects with the next Vesper release (maintainers: npm run vendor:sync ${n.map(s=>s.skill).join(" ")}).`)),t()}function Vr(e,{log:t=u}={}){if(!e.rosterFound){t.info(`Packs: no Team Roster at ${e.rosterPath} yet \u2014 nothing to enable (run \`vespercli packs sync\` after the roster is written).`);return}e.enabled.length&&t.success(`Packs enabled for ${e.host}: ${e.enabled.map(Le).join(", ")} (named by the Team Roster).`),e.already.length&&t.info(`Packs already enabled: ${e.already.map(Le).join(", ")}.`),!e.enabled.length&&!e.already.length&&t.info("Packs: the Team Roster names core assets only \u2014 no pack needed."),e.unused.length&&t.info(`Packs enabled but unused by the Team Roster (kept; \`vespercli packs disable <pack>\` removes one): ${e.unused.join(", ")}.`),e.unknownAgents.length&&t.dim(` roster agents not in the catalog (project agents or typos): ${e.unknownAgents.join(", ")}`),e.unknownSkills.length&&t.dim(` roster skills not in the catalog (project skills or typos): ${e.unknownSkills.join(", ")}`)}function Cl(e){if(!e)return;let{gitignore:t,hook:r,mcp:n}=e;(t.status==="created"||t.status==="updated")&&u.info(" .gitignore block written: graphify-out/* ignored, graphify-out/graph.json committed"),t.status==="kept-edited"&&u.warn(Ss(t.path)),r.status==="created"&&u.info(` post-checkout hook block written (\`graphify update .\` after a branch checkout, no-op without the tool): ${r.path}`),r.status==="kept-edited"&&u.warn(Ss(r.path)),r.status==="skipped"&&u.info(` post-checkout hook block not written (${r.reason}) \u2014 run \`vespercli worktree bootstrap\` to install Vesper's hooks, then \`vespercli packs enable graphify\` again.`),n?.added?u.info(" MCP server registered: graphify (`vespercli mcp remove graphify` removes it)"):n?.error&&n.error!=="Already configured"&&u.warn(` MCP server not registered: ${n.error}`);for(let s of Md())u.info(` ${s}`)}async function $l({interactive:e,plan:t,confirmImpl:r=xE,spawnImpl:n,env:s=process.env}){if(dt(s))return{status:"present"};let o=t??mn({env:s});if(!e||!o.command)return{status:"skipped",plan:o};if(!await r({message:`Install graphifyy now? (${o.command})`,default:!0}))return{status:"declined",plan:o};u.info(`Running \`${o.command}\` \u2026`);let a=await Fd(o,n?{spawn:n}:{});if(a.ok){let c=!!dt(s);return u.success(`graphify installed${c?"":" (not on PATH in this shell yet \u2014 open a new shell, or add the installer's bin directory to PATH)"}. Run \`${Ge}\` to build the graph.`),{status:"installed",plan:o,code:a.code}}return u.warn(`\`${o.command}\` failed${a.code!=null?` (exit ${a.code})`:a.error?` (${a.error})`:""} \u2014 nothing else changed. ${o.hint}`),{status:"failed",plan:o,code:a.code,error:a.error}}async function Ol(e,{spawnImpl:t,env:r=process.env}={}){if(!dt(r))return{status:"no-binary"};if(Vd(e))return{status:"graph-exists"};u.info(`Building the code graph (${Ge}) \u2014 first build takes about half a minute\u2026`);let n=await Dd(e,{env:r,...t?{spawn:t}:{}});return n.ok?(u.success(`Code graph built: ${xe} (commit it \u2014 the post-checkout hook keeps it fresh).`),{status:"built",code:n.code}):(u.warn(`\`${Ge}\` failed${n.code!=null?` (exit ${n.code})`:n.error?` (${n.error})`:""} \u2014 the pack stays enabled; run \`${Ge}\` by hand.`),{status:"failed",code:n.code,error:n.error})}function _E(e){if(!e)return;let{gitignore:t,hook:r,mcp:n}=e;t.status==="removed"&&u.info(" .gitignore block removed"),t.status==="kept"&&u.warn(Ss(t.path)),r.status==="removed"&&u.info(` post-checkout hook block removed: ${r.path}`),r.status==="kept"&&u.warn(Ss(r.path)),n?.removed&&u.info(" MCP server removed: graphify"),u.info(" graphify-out/graph.json (if any) is yours to keep or delete; the tool itself is not touched.")}async function CE(e,t){let r=await B(e);(await Oe(e,{checkout:r})).unmigrated&&(u.error(nt),process.exit(1));let n=r.host?[r.host]:await ge(e);!t.target&&n.length>1&&(u.error(et),process.exit(1));let s=t.target||r.host||null;return{host:s,provisioned:!!r.host&&r.host===s}}function zh({host:e,provisioned:t},r){t||(e?u.error(`\`vespercli packs ${r}\` for ${e} needs a workspace provisioned for ${e} \u2014 nothing was written. Run \`vespercli init --host ${e}\` first.`):u.error(`\`vespercli packs ${r}\` needs a workspace provisioned for a host \u2014 nothing was written. Run \`vespercli init\` first.`),process.exit(1))}async function $E(e,{host:t}){let r=rt(),{enabled:n,unknown:s}=t?await Lr(e,t):{enabled:[],unknown:[]},o=t?await lr(e,t):null,i=o!==null?await ur(o):null;if(console.log(),console.log(ae.bold("Vesper packs")),console.log(ae.dim(t?`Host: ${t}${o===null?` (no Team Roster at ${vn[t]})`:""}`:"Host: not provisioned (catalog only)")),console.log(ae.dim("Core (vesper) is always enabled; a pack is enabled when the Team Roster names one of its assets (`vespercli packs sync`).")),console.log(),!r.length){console.log(ae.dim(" (this package ships no packs)")),console.log();return}for(let a of r){let{agents:c,skills:l}=fp(a),d=n.includes(a)?ae.green("enabled"):ae.dim("disabled"),p=i?.needed[a],f=p?` \u2014 roster needs it: ${[...p.agents,...p.skills].join(", ")}`:i?ae.dim(" \u2014 not named by the roster"):"";console.log(` ${ae.bold(a)} (${Le(a)}) ${d}${f}`),console.log(ae.dim(` agents: ${c.join(", ")||"\u2014"}`)),console.log(ae.dim(` skills: ${l.join(", ")||"\u2014"}`)),Ir(a)&&console.log(ae.dim(" opt-in: enabling writes an always-on pointer rule that applies these styles (`vespercli packs enable styles`)")),a===Me&&console.log(ae.dim(` opt-in: graphify is an external tool (\`${Xo}\`); enabling adds the gitignore + post-checkout blocks and the graphify MCP server (\`vespercli packs enable graphify\`)`))}if(s.length&&(console.log(),u.warn(`Enabled pack keys this package does not ship: ${s.join(", ")} (an older/newer Vesper wrote them; \`vespercli packs disable <pack>\` cannot remove an unknown pack \u2014 edit the settings by hand).`)),i){let a=i.packs.filter(c=>!n.includes(c));console.log(),a.length?u.warn(`The Team Roster needs ${a.join(", ")} but they are not enabled \u2014 run \`vespercli packs sync\`.`):u.success("Every pack the Team Roster needs is enabled.")}console.log()}async function Yh(e="list",t,r={}){try{let n=bE(r.path||process.cwd());await w(n)||(u.error(`Directory not found: ${u.formatPath(n)}`),process.exit(1));let s=e||"list";Bh.includes(s)||(u.error(`Unknown packs subcommand: ${s}. Subcommands: ${Bh.join(", ")}`),process.exit(1));let o=await CE(n,r);if(s==="list")return await $E(n,o);if(s==="upstream"){AE(await ea());return}if(s==="sync"){zh(o,"sync");let l=await dr(n,o.host);Vr(l);return}if(t||(u.error(`\`vespercli packs ${s}\` needs a pack name. Packs: ${rt().join(", ")||"none"}`),process.exit(1)),rt().includes(t)||(u.error(`Unknown pack "${t}". Packs: ${rt().join(", ")||"none"}`),process.exit(1)),zh(o,s),s==="enable"){let{enabled:l,rule:d,graphify:p}=await cr(n,o.host,t);l?u.success(`Enabled the ${t} pack (${Le(t)}) for ${o.host}.${o.host==="copilot"?" Reload VS Code to apply.":""}`):u.info(`The ${t} pack is already enabled for ${o.host}.`),(d?.status==="created"||d?.status==="updated")&&u.info(` always-on pointer rule written: ${d.path}`),d?.status==="kept-edited"&&u.warn(nc(d.path)),Cl(p),t===Me&&(await $l({interactive:!!process.stdin.isTTY}),await Ol(n));return}let{disabled:i,rule:a,graphify:c}=await wp(n,o.host,t);if(a?.status==="removed"&&u.info(` always-on pointer rule removed: ${a.path}`),a?.status==="kept"&&u.warn(nc(a.path)),_E(c),i){u.success(`Disabled the ${t} pack (${Le(t)}) for ${o.host}.`);let l=await lr(n,o.host);l!==null&&(await ur(l)).packs.includes(t)&&u.warn(`The Team Roster still names assets of the ${t} pack \u2014 \`vespercli doctor\` will report it; \`vespercli packs sync\` re-enables it.`)}else u.info(`The ${t} pack was not enabled for ${o.host}.`)}catch(n){u.error(`Packs failed: ${n.message}`),process.exit(1)}}pt();Pe();var Tl=["copilot","claude"];function ME(e,t){return Xa(e)}async function GE(e,t,{settingsEntries:r,hooksDir:n=null,hookNames:s,version:o}={}){await cn(e,{frameworkVersion:o}),await od(e,t);let i=await qa(e,t,{settingsEntries:r,hooksDir:n,hookNames:s});await W(e,ME(i,t)),await cd(e)}function qh(e){return e==="claude"?"Claude Code + OpenCode":"GitHub Copilot"}async function Xh(e,t,{thirdPartyBackup:r=null}={}){let n=await Yf(e,{backup:r||void 0}),{info:s,warn:o}=Jf(n);for(let i of s)u.info(i);if(o&&u.warn(o),n.stylesConsent)try{await cr(e,t,Uu)}catch(i){u.warn(`Could not enable the styles pack (${i?.message??i}); run \`vespercli packs enable styles\` by hand.`)}}async function FE(e,t,{legacyHint:r,checkout:n}={}){let s=await ge(t),o=n?n.host:await sn(t),i=o?[o]:s,a=()=>{u.error("Vesper 2.0 provisions exactly one host per workspace \u2014 pass a single `--host claude` or `--host copilot` (not `all` or a comma list)."),process.exit(1)},c=e.host;if(!c&&e.target&&(u.warn("`--target` is deprecated on `init`; use `--host` instead."),c=e.target),c){let h=String(c).toLowerCase();h==="all"&&a();let g=[...new Set(h.split(",").map(y=>y.trim()).filter(Boolean))];for(let y of g)Tl.includes(y)||(u.error(`Unknown host: ${y}. Valid hosts: copilot, claude`),process.exit(1));return g.length>1&&a(),{selected:g,installed:i}}let l=await Gt(t),d=l&&Tl.includes(l.to)?l.to:null,p=r?.needsMigration?Tl.filter(h=>r.hosts?.[h]):[],f=d??(p.length>1?null:o??p[0]??null);if(!process.stdin.isTTY){let h=s.length===1?s[0]:null;if(f&&(p.length===0||(o??h)===f))return{selected:[f],installed:i};u.error(p.length?`Non-interactive run on a pre-2.0 Vesper workspace (${p.join(" + ")}) without --host. Vesper 2.0 provisions exactly one host \u2014 re-run with --host claude or --host copilot to migrate.`:"Non-interactive run without --host, and this checkout carries no Vesper provisioning \u2014 specify the single platform, e.g. --host copilot or --host claude."),process.exit(1)}return{selected:[await LE({message:i.length?"Host for this workspace (Vesper provisions exactly one):":"Which AI host is this workspace for?",choices:[{name:"GitHub Copilot (VS Code)",value:"copilot"},{name:"Claude Code + OpenCode (Claude Code CLI / VS Code extension / JetBrains / desktop; OpenCode reads the same setup)",value:"claude"}],...f?{default:f}:{}})],installed:i}}function DE(e){if(!e)return;console.log();let t=e.level==="warn"?u.warn:u.success;for(let r of e.lines)t(r);console.log()}async function VE(e,t,{backup:r,workspaceRoot:n}={}){let s=await vi({staleDir:void 0,dryRun:!0,workspaceRoot:n});if(s.reason==="absent"||s.reason==="not-ours"||!s.proven?.length)return null;let o=t;if(t||(o=await Kt({message:`Clean the pre-1.9 MACHINE-WIDE Vesper Claude catalog at ${s.path}? ${s.proven.length} file(s) there are byte-identical to a released Vesper build and are removed (backed up first); ${s.kept.length?`${s.kept.length} other file(s) (your edits or your own files) are kept. `:""}Every other pre-1.9 Vesper project on this machine loses its specialists until you run \`vespercli init\` in it.`,default:!0})),!o)return u.info("Left the stale machine-wide Vesper Claude catalog in place (`vespercli doctor` names it)."),null;let i=await vi({backup:r,workspaceRoot:n});return DE(Bp(i)),i}async function HE(e,t={},r=!1){let n="";console.log(),u.header("Installing Vesper for Claude Code"),console.log();let{pluginDir:s,counts:o,pruned:i,keptEdited:a=[]}=await yi({workspaceRoot:e,namePrefix:n,version:t.version});u.success(`Committed fallback surface installed: ${s}`),u.info(` main-thread agent: ${o.agents} (vesper-orchestrator), maintenance skills: ${o.skills}`),u.info(" full specialist catalog served via the vesper marketplace plugin (see .claude/settings.json)"),i.length&&u.info(` pruned ${i.length} legacy project-committed asset(s): ${i.join(", ")}`),a.length&&u.warn(`Left in place \u2014 no longer shipped, but they hold your edits, so Vesper could not prove them its own and no longer tracks them: ${a.map(f=>`.claude/${f}`).join(", ")}. Delete them yourself if you do not need them.`);let c=await ki(e);u.success("Project files ready:"),u.info(` .claude/rules/vesper-orchestrator.md (${c.orchestrator})`),u.info(` .claude/rules/vesper-orchestration.md (${c.orchestration})`),u.info(` .claude/rules/vesper-context.md (${c.context})`),u.info(` .vesper/gates.json (${c.gates})`),u.info(` CLAUDE.md pointer (${c.claudeMd})`);let l=await hr(e,!0),d=await qp(e);u.success(`MCP servers configured: .mcp.json (${l.servers.join(", ")})`);let p=d.opencode||{};u.success("OpenCode overlay ready (the same setup, read by OpenCode):"),u.info(` opencode.json (${p.status||"unchanged"}${p.status==="skipped-malformed"?" \u2014 the file does not parse as JSON; fix it and re-run":""})`),u.info(` .opencode/agents/vesper-orchestrator.md (${c.opencodeAgent})`),u.info(` .opencode/plugins/vesper.js (${c.opencodePlugin})`),c.opencodeKept?.length&&u.warn(`Left in place \u2014 they differ from what Vesper writes (your edits, or an older build's copy), so Vesper could not prove them its own and no longer tracks them: ${c.opencodeKept.join(", ")}. Delete them to get this version's copy on the next init.`),Vr(await dr(e,"claude")),await Xh(e,"claude",t),await rf(e,{pluginPath:Mr(e),namePrefix:n,mcpConfigPath:Ve(e),settingsPath:Fe(e),installedAt:new Date().toISOString()})}async function UE(e,t,r,n={}){console.log(),u.header("Configuring GitHub Copilot"),console.log(),await Zr(e);let s=await Io(e);await $o(e,{maxRequests:r.maxRequests,omitBaseAgentInstructions:r.omitBaseAgentInstructions});let o=await Co(e,r.terminalEnableAutoApprove),i=!1;r.enableMcpServer&&(i=(await Fs(e,!0)).configured,await Lo(e)),await Xn(e);let a=await Mi(e,{version:n.version});return await Xc(e,{settingsEntries:await xt(e)}),Vr(await dr(e,"copilot")),await Xh(e,"copilot",n),u.success("Core assets ensured: agents, prompts, instructions, skills"),u.success("Project brain ready:"),u.info(` .vesper/agents/vesper-orchestrator.agent.md (${a.orchestratorAgent}) \u2014 the one pickable agent`),u.info(` .vesper/instructions/vesper-orchestrator.instructions.md (${a.orchestrator})`),u.info(` .vesper/instructions/vesper-orchestration.instructions.md (${a.orchestration})`),u.info(` .vesper/instructions/vesper-context.instructions.md (${a.context})`),u.info(` .vesper/context/ (${a.contextTier}) \u2014 on-demand tier`),u.info(` .vesper/gates.json (${a.gates})`),u.info(`Max agent requests: ${r.maxRequests}`),o.configured>0?u.info(`Terminal auto-approval: ${o.configured} safe commands configured`):r.terminalEnableAutoApprove===!1&&u.info("Terminal auto-approval: disabled"),i&&(u.info("MCP servers: vesper-indexing, sequential-thinking, memory (.vscode/mcp.json)"),u.info("MCP tools auto-approval: vesper-indexing + context7 + sequential-thinking + memory")),s.workspaceType===he.WORKSPACE_FILE?u.info(`Settings added to: ${Jh(t.settingsPath)}`):u.info("Settings added to: .vscode/settings.json"),u.info("Tracking file: .vesperrc"),u.info("Worktree bootstrap task: .vscode/tasks.json (runs on folder open)"),{mcpConfigured:i}}async function WE(e,t,r=null){let n=await Qn(e);if(!n.found)return{migrated:!1,from:null,preCreated:[],backedUp:!1};let{paths:s}=n;console.log(),u.warn(`Found .vesperrc in nested folder${s.length>1?"s":""}:`);for(let{folderPath:c}of s)u.info(` \u2192 ${c}`);console.log();let o=s[0],i=!0;t||(i=await Kt({message:"Migrate .vesperrc to workspace level? (recommended for multi-root workspaces)",default:!0}));let a=[];if(i&&r)try{let c=await Et(e),l=TE(e,c).split(PE).join("/");l&&!l.startsWith("..")&&!IE(l)&&(await w(c)?await r.snapshot(l):(await r.snapshot(l),a=[l]));for(let{vesperrcPath:p}of s)await r.nestedConfig(p)}catch(c){return u.warn(`Not moving the nested .vesperrc: it could not be backed up first (${c?.message||c}). Nothing was changed.`),console.log(),{migrated:!1,from:null,preCreated:[],backedUp:!1}}if(i){let c=await Eo(e,o.vesperrcPath,o.tracking);if(c.success){if(u.success("Migrated .vesperrc to workspace level"),u.info(` From: ${o.vesperrcPath}`),u.info(` To: ${c.newPath}`),s.length>1){let{unlink:l}=await import("node:fs/promises");for(let d=1;d<s.length;d++)try{await l(s[d].vesperrcPath),u.info(` Removed: ${s[d].vesperrcPath}`)}catch{}}return console.log(),{migrated:!0,from:o.folderPath,preCreated:a,backedUp:!!r}}}else u.info("Migration skipped. .vesperrc will remain in nested folder."),console.log();return{migrated:!1,from:null,preCreated:[],backedUp:!!r&&i}}async function KE(e,t){let r=e;return t||(r=await RE({message:"Workspace root directory:",default:r})),OE(r)}async function BE(e,t,r){let n=[];for(let s of t){let o=qh(s),i=r;if(r||(i=await Kt({message:`${o} is installed but was unchecked. Remove it from this project?`,default:!1})),!i){u.info(`Kept ${o}.`);continue}s==="claude"?await bn(e):await Vs(e),n.push(s),u.success(`Removed ${o} from this project.`)}return n}async function zE(e,t,r,n,{switchSnapshot:s=null}={}){if(await fn(e,t)||(s?.packs||[]).includes(Me))return!1;if(r.graphify)return!0;if(n||r.force||!process.stdin.isTTY)return!1;let i=mn(),a=dt()?"graphify found on PATH":`external tool, not on PATH yet: ${i.command?`\`${i.command}\``:i.hint}`;return Kt({message:`Enable the graphify pack? (code knowledge graph for the research roles \u2014 ${a})`,default:!1})}async function YE(e,t,{interactive:r=!1}={}){try{let n=await cr(e,t,Me);u.success(`Enabled the graphify pack (vesper-graphify) for ${t}.`),Cl(n.graphify)}catch(n){u.warn(`Could not enable the graphify pack (${n?.message??n}); run \`vespercli packs enable graphify\` by hand.`);return}await $l({interactive:r}),await Ol(e)}async function JE(e){if(e)return{maxRequests:je.maxRequests,terminalEnableAutoApprove:je.terminalEnableAutoApprove,omitBaseAgentInstructions:je.omitBaseAgentInstructions,enableMcpServer:je.enableMcpServer};console.log(),u.info("Configure VS Code Chat settings:");let t=await NE({message:"Max agent requests per session (chat.agent.maxRequests):",default:je.maxRequests,min:1,max:1e3}),r=await Kt({message:"Controls whether terminal commands are automatically approved. Enable terminal auto-approval? (chat.tools.terminal.enableAutoApprove)",default:je.terminalEnableAutoApprove});r&&u.info("Terminal auto-approval enabled with safe command whitelist");let n=await Kt({message:"Omit base agent instructions for custom agents? (github.copilot.chat.omitBaseAgentInstructions)",default:je.omitBaseAgentInstructions}),s=await Kt({message:"Enable vesper-indexing MCP server for fast code search?",default:je.enableMcpServer});return{maxRequests:t||je.maxRequests,terminalEnableAutoApprove:r,omitBaseAgentInstructions:n,enableMcpServer:s}}async function ta(e,t=!1){let r=Be().replace("index.js","cli-index.js");if(!await w(r))return{success:!1,error:"MCP server not built"};t&&(console.log(),u.info("Starting workspace indexing..."));let n=t?null:u.createSpinner("Indexing workspace...");return n&&n.start(),new Promise(s=>{let o=jE(process.execPath,["--disable-warning=ExperimentalWarning",r,e],{stdio:["ignore","pipe","pipe"],env:{...process.env}}),i="",a=0;o.stderr.on("data",c=>{let l=c.toString().trim(),d=l.match(/Indexed (\d+) files/);if(d&&(a=parseInt(d[1],10),n&&n.update(`Indexing workspace... ${a} files`)),t&&l)for(let p of l.split(`
202
+ `))p.trim()&&u.info(p.replace("[vesper-indexing] ",""))}),o.stdout.on("data",c=>{i+=c.toString()}),o.on("close",c=>{try{let l=JSON.parse(i.trim());l.success?n?n.succeed(`Workspace indexed: ${l.filesIndexed} files`):u.success(`Workspace indexed: ${l.filesIndexed} files`):n?n.fail(`Indexing failed: ${l.error}`):u.error(`Indexing failed: ${l.error}`),s(l)}catch{c===0?(n?n.succeed(`Workspace indexed: ${a} files`):u.success(`Workspace indexed: ${a} files`),s({success:!0,filesIndexed:a})):(n?n.fail("Indexing failed"):u.error("Indexing failed"),s({success:!1,error:"Unknown error"}))}}),o.on("error",c=>{n?n.fail(`Indexing failed: ${c.message}`):u.error(`Indexing failed: ${c.message}`),s({success:!1,error:c.message})})})}function qE({copilot:e,claude:t,indexingResult:r}){console.log(),u.success("Vesper is ready."),r?.success?u.info(`Code index built: ${r.filesIndexed} files.`):r?.error&&u.info("Code index will be built on first MCP server start."),console.log(),u.header("Next Steps"),console.log(),e&&(u.info("GitHub Copilot \u2014 reload VS Code to activate Vesper:"),u.info(' Cmd+Shift+P (macOS) / Ctrl+Shift+P (Windows/Linux) \u2192 "Developer: Reload Window"')),t&&(u.info("Claude Code \u2014 open a session in this workspace; the orchestrator"),u.info(" activates automatically via the always-on rules in .claude/rules/ plus the"),u.info(" default-agent key in .claude/settings.json (vesper-orchestrator)."),u.info(" Committed to the repo: the orchestrator agent, four maintenance skills, and"),u.info(" the three .claude/rules/vesper-*.md files. The full specialist catalog ships"),u.info(' as the "vesper" marketplace plugin \u2014 Claude Code shows a one-time'),u.info(" workspace-trust dialog to load it (decline it, or a cloud/headless session,"),u.info(" and Vesper runs in degraded mode on the committed fallback)."),u.info("OpenCode \u2014 open the same checkout: opencode.json makes vesper-orchestrator the"),u.info(" default agent, loads the three .claude/rules files as instructions, runs the MCP"),u.info(" servers through `vespercli mcp serve`, and .opencode/plugins/vesper.js registers"),u.info(" the specialists. Commit opencode.json and .opencode/ with the rest.")),console.log(),e&&u.vesperTip()}async function Qh(e={}){try{await XE(e)}finally{kl()}}async function XE(e){try{let t=e.yes||e.forceDefault,r=await KE(e.path||process.cwd(),t);await w(r)||(u.error(`Directory not found: ${u.formatPath(r)}`),process.exit(1));let n=await q(r),s=await B(r),o=await Oe(r,{checkout:s}),i=n.type===he.WORKSPACE_FILE?await Qn(r):{found:!1,paths:[]},a=i.found&&i.paths.some(j=>!(Number(j?.tracking?.schemaVersion)>=2)),c=await af(r);c&&u.warn(`An interrupted migration's record (${c.from}) was unreadable and was set aside as ${Jh(c.to)}; its backups are kept. If files look half-migrated, restore them from that folder.`);let l=await _h(r),d=await Yi(r),p=null;if(o.needsMigration||a){let j=await Sh(r,{record:o.record}),Q=l?.status==="started"&&l.latest.head===d&&l.root.head===d?l:null;if(j.dirty.length){let st=Q?await $h(r,Q,j):j.dirty;st.length&&(u.error(Eh(st,{interrupted:Q?Q.latest.dir:null})),process.exit(1)),u.warn(`Resuming an interrupted migration (its backups: ${Q.latest.dir}) \u2014 every uncommitted change is its own write.`)}p=Q}let f=fl(r),m={migrated:!1,preCreated:[],backedUp:!1};n.type===he.WORKSPACE_FILE&&(m=await WE(r,t,f),i.found&&(o=await Oe(r,{checkout:s})));let{selected:h,installed:g}=await FE(e,r,{legacyHint:o,checkout:s}),y=h[0],k=y==="claude"?"copilot":"claude",v=o.needsMigration&&o.hosts[k]?k:null,S=null,C=s,N=async()=>!!y&&!!C.host&&C.host!==y&&(await Pr(r,C.host)||await Er(r,C.host)),E=!!v||await N(),b=()=>v??C.host;await Ka(r)&&(u.warn(`An unreadable host-switch journal (${ir}) was found and removed: an earlier switch was interrupted before its record was saved. Check your added assets and MCP servers (\`vespercli list\`, \`vespercli mcp list\`) and re-add any that are missing.`),await sl(r));let F=await Gt(r),X=F?F.snapshot:null;if(F&&u.warn(E?`Resuming an interrupted host switch (${F.from} \u2192 ${F.to}, started ${F.startedAt}): completing it now \u2014 ${b()}'s remaining Vesper artifacts are cleaned, and the assets and MCP servers preserved when it started are restored onto ${y}.`:`Resuming an interrupted host switch (${F.from} \u2192 ${F.to}, started ${F.startedAt}): its preserved assets and MCP servers will be restored onto ${y}.`),E){let j=b(),Q=v?`the pre-2.0 (1.x) ${j} setup`:`${j}'s Vesper artifacts`;if(!t&&!process.stdin.isTTY&&(u.error(`This workspace is provisioned for "${j}"${v?" (pre-2.0)":""}; switching to "${y}" removes ${Q}. Re-run with --yes to confirm (non-interactive), or interactively.`),process.exit(1)),!t&&!await Kt({message:`Switch this workspace from ${j} to ${y}? This removes ${Q}. Your .vesper/.tracking/ (run ledger included) and memory.jsonl are untouched, and the Team Roster + project whitepaper are preserved.`,default:!1})){u.info("Initialization cancelled.");return}}let He=null;if(o.needsMigration){if(l?.status==="started"&&l!==p){let st=await Ch(l);u.warn(`An interrupted migration from another commit (${l.root.head?l.root.head.slice(0,12):"no git"}) cannot be resumed and was abandoned; its backups are kept \u2014 remove them when you no longer need them: ${st.join(", ")}`)}let j=await vi({dryRun:!0,workspaceRoot:r});S=await vl(r,f,{record:o.record,previousVersion:await Th(r,o.record,j.version||null),chain:p,preCreated:m.preCreated});let Q=v??y;He=await Ih(r,y,{legacy:o,recordHost:Q,frameworkVersion:e.version,log:u,backup:f}),C={host:Q,source:"migration"},E=!!v||E&&await N()}else l&&(u.warn(`Completing an interrupted 1.x migration (its backups: ${l.latest.dir}): its rollback record is finished and its backup and rollback guidance printed at the end of this run.`),l.latest.head===d?S=await vl(r,f,{record:o.record,chain:l}):l.status==="started"&&await Sl(r,l.latest.dir));if(E){await nl(r,C.host),F||(X=await ol(r),await qf(r,{from:C.host,to:y,snapshot:X}));let{retained:j}=await Vi(r,C.host,{fullTeardown:!0});await Cn(r,j,C.host,u)}let Tn=E||He?[]:g.filter(j=>!h.includes(j));if(h.length===0&&Tn.length===0){u.info("No platforms selected. Nothing to do.");return}if(!t&&g.length===0&&h.length>0&&!await Kt({message:`Set up ${h.map(qh).join(" + ")} in ${r}?`,default:!0})){u.info("Initialization cancelled.");return}Tn.length>0&&await BE(r,Tn,t);let _t=h.includes("copilot"),zt=h.includes("claude"),Ue=null;_t&&(Ue=await JE(t));let yr=await zE(r,y,e,t,{switchSnapshot:X}),wr={...e,thirdPartyBackup:He?j=>f.project(j):null};_t&&(await ld(r,"copilot"),await UE(r,n,Ue,wr)),zt&&await HE(r,wr,g.includes("claude"));let Ct=null;if((_t||zt)&&(Ct=await VE(g.includes(y),t,{backup:async j=>f.home(j),workspaceRoot:r}),Ct?.kept?.length&&(Ct.removed||Ct.partial)))try{await El(f,Ct.kept.map(j=>({rel:`~/.claude/skills/vesper/${j}`,reason:"plugin-folder"})))}catch{}if(_t||zt){let j=await Wh(r);j.archived&&u.success(`Archived .vesper/history.md \u2192 ${j.to} (${j.method==="git"?"git mv, staged":"moved"}). Vesper 2.0 keeps the run ledger under .vesper/.tracking/runs/ instead; the archive is read-only and reachable by /revalidate-knowledge.`)}let oa=null,Pn=[];if(_t||zt){await zn(r);let j=await Yn(r);if(j.length>0){let $t=j.map(Zm=>`'${Zm.replace(/'/g,"'\\''")}'`);u.warn(`Local-only file(s) are git-tracked despite .gitignore: ${$t.join(", ")}`),u.warn(`Untrack them yourself (Vesper won't touch your git index): git rm --cached -- ${$t.join(" ")}`)}let Q=await ts(r);Pn=ct.filter($t=>Q[$t]&&!Q[$t].reason),oa=Pn.length&&Q[Pn[0]].hooksDir||null;for(let $t of es(Q))$t.startsWith("Git hooks not installed")?u.info($t):u.warn($t);oa&&(u.success("Local-only Vesper files gitignored (.vesperrc, .mcp.json, .vesper/index.db)"),Pn.includes("pre-commit")&&u.info("Commit-hygiene git hook installed (pre-commit): keeps team roster/context/tracking/memory in sync with every commit")),yr&&await YE(r,y,{interactive:!t&&!e.force&&!!process.stdin.isTTY});let st=await rs(r);await ns(r),st.skipped||u.info("Merge strategy configured (.gitattributes): memory.jsonl merges entity-aware across worktrees, recent-decisions.md unions")}if(h.length===1){let j=h[0],Q=j==="copilot"?await xt(r):void 0;await GE(r,j,{settingsEntries:Q,hooksDir:oa,hookNames:Pn,version:e.version}),X&&(await Xf(r,j,X),await sl(r));let{legacyGuardRule:st}=await Pi(r,j);st==="kept"&&u.warn(xn())}if(He)try{let Q=(await _n(r)).findings.filter(st=>st.code.startsWith("legacy-"));Q.length&&u.warn(`The migration left ${Q.length} pre-2.0 item(s) \u2014 see \`vespercli doctor\`.`)}catch{}if(S)try{await Sl(r,f.dir)}catch(j){u.warn(`Could not finish the migration's rollback record (${j?.message||j}); the backups are under .vesper/.migration-backup/.`)}let Qm=_t&&Ue?.enableMcpServer||zt,Wl=null;Qm&&(Wl=await ta(r,!0));let In=[];if((S||Ct?.backedUpTo||m.backedUp)&&In.push(f.dir),l&&!o.needsMigration&&!S&&In.push(l.latest.dir),In.length)try{let j=await Ph(r,{runDirs:In});if(j.length){console.log();for(let Q of j)u.info(Q)}await Oh(r,In)}catch(j){u.warn(`Could not print the migration backup guidance (${j?.message||j}); the backups are under .vesper/.migration-backup/.`)}qE({copilot:_t,claude:zt,indexingResult:Wl})}catch(t){if(t.name==="ExitPromptError"){console.log(),u.info("Initialization cancelled.");return}t.name==="HostCleanRefused"&&(u.error(t.message),process.exit(1)),u.error(`Initialization failed: ${t.message}`),process.exit(1)}}U();H();te();be();Ee();Ae();Ut();import{resolve as QE,join as Zh}from"node:path";import{checkbox as ZE}from"@inquirer/prompts";Pe();var em=["agents","skills"];async function eb(e,t){let r=t?[t]:await ge(e);return r.length===0&&(u.warn('Vesper is not initialized in this workspace. Run "vespercli init" first.'),process.exit(0)),r.length>1&&(u.error(et),process.exit(1)),r[0]}async function tm(e,t,r){r!==t&&(u.error(`\`vespercli add\` for ${t==="claude"?"Claude Code":"Copilot"} needs a workspace provisioned for ${t}${r?` (this one is provisioned for ${r})`:""} \u2014 nothing was written. Run \`vespercli init --host ${t}\` first.`),process.exit(1))}async function tb(e,t){return await Ps(e,t)!==null}async function rb(e,t,r){if(!t.type||!t.name){u.info("Every Vesper specialist and skill is served by the vesper plugin as `vesper:<name>` \u2014 there is nothing to add."),u.info("To pin a project-level copy anyway: vespercli add <agents|skills> <name> --override");return}if(t.type==="prompts"&&(u.error("Vesper 2.0 ships its maintenance workflows as skills (served by the plugin); slash commands are no longer provisioned."),process.exit(1)),em.includes(t.type)||(u.error(`Unknown asset type for Claude Code: ${t.type}. Types: ${em.join(", ")}`),process.exit(1)),await tb(t.type,t.name)||(u.error(`${t.type}/${t.name} is not in the Vesper catalog.`),process.exit(1)),!t.override){let n=await Ps(t.type,t.name),s=t.type==="agents"?await vp(t.name):`/${n.pack==="core"?"vesper":`vesper-${n.pack}`}:${t.name}`;u.info(`\`${t.name}\` is already available as \`${s}\` from the ${n.pack==="core"?"vesper plugin":`vesper-${n.pack} pack (enabled per project by \`vespercli packs sync\`)`} \u2014 nothing to add.`),u.info("A project-level copy would shadow the plugin's version. To pin one anyway (not recommended): add --override.");return}await tm(e,"claude",r);try{let n=await wi(t.type,t.name,{workspaceRoot:e,namePrefix:await on(e)});u.success(`Pinned a project-level copy of ${t.type}/${t.name} as "${n.installedAs}" (recorded; \`vespercli reset --host claude\` removes it).`)}catch(n){u.error(n.message),process.exit(1)}}async function nb(e,t,r){let n=await Df(),s=new Set(await bt(e)),o=c=>[...s].some(l=>l.replace(/\\/g,"/").endsWith(`/instructions-extended/${c}`));if(t.type&&t.type!=="instructions"){Xe[t.type]||(u.error(`Unknown asset type: ${t.type}. Types: ${Object.keys(Xe).join(", ")}`),process.exit(1));let c=ci(),l=[...new Set([...await Zs(t.type),...c[t.type]||[]])];t.name&&!l.includes(t.name)&&(u.error(`${t.type}/${t.name} is not in the Vesper catalog.`),process.exit(1));let d=t.name?c.assetPacks[t.type]?.[t.name]??"core":"core",p=d==="core"?`${Zh(Ot,Xe[t.type].dir)} (the whole folder is injected)`:`${Zh(Ot,"packs",d,Xe[t.type].dir)} (the ${d} pack's folder, injected when the pack is enabled \u2014 \`vespercli packs sync\`)`;u.info(`Copilot reads every Vesper ${t.type.replace(/s$/,"")} from ${p}${t.name?` \u2014 \`${t.name}\` is already available`:""}. Nothing to add.`);return}let i=[];if(t.name)n.includes(t.name)||(u.error(`Unknown opt-in instruction: ${t.name}. Available: ${n.join(", ")||"none"}`),process.exit(1)),i=[t.name];else{let c=n.filter(l=>!o(l));if(c.length===0){u.info("Every opt-in instruction is already added.");return}if(!process.stdin.isTTY){u.info(`Opt-in instructions you can add: ${c.join(", ")} \u2014 run \`vespercli add instructions <name>\`.`);return}if(i=await ZE({message:"Select opt-in instructions to add:",choices:c.map(l=>({name:l,value:l}))}),i.length===0){u.info("Nothing selected.");return}}await tm(e,"copilot",r);let a=[];for(let c of i)(await Gi(e,c)).added&&a.push(c);a.length?u.success(`Added opt-in instruction(s): ${a.join(", ")} \u2014 reload VS Code to apply.`):u.info("All selected instructions were already added.")}async function rm(e={}){try{let t=QE(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await B(t);return(await Oe(t,{checkout:r})).unmigrated&&(u.error(nt),process.exit(1)),(e.target||await eb(t,r.host))==="claude"?await rb(t,e,r.host):await nb(t,e,r.host)}catch(t){if(t.name==="ExitPromptError"){console.log(),u.info("Cancelled.");return}u.error(`Add failed: ${t.message}`),process.exit(1)}}U();Ee();H();import{resolve as sm,join as sb}from"node:path";import{readdir as om}from"node:fs/promises";te();be();Ae();Ut();Pe();import se from"picocolors";async function nm(e={},t){let r=sm(e.path||process.cwd());if(console.log(),console.log(se.bold("Claude Code target")),t!=="claude"){console.log(),u.warn('Not initialized for Claude Code. Run "vespercli init --host claude" first.'),console.log();return}let n=await id(r)||Mr(r);console.log(se.dim(`Project catalog: ${n}`));let s=await Wo(r),o=Qs();s&&o&&s!==o&&u.warn(`Catalog drift: installed catalog is v${s}, but Vesper is v${o}. Run \`vespercli update\` to refresh the committed orchestrator, maintenance skills and playbook.`);let i=await Kp(r);for(let[a,c]of Object.entries(i))console.log(),console.log(se.bold(a.charAt(0).toUpperCase()+a.slice(1))),c.length===0?console.log(se.dim(" (none installed)")):c.forEach(l=>console.log(` ${l}`));console.log(),console.log(se.dim("The full specialist catalog is served by the vesper plugin (vesper:<name>) and its packs (vesper-<pack>:<name>) \u2014 see `vespercli catalog`.")),await im(r,"claude"),console.log(),console.log(se.bold("Project files")),console.log(" CLAUDE.md (pointer), .claude/rules/vesper-{orchestrator,orchestration,context}.md, .mcp.json, .claude/settings.json"),console.log()}async function im(e,t){let r=rt();if(console.log(),console.log(se.bold("Packs")),!r.length){console.log(se.dim(" (this package ships no packs)"));return}let{enabled:n,unknown:s}=await Lr(e,t),o=await lr(e,t),i=o!==null?await ur(o):null;for(let a of r){let c=n.includes(a)?se.green("(enabled)"):se.dim("(disabled)"),l=i?.packs.includes(a)?n.includes(a)?se.dim("\u2014 roster needs it"):se.yellow("\u2014 roster needs it: run `vespercli packs sync`"):"";console.log(` ${a} ${c} ${l}`.trimEnd())}s.length&&console.log(se.yellow(` enabled but not shipped by this package: ${s.join(", ")}`)),console.log(se.dim(" `vespercli packs` for contents; `vespercli packs sync` enables what the Team Roster names."))}async function ob(e,t){try{let r=await om(sb(e,".vesper",t),{withFileTypes:!0});return t==="skills"?r.filter(n=>n.isDirectory()&&!n.name.startsWith(".")).map(n=>n.name).sort():r.filter(n=>n.isFile()&&n.name.endsWith(".md")).map(n=>n.name.replace(/\.(agent|instructions|prompt)\.md$|\.md$/,"")).sort()}catch{return[]}}async function ib(){try{return(await om(Kn,{withFileTypes:!0})).filter(e=>e.isFile()&&e.name.endsWith(".md")).map(e=>e.name.replace(/\.instructions\.md$|\.md$/,"")).sort()}catch{return[]}}async function ab(e,t){let n=(await bt(e)).map(o=>/\/instructions-extended\/([^/]+)\/?$/.exec(String(o).replace(/\\/g,"/"))).filter(Boolean).map(o=>o[1]).sort(),s=t.type?[t.type]:Object.keys(Xe);console.log(),console.log(se.bold("GitHub Copilot target")),console.log(se.dim(`Package catalog: ${Ot}`));for(let o of s){let i=o.charAt(0).toUpperCase()+o.slice(1),a=o==="instructions"?await ib():await Zs(o),c=await ob(e,o),l=o==="instructions"?n:[];if(console.log(),console.log(se.bold(i)),!a.length&&!c.length&&!l.length){console.log(se.dim(" (none)"));continue}a.forEach(d=>console.log(` ${d} ${se.dim("(package)")}`)),l.forEach(d=>console.log(` ${d} ${se.dim("(opt-in)")}`)),c.forEach(d=>console.log(` ${d} ${se.dim("(project)")}`))}await im(e,"copilot"),console.log()}async function am(e={}){try{let t=sm(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await B(t),n=r.host,s=n?[n]:await ge(t);if(e.target==="claude")return await nm({...e,path:t},n);if(!e.target){if((await Oe(t,{checkout:r})).unmigrated&&(u.error(nt),process.exit(1)),s.length===0){console.log(),u.warn('Vesper is not initialized. Run "vespercli init" first.'),console.log();return}if(s.length>1&&(u.error(et),process.exit(1)),s[0]==="claude")return await nm({...e,path:t},n)}e.type&&!Xe[e.type]&&(u.error(`Unknown asset type: ${e.type}`),u.info(`Valid types: ${Object.keys(Xe).join(", ")}`),process.exit(1)),await ab(t,e)}catch(t){u.error(`List failed: ${t.message}`),process.exit(1)}}Ee();import{readFileSync as cb,existsSync as lb}from"node:fs";import{join as ub}from"node:path";var Pl=ub(O,"CATALOG.md");function db(){return lb(Pl)?cb(Pl,"utf-8"):null}async function cm(){let e=db();e===null&&(console.error(`Error loading catalog: ${Pl} not found in the installed package.`),process.exit(1)),console.log(e)}U();H();te();be();Ae();import{resolve as mm,join as zs,dirname as dm}from"node:path";import{stat as pb,readFile as gm}from"node:fs/promises";import{existsSync as fb}from"node:fs";import{spawn as hb}from"node:child_process";import"@inquirer/prompts";H();pt();var lm=Object.freeze(Object.keys(we)),KP=Object.freeze(["vesper-indexing","sequential-thinking","memory"]);function Il(e,{workspaceRoot:t,env:r,indexingPath:n}){return String(e).replace(/\$\{VESPER_INDEXING_PATH\}/g,n).replace(/\$\{workspaceFolder\}/g,t).replace(/\$\{env:([^}]+)\}/g,(s,o)=>r[o]??"")}function um(e,t,{env:r=process.env,indexingPath:n=Be(),which:s}={}){let o=we[e];if(!o||!o.config)return null;if(e===Vt)return{command:Hd(String(t),{env:r||{},...s?{which:s}:{}}),args:["-m","graphify.serve",`${t}/${xe}`],env:{}};let{type:i,...a}=structuredClone(o.config),c={workspaceRoot:String(t),env:r||{},indexingPath:n},l={command:Il(a.command,c),args:(Array.isArray(a.args)?a.args:[]).map(d=>Il(d,c)),env:{}};for(let[d,p]of Object.entries(a.env||{})){let f=Il(p,c);f!==""&&(l.env[d]=f)}return l}pt();Pe();import ht from"picocolors";async function ym(e,t){if(!t.includes(Vt))return;let r=await w(zs(e,xe));console.log(),u.info(`graphify (opt-in pack): configured \u2014 tool on PATH: ${dt()?"\u2713 yes":`\u2717 no (${Zo()})`}; ${xe}: ${r?"\u2713 exists":`\u2717 missing (run \`${Ge}\`)`}`)}async function pm(e,t){if(console.log(),u.header("vesper-indexing MCP Server (Claude Code target)"),console.log(),t!=="claude"){u.info("Claude Code target is not initialized. Run `vesper init --target claude` first.");return}let r=Ve(e),n=!1;if(await w(r))try{n=!!JSON.parse(await gm(r,"utf-8")).mcpServers?.["vesper-indexing"]}catch{n=!1}u.info(`Configured: ${n?"\u2713 yes":"\u2717 no"} (${r})`),u.info(`Server built: ${Em(await Sm())}`);let s=Rl(e);u.info(`Index exists: ${await w(s)?"\u2713 yes":"\u2717 no"} (shared with the Copilot target if both are installed)`),await ym(e,(await Rc(e)).configured);try{let{drifted:o}=await ji(e);o.length&&(console.log(),u.warn(`MCP config drift: ${o.join(", ")} present in the live MCP config but not tracked in .vesperrc mcp.servers.`),u.warn("Run `/reinit` (or re-run workspace-learner) to resync tracking and the generated docs."))}catch{}}var wm=new Set(["enable","disable","sync","add","remove"]),mb=wm,vm="Vesper regenerates them at every session start \u2014 `vespercli mcp disable` makes no lasting change.";function gb(e){return`\`vespercli mcp ${e}\` for Claude Code needs a workspace provisioned for Claude \u2014 nothing was written. Run \`vespercli init --host claude\` first.`}async function jl(e,t=!0){if(await hr(e,t),t){let r=await Jp(e);r.skipped==="malformed"&&u.warn(`${r.settingsPath} is not valid JSON \u2014 MCP tool permissions were not added (the file was left as found).`)}t?u.success("Claude Code target: vesper-indexing enabled in .mcp.json"):(u.success("MCP servers removed from .mcp.json until the next session start"),u.info(vm))}function Rl(e){return zs(e,".vesper","index.db")}function yb(e){return zs(e,".vesper","indexing-status.json")}async function km(e){let t=yb(e);try{let r=await gm(t,"utf-8");return JSON.parse(r)}catch{return null}}async function Sm(){let e=Be();if(!await w(e))return"missing";let t=dm(dm(e)),r=[zs(t,"node_modules","@modelcontextprotocol","sdk","package.json"),zs(t,"node_modules","zod","package.json")];for(let n of r)if(!await w(n))return"broken";return"ready"}function Em(e){switch(e){case"ready":return"\u2713 yes";case"broken":return"\u26A0 yes, but dependencies missing \u2014 run 'npm install' in src/mcp/vesper-indexing (or reinstall Vesper)";default:return"\u2717 no"}}async function wb(e){try{let t=await pb(e),r=t.size,n=`${r} bytes`;return r>1024*1024?n=`${(r/(1024*1024)).toFixed(2)} MB`:r>1024&&(n=`${(r/1024).toFixed(1)} KB`),{dbSize:n,lastModified:t.mtime.toISOString()}}catch{return null}}async function fm(e,t=!1){let r=await No(e),n=await Sm(),s=Rl(e),o=await w(s),i=await km(e);if(console.log(),u.header("vesper-indexing MCP Server"),console.log(),u.info(`Configured: ${r?"\u2713 yes":"\u2717 no"}`),u.info(`Server built: ${Em(n)}`),u.info(`Index exists: ${o?"\u2713 yes":"\u2717 no"}`),await ym(e,await Mo(e)),i)if(console.log(),i.status==="indexing")if(t){await vb(e,i);return}else{let a=i.startedAt?Math.round((Date.now()-new Date(i.startedAt).getTime())/1e3):0;u.info(ht.yellow("\u27F3 Indexing in progress...")),u.info(` Files processed: ${ht.cyan(i.filesProcessed)}`),u.info(` Elapsed: ${ht.dim(`${a}s`)}`),console.log(),u.info("Use --watch to follow indexing progress until completion")}else i.status==="error"&&(u.error(`Indexing error: ${i.error}`),u.info(` Files processed before error: ${i.filesProcessed}`));if(!r){console.log(),u.info("Run `vespercli init` to configure the MCP server");return}if(n==="missing"){console.log(),u.warn("MCP server not built. Run: cd src/mcp/vesper-indexing && npm install && npm run build");return}if(n==="broken"){console.log(),u.warn("MCP server dependencies are missing/corrupt. Run: cd src/mcp/vesper-indexing && npm install (or reinstall Vesper)");return}if(o&&!i){let a=await wb(s);a&&(console.log(),u.info(`Index size: ${a.dbSize}`),u.info(`Last modified: ${a.lastModified}`)),u.vesperTip()}else!o&&!i&&(console.log(),u.info("Index not yet created. It will be built when VS Code loads the MCP server."),console.log())}async function vb(e,t){let r=u.createSpinner(`Indexing... ${t.filesProcessed} files processed`);r.start();let n=500,s=30*60*1e3,o=Date.now();return new Promise(i=>{let a=async()=>{let c=await km(e);if(!c||c.status!=="indexing"){c?.status==="error"?r.fail(`Indexing failed: ${c.error}`):(r.succeed(`Indexing complete! ${c?.filesProcessed||"All"} files indexed`),u.info(`
203
+ \u2192 Reload VS Code to update MCP tools with the new index`),u.vesperTip()),i();return}let l=c.startedAt?Math.round((Date.now()-new Date(c.startedAt).getTime())/1e3):0;if(r.update(`Indexing... ${c.filesProcessed} files processed (${l}s)`),Date.now()-o>s){r.fail("Indexing watch timed out (30 minutes)"),i();return}setTimeout(a,n)};setTimeout(a,n)})}async function hm(e,t=!1){let r=Rl(e);if(!await w(r))u.info("No index exists. It will be built when VS Code loads the MCP server.");else if(t){let{unlink:s}=await import("node:fs/promises");await s(r),u.success("Index cleared. Reload VS Code to rebuild.")}else u.info("Incremental reindex happens automatically when files change."),u.info("Use --full to clear and rebuild the entire index.")}async function kb(e){let t=await Ar(e,!0);t.configured&&(u.success("MCP server enabled"),u.info(`Config: ${t.mcpPath}`),u.info("Reload VS Code to start the server"))}async function Sb(e){await Ar(e,!1),u.success("MCP servers removed from .vscode/mcp.json until the next session start"),u.info(vm),u.info("Reload VS Code to apply changes")}async function bm(e){let t=await bt(e),r=[];for(let n of t){let s=n.match(/agents\/([^/]+)\/?$/);s&&MCP_TOOLS_BY_AGENT[s[1]]&&r.push(s[1])}return r}async function Eb(e){let t=await q(e),r=await x(e,t),n=await K(e,t),s=await bm(e),o=n[V]||{},i=new Set(Re),a=[],c=[],l=!1;n[V]||(n[V]={});for(let p of Re)o[p]||(n[V][p]=!0,a.push(p),l=!0);for(let p of s){let f=MCP_TOOLS_BY_AGENT[p]||[];for(let m of f)o[m]||(n[V][m]=!0,a.push(m),l=!0)}let d=new Set;for(let p of s)for(let f of MCP_TOOLS_BY_AGENT[p]||[])d.add(f);for(let p of Object.keys(o)){if(i.has(p))continue;let f=!1;for(let[m,h]of Object.entries(MCP_TOOLS_BY_AGENT))if(h.includes(p)){f=!0;break}f&&!d.has(p)&&(delete n[V][p],c.push(p),l=!0)}if(r.mcp=r.mcp||{},r.mcp.syncedAt=new Date().toISOString(),r.mcp.approvedAgents=s,r.mcp.toolCount=Object.keys(n[V]).length,l&&await ce(e,n),await T(e,r),console.log(),u.header("MCP Tools Sync"),console.log(),a.length===0&&c.length===0)u.success("Already in sync");else{if(a.length>0){u.success(`Added ${a.length} tool(s)`);let p=a.filter(f=>i.has(f));p.length>0&&u.info(` Core: ${p.length} tools`);for(let f of s){let m=a.filter(h=>(MCP_TOOLS_BY_AGENT[f]||[]).includes(h));m.length>0&&u.info(` ${f}: ${m.length} tools`)}}c.length>0&&u.info(`Removed ${c.length} orphaned tool(s)`)}u.info(`
191
204
  Total approved tools: ${r.mcp.toolCount}`),s.length>0&&u.info(`Agents with tools: ${s.join(", ")}`),l&&u.info(`
192
- Reload VS Code to apply changes`)}async function lE(e){let t=await z(e),r=await x(e,t),s=(await J(e,t))[V]||{},o=Object.keys(s).length,i=await Oh(e);console.log(),u.header("MCP Tool Approval Status"),console.log();let a=je.filter(d=>s[d]);if(u.info(`Core tools: ${a.length}/${je.length} approved`),i.length>0){console.log(),u.info("Agent tools:");for(let d of i){let p=MCP_TOOLS_BY_AGENT[d]||[],h=p.filter(f=>s[f]),m=h.length===p.length?it.green("\u2713"):it.yellow("\u26A0");u.info(` ${m} ${d}: ${h.length}/${p.length} approved`)}}let c=[...je];for(let d of i)c.push(...MCP_TOOLS_BY_AGENT[d]||[]);let l=c.filter(d=>!s[d]);console.log(),u.info(`Total approved: ${o} tools`),l.length>0?(console.log(),u.warn(`${l.length} tools missing approval`),u.info("Run `vespercli mcp sync` to fix")):r.mcp?.syncedAt&&u.info(`Last synced: ${r.mcp.syncedAt}`)}function Th(){return Object.keys(we).filter(e=>!fe.includes(e))}async function uE(e,t){t||(u.error("Server name required. Usage: vespercli mcp add <server>"),u.info(`Available servers: ${Th().join(", ")}`),process.exit(1)),console.log(),u.header("Add MCP Server"),console.log();let r=await Kr(e,t);if(!r.added){r.error==="Already configured"?u.info(`MCP server '${t}' is already configured`):(u.error(r.error),process.exit(1));return}u.success(`Added MCP server: ${t}`),r.tools.length>0&&u.info(`Approved ${r.tools.length} tool(s) for auto-execution`),u.info(`
193
- Reload VS Code to activate the MCP server`)}async function dE(e,t){t||(u.error("Server name required. Usage: vespercli mcp remove <server>"),process.exit(1)),console.log(),u.header("Remove MCP Server"),console.log();let r=await yo(e,t);if(!r.removed){u.info(`MCP server '${t}' is not configured`);return}u.success(`Removed MCP server: ${t}`),r.tools.length>0&&u.info(`Removed ${r.tools.length} tool(s) from auto-approval`),u.info(`
194
- Reload VS Code to deactivate the MCP server`)}async function pE(e){let t=await z(e),r=await x(e,t),n=await Ye(e);console.log(),u.header("MCP Servers"),console.log();let s=r.mcp?.servers||[],o=Object.keys(n.servers||{});u.info("Available servers:");for(let[a,c]of Object.entries(we)){let d=o.includes(a)?it.green("\u2713"):it.dim("\u25CB"),p=c.tools?.length||0;u.info(` ${d} ${a} (${p} tools)`)}let i=o.filter(a=>!we[a]);if(i.length>0){console.log(),u.info("Custom servers:");for(let a of i)u.info(` ${it.blue("\u25C6")} ${a}`)}console.log(),u.info(`Installed: ${o.length} server(s)`)}async function fE(e,t){t||(u.error("Server name required. Usage: vespercli mcp add <server> --target claude"),u.info(`Available servers: ${Th().join(", ")}`),process.exit(1));let r=await Xo(e,t);if(!r.added){r.error==="Already configured"?u.info(`MCP server '${t}' is already configured for the Claude Code target`):u.error(r.error);return}u.success(`Added MCP server: ${t} (Claude Code target)`),u.info(`
195
- Reload the Claude Code session to activate the MCP server`)}async function hE(e,t){t||(u.error("Server name required. Usage: vespercli mcp remove <server> --target claude"),process.exit(1));let r=await Qd(e,t);if(r.error){u.error(r.error);return}if(!r.removed){u.info(`MCP server '${t}' is not configured for the Claude Code target`);return}u.success(`Removed MCP server: ${t} (Claude Code target)`),u.info(`
196
- Reload the Claude Code session to deactivate the MCP server`)}async function mE(e){let{configured:t,custom:r}=await Zd(e);console.log(),u.header("MCP Servers (Claude Code target)"),console.log(),u.info("Available servers:");for(let[n,s]of Object.entries(we)){let i=t.includes(n)?it.green("\u2713"):it.dim("\u25CB"),a=s.tools?.length||0;u.info(` ${i} ${n} (${a} tools)`)}if(r.length>0){console.log(),u.info("Custom servers:");for(let n of r)u.info(` ${it.blue("\u25C6")} ${n}`)}console.log(),u.info(`Installed: ${t.length} server(s)`)}var Pi=Object.freeze({START_FAILED:1,UNKNOWN:2});async function gE(e,t={}){let r=Eh(t.path||process.cwd()),n=e?yh(e,r):null;if(!n)return console.error(`Unknown MCP server "${e??""}". \`vespercli mcp serve <name>\` knows: ${gh.join(", ")}.`),{exitCode:Pi.UNKNOWN};if(e==="vesper-indexing"&&!ZS(n.args[0]))return console.error(`vesper-indexing is not built (${n.args[0]} is missing) \u2014 reinstall @mthanh/vespercli or run \`npm run build:mcp\` in the package.`),{exitCode:Pi.START_FAILED};let s=n.command==="node"?process.execPath:n.command;return new Promise(o=>{let i;try{i=eE(s,n.args,{stdio:"inherit",env:{...process.env,...n.env},shell:process.platform==="win32"&&s!==process.execPath})}catch(c){return console.error(`Could not start ${e}: ${c?.message||c}`),o({exitCode:Pi.START_FAILED})}let a=c=>{try{i.kill(c)}catch{}};for(let c of["SIGINT","SIGTERM","SIGHUP"])process.on(c,a);i.on("error",c=>{console.error(`Could not start ${e}: ${c?.message||c}`),o({exitCode:Pi.START_FAILED})}),i.on("exit",(c,l)=>o({exitCode:c??(l?1:0)}))})}async function Ph(e,t,r={}){let n=Eh(r.path||process.cwd());if(await w(n)||(u.error(`Directory not found: ${n}`),process.exit(1)),e==="serve"){let{exitCode:l}=await gE(t,r);process.exitCode=l;return}let s=(await W(n)).host,o=s?[s]:await he(n);!r.target&&o.length>1&&(u.error(Xe),process.exit(1)),!r.target&&o.length===0&&tE.has(e)&&(u.error(`\`vespercli mcp ${e}\` needs an initialized workspace \u2014 nothing was written. Run \`vespercli init\` first.`),process.exit(1));let i=r.target?[r.target]:o.length?o:["copilot"],a=i.includes("copilot"),c=i.includes("claude");if(c&&!a)switch(xh.has(e)&&s!=="claude"&&(u.error(rE(e)),process.exit(1)),e){case"enable":return await Qc(n,!0);case"disable":return await Qc(n,!1);case"sync":return await Qc(n,!0);case"add":return await fE(n,t);case"remove":return await hE(n,t);case"list":return await mE(n);case"status":return await vh(n,s);case"reindex":return await Sh(n,r.full);default:return e&&u.warn(`'${e}' is not applicable to the Claude Code target \u2014 showing status instead.`),await vh(n,s)}switch(e){case"status":await kh(n,r.watch);break;case"add":await uE(n,t);break;case"remove":await dE(n,t);break;case"list":await pE(n);break;case"reindex":await Sh(n,r.full);break;case"enable":await iE(n);break;case"disable":await aE(n);break;case"sync":await cE(n);break;case"approve":await lE(n);break;default:await kh(n,r.watch)}}Te();H();import{resolve as yE}from"node:path";async function jh(e,t,r,n={}){let s=yE(n.path||process.cwd());if(!e){Ih();return}switch(e){case"add":await wE(s,t,r);break;case"remove":await vE(s,t,r);break;case"list":await kE(s,t);break;default:u.error(`Unknown subcommand: ${e}`),Ih()}}async function wE(e,t,r){if(!t){u.error("Setting key required"),u.info("Usage: vespercli settings add <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!r){u.error("Path value required"),u.info("Usage: vespercli settings add read-access <path>");return}let n=await ao(e,r);u.success(`Added "${r}" to additional read access paths`),u.info(`Current paths: ${n.length>0?n.join(", "):"(none)"}`);break;default:u.error(`Unknown setting: ${t}`),u.info("Supported settings:"),u.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function vE(e,t,r){if(!t){u.error("Setting key required"),u.info("Usage: vespercli settings remove <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!r){u.error("Path value required"),u.info("Usage: vespercli settings remove read-access <path>");return}let n=await co(e,r);u.success(`Removed "${r}" from additional read access paths`),u.info(`Current paths: ${n.length>0?n.join(", "):"(none)"}`);break;default:u.error(`Unknown setting: ${t}`),u.info("Supported settings:"),u.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function kE(e,t){if(!t){u.info("Managed settings:"),u.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)"),u.info(""),u.info("Use: vespercli settings list <setting-key>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":let r=await lo(e);u.info(`${ne}:`),r.length===0?u.info(" (empty)"):r.forEach(n=>u.info(` - ${n}`));break;default:u.error(`Unknown setting: ${t}`),u.info("Supported settings:"),u.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}function Ih(){u.info("Usage: vespercli settings <subcommand> [setting-key] [value]"),u.info(""),u.info("Subcommands:"),u.info(" add <setting-key> <value> Add a value to an array setting"),u.info(" remove <setting-key> <value> Remove a value from an array setting"),u.info(" list [setting-key] List current values"),u.info(""),u.info("Supported settings:"),u.info(" read-access github.copilot.chat.additionalReadAccessPaths"),u.info(""),u.info("Examples:"),u.info(" vespercli settings add read-access /path/to/external/repo"),u.info(" vespercli settings remove read-access /path/to/external/repo"),u.info(" vespercli settings list read-access")}U();H();te();be();xe();import{resolve as Rh}from"node:path";Rt();Te();async function SE(e={},t){let r=Rh(e.path||process.cwd());if(t!=="claude"){u.warn('Claude Code target is not initialized. Run "vesper init --target claude" first.');return}console.log(),u.info("Refreshing Claude Code project catalog and orchestrator playbook...");let{pluginDir:n,counts:s,pruned:o}=await Ko({workspaceRoot:r,namePrefix:await Jr(r),version:e.version});u.success(`Project catalog refreshed: ${n}`),u.info(` agents: ${s.agents}, commands: ${s.commands}, skills: ${s.skills}`),o.length&&u.info(` pruned ${o.length} asset(s) removed in this version: ${o.join(", ")}`);let i=await Jo(r);u.success(`Orchestrator playbook refreshed (.claude/rules/vesper-orchestrator.md: ${i.orchestrator})`),u.info("Team roster (.claude/rules/vesper-orchestration.md) and project context (.claude/rules/vesper-context.md) are left alone \u2014 they belong to this project."),u.info(`OpenCode overlay: .opencode/agents/vesper-orchestrator.md (${i.opencodeAgent}), .opencode/plugins/vesper.js (${i.opencodePlugin})`),i.opencodeKept?.length&&u.warn(`Left in place \u2014 they differ from what Vesper writes (your edits, or an older build's copy): ${i.opencodeKept.join(", ")}. Delete them to get this version's copy.`),Cr(await qt(r,"claude"))}async function EE({isTTY:e=!!process.stdout.isTTY,check:t=Oi,timeoutMs:r=$i}={}){if(!e)return[];let n=[];try{n=await t({timeoutMs:r})}catch{n=[]}let s=n.filter(o=>o.status==="stale").map(Qf);for(let o of s)u.info(o);return s}async function Nh(e={}){try{let t=Rh(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await W(t);(await $e(t,{checkout:r})).unmigrated&&(u.error(Ze),process.exit(1));let n=e.target?null:r.host,s=e.target?[e.target]:n?[n]:await he(t);if(s.length===0){u.warn('Vesper is not initialized. Run "vespercli init" first.');return}if(!e.target&&s.length>1&&(u.error(Xe),process.exit(1)),s.includes("claude")&&await SE({...e,path:t},r.host),s.includes("copilot")){console.log(),u.info("Copilot assets are linked from the package, not copied."),u.info("Update the vesper package to get the latest assets:"),u.dim(" npm update -g @mthanh/vespercli"),console.log();let o=await pi(t),i=[[".vesper/agents/vesper-orchestrator.agent.md",o.orchestratorAgent],[".vesper/instructions/vesper-orchestrator.instructions.md",o.orchestrator]].filter(([,c])=>c==="created"||c==="updated");i.length?u.success(`Project brain refreshed: ${i.map(([c])=>c).join(", ")}`):u.info("Project brain already up to date."),Cr(await qt(t,"copilot"));let a=await _r(t);a==="removed"&&u.info("Retired .vesper/instructions/vesper-host-guard.instructions.md (no longer used)."),a==="kept"&&u.warn(cn())}await EE(e)}catch(t){u.error(`Update failed: ${t.message}`),process.exit(1)}}U();H();xe();te();import{resolve as bE,join as Lh}from"node:path";ct();dt();Te();async function xE(e){await Iu(e)}async function tl(e,t,{quiet:r=!1}={}){if(t?.action!=="bootstrap"||!K.includes(t.host))throw new Error("runBootstrap requires a bootstrap decision");let n=t.host,s=t.network!==!1;if(t.checkout?.source==="local")return _E(e,t,{quiet:r});let o=[],i=[],a=async(m,f)=>{try{return await f()}catch(g){i.push(m),u.warn(`Bootstrap step "${m}" failed (continuing): ${g?.message??g}`);return}},l={sshCommandConfigured:s?!!await G(["config","--get","core.sshCommand"],{cwd:e}):!1},d=s?CE(e,l).catch(()=>({})):Promise.resolve({});await a("mcp",async()=>{n==="claude"?(await Zt(e,!0),o.push(".mcp.json regenerated for this worktree"),await Qo(e),o.push(".claude/settings.local.json marketplace source regenerated for this machine")):(await vs(e,!0),o.push(".vscode/mcp.json regenerated for this worktree"))}),await a("index",async()=>{let m=Lh(e,".vesper","index.db");if(!await w(m)){let f=await Ti(e,!1);f.success&&o.push(`code index built (${f.filesIndexed} files)`)}}),await a("gitignore",()=>jn(e)),await a("tracked-local",async()=>{let m=await Rn(e);if(m.length>0){let f=m.map(g=>`'${g.replace(/'/g,"'\\''")}'`);u.warn(`Local-only file(s) git-tracked despite .gitignore: ${f.join(", ")} \u2014 untrack with: git rm --cached -- ${f.join(" ")}`)}});let p=await a("hooks",()=>Gn(e));p&&o.push(...Vn(p)),await a("attributes",()=>Hn(e)),await a("merge-driver",()=>Un(e)),o.push(p&&ua(p)?"gitignore + git hooks + merge strategy ensured":"gitignore + merge strategy ensured");let h=await a("fetch",()=>d)??{};if(h.action&&o.unshift(h.action),h.note&&!r&&u.info(h.note),await a("triggers",()=>ii(e,n,{unattended:!0})),await a("ledger",()=>xE(e)),o.push(`host guard triggers ensured (${n} + cross-host)`),i.length&&u.warn(`Worktree bootstrap finished with errors in: ${i.join(", ")}`),!r){u.success(i.length?"Worktree bootstrap finished (with errors)":"Worktree bootstrap complete");for(let m of o)u.info(` ${m}`)}return{host:n,failed:i}}async function el(e,t){return await G(["check-ignore","-q","--",t],{cwd:e,timeout:5e3})!==null}async function _E(e,t,{quiet:r=!1}={}){let n=t.host,s=[],o=[],i=[],a=async(d,p)=>{try{return await p()}catch(h){o.push(d),u.warn(`Bootstrap step "${d}" failed (continuing): ${h?.message??h}`);return}},c=n==="claude"?[".mcp.json",".claude/settings.local.json"]:[".vscode/mcp.json"],l=await el(e,".vesperrc");if(l||i.push(".vesperrc (ledger not re-recorded)"),await a("mcp",async()=>{for(let d of c){if(!await el(e,d)){i.push(d);continue}d===".mcp.json"?(await Zt(e,!0,{record:l}),s.push(".mcp.json regenerated")):d===".claude/settings.local.json"?(await Qo(e,{record:l}),s.push(".claude/settings.local.json regenerated")):(await vs(e,!0,{record:l}),s.push(".vscode/mcp.json regenerated"))}}),await a("index",async()=>{let d=".vesper/index.db";if(!await el(e,d)){i.push(d);return}if(!await w(Lh(e,d))){let p=await Ti(e,!1);p.success&&s.push(`code index built (${p.filesIndexed} files)`)}}),s.push(`local-only activation (${n}): tracked files, hooks and triggers left untouched`),o.length&&u.warn(`Worktree bootstrap finished with errors in: ${o.join(", ")}`),!r){u.success("Worktree bootstrap complete (local-only activation)");for(let d of s)u.info(` ${d}`);i.length&&u.info(` not written (git would track them here): ${i.join(", ")}`)}return{host:n,failed:o,localOnly:!0}}async function AE(e,t,{runningHost:r}={}){if(!await w(e))return{skipped:"not-vesperized"};let n=await ai(e,{runningHost:r});if(n.action==="bootstrap"){let{host:o,failed:i}=await tl(e,n,{quiet:t});return i.length?{host:o,failed:i}:{host:o}}n.action==="refuse"?u.warn(n.reason==="host-mismatch"?`This workspace is provisioned for "${n.host}" but bootstrap was invoked as "${r}" \u2014 skipping all provisioning. Run \`vespercli init --host ${r}\` to switch, or \`vespercli reset --host ${r}\` to remove stray ${r} files.`:`Bootstrap wrote nothing. ${n.message}`):n.note&&(!t||n.reason==="legacy-unmigrated"||n.reason==="migration-in-progress")&&(n.reason==="legacy-unmigrated"||n.reason==="migration-in-progress"?u.warn(n.note):u.info(n.note));let s=n.host??n.checkout?.candidate??null;return{skipped:n.action==="refuse"?"host-mismatch":n.reason,...s?{host:s}:{}}}async function CE(e,{sshCommandConfigured:t=!1}={}){let r=await G(["rev-parse","--abbrev-ref","origin/HEAD"],{cwd:e}),n=r===null?-1:r.indexOf("/");if(n===-1)return{note:"No base branch remote to refresh (origin/HEAD unset or no remote)."};let s=r.slice(0,n),o=r.slice(n+1),i=await Et(["fetch",s,o],{cwd:e,timeout:15e3,env:Cn(process.env,{sshCommandConfigured:t}),detached:!0});return!i.ok&&Yi.test(i.stderr)?(u.warn(qi(`Fetching the latest ${s}/${o}`)),{}):i.ok?{action:`${s}/${o} fetched (latest base branch ref)`}:(u.warn(`Could not fetch the latest ${s}/${o} (offline, unreachable or timed out) \u2014 continuing with existing local refs.`),{})}async function Mh(e,t={}){let r=bE(t.path||process.cwd()),n=!!t.quiet;switch(e){case"bootstrap":case void 0:return AE(r,n,{runningHost:t.runningHost});default:u.error(`Unknown subcommand: ${e}. Usage: vespercli worktree bootstrap`),process.exit(1)}}import{resolve as $E}from"node:path";te();Te();async function Dh(e={}){let t=$E(e.path||process.cwd()),r=!!e.quiet,n=e.runningHost;if(n!==void 0&&!K.includes(n))return r||u.error(`--running-host must be one of: ${K.join(", ")} (received "${n}").`),{exitCode:Oe.ERROR,report:null};let s;try{s=await un(t,{runningHost:n})}catch(i){return r||u.error(`doctor failed unexpectedly: ${i?.message||i}`),{exitCode:Oe.ERROR,report:null}}let o=li(s);return r||OE(s),{exitCode:o,report:s}}function OE(e){if(e.errors.length+e.warnings.length+e.infos.length===0){u.success("No issues found \u2014 this Vesper workspace is healthy.");return}rl("Errors",e.errors,r=>u.error(r)),rl("Warnings",e.warnings,r=>u.warn(r)),rl("Info",e.infos,r=>u.info(r))}function rl(e,t,r){if(t.length){console.log(),u.header(e);for(let n of t){let s=n.path?` (${n.path})`:"";r(`${n.message}${s}`),u.dim(` fix: ${n.fix}`)}}}import{resolve as ME}from"node:path";te();xe();import{readFile as TE,readdir as PE,stat as Uh}from"node:fs/promises";import{homedir as Cs}from"node:os";import{join as Lt,resolve as Wh,isAbsolute as IE}from"node:path";var ji=Object.freeze({NOT_ENABLED:"plugin-not-enabled",NOT_DECLARED:"marketplace-not-declared",SOURCE_MISSING:"marketplace-source-missing",INVALID_DECLARATION:"marketplace-declaration-invalid"});function nl(e,t){return e.replace(/^~(?=$|[\\/])/,t)}function Kh({env:e=process.env,homeDir:t=Cs()}={}){let r=typeof e.CLAUDE_CONFIG_DIR=="string"?e.CLAUDE_CONFIG_DIR.trim():"";return r?Wh(nl(r,t)):Lt(t,".claude")}function Fh({env:e=process.env,homeDir:t=Cs()}={}){let r=typeof e.CLAUDE_CODE_PLUGIN_CACHE_DIR=="string"?e.CLAUDE_CODE_PLUGIN_CACHE_DIR.trim():"";return r?Wh(nl(r,t)):Lt(Kh({env:e,homeDir:t}),"plugins")}function jE(e=process.platform){return e==="darwin"?"/Library/Application Support/ClaudeCode":e==="win32"?"C:\\Program Files\\ClaudeCode":"/etc/claude-code"}async function Vh(e){try{let t=JSON.parse(await TE(e,"utf-8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}async function Gh(e){try{return await Uh(e),!0}catch{return!1}}async function RE(e){try{return(await Uh(e)).isFile()}catch{return!1}}async function NE(e,{env:t=process.env,homeDir:r=Cs(),platform:n=process.platform,managedDir:s}={}){let o=s??jE(n),i=[{scope:"user",path:Lt(Kh({env:t,homeDir:r}),"settings.json")},{scope:"project",path:Le(e)},{scope:"local",path:on(e)},{scope:"managed",path:Lt(o,"managed-settings.json")}];try{let a=(await PE(Lt(o,"managed-settings.d"))).filter(c=>c.endsWith(".json")).sort();for(let c of a)i.push({scope:"managed",path:Lt(o,"managed-settings.d",c)})}catch{}return i}function Hh(e,t=Cs()){let r=s=>{if(typeof s!="string"||!s.trim())return null;let o=nl(s.trim(),t);return IE(o)?o:null};if(typeof e=="string")return r(e);if(!e||typeof e!="object")return null;let n=e.source;return typeof n=="string"?null:n&&typeof n=="object"?(n.source==="directory"||n.source==="file")&&typeof n.path=="string"?r(n.path):null:typeof e.installLocation=="string"?r(e.installLocation):null}async function LE(e){return await Gh(e)?await RE(e)?!0:Gh(Lt(e,".claude-plugin","marketplace.json")):!1}async function Bh(e,t={}){let r=t.env??process.env,n=t.homeDir??Cs(),s=await NE(e,{...t,env:r,homeDir:n}),o,i=null,a,c=[],l=[];for(let m of s){let f=await Vh(m.path);if(!f)continue;let g=f.enabledPlugins;g&&typeof g=="object"&&typeof g[ut]=="boolean"&&(m.scope==="managed"?a!==!0&&(a=g[ut]):(o=g[ut],i=m.scope));let y=f.extraKnownMarketplaces;if(y&&typeof y=="object"&&y[Ce]!==void 0&&y[Ce]!==null){let k=y[Ce];if(k&&typeof k=="object"&&typeof k.source=="string"){l.push({scope:m.scope,path:m.path});continue}c.push({scope:m.scope,path:m.path,localPath:Hh(k,n),exists:null})}}a!==void 0&&(o=a,i="managed");let d=await Vh(Lt(Fh({env:r,homeDir:n}),"known_marketplaces.json"));if(d&&d[Ce]!==void 0&&d[Ce]!==null){let m=d[Ce],f=m&&typeof m=="object"&&m.source&&typeof m.source=="object"&&m.source.source!=="directory"&&m.source.source!=="file";c.push({scope:"known_marketplaces",path:Lt(Fh({env:r,homeDir:n}),"known_marketplaces.json"),localPath:f?null:Hh(m,n),exists:null})}let p=typeof r.CLAUDE_CODE_PLUGIN_SEED_DIR=="string"&&r.CLAUDE_CODE_PLUGIN_SEED_DIR.trim()!=="",h=[];if(o!==!0&&h.push(ji.NOT_ENABLED),c.length===0&&!p)h.push(l.length?ji.INVALID_DECLARATION:ji.NOT_DECLARED);else if(c.length>0&&!p){let m=!1,f=!1;for(let g of c){if(g.localPath===null){m=!0;continue}g.exists=await LE(g.localPath),g.exists&&(f=!0)}!m&&!f&&h.push(ji.SOURCE_MISSING)}return{absent:h.length>0,missing:h,enabled:o,enabledBy:i,declarations:c,invalidDeclarations:l}}dt();ct();async function DE(e,t){try{let{realpath:r}=await import("node:fs/promises"),{resolve:n}=await import("node:path"),s=await G(["rev-parse","--absolute-git-dir"],{cwd:t,env:ar(process.env),timeout:5e3});return s?await r(n(process.cwd(),e))===await r(s):!1}catch{return!1}}async function zh(e){let t=process.stdout.write,r=[];process.stdout.write=(n,...s)=>{r.push(typeof n=="string"?n:String(n));let o=s.find(i=>typeof i=="function");return o&&o(),!0};try{return await e()}finally{process.stdout.write=t,r.length&&process.stderr.write(r.join(""))}}function Jh(e){process.stdout.write(`${e}
197
- `)}async function Yh(e={}){let t=ME(e.path||process.cwd()),r={};if(process.env.GIT_DIR&&await DE(process.env.GIT_DIR,t))for(let n of Fs())n in process.env&&(r[n]=process.env[n],delete process.env[n]);try{return await FE(t,e)}finally{Object.assign(process.env,r)}}async function FE(e,t){let r=t.bootstrap!==!1;if(t.runningHost!==void 0&&!kp(t.runningHost))return process.stderr.write(`vespercli guard: --running-host must be one of: ${[...K,ms].join(", ")} (received "${t.runningHost}")
198
- `),{exitCode:Oe.ERROR,emitted:[],resolved:{host:null,source:null}};let n=vp(t.runningHost),s=await ai(e,{runningHost:n,runningLabel:t.runningHost}),o={host:s.checkout?.host??null,source:s.checkout?.source??null},i=null;if(s.identity)try{i=await un(e,{runningHost:n,checkout:s.checkout})}catch{i=null}if(s.action==="refuse")return Jh(oi),process.stdout.write(`${s.message}
199
- `),await zh(async()=>{if(s.reason!=="switch-in-progress")try{await bp(e,n,{checkout:s.checkout})}catch{}}),{exitCode:Oe.HOST_MISMATCH,emitted:[oi],resolved:o,decision:s};let a=[];if(await zh(async()=>{s.action==="bootstrap"&&r&&({failed:a}=await tl(e,s,{quiet:!0}))}),s.action==="none"&&s.note&&(s.identity||process.stderr.isTTY)&&process.stderr.write(`${s.note}
200
- `),!s.identity)return{exitCode:a.length?Oe.ERROR:Oe.OK,emitted:[],resolved:o,decision:s};let c=[];if(t.runningHost==="claude"&&o.host==="claude"){let d=null;try{d=await Bh(e)}catch{d=null}d?.absent&&(Jh(pc),c.push(pc))}let l=i?li(i):Oe.ERROR;if(a.length&&l===Oe.OK&&(l=Oe.ERROR),i&&l===Oe.ERROR)for(let d of i.errors)process.stderr.write(`vespercli guard: ${d.message} (fix: ${d.fix})
201
- `);return{exitCode:l,emitted:c,resolved:o,decision:s}}rs();U();import{resolve as VE,isAbsolute as GE,join as HE}from"node:path";async function qh(e={}){let t=VE(e.path||process.cwd()),r=!!e.json,n=await Zu(t);if(!n.ok){let l=n.reason==="missing"?`No ${ce} in ${t} \u2014 run \`vespercli init\` to seed one.`:`${ce} is invalid: ${n.errors.join("; ")}`;return r?console.log(JSON.stringify({pass:!1,error:l,exitCode:wr.NO_CONFIG})):console.error(l),{exitCode:wr.NO_CONFIG,report:null}}let s=null;if(e.plan){let l=GE(e.plan)?e.plan:HE(t,e.plan);if(!await w(l)){let d=`--plan file not found: ${e.plan}`;return r?console.log(JSON.stringify({pass:!1,error:d,exitCode:wr.NO_CONFIG})):console.error(d),{exitCode:wr.NO_CONFIG,report:null}}s=(await ed(l)).planned}let o=[];for(let l of n.config.checks)o.push(nd(l,t));let i=await sd(t,e.base),a=i.skipped?null:i,c=td({config:n.config,checks:o,diff:a,planned:s,diffSkipped:i.skipped||null});return console.log(r?JSON.stringify(c):rd(c)),{exitCode:c.pass?wr.PASS:wr.FAIL,report:c}}import{resolve as UE}from"node:path";async function WE(){if(process.stdin.isTTY)return"";let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function Xh(e,t={}){let r=UE(t.path||process.cwd()),n=!!t.json;if(e==="tail"){let a=t.lines===void 0?Ai:Number(t.lines);if(!Number.isFinite(a)||a<0)return console.error(`-n must be a non-negative number (received "${t.lines}")`),{exitCode:fn.INVALID};let{rows:c,malformed:l}=await Kf(r,{slug:t.slug}),d=Bf(c,a);if(n)for(let p of d)console.log(JSON.stringify(p));else if(d.length===0)console.log(t.slug?`No run ledger rows for slug "${t.slug}".`:"No run ledger rows yet.");else for(let p of d)console.log(zf(p));return l>0&&!n&&console.error(`(${l} malformed line(s) skipped)`),{exitCode:fn.OK}}if(!As.includes(e))return console.error(`Unknown log event "${e}". Use one of: ${As.join(", ")}, tail.`),{exitCode:fn.INVALID};let s={event:e,pipeline:t.pipeline,step:t.step,agent:t.agent,goal:t.goal,author:t.author,status:t.status,note:t.note,session:t.session};if(t.stdin){let a=Jf(await WE());a&&(!s.agent&&a.agent&&(s.agent=a.agent),!s.session&&a.session&&(s.session=a.session))}let o=Uf(s);if(!o.ok){for(let a of o.errors)console.error(a);return{exitCode:fn.INVALID}}let{rel:i}=await Wf(r,o.row,{slug:t.slug});return console.log(n?JSON.stringify({...o.row,file:i}):`logged ${e} \u2192 ${i}`),{exitCode:fn.OK}}import{resolve as qE}from"node:path";U();import{readdir as KE,readFile as BE}from"node:fs/promises";import{join as sl}from"node:path";var ol=".vesper/.tracking/stories",$r=Object.freeze(["refining","backlog","inprogress","inreview","completed"]),rr=Object.freeze({OK:0,REFUSED:1,INVALID:2});function zE(e){return e.replace(/\.md$/i,"").replace(/^\d{8}-/,"").replace(/-story$/i,"")}function JE(e){let t=/^#\s+(.+?)\s*$/m.exec(String(e??""));return t?t[1]:null}async function il(e,{folder:t}={}){let r=t?[t]:$r,n=[];for(let s of r){let o=sl(e,ol,s),i=[];try{i=await KE(o,{withFileTypes:!0})}catch{continue}for(let a of i.filter(c=>c.isFile()&&c.name.toLowerCase().endsWith(".md")).sort((c,l)=>c.name.localeCompare(l.name))){let c=`${ol}/${s}/${a.name}`,l=null;try{l=JE(await BE(sl(o,a.name),"utf-8"))}catch{l=null}n.push({slug:zE(a.name),folder:s,file:a.name,rel:c,title:l})}}return n}async function YE(e,t){let r=String(t??"").trim().toLowerCase();return r?(await il(e)).filter(n=>n.file.toLowerCase().includes(r)):[]}async function Qh(e,t,r){if(!$r.includes(r))return{ok:!1,reason:"invalid-folder"};let n=await YE(e,t);if(n.length===0)return{ok:!1,reason:"not-found",matches:n};if(n.length>1)return{ok:!1,reason:"ambiguous",matches:n};let[s]=n,o=`${ol}/${r}/${s.file}`;if(s.folder===r)return{ok:!0,from:s.rel,to:o,method:"noop"};if(await w(sl(e,o)))return{ok:!1,reason:"exists",matches:n};let i=await xi(e,s.rel,o);return i.ok?{ok:!0,from:s.rel,to:o,method:i.method}:{ok:!1,reason:i.reason,matches:n}}function Zh(e){if(e.length===0)return"(no stories)";let t=Math.max(...e.map(r=>r.folder.length));return e.map(r=>`${r.folder.padEnd(t)} ${r.slug}${r.title?` \u2014 ${r.title}`:""}`).join(`
202
- `)}async function em(e,t,r,n={}){let s=qE(n.path||process.cwd()),o=!!n.json;if(e==="list"){if(n.folder&&!$r.includes(n.folder))return console.error(`--folder must be one of ${$r.join("|")} (received "${n.folder}")`),{exitCode:rr.INVALID};let i=await il(s,{folder:n.folder});return console.log(o?JSON.stringify(i):Zh(i)),{exitCode:rr.OK}}if(e==="move"){if(!t||!r)return console.error("Usage: vespercli story move <slug> <folder>"),{exitCode:rr.INVALID};if(!$r.includes(r))return console.error(`Folder must be one of ${$r.join("|")} (received "${r}")`),{exitCode:rr.INVALID};let i=await Qh(s,t,r);if(!i.ok){let a=(i.matches||[]).map(l=>l.rel),c=i.reason==="not-found"?`No story matches "${t}" under .vesper/.tracking/stories/.`:i.reason==="ambiguous"?`"${t}" matches ${a.length} stories \u2014 be more specific:
205
+ Reload VS Code to apply changes`)}async function bb(e){let t=await q(e),r=await x(e,t),s=(await K(e,t))[V]||{},o=Object.keys(s).length,i=await bm(e);console.log(),u.header("MCP Tool Approval Status"),console.log();let a=Re.filter(d=>s[d]);if(u.info(`Core tools: ${a.length}/${Re.length} approved`),i.length>0){console.log(),u.info("Agent tools:");for(let d of i){let p=MCP_TOOLS_BY_AGENT[d]||[],f=p.filter(h=>s[h]),m=f.length===p.length?ht.green("\u2713"):ht.yellow("\u26A0");u.info(` ${m} ${d}: ${f.length}/${p.length} approved`)}}let c=[...Re];for(let d of i)c.push(...MCP_TOOLS_BY_AGENT[d]||[]);let l=c.filter(d=>!s[d]);console.log(),u.info(`Total approved: ${o} tools`),l.length>0?(console.log(),u.warn(`${l.length} tools missing approval`),u.info("Run `vespercli mcp sync` to fix")):r.mcp?.syncedAt&&u.info(`Last synced: ${r.mcp.syncedAt}`)}function xm(){return Object.keys(we).filter(e=>!me.includes(e))}async function xb(e,t){t||(u.error("Server name required. Usage: vespercli mcp add <server>"),u.info(`Available servers: ${xm().join(", ")}`),process.exit(1)),console.log(),u.header("Add MCP Server"),console.log();let r=await sr(e,t);if(!r.added){r.error==="Already configured"?u.info(`MCP server '${t}' is already configured`):(u.error(r.error),process.exit(1));return}u.success(`Added MCP server: ${t}`),r.tools.length>0&&u.info(`Approved ${r.tools.length} tool(s) for auto-execution`),u.info(`
206
+ Reload VS Code to activate the MCP server`)}async function Ab(e,t){t||(u.error("Server name required. Usage: vespercli mcp remove <server>"),process.exit(1)),console.log(),u.header("Remove MCP Server"),console.log();let r=await rn(e,t);if(!r.removed){u.info(`MCP server '${t}' is not configured`);return}u.success(`Removed MCP server: ${t}`),r.tools.length>0&&u.info(`Removed ${r.tools.length} tool(s) from auto-approval`),u.info(`
207
+ Reload VS Code to deactivate the MCP server`)}async function _b(e){let t=await q(e),r=await x(e,t),n=await Ze(e);console.log(),u.header("MCP Servers"),console.log();let s=r.mcp?.servers||[],o=Object.keys(n.servers||{});u.info("Available servers:");for(let[a,c]of Object.entries(we)){let d=o.includes(a)?ht.green("\u2713"):ht.dim("\u25CB"),p=c.tools?.length||0;u.info(` ${d} ${a} (${p} tools)`)}let i=o.filter(a=>!we[a]);if(i.length>0){console.log(),u.info("Custom servers:");for(let a of i)u.info(` ${ht.blue("\u25C6")} ${a}`)}console.log(),u.info(`Installed: ${o.length} server(s)`)}async function Cb(e,t){t||(u.error("Server name required. Usage: vespercli mcp add <server> --target claude"),u.info(`Available servers: ${xm().join(", ")}`),process.exit(1));let r=await kn(e,t);if(!r.added){r.error==="Already configured"?u.info(`MCP server '${t}' is already configured for the Claude Code target`):u.error(r.error);return}u.success(`Added MCP server: ${t} (Claude Code target)`),u.info(`
208
+ Reload the Claude Code session to activate the MCP server`)}async function $b(e,t){t||(u.error("Server name required. Usage: vespercli mcp remove <server> --target claude"),process.exit(1));let r=await ui(e,t);if(r.error){u.error(r.error);return}if(!r.removed){u.info(`MCP server '${t}' is not configured for the Claude Code target`);return}u.success(`Removed MCP server: ${t} (Claude Code target)`),u.info(`
209
+ Reload the Claude Code session to deactivate the MCP server`)}async function Ob(e){let{configured:t,custom:r}=await Rc(e);console.log(),u.header("MCP Servers (Claude Code target)"),console.log(),u.info("Available servers:");for(let[n,s]of Object.entries(we)){let i=t.includes(n)?ht.green("\u2713"):ht.dim("\u25CB"),a=s.tools?.length||0;u.info(` ${i} ${n} (${a} tools)`)}if(r.length>0){console.log(),u.info("Custom servers:");for(let n of r)u.info(` ${ht.blue("\u25C6")} ${n}`)}console.log(),u.info(`Installed: ${t.length} server(s)`)}var ra=Object.freeze({START_FAILED:1,UNKNOWN:2});async function Tb(e,t={}){let r=mm(t.path||process.cwd()),n=e?um(e,r):null;if(!n)return console.error(`Unknown MCP server "${e??""}". \`vespercli mcp serve <name>\` knows: ${lm.join(", ")}.`),{exitCode:ra.UNKNOWN};if(e==="vesper-indexing"&&!fb(n.args[0]))return console.error(`vesper-indexing is not built (${n.args[0]} is missing) \u2014 reinstall @mthanh/vespercli or run \`npm run build:mcp\` in the package.`),{exitCode:ra.START_FAILED};let s=n.command==="node"?process.execPath:n.command;return new Promise(o=>{let i;try{i=hb(s,n.args,{stdio:"inherit",env:{...process.env,...n.env},shell:process.platform==="win32"&&s!==process.execPath})}catch(c){return console.error(`Could not start ${e}: ${c?.message||c}`),o({exitCode:ra.START_FAILED})}let a=c=>{try{i.kill(c)}catch{}};for(let c of["SIGINT","SIGTERM","SIGHUP"])process.on(c,a);i.on("error",c=>{console.error(`Could not start ${e}: ${c?.message||c}`),o({exitCode:ra.START_FAILED})}),i.on("exit",(c,l)=>o({exitCode:c??(l?1:0)}))})}async function Am(e,t,r={}){let n=mm(r.path||process.cwd());if(await w(n)||(u.error(`Directory not found: ${n}`),process.exit(1)),e==="serve"){let{exitCode:l}=await Tb(t,r);process.exitCode=l;return}let s=(await B(n)).host,o=s?[s]:await ge(n);!r.target&&o.length>1&&(u.error(et),process.exit(1)),!r.target&&o.length===0&&mb.has(e)&&(u.error(`\`vespercli mcp ${e}\` needs an initialized workspace \u2014 nothing was written. Run \`vespercli init\` first.`),process.exit(1));let i=r.target?[r.target]:o.length?o:["copilot"],a=i.includes("copilot"),c=i.includes("claude");if(c&&!a)switch(wm.has(e)&&s!=="claude"&&(u.error(gb(e)),process.exit(1)),e){case"enable":return await jl(n,!0);case"disable":return await jl(n,!1);case"sync":return await jl(n,!0);case"add":return await Cb(n,t);case"remove":return await $b(n,t);case"list":return await Ob(n);case"status":return await pm(n,s);case"reindex":return await hm(n,r.full);default:return e&&u.warn(`'${e}' is not applicable to the Claude Code target \u2014 showing status instead.`),await pm(n,s)}switch(e){case"status":await fm(n,r.watch);break;case"add":await xb(n,t);break;case"remove":await Ab(n,t);break;case"list":await _b(n);break;case"reindex":await hm(n,r.full);break;case"enable":await kb(n);break;case"disable":await Sb(n);break;case"sync":await Eb(n);break;case"approve":await bb(n);break;default:await fm(n,r.watch)}}Pe();H();import{resolve as Pb}from"node:path";async function Cm(e,t,r,n={}){let s=Pb(n.path||process.cwd());if(!e){_m();return}switch(e){case"add":await Ib(s,t,r);break;case"remove":await jb(s,t,r);break;case"list":await Rb(s,t);break;default:u.error(`Unknown subcommand: ${e}`),_m()}}async function Ib(e,t,r){if(!t){u.error("Setting key required"),u.info("Usage: vespercli settings add <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!r){u.error("Path value required"),u.info("Usage: vespercli settings add read-access <path>");return}let n=await Oo(e,r);u.success(`Added "${r}" to additional read access paths`),u.info(`Current paths: ${n.length>0?n.join(", "):"(none)"}`);break;default:u.error(`Unknown setting: ${t}`),u.info("Supported settings:"),u.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function jb(e,t,r){if(!t){u.error("Setting key required"),u.info("Usage: vespercli settings remove <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!r){u.error("Path value required"),u.info("Usage: vespercli settings remove read-access <path>");return}let n=await To(e,r);u.success(`Removed "${r}" from additional read access paths`),u.info(`Current paths: ${n.length>0?n.join(", "):"(none)"}`);break;default:u.error(`Unknown setting: ${t}`),u.info("Supported settings:"),u.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function Rb(e,t){if(!t){u.info("Managed settings:"),u.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)"),u.info(""),u.info("Use: vespercli settings list <setting-key>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":let r=await Po(e);u.info(`${oe}:`),r.length===0?u.info(" (empty)"):r.forEach(n=>u.info(` - ${n}`));break;default:u.error(`Unknown setting: ${t}`),u.info("Supported settings:"),u.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}function _m(){u.info("Usage: vespercli settings <subcommand> [setting-key] [value]"),u.info(""),u.info("Subcommands:"),u.info(" add <setting-key> <value> Add a value to an array setting"),u.info(" remove <setting-key> <value> Remove a value from an array setting"),u.info(" list [setting-key] List current values"),u.info(""),u.info("Supported settings:"),u.info(" read-access github.copilot.chat.additionalReadAccessPaths"),u.info(""),u.info("Examples:"),u.info(" vespercli settings add read-access /path/to/external/repo"),u.info(" vespercli settings remove read-access /path/to/external/repo"),u.info(" vespercli settings list read-access")}U();H();te();be();Ae();import{resolve as $m}from"node:path";Ut();Pe();async function Nb(e={},t){let r=$m(e.path||process.cwd());if(t!=="claude"){u.warn('Claude Code target is not initialized. Run "vesper init --target claude" first.');return}console.log(),u.info("Refreshing Claude Code project catalog and orchestrator playbook...");let{pluginDir:n,counts:s,pruned:o}=await yi({workspaceRoot:r,namePrefix:await on(r),version:e.version});u.success(`Project catalog refreshed: ${n}`),u.info(` agents: ${s.agents}, commands: ${s.commands}, skills: ${s.skills}`),o.length&&u.info(` pruned ${o.length} asset(s) removed in this version: ${o.join(", ")}`);let i=await ki(r);u.success(`Orchestrator playbook refreshed (.claude/rules/vesper-orchestrator.md: ${i.orchestrator})`),u.info("Team roster (.claude/rules/vesper-orchestration.md) and project context (.claude/rules/vesper-context.md) are left alone \u2014 they belong to this project."),u.info(`OpenCode overlay: .opencode/agents/vesper-orchestrator.md (${i.opencodeAgent}), .opencode/plugins/vesper.js (${i.opencodePlugin})`),i.opencodeKept?.length&&u.warn(`Left in place \u2014 they differ from what Vesper writes (your edits, or an older build's copy): ${i.opencodeKept.join(", ")}. Delete them to get this version's copy.`),Vr(await dr(r,"claude"))}async function Lb({isTTY:e=!!process.stdout.isTTY,check:t=ea,timeoutMs:r=Zi}={}){if(!e)return[];let n=[];try{n=await t({timeoutMs:r})}catch{n=[]}let s=n.filter(o=>o.status==="stale").map(Kh);for(let o of s)u.info(o);return s}async function Om(e={}){try{let t=$m(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await B(t);(await Oe(t,{checkout:r})).unmigrated&&(u.error(nt),process.exit(1));let n=e.target?null:r.host,s=e.target?[e.target]:n?[n]:await ge(t);if(s.length===0){u.warn('Vesper is not initialized. Run "vespercli init" first.');return}if(!e.target&&s.length>1&&(u.error(et),process.exit(1)),s.includes("claude")&&await Nb({...e,path:t},r.host),s.includes("copilot")){console.log(),u.info("Copilot assets are linked from the package, not copied."),u.info("Update the vesper package to get the latest assets:"),u.dim(" npm update -g @mthanh/vespercli"),console.log();let o=await Mi(t),i=[[".vesper/agents/vesper-orchestrator.agent.md",o.orchestratorAgent],[".vesper/instructions/vesper-orchestrator.instructions.md",o.orchestrator]].filter(([,c])=>c==="created"||c==="updated");i.length?u.success(`Project brain refreshed: ${i.map(([c])=>c).join(", ")}`):u.info("Project brain already up to date."),Vr(await dr(t,"copilot"));let a=await Fr(t);a==="removed"&&u.info("Retired .vesper/instructions/vesper-host-guard.instructions.md (no longer used)."),a==="kept"&&u.warn(xn())}await Lb(e)}catch(t){u.error(`Update failed: ${t.message}`),process.exit(1)}}U();H();Ae();te();import{resolve as Mb,join as Tm}from"node:path";it();wt();pt();Pe();async function Gb(e){await pd(e)}async function Ll(e,t,{quiet:r=!1}={}){if(t?.action!=="bootstrap"||!z.includes(t.host))throw new Error("runBootstrap requires a bootstrap decision");let n=t.host,s=t.network!==!1;if(t.checkout?.source==="local")return Fb(e,t,{quiet:r});let o=[],i=[],a=async(m,h)=>{try{return await h()}catch(g){i.push(m),u.warn(`Bootstrap step "${m}" failed (continuing): ${g?.message??g}`);return}},l={sshCommandConfigured:s?!!await D(["config","--get","core.sshCommand"],{cwd:e}):!1},d=s?Vb(e,l).catch(()=>({})):Promise.resolve({});await a("mcp",async()=>{n==="claude"?(await hr(e,!0),o.push(".mcp.json regenerated for this worktree"),await bi(e),o.push(".claude/settings.local.json marketplace source regenerated for this machine")):(await Fs(e,!0),o.push(".vscode/mcp.json regenerated for this worktree"))}),await a("index",async()=>{let m=Tm(e,".vesper","index.db");if(!await w(m)){let h=await ta(e,!1);h.success&&o.push(`code index built (${h.filesIndexed} files)`)}}),await a("gitignore",()=>zn(e)),await a("tracked-local",async()=>{let m=await Yn(e);if(m.length>0){let h=m.map(g=>`'${g.replace(/'/g,"'\\''")}'`);u.warn(`Local-only file(s) git-tracked despite .gitignore: ${h.join(", ")} \u2014 untrack with: git rm --cached -- ${h.join(" ")}`)}});let p=await a("hooks",()=>ts(e));p&&o.push(...es(p)),await a("graphify",async()=>{await fn(e,n)&&await ks(e,n)}),await a("attributes",()=>rs(e)),await a("merge-driver",()=>ns(e)),o.push(p&&Na(p)?"gitignore + git hooks + merge strategy ensured":"gitignore + merge strategy ensured");let f=await a("fetch",()=>d)??{};if(f.action&&o.unshift(f.action),f.note&&!r&&u.info(f.note),await a("triggers",()=>Pi(e,n,{unattended:!0})),await a("ledger",()=>Gb(e)),o.push(`host guard triggers ensured (${n} + cross-host)`),i.length&&u.warn(`Worktree bootstrap finished with errors in: ${i.join(", ")}`),!r){u.success(i.length?"Worktree bootstrap finished (with errors)":"Worktree bootstrap complete");for(let m of o)u.info(` ${m}`)}return{host:n,failed:i}}async function Nl(e,t){return await D(["check-ignore","-q","--",t],{cwd:e,timeout:5e3})!==null}async function Fb(e,t,{quiet:r=!1}={}){let n=t.host,s=[],o=[],i=[],a=async(d,p)=>{try{return await p()}catch(f){o.push(d),u.warn(`Bootstrap step "${d}" failed (continuing): ${f?.message??f}`);return}},c=n==="claude"?[".mcp.json",".claude/settings.local.json"]:[".vscode/mcp.json"],l=await Nl(e,".vesperrc");if(l||i.push(".vesperrc (ledger not re-recorded)"),await a("mcp",async()=>{for(let d of c){if(!await Nl(e,d)){i.push(d);continue}d===".mcp.json"?(await hr(e,!0,{record:l}),s.push(".mcp.json regenerated")):d===".claude/settings.local.json"?(await bi(e,{record:l}),s.push(".claude/settings.local.json regenerated")):(await Fs(e,!0,{record:l}),s.push(".vscode/mcp.json regenerated"))}}),await a("index",async()=>{let d=".vesper/index.db";if(!await Nl(e,d)){i.push(d);return}if(!await w(Tm(e,d))){let p=await ta(e,!1);p.success&&s.push(`code index built (${p.filesIndexed} files)`)}}),s.push(`local-only activation (${n}): tracked files, hooks and triggers left untouched`),o.length&&u.warn(`Worktree bootstrap finished with errors in: ${o.join(", ")}`),!r){u.success("Worktree bootstrap complete (local-only activation)");for(let d of s)u.info(` ${d}`);i.length&&u.info(` not written (git would track them here): ${i.join(", ")}`)}return{host:n,failed:o,localOnly:!0}}async function Db(e,t,{runningHost:r}={}){if(!await w(e))return{skipped:"not-vesperized"};let n=await Ii(e,{runningHost:r});if(n.action==="bootstrap"){let{host:o,failed:i}=await Ll(e,n,{quiet:t});return i.length?{host:o,failed:i}:{host:o}}n.action==="refuse"?u.warn(n.reason==="host-mismatch"?`This workspace is provisioned for "${n.host}" but bootstrap was invoked as "${r}" \u2014 skipping all provisioning. Run \`vespercli init --host ${r}\` to switch, or \`vespercli reset --host ${r}\` to remove stray ${r} files.`:`Bootstrap wrote nothing. ${n.message}`):n.note&&(!t||n.reason==="legacy-unmigrated"||n.reason==="migration-in-progress")&&(n.reason==="legacy-unmigrated"||n.reason==="migration-in-progress"?u.warn(n.note):u.info(n.note));let s=n.host??n.checkout?.candidate??null;return{skipped:n.action==="refuse"?"host-mismatch":n.reason,...s?{host:s}:{}}}async function Vb(e,{sshCommandConfigured:t=!1}={}){let r=await D(["rev-parse","--abbrev-ref","origin/HEAD"],{cwd:e}),n=r===null?-1:r.indexOf("/");if(n===-1)return{note:"No base branch remote to refresh (origin/HEAD unset or no remote)."};let s=r.slice(0,n),o=r.slice(n+1),i=await Tt(["fetch",s,o],{cwd:e,timeout:15e3,env:Vn(process.env,{sshCommandConfigured:t}),detached:!0});return!i.ok&&ka.test(i.stderr)?(u.warn(Sa(`Fetching the latest ${s}/${o}`)),{}):i.ok?{action:`${s}/${o} fetched (latest base branch ref)`}:(u.warn(`Could not fetch the latest ${s}/${o} (offline, unreachable or timed out) \u2014 continuing with existing local refs.`),{})}async function Pm(e,t={}){let r=Mb(t.path||process.cwd()),n=!!t.quiet;switch(e){case"bootstrap":case void 0:return Db(r,n,{runningHost:t.runningHost});default:u.error(`Unknown subcommand: ${e}. Usage: vespercli worktree bootstrap`),process.exit(1)}}import{resolve as Hb}from"node:path";te();Pe();async function Im(e={}){let t=Hb(e.path||process.cwd()),r=!!e.quiet,n=e.runningHost;if(n!==void 0&&!z.includes(n))return r||u.error(`--running-host must be one of: ${z.join(", ")} (received "${n}").`),{exitCode:Te.ERROR,report:null};let s;try{s=await _n(t,{runningHost:n})}catch(i){return r||u.error(`doctor failed unexpectedly: ${i?.message||i}`),{exitCode:Te.ERROR,report:null}}let o=Ri(s);return r||Ub(s),{exitCode:o,report:s}}function Ub(e){if(e.errors.length+e.warnings.length+e.infos.length===0){u.success("No issues found \u2014 this Vesper workspace is healthy.");return}Ml("Errors",e.errors,r=>u.error(r)),Ml("Warnings",e.warnings,r=>u.warn(r)),Ml("Info",e.infos,r=>u.info(r))}function Ml(e,t,r){if(t.length){console.log(),u.header(e);for(let n of t){let s=n.path?` (${n.path})`:"";r(`${n.message}${s}`),u.dim(` fix: ${n.fix}`)}}}import{resolve as Xb}from"node:path";te();Ae();import{readFile as Wb,readdir as Kb,stat as Mm}from"node:fs/promises";import{homedir as Ys}from"node:os";import{join as Bt,resolve as Gm,isAbsolute as Bb}from"node:path";var na=Object.freeze({NOT_ENABLED:"plugin-not-enabled",NOT_DECLARED:"marketplace-not-declared",SOURCE_MISSING:"marketplace-source-missing",INVALID_DECLARATION:"marketplace-declaration-invalid"});function Gl(e,t){return e.replace(/^~(?=$|[\\/])/,t)}function Fm({env:e=process.env,homeDir:t=Ys()}={}){let r=typeof e.CLAUDE_CONFIG_DIR=="string"?e.CLAUDE_CONFIG_DIR.trim():"";return r?Gm(Gl(r,t)):Bt(t,".claude")}function jm({env:e=process.env,homeDir:t=Ys()}={}){let r=typeof e.CLAUDE_CODE_PLUGIN_CACHE_DIR=="string"?e.CLAUDE_CODE_PLUGIN_CACHE_DIR.trim():"";return r?Gm(Gl(r,t)):Bt(Fm({env:e,homeDir:t}),"plugins")}function zb(e=process.platform){return e==="darwin"?"/Library/Application Support/ClaudeCode":e==="win32"?"C:\\Program Files\\ClaudeCode":"/etc/claude-code"}async function Rm(e){try{let t=JSON.parse(await Wb(e,"utf-8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}async function Nm(e){try{return await Mm(e),!0}catch{return!1}}async function Yb(e){try{return(await Mm(e)).isFile()}catch{return!1}}async function Jb(e,{env:t=process.env,homeDir:r=Ys(),platform:n=process.platform,managedDir:s}={}){let o=s??zb(n),i=[{scope:"user",path:Bt(Fm({env:t,homeDir:r}),"settings.json")},{scope:"project",path:Fe(e)},{scope:"local",path:En(e)},{scope:"managed",path:Bt(o,"managed-settings.json")}];try{let a=(await Kb(Bt(o,"managed-settings.d"))).filter(c=>c.endsWith(".json")).sort();for(let c of a)i.push({scope:"managed",path:Bt(o,"managed-settings.d",c)})}catch{}return i}function Lm(e,t=Ys()){let r=s=>{if(typeof s!="string"||!s.trim())return null;let o=Gl(s.trim(),t);return Bb(o)?o:null};if(typeof e=="string")return r(e);if(!e||typeof e!="object")return null;let n=e.source;return typeof n=="string"?null:n&&typeof n=="object"?(n.source==="directory"||n.source==="file")&&typeof n.path=="string"?r(n.path):null:typeof e.installLocation=="string"?r(e.installLocation):null}async function qb(e){return await Nm(e)?await Yb(e)?!0:Nm(Bt(e,".claude-plugin","marketplace.json")):!1}async function Dm(e,t={}){let r=t.env??process.env,n=t.homeDir??Ys(),s=await Jb(e,{...t,env:r,homeDir:n}),o,i=null,a,c=[],l=[];for(let m of s){let h=await Rm(m.path);if(!h)continue;let g=h.enabledPlugins;g&&typeof g=="object"&&typeof g[yt]=="boolean"&&(m.scope==="managed"?a!==!0&&(a=g[yt]):(o=g[yt],i=m.scope));let y=h.extraKnownMarketplaces;if(y&&typeof y=="object"&&y[$e]!==void 0&&y[$e]!==null){let k=y[$e];if(k&&typeof k=="object"&&typeof k.source=="string"){l.push({scope:m.scope,path:m.path});continue}c.push({scope:m.scope,path:m.path,localPath:Lm(k,n),exists:null})}}a!==void 0&&(o=a,i="managed");let d=await Rm(Bt(jm({env:r,homeDir:n}),"known_marketplaces.json"));if(d&&d[$e]!==void 0&&d[$e]!==null){let m=d[$e],h=m&&typeof m=="object"&&m.source&&typeof m.source=="object"&&m.source.source!=="directory"&&m.source.source!=="file";c.push({scope:"known_marketplaces",path:Bt(jm({env:r,homeDir:n}),"known_marketplaces.json"),localPath:h?null:Lm(m,n),exists:null})}let p=typeof r.CLAUDE_CODE_PLUGIN_SEED_DIR=="string"&&r.CLAUDE_CODE_PLUGIN_SEED_DIR.trim()!=="",f=[];if(o!==!0&&f.push(na.NOT_ENABLED),c.length===0&&!p)f.push(l.length?na.INVALID_DECLARATION:na.NOT_DECLARED);else if(c.length>0&&!p){let m=!1,h=!1;for(let g of c){if(g.localPath===null){m=!0;continue}g.exists=await qb(g.localPath),g.exists&&(h=!0)}!m&&!h&&f.push(na.SOURCE_MISSING)}return{absent:f.length>0,missing:f,enabled:o,enabledBy:i,declarations:c,invalidDeclarations:l}}wt();it();async function Qb(e,t){try{let{realpath:r}=await import("node:fs/promises"),{resolve:n}=await import("node:path"),s=await D(["rev-parse","--absolute-git-dir"],{cwd:t,env:br(process.env),timeout:5e3});return s?await r(n(process.cwd(),e))===await r(s):!1}catch{return!1}}async function Vm(e){let t=process.stdout.write,r=[];process.stdout.write=(n,...s)=>{r.push(typeof n=="string"?n:String(n));let o=s.find(i=>typeof i=="function");return o&&o(),!0};try{return await e()}finally{process.stdout.write=t,r.length&&process.stderr.write(r.join(""))}}function Hm(e){process.stdout.write(`${e}
210
+ `)}async function Um(e={}){let t=Xb(e.path||process.cwd()),r={};if(process.env.GIT_DIR&&await Qb(process.env.GIT_DIR,t))for(let n of io())n in process.env&&(r[n]=process.env[n],delete process.env[n]);try{return await Zb(t,e)}finally{Object.assign(process.env,r)}}async function Zb(e,t){let r=t.bootstrap!==!1;if(t.runningHost!==void 0&&!hf(t.runningHost))return process.stderr.write(`vespercli guard: --running-host must be one of: ${[...z,Ns].join(", ")} (received "${t.runningHost}")
211
+ `),{exitCode:Te.ERROR,emitted:[],resolved:{host:null,source:null}};let n=ff(t.runningHost),s=await Ii(e,{runningHost:n,runningLabel:t.runningHost}),o={host:s.checkout?.host??null,source:s.checkout?.source??null},i=null;if(s.identity)try{i=await _n(e,{runningHost:n,checkout:s.checkout})}catch{i=null}if(s.action==="refuse")return Hm(Ti),process.stdout.write(`${s.message}
212
+ `),await Vm(async()=>{if(s.reason!=="switch-in-progress")try{await yf(e,n,{checkout:s.checkout})}catch{}}),{exitCode:Te.HOST_MISMATCH,emitted:[Ti],resolved:o,decision:s};let a=[];if(await Vm(async()=>{s.action==="bootstrap"&&r&&({failed:a}=await Ll(e,s,{quiet:!0}))}),s.action==="none"&&s.note&&(s.identity||process.stderr.isTTY)&&process.stderr.write(`${s.note}
213
+ `),!s.identity)return{exitCode:a.length?Te.ERROR:Te.OK,emitted:[],resolved:o,decision:s};let c=[];if(t.runningHost==="claude"&&o.host==="claude"){let d=null;try{d=await Dm(e)}catch{d=null}d?.absent&&(Hm(Wc),c.push(Wc))}let l=i?Ri(i):Te.ERROR;if(a.length&&l===Te.OK&&(l=Te.ERROR),i&&l===Te.ERROR)for(let d of i.errors)process.stderr.write(`vespercli guard: ${d.message} (fix: ${d.fix})
214
+ `);return{exitCode:l,emitted:c,resolved:o,decision:s}}Es();U();import{resolve as ex,isAbsolute as tx,join as rx}from"node:path";async function Wm(e={}){let t=ex(e.path||process.cwd()),r=!!e.json,n=await Yd(t);if(!n.ok){let l=n.reason==="missing"?`No ${ue} in ${t} \u2014 run \`vespercli init\` to seed one.`:`${ue} is invalid: ${n.errors.join("; ")}`;return r?console.log(JSON.stringify({pass:!1,error:l,exitCode:jr.NO_CONFIG})):console.error(l),{exitCode:jr.NO_CONFIG,report:null}}let s=null;if(e.plan){let l=tx(e.plan)?e.plan:rx(t,e.plan);if(!await w(l)){let d=`--plan file not found: ${e.plan}`;return r?console.log(JSON.stringify({pass:!1,error:d,exitCode:jr.NO_CONFIG})):console.error(d),{exitCode:jr.NO_CONFIG,report:null}}s=(await Jd(l)).planned}let o=[];for(let l of n.config.checks)o.push(Qd(l,t));let i=await Zd(t,e.base),a=i.skipped?null:i,c=qd({config:n.config,checks:o,diff:a,planned:s,diffSkipped:i.skipped||null});return console.log(r?JSON.stringify(c):Xd(c)),{exitCode:c.pass?jr.PASS:jr.FAIL,report:c}}import{resolve as nx}from"node:path";async function sx(){if(process.stdin.isTTY)return"";let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function Km(e,t={}){let r=nx(t.path||process.cwd()),n=!!t.json;if(e==="tail"){let a=t.lines===void 0?Xi:Number(t.lines);if(!Number.isFinite(a)||a<0)return console.error(`-n must be a non-negative number (received "${t.lines}")`),{exitCode:On.INVALID};let{rows:c,malformed:l}=await Gh(r,{slug:t.slug}),d=Fh(c,a);if(n)for(let p of d)console.log(JSON.stringify(p));else if(d.length===0)console.log(t.slug?`No run ledger rows for slug "${t.slug}".`:"No run ledger rows yet.");else for(let p of d)console.log(Dh(p));return l>0&&!n&&console.error(`(${l} malformed line(s) skipped)`),{exitCode:On.OK}}if(!Bs.includes(e))return console.error(`Unknown log event "${e}". Use one of: ${Bs.join(", ")}, tail.`),{exitCode:On.INVALID};let s={event:e,pipeline:t.pipeline,step:t.step,agent:t.agent,goal:t.goal,author:t.author,status:t.status,note:t.note,session:t.session};if(t.stdin){let a=Vh(await sx());a&&(!s.agent&&a.agent&&(s.agent=a.agent),!s.session&&a.session&&(s.session=a.session))}let o=Lh(s);if(!o.ok){for(let a of o.errors)console.error(a);return{exitCode:On.INVALID}}let{rel:i}=await Mh(r,o.row,{slug:t.slug});return console.log(n?JSON.stringify({...o.row,file:i}):`logged ${e} \u2192 ${i}`),{exitCode:On.OK}}import{resolve as ux}from"node:path";U();import{readdir as ox,readFile as ix}from"node:fs/promises";import{join as Fl}from"node:path";var Dl=".vesper/.tracking/stories",Hr=Object.freeze(["refining","backlog","inprogress","inreview","completed"]),gr=Object.freeze({OK:0,REFUSED:1,INVALID:2});function ax(e){return e.replace(/\.md$/i,"").replace(/^\d{8}-/,"").replace(/-story$/i,"")}function cx(e){let t=/^#\s+(.+?)\s*$/m.exec(String(e??""));return t?t[1]:null}async function Vl(e,{folder:t}={}){let r=t?[t]:Hr,n=[];for(let s of r){let o=Fl(e,Dl,s),i=[];try{i=await ox(o,{withFileTypes:!0})}catch{continue}for(let a of i.filter(c=>c.isFile()&&c.name.toLowerCase().endsWith(".md")).sort((c,l)=>c.name.localeCompare(l.name))){let c=`${Dl}/${s}/${a.name}`,l=null;try{l=cx(await ix(Fl(o,a.name),"utf-8"))}catch{l=null}n.push({slug:ax(a.name),folder:s,file:a.name,rel:c,title:l})}}return n}async function lx(e,t){let r=String(t??"").trim().toLowerCase();return r?(await Vl(e)).filter(n=>n.file.toLowerCase().includes(r)):[]}async function Bm(e,t,r){if(!Hr.includes(r))return{ok:!1,reason:"invalid-folder"};let n=await lx(e,t);if(n.length===0)return{ok:!1,reason:"not-found",matches:n};if(n.length>1)return{ok:!1,reason:"ambiguous",matches:n};let[s]=n,o=`${Dl}/${r}/${s.file}`;if(s.folder===r)return{ok:!0,from:s.rel,to:o,method:"noop"};if(await w(Fl(e,o)))return{ok:!1,reason:"exists",matches:n};let i=await Ji(e,s.rel,o);return i.ok?{ok:!0,from:s.rel,to:o,method:i.method}:{ok:!1,reason:i.reason,matches:n}}function zm(e){if(e.length===0)return"(no stories)";let t=Math.max(...e.map(r=>r.folder.length));return e.map(r=>`${r.folder.padEnd(t)} ${r.slug}${r.title?` \u2014 ${r.title}`:""}`).join(`
215
+ `)}async function Ym(e,t,r,n={}){let s=ux(n.path||process.cwd()),o=!!n.json;if(e==="list"){if(n.folder&&!Hr.includes(n.folder))return console.error(`--folder must be one of ${Hr.join("|")} (received "${n.folder}")`),{exitCode:gr.INVALID};let i=await Vl(s,{folder:n.folder});return console.log(o?JSON.stringify(i):zm(i)),{exitCode:gr.OK}}if(e==="move"){if(!t||!r)return console.error("Usage: vespercli story move <slug> <folder>"),{exitCode:gr.INVALID};if(!Hr.includes(r))return console.error(`Folder must be one of ${Hr.join("|")} (received "${r}")`),{exitCode:gr.INVALID};let i=await Bm(s,t,r);if(!i.ok){let a=(i.matches||[]).map(l=>l.rel),c=i.reason==="not-found"?`No story matches "${t}" under .vesper/.tracking/stories/.`:i.reason==="ambiguous"?`"${t}" matches ${a.length} stories \u2014 be more specific:
203
216
  ${a.join(`
204
- `)}`:i.reason==="exists"?`Refusing: a file with that name already exists in ${r}/.`:`Refusing: ${i.reason}.`;return o?console.log(JSON.stringify({ok:!1,reason:i.reason,matches:a})):console.error(c),{exitCode:rr.REFUSED}}return console.log(o?JSON.stringify(i):i.method==="noop"?`Already in ${r}/: ${i.from}`:`Moved (${i.method}): ${i.from} \u2192 ${i.to}`),{exitCode:rr.OK}}return console.error(`Unknown story subcommand "${e}". Use: move <slug> <folder>, list [--folder <f>].`),{exitCode:rr.INVALID}}be();Ja();Lo();Te();import{resolve as XE}from"node:path";var Ri=Object.freeze({OK:0,REFUSED:1,USAGE:2}),tm=["Usage: vespercli opencode <subcommand> [--path <dir>]","","OpenCode is a companion of the Claude host: `vespercli init --host claude` writes the overlay",`(\`${as}\`, \`${kr}/vesper-orchestrator.md\`, \`.opencode/plugins/vesper.js\`),`,"and the plugin registers every specialist from the installed package at runtime.","","Subcommands:",` render-agents Write \`${kr}/<id>.md\` for every core + enabled-pack specialist`,' (the generated-files fallback \u2014 `vesper.agentsMode: "files"` in opencode.json),'," record them in the ledger and prune the recorded files whose agent is gone."," Idempotent. Packs: opencode.json `vesper.packs`, else the Claude host's enabled packs.","","Related:"," vespercli mcp serve <name> Run a catalog MCP server from the package (what opencode.json `mcp` points at)"," vespercli --print-assets-dir Print the package assets directory (what the plugin locates the catalog with)"].join(`
205
- `);async function rm(e,t={}){let r=XE(t.path||process.cwd());if(!e||e==="help")return console.log(tm),{exitCode:Ri.OK};if(e!=="render-agents")return console.error(`Unknown opencode subcommand "${e}".
217
+ `)}`:i.reason==="exists"?`Refusing: a file with that name already exists in ${r}/.`:`Refusing: ${i.reason}.`;return o?console.log(JSON.stringify({ok:!1,reason:i.reason,matches:a})):console.error(c),{exitCode:gr.REFUSED}}return console.log(o?JSON.stringify(i):i.method==="noop"?`Already in ${r}/: ${i.from}`:`Moved (${i.method}): ${i.from} \u2192 ${i.to}`),{exitCode:gr.OK}}return console.error(`Unknown story subcommand "${e}". Use: move <slug> <folder>, list [--folder <f>].`),{exitCode:gr.INVALID}}be();Ac();ai();Pe();import{resolve as dx}from"node:path";var sa=Object.freeze({OK:0,REFUSED:1,USAGE:2}),Jm=["Usage: vespercli opencode <subcommand> [--path <dir>]","","OpenCode is a companion of the Claude host: `vespercli init --host claude` writes the overlay",`(\`${Cs}\`, \`${Nr}/vesper-orchestrator.md\`, \`.opencode/plugins/vesper.js\`),`,"and the plugin registers every specialist from the installed package at runtime.","","Subcommands:",` render-agents Write \`${Nr}/<id>.md\` for every core + enabled-pack specialist`,' (the generated-files fallback \u2014 `vesper.agentsMode: "files"` in opencode.json),'," record them in the ledger and prune the recorded files whose agent is gone."," Idempotent. Packs: opencode.json `vesper.packs`, else the Claude host's enabled packs.","","Related:"," vespercli mcp serve <name> Run a catalog MCP server from the package (what opencode.json `mcp` points at)"," vespercli --print-assets-dir Print the package assets directory (what the plugin locates the catalog with)"].join(`
218
+ `);async function qm(e,t={}){let r=dx(t.path||process.cwd());if(!e||e==="help")return console.log(Jm),{exitCode:sa.OK};if(e!=="render-agents")return console.error(`Unknown opencode subcommand "${e}".
206
219
 
207
- ${tm}`),{exitCode:Ri.USAGE};let{host:n}=await W(r);if(n!=="claude")return u.error("`vespercli opencode render-agents` needs a workspace provisioned for the Claude host (OpenCode is its companion) \u2014 nothing was written. Run `vespercli init --host claude` first."),{exitCode:Ri.REFUSED};let s=await Vo(r,{packs:t.packs}),o=s.packs.length?s.packs.join(", "):"none";return u.success(`OpenCode agents: ${s.agents.length} specialist file(s) under ${kr}/ (core + packs: ${o}) \u2014 ${s.written.length} written, ${s.unchanged.length} unchanged.`),s.pruned.length&&u.info(`Pruned (agent gone): ${s.pruned.join(", ")}`),s.kept.length&&u.warn(`Kept (edited by hand, record dropped): ${s.kept.join(", ")}`),u.dim(' OpenCode reads these when opencode.json sets `vesper.agentsMode: "files"`; in the default plugin mode the plugin registers the same ids at runtime.'),{exitCode:Ri.OK}}Ee();var rb=tb(import.meta.url),nb=al(rb);function sb(e){let t=e;for(;t!==al(t);){let r=nm(t,"package.json");if(eb(r))return r;t=al(t)}return nm(e,"..","..","package.json")}var ob=sb(nb),cl=JSON.parse(ZE(ob,"utf-8")),ue=new QE;ue.name("vespercli").description("Vesper VS Code Agent Suite \u2014 provision an AI agent suite for Claude Code + OpenCode, or GitHub Copilot (one host per workspace)").version(cl.version,"-v, --version","Output the current version").option("--print-assets-dir","Print the absolute path of the package's assets directory and exit");process.argv[2]==="--print-assets-dir"&&(process.stdout.write(`${O}
208
- `),process.exit(0));ue.command("init").description("Initialize vesper for exactly ONE host (GitHub Copilot, or Claude Code + OpenCode) in this workspace \u2014 prompts when omitted; switching hosts cleans the other host's artifacts after confirmation").option("-p, --path <path>","Workspace root directory",process.cwd()).option("-y, --yes","Skip follow-up prompts and the host-switch confirmation (not the host selection)").option("-f, --force","Force re-initialization (skips follow-up prompts)").option("--force-default","Use all default values for follow-up prompts (not the host selection)").addOption(new at("--host <host>","The single host to provision: claude (Claude Code + OpenCode \u2014 the OpenCode overlay is always written) or copilot. Interactive prompt if omitted (non-interactive runs reuse the recorded host).").choices(["claude","copilot"])).addOption(new at("--target <target>","Deprecated alias of --host").hideHelp()).action(e=>oh({...e,version:cl.version}));function $s(e){return new at("--host <host>",e).choices(["claude","copilot"])}var Os=()=>new at("--target <target>","Deprecated alias of --host").hideHelp();function Ts(e,t){return t.host?{...t,target:t.host}:(t.target&&process.stderr.write(`\`--target\` is deprecated on \`${e}\`; use \`--host\` instead.
209
- `),t)}ue.command("add").description("Add an opt-in asset. Copilot: opt-in instructions (every agent, prompt and skill is already available). Claude Code: every specialist and skill is served by the vesper plugin \u2014 `--override` pins a project-level copy. Host auto-detected when omitted.").argument("[type]","Asset type (agents, prompts, instructions, skills)").argument("[name]","Asset name (specific asset to add)").option("--path <path>","Workspace root directory",process.cwd()).addOption($s("Host to act on: claude or copilot (the checkout decides when omitted)")).addOption(Os()).option("--override","Claude Code only: pin a project-level copy of a plugin asset (recorded; reset removes it)").action((e,t,r)=>lh({type:e,name:t,...Ts("add",r)}));ue.command("reset").description("Remove a host's Vesper artifacts. `--host <x>` force-cleans host x (the active host = full teardown; the other host = foreign-residue clean, never an ambiguity error). Auto-detected from the workspace when omitted.").option("--path <path>","Workspace root directory",process.cwd()).option("-y, --yes","Skip confirmation prompts").addOption(new at("--host <host>","Host whose artifacts to remove: claude or copilot").choices(["claude","copilot"])).option("--purge-knowledge","On a FULL teardown, also delete the Team Roster, project whitepaper and on-demand context tier (kept by default)").addOption(new at("--target <target>","Deprecated alias of --host").hideHelp()).action(pf);ue.command("list").alias("ls").description("List enabled assets").argument("[type]","Filter by asset type (agents, prompts, instructions, skills)").option("--path <path>","Workspace root directory",process.cwd()).addOption($s("Host to list: claude or copilot (the checkout decides when omitted)")).addOption(Os()).action((e,t)=>hh({type:e,...Ts("list",t)}));ue.command("update").description("Refresh the checkout's host \u2014 the Claude Code committed fallback + orchestrator playbook, or the Copilot surface.").option("--path <path>","Workspace root directory",process.cwd()).addOption($s("Host to refresh: claude or copilot (the checkout decides when omitted)")).addOption(Os()).action(e=>Nh({...Ts("update",e),version:cl.version}));ue.command("packs").description("Manage the stack packs (vesper-<pack> plugins / Copilot pack folders) this project enables. `list` shows what the package ships, what is enabled here and what the Team Roster needs; `enable`/`disable <pack>` act on one pack (`styles` also writes/removes its always-on pointer rule); `sync` enables every pack the Team Roster names an asset of (never disables \u2014 it prints what it would); `upstream` compares each third-party pack skill with its upstream (network).").argument("[subcommand]","Subcommand: list (default), enable, disable, sync, upstream").argument("[pack]","Pack name for enable/disable (e.g. frontend, playwright, backend, styles)").option("--path <path>","Workspace root directory",process.cwd()).addOption($s("Host to act on: claude or copilot (the checkout decides when omitted)")).addOption(Os()).action((e,t,r)=>th(e,t,Ts("packs",r)));ue.command("opencode").description("OpenCode companion helpers. `render-agents` writes `.opencode/agents/<id>.md` for every core + enabled-pack specialist (the generated-files fallback of the OpenCode plugin), records them and prunes the gone ones. No subcommand prints the usage.").argument("[subcommand]","Subcommand: render-agents").option("--path <path>","Workspace root directory",process.cwd()).action(async(e,t)=>{let{exitCode:r}=await rm(e,t);process.exit(r)});ue.command("catalog").description("Show the Vesper catalog (agents, dependencies, requirements)").action(mh);ue.command("mcp").description("Manage MCP servers and tool auto-approval. `serve <name>` runs a catalog MCP server (vesper-indexing, sequential-thinking, memory, \u2026) from the installed package with stdio inherited \u2014 what a committed `opencode.json` points at path-free (exit 2 on an unknown name).").argument("[subcommand]","Subcommand: status, add, remove, list, sync, approve, reindex, enable, disable, serve").argument("[argument]","Argument for subcommand (e.g., server name for add/remove/serve)").option("--path <path>","Workspace root directory",process.cwd()).option("--full","Full reindex (clears existing index)").option("-w, --watch","Watch indexing progress until completion").addOption($s("Host whose MCP config to manage: claude or copilot (the checkout decides when omitted)")).addOption(Os()).action((e,t,r)=>Ph(e,t,Ts("mcp",r)));ue.command("settings").description("Manage VS Code settings").argument("[subcommand]","Subcommand: add, remove, list").argument("[setting-key]","Setting key (e.g., read-access)").argument("[value]","Value to add/remove").option("--path <path>","Workspace root directory",process.cwd()).action((e,t,r,n)=>jh(e,t,r,n));ue.command("doctor").description("Validate this workspace's Vesper install (read-only) \u2014 host identity, owned-files manifest, MCP config, tracking, framework version").option("--path <path>","Workspace root directory",process.cwd()).option("--quiet","Suppress all output; communicate only via exit code (guard mode)").addOption(new at("--running-host <host>","The host currently running \u2014 enables the host-identity check").choices(["claude","copilot"])).action(async e=>{let{exitCode:t}=await Dh(e);process.exit(t)});ue.command("guard").description("Session-start host guard \u2014 verifies this workspace's provisioned host against the running one, emits VESPER_HOST_MISMATCH on stdout on a mismatch (no bootstrap), otherwise runs `worktree bootstrap`. With --running-host claude the healthy path also emits VESPER_PLUGIN_ABSENT when the Vesper plugin verifiably cannot load on this machine (not enabled, or no vesper-marketplace source declared); presence is never claimed. `--running-host opencode` is the Claude host's identity (a Claude workspace is healthy, a Copilot one a mismatch; the plugin token is never emitted for it). The installed triggers pass --running-host; omit it (git hooks, manual runs) for no identity claim: no mismatch check, no mismatch marker, and it acts only when the checked-out commit confirms the provisioned host. Exit code (0 ok / 1 degraded / 2 mismatch) is meaningful ONLY on direct invocation \u2014 the installed hook/task wrappers force exit 0 by design; the marker on stdout is the contract.").option("--path <path>","Workspace root directory",process.cwd()).addOption(new at("--running-host <host>","The host currently running (claude|copilot|opencode \u2014 opencode stands for the claude host); omit for no identity claim").choices(["claude","copilot","opencode"])).option("--no-bootstrap","Do not invoke worktree bootstrap on the healthy path (testing)").action(async e=>{let{exitCode:t}=await Yh(e);process.exit(t)});ue.command("gate").description("Run the project's committed gate policy (.vesper/gates.json): every configured check (`sh -c`, from the workspace root), plan conformance (--plan), the diff-size cap and the protected paths. Exit 0 pass, 1 fail, 2 no/invalid config. Read-only apart from what the checks themselves do.").option("--path <path>","Workspace root directory",process.cwd()).option("--plan <file>","A plan (or details) file: changed files it does not name fail the gate (.vesper/.tracking/ is always allowed)").option("--base <ref>","Diff the working tree against this ref instead of HEAD (untracked files always count)").option("--json","Print one JSON object on stdout and nothing else").action(async e=>{let{exitCode:t}=await qh(e);process.exit(t)});ue.command("log").description("Append one row to the run ledger (.vesper/.tracking/runs/YYYYMMDD-<slug>.jsonl) \u2014 `started|completed|note|delegated|returned` \u2014 or print its last rows with `tail`. The orchestrator calls it before and after each pipeline on both hosts; Claude Code's SubagentStart hook adds `delegated` rows as optional enrichment (`--stdin`). Exit 0; exit 2 on a missing or invalid required field.").argument("<event>","started | completed | note | delegated | returned | tail").option("--path <path>","Workspace root directory",process.cwd()).option("--pipeline <pipeline>","Pipeline name (required for every event but tail), e.g. implementation, refinement, testing").option("--step <step>","Pipeline step").option("--agent <agent>","Subagent name (required for delegated/returned)").option("--goal <goal>","What the run is for (required for started)").option("--author <author>","Who is orchestrating, e.g. the model/session identity").addOption(new at("--status <status>","Handoff status (required for completed/returned)").choices(["DONE","NEED_HELP","BLOCKED"])).option("--slug <slug>","Story/task slug the row belongs to (default: adhoc); tail: only this slug").option("--note <text>","Free text").option("--session <id>","Session identifier (hooks pass session_id)").option("--stdin","Read a Claude Code hook's JSON from stdin: agent_type \u2192 --agent, session_id \u2192 --session (when the flags are absent)").option("-n, --lines <n>","tail: how many rows (default 5)").option("--json","Print the appended row (or each tailed row) as JSON and nothing else").action(async(e,t)=>{let{exitCode:r}=await Xh(e,t);process.exit(r)});ue.command("story").description("Story folders under .vesper/.tracking/stories/ (folder = status). `move <slug> <folder>` finds the story by substring of its file name and refuses on 0 or >1 matches (git mv when tracked and clean, plain rename otherwise); `list [--folder <f>]` prints slug, folder and title. Exit 0; 1 refused; 2 usage.").argument("<subcommand>","move | list").argument("[slug]","move: the story slug (or any unique substring of its file name)").argument("[folder]","move: refining | backlog | inprogress | inreview | completed").option("--path <path>","Workspace root directory",process.cwd()).addOption(new at("--folder <folder>","list: only this folder").choices(["refining","backlog","inprogress","inreview","completed"])).option("--json","Print JSON and nothing else").action(async(e,t,r,n)=>{let{exitCode:s}=await em(e,t,r,n);process.exit(s)});ue.command("worktree").description("Bootstrap a git worktree with Vesper's local-only artifacts (host MCP config, code index, gitignore, git hooks). Gated on the provisioned host: with --running-host set and disagreeing, nothing is written; without it, nothing is written unless the checked-out commit confirms the provisioned host.").argument("[subcommand]","Subcommand: bootstrap (default)").option("--path <path>","Workspace root directory",process.cwd()).option("-q, --quiet","Suppress non-error output (used by hooks/tasks)").addOption(new at("--running-host <host>","The host invoking bootstrap; a mismatch with the provisioned host skips all provisioning").choices(["claude","copilot"])).action(async(e,t)=>{(await Mh(e,t))?.failed?.length&&(process.exitCode=1)});ue.addHelpText("after",`
220
+ ${Jm}`),{exitCode:sa.USAGE};let{host:n}=await B(r);if(n!=="claude")return u.error("`vespercli opencode render-agents` needs a workspace provisioned for the Claude host (OpenCode is its companion) \u2014 nothing was written. Run `vespercli init --host claude` first."),{exitCode:sa.REFUSED};let s=await pi(r,{packs:t.packs}),o=s.packs.length?s.packs.join(", "):"none";return u.success(`OpenCode agents: ${s.agents.length} specialist file(s) under ${Nr}/ (core + packs: ${o}) \u2014 ${s.written.length} written, ${s.unchanged.length} unchanged.`),s.pruned.length&&u.info(`Pruned (agent gone): ${s.pruned.join(", ")}`),s.kept.length&&u.warn(`Kept (edited by hand, record dropped): ${s.kept.join(", ")}`),u.dim(' OpenCode reads these when opencode.json sets `vesper.agentsMode: "files"`; in the default plugin mode the plugin registers the same ids at runtime.'),{exitCode:sa.OK}}Ee();var gx=mx(import.meta.url),yx=Hl(gx);function wx(e){let t=e;for(;t!==Hl(t);){let r=Xm(t,"package.json");if(hx(r))return r;t=Hl(t)}return Xm(e,"..","..","package.json")}var vx=wx(yx),Ul=JSON.parse(fx(vx,"utf-8")),de=new px;de.name("vespercli").description("Vesper VS Code Agent Suite \u2014 provision an AI agent suite for Claude Code + OpenCode, or GitHub Copilot (one host per workspace)").version(Ul.version,"-v, --version","Output the current version").option("--print-assets-dir","Print the absolute path of the package's assets directory and exit");process.argv[2]==="--print-assets-dir"&&(process.stdout.write(`${O}
221
+ `),process.exit(0));de.command("init").description("Initialize vesper for exactly ONE host (GitHub Copilot, or Claude Code + OpenCode) in this workspace \u2014 prompts when omitted; switching hosts cleans the other host's artifacts after confirmation").option("-p, --path <path>","Workspace root directory",process.cwd()).option("-y, --yes","Skip follow-up prompts and the host-switch confirmation (not the host selection)").option("-f, --force","Force re-initialization (skips follow-up prompts)").option("--force-default","Use all default values for follow-up prompts (not the host selection)").option("--graphify","Enable the opt-in graphify pack (code knowledge graph for the research roles; external tool: `uv tool install graphifyy`) without asking \u2014 the default, and what -y/--force-default/--force/no TTY keep, is no pack").addOption(new mt("--host <host>","The single host to provision: claude (Claude Code + OpenCode \u2014 the OpenCode overlay is always written) or copilot. Interactive prompt if omitted (non-interactive runs reuse the recorded host).").choices(["claude","copilot"])).addOption(new mt("--target <target>","Deprecated alias of --host").hideHelp()).action(e=>Qh({...e,version:Ul.version}));function Js(e){return new mt("--host <host>",e).choices(["claude","copilot"])}var qs=()=>new mt("--target <target>","Deprecated alias of --host").hideHelp();function Xs(e,t){return t.host?{...t,target:t.host}:(t.target&&process.stderr.write(`\`--target\` is deprecated on \`${e}\`; use \`--host\` instead.
222
+ `),t)}de.command("add").description("Add an opt-in asset. Copilot: opt-in instructions (every agent, prompt and skill is already available). Claude Code: every specialist and skill is served by the vesper plugin \u2014 `--override` pins a project-level copy. Host auto-detected when omitted.").argument("[type]","Asset type (agents, prompts, instructions, skills)").argument("[name]","Asset name (specific asset to add)").option("--path <path>","Workspace root directory",process.cwd()).addOption(Js("Host to act on: claude or copilot (the checkout decides when omitted)")).addOption(qs()).option("--override","Claude Code only: pin a project-level copy of a plugin asset (recorded; reset removes it)").action((e,t,r)=>rm({type:e,name:t,...Xs("add",r)}));de.command("reset").description("Remove a host's Vesper artifacts. `--host <x>` force-cleans host x (the active host = full teardown; the other host = foreign-residue clean, never an ambiguity error). Auto-detected from the workspace when omitted.").option("--path <path>","Workspace root directory",process.cwd()).option("-y, --yes","Skip confirmation prompts").addOption(new mt("--host <host>","Host whose artifacts to remove: claude or copilot").choices(["claude","copilot"])).option("--purge-knowledge","On a FULL teardown, also delete the Team Roster, project whitepaper and on-demand context tier (kept by default)").addOption(new mt("--target <target>","Deprecated alias of --host").hideHelp()).action(oh);de.command("list").alias("ls").description("List enabled assets").argument("[type]","Filter by asset type (agents, prompts, instructions, skills)").option("--path <path>","Workspace root directory",process.cwd()).addOption(Js("Host to list: claude or copilot (the checkout decides when omitted)")).addOption(qs()).action((e,t)=>am({type:e,...Xs("list",t)}));de.command("update").description("Refresh the checkout's host \u2014 the Claude Code committed fallback + orchestrator playbook, or the Copilot surface.").option("--path <path>","Workspace root directory",process.cwd()).addOption(Js("Host to refresh: claude or copilot (the checkout decides when omitted)")).addOption(qs()).action(e=>Om({...Xs("update",e),version:Ul.version}));de.command("packs").description("Manage the stack packs (vesper-<pack> plugins / Copilot pack folders) this project enables. `list` shows what the package ships, what is enabled here and what the Team Roster needs; `enable`/`disable <pack>` act on one pack (`styles` also writes/removes its always-on pointer rule); `sync` enables every pack the Team Roster names an asset of (never disables \u2014 it prints what it would); `upstream` compares each third-party pack skill with its upstream (network).").argument("[subcommand]","Subcommand: list (default), enable, disable, sync, upstream").argument("[pack]","Pack name for enable/disable (e.g. frontend, playwright, backend, styles)").option("--path <path>","Workspace root directory",process.cwd()).addOption(Js("Host to act on: claude or copilot (the checkout decides when omitted)")).addOption(qs()).action((e,t,r)=>Yh(e,t,Xs("packs",r)));de.command("opencode").description("OpenCode companion helpers. `render-agents` writes `.opencode/agents/<id>.md` for every core + enabled-pack specialist (the generated-files fallback of the OpenCode plugin), records them and prunes the gone ones. No subcommand prints the usage.").argument("[subcommand]","Subcommand: render-agents").option("--path <path>","Workspace root directory",process.cwd()).action(async(e,t)=>{let{exitCode:r}=await qm(e,t);process.exit(r)});de.command("catalog").description("Show the Vesper catalog (agents, dependencies, requirements)").action(cm);de.command("mcp").description("Manage MCP servers and tool auto-approval. `serve <name>` runs a catalog MCP server (vesper-indexing, sequential-thinking, memory, \u2026) from the installed package with stdio inherited \u2014 what a committed `opencode.json` points at path-free (exit 2 on an unknown name).").argument("[subcommand]","Subcommand: status, add, remove, list, sync, approve, reindex, enable, disable, serve").argument("[argument]","Argument for subcommand (e.g., server name for add/remove/serve)").option("--path <path>","Workspace root directory",process.cwd()).option("--full","Full reindex (clears existing index)").option("-w, --watch","Watch indexing progress until completion").addOption(Js("Host whose MCP config to manage: claude or copilot (the checkout decides when omitted)")).addOption(qs()).action((e,t,r)=>Am(e,t,Xs("mcp",r)));de.command("settings").description("Manage VS Code settings").argument("[subcommand]","Subcommand: add, remove, list").argument("[setting-key]","Setting key (e.g., read-access)").argument("[value]","Value to add/remove").option("--path <path>","Workspace root directory",process.cwd()).action((e,t,r,n)=>Cm(e,t,r,n));de.command("doctor").description("Validate this workspace's Vesper install (read-only) \u2014 host identity, owned-files manifest, MCP config, tracking, framework version").option("--path <path>","Workspace root directory",process.cwd()).option("--quiet","Suppress all output; communicate only via exit code (guard mode)").addOption(new mt("--running-host <host>","The host currently running \u2014 enables the host-identity check").choices(["claude","copilot"])).action(async e=>{let{exitCode:t}=await Im(e);process.exit(t)});de.command("guard").description("Session-start host guard \u2014 verifies this workspace's provisioned host against the running one, emits VESPER_HOST_MISMATCH on stdout on a mismatch (no bootstrap), otherwise runs `worktree bootstrap`. With --running-host claude the healthy path also emits VESPER_PLUGIN_ABSENT when the Vesper plugin verifiably cannot load on this machine (not enabled, or no vesper-marketplace source declared); presence is never claimed. `--running-host opencode` is the Claude host's identity (a Claude workspace is healthy, a Copilot one a mismatch; the plugin token is never emitted for it). The installed triggers pass --running-host; omit it (git hooks, manual runs) for no identity claim: no mismatch check, no mismatch marker, and it acts only when the checked-out commit confirms the provisioned host. Exit code (0 ok / 1 degraded / 2 mismatch) is meaningful ONLY on direct invocation \u2014 the installed hook/task wrappers force exit 0 by design; the marker on stdout is the contract.").option("--path <path>","Workspace root directory",process.cwd()).addOption(new mt("--running-host <host>","The host currently running (claude|copilot|opencode \u2014 opencode stands for the claude host); omit for no identity claim").choices(["claude","copilot","opencode"])).option("--no-bootstrap","Do not invoke worktree bootstrap on the healthy path (testing)").action(async e=>{let{exitCode:t}=await Um(e);process.exit(t)});de.command("gate").description("Run the project's committed gate policy (.vesper/gates.json): every configured check (`sh -c`, from the workspace root), plan conformance (--plan), the diff-size cap and the protected paths. Exit 0 pass, 1 fail, 2 no/invalid config. Read-only apart from what the checks themselves do.").option("--path <path>","Workspace root directory",process.cwd()).option("--plan <file>","A plan (or details) file: changed files it does not name fail the gate (.vesper/.tracking/ is always allowed)").option("--base <ref>","Diff the working tree against this ref instead of HEAD (untracked files always count)").option("--json","Print one JSON object on stdout and nothing else").action(async e=>{let{exitCode:t}=await Wm(e);process.exit(t)});de.command("log").description("Append one row to the run ledger (.vesper/.tracking/runs/YYYYMMDD-<slug>.jsonl) \u2014 `started|completed|note|delegated|returned` \u2014 or print its last rows with `tail`. The orchestrator calls it before and after each pipeline on both hosts; Claude Code's SubagentStart hook adds `delegated` rows as optional enrichment (`--stdin`). Exit 0; exit 2 on a missing or invalid required field.").argument("<event>","started | completed | note | delegated | returned | tail").option("--path <path>","Workspace root directory",process.cwd()).option("--pipeline <pipeline>","Pipeline name (required for every event but tail), e.g. implementation, refinement, testing").option("--step <step>","Pipeline step").option("--agent <agent>","Subagent name (required for delegated/returned)").option("--goal <goal>","What the run is for (required for started)").option("--author <author>","Who is orchestrating, e.g. the model/session identity").addOption(new mt("--status <status>","Handoff status (required for completed/returned)").choices(["DONE","NEED_HELP","BLOCKED"])).option("--slug <slug>","Story/task slug the row belongs to (default: adhoc); tail: only this slug").option("--note <text>","Free text").option("--session <id>","Session identifier (hooks pass session_id)").option("--stdin","Read a Claude Code hook's JSON from stdin: agent_type \u2192 --agent, session_id \u2192 --session (when the flags are absent)").option("-n, --lines <n>","tail: how many rows (default 5)").option("--json","Print the appended row (or each tailed row) as JSON and nothing else").action(async(e,t)=>{let{exitCode:r}=await Km(e,t);process.exit(r)});de.command("story").description("Story folders under .vesper/.tracking/stories/ (folder = status). `move <slug> <folder>` finds the story by substring of its file name and refuses on 0 or >1 matches (git mv when tracked and clean, plain rename otherwise); `list [--folder <f>]` prints slug, folder and title. Exit 0; 1 refused; 2 usage.").argument("<subcommand>","move | list").argument("[slug]","move: the story slug (or any unique substring of its file name)").argument("[folder]","move: refining | backlog | inprogress | inreview | completed").option("--path <path>","Workspace root directory",process.cwd()).addOption(new mt("--folder <folder>","list: only this folder").choices(["refining","backlog","inprogress","inreview","completed"])).option("--json","Print JSON and nothing else").action(async(e,t,r,n)=>{let{exitCode:s}=await Ym(e,t,r,n);process.exit(s)});de.command("worktree").description("Bootstrap a git worktree with Vesper's local-only artifacts (host MCP config, code index, gitignore, git hooks). Gated on the provisioned host: with --running-host set and disagreeing, nothing is written; without it, nothing is written unless the checked-out commit confirms the provisioned host.").argument("[subcommand]","Subcommand: bootstrap (default)").option("--path <path>","Workspace root directory",process.cwd()).option("-q, --quiet","Suppress non-error output (used by hooks/tasks)").addOption(new mt("--running-host <host>","The host invoking bootstrap; a mismatch with the provisioned host skips all provisioning").choices(["claude","copilot"])).action(async(e,t)=>{(await Pm(e,t))?.failed?.length&&(process.exitCode=1)});de.addHelpText("after",`
210
223
  Examples:
211
224
  $ vespercli init Pick the single host for this workspace, then initialize
212
225
  $ vespercli init --host claude Provision the Claude Code + OpenCode host (CI-friendly)
213
226
  $ vespercli init --host copilot --force-default Non-interactive: Copilot with default settings
227
+ $ vespercli init --host claude --yes --graphify Non-interactive, plus the opt-in graphify pack (interactive init asks)
214
228
  $ vespercli guard --running-host claude Session-start host guard (installed as the SessionStart hook / folder-open task)
215
229
  $ vespercli doctor Validate this workspace's Vesper install (read-only)
216
230
  $ vespercli gate --plan .vesper/.tracking/plans/<plan>.md Run the gate policy; exit 0 pass / 1 fail / 2 no config
@@ -229,6 +243,7 @@ Examples:
229
243
  $ vespercli packs sync Enable every pack the Team Roster names an asset of
230
244
  $ vespercli packs enable frontend Enable one pack by hand (packs disable <pack> removes it)
231
245
  $ vespercli packs enable styles Opt in to the third-party output styles (writes the always-on pointer rule)
246
+ $ vespercli packs enable graphify Opt in to the graphify code knowledge graph (init offers it too; --graphify answers yes)
232
247
  $ vespercli packs upstream Check the third-party pack skills against their upstreams (network)
233
248
  $ vespercli mcp Show MCP server status
234
249
  $ vespercli mcp list List available MCP servers
@@ -258,4 +273,4 @@ Single-host notes:
258
273
 
259
274
  Documentation:
260
275
  https://github.com/mthanhtran/vesper
261
- `);ue.parse();
276
+ `);de.parse();