@mthanh/vespercli 2.0.0 → 2.0.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.
- package/README.md +2 -2
- package/assets/claude/.claude-plugin/marketplace.json +8 -8
- package/assets/claude/.claude-plugin/plugin.json +1 -1
- package/assets/claude/packs/backend/.claude-plugin/plugin.json +1 -1
- package/assets/claude/packs/docs/.claude-plugin/plugin.json +1 -1
- package/assets/claude/packs/frontend/.claude-plugin/plugin.json +1 -1
- package/assets/claude/packs/integrations/.claude-plugin/plugin.json +1 -1
- package/assets/claude/packs/playwright/.claude-plugin/plugin.json +1 -1
- package/assets/claude/packs/polyglot/.claude-plugin/plugin.json +1 -1
- package/assets/claude/packs/styles/.claude-plugin/plugin.json +1 -1
- package/dist/cli.min.js +83 -81
- package/package.json +1 -1
package/dist/cli.min.js
CHANGED
|
@@ -1,83 +1,85 @@
|
|
|
1
|
-
var
|
|
2
|
-
`,1)[0].replace(/\r$/,""),i=
|
|
1
|
+
var Mf=Object.defineProperty;var Ot=(e,t)=>()=>(e&&(t=e(e=0)),t);var ns=(e,t)=>{for(var r in t)Mf(e,r,{get:t[r],enumerable:!0})};var wc={};ns(wc,{HOOK_GUARD_END:()=>wr,HOOK_GUARD_START:()=>mt,classifyForeignHook:()=>vr,findTopLevelExit:()=>yc,hookInterpreter:()=>gc,isBinaryHook:()=>Xo,removeHookRegion:()=>zt});function Xo(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 gc(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 vr(e,{whole:t}={}){let r=c=>Buffer.isBuffer(c)?c:Buffer.from(String(c??""),"utf-8"),n=r(e);if(Xo(r(t??n))||Xo(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=gc(o);if(!Ff.test(i))return{ok:!1,reason:"foreign-hook-language",interpreter:i};let a=yc(s);return a?{ok:!1,reason:"foreign-hook-exits",interpreter:i,line:a}:{ok:!0,interpreter:i}}function zt(e){let t=e.indexOf(mt);if(t===-1)return null;let r=e.indexOf(wr,t);if(r===-1)return null;let n=t,s=r+wr.length;return n>0&&e[n-1]===`
|
|
3
3
|
`&&(n-=1),e[s]===`
|
|
4
|
-
`&&(s+=1),e.slice(0,n)+e.slice(s)}function
|
|
5
|
-
`&&(s+=1),v==="'"&&m==="("){let S=e.indexOf("'",f+1);if(S===-1)return-1;s+=
|
|
4
|
+
`&&(s+=1),e.slice(0,n)+e.slice(s)}function Uf(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,m,y)=>{let k=0;for(;f<c;f+=1){let v=e[f];if(v==="\\"){f+=1;continue}if(v===`
|
|
5
|
+
`&&(s+=1),v==="'"&&m==="("){let S=e.indexOf("'",f+1);if(S===-1)return-1;s+=mc(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=g(f+1);if(S===-1)return-1;f=S;continue}if(v===m)k+=1;else if(v===y&&(k-=1,k===0))return f}return-1},h=f=>{for(;f<c;f+=1){let m=e[f];if(m==="\\"){f+=1;continue}if(m===`
|
|
6
6
|
`&&(s+=1),m==='"')return f;if(m==="$"&&(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(m==="`"){let y=g(f+1);if(y===-1)return-1;f=y}}return-1},g=f=>{for(;f<c;f+=1){let m=e[f];if(m==="\\"){f+=1;continue}if(m===`
|
|
7
7
|
`&&(s+=1),m==="`")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 m=e.indexOf("'",n+1);if(m===-1)return null;o===""&&!a&&(i=s),s+=
|
|
8
|
+
`){n+=2,s+=1;continue}d(e.slice(n,n+2)),n+=2;continue}if(f==="'"){let m=e.indexOf("'",n+1);if(m===-1)return null;o===""&&!a&&(i=s),s+=mc(e,n,m),o+=e.slice(n+1,m),a=!0,n=m+1;continue}if(f==='"'){let m=s,y=h(n+1);if(y===-1)return null;o===""&&!a&&(i=m),o+=e.slice(n+1,y),a=!0,n=y+1;continue}if(f==="`"){let m=g(n+1);if(m===-1)return null;d(e.slice(n,m+1)),n=m+1;continue}if(f==="$"&&(e[n+1]==="("||e[n+1]==="{")){let m=s,y=p(n+1,e[n+1],e[n+1]==="("?")":"}");if(y===-1)return null;o===""&&!a&&(i=m),o+=e.slice(n,y+1),n=y+1;continue}if(f==="#"&&o===""&&!a){let m=e.indexOf(`
|
|
9
9
|
`,n);n=m===-1?c:m;continue}if(f===`
|
|
10
10
|
`){for(l(),t.push({t:"op",v:`
|
|
11
11
|
`,line:s}),s+=1,n+=1;r.length>0;){let{delim:m,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===m){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 m=p(n,"(",")");if(m===-1)return null;o+=e.slice(n,m+1),n=m+1;continue}l(),t.push({t:"op",v:f,line:s}),n+=1;continue}if(f==="<"&&e[n+1]==="<"&&e[n+2]!=="<"){l();let m=n+2,y=e[m]==="-";for(y&&(m+=1);e[m]===" "||e[m]===" ";)m+=1;let k="";for(;m<c&&!/[\s;&|<>()]/.test(e[m]);){if(e[m]==="'"||e[m]==='"'){let v=e[m],S=e.indexOf(v,m+1);if(S===-1)return null;k+=e.slice(m+1,S),m=S+1;continue}if(e[m]==="\\"){k+=e[m+1]??"",m+=2;continue}k+=e[m],m+=1}if(k==="")return null;r.push({delim:k,strip:y}),t.push({t:"word",v:`<<${k}`,line:s,heredoc:!0}),n=m;continue}d(f),n+=1}return l(),r.length>0?null:t}function
|
|
13
|
-
`&&(n+=1);return n}function
|
|
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===m){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 m=p(n,"(",")");if(m===-1)return null;o+=e.slice(n,m+1),n=m+1;continue}l(),t.push({t:"op",v:f,line:s}),n+=1;continue}if(f==="<"&&e[n+1]==="<"&&e[n+2]!=="<"){l();let m=n+2,y=e[m]==="-";for(y&&(m+=1);e[m]===" "||e[m]===" ";)m+=1;let k="";for(;m<c&&!/[\s;&|<>()]/.test(e[m]);){if(e[m]==="'"||e[m]==='"'){let v=e[m],S=e.indexOf(v,m+1);if(S===-1)return null;k+=e.slice(m+1,S),m=S+1;continue}if(e[m]==="\\"){k+=e[m+1]??"",m+=2;continue}k+=e[m],m+=1}if(k==="")return null;r.push({delim:k,strip:y}),t.push({t:"word",v:`<<${k}`,line:s,heredoc:!0}),n=m;continue}d(f),n+=1}return l(),r.length>0?null:t}function mc(e,t,r){let n=0;for(let s=t;s<r;s+=1)e[s]===`
|
|
13
|
+
`&&(n+=1);return n}function yc(e){let t=Uf(e);if(!t)return"(unparsable)";let r=e.split(`
|
|
14
14
|
`),n=g=>(r[g-1]??"").trim(),s=[],o=!0,i="start",a=!1,c=0,l=!1,d=!1,p=()=>s.every(g=>g.kind==="group"&&g.uncond),h=()=>["start",";","nl","&"].includes(i);for(let g=0;g<t.length;g+=1){let f=t[g],m=s[s.length-1];if(f.t==="op"){let v=f.v;if(v==="("){if(m?.kind==="case")continue;if(!o&&t[g+1]?.t==="op"&&t[g+1].v===")"){g+=1,a=!0,o=!0;continue}s.push({kind:"sub",close:")",uncond:h()}),o=!0,i="kw";continue}if(v===")"){if(m?.kind==="case"){l=!1,o=!0,i="kw";continue}if(!m||m.kind!=="sub")return"(unparsable)";s.pop(),o=!1;continue}if(v===";;"){if(m?.kind!=="case")return"(unparsable)";l=!0,o=!0,i=";";continue}if(o=!0,i=v===`
|
|
15
15
|
`?i==="&&"||i==="||"||i==="|"?i:"nl":v,m?.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(m?.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(!m||m.kind!=="group"&&m.kind!=="func")return"(unparsable)";s.pop(),o=!1;continue}if(y!==null&&
|
|
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(`${ie.green("\u2713")} ${i||s}`)},fail(i){this.stop(),console.log(`${ie.red("\u2717")} ${i||s}`)}}}var u,Me=Ot(()=>{u={success:Ff,error:Vf,warn:qo,info:Df,dim:Gf,formatPath:Hf,formatName:Uf,header:Wf,listItem:Bf,vesperTip:Kf,createSpinner:zf}});import{fileURLToPath as Jf}from"node:url";import{dirname as Xo,join as Zr,resolve as Yf}from"node:path";import{readdir as qf}from"node:fs/promises";import{existsSync as Xf,readFileSync as Qf}from"node:fs";function th(e){let t=e;for(;t!==Xo(t);){if(Xf(Zr(t,"package.json")))return t;t=Xo(t)}return Yf(e,"..","..","..")}function ns(){try{return JSON.parse(Qf(Zr(en,"package.json"),"utf-8")).version??null}catch{return null}}function Qo(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 ss(e){let t=Fe[e];if(!t)throw new Error(`Unknown asset type: ${e}`);try{let r=await qf(Zr(gt,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 Zf,eh,en,I,gt,Fe,je=Ot(()=>{Zf=Jf(import.meta.url),eh=Xo(Zf);en=th(eh),I=Zr(en,"assets");gt=Zr(I,"copilot");Fe={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 Zo={};rs(Zo,{DEFAULT_GIT_TIMEOUT_MS:()=>rh,default:()=>nh,runGit:()=>V,runGitCapture:()=>yt});async function V(e,{cwd:t,timeout:r=3e4,env:n,detached:s=!1}={}){if(s){let c=await yt(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 yt(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(m){a({ok:!1,stdout:"",stderr:String(m?.message??m),timedOut:!1});return}let l="",d="",p=!1,h=!1;c.stdout.on("data",m=>{l+=m}),c.stderr.on("data",m=>{d+=m});let g=r?setTimeout(()=>{p=!0;try{i?process.kill(-c.pid,"SIGKILL"):c.kill("SIGKILL")}catch{}},r):null,f=m=>{if(!h){if(h=!0,g&&clearTimeout(g),i)try{process.kill(-c.pid,"SIGKILL")}catch{}a({ok:m,stdout:l,stderr:d,timedOut:p})}};c.on("error",m=>{d+=String(m?.message??m),f(!1)}),c.on("close",m=>f(m===0&&!p))})}var rh,nh,rt=Ot(()=>{rh=3e4;nh=V});import{access as sh,constants as oh,readFile as Sc,readdir as ih}from"node:fs/promises";import{execFile as ah}from"node:child_process";import{join as ei}from"node:path";import ch from"strip-json-comments";async function Ec(e){try{return await sh(e,oh.F_OK),!0}catch{return!1}}function bc(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 ti(e,t){let r=bc(t,"findCodeWorkspaceFile");try{let s=(await ih(e,{withFileTypes:!0})).find(o=>o.isFile()&&o.name.endsWith(".code-workspace")&&(!r||r.has(o.name)));return s?ei(e,s.name):null}catch{return null}}function tn(e){let t=typeof e=="string"?lh.exec(e):null;return t?t[1]:null}function Se(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(Ac,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,ri,{value:!0,enumerable:!1}),Object.freeze(o)}function Sr(e){return!!e&&typeof e=="object"&&e[ri]===!0&&typeof e.test=="function"}function $c(e){if(typeof e!="string"&&!(e&&typeof e=="object"&&e[ri]===!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 nt(e){return $c(e),typeof e=="string"?e:e.path}async function Pt(e,t,r){let n=bc(r,"fingerprintMatchesEntry"),s=nt(t),o=ei(e,s);if(typeof t=="string")return(!n||n.has(s))&&Ec(o);let i=Sr(t)&&t.vscodeSettings?await ti(e,{visible:n}):null;if(i)o=i;else if(n&&!n.has(s))return!1;let a;try{a=await Sc(o,"utf-8")}catch{return!1}return ni(t,a,{fromWorkspaceFile:!!i})}function ni(e,t,{fromWorkspaceFile:r=!1}={}){if(Sr(e)){let n;try{n=Ac[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 si(e,t){return new Promise(r=>{ah("git",t,{cwd:e,maxBuffer:16777216,timeout:5e3,env:ph(process.env)},(s,o)=>{r(s?null:String(o))}).stdin?.end()})}function ph(e){let t={...e,...uh};return!t.GIT_SSH_COMMAND&&!t.GIT_SSH&&(t.GIT_SSH_COMMAND=dh),t}async function fh(e,t){return si(e,["show",`HEAD:./${t}`])}async function hh(e){let t=await si(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 mh(e,t){let r=nt(t);if(typeof t=="string"){let a=await si(e,["cat-file","-e",`HEAD:./${r}`])!==null;return{matched:a,path:a?r:null}}let n=Sr(t)&&t.vscodeSettings?await hh(e):null,s=n||r,o=await fh(e,s);if(o===null)return{matched:!1,path:null};let i=ni(t,o,{fromWorkspaceFile:!!n});return{matched:i,path:i?s:null}}async function oi(e,t,r){let n=ei(e,r);if(typeof t=="string")return Ec(n);nt(t);let s;try{s=await Sc(n,"utf-8")}catch{return!1}let o=Sr(t)&&!!t.vscodeSettings&&r.endsWith(".code-workspace");return ni(t,s,{fromWorkspaceFile:o})}async function Cc(e,{fingerprints:t=Rt()}={}){let r={};for(let s of Object.keys(t)){let o=[];for(let i of t[s]||[]){let a=await mh(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 ii(e){return $c(e),typeof e!="string"?!0:e.toLowerCase().includes("vesper")}function gh(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&&st in e.enabledPlugins||e.agent===H}function yh(e){return!e||typeof e!="object"?!1:_c.some(t=>{let r=e[t];return!!r&&Object.keys(r).includes(xc)})}function wh(e){return Array.isArray(e?.tasks)&&e.tasks.some(t=>t?.label===is&&typeof t.command=="string"&&vh.test(t.command))}function kh(e){let t=new Set([rn,nn,sn]),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 Sh(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 ai(e){let t=as.exec(String(e).replace(/\\/g,"/"));if(!t)return!1;let r=t[1].replace(/\/+$/,"");return Eh.some(n=>n.endsWith("/")?r.startsWith(n):r===n||r.startsWith(`${n}/`))}function Tc(e){return!e||typeof e!="object"?!1:_c.some(t=>{let r=e[t];return!!r&&typeof r=="object"&&Object.keys(r).some(ai)})}function Rt(){return{...Oc,...Pc}}function bh(){return{...Ic,...jc}}async function on(e,t){let r=[];for(let n of bh()[t]||[])await Lc(e,n)&&r.push(nt(n));return r.sort()}async function cs(e,t){return(await on(e,t)).length>0}async function Rc(e,{vscodeSettings:t}={}){let r={claude:!1,copilot:!1},n=[];for(let o of["claude","copilot"])for(let i of kc.primaryByHost[o])await Pt(e,i,{visible:null})&&(r[o]=!0,n.push(nt(i)));!r.copilot&&t&&Tc(t)&&(r.copilot=!0,n.push("<workspace settings>"));let s=[];for(let o of kc.residue)await Pt(e,o,{visible:null})&&s.push(nt(o));return{primary:r.claude||r.copilot,residue:s,hosts:r,matched:[...new Set(n)].sort()}}async function Yt(e,t,{fingerprints:r=Rt()}={}){for(let n of r[t]||[])if(await Lc(e,n))return!0;return!1}async function Lc(e,t){return Pt(e,t,{visible:null})}var H,st,lh,wt,It,os,is,Jt,xc,_c,jt,rn,nn,sn,ri,Ac,uh,dh,vh,as,Eh,Oc,Pc,Ic,jc,yc,wc,vc,kc,he=Ot(()=>{H="vesper-orchestrator",st="vesper@vesper-marketplace",lh=/^vesper-([a-z0-9][a-z0-9-]*)@vesper-marketplace$/;wt=`.vesper/agents/${H}.agent.md`;It=".vscode/settings.json",os=".vscode/tasks.json",is="Vesper: worktree bootstrap",Jt=".claude/settings.json",xc="${workspaceFolder}/.vesper/agents",_c=Object.freeze(["chat.agentFilesLocations","chat.instructionsFilesLocations","chat.promptFilesLocations","chat.agentSkillsLocations"]),jt=Object.freeze(["reinit","compact-knowledge","revalidate-knowledge","revalidate-team"]),rn=`node -e "['orchestrator','orchestration','context'].forEach(n=>{try{process.stdout.write(require('fs').readFileSync('.claude/vesper/'+n+'.md','utf8')+'\\n\\n')}catch(e){}})"`,nn=`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){}"`,sn="command -v vespercli >/dev/null 2>&1 && vespercli worktree bootstrap --quiet || true",ri=Symbol.for("vesper.fingerprintEntry"),Ac=Object.freeze({json:e=>JSON.parse(e),jsonc:e=>JSON.parse(ch(e,{trailingCommas:!0})),text:e=>e});uh=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"}),dh="ssh -o BatchMode=yes -o ConnectTimeout=10";vh=/(^|[\s;&|(])vespercli\s+guard\s+--running-host(\s+|=)copilot(?![\w-])/;as=/node_modules\/(?:@[^/]+\/)?(?:vesper-cli|vespercli)\/(.+)$/,Eh=Object.freeze(["assets/core/","assets/skills","assets/agents/","assets/prompts/","assets/instructions/"]);Oc=Object.freeze({claude:Object.freeze([kr({path:Jt,parse:"json",test:gh,describe:`"enabledPlugins[${st}]" or "agent": "${H}"`})])}),Pc=Object.freeze({copilot:Object.freeze([kr({path:os,parse:"jsonc",test:wh,describe:`task "${is}"`}),kr({path:It,parse:"jsonc",test:yh,describe:`"${xc}" in a chat.*FilesLocations setting (of the root *.code-workspace file when one exists)`,vscodeSettings:!0})])});Ic=Object.freeze({claude:Object.freeze([".claude/rules/vesper-orchestrator.md",`.claude/agents/${H}.md`,...jt.map(e=>`.claude/skills/${e}/SKILL.md`)])}),jc=Object.freeze({copilot:Object.freeze([wt,Se(H)])});yc=kr({path:Jt,parse:"json",test:kh,describe:"an exact 1.x SessionStart command"}),wc=kr({path:"CLAUDE.md",parse:"text",test:Sh,describe:"the 1.x guard block importing .claude/vesper/*.md"}),vc=kr({path:It,parse:"jsonc",test:Tc,describe:"a 1.x package location (assets/core, assets/skills, assets/<type>/<name>)"}),kc=Object.freeze({primary:Object.freeze([yc,wc,vc]),primaryByHost:Object.freeze({claude:Object.freeze([yc,wc]),copilot:Object.freeze([vc])}),residue:Object.freeze([".claude/vesper/orchestrator.md"])})});var di={};rs(di,{AUTH_FAILURE_RE:()=>li,BATCH_SSH:()=>Mc,CONFIG_VARS_KEPT:()=>Nc,NON_INTERACTIVE:()=>an,NO_PROMPT_PROGRAM:()=>ci,READ_ONLY_GIT_ENV:()=>vt,REPO_LOCATION_VARS:()=>us,authFailureLine:()=>ui,nonInteractiveGitEnv:()=>cn,repoLocationVars:()=>ds,stripRepoLocationEnv:()=>qt});import{execFileSync as xh}from"node:child_process";function ds(){if(ls)return ls;let e=[];try{let r={...process.env,LC_ALL:"C"};for(let n of us)delete r[n];e=xh("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=>!
|
|
19
|
-
`),n=new RegExp(`${
|
|
16
|
+
`)continue;continue}let y=f.quoted?null:f.v;if(d){y==="in"&&(d=!1,l=!0,o=!0,i="kw");continue}if(m?.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(!m||m.kind!=="group"&&m.kind!=="func")return"(unparsable)";s.pop(),o=!1;continue}if(y!==null&&hc.has(y)){s.push({kind:y==="if"?"if":y==="case"?"case":"loop",close:hc.get(y)}),y==="case"?(d=!0,o=!1):(o=y==="if"||y==="while"||y==="until",i="kw");continue}if(y!==null&&Gf.has(y)){if(!m||m.close!==y)return"(unparsable)";s.pop(),o=!1;continue}if(y!==null&&Hf.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=g+1;A<t.length;A+=1){let L=t[A];if(L.t==="op")break;if(S){S=!1;continue}if(!L.heredoc){if(!L.quoted&&Vf.test(L.v)){Df.test(L.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 mt,wr,Ff,Vf,Df,hc,Gf,Hf,en=Ot(()=>{mt="# <!-- vesper:hook:start -->",wr="# <!-- vesper:hook:end -->",Ff=/^(sh|bash|dash|zsh|ksh|mksh|ash)(\d[\d.]*)?$/,Vf=/^[0-9]*(>>|<>|<&|>&|>\||&>>|&>|<|>)/,Df=/^[0-9]*(>>|<>|<&|>&|>\||&>>|&>|<|>)$/;hc=new Map([["if","fi"],["case","esac"],["for","done"],["while","done"],["until","done"],["select","done"]]),Gf=new Set(["fi","esac","done"]),Hf=new Set(["then","do","else","elif","!","time"])});import ie from"picocolors";function Wf(e){console.log(`${ie.green("\u2713")} ${e}`)}function Bf(e){console.log(`${ie.red("\u2717")} ${e}`)}function Qo(e){console.log(`${ie.yellow("!")} ${e}`)}function Kf(e){console.log(`${ie.cyan("\u2192")} ${e}`)}function zf(e){console.log(ie.dim(e))}function Jf(e){return ie.cyan(e)}function Yf(e){return ie.bold(e)}function qf(e){console.log(),console.log(ie.bold(ie.underline(e)))}function Xf(e,t=!1){let r=t?ie.green("\u25CF"):ie.dim("\u25CB");console.log(` ${r} ${e}`)}function Qf(){console.log(),console.log(ie.bold(ie.magenta("\u{1F3AF} Ready to use Vesper!"))),console.log(ie.cyan(' In VS Code Chat, select "Vesper" from the agent dropdown')),console.log(ie.cyan(" and start requesting!")),console.log()}function Zf(e){let t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],r=0,n=null,s=e,o=()=>{let i=ie.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(`${ie.green("\u2713")} ${i||s}`)},fail(i){this.stop(),console.log(`${ie.red("\u2717")} ${i||s}`)}}}var u,Fe=Ot(()=>{u={success:Wf,error:Bf,warn:Qo,info:Kf,dim:zf,formatPath:Jf,formatName:Yf,header:qf,listItem:Xf,vesperTip:Qf,createSpinner:Zf}});import{fileURLToPath as eh}from"node:url";import{dirname as Zo,join as tn,resolve as th}from"node:path";import{readdir as rh}from"node:fs/promises";import{existsSync as nh,readFileSync as sh}from"node:fs";function ah(e){let t=e;for(;t!==Zo(t);){if(nh(tn(t,"package.json")))return t;t=Zo(t)}return th(e,"..","..","..")}function ss(){try{return JSON.parse(sh(tn(rn,"package.json"),"utf-8")).version??null}catch{return null}}function ei(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 os(e){let t=Ve[e];if(!t)throw new Error(`Unknown asset type: ${e}`);try{let r=await rh(tn(gt,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 oh,ih,rn,I,gt,Ve,Re=Ot(()=>{oh=eh(import.meta.url),ih=Zo(oh);rn=ah(ih),I=tn(rn,"assets");gt=tn(I,"copilot");Ve={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 ti={};ns(ti,{DEFAULT_GIT_TIMEOUT_MS:()=>ch,default:()=>lh,runGit:()=>V,runGitCapture:()=>yt});async function V(e,{cwd:t,timeout:r=3e4,env:n,detached:s=!1}={}){if(s){let c=await yt(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 yt(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(m){a({ok:!1,stdout:"",stderr:String(m?.message??m),timedOut:!1});return}let l="",d="",p=!1,h=!1;c.stdout.on("data",m=>{l+=m}),c.stderr.on("data",m=>{d+=m});let g=r?setTimeout(()=>{p=!0;try{i?process.kill(-c.pid,"SIGKILL"):c.kill("SIGKILL")}catch{}},r):null,f=m=>{if(!h){if(h=!0,g&&clearTimeout(g),i)try{process.kill(-c.pid,"SIGKILL")}catch{}a({ok:m,stdout:l,stderr:d,timedOut:p})}};c.on("error",m=>{d+=String(m?.message??m),f(!1)}),c.on("close",m=>f(m===0&&!p))})}var ch,lh,rt=Ot(()=>{ch=3e4;lh=V});import{access as uh,constants as dh,readFile as bc,readdir as ph}from"node:fs/promises";import{execFile as fh}from"node:child_process";import{join as ri}from"node:path";import hh from"strip-json-comments";async function xc(e){try{return await uh(e,dh.F_OK),!0}catch{return!1}}function _c(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 ni(e,t){let r=_c(t,"findCodeWorkspaceFile");try{let s=(await ph(e,{withFileTypes:!0})).find(o=>o.isFile()&&o.name.endsWith(".code-workspace")&&(!r||r.has(o.name)));return s?ri(e,s.name):null}catch{return null}}function nn(e){let t=typeof e=="string"?mh.exec(e):null;return t?t[1]:null}function Ee(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(Cc,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,si,{value:!0,enumerable:!1}),Object.freeze(o)}function Sr(e){return!!e&&typeof e=="object"&&e[si]===!0&&typeof e.test=="function"}function Tc(e){if(typeof e!="string"&&!(e&&typeof e=="object"&&e[si]===!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 nt(e){return Tc(e),typeof e=="string"?e:e.path}async function Pt(e,t,r){let n=_c(r,"fingerprintMatchesEntry"),s=nt(t),o=ri(e,s);if(typeof t=="string")return(!n||n.has(s))&&xc(o);let i=Sr(t)&&t.vscodeSettings?await ni(e,{visible:n}):null;if(i)o=i;else if(n&&!n.has(s))return!1;let a;try{a=await bc(o,"utf-8")}catch{return!1}return oi(t,a,{fromWorkspaceFile:!!i})}function oi(e,t,{fromWorkspaceFile:r=!1}={}){if(Sr(e)){let n;try{n=Cc[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 ii(e,t){return new Promise(r=>{fh("git",t,{cwd:e,maxBuffer:16777216,timeout:5e3,env:wh(process.env)},(s,o)=>{r(s?null:String(o))}).stdin?.end()})}function wh(e){let t={...e,...gh};return!t.GIT_SSH_COMMAND&&!t.GIT_SSH&&(t.GIT_SSH_COMMAND=yh),t}async function vh(e,t){return ii(e,["show",`HEAD:./${t}`])}async function kh(e){let t=await ii(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 Sh(e,t){let r=nt(t);if(typeof t=="string"){let a=await ii(e,["cat-file","-e",`HEAD:./${r}`])!==null;return{matched:a,path:a?r:null}}let n=Sr(t)&&t.vscodeSettings?await kh(e):null,s=n||r,o=await vh(e,s);if(o===null)return{matched:!1,path:null};let i=oi(t,o,{fromWorkspaceFile:!!n});return{matched:i,path:i?s:null}}async function ai(e,t,r){let n=ri(e,r);if(typeof t=="string")return xc(n);nt(t);let s;try{s=await bc(n,"utf-8")}catch{return!1}let o=Sr(t)&&!!t.vscodeSettings&&r.endsWith(".code-workspace");return oi(t,s,{fromWorkspaceFile:o})}async function Oc(e,{fingerprints:t=Rt()}={}){let r={};for(let s of Object.keys(t)){let o=[];for(let i of t[s]||[]){let a=await Sh(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 ci(e){return Tc(e),typeof e!="string"?!0:e.toLowerCase().includes("vesper")}function Eh(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&&st in e.enabledPlugins||e.agent===H}function bh(e){return!e||typeof e!="object"?!1:$c.some(t=>{let r=e[t];return!!r&&Object.keys(r).includes(Ac)})}function xh(e){return Array.isArray(e?.tasks)&&e.tasks.some(t=>t?.label===as&&typeof t.command=="string"&&_h.test(t.command))}function Ah(e){let t=new Set([sn,on,an]),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 $h(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 li(e){let t=cs.exec(String(e).replace(/\\/g,"/"));if(!t)return!1;let r=t[1].replace(/\/+$/,"");return Ch.some(n=>n.endsWith("/")?r.startsWith(n):r===n||r.startsWith(`${n}/`))}function Pc(e){return!e||typeof e!="object"?!1:$c.some(t=>{let r=e[t];return!!r&&typeof r=="object"&&Object.keys(r).some(li)})}function Rt(){return{...Ic,...jc}}function Th(){return{...Rc,...Lc}}async function cn(e,t){let r=[];for(let n of Th()[t]||[])await Mc(e,n)&&r.push(nt(n));return r.sort()}async function ls(e,t){return(await cn(e,t)).length>0}async function Nc(e,{vscodeSettings:t}={}){let r={claude:!1,copilot:!1},n=[];for(let o of["claude","copilot"])for(let i of Ec.primaryByHost[o])await Pt(e,i,{visible:null})&&(r[o]=!0,n.push(nt(i)));!r.copilot&&t&&Pc(t)&&(r.copilot=!0,n.push("<workspace settings>"));let s=[];for(let o of Ec.residue)await Pt(e,o,{visible:null})&&s.push(nt(o));return{primary:r.claude||r.copilot,residue:s,hosts:r,matched:[...new Set(n)].sort()}}async function Yt(e,t,{fingerprints:r=Rt()}={}){for(let n of r[t]||[])if(await Mc(e,n))return!0;return!1}async function Mc(e,t){return Pt(e,t,{visible:null})}var H,st,mh,wt,It,is,as,Jt,Ac,$c,jt,sn,on,an,si,Cc,gh,yh,_h,cs,Ch,Ic,jc,Rc,Lc,vc,kc,Sc,Ec,he=Ot(()=>{H="vesper-orchestrator",st="vesper@vesper-marketplace",mh=/^vesper-([a-z0-9][a-z0-9-]*)@vesper-marketplace$/;wt=`.vesper/agents/${H}.agent.md`;It=".vscode/settings.json",is=".vscode/tasks.json",as="Vesper: worktree bootstrap",Jt=".claude/settings.json",Ac="${workspaceFolder}/.vesper/agents",$c=Object.freeze(["chat.agentFilesLocations","chat.instructionsFilesLocations","chat.promptFilesLocations","chat.agentSkillsLocations"]),jt=Object.freeze(["reinit","compact-knowledge","revalidate-knowledge","revalidate-team"]),sn=`node -e "['orchestrator','orchestration','context'].forEach(n=>{try{process.stdout.write(require('fs').readFileSync('.claude/vesper/'+n+'.md','utf8')+'\\n\\n')}catch(e){}})"`,on=`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){}"`,an="command -v vespercli >/dev/null 2>&1 && vespercli worktree bootstrap --quiet || true",si=Symbol.for("vesper.fingerprintEntry"),Cc=Object.freeze({json:e=>JSON.parse(e),jsonc:e=>JSON.parse(hh(e,{trailingCommas:!0})),text:e=>e});gh=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"}),yh="ssh -o BatchMode=yes -o ConnectTimeout=10";_h=/(^|[\s;&|(])vespercli\s+guard\s+--running-host(\s+|=)copilot(?![\w-])/;cs=/node_modules\/(?:@[^/]+\/)?(?:vesper-cli|vespercli)\/(.+)$/,Ch=Object.freeze(["assets/core/","assets/skills","assets/agents/","assets/prompts/","assets/instructions/"]);Ic=Object.freeze({claude:Object.freeze([kr({path:Jt,parse:"json",test:Eh,describe:`"enabledPlugins[${st}]" or "agent": "${H}"`})])}),jc=Object.freeze({copilot:Object.freeze([kr({path:is,parse:"jsonc",test:xh,describe:`task "${as}"`}),kr({path:It,parse:"jsonc",test:bh,describe:`"${Ac}" in a chat.*FilesLocations setting (of the root *.code-workspace file when one exists)`,vscodeSettings:!0})])});Rc=Object.freeze({claude:Object.freeze([".claude/rules/vesper-orchestrator.md",`.claude/agents/${H}.md`,...jt.map(e=>`.claude/skills/${e}/SKILL.md`)])}),Lc=Object.freeze({copilot:Object.freeze([wt,Ee(H)])});vc=kr({path:Jt,parse:"json",test:Ah,describe:"an exact 1.x SessionStart command"}),kc=kr({path:"CLAUDE.md",parse:"text",test:$h,describe:"the 1.x guard block importing .claude/vesper/*.md"}),Sc=kr({path:It,parse:"jsonc",test:Pc,describe:"a 1.x package location (assets/core, assets/skills, assets/<type>/<name>)"}),Ec=Object.freeze({primary:Object.freeze([vc,kc,Sc]),primaryByHost:Object.freeze({claude:Object.freeze([vc,kc]),copilot:Object.freeze([Sc])}),residue:Object.freeze([".claude/vesper/orchestrator.md"])})});var fi={};ns(fi,{AUTH_FAILURE_RE:()=>di,BATCH_SSH:()=>Vc,CONFIG_VARS_KEPT:()=>Fc,NON_INTERACTIVE:()=>ln,NO_PROMPT_PROGRAM:()=>ui,READ_ONLY_GIT_ENV:()=>vt,REPO_LOCATION_VARS:()=>ds,authFailureLine:()=>pi,nonInteractiveGitEnv:()=>un,repoLocationVars:()=>ps,stripRepoLocationEnv:()=>qt});import{execFileSync as Oh}from"node:child_process";function ps(){if(us)return us;let e=[];try{let r={...process.env,LC_ALL:"C"};for(let n of ds)delete r[n];e=Oh("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=>!Fc.includes(r)&&!Ph.includes(r)&&!ds.includes(r));return us=Object.freeze([...ds,...t]),us}function qt(e=process.env){let t={...e};for(let r of ps())delete t[r];return t}function un(e=process.env,{sshCommandConfigured:t=!1}={}){let r={...e,...ln};!r.GIT_SSH_COMMAND&&!r.GIT_SSH&&!t&&(r.GIT_SSH_COMMAND=Vc),r.GIT_ASKPASS=ui,r.SSH_ASKPASS=ui;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 pi(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,Fc,Ph,us,ln,Vc,ui,vt,di,ot=Ot(()=>{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"]),Fc=Object.freeze(["GIT_CONFIG","GIT_CONFIG_PARAMETERS","GIT_CONFIG_COUNT"]),Ph=Object.freeze(["GIT_INTERNAL_SUPER_PREFIX"]),us=null;ln=Object.freeze({GIT_TERMINAL_PROMPT:"0",GCM_INTERACTIVE:"never",SSH_ASKPASS_REQUIRE:"never",LC_ALL:"C"}),Vc="ssh -o BatchMode=yes -o ConnectTimeout=10";ui=process.platform==="win32"?"false":"/bin/false",vt=Object.freeze({GIT_NO_LAZY_FETCH:"1",GIT_OPTIONAL_LOCKS:"0",...ln}),di=/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 Ci={};ns(Ci,{ADDITIONAL_READ_ACCESS_PATHS_SETTING:()=>te,AGENT_MAX_REQUESTS_SETTING:()=>ys,CHAT_AGENT_ENABLED_SETTING:()=>ks,COPILOT_PACKS_DIR:()=>ms,CORE_INSTRUCTIONS_DIR:()=>hn,CUSTOM_AGENT_IN_SUBAGENT_SETTING:()=>vs,EXTENDED_INSTRUCTIONS_DIR:()=>hs,GIT_PLUMBING_TIMEOUT_MS:()=>wi,GUARD_TRIGGER_MARKERS:()=>wn,INCLUDE_REFERENCED_INSTRUCTIONS_SETTING:()=>ws,INIT_DEFAULTS:()=>be,LOCAL_STATE:()=>vi,MCP_AUTO_START_SETTING:()=>bs,MCP_DISCOVERY_ENABLED_SETTING:()=>Es,MCP_SERVERS:()=>Ae,MCP_TOOLS_AUTO_APPROVAL:()=>zc,MCP_TOOLS_BY_AGENT:()=>As,MCP_TOOLS_CORE:()=>xe,NEVER_WRITE_USER_PATHS:()=>Si,OMIT_BASE_AGENT_INSTRUCTIONS_SETTING:()=>Ss,PERMITTED_USER_PATHS:()=>Ei,SAFE_AUTO_APPROVAL_COMMANDS:()=>fn,SIBLING_GIT_ARGS:()=>Or,TERMINAL_AUTO_APPROVAL_SETTING:()=>kt,TERMINAL_ENABLE_AUTO_APPROVAL_SETTING:()=>gs,TOOLS_AUTO_APPROVE_SETTING:()=>xr,TOOLS_ELIGIBLE_FOR_AUTO_APPROVAL_SETTING:()=>F,VESPER_BOOTSTRAP_TASK_LABEL:()=>xs,VESPER_GIT_PATHS:()=>Mh,VESPER_LOCAL_PATHS:()=>pn,VESPER_MANAGED_GIT_HOOKS:()=>Ye,VESPER_MANAGED_MCP_SERVERS:()=>_e,VESPER_MANAGED_SETTINGS:()=>Et,VSCODE_SETTINGS_MAP:()=>Le,WORKSPACE_TYPES:()=>ae,addAgentToolsToAutoApproval:()=>nl,addMcpServer:()=>Ir,addReadAccessPath:()=>Rs,addToSettings:()=>$r,allPackAssetEntries:()=>Qc,buildGuardCommand:()=>_r,classifyForeignHook:()=>vr,configureChatSettings:()=>js,configureMcpServer:()=>Zt,configureMcpToolsAutoApproval:()=>Hs,configureTerminalAutoApproval:()=>Is,configureVesperMergeDriver:()=>An,default:()=>Jh,deriveHost:()=>mn,ensureCopilotFolderOpenTask:()=>kn,ensureCoreSettings:()=>Ms,ensureFolderOpenTask:()=>_s,ensureVesperGitattributes:()=>_n,ensureVesperGitignore:()=>gn,findNestedVesperrc:()=>Sn,findTrackedLocalPaths:()=>yn,findWorkspaceFile:()=>bi,getAutoApprovalCommands:()=>Zc,getConfiguredMcpServers:()=>ol,getCoreAssetEntries:()=>Os,getExtendedInstructionEntry:()=>Ts,getInstalledTargets:()=>ce,getMcpConfigPath:()=>De,getPackAssetEntries:()=>Tr,getReadAccessPaths:()=>Ns,getSettingsPath:()=>Jc,getTrackedPaths:()=>ct,getTrackingPath:()=>Ar,getTrackingPathAsync:()=>at,getVesperIndexingPath:()=>qe,getWorkspaceConfig:()=>B,getWorkspaceFolders:()=>xi,gitHookResultLines:()=>bn,gitHooksEnsured:()=>Ai,gitHooksSkipMessage:()=>rl,installVesperGitHook:()=>tl,installVesperGitHooks:()=>xn,isHookTrackedByGit:()=>br,isInsideRepository:()=>Nt,isMcpServerConfigured:()=>Gs,isUserLevelViolation:()=>Qt,listCopilotPackNames:()=>Ps,listExtendedInstructions:()=>Cs,listMcpServers:()=>sl,listWorktrees:()=>Vs,migrateVesperrcToWorkspaceLevel:()=>$s,parseJsonc:()=>bt,parseWorktreeList:()=>Fs,pruneLegacySettingsEntries:()=>Cr,readMcpConfig:()=>Ge,readTracking:()=>_,readVSCodeSettings:()=>K,realOrNearestAncestor:()=>St,removeFolderOpenTask:()=>vn,removeFromSettings:()=>En,removeHookRegion:()=>zt,removeLegacyTracking:()=>qc,removeMcpServer:()=>Us,removePathsFromSettings:()=>_i,removeReadAccessPath:()=>Ls,repositoryRoots:()=>el,resetVesperConfig:()=>Yc,resolveGitHooksDir:()=>Pr,resolveHookWriteTarget:()=>Ds,sweepResetLocalState:()=>ki,writeHookAtomic:()=>Xt,writeTracking:()=>O,writeVSCodeSettings:()=>ne});import{readFile as Ne,readdir as Ih,rename as jh}from"node:fs/promises";import{existsSync as Er,readdirSync as Rh}from"node:fs";import{join as N,dirname as it}from"node:path";import*as Lh from"node:path";import{homedir as yi}from"node:os";import Nh from"strip-json-comments";function Lt(e){let t=yi();return e.startsWith(t)?"~"+e.slice(t.length).replace(/\\/g,"/"):e.replace(/\\/g,"/")}function Kc(e){return e==="vesper-cli"||e.startsWith("vesper-cli ")||e.endsWith("/vesper-cli")}async function ki(e){let{rm:t,readdir:r,lstat:n}=await import("node:fs/promises"),s=[],o=async i=>{let a=N(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 vi.filter(a=>a.resetRemoves)){let a=i.endsWith("/")?null:it(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(N(e,a))}catch{d=[]}for(let p of d)l.test(p)&&await o(`${a}/${p}`)}else await o(i)}return s}function Qt(e){if(typeof e!="string"||e.length===0)return!1;let t=yi(),r=e.startsWith("~")?N(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 Ei.some(o)?!1:!!Si.some(o)}function mn(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 gn(e){let t=N(e,".gitignore"),r=[Dc,...pn,Gc].join(`
|
|
19
|
+
`),n=new RegExp(`${Dc}[\\s\\S]*?${Gc}`),s="";try{s=await Ne(t,"utf-8")}catch(i){if(i.code!=="ENOENT")throw i;return await $(t,`${r}
|
|
20
20
|
`,"utf-8"),{created:!0,updated:!1}}if(n.test(s)){let i=s.replace(n,r);return i!==s?(await $(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=s.endsWith(`
|
|
21
21
|
`)?`
|
|
22
22
|
`:`
|
|
23
23
|
|
|
24
24
|
`;return await $(t,`${s}${o}${r}
|
|
25
|
-
`,"utf-8"),{created:!1,updated:!0}}function Ih(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 mn(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:gi,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=>Ih(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 _r(e){return`vespercli guard --running-host ${e}`}async function xs(e,t,{createOnly:r=!1}={}){let n=N(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 Le(n,"utf-8");o=bt(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 j(it(n),{recursive:!0}),await $(n,JSON.stringify(o,null," "),"utf-8"),{created:!i,updated:i}}async function yn(e,t,{removeFileIfEmpty:r=!1}={}){let n=N(e,".vscode","tasks.json"),s;try{s=bt(await Le(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 $(n,JSON.stringify(s,null," "),"utf-8"),{removed:!0,fileRemoved:!1}}async function wn(e,{createOnly:t=!1}={}){return xs(e,{label:bs,command:_r("copilot"),presentation:{reveal:"silent",panel:"shared"}},{createOnly:t})}async function Si(e){return ti(e,{visible:null})}async function B(e){let t=await Si(e);return t?{type:ae.WORKSPACE_FILE,settingsPath:t,workspaceFile:t}:{type:ae.FOLDER,settingsPath:N(e,".vscode","settings.json"),workspaceFile:null}}function Kc(e){return N(e,".vscode","settings.json")}function Ar(e,t=null){return t?.workspaceFile?N(it(t.workspaceFile),".vesperrc"):N(e,".vesperrc")}async function at(e){let t=await B(e);return Ar(e,t)}function bt(e){let t=Oh(e,{trailingCommas:!0});return JSON.parse(t)}async function K(e){let t=await B(e);try{let r=await Le(t.settingsPath,"utf-8"),n=bt(r);return t.type===ae.WORKSPACE_FILE?n.settings||{}:n}catch(r){if(r.code==="ENOENT")return{};if(r instanceof SyntaxError){if(t.type===ae.WORKSPACE_FILE)throw new Error(`Failed to parse workspace file: ${t.settingsPath}. ${r.message}`);return{}}throw r}}async function ne(e,t){let r=await B(e);if(r.type===ae.WORKSPACE_FILE){let n;try{let s=await Le(r.settingsPath,"utf-8");n=bt(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 $(r.settingsPath,JSON.stringify(n,null," "),"utf-8")}else{let n=it(r.settingsPath);await j(n,{recursive:!0}),await $(r.settingsPath,JSON.stringify(t,null," "),"utf-8")}}function jh(e){return N(e,".vesper","tracking.json")}function pi(){return{schemaVersion:2,manifest:[]}}async function fi(e){let t;try{t=await Le(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 hi(e,t){let r=`${e}.corrupt-${Date.now()}`,n=!1;try{await $h(e,r),n=!0}catch{if(typeof t=="string")try{await $(r,t,"utf-8"),n=!0}catch{}}Dc.has(e)||(Dc.add(e),qo(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 _(e){let t=await B(e),r=Ar(e,t),n=jh(e),s=N(e,".vesperrc"),o=await fi(r);if(o.parsed!==void 0)return o.parsed;if(o.corrupt)return await hi(r,o.raw),pi();if(r!==s){let a=await fi(s);if(a.parsed!==void 0)return a.parsed;if(a.corrupt)return await hi(s,a.raw),pi()}let i=await fi(n);return i.parsed!==void 0?i.parsed:(i.corrupt&&await hi(n,i.raw),pi())}async function zc(e){return await kn(e)}async function Jc(e){return await zc(e)}async function Ei(e){try{let t=await Le(e,"utf-8"),n=bt(t).folders||[],s=it(e);return n.map(o=>{let i=o.path||o;return i.startsWith("/")||i.startsWith("~")?i.replace(/^~/,mi()):N(s,i)})}catch{return[]}}async function vn(e){let t=await B(e);if(t.type!==ae.WORKSPACE_FILE)return{found:!1,paths:[]};let r=it(t.workspaceFile),n=N(r,".vesperrc"),s=await Ei(t.workspaceFile),o=[];for(let i of s){let a=N(i,".vesperrc");if(a!==n)try{let c=await Le(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 As(e,t,r){let n=await B(e),s=Ar(e,n),o={...r,workspaceType:ae.WORKSPACE_FILE,settingsPath:n.settingsPath,migratedFrom:t,migratedAt:new Date().toISOString()};await $(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 O(e,t){let r=await B(e),n=Ar(e,r);try{let s=JSON.parse(await Le(n,"utf-8"));if(Gc(s)===Gc(t))return}catch{}await er(n,JSON.stringify(t,null,2))}function Gc(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 $r(e,t){let r=await B(e),n=await K(e),s=await _(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 ne(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 O(e,s)),{added:o,skipped:i,workspaceType:r.type}}async function kn(e){let t=await K(e),r=await _(e),n={paths:[],settings:[],mcpServers:[],agentTools:[]},s=/vespercli|vesper-cli/,o=[...new Set([...Yc(r),...Ts().map(h=>h.path),...qc().map(h=>h.path)])];for(let h of Object.values(Re))if(t[h]){for(let g of Object.keys(t[h])){let f=o.includes(g),m=s.test(g);(f||m)&&(delete t[h][g],n.paths.includes(g)||n.paths.push(g))}Object.keys(t[h]).length===0&&delete t[h]}let i=[...new Set([...r.readAccessPaths||[],I])];if(i.length>0){let h=t[te]||[],g=h.filter(f=>!i.includes(f));g.length!==h.length&&(g.length>0?t[te]=g:delete t[te],n.settings.push(te))}let a=Lh();for(let h of Et){if(t[h]===void 0)continue;let g=t[h];if(Rh.has(h)&&g&&typeof g=="object"&&!Array.isArray(g)){let f=!1;for(let m of Object.keys(g))(a.has(m)||Wc(m))&&(delete g[m],f=!0);Object.keys(g).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,g]of Object.entries(c))n.agentTools.push({agent:h,tools:g});(n.paths.length>0||n.settings.length>0)&&await ne(e,t);let l=await De(e),d=r.mcp?.servers||[],p=[...new Set([...xe,...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=Ve(e),g=it(h);await j(g,{recursive:!0}),await $(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 O(e,r),{removed:n}}function Lh(){return new Set([...dn,...be,...Object.values(_s).flat()])}async function Cr(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(Re)){let p=s[d];if(!(!p||typeof p!="object"||Array.isArray(p))){for(let h of Object.keys(p)){let g=h.replace(/\\/g,"/");if(ai(g)||o.has(h)&&i.test(g)){delete p[h],n.removed.push(h),a=!0;continue}let f=as.exec(g);if(f&&f[1].startsWith("assets/copilot/")){let m=Lt(N(en,f[1]));if(m!==h){let y=p[h];delete p[h],p[m]=p[m]===!0?!0:y,n.rehomed.push(h),a=!0}}}Object.keys(p).length===0&&(delete s[d],a=!0)}}let c=s[te];if(Array.isArray(c)){let d=new Set([I,Lt(I)]),p=new Set(r.filter(g=>typeof g=="string"&&/\/assets\/?$/.test(g.replace(/\\/g,"/")))),h=c.filter(g=>{if(typeof g!="string"||d.has(g))return!0;let f=as.exec(g.replace(/\\/g,"/")),m=!!f&&/^assets\/?$/.test(f[1])||p.has(g);return m&&n.readAccessRemoved.push(g),!m});h.length!==c.length&&(h.length?s[te]=h:delete s[te],a=!0)}let l=s[kt];if(l&&typeof l=="object"&&!Array.isArray(l))for(let d of Object.keys(l))Wc(d)&&(delete l[d],n.commandKeysRemoved.push(d),a=!0);if(a&&await ne(e,s),n.removed.length||n.rehomed.length||n.readAccessRemoved.length){let d=await _(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 g=new Set(n.readAccessRemoved);Array.isArray(d.readAccessPaths)&&d.readAccessPaths.some(f=>g.has(f))&&(d.readAccessPaths=d.readAccessPaths.filter(f=>!g.has(f)),p=!0),p&&await O(e,d)}return n}function Yc(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 ce(e){let t=await _(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 $s(){try{return(await Ah(fs,{withFileTypes:!0})).filter(t=>t.isDirectory()&&!t.name.startsWith(".")).map(t=>t.name).sort()}catch{return[]}}function Cs(e){Qo(e);let t=N(fs,e);if(!Er(N(t,`${e}.instructions.md`)))throw new Error(`Unknown instruction "${e}" \u2014 not in ${fs}`);return{path:Lt(t),settingKey:Re.instructions,type:"instructions",name:e}}function Ts(){let e=[];for(let s of Mh){let o=Fe[s],i=Re[s];i&&o&&e.push({path:Lt(N(Nh,o.dir)),settingKey:i,type:s})}Re.instructions&&Er(pn)&&e.push({path:Lt(pn),settingKey:Re.instructions,type:"instructions"});let t=Re.agents;t&&e.push({path:"${workspaceFolder}/.vesper/agents",settingKey:t,type:"agents"});let r=Re.instructions;r&&e.push({path:"${workspaceFolder}/.vesper/instructions",settingKey:r,type:"instructions"});let n=Re.skills;return n&&e.push({path:"${workspaceFolder}/.vesper/skills",settingKey:n,type:"skills"}),e}function Os(){try{return Ch(hs,{withFileTypes:!0}).filter(e=>e.isDirectory()&&!e.name.startsWith(".")).map(e=>e.name).sort()}catch{return[]}}function Tr(e){Qo(e);let t=N(hs,e);if(!Er(t))throw new Error(`Unknown pack "${e}" \u2014 not in ${hs}`);let r=[];for(let n of["agents","skills"]){let s=N(t,n);Er(s)&&r.push({path:Lt(s),settingKey:Re[n],type:n,pack:e})}return r}function qc(){return Os().flatMap(e=>Tr(e))}async function bi(e,t){let r=await K(e),n=await _(e),s=new Set(t),o=[];for(let i of Object.values(Re)){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 ne(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 O(e,n)),{removed:o}}async function Ps(e,t=!0){let r=await B(e),n=await K(e);if(n[ms]=t,t){n[kt]||(n[kt]={});for(let s of dn)n[kt][s]=!0}return await ne(e,n),{configured:t?dn.length:0,workspaceType:r.type}}async function Is(e,t={}){let{maxRequests:r=Ee.maxRequests,omitBaseAgentInstructions:n=Ee.omitBaseAgentInstructions}=t,s=await K(e);s[gs]=r,s[ys]=!0,s[ws]=!0,s[vs]=!0,s[ks]=n,s[Ss]=!0,s[Es]="newAndOutdated",s[te]||(s[te]=[]),await ne(e,s)}async function Xc(e){let r=(await K(e))[kt]||{};return Object.entries(r).filter(([,n])=>n===!0).map(([n])=>n)}async function js(e,t){let r=await K(e),n=r[te]||[];n.includes(t)||(n.push(t),r[te]=n,await ne(e,r));let s=await _(e);return s.readAccessPaths||(s.readAccessPaths=[]),s.readAccessPaths.includes(t)||(s.readAccessPaths.push(t),s.updatedAt=new Date().toISOString(),await O(e,s)),n}async function Rs(e,t){let r=await K(e),n=r[te]||[],s=n.indexOf(t);s!==-1&&(n.splice(s,1),r[te]=n,await ne(e,r));let o=await _(e);if(o.readAccessPaths){let i=o.readAccessPaths.indexOf(t);i!==-1&&(o.readAccessPaths.splice(i,1),o.updatedAt=new Date().toISOString(),await O(e,o))}return n}async function Ls(e){return(await K(e))[te]||[]}async function ct(e){let t=await _(e);return Yc(t)}async function Ns(e){let t=await B(e),r=await K(e),n=await _(e);Array.isArray(n.paths)||(n.paths=[]);let s=Ts(),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=I,c=r[te]||[];return c.includes(a)||(c.push(a),r[te]=c,o.push(a)),n.readAccessPaths||(n.readAccessPaths=[]),n.readAccessPaths.includes(a)||n.readAccessPaths.push(a),o.length>0&&await ne(e,r),n.addedAt=n.addedAt||new Date().toISOString(),n.updatedAt=new Date().toISOString(),n.workspaceType=t.type,n.settingsPath=t.settingsPath,await O(e,n),{added:o,existed:i,workspaceType:t.type}}async function Fh(e,{cwd:t,env:r,gitArgs:n=[],timeout:s=gi}={}){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 Ms(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
|
|
25
|
+
`,"utf-8"),{created:!1,updated:!0}}function Fh(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:wi,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=pn.map(l=>l.endsWith("/")?`${l}*`:l),a=await s(["ls-files","-z","--",...i]);if(!a)return[];let c=l=>{let d=pn.findIndex(p=>Fh(p,l));return d===-1?pn.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 _r(e){return`vespercli guard --running-host ${e}`}async function _s(e,t,{createOnly:r=!1}={}){let n=N(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 Ne(n,"utf-8");o=bt(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 j(it(n),{recursive:!0}),await $(n,JSON.stringify(o,null," "),"utf-8"),{created:!i,updated:i}}async function vn(e,t,{removeFileIfEmpty:r=!1}={}){let n=N(e,".vscode","tasks.json"),s;try{s=bt(await Ne(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 $(n,JSON.stringify(s,null," "),"utf-8"),{removed:!0,fileRemoved:!1}}async function kn(e,{createOnly:t=!1}={}){return _s(e,{label:xs,command:_r("copilot"),presentation:{reveal:"silent",panel:"shared"}},{createOnly:t})}async function bi(e){return ni(e,{visible:null})}async function B(e){let t=await bi(e);return t?{type:ae.WORKSPACE_FILE,settingsPath:t,workspaceFile:t}:{type:ae.FOLDER,settingsPath:N(e,".vscode","settings.json"),workspaceFile:null}}function Jc(e){return N(e,".vscode","settings.json")}function Ar(e,t=null){return t?.workspaceFile?N(it(t.workspaceFile),".vesperrc"):N(e,".vesperrc")}async function at(e){let t=await B(e);return Ar(e,t)}function bt(e){let t=Nh(e,{trailingCommas:!0});return JSON.parse(t)}async function K(e){let t=await B(e);try{let r=await Ne(t.settingsPath,"utf-8"),n=bt(r);return t.type===ae.WORKSPACE_FILE?n.settings||{}:n}catch(r){if(r.code==="ENOENT")return{};if(r instanceof SyntaxError){if(t.type===ae.WORKSPACE_FILE)throw new Error(`Failed to parse workspace file: ${t.settingsPath}. ${r.message}`);return{}}throw r}}async function ne(e,t){let r=await B(e);if(r.type===ae.WORKSPACE_FILE){let n;try{let s=await Ne(r.settingsPath,"utf-8");n=bt(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 $(r.settingsPath,JSON.stringify(n,null," "),"utf-8")}else{let n=it(r.settingsPath);await j(n,{recursive:!0}),await $(r.settingsPath,JSON.stringify(t,null," "),"utf-8")}}function Vh(e){return N(e,".vesper","tracking.json")}function hi(){return{schemaVersion:2,manifest:[]}}async function mi(e){let t;try{t=await Ne(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 gi(e,t){let r=`${e}.corrupt-${Date.now()}`,n=!1;try{await jh(e,r),n=!0}catch{if(typeof t=="string")try{await $(r,t,"utf-8"),n=!0}catch{}}Hc.has(e)||(Hc.add(e),Qo(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 _(e){let t=await B(e),r=Ar(e,t),n=Vh(e),s=N(e,".vesperrc"),o=await mi(r);if(o.parsed!==void 0)return o.parsed;if(o.corrupt)return await gi(r,o.raw),hi();if(r!==s){let a=await mi(s);if(a.parsed!==void 0)return a.parsed;if(a.corrupt)return await gi(s,a.raw),hi()}let i=await mi(n);return i.parsed!==void 0?i.parsed:(i.corrupt&&await gi(n,i.raw),hi())}async function Yc(e){return await En(e)}async function qc(e){return await Yc(e)}async function xi(e){try{let t=await Ne(e,"utf-8"),n=bt(t).folders||[],s=it(e);return n.map(o=>{let i=o.path||o;return i.startsWith("/")||i.startsWith("~")?i.replace(/^~/,yi()):N(s,i)})}catch{return[]}}async function Sn(e){let t=await B(e);if(t.type!==ae.WORKSPACE_FILE)return{found:!1,paths:[]};let r=it(t.workspaceFile),n=N(r,".vesperrc"),s=await xi(t.workspaceFile),o=[];for(let i of s){let a=N(i,".vesperrc");if(a!==n)try{let c=await Ne(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 $s(e,t,r){let n=await B(e),s=Ar(e,n),o={...r,workspaceType:ae.WORKSPACE_FILE,settingsPath:n.settingsPath,migratedFrom:t,migratedAt:new Date().toISOString()};await $(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 O(e,t){let r=await B(e),n=Ar(e,r);try{let s=JSON.parse(await Ne(n,"utf-8"));if(Uc(s)===Uc(t))return}catch{}await er(n,JSON.stringify(t,null,2))}function Uc(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 $r(e,t){let r=await B(e),n=await K(e),s=await _(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 ne(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 O(e,s)),{added:o,skipped:i,workspaceType:r.type}}async function En(e){let t=await K(e),r=await _(e),n={paths:[],settings:[],mcpServers:[],agentTools:[]},s=/vespercli|vesper-cli/,o=[...new Set([...Xc(r),...Os().map(h=>h.path),...Qc().map(h=>h.path)])];for(let h of Object.values(Le))if(t[h]){for(let g of Object.keys(t[h])){let f=o.includes(g),m=s.test(g);(f||m)&&(delete t[h][g],n.paths.includes(g)||n.paths.push(g))}Object.keys(t[h]).length===0&&delete t[h]}let i=[...new Set([...r.readAccessPaths||[],I])];if(i.length>0){let h=t[te]||[],g=h.filter(f=>!i.includes(f));g.length!==h.length&&(g.length>0?t[te]=g:delete t[te],n.settings.push(te))}let a=Gh();for(let h of Et){if(t[h]===void 0)continue;let g=t[h];if(Dh.has(h)&&g&&typeof g=="object"&&!Array.isArray(g)){let f=!1;for(let m of Object.keys(g))(a.has(m)||Kc(m))&&(delete g[m],f=!0);Object.keys(g).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,g]of Object.entries(c))n.agentTools.push({agent:h,tools:g});(n.paths.length>0||n.settings.length>0)&&await ne(e,t);let l=await Ge(e),d=r.mcp?.servers||[],p=[...new Set([..._e,...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=De(e),g=it(h);await j(g,{recursive:!0}),await $(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 O(e,r),{removed:n}}function Gh(){return new Set([...fn,...xe,...Object.values(As).flat()])}async function Cr(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(Le)){let p=s[d];if(!(!p||typeof p!="object"||Array.isArray(p))){for(let h of Object.keys(p)){let g=h.replace(/\\/g,"/");if(li(g)||o.has(h)&&i.test(g)){delete p[h],n.removed.push(h),a=!0;continue}let f=cs.exec(g);if(f&&f[1].startsWith("assets/copilot/")){let m=Lt(N(rn,f[1]));if(m!==h){let y=p[h];delete p[h],p[m]=p[m]===!0?!0:y,n.rehomed.push(h),a=!0}}}Object.keys(p).length===0&&(delete s[d],a=!0)}}let c=s[te];if(Array.isArray(c)){let d=new Set([I,Lt(I)]),p=new Set(r.filter(g=>typeof g=="string"&&/\/assets\/?$/.test(g.replace(/\\/g,"/")))),h=c.filter(g=>{if(typeof g!="string"||d.has(g))return!0;let f=cs.exec(g.replace(/\\/g,"/")),m=!!f&&/^assets\/?$/.test(f[1])||p.has(g);return m&&n.readAccessRemoved.push(g),!m});h.length!==c.length&&(h.length?s[te]=h:delete s[te],a=!0)}let l=s[kt];if(l&&typeof l=="object"&&!Array.isArray(l))for(let d of Object.keys(l))Kc(d)&&(delete l[d],n.commandKeysRemoved.push(d),a=!0);if(a&&await ne(e,s),n.removed.length||n.rehomed.length||n.readAccessRemoved.length){let d=await _(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 g=new Set(n.readAccessRemoved);Array.isArray(d.readAccessPaths)&&d.readAccessPaths.some(f=>g.has(f))&&(d.readAccessPaths=d.readAccessPaths.filter(f=>!g.has(f)),p=!0),p&&await O(e,d)}return n}function Xc(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 ce(e){let t=await _(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 Cs(){try{return(await Ih(hs,{withFileTypes:!0})).filter(t=>t.isDirectory()&&!t.name.startsWith(".")).map(t=>t.name).sort()}catch{return[]}}function Ts(e){ei(e);let t=N(hs,e);if(!Er(N(t,`${e}.instructions.md`)))throw new Error(`Unknown instruction "${e}" \u2014 not in ${hs}`);return{path:Lt(t),settingKey:Le.instructions,type:"instructions",name:e}}function Os(){let e=[];for(let s of Uh){let o=Ve[s],i=Le[s];i&&o&&e.push({path:Lt(N(Hh,o.dir)),settingKey:i,type:s})}Le.instructions&&Er(hn)&&e.push({path:Lt(hn),settingKey:Le.instructions,type:"instructions"});let t=Le.agents;t&&e.push({path:"${workspaceFolder}/.vesper/agents",settingKey:t,type:"agents"});let r=Le.instructions;r&&e.push({path:"${workspaceFolder}/.vesper/instructions",settingKey:r,type:"instructions"});let n=Le.skills;return n&&e.push({path:"${workspaceFolder}/.vesper/skills",settingKey:n,type:"skills"}),e}function Ps(){try{return Rh(ms,{withFileTypes:!0}).filter(e=>e.isDirectory()&&!e.name.startsWith(".")).map(e=>e.name).sort()}catch{return[]}}function Tr(e){ei(e);let t=N(ms,e);if(!Er(t))throw new Error(`Unknown pack "${e}" \u2014 not in ${ms}`);let r=[];for(let n of["agents","skills"]){let s=N(t,n);Er(s)&&r.push({path:Lt(s),settingKey:Le[n],type:n,pack:e})}return r}function Qc(){return Ps().flatMap(e=>Tr(e))}async function _i(e,t){let r=await K(e),n=await _(e),s=new Set(t),o=[];for(let i of Object.values(Le)){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 ne(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 O(e,n)),{removed:o}}async function Is(e,t=!0){let r=await B(e),n=await K(e);if(n[gs]=t,t){n[kt]||(n[kt]={});for(let s of fn)n[kt][s]=!0}return await ne(e,n),{configured:t?fn.length:0,workspaceType:r.type}}async function js(e,t={}){let{maxRequests:r=be.maxRequests,omitBaseAgentInstructions:n=be.omitBaseAgentInstructions}=t,s=await K(e);s[ys]=r,s[ws]=!0,s[vs]=!0,s[ks]=!0,s[Ss]=n,s[Es]=!0,s[bs]="newAndOutdated",s[te]||(s[te]=[]),await ne(e,s)}async function Zc(e){let r=(await K(e))[kt]||{};return Object.entries(r).filter(([,n])=>n===!0).map(([n])=>n)}async function Rs(e,t){let r=await K(e),n=r[te]||[];n.includes(t)||(n.push(t),r[te]=n,await ne(e,r));let s=await _(e);return s.readAccessPaths||(s.readAccessPaths=[]),s.readAccessPaths.includes(t)||(s.readAccessPaths.push(t),s.updatedAt=new Date().toISOString(),await O(e,s)),n}async function Ls(e,t){let r=await K(e),n=r[te]||[],s=n.indexOf(t);s!==-1&&(n.splice(s,1),r[te]=n,await ne(e,r));let o=await _(e);if(o.readAccessPaths){let i=o.readAccessPaths.indexOf(t);i!==-1&&(o.readAccessPaths.splice(i,1),o.updatedAt=new Date().toISOString(),await O(e,o))}return n}async function Ns(e){return(await K(e))[te]||[]}async function ct(e){let t=await _(e);return Xc(t)}async function Ms(e){let t=await B(e),r=await K(e),n=await _(e);Array.isArray(n.paths)||(n.paths=[]);let s=Os(),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=I,c=r[te]||[];return c.includes(a)||(c.push(a),r[te]=c,o.push(a)),n.readAccessPaths||(n.readAccessPaths=[]),n.readAccessPaths.includes(a)||n.readAccessPaths.push(a),o.length>0&&await ne(e,r),n.addedAt=n.addedAt||new Date().toISOString(),n.updatedAt=new Date().toISOString(),n.workspaceType=t.type,n.settingsPath=t.settingsPath,await O(e,n),{added:o,existed:i,workspaceType:t.type}}async function Wh(e,{cwd:t,env:r,gitArgs:n=[],timeout:s=wi}={}){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 Fs(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 Bh(){if(fs)return fs;let e=await V(["version"]),t=/(\d+)\.(\d+)/.exec(e||"");return fs=t?[Number(t[1]),Number(t[2])]:[0,0],fs}async function Vs(e,{env:t,gitArgs:r=[],gitVersion:n}={}){let[s,o]=n??await Bh(),i=s>2||s===2&&o>=36,a=await Wh(["worktree","list","--porcelain",...i?["-z"]:[]],{cwd:e,env:t,gitArgs:r});return a===null?null:{out:a,nul:i}}async function dn(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 St(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 el(e,{top:t,common:r},{git:n=V,env:s,gitArgs:o=[]}={}){let i=new Set([await dn(t),await dn(r)]);await n(["rev-parse","--is-bare-repository"],{cwd:e})==="true"||i.add(await dn(it(r)));let c=await Vs(e,{env:s,gitArgs:o});for(let l of Fs(c?.out??null))l.worktree&&!l.bare&&i.add(await dn(l.worktree));return[...i]}function Nt(e,t){let{sep:r}=Lh;return(t||[]).some(n=>e===n||e.startsWith(`${n}${r}`))}async function Pr(e,{runGit:t=V,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 el(e,{top:l,common:p},{git:s,env:r,gitArgs:n}),g={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=N(p,"hooks"),M=await St(b);if(!Nt(M,h))return{dir:null,disabled:!0,reason:"outside-repository",configured:b,defaultDir:!0};if(Er(b))try{if(!(await c(M)).isDirectory())return{dir:null,disabled:!0,reason:"not-a-directory",configured:b,defaultDir:!0}}catch{}return{dir:b,default:!0,...g}}let m=f.indexOf(" "),y=m===-1?"":f.slice(0,m),k=m===-1?f:f.slice(m+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(Kh(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 L=S??i(v);return Nt(L,h)?A?{dir:v,scope:y,configured:k,...g}:{dir:null,disabled:!0,reason:"not-a-directory",scope:y,configured:k}:{dir:null,disabled:!0,reason:"outside-repository",scope:y,configured:k}}function Kh(e){let t=e.replace(/\\/g,"/").replace(/\/+$/,"").split("/");return t.at(-1)==="_"&&t.at(-2)===".husky"&&Er(N(e,"h"))}async function Ds(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 Xt(e,t){let{basename:r}=await import("node:path");await er(e,t,{mode:493,tempName:n=>N(it(n),`.${r(n)}.vesper-${process.pid}.tmp`),sweepPattern:/^\..+\.vesper-\d+\.tmp$/})}async function br(e,t,{dir:r=!1}={}){let{relative:n}=await import("node:path"),s=await dn(t.common??"");if(Nt(e,[s]))return!1;let o=(t.roots||[]).filter(l=>l!==s&&Nt(e,[l])).sort((l,d)=>d.length-l.length),{stripRepoLocationEnv:i,READ_ONLY_GIT_ENV:a}=await Promise.resolve().then(()=>(ot(),fi)),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 V([...Or,...p],{cwd:l,env:c,timeout:1e4});return r?!!h:h!==null}return!1}async function tl(e,t,{resolved:r,dirTracked:n}={}){let s=r??await Pr(e);if(!s.dir){let{reason:L,disabled:E,scope:b,configured:M,defaultDir:X}=s;return{installed:!1,updated:!1,hooksDir:null,reason:L,...E?{disabled:E}:{},...b?{scope:b}:{},...M!==void 0?{configured:M}:{},...X?{defaultDir:X}:{}}}let o=s.dir,i=(L,E={})=>({installed:!1,updated:!1,hooksDir:o,hook:t,reason:L,...E}),a=N(I,"hooks",t),c=await Ne(a,"utf-8"),l=c.match(new RegExp(`${mt}[\\s\\S]*?${wr}`));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(`${mt}[\\s\\S]*?${wr}`);if(n??(!s.default&&await br(await St(o),s,{dir:!0})))return{installed:!1,updated:!1,hooksDir:null,reason:"tracked-by-git",configured:o};let g=N(o,t),f=await Ds(g);if(!f.path)return i(f.reason,{configured:g});let m=await St(f.path);if(!Nt(m,s.roots))return i("outside-repository",{configured:f.path});if(Qt(f.path))return i("write-refused",{configured:f.path});if(await br(m,s))return i("tracked-by-git",{configured:m});s.default&&await j(o,{recursive:!0});let y=null;try{y=await Ne(f.path)}catch(L){if(L.code!=="ENOENT")throw L}if(y===null)return await Xt(f.path,c),{installed:!0,updated:!1,hooksDir:o};let k=y.toString("latin1"),v=k.indexOf(mt);if(v!==-1&&p.test(k)){let L=vr(y.subarray(0,v),{whole:y});if(!L.ok){let b=zt(k);return b!==null&&b!==k&&await Xt(f.path,Buffer.from(b,"latin1")),{installed:!1,updated:!0,hooksDir:o,hook:t,reason:"foreign-hook-repaired",interpreter:L.interpreter}}let E=k.replace(p,()=>d);return E!==k?(await Xt(f.path,Buffer.from(E,"latin1")),{installed:!1,updated:!0,hooksDir:o}):{installed:!1,updated:!1,hooksDir:o}}let S=vr(y);if(!S.ok){let{reason:L,interpreter:E,line:b}=S;return i(L,{interpreter:E,...b!==void 0?{line:b}:{}})}let A=k.endsWith(`
|
|
27
27
|
`)?`
|
|
28
28
|
`:`
|
|
29
29
|
|
|
30
30
|
`;return await Xt(f.path,Buffer.from(`${k}${A}${d}
|
|
31
|
-
`,"latin1")),{installed:!1,updated:!0,hooksDir:o}}function
|
|
32
|
-
`),n=new RegExp(`${
|
|
31
|
+
`,"latin1")),{installed:!1,updated:!0,hooksDir:o}}function rl(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 ${N(I,"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 bn(e){let t=[];for(let r of Ye){let n=e?.[r];if(!n)continue;let s=rl({...n,hook:n.hook??r});s&&!t.includes(s)&&t.push(s)}return t}function Ai(e){return Ye.every(t=>e?.[t]&&!e[t].reason)}async function xn(e){let t={};if(await V(["config","--type=bool","--get","vesper.hooks"],{cwd:e})==="false"){for(let s of Ye)t[s]={installed:!1,updated:!1,hooksDir:null,reason:"opted-out"};return t}let r=await Pr(e),n=!!r.dir&&!r.default&&await br(await St(r.dir),r,{dir:!0});for(let s of Ye)t[s]=await tl(e,s,{resolved:r,dirTracked:n});return t}async function _n(e){if(await V(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{created:!1,updated:!1,skipped:"not-a-repo"};let t=N(e,".gitattributes"),r=[Wc,...zh,Bc].join(`
|
|
32
|
+
`),n=new RegExp(`${Wc}[\\s\\S]*?${Bc}`),s="";try{s=await Ne(t,"utf-8")}catch(i){if(i.code!=="ENOENT")throw i;return await $(t,`${r}
|
|
33
33
|
`,"utf-8"),{created:!0,updated:!1}}if(n.test(s)){let i=s.replace(n,r);return i!==s?(await $(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=s.endsWith(`
|
|
34
34
|
`)?`
|
|
35
35
|
`:`
|
|
36
36
|
|
|
37
37
|
`;return await $(t,`${s}${o}${r}
|
|
38
|
-
`,"utf-8"),{created:!1,updated:!0}}async function xn(e){if(await V(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{configured:!1};let n=`node "${N(I,"hooks","merge-memory-jsonl.js")}" %O %A %B`;return await V(["config","merge.vesper-memory.name","Vesper memory.jsonl entity-aware merge"],{cwd:e}),{configured:await V(["config","merge.vesper-memory.driver",n],{cwd:e})!==null}}function Ve(e){return N(e,".vscode","mcp.json")}function qe(){return N(en,"src","mcp","vesper-indexing","dist","index.js")}async function De(e){let t=Ve(e);try{let r=await Le(t,"utf-8");return bt(r)}catch(r){if(r.code==="ENOENT")return{servers:{}};if(r instanceof SyntaxError)return{servers:{}};throw r}}async function _i(e,t){let r=Ve(e),n=it(r);await j(n,{recursive:!0}),await $(r,JSON.stringify(t,null," "),"utf-8")}async function Zt(e,t=!0,{record:r=!0}={}){let n=await De(e),s=Lt(qe()),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 _i(e,n),r&&t&&o.length>0){let i=await _(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 O(e,i)}return{configured:t,mcpPath:Ve(e),servers:o}}async function Ds(e){return!!(await De(e)).servers?.["vesper-indexing"]}async function Gs(e){let t=await B(e),r=await K(e);r[xr]=!1,r[F]||(r[F]={});for(let n of be)r[F][n]=!0;return await ne(e,r),{configured:be.length,workspaceType:t.type}}async function tl(e,t){let r=_s[t];if(!r||r.length===0)return{added:[],agentName:t};let n=await K(e),s=await B(e),o=await _(e,s);n[F]||(n[F]={});let i=[];for(let a of r)n[F][a]||(n[F][a]=!0,i.push(a));return i.length>0&&(await ne(e,n),o.mcp=o.mcp||{},o.mcp.agentTools=o.mcp.agentTools||{},o.mcp.agentTools[t]=r,o.mcp.updatedAt=new Date().toISOString(),await O(e,o)),{added:i,agentName:t}}async function Ir(e,t){let r=_e[t];if(!r)return{added:!1,serverName:t,tools:[],error:`Unknown MCP server: ${t}`};let n=await De(e),s=await K(e),o=await B(e),i=await _(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=Lt(qe());a.args&&(a.args=a.args.map(d=>d==="${VESPER_INDEXING_PATH}"?l:d))}n.servers[t]=a,await _i(e,n),s[F]||(s[F]={});let c=[];for(let l of r.tools||[])s[F][l]||(s[F][l]=!0,c.push(l));return s[xr]=!1,await ne(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 O(e,i),{added:!0,serverName:t,tools:c}}async function Hs(e,t){let r=_e[t],n=await De(e),s=await K(e),o=await B(e),i=await _(e,o),a=!1;n.servers&&n.servers[t]&&(delete n.servers[t],await _i(e,n),a=!0);let c=[];if(r&&s[F]){for(let l of r.tools||[])s[F][l]&&(delete s[F][l],c.push(l));c.length>0&&await ne(e,s)}return i.mcp?.servers&&(i.mcp.servers=i.mcp.servers.filter(l=>l!==t),i.mcp.updatedAt=new Date().toISOString(),await O(e,i)),{removed:a,serverName:t,tools:c}}function rl(){return Object.entries(_e).map(([e,t])=>({name:e,description:t.description,tools:t.tools?.length||0}))}async function nl(e){let t=await De(e);return Object.keys(t.servers||{})}var gi,Re,kt,ms,xr,F,gs,ys,ws,vs,ks,Ss,Es,te,Ee,Et,xe,yi,un,vi,ki,Ph,Fc,Vc,bs,gn,dn,be,_s,_e,Bc,ae,Dc,Rh,Nh,Mh,pn,fs,hs,Or,ps,Ye,Hc,Uc,Gh,Hh,U=Ot(()=>{Qr();W();Me();je();rt();he();Qr();gi=1e4;Re={agents:"chat.agentFilesLocations",instructions:"chat.instructionsFilesLocations",prompts:"chat.promptFilesLocations",skills:"chat.agentSkillsLocations"},kt="chat.tools.terminal.autoApprove",ms="chat.tools.terminal.enableAutoApprove",xr="chat.tools.autoApprove",F="chat.tools.eligibleForAutoApproval",gs="chat.agent.maxRequests",ys="chat.includeReferencedInstructions",ws="chat.customAgentInSubagent.enabled",vs="chat.agent.enabled",ks="github.copilot.chat.omitBaseAgentInstructions",Ss="chat.mcp.discovery.enabled",Es="chat.mcp.autoStart",te="github.copilot.chat.additionalReadAccessPaths",Ee={maxRequests:300,terminalEnableAutoApprove:!0,omitBaseAgentInstructions:!0,enableMcpServer:!0},Et=[gs,ys,ws,vs,ks,Ss,Es,ms,kt,xr,F],xe=["vesper-indexing","sequential-thinking","memory"],yi=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=yi.map(e=>e.path);vi=[".claude/skills",".claude/rules",".claude/agents",".claude/commands",".claude/CLAUDE.md",".claude/settings.json",".copilot/agents",".copilot/skills",".copilot/instructions"],ki=[".claude/plugins",".vesperrc"];Ph=[".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"],Fc="# <!-- vesper:gitignore:start -->",Vc="# <!-- vesper:gitignore:end -->";bs="Vesper: worktree bootstrap",gn=Object.freeze({taskLabel:"Vesper: host guard",hookCommandMarker:"vespercli guard --running-host"});dn=["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"],be=["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"],_s={"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"]},_e={"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"]}},Bc=be,ae={FOLDER:"folder",WORKSPACE_FILE:"workspace"};Dc=new Set;Rh=new Set([kt,xr,F]);Nh=gt,Mh=["agents","prompts","skills"],pn=N(I,"copilot","instructions"),fs=N(I,"copilot","instructions-extended");hs=N(gt,"packs");Or=Object.freeze(["-c","core.fsmonitor=false","-c","core.untrackedCache=false"]),ps=null;Ye=["pre-commit","post-checkout"];Hc="# <!-- vesper:gitattributes:start -->",Uc="# <!-- vesper:gitattributes:end -->",Gh=[".vesper/memory.jsonl merge=vesper-memory",".claude/vesper/context/recent-decisions.md merge=union",".vesper/context/recent-decisions.md merge=union"];Hh={VSCODE_SETTINGS_MAP:Re,WORKSPACE_TYPES:ae,TERMINAL_AUTO_APPROVAL_SETTING:kt,TERMINAL_ENABLE_AUTO_APPROVAL_SETTING:ms,TOOLS_AUTO_APPROVE_SETTING:xr,TOOLS_ELIGIBLE_FOR_AUTO_APPROVAL_SETTING:F,AGENT_MAX_REQUESTS_SETTING:gs,INCLUDE_REFERENCED_INSTRUCTIONS_SETTING:ys,CUSTOM_AGENT_IN_SUBAGENT_SETTING:ws,CHAT_AGENT_ENABLED_SETTING:vs,OMIT_BASE_AGENT_INSTRUCTIONS_SETTING:ks,MCP_DISCOVERY_ENABLED_SETTING:Ss,MCP_AUTO_START_SETTING:Es,ADDITIONAL_READ_ACCESS_PATHS_SETTING:te,SAFE_AUTO_APPROVAL_COMMANDS:dn,MCP_TOOLS_CORE:be,MCP_TOOLS_BY_AGENT:_s,MCP_SERVERS:_e,MCP_TOOLS_AUTO_APPROVAL:Bc,INIT_DEFAULTS:Ee,VESPER_MANAGED_SETTINGS:Et,VESPER_MANAGED_MCP_SERVERS:xe,findWorkspaceFile:Si,getWorkspaceConfig:B,getSettingsPath:Kc,getTrackingPath:Ar,getTrackingPathAsync:at,readVSCodeSettings:K,writeVSCodeSettings:ne,readTracking:_,writeTracking:O,removeLegacyTracking:Jc,addToSettings:$r,removeFromSettings:kn,getCoreAssetEntries:Ts,pruneLegacySettingsEntries:Cr,listExtendedInstructions:$s,getExtendedInstructionEntry:Cs,getTrackedPaths:ct,configureTerminalAutoApproval:Ps,configureChatSettings:Is,getAutoApprovalCommands:Xc,addReadAccessPath:js,removeReadAccessPath:Rs,getReadAccessPaths:Ls,getMcpConfigPath:Ve,getVesperIndexingPath:qe,readMcpConfig:De,configureMcpServer:Zt,isMcpServerConfigured:Ds,configureMcpToolsAutoApproval:Gs,addAgentToolsToAutoApproval:tl,addMcpServer:Ir,removeMcpServer:Hs,listMcpServers:rl,getConfiguredMcpServers:nl,getWorkspaceFolders:Ei,findNestedVesperrc:vn,migrateVesperrcToWorkspaceLevel:As,ensureCoreSettings:Ns}});import{access as Uh,constants as Wh,stat as bS,lstat as Bh,readdir as Kh,readFile as zh,readlink as Jh,rename as Yh,writeFile as qh,mkdir as Xh,cp as Qh,appendFile as sl}from"node:fs/promises";import{createHash as Zh}from"node:crypto";import{isAbsolute as em,join as tm,relative as rm,resolve as Us,sep as nm}from"node:path";function Ci(e){$i=e?{root:Us(e.root),log:e.log,exclude:e.exclude||(()=>!1)}:null}async function ol(e,t,r){let n=await Bh(e);if(n.isSymbolicLink())r.push([t,`link:${await Jh(e)}`]);else if(n.isDirectory())for(let s of await Kh(e))await ol(tm(e,s),`${t}/${s}`,r);else n.isFile()&&r.push([t,Zh("sha256").update(await zh(e)).digest("hex")])}function il(e,t){let r=Us(t),n=rm(e.root,r);if(!n||n.startsWith("..")||em(n))return null;let s=n.split(nm).join("/");return e.exclude(s)?null:s}async function Ti(e){let t=$i;if(t)try{let r=il(t,e);r&&await sl(t.log,`${JSON.stringify([r,_n])}
|
|
39
|
-
`,"utf-8")}catch{}}async function
|
|
40
|
-
`).join("");o&&await
|
|
41
|
-
`);return`sha256:${
|
|
42
|
-
`);return`sha256:${
|
|
43
|
-
`).
|
|
44
|
-
`)}function
|
|
38
|
+
`,"utf-8"),{created:!1,updated:!0}}async function An(e){if(await V(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{configured:!1};let n=`node "${N(I,"hooks","merge-memory-jsonl.js")}" %O %A %B`;return await V(["config","merge.vesper-memory.name","Vesper memory.jsonl entity-aware merge"],{cwd:e}),{configured:await V(["config","merge.vesper-memory.driver",n],{cwd:e})!==null}}function De(e){return N(e,".vscode","mcp.json")}function qe(){return N(rn,"src","mcp","vesper-indexing","dist","index.js")}async function Ge(e){let t=De(e);try{let r=await Ne(t,"utf-8");return bt(r)}catch(r){if(r.code==="ENOENT")return{servers:{}};if(r instanceof SyntaxError)return{servers:{}};throw r}}async function $i(e,t){let r=De(e),n=it(r);await j(n,{recursive:!0}),await $(r,JSON.stringify(t,null," "),"utf-8")}async function Zt(e,t=!0,{record:r=!0}={}){let n=await Ge(e),s=Lt(qe()),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 $i(e,n),r&&t&&o.length>0){let i=await _(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 O(e,i)}return{configured:t,mcpPath:De(e),servers:o}}async function Gs(e){return!!(await Ge(e)).servers?.["vesper-indexing"]}async function Hs(e){let t=await B(e),r=await K(e);r[xr]=!1,r[F]||(r[F]={});for(let n of xe)r[F][n]=!0;return await ne(e,r),{configured:xe.length,workspaceType:t.type}}async function nl(e,t){let r=As[t];if(!r||r.length===0)return{added:[],agentName:t};let n=await K(e),s=await B(e),o=await _(e,s);n[F]||(n[F]={});let i=[];for(let a of r)n[F][a]||(n[F][a]=!0,i.push(a));return i.length>0&&(await ne(e,n),o.mcp=o.mcp||{},o.mcp.agentTools=o.mcp.agentTools||{},o.mcp.agentTools[t]=r,o.mcp.updatedAt=new Date().toISOString(),await O(e,o)),{added:i,agentName:t}}async function Ir(e,t){let r=Ae[t];if(!r)return{added:!1,serverName:t,tools:[],error:`Unknown MCP server: ${t}`};let n=await Ge(e),s=await K(e),o=await B(e),i=await _(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=Lt(qe());a.args&&(a.args=a.args.map(d=>d==="${VESPER_INDEXING_PATH}"?l:d))}n.servers[t]=a,await $i(e,n),s[F]||(s[F]={});let c=[];for(let l of r.tools||[])s[F][l]||(s[F][l]=!0,c.push(l));return s[xr]=!1,await ne(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 O(e,i),{added:!0,serverName:t,tools:c}}async function Us(e,t){let r=Ae[t],n=await Ge(e),s=await K(e),o=await B(e),i=await _(e,o),a=!1;n.servers&&n.servers[t]&&(delete n.servers[t],await $i(e,n),a=!0);let c=[];if(r&&s[F]){for(let l of r.tools||[])s[F][l]&&(delete s[F][l],c.push(l));c.length>0&&await ne(e,s)}return i.mcp?.servers&&(i.mcp.servers=i.mcp.servers.filter(l=>l!==t),i.mcp.updatedAt=new Date().toISOString(),await O(e,i)),{removed:a,serverName:t,tools:c}}function sl(){return Object.entries(Ae).map(([e,t])=>({name:e,description:t.description,tools:t.tools?.length||0}))}async function ol(e){let t=await Ge(e);return Object.keys(t.servers||{})}var wi,Le,kt,gs,xr,F,ys,ws,vs,ks,Ss,Es,bs,te,be,Et,_e,vi,pn,Si,Ei,Mh,Dc,Gc,xs,wn,fn,xe,As,Ae,zc,ae,Hc,Dh,Hh,Uh,hn,hs,ms,Or,fs,Ye,Wc,Bc,zh,Jh,U=Ot(()=>{en();W();Fe();Re();rt();he();en();wi=1e4;Le={agents:"chat.agentFilesLocations",instructions:"chat.instructionsFilesLocations",prompts:"chat.promptFilesLocations",skills:"chat.agentSkillsLocations"},kt="chat.tools.terminal.autoApprove",gs="chat.tools.terminal.enableAutoApprove",xr="chat.tools.autoApprove",F="chat.tools.eligibleForAutoApproval",ys="chat.agent.maxRequests",ws="chat.includeReferencedInstructions",vs="chat.customAgentInSubagent.enabled",ks="chat.agent.enabled",Ss="github.copilot.chat.omitBaseAgentInstructions",Es="chat.mcp.discovery.enabled",bs="chat.mcp.autoStart",te="github.copilot.chat.additionalReadAccessPaths",be={maxRequests:300,terminalEnableAutoApprove:!0,omitBaseAgentInstructions:!0,enableMcpServer:!0},Et=[ys,ws,vs,ks,Ss,Es,bs,gs,kt,xr,F],_e=["vesper-indexing","sequential-thinking","memory"],vi=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/"})]),pn=vi.map(e=>e.path);Si=[".claude/skills",".claude/rules",".claude/agents",".claude/commands",".claude/CLAUDE.md",".claude/settings.json",".copilot/agents",".copilot/skills",".copilot/instructions"],Ei=[".claude/plugins",".vesperrc"];Mh=[".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"],Dc="# <!-- vesper:gitignore:start -->",Gc="# <!-- vesper:gitignore:end -->";xs="Vesper: worktree bootstrap",wn=Object.freeze({taskLabel:"Vesper: host guard",hookCommandMarker:"vespercli guard --running-host"});fn=["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"],xe=["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"],As={"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"]},Ae={"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"]}},zc=xe,ae={FOLDER:"folder",WORKSPACE_FILE:"workspace"};Hc=new Set;Dh=new Set([kt,xr,F]);Hh=gt,Uh=["agents","prompts","skills"],hn=N(I,"copilot","instructions"),hs=N(I,"copilot","instructions-extended");ms=N(gt,"packs");Or=Object.freeze(["-c","core.fsmonitor=false","-c","core.untrackedCache=false"]),fs=null;Ye=["pre-commit","post-checkout"];Wc="# <!-- vesper:gitattributes:start -->",Bc="# <!-- vesper:gitattributes:end -->",zh=[".vesper/memory.jsonl merge=vesper-memory",".claude/vesper/context/recent-decisions.md merge=union",".vesper/context/recent-decisions.md merge=union"];Jh={VSCODE_SETTINGS_MAP:Le,WORKSPACE_TYPES:ae,TERMINAL_AUTO_APPROVAL_SETTING:kt,TERMINAL_ENABLE_AUTO_APPROVAL_SETTING:gs,TOOLS_AUTO_APPROVE_SETTING:xr,TOOLS_ELIGIBLE_FOR_AUTO_APPROVAL_SETTING:F,AGENT_MAX_REQUESTS_SETTING:ys,INCLUDE_REFERENCED_INSTRUCTIONS_SETTING:ws,CUSTOM_AGENT_IN_SUBAGENT_SETTING:vs,CHAT_AGENT_ENABLED_SETTING:ks,OMIT_BASE_AGENT_INSTRUCTIONS_SETTING:Ss,MCP_DISCOVERY_ENABLED_SETTING:Es,MCP_AUTO_START_SETTING:bs,ADDITIONAL_READ_ACCESS_PATHS_SETTING:te,SAFE_AUTO_APPROVAL_COMMANDS:fn,MCP_TOOLS_CORE:xe,MCP_TOOLS_BY_AGENT:As,MCP_SERVERS:Ae,MCP_TOOLS_AUTO_APPROVAL:zc,INIT_DEFAULTS:be,VESPER_MANAGED_SETTINGS:Et,VESPER_MANAGED_MCP_SERVERS:_e,findWorkspaceFile:bi,getWorkspaceConfig:B,getSettingsPath:Jc,getTrackingPath:Ar,getTrackingPathAsync:at,readVSCodeSettings:K,writeVSCodeSettings:ne,readTracking:_,writeTracking:O,removeLegacyTracking:qc,addToSettings:$r,removeFromSettings:En,getCoreAssetEntries:Os,pruneLegacySettingsEntries:Cr,listExtendedInstructions:Cs,getExtendedInstructionEntry:Ts,getTrackedPaths:ct,configureTerminalAutoApproval:Is,configureChatSettings:js,getAutoApprovalCommands:Zc,addReadAccessPath:Rs,removeReadAccessPath:Ls,getReadAccessPaths:Ns,getMcpConfigPath:De,getVesperIndexingPath:qe,readMcpConfig:Ge,configureMcpServer:Zt,isMcpServerConfigured:Gs,configureMcpToolsAutoApproval:Hs,addAgentToolsToAutoApproval:nl,addMcpServer:Ir,removeMcpServer:Us,listMcpServers:sl,getConfiguredMcpServers:ol,getWorkspaceFolders:xi,findNestedVesperrc:Sn,migrateVesperrcToWorkspaceLevel:$s,ensureCoreSettings:Ms}});import{access as Yh,constants as qh,stat as IS,lstat as Xh,readdir as Qh,readFile as Zh,readlink as em,rename as tm,writeFile as rm,mkdir as nm,cp as sm,appendFile as il}from"node:fs/promises";import{createHash as om}from"node:crypto";import{isAbsolute as im,join as am,relative as cm,resolve as Ws,sep as lm}from"node:path";function Oi(e){Ti=e?{root:Ws(e.root),log:e.log,exclude:e.exclude||(()=>!1)}:null}async function al(e,t,r){let n=await Xh(e);if(n.isSymbolicLink())r.push([t,`link:${await em(e)}`]);else if(n.isDirectory())for(let s of await Qh(e))await al(am(e,s),`${t}/${s}`,r);else n.isFile()&&r.push([t,om("sha256").update(await Zh(e)).digest("hex")])}function cl(e,t){let r=Ws(t),n=cm(e.root,r);if(!n||n.startsWith("..")||im(n))return null;let s=n.split(lm).join("/");return e.exclude(s)?null:s}async function Pi(e){let t=Ti;if(t)try{let r=cl(t,e);r&&await il(t.log,`${JSON.stringify([r,$n])}
|
|
39
|
+
`,"utf-8")}catch{}}async function Ii(e){let t=Ti;if(t)try{let r=Ws(e),n=cl(t,e);if(!n)return;let s=[];await al(r,n,s);let o=s.filter(([i])=>!t.exclude(i)).map(i=>`${JSON.stringify(i)}
|
|
40
|
+
`).join("");o&&await il(t.log,o,"utf-8")}catch{}}async function w(e){try{return await Yh(e,qh.F_OK),!0}catch{return!1}}function ji(e){let t=Ws(e);if(Qt(t)||Qt(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 $(e,t,r){ji(e),await Pi(e);let n=await rm(e,t,r);return await Ii(e),n}async function j(e,t){return ji(e),nm(e,t)}async function Cn(e,t,r){ji(t),await Pi(t);let n=await sm(e,t,r);return await Ii(t),n}async function um(e,t){await Pi(t);let r=await tm(e,t);return await Ii(t),r}async function er(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 g=c(e).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),f=o??new RegExp(`^${g}\\.\\d+\\.tmp$`),m=[];try{m=await d.readdir(p)}catch{m=[]}for(let y of m){if(!f.test(y))continue;let k=l(p,y);try{Date.now()-(await d.stat(k)).mtimeMs>dm&&await d.unlink(k)}catch{}}}let h=s?s(e):`${e}.${process.pid}.tmp`;try{await $(h,t,r===void 0?n:{encoding:n,mode:r}),r!==void 0&&await d.chmod(h,r).catch(()=>{}),await um(h,e)}catch(g){throw await d.unlink(h).catch(()=>{}),g}}var Ti,$n,dm,W=Ot(()=>{U();Ti=null;$n="intent";dm=5*60*1e3});import{Command as Yk,Option as tt}from"commander";import{readFileSync as qk,existsSync as Xk}from"node:fs";import{fileURLToPath as Qk}from"node:url";import{dirname as dc,join as Rf}from"node:path";W();U();import{resolve as yv,basename as Mp,relative as wv,sep as vv,isAbsolute as kv}from"node:path";import{spawn as Sv}from"node:child_process";import{confirm as Bt,input as Ev,number as bv,select as xv}from"@inquirer/prompts";U();W();import{createHash as Tm}from"node:crypto";import{readFile as Al,readdir as $l}from"node:fs/promises";import{join as jr,isAbsolute as Om}from"node:path";Re();import{lstat as yl,readdir as wl,readFile as Ks,rm as vl,rmdir as ml}from"node:fs/promises";import{basename as kl,join as He,relative as fm,sep as hm}from"node:path";import{existsSync as Li}from"node:fs";import{createHash as Sl}from"node:crypto";Re();import{existsSync as ll,readdirSync as pm}from"node:fs";import{readdir as ul,readFile as dl}from"node:fs/promises";import{join as Mt}from"node:path";var Ri="UPSTREAM.json",tr=Object.freeze(["gitlab-ci-skill","github-actions-to-gitlab-ci","i-have-adhd","ponytail"]),pl="styles";function fl(e=I){try{return pm(Mt(e,"claude","packs"),{withFileTypes:!0}).filter(t=>t.isDirectory()&&!t.name.startsWith(".")).map(t=>t.name).sort()}catch{return[]}}function rr(e,t=I){if(typeof e!="string"||!e||/[\\/]|\.\./.test(e))return null;for(let r of fl(t)){let n=Mt(t,"claude","packs",r,"skills",e);if(ll(Mt(n,Ri)))return{pack:r,dir:n}}return null}async function Bs(e){let t={},r=async n=>{let s=await ul(Mt(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!==Ri&&(t[i]=await dl(Mt(e,i)))}};return await r(""),t}async function hl(e=I){let t=[];for(let r of fl(e)){let n=[];try{n=(await ul(Mt(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=Mt(e,"claude","packs",r,"skills",s),i=Mt(o,Ri);if(!ll(i))continue;let a=null;try{let c=JSON.parse(await dl(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}async function Xe(e){let t=[],r=[],n=[],s=async o=>{let i=await wl(o,{withFileTypes:!0});for(let a of i){let c=He(o,a.name),l=fm(e,c).split(hm).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 mm(e){return`sha256:${Sl("sha256").update(e).digest("hex")}`}function Qe(e){let t=e.toString("utf-8").replace(/\r\n/g,`
|
|
41
|
+
`);return`sha256:${Sl("sha256").update(t,"utf8").digest("hex")}`}function gl(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 ge(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 gl(r).equals(gl(n))}async function gm({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=>mm(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=>ge(l,c))}if(e&&Li(e)){let{files:i}=await Xe(e);for(let a of i)o(a,async c=>ge(c,await Ks(He(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(Qe(l)))}return s}async function xt(e,{sourceDir:t,sourceFiles:r,sourceHashes:n,sourceLfHashes:s,sourceMatch:o,anchor:i="SKILL.md"}={}){let a;try{a=await yl(e)}catch{return{status:"absent",proven:[],kept:[],dirs:[]}}if(!a.isDirectory())return{status:"not-directory",proven:[],kept:[kl(e)],dirs:[]};let c=await gm({sourceDir:t,sourceFiles:r,sourceHashes:n,sourceLfHashes:s}),{files:l,others:d,dirs:p}=await Xe(e),h=[],g=[...d];for(let f of l){let y=c.get(f)||(o?async k=>!!await o(f,k):null);if(!y){g.push(f);continue}try{await y(await Ks(He(e,f)))?h.push(f):g.push(f)}catch{g.push(f)}}return g.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:g,dirs:p}}async function Tn(e,t={}){let r=await xt(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 vl(He(e,o),{force:!0});for(let o of r.dirs)try{await ml(He(e,o))}catch{}let n=!1;try{await ml(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 ym(e){let t=kl(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=rr(t);return s?{sourceFiles:await Bs(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=He(I,s,"skills",t);if(Li(o)){r=o;break}}if(!r){let s=[];try{s=(await wl(He(I,"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=He(I,"claude","packs",o,"skills",t);if(Li(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 wm(e){let t=String(e?.path||""),r=[];t===".claude/rules/vesper-orchestrator.md"&&r.push(He(I,"claude","vesper-orchestrator.md"));let n=/^\.claude\/agents\/([^/]+\.md)$/.exec(t);n&&r.push(He(I,"claude-committed","agents",n[1]),He(I,"claude","agents",n[1])),n=/^\.claude\/commands\/([^/]+\.md)$/.exec(t),n&&r.push(He(I,"claude","commands",n[1]));let s=[];for(let o of r)try{s.push(await Ks(o))}catch{}return s}async function Ni(e,t,{expected:r=[]}={}){let n;try{n=await Ks(e)}catch{return!1}return typeof t?.hash=="string"&&t.hash&&Qe(n)===t.hash?!0:[...r.map(o=>Buffer.isBuffer(o)?o:Buffer.from(String(o),"utf-8")),...await wm(t)].some(o=>ge(n,o))}async function ue(e,t,{expected:r=[],purgeProjectAuthored:n=!1}={}){let s;try{s=await yl(e)}catch{return"absent"}if(s.isFile())return!(n===!0&&t?.category==="per-project-authored")&&!await Ni(e,t,{expected:r})?"kept":(await vl(e,{force:!0}),"removed");if(!s.isDirectory())return"kept";let o=await ym(t);return o?(await Tn(e,o)).status:"kept"}he();U();ot();import{access as vm,constants as km,readFile as bl,readdir as Sm}from"node:fs/promises";import{execFile as Em}from"node:child_process";import{join as zs}from"node:path";var On=Object.freeze(["claude","copilot"]),Ft=".vesper/.host-switch-journal.json";async function bm(e){try{return await vm(e,km.F_OK),!0}catch{return!1}}async function _t(e){try{let t=JSON.parse(await bl(zs(e,Ft),"utf-8"));if(t&&typeof t=="object"&&t.snapshot&&On.includes(t.from))return t}catch{}return null}async function Mi(e){return await bm(zs(e,Ft))?await _t(e)===null:!1}async function xm(e){let t;try{t=[await at(e),zs(e,".vesperrc")]}catch{t=[zs(e,".vesperrc")]}let r=new Set;for(let n of t)if(!r.has(n)){r.add(n);try{return JSON.parse(await bl(n,"utf-8"))}catch(s){if(s&&s.code==="ENOENT")continue;return null}}return null}function xl(e,t,{env:r,gitArgs:n=[]}={}){return new Promise(s=>{let o;try{o=Em("git",[...n,...t],{cwd:e,timeout:5e3,maxBuffer:16*1024*1024,encoding:"utf-8",env:{...r??process.env,...vt}},(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 _m(e,t={}){let r=await xl(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 Am(e,t){if(!t?.host)return!1;try{let{host:r,matched:n}=await Oc(e);if(r!==t.host||n.length===0)return!1;for(let{entry:s,path:o}of n)if(!await ai(e,s,o))return!1;return!0}catch{return!1}}async function $m(e){try{return(await Sm(e,{withFileTypes:!0})).filter(t=>t.isFile()&&t.name.endsWith(".code-workspace")).map(t=>t.name).sort()}catch{return[]}}function Cm(e){let t=[];for(let r of On)for(let n of e[r]||[])t.push(nt(n));return[...new Set(t)]}async function El(e,t,r,n){let s=[],o=null;for(let i of On){let a=!1,c=[...t[i]||[]].sort((l,d)=>+!!d?.vscodeSettings-+!!l?.vscodeSettings);for(let l of c){let d=nt(l),p=Sr(l)&&l.vscodeSettings?[...n,d]:[d];for(let h of p)if(!r.has(h)&&await ai(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 z(e,{requireCommitted:t=!1,withCommitted:r=!1,env:n,gitArgs:s}={}){let o={env:n,gitArgs:s},i=await nr(e),a={host:null,source:null,ambiguous:!1,committed:!1,ignoredEvidence:null,ignoredFile:null,candidate:null,visible:null,gitError:null};try{let c=await _m(e,o);if(c.state==="error")return{...a,gitError:c.gitError};let l=Rt(),d=await $m(e),p=null;if(c.state==="repo"){let f=[...new Set([...Cm(l),...d])],m=await xl(e,["--literal-pathspecs","ls-files","-z","--cached","--others","--exclude-standard","--",...f],o);if(!m.ok)return{...a,gitError:"unknown"};p=new Set(m.stdout.split("\0").filter(Boolean))}a.visible=p;let h=[];for(let f of On)for(let m of l[f]||[])if(await Pt(e,m,{visible:p})){h.push(f);break}if(h.length>1)return{...a,ambiguous:!0};let g=h[0]??null;if(g){if(t||r){let f=await Am(e,{host:g});return a.committed=f,t&&!f?(p&&Object.assign(a,await El(e,l,p,d)),{...a,candidate:g}):{...a,host:g,source:f?"committed":"working-tree"}}return{...a,host:g,source:"working-tree"}}return c.state!=="repo"?a:(Object.assign(a,await El(e,l,p,d)),!t&&a.ignoredEvidence&&a.ignoredEvidence!=="both"&&a.ignoredEvidence===i?{...a,host:i,source:"local"}:a)}catch{return a}}async function nr(e){try{let t=await xm(e);return t&&On.includes(t.host)?t.host:null}catch{return null}}he();var de=2,G=["claude","copilot"],Ue="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`.",Js="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.";var At={"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"}},Pm=new Set(Object.entries(At).filter(([,e])=>e.doctor==="content-hash").map(([e])=>e));function Vi(e){let t=String(e).replace(/\r\n/g,`
|
|
42
|
+
`);return`sha256:${Tm("sha256").update(t,"utf8").digest("hex")}`}async function ye(e){try{return Vi(await Al(e,"utf-8"))}catch{return null}}function D({path:e,host:t,category:r,hash:n=null}){if(Pm.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 Q({path:e,host:t,category:r,owns:n}){return{path:e,host:t,category:r,owns:n||{}}}async function Rr(e){return(await z(e)).host}async function Cl(e,t){if(!G.includes(t))throw new Error(`Invalid host "${t}". Vesper 2.0 provisions exactly one of: ${G.join(", ")}.`);let r=await _(e);return r.schemaVersion=de,r.host=t,await O(e,r),t}async function Ys(e,t){return(await _(e))[t]}async function Im(e,t,r){let n=await _(e);return n[t]=r,await O(e,n),r}var qs=e=>Ys(e,"frameworkVersion");var Lr=async e=>await Ys(e,"namePrefix")??"";var Tl=e=>Ys(e,"pluginPath");var Di="manifestProvenance",Gi="granular";async function Ol(e){return await Ys(e,Di)===Gi}function Pl(e){return Im(e,Di,Gi)}async function Il(e,t){let r=await _(e);if(r[Di]===Gi)return[];let n=Y(r),s=[],o=n.filter(i=>{let a=i.host===t&&i.category!=="added-asset"&&At[i.category]?.ownership==="whole-file";return a&&s.push(i.path),!a});return s.length===0?[]:(r.manifest=o,await O(e,r),s)}function Pn(e){return e&&typeof e.path=="string"&&typeof e.host=="string"&&typeof e.category=="string"}async function $e(e){let t=await _(e);return Y(t)}function Y(e){let t=e?.manifest;return Array.isArray(t)?t.filter(Pn):[]}function lt(e){return[...e].sort((t,r)=>String(t.path).localeCompare(String(r.path))||String(t.host).localeCompare(String(r.host)))}function Hi(e,t){let r=[...e];for(let n of t){if(!Pn(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 J(e,t){let r=await _(e);return r.schemaVersion=de,r.manifest=lt(Hi(Y(r),t||[])),await O(e,r),r.manifest}function jm(e){return typeof e=="string"&&e.length>0&&!e.includes("..")&&!e.startsWith("/")}var Ce=new Set(["per-project-authored"]);function Xs(e,{host:t,keep:r,purgeProjectAuthored:n=!1}={}){return!e||typeof e.path!="string"||e.host==="shared"||Ce.has(e.category)&&!n||t&&e.host!==t||At[e.category]?.ownership!=="whole-file"||r&&r.has(e.path)?!1:jm(e.path)}async function jl(e,t,{prune:r=!0,categories:n}={}){let s=await $e(e),o=(t||[]).filter(Pn),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)||!Xs(f,{keep:l}))continue;let m=jr(e,f.path);if(await w(m)){let y=await ue(m,f);(y==="kept"||y==="partial")&&p.push(f.path),y!=="kept"&&d.push(f.path)}}let h=s.filter(f=>!c(f)),g=await _(e);return g.schemaVersion=de,g.manifest=lt(Hi(h,o)),await O(e,g),{pruned:d,kept:p,manifest:g.manifest}}async function Rl(e,t,{host:r,purgeProjectAuthored:n=!1}={}){let s=new Set(t||[]),o=await $e(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(Xs(p,{host:r,keep:s,purgeProjectAuthored:n})){let h=jr(e,p.path);if(l(p)){i.push(p.path);continue}if(await w(h)){let g=await ue(h,p,{purgeProjectAuthored:n});(g==="kept"||g==="partial")&&a.push(p.path)}i.push(p.path);continue}c.push(p)}let d=await _(e);return d.manifest=lt(c),await O(e,d),{pruned:i,kept:a,manifest:d.manifest}}async function Ll(e){let t=await $e(e),r={missing:[],modified:[],clean:[],userLevelViolations:[]};for(let n of t){let s=Om(n.path)?n.path:jr(e,n.path);Qt(s)&&r.userLevelViolations.push(n);let o=At[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 Fi(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 Fi(e){try{let t=JSON.parse(await Al(e,"utf-8"));return Object.keys(t.mcpServers||t.servers||{})}catch{return[]}}async function _l(e){try{return(await $l(e,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(".md")).map(r=>r.name)}catch{return[]}}async function Rm(e){try{return(await $l(e,{withFileTypes:!0})).filter(r=>r.isDirectory()).map(r=>r.name)}catch{return[]}}async function Ui(e,t,{settingsEntries:r,hooksDir:n,hookNames:s,provisionedSkillNames:o,provisionedInstructionNames:i}={}){let a=[],c=d=>jr(e,d),l=async(d,p)=>{a.push(D({path:d,host:t,category:p,hash:await ye(c(d))}))};if(t==="claude"){for(let p of await _l(c(".claude/agents")))await l(`.claude/agents/${p}`,"catalog-agent");for(let p of await _l(c(".claude/commands")))await l(`.claude/commands/${p}`,"catalog-command");let d=new Set(o||[]);for(let p of await Rm(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(Q({path:"CLAUDE.md",host:t,category:"pointer",owns:{region:"vesper"}})),await w(c(".mcp.json"))&&a.push(Q({path:".mcp.json",host:t,category:"mcp-config",owns:{keys:await Fi(c(".mcp.json"))}})),await w(c(".claude/settings.json"))&&a.push(Q({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(Q({path:".vscode/settings.json",host:t,category:"settings",owns:{keys:[...Et],entries:r?[...r]:[]}})),await w(c(".vscode/mcp.json"))&&a.push(Q({path:".vscode/mcp.json",host:t,category:"mcp-config",owns:{keys:await Fi(c(".vscode/mcp.json"))}})),await w(c(".vscode/tasks.json"))&&a.push(Q({path:".vscode/tasks.json",host:t,category:"bootstrap-task",owns:{keys:["Vesper: worktree bootstrap"]}}))),await w(c(".gitignore"))&&a.push(Q({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=jr(n,d);await w(p)&&a.push(Q({path:p,host:"shared",category:"hook",owns:{region:"vesper:hook"}}))}return a}var In=Object.freeze(["paths","claude","addedAt","workspaceType","settingsPath","updatedAt","catalogVersion","targets"]);function Wi(e){return(e||[]).filter(t=>t&&t.host==="shared")}function Lm(e){let t=!1;for(let r of In)r in e&&(delete e[r],t=!0);return t}async function Nl(e){!await w(jr(e,".vesperrc"))||(await _(e)).schemaVersion!==de||await Nr(e)}async function Nr(e,{frameworkVersion:t,legacyEntries:r=[],host:n}={}){let s=await _(e);if(s.schemaVersion===de){let f=!1;if("host"in s&&!G.includes(s.host)&&(delete s.host,f=!0),!Array.isArray(s.manifest))s.manifest=[],f=!0;else{let m=s.manifest.filter(Pn);m.length!==s.manifest.length&&(s.manifest=m,f=!0)}return Lm(s)&&(f=!0),f&&await O(e,s),s}let o=(G.includes(n)?n:null)||mn(s)||(await z(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 Ui(e,i,{settingsEntries:l}),p=lt(Hi(Wi(d),(r||[]).filter(Pn))),h={schemaVersion:de,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 g=new Set([...In,"schemaVersion","host","frameworkVersion","manifest","namePrefix","pluginPath","vendored","mcp","readAccessPaths"]);for(let[f,m]of Object.entries(s))g.has(f)||(h[f]=m);return await O(e,h),h}async function sr(e,t){let r=await _(e);return!!(Y(r).some(s=>s.host===t&&!Ce.has(s.category))||t==="claude"&&r.claude||t==="copilot"&&Array.isArray(r.paths)&&r.paths.length>0)}async function ut(e){let t=await _(e),n=Y(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]:[]}import{readFile as re,readdir as ku,rm as Gr,rmdir as na}from"node:fs/promises";import{join as P,dirname as Dn,basename as kg}from"node:path";Re();Re();import{readdir as Bi}from"node:fs/promises";import{join as jn}from"node:path";var Qs=Object.freeze({"history-logger":"vespercli log (the run ledger)"});function Vl(e){let t=[],r=null;return{text:String(e||"").split(`
|
|
43
|
+
`).filter(s=>{if(!/^\s*\|/.test(s))return r=null,!0;let o=Gl(s);if(Hl(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=Dl.exec(o[i]||"")?.[2],c=a?Mr(a).name:null;if(c&&Object.hasOwn(Qs,c))return t.push({role:(o[0]||"").trim(),agent:c,replacement:Qs[c]}),!1}return!0}).join(`
|
|
44
|
+
`),removed:t}}var or="vesper";function We(e){return`${or}-${e}`}async function Ml(e){try{return(await Bi(e)).filter(t=>t.endsWith(".md")).map(t=>t.slice(0,-3))}catch{return[]}}async function Fl(e){try{return(await Bi(e,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name)}catch{return[]}}async function dt(e=I){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 Ml(jn(e,"claude","agents")))r("agents",s,or,"core");for(let s of await Fl(jn(e,"claude","skills")))r("skills",s,or,"core");let n=[];try{n=(await Bi(jn(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=We(s);for(let i of await Ml(jn(e,"claude","packs",s,"agents")))r("agents",i,o,s);for(let i of await Fl(jn(e,"claude","packs",s,"skills")))r("skills",i,o,s)}return t}var Dl=/^(\s*`?)([a-z0-9:-]+)/;function Gl(e){return e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|")}function Hl(e){return e.every(t=>/^:?-{2,}:?$/.test(t.trim()))}function Ul(e,t,r){let n=null;return e.split(`
|
|
45
|
+
`).map(s=>{if(!/^\s*\|/.test(s))return n=null,s;let o=Gl(s);if(Hl(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 Ki(e,t){return Ul(e,/agent/i,r=>{let n=Dl.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 Mr(e){let t=e.lastIndexOf(":");return t===-1?{plugin:null,name:e}:{plugin:e.slice(0,t),name:e.slice(t+1)}}function Wl(e,t){let r=new Set;return Ki(e,n=>(!n.includes(":")&&t.has(n)&&r.add(n),null)),[...r].sort()}function Zs(e,t,{skip:r=new Set}={}){let n=t instanceof Set?t:t.agents,s=a=>t instanceof Set?or:t.agentPlugin?.get(a)??or,o=new Set;return{text:Ki(e,a=>{let{plugin:c,name:l}=Mr(a);if(!n.has(l)||r.has(l))return null;let d=s(l);return c===d||c!==null&&!(c===or||c.startsWith(`${or}-`))?null:(o.add(l),`${d}:${l}`)}),qualified:[...o].sort()}}function Bl(e){return String(e||"").replace(/<!--[\s\S]*?-->/g,"")}function Kl(e){let t=new Set;return Ki(Bl(e),r=>(t.add(Mr(r).name),null)),[...t].sort()}function zl(e){let t=new Set;return Ul(Bl(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()}W();W();U();import{readFile as Jl}from"node:fs/promises";import{join as Rn,dirname as Nm}from"node:path";he();var Ln="pack-rule",zi=Object.freeze({styles:Object.freeze({claude:".claude/rules/vesper-styles.md",copilot:Ee("vesper-styles")})});function Yl(){return Object.keys(zi).sort()}function ir(e){return Object.prototype.hasOwnProperty.call(zi,e)}function Nn(e,t){return zi[e]?.[t]??null}function Ji(e,t){if(e!=="styles"||!Nn(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(`
|
|
45
47
|
`);return t==="claude"?n:`---
|
|
46
48
|
applyTo: '**'
|
|
47
49
|
description: 'Vesper styles pack \u2014 apply the i-have-adhd output style and the ponytail decision ladder on every reply.'
|
|
48
50
|
---
|
|
49
51
|
|
|
50
|
-
${n}`}async function
|
|
51
|
-
`,"utf-8"),{created:!0,path:se,checks:
|
|
52
|
-
`)}function
|
|
52
|
+
${n}`}async function ql(e,t,r){return(await $e(e)).find(n=>n.host===t&&n.path===r&&n.category===Ln)||null}async function Mm(e,t,r){let n=await _(e),s=Y(n),o=s.filter(i=>!(i.host===t&&i.path===r&&i.category===Ln));return o.length===s.length?!1:(n.manifest=lt(o),await O(e,n),!0)}async function Xl(e,t,r){let n=Nn(r,t);if(!n)return null;let s=Ji(r,t),o=Rn(e,n),i=async()=>J(e,[D({path:n,host:t,category:Ln,hash:Vi(s)})]),a=null;try{a=await Jl(o)}catch{a=null}if(a===null)return await j(Nm(o),{recursive:!0}),await $(o,s,"utf-8"),await i(),{path:n,status:"created"};if(ge(a,s))return await i(),{path:n,status:"unchanged"};let c=await ql(e,t,n);return c?.hash&&await ye(o)===c.hash?(await $(o,s,"utf-8"),await i(),{path:n,status:"updated"}):{path:n,status:"kept-edited"}}async function Yi(e,t,r){let n=Nn(r,t);if(!n)return null;let o=await ql(e,t,n)??{path:n,category:Ln,hash:null},i=await ue(Rn(e,n),o,{expected:[Ji(r,t)]});return await Mm(e,t,n),{path:n,status:i==="partial"?"kept":i}}async function eo(e,t){let r={removed:[],kept:[]};for(let n of Yl()){let s=await Yi(e,t,n);s?.status==="removed"?r.removed.push(s.path):s?.status==="kept"&&r.kept.push(s.path)}return r}async function Ql(e,t){let r=[];for(let n of Yl()){let s=Nn(n,t);if(!s||!await w(Rn(e,s)))continue;let o=null;try{o=await Jl(Rn(e,s))}catch{o=null}!o||!ge(o,Ji(n,t))||r.push(D({path:s,host:t,category:Ln,hash:await ye(Rn(e,s))}))}return r}function qi(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.`}W();ot();import{readFile as to,readdir as Fm}from"node:fs/promises";import{join as Vr,dirname as eu,basename as Vm}from"node:path";import{spawnSync as tu}from"node:child_process";var se=".vesper/gates.json",Qi=1,ru=Object.freeze({files:40,lines:1500}),Dm=30,Gm=".vesper/.tracking/",ar=Object.freeze({PASS:0,FAIL:1,NO_CONFIG:2}),Hm="4b825dc642cb6eb9a060e54bf8d69288fbee4904",Um=Object.freeze([{candidates:["test"]},{candidates:["lint"]},{candidates:["typecheck","tsc","type-check"]},{candidates:["build"]}]),Wm=Object.freeze(["npm","pnpm","yarn","bun"]),Bm=Object.freeze([["pnpm-lock.yaml","pnpm"],["yarn.lock","yarn"],["bun.lockb","bun"],["bun.lock","bun"],["package-lock.json","npm"]]);function Km(e,t=[]){let r=typeof e?.packageManager=="string"?e.packageManager.trim().split("@")[0]:"";if(Wm.includes(r))return r;let n=new Set(t);for(let[s,o]of Bm)if(n.has(s))return o;return"npm"}function zm(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 Jm(e,t="npm"){let r=[];if(!e||typeof e!="object")return r;for(let n of Um){let s=n.candidates.find(o=>typeof e[o]=="string"&&e[o].trim()!=="");s&&r.push({name:s,command:zm(t,s),detected:!0})}return r}function Ym(e,t=[]){return{schemaVersion:Qi,checks:Jm(e?.scripts,Km(e,t)),diffSizeCap:{...ru},protectedPaths:[]}}async function ro(e){let t=Vr(e,se);if(await w(t))return{created:!1,path:se,checks:[]};let r=null;try{r=JSON.parse(await to(Vr(e,"package.json"),"utf-8"))}catch{r=null}let n=[];try{n=await Fm(e)}catch{n=[]}let s=Ym(r,n);return await j(eu(t),{recursive:!0}),await $(t,`${JSON.stringify(s,null,2)}
|
|
53
|
+
`,"utf-8"),{created:!0,path:se,checks:s.checks.map(o=>o.name)}}function qm(e){let t=[];if(!e||typeof e!="object"||Array.isArray(e))return["config is not an object"];e.schemaVersion!==Qi&&t.push(`schemaVersion must be ${Qi}`),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 nu(e){let t;try{t=await to(Vr(e,se),"utf-8")}catch{return{ok:!1,reason:"missing",errors:[`${se} not found`]}}let r;try{r=JSON.parse(t)}catch(s){return{ok:!1,reason:"invalid",errors:[`${se} is not valid JSON: ${s.message}`]}}let n=qm(r);return n.length?{ok:!1,reason:"invalid",errors:n}:{ok:!0,config:{...r,diffSizeCap:{...ru,...r.diffSizeCap||{}},protectedPaths:r.protectedPaths||[]}}}var Xm=/^(?:[\w.@-]+\/)*[\w.@-]+(?:\.[A-Za-z0-9]+)?$/,Qm=/\.[A-Za-z0-9]{1,10}$/;function Zl(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!Xm.test(n)||!r&&!n.includes("/")&&!Qm.test(n)||/^\.+$/.test(n)?null:r?`${n}/`:n}var Zm=/^\s*(?:#{1,6}\s*|[-*]\s*\*\*)(?:files?(?:\s+operations?)?|file\s+list)\*{0,2}\s*:?\s*$/i,eg=/^\s*#{1,6}\s/,tg=/^\s*[-*]\s*\*\*[^*]+\*\*\s*:?/,rg=/^\s*[-*+]\s+(.*)$/;function ng(e){let t=new Set,r=String(e||"");for(let i of r.matchAll(/`([^`\n]+)`/g)){let a=Zl(i[1]);a&&t.add(a)}let n=r.split(/\r?\n/),s=!1,o=-1;for(let i of n){if(Zm.test(i)){s=!0,o=-1;continue}if(!s)continue;if(!i.trim()){o>=0&&(s=!1);continue}if(eg.test(i)||tg.test(i)){s=!1;continue}let a=rg.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=Zl(l);d&&t.add(d)}return[...t].sort()}function sg(e){let t=Vm(e);if(!/-plan\.md$/i.test(t))return[];let r=t.replace(/-plan\.md$/i,"-details.md"),n=eu(e);return[Vr(n,"..","details",r),Vr(n,r)]}async function su(e){let t=[e];for(let s of sg(e))if(await w(s)){t.push(s);break}let r=await Promise.all(t.map(s=>to(s,"utf-8"))),n=new Set;for(let s of r)for(let o of ng(s))n.add(o);return{planned:[...n].sort(),sources:t}}function og(e,t){for(let r of t)if(r===e||r.endsWith("/")&&e.startsWith(r))return!0;return!1}function ig(e,t){let r=e.filter(n=>!n.startsWith(Gm)).filter(n=>!og(n,t)).sort();return{planned:[...t].sort(),unplanned:r,skipped:null}}var Xi=new Map;function ag(e){if(Xi.has(e))return Xi.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 Xi.set(e,n),n}function cg(e,t){return ag(t).test(String(e).replace(/^\.\//,""))}function lg(e,t){return t?.length?e.filter(r=>t.some(n=>cg(r,n))).sort():[]}function ou({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=ig(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=lg(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 iu(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 ug(e,t=Dm){let r=String(e||"").replace(/\r\n/g,`
|
|
53
55
|
`).split(`
|
|
54
|
-
`);for(;r.length&&r[r.length-1]==="";)r.pop();for(;r.length&&r[0]==="";)r.shift();return r.slice(-t)}function
|
|
55
|
-
${n.error.message}`:""}`,i=n.error&&n.status===null?127:n.status;return{name:e.name,command:e.command,exitCode:i,durationMs:s,tail:
|
|
56
|
-
`),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,
|
|
57
|
-
`)}async function
|
|
56
|
+
`);for(;r.length&&r[r.length-1]==="";)r.pop();for(;r.length&&r[0]==="";)r.shift();return r.slice(-t)}function au(e,t){let r=Date.now(),n=tu("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:ug(o)}}function Fr(e,t){let r=tu("git",t,{cwd:e,env:{...process.env,...vt},encoding:"utf-8",stdio:["ignore","pipe","ignore"],maxBuffer:67108864});return{status:r.error?-1:r.status,stdout:r.stdout||""}}async function dg(e){try{let t=await to(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 cu(e,t){let r=Fr(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=Fr(e,["rev-parse","--verify","--quiet","HEAD"]).status===0?"HEAD":Hm;else if(Fr(e,["rev-parse","--verify","--quiet",`${n}^{commit}`]).status!==0)return{skipped:`unknown --base ref "${t}"`};let s=Fr(e,["diff","--name-only","-z",n,"--"]);if(s.status!==0)return{skipped:`git diff against ${n} failed`};let o=Fr(e,["diff","--numstat","-z",n,"--"]),i=Fr(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 dg(Vr(e,d));return{changed:[...a].sort(),lines:l}}W();import{readFile as fu,readdir as gg}from"node:fs/promises";import{join as cr}from"node:path";import{homedir as yg}from"node:os";Re();import{readFileSync as pg}from"node:fs";import{join as fg}from"node:path";var hg=fg(I,"legacy","claude-1x-digests.json"),no=null,Zi=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};function Dr(){if(no)return no;let e={};try{e=JSON.parse(pg(hg,"utf-8"))}catch{e={}}return no={files:Zi(e.files),playbook:new Set(Array.isArray(e.playbook)?e.playbook.filter(t=>typeof t=="string"):[]),pluginFiles:Zi(e.pluginFiles),pluginDescriptions:new Set(Array.isArray(e.pluginManifestDescriptions)?e.pluginManifestDescriptions.filter(t=>typeof t=="string"):[]),vendoredFiles:Zi(e.vendoredFiles)},no}function mg(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 lu(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,mg(o,a)]))if(c.has(Qe(Buffer.from(l,"utf-8"))))return!0}}return!1}function so(e,t,{namePrefix:r}={}){let n=/^(agents|commands)\/([^/]+\.md)$/.exec(String(t||""));return n?lu(Dr().files,e,n[1],n[2],r):!1}function uu(e){return Dr().playbook.has(Qe(e))}function du(e){if(!e||e.includes("/")||e.includes(".."))return null;let t=`skills/${e}/`,r={};for(let[n,s]of Dr().files)n.startsWith(t)&&(r[n.slice(t.length)]=[...s]);return Object.keys(r).length?r:null}function oo(e,t,r){let{files:n}=Dr();return n.has(`${e}/${t}`)?!0:!!r&&t.startsWith(r)&&n.has(`${e}/${t.slice(r.length)}`)}function pu(e,t,{pluginName:r="vesper"}={}){let n=String(t||""),{pluginFiles:s,pluginDescriptions:o}=Dr();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 lu(s,e,i[1],i[2]);let a=s.get(n);return!!a&&a.has(Qe(e))}function ea(e,t){let r=Dr().vendoredFiles.get(String(t||""));return!!r&&r.has(Qe(e))}var ta="vesper",wg=Object.freeze(["gitlab-ci-skill","github-actions-to-gitlab-ci"]);function hu(e=ta,t=yg()){return cr(t,".claude","skills",e)}async function vg(e){for(let t of["agents","commands","skills"])if(!await w(cr(e,t)))return!1;for(let t of["agents","commands"]){let r;try{r=await gg(cr(e,t),{withFileTypes:!0})}catch{continue}if(r.some(n=>n.isFile()&&n.name.startsWith("vesper-")))return!0}return!1}function mu({pluginName:e,workspaceRoot:t}){return async(r,n)=>{if(pu(n,r,{pluginName:e}))return!0;let s=/^skills\/([^/]+)\/(.+)$/.exec(r);if(!s||!wg.includes(s[1]))return!1;let o=rr(s[1]),i=[...o?[o.dir]:[],...t?[cr(t,".claude","skills",s[1]),cr(t,".vesper","skills",s[1])]:[]];for(let a of i)try{if(ge(n,await fu(cr(a,s[2]))))return!0}catch{}return!1}}async function Mn({pluginName:e=ta,staleDir:t,homeDir:r,workspaceRoot:n}={}){if(typeof e!="string"||e===""||/[\\/]|\.\./.test(e))return{reason:"not-ours",proven:[],kept:[]};let s=t??hu(e,r);if(!await w(s))return{reason:"absent",proven:[],kept:[]};let o="not-ours",i=null;try{let c=JSON.parse(await fu(cr(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 vg(s)&&(o="manifest-less-ours"),o==="not-ours")return{reason:o,path:s,proven:[],kept:[]};let a=await xt(s,{sourceMatch:mu({pluginName:e,workspaceRoot:n}),anchor:null});return{reason:o,path:s,proven:a.proven,kept:a.kept,version:i}}async function gu({pluginName:e=ta,staleDir:t,homeDir:r,workspaceRoot:n,backup:s}={}){let o=await Mn({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 Tn(o.path,{sourceMatch:mu({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}}U();he();var Te=P(I,"claude"),Vt=P(I,"claude-committed"),we="vesper-marketplace",Sg=["agents","skills"],Eg=["agents","commands","skills"],bg="vesper";function lr(e){return P(e,".claude")}function Su(e){return P(e,".claude","vesper")}function Eu(e){return P(e,"CLAUDE.md")}var bu=".mcp.json";function Oe(e){return P(e,bu)}function Pe(e){return P(e,".claude","settings.json")}function xg(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 io({workspaceRoot:e,namePrefix:t,version:r}={}){let n=lr(e),s=[],o=`.claude/agents/${H}.md`,i=P(Vt,"agents",`${H}.md`);await j(P(n,"agents"),{recursive:!0}),await $(P(e,o),await re(i,"utf-8"),"utf-8"),s.push(D({path:o,host:"claude",category:"catalog-agent",hash:await ye(P(e,o))}));for(let d of jt){let p=P(Vt,"skills",d),h=`.claude/skills/${d}`;await Cn(p,P(e,h),{recursive:!0}),s.push(D({path:h,host:"claude",category:"catalog-skill",hash:null}))}let{pruned:a,kept:c}=await jl(e,s,{categories:["catalog-agent","catalog-command","catalog-skill"]});if(r!==void 0){let d=await _(e);d.schemaVersion=de,d.frameworkVersion=r,await O(e,d)}let l={agents:1,skills:jt.length,commands:0};return{pluginDir:n,counts:l,pruned:a.map(d=>d.replace(/^\.claude\//,"")),keptEdited:c.map(d=>d.replace(/^\.claude\//,""))}}async function Fn(e,t){let r=s=>e==="skills"?P(s,"skills",t):P(s,e,`${t}.md`);if(await w(r(Te)))return{path:r(Te),pack:"core"};let n=[];try{n=(await ku(P(Te,"packs"),{withFileTypes:!0})).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>s.name).sort()}catch{n=[]}for(let s of n){let o=P(Te,"packs",s);if(await w(r(o)))return{path:r(o),pack:s}}return null}async function ao(e,t,{workspaceRoot:r,namePrefix:n=""}={}){let s=lr(r),o=P(s,e);if(await j(o,{recursive:!0}),e==="skills"){let g=await Fn("skills",t);if(!g)throw new Error(`Skill "${t}" not found in assets/claude/skills/ or any assets/claude/packs/<pack>/skills/`);let f=g.path,m=P(o,t),y=await xt(m,{sourceDir:f});if(y.status!=="absent"&&!(y.status==="classified"&&y.kept.length===0))throw yu(`.claude/skills/${t}`,`vesper:${t}`);return await Cn(f,m,{recursive:!0}),await J(r,[D({path:`.claude/skills/${t}`,host:"claude",category:"added-asset",hash:null})]),{installedAs:t}}let i=".md",a=await Fn(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 re(c,"utf-8"),d=xg(l,n),p=n&&!t.startsWith(n)?`${n}${t}${i}`:`${t}${i}`,h=null;try{h=await re(P(o,p))}catch{h=null}if(h!==null&&!ge(h,d))throw yu(`.claude/${e}/${p}`,`vesper:${t}`);return await $(P(o,p),d,"utf-8"),await J(r,[D({path:`.claude/${e}/${p}`,host:"claude",category:"added-asset",hash:await ye(P(o,p))})]),{installedAs:kg(p,i)}}function yu(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 xu(e){let t=lr(e),r={};for(let n of Sg){let s=P(t,n);if(!await w(s)){r[n]=[];continue}let o=await ku(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 co({pluginName:e=bg,staleDir:t,dryRun:r=!1,workspaceRoot:n,backup:s}={}){return r?{removed:!1,...await Mn({pluginName:e,staleDir:t,workspaceRoot:n})}:gu({pluginName:e,staleDir:t,workspaceRoot:n,backup:s})}function _u(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}var sa="<!-- vesper:start -->",oa="<!-- vesper:end -->";function _g(){return[sa,"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.",oa].join(`
|
|
59
|
+
`)}async function Ag(e){let t=Eu(e),r=_g(),n=new RegExp(`${sa}[\\s\\S]*?${oa}`);if(!await w(t))return await j(Dn(t),{recursive:!0}),await $(t,`${r}
|
|
58
60
|
`,"utf-8"),{created:!0,updated:!1};let s=await re(t,"utf-8");if(n.test(s)){let i=s.replace(n,r);return i!==s?(await $(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=`${r}
|
|
59
61
|
|
|
60
|
-
${s}`;return await $(t,o,"utf-8"),{created:!1,updated:!0}}function
|
|
61
|
-
`);return t}async function
|
|
62
|
-
`),r=/^---\n[\s\S]*?\n---\n/.exec(t);return(r?t.slice(r[0].length):t).trim()}async function Tg(e){let t={removed:[],kept:[]};for(let r of["orchestration","context"]){let n=`.claude/vesper/${r}.md`,s;try{s=await re(P(e,n),"utf-8")}catch{continue}let o=null;try{o=await re(P(e,".vesper","instructions",`vesper-${r}.instructions.md`),"utf-8")}catch{o=null}let i=fu(s);o===null||i!==""&&fu(o).includes(i)?(await Dr(P(e,n),{force:!0}),t.removed.push(n)):t.kept.push(n)}return t}async function Gr(e,{purgeProjectAuthored:t=!1}={}){let r=mu(e),n=".claude/vesper/orchestrator.md";await ue(P(e,n),{path:n,category:"playbook"});let s=[];t&&(s.push(...(await Tg(e)).kept),s.push(...(await Cg(e)).kept.map(m=>`.claude/vesper/context/${m}`)));try{await ta(r)}catch{}let o=await _(e),i=new Set,a=Array.isArray(o.manifest)?o.manifest:[],c=new Set(a.filter(m=>m&&m.host!=="claude"&&m.category==="per-project-authored").map(m=>m.path));for(let m of a)qs(m,{host:"claude",purgeProjectAuthored:t})&&(m.category==="per-project-authored"&&c.has(m.path)||i.add(m.path));for(let m of Array.isArray(o.claude?.catalogManifest)?o.claude.catalogManifest:[]){if(typeof m!="string"||m.includes(".."))continue;let[y,...k]=m.split("/");!hg.includes(y)||k.length===0||i.add(`.claude/${m}`)}for(let m of i){let y=(o.manifest||[]).find(k=>k?.path===m)||{path:m,category:m.startsWith(".claude/skills/")?"catalog-skill":"catalog-agent"};await ue(P(e,m),y,{purgeProjectAuthored:t})}let{kept:l}=await Qs(e,"claude"),d=gu(e);if(await w(d)){let m=await re(d,"utf-8"),y=oa(vg(m));y.trim()?await $(d,y,"utf-8"):await Dr(d,{force:!0})}await Dt(e,!1);let p=Array.isArray(o.mcp?.servers)?o.mcp.servers:[];if(p.length&&await w(Te(e)))try{let m=JSON.parse(await re(Te(e),"utf-8")),y=!1;for(let k of p)m?.mcpServers&&typeof m.mcpServers=="object"&&k in m.mcpServers&&(delete m.mcpServers[k],y=!0);y&&await lo(e,m)}catch{}try{let m=JSON.parse(await re(Te(e),"utf-8"));m&&typeof m=="object"&&Object.keys(m).every(k=>k==="mcpServers")&&(!m.mcpServers||Object.keys(m.mcpServers).length===0)&&await Dr(Te(e),{force:!0})}catch{}let h=Oe(e);if(await w(h))try{let m=JSON.parse(await re(h,"utf-8")),y=ho(m,{markers:[Fn.legacy,Fn.bootstrap]}),k=Tu(m),v=pu(m),S=bg(m);(y||k||v||S)&&(Object.keys(m).length===0?await Dr(h,{force:!0}):await $(h,JSON.stringify(m,null," "),"utf-8"))}catch{}let g=po(e);if(await w(g))try{let m=JSON.parse(await re(g,"utf-8"));pu(m)&&(Object.keys(m).length===0?await Dr(g,{force:!0}):await $(g,JSON.stringify(m,null," "),"utf-8"))}catch{}let f=await _(e);return delete f.claude,f.host==="claude"&&delete f.host,delete f.namePrefix,delete f.pluginPath,Array.isArray(f.manifest)&&(f.manifest=f.manifest.filter(m=>!(m&&m.host==="claude")||!t&&$e.has(m.category))),await O(e,f),{kept:l,knowledgeKept:s}}W();import{readFile as Un,rm as fd,rmdir as Wy}from"node:fs/promises";import{join as Ne}from"node:path";U();he();import{readFile as Hn,readdir as iy}from"node:fs/promises";import{join as ve,isAbsolute as ay,relative as cy}from"node:path";U();import{readdir as Og,readFile as Pu,rename as Pg,access as Ig,constants as jg}from"node:fs/promises";import{join as Gt}from"node:path";import{execFile as Rg}from"node:child_process";var ia=".vesper/.migration-backup";async function Iu(e){try{return await Ig(e,jg.F_OK),!0}catch{return!1}}function Lg(e){return new Promise(t=>{try{Rg("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 ju(e){try{return(await Og(Gt(e,ia),{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name).sort()}catch{return[]}}async function mo(e,{head:t}={}){let r=await ju(e);if(r.length===0)return!1;let n=Gt(e,ia),s=t!==void 0?t:await Lg(e),o=r.at(-1);for(let i of[...r].reverse()){let a;try{a=await Pu(Gt(n,i,"rollback.json"),"utf-8")}catch{continue}let c;try{c=JSON.parse(a)}catch{if(i!==o)continue;return!await Iu(Gt(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 aa(e){let t=await ju(e);if(!t.length)return null;let r=Gt(e,ia,t.at(-1)),n;try{n=await Pu(Gt(r,"rollback.json"),"utf-8")}catch{return null}try{return JSON.parse(n),null}catch{}return await Iu(Gt(r,"created.txt"))?null:Gt(r,"rollback.json")}async function Ru(e,{now:t=new Date}={}){let r=await aa(e);if(!r)return null;let n=`${r}.torn-${t.toISOString().replace(/[:.]/g,"-")}`;return await Pg(r,n),{from:r,to:n}}W();U();import{readFile as Vu,rm as Wg,rmdir as Bg}from"node:fs/promises";import{join as pa}from"node:path";he();U();he();je();import{readFile as la,readdir as Mu}from"node:fs/promises";import{readdirSync as Ng}from"node:fs";import{join as me,basename as Mg}from"node:path";import{homedir as Fg}from"node:os";var Vg=Object.freeze(["agents","commands","skills"]),Dg=Object.freeze(["claude","paths","catalogVersion","targets"]),ur=".vesper/.migration-backup",Be="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 wo(e){let t=[...new Set([await at(e),me(e,".vesperrc"),me(e,".vesper","tracking.json")])],r=null,n=null;for(let c of t){let l;try{l=await la(c,"utf-8")}catch(d){if(d&&d.code==="ENOENT")continue;return go({config:"corrupt",path:c})}try{r=JSON.parse(l),n=c}catch{return go({config:"corrupt",path:c})}break}if(!r||typeof r!="object")return go({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("/");!Vg.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 go({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"?Dg.filter(c=>c in r):[],recordedHost:s==="v2"?fn({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 go(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 we(e,{checkout:t}={}){let r=await wo(e),n;try{n=await K(e)}catch{n=void 0}let s=await Rc(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(`${Mg(r.path||".vesperrc")} (1.x record)`);let a=!1,c=!1,l=!1,d=null;try{let h=t??await z(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 Gg="<!-- vesper(?::[a-z0-9-]+)?:start -->[\\s\\S]*?<!-- vesper(?::[a-z0-9-]+)?:end -->",Lu=e=>new RegExp(Gg).test(e),Hg=Object.freeze([rn,nn,sn]);async function ca(e){try{return await Mu(e,{withFileTypes:!0})}catch{return[]}}async function yo(e){try{return await la(e)}catch{return null}}function Nu(e){let t=new Set;for(let r of[me(I,"claude",e),me(I,"claude-committed",e)])try{for(let n of Ng(r))t.add(n.replace(/\.md$/,""))}catch{}return t}function Ug(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 vo({homeDir:e=Fg(),pluginName:t="vesper",workspaceRoot:r}={}){let n=[],s=(p,h,g,f,m={})=>n.push({path:me(e,p),rel:p,kind:h,tier:g,marker:f,...m}),o=Nu("agents"),i=Nu("skills"),a=`.claude/skills/${t}`,c=await Nn({pluginName:t,staleDir:me(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",g=>g.endsWith(".md")],[".copilot/instructions",()=>!0]])for(let g of await ca(me(e,p))){if(!g.isFile()||!h(g.name))continue;let f=`${p}/${g.name}`,m=(await yo(me(e,f)))?.toString("utf-8")??"";Lu(m)?s(f,"file",3,"a Vesper guard block"):g.name.startsWith("vesper-")&&s(f,"file",3,"a vesper- file name")}for(let p of[".claude/agents",".copilot/agents"])for(let h of await ca(me(e,p))){if(!h.isFile()||!h.name.endsWith(".md"))continue;let g=`${p}/${h.name}`,f=await yo(me(e,g));if(!f)continue;let m=h.name.replace(/(\.agent)?\.md$/,"");(o.has(Ug(f.toString("utf-8"))||m)||o.has(m)||h.name.startsWith("vesper-"))&&s(g,"file",3,"a Vesper agent name")}for(let p of[".claude/skills",".copilot/skills"])for(let h of await ca(me(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 yo(me(e,".claude","CLAUDE.md")))?.toString("utf-8");l&&Lu(l)&&s(".claude/CLAUDE.md","region",3,"a Vesper guard block");let d=await yo(me(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=[],g=p.hooks&&typeof p.hooks=="object"?p.hooks:{};for(let[f,m]of Object.entries(g))Array.isArray(m)&&m.some(y=>Array.isArray(y?.hooks)&&y.hooks.some(k=>typeof k?.command=="string"&&Hg.includes(k.command.trim())))&&h.push(`hooks.${f}`);p.agent===H&&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 Fu(e){let t=me(e,ur),r=[];try{r=(await Mu(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 la(me(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:me(t,s)})}return n}rt();var ko="VESPER_HOST_MISMATCH",fa="VESPER_PLUGIN_ABSENT",Z="vespercli init",Ke=e=>`vespercli init --host ${e}`;function Kg(e,t){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.`:`This workspace is provisioned for "${e}" but is running under "${t}". Fix: ${Ke(t)}`}var Dn=".vesper/instructions/vesper-host-guard.instructions.md",ua="guard-rule",zg=["---","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 \`${ko}\`: 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(`
|
|
63
|
-
`);function ha(e){return e==="claude"?"copilot":"claude"}async function Du(e){let t=Oe(e),r={},n=!0;try{r=JSON.parse(await Vu(t,"utf-8")),n=!1}catch{r={}}(!r||typeof r!="object"||Array.isArray(r))&&(r={});let s=sa(r);return(s||n)&&(await j(pa(e,".claude"),{recursive:!0}),await $(t,JSON.stringify(r,null," "),"utf-8")),{changed:s,created:n}}function Jg(){return{label:gn.taskLabel,command:_r("copilot"),presentation:{reveal:"always",panel:"shared"}}}async function Yg(e,t,{unattended:r=!1}={}){return Ur(t),t==="claude"?Du(e):wn(e,{createOnly:r})}async function Gu(e,t){if(Ur(t),t==="claude"){let n=await Du(e);return await J(e,[Q({path:".claude/settings.json",host:"shared",category:"guard-trigger",owns:{keys:["hooks.SessionStart"]}})]),n}let r=await xs(e,Jg());return await J(e,[Q({path:".vscode/tasks.json",host:"shared",category:"guard-trigger",owns:{keys:[gn.taskLabel]}})]),r}async function So(e,t,{unattended:r=!1}={}){return Ur(t),await Yg(e,t,{unattended:r}),await Gu(e,ha(t)),{legacyGuardRule:await dr(e)}}async function da(e,t){let r=await _(e),n=Y(r),s=n.filter(o=>!t(o));return s.length===n.length?!1:(r.manifest=s,await O(e,r),!0)}async function Gn(e,t){Ur(t);let r=Y(await _(e));if(t==="claude"){let i=Oe(e);if(await w(i))try{let a=JSON.parse(await Vu(i,"utf-8"));ho(a,{markers:[Fn.guard]})&&(Object.keys(a).length===0?await Wg(i,{force:!0}):await $(i,JSON.stringify(a,null," "),"utf-8"))}catch{}await da(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 yn(e,gn.taskLabel,{removeFileIfEmpty:n&&!s});if(o)try{await Bg(pa(e,".vscode"))}catch{}await da(e,i=>i.path===".vscode/tasks.json"&&i.category==="guard-trigger")}async function dr(e){let n=Y(await _(e)).find(o=>o.path===Dn&&o.category===ua)??{path:Dn,category:ua,hash:null},s=await ue(pa(e,Dn),n,{expected:[zg]});return await da(e,o=>o.path===Dn&&o.category===ua),s==="partial"?"kept":s}function Hr(){return`Kept your edited ${Dn} \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 qg(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 Xg(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 Eo(e,{runningHost:t}={}){let r=t!==void 0,n={identity:r,network:r,runningHost:t,journal:null,fix:null,note:null,message:null},s=await _t(e),o=await z(e,{requireCommitted:!r&&!s});if(s)return r&&t!==s.to?{...n,action:"refuse",reason:"switch-in-progress",host:s.to,checkout:o,journal:s,fix:Z,message:`An interrupted host switch (${s.from} \u2192 ${s.to}) is pending in this workspace. Fix: ${Z}`}:{...n,action:"none",reason:"switch-in-progress",host:null,checkout:o,journal:s,note:`An interrupted host switch (${s.from} \u2192 ${s.to}) is pending \u2014 run \`vespercli init\` to finish it.`};let i=async()=>{let c=null;try{c=await we(e,{checkout:o})}catch{c=null}return c?.unmigrated?{...n,action:"none",reason:"legacy-unmigrated",host:null,checkout:o,note:`Bootstrap wrote nothing. ${Be}`}:await mo(e)?{...n,action:"none",reason:"migration-in-progress",host:null,checkout:o,note:"A Vesper 1.x migration was interrupted in this workspace \u2014 run `vespercli init` to finish it. Nothing was provisioned."}:null},a=o.source==="local";if(a){let c=await i();if(c)return c}if(r&&o.host&&o.host!==t)return{...n,action:"refuse",reason:"host-mismatch",host:o.host,checkout:o,fix:Ke(t),message:Kg(o.host,t)};if(!a){let c=await i();if(c)return c}if(o.gitError)return{...n,action:"none",reason:o.gitError==="dubious-ownership"?"not-vesperized":"git-unreadable",host:null,checkout:o,note:Xg(o,e)};if(o.ambiguous)return{...n,action:"none",reason:"host-ambiguous",host:null,checkout:o,note:r?He:null};if(!o.host){let c=!r&&o.candidate?"host-unconfirmed":"not-vesperized",l=r?await nr(e):null,d=l?`This worktree's local record names ${l}, but the checked-out commit carries no Vesper provisioning \u2014 nothing was provisioned. \`vespercli init --host ${t}\` provisions it.`:qg(o);return{...n,action:"none",reason:c,host:null,checkout:o,note:d}}return{...n,action:"bootstrap",reason:"healthy",host:o.host,checkout:o}}async function Hu(e,t,{checkout:r}={}){if(Ur(t),r?.source==="local"){for(let n of[Qg(t),".vesperrc"])if(!await Zg(e,n))return{healed:!1,reason:"local-tier"}}return await Gu(e,t),{healed:!0}}function Qg(e){return Ur(e),e==="claude"?".claude/settings.json":".vscode/tasks.json"}async function Zg(e,t){return await V(["check-ignore","-q","--",t],{cwd:e,timeout:5e3})!==null}function Ur(e){if(!G.includes(e))throw new Error(`host must be one of: ${G.join(", ")} (received "${e}")`)}he();je();je();U();import{readFileSync as ey}from"node:fs";import{readFile as Uu}from"node:fs/promises";import{join as ma,dirname as ty}from"node:path";he();W();var Wr=Object.freeze({claude:".claude/rules/vesper-orchestration.md",copilot:".vesper/instructions/vesper-orchestration.instructions.md"}),Wu="vespercli packs sync";function Bu(e){return`${Ue(e)}@${We}`}function ry(e){return tn(e)!==null}function bo(e=I){let t=null;try{t=JSON.parse(ey(ma(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 pt(e=I){return[...bo(e).packs].sort()}function Ku(e,t=I){let r=bo(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 ga(e){try{let t=JSON.parse(await Uu(Oe(e),"utf-8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}async function pr(e,t){let r=new Set(pt()),n=new Set,s=new Set;if(t==="claude"){let i=(await ga(e))?.enabledPlugins;if(i&&typeof i=="object"&&!Array.isArray(i))for(let[a,c]of Object.entries(i)){let l=tn(a);!l||c!==!0||(r.has(l)?n:s).add(l)}}else if(t==="copilot"){let o=await K(e);for(let i of Os())for(let{path:a,settingKey:c}of Tr(i))if(o[c]?.[a]===!0){n.add(i);break}}return{enabled:[...n].sort(),unknown:[...s].sort()}}async function xo(e,t){return(await pr(e,t)).enabled}var ny=Object.freeze(["permissions.allow","hooks.SessionStart","agent","enabledPlugins"]);async function zu(e,t){let n=(await Ae(e)).find(i=>i&&i.path===Jt&&i.host==="claude"&&i.category==="settings"),o={keys:Array.isArray(n?.owns?.keys)&&n.owns.keys.length?[...n.owns.keys]:[...ny]};t.length&&(o.entries=[...t].sort()),await J(e,[Q({path:Jt,host:"claude",category:"settings",owns:o})])}async function Ju(e){let r=(await Ae(e)).find(n=>n&&n.path===Jt&&n.host==="claude"&&n.category==="settings");return(Array.isArray(r?.owns?.entries)?r.owns.entries:[]).filter(ry).sort()}async function Yu(e,t){if(!await w(ma(e,It)))return;await J(e,[Q({path:It,host:"copilot",category:"settings",owns:{keys:[...Et],entries:[...t]}})]);let r=await _(e);if(Number(r.schemaVersion)===2&&On.some(n=>n in r)){for(let n of On)delete r[n];await O(e,r)}}function qu(e){if(!pt().includes(e))throw new Error(`Unknown pack "${e}". Available packs: ${pt().join(", ")||"none"}.`)}async function fr(e,t,r){qu(r);let n=await sy(e,t,r);if(ir(r)){let s=await Bl(e,t,r);s&&(n.rule=s)}return n}async function sy(e,t,r){if(t==="claude"){let n=Oe(e),s=await ga(e);if(s===null&&await w(n))throw new Error(`${Jt} 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=Bu(r),i=s.enabledPlugins[o]===!0;i||(s.enabledPlugins[o]=!0,await j(ty(n),{recursive:!0}),await $(n,JSON.stringify(s,null," "),"utf-8"));let a=new Set([...await Ju(e),o]);return await zu(e,[...a]),{pack:r,enabled:!i}}if(t==="copilot"){let n=Tr(r),{added:s}=await $r(e,n),o=new Set([...await ut(e),...n.map(i=>i.path)]);return await Yu(e,[...o]),{pack:r,enabled:s.length>0}}throw new Error(`Unknown host "${t}"`)}async function Xu(e,t,r){qu(r);let n=await oy(e,t,r);if(ir(r)){let s=await zi(e,t,r);s&&(n.rule=s)}return n}async function oy(e,t,r){if(t==="claude"){let n=Oe(e),s=await ga(e),o=Bu(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 $(n,JSON.stringify(s,null," "),"utf-8"),i=!0);let a=(await Ju(e)).filter(c=>c!==o);return await zu(e,a),{pack:r,disabled:i}}if(t==="copilot"){let n=Tr(r).map(i=>i.path),{removed:s}=await bi(e,n),o=(await ut(e)).filter(i=>!n.includes(i));return await Yu(e,o),{pack:r,disabled:s.length>0}}throw new Error(`Unknown host "${t}"`)}async function Ht(e,t){let r=Wr[t];if(!r)return null;try{return await Uu(ma(e,r),"utf-8")}catch{return null}}async function Ut(e,t){let r=t||await dt(),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 Dl(e||"")){let c=r.agentPack.get(a);if(c===void 0){o.push(a);continue}c!=="core"&&s(c,"agents",a)}for(let a of Gl(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 Wt(e,t,{dryRun:r=!1}={}){let n=Wr[t],s=await Ht(e,t),o=await Ut(s||""),i=await xo(e,t),a=[],c=[];for(let d of o.packs){if(i.includes(d)){c.push(d);continue}r||await fr(e,t,d),a.push(d)}let l=i.filter(d=>!o.packs.includes(d));return{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 Qu(e){let r=(await dt()).agentPlugin.get(In(e).name);return r?`${r}:${In(e).name}`:null}W();import{readFile as od,readdir as ly}from"node:fs/promises";import{homedir as uy}from"node:os";var C=Object.freeze({ERROR:"error",WARN:"warn",INFO:"info"}),ke=Object.freeze({OK:0,ERROR:1,HOST_MISMATCH:2}),Zu=new Set(Object.values(C)),id="host-mismatch",dy="check-failed",py=new Set(["playbook","pointer","mcp-config","settings"]);var ed=zs,fy=e=>`vespercli reset --host ${e}`;function L({code:e,severity:t,message:r,fix:n,category:s,path:o}){if(!Zu.has(t))throw new Error(`makeFinding: unknown severity "${t}" for code "${e}". Valid severities: ${[...Zu].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 ya(e,t){if(!t)return t;let r=cy(e,t);return r.startsWith("..")?t:r}async function hy(e){let r=[await at(e),ve(e,".vesperrc"),ve(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 Hn(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 td(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 Hn(e,"utf-8"));return{path:e,exists:!0,servers:Object.keys(n[t]||{})}}catch{return{path:e,exists:!0,servers:[]}}}async function my(e,t,{visible:r}={}){let n={};for(let s of Object.keys(t)){n[s]=[];for(let o of t[s])try{await Pt(e,o,{visible:r})&&n[s].push(o)}catch(i){if(!gy(i))throw i}}return n}function gy(e){return!!e&&typeof e.code=="string"&&["ENOENT","EACCES","EISDIR","ENOTDIR","EPERM","ELOOP","ENAMETOOLONG"].includes(e.code)}function yy(e){return ii(e)}async function wy(e,t,{homeDir:r=uy(),checkout:n=null}={}){let s=await hy(e);if(s.corrupt)return{workspaceRoot:e,runningHost:t,corrupt:!0,corruptPath:s.corruptPath};let o=s.tracking||null,i=n;i||(i=await z(e,{withCommitted:!0}));let a=i.host,c=null;try{c=await _t(e)}catch{c=null}let l=null,d=!1;try{l=await aa(e)}catch{l=null}try{d=await mo(e)}catch{d=!1}let p=await jl(e),h=[...p.missing,...p.modified,...p.clean],g=await Ys(e),f=ns(),m=[];try{m=await ce(e)}catch{m=[]}let y=a?[a]:m,k={claude:await td(Te(e),"mcpServers"),copilot:await td(Ve(e),"servers")},v=Rt(),S=i.ambiguous?"both":i.host,A=await my(e,v,{visible:i.visible}),R={};for(let[Ie,Tt]of Object.entries(A))R[Ie]=Tt.some(yy);let E={};for(let Ie of G)E[Ie]=await on(e,Ie);let b=null;try{b=await we(e,{checkout:i})}catch{b=null}let M=[];try{M=(await vo({homeDir:r,workspaceRoot:e})).filter(Ie=>Ie.kind==="plugin")}catch{M=[]}let X=[];try{X=await Fu(e)}catch{X=[]}let Pe=await nr(e),Yr=!!Pe&&Pe!==a;{let Ie=i.source==="local"?null:a,Tt=ze=>{if(!ze)return!1;if(G.includes(ze.host))return ze.host===Ie;let yr=vy(ze);return!yr||yr===Ie};p={...p,missing:p.missing.filter(Tt),modified:p.modified.filter(Tt),clean:p.clean.filter(Tt),userLevelViolations:p.userLevelViolations}}let ft=[...p.missing,...p.modified,...p.clean],Ct=!!a||h.length>0;return{workspaceRoot:e,runningHost:t,absent:!!s.absent,tracking:o,host:a,checkout:i,ledgerHostForReporting:Pe,verify:p,manifestEntries:ft,manifestAll:h,recordStale:Yr,journal:c,migrationTorn:l,migrationActive:d,frameworkVersion:g,packageVersion:f,installedTargets:y,mcpConfigs:k,detectedHost:S,fingerprintMatches:A,fingerprintSpecific:R,residue:E,legacy:b,userResidue:M,keptItems:X,initialised:Ct}}function vy(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 ad(e,t){return e.checkout?.host===t||!!e.fingerprintSpecific?.[t]}function ky(e){let t=[],{verify:r}=e;for(let n of r.userLevelViolations)t.push(L({code:"user-level-violation",severity:C.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)(At[n.category]||{}).doctor==="server-drift"?t.push(L({code:"mcp-core-missing",severity:C.ERROR,category:n.category,path:n.path,message:`A required Vesper-core MCP server is missing from "${n.path}".`,fix:Z})):t.push(L({code:"file-edited",severity:C.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=py.has(n.category);t.push(L({code:"owned-file-missing",severity:s?C.ERROR:C.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 _o(e,t={}){let r=new Set,n=t.installedTargets;if(!Array.isArray(n))try{let a=await Rr(e);n=a?[a]:await ce(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 Sy(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 De(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 _(e);s=Array.isArray(a.mcp?.servers)?a.mcp.servers:[]}catch{s=[]}let o=new Set(s);return{drifted:[...r].filter(a=>!xe.includes(a)&&!o.has(a))}}async function Sy(e){try{return JSON.parse(await Hn(Te(e),"utf-8"))}catch{return{mcpServers:{}}}}async function Ey(e){let{drifted:t}=await _o(e.workspaceRoot,{tracking:e.tracking,mcpConfigs:e.mcpConfigs,installedTargets:e.installedTargets});return t.map(r=>L({code:"mcp-drift",severity:C.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 by(e){return!e.initialised||!e.host?[]:(e.manifestAll??e.manifestEntries).some(r=>r.category==="mcp-config")?[]:xy(e)?[L({code:"mcp-config-unrecorded",severity:C.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 xy(e){return!!e.mcpConfigs?.[e.host]?.exists}function _y(e){if(e.absent||!e.tracking)return[];let t=e.tracking;return(t.host===void 0||G.includes(t.host))&&Array.isArray(t.manifest)&&t.schemaVersion===de?[]:[L({code:"tracking-shape-invalid",severity:C.WARN,path:".vesperrc",message:".vesperrc parses but its shape is invalid (host/manifest/schemaVersion) \u2014 `vespercli init` repairs it.",fix:Z})]}async function Ay(e){let t=[];if(e.detectedHost==="both"){let r=G.every(n=>ad(e,n));t.push(L({code:"host-ambiguous",severity:r?C.ERROR:C.WARN,message:r?ed:`${ed} (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 $y(e,r)&&t.push(L({code:"host-residue",severity:C.WARN,message:`This workspace is host "${e.host}" but still carries "${r}" artifacts (a leftover from a host switch).`,fix:fy(r)}))}return t}async function $y(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||$e.has(a.category)||typeof a.path!="string"||a.path.includes("..")||ay(a.path)||await w(ve(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(()=>(rt(),Zo)),{READ_ONLY_GIT_ENV:o}=await Promise.resolve().then(()=>(ot(),di)),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 Cy(e){let t=[],r=e.checkout||{},n=e.ledgerHostForReporting??null;r.gitError==="dubious-ownership"?t.push(L({code:"git-dubious-ownership",severity:C.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(L({code:"git-unreadable",severity:C.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(L({code:"host-switch-pending",severity:C.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(L({code:"host-record-stale",severity:C.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(L({code:"host-local-only",severity:C.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(L({code:"host-local-unconfirmed",severity:C.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 Ty(e){let t=[];for(let r of G){let n=e.residue?.[r]||[];n.length&&((e.fingerprintMatches?.[r]||[]).length>0||e.host!==r&&t.push(L({code:"host-leftover-files",severity:C.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 rd(e){let t=G.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 Oy(e){let t=[],r=e.legacy;r?.unmigrated?t.push(L({code:"legacy-workspace",severity:C.ERROR,message:`${Be} Evidence: ${r.evidence.join(", ")||"1.x record"}.`,fix:rd(r)})):(r?.advisory||r?.residue)&&t.push(L({code:"legacy-residue",severity:C.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):rd(r)})),r&&!r.unmigrated&&!r.advisory&&r.leftovers.length&&t.push(L({code:"legacy-leftover-files",severity:C.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(L({code:"user-level-residue",severity:C.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(L({code:"migration-record-unreadable",severity:C.WARN,path:ya(e.workspaceRoot,e.migrationTorn),message:`The newest migration record (${ya(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(L({code:"migration-in-progress",severity:C.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 Py(e){if(e.host!=="claude"||e.legacy?.needsMigration)return[];let t=await dt(),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 ly(ve(e.workspaceRoot,".claude","agents"))){let i=`.claude/agents/${o}`;if(!o.endsWith(".md")||r.has(i)||!no("agents",o,""))continue;let a=null;try{a=await od(ve(e.workspaceRoot,i))}catch{a=null}a&&!ro(a,`agents/${o}`)&&n.add(i)}}catch{}let s=[];for(let o of[...n].sort()){if(r.has(o)||!await w(ve(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(ve(e.workspaceRoot,o,"SKILL.md")))continue;let l=a==="agents"?ve(I,"claude","agents",`${c}.md`):ve(I,"claude","skills",c);s.push(L({code:"kept-shadows-plugin",severity:C.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"} "${ve(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 Iy(e){if(e.host!=="claude")return[];let t;try{t=await od(ve(e.workspaceRoot,".claude","rules","vesper-orchestration.md"),"utf-8")}catch{return[]}let r=Fl(t,(await dt()).agents);return r.length?[L({code:"roster-unqualified-agents",severity:C.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 jy(e){if(!e.host)return[];let t=await Ht(e.workspaceRoot,e.host);if(t===null)return[];let r=await Ut(t),{enabled:n}=await pr(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(L({code:"pack-not-enabled",severity:C.WARN,path:Wr[e.host],message:`The Team Roster names ${i.length} asset(s) of the "${o}" pack (${Ue(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:Wu}))}for(let o of n)r.packs.includes(o)||ir(o)||s.push(L({code:"pack-unused",severity:C.INFO,path:e.host==="claude"?".claude/settings.json":".vscode/settings.json",message:`The "${o}" pack (${Ue(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 Ry(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(L({code:"host-unresolved",severity:C.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=ad(e,r);t.push(L({code:id,severity:n?C.ERROR:C.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}function Ly(e){if(!e.initialised)return[];let t=e.packageVersion;if(!t)return[];let r=e.frameworkVersion;return r?r!==t?[L({code:"framework-stale",severity:C.WARN,message:`Workspace provisioned with Vesper ${r}, running ${t}.`,fix:Z})]:[]:[L({code:"ledger-unstamped",severity:C.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 Ny(e){return e.initialised?await w(ve(e.workspaceRoot,se))?[]:e.manifestAll?.some(t=>t?.path===se)?[]:[L({code:"gates-missing",severity:C.INFO,path:se,message:"No gate policy (`.vesper/gates.json`) \u2014 `vespercli gate` exits 2 here until `init` seeds one.",fix:Z})]:[]}async function My(e){if(e.host!=="claude")return[];let t=ve(e.workspaceRoot,".claude","agents"),r=[];try{r=(await iy(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 Hn(ve(t,s),"utf-8"),a=Fy(i);(!a||!nd(a.name)||!nd(a.description))&&n.push(L({code:"agent-frontmatter-incomplete",severity:C.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 nd(e){return typeof e=="string"&&e.trim().length>0}function Fy(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 Vy(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(()=>(U(),Ai)),{runGit:l}=await Promise.resolve().then(()=>(rt(),Zo)),{classifyForeignHook:d,HOOK_GUARD_START:p,HOOK_GUARD_END:h}=await Promise.resolve().then(()=>(Qr(),gc));if(await l(["config","--type=bool","--get","vesper.hooks"],{cwd:e.workspaceRoot,timeout:5e3})==="false")return t.push(L({code:"git-hooks-opted-out",severity:C.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 g=await n(e.workspaceRoot);if(!g.dir)return g.reason==="not-a-repo"||t.push(L({code:"git-hooks-not-installable",severity:C.INFO,message:s({...g,hook:"hook"})??`Git hooks not installable (${g.reason}).`,fix:"see the message"})),t;if(!g.default&&await i(await a(g.dir),g,{dir:!0}))return t.push(L({code:"git-hooks-not-installable",severity:C.INFO,message:s({reason:"tracked-by-git",configured:g.dir}),fix:"see the message"})),t;for(let f of o){let m=ve(g.dir,f),y=await c(m),k=null;if(y.path)try{k=await Hn(y.path)}catch{k=null}let v=k?k.toString("latin1"):"",S=v.indexOf(p);if(S!==-1){let R=v.indexOf(h,S),E=v.slice(S,R===-1?void 0:R);E.includes("vesper.hooks")?f==="pre-commit"&&!E.includes("VESPER_NO_SWEEP")&&t.push(L({code:"git-hook-outdated",severity:C.INFO,path:m,message:`Vesper's pre-commit git hook block (${m}) predates VESPER_NO_SWEEP: an agent's commit still sweeps every dirty knowledge path into it.`,fix:"vespercli worktree bootstrap"})):t.push(L({code:"git-hook-outdated",severity:C.INFO,path:m,message:`Vesper's ${f} git hook block (${m}) 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:m};else if(k&&await i(await a(y.path),g))A={reason:"tracked-by-git",configured:y.path};else if(k){let R=d(k);R.ok||(A={reason:R.reason,interpreter:R.interpreter,line:R.line})}if(A){t.push(L({code:"git-hook-not-modifiable",severity:C.INFO,path:m,message:s({...A,hook:f,hooksDir:g.dir})??`Git hook ${f} cannot carry Vesper's block (${A.reason}).`,fix:"see the message"}));continue}t.push(L({code:"git-hook-missing",severity:C.WARN,path:m,message:`Vesper's ${f} git hook block is missing (${m}): ${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 cd=[{id:"manifest",title:"Owned-files manifest",run:e=>ky(e)},{id:"mcp-drift",title:"MCP config drift",run:e=>Ey(e)},{id:"mcp-required",title:"MCP config recorded",run:e=>by(e)},{id:"tracking",title:"Tracking structure",run:e=>_y(e)},{id:"host-conflict",title:"Host conflict",run:e=>Ay(e)},{id:"host-authority",title:"Host authority (checkout vs worktree record)",run:e=>Cy(e)},{id:"host-leftover",title:"Leftover host files",run:e=>Ty(e)},{id:"legacy",title:"Pre-2.0 (1.x) residue",run:e=>Oy(e)},{id:"legacy-kept-shadows",title:"Kept 1.x copies shadowing plugin specialists",run:e=>Py(e)},{id:"roster-namespaces",title:"Team Roster delegation names",run:e=>Iy(e)},{id:"packs",title:"Packs the Team Roster needs",run:e=>jy(e)},{id:"git-hooks",title:"Vesper git hooks",run:e=>Vy(e)},{id:"host-mismatch",title:"Host identity",run:e=>Ry(e),failureSeverity:e=>e.runningHost?C.ERROR:C.WARN},{id:"framework-version",title:"Framework version",run:e=>Ly(e)},{id:"agent-frontmatter",title:"Agent frontmatter",run:e=>My(e)},{id:"gates-config",title:"Gate policy",run:e=>Ny(e)}];function sd(e){let t=e.filter(o=>o.severity===C.ERROR),r=e.filter(o=>o.severity===C.WARN),n=e.filter(o=>o.severity===C.INFO),s=t.some(o=>o.code===id);return{findings:e,errors:t,warnings:r,infos:n,summary:{hasError:t.length>0,hostMismatch:s}}}async function Br(e,{runningHost:t,homeDir:r,checkout:n}={}){let s=await wy(e,t,{homeDir:r,checkout:n});return s.corrupt?sd([L({code:"tracking-unparseable",severity:C.ERROR,path:ya(e,s.corruptPath),message:"Malformed .tracking structure (.vesperrc is present but unparseable) \u2014 framework cannot operate.",fix:Z})]):sd(await Dy(s,cd))}async function Dy(e,t=cd){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):C.WARN;r.push(L({code:dy,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 Ao(e){return e.summary.hostMismatch?ke.HOST_MISMATCH:e.summary.hasError?ke.ERROR:ke.OK}U();function wa(e){return String(e??"").replace(/\r\n?/g,`
|
|
64
|
-
`)}function Ze(e){let t=
|
|
65
|
-
`),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
|
|
66
|
-
`)}function
|
|
67
|
-
`).map(t=>t.trimStart().startsWith("- ")&&t.includes(
|
|
68
|
-
`)}function
|
|
69
|
-
`,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 \`${H}\`, provisioned project-local at \`${wt}\`. 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
|
|
62
|
+
${s}`;return await $(t,o,"utf-8"),{created:!1,updated:!0}}function $g(e){let t=new RegExp(`${sa}[\\s\\S]*?${oa}\\n*`);return e.replace(t,"")}function Cg(e){return P(e,".claude","rules")}async function lo(e){let t=Cg(e);await j(t,{recursive:!0});let r={orchestrator:"refreshed",orchestration:"skipped",context:"skipped"},n=[],s=".claude/rules/vesper-orchestrator.md";await $(P(e,s),await re(P(Te,"vesper-orchestrator.md"),"utf-8"),"utf-8"),n.push(D({path:s,host:"claude",category:"playbook",hash:await ye(P(e,s))}));let o=async(c,l,d)=>{await w(P(e,c))||(await $(P(e,c),await re(P(Te,l),"utf-8"),"utf-8"),r[d]="created"),n.push(D({path:c,host:"claude",category:"per-project-authored",hash:null}))};if(await o(".claude/rules/vesper-orchestration.md","orchestration.md.tpl","orchestration"),r.orchestration==="skipped"){let c=P(e,".claude/rules/vesper-orchestration.md"),l=await re(c,"utf-8"),d=await dt(),p=new Set;for(let g of d.agents)await w(P(e,".claude","agents",`${g}.md`))&&p.add(g);let h=Zs(l,d,{skip:p});h.qualified.length&&(await $(c,h.text,"utf-8"),r.orchestration=`namespaced ${h.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 ro(e);r.gates=i.created?`created (checks: ${i.checks.join(", ")||"none"})`:"skipped",n.push(D({path:se,host:"claude",category:"per-project-authored",hash:null}));let a=await Ag(e);return r.claudeMd=a.created?"created":a.updated?"updated":"unchanged",n.push(Q({path:"CLAUDE.md",host:"claude",category:"pointer",owns:{region:"vesper"}})),await J(e,n),r}async function uo(e){let t=Oe(e);try{let r=await re(t,"utf-8");return JSON.parse(r)}catch(r){return r.code==="ENOENT"?{mcpServers:{}}:{mcpServers:{}}}}async function po(e,t){let r=Oe(e);await j(Dn(r),{recursive:!0}),await $(r,JSON.stringify(t,null," "),"utf-8")}function Tg(e){return{"vesper-indexing":{command:"node",args:[qe()],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:P(e,".vesper","memory.jsonl")}}}}async function Dt(e,t=!0,{record:r=!0}={}){let n=await uo(e);n.mcpServers||(n.mcpServers={});let s=Tg(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 po(e,n),t&&r&&await J(e,[Q({path:bu,host:"claude",category:"mcp-config",owns:{keys:o}})]),{configured:t,mcpPath:Oe(e),servers:t?o:[]}}function ra(e,t){return String(e).replace(/\$\{VESPER_INDEXING_PATH\}/g,qe()).replace(/\$\{workspaceFolder\}/g,t).replace(/\$\{env:([^}]+)\}/g,"$${$1}")}function Og(e,{workspaceRoot:t}){let{type:r,...n}=structuredClone(e);if(typeof n.command=="string"&&(n.command=ra(n.command,t)),Array.isArray(n.args)&&(n.args=n.args.map(s=>ra(s,t))),n.env&&typeof n.env=="object")for(let[s,o]of Object.entries(n.env))n.env[s]=ra(o,t);return n}async function fo(e,t){if(_e.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=Ae[t];if(!r)return{added:!1,serverName:t,error:`Unknown MCP server: ${t}`};let n=await uo(e);if(n.mcpServers||(n.mcpServers={}),n.mcpServers[t])return{added:!1,serverName:t,error:"Already configured"};n.mcpServers[t]=Og(r.config,{workspaceRoot:e}),await po(e,n);let s=await _(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 O(e,s),{added:!0,serverName:t}}async function Au(e,t){if(_e.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 uo(e),n=!1;r.mcpServers&&r.mcpServers[t]&&(delete r.mcpServers[t],await po(e,r),n=!0);let s=await _(e);return s.mcp?.servers&&(s.mcp.servers=s.mcp.servers.filter(o=>o!==t),s.mcp.updatedAt=new Date().toISOString(),await O(e,s)),{removed:n,serverName:t}}async function $u(e){let t=await uo(e),r=Object.keys(t.mcpServers||{}),n=r.filter(s=>!Ae[s]);return{configured:r,custom:n}}var Cu=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"]);function Pg(e){let t=e?.permissions?.allow;if(!Array.isArray(t))return!1;let r=new Set(Cu),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 Tu(e){(!e.permissions||typeof e.permissions!="object")&&(e.permissions={}),Array.isArray(e.permissions.allow)||(e.permissions.allow=[]);let t=0;for(let r of Cu)e.permissions.allow.includes(r)||(e.permissions.allow.push(r),t+=1);return t}async function Ou(e){let t=Pe(e),r={},n=null;try{n=await re(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=Tu(r);return(s>0||n===null)&&(await j(Dn(t),{recursive:!0}),await $(t,JSON.stringify(r,null," "),"utf-8")),{configured:s,settingsPath:t}}async function Pu(e){let t=Pe(e),r={};try{r=JSON.parse(await re(t,"utf-8"))}catch{r={}}let n=Tu(r);(!r.enabledPlugins||typeof r.enabledPlugins!="object")&&(r.enabledPlugins={}),r.enabledPlugins[st]=!0,r.agent=H,jg(r),Lg(r),await j(Dn(t),{recursive:!0}),await $(t,JSON.stringify(r,null," "),"utf-8");let s=(await $e(e)).find(i=>i&&i.path===".claude/settings.json"&&i.host==="claude"&&i.category==="settings"),o={keys:["permissions.allow","hooks.SessionStart","hooks.SubagentStart","agent","enabledPlugins"]};return Array.isArray(s?.owns?.entries)&&s.owns.entries.length&&(o.entries=[...s.owns.entries]),await J(e,[Q({path:".claude/settings.json",host:"claude",category:"settings",owns:o})]),await ho(e),{configured:n,settingsPath:t}}function Hr(e){return P(e,".claude","settings.local.json")}function Ig(){return{source:{source:"directory",path:Te}}}function Iu(e){return!!e&&typeof e=="object"&&!!e.source&&typeof e.source=="object"&&typeof e.source.source=="string"&&e.source.source.length>0}async function ho(e,{record:t=!0}={}){let r=Hr(e),n={};try{n=JSON.parse(await re(r,"utf-8"))||{}}catch{n={}}return(!n.extraKnownMarketplaces||typeof n.extraKnownMarketplaces!="object")&&(n.extraKnownMarketplaces={}),n.extraKnownMarketplaces[we]=Ig(),await j(Dn(r),{recursive:!0}),await $(r,JSON.stringify(n,null," "),"utf-8"),t&&await J(e,[Q({path:".claude/settings.local.json",host:"claude",category:"settings",owns:{keys:["extraKnownMarketplaces"]}})]),{localPath:r}}function wu(e){let t=!1;if(e?.extraKnownMarketplaces&&we in e.extraKnownMarketplaces&&(delete e.extraKnownMarketplaces[we],Object.keys(e.extraKnownMarketplaces).length===0&&delete e.extraKnownMarketplaces,t=!0),e?.enabledPlugins&&st in e.enabledPlugins&&(delete e.enabledPlugins[st],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))nn(r)!==null&&(delete e.enabledPlugins[r],t=!0);Object.keys(e.enabledPlugins).length===0&&delete e.enabledPlugins}return e?.agent===H&&(delete e.agent,t=!0),t}var ju=`command -v vespercli >/dev/null 2>&1 && ${_r("claude")} || true`,Vn=Object.freeze({legacy:Object.freeze([sn,on]),bootstrap:Object.freeze([an]),guard:Object.freeze([ju])});function ia(e,{command:t=ju,markers:r=Object.values(Vn)}={}){let n=JSON.stringify(e.hooks?.SessionStart??null);return mo(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 jg(e){ia(e)}function mo(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 Ru(e,"SessionStart",t)}function Ru(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}var Lu="command -v vespercli >/dev/null 2>&1 && vespercli log delegated --pipeline hook --note hook --stdin || true",Rg=Object.freeze({runLedger:Object.freeze([Lu])});function Lg(e){let t=JSON.stringify(e.hooks?.SubagentStart??null);return Nu(e),e.hooks||(e.hooks={}),Array.isArray(e.hooks.SubagentStart)||(e.hooks.SubagentStart=[]),e.hooks.SubagentStart.push({hooks:[{type:"command",command:Lu}]}),JSON.stringify(e.hooks.SubagentStart)!==t}function Nu(e,{markers:t=Object.values(Rg)}={}){return Ru(e,"SubagentStart",t)}async function Mu(e,t={}){let r=await _(e);return r.schemaVersion=de,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 O(e,r),r}function aa(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*`),`
|
|
63
|
+
`);return t}async function Ng(e){let t=P(Su(e),"context"),r=P(e,".vesper","context"),n=await w(r),s={removed:[],kept:[]},o;try{o=await Xe(t)}catch{return s}for(let i of o.files){let a=!n;if(n)try{a=ge(await re(P(t,i)),await re(P(r,i)))}catch{a=!1}a?(await Gr(P(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 na(P(t,i))}catch{}try{await na(t)}catch{}return s}function vu(e){let t=String(e).replace(/\r\n/g,`
|
|
64
|
+
`),r=/^---\n[\s\S]*?\n---\n/.exec(t);return(r?t.slice(r[0].length):t).trim()}async function Mg(e){let t={removed:[],kept:[]};for(let r of["orchestration","context"]){let n=`.claude/vesper/${r}.md`,s;try{s=await re(P(e,n),"utf-8")}catch{continue}let o=null;try{o=await re(P(e,".vesper","instructions",`vesper-${r}.instructions.md`),"utf-8")}catch{o=null}let i=vu(s);o===null||i!==""&&vu(o).includes(i)?(await Gr(P(e,n),{force:!0}),t.removed.push(n)):t.kept.push(n)}return t}async function Ur(e,{purgeProjectAuthored:t=!1}={}){let r=Su(e),n=".claude/vesper/orchestrator.md";await ue(P(e,n),{path:n,category:"playbook"});let s=[];t&&(s.push(...(await Mg(e)).kept),s.push(...(await Ng(e)).kept.map(m=>`.claude/vesper/context/${m}`)));try{await na(r)}catch{}let o=await _(e),i=new Set,a=Array.isArray(o.manifest)?o.manifest:[],c=new Set(a.filter(m=>m&&m.host!=="claude"&&m.category==="per-project-authored").map(m=>m.path));for(let m of a)Xs(m,{host:"claude",purgeProjectAuthored:t})&&(m.category==="per-project-authored"&&c.has(m.path)||i.add(m.path));for(let m of Array.isArray(o.claude?.catalogManifest)?o.claude.catalogManifest:[]){if(typeof m!="string"||m.includes(".."))continue;let[y,...k]=m.split("/");!Eg.includes(y)||k.length===0||i.add(`.claude/${m}`)}for(let m of i){let y=(o.manifest||[]).find(k=>k?.path===m)||{path:m,category:m.startsWith(".claude/skills/")?"catalog-skill":"catalog-agent"};await ue(P(e,m),y,{purgeProjectAuthored:t})}let{kept:l}=await eo(e,"claude"),d=Eu(e);if(await w(d)){let m=await re(d,"utf-8"),y=aa($g(m));y.trim()?await $(d,y,"utf-8"):await Gr(d,{force:!0})}await Dt(e,!1);let p=Array.isArray(o.mcp?.servers)?o.mcp.servers:[];if(p.length&&await w(Oe(e)))try{let m=JSON.parse(await re(Oe(e),"utf-8")),y=!1;for(let k of p)m?.mcpServers&&typeof m.mcpServers=="object"&&k in m.mcpServers&&(delete m.mcpServers[k],y=!0);y&&await po(e,m)}catch{}try{let m=JSON.parse(await re(Oe(e),"utf-8"));m&&typeof m=="object"&&Object.keys(m).every(k=>k==="mcpServers")&&(!m.mcpServers||Object.keys(m.mcpServers).length===0)&&await Gr(Oe(e),{force:!0})}catch{}let h=Pe(e);if(await w(h))try{let m=JSON.parse(await re(h,"utf-8")),y=mo(m,{markers:[Vn.legacy,Vn.bootstrap]}),k=Nu(m),v=wu(m),S=Pg(m);(y||k||v||S)&&(Object.keys(m).length===0?await Gr(h,{force:!0}):await $(h,JSON.stringify(m,null," "),"utf-8"))}catch{}let g=Hr(e);if(await w(g))try{let m=JSON.parse(await re(g,"utf-8"));wu(m)&&(Object.keys(m).length===0?await Gr(g,{force:!0}):await $(g,JSON.stringify(m,null," "),"utf-8"))}catch{}let f=await _(e);return delete f.claude,f.host==="claude"&&delete f.host,delete f.namePrefix,delete f.pluginPath,Array.isArray(f.manifest)&&(f.manifest=f.manifest.filter(m=>!(m&&m.host==="claude")||!t&&Ce.has(m.category))),await O(e,f),{kept:l,knowledgeKept:s}}W();import{readFile as Wn,rm as vd,rmdir as Zy}from"node:fs/promises";import{join as Me}from"node:path";U();he();import{readFile as Un,readdir as hy}from"node:fs/promises";import{join as ke,isAbsolute as my,relative as gy}from"node:path";U();import{readdir as Fg,readFile as Fu,rename as Vg,access as Dg,constants as Gg}from"node:fs/promises";import{join as Gt}from"node:path";import{execFile as Hg}from"node:child_process";var ca=".vesper/.migration-backup";async function Vu(e){try{return await Dg(e,Gg.F_OK),!0}catch{return!1}}function Ug(e){return new Promise(t=>{try{Hg("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 Du(e){try{return(await Fg(Gt(e,ca),{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name).sort()}catch{return[]}}async function go(e,{head:t}={}){let r=await Du(e);if(r.length===0)return!1;let n=Gt(e,ca),s=t!==void 0?t:await Ug(e),o=r.at(-1);for(let i of[...r].reverse()){let a;try{a=await Fu(Gt(n,i,"rollback.json"),"utf-8")}catch{continue}let c;try{c=JSON.parse(a)}catch{if(i!==o)continue;return!await Vu(Gt(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 la(e){let t=await Du(e);if(!t.length)return null;let r=Gt(e,ca,t.at(-1)),n;try{n=await Fu(Gt(r,"rollback.json"),"utf-8")}catch{return null}try{return JSON.parse(n),null}catch{}return await Vu(Gt(r,"created.txt"))?null:Gt(r,"rollback.json")}async function Gu(e,{now:t=new Date}={}){let r=await la(e);if(!r)return null;let n=`${r}.torn-${t.toISOString().replace(/[:.]/g,"-")}`;return await Vg(r,n),{from:r,to:n}}W();U();import{readFile as Ku,rm as Qg,rmdir as Zg}from"node:fs/promises";import{join as ha}from"node:path";he();U();he();Re();import{readFile as da,readdir as Wu}from"node:fs/promises";import{readdirSync as Wg}from"node:fs";import{join as me,basename as Bg}from"node:path";import{homedir as Kg}from"node:os";var zg=Object.freeze(["agents","commands","skills"]),Jg=Object.freeze(["claude","paths","catalogVersion","targets"]),ur=".vesper/.migration-backup",Be="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 vo(e){let t=[...new Set([await at(e),me(e,".vesperrc"),me(e,".vesper","tracking.json")])],r=null,n=null;for(let c of t){let l;try{l=await da(c,"utf-8")}catch(d){if(d&&d.code==="ENOENT")continue;return yo({config:"corrupt",path:c})}try{r=JSON.parse(l),n=c}catch{return yo({config:"corrupt",path:c})}break}if(!r||typeof r!="object")return yo({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("/");!zg.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 yo({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"?Jg.filter(c=>c in r):[],recordedHost:s==="v2"?mn({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 yo(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 ve(e,{checkout:t}={}){let r=await vo(e),n;try{n=await K(e)}catch{n=void 0}let s=await Nc(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(`${Bg(r.path||".vesperrc")} (1.x record)`);let a=!1,c=!1,l=!1,d=null;try{let h=t??await z(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 Yg="<!-- vesper(?::[a-z0-9-]+)?:start -->[\\s\\S]*?<!-- vesper(?::[a-z0-9-]+)?:end -->",Hu=e=>new RegExp(Yg).test(e),qg=Object.freeze([sn,on,an]);async function ua(e){try{return await Wu(e,{withFileTypes:!0})}catch{return[]}}async function wo(e){try{return await da(e)}catch{return null}}function Uu(e){let t=new Set;for(let r of[me(I,"claude",e),me(I,"claude-committed",e)])try{for(let n of Wg(r))t.add(n.replace(/\.md$/,""))}catch{}return t}function Xg(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 ko({homeDir:e=Kg(),pluginName:t="vesper",workspaceRoot:r}={}){let n=[],s=(p,h,g,f,m={})=>n.push({path:me(e,p),rel:p,kind:h,tier:g,marker:f,...m}),o=Uu("agents"),i=Uu("skills"),a=`.claude/skills/${t}`,c=await Mn({pluginName:t,staleDir:me(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",g=>g.endsWith(".md")],[".copilot/instructions",()=>!0]])for(let g of await ua(me(e,p))){if(!g.isFile()||!h(g.name))continue;let f=`${p}/${g.name}`,m=(await wo(me(e,f)))?.toString("utf-8")??"";Hu(m)?s(f,"file",3,"a Vesper guard block"):g.name.startsWith("vesper-")&&s(f,"file",3,"a vesper- file name")}for(let p of[".claude/agents",".copilot/agents"])for(let h of await ua(me(e,p))){if(!h.isFile()||!h.name.endsWith(".md"))continue;let g=`${p}/${h.name}`,f=await wo(me(e,g));if(!f)continue;let m=h.name.replace(/(\.agent)?\.md$/,"");(o.has(Xg(f.toString("utf-8"))||m)||o.has(m)||h.name.startsWith("vesper-"))&&s(g,"file",3,"a Vesper agent name")}for(let p of[".claude/skills",".copilot/skills"])for(let h of await ua(me(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 wo(me(e,".claude","CLAUDE.md")))?.toString("utf-8");l&&Hu(l)&&s(".claude/CLAUDE.md","region",3,"a Vesper guard block");let d=await wo(me(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=[],g=p.hooks&&typeof p.hooks=="object"?p.hooks:{};for(let[f,m]of Object.entries(g))Array.isArray(m)&&m.some(y=>Array.isArray(y?.hooks)&&y.hooks.some(k=>typeof k?.command=="string"&&qg.includes(k.command.trim())))&&h.push(`hooks.${f}`);p.agent===H&&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 Bu(e){let t=me(e,ur),r=[];try{r=(await Wu(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 da(me(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:me(t,s)})}return n}rt();var So="VESPER_HOST_MISMATCH",ma="VESPER_PLUGIN_ABSENT",Z="vespercli init",Ke=e=>`vespercli init --host ${e}`;function ey(e,t){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.`:`This workspace is provisioned for "${e}" but is running under "${t}". Fix: ${Ke(t)}`}var Gn=".vesper/instructions/vesper-host-guard.instructions.md",pa="guard-rule",ty=["---","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 \`${So}\`: 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(`
|
|
65
|
+
`);function ga(e){return e==="claude"?"copilot":"claude"}async function zu(e){let t=Pe(e),r={},n=!0;try{r=JSON.parse(await Ku(t,"utf-8")),n=!1}catch{r={}}(!r||typeof r!="object"||Array.isArray(r))&&(r={});let s=ia(r);return(s||n)&&(await j(ha(e,".claude"),{recursive:!0}),await $(t,JSON.stringify(r,null," "),"utf-8")),{changed:s,created:n}}function ry(){return{label:wn.taskLabel,command:_r("copilot"),presentation:{reveal:"always",panel:"shared"}}}async function ny(e,t,{unattended:r=!1}={}){return Br(t),t==="claude"?zu(e):kn(e,{createOnly:r})}async function Ju(e,t){if(Br(t),t==="claude"){let n=await zu(e);return await J(e,[Q({path:".claude/settings.json",host:"shared",category:"guard-trigger",owns:{keys:["hooks.SessionStart"]}})]),n}let r=await _s(e,ry());return await J(e,[Q({path:".vscode/tasks.json",host:"shared",category:"guard-trigger",owns:{keys:[wn.taskLabel]}})]),r}async function Eo(e,t,{unattended:r=!1}={}){return Br(t),await ny(e,t,{unattended:r}),await Ju(e,ga(t)),{legacyGuardRule:await dr(e)}}async function fa(e,t){let r=await _(e),n=Y(r),s=n.filter(o=>!t(o));return s.length===n.length?!1:(r.manifest=s,await O(e,r),!0)}async function Hn(e,t){Br(t);let r=Y(await _(e));if(t==="claude"){let i=Pe(e);if(await w(i))try{let a=JSON.parse(await Ku(i,"utf-8"));mo(a,{markers:[Vn.guard]})&&(Object.keys(a).length===0?await Qg(i,{force:!0}):await $(i,JSON.stringify(a,null," "),"utf-8"))}catch{}await fa(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 vn(e,wn.taskLabel,{removeFileIfEmpty:n&&!s});if(o)try{await Zg(ha(e,".vscode"))}catch{}await fa(e,i=>i.path===".vscode/tasks.json"&&i.category==="guard-trigger")}async function dr(e){let n=Y(await _(e)).find(o=>o.path===Gn&&o.category===pa)??{path:Gn,category:pa,hash:null},s=await ue(ha(e,Gn),n,{expected:[ty]});return await fa(e,o=>o.path===Gn&&o.category===pa),s==="partial"?"kept":s}function Wr(){return`Kept your edited ${Gn} \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 sy(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 oy(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 bo(e,{runningHost:t}={}){let r=t!==void 0,n={identity:r,network:r,runningHost:t,journal:null,fix:null,note:null,message:null},s=await _t(e),o=await z(e,{requireCommitted:!r&&!s});if(s)return r&&t!==s.to?{...n,action:"refuse",reason:"switch-in-progress",host:s.to,checkout:o,journal:s,fix:Z,message:`An interrupted host switch (${s.from} \u2192 ${s.to}) is pending in this workspace. Fix: ${Z}`}:{...n,action:"none",reason:"switch-in-progress",host:null,checkout:o,journal:s,note:`An interrupted host switch (${s.from} \u2192 ${s.to}) is pending \u2014 run \`vespercli init\` to finish it.`};let i=async()=>{let c=null;try{c=await ve(e,{checkout:o})}catch{c=null}return c?.unmigrated?{...n,action:"none",reason:"legacy-unmigrated",host:null,checkout:o,note:`Bootstrap wrote nothing. ${Be}`}:await go(e)?{...n,action:"none",reason:"migration-in-progress",host:null,checkout:o,note:"A Vesper 1.x migration was interrupted in this workspace \u2014 run `vespercli init` to finish it. Nothing was provisioned."}:null},a=o.source==="local";if(a){let c=await i();if(c)return c}if(r&&o.host&&o.host!==t)return{...n,action:"refuse",reason:"host-mismatch",host:o.host,checkout:o,fix:Ke(t),message:ey(o.host,t)};if(!a){let c=await i();if(c)return c}if(o.gitError)return{...n,action:"none",reason:o.gitError==="dubious-ownership"?"not-vesperized":"git-unreadable",host:null,checkout:o,note:oy(o,e)};if(o.ambiguous)return{...n,action:"none",reason:"host-ambiguous",host:null,checkout:o,note:r?Ue:null};if(!o.host){let c=!r&&o.candidate?"host-unconfirmed":"not-vesperized",l=r?await nr(e):null,d=l?`This worktree's local record names ${l}, but the checked-out commit carries no Vesper provisioning \u2014 nothing was provisioned. \`vespercli init --host ${t}\` provisions it.`:sy(o);return{...n,action:"none",reason:c,host:null,checkout:o,note:d}}return{...n,action:"bootstrap",reason:"healthy",host:o.host,checkout:o}}async function Yu(e,t,{checkout:r}={}){if(Br(t),r?.source==="local"){for(let n of[iy(t),".vesperrc"])if(!await ay(e,n))return{healed:!1,reason:"local-tier"}}return await Ju(e,t),{healed:!0}}function iy(e){return Br(e),e==="claude"?".claude/settings.json":".vscode/tasks.json"}async function ay(e,t){return await V(["check-ignore","-q","--",t],{cwd:e,timeout:5e3})!==null}function Br(e){if(!G.includes(e))throw new Error(`host must be one of: ${G.join(", ")} (received "${e}")`)}he();Re();Re();U();import{readFileSync as cy}from"node:fs";import{readFile as qu}from"node:fs/promises";import{join as ya,dirname as ly}from"node:path";he();W();var Kr=Object.freeze({claude:".claude/rules/vesper-orchestration.md",copilot:".vesper/instructions/vesper-orchestration.instructions.md"}),Xu="vespercli packs sync";function Qu(e){return`${We(e)}@${we}`}function uy(e){return nn(e)!==null}function xo(e=I){let t=null;try{t=JSON.parse(cy(ya(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 pt(e=I){return[...xo(e).packs].sort()}function Zu(e,t=I){let r=xo(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 wa(e){try{let t=JSON.parse(await qu(Pe(e),"utf-8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}async function pr(e,t){let r=new Set(pt()),n=new Set,s=new Set;if(t==="claude"){let i=(await wa(e))?.enabledPlugins;if(i&&typeof i=="object"&&!Array.isArray(i))for(let[a,c]of Object.entries(i)){let l=nn(a);!l||c!==!0||(r.has(l)?n:s).add(l)}}else if(t==="copilot"){let o=await K(e);for(let i of Ps())for(let{path:a,settingKey:c}of Tr(i))if(o[c]?.[a]===!0){n.add(i);break}}return{enabled:[...n].sort(),unknown:[...s].sort()}}async function _o(e,t){return(await pr(e,t)).enabled}var dy=Object.freeze(["permissions.allow","hooks.SessionStart","agent","enabledPlugins"]);async function ed(e,t){let n=(await $e(e)).find(i=>i&&i.path===Jt&&i.host==="claude"&&i.category==="settings"),o={keys:Array.isArray(n?.owns?.keys)&&n.owns.keys.length?[...n.owns.keys]:[...dy]};t.length&&(o.entries=[...t].sort()),await J(e,[Q({path:Jt,host:"claude",category:"settings",owns:o})])}async function td(e){let r=(await $e(e)).find(n=>n&&n.path===Jt&&n.host==="claude"&&n.category==="settings");return(Array.isArray(r?.owns?.entries)?r.owns.entries:[]).filter(uy).sort()}async function rd(e,t){if(!await w(ya(e,It)))return;await J(e,[Q({path:It,host:"copilot",category:"settings",owns:{keys:[...Et],entries:[...t]}})]);let r=await _(e);if(Number(r.schemaVersion)===2&&In.some(n=>n in r)){for(let n of In)delete r[n];await O(e,r)}}function nd(e){if(!pt().includes(e))throw new Error(`Unknown pack "${e}". Available packs: ${pt().join(", ")||"none"}.`)}async function fr(e,t,r){nd(r);let n=await py(e,t,r);if(ir(r)){let s=await Xl(e,t,r);s&&(n.rule=s)}return n}async function py(e,t,r){if(t==="claude"){let n=Pe(e),s=await wa(e);if(s===null&&await w(n))throw new Error(`${Jt} 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=Qu(r),i=s.enabledPlugins[o]===!0;i||(s.enabledPlugins[o]=!0,await j(ly(n),{recursive:!0}),await $(n,JSON.stringify(s,null," "),"utf-8"));let a=new Set([...await td(e),o]);return await ed(e,[...a]),{pack:r,enabled:!i}}if(t==="copilot"){let n=Tr(r),{added:s}=await $r(e,n),o=new Set([...await ut(e),...n.map(i=>i.path)]);return await rd(e,[...o]),{pack:r,enabled:s.length>0}}throw new Error(`Unknown host "${t}"`)}async function sd(e,t,r){nd(r);let n=await fy(e,t,r);if(ir(r)){let s=await Yi(e,t,r);s&&(n.rule=s)}return n}async function fy(e,t,r){if(t==="claude"){let n=Pe(e),s=await wa(e),o=Qu(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 $(n,JSON.stringify(s,null," "),"utf-8"),i=!0);let a=(await td(e)).filter(c=>c!==o);return await ed(e,a),{pack:r,disabled:i}}if(t==="copilot"){let n=Tr(r).map(i=>i.path),{removed:s}=await _i(e,n),o=(await ut(e)).filter(i=>!n.includes(i));return await rd(e,o),{pack:r,disabled:s.length>0}}throw new Error(`Unknown host "${t}"`)}async function Ht(e,t){let r=Kr[t];if(!r)return null;try{return await qu(ya(e,r),"utf-8")}catch{return null}}async function Ut(e,t){let r=t||await dt(),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 Kl(e||"")){let c=r.agentPack.get(a);if(c===void 0){Object.hasOwn(Qs,a)||o.push(a);continue}c!=="core"&&s(c,"agents",a)}for(let a of zl(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 Wt(e,t,{dryRun:r=!1}={}){let n=Kr[t],s=await Ht(e,t),o=await Ut(s||""),i=await _o(e,t),a=[],c=[];for(let d of o.packs){if(i.includes(d)){c.push(d);continue}r||await fr(e,t,d),a.push(d)}let l=i.filter(d=>!o.packs.includes(d));return{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 od(e){let r=(await dt()).agentPlugin.get(Mr(e).name);return r?`${r}:${Mr(e).name}`:null}W();import{readFile as ka,readdir as yy}from"node:fs/promises";import{homedir as wy}from"node:os";var C=Object.freeze({ERROR:"error",WARN:"warn",INFO:"info"}),Se=Object.freeze({OK:0,ERROR:1,HOST_MISMATCH:2}),id=new Set(Object.values(C)),pd="host-mismatch",vy="check-failed",ky=new Set(["playbook","pointer","mcp-config","settings"]);var ad=Js,Sy=e=>`vespercli reset --host ${e}`;function R({code:e,severity:t,message:r,fix:n,category:s,path:o}){if(!id.has(t))throw new Error(`makeFinding: unknown severity "${t}" for code "${e}". Valid severities: ${[...id].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 va(e,t){if(!t)return t;let r=gy(e,t);return r.startsWith("..")?t:r}async function Ey(e){let r=[await at(e),ke(e,".vesperrc"),ke(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 Un(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 cd(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 Un(e,"utf-8"));return{path:e,exists:!0,servers:Object.keys(n[t]||{})}}catch{return{path:e,exists:!0,servers:[]}}}async function by(e,t,{visible:r}={}){let n={};for(let s of Object.keys(t)){n[s]=[];for(let o of t[s])try{await Pt(e,o,{visible:r})&&n[s].push(o)}catch(i){if(!xy(i))throw i}}return n}function xy(e){return!!e&&typeof e.code=="string"&&["ENOENT","EACCES","EISDIR","ENOTDIR","EPERM","ELOOP","ENAMETOOLONG"].includes(e.code)}function _y(e){return ci(e)}async function Ay(e,t,{homeDir:r=wy(),checkout:n=null}={}){let s=await Ey(e);if(s.corrupt)return{workspaceRoot:e,runningHost:t,corrupt:!0,corruptPath:s.corruptPath};let o=s.tracking||null,i=n;i||(i=await z(e,{withCommitted:!0}));let a=i.host,c=null;try{c=await _t(e)}catch{c=null}let l=null,d=!1;try{l=await la(e)}catch{l=null}try{d=await go(e)}catch{d=!1}let p=await Ll(e),h=[...p.missing,...p.modified,...p.clean],g=await qs(e),f=ss(),m=[];try{m=await ce(e)}catch{m=[]}let y=a?[a]:m,k={claude:await cd(Oe(e),"mcpServers"),copilot:await cd(De(e),"servers")},v=Rt(),S=i.ambiguous?"both":i.host,A=await by(e,v,{visible:i.visible}),L={};for(let[je,Tt]of Object.entries(A))L[je]=Tt.some(_y);let E={};for(let je of G)E[je]=await cn(e,je);let b=null;try{b=await ve(e,{checkout:i})}catch{b=null}let M=[];try{M=(await ko({homeDir:r,workspaceRoot:e})).filter(je=>je.kind==="plugin")}catch{M=[]}let X=[];try{X=await Bu(e)}catch{X=[]}let Ie=await nr(e),Xr=!!Ie&&Ie!==a;{let je=i.source==="local"?null:a,Tt=ze=>{if(!ze)return!1;if(G.includes(ze.host))return ze.host===je;let yr=$y(ze);return!yr||yr===je};p={...p,missing:p.missing.filter(Tt),modified:p.modified.filter(Tt),clean:p.clean.filter(Tt),userLevelViolations:p.userLevelViolations}}let ft=[...p.missing,...p.modified,...p.clean],Ct=!!a||h.length>0;return{workspaceRoot:e,runningHost:t,absent:!!s.absent,tracking:o,host:a,checkout:i,ledgerHostForReporting:Ie,verify:p,manifestEntries:ft,manifestAll:h,recordStale:Xr,journal:c,migrationTorn:l,migrationActive:d,frameworkVersion:g,packageVersion:f,installedTargets:y,mcpConfigs:k,detectedHost:S,fingerprintMatches:A,fingerprintSpecific:L,residue:E,legacy:b,userResidue:M,keptItems:X,initialised:Ct}}function $y(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 fd(e,t){return e.checkout?.host===t||!!e.fingerprintSpecific?.[t]}function Cy(e){let t=[],{verify:r}=e;for(let n of r.userLevelViolations)t.push(R({code:"user-level-violation",severity:C.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)(At[n.category]||{}).doctor==="server-drift"?t.push(R({code:"mcp-core-missing",severity:C.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:C.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=ky.has(n.category);t.push(R({code:"owned-file-missing",severity:s?C.ERROR:C.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 Ao(e,t={}){let r=new Set,n=t.installedTargets;if(!Array.isArray(n))try{let a=await Rr(e);n=a?[a]:await ce(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 Ty(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 Ge(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 _(e);s=Array.isArray(a.mcp?.servers)?a.mcp.servers:[]}catch{s=[]}let o=new Set(s);return{drifted:[...r].filter(a=>!_e.includes(a)&&!o.has(a))}}async function Ty(e){try{return JSON.parse(await Un(Oe(e),"utf-8"))}catch{return{mcpServers:{}}}}async function Oy(e){let{drifted:t}=await Ao(e.workspaceRoot,{tracking:e.tracking,mcpConfigs:e.mcpConfigs,installedTargets:e.installedTargets});return t.map(r=>R({code:"mcp-drift",severity:C.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 Py(e){return!e.initialised||!e.host?[]:(e.manifestAll??e.manifestEntries).some(r=>r.category==="mcp-config")?[]:Iy(e)?[R({code:"mcp-config-unrecorded",severity:C.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 Iy(e){return!!e.mcpConfigs?.[e.host]?.exists}function jy(e){if(e.absent||!e.tracking)return[];let t=e.tracking;return(t.host===void 0||G.includes(t.host))&&Array.isArray(t.manifest)&&t.schemaVersion===de?[]:[R({code:"tracking-shape-invalid",severity:C.WARN,path:".vesperrc",message:".vesperrc parses but its shape is invalid (host/manifest/schemaVersion) \u2014 `vespercli init` repairs it.",fix:Z})]}async function Ry(e){let t=[];if(e.detectedHost==="both"){let r=G.every(n=>fd(e,n));t.push(R({code:"host-ambiguous",severity:r?C.ERROR:C.WARN,message:r?ad:`${ad} (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 Ly(e,r)&&t.push(R({code:"host-residue",severity:C.WARN,message:`This workspace is host "${e.host}" but still carries "${r}" artifacts (a leftover from a host switch).`,fix:Sy(r)}))}return t}async function Ly(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||Ce.has(a.category)||typeof a.path!="string"||a.path.includes("..")||my(a.path)||await w(ke(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(()=>(rt(),ti)),{READ_ONLY_GIT_ENV:o}=await Promise.resolve().then(()=>(ot(),fi)),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 Ny(e){let t=[],r=e.checkout||{},n=e.ledgerHostForReporting??null;r.gitError==="dubious-ownership"?t.push(R({code:"git-dubious-ownership",severity:C.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:C.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:C.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:C.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:C.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:C.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 My(e){let t=[];for(let r of G){let n=e.residue?.[r]||[];n.length&&((e.fingerprintMatches?.[r]||[]).length>0||e.host!==r&&t.push(R({code:"host-leftover-files",severity:C.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 ld(e){let t=G.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 Fy(e){let t=[],r=e.legacy;r?.unmigrated?t.push(R({code:"legacy-workspace",severity:C.ERROR,message:`${Be} Evidence: ${r.evidence.join(", ")||"1.x record"}.`,fix:ld(r)})):(r?.advisory||r?.residue)&&t.push(R({code:"legacy-residue",severity:C.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):ld(r)})),r&&!r.unmigrated&&!r.advisory&&r.leftovers.length&&t.push(R({code:"legacy-leftover-files",severity:C.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:C.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:C.WARN,path:va(e.workspaceRoot,e.migrationTorn),message:`The newest migration record (${va(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:C.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 Vy(e){if(e.host!=="claude"||e.legacy?.needsMigration)return[];let t=await dt(),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 yy(ke(e.workspaceRoot,".claude","agents"))){let i=`.claude/agents/${o}`;if(!o.endsWith(".md")||r.has(i)||!oo("agents",o,""))continue;let a=null;try{a=await ka(ke(e.workspaceRoot,i))}catch{a=null}a&&!so(a,`agents/${o}`)&&n.add(i)}}catch{}let s=[];for(let o of[...n].sort()){if(r.has(o)||!await w(ke(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(ke(e.workspaceRoot,o,"SKILL.md")))continue;let l=a==="agents"?ke(I,"claude","agents",`${c}.md`):ke(I,"claude","skills",c);s.push(R({code:"kept-shadows-plugin",severity:C.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"} "${ke(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 Dy(e){if(e.host!=="claude")return[];let t;try{t=await ka(ke(e.workspaceRoot,".claude","rules","vesper-orchestration.md"),"utf-8")}catch{return[]}let r=Wl(t,(await dt()).agents);return r.length?[R({code:"roster-unqualified-agents",severity:C.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 Gy(e){if(!e.host)return[];let t=await Ht(e.workspaceRoot,e.host);if(t===null)return[];let r=await Ut(t),{enabled:n}=await pr(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:C.WARN,path:Kr[e.host],message:`The Team Roster names ${i.length} asset(s) of the "${o}" pack (${We(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:Xu}))}for(let o of n)r.packs.includes(o)||ir(o)||s.push(R({code:"pack-unused",severity:C.INFO,path:e.host==="claude"?".claude/settings.json":".vscode/settings.json",message:`The "${o}" pack (${We(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 Hy(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:C.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=fd(e,r);t.push(R({code:pd,severity:n?C.ERROR:C.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 Uy(e){if(e.host!=="claude")return[];let t;try{t=JSON.parse(await ka(Hr(e.workspaceRoot),"utf-8"))}catch{return[]}let r=t?.extraKnownMarketplaces?.[we];return r===void 0||Iu(r)?[]:[R({code:"marketplace-entry-invalid",severity:C.WARN,path:".claude/settings.local.json",message:`The \`extraKnownMarketplaces.${we}\` 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 Wy(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:C.WARN,message:`Workspace provisioned with Vesper ${r}, running ${t}.`,fix:Z})]:[]:[R({code:"ledger-unstamped",severity:C.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 By(e){return e.initialised?await w(ke(e.workspaceRoot,se))?[]:e.manifestAll?.some(t=>t?.path===se)?[]:[R({code:"gates-missing",severity:C.INFO,path:se,message:"No gate policy (`.vesper/gates.json`) \u2014 `vespercli gate` exits 2 here until `init` seeds one.",fix:Z})]:[]}async function Ky(e){if(e.host!=="claude")return[];let t=ke(e.workspaceRoot,".claude","agents"),r=[];try{r=(await hy(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 Un(ke(t,s),"utf-8"),a=zy(i);(!a||!ud(a.name)||!ud(a.description))&&n.push(R({code:"agent-frontmatter-incomplete",severity:C.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 ud(e){return typeof e=="string"&&e.trim().length>0}function zy(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 Jy(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(()=>(U(),Ci)),{runGit:l}=await Promise.resolve().then(()=>(rt(),ti)),{classifyForeignHook:d,HOOK_GUARD_START:p,HOOK_GUARD_END:h}=await Promise.resolve().then(()=>(en(),wc));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:C.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 g=await n(e.workspaceRoot);if(!g.dir)return g.reason==="not-a-repo"||t.push(R({code:"git-hooks-not-installable",severity:C.INFO,message:s({...g,hook:"hook"})??`Git hooks not installable (${g.reason}).`,fix:"see the message"})),t;if(!g.default&&await i(await a(g.dir),g,{dir:!0}))return t.push(R({code:"git-hooks-not-installable",severity:C.INFO,message:s({reason:"tracked-by-git",configured:g.dir}),fix:"see the message"})),t;for(let f of o){let m=ke(g.dir,f),y=await c(m),k=null;if(y.path)try{k=await Un(y.path)}catch{k=null}let v=k?k.toString("latin1"):"",S=v.indexOf(p);if(S!==-1){let L=v.indexOf(h,S),E=v.slice(S,L===-1?void 0:L);E.includes("vesper.hooks")?f==="pre-commit"&&!E.includes("VESPER_NO_SWEEP")&&t.push(R({code:"git-hook-outdated",severity:C.INFO,path:m,message:`Vesper's pre-commit git hook block (${m}) 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:C.INFO,path:m,message:`Vesper's ${f} git hook block (${m}) 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:m};else if(k&&await i(await a(y.path),g))A={reason:"tracked-by-git",configured:y.path};else if(k){let L=d(k);L.ok||(A={reason:L.reason,interpreter:L.interpreter,line:L.line})}if(A){t.push(R({code:"git-hook-not-modifiable",severity:C.INFO,path:m,message:s({...A,hook:f,hooksDir:g.dir})??`Git hook ${f} cannot carry Vesper's block (${A.reason}).`,fix:"see the message"}));continue}t.push(R({code:"git-hook-missing",severity:C.WARN,path:m,message:`Vesper's ${f} git hook block is missing (${m}): ${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 hd=[{id:"manifest",title:"Owned-files manifest",run:e=>Cy(e)},{id:"mcp-drift",title:"MCP config drift",run:e=>Oy(e)},{id:"mcp-required",title:"MCP config recorded",run:e=>Py(e)},{id:"tracking",title:"Tracking structure",run:e=>jy(e)},{id:"host-conflict",title:"Host conflict",run:e=>Ry(e)},{id:"host-authority",title:"Host authority (checkout vs worktree record)",run:e=>Ny(e)},{id:"host-leftover",title:"Leftover host files",run:e=>My(e)},{id:"legacy",title:"Pre-2.0 (1.x) residue",run:e=>Fy(e)},{id:"legacy-kept-shadows",title:"Kept 1.x copies shadowing plugin specialists",run:e=>Vy(e)},{id:"roster-namespaces",title:"Team Roster delegation names",run:e=>Dy(e)},{id:"packs",title:"Packs the Team Roster needs",run:e=>Gy(e)},{id:"git-hooks",title:"Vesper git hooks",run:e=>Jy(e)},{id:"host-mismatch",title:"Host identity",run:e=>Hy(e),failureSeverity:e=>e.runningHost?C.ERROR:C.WARN},{id:"framework-version",title:"Framework version",run:e=>Wy(e)},{id:"marketplace-entry",title:"Marketplace entry shape",run:e=>Uy(e)},{id:"agent-frontmatter",title:"Agent frontmatter",run:e=>Ky(e)},{id:"gates-config",title:"Gate policy",run:e=>By(e)}];function dd(e){let t=e.filter(o=>o.severity===C.ERROR),r=e.filter(o=>o.severity===C.WARN),n=e.filter(o=>o.severity===C.INFO),s=t.some(o=>o.code===pd);return{findings:e,errors:t,warnings:r,infos:n,summary:{hasError:t.length>0,hostMismatch:s}}}async function zr(e,{runningHost:t,homeDir:r,checkout:n}={}){let s=await Ay(e,t,{homeDir:r,checkout:n});return s.corrupt?dd([R({code:"tracking-unparseable",severity:C.ERROR,path:va(e,s.corruptPath),message:"Malformed .tracking structure (.vesperrc is present but unparseable) \u2014 framework cannot operate.",fix:Z})]):dd(await Yy(s,hd))}async function Yy(e,t=hd){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):C.WARN;r.push(R({code:vy,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 $o(e){return e.summary.hostMismatch?Se.HOST_MISMATCH:e.summary.hasError?Se.ERROR:Se.OK}U();function Sa(e){return String(e??"").replace(/\r\n?/g,`
|
|
66
|
+
`)}function Ze(e){let t=Sa(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 hr(e,t){if(!e)return null;let r=Sa(e).split(`
|
|
67
|
+
`),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 Co(e){return`'${String(e??"").replace(/[\u0000-\u001f]+/g," ").replace(/\s+/g," ").trim().replace(/'/g,"''")}'`}var gd=Object.freeze(["vesper-orchestrator","vesper-orchestration","vesper-context"]);function qy(e){let t=e;for(let r of gd){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 Xy(e){return qy(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 Qy(e){let t=e;for(let r of gd)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 md=Object.freeze(["start","end","gitignore","hook"]);function yd(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)=>md.includes(r)?t:`\`${r}\``).replace(/\bvesper:([a-z][a-z0-9-]*)\b/g,(t,r)=>md.includes(r)?t:r)}function wd(e){return yd(Qy(Xy(Sa(e))))}var Sx=Object.freeze({Read:"read/readFile",Bash:"execute/runInTerminal",Grep:"search/codebase",Glob:"search/fileSearch",TodoWrite:"todo",AskUserQuestion:"vscode/askQuestions",Agent:"agent/runSubagent"}),Ex=Object.freeze(["read/readFile","search/codebase","search/fileSearch","edit/editFiles","edit/createFile","execute/runInTerminal","agent/runSubagent","todo","vscode/askQuestions","web","web/fetch"]),bx=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 xx=Object.freeze(["core","extended"]);var _x=Object.freeze(["copilot-apply-to","copilot-instructions-tier"]);var Ea=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}]),Ed=".vesper/context";function bd(e){return Me(e,".vesper","agents")}function ew(e){return Me(e,".vesper","instructions")}function xd(e){return Me(e,Ed)}var tw=".vscode/mcp.json",Vx=Object.freeze([".github/",".claude/rules/",".claude/agents/",".claude/commands/",".claude/skills/"]);function To(e){return wd(e)}function _d(e){return Co(e).slice(1,-1)}var kd="VESPER_HOST_MISMATCH";function rw(){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 \`${H}\`** \u2014 the single pickable Vesper agent`,` (\`${wt}\`). 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(`
|
|
68
|
+
`)}function nw(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 sw=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)"]]),ow="**Namespaced delegation names",iw=`- **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 \`${H}\` (this persona). The four maintenance prompts are invoked unqualified (\`/reinit\`, \`/compact-knowledge\`, \`/revalidate-knowledge\`, \`/revalidate-team\`).`;function aw(e){return e.split(`
|
|
69
|
+
`).map(t=>t.trimStart().startsWith("- ")&&t.includes(ow)?iw:t).join(`
|
|
70
|
+
`)}function cw(e){let t=sw.reduce((r,[n,s])=>nw(r,n,s),e);return aw(t)}function lw(e){let r=e.indexOf("> **First-run workspace trust & plugin resolution:**");if(r===-1)return e;let n=e.indexOf(`
|
|
71
|
+
`,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 \`${H}\`, provisioned project-local at \`${wt}\`. 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 Ad(e){let{body:t}=Ze(e);if(!t.includes(kd))throw new Error(`renderCopilotPlaybook: the canonical playbook no longer contains the ${kd} marker. The host-mismatch warning keys off it \u2014 restore the "Host-mismatch warning" section in assets/claude/vesper-orchestrator.md.`);let r=cw(To(lw(t))),n=["---","applyTo: '**'",`description: 'Vesper orchestrator playbook \u2014 delegation law, purpose router, and pipelines. Binds the ${H} persona; see the scope block at the top.'`,"---",""].join(`
|
|
70
72
|
`),[s,...o]=r.split(`
|
|
71
73
|
`),i=o.join(`
|
|
72
74
|
`).replace(/^\n+/,"");return`${n}${s}
|
|
73
75
|
|
|
74
|
-
${
|
|
75
|
-
`)+
|
|
76
|
+
${rw()}${i}`}function ba(e,t){let{frontmatter:r,body:n}=Ze(e),s=hr(r,"description")||t;return["---","applyTo: '**'",`description: '${_d(s)}'`,"---",""].join(`
|
|
77
|
+
`)+To(n).replace(/^\n+/,"")}var uw=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 dw(e,t){let r=uw.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 pw=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 `"+H+"` 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 fw(e){return e.split(`
|
|
76
78
|
|
|
77
|
-
`).map(t=>{let r=
|
|
79
|
+
`).map(t=>{let r=pw.find(n=>t.includes(n.anchor));return r?r.replace(t):t}).join(`
|
|
78
80
|
|
|
79
|
-
`)}function
|
|
80
|
-
`)+
|
|
81
|
+
`)}function hw(e){let t=e.indexOf("This is a COMMITTED project agent"),r=(t===-1?e:e.slice(0,t)).trim();return`${To(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 $d(e){let{frontmatter:t,body:r}=Ze(e),n=hr(t,"description")||"Vesper super-orchestrator \u2014 routes every request to the specialist team.",o=["---",`description: '${_d(hw(n))}'`,`name: ${H}`,"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(`
|
|
82
|
+
`)+fw(To(r)).replace(/^\n+/,"");return dw(o,"the pickable orchestrator agent"),o}async function Sd(e,t){if(await w(e)){try{if(await Wn(e,"utf-8")===t)return"unchanged"}catch{}return await $(e,t,"utf-8"),"updated"}return await $(e,t,"utf-8"),"created"}async function Oo(e,{version:t}={}){await j(bd(e),{recursive:!0}),await j(ew(e),{recursive:!0}),await j(xd(e),{recursive:!0});let r={},n=[],s=Me(Vt,"agents",`${H}.md`);r.orchestratorAgent=await Sd(Me(e,wt),$d(await Wn(s,"utf-8"))),n.push(D({path:wt,host:"copilot",category:"catalog-agent",hash:await ye(Me(e,wt))}));for(let i of Ea){let a=Ee(i.name),c=Me(e,a),l=await Wn(Me(Te,i.source),"utf-8");i.seedOnce?(r[i.key]="skipped",await w(c)||(await $(c,ba(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 Sd(c,Ad(l)),n.push(D({path:a,host:"copilot",category:"playbook",hash:await ye(c)})))}r.contextTier="ensured",n.push(D({path:Ed,host:"copilot",category:"per-project-authored",hash:null}));let o=await ro(e);if(r.gates=o.created?`created (checks: ${o.checks.join(", ")||"none"})`:"skipped",n.push(D({path:se,host:"copilot",category:"per-project-authored",hash:null})),await J(e,n),t!==void 0){let i=await _(e);i.schemaVersion=de,i.frameworkVersion=t,await O(e,i)}return r}async function xa(e,{settingsEntries:t=[]}={}){let r=[],n=s=>Me(e,s);return await w(n(It))&&r.push(Q({path:It,host:"copilot",category:"settings",owns:{keys:[...Et],entries:[...t]}})),await w(n(is))&&r.push(Q({path:is,host:"copilot",category:"bootstrap-task",owns:{keys:[as]}})),r.length>0&&await J(e,r),r}function Cd(){return Cs()}async function Po(e,t){let r=Ts(t),{added:n}=await $r(e,[r]),s=new Set([...await ut(e),r.path]);return await xa(e,{settingsEntries:[...s]}),{name:t,path:r.path,added:n.includes(r.path)}}async function Bn(e,t=!0,{record:r=!0}={}){let n=await Zt(e,t,{record:r});return t&&r&&await J(e,[Q({path:tw,host:"copilot",category:"mcp-config",owns:{keys:[..._e]}})]),{...n,mcpPath:De(e)}}async function Td(e,{purgeProjectAuthored:t=!1}={}){let r=[],n=[],s=new Map(Y(await _(e)).filter(l=>l.host==="copilot").map(l=>[l.path,l])),o=await mw(),i=[wt,Ee(H)];for(let l of i){let d=await ue(Me(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=Y(await _(e)).some(l=>l.host!=="copilot"&&l.path===se&&l.category==="per-project-authored"),c=t?[...Ea.filter(l=>l.seedOnce).map(l=>Ee(l.name)),...a?[]:[se]]:[];for(let l of c){let d=Me(e,l);await w(d)&&(await vd(d,{force:!0}),r.push(l))}try{await Zy(bd(e))}catch{}return t&&await vd(xd(e),{recursive:!0,force:!0}),{removed:r,kept:n}}async function mw(){let e={};try{e[wt]=$d(await Wn(Me(Vt,"agents",`${H}.md`),"utf-8"))}catch{}let t=Ea.find(r=>!r.seedOnce);try{e[Ee(t.name)]=Ad(await Wn(Me(Te,t.source),"utf-8"))}catch{}return e}W();U();import{resolve as Yr,basename as Vw}from"node:path";import{confirm as Na}from"@inquirer/prompts";W();U();import{resolve as Ew,join as pe}from"node:path";import{rm as Kn,rmdir as bw,readFile as Ca,readdir as xw}from"node:fs/promises";he();W();U();import{readFile as _a,rm as gw}from"node:fs/promises";import{join as Io}from"node:path";he();var Id=Object.freeze(["i-have-adhd","ponytail"]),Od=Object.freeze(["vendored-body","vendored-activation"]);function yw(){return tr.flatMap(e=>[`.claude/skills/${e}`,`.vesper/skills/${e}`])}function jd(){return[...Id.map(e=>`.claude/rules/${e}.md`),...tr.map(e=>Ee(e))]}function Aa(){return[...yw(),...jd()].sort()}function $a(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 Rd=`# ADHD-friendly output (always on)
|
|
81
83
|
|
|
82
84
|
Shape every response so a reader with ADHD can act on it: lead with the next
|
|
83
85
|
concrete action (a command, path, or snippet \u2014 not preamble), keep it brief and
|
|
@@ -87,7 +89,7 @@ always win over brevity, and the harness/system prompt always outranks this rule
|
|
|
87
89
|
Follow the full \`i-have-adhd\` skill for the specifics
|
|
88
90
|
(\`.claude/skills/i-have-adhd/SKILL.md\`). It stays in effect for the whole
|
|
89
91
|
session until the reader says "stop adhd mode" or "normal mode".
|
|
90
|
-
`,
|
|
92
|
+
`,Ld=`# Ponytail: the laziest solution that works (always on)
|
|
91
93
|
|
|
92
94
|
Prefer the simplest, shortest, most minimal solution \u2014 but only after you
|
|
93
95
|
understand the problem and trace the flow. Climb the ladder, stop at the first
|
|
@@ -105,9 +107,9 @@ for \u2014 build it in full, no re-arguing. Intensity: \`/ponytail lite|full|ult
|
|
|
105
107
|
Follow the full \`ponytail\` skill for the specifics
|
|
106
108
|
(\`.claude/skills/ponytail/SKILL.md\`). It stays in effect for the
|
|
107
109
|
whole session until the user says "stop ponytail" or "normal mode".
|
|
108
|
-
`,
|
|
110
|
+
`,ww=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 vw(e){let t=e==="i-have-adhd"?Rd:Ld;return`${["---","applyTo: '**'",`description: '${ww[e].replace(/'/g,"''")}'`,"---",""].join(`
|
|
109
111
|
`)}
|
|
110
|
-
${t.split(`.claude/skills/${e}/`).join(`.vesper/skills/${e}/`)}`}function
|
|
112
|
+
${t.split(`.claude/skills/${e}/`).join(`.vesper/skills/${e}/`)}`}function Pd(e,t){return`${["---","applyTo: '**'",`description: '${Co(t||`Vendored skill "${e}", a reviewed snapshot pinned to an upstream commit and installed by Vesper.`)}'`,"---",""].join(`
|
|
111
113
|
`)}
|
|
112
114
|
# ${e} (vendored skill)
|
|
113
115
|
|
|
@@ -119,22 +121,22 @@ anything the skill covers, rather than working from memory.
|
|
|
119
121
|
Vesper places this skill but does not author it. A newer upstream arrives only with
|
|
120
122
|
a Vesper release that re-vendors it (a reviewed change); a file you edit is kept and
|
|
121
123
|
reported, never overwritten.
|
|
122
|
-
`}async function dw(e){let t=rr(e);if(!t)return null;try{let{frontmatter:r}=Ze(await Ea(Po(t.dir,"SKILL.md"),"utf-8")),n=r?hr(r,"description"):null;return n&&String(n).trim()||null}catch{return null}}async function pw(e){if(e===".claude/rules/i-have-adhd.md")return[Cd];if(e===".claude/rules/ponytail.md")return[Td];for(let t of tr)if(e===Se(t))return Ad.includes(t)?[uw(t)]:[_d(t,await dw(t)),_d(t,null)];return[]}async function Od(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 _(e),i=Y(o),a=f=>i.find(m=>m.path===f&&xd.includes(m.category))||null;for(let f of tr){let m=rr(f),y=m?await Ws(m.dir):{};for(let k of[`.claude/skills/${f}`,`.vesper/skills/${f}`]){let v=Po(e,k);if(!await w(v))continue;let S=a(k),A=S?.placedFiles??S?.syncedFiles,R=A&&typeof A=="object"&&Object.keys(A).length?{...A}:void 0,E={sourceFiles:y,...R?{sourceHashes:R}:{},sourceMatch:(X,Pe)=>Qi(Pe,`${k}/${X}`),anchor:"SKILL.md"},b=await xt(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 M=await $n(v,E);M.status==="removed"?r.removed.push(k):M.status!=="absent"&&r.kept.push({path:k,files:M.kept})}}for(let f of $d()){let m=Po(e,f);if(!await w(m))continue;let y=null;try{y=await Ea(m)}catch{y=null}if(y&&Qi(y,f)){await s(f),await aw(m,{force:!0}),r.removed.push(f);continue}let k=a(f)??{path:f,category:"vendored-activation",hash:null},v=await pw(f);if(!await Ri(m,k,{expected:v})){r.kept.push({path:f});continue}await s(f);let S=await ue(m,k,{expected:v});S==="removed"?r.removed.push(f):S!=="absent"&&r.kept.push({path:f})}let c=Po(e,"CLAUDE.md");if(await w(c)){let f=await Ea(c,"utf-8"),m=oa(f);ge(m,f)||(await $(c,m,"utf-8"),r.claudeMd=!0)}let l=await _(e),d=new Set(ba()),p=Y(l),h=p.filter(f=>!(d.has(f.path)&&xd.includes(f.category)));return r.rowsDropped=p.length-h.length,r.stylesConsent=xa(l),(r.rowsDropped>0||l.vendored!==void 0||l.adhd!==void 0)&&(l.manifest=lt(h),delete l.vendored,delete l.adhd,await O(e,l)),r}function Pd(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 Aa=class extends Error{constructor(t){super(t),this.name="HostCleanRefused",this.code="HOST_CLEAN_REFUSED"}};async function $a(e,t){if(t==="copilot"&&!await Cl(e)&&await gw(e)!==0)throw new Aa(`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 \`${yw}\` to re-record it granularly, then retry.`)}async function gw(e){return Y(await _(e)).filter(r=>r.host==="copilot"&&At[r.category]?.ownership==="whole-file").length}var yw="vespercli init --host copilot";async function Id(e,{from:t,to:r,snapshot:n}){await j(pe(e,".vesper"),{recursive:!0});let s={from:t,to:r,snapshot:n,startedAt:new Date().toISOString()};await er(pe(e,Ft),JSON.stringify(s,null,2))}async function Ca(e){await Bn(pe(e,Ft),{force:!0});let t=Ft.split("/").pop();try{for(let r of await mw(pe(e,".vesper")))r.startsWith(`${t}.`)&&r.endsWith(".tmp")&&await Bn(pe(e,".vesper",r),{force:!0})}catch{}}async function Ta(e){let t=await _(e),r=Y(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 ut(e),addedAssets:r.filter(n=>n.category==="added-asset").map(n=>n.path),namePrefix:typeof t.namePrefix=="string"?t.namePrefix:"",packs:[...new Set([...await xo(e,"claude"),...await xo(e,"copilot"),...xa(t)?["styles"]:[]])].sort()}}async function ww(e,t={}){let r=pe(e,".vscode"),n=async i=>{try{return bt(await _a(i,"utf-8"))}catch{return}},s=pe(r,"settings.json");if((await B(e)).type!==ae.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 Bn(s,{force:!0})}if((t.mcpServers?.length??0)>0){let i=Ve(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 Bn(i,{force:!0})}try{await hw(r)}catch{}}async function Kn(e,{purgeProjectAuthored:t=!1}={}){let r=await _(e),n=await sr(e,"claude"),{removed:s}=await kn(e);try{let i=await K(e);if(i[F]){let a=new Set(be),c=!1;for(let l of Object.keys(i[F]))a.has(l)||(delete i[F][l],c=!0);c&&await ne(e,i)}}catch{}await Qs(e,"copilot"),await bd(e,{purgeProjectAuthored:t}),await yn(e,bs,{removeFileIfEmpty:!0}),await ww(e,s);let o=fw(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 $(o,JSON.stringify(r,null,2),"utf-8")):await Bn(o,{force:!0})}catch{}}async function Io(e,t,r){let n=new Set(Y(await _(e)).map(o=>`${o.host}\0${o.path}`)),s=[];for(let o of t||[])!o||o.host!==r||At[o.category]?.ownership!=="whole-file"||$e.has(o.category)||n.has(`${o.host}\0${o.path}`)||await w(pe(e,o.path))&&s.push(o.path);return[...new Set(s)].sort()}async function Kr(e,t,r,n){let o=(await on(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 Yt(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 vw(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 jo(e,t,{keepPaths:r=[],purgeProjectAuthored:n=!1,fullTeardown:s=!1}={}){if(!G.includes(t))throw new Error(`cleanHost: host must be one of ${G.join(", ")} (received "${t}")`);let o=!!n;await $a(e,t),await Oa(e,t);let i=await Ta(e),{pruned:a}=await Il(e,r,{host:t,purgeProjectAuthored:o});t==="claude"?await Gr(e,{purgeProjectAuthored:o}):await Kn(e,{purgeProjectAuthored:o}),s&&(await Gn(e,t),t==="copilot"&&await dr(e));let c=await _(e);c.schemaVersion=de,c.manifest=Y(c).filter(d=>d.host!==t||!o&&$e.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(vw(d,t,s))continue;c.manifest.push(d)}else d.host===t&&!o&&$e.has(d.category)&&await w(pe(e,d.path))&&c.manifest.push(d);c.manifest=lt(c.manifest),i.mcp!==void 0?c.mcp=i.mcp:delete c.mcp,await O(e,c);let l=await Io(e,i.manifest,t);return{...i,pruned:a,retained:l}}async function Oa(e,t){if(t!=="claude")return[];if(!await Yt(e,"claude")&&!await cs(e,"claude"))return[];let r=new Set(Y(await _(e)).filter(a=>a.host==="claude").map(a=>a.path)),n=async(a,c)=>{try{let[l,d]=await Promise.all([_a(pe(e,a)),_a(c)]);return ge(l,d)}catch{return!1}},s=[],o=`.claude/agents/${H}.md`;!r.has(o)&&await n(o,pe(Vt,"agents",`${H}.md`))&&s.push(D({path:o,host:"claude",category:"catalog-agent",hash:await ye(pe(e,o))}));for(let a of jt){let c=`.claude/skills/${a}`;!r.has(c)&&await n(`${c}/SKILL.md`,pe(Vt,"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,pe(Ce,"vesper-orchestrator.md"))&&s.push(D({path:i,host:"claude",category:"playbook",hash:await ye(pe(e,i))}));for(let a of[".claude/rules/vesper-orchestration.md",".claude/rules/vesper-context.md"])!r.has(a)&&await w(pe(e,a))&&s.push(D({path:a,host:"claude",category:"per-project-authored",hash:null}));for(let a of await Kl(e,"claude"))r.has(a.path)||s.push(a);return s.length&&await J(e,s),s.map(a=>a.path)}function kw(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 Sw(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 jd(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 fr(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(!xe.includes(l))try{((t==="claude"?await uo(e,l):await Ir(e,l)).added?n.mcpServers.added:n.mcpServers.skipped).push(l)}catch{n.mcpServers.skipped.push(l)}let s=await Lr(e)||"",o=r.namePrefix??s,i=l=>o&&l.startsWith(o)?l.slice(o.length):l,a=[...(r.addedAssets||[]).map(kw).filter(Boolean).map(l=>({...l,name:i(l.name),source:"claude-record"})),...(r.settingsEntries||[]).map(Sw).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:g}=await Oo(e,d);(g?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 g=l==="prompts"?"commands":l,f=Ew(g,d,s);if(await w(pe(e,f))){await J(e,[D({path:f,host:"claude",category:"added-asset",hash:null})]),n.assets.kept.push(h);continue}await oo(g,d,{workspaceRoot:e,namePrefix:s}),n.assets.added.push(h)}}catch{n.assets.skipped.push(h)}}}return n}function Ew(e,t,r=""){if(e==="skills")return`.claude/skills/${t}`;let n=r&&!t.startsWith(r)?`${r}${t}`:t;return`.claude/${e}/${n}.md`}he();Me();U();import{lstat as bw,readFile as Rd,realpath as xw,rm as Ld,stat as _w}from"node:fs/promises";import{join as Nd,resolve as Aw}from"node:path";Qr();ot();function $w(e){return e.split(`
|
|
123
|
-
`).every(t=>{let r=t.trim();return r===""||r.startsWith("#")||/^exit\s+0\s*;?$/.test(r)})}async function Md(e){try{return await xw(e)}catch{return Aw(e)}}async function Cw(e){try{return(await _w(e)).isDirectory()}catch{return!1}}async function Tw(e,t,{gitVersion:r,resolveHooksDir:n=Pr}={}){let s={...qt(process.env),...vt},o=await Fs(e,{env:s,gitArgs:Or,gitVersion:r});if(o===null)return[{worktree:"(unknown)",host:null,why:"git worktree list failed"}];let i=await St(t.dir),a=await Md(t.top??e),c=[];for(let l of Ms(o.out)){if(l.bare||!l.worktree||await Md(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 Cw(l.worktree)){c.push({worktree:l.worktree,host:null,why:"missing"});continue}let p=await n(l.worktree,{env:s,gitArgs:Or});if(!p.dir&&["machine-wide","not-a-directory","husky-v9"].includes(p.reason)||p.dir&&!p.default&&await St(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 z(l.worktree,{env:s,gitArgs:Or})}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 Pa(e,{gitVersion:t,resolveHooksDir:r}={}){let n=Object.fromEntries(Ye.map(c=>[c,null])),s=await Pr(e);if(!s.dir)return{action:"none",hooks:n,reason:s.reason};let o=[];for(let c of Ye){let l=Nd(s.dir,c);try{(await Rd(l)).toString("latin1").includes(mt)&&o.push(l)}catch{}}if(!o.length)return{action:"none",hooks:n};let i=await z(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 Tw(e,s,{gitVersion:t,...r?{resolveHooksDir:r}:{}});if(a.length)return{action:"kept",hooks:n,paths:o,keptFor:a};for(let c of Ye){let l=Nd(s.dir,c),d=await Vs(l);if(!d.path)continue;let p=await St(d.path);if(!Nt(p,s.roots)||await br(p,s))continue;let h;try{h=await Rd(d.path)}catch{continue}let g=h.toString("latin1");if(!g.includes(mt))continue;let f=zt(g);if(f!==null)if($w(f)){await Ld(d.path,{force:!0});try{(await bw(l)).isSymbolicLink()&&l!==d.path&&await Ld(l,{force:!0})}catch{}n[c]="file"}else await Xt(d.path,Buffer.from(f,"latin1")),n[c]="region"}return{action:Object.values(n).some(Boolean)?"removed":"none",hooks:n}}function Ia(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 Fd=".claude/rules/vesper-orchestrator.md";async function Ra(e,t,{purge:r=!1}={}){if(await sr(e,t)||await Yt(e,t)||await cs(e,t))return!0;if(r){if((await Ae(e)).some(s=>s.host===t&&$e.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(zr(e,s)))return!0}}return!1}async function Ro(e){try{let t=await Pa(e),r=Ia(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 Dd(e,t){await Gn(e,t),await Gn(e,ha(t)),await dr(e)==="kept"&&u.warn(Hr());try{let r=await Pa(e),n=Ia(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 wi(e)}async function Pw(e={}){let t=zr(e.path||process.cwd()),r=!!e.purgeKnowledge;if(!await Ra(t,"claude",{purge:r})){u.warn("Claude Code target is not initialized in this workspace."),await Ro(t);return}if(!e.yes&&!await ja({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 Oa(t,"claude");let n=await Ae(t),s=await w(zr(t,Fd)),{kept:o=[],knowledgeKept:i=[]}=await Gr(t,{purgeProjectAuthored:r})||{};await Dd(t,"claude");let a=await Io(t,n,"claude"),c=s&&!await w(zr(t,Fd));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, .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 Kr(t,a,"claude",u)}async function Iw(e={}){let t=zr(e.path||process.cwd()),r=!!e.purgeKnowledge;if(!await Ra(t,"copilot",{purge:r})){u.warn("Vesper is not initialized in this workspace."),await Ro(t);return}let n=await ct(t),s=jw(n);if(!e.yes&&!await ja({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 _(t),i=await B(t),a=await sr(t,"claude"),c=await Ae(t);await Kn(t,{purgeProjectAuthored:r}),await Dd(t,"copilot");let l=await Io(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===ae.WORKSPACE_FILE||i.type===ae.WORKSPACE_FILE?u.info(`Cleaned: ${Ow(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 Kr(t,l,"copilot",u)}function jw(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 Vd(e,t,r){return t==="claude"?Pw({...r,path:e}):Iw({...r,path:e})}async function Rw(e,t,r){let n=!!r.purgeKnowledge;if(!await Ra(e,t,{purge:n})){u.info(`No ${t} artifacts found to clean \u2014 nothing to do.`);return}if(!r.yes&&!await ja({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 jo(e,t,{fullTeardown:!1,purgeProjectAuthored:n});console.log(),u.success(`Foreign ${t} residue removed.`),await Kr(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 Gd(e={}){try{let t=zr(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();G.includes(i)||(u.error(`Unknown target: ${e.target}. Valid: ${G.join(", ")}.`),process.exit(1)),u.warn("`--target` is deprecated; use `--host` instead. Mapping to `--host "+i+"`."),r=i}let n=await ce(t),o=await Rr(t)??(n.length===1?n[0]:null);if(!r){if(n.length>1&&(u.error(zs),process.exit(1)),!o){let i=await nr(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 Ro(t);return}u.warn("Vesper is not initialized in this workspace."),await Ro(t);return}return await Vd(t,o,e)}return o&&o!==r?await Rw(t,r,e):await Vd(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)}}he();W();import{lstat as Lo,readFile as fe,readdir as Fo,readlink as zn,rmdir as Bd}from"node:fs/promises";import{createHash as Lw}from"node:crypto";import{basename as Kd,dirname as La,isAbsolute as No,join as x,relative as Na,sep as Jn}from"node:path";import{homedir as Yn}from"node:os";U();he();rt();var Nw=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",ur]);function Mo(e){return Nw.some(t=>e===t||e.startsWith(`${t}/`))}var zd=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"]),Jd=Object.freeze([".claude",".vscode",".vesper",".github"]);async function Mw(e,t){let r,n;try{[r,n]=await Promise.all([Lo(e),Lo(t)])}catch{return!1}if(r.isSymbolicLink()||n.isSymbolicLink())return r.isSymbolicLink()&&n.isSymbolicLink()&&await zn(e)===await zn(t);if(r.isFile()&&n.isFile())return(await fe(e)).equals(await fe(t));if(!r.isDirectory()||!n.isDirectory())return!1;let[s,o]=await Promise.all([Xe(e),Xe(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 fe(x(e,a))).equals(await fe(x(t,a))))return!1;for(let a of s.others)try{if(await zn(x(e,a))!==await zn(x(t,a)))return!1}catch{return!1}return!0}async function Hd(e){let t=x(e,ur);await j(t,{recursive:!0});let r=x(t,".gitignore"),n=null;try{n=await fe(r,"utf-8")}catch{n=null}n!==`*
|
|
124
|
+
`}async function kw(e){let t=rr(e);if(!t)return null;try{let{frontmatter:r}=Ze(await _a(Io(t.dir,"SKILL.md"),"utf-8")),n=r?hr(r,"description"):null;return n&&String(n).trim()||null}catch{return null}}async function Sw(e){if(e===".claude/rules/i-have-adhd.md")return[Rd];if(e===".claude/rules/ponytail.md")return[Ld];for(let t of tr)if(e===Ee(t))return Id.includes(t)?[vw(t)]:[Pd(t,await kw(t)),Pd(t,null)];return[]}async function Nd(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 _(e),i=Y(o),a=f=>i.find(m=>m.path===f&&Od.includes(m.category))||null;for(let f of tr){let m=rr(f),y=m?await Bs(m.dir):{};for(let k of[`.claude/skills/${f}`,`.vesper/skills/${f}`]){let v=Io(e,k);if(!await w(v))continue;let S=a(k),A=S?.placedFiles??S?.syncedFiles,L=A&&typeof A=="object"&&Object.keys(A).length?{...A}:void 0,E={sourceFiles:y,...L?{sourceHashes:L}:{},sourceMatch:(X,Ie)=>ea(Ie,`${k}/${X}`),anchor:"SKILL.md"},b=await xt(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 M=await Tn(v,E);M.status==="removed"?r.removed.push(k):M.status!=="absent"&&r.kept.push({path:k,files:M.kept})}}for(let f of jd()){let m=Io(e,f);if(!await w(m))continue;let y=null;try{y=await _a(m)}catch{y=null}if(y&&ea(y,f)){await s(f),await gw(m,{force:!0}),r.removed.push(f);continue}let k=a(f)??{path:f,category:"vendored-activation",hash:null},v=await Sw(f);if(!await Ni(m,k,{expected:v})){r.kept.push({path:f});continue}await s(f);let S=await ue(m,k,{expected:v});S==="removed"?r.removed.push(f):S!=="absent"&&r.kept.push({path:f})}let c=Io(e,"CLAUDE.md");if(await w(c)){let f=await _a(c,"utf-8"),m=aa(f);ge(m,f)||(await $(c,m,"utf-8"),r.claudeMd=!0)}let l=await _(e),d=new Set(Aa()),p=Y(l),h=p.filter(f=>!(d.has(f.path)&&Od.includes(f.category)));return r.rowsDropped=p.length-h.length,r.stylesConsent=$a(l),(r.rowsDropped>0||l.vendored!==void 0||l.adhd!==void 0)&&(l.manifest=lt(h),delete l.vendored,delete l.adhd,await O(e,l)),r}function Md(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 Ta=class extends Error{constructor(t){super(t),this.name="HostCleanRefused",this.code="HOST_CLEAN_REFUSED"}};async function Oa(e,t){if(t==="copilot"&&!await Ol(e)&&await _w(e)!==0)throw new Ta(`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 \`${Aw}\` to re-record it granularly, then retry.`)}async function _w(e){return Y(await _(e)).filter(r=>r.host==="copilot"&&At[r.category]?.ownership==="whole-file").length}var Aw="vespercli init --host copilot";async function Fd(e,{from:t,to:r,snapshot:n}){await j(pe(e,".vesper"),{recursive:!0});let s={from:t,to:r,snapshot:n,startedAt:new Date().toISOString()};await er(pe(e,Ft),JSON.stringify(s,null,2))}async function Pa(e){await Kn(pe(e,Ft),{force:!0});let t=Ft.split("/").pop();try{for(let r of await xw(pe(e,".vesper")))r.startsWith(`${t}.`)&&r.endsWith(".tmp")&&await Kn(pe(e,".vesper",r),{force:!0})}catch{}}async function Ia(e){let t=await _(e),r=Y(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 ut(e),addedAssets:r.filter(n=>n.category==="added-asset").map(n=>n.path),namePrefix:typeof t.namePrefix=="string"?t.namePrefix:"",packs:[...new Set([...await _o(e,"claude"),...await _o(e,"copilot"),...$a(t)?["styles"]:[]])].sort()}}async function $w(e,t={}){let r=pe(e,".vscode"),n=async i=>{try{return bt(await Ca(i,"utf-8"))}catch{return}},s=pe(r,"settings.json");if((await B(e)).type!==ae.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 Kn(s,{force:!0})}if((t.mcpServers?.length??0)>0){let i=De(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 Kn(i,{force:!0})}try{await bw(r)}catch{}}async function zn(e,{purgeProjectAuthored:t=!1}={}){let r=await _(e),n=await sr(e,"claude"),{removed:s}=await En(e);try{let i=await K(e);if(i[F]){let a=new Set(xe),c=!1;for(let l of Object.keys(i[F]))a.has(l)||(delete i[F][l],c=!0);c&&await ne(e,i)}}catch{}await eo(e,"copilot"),await Td(e,{purgeProjectAuthored:t}),await vn(e,xs,{removeFileIfEmpty:!0}),await $w(e,s);let o=Ew(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 $(o,JSON.stringify(r,null,2),"utf-8")):await Kn(o,{force:!0})}catch{}}async function jo(e,t,r){let n=new Set(Y(await _(e)).map(o=>`${o.host}\0${o.path}`)),s=[];for(let o of t||[])!o||o.host!==r||At[o.category]?.ownership!=="whole-file"||Ce.has(o.category)||n.has(`${o.host}\0${o.path}`)||await w(pe(e,o.path))&&s.push(o.path);return[...new Set(s)].sort()}async function Jr(e,t,r,n){let o=(await cn(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 Yt(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 Cw(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 Ro(e,t,{keepPaths:r=[],purgeProjectAuthored:n=!1,fullTeardown:s=!1}={}){if(!G.includes(t))throw new Error(`cleanHost: host must be one of ${G.join(", ")} (received "${t}")`);let o=!!n;await Oa(e,t),await ja(e,t);let i=await Ia(e),{pruned:a}=await Rl(e,r,{host:t,purgeProjectAuthored:o});t==="claude"?await Ur(e,{purgeProjectAuthored:o}):await zn(e,{purgeProjectAuthored:o}),s&&(await Hn(e,t),t==="copilot"&&await dr(e));let c=await _(e);c.schemaVersion=de,c.manifest=Y(c).filter(d=>d.host!==t||!o&&Ce.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(Cw(d,t,s))continue;c.manifest.push(d)}else d.host===t&&!o&&Ce.has(d.category)&&await w(pe(e,d.path))&&c.manifest.push(d);c.manifest=lt(c.manifest),i.mcp!==void 0?c.mcp=i.mcp:delete c.mcp,await O(e,c);let l=await jo(e,i.manifest,t);return{...i,pruned:a,retained:l}}async function ja(e,t){if(t!=="claude")return[];if(!await Yt(e,"claude")&&!await ls(e,"claude"))return[];let r=new Set(Y(await _(e)).filter(a=>a.host==="claude").map(a=>a.path)),n=async(a,c)=>{try{let[l,d]=await Promise.all([Ca(pe(e,a)),Ca(c)]);return ge(l,d)}catch{return!1}},s=[],o=`.claude/agents/${H}.md`;!r.has(o)&&await n(o,pe(Vt,"agents",`${H}.md`))&&s.push(D({path:o,host:"claude",category:"catalog-agent",hash:await ye(pe(e,o))}));for(let a of jt){let c=`.claude/skills/${a}`;!r.has(c)&&await n(`${c}/SKILL.md`,pe(Vt,"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,pe(Te,"vesper-orchestrator.md"))&&s.push(D({path:i,host:"claude",category:"playbook",hash:await ye(pe(e,i))}));for(let a of[".claude/rules/vesper-orchestration.md",".claude/rules/vesper-context.md"])!r.has(a)&&await w(pe(e,a))&&s.push(D({path:a,host:"claude",category:"per-project-authored",hash:null}));for(let a of await Ql(e,"claude"))r.has(a.path)||s.push(a);return s.length&&await J(e,s),s.map(a=>a.path)}function Tw(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 Ow(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 Vd(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 fr(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(!_e.includes(l))try{((t==="claude"?await fo(e,l):await Ir(e,l)).added?n.mcpServers.added:n.mcpServers.skipped).push(l)}catch{n.mcpServers.skipped.push(l)}let s=await Lr(e)||"",o=r.namePrefix??s,i=l=>o&&l.startsWith(o)?l.slice(o.length):l,a=[...(r.addedAssets||[]).map(Tw).filter(Boolean).map(l=>({...l,name:i(l.name),source:"claude-record"})),...(r.settingsEntries||[]).map(Ow).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:g}=await Po(e,d);(g?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 g=l==="prompts"?"commands":l,f=Pw(g,d,s);if(await w(pe(e,f))){await J(e,[D({path:f,host:"claude",category:"added-asset",hash:null})]),n.assets.kept.push(h);continue}await ao(g,d,{workspaceRoot:e,namePrefix:s}),n.assets.added.push(h)}}catch{n.assets.skipped.push(h)}}}return n}function Pw(e,t,r=""){if(e==="skills")return`.claude/skills/${t}`;let n=r&&!t.startsWith(r)?`${r}${t}`:t;return`.claude/${e}/${n}.md`}he();Fe();U();import{lstat as Iw,readFile as Dd,realpath as jw,rm as Gd,stat as Rw}from"node:fs/promises";import{join as Hd,resolve as Lw}from"node:path";en();ot();function Nw(e){return e.split(`
|
|
125
|
+
`).every(t=>{let r=t.trim();return r===""||r.startsWith("#")||/^exit\s+0\s*;?$/.test(r)})}async function Ud(e){try{return await jw(e)}catch{return Lw(e)}}async function Mw(e){try{return(await Rw(e)).isDirectory()}catch{return!1}}async function Fw(e,t,{gitVersion:r,resolveHooksDir:n=Pr}={}){let s={...qt(process.env),...vt},o=await Vs(e,{env:s,gitArgs:Or,gitVersion:r});if(o===null)return[{worktree:"(unknown)",host:null,why:"git worktree list failed"}];let i=await St(t.dir),a=await Ud(t.top??e),c=[];for(let l of Fs(o.out)){if(l.bare||!l.worktree||await Ud(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 Mw(l.worktree)){c.push({worktree:l.worktree,host:null,why:"missing"});continue}let p=await n(l.worktree,{env:s,gitArgs:Or});if(!p.dir&&["machine-wide","not-a-directory","husky-v9"].includes(p.reason)||p.dir&&!p.default&&await St(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 z(l.worktree,{env:s,gitArgs:Or})}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 Ra(e,{gitVersion:t,resolveHooksDir:r}={}){let n=Object.fromEntries(Ye.map(c=>[c,null])),s=await Pr(e);if(!s.dir)return{action:"none",hooks:n,reason:s.reason};let o=[];for(let c of Ye){let l=Hd(s.dir,c);try{(await Dd(l)).toString("latin1").includes(mt)&&o.push(l)}catch{}}if(!o.length)return{action:"none",hooks:n};let i=await z(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 Fw(e,s,{gitVersion:t,...r?{resolveHooksDir:r}:{}});if(a.length)return{action:"kept",hooks:n,paths:o,keptFor:a};for(let c of Ye){let l=Hd(s.dir,c),d=await Ds(l);if(!d.path)continue;let p=await St(d.path);if(!Nt(p,s.roots)||await br(p,s))continue;let h;try{h=await Dd(d.path)}catch{continue}let g=h.toString("latin1");if(!g.includes(mt))continue;let f=zt(g);if(f!==null)if(Nw(f)){await Gd(d.path,{force:!0});try{(await Iw(l)).isSymbolicLink()&&l!==d.path&&await Gd(l,{force:!0})}catch{}n[c]="file"}else await Xt(d.path,Buffer.from(f,"latin1")),n[c]="region"}return{action:Object.values(n).some(Boolean)?"removed":"none",hooks:n}}function La(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 Wd=".claude/rules/vesper-orchestrator.md";async function Ma(e,t,{purge:r=!1}={}){if(await sr(e,t)||await Yt(e,t)||await ls(e,t))return!0;if(r){if((await $e(e)).some(s=>s.host===t&&Ce.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(Yr(e,s)))return!0}}return!1}async function Lo(e){try{let t=await Ra(e),r=La(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 Kd(e,t){await Hn(e,t),await Hn(e,ga(t)),await dr(e)==="kept"&&u.warn(Wr());try{let r=await Ra(e),n=La(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 ki(e)}async function Dw(e={}){let t=Yr(e.path||process.cwd()),r=!!e.purgeKnowledge;if(!await Ma(t,"claude",{purge:r})){u.warn("Claude Code target is not initialized in this workspace."),await Lo(t);return}if(!e.yes&&!await Na({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 ja(t,"claude");let n=await $e(t),s=await w(Yr(t,Wd)),{kept:o=[],knowledgeKept:i=[]}=await Ur(t,{purgeProjectAuthored:r})||{};await Kd(t,"claude");let a=await jo(t,n,"claude"),c=s&&!await w(Yr(t,Wd));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, .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 Jr(t,a,"claude",u)}async function Gw(e={}){let t=Yr(e.path||process.cwd()),r=!!e.purgeKnowledge;if(!await Ma(t,"copilot",{purge:r})){u.warn("Vesper is not initialized in this workspace."),await Lo(t);return}let n=await ct(t),s=Hw(n);if(!e.yes&&!await Na({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 _(t),i=await B(t),a=await sr(t,"claude"),c=await $e(t);await zn(t,{purgeProjectAuthored:r}),await Kd(t,"copilot");let l=await jo(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===ae.WORKSPACE_FILE||i.type===ae.WORKSPACE_FILE?u.info(`Cleaned: ${Vw(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 Jr(t,l,"copilot",u)}function Hw(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 Bd(e,t,r){return t==="claude"?Dw({...r,path:e}):Gw({...r,path:e})}async function Uw(e,t,r){let n=!!r.purgeKnowledge;if(!await Ma(e,t,{purge:n})){u.info(`No ${t} artifacts found to clean \u2014 nothing to do.`);return}if(!r.yes&&!await Na({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 Ro(e,t,{fullTeardown:!1,purgeProjectAuthored:n});console.log(),u.success(`Foreign ${t} residue removed.`),await Jr(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 zd(e={}){try{let t=Yr(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();G.includes(i)||(u.error(`Unknown target: ${e.target}. Valid: ${G.join(", ")}.`),process.exit(1)),u.warn("`--target` is deprecated; use `--host` instead. Mapping to `--host "+i+"`."),r=i}let n=await ce(t),o=await Rr(t)??(n.length===1?n[0]:null);if(!r){if(n.length>1&&(u.error(Js),process.exit(1)),!o){let i=await nr(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 Lo(t);return}u.warn("Vesper is not initialized in this workspace."),await Lo(t);return}return await Bd(t,o,e)}return o&&o!==r?await Uw(t,r,e):await Bd(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)}}he();W();import{lstat as No,readFile as fe,readdir as Vo,readlink as Jn,rmdir as Xd}from"node:fs/promises";import{createHash as Ww}from"node:crypto";import{basename as Qd,dirname as Fa,isAbsolute as Mo,join as x,relative as Va,sep as Yn}from"node:path";import{homedir as qn}from"node:os";U();he();rt();var Bw=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",ur]);function Fo(e){return Bw.some(t=>e===t||e.startsWith(`${t}/`))}var Zd=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"]),ep=Object.freeze([".claude",".vscode",".vesper",".github"]);async function Kw(e,t){let r,n;try{[r,n]=await Promise.all([No(e),No(t)])}catch{return!1}if(r.isSymbolicLink()||n.isSymbolicLink())return r.isSymbolicLink()&&n.isSymbolicLink()&&await Jn(e)===await Jn(t);if(r.isFile()&&n.isFile())return(await fe(e)).equals(await fe(t));if(!r.isDirectory()||!n.isDirectory())return!1;let[s,o]=await Promise.all([Xe(e),Xe(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 fe(x(e,a))).equals(await fe(x(t,a))))return!1;for(let a of s.others)try{if(await Jn(x(e,a))!==await Jn(x(t,a)))return!1}catch{return!1}return!0}async function Jd(e){let t=x(e,ur);await j(t,{recursive:!0});let r=x(t,".gitignore"),n=null;try{n=await fe(r,"utf-8")}catch{n=null}n!==`*
|
|
124
126
|
`&&await $(r,`*
|
|
125
|
-
`,"utf-8")}async function
|
|
126
|
-
`,"utf-8"),g},async snapshot(c){return i.has(c)||(i.add(c),!await w(x(e,c)))?null:a("rewritten",c,x(e,c))},async writeSidecar(c,l){return await
|
|
127
|
+
`,"utf-8")}async function tp(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(Yn).join("/");if(!s||Mo(s)||s.split("/").includes(".."))throw new Error(`backupPath: unsafe relative path "${r}"`);let o=x(e,t,s);if(await w(o))throw new Error(`backupPath: refusing to overwrite an existing backup at ${o}`);if(await j(Fa(o),{recursive:!0}),await Cn(n,o,{recursive:!0,errorOnExist:!0,force:!1,verbatimSymlinks:!0,preserveTimestamps:!0}),!await Kw(n,o))throw new Error(`backupPath: the backup of ${n} at ${o} is not byte-identical \u2014 nothing was removed`);return o}function Da(e,{now:t=new Date,homeDir:r=qn()}={}){let n=t.toISOString().replace(/[:.]/g,"-"),s=x(e,ur,n),o=[],i=new Set,a=async(c,l,d)=>{await Jd(e);let p=await tp(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,x(e,c)),home:c=>a("home",Va(r,c).split(Yn).join("/"),c),async nestedConfig(c){let l=Va(e,c).split(Yn).join("/");if(l&&!l.startsWith("..")&&!Mo(l))return a("project",l,c);let d=x(s,rp),p=[];try{p=JSON.parse(await fe(d,"utf-8"))}catch{p=[]}let h=`${p.length}/${Qd(c)}`,g=await a("outside",h,c);return p.push({original:c,backup:x("outside",h).split(Yn).join("/")}),await $(d,`${JSON.stringify(p,null,2)}
|
|
128
|
+
`,"utf-8"),g},async snapshot(c){return i.has(c)||(i.add(c),!await w(x(e,c)))?null:a("rewritten",c,x(e,c))},async writeSidecar(c,l){return await Jd(e),await j(s,{recursive:!0}),await $(x(s,c),l,"utf-8"),x(s,c)},restoreCommands(){let c=new Set(o.map(d=>d.sourceRoot)),l=[];return c.has("project")&&l.push(`cp -R "${x(s,"project")}/." "${e}/"`),c.has("home")&&l.push(`cp -R "${x(s,"home")}/." "${r}/"`),l}}}var rp="outside.json";async function Do(e){let t=x(e,ur),r=[];try{r=(await Vo(t,{withFileTypes:!0})).filter(s=>s.isDirectory()).map(s=>s.name).sort()}catch{r=[]}let n=[];for(let s of r){let o=x(t,s),i=async h=>{try{return JSON.parse(await fe(x(o,h),"utf-8"))}catch{return null}},a=await i("kept.json"),c=await i("rollback.json"),l=await i(rp),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(x(o,"project")),home:await w(x(o,"home")),rewritten:await w(x(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(x(o,Ha))&&await w(x(o,Ua)),guidancePrinted:d?typeof c.guidancePrinted=="boolean"?c.guidancePrinted:p==="finished":!1})}return n}async function np(e,t=".md"){try{return(await Vo(e,{withFileTypes:!0})).filter(r=>r.isFile()&&r.name.endsWith(t)).map(r=>r.name).sort()}catch{return[]}}async function zw(e){try{return(await Vo(e,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name).sort()}catch{return[]}}async function sp(e){try{return await fe(e)}catch{return null}}var Jw=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 op(e,t){let r=new Set(t.catalogManifest),n={record:[],keep:[]},s=new Set([...jt,...tr]);for(let[o,i]of[["agents","catalog-agent"],["commands","catalog-command"]])for(let a of await np(x(e,".claude",o))){if(o==="agents"&&a===`${H}.md`)continue;let c=`.claude/${o}/${a}`,l=await sp(x(e,c));if(!l)continue;let d=r.has(c)?1:2;so(l,`${o}/${a}`,{namePrefix:t.namePrefix})?n.record.push({rel:c,kind:"file",tier:d,entry:D({path:c,host:"claude",category:i,hash:Qe(l)})}):(r.has(c)||oo(o,a,t.namePrefix))&&n.keep.push({rel:c,reason:"edited-catalog"})}for(let o of await zw(x(e,".claude","skills"))){if(s.has(o))continue;let i=`.claude/skills/${o}`,a=du(o);if(!a&&!r.has(i))continue;let c=a?await xt(x(e,i),{sourceLfHashes:a}):{status:"none",proven:[]};if(c.status==="classified"&&c.proven.length){let l={};for(let d of c.proven)l[d]=Qe(await fe(x(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 Yd(e){let{frontmatter:t}=Ze(await fe(x(Te,e),"utf-8"));return t===null?"":`---
|
|
127
129
|
${t}
|
|
128
130
|
---
|
|
129
131
|
|
|
130
|
-
`}function
|
|
132
|
+
`}function Yw(e){let{frontmatter:t}=Ze(e);return/Vesper orchestration/.test(hr(t,"description")||"")}function qw(e){let t=e.split(`
|
|
131
133
|
`).slice(0,40).join(`
|
|
132
|
-
`);return/^#\s*Vesper\b/m.test(t)||t.includes(".vesper/")||t.includes(".claude/vesper/context")}async function
|
|
133
|
-
`).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 V(["-c","core.quotepath=off",...i],{cwd:e})))n.add(c),a&&a.add(c);return{inGit:!0,dirty:[...n].sort(),staged:[...s].sort()}}function
|
|
134
|
+
`);return/^#\s*Vesper\b/m.test(t)||t.includes(".vesper/")||t.includes(".claude/vesper/context")}async function ip(e){return await np(e,".code-workspace")}async function ap(e,{record:t}={}){let r=t||await vo(e),n=await op(e,r),s=new Set([...Zd,...await ip(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 Aa())s.add(o);return[...s].sort()}async function Ga(e){let t=await V(["rev-parse","--git-path","hooks"],{cwd:e});if(!t)return null;let n=(Mo(t)?Va(e,t):t).split(Yn).join("/");return!n||n.startsWith("..")||Mo(n)?null:n}async function cp(e){return await V(["rev-parse","--is-inside-work-tree"],{cwd:e})==="true"}async function lp(e,{record:t}={}){if(!await cp(e))return{inGit:!1,dirty:[],staged:[]};let r=await ap(e,{record:t}),n=new Set,s=new Set,o=i=>i?i.split(`
|
|
135
|
+
`).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 V(["-c","core.quotepath=off",...i],{cwd:e})))n.add(c),a&&a.add(c);return{inGit:!0,dirty:[...n].sort(),staged:[...s].sort()}}function up(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 Xw(e){let t=new Set,r=s=>Fo(s)||/^\.vesper\/index\.db/.test(s),n=await Ga(e);for(let s of[...ep,...n?[n]:[]]){let o;try{o=await Xe(x(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 Vo(e,{withFileTypes:!0}))(s.isFile()||s.isSymbolicLink())&&t.add(s.name)}catch{}return t}var dp="written.log",pp="no-hooks",Ha="created.sha256",Ua="remove-created.sh",Qw=`#!/bin/sh
|
|
134
136
|
# Written by vespercli (1.x migration rollback). Run from the workspace root.
|
|
135
137
|
# Removes the files this migration created, ONLY while they still hold the bytes it wrote.
|
|
136
138
|
# A file changed since is KEPT and listed below: review it and delete it yourself.
|
|
137
|
-
list="$(dirname -- "$0")/${
|
|
139
|
+
list="$(dirname -- "$0")/${Ha}"
|
|
138
140
|
kept=0
|
|
139
141
|
tab="$(printf ' ')"
|
|
140
142
|
while IFS="$tab" read -r want f; do
|
|
@@ -157,37 +159,37 @@ if [ "$kept" -gt 0 ]; then
|
|
|
157
159
|
echo "$kept file(s) this migration created were changed since and were NOT removed - review them and delete them yourself." >&2
|
|
158
160
|
fi
|
|
159
161
|
exit 0
|
|
160
|
-
`;async function
|
|
161
|
-
`))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
|
|
162
|
-
`)}async function
|
|
163
|
-
`).map(h=>h.trim()).filter(h=>h&&!
|
|
162
|
+
`;async function Wa(e){let t="";try{t=await fe(x(e,dp),"utf-8")}catch{return[]}let r=[];for(let n of t.split(`
|
|
163
|
+
`))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 Zw(e,t){let r=[];for(let[n,s]of await Wa(t)){if(r.push([n,s]),s!==$n)continue;let o=null;try{o=await No(x(e,n))}catch{o=null}if(!o?.isDirectory())continue;let i=null;try{i=await Xe(x(e,n))}catch{i=null}for(let a of i?[...i.files,...i.others]:[])r.push([`${n}/${a}`,$n])}return r}async function fp(e){let t;try{t=await No(e)}catch{return null}return t.isSymbolicLink()?`link:${await Jn(e)}`:t.isFile()?Ww("sha256").update(await fe(e)).digest("hex"):null}async function Ba(e,t){let r=x(e,"rollback.json"),n;try{n=JSON.parse(await fe(r,"utf-8"))}catch{return}await er(r,`${JSON.stringify({...n,...t},null,2)}
|
|
164
|
+
`)}async function Go(e){return await V(["rev-parse","HEAD"],{cwd:e})||null}async function ev(e){let t=(await Do(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 hp(e){let t=await ev(e);return t&&(t.status==="started"||t.status==="finished"&&!t.guidancePrinted)?t:null}async function mp(e){for(let t of e.members)await Ba(t.dir,{status:"abandoned",guidancePrinted:!0});return e.members.map(t=>t.dir)}async function gp(e,t,{dirty:r,staged:n=[]}){let s=new Map;for(let c of t.members)for(let[l,d]of await Wa(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 fp(x(e,c));l===null?o.has(c)||a.push(c):s.get(c)!==l&&a.push(c)}return a}async function Ka(e,t,{record:r,previousVersion:n=null,chain:s=null,preCreated:o=[]}={}){let i=await cp(e),a=null,c=[];if(i){a=await Go(e);let d=await ap(e,{record:r}),p=a?await V(["-c","core.quotepath=off","ls-files","--",...d],{cwd:e}):null;c=p?p.split(`
|
|
165
|
+
`).map(h=>h.trim()).filter(h=>h&&!Fo(h)).sort():[]}let l={version:2,startedAt:new Date().toISOString(),head:a,trackedPaths:c,previousVersion:n||s?.root.previousVersion||null,before:[...await Xw(e)].sort(),chainRoot:s?s.root.chainRoot:Qd(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(`
|
|
164
166
|
`)}
|
|
165
167
|
`),await t.writeSidecar("rollback.json",`${JSON.stringify(l,null,2)}
|
|
166
|
-
`),
|
|
168
|
+
`),Oi({root:e,log:x(t.dir,dp),exclude:Fo}),l}function za(){Oi(null)}async function Ja(e,t){za();let r=await Do(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 Ga(e),a=v=>!v.includes("/")||ep.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,g=new Map;for(let v of s)for(let[S,A]of await Zw(e,v.dir))p.add(S),g.set(S,A),v!==n&&h.add(S);let f=[],m=[];for(let v of[...p].sort()){if(!a(v)||Fo(v)||l.has(v)||d.has(v)&&!h.has(v))continue;let S=await fp(x(e,v));if(S===null)continue;f.push(v);let A=g.get(v);m.push([A===$n?S:A,v])}await $(x(n.dir,"created.txt"),f.length?`${f.join(`
|
|
167
169
|
`)}
|
|
168
|
-
`:"","utf-8"),await $(x(n.dir,
|
|
169
|
-
`).join(""),"utf-8"),await $(x(n.dir,
|
|
170
|
-
`)}async function
|
|
171
|
-
`;return await $(i,a,{encoding:"utf-8",flag:"a"}),{rel:`${
|
|
172
|
-
`))if(d.trim()!=="")try{let p=JSON.parse(d);if(!p||typeof p!="object"||Array.isArray(p)){i+=1;continue}o.push({...p,slug:
|
|
173
|
-
`).map(o=>o.trim()).find(o=>/^[0-9a-f]{40}\s+HEAD$/.test(o));return s?s.slice(0,40):null}async function Ko({assetsDir:e,timeoutMs:t=Bo,env:r}={}){let n=[];for(let{pack:s,skill:o,record:i}of await pl(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 nv(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 $p(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.`}Me();var Cp=["list","enable","disable","sync","upstream"];function ov(e,{log:t=console.log}={}){if(t(),t(oe.bold("Third-party pack skills \u2014 upstream check")),t(oe.dim("Pinned = the commit the shipped snapshot was taken at (UPSTREAM.json); remote = upstream HEAD now.")),t(),!e.length){t(oe.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"?oe.yellow("newer upstream"):s.status==="current"?oe.green("current"):s.status==="unreachable"?oe.dim("unreachable"):oe.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(oe.dim(`A newer upstream reaches projects with the next Vesper release (maintainers: npm run vendor:sync ${n.map(s=>s.skill).join(" ")}).`)),t()}function mr(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(Ue).join(", ")} (named by the Team Roster).`),e.already.length&&t.info(`Packs already enabled: ${e.already.map(Ue).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 iv(e,t){let r=await z(e);(await we(e,{checkout:r})).unmigrated&&(u.error(Be),process.exit(1));let n=r.host?[r.host]:await ce(e);!t.target&&n.length>1&&(u.error(He),process.exit(1));let s=t.target||r.host||null;return{host:s,provisioned:!!r.host&&r.host===s}}function Tp({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 av(e,{host:t}){let r=pt(),{enabled:n,unknown:s}=t?await pr(e,t):{enabled:[],unknown:[]},o=t?await Ht(e,t):null,i=o!==null?await Ut(o):null;if(console.log(),console.log(oe.bold("Vesper packs")),console.log(oe.dim(t?`Host: ${t}${o===null?` (no Team Roster at ${Wr[t]})`:""}`:"Host: not provisioned (catalog only)")),console.log(oe.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(oe.dim(" (this package ships no packs)")),console.log();return}for(let a of r){let{agents:c,skills:l}=Ku(a),d=n.includes(a)?oe.green("enabled"):oe.dim("disabled"),p=i?.needed[a],h=p?` \u2014 roster needs it: ${[...p.agents,...p.skills].join(", ")}`:i?oe.dim(" \u2014 not named by the roster"):"";console.log(` ${oe.bold(a)} (${Ue(a)}) ${d}${h}`),console.log(oe.dim(` agents: ${c.join(", ")||"\u2014"}`)),console.log(oe.dim(` skills: ${l.join(", ")||"\u2014"}`)),ir(a)&&console.log(oe.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 Op(e="list",t,r={}){try{let n=sv(r.path||process.cwd());await w(n)||(u.error(`Directory not found: ${u.formatPath(n)}`),process.exit(1));let s=e||"list";Cp.includes(s)||(u.error(`Unknown packs subcommand: ${s}. Subcommands: ${Cp.join(", ")}`),process.exit(1));let o=await iv(n,r);if(s==="list")return await av(n,o);if(s==="upstream"){ov(await Ko());return}if(s==="sync"){Tp(o,"sync");let c=await Wt(n,o.host);mr(c);return}if(t||(u.error(`\`vespercli packs ${s}\` needs a pack name. Packs: ${pt().join(", ")||"none"}`),process.exit(1)),pt().includes(t)||(u.error(`Unknown pack "${t}". Packs: ${pt().join(", ")||"none"}`),process.exit(1)),Tp(o,s),s==="enable"){let{enabled:c,rule:l}=await fr(n,o.host,t);c?u.success(`Enabled the ${t} pack (${Ue(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(Ji(l.path));return}let{disabled:i,rule:a}=await Xu(n,o.host,t);if(a?.status==="removed"&&u.info(` always-on pointer rule removed: ${a.path}`),a?.status==="kept"&&u.warn(Ji(a.path)),i){u.success(`Disabled the ${t} pack (${Ue(t)}) for ${o.host}.`);let c=await Ht(n,o.host);c!==null&&(await Ut(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)}}Me();var Xa=["copilot","claude"];function gv(e,t){return Hi(e)}async function yv(e,t,{settingsEntries:r,hooksDir:n=null,hookNames:s,version:o}={}){await Nr(e,{frameworkVersion:o}),await Al(e,t);let i=await Gi(e,t,{settingsEntries:r,hooksDir:n,hookNames:s});await J(e,gv(i,t)),await Tl(e)}function Ip(e){return e==="claude"?"Claude Code":"GitHub Copilot"}async function jp(e,t,{thirdPartyBackup:r=null}={}){let n=await Od(e,{backup:r||void 0}),{info:s,warn:o}=Pd(n);for(let i of s)u.info(i);if(o&&u.warn(o),n.stylesConsent)try{await fr(e,t,ul)}catch(i){u.warn(`Could not enable the styles pack (${i?.message??i}); run \`vespercli packs enable styles\` by hand.`)}}async function wv(e,t,{legacyHint:r,checkout:n}={}){let s=await ce(t),o=n?n.host:await Rr(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 m=[...new Set(f.split(",").map(y=>y.trim()).filter(Boolean))];for(let y of m)Xa.includes(y)||(u.error(`Unknown host: ${y}. Valid hosts: copilot, claude`),process.exit(1));return m.length>1&&a(),{selected:m,installed:i}}let l=await _t(t),d=l&&Xa.includes(l.to)?l.to:null,p=r?.needsMigration?Xa.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 mv({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 (CLI / VS Code extension / JetBrains / desktop)",value:"claude"}],...h?{default:h}:{}})],installed:i}}function vv(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 kv(e,t,{backup:r,workspaceRoot:n}={}){let s=await io({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 Bt({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 io({backup:r,workspaceRoot:n});return vv(vu(i)),i}async function Sv(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 so({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(d=>`.claude/${d}`).join(", ")}. Delete them yourself if you do not need them.`);let c=await ao(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 Dt(e,!0);await _u(e),u.success(`MCP servers configured: .mcp.json (${l.servers.join(", ")})`),mr(await Wt(e,"claude")),await jp(e,"claude",t),await Ou(e,{pluginPath:lr(e),namePrefix:n,mcpConfigPath:Te(e),settingsPath:Oe(e),installedAt:new Date().toISOString()})}async function Ev(e,t,r,n={}){console.log(),u.header("Configuring GitHub Copilot"),console.log(),await Cr(e);let s=await Ns(e);await Is(e,{maxRequests:r.maxRequests,omitBaseAgentInstructions:r.omitBaseAgentInstructions});let o=await Ps(e,r.terminalEnableAutoApprove),i=!1;r.enableMcpServer&&(i=(await Wn(e,!0)).configured,await Gs(e)),await wn(e);let a=await To(e,{version:n.version});return await Sa(e,{settingsEntries:await ut(e)}),mr(await Wt(e,"copilot")),await jp(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===ae.WORKSPACE_FILE?u.info(`Settings added to: ${Pp(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 bv(e,t,r=null){let n=await vn(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 Bt({message:"Migrate .vesperrc to workspace level? (recommended for multi-root workspaces)",default:!0}));let a=[];if(i&&r)try{let c=await at(e),l=lv(e,c).split(uv).join("/");l&&!l.startsWith("..")&&!dv(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 As(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 xv(e,t){let r=e;return t||(r=await fv({message:"Workspace root directory:",default:r})),cv(r)}async function _v(e,t,r){let n=[];for(let s of t){let o=Ip(s),i=r;if(r||(i=await Bt({message:`${o} is installed but was unchecked. Remove it from this project?`,default:!1})),!i){u.info(`Kept ${o}.`);continue}s==="claude"?await Gr(e):await Kn(e),n.push(s),u.success(`Removed ${o} from this project.`)}return n}async function Av(e){if(e)return{maxRequests:Ee.maxRequests,terminalEnableAutoApprove:Ee.terminalEnableAutoApprove,omitBaseAgentInstructions:Ee.omitBaseAgentInstructions,enableMcpServer:Ee.enableMcpServer};console.log(),u.info("Configure VS Code Chat settings:");let t=await hv({message:"Max agent requests per session (chat.agent.maxRequests):",default:Ee.maxRequests,min:1,max:1e3}),r=await Bt({message:"Controls whether terminal commands are automatically approved. Enable terminal auto-approval? (chat.tools.terminal.enableAutoApprove)",default:Ee.terminalEnableAutoApprove});r&&u.info("Terminal auto-approval enabled with safe command whitelist");let n=await Bt({message:"Omit base agent instructions for custom agents? (github.copilot.chat.omitBaseAgentInstructions)",default:Ee.omitBaseAgentInstructions}),s=await Bt({message:"Enable vesper-indexing MCP server for fast code search?",default:Ee.enableMcpServer});return{maxRequests:t||Ee.maxRequests,terminalEnableAutoApprove:r,omitBaseAgentInstructions:n,enableMcpServer:s}}async function zo(e,t=!1){let r=qe().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=pv(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(`
|
|
174
|
-
`))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 $v({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).")),console.log(),e&&u.vesperTip()}async function Rp(e={}){try{await Cv(e)}finally{Wa()}}async function Cv(e){try{let t=e.yes||e.forceDefault,r=await xv(e.path||process.cwd(),t);await w(r)||(u.error(`Directory not found: ${u.formatPath(r)}`),process.exit(1));let n=await B(r),s=await z(r),o=await we(r,{checkout:s}),i=n.type===ae.WORKSPACE_FILE?await vn(r):{found:!1,paths:[]},a=i.found&&i.paths.some(T=>!(Number(T?.tracking?.schemaVersion)>=2)),c=await Ru(r);c&&u.warn(`An interrupted migration's record (${c.from}) was unreadable and was set aside as ${Pp(c.to)}; its backups are kept. If files look half-migrated, restore them from that folder.`);let l=await cp(r),d=await Do(r),p=null;if(o.needsMigration||a){let T=await np(r,{record:o.record}),q=l?.status==="started"&&l.latest.head===d&&l.root.head===d?l:null;if(T.dirty.length){let Je=q?await up(r,q,T):T.dirty;Je.length&&(u.error(sp(Je,{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 h=Ma(r),g={migrated:!1,preCreated:[],backedUp:!1};n.type===ae.WORKSPACE_FILE&&(g=await bv(r,t,h),i.found&&(o=await we(r,{checkout:s})));let{selected:f,installed:m}=await wv(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,R=async()=>!!y&&!!A.host&&A.host!==y&&(await sr(r,A.host)||await Yt(r,A.host)),E=!!v||await R(),b=()=>v??A.host;await Li(r)&&(u.warn(`An unreadable host-switch journal (${Ft}) 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 Ca(r));let M=await _t(r),X=M?M.snapshot:null;if(M&&u.warn(E?`Resuming an interrupted host switch (${M.from} \u2192 ${M.to}, started ${M.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 (${M.from} \u2192 ${M.to}, started ${M.startedAt}): its preserved assets and MCP servers will be restored onto ${y}.`),E){let T=b(),q=v?`the pre-2.0 (1.x) ${T} setup`:`${T}'s Vesper artifacts`;if(!t&&!process.stdin.isTTY&&(u.error(`This workspace is provisioned for "${T}"${v?" (pre-2.0)":""}; switching to "${y}" removes ${q}. Re-run with --yes to confirm (non-interactive), or interactively.`),process.exit(1)),!t&&!await Bt({message:`Switch this workspace from ${T} 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 Pe=null;if(o.needsMigration){if(l?.status==="started"&&l!==p){let Je=await lp(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: ${Je.join(", ")}`)}let T=await io({dryRun:!0,workspaceRoot:r});S=await Ua(r,h,{record:o.record,previousVersion:await pp(r,o.record,T.version||null),chain:p,preCreated:g.preCreated});let q=v??y;Pe=await hp(r,y,{legacy:o,recordHost:q,frameworkVersion:e.version,log:u,backup:h}),A={host:q,source:"migration"},E=!!v||E&&await R()}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 Ua(r,h,{record:o.record,chain:l}):l.status==="started"&&await Ba(r,l.latest.dir));if(E){await $a(r,A.host),M||(X=await Ta(r),await Id(r,{from:A.host,to:y,snapshot:X}));let{retained:T}=await jo(r,A.host,{fullTeardown:!0});await Kr(r,T,A.host,u)}let Yr=E||Pe?[]:m.filter(T=>!f.includes(T));if(f.length===0&&Yr.length===0){u.info("No platforms selected. Nothing to do.");return}if(!t&&m.length===0&&f.length>0&&!await Bt({message:`Set up ${f.map(Ip).join(" + ")} in ${r}?`,default:!0})){u.info("Initialization cancelled.");return}Yr.length>0&&await _v(r,Yr,t);let ft=f.includes("copilot"),Ct=f.includes("claude"),Ie=null;ft&&(Ie=await Av(t));let Tt={...e,thirdPartyBackup:Pe?T=>h.project(T):null};ft&&(await Ol(r,"copilot"),await Ev(r,n,Ie,Tt)),Ct&&await Sv(r,Tt,m.includes("claude"));let ze=null;if((ft||Ct)&&(ze=await kv(m.includes(y),t,{backup:async T=>h.home(T),workspaceRoot:r}),ze?.kept?.length&&(ze.removed||ze.partial)))try{await Ka(h,ze.kept.map(T=>({rel:`~/.claude/skills/vesper/${T}`,reason:"plugin-folder"})))}catch{}if(ft||Ct){let T=await Ap(r);T.archived&&u.success(`Archived .vesper/history.md \u2192 ${T.to} (${T.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 yr=null,qr=[];if(ft||Ct){await hn(r);let T=await mn(r);if(T.length>0){let ht=T.map(Of=>`'${Of.replace(/'/g,"'\\''")}'`);u.warn(`Local-only file(s) are git-tracked despite .gitignore: ${ht.join(", ")}`),u.warn(`Untrack them yourself (Vesper won't touch your git index): git rm --cached -- ${ht.join(" ")}`)}let q=await En(r);qr=Ye.filter(ht=>q[ht]&&!q[ht].reason),yr=qr.length&&q[qr[0]].hooksDir||null;for(let ht of Sn(q))ht.startsWith("Git hooks not installed")?u.info(ht):u.warn(ht);yr&&(u.success("Local-only Vesper files gitignored (.vesperrc, .mcp.json, .vesper/index.db)"),qr.includes("pre-commit")&&u.info("Commit-hygiene git hook installed (pre-commit): keeps team roster/context/tracking/memory in sync with every commit"));let Je=await bn(r);await xn(r),Je.skipped||u.info("Merge strategy configured (.gitattributes): memory.jsonl merges entity-aware across worktrees, recent-decisions.md unions")}if(f.length===1){let T=f[0],q=T==="copilot"?await ut(r):void 0;await yv(r,T,{settingsEntries:q,hooksDir:yr,hookNames:qr,version:e.version}),X&&(await jd(r,T,X),await Ca(r));let{legacyGuardRule:Je}=await So(r,T);Je==="kept"&&u.warn(Hr())}if(Pe)try{let q=(await Br(r)).findings.filter(Je=>Je.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 Ba(r,h.dir)}catch(T){u.warn(`Could not finish the migration's rollback record (${T?.message||T}); the backups are under .vesper/.migration-backup/.`)}let Tf=ft&&Ie?.enableMcpServer||Ct,dc=null;Tf&&(dc=await zo(r,!0));let Xr=[];if((S||ze?.backedUpTo||g.backedUp)&&Xr.push(h.dir),l&&!o.needsMigration&&!S&&Xr.push(l.latest.dir),Xr.length)try{let T=await fp(r,{runDirs:Xr});if(T.length){console.log();for(let q of T)u.info(q)}await dp(r,Xr)}catch(T){u.warn(`Could not print the migration backup guidance (${T?.message||T}); the backups are under .vesper/.migration-backup/.`)}$v({copilot:ft,claude:Ct,indexingResult:dc})}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)}}W();U();import{resolve as Tv,join as Lp}from"node:path";import{checkbox as Ov}from"@inquirer/prompts";je();Me();var Np=["agents","skills"];async function Pv(e,t){let r=t?[t]:await ce(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(He),process.exit(1)),r[0]}async function Mp(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 Iv(e,t){return await Mn(e,t)!==null}async function jv(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)),Np.includes(t.type)||(u.error(`Unknown asset type for Claude Code: ${t.type}. Types: ${Np.join(", ")}`),process.exit(1)),await Iv(t.type,t.name)||(u.error(`${t.type}/${t.name} is not in the Vesper catalog.`),process.exit(1)),!t.override){let n=await Mn(t.type,t.name),s=t.type==="agents"?await Qu(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 Mp(e,"claude",r);try{let n=await oo(t.type,t.name,{workspaceRoot:e,namePrefix:await Lr(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 Rv(e,t,r){let n=await Ed(),s=new Set(await ct(e)),o=c=>[...s].some(l=>l.replace(/\\/g,"/").endsWith(`/instructions-extended/${c}`));if(t.type&&t.type!=="instructions"){Fe[t.type]||(u.error(`Unknown asset type: ${t.type}. Types: ${Object.keys(Fe).join(", ")}`),process.exit(1));let c=bo(),l=[...new Set([...await ss(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"?`${Lp(gt,Fe[t.type].dir)} (the whole folder is injected)`:`${Lp(gt,"packs",d,Fe[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 Ov({message:"Select opt-in instructions to add:",choices:c.map(l=>({name:l,value:l}))}),i.length===0){u.info("Nothing selected.");return}}await Mp(e,"copilot",r);let a=[];for(let c of i)(await Oo(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 Fp(e={}){try{let t=Tv(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await z(t);return(await we(t,{checkout:r})).unmigrated&&(u.error(Be),process.exit(1)),(e.target||await Pv(t,r.host))==="claude"?await jv(t,e,r.host):await Rv(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)}}W();je();U();import{resolve as Dp,join as Lv}from"node:path";import{readdir as Gp}from"node:fs/promises";Me();import ee from"picocolors";async function Vp(e={},t){let r=Dp(e.path||process.cwd());if(console.log(),console.log(ee.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 $l(r)||lr(r);console.log(ee.dim(`Project catalog: ${n}`));let s=await Ys(r),o=ns();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 wu(r);for(let[a,c]of Object.entries(i))console.log(),console.log(ee.bold(a.charAt(0).toUpperCase()+a.slice(1))),c.length===0?console.log(ee.dim(" (none installed)")):c.forEach(l=>console.log(` ${l}`));console.log(),console.log(ee.dim("The full specialist catalog is served by the vesper plugin (vesper:<name>) and its packs (vesper-<pack>:<name>) \u2014 see `vespercli catalog`.")),await Hp(r,"claude"),console.log(),console.log(ee.bold("Project files")),console.log(" CLAUDE.md (pointer), .claude/rules/vesper-{orchestrator,orchestration,context}.md, .mcp.json, .claude/settings.json"),console.log()}async function Hp(e,t){let r=pt();if(console.log(),console.log(ee.bold("Packs")),!r.length){console.log(ee.dim(" (this package ships no packs)"));return}let{enabled:n,unknown:s}=await pr(e,t),o=await Ht(e,t),i=o!==null?await Ut(o):null;for(let a of r){let c=n.includes(a)?ee.green("(enabled)"):ee.dim("(disabled)"),l=i?.packs.includes(a)?n.includes(a)?ee.dim("\u2014 roster needs it"):ee.yellow("\u2014 roster needs it: run `vespercli packs sync`"):"";console.log(` ${a} ${c} ${l}`.trimEnd())}s.length&&console.log(ee.yellow(` enabled but not shipped by this package: ${s.join(", ")}`)),console.log(ee.dim(" `vespercli packs` for contents; `vespercli packs sync` enables what the Team Roster names."))}async function Nv(e,t){try{let r=await Gp(Lv(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 Mv(){try{return(await Gp(pn,{withFileTypes:!0})).filter(e=>e.isFile()&&e.name.endsWith(".md")).map(e=>e.name.replace(/\.instructions\.md$|\.md$/,"")).sort()}catch{return[]}}async function Fv(e,t){let n=(await ct(e)).map(o=>/\/instructions-extended\/([^/]+)\/?$/.exec(String(o).replace(/\\/g,"/"))).filter(Boolean).map(o=>o[1]).sort(),s=t.type?[t.type]:Object.keys(Fe);console.log(),console.log(ee.bold("GitHub Copilot target")),console.log(ee.dim(`Package catalog: ${gt}`));for(let o of s){let i=o.charAt(0).toUpperCase()+o.slice(1),a=o==="instructions"?await Mv():await ss(o),c=await Nv(e,o),l=o==="instructions"?n:[];if(console.log(),console.log(ee.bold(i)),!a.length&&!c.length&&!l.length){console.log(ee.dim(" (none)"));continue}a.forEach(d=>console.log(` ${d} ${ee.dim("(package)")}`)),l.forEach(d=>console.log(` ${d} ${ee.dim("(opt-in)")}`)),c.forEach(d=>console.log(` ${d} ${ee.dim("(project)")}`))}await Hp(e,"copilot"),console.log()}async function Up(e={}){try{let t=Dp(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await z(t),n=r.host,s=n?[n]:await ce(t);if(e.target==="claude")return await Vp({...e,path:t},n);if(!e.target){if((await we(t,{checkout:r})).unmigrated&&(u.error(Be),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(He),process.exit(1)),s[0]==="claude")return await Vp({...e,path:t},n)}e.type&&!Fe[e.type]&&(u.error(`Unknown asset type: ${e.type}`),u.info(`Valid types: ${Object.keys(Fe).join(", ")}`),process.exit(1)),await Fv(t,e)}catch(t){u.error(`List failed: ${t.message}`),process.exit(1)}}je();import{readFileSync as Vv,existsSync as Dv}from"node:fs";import{join as Gv}from"node:path";var Qa=Gv(I,"CATALOG.md");function Hv(){return Dv(Qa)?Vv(Qa,"utf-8"):null}async function Wp(){let e=Hv();e===null&&(console.error(`Error loading catalog: ${Qa} not found in the installed package.`),process.exit(1)),console.log(e)}W();U();import{resolve as Uv,join as Jo,dirname as Bp}from"node:path";import{stat as Wv,readFile as Yp}from"node:fs/promises";import"@inquirer/prompts";Me();import et from"picocolors";async function Kp(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=Te(e),n=!1;if(await w(r))try{n=!!JSON.parse(await Yp(r,"utf-8")).mcpServers?.["vesper-indexing"]}catch{n=!1}u.info(`Configured: ${n?"\u2713 yes":"\u2717 no"} (${r})`),u.info(`Server built: ${ef(await Zp())}`);let s=ec(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 _o(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 qp=new Set(["enable","disable","sync","add","remove"]),Bv=qp,Xp="Vesper regenerates them at every session start \u2014 `vespercli mcp disable` makes no lasting change.";function Kv(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 Za(e,t=!0){if(await Dt(e,t),t){let r=await xu(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(Xp))}function ec(e){return Jo(e,".vesper","index.db")}function zv(e){return Jo(e,".vesper","indexing-status.json")}async function Qp(e){let t=zv(e);try{let r=await Yp(t,"utf-8");return JSON.parse(r)}catch{return null}}async function Zp(){let e=qe();if(!await w(e))return"missing";let t=Bp(Bp(e)),r=[Jo(t,"node_modules","@modelcontextprotocol","sdk","package.json"),Jo(t,"node_modules","zod","package.json")];for(let n of r)if(!await w(n))return"broken";return"ready"}function ef(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 Jv(e){try{let t=await Wv(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 zp(e,t=!1){let r=await Ds(e),n=await Zp(),s=ec(e),o=await w(s),i=await Qp(e);if(console.log(),u.header("vesper-indexing MCP Server"),console.log(),u.info(`Configured: ${r?"\u2713 yes":"\u2717 no"}`),u.info(`Server built: ${ef(n)}`),u.info(`Index exists: ${o?"\u2713 yes":"\u2717 no"}`),i)if(console.log(),i.status==="indexing")if(t){await Yv(e,i);return}else{let a=i.startedAt?Math.round((Date.now()-new Date(i.startedAt).getTime())/1e3):0;u.info(et.yellow("\u27F3 Indexing in progress...")),u.info(` Files processed: ${et.cyan(i.filesProcessed)}`),u.info(` Elapsed: ${et.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 Jv(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 Yv(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 Qp(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(`
|
|
175
|
-
\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
|
|
170
|
+
`:"","utf-8"),await $(x(n.dir,Ha),m.map(([v,S])=>`${v} ${S}
|
|
171
|
+
`).join(""),"utf-8"),await $(x(n.dir,Ua),Qw,"utf-8");let y=new Set;for(let v of s){if(v!==o){let S=null;try{S=await Xe(x(v.dir,"rewritten"))}catch{S=null}for(let A of S?S.files:[])!l.has(A)||y.has(A)||await w(x(o.dir,"rewritten",A))||await tp(o.dir,"rewritten",A,x(v.dir,"rewritten",A))}for(let[S]of await Wa(v.dir))y.add(S)}await j(x(n.dir,pp),{recursive:!0});let k=new Date().toISOString();for(let v of s)await Ba(v.dir,{status:"finished",finishedAt:k,...v.dir===n.dir?{created:f}:{}});return f}async function yp(e,t){for(let r of await Do(e))r.migration&&t.includes(r.dir)&&await Ba(r.dir,{guidancePrinted:!0})}async function qd(e,{homeDir:t=qn()}={}){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("~/")?x(t,s[1].slice(2)):s[1])}for(let n of r)try{let s=JSON.parse(await fe(x(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 wp(e,t,r,{homeDir:n=qn()}={}){if(t?.version)return t.version;let s=await qd(t,{homeDir:n});if(s)return s;let o=[];try{let{readVSCodeSettings:a}=await Promise.resolve().then(()=>(U(),Ci)),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 qd({injectedPaths:o},{homeDir:n});return i||t?.config==="v1"&&r||null}async function vp(e,{runDirs:t=[],homeDir:r=qn()}={}){let n=await Do(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 ${x(e,ur)}, 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(x(E.dir,b.backup))} ${d(b.original)}`),g=[];for(let E of a)E.project&&g.push(`cp -R ${d(x(E.dir,"project"))}/. ${d(e)}/`),E.home&&g.push(`cp -R ${d(x(E.dir,"home"))}/. ${d(r)}/`),g.push(...h(E));if(g.length){p.push("Recover the files the migration REMOVED (copies them back; this alone is not a rollback):");for(let E of g)p.push(` ${E}`)}if(!i.length)return p;let f=i[0],m=i[i.length-1],y=m.created,k=i.map(E=>E.previousVersion).find(Boolean),v=f.head?await Go(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&&m.createdChecked?p.push(` ${S++}. sh ${d(x(m.dir,Ua))} (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(x(m.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(x(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=x(f.dir,"tracked-paths.txt");p.push(` ${S++}. git -c core.hooksPath=${d(x(m.dir,pp))} 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(x(E.dir,"project"))}/. ${d(e)}/`),E.home&&A.push(`cp -R ${d(x(E.dir,"home"))}/. ${d(r)}/`),A.push(...h(E));A.length&&p.push(` ${S++}. ${A.join(" && ")} (the removed files)`);let L=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${L})`),p}async function kp(e,t,{legacy:r,recordHost:n,frameworkVersion:s,homeDir:o=qn(),now:i=new Date,log:a,backup:c}={}){let l=await vo(e),d=a||{info(){},success(){},warn(){}},p=c||Da(e,{now:i,homeDir:o}),h={record:l,backupDir:null,relocated:[],recorded:[],removed:[],moved:[],kept:[],homeLookalikes:[],settings:null},g=(b,M,X={})=>h.kept.push({rel:b,reason:M,...X}),f=async(b,M)=>{try{return await M()}catch(X){g(b,"error",{detail:String(X?.message||X)});return}},m=await Ga(e),y=m?["pre-commit","post-checkout"].map(b=>`${m}/${b}`):[];for(let b of[...Zd,...await ip(e),...y])await f(b,()=>p.snapshot(b));let k=l;if(l.config==="v2"&&l.recordedHost){let b=null;try{b=(await z(e)).host}catch{b=null}if(l.recordedHost!==b){let M=l.recordedHost;d.info(`This worktree's 2.0 record describes another branch (${M}); 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 X=await _(e);X.manifest=Y(X).filter(Ie=>Ie.host!==M||Ce.has(Ie.category)),delete X.host,await O(e,X)})}}let v=await op(e,k);await tv(e,t,{backup:p,result:h,safely:f,keep:g,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)g(b.rel,b.reason,b.files?{files:b.files}:{});let A=".claude/vesper/orchestrator.md";await w(x(e,A))&&await f(A,async()=>{let b=await fe(x(e,A));if(!uu(b)){g(A,"edited-playbook");return}await p.project(A),await ue(x(e,A),{path:A,category:"playbook",hash:Qe(b)})==="removed"&&h.removed.push(A)});try{await Xd(x(e,".claude","vesper"))}catch{}t==="copilot"&&(h.settings=await f(".vscode/settings.json",()=>Cr(e,{trackedPaths:k.injectedPaths,trackedReadAccess:k.readAccessPaths})));let L=await ko({homeDir:o}).catch(()=>[]);if(h.homeLookalikes=L.filter(b=>b.tier===3),(await _(e)).schemaVersion===de){await Nr(e,{frameworkVersion:s}),S.length&&await J(e,S);let b=await _(e);!b.host&&n&&(b.host=n,await O(e,b))}else await Nr(e,{frameworkVersion:s,legacyEntries:S,host:n});return h.kept.length&&await f("kept.json",()=>Ya(p,h.kept)),h.backup=p,h.backupDir=p.items.length?p.dir:null,nv(h,d),h}async function Ya(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)}
|
|
172
|
+
`)}async function tv(e,t,{backup:r,result:n,safely:s,keep:o,catalog:i}){let a=null,c=new Set;if(t==="claude"){a=await dt();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(x(e,h))&&c.add(p)}}let l=[{key:"orchestration",claudeDest:".claude/rules/vesper-orchestration.md",copilotDest:Ee("vesper-orchestration"),tpl:"orchestration.md.tpl",sources:[{rel:".claude/vesper/orchestration.md",vesper:()=>!0,move:!0},{rel:".github/instructions/orchestration.instructions.md",vesper:Yw,move:!0,unmarked:"report"}]},{key:"context",claudeDest:".claude/rules/vesper-context.md",copilotDest:Ee("vesper-context"),tpl:"context.md.tpl",sources:[{rel:".claude/vesper/context.md",vesper:()=>!0,move:!0},{rel:".github/copilot-instructions.md",vesper:qw,move:!1,unmarked:"claude-only"}]}];for(let d of l){let p=t==="claude"?d.claudeDest:d.copilotDest,h=null;for(let g of d.sources){let f=x(e,g.rel),m=(await sp(f))?.toString("utf-8");if(m===void 0)continue;let y=g.vesper(m);if(!y&&g.unmarked==="report"){o(g.rel,"unmarked-knowledge");continue}if(!y&&g.unmarked==="claude-only"&&t!=="claude"){o(g.rel,"github-own");continue}if(h||await w(x(e,p))){let k="duplicate-knowledge";g.move||(k=y?h?"github-brain-kept":"github-brain-dest":"github-own"),o(g.rel,k);continue}await s(g.rel,async()=>{let{body:k}=Ze(m),v=k.replace(/^\n+/,"");if(t==="claude"&&d.key==="orchestration"){let E=Vl(v);n.rosterRetired=E.removed;let b=Zs(E.text,a,{skip:c});v=b.text,n.rosterQualified=b.qualified}let S=t==="claude"?`${await Yd(d.tpl)}${v}`:ba(Ze(m).frontmatter===null?`${await Yd(d.tpl)}${k}`:m,`Vesper ${d.key}`),A=x(e,p);if(await j(Fa(A),{recursive:!0}),await $(A,S,"utf-8"),await fe(A,"utf-8")!==S)throw new Error(`could not verify ${p}`);if(h=g.rel,!g.move||!y){n.relocated.push({from:g.rel,to:p,copied:!0}),o(g.rel,g.move?"unmarked-knowledge":"github-brain");return}n.relocated.push({from:g.rel,to:p}),await r.project(g.rel),await ue(f,{path:g.rel,category:"relocated-original"},{expected:[Buffer.from(m,"utf-8")]})==="removed"&&n.moved.push({from:g.rel,to:p})})}}for(let d of[".github/instructions",".github"])try{await Xd(x(e,d))}catch{}if(t==="copilot"){let d=x(e,".claude","vesper","context"),p=[];try{p=(await Xe(d)).files}catch{p=[]}for(let h of p){let g=x(e,".vesper","context",h);await w(g)||await s(`.claude/vesper/context/${h}`,async()=>{await j(Fa(g),{recursive:!0}),await $(g,await fe(x(d,h))),n.relocated.push({from:`.claude/vesper/context/${h}`,to:`.vesper/context/${h}`,copied:!0})})}}}function rv(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 ${Jw[s]||s}: ${i}`)}return n}function nv(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 rv(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.`)}}W();import{join as Za}from"node:path";W();rt();ot();import{rename as sv}from"node:fs/promises";import{dirname as ov,join as Sp}from"node:path";async function Ho(e,t,r){let n=Sp(e,t),s=Sp(e,r);if(!await w(n))return{ok:!1,reason:"missing"};if(await w(s))return{ok:!1,reason:"exists"};await j(ov(s),{recursive:!0});let o={...process.env,...vt};return await V(["rev-parse","--is-inside-work-tree"],{cwd:e,env:o})==="true"&&(await yt(["--literal-pathspecs","ls-files","--error-unmatch","--",t],{cwd:e,env:o})).ok&&await V(["--literal-pathspecs","status","--porcelain","--",t],{cwd:e,env:o})===""&&(await yt(["--literal-pathspecs","mv","--",t,r],{cwd:e,env:{...process.env,...ln}})).ok?{ok:!0,method:"git"}:(await sv(n,s),{ok:!0,method:"rename"})}W();import{readdir as iv,readFile as av}from"node:fs/promises";import{join as Uo}from"node:path";var Xa=".vesper/.tracking/runs",Qn=Object.freeze(["started","completed","note","delegated","returned"]),Ep=Object.freeze(["DONE","NEED_HELP","BLOCKED"]),cv="adhoc",Wo=5,qr=Object.freeze({OK:0,INVALID:2}),lv=Object.freeze(["ts","event","pipeline","step","agent","goal","author","status","note"]),uv=Object.freeze({started:["goal"],completed:["status"],note:[],delegated:["agent"],returned:["agent","status"]});function bp(e){return String(e??"").toLowerCase().replace(/[^a-z0-9-]+/g,"-").replace(/-{2,}/g,"-").replace(/^-|-$/g,"")||cv}function Qa(e=new Date){return e.toISOString().slice(0,10).replace(/-/g,"")}function dv(e,t=new Date){return`${Qa(t)}-${bp(e)}.jsonl`}function Xn(e){return typeof e=="string"&&e.trim()!==""}function xp(e={},{now:t=new Date}={}){let r=[],n=typeof e.event=="string"?e.event.trim():"";Qn.includes(n)||r.push(`event must be one of ${Qn.join("|")} (received "${n}")`),Xn(e.pipeline)||r.push("--pipeline is required");for(let o of uv[n]||[])Xn(e[o])||r.push(`--${o} is required for \`${n}\``);if(e.status!==void 0&&e.status!==null&&!Ep.includes(String(e.status))&&r.push(`--status must be one of ${Ep.join("|")} (received "${e.status}")`),r.length)return{ok:!1,errors:r};let s={ts:t.toISOString(),event:n};for(let o of lv.slice(2))s[o]=Xn(e[o])?e[o].trim():null;return Xn(e.session)&&(s.session=e.session.trim()),{ok:!0,row:s}}async function _p(e,t,{slug:r,now:n=new Date}={}){let s=Uo(e,Xa);await j(s,{recursive:!0});let o=dv(r,n),i=Uo(s,o),a=`${JSON.stringify(t)}
|
|
173
|
+
`;return await $(i,a,{encoding:"utf-8",flag:"a"}),{rel:`${Xa}/${o}`,abs:i,line:a}}function qa(e){let t=/^\d{8}-(.+)\.jsonl$/.exec(e);return t?t[1]:null}async function Ap(e,{slug:t}={}){let r=Uo(e,Xa);if(!await w(r))return{rows:[],files:[],malformed:0};let n=t?bp(t):null,s=(await iv(r)).filter(c=>c.endsWith(".jsonl")&&qa(c)!==null&&(!n||qa(c)===n)).sort(),o=[],i=0,a=0;for(let c of s){let l=await av(Uo(r,c),"utf-8");for(let d of l.split(`
|
|
174
|
+
`))if(d.trim()!=="")try{let p=JSON.parse(d);if(!p||typeof p!="object"||Array.isArray(p)){i+=1;continue}o.push({...p,slug:qa(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 $p(e,t=Wo){let r=Number.isFinite(t)?Math.max(0,Math.floor(t)):Wo;return r===0?[]:e.slice(-r)}function Cp(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 Tp(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=>Xn(t[n])?t[n].trim():null;return{agent:r("agent_type"),agentId:r("agent_id"),session:r("session_id")}}var Bo=".vesper/history.md",Op=".vesper/history-archive";function Pp(e=new Date,t=0){return`history-${Qa(e)}${t>0?`-${t}`:""}.md`}async function Ip(e,{now:t=new Date}={}){if(!await w(Za(e,Bo)))return{archived:!1};let r=Za(e,Op);await j(r,{recursive:!0});let n=0,s=Pp(t,n);for(;await w(Za(r,s));)n+=1,s=Pp(t,n);let o=`${Op}/${s}`,i=await Ho(e,Bo,o);if(!i.ok)throw new Error(`Could not archive ${Bo}: ${i.reason}`);return{archived:!0,from:Bo,to:o,method:i.method}}W();import{resolve as fv}from"node:path";import oe from"picocolors";U();rt();ot();var Ko=3e3;async function pv(e,{timeoutMs:t=Ko,env:r}={}){let n=await yt(["ls-remote","--",e,"HEAD"],{timeout:t,env:un(qt(r??process.env)),detached:!0});if(!n.ok)return null;let s=n.stdout.split(`
|
|
175
|
+
`).map(o=>o.trim()).find(o=>/^[0-9a-f]{40}\s+HEAD$/.test(o));return s?s.slice(0,40):null}async function zo({assetsDir:e,timeoutMs:t=Ko,env:r}={}){let n=[];for(let{pack:s,skill:o,record:i}of await hl(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 pv(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 jp(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.`}Fe();var Rp=["list","enable","disable","sync","upstream"];function hv(e,{log:t=console.log}={}){if(t(),t(oe.bold("Third-party pack skills \u2014 upstream check")),t(oe.dim("Pinned = the commit the shipped snapshot was taken at (UPSTREAM.json); remote = upstream HEAD now.")),t(),!e.length){t(oe.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"?oe.yellow("newer upstream"):s.status==="current"?oe.green("current"):s.status==="unreachable"?oe.dim("unreachable"):oe.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(oe.dim(`A newer upstream reaches projects with the next Vesper release (maintainers: npm run vendor:sync ${n.map(s=>s.skill).join(" ")}).`)),t()}function mr(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(We).join(", ")} (named by the Team Roster).`),e.already.length&&t.info(`Packs already enabled: ${e.already.map(We).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 mv(e,t){let r=await z(e);(await ve(e,{checkout:r})).unmigrated&&(u.error(Be),process.exit(1));let n=r.host?[r.host]:await ce(e);!t.target&&n.length>1&&(u.error(Ue),process.exit(1));let s=t.target||r.host||null;return{host:s,provisioned:!!r.host&&r.host===s}}function Lp({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 gv(e,{host:t}){let r=pt(),{enabled:n,unknown:s}=t?await pr(e,t):{enabled:[],unknown:[]},o=t?await Ht(e,t):null,i=o!==null?await Ut(o):null;if(console.log(),console.log(oe.bold("Vesper packs")),console.log(oe.dim(t?`Host: ${t}${o===null?` (no Team Roster at ${Kr[t]})`:""}`:"Host: not provisioned (catalog only)")),console.log(oe.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(oe.dim(" (this package ships no packs)")),console.log();return}for(let a of r){let{agents:c,skills:l}=Zu(a),d=n.includes(a)?oe.green("enabled"):oe.dim("disabled"),p=i?.needed[a],h=p?` \u2014 roster needs it: ${[...p.agents,...p.skills].join(", ")}`:i?oe.dim(" \u2014 not named by the roster"):"";console.log(` ${oe.bold(a)} (${We(a)}) ${d}${h}`),console.log(oe.dim(` agents: ${c.join(", ")||"\u2014"}`)),console.log(oe.dim(` skills: ${l.join(", ")||"\u2014"}`)),ir(a)&&console.log(oe.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 Np(e="list",t,r={}){try{let n=fv(r.path||process.cwd());await w(n)||(u.error(`Directory not found: ${u.formatPath(n)}`),process.exit(1));let s=e||"list";Rp.includes(s)||(u.error(`Unknown packs subcommand: ${s}. Subcommands: ${Rp.join(", ")}`),process.exit(1));let o=await mv(n,r);if(s==="list")return await gv(n,o);if(s==="upstream"){hv(await zo());return}if(s==="sync"){Lp(o,"sync");let c=await Wt(n,o.host);mr(c);return}if(t||(u.error(`\`vespercli packs ${s}\` needs a pack name. Packs: ${pt().join(", ")||"none"}`),process.exit(1)),pt().includes(t)||(u.error(`Unknown pack "${t}". Packs: ${pt().join(", ")||"none"}`),process.exit(1)),Lp(o,s),s==="enable"){let{enabled:c,rule:l}=await fr(n,o.host,t);c?u.success(`Enabled the ${t} pack (${We(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(qi(l.path));return}let{disabled:i,rule:a}=await sd(n,o.host,t);if(a?.status==="removed"&&u.info(` always-on pointer rule removed: ${a.path}`),a?.status==="kept"&&u.warn(qi(a.path)),i){u.success(`Disabled the ${t} pack (${We(t)}) for ${o.host}.`);let c=await Ht(n,o.host);c!==null&&(await Ut(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)}}Fe();var ec=["copilot","claude"];function _v(e,t){return Wi(e)}async function Av(e,t,{settingsEntries:r,hooksDir:n=null,hookNames:s,version:o}={}){await Nr(e,{frameworkVersion:o}),await Cl(e,t);let i=await Ui(e,t,{settingsEntries:r,hooksDir:n,hookNames:s});await J(e,_v(i,t)),await Pl(e)}function Fp(e){return e==="claude"?"Claude Code":"GitHub Copilot"}async function Vp(e,t,{thirdPartyBackup:r=null}={}){let n=await Nd(e,{backup:r||void 0}),{info:s,warn:o}=Md(n);for(let i of s)u.info(i);if(o&&u.warn(o),n.stylesConsent)try{await fr(e,t,pl)}catch(i){u.warn(`Could not enable the styles pack (${i?.message??i}); run \`vespercli packs enable styles\` by hand.`)}}async function $v(e,t,{legacyHint:r,checkout:n}={}){let s=await ce(t),o=n?n.host:await Rr(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 m=[...new Set(f.split(",").map(y=>y.trim()).filter(Boolean))];for(let y of m)ec.includes(y)||(u.error(`Unknown host: ${y}. Valid hosts: copilot, claude`),process.exit(1));return m.length>1&&a(),{selected:m,installed:i}}let l=await _t(t),d=l&&ec.includes(l.to)?l.to:null,p=r?.needsMigration?ec.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 xv({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 (CLI / VS Code extension / JetBrains / desktop)",value:"claude"}],...h?{default:h}:{}})],installed:i}}function Cv(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 Tv(e,t,{backup:r,workspaceRoot:n}={}){let s=await co({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 Bt({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 co({backup:r,workspaceRoot:n});return Cv(_u(i)),i}async function Ov(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 io({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(d=>`.claude/${d}`).join(", ")}. Delete them yourself if you do not need them.`);let c=await lo(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 Dt(e,!0);await Pu(e),u.success(`MCP servers configured: .mcp.json (${l.servers.join(", ")})`),mr(await Wt(e,"claude")),await Vp(e,"claude",t),await Mu(e,{pluginPath:lr(e),namePrefix:n,mcpConfigPath:Oe(e),settingsPath:Pe(e),installedAt:new Date().toISOString()})}async function Pv(e,t,r,n={}){console.log(),u.header("Configuring GitHub Copilot"),console.log(),await Cr(e);let s=await Ms(e);await js(e,{maxRequests:r.maxRequests,omitBaseAgentInstructions:r.omitBaseAgentInstructions});let o=await Is(e,r.terminalEnableAutoApprove),i=!1;r.enableMcpServer&&(i=(await Bn(e,!0)).configured,await Hs(e)),await kn(e);let a=await Oo(e,{version:n.version});return await xa(e,{settingsEntries:await ut(e)}),mr(await Wt(e,"copilot")),await Vp(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===ae.WORKSPACE_FILE?u.info(`Settings added to: ${Mp(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 Iv(e,t,r=null){let n=await Sn(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 Bt({message:"Migrate .vesperrc to workspace level? (recommended for multi-root workspaces)",default:!0}));let a=[];if(i&&r)try{let c=await at(e),l=wv(e,c).split(vv).join("/");l&&!l.startsWith("..")&&!kv(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 $s(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 jv(e,t){let r=e;return t||(r=await Ev({message:"Workspace root directory:",default:r})),yv(r)}async function Rv(e,t,r){let n=[];for(let s of t){let o=Fp(s),i=r;if(r||(i=await Bt({message:`${o} is installed but was unchecked. Remove it from this project?`,default:!1})),!i){u.info(`Kept ${o}.`);continue}s==="claude"?await Ur(e):await zn(e),n.push(s),u.success(`Removed ${o} from this project.`)}return n}async function Lv(e){if(e)return{maxRequests:be.maxRequests,terminalEnableAutoApprove:be.terminalEnableAutoApprove,omitBaseAgentInstructions:be.omitBaseAgentInstructions,enableMcpServer:be.enableMcpServer};console.log(),u.info("Configure VS Code Chat settings:");let t=await bv({message:"Max agent requests per session (chat.agent.maxRequests):",default:be.maxRequests,min:1,max:1e3}),r=await Bt({message:"Controls whether terminal commands are automatically approved. Enable terminal auto-approval? (chat.tools.terminal.enableAutoApprove)",default:be.terminalEnableAutoApprove});r&&u.info("Terminal auto-approval enabled with safe command whitelist");let n=await Bt({message:"Omit base agent instructions for custom agents? (github.copilot.chat.omitBaseAgentInstructions)",default:be.omitBaseAgentInstructions}),s=await Bt({message:"Enable vesper-indexing MCP server for fast code search?",default:be.enableMcpServer});return{maxRequests:t||be.maxRequests,terminalEnableAutoApprove:r,omitBaseAgentInstructions:n,enableMcpServer:s}}async function Jo(e,t=!1){let r=qe().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=Sv(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(`
|
|
176
|
+
`))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 Nv({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).")),console.log(),e&&u.vesperTip()}async function Dp(e={}){try{await Mv(e)}finally{za()}}async function Mv(e){try{let t=e.yes||e.forceDefault,r=await jv(e.path||process.cwd(),t);await w(r)||(u.error(`Directory not found: ${u.formatPath(r)}`),process.exit(1));let n=await B(r),s=await z(r),o=await ve(r,{checkout:s}),i=n.type===ae.WORKSPACE_FILE?await Sn(r):{found:!1,paths:[]},a=i.found&&i.paths.some(T=>!(Number(T?.tracking?.schemaVersion)>=2)),c=await Gu(r);c&&u.warn(`An interrupted migration's record (${c.from}) was unreadable and was set aside as ${Mp(c.to)}; its backups are kept. If files look half-migrated, restore them from that folder.`);let l=await hp(r),d=await Go(r),p=null;if(o.needsMigration||a){let T=await lp(r,{record:o.record}),q=l?.status==="started"&&l.latest.head===d&&l.root.head===d?l:null;if(T.dirty.length){let Je=q?await gp(r,q,T):T.dirty;Je.length&&(u.error(up(Je,{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 h=Da(r),g={migrated:!1,preCreated:[],backedUp:!1};n.type===ae.WORKSPACE_FILE&&(g=await Iv(r,t,h),i.found&&(o=await ve(r,{checkout:s})));let{selected:f,installed:m}=await $v(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,L=async()=>!!y&&!!A.host&&A.host!==y&&(await sr(r,A.host)||await Yt(r,A.host)),E=!!v||await L(),b=()=>v??A.host;await Mi(r)&&(u.warn(`An unreadable host-switch journal (${Ft}) 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 Pa(r));let M=await _t(r),X=M?M.snapshot:null;if(M&&u.warn(E?`Resuming an interrupted host switch (${M.from} \u2192 ${M.to}, started ${M.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 (${M.from} \u2192 ${M.to}, started ${M.startedAt}): its preserved assets and MCP servers will be restored onto ${y}.`),E){let T=b(),q=v?`the pre-2.0 (1.x) ${T} setup`:`${T}'s Vesper artifacts`;if(!t&&!process.stdin.isTTY&&(u.error(`This workspace is provisioned for "${T}"${v?" (pre-2.0)":""}; switching to "${y}" removes ${q}. Re-run with --yes to confirm (non-interactive), or interactively.`),process.exit(1)),!t&&!await Bt({message:`Switch this workspace from ${T} 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 Ie=null;if(o.needsMigration){if(l?.status==="started"&&l!==p){let Je=await mp(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: ${Je.join(", ")}`)}let T=await co({dryRun:!0,workspaceRoot:r});S=await Ka(r,h,{record:o.record,previousVersion:await wp(r,o.record,T.version||null),chain:p,preCreated:g.preCreated});let q=v??y;Ie=await kp(r,y,{legacy:o,recordHost:q,frameworkVersion:e.version,log:u,backup:h}),A={host:q,source:"migration"},E=!!v||E&&await L()}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 Ka(r,h,{record:o.record,chain:l}):l.status==="started"&&await Ja(r,l.latest.dir));if(E){await Oa(r,A.host),M||(X=await Ia(r),await Fd(r,{from:A.host,to:y,snapshot:X}));let{retained:T}=await Ro(r,A.host,{fullTeardown:!0});await Jr(r,T,A.host,u)}let Xr=E||Ie?[]:m.filter(T=>!f.includes(T));if(f.length===0&&Xr.length===0){u.info("No platforms selected. Nothing to do.");return}if(!t&&m.length===0&&f.length>0&&!await Bt({message:`Set up ${f.map(Fp).join(" + ")} in ${r}?`,default:!0})){u.info("Initialization cancelled.");return}Xr.length>0&&await Rv(r,Xr,t);let ft=f.includes("copilot"),Ct=f.includes("claude"),je=null;ft&&(je=await Lv(t));let Tt={...e,thirdPartyBackup:Ie?T=>h.project(T):null};ft&&(await Il(r,"copilot"),await Pv(r,n,je,Tt)),Ct&&await Ov(r,Tt,m.includes("claude"));let ze=null;if((ft||Ct)&&(ze=await Tv(m.includes(y),t,{backup:async T=>h.home(T),workspaceRoot:r}),ze?.kept?.length&&(ze.removed||ze.partial)))try{await Ya(h,ze.kept.map(T=>({rel:`~/.claude/skills/vesper/${T}`,reason:"plugin-folder"})))}catch{}if(ft||Ct){let T=await Ip(r);T.archived&&u.success(`Archived .vesper/history.md \u2192 ${T.to} (${T.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 yr=null,Qr=[];if(ft||Ct){await gn(r);let T=await yn(r);if(T.length>0){let ht=T.map(Nf=>`'${Nf.replace(/'/g,"'\\''")}'`);u.warn(`Local-only file(s) are git-tracked despite .gitignore: ${ht.join(", ")}`),u.warn(`Untrack them yourself (Vesper won't touch your git index): git rm --cached -- ${ht.join(" ")}`)}let q=await xn(r);Qr=Ye.filter(ht=>q[ht]&&!q[ht].reason),yr=Qr.length&&q[Qr[0]].hooksDir||null;for(let ht of bn(q))ht.startsWith("Git hooks not installed")?u.info(ht):u.warn(ht);yr&&(u.success("Local-only Vesper files gitignored (.vesperrc, .mcp.json, .vesper/index.db)"),Qr.includes("pre-commit")&&u.info("Commit-hygiene git hook installed (pre-commit): keeps team roster/context/tracking/memory in sync with every commit"));let Je=await _n(r);await An(r),Je.skipped||u.info("Merge strategy configured (.gitattributes): memory.jsonl merges entity-aware across worktrees, recent-decisions.md unions")}if(f.length===1){let T=f[0],q=T==="copilot"?await ut(r):void 0;await Av(r,T,{settingsEntries:q,hooksDir:yr,hookNames:Qr,version:e.version}),X&&(await Vd(r,T,X),await Pa(r));let{legacyGuardRule:Je}=await Eo(r,T);Je==="kept"&&u.warn(Wr())}if(Ie)try{let q=(await zr(r)).findings.filter(Je=>Je.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 Ja(r,h.dir)}catch(T){u.warn(`Could not finish the migration's rollback record (${T?.message||T}); the backups are under .vesper/.migration-backup/.`)}let Lf=ft&&je?.enableMcpServer||Ct,fc=null;Lf&&(fc=await Jo(r,!0));let Zr=[];if((S||ze?.backedUpTo||g.backedUp)&&Zr.push(h.dir),l&&!o.needsMigration&&!S&&Zr.push(l.latest.dir),Zr.length)try{let T=await vp(r,{runDirs:Zr});if(T.length){console.log();for(let q of T)u.info(q)}await yp(r,Zr)}catch(T){u.warn(`Could not print the migration backup guidance (${T?.message||T}); the backups are under .vesper/.migration-backup/.`)}Nv({copilot:ft,claude:Ct,indexingResult:fc})}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)}}W();U();import{resolve as Fv,join as Gp}from"node:path";import{checkbox as Vv}from"@inquirer/prompts";Re();Fe();var Hp=["agents","skills"];async function Dv(e,t){let r=t?[t]:await ce(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(Ue),process.exit(1)),r[0]}async function Up(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 Gv(e,t){return await Fn(e,t)!==null}async function Hv(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)),Hp.includes(t.type)||(u.error(`Unknown asset type for Claude Code: ${t.type}. Types: ${Hp.join(", ")}`),process.exit(1)),await Gv(t.type,t.name)||(u.error(`${t.type}/${t.name} is not in the Vesper catalog.`),process.exit(1)),!t.override){let n=await Fn(t.type,t.name),s=t.type==="agents"?await od(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 Up(e,"claude",r);try{let n=await ao(t.type,t.name,{workspaceRoot:e,namePrefix:await Lr(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 Uv(e,t,r){let n=await Cd(),s=new Set(await ct(e)),o=c=>[...s].some(l=>l.replace(/\\/g,"/").endsWith(`/instructions-extended/${c}`));if(t.type&&t.type!=="instructions"){Ve[t.type]||(u.error(`Unknown asset type: ${t.type}. Types: ${Object.keys(Ve).join(", ")}`),process.exit(1));let c=xo(),l=[...new Set([...await os(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"?`${Gp(gt,Ve[t.type].dir)} (the whole folder is injected)`:`${Gp(gt,"packs",d,Ve[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 Vv({message:"Select opt-in instructions to add:",choices:c.map(l=>({name:l,value:l}))}),i.length===0){u.info("Nothing selected.");return}}await Up(e,"copilot",r);let a=[];for(let c of i)(await Po(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 Wp(e={}){try{let t=Fv(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await z(t);return(await ve(t,{checkout:r})).unmigrated&&(u.error(Be),process.exit(1)),(e.target||await Dv(t,r.host))==="claude"?await Hv(t,e,r.host):await Uv(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)}}W();Re();U();import{resolve as Kp,join as Wv}from"node:path";import{readdir as zp}from"node:fs/promises";Fe();import ee from"picocolors";async function Bp(e={},t){let r=Kp(e.path||process.cwd());if(console.log(),console.log(ee.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 Tl(r)||lr(r);console.log(ee.dim(`Project catalog: ${n}`));let s=await qs(r),o=ss();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 xu(r);for(let[a,c]of Object.entries(i))console.log(),console.log(ee.bold(a.charAt(0).toUpperCase()+a.slice(1))),c.length===0?console.log(ee.dim(" (none installed)")):c.forEach(l=>console.log(` ${l}`));console.log(),console.log(ee.dim("The full specialist catalog is served by the vesper plugin (vesper:<name>) and its packs (vesper-<pack>:<name>) \u2014 see `vespercli catalog`.")),await Jp(r,"claude"),console.log(),console.log(ee.bold("Project files")),console.log(" CLAUDE.md (pointer), .claude/rules/vesper-{orchestrator,orchestration,context}.md, .mcp.json, .claude/settings.json"),console.log()}async function Jp(e,t){let r=pt();if(console.log(),console.log(ee.bold("Packs")),!r.length){console.log(ee.dim(" (this package ships no packs)"));return}let{enabled:n,unknown:s}=await pr(e,t),o=await Ht(e,t),i=o!==null?await Ut(o):null;for(let a of r){let c=n.includes(a)?ee.green("(enabled)"):ee.dim("(disabled)"),l=i?.packs.includes(a)?n.includes(a)?ee.dim("\u2014 roster needs it"):ee.yellow("\u2014 roster needs it: run `vespercli packs sync`"):"";console.log(` ${a} ${c} ${l}`.trimEnd())}s.length&&console.log(ee.yellow(` enabled but not shipped by this package: ${s.join(", ")}`)),console.log(ee.dim(" `vespercli packs` for contents; `vespercli packs sync` enables what the Team Roster names."))}async function Bv(e,t){try{let r=await zp(Wv(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 Kv(){try{return(await zp(hn,{withFileTypes:!0})).filter(e=>e.isFile()&&e.name.endsWith(".md")).map(e=>e.name.replace(/\.instructions\.md$|\.md$/,"")).sort()}catch{return[]}}async function zv(e,t){let n=(await ct(e)).map(o=>/\/instructions-extended\/([^/]+)\/?$/.exec(String(o).replace(/\\/g,"/"))).filter(Boolean).map(o=>o[1]).sort(),s=t.type?[t.type]:Object.keys(Ve);console.log(),console.log(ee.bold("GitHub Copilot target")),console.log(ee.dim(`Package catalog: ${gt}`));for(let o of s){let i=o.charAt(0).toUpperCase()+o.slice(1),a=o==="instructions"?await Kv():await os(o),c=await Bv(e,o),l=o==="instructions"?n:[];if(console.log(),console.log(ee.bold(i)),!a.length&&!c.length&&!l.length){console.log(ee.dim(" (none)"));continue}a.forEach(d=>console.log(` ${d} ${ee.dim("(package)")}`)),l.forEach(d=>console.log(` ${d} ${ee.dim("(opt-in)")}`)),c.forEach(d=>console.log(` ${d} ${ee.dim("(project)")}`))}await Jp(e,"copilot"),console.log()}async function Yp(e={}){try{let t=Kp(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await z(t),n=r.host,s=n?[n]:await ce(t);if(e.target==="claude")return await Bp({...e,path:t},n);if(!e.target){if((await ve(t,{checkout:r})).unmigrated&&(u.error(Be),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(Ue),process.exit(1)),s[0]==="claude")return await Bp({...e,path:t},n)}e.type&&!Ve[e.type]&&(u.error(`Unknown asset type: ${e.type}`),u.info(`Valid types: ${Object.keys(Ve).join(", ")}`),process.exit(1)),await zv(t,e)}catch(t){u.error(`List failed: ${t.message}`),process.exit(1)}}Re();import{readFileSync as Jv,existsSync as Yv}from"node:fs";import{join as qv}from"node:path";var tc=qv(I,"CATALOG.md");function Xv(){return Yv(tc)?Jv(tc,"utf-8"):null}async function qp(){let e=Xv();e===null&&(console.error(`Error loading catalog: ${tc} not found in the installed package.`),process.exit(1)),console.log(e)}W();U();import{resolve as Qv,join as Yo,dirname as Xp}from"node:path";import{stat as Zv,readFile as tf}from"node:fs/promises";import"@inquirer/prompts";Fe();import et from"picocolors";async function Qp(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=Oe(e),n=!1;if(await w(r))try{n=!!JSON.parse(await tf(r,"utf-8")).mcpServers?.["vesper-indexing"]}catch{n=!1}u.info(`Configured: ${n?"\u2713 yes":"\u2717 no"} (${r})`),u.info(`Server built: ${af(await of())}`);let s=nc(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 Ao(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 rf=new Set(["enable","disable","sync","add","remove"]),ek=rf,nf="Vesper regenerates them at every session start \u2014 `vespercli mcp disable` makes no lasting change.";function tk(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 rc(e,t=!0){if(await Dt(e,t),t){let r=await Ou(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(nf))}function nc(e){return Yo(e,".vesper","index.db")}function rk(e){return Yo(e,".vesper","indexing-status.json")}async function sf(e){let t=rk(e);try{let r=await tf(t,"utf-8");return JSON.parse(r)}catch{return null}}async function of(){let e=qe();if(!await w(e))return"missing";let t=Xp(Xp(e)),r=[Yo(t,"node_modules","@modelcontextprotocol","sdk","package.json"),Yo(t,"node_modules","zod","package.json")];for(let n of r)if(!await w(n))return"broken";return"ready"}function af(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 nk(e){try{let t=await Zv(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 Zp(e,t=!1){let r=await Gs(e),n=await of(),s=nc(e),o=await w(s),i=await sf(e);if(console.log(),u.header("vesper-indexing MCP Server"),console.log(),u.info(`Configured: ${r?"\u2713 yes":"\u2717 no"}`),u.info(`Server built: ${af(n)}`),u.info(`Index exists: ${o?"\u2713 yes":"\u2717 no"}`),i)if(console.log(),i.status==="indexing")if(t){await sk(e,i);return}else{let a=i.startedAt?Math.round((Date.now()-new Date(i.startedAt).getTime())/1e3):0;u.info(et.yellow("\u27F3 Indexing in progress...")),u.info(` Files processed: ${et.cyan(i.filesProcessed)}`),u.info(` Elapsed: ${et.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 nk(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 sk(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 sf(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(`
|
|
177
|
+
\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 ef(e,t=!1){let r=nc(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 ok(e){let t=await Zt(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 ik(e){await Zt(e,!1),u.success("MCP servers removed from .vscode/mcp.json until the next session start"),u.info(nf),u.info("Reload VS Code to apply changes")}async function cf(e){let t=await ct(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 ak(e){let t=await B(e),r=await _(e,t),n=await K(e,t),s=await cf(e),o=n[F]||{},i=new Set(xe),a=[],c=[],l=!1;n[F]||(n[F]={});for(let p of xe)o[p]||(n[F][p]=!0,a.push(p),l=!0);for(let p of s){let h=MCP_TOOLS_BY_AGENT[p]||[];for(let g of h)o[g]||(n[F][g]=!0,a.push(g),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[g,f]of Object.entries(MCP_TOOLS_BY_AGENT))if(f.includes(p)){h=!0;break}h&&!d.has(p)&&(delete n[F][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[F]).length,l&&await ne(e,n),await O(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 g=a.filter(f=>(MCP_TOOLS_BY_AGENT[h]||[]).includes(f));g.length>0&&u.info(` ${h}: ${g.length} tools`)}}c.length>0&&u.info(`Removed ${c.length} orphaned tool(s)`)}u.info(`
|
|
176
178
|
Total approved tools: ${r.mcp.toolCount}`),s.length>0&&u.info(`Agents with tools: ${s.join(", ")}`),l&&u.info(`
|
|
177
|
-
Reload VS Code to apply changes`)}async function
|
|
178
|
-
Reload VS Code to activate the MCP server`)}async function
|
|
179
|
-
Reload VS Code to deactivate the MCP server`)}async function
|
|
180
|
-
Reload the Claude Code session to activate the MCP server`)}async function
|
|
181
|
-
Reload the Claude Code session to deactivate the MCP server`)}async function ok(e){let{configured:t,custom:r}=await Su(e);console.log(),u.header("MCP Servers (Claude Code target)"),console.log(),u.info("Available servers:");for(let[n,s]of Object.entries(_e)){let i=t.includes(n)?et.green("\u2713"):et.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(` ${et.blue("\u25C6")} ${n}`)}console.log(),u.info(`Installed: ${t.length} server(s)`)}async function nf(e,t,r={}){let n=Uv(r.path||process.cwd());await w(n)||(u.error(`Directory not found: ${n}`),process.exit(1));let s=(await z(n)).host,o=s?[s]:await ce(n);!r.target&&o.length>1&&(u.error(He),process.exit(1)),!r.target&&o.length===0&&Bv.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(qp.has(e)&&s!=="claude"&&(u.error(Kv(e)),process.exit(1)),e){case"enable":return await Za(n,!0);case"disable":return await Za(n,!1);case"sync":return await Za(n,!0);case"add":return await nk(n,t);case"remove":return await sk(n,t);case"list":return await ok(n);case"status":return await Kp(n,s);case"reindex":return await Jp(n,r.full);default:return e&&u.warn(`'${e}' is not applicable to the Claude Code target \u2014 showing status instead.`),await Kp(n,s)}switch(e){case"status":await zp(n,r.watch);break;case"add":await ek(n,t);break;case"remove":await tk(n,t);break;case"list":await rk(n);break;case"reindex":await Jp(n,r.full);break;case"enable":await qv(n);break;case"disable":await Xv(n);break;case"sync":await Qv(n);break;case"approve":await Zv(n);break;default:await zp(n,r.watch)}}Me();U();import{resolve as ik}from"node:path";async function of(e,t,r,n={}){let s=ik(n.path||process.cwd());if(!e){sf();return}switch(e){case"add":await ak(s,t,r);break;case"remove":await ck(s,t,r);break;case"list":await lk(s,t);break;default:u.error(`Unknown subcommand: ${e}`),sf()}}async function ak(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 js(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 ck(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 Rs(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 lk(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 Ls(e);u.info(`${te}:`),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 sf(){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")}W();U();import{resolve as af}from"node:path";Me();async function uk(e={},t){let r=af(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 so({workspaceRoot:r,namePrefix:await Lr(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 ao(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."),mr(await Wt(r,"claude"))}async function dk({isTTY:e=!!process.stdout.isTTY,check:t=Ko,timeoutMs:r=Bo}={}){if(!e)return[];let n=[];try{n=await t({timeoutMs:r})}catch{n=[]}let s=n.filter(o=>o.status==="stale").map($p);for(let o of s)u.info(o);return s}async function cf(e={}){try{let t=af(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await z(t);(await we(t,{checkout:r})).unmigrated&&(u.error(Be),process.exit(1));let n=e.target?null:r.host,s=e.target?[e.target]:n?[n]:await ce(t);if(s.length===0){u.warn('Vesper is not initialized. Run "vespercli init" first.');return}if(!e.target&&s.length>1&&(u.error(He),process.exit(1)),s.includes("claude")&&await uk({...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 To(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."),mr(await Wt(t,"copilot"));let a=await dr(t);a==="removed"&&u.info("Retired .vesper/instructions/vesper-host-guard.instructions.md (no longer used)."),a==="kept"&&u.warn(Hr())}await dk(e)}catch(t){u.error(`Update failed: ${t.message}`),process.exit(1)}}W();U();import{resolve as pk,join as lf}from"node:path";rt();ot();Me();async function fk(e){await Rl(e)}async function rc(e,t,{quiet:r=!1}={}){if(t?.action!=="bootstrap"||!G.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 hk(e,t,{quiet:r});let o=[],i=[],a=async(g,f)=>{try{return await f()}catch(m){i.push(g),u.warn(`Bootstrap step "${g}" failed (continuing): ${m?.message??m}`);return}},l={sshCommandConfigured:s?!!await V(["config","--get","core.sshCommand"],{cwd:e}):!1},d=s?gk(e,l).catch(()=>({})):Promise.resolve({});await a("mcp",async()=>{n==="claude"?(await Dt(e,!0),o.push(".mcp.json regenerated for this worktree"),await fo(e),o.push(".claude/settings.local.json marketplace source regenerated for this machine")):(await Wn(e,!0),o.push(".vscode/mcp.json regenerated for this worktree"))}),await a("index",async()=>{let g=lf(e,".vesper","index.db");if(!await w(g)){let f=await zo(e,!1);f.success&&o.push(`code index built (${f.filesIndexed} files)`)}}),await a("gitignore",()=>hn(e)),await a("tracked-local",async()=>{let g=await mn(e);if(g.length>0){let f=g.map(m=>`'${m.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",()=>En(e));p&&o.push(...Sn(p)),await a("attributes",()=>bn(e)),await a("merge-driver",()=>xn(e)),o.push(p&&xi(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",()=>So(e,n,{unattended:!0})),await a("ledger",()=>fk(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 g of o)u.info(` ${g}`)}return{host:n,failed:i}}async function tc(e,t){return await V(["check-ignore","-q","--",t],{cwd:e,timeout:5e3})!==null}async function hk(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 tc(e,".vesperrc");if(l||i.push(".vesperrc (ledger not re-recorded)"),await a("mcp",async()=>{for(let d of c){if(!await tc(e,d)){i.push(d);continue}d===".mcp.json"?(await Dt(e,!0,{record:l}),s.push(".mcp.json regenerated")):d===".claude/settings.local.json"?(await fo(e,{record:l}),s.push(".claude/settings.local.json regenerated")):(await Wn(e,!0,{record:l}),s.push(".vscode/mcp.json regenerated"))}}),await a("index",async()=>{let d=".vesper/index.db";if(!await tc(e,d)){i.push(d);return}if(!await w(lf(e,d))){let p=await zo(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 mk(e,t,{runningHost:r}={}){if(!await w(e))return{skipped:"not-vesperized"};let n=await Eo(e,{runningHost:r});if(n.action==="bootstrap"){let{host:o,failed:i}=await rc(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 gk(e,{sshCommandConfigured:t=!1}={}){let r=await V(["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 yt(["fetch",s,o],{cwd:e,timeout:15e3,env:cn(process.env,{sshCommandConfigured:t}),detached:!0});return!i.ok&&li.test(i.stderr)?(u.warn(ui(`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 uf(e,t={}){let r=pk(t.path||process.cwd()),n=!!t.quiet;switch(e){case"bootstrap":case void 0:return mk(r,n,{runningHost:t.runningHost});default:u.error(`Unknown subcommand: ${e}. Usage: vespercli worktree bootstrap`),process.exit(1)}}import{resolve as yk}from"node:path";Me();async function df(e={}){let t=yk(e.path||process.cwd()),r=!!e.quiet,n=e.runningHost;if(n!==void 0&&!G.includes(n))return r||u.error(`--running-host must be one of: ${G.join(", ")} (received "${n}").`),{exitCode:ke.ERROR,report:null};let s;try{s=await Br(t,{runningHost:n})}catch(i){return r||u.error(`doctor failed unexpectedly: ${i?.message||i}`),{exitCode:ke.ERROR,report:null}}let o=Ao(s);return r||wk(s),{exitCode:o,report:s}}function wk(e){if(e.errors.length+e.warnings.length+e.infos.length===0){u.success("No issues found \u2014 this Vesper workspace is healthy.");return}nc("Errors",e.errors,r=>u.error(r)),nc("Warnings",e.warnings,r=>u.warn(r)),nc("Info",e.infos,r=>u.info(r))}function nc(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 Ak}from"node:path";import{readFile as vk,readdir as kk,stat as gf}from"node:fs/promises";import{homedir as Qn}from"node:os";import{join as $t,resolve as yf,isAbsolute as Sk}from"node:path";var sc=Object.freeze({NOT_ENABLED:"plugin-not-enabled",NOT_DECLARED:"marketplace-not-declared",SOURCE_MISSING:"marketplace-source-missing"});function oc(e,t){return e.replace(/^~(?=$|[\\/])/,t)}function wf({env:e=process.env,homeDir:t=Qn()}={}){let r=typeof e.CLAUDE_CONFIG_DIR=="string"?e.CLAUDE_CONFIG_DIR.trim():"";return r?yf(oc(r,t)):$t(t,".claude")}function pf({env:e=process.env,homeDir:t=Qn()}={}){let r=typeof e.CLAUDE_CODE_PLUGIN_CACHE_DIR=="string"?e.CLAUDE_CODE_PLUGIN_CACHE_DIR.trim():"";return r?yf(oc(r,t)):$t(wf({env:e,homeDir:t}),"plugins")}function Ek(e=process.platform){return e==="darwin"?"/Library/Application Support/ClaudeCode":e==="win32"?"C:\\Program Files\\ClaudeCode":"/etc/claude-code"}async function ff(e){try{let t=JSON.parse(await vk(e,"utf-8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}async function hf(e){try{return await gf(e),!0}catch{return!1}}async function bk(e){try{return(await gf(e)).isFile()}catch{return!1}}async function xk(e,{env:t=process.env,homeDir:r=Qn(),platform:n=process.platform,managedDir:s}={}){let o=s??Ek(n),i=[{scope:"user",path:$t(wf({env:t,homeDir:r}),"settings.json")},{scope:"project",path:Oe(e)},{scope:"local",path:po(e)},{scope:"managed",path:$t(o,"managed-settings.json")}];try{let a=(await kk($t(o,"managed-settings.d"))).filter(c=>c.endsWith(".json")).sort();for(let c of a)i.push({scope:"managed",path:$t(o,"managed-settings.d",c)})}catch{}return i}function mf(e,t=Qn()){let r=s=>{if(typeof s!="string"||!s.trim())return null;let o=oc(s.trim(),t);return Sk(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"?r(n):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 _k(e){return await hf(e)?await bk(e)?!0:hf($t(e,".claude-plugin","marketplace.json")):!1}async function vf(e,t={}){let r=t.env??process.env,n=t.homeDir??Qn(),s=await xk(e,{...t,env:r,homeDir:n}),o,i=null,a,c=[];for(let h of s){let g=await ff(h.path);if(!g)continue;let f=g.enabledPlugins;f&&typeof f=="object"&&typeof f[st]=="boolean"&&(h.scope==="managed"?a!==!0&&(a=f[st]):(o=f[st],i=h.scope));let m=g.extraKnownMarketplaces;m&&typeof m=="object"&&m[We]!==void 0&&m[We]!==null&&c.push({scope:h.scope,path:h.path,localPath:mf(m[We],n),exists:null})}a!==void 0&&(o=a,i="managed");let l=await ff($t(pf({env:r,homeDir:n}),"known_marketplaces.json"));if(l&&l[We]!==void 0&&l[We]!==null){let h=l[We],g=h&&typeof h=="object"&&h.source&&typeof h.source=="object"&&h.source.source!=="directory"&&h.source.source!=="file";c.push({scope:"known_marketplaces",path:$t(pf({env:r,homeDir:n}),"known_marketplaces.json"),localPath:g?null:mf(h,n),exists:null})}let d=typeof r.CLAUDE_CODE_PLUGIN_SEED_DIR=="string"&&r.CLAUDE_CODE_PLUGIN_SEED_DIR.trim()!=="",p=[];if(o!==!0&&p.push(sc.NOT_ENABLED),c.length===0&&!d)p.push(sc.NOT_DECLARED);else if(c.length>0&&!d){let h=!1,g=!1;for(let f of c){if(f.localPath===null){h=!0;continue}f.exists=await _k(f.localPath),f.exists&&(g=!0)}!h&&!g&&p.push(sc.SOURCE_MISSING)}return{absent:p.length>0,missing:p,enabled:o,enabledBy:i,declarations:c}}ot();rt();async function $k(e,t){try{let{realpath:r}=await import("node:fs/promises"),{resolve:n}=await import("node:path"),s=await V(["rev-parse","--absolute-git-dir"],{cwd:t,env:qt(process.env),timeout:5e3});return s?await r(n(process.cwd(),e))===await r(s):!1}catch{return!1}}async function kf(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 Sf(e){process.stdout.write(`${e}
|
|
182
|
-
`)}async function
|
|
183
|
-
`),{exitCode:
|
|
184
|
-
`),await
|
|
185
|
-
`),!s.identity)return{exitCode:a.length?
|
|
186
|
-
`);return{exitCode:l,emitted:c,resolved:o,decision:s}}import{resolve as
|
|
187
|
-
`)}async function
|
|
179
|
+
Reload VS Code to apply changes`)}async function ck(e){let t=await B(e),r=await _(e,t),s=(await K(e,t))[F]||{},o=Object.keys(s).length,i=await cf(e);console.log(),u.header("MCP Tool Approval Status"),console.log();let a=xe.filter(d=>s[d]);if(u.info(`Core tools: ${a.length}/${xe.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]),g=h.length===p.length?et.green("\u2713"):et.yellow("\u26A0");u.info(` ${g} ${d}: ${h.length}/${p.length} approved`)}}let c=[...xe];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 lf(){return Object.keys(Ae).filter(e=>!_e.includes(e))}async function lk(e,t){t||(u.error("Server name required. Usage: vespercli mcp add <server>"),u.info(`Available servers: ${lf().join(", ")}`),process.exit(1)),console.log(),u.header("Add MCP Server"),console.log();let r=await Ir(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(`
|
|
180
|
+
Reload VS Code to activate the MCP server`)}async function uk(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 Us(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(`
|
|
181
|
+
Reload VS Code to deactivate the MCP server`)}async function dk(e){let t=await B(e),r=await _(e,t),n=await Ge(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(Ae)){let d=o.includes(a)?et.green("\u2713"):et.dim("\u25CB"),p=c.tools?.length||0;u.info(` ${d} ${a} (${p} tools)`)}let i=o.filter(a=>!Ae[a]);if(i.length>0){console.log(),u.info("Custom servers:");for(let a of i)u.info(` ${et.blue("\u25C6")} ${a}`)}console.log(),u.info(`Installed: ${o.length} server(s)`)}async function pk(e,t){t||(u.error("Server name required. Usage: vespercli mcp add <server> --target claude"),u.info(`Available servers: ${lf().join(", ")}`),process.exit(1));let r=await fo(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(`
|
|
182
|
+
Reload the Claude Code session to activate the MCP server`)}async function fk(e,t){t||(u.error("Server name required. Usage: vespercli mcp remove <server> --target claude"),process.exit(1));let r=await Au(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(`
|
|
183
|
+
Reload the Claude Code session to deactivate the MCP server`)}async function hk(e){let{configured:t,custom:r}=await $u(e);console.log(),u.header("MCP Servers (Claude Code target)"),console.log(),u.info("Available servers:");for(let[n,s]of Object.entries(Ae)){let i=t.includes(n)?et.green("\u2713"):et.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(` ${et.blue("\u25C6")} ${n}`)}console.log(),u.info(`Installed: ${t.length} server(s)`)}async function uf(e,t,r={}){let n=Qv(r.path||process.cwd());await w(n)||(u.error(`Directory not found: ${n}`),process.exit(1));let s=(await z(n)).host,o=s?[s]:await ce(n);!r.target&&o.length>1&&(u.error(Ue),process.exit(1)),!r.target&&o.length===0&&ek.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(rf.has(e)&&s!=="claude"&&(u.error(tk(e)),process.exit(1)),e){case"enable":return await rc(n,!0);case"disable":return await rc(n,!1);case"sync":return await rc(n,!0);case"add":return await pk(n,t);case"remove":return await fk(n,t);case"list":return await hk(n);case"status":return await Qp(n,s);case"reindex":return await ef(n,r.full);default:return e&&u.warn(`'${e}' is not applicable to the Claude Code target \u2014 showing status instead.`),await Qp(n,s)}switch(e){case"status":await Zp(n,r.watch);break;case"add":await lk(n,t);break;case"remove":await uk(n,t);break;case"list":await dk(n);break;case"reindex":await ef(n,r.full);break;case"enable":await ok(n);break;case"disable":await ik(n);break;case"sync":await ak(n);break;case"approve":await ck(n);break;default:await Zp(n,r.watch)}}Fe();U();import{resolve as mk}from"node:path";async function pf(e,t,r,n={}){let s=mk(n.path||process.cwd());if(!e){df();return}switch(e){case"add":await gk(s,t,r);break;case"remove":await yk(s,t,r);break;case"list":await wk(s,t);break;default:u.error(`Unknown subcommand: ${e}`),df()}}async function gk(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 Rs(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 yk(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 Ls(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 wk(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 Ns(e);u.info(`${te}:`),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 df(){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")}W();U();import{resolve as ff}from"node:path";Fe();async function vk(e={},t){let r=ff(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 io({workspaceRoot:r,namePrefix:await Lr(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 lo(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."),mr(await Wt(r,"claude"))}async function kk({isTTY:e=!!process.stdout.isTTY,check:t=zo,timeoutMs:r=Ko}={}){if(!e)return[];let n=[];try{n=await t({timeoutMs:r})}catch{n=[]}let s=n.filter(o=>o.status==="stale").map(jp);for(let o of s)u.info(o);return s}async function hf(e={}){try{let t=ff(e.path||process.cwd());await w(t)||(u.error(`Directory not found: ${u.formatPath(t)}`),process.exit(1));let r=await z(t);(await ve(t,{checkout:r})).unmigrated&&(u.error(Be),process.exit(1));let n=e.target?null:r.host,s=e.target?[e.target]:n?[n]:await ce(t);if(s.length===0){u.warn('Vesper is not initialized. Run "vespercli init" first.');return}if(!e.target&&s.length>1&&(u.error(Ue),process.exit(1)),s.includes("claude")&&await vk({...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 Oo(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."),mr(await Wt(t,"copilot"));let a=await dr(t);a==="removed"&&u.info("Retired .vesper/instructions/vesper-host-guard.instructions.md (no longer used)."),a==="kept"&&u.warn(Wr())}await kk(e)}catch(t){u.error(`Update failed: ${t.message}`),process.exit(1)}}W();U();import{resolve as Sk,join as mf}from"node:path";rt();ot();Fe();async function Ek(e){await Nl(e)}async function oc(e,t,{quiet:r=!1}={}){if(t?.action!=="bootstrap"||!G.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 bk(e,t,{quiet:r});let o=[],i=[],a=async(g,f)=>{try{return await f()}catch(m){i.push(g),u.warn(`Bootstrap step "${g}" failed (continuing): ${m?.message??m}`);return}},l={sshCommandConfigured:s?!!await V(["config","--get","core.sshCommand"],{cwd:e}):!1},d=s?_k(e,l).catch(()=>({})):Promise.resolve({});await a("mcp",async()=>{n==="claude"?(await Dt(e,!0),o.push(".mcp.json regenerated for this worktree"),await ho(e),o.push(".claude/settings.local.json marketplace source regenerated for this machine")):(await Bn(e,!0),o.push(".vscode/mcp.json regenerated for this worktree"))}),await a("index",async()=>{let g=mf(e,".vesper","index.db");if(!await w(g)){let f=await Jo(e,!1);f.success&&o.push(`code index built (${f.filesIndexed} files)`)}}),await a("gitignore",()=>gn(e)),await a("tracked-local",async()=>{let g=await yn(e);if(g.length>0){let f=g.map(m=>`'${m.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",()=>xn(e));p&&o.push(...bn(p)),await a("attributes",()=>_n(e)),await a("merge-driver",()=>An(e)),o.push(p&&Ai(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",()=>Eo(e,n,{unattended:!0})),await a("ledger",()=>Ek(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 g of o)u.info(` ${g}`)}return{host:n,failed:i}}async function sc(e,t){return await V(["check-ignore","-q","--",t],{cwd:e,timeout:5e3})!==null}async function bk(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 sc(e,".vesperrc");if(l||i.push(".vesperrc (ledger not re-recorded)"),await a("mcp",async()=>{for(let d of c){if(!await sc(e,d)){i.push(d);continue}d===".mcp.json"?(await Dt(e,!0,{record:l}),s.push(".mcp.json regenerated")):d===".claude/settings.local.json"?(await ho(e,{record:l}),s.push(".claude/settings.local.json regenerated")):(await Bn(e,!0,{record:l}),s.push(".vscode/mcp.json regenerated"))}}),await a("index",async()=>{let d=".vesper/index.db";if(!await sc(e,d)){i.push(d);return}if(!await w(mf(e,d))){let p=await Jo(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 xk(e,t,{runningHost:r}={}){if(!await w(e))return{skipped:"not-vesperized"};let n=await bo(e,{runningHost:r});if(n.action==="bootstrap"){let{host:o,failed:i}=await oc(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 _k(e,{sshCommandConfigured:t=!1}={}){let r=await V(["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 yt(["fetch",s,o],{cwd:e,timeout:15e3,env:un(process.env,{sshCommandConfigured:t}),detached:!0});return!i.ok&&di.test(i.stderr)?(u.warn(pi(`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 gf(e,t={}){let r=Sk(t.path||process.cwd()),n=!!t.quiet;switch(e){case"bootstrap":case void 0:return xk(r,n,{runningHost:t.runningHost});default:u.error(`Unknown subcommand: ${e}. Usage: vespercli worktree bootstrap`),process.exit(1)}}import{resolve as Ak}from"node:path";Fe();async function yf(e={}){let t=Ak(e.path||process.cwd()),r=!!e.quiet,n=e.runningHost;if(n!==void 0&&!G.includes(n))return r||u.error(`--running-host must be one of: ${G.join(", ")} (received "${n}").`),{exitCode:Se.ERROR,report:null};let s;try{s=await zr(t,{runningHost:n})}catch(i){return r||u.error(`doctor failed unexpectedly: ${i?.message||i}`),{exitCode:Se.ERROR,report:null}}let o=$o(s);return r||$k(s),{exitCode:o,report:s}}function $k(e){if(e.errors.length+e.warnings.length+e.infos.length===0){u.success("No issues found \u2014 this Vesper workspace is healthy.");return}ic("Errors",e.errors,r=>u.error(r)),ic("Warnings",e.warnings,r=>u.warn(r)),ic("Info",e.infos,r=>u.info(r))}function ic(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 Lk}from"node:path";import{readFile as Ck,readdir as Tk,stat as Ef}from"node:fs/promises";import{homedir as Zn}from"node:os";import{join as $t,resolve as bf,isAbsolute as Ok}from"node:path";var qo=Object.freeze({NOT_ENABLED:"plugin-not-enabled",NOT_DECLARED:"marketplace-not-declared",SOURCE_MISSING:"marketplace-source-missing",INVALID_DECLARATION:"marketplace-declaration-invalid"});function ac(e,t){return e.replace(/^~(?=$|[\\/])/,t)}function xf({env:e=process.env,homeDir:t=Zn()}={}){let r=typeof e.CLAUDE_CONFIG_DIR=="string"?e.CLAUDE_CONFIG_DIR.trim():"";return r?bf(ac(r,t)):$t(t,".claude")}function wf({env:e=process.env,homeDir:t=Zn()}={}){let r=typeof e.CLAUDE_CODE_PLUGIN_CACHE_DIR=="string"?e.CLAUDE_CODE_PLUGIN_CACHE_DIR.trim():"";return r?bf(ac(r,t)):$t(xf({env:e,homeDir:t}),"plugins")}function Pk(e=process.platform){return e==="darwin"?"/Library/Application Support/ClaudeCode":e==="win32"?"C:\\Program Files\\ClaudeCode":"/etc/claude-code"}async function vf(e){try{let t=JSON.parse(await Ck(e,"utf-8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}async function kf(e){try{return await Ef(e),!0}catch{return!1}}async function Ik(e){try{return(await Ef(e)).isFile()}catch{return!1}}async function jk(e,{env:t=process.env,homeDir:r=Zn(),platform:n=process.platform,managedDir:s}={}){let o=s??Pk(n),i=[{scope:"user",path:$t(xf({env:t,homeDir:r}),"settings.json")},{scope:"project",path:Pe(e)},{scope:"local",path:Hr(e)},{scope:"managed",path:$t(o,"managed-settings.json")}];try{let a=(await Tk($t(o,"managed-settings.d"))).filter(c=>c.endsWith(".json")).sort();for(let c of a)i.push({scope:"managed",path:$t(o,"managed-settings.d",c)})}catch{}return i}function Sf(e,t=Zn()){let r=s=>{if(typeof s!="string"||!s.trim())return null;let o=ac(s.trim(),t);return Ok(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 Rk(e){return await kf(e)?await Ik(e)?!0:kf($t(e,".claude-plugin","marketplace.json")):!1}async function _f(e,t={}){let r=t.env??process.env,n=t.homeDir??Zn(),s=await jk(e,{...t,env:r,homeDir:n}),o,i=null,a,c=[],l=[];for(let g of s){let f=await vf(g.path);if(!f)continue;let m=f.enabledPlugins;m&&typeof m=="object"&&typeof m[st]=="boolean"&&(g.scope==="managed"?a!==!0&&(a=m[st]):(o=m[st],i=g.scope));let y=f.extraKnownMarketplaces;if(y&&typeof y=="object"&&y[we]!==void 0&&y[we]!==null){let k=y[we];if(k&&typeof k=="object"&&typeof k.source=="string"){l.push({scope:g.scope,path:g.path});continue}c.push({scope:g.scope,path:g.path,localPath:Sf(k,n),exists:null})}}a!==void 0&&(o=a,i="managed");let d=await vf($t(wf({env:r,homeDir:n}),"known_marketplaces.json"));if(d&&d[we]!==void 0&&d[we]!==null){let g=d[we],f=g&&typeof g=="object"&&g.source&&typeof g.source=="object"&&g.source.source!=="directory"&&g.source.source!=="file";c.push({scope:"known_marketplaces",path:$t(wf({env:r,homeDir:n}),"known_marketplaces.json"),localPath:f?null:Sf(g,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(qo.NOT_ENABLED),c.length===0&&!p)h.push(l.length?qo.INVALID_DECLARATION:qo.NOT_DECLARED);else if(c.length>0&&!p){let g=!1,f=!1;for(let m of c){if(m.localPath===null){g=!0;continue}m.exists=await Rk(m.localPath),m.exists&&(f=!0)}!g&&!f&&h.push(qo.SOURCE_MISSING)}return{absent:h.length>0,missing:h,enabled:o,enabledBy:i,declarations:c,invalidDeclarations:l}}ot();rt();async function Nk(e,t){try{let{realpath:r}=await import("node:fs/promises"),{resolve:n}=await import("node:path"),s=await V(["rev-parse","--absolute-git-dir"],{cwd:t,env:qt(process.env),timeout:5e3});return s?await r(n(process.cwd(),e))===await r(s):!1}catch{return!1}}async function Af(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 $f(e){process.stdout.write(`${e}
|
|
184
|
+
`)}async function Cf(e={}){let t=Lk(e.path||process.cwd()),r={};if(process.env.GIT_DIR&&await Nk(process.env.GIT_DIR,t))for(let n of ps())n in process.env&&(r[n]=process.env[n],delete process.env[n]);try{return await Mk(t,e)}finally{Object.assign(process.env,r)}}async function Mk(e,t){let{runningHost:r}=t,n=t.bootstrap!==!1;if(r!==void 0&&!G.includes(r))return process.stderr.write(`vespercli guard: --running-host must be one of: ${G.join(", ")} (received "${r}")
|
|
185
|
+
`),{exitCode:Se.ERROR,emitted:[],resolved:{host:null,source:null}};let s=await bo(e,{runningHost:r}),o={host:s.checkout?.host??null,source:s.checkout?.source??null},i=null;if(s.identity)try{i=await zr(e,{runningHost:r,checkout:s.checkout})}catch{i=null}if(s.action==="refuse")return $f(So),process.stdout.write(`${s.message}
|
|
186
|
+
`),await Af(async()=>{if(s.reason!=="switch-in-progress")try{await Yu(e,r,{checkout:s.checkout})}catch{}}),{exitCode:Se.HOST_MISMATCH,emitted:[So],resolved:o,decision:s};let a=[];if(await Af(async()=>{s.action==="bootstrap"&&n&&({failed:a}=await oc(e,s,{quiet:!0}))}),s.action==="none"&&s.note&&(s.identity||process.stderr.isTTY)&&process.stderr.write(`${s.note}
|
|
187
|
+
`),!s.identity)return{exitCode:a.length?Se.ERROR:Se.OK,emitted:[],resolved:o,decision:s};let c=[];if(r==="claude"&&o.host==="claude"){let d=null;try{d=await _f(e)}catch{d=null}d?.absent&&($f(ma),c.push(ma))}let l=i?$o(i):Se.ERROR;if(a.length&&l===Se.OK&&(l=Se.ERROR),i&&l===Se.ERROR)for(let d of i.errors)process.stderr.write(`vespercli guard: ${d.message} (fix: ${d.fix})
|
|
188
|
+
`);return{exitCode:l,emitted:c,resolved:o,decision:s}}import{resolve as Fk,isAbsolute as Vk,join as Dk}from"node:path";W();async function Tf(e={}){let t=Fk(e.path||process.cwd()),r=!!e.json,n=await nu(t);if(!n.ok){let l=n.reason==="missing"?`No ${se} in ${t} \u2014 run \`vespercli init\` to seed one.`:`${se} is invalid: ${n.errors.join("; ")}`;return r?console.log(JSON.stringify({pass:!1,error:l,exitCode:ar.NO_CONFIG})):console.error(l),{exitCode:ar.NO_CONFIG,report:null}}let s=null;if(e.plan){let l=Vk(e.plan)?e.plan:Dk(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:ar.NO_CONFIG})):console.error(d),{exitCode:ar.NO_CONFIG,report:null}}s=(await su(l)).planned}let o=[];for(let l of n.config.checks)o.push(au(l,t));let i=await cu(t,e.base),a=i.skipped?null:i,c=ou({config:n.config,checks:o,diff:a,planned:s,diffSkipped:i.skipped||null});return console.log(r?JSON.stringify(c):iu(c)),{exitCode:c.pass?ar.PASS:ar.FAIL,report:c}}import{resolve as Gk}from"node:path";async function Hk(){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 Of(e,t={}){let r=Gk(t.path||process.cwd()),n=!!t.json;if(e==="tail"){let a=t.lines===void 0?Wo:Number(t.lines);if(!Number.isFinite(a)||a<0)return console.error(`-n must be a non-negative number (received "${t.lines}")`),{exitCode:qr.INVALID};let{rows:c,malformed:l}=await Ap(r,{slug:t.slug}),d=$p(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(Cp(p));return l>0&&!n&&console.error(`(${l} malformed line(s) skipped)`),{exitCode:qr.OK}}if(!Qn.includes(e))return console.error(`Unknown log event "${e}". Use one of: ${Qn.join(", ")}, tail.`),{exitCode:qr.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=Tp(await Hk());a&&(!s.agent&&a.agent&&(s.agent=a.agent),!s.session&&a.session&&(s.session=a.session))}let o=xp(s);if(!o.ok){for(let a of o.errors)console.error(a);return{exitCode:qr.INVALID}}let{rel:i}=await _p(r,o.row,{slug:t.slug});return console.log(n?JSON.stringify({...o.row,file:i}):`logged ${e} \u2192 ${i}`),{exitCode:qr.OK}}import{resolve as Jk}from"node:path";W();import{readdir as Uk,readFile as Wk}from"node:fs/promises";import{join as cc}from"node:path";var lc=".vesper/.tracking/stories",gr=Object.freeze(["refining","backlog","inprogress","inreview","completed"]),Kt=Object.freeze({OK:0,REFUSED:1,INVALID:2});function Bk(e){return e.replace(/\.md$/i,"").replace(/^\d{8}-/,"").replace(/-story$/i,"")}function Kk(e){let t=/^#\s+(.+?)\s*$/m.exec(String(e??""));return t?t[1]:null}async function uc(e,{folder:t}={}){let r=t?[t]:gr,n=[];for(let s of r){let o=cc(e,lc,s),i=[];try{i=await Uk(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=`${lc}/${s}/${a.name}`,l=null;try{l=Kk(await Wk(cc(o,a.name),"utf-8"))}catch{l=null}n.push({slug:Bk(a.name),folder:s,file:a.name,rel:c,title:l})}}return n}async function zk(e,t){let r=String(t??"").trim().toLowerCase();return r?(await uc(e)).filter(n=>n.file.toLowerCase().includes(r)):[]}async function Pf(e,t,r){if(!gr.includes(r))return{ok:!1,reason:"invalid-folder"};let n=await zk(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=`${lc}/${r}/${s.file}`;if(s.folder===r)return{ok:!0,from:s.rel,to:o,method:"noop"};if(await w(cc(e,o)))return{ok:!1,reason:"exists",matches:n};let i=await Ho(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 If(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(`
|
|
189
|
+
`)}async function jf(e,t,r,n={}){let s=Jk(n.path||process.cwd()),o=!!n.json;if(e==="list"){if(n.folder&&!gr.includes(n.folder))return console.error(`--folder must be one of ${gr.join("|")} (received "${n.folder}")`),{exitCode:Kt.INVALID};let i=await uc(s,{folder:n.folder});return console.log(o?JSON.stringify(i):If(i)),{exitCode:Kt.OK}}if(e==="move"){if(!t||!r)return console.error("Usage: vespercli story move <slug> <folder>"),{exitCode:Kt.INVALID};if(!gr.includes(r))return console.error(`Folder must be one of ${gr.join("|")} (received "${r}")`),{exitCode:Kt.INVALID};let i=await Pf(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:
|
|
188
190
|
${a.join(`
|
|
189
|
-
`)}`: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:Kt.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:Kt.OK}}return console.error(`Unknown story subcommand "${e}". Use: move <slug> <folder>, list [--folder <f>].`),{exitCode:Kt.INVALID}}var
|
|
190
|
-
`),t)}le.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(
|
|
191
|
+
`)}`: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:Kt.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:Kt.OK}}return console.error(`Unknown story subcommand "${e}". Use: move <slug> <folder>, list [--folder <f>].`),{exitCode:Kt.INVALID}}var Zk=Qk(import.meta.url),eS=dc(Zk);function tS(e){let t=e;for(;t!==dc(t);){let r=Rf(t,"package.json");if(Xk(r))return r;t=dc(t)}return Rf(e,"..","..","package.json")}var rS=tS(eS),pc=JSON.parse(qk(rS,"utf-8")),le=new Yk;le.name("vespercli").description("Vesper VS Code Agent Suite \u2014 provision an AI agent suite for Claude Code or GitHub Copilot (one host per workspace)").version(pc.version,"-v, --version","Output the current version");le.command("init").description("Initialize vesper for exactly ONE host (GitHub Copilot or Claude Code) 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 tt("--host <host>","The single host to provision: claude or copilot. Interactive prompt if omitted (non-interactive runs reuse the recorded host).").choices(["claude","copilot"])).addOption(new tt("--target <target>","Deprecated alias of --host").hideHelp()).action(e=>Dp({...e,version:pc.version}));function es(e){return new tt("--host <host>",e).choices(["claude","copilot"])}var ts=()=>new tt("--target <target>","Deprecated alias of --host").hideHelp();function rs(e,t){return t.host?{...t,target:t.host}:(t.target&&process.stderr.write(`\`--target\` is deprecated on \`${e}\`; use \`--host\` instead.
|
|
192
|
+
`),t)}le.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(es("Host to act on: claude or copilot (the checkout decides when omitted)")).addOption(ts()).option("--override","Claude Code only: pin a project-level copy of a plugin asset (recorded; reset removes it)").action((e,t,r)=>Wp({type:e,name:t,...rs("add",r)}));le.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 tt("--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 tt("--target <target>","Deprecated alias of --host").hideHelp()).action(zd);le.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(es("Host to list: claude or copilot (the checkout decides when omitted)")).addOption(ts()).action((e,t)=>Yp({type:e,...rs("list",t)}));le.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(es("Host to refresh: claude or copilot (the checkout decides when omitted)")).addOption(ts()).action(e=>hf({...rs("update",e),version:pc.version}));le.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(es("Host to act on: claude or copilot (the checkout decides when omitted)")).addOption(ts()).action((e,t,r)=>Np(e,t,rs("packs",r)));le.command("catalog").description("Show the Vesper catalog (agents, dependencies, requirements)").action(qp);le.command("mcp").description("Manage MCP servers and tool auto-approval").argument("[subcommand]","Subcommand: status, add, remove, list, sync, approve, reindex, enable, disable").argument("[argument]","Argument for subcommand (e.g., server name for add/remove)").option("--path <path>","Workspace root directory",process.cwd()).option("--full","Full reindex (clears existing index)").option("-w, --watch","Watch indexing progress until completion").addOption(es("Host whose MCP config to manage: claude or copilot (the checkout decides when omitted)")).addOption(ts()).action((e,t,r)=>uf(e,t,rs("mcp",r)));le.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)=>pf(e,t,r,n));le.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 tt("--running-host <host>","The host currently running \u2014 enables the host-identity check").choices(["claude","copilot"])).action(async e=>{let{exitCode:t}=await yf(e);process.exit(t)});le.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. 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 tt("--running-host <host>","The host currently running (claude|copilot); omit for no identity claim").choices(["claude","copilot"])).option("--no-bootstrap","Do not invoke worktree bootstrap on the healthy path (testing)").action(async e=>{let{exitCode:t}=await Cf(e);process.exit(t)});le.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 Tf(e);process.exit(t)});le.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 tt("--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 Of(e,t);process.exit(r)});le.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 tt("--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 jf(e,t,r,n);process.exit(s)});le.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 tt("--running-host <host>","The host invoking bootstrap; a mismatch with the provisioned host skips all provisioning").choices(["claude","copilot"])).action(async(e,t)=>{(await gf(e,t))?.failed?.length&&(process.exitCode=1)});le.addHelpText("after",`
|
|
191
193
|
Examples:
|
|
192
194
|
$ vespercli init Pick the single host for this workspace, then initialize
|
|
193
195
|
$ vespercli init --host claude Provision the Claude Code host (CI-friendly)
|