@mthanh/vespercli 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +139 -78
  2. package/assets/CATALOG.md +6 -0
  3. package/assets/claude/agents/feature-wrap-document.md +112 -9
  4. package/assets/claude/skills/agent-fundamentals/SKILL.md +14 -0
  5. package/assets/claude/skills/gitlab-guardrails/SKILL.md +62 -0
  6. package/assets/claude/vesper-orchestrator.md +3 -0
  7. package/assets/core/agents/feature-wrap-document.agent.md +20 -11
  8. package/assets/core/agents/vesper.agent.md +3 -0
  9. package/assets/core/skills/agent-fundamentals/SKILL.md +14 -0
  10. package/assets/hooks/pre-commit +17 -1
  11. package/assets/manifest.json +36 -0
  12. package/assets/skills/aesthetic/manifest.json +1 -1
  13. package/assets/skills/ai-multimodal/manifest.json +1 -1
  14. package/assets/skills/backend-development/manifest.json +1 -1
  15. package/assets/skills/better-auth/manifest.json +1 -1
  16. package/assets/skills/chrome-devtools/manifest.json +1 -1
  17. package/assets/skills/code-review/manifest.json +1 -1
  18. package/assets/skills/databases/manifest.json +1 -1
  19. package/assets/skills/debugging/manifest.json +1 -1
  20. package/assets/skills/devops/manifest.json +1 -1
  21. package/assets/skills/docs-seeker/manifest.json +1 -1
  22. package/assets/skills/document-skills/manifest.json +1 -1
  23. package/assets/skills/frontend-design/manifest.json +1 -1
  24. package/assets/skills/gitlab-guardrails/SKILL.md +62 -0
  25. package/assets/skills/gitlab-guardrails/manifest.json +8 -0
  26. package/assets/skills/google-adk-python/manifest.json +1 -1
  27. package/assets/skills/mcp-builder/manifest.json +1 -1
  28. package/assets/skills/mermaidjs-v11/manifest.json +1 -1
  29. package/assets/skills/premium-frontend-ui/manifest.json +6 -4
  30. package/assets/skills/problem-solving/manifest.json +1 -1
  31. package/assets/skills/react-mui-tanstack/manifest.json +16 -16
  32. package/assets/skills/sequential-thinking/manifest.json +1 -1
  33. package/assets/skills/skill-creator/manifest.json +1 -1
  34. package/assets/skills/tailwind-shadcn/manifest.json +102 -102
  35. package/assets/skills/vercel-react-best-practices/manifest.json +2 -2
  36. package/assets/skills/vscode-agent-config/manifest.json +8 -0
  37. package/assets/skills/web-design-guidelines/manifest.json +1 -1
  38. package/assets/skills/web-frameworks/manifest.json +1 -1
  39. package/dist/cli.min.js +26 -24
  40. package/package.json +8 -4
package/dist/cli.min.js CHANGED
@@ -1,36 +1,38 @@
1
- var ps=(e,t)=>()=>(e&&(t=e(e=0)),t);import{access as us,constants as fs,stat as Pr}from"node:fs/promises";async function m(e){try{return await us(e,fs.F_OK),!0}catch{return!1}}var V=ps(()=>{});import{Command as hr}from"commander";import{readFileSync as wr,existsSync as vr}from"node:fs";import{fileURLToPath as yr}from"node:url";import{dirname as Ge,join as ds}from"node:path";V();import{resolve as fn,basename as gn}from"node:path";import{spawn as mn}from"node:child_process";import{confirm as se,input as hn,number as wn,select as vn,checkbox as yn}from"@inquirer/prompts";import{readFile as b,writeFile as A,mkdir as ie,readdir as xs}from"node:fs/promises";import{join as y,dirname as B}from"node:path";import{homedir as tt}from"node:os";import Ss from"strip-json-comments";import{fileURLToPath as gs}from"node:url";import{dirname as Ee,join as oe,resolve as ms}from"node:path";import{readdir as hs}from"node:fs/promises";import{existsSync as ws}from"node:fs";var vs=gs(import.meta.url),ys=Ee(vs);function _s(e){let t=e;for(;t!==Ee(t);){if(ws(oe(t,"package.json")))return t;t=Ee(t)}return ms(e,"..","..","..")}var X=_s(ys),T=oe(X,"assets"),Be=oe(T,"core");function Te(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}`)}var I={agents:{dir:"agents",destDir:"agents",extension:".agent.md",isFolder:!0},prompts:{dir:"prompts",destDir:"prompts",extension:".prompt.md",isFolder:!0},instructions:{dir:"instructions",destDir:"instructions",extension:".instructions.md",isFolder:!0},skills:{dir:"skills",destDir:"skills",extension:"",isFolder:!0}};async function Q(e){let t=I[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=oe(T,t.dir);try{return(await hs(s,{withFileTypes:!0})).filter(o=>o.isDirectory()&&!o.name.startsWith(".")).map(o=>o.name)}catch{return[]}}function qe(e,t){Te(t);let s=I[e];if(!s)throw new Error(`Unknown asset type: ${e}`);return oe(T,s.dir,t)}function j(e){let t=tt();return e.startsWith(t)?"~"+e.slice(t.length).replace(/\\/g,"/"):e.replace(/\\/g,"/")}var ks=/node_modules\/(?:vesper-cli|vespercli)\/(.+)$/;function pe(e){if(typeof e!="string")return e;let t=e.match(ks);return t?j(y(X,t[1])):e}function As(e){return e==="vesper-cli"||e.startsWith("vesper-cli ")||e.endsWith("/vesper-cli")}var Z={agents:"chat.agentFilesLocations",instructions:"chat.instructionsFilesLocations",prompts:"chat.promptFilesLocations",skills:"chat.agentSkillsLocations"},ae="chat.tools.terminal.autoApprove",st="chat.tools.terminal.enableAutoApprove",be="chat.tools.autoApprove",w="chat.tools.eligibleForAutoApproval",nt="chat.agent.maxRequests",rt="chat.includeReferencedInstructions",ot="chat.customAgentInSubagent.enabled",at="chat.agent.enabled",it="github.copilot.chat.omitBaseAgentInstructions",ct="chat.mcp.discovery.enabled",lt="chat.mcp.autoStart",x="github.copilot.chat.additionalReadAccessPaths",M={maxRequests:300,terminalEnableAutoApprove:!0,omitBaseAgentInstructions:!0,enableMcpServer:!0},Cs=[nt,rt,ot,at,it,ct,lt,st,ae,be,w],Ps=["vesper-indexing","sequential-thinking","memory"],Es=[".vesperrc",".mcp.json",".vscode/mcp.json",".vesper/index.db",".vesper/index.db-wal",".vesper/index.db-shm",".vesper/indexing-status.json",".claude/settings.local.json"];var Ke="# <!-- vesper:gitignore:start -->",He="# <!-- vesper:gitignore:end -->";async function ue(e){let t=y(e,".gitignore"),s=[Ke,...Es,He].join(`
2
- `),n=new RegExp(`${Ke}[\\s\\S]*?${He}`),o="";try{o=await b(t,"utf-8")}catch(i){if(i.code!=="ENOENT")throw i;return await A(t,`${s}
3
- `,"utf-8"),{created:!0,updated:!1}}if(n.test(o)){let i=o.replace(n,s);return i!==o?(await A(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let a=o.endsWith(`
1
+ var Ms=(e,t)=>()=>(e&&(t=e(e=0)),t);import{access as Ds,constants as Ls,stat as to}from"node:fs/promises";async function g(e){try{return await Ds(e,Ls.F_OK),!0}catch{return!1}}var F=Ms(()=>{});import{Command as qn}from"commander";import{readFileSync as Kn,existsSync as Hn}from"node:fs";import{fileURLToPath as Jn}from"node:url";import{dirname as et,join as Is}from"node:path";F();import{resolve as Ur,basename as Wr}from"node:path";import{spawn as Br}from"node:child_process";import{confirm as ie,input as qr,number as Kr,select as Hr,checkbox as Jr}from"@inquirer/prompts";import{readFile as T,writeFile as A,mkdir as ue,readdir as Ws}from"node:fs/promises";import{join as y,dirname as J}from"node:path";import{homedir as ft}from"node:os";import Bs from"strip-json-comments";import{fileURLToPath as js}from"node:url";import{dirname as Le,join as le,resolve as Fs}from"node:path";import{readdir as Rs}from"node:fs/promises";import{existsSync as Vs}from"node:fs";var Ns=js(import.meta.url),Gs=Le(Ns);function Us(e){let t=e;for(;t!==Le(t);){if(Vs(le(t,"package.json")))return t;t=Le(t)}return Fs(e,"..","..","..")}var se=Us(Gs),b=le(se,"assets"),st=le(b,"core");function je(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}`)}var I={agents:{dir:"agents",destDir:"agents",extension:".agent.md",isFolder:!0},prompts:{dir:"prompts",destDir:"prompts",extension:".prompt.md",isFolder:!0},instructions:{dir:"instructions",destDir:"instructions",extension:".instructions.md",isFolder:!0},skills:{dir:"skills",destDir:"skills",extension:"",isFolder:!0}};async function re(e){let t=I[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=le(b,t.dir);try{return(await Rs(s,{withFileTypes:!0})).filter(n=>n.isDirectory()&&!n.name.startsWith(".")).map(n=>n.name)}catch{return[]}}function rt(e,t){je(t);let s=I[e];if(!s)throw new Error(`Unknown asset type: ${e}`);return le(b,s.dir,t)}function q(e){let t=ft();return e.startsWith(t)?"~"+e.slice(t.length).replace(/\\/g,"/"):e.replace(/\\/g,"/")}var qs=/node_modules\/(?:vesper-cli|vespercli)\/(.+)$/;function me(e){if(typeof e!="string")return e;let t=e.match(qs);return t?q(y(se,t[1])):e}function Ks(e){return e==="vesper-cli"||e.startsWith("vesper-cli ")||e.endsWith("/vesper-cli")}var H={agents:"chat.agentFilesLocations",instructions:"chat.instructionsFilesLocations",prompts:"chat.promptFilesLocations",skills:"chat.agentSkillsLocations"},de="chat.tools.terminal.autoApprove",gt="chat.tools.terminal.enableAutoApprove",Re="chat.tools.autoApprove",w="chat.tools.eligibleForAutoApproval",mt="chat.agent.maxRequests",ht="chat.includeReferencedInstructions",wt="chat.customAgentInSubagent.enabled",vt="chat.agent.enabled",yt="github.copilot.chat.omitBaseAgentInstructions",_t="chat.mcp.discovery.enabled",St="chat.mcp.autoStart",S="github.copilot.chat.additionalReadAccessPaths",M={maxRequests:300,terminalEnableAutoApprove:!0,omitBaseAgentInstructions:!0,enableMcpServer:!0},Hs=[mt,ht,wt,vt,yt,_t,St,gt,de,Re,w],z=["vesper-indexing","sequential-thinking","memory"],Fe=[".vesperrc",".mcp.json",".vscode/mcp.json",".vesper/index.db",".vesper/index.db-wal",".vesper/index.db-shm",".vesper/indexing-status.json",".claude/settings.local.json"];var nt="# <!-- vesper:gitignore:start -->",ot="# <!-- vesper:gitignore:end -->";async function he(e){let t=y(e,".gitignore"),s=[nt,...Fe,ot].join(`
2
+ `),r=new RegExp(`${nt}[\\s\\S]*?${ot}`),n="";try{n=await T(t,"utf-8")}catch(a){if(a.code!=="ENOENT")throw a;return await A(t,`${s}
3
+ `,"utf-8"),{created:!0,updated:!1}}if(r.test(n)){let a=n.replace(r,s);return a!==n?(await A(t,a,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let i=n.endsWith(`
4
4
  `)?`
5
5
  `:`
6
6
 
7
- `;return await A(t,`${o}${a}${s}
8
- `,"utf-8"),{created:!1,updated:!0}}var Je="Vesper: worktree bootstrap";async function dt(e){let t=y(e,".vscode","tasks.json"),s={label:Je,type:"shell",command:"vespercli worktree bootstrap --quiet",presentation:{reveal:"silent",panel:"shared"},problemMatcher:[],runOptions:{runOn:"folderOpen"}},n={version:"2.0.0",tasks:[]},o=!1;try{let i=await b(t,"utf-8");n=le(i),Array.isArray(n.tasks)||(n.tasks=[]),o=!0}catch(i){if(i.code!=="ENOENT")throw i}let a=n.tasks.findIndex(i=>i?.label===Je);if(a===-1)n.tasks.push(s);else if(JSON.stringify(n.tasks[a])!==JSON.stringify(s))n.tasks[a]=s;else return{created:!1,updated:!1};return await ie(B(t),{recursive:!0}),await A(t,JSON.stringify(n,null," "),"utf-8"),{created:!o,updated:o}}var Ye=["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"],R=["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"],$e={"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"]},ce={"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"]}};var P={FOLDER:"folder",WORKSPACE_FILE:"workspace"};async function Ts(e){try{let s=(await xs(e,{withFileTypes:!0})).find(n=>n.isFile()&&n.name.endsWith(".code-workspace"));return s?y(e,s.name):null}catch{return null}}async function _(e){let t=await Ts(e);return t?{type:P.WORKSPACE_FILE,settingsPath:t,workspaceFile:t}:{type:P.FOLDER,settingsPath:y(e,".vscode","settings.json"),workspaceFile:null}}function Oe(e,t=null){return t?.workspaceFile?y(B(t.workspaceFile),".vesperrc"):y(e,".vesperrc")}function le(e){let t=Ss(e,{trailingCommas:!0});return JSON.parse(t)}async function S(e){let t=await _(e);try{let s=await b(t.settingsPath,"utf-8"),n=le(s);return t.type===P.WORKSPACE_FILE?n.settings||{}:n}catch(s){if(s.code==="ENOENT")return{};if(s instanceof SyntaxError){if(t.type===P.WORKSPACE_FILE)throw new Error(`Failed to parse workspace file: ${t.settingsPath}. ${s.message}`);return{}}throw s}}async function C(e,t){let s=await _(e);if(s.type===P.WORKSPACE_FILE){let n;try{let o=await b(s.settingsPath,"utf-8");n=le(o)}catch(o){if(o.code==="ENOENT")n={folders:[],settings:{}};else throw new Error(`Failed to read workspace file: ${s.settingsPath}. ${o.message}`)}n.settings=t,await A(s.settingsPath,JSON.stringify(n,null," "),"utf-8")}else{let n=B(s.settingsPath);await ie(n,{recursive:!0}),await A(s.settingsPath,JSON.stringify(t,null," "),"utf-8")}}function bs(e){return y(e,".vesper","tracking.json")}async function g(e){let t=await _(e),s=Oe(e,t),n=bs(e),o=y(e,".vesperrc");try{let a=await b(s,"utf-8");return JSON.parse(a)}catch{if(s!==o)try{let a=await b(o,"utf-8");return JSON.parse(a)}catch{}try{let a=await b(n,"utf-8");return JSON.parse(a)}catch{return{paths:[],addedAt:null,workspaceType:null,settingsPath:null}}}}async function $s(e){try{let t=await b(e,"utf-8"),n=le(t).folders||[],o=B(e);return n.map(a=>{let i=a.path||a;return i.startsWith("/")||i.startsWith("~")?i.replace(/^~/,tt()):y(o,i)})}catch{return[]}}async function pt(e){let t=await _(e);if(t.type!==P.WORKSPACE_FILE)return{found:!1,paths:[]};let s=B(t.workspaceFile),n=y(s,".vesperrc"),o=await $s(t.workspaceFile),a=[];for(let i of o){let c=y(i,".vesperrc");if(c!==n)try{let d=await b(c,"utf-8"),l=JSON.parse(d);a.push({folderPath:i,vesperrcPath:c,tracking:l})}catch{}}return{found:a.length>0,paths:a}}async function ut(e,t,s){let n=await _(e),o=Oe(e,n),a={...s,workspaceType:P.WORKSPACE_FILE,settingsPath:n.settingsPath,migratedFrom:t,migratedAt:new Date().toISOString()};await A(o,JSON.stringify(a,null,2),"utf-8");try{let{unlink:i}=await import("node:fs/promises");await i(t)}catch{}return{success:!0,newPath:o}}async function E(e,t){let s=await _(e),n=Oe(e,s);await A(n,JSON.stringify(t,null,2),"utf-8")}async function ft(e,t){let s=await _(e),n=await S(e),o=await g(e),a=[],i=[];for(let{path:c,settingKey:d}of t){if(n[d]||(n[d]={}),n[d][c]){i.push(c),o.paths.includes(c)||o.paths.push(c);continue}n[d][c]=!0,a.push(c),o.paths.includes(c)||o.paths.push(c)}return a.length>0&&await C(e,n),o.paths.length>0&&(o.addedAt=o.addedAt||new Date().toISOString(),o.updatedAt=new Date().toISOString(),o.workspaceType=s.type,o.settingsPath=s.settingsPath,await E(e,o)),{added:a,skipped:i,workspaceType:s.type}}async function gt(e){let t=await S(e),s=await g(e),n={paths:[],settings:[],mcpServers:[],agentTools:[]},o=/vespercli|vesper-cli/;for(let u of Object.values(Z))if(t[u]){for(let p of Object.keys(t[u])){let f=s.paths?.includes(p),h=o.test(p);(f||h)&&(delete t[u][p],n.paths.includes(p)||n.paths.push(p))}Object.keys(t[u]).length===0&&delete t[u]}let a=s.readAccessPaths||[];if(a.length>0){let u=t[x]||[],p=u.filter(f=>!a.includes(f));p.length!==u.length&&(p.length>0?t[x]=p:delete t[x],n.settings.push(x))}for(let u of Cs)t[u]!==void 0&&(delete t[u],n.settings.push(u));let i=s.mcp?.agentTools||{};for(let[u,p]of Object.entries(i))n.agentTools.push({agent:u,tools:p});(n.paths.length>0||n.settings.length>0)&&await C(e,t);let c=await G(e),d=s.mcp?.servers||[],l=[...new Set([...Ps,...d])];if(c.servers){for(let u of l)c.servers[u]&&(delete c.servers[u],n.mcpServers.push(u));if(n.mcpServers.length>0){let u=we(e),p=B(u);await ie(p,{recursive:!0}),await A(u,JSON.stringify(c,null," "),"utf-8")}}return await E(e,{paths:[],readAccessPaths:[],addedAt:null,workspaceType:null,settingsPath:null,mcp:null}),{removed:n}}async function fe(e){return(await g(e)).paths.length>0}async function N(e){let t=await g(e),s=[];return Array.isArray(t.paths)&&t.paths.length>0&&s.push("copilot"),t.claude&&s.push("claude"),s}var Os=["agents","prompts","instructions"];function Is(){let e=[];for(let n of Os){let o=I[n],a=Z[n];if(a&&o){let i=j(y(T,"core",o.dir));e.push({path:i,settingKey:a,type:n})}}let t=Z.skills;if(t){let n=j(y(T,"core","skills"));e.push({path:n,settingKey:t,type:"skills"})}let s=I.skills;if(t&&s){let n=j(y(T,s.dir));e.push({path:n,settingKey:t,type:"skills"})}return e}async function mt(e,t=!0){let s=await _(e),n=await S(e);if(n[st]=t,t){n[ae]||(n[ae]={});for(let o of Ye)n[ae][o]=!0}return await C(e,n),{configured:t?Ye.length:0,workspaceType:s.type}}async function ht(e,t={}){let{maxRequests:s=M.maxRequests,omitBaseAgentInstructions:n=M.omitBaseAgentInstructions}=t,o=await S(e);o[nt]=s,o[rt]=!0,o[ot]=!0,o[at]=!0,o[it]=n,o[ct]=!0,o[lt]="newAndOutdated",o[x]||(o[x]=[]),await C(e,o)}async function wt(e,t){let s=await S(e),n=s[x]||[];n.includes(t)||(n.push(t),s[x]=n,await C(e,s));let o=await g(e);return o.readAccessPaths||(o.readAccessPaths=[]),o.readAccessPaths.includes(t)||(o.readAccessPaths.push(t),o.updatedAt=new Date().toISOString(),await E(e,o)),n}async function vt(e,t){let s=await S(e),n=s[x]||[],o=n.indexOf(t);o!==-1&&(n.splice(o,1),s[x]=n,await C(e,s));let a=await g(e);if(a.readAccessPaths){let i=a.readAccessPaths.indexOf(t);i!==-1&&(a.readAccessPaths.splice(i,1),a.updatedAt=new Date().toISOString(),await E(e,a))}return n}async function yt(e){return(await S(e))[x]||[]}function _t(e){let t=I[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=Z[e];return{path:j(y(T,t.dir)),settingKey:s,type:e}}function q(e,t){if(Te(t),!I[e])throw new Error(`Unknown asset type: ${e}`);let n=Z[e];return{path:j(qe(e,t)),settingKey:n,type:e,name:t}}async function ee(e){return(await g(e)).paths}async function xt(e){let t={assetPaths:0,readAccess:0,commandKeys:0,trackingPaths:0,mcpArgs:0},s=(p,f)=>{let h=[];for(let O of p){let re=pe(O);re!==O&&t[f]++,h.includes(re)||h.push(re)}return h},n=await S(e),o=!1;for(let p of Object.values(Z)){let f=n[p];if(!(!f||typeof f!="object"))for(let h of Object.keys(f)){let O=pe(h);if(O===h)continue;let re=f[h];delete f[h],f[O]=f[O]===!0?!0:re,t.assetPaths++,o=!0}}if(Array.isArray(n[x])){let p=t.readAccess;n[x]=s(n[x],"readAccess"),t.readAccess!==p&&(o=!0)}let a=n[ae];if(a&&typeof a=="object")for(let p of Object.keys(a))As(p)&&(delete a[p],t.commandKeys++,o=!0);o&&await C(e,n);let i=await g(e),c=!1;if(Array.isArray(i.paths)){let p=t.trackingPaths;i.paths=s(i.paths,"trackingPaths"),t.trackingPaths!==p&&(c=!0)}if(Array.isArray(i.readAccessPaths)){let p=[];for(let f of i.readAccessPaths){let h=pe(f);h!==f&&(c=!0),p.includes(h)||p.push(h)}i.readAccessPaths=p}c&&(i.updatedAt=new Date().toISOString(),await E(e,i));let d=await G(e),l=d.servers?.["vesper-indexing"];if(l&&Array.isArray(l.args)){let p=!1;l.args=l.args.map(f=>{let h=pe(f);return h!==f&&(t.mcpArgs++,p=!0),h}),p&&await ve(e,d)}return{migrated:t.assetPaths+t.readAccess+t.commandKeys+t.trackingPaths+t.mcpArgs>0,changed:t}}async function St(e){let t=await _(e),s=await S(e),n=await g(e),o=Is(),a=[],i=[];for(let{path:l,settingKey:u}of o)s[u]||(s[u]={}),s[u][l]===!0?i.push(l):(s[u][l]=!0,a.push(l)),n.paths.includes(l)||n.paths.push(l);let c=T,d=s[x]||[];return d.includes(c)||(d.push(c),s[x]=d,a.push(c)),n.readAccessPaths||(n.readAccessPaths=[]),n.readAccessPaths.includes(c)||n.readAccessPaths.push(c),a.length>0&&await C(e,s),n.addedAt=n.addedAt||new Date().toISOString(),n.updatedAt=new Date().toISOString(),n.workspaceType=t.type,n.settingsPath=t.settingsPath,await E(e,n),{added:a,existed:i,workspaceType:t.type}}var ze="# <!-- vesper:hook:start -->",Xe="# <!-- vesper:hook:end -->";async function Ms(e){let{execFile:t}=await import("node:child_process"),{promisify:s}=await import("node:util"),n=s(t),o=async u=>{try{let{stdout:p}=await n("git",u,{cwd:e});return p.trim()}catch{return null}};if(await o(["rev-parse","--is-inside-work-tree"])!=="true")return null;let{isAbsolute:i}=await import("node:path"),c=u=>i(u)?u:y(e,u),d=await o(["config","core.hooksPath"]);if(d)return c(d);let l=await o(["rev-parse","--git-common-dir"]);return l?y(c(l),"hooks"):null}async function Ds(e,t){let s=await Ms(e);if(!s)return{installed:!1,updated:!1,hooksDir:null};let n=y(T,"hooks",t),o=await b(n,"utf-8"),a=o.match(new RegExp(`${ze}[\\s\\S]*?${Xe}`));if(!a)throw new Error(`Hook source ${n} is missing its vesper:hook guard markers`);let i=a[0],c=new RegExp(`${ze}[\\s\\S]*?${Xe}`);await ie(s,{recursive:!0});let d=y(s,t),l="",u=!0;try{l=await b(d,"utf-8")}catch(f){if(f.code!=="ENOENT")throw f;u=!1}if(!u)return await A(d,o,{encoding:"utf-8",mode:493}),{installed:!0,updated:!1,hooksDir:s};if(c.test(l)){let f=l.replace(c,i);return f!==l?(await A(d,f,"utf-8"),await Qe(d),{installed:!1,updated:!0,hooksDir:s}):{installed:!1,updated:!1,hooksDir:s}}let p=l.endsWith(`
7
+ `;return await A(t,`${n}${i}${s}
8
+ `,"utf-8"),{created:!1,updated:!0}}async function we(e){let{execFile:t}=await import("node:child_process"),{promisify:s}=await import("node:util"),r=s(t),n=async d=>{try{let{stdout:l}=await r("git",d,{cwd:e});return l}catch{return null}},i=await n(["rev-parse","--is-inside-work-tree"]);if(i===null||i.trim()!=="true")return[];let a=await n(["ls-files","-z","--",...Fe]);if(!a)return[];let c=new Set(a.split("\0").filter(Boolean));return Fe.filter(d=>c.has(d))}var it="Vesper: worktree bootstrap";async function kt(e){let t=y(e,".vscode","tasks.json"),s={label:it,type:"shell",command:"vespercli worktree bootstrap --quiet",presentation:{reveal:"silent",panel:"shared"},problemMatcher:[],runOptions:{runOn:"folderOpen"}},r={version:"2.0.0",tasks:[]},n=!1;try{let a=await T(t,"utf-8");r=pe(a),Array.isArray(r.tasks)||(r.tasks=[]),n=!0}catch(a){if(a.code!=="ENOENT")throw a}let i=r.tasks.findIndex(a=>a?.label===it);if(i===-1)r.tasks.push(s);else if(JSON.stringify(r.tasks[i])!==JSON.stringify(s))r.tasks[i]=s;else return{created:!1,updated:!1};return await ue(J(t),{recursive:!0}),await A(t,JSON.stringify(r,null," "),"utf-8"),{created:!n,updated:n}}var at=["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"],R=["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"],Ve={"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"]},V={"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"]}};var E={FOLDER:"folder",WORKSPACE_FILE:"workspace"};async function Js(e){try{let s=(await Ws(e,{withFileTypes:!0})).find(r=>r.isFile()&&r.name.endsWith(".code-workspace"));return s?y(e,s.name):null}catch{return null}}async function _(e){let t=await Js(e);return t?{type:E.WORKSPACE_FILE,settingsPath:t,workspaceFile:t}:{type:E.FOLDER,settingsPath:y(e,".vscode","settings.json"),workspaceFile:null}}function Ne(e,t=null){return t?.workspaceFile?y(J(t.workspaceFile),".vesperrc"):y(e,".vesperrc")}function pe(e){let t=Bs(e,{trailingCommas:!0});return JSON.parse(t)}async function k(e){let t=await _(e);try{let s=await T(t.settingsPath,"utf-8"),r=pe(s);return t.type===E.WORKSPACE_FILE?r.settings||{}:r}catch(s){if(s.code==="ENOENT")return{};if(s instanceof SyntaxError){if(t.type===E.WORKSPACE_FILE)throw new Error(`Failed to parse workspace file: ${t.settingsPath}. ${s.message}`);return{}}throw s}}async function P(e,t){let s=await _(e);if(s.type===E.WORKSPACE_FILE){let r;try{let n=await T(s.settingsPath,"utf-8");r=pe(n)}catch(n){if(n.code==="ENOENT")r={folders:[],settings:{}};else throw new Error(`Failed to read workspace file: ${s.settingsPath}. ${n.message}`)}r.settings=t,await A(s.settingsPath,JSON.stringify(r,null," "),"utf-8")}else{let r=J(s.settingsPath);await ue(r,{recursive:!0}),await A(s.settingsPath,JSON.stringify(t,null," "),"utf-8")}}function zs(e){return y(e,".vesper","tracking.json")}async function m(e){let t=await _(e),s=Ne(e,t),r=zs(e),n=y(e,".vesperrc");try{let i=await T(s,"utf-8");return JSON.parse(i)}catch{if(s!==n)try{let i=await T(n,"utf-8");return JSON.parse(i)}catch{}try{let i=await T(r,"utf-8");return JSON.parse(i)}catch{return{paths:[],addedAt:null,workspaceType:null,settingsPath:null}}}}async function Ys(e){try{let t=await T(e,"utf-8"),r=pe(t).folders||[],n=J(e);return r.map(i=>{let a=i.path||i;return a.startsWith("/")||a.startsWith("~")?a.replace(/^~/,ft()):y(n,a)})}catch{return[]}}async function xt(e){let t=await _(e);if(t.type!==E.WORKSPACE_FILE)return{found:!1,paths:[]};let s=J(t.workspaceFile),r=y(s,".vesperrc"),n=await Ys(t.workspaceFile),i=[];for(let a of n){let c=y(a,".vesperrc");if(c!==r)try{let d=await T(c,"utf-8"),l=JSON.parse(d);i.push({folderPath:a,vesperrcPath:c,tracking:l})}catch{}}return{found:i.length>0,paths:i}}async function Ct(e,t,s){let r=await _(e),n=Ne(e,r),i={...s,workspaceType:E.WORKSPACE_FILE,settingsPath:r.settingsPath,migratedFrom:t,migratedAt:new Date().toISOString()};await A(n,JSON.stringify(i,null,2),"utf-8");try{let{unlink:a}=await import("node:fs/promises");await a(t)}catch{}return{success:!0,newPath:n}}async function C(e,t){let s=await _(e),r=Ne(e,s);await A(r,JSON.stringify(t,null,2),"utf-8")}async function At(e,t){let s=await _(e),r=await k(e),n=await m(e),i=[],a=[];for(let{path:c,settingKey:d}of t){if(r[d]||(r[d]={}),r[d][c]){a.push(c),n.paths.includes(c)||n.paths.push(c);continue}r[d][c]=!0,i.push(c),n.paths.includes(c)||n.paths.push(c)}return i.length>0&&await P(e,r),n.paths.length>0&&(n.addedAt=n.addedAt||new Date().toISOString(),n.updatedAt=new Date().toISOString(),n.workspaceType=s.type,n.settingsPath=s.settingsPath,await C(e,n)),{added:i,skipped:a,workspaceType:s.type}}async function Pt(e){let t=await k(e),s=await m(e),r={paths:[],settings:[],mcpServers:[],agentTools:[]},n=/vespercli|vesper-cli/;for(let u of Object.values(H))if(t[u]){for(let p of Object.keys(t[u])){let f=s.paths?.includes(p),h=n.test(p);(f||h)&&(delete t[u][p],r.paths.includes(p)||r.paths.push(p))}Object.keys(t[u]).length===0&&delete t[u]}let i=s.readAccessPaths||[];if(i.length>0){let u=t[S]||[],p=u.filter(f=>!i.includes(f));p.length!==u.length&&(p.length>0?t[S]=p:delete t[S],r.settings.push(S))}for(let u of Hs)t[u]!==void 0&&(delete t[u],r.settings.push(u));let a=s.mcp?.agentTools||{};for(let[u,p]of Object.entries(a))r.agentTools.push({agent:u,tools:p});(r.paths.length>0||r.settings.length>0)&&await P(e,t);let c=await N(e),d=s.mcp?.servers||[],l=[...new Set([...z,...d])];if(c.servers){for(let u of l)c.servers[u]&&(delete c.servers[u],r.mcpServers.push(u));if(r.mcpServers.length>0){let u=ke(e),p=J(u);await ue(p,{recursive:!0}),await A(u,JSON.stringify(c,null," "),"utf-8")}}return await C(e,{paths:[],readAccessPaths:[],addedAt:null,workspaceType:null,settingsPath:null,mcp:null}),{removed:r}}async function ve(e){return(await m(e)).paths.length>0}async function D(e){let t=await m(e),s=[];return Array.isArray(t.paths)&&t.paths.length>0&&s.push("copilot"),t.claude&&s.push("claude"),s}var Xs=["agents","prompts","instructions"];function Qs(){let e=[];for(let n of Xs){let i=I[n],a=H[n];if(a&&i){let c=q(y(b,"core",i.dir));e.push({path:c,settingKey:a,type:n})}}let t=H.skills;if(t){let n=q(y(b,"core","skills"));e.push({path:n,settingKey:t,type:"skills"})}let s=I.skills;if(t&&s){let n=q(y(b,s.dir));e.push({path:n,settingKey:t,type:"skills"})}let r=H.instructions;return r&&e.push({path:"${workspaceFolder}/.vesper/instructions",settingKey:r,type:"instructions"}),t&&e.push({path:"${workspaceFolder}/.vesper/skills",settingKey:t,type:"skills"}),e}async function Et(e,t=!0){let s=await _(e),r=await k(e);if(r[gt]=t,t){r[de]||(r[de]={});for(let n of at)r[de][n]=!0}return await P(e,r),{configured:t?at.length:0,workspaceType:s.type}}async function bt(e,t={}){let{maxRequests:s=M.maxRequests,omitBaseAgentInstructions:r=M.omitBaseAgentInstructions}=t,n=await k(e);n[mt]=s,n[ht]=!0,n[wt]=!0,n[vt]=!0,n[yt]=r,n[_t]=!0,n[St]="newAndOutdated",n[S]||(n[S]=[]),await P(e,n)}async function Tt(e,t){let s=await k(e),r=s[S]||[];r.includes(t)||(r.push(t),s[S]=r,await P(e,s));let n=await m(e);return n.readAccessPaths||(n.readAccessPaths=[]),n.readAccessPaths.includes(t)||(n.readAccessPaths.push(t),n.updatedAt=new Date().toISOString(),await C(e,n)),r}async function $t(e,t){let s=await k(e),r=s[S]||[],n=r.indexOf(t);n!==-1&&(r.splice(n,1),s[S]=r,await P(e,s));let i=await m(e);if(i.readAccessPaths){let a=i.readAccessPaths.indexOf(t);a!==-1&&(i.readAccessPaths.splice(a,1),i.updatedAt=new Date().toISOString(),await C(e,i))}return r}async function Ot(e){return(await k(e))[S]||[]}function It(e){let t=I[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=H[e];return{path:q(y(b,t.dir)),settingKey:s,type:e}}function Y(e,t){if(je(t),!I[e])throw new Error(`Unknown asset type: ${e}`);let r=H[e];return{path:q(rt(e,t)),settingKey:r,type:e,name:t}}async function ne(e){return(await m(e)).paths}async function Mt(e){let t={assetPaths:0,readAccess:0,commandKeys:0,trackingPaths:0,mcpArgs:0},s=(p,f)=>{let h=[];for(let O of p){let ce=me(O);ce!==O&&t[f]++,h.includes(ce)||h.push(ce)}return h},r=await k(e),n=!1;for(let p of Object.values(H)){let f=r[p];if(!(!f||typeof f!="object"))for(let h of Object.keys(f)){let O=me(h);if(O===h)continue;let ce=f[h];delete f[h],f[O]=f[O]===!0?!0:ce,t.assetPaths++,n=!0}}if(Array.isArray(r[S])){let p=t.readAccess;r[S]=s(r[S],"readAccess"),t.readAccess!==p&&(n=!0)}let i=r[de];if(i&&typeof i=="object")for(let p of Object.keys(i))Ks(p)&&(delete i[p],t.commandKeys++,n=!0);n&&await P(e,r);let a=await m(e),c=!1;if(Array.isArray(a.paths)){let p=t.trackingPaths;a.paths=s(a.paths,"trackingPaths"),t.trackingPaths!==p&&(c=!0)}if(Array.isArray(a.readAccessPaths)){let p=[];for(let f of a.readAccessPaths){let h=me(f);h!==f&&(c=!0),p.includes(h)||p.push(h)}a.readAccessPaths=p}c&&(a.updatedAt=new Date().toISOString(),await C(e,a));let d=await N(e),l=d.servers?.["vesper-indexing"];if(l&&Array.isArray(l.args)){let p=!1;l.args=l.args.map(f=>{let h=me(f);return h!==f&&(t.mcpArgs++,p=!0),h}),p&&await xe(e,d)}return{migrated:t.assetPaths+t.readAccess+t.commandKeys+t.trackingPaths+t.mcpArgs>0,changed:t}}async function Dt(e){let t=await _(e),s=await k(e),r=await m(e),n=Qs(),i=[],a=[];for(let{path:l,settingKey:u}of n)s[u]||(s[u]={}),s[u][l]===!0?a.push(l):(s[u][l]=!0,i.push(l)),r.paths.includes(l)||r.paths.push(l);let c=b,d=s[S]||[];return d.includes(c)||(d.push(c),s[S]=d,i.push(c)),r.readAccessPaths||(r.readAccessPaths=[]),r.readAccessPaths.includes(c)||r.readAccessPaths.push(c),i.length>0&&await P(e,s),r.addedAt=r.addedAt||new Date().toISOString(),r.updatedAt=new Date().toISOString(),r.workspaceType=t.type,r.settingsPath=t.settingsPath,await C(e,r),{added:i,existed:a,workspaceType:t.type}}var ct="# <!-- vesper:hook:start -->",lt="# <!-- vesper:hook:end -->";async function Zs(e){let{execFile:t}=await import("node:child_process"),{promisify:s}=await import("node:util"),r=s(t),n=async u=>{try{let{stdout:p}=await r("git",u,{cwd:e});return p.trim()}catch{return null}};if(await n(["rev-parse","--is-inside-work-tree"])!=="true")return null;let{isAbsolute:a}=await import("node:path"),c=u=>a(u)?u:y(e,u),d=await n(["config","core.hooksPath"]);if(d)return c(d);let l=await n(["rev-parse","--git-common-dir"]);return l?y(c(l),"hooks"):null}async function er(e,t){let s=await Zs(e);if(!s)return{installed:!1,updated:!1,hooksDir:null};let r=y(b,"hooks",t),n=await T(r,"utf-8"),i=n.match(new RegExp(`${ct}[\\s\\S]*?${lt}`));if(!i)throw new Error(`Hook source ${r} is missing its vesper:hook guard markers`);let a=i[0],c=new RegExp(`${ct}[\\s\\S]*?${lt}`);await ue(s,{recursive:!0});let d=y(s,t),l="",u=!0;try{l=await T(d,"utf-8")}catch(f){if(f.code!=="ENOENT")throw f;u=!1}if(!u)return await A(d,n,{encoding:"utf-8",mode:493}),{installed:!0,updated:!1,hooksDir:s};if(c.test(l)){let f=l.replace(c,a);return f!==l?(await A(d,f,"utf-8"),await dt(d),{installed:!1,updated:!0,hooksDir:s}):{installed:!1,updated:!1,hooksDir:s}}let p=l.endsWith(`
9
9
  `)?`
10
10
  `:`
11
11
 
12
- `;return await A(d,`${l}${p}${i}
13
- `,"utf-8"),await Qe(d),{installed:!1,updated:!0,hooksDir:s}}async function Qe(e){let{chmod:t}=await import("node:fs/promises");try{await t(e,493)}catch{}}var Rs=["pre-commit","post-checkout"];async function ge(e){let t={};for(let s of Rs)t[s]=await Ds(e,s);return t}var Ze="# <!-- vesper:gitattributes:start -->",et="# <!-- vesper:gitattributes:end -->",Ns=[".vesper/history.md merge=union",".vesper/memory.jsonl merge=vesper-memory"];async function me(e){let t=y(e,".gitattributes"),s=[Ze,...Ns,et].join(`
14
- `),n=new RegExp(`${Ze}[\\s\\S]*?${et}`),o="";try{o=await b(t,"utf-8")}catch(i){if(i.code!=="ENOENT")throw i;return await A(t,`${s}
15
- `,"utf-8"),{created:!0,updated:!1}}if(n.test(o)){let i=o.replace(n,s);return i!==o?(await A(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let a=o.endsWith(`
12
+ `;return await A(d,`${l}${p}${a}
13
+ `,"utf-8"),await dt(d),{installed:!1,updated:!0,hooksDir:s}}async function dt(e){let{chmod:t}=await import("node:fs/promises");try{await t(e,493)}catch{}}var tr=["pre-commit","post-checkout"];async function ye(e){let t={};for(let s of tr)t[s]=await er(e,s);return t}var ut="# <!-- vesper:gitattributes:start -->",pt="# <!-- vesper:gitattributes:end -->",sr=[".vesper/history.md merge=union",".vesper/memory.jsonl merge=vesper-memory"];async function _e(e){let t=y(e,".gitattributes"),s=[ut,...sr,pt].join(`
14
+ `),r=new RegExp(`${ut}[\\s\\S]*?${pt}`),n="";try{n=await T(t,"utf-8")}catch(a){if(a.code!=="ENOENT")throw a;return await A(t,`${s}
15
+ `,"utf-8"),{created:!0,updated:!1}}if(r.test(n)){let a=n.replace(r,s);return a!==n?(await A(t,a,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let i=n.endsWith(`
16
16
  `)?`
17
17
  `:`
18
18
 
19
- `;return await A(t,`${o}${a}${s}
20
- `,"utf-8"),{created:!1,updated:!0}}async function he(e){let{execFile:t}=await import("node:child_process"),{promisify:s}=await import("node:util"),n=s(t),o=async l=>{try{return await n("git",l,{cwd:e}),!0}catch{return!1}};if(!await o(["rev-parse","--is-inside-work-tree"]))return{configured:!1};let c=`node "${y(T,"hooks","merge-memory-jsonl.js")}" %O %A %B`;return await o(["config","merge.vesper-memory.name","Vesper memory.jsonl entity-aware merge"]),{configured:await o(["config","merge.vesper-memory.driver",c])}}function we(e){return y(e,".vscode","mcp.json")}function U(){return y(X,"src","mcp","vesper-indexing","dist","index.js")}async function G(e){let t=we(e);try{let s=await b(t,"utf-8");return le(s)}catch(s){if(s.code==="ENOENT")return{servers:{}};if(s instanceof SyntaxError)return{servers:{}};throw s}}async function ve(e,t){let s=we(e),n=B(s);await ie(n,{recursive:!0}),await A(s,JSON.stringify(t,null," "),"utf-8")}async function K(e,t=!0){let s=await G(e),n=j(U()),o=[];if(s.servers||(s.servers={}),t?(s.servers["vesper-indexing"]={type:"stdio",command:"node",args:[n],env:{VESPER_INDEX_ROOT:"${workspaceFolder}"}},o.push("vesper-indexing"),s.servers["sequential-thinking"]={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},o.push("sequential-thinking"),s.servers.memory={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:"${workspaceFolder}/.vesper/memory.jsonl"}},o.push("memory")):(delete s.servers["vesper-indexing"],delete s.servers["sequential-thinking"],delete s.servers.memory),await ve(e,s),t&&o.length>0){let a=await g(e);a.mcp=a.mcp||{},a.mcp.servers=o,a.mcp.updatedAt=new Date().toISOString(),await E(e,a)}return{configured:t,mcpPath:we(e),servers:o}}async function ye(e){return!!(await G(e)).servers?.["vesper-indexing"]}async function kt(e){let t=await _(e),s=await S(e);s[be]=!1,s[w]||(s[w]={});for(let n of R)s[w][n]=!0;return await C(e,s),{configured:R.length,workspaceType:t.type}}async function At(e,t){let s=$e[t];if(!s||s.length===0)return{added:[],agentName:t};let n=await S(e),o=await _(e),a=await g(e,o);n[w]||(n[w]={});let i=[];for(let c of s)n[w][c]||(n[w][c]=!0,i.push(c));return i.length>0&&(await C(e,n),a.mcp=a.mcp||{},a.mcp.agentTools=a.mcp.agentTools||{},a.mcp.agentTools[t]=s,a.mcp.updatedAt=new Date().toISOString(),await E(e,a)),{added:i,agentName:t}}async function Ct(e,t){let s=ce[t];if(!s)return{added:!1,serverName:t,tools:[],error:`Unknown MCP server: ${t}`};let n=await G(e),o=await S(e),a=await _(e),i=await g(e,a);if(n.servers||(n.servers={}),n.servers[t])return{added:!1,serverName:t,tools:[],error:"Already configured"};let c=JSON.parse(JSON.stringify(s.config));if(t==="vesper-indexing"){let l=j(U());c.args&&(c.args=c.args.map(u=>u==="${VESPER_INDEXING_PATH}"?l:u))}n.servers[t]=c,await ve(e,n),o[w]||(o[w]={});let d=[];for(let l of s.tools||[])o[w][l]||(o[w][l]=!0,d.push(l));return o[be]=!1,await C(e,o),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 E(e,i),{added:!0,serverName:t,tools:d}}async function Pt(e,t){let s=ce[t],n=await G(e),o=await S(e),a=await _(e),i=await g(e,a),c=!1;n.servers&&n.servers[t]&&(delete n.servers[t],await ve(e,n),c=!0);let d=[];if(s&&o[w]){for(let l of s.tools||[])o[w][l]&&(delete o[w][l],d.push(l));d.length>0&&await C(e,o)}return i.mcp?.servers&&(i.mcp.servers=i.mcp.servers.filter(l=>l!==t),i.mcp.updatedAt=new Date().toISOString(),await E(e,i)),{removed:c,serverName:t,tools:d}}import{readFile as F,writeFile as $,mkdir as H,readdir as Tt,rm as Et,cp as bt}from"node:fs/promises";import{join as v,dirname as Ie,basename as Fs}from"node:path";import{homedir as Ls}from"node:os";V();var te=v(T,"claude"),$t=["agents","commands","skills"],_e="vesper";function J(e=_e){return v(Ls(),".claude","skills",e)}function xe(e){return v(e,".claude","vesper")}function Ot(e){return v(e,"CLAUDE.md")}function Y(e){return v(e,".mcp.json")}function Se(e){return v(e,".claude","settings.json")}function It(e,t){return t?e.replace(/^(name:\s*)([a-z0-9-]+)/m,(s,n,o)=>o.startsWith(t)?s:`${n}${t}${o}`):e}async function Vs(e,t,s,n){if(!await m(e))return{copied:0};await H(t,{recursive:!0});let o=await Tt(e,{withFileTypes:!0}),a=0;for(let i of o){let c=v(e,i.name);if(i.isDirectory()){await bt(c,v(t,i.name),{recursive:!0}),a+=1;continue}if(!i.name.endsWith(".md"))continue;let d=await F(c,"utf-8"),l=It(d,s),u=n&&s&&!i.name.startsWith(s)?`${s}${i.name}`:i.name;await $(v(t,u),l,"utf-8"),a+=1}return{copied:a}}async function js(e,t,s){let n=v(e,".claude-plugin");await H(n,{recursive:!0});let o={name:t,description:"Vesper specialist catalog \u2014 subagents, slash commands, and skills for AI-orchestrated development.",version:s};await $(v(n,"plugin.json"),JSON.stringify(o,null,2),"utf-8")}async function ke({pluginName:e=_e,namePrefix:t="",version:s="0.0.0"}={}){let n=J(e),o={};for(let a of $t){let i=v(te,a),c=v(n,a),l=await Vs(i,c,a==="skills"?"":t,a!=="skills");o[a]=l.copied}return await js(n,e,s),{pluginDir:n,counts:o}}async function Mt(e,t,{pluginName:s=_e,namePrefix:n=""}={}){let o=J(s),a=v(o,e);if(await H(a,{recursive:!0}),e==="skills"){let p=v(te,"skills",t);if(!await m(p))throw new Error(`Skill "${t}" not found in assets/claude/skills/`);return await bt(p,v(a,t),{recursive:!0}),{installedAs:t}}let i=".md",c=v(te,e,`${t}${i}`);if(!await m(c))throw new Error(`${e.slice(0,-1)} "${t}" not found in assets/claude/${e}/`);let d=await F(c,"utf-8"),l=It(d,n),u=n&&!t.startsWith(n)?`${n}${t}${i}`:`${t}${i}`;return await $(v(a,u),l,"utf-8"),{installedAs:Fs(u,i)}}async function Dt(e=_e){let t=J(e),s={};for(let n of $t){let o=v(t,n);if(!await m(o)){s[n]=[];continue}let a=await Tt(o,{withFileTypes:!0});s[n]=n==="skills"?a.filter(i=>i.isDirectory()).map(i=>i.name).sort():a.filter(i=>i.isFile()&&i.name.endsWith(".md")).map(i=>i.name.replace(/\.md$/,"")).sort()}return s}var Me="<!-- vesper:start -->",De="<!-- vesper:end -->";function Us(){return[Me,"@.claude/vesper/orchestrator.md","@.claude/vesper/orchestration.md","@.claude/vesper/context.md",De].join(`
21
- `)}async function Gs(e){let t=Ot(e),s=Us(),n=new RegExp(`${Me}[\\s\\S]*?${De}`);if(!await m(t))return await H(Ie(t),{recursive:!0}),await $(t,`${s}
22
- `,"utf-8"),{created:!0,updated:!1};let o=await F(t,"utf-8");if(n.test(o)){let i=o.replace(n,s);return i!==o?(await $(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let a=`${s}
19
+ `;return await A(t,`${n}${i}${s}
20
+ `,"utf-8"),{created:!1,updated:!0}}async function Se(e){let{execFile:t}=await import("node:child_process"),{promisify:s}=await import("node:util"),r=s(t),n=async l=>{try{return await r("git",l,{cwd:e}),!0}catch{return!1}};if(!await n(["rev-parse","--is-inside-work-tree"]))return{configured:!1};let c=`node "${y(b,"hooks","merge-memory-jsonl.js")}" %O %A %B`;return await n(["config","merge.vesper-memory.name","Vesper memory.jsonl entity-aware merge"]),{configured:await n(["config","merge.vesper-memory.driver",c])}}function ke(e){return y(e,".vscode","mcp.json")}function B(){return y(se,"src","mcp","vesper-indexing","dist","index.js")}async function N(e){let t=ke(e);try{let s=await T(t,"utf-8");return pe(s)}catch(s){if(s.code==="ENOENT")return{servers:{}};if(s instanceof SyntaxError)return{servers:{}};throw s}}async function xe(e,t){let s=ke(e),r=J(s);await ue(r,{recursive:!0}),await A(s,JSON.stringify(t,null," "),"utf-8")}async function X(e,t=!0){let s=await N(e),r=q(B()),n=[];if(s.servers||(s.servers={}),t?(s.servers["vesper-indexing"]={type:"stdio",command:"node",args:[r],env:{VESPER_INDEX_ROOT:"${workspaceFolder}"}},n.push("vesper-indexing"),s.servers["sequential-thinking"]={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},n.push("sequential-thinking"),s.servers.memory={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:"${workspaceFolder}/.vesper/memory.jsonl"}},n.push("memory")):(delete s.servers["vesper-indexing"],delete s.servers["sequential-thinking"],delete s.servers.memory),await xe(e,s),t&&n.length>0){let i=await m(e);i.mcp=i.mcp||{},i.mcp.servers=n,i.mcp.updatedAt=new Date().toISOString(),await C(e,i)}return{configured:t,mcpPath:ke(e),servers:n}}async function Ce(e){return!!(await N(e)).servers?.["vesper-indexing"]}async function Lt(e){let t=await _(e),s=await k(e);s[Re]=!1,s[w]||(s[w]={});for(let r of R)s[w][r]=!0;return await P(e,s),{configured:R.length,workspaceType:t.type}}async function jt(e,t){let s=Ve[t];if(!s||s.length===0)return{added:[],agentName:t};let r=await k(e),n=await _(e),i=await m(e,n);r[w]||(r[w]={});let a=[];for(let c of s)r[w][c]||(r[w][c]=!0,a.push(c));return a.length>0&&(await P(e,r),i.mcp=i.mcp||{},i.mcp.agentTools=i.mcp.agentTools||{},i.mcp.agentTools[t]=s,i.mcp.updatedAt=new Date().toISOString(),await C(e,i)),{added:a,agentName:t}}async function Ft(e,t){let s=V[t];if(!s)return{added:!1,serverName:t,tools:[],error:`Unknown MCP server: ${t}`};let r=await N(e),n=await k(e),i=await _(e),a=await m(e,i);if(r.servers||(r.servers={}),r.servers[t])return{added:!1,serverName:t,tools:[],error:"Already configured"};let c=JSON.parse(JSON.stringify(s.config));if(t==="vesper-indexing"){let l=q(B());c.args&&(c.args=c.args.map(u=>u==="${VESPER_INDEXING_PATH}"?l:u))}r.servers[t]=c,await xe(e,r),n[w]||(n[w]={});let d=[];for(let l of s.tools||[])n[w][l]||(n[w][l]=!0,d.push(l));return n[Re]=!1,await P(e,n),a.mcp=a.mcp||{},a.mcp.servers=a.mcp.servers||[],a.mcp.servers.includes(t)||a.mcp.servers.push(t),a.mcp.updatedAt=new Date().toISOString(),await C(e,a),{added:!0,serverName:t,tools:d}}async function Rt(e,t){let s=V[t],r=await N(e),n=await k(e),i=await _(e),a=await m(e,i),c=!1;r.servers&&r.servers[t]&&(delete r.servers[t],await xe(e,r),c=!0);let d=[];if(s&&n[w]){for(let l of s.tools||[])n[w][l]&&(delete n[w][l],d.push(l));d.length>0&&await P(e,n)}return a.mcp?.servers&&(a.mcp.servers=a.mcp.servers.filter(l=>l!==t),a.mcp.updatedAt=new Date().toISOString(),await C(e,a)),{removed:c,serverName:t,tools:d}}import{readFile as G,writeFile as $,mkdir as Q,readdir as Nt,rm as Vt,cp as Gt}from"node:fs/promises";import{join as v,dirname as Ue,basename as rr}from"node:path";import{homedir as nr}from"node:os";F();var oe=v(b,"claude"),Ut=["agents","commands","skills"],Ae="vesper";function U(e=Ae){return v(nr(),".claude","skills",e)}function Pe(e){return v(e,".claude","vesper")}function Wt(e){return v(e,"CLAUDE.md")}function Z(e){return v(e,".mcp.json")}function Ee(e){return v(e,".claude","settings.json")}function Bt(e,t){return t?e.replace(/^(name:\s*)([a-z0-9-]+)/m,(s,r,n)=>n.startsWith(t)?s:`${r}${t}${n}`):e}async function or(e,t,s,r){if(!await g(e))return{copied:0};await Q(t,{recursive:!0});let n=await Nt(e,{withFileTypes:!0}),i=0;for(let a of n){let c=v(e,a.name);if(a.isDirectory()){await Gt(c,v(t,a.name),{recursive:!0}),i+=1;continue}if(!a.name.endsWith(".md"))continue;let d=await G(c,"utf-8"),l=Bt(d,s),u=r&&s&&!a.name.startsWith(s)?`${s}${a.name}`:a.name;await $(v(t,u),l,"utf-8"),i+=1}return{copied:i}}async function ir(e,t,s){let r=v(e,".claude-plugin");await Q(r,{recursive:!0});let n={name:t,description:"Vesper specialist catalog \u2014 subagents, slash commands, and skills for AI-orchestrated development.",version:s};await $(v(r,"plugin.json"),JSON.stringify(n,null,2),"utf-8")}async function be({pluginName:e=Ae,namePrefix:t="",version:s="0.0.0"}={}){let r=U(e),n={};for(let i of Ut){let a=v(oe,i),c=v(r,i),l=await or(a,c,i==="skills"?"":t,i!=="skills");n[i]=l.copied}return await ir(r,e,s),{pluginDir:r,counts:n}}async function qt(e,t,{pluginName:s=Ae,namePrefix:r=""}={}){let n=U(s),i=v(n,e);if(await Q(i,{recursive:!0}),e==="skills"){let p=v(oe,"skills",t);if(!await g(p))throw new Error(`Skill "${t}" not found in assets/claude/skills/`);return await Gt(p,v(i,t),{recursive:!0}),{installedAs:t}}let a=".md",c=v(oe,e,`${t}${a}`);if(!await g(c))throw new Error(`${e.slice(0,-1)} "${t}" not found in assets/claude/${e}/`);let d=await G(c,"utf-8"),l=Bt(d,r),u=r&&!t.startsWith(r)?`${r}${t}${a}`:`${t}${a}`;return await $(v(i,u),l,"utf-8"),{installedAs:rr(u,a)}}async function Kt(e=Ae){let t=U(e),s={};for(let r of Ut){let n=v(t,r);if(!await g(n)){s[r]=[];continue}let i=await Nt(n,{withFileTypes:!0});s[r]=r==="skills"?i.filter(a=>a.isDirectory()).map(a=>a.name).sort():i.filter(a=>a.isFile()&&a.name.endsWith(".md")).map(a=>a.name.replace(/\.md$/,"")).sort()}return s}var We="<!-- vesper:start -->",Be="<!-- vesper:end -->";function ar(){return[We,"@.claude/vesper/orchestrator.md","@.claude/vesper/orchestration.md","@.claude/vesper/context.md",Be].join(`
21
+ `)}async function cr(e){let t=Wt(e),s=ar(),r=new RegExp(`${We}[\\s\\S]*?${Be}`);if(!await g(t))return await Q(Ue(t),{recursive:!0}),await $(t,`${s}
22
+ `,"utf-8"),{created:!0,updated:!1};let n=await G(t,"utf-8");if(r.test(n)){let a=n.replace(r,s);return a!==n?(await $(t,a,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let i=`${s}
23
23
 
24
- ${o}`;return await $(t,a,"utf-8"),{created:!1,updated:!0}}function Ws(e){let t=new RegExp(`${Me}[\\s\\S]*?${De}\\n*`);return e.replace(t,"")}async function Ae(e){let t=xe(e);await H(t,{recursive:!0});let s={orchestrator:"refreshed",orchestration:"skipped",context:"skipped"},n=v(te,"vesper-orchestrator.md"),o=v(t,"orchestrator.md");await $(o,await F(n,"utf-8"),"utf-8");let a=v(t,"orchestration.md");await m(a)||(await $(a,await F(v(te,"orchestration.md.tpl"),"utf-8"),"utf-8"),s.orchestration="created");let i=v(t,"context.md");await m(i)||(await $(i,await F(v(te,"context.md.tpl"),"utf-8"),"utf-8"),s.context="created");let c=await Gs(e);return s.claudeMd=c.created?"created":c.updated?"updated":"unchanged",s}async function Bs(e){let t=Y(e);try{let s=await F(t,"utf-8");return JSON.parse(s)}catch(s){return s.code==="ENOENT"?{mcpServers:{}}:{mcpServers:{}}}}async function qs(e,t){let s=Y(e);await H(Ie(s),{recursive:!0}),await $(s,JSON.stringify(t,null," "),"utf-8")}function Ks(e){return{"vesper-indexing":{command:"node",args:[U()],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:v(e,".vesper","memory.jsonl")}}}}async function z(e,t=!0){let s=await Bs(e);s.mcpServers||(s.mcpServers={});let n=Ks(e),o=Object.keys(n);if(t)for(let[a,i]of Object.entries(n))s.mcpServers[a]=i;else for(let a of o)delete s.mcpServers[a];return await qs(e,s),{configured:t,mcpPath:Y(e),servers:t?o:[]}}async function Ce(e){let t=Se(e),s={};try{s=JSON.parse(await F(t,"utf-8"))}catch{s={}}s.permissions||(s.permissions={}),Array.isArray(s.permissions.allow)||(s.permissions.allow=[]);let n=["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"],o=0;for(let a of n)s.permissions.allow.includes(a)||(s.permissions.allow.push(a),o+=1);return Ys(s),await H(Ie(t),{recursive:!0}),await $(t,JSON.stringify(s,null," "),"utf-8"),{configured:o,settingsPath:t}}var Rt=".claude/vesper/",Hs=`node -e "['orchestrator','orchestration','context'].forEach(n=>{try{process.stdout.write(require('fs').readFileSync('.claude/vesper/'+n+'.md','utf8')+'\\n\\n')}catch(e){}})"`,Nt="worktree bootstrap",Js="command -v vespercli >/dev/null 2>&1 && vespercli worktree bootstrap --quiet || true";function Ys(e){e.hooks||(e.hooks={}),Array.isArray(e.hooks.SessionStart)||(e.hooks.SessionStart=[]);let t=s=>e.hooks.SessionStart.some(n=>(n?.hooks||[]).some(o=>typeof o?.command=="string"&&o.command.includes(s)));t(Rt)||e.hooks.SessionStart.push({matcher:"clear",hooks:[{type:"command",command:Hs}]}),t(Nt)||e.hooks.SessionStart.push({hooks:[{type:"command",command:Js}]})}function zs(e){Array.isArray(e?.hooks?.SessionStart)&&(e.hooks.SessionStart=e.hooks.SessionStart.filter(t=>!(t?.hooks||[]).some(s=>typeof s?.command=="string"&&(s.command.includes(Rt)||s.command.includes(Nt)))),e.hooks.SessionStart.length===0&&delete e.hooks.SessionStart,e.hooks&&Object.keys(e.hooks).length===0&&delete e.hooks)}async function Ft(e,t){let s=await g(e);return s.claude={...s.claude,...t,updatedAt:new Date().toISOString()},await E(e,s),s.claude}async function Pe(e){let t=xe(e);await Et(t,{recursive:!0,force:!0});let s=Ot(e);if(await m(s)){let a=await F(s,"utf-8"),i=Ws(a);i.trim()?await $(s,i,"utf-8"):await Et(s,{force:!0})}await z(e,!1);let n=Se(e);if(await m(n))try{let a=JSON.parse(await F(n,"utf-8"));zs(a),await $(n,JSON.stringify(a,null," "),"utf-8")}catch{}let o=await g(e);delete o.claude,await E(e,o)}V();import{resolve as Re,basename as ln}from"node:path";import{rm as dn}from"node:fs/promises";import{confirm as Lt}from"@inquirer/prompts";import k from"picocolors";function Xs(e){console.log(`${k.green("\u2713")} ${e}`)}function Qs(e){console.log(`${k.red("\u2717")} ${e}`)}function Zs(e){console.log(`${k.yellow("!")} ${e}`)}function en(e){console.log(`${k.cyan("\u2192")} ${e}`)}function tn(e){console.log(k.dim(e))}function sn(e){return k.cyan(e)}function nn(e){return k.bold(e)}function rn(e){console.log(),console.log(k.bold(k.underline(e)))}function on(e,t=!1){let s=t?k.green("\u25CF"):k.dim("\u25CB");console.log(` ${s} ${e}`)}function an(){console.log(),console.log(k.bold(k.magenta("\u{1F3AF} Ready to use Vesper!"))),console.log(k.cyan(' In VS Code Chat, select "Vesper" from the agent dropdown')),console.log(k.cyan(" and start requesting!")),console.log()}function cn(e){let t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],s=0,n=null,o=e,a=()=>{let i=k.cyan(t[s]);process.stdout.write(`\r${i} ${o}`),s=(s+1)%t.length};return{start(){process.stdout.write(`
25
- `),n=setInterval(a,80),a()},update(i){o=i},stop(){n&&(clearInterval(n),n=null,process.stdout.write("\r"+" ".repeat(o.length+4)+"\r"))},succeed(i){this.stop(),console.log(`${k.green("\u2713")} ${i||o}`)},fail(i){this.stop(),console.log(`${k.red("\u2717")} ${i||o}`)}}}var r={success:Xs,error:Qs,warn:Zs,info:en,dim:tn,formatPath:sn,formatName:nn,header:rn,listItem:on,vesperTip:an,createSpinner:cn};async function pn(e={}){let t=Re(e.path||process.cwd());if(!(await g(t)).claude){r.warn("Claude Code target is not initialized in this workspace.");return}if(!e.yes&&!await Lt({message:"Remove the Claude Code target from this project? (the shared plugin catalog at the user level is left untouched)",default:!1})){r.info("Reset cancelled.");return}await Pe(t),console.log(),r.success("Claude Code target reset complete."),r.info("Removed: .claude/vesper/, CLAUDE.md guard block, .mcp.json entry, .vesperrc.claude"),r.info("Left untouched: the shared plugin catalog at ~/.claude/skills/vesper/")}function un(e){let t=new Set;for(let s of e)s.includes("/agents")&&t.add("Agents"),s.includes("/instructions")&&t.add("Instructions"),s.includes("/prompts")&&t.add("Prompts"),s.includes("/skills")&&t.add("Skills");return Array.from(t)}async function Ne(e){let t=await g(e);await gt(e);try{let n=await S(e);if(n[w]){let o=new Set(R),a=!1;for(let i of Object.keys(n[w]))o.has(i)||(delete n[w][i],a=!0);a&&await C(e,n)}}catch{}let s=Re(e,".vesperrc");try{if(t.claude){let{writeFile:n}=await import("node:fs/promises");await n(s,JSON.stringify({paths:[],addedAt:null,workspaceType:null,settingsPath:null,claude:t.claude},null,2),"utf-8")}else await dn(s,{force:!0})}catch{}}async function Vt(e={}){try{let t=Re(e.path||process.cwd());await m(t)||(r.error(`Directory not found: ${r.formatPath(t)}`),process.exit(1));let s=e.target;if(!s){let c=await N(t);if(c.length===0){r.warn("Vesper is not initialized in this workspace.");return}c.length>1&&(r.error("Both Copilot and Claude targets are installed here \u2014 specify which to reset: --target copilot|claude"),process.exit(1)),s=c[0]}if(s==="claude")return await pn({...e,path:t});if(!await fe(t)){r.warn("Vesper is not initialized in this workspace.");return}let n=await ee(t);if(n.length===0){r.info("Nothing to reset.");return}let o=un(n);if(!e.yes&&!await Lt({message:`Remove all Vesper assets (${o.join(", ")})?`,default:!1})){r.info("Reset cancelled.");return}let a=await g(t),i=await _(t);await Ne(t),a.claude&&r.info("Claude Code target detected \u2014 kept its record in .vesperrc"),console.log(),r.success("Vesper reset complete."),a.workspaceType===P.WORKSPACE_FILE||i.type===P.WORKSPACE_FILE?r.info(`Cleaned: ${ln(i.settingsPath)}`):r.info("Cleaned: .vscode/settings.json"),r.info("Reload VS Code to apply changes")}catch(t){if(t.name==="ExitPromptError"){console.log(),r.info("Reset cancelled.");return}r.error(`Reset failed: ${t.message}`),process.exit(1)}}var jt=["copilot","claude"];function Ut(e){return e==="claude"?"Claude Code":"GitHub Copilot"}async function _n(e){let t=await g(e),s=[];return Array.isArray(t.paths)&&t.paths.length>0&&s.push("copilot"),t.claude&&s.push("claude"),s}async function xn(e,t){let s=await _n(t);if(e.target){let o=String(e.target).toLowerCase(),a=o==="all"?[...jt]:o.split(",").map(i=>i.trim()).filter(Boolean);for(let i of a)jt.includes(i)||(r.error(`Unknown target: ${i}. Valid targets: copilot, claude, all`),process.exit(1));return{selected:[...new Set(a)],installed:s}}return process.stdin.isTTY||(r.error("Non-interactive run without --target. Specify the platform(s), e.g. --target copilot,claude (or --target all)."),process.exit(1)),{selected:await yn({message:s.length?"Platforms to set up (checked = installed; uncheck to remove):":"Which AI platform(s) is this workspace for?",choices:[{name:"GitHub Copilot (VS Code)",value:"copilot",checked:s.includes("copilot")},{name:"Claude Code (CLI / VS Code extension / JetBrains / desktop)",value:"claude",checked:s.includes("claude")}]}),installed:s}}async function Sn(e){return e?"":await vn({message:"Name Vesper's Claude Code subagents/skills/commands:",choices:[{name:"Plain names (recommended \u2014 matches the Copilot catalog 1:1)",value:""},{name:'Prefix with "vesper-" (avoids collisions with other Claude Code kits)',value:"vesper-"}],default:""})}async function kn(e,t={}){let s=t.yes||t.forceDefault,n=await Sn(s);console.log(),r.header("Installing Vesper for Claude Code"),console.log();let{pluginDir:o,counts:a}=await ke({namePrefix:n,version:t.version||"0.0.0"});r.success(`Specialist catalog installed: ${o}`),r.info(` agents: ${a.agents}, commands: ${a.commands}, skills: ${a.skills}`);let i=await Ae(e);r.success("Project files ready:"),r.info(` .claude/vesper/orchestrator.md (${i.orchestrator})`),r.info(` .claude/vesper/orchestration.md (${i.orchestration})`),r.info(` .claude/vesper/context.md (${i.context})`),r.info(` CLAUDE.md (${i.claudeMd})`);let c=await z(e,!0);await Ce(e),r.success(`MCP servers configured: .mcp.json (${c.servers.join(", ")})`),await Ft(e,{pluginPath:J(),namePrefix:n,mcpConfigPath:Y(e),settingsPath:Se(e),installedAt:new Date().toISOString()})}async function An(e,t,s){console.log(),r.header("Configuring GitHub Copilot"),console.log();let n=await St(e);await ht(e,{maxRequests:s.maxRequests,omitBaseAgentInstructions:s.omitBaseAgentInstructions});let o=await mt(e,s.terminalEnableAutoApprove),a=!1;return s.enableMcpServer&&(a=(await K(e,!0)).configured,await kt(e)),await dt(e),r.success("Core assets ensured: agents, prompts, instructions, skills"),r.info(`Max agent requests: ${s.maxRequests}`),o.configured>0?r.info(`Terminal auto-approval: ${o.configured} safe commands configured`):s.terminalEnableAutoApprove===!1&&r.info("Terminal auto-approval: disabled"),a&&(r.info("MCP servers: vesper-indexing, sequential-thinking, memory (.vscode/mcp.json)"),r.info("MCP tools auto-approval: vesper-indexing + context7 + sequential-thinking + memory")),n.workspaceType===P.WORKSPACE_FILE?r.info(`Settings added to: ${gn(t.settingsPath)}`):r.info("Settings added to: .vscode/settings.json"),r.info("Tracking file: .vesperrc"),r.info("Worktree bootstrap task: .vscode/tasks.json (runs on folder open)"),{mcpConfigured:a}}async function Cn(e,t){let s=await pt(e);if(!s.found)return{migrated:!1,from:null};let{paths:n}=s;console.log(),r.warn(`Found .vesperrc in nested folder${n.length>1?"s":""}:`);for(let{folderPath:i}of n)r.info(` \u2192 ${i}`);console.log();let o=n[0],a=!0;if(t||(a=await se({message:"Migrate .vesperrc to workspace level? (recommended for multi-root workspaces)",default:!0})),a){let i=await ut(e,o.vesperrcPath,o.tracking);if(i.success){if(r.success("Migrated .vesperrc to workspace level"),r.info(` From: ${o.vesperrcPath}`),r.info(` To: ${i.newPath}`),n.length>1){let{unlink:c}=await import("node:fs/promises");for(let d=1;d<n.length;d++)try{await c(n[d].vesperrcPath),r.info(` Removed: ${n[d].vesperrcPath}`)}catch{}}return console.log(),{migrated:!0,from:o.folderPath}}}else r.info("Migration skipped. .vesperrc will remain in nested folder."),console.log();return{migrated:!1,from:null}}async function Pn(e){let{migrated:t,changed:s}=await xt(e);if(!t)return;let n=(a,i)=>`${a} ${i}${a>1?"s":""}`,o=[];s.assetPaths&&o.push(n(s.assetPaths,"asset path")),s.readAccess&&o.push(n(s.readAccess,"read-access path")),s.commandKeys&&o.push(n(s.commandKeys,"stale command")),s.trackingPaths&&o.push(n(s.trackingPaths,"tracked path")),s.mcpArgs&&o.push("MCP server path"),console.log(),r.info("Detected a workspace set up under the older `vesper-cli` package \u2014 migrating install paths."),r.success(`Migrated: ${o.join(", ")}`),console.log()}async function En(e,t){let s=e;return t||(s=await hn({message:"Workspace root directory:",default:s})),fn(s)}async function Tn(e,t,s){let n=[];for(let o of t){let a=Ut(o),i=s;if(s||(i=await se({message:`${a} is installed but was unchecked. Remove it from this project?`,default:!1})),!i){r.info(`Kept ${a}.`);continue}o==="claude"?await Pe(e):await Ne(e),n.push(o),r.success(`Removed ${a} from this project.`)}return n}async function bn(e){if(e)return{maxRequests:M.maxRequests,terminalEnableAutoApprove:M.terminalEnableAutoApprove,omitBaseAgentInstructions:M.omitBaseAgentInstructions,enableMcpServer:M.enableMcpServer};console.log(),r.info("Configure VS Code Chat settings:");let t=await wn({message:"Max agent requests per session (chat.agent.maxRequests):",default:M.maxRequests,min:1,max:1e3}),s=await se({message:"Controls whether terminal commands are automatically approved. Enable terminal auto-approval? (chat.tools.terminal.enableAutoApprove)",default:M.terminalEnableAutoApprove});s&&r.info("Terminal auto-approval enabled with safe command whitelist");let n=await se({message:"Omit base agent instructions for custom agents? (github.copilot.chat.omitBaseAgentInstructions)",default:M.omitBaseAgentInstructions}),o=await se({message:"Enable vesper-indexing MCP server for fast code search?",default:M.enableMcpServer});return{maxRequests:t||M.maxRequests,terminalEnableAutoApprove:s,omitBaseAgentInstructions:n,enableMcpServer:o}}async function Fe(e,t=!1){let s=U().replace("index.js","cli-index.js");if(!await m(s))return{success:!1,error:"MCP server not built"};t&&(console.log(),r.info("Starting workspace indexing..."));let n=t?null:r.createSpinner("Indexing workspace...");return n&&n.start(),new Promise(o=>{let a=mn("node",[s,e],{stdio:["ignore","pipe","pipe"],env:{...process.env}}),i="",c=0;a.stderr.on("data",d=>{let l=d.toString().trim(),u=l.match(/Indexed (\d+) files/);if(u&&(c=parseInt(u[1],10),n&&n.update(`Indexing workspace... ${c} files`)),t&&l)for(let p of l.split(`
26
- `))p.trim()&&r.info(p.replace("[vesper-indexing] ",""))}),a.stdout.on("data",d=>{i+=d.toString()}),a.on("close",d=>{try{let l=JSON.parse(i.trim());l.success?n?n.succeed(`Workspace indexed: ${l.filesIndexed} files`):r.success(`Workspace indexed: ${l.filesIndexed} files`):n?n.fail(`Indexing failed: ${l.error}`):r.error(`Indexing failed: ${l.error}`),o(l)}catch{d===0?(n?n.succeed(`Workspace indexed: ${c} files`):r.success(`Workspace indexed: ${c} files`),o({success:!0,filesIndexed:c})):(n?n.fail("Indexing failed"):r.error("Indexing failed"),o({success:!1,error:"Unknown error"}))}}),a.on("error",d=>{n?n.fail(`Indexing failed: ${d.message}`):r.error(`Indexing failed: ${d.message}`),o({success:!1,error:d.message})})})}function $n({copilot:e,claude:t,indexingResult:s}){console.log(),r.success("Vesper is ready."),s?.success?r.info(`Code index built: ${s.filesIndexed} files.`):s?.error&&r.info("Code index will be built on first MCP server start."),console.log(),r.header("Next Steps"),console.log(),e&&(r.info("GitHub Copilot \u2014 reload VS Code to activate Vesper:"),r.info(' Cmd+Shift+P (macOS) / Ctrl+Shift+P (Windows/Linux) \u2192 "Developer: Reload Window"')),t&&(r.info("Claude Code \u2014 open a session in this workspace; the orchestrator"),r.info(" activates automatically via CLAUDE.md.")),console.log(),e&&r.vesperTip()}async function Gt(e={}){try{let t=e.yes||e.forceDefault,s=await En(e.path||process.cwd(),t);await m(s)||(r.error(`Directory not found: ${r.formatPath(s)}`),process.exit(1));let n=await _(s);n.type===P.WORKSPACE_FILE&&await Cn(s,t),await Pn(s);let{selected:o,installed:a}=await xn(e,s),i=a.filter(f=>!o.includes(f));if(o.length===0&&i.length===0){r.info("No platforms selected. Nothing to do.");return}if(!t&&a.length===0&&o.length>0&&!await se({message:`Set up ${o.map(Ut).join(" + ")} in ${s}?`,default:!0})){r.info("Initialization cancelled.");return}i.length>0&&await Tn(s,i,t);let c=o.includes("copilot"),d=o.includes("claude"),l=null;c&&(l=await bn(t)),c&&await An(s,n,l),d&&await kn(s,e),(c||d)&&(await ue(s),(await ge(s))["pre-commit"]?.hooksDir&&(r.success("Local-only Vesper files gitignored (.vesperrc, .mcp.json, .vesper/index.db)"),r.info("Commit-hygiene git hook installed (pre-commit): keeps team roster/context/history/memory in sync with every commit"),await me(s),await he(s),r.info("Merge strategy configured (.gitattributes): history.md unions, memory.jsonl merges entity-aware across worktrees")));let u=c&&l?.enableMcpServer||d,p=null;u&&(p=await Fe(s,!0)),$n({copilot:c,claude:d,indexingResult:p})}catch(t){if(t.name==="ExitPromptError"){console.log(),r.info("Initialization cancelled.");return}r.error(`Initialization failed: ${t.message}`),process.exit(1)}}V();import{resolve as Bt,basename as On}from"node:path";import{checkbox as qt,select as In}from"@inquirer/prompts";var Wt={agents:"agents",prompts:"commands",skills:"skills"};async function Mn(e,t){let s=await N(e);if(s.length===1)return s[0];s.length===0&&(r.warn('Vesper is not initialized in this workspace. Run "vespercli init" first.'),process.exit(0)),r.error(`Both Copilot and Claude targets are installed here \u2014 specify which to ${t}: --target copilot|claude`),process.exit(1)}async function Dn(e={}){let t=Bt(e.path||process.cwd());(!e.type||!e.name)&&(r.error("Usage: vesper add <type> <name> --target claude"),r.info("Types: agents, prompts (installed as slash commands), skills"),process.exit(1));let s=Wt[e.type];s||(r.error(`Unknown asset type for --target claude: ${e.type}`),r.info(`Available types: ${Object.keys(Wt).join(", ")}`),process.exit(1));let o=(await g(t)).claude?.namePrefix??"";try{let a=await Mt(s,e.name,{namePrefix:o});r.success(`Added ${e.type}/${e.name} to the Claude plugin catalog as "${a.installedAs}"`)}catch(a){r.error(a.message),process.exit(1)}}var de=["agents","prompts","instructions"];async function Le(e,t){let s=await ee(e);return(await Q(t)).filter(o=>{let a=q(t,o);return!s.includes(a.path)})}async function Rn(e){let t=[];for(let i of de){let c=await Le(e,i);c.length>0&&t.push({name:`${i.charAt(0).toUpperCase()+i.slice(1)} (${c.length} available)`,value:i})}if(t.length===0)return r.info("All extended assets are already added."),[];let s=await In({message:"Select asset type:",choices:t}),o=(await Le(e,s)).map(i=>({name:i,value:i,checked:!1}));return(await qt({message:`Select ${s} to add:`,choices:o})).map(i=>({type:s,name:i}))}async function Kt(e={}){try{let t=Bt(e.path||process.cwd());if(await m(t)||(r.error(`Directory not found: ${r.formatPath(t)}`),process.exit(1)),(e.target||await Mn(t,"add"))==="claude")return await Dn({...e,path:t});if(!await fe(t)){r.warn('Vesper is not initialized. Run "vespercli init" first.');return}let n=[];if(e.type&&e.name){if(e.type==="skills"){r.info("Skills are automatically added during init.");return}de.includes(e.type)||(r.error(`Unknown asset type: ${e.type}`),r.info(`Available types: ${de.join(", ")}`),process.exit(1));let l=await Q(e.type);l.includes(e.name)||(r.error(`Asset not found: ${e.name}`),r.info(`Available ${e.type}: ${l.join(", ")||"none"}`),process.exit(1)),n=[{type:e.type,name:e.name}]}else if(e.type){if(e.type==="skills"){r.info("Skills are automatically added during init.");return}de.includes(e.type)||(r.error(`Unknown asset type: ${e.type}`),r.info(`Available types: ${de.join(", ")}`),process.exit(1));let l=await Le(t,e.type);if(l.length===0){r.info(`All ${e.type} are already added.`);return}let u=l.map(f=>({name:f,value:f,checked:!1})),p=await qt({message:`Select ${e.type} to add:`,choices:u});if(p.length===0){r.info("Nothing selected.");return}n=p.map(f=>({type:e.type,name:f}))}else if(n=await Rn(t),n.length===0){r.info("Nothing selected.");return}let o=n.map(({type:l,name:u})=>q(l,u)),{added:a,skipped:i,workspaceType:c}=await ft(t,o),d=n.filter(l=>l.type==="agents"&&a.includes(q(l.type,l.name).path));for(let{name:l}of d)$e[l]&&(await At(t,l),r.info(` Added MCP tools auto-approval for agent: ${l}`));if(a.length>0){let l=await _(t);console.log(),r.success(`Added ${a.length} asset(s):`);for(let{type:u,name:p}of n.filter(f=>a.includes(q(f.type,f.name).path)))r.info(` ${u}/${p}`);c===P.WORKSPACE_FILE&&r.info(`
27
- Updated: ${On(l.settingsPath)}`),r.info(`
28
- Reload VS Code to apply changes`)}else i.length>0&&r.info("All selected assets are already added.")}catch(t){if(t.name==="ExitPromptError"){console.log(),r.info("Cancelled.");return}r.error(`Add failed: ${t.message}`),process.exit(1)}}V();import{resolve as Jt,join as Nn}from"node:path";import{readdir as Fn}from"node:fs/promises";import L from"picocolors";async function Ht(e={}){let t=Jt(e.path||process.cwd()),s=await g(t);if(console.log(),console.log(L.bold("Claude Code target")),!s.claude){console.log(),r.warn('Not initialized for Claude Code. Run "vesper init --target claude" first.'),console.log();return}let n=s.claude.pluginPath||J();console.log(L.dim(`Plugin catalog: ${n}`));let o=await Dt();for(let[a,i]of Object.entries(o))console.log(),console.log(L.bold(a.charAt(0).toUpperCase()+a.slice(1))),i.length===0?console.log(L.dim(" (none installed)")):i.forEach(c=>console.log(` ${c}`));console.log(),console.log(L.bold("Project files")),console.log(" CLAUDE.md, .claude/vesper/{orchestrator,orchestration,context}.md, .mcp.json, .claude/settings.json"),console.log()}async function Ln(e,t,s=!1){try{let n=await Fn(e,{withFileTypes:!0});return s||t.dir==="skills"?n.filter(a=>a.isDirectory()&&!a.name.startsWith(".")).map(a=>a.name):n.filter(a=>a.isFile()&&a.name.endsWith(t.extension)).map(a=>a.name.replace(t.extension,""))}catch{return[]}}async function Yt(e={}){try{let t=Jt(e.path||process.cwd());await m(t)||(r.error(`Directory not found: ${r.formatPath(t)}`),process.exit(1));let s=await N(t);if(e.target==="claude")return await Ht({...e,path:t});if(!e.target){if(s.length===0){console.log(),r.warn('Vesper is not initialized. Run "vespercli init" first.'),console.log();return}if(s.length===1&&s[0]==="claude")return await Ht({...e,path:t});s.includes("claude")&&r.info("Claude Code target is also installed here \u2014 run `vespercli list --target claude` to see it.")}let n=await ee(t);e.type&&!I[e.type]&&(r.error(`Unknown asset type: ${e.type}`),r.info(`Valid types: ${Object.keys(I).join(", ")}`),process.exit(1));let o=e.type?[e.type]:Object.keys(I);console.log(),console.log(L.bold("Assets"));for(let a of o){let i=I[a],c=a.charAt(0).toUpperCase()+a.slice(1);if(a==="skills"){let f=_t("skills");if(n.includes(f.path)){let h=await Q("skills");console.log(),console.log(L.bold(`${c}`)),console.log(` ${h.length} skills enabled ${L.dim("(all)")}`)}continue}let d=Nn(Be,i.dir),l=await Ln(d,i,!1),p=(await Q(a)).filter(f=>{let h=q(a,f);return n.includes(h.path)});(l.length>0||p.length>0)&&(console.log(),console.log(L.bold(`${c}`)),l.forEach(f=>{console.log(` ${f} ${L.dim("(core)")}`)}),p.forEach(f=>{console.log(` ${f}`)}))}console.log()}catch(t){r.error(`List failed: ${t.message}`),process.exit(1)}}import{readFileSync as Vn,existsSync as jn}from"node:fs";import{join as Un}from"node:path";var zt="catalog.md",Gn="mthanhtran",Wn="vesper",Bn="main";function qn(){return`https://raw.githubusercontent.com/${Gn}/${Wn}/${Bn}/assets/${zt}`}function Kn(){let e=Un(X,"assets",zt);return jn(e)?Vn(e,"utf-8"):null}async function Hn(){try{let e=qn(),t=await fetch(e);return t.ok?t.text():null}catch{return null}}async function Jn(){let e=await Hn();if(e)return e;let t=Kn();if(t)return t;throw new Error("Catalog not available from remote or local")}async function Xt(){try{let e=await Jn();console.log(e)}catch(e){console.error(`Error loading catalog: ${e.message}`),process.exit(1)}}V();import{resolve as Yn,join as Zt}from"node:path";import{stat as zn,readFile as es}from"node:fs/promises";import"@inquirer/prompts";import W from"picocolors";async function Ve(e){let t=await g(e);if(console.log(),r.header("vesper-indexing MCP Server (Claude Code target)"),console.log(),!t.claude){r.info("Claude Code target is not initialized. Run `vesper init --target claude` first.");return}let s=Y(e),n=!1;if(await m(s))try{n=!!JSON.parse(await es(s,"utf-8")).mcpServers?.["vesper-indexing"]}catch{n=!1}r.info(`Configured: ${n?"\u2713 yes":"\u2717 no"} (${s})`),r.info(`Server built: ${await ss()?"\u2713 yes":"\u2717 no"}`);let o=je(e);r.info(`Index exists: ${await m(o)?"\u2713 yes":"\u2717 no"} (shared with the Copilot target if both are installed)`)}async function ne(e,t=!0){await z(e,t),t&&await Ce(e),r.success(`Claude Code target: vesper-indexing ${t?"enabled":"disabled"} in .mcp.json`)}function je(e){return Zt(e,".vesper","index.db")}function Xn(e){return Zt(e,".vesper","indexing-status.json")}async function ts(e){let t=Xn(e);try{let s=await es(t,"utf-8");return JSON.parse(s)}catch{return null}}async function ss(){let e=U();return await m(e)}async function Qn(e){try{let t=await zn(e),s=t.size,n=`${s} bytes`;return s>1024*1024?n=`${(s/(1024*1024)).toFixed(2)} MB`:s>1024&&(n=`${(s/1024).toFixed(1)} KB`),{dbSize:n,lastModified:t.mtime.toISOString()}}catch{return null}}async function Qt(e,t=!1){let s=await ye(e),n=await ss(),o=je(e),a=await m(o),i=await ts(e);if(console.log(),r.header("vesper-indexing MCP Server"),console.log(),r.info(`Configured: ${s?"\u2713 yes":"\u2717 no"}`),r.info(`Server built: ${n?"\u2713 yes":"\u2717 no"}`),r.info(`Index exists: ${a?"\u2713 yes":"\u2717 no"}`),i)if(console.log(),i.status==="indexing")if(t){await Zn(e,i);return}else{let c=i.startedAt?Math.round((Date.now()-new Date(i.startedAt).getTime())/1e3):0;r.info(W.yellow("\u27F3 Indexing in progress...")),r.info(` Files processed: ${W.cyan(i.filesProcessed)}`),r.info(` Elapsed: ${W.dim(`${c}s`)}`),console.log(),r.info("Use --watch to follow indexing progress until completion")}else i.status==="error"&&(r.error(`Indexing error: ${i.error}`),r.info(` Files processed before error: ${i.filesProcessed}`));if(!s){console.log(),r.info("Run `vespercli init` to configure the MCP server");return}if(!n){console.log(),r.warn("MCP server not built. Run: cd src/mcp/vesper-indexing && npm install && npm run build");return}if(a&&!i){let c=await Qn(o);c&&(console.log(),r.info(`Index size: ${c.dbSize}`),r.info(`Last modified: ${c.lastModified}`)),r.vesperTip()}else!a&&!i&&(console.log(),r.info("Index not yet created. It will be built when VS Code loads the MCP server."),console.log())}async function Zn(e,t){let s=r.createSpinner(`Indexing... ${t.filesProcessed} files processed`);s.start();let n=500,o=30*60*1e3,a=Date.now();return new Promise(i=>{let c=async()=>{let d=await ts(e);if(!d||d.status!=="indexing"){d?.status==="error"?s.fail(`Indexing failed: ${d.error}`):(s.succeed(`Indexing complete! ${d?.filesProcessed||"All"} files indexed`),r.info(`
29
- \u2192 Reload VS Code to update MCP tools with the new index`),r.vesperTip()),i();return}let l=d.startedAt?Math.round((Date.now()-new Date(d.startedAt).getTime())/1e3):0;if(s.update(`Indexing... ${d.filesProcessed} files processed (${l}s)`),Date.now()-a>o){s.fail("Indexing watch timed out (30 minutes)"),i();return}setTimeout(c,n)};setTimeout(c,n)})}async function er(e,t=!1){let s=je(e);if(!await m(s))r.info("No index exists. It will be built when VS Code loads the MCP server.");else if(t){let{unlink:o}=await import("node:fs/promises");await o(s),r.success("Index cleared. Reload VS Code to rebuild.")}else r.info("Incremental reindex happens automatically when files change."),r.info("Use --full to clear and rebuild the entire index.")}async function tr(e){let t=await K(e,!0);t.configured&&(r.success("MCP server enabled"),r.info(`Config: ${t.mcpPath}`),r.info("Reload VS Code to start the server"))}async function sr(e){await K(e,!1),r.success("MCP server disabled"),r.info("Reload VS Code to apply changes")}async function ns(e){let t=await _(e),s=await g(e,t);if(!Array.isArray(s.paths))return[];let n=[];for(let o of s.paths){let a=o.match(/agents\/([^/]+)\/?$/);a&&MCP_TOOLS_BY_AGENT[a[1]]&&n.push(a[1])}return n}async function nr(e){let t=await _(e),s=await g(e,t),n=await S(e,t),o=await ns(e),a=n[w]||{},i=new Set(R),c=[],d=[],l=!1;n[w]||(n[w]={});for(let p of R)a[p]||(n[w][p]=!0,c.push(p),l=!0);for(let p of o){let f=MCP_TOOLS_BY_AGENT[p]||[];for(let h of f)a[h]||(n[w][h]=!0,c.push(h),l=!0)}let u=new Set;for(let p of o)for(let f of MCP_TOOLS_BY_AGENT[p]||[])u.add(f);for(let p of Object.keys(a)){if(i.has(p))continue;let f=!1;for(let[h,O]of Object.entries(MCP_TOOLS_BY_AGENT))if(O.includes(p)){f=!0;break}f&&!u.has(p)&&(delete n[w][p],d.push(p),l=!0)}if(s.mcp=s.mcp||{},s.mcp.syncedAt=new Date().toISOString(),s.mcp.approvedAgents=o,s.mcp.toolCount=Object.keys(n[w]).length,l&&await C(e,n),await E(e,s),console.log(),r.header("MCP Tools Sync"),console.log(),c.length===0&&d.length===0)r.success("Already in sync");else{if(c.length>0){r.success(`Added ${c.length} tool(s)`);let p=c.filter(f=>i.has(f));p.length>0&&r.info(` Core: ${p.length} tools`);for(let f of o){let h=c.filter(O=>(MCP_TOOLS_BY_AGENT[f]||[]).includes(O));h.length>0&&r.info(` ${f}: ${h.length} tools`)}}d.length>0&&r.info(`Removed ${d.length} orphaned tool(s)`)}r.info(`
30
- Total approved tools: ${s.mcp.toolCount}`),o.length>0&&r.info(`Agents with tools: ${o.join(", ")}`),l&&r.info(`
31
- Reload VS Code to apply changes`)}async function rr(e){let t=await _(e),s=await g(e,t),o=(await S(e,t))[w]||{},a=Object.keys(o).length,i=await ns(e);console.log(),r.header("MCP Tool Approval Status"),console.log();let c=R.filter(u=>o[u]);if(r.info(`Core tools: ${c.length}/${R.length} approved`),i.length>0){console.log(),r.info("Agent tools:");for(let u of i){let p=MCP_TOOLS_BY_AGENT[u]||[],f=p.filter(O=>o[O]),h=f.length===p.length?W.green("\u2713"):W.yellow("\u26A0");r.info(` ${h} ${u}: ${f.length}/${p.length} approved`)}}let d=[...R];for(let u of i)d.push(...MCP_TOOLS_BY_AGENT[u]||[]);let l=d.filter(u=>!o[u]);console.log(),r.info(`Total approved: ${a} tools`),l.length>0?(console.log(),r.warn(`${l.length} tools missing approval`),r.info("Run `vespercli mcp sync` to fix")):s.mcp?.syncedAt&&r.info(`Last synced: ${s.mcp.syncedAt}`)}async function or(e,t){t||(r.error("Server name required. Usage: vespercli mcp add <server>"),r.info("Available servers: clickup, vesper-indexing, sequential-thinking"),process.exit(1)),console.log(),r.header("Add MCP Server"),console.log();let s=await Ct(e,t);if(!s.added){s.error==="Already configured"?r.info(`MCP server '${t}' is already configured`):(r.error(s.error),process.exit(1));return}r.success(`Added MCP server: ${t}`),s.tools.length>0&&r.info(`Approved ${s.tools.length} tool(s) for auto-execution`),r.info(`
32
- Reload VS Code to activate the MCP server`)}async function ar(e,t){t||(r.error("Server name required. Usage: vespercli mcp remove <server>"),process.exit(1)),console.log(),r.header("Remove MCP Server"),console.log();let s=await Pt(e,t);if(!s.removed){r.info(`MCP server '${t}' is not configured`);return}r.success(`Removed MCP server: ${t}`),s.tools.length>0&&r.info(`Removed ${s.tools.length} tool(s) from auto-approval`),r.info(`
33
- Reload VS Code to deactivate the MCP server`)}async function ir(e){let t=await _(e),s=await g(e,t),n=await G(e);console.log(),r.header("MCP Servers"),console.log();let o=s.mcp?.servers||[],a=Object.keys(n.servers||{});r.info("Available servers:");for(let[c,d]of Object.entries(ce)){let u=a.includes(c)?W.green("\u2713"):W.dim("\u25CB"),p=d.tools?.length||0;r.info(` ${u} ${c} (${p} tools)`)}let i=a.filter(c=>!ce[c]);if(i.length>0){console.log(),r.info("Custom servers:");for(let c of i)r.info(` ${W.blue("\u25C6")} ${c}`)}console.log(),r.info(`Installed: ${a.length} server(s)`)}async function rs(e,t,s={}){let n=Yn(s.path||process.cwd());await m(n)||(r.error(`Directory not found: ${n}`),process.exit(1));let o=await N(n),a=s.target?[s.target]:o.length?o:["copilot"],i=a.includes("copilot"),c=a.includes("claude");if(c&&!i)switch(e){case"enable":return await ne(n,!0);case"disable":return await ne(n,!1);case"sync":return await ne(n,!0);case"status":default:return await Ve(n)}let d=i&&c;switch(e){case"status":await Qt(n,s.watch),d&&await Ve(n);break;case"add":await or(n,t);break;case"remove":await ar(n,t);break;case"list":await ir(n);break;case"reindex":await er(n,s.full);break;case"enable":await tr(n),d&&await ne(n,!0);break;case"disable":await sr(n),d&&await ne(n,!1);break;case"sync":await nr(n),d&&await ne(n,!0);break;case"approve":await rr(n);break;default:await Qt(n,s.watch),d&&await Ve(n)}}import{resolve as cr}from"node:path";async function as(e,t,s,n={}){let o=cr(n.path||process.cwd());if(!e){os();return}switch(e){case"add":await lr(o,t,s);break;case"remove":await dr(o,t,s);break;case"list":await pr(o,t);break;default:r.error(`Unknown subcommand: ${e}`),os()}}async function lr(e,t,s){if(!t){r.error("Setting key required"),r.info("Usage: vespercli settings add <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!s){r.error("Path value required"),r.info("Usage: vespercli settings add read-access <path>");return}let n=await wt(e,s);r.success(`Added "${s}" to additional read access paths`),r.info(`Current paths: ${n.length>0?n.join(", "):"(none)"}`);break;default:r.error(`Unknown setting: ${t}`),r.info("Supported settings:"),r.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function dr(e,t,s){if(!t){r.error("Setting key required"),r.info("Usage: vespercli settings remove <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!s){r.error("Path value required"),r.info("Usage: vespercli settings remove read-access <path>");return}let n=await vt(e,s);r.success(`Removed "${s}" from additional read access paths`),r.info(`Current paths: ${n.length>0?n.join(", "):"(none)"}`);break;default:r.error(`Unknown setting: ${t}`),r.info("Supported settings:"),r.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function pr(e,t){if(!t){r.info("Managed settings:"),r.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)"),r.info(""),r.info("Use: vespercli settings list <setting-key>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":let s=await yt(e);r.info(`${x}:`),s.length===0?r.info(" (empty)"):s.forEach(n=>r.info(` - ${n}`));break;default:r.error(`Unknown setting: ${t}`),r.info("Supported settings:"),r.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}function os(){r.info("Usage: vespercli settings <subcommand> [setting-key] [value]"),r.info(""),r.info("Subcommands:"),r.info(" add <setting-key> <value> Add a value to an array setting"),r.info(" remove <setting-key> <value> Remove a value from an array setting"),r.info(" list [setting-key] List current values"),r.info(""),r.info("Supported settings:"),r.info(" read-access github.copilot.chat.additionalReadAccessPaths"),r.info(""),r.info("Examples:"),r.info(" vespercli settings add read-access /path/to/external/repo"),r.info(" vespercli settings remove read-access /path/to/external/repo"),r.info(" vespercli settings list read-access")}V();import{resolve as is}from"node:path";async function ur(e={}){let t=is(e.path||process.cwd()),s=await g(t);if(!s.claude){r.warn('Claude Code target is not initialized. Run "vesper init --target claude" first.');return}console.log(),r.info("Refreshing Claude Code plugin catalog and orchestrator playbook...");let{pluginDir:n,counts:o}=await ke({namePrefix:s.claude.namePrefix||"",version:e.version||"0.0.0"});r.success(`Plugin catalog refreshed: ${n}`),r.info(` agents: ${o.agents}, commands: ${o.commands}, skills: ${o.skills}`);let a=await Ae(t);r.success(`Orchestrator playbook refreshed (.claude/vesper/orchestrator.md: ${a.orchestrator})`),r.info("Team roster (.claude/vesper/orchestration.md) and project context (.claude/vesper/context.md) are left alone \u2014 they belong to this project.")}async function cs(e={}){try{let t=is(e.path||process.cwd());await m(t)||(r.error(`Directory not found: ${r.formatPath(t)}`),process.exit(1));let s=e.target?[e.target]:await N(t);if(s.length===0){r.warn('Vesper is not initialized. Run "vespercli init" first.');return}s.includes("claude")&&await ur({...e,path:t}),s.includes("copilot")&&(console.log(),r.info("Copilot assets are linked from the package, not copied."),r.info("Update the vesper package to get the latest assets:"),r.dim(" npm update -g @mthanh/vespercli"),console.log())}catch(t){r.error(`Update failed: ${t.message}`),process.exit(1)}}V();import{resolve as fr,join as Ue}from"node:path";async function gr(e){let t=await m(Ue(xe(e),"orchestration.md")),s=await m(Ue(e,".github","copilot-instructions.md"));return{claude:t,copilot:s}}async function mr(e,t){if(!await m(e))return;let{claude:s,copilot:n}=await gr(e);if(!s&&!n){t||r.info("Not a vesperized workspace \u2014 nothing to bootstrap. Run `vespercli init` to set up.");return}let o=[];s&&(await z(e,!0),o.push(".mcp.json regenerated for this worktree (Claude target)")),n&&await ye(e)&&(await K(e,!0),o.push(".vscode/mcp.json refreshed (Copilot target)"));let a=Ue(e,".vesper","index.db");if(!await m(a)){let i=await Fe(e,!1);i.success&&o.push(`code index built (${i.filesIndexed} files)`)}if(await ue(e),await ge(e),await me(e),await he(e),o.push("gitignore + git hooks + merge strategy ensured"),!t){r.success("Worktree bootstrap complete");for(let i of o)r.info(` ${i}`)}}async function ls(e,t={}){let s=fr(t.path||process.cwd()),n=!!t.quiet;switch(e){case"bootstrap":case void 0:await mr(s,n);break;default:r.error(`Unknown subcommand: ${e}. Usage: vespercli worktree bootstrap`),process.exit(1)}}var _r=yr(import.meta.url),xr=Ge(_r);function Sr(e){let t=e;for(;t!==Ge(t);){let s=ds(t,"package.json");if(vr(s))return s;t=Ge(t)}return ds(e,"..","..","package.json")}var kr=Sr(xr),We=JSON.parse(wr(kr,"utf-8")),D=new hr;D.name("vespercli").description("Vesper VS Code Agent Suite \u2014 manage GitHub Copilot agents, prompts, instructions, and skills").version(We.version,"-v, --version","Output the current version");D.command("init").description("Initialize vesper for one or more platforms (GitHub Copilot and/or Claude Code) in this workspace").option("-p, --path <path>","Workspace root directory",process.cwd()).option("-y, --yes","Skip follow-up prompts (not the platform selection)").option("-f, --force","Force re-initialization (skips follow-up prompts)").option("--force-default","Use all default values for follow-up prompts (not the platform selection)").option("--target <targets>","Platform(s) to set up: copilot, claude, a comma list (copilot,claude), or all. Multi-select prompt if omitted.").action(e=>Gt({...e,version:We.version}));D.command("add").description("Add extended assets \u2014 to VS Code settings (Copilot) or the Claude Code plugin catalog. Target is auto-detected from the workspace 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()).option("--target <target>","Install target: copilot or claude (auto-detected if omitted)").action((e,t,s)=>Kt({type:e,name:t,...s}));D.command("reset").description("Remove the Vesper install \u2014 Copilot settings or the Claude Code target. Target is auto-detected from the workspace when omitted.").option("--path <path>","Workspace root directory",process.cwd()).option("-y, --yes","Skip confirmation prompts").option("--target <target>","Install target: copilot or claude (auto-detected if omitted)").action(Vt);D.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()).option("--target <target>","Install target: copilot or claude (omit to see all installed targets)").action((e,t)=>Yt({type:e,...t}));D.command("update").description("Refresh installed targets \u2014 the Claude Code plugin catalog + orchestrator playbook, and/or the Copilot package-link note. Auto-detected from the workspace when omitted.").option("--path <path>","Workspace root directory",process.cwd()).option("--target <target>","Install target: copilot or claude (auto-detected if omitted)").action(e=>cs({...e,version:We.version}));D.command("catalog").description("Show the Vesper catalog (agents, dependencies, requirements)").action(Xt);D.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").option("--target <target>","Install target: copilot, claude, or omit for all installed targets").action((e,t,s)=>rs(e,t,s));D.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,s,n)=>as(e,t,s,n));D.command("worktree").description("Bootstrap a git worktree with Vesper's local-only artifacts (.mcp.json, code index, gitignore, git hooks)").argument("[subcommand]","Subcommand: bootstrap (default)").option("--path <path>","Workspace root directory",process.cwd()).option("-q, --quiet","Suppress non-error output (used by hooks/tasks)").action((e,t)=>ls(e,t));D.addHelpText("after",`
24
+ ${n}`;return await $(t,i,"utf-8"),{created:!1,updated:!0}}function lr(e){let t=new RegExp(`${We}[\\s\\S]*?${Be}\\n*`);return e.replace(t,"")}async function Te(e){let t=Pe(e);await Q(t,{recursive:!0});let s={orchestrator:"refreshed",orchestration:"skipped",context:"skipped"},r=v(oe,"vesper-orchestrator.md"),n=v(t,"orchestrator.md");await $(n,await G(r,"utf-8"),"utf-8");let i=v(t,"orchestration.md");await g(i)||(await $(i,await G(v(oe,"orchestration.md.tpl"),"utf-8"),"utf-8"),s.orchestration="created");let a=v(t,"context.md");await g(a)||(await $(a,await G(v(oe,"context.md.tpl"),"utf-8"),"utf-8"),s.context="created");let c=await cr(e);return s.claudeMd=c.created?"created":c.updated?"updated":"unchanged",s}async function fe(e){let t=Z(e);try{let s=await G(t,"utf-8");return JSON.parse(s)}catch(s){return s.code==="ENOENT"?{mcpServers:{}}:{mcpServers:{}}}}async function qe(e,t){let s=Z(e);await Q(Ue(s),{recursive:!0}),await $(s,JSON.stringify(t,null," "),"utf-8")}function dr(e){return{"vesper-indexing":{command:"node",args:[B()],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:v(e,".vesper","memory.jsonl")}}}}async function ee(e,t=!0){let s=await fe(e);s.mcpServers||(s.mcpServers={});let r=dr(e),n=Object.keys(r);if(t)for(let[i,a]of Object.entries(r))s.mcpServers[i]=a;else for(let i of n)delete s.mcpServers[i];return await qe(e,s),{configured:t,mcpPath:Z(e),servers:t?n:[]}}function Ge(e,t){return String(e).replace(/\$\{VESPER_INDEXING_PATH\}/g,B()).replace(/\$\{workspaceFolder\}/g,t).replace(/\$\{env:([^}]+)\}/g,"$${$1}")}function ur(e,{workspaceRoot:t}){let{type:s,...r}=structuredClone(e);if(typeof r.command=="string"&&(r.command=Ge(r.command,t)),Array.isArray(r.args)&&(r.args=r.args.map(n=>Ge(n,t))),r.env&&typeof r.env=="object")for(let[n,i]of Object.entries(r.env))r.env[n]=Ge(i,t);return r}async function Ht(e,t){if(z.includes(t))return{added:!1,serverName:t,error:`${t} is a Vesper-managed core server \u2014 use "vespercli mcp enable --target claude" instead.`};let s=V[t];if(!s)return{added:!1,serverName:t,error:`Unknown MCP server: ${t}`};let r=await fe(e);if(r.mcpServers||(r.mcpServers={}),r.mcpServers[t])return{added:!1,serverName:t,error:"Already configured"};r.mcpServers[t]=ur(s.config,{workspaceRoot:e}),await qe(e,r);let n=await m(e);return n.mcp=n.mcp||{},n.mcp.servers=n.mcp.servers||[],n.mcp.servers.includes(t)||n.mcp.servers.push(t),n.mcp.updatedAt=new Date().toISOString(),await C(e,n),{added:!0,serverName:t}}async function Jt(e,t){if(z.includes(t))return{removed:!1,serverName:t,error:`${t} is a Vesper-managed core server \u2014 use "vespercli mcp disable --target claude" instead.`};let s=await fe(e),r=!1;s.mcpServers&&s.mcpServers[t]&&(delete s.mcpServers[t],await qe(e,s),r=!0);let n=await m(e);return n.mcp?.servers&&(n.mcp.servers=n.mcp.servers.filter(i=>i!==t),n.mcp.updatedAt=new Date().toISOString(),await C(e,n)),{removed:r,serverName:t}}async function zt(e){let t=await fe(e),s=Object.keys(t.mcpServers||{}),r=s.filter(n=>!V[n]);return{configured:s,custom:r}}async function Yt(e){let t=new Set,s=[];try{s=await D(e)}catch{s=[]}if(s.includes("claude"))try{let a=await fe(e);for(let c of Object.keys(a.mcpServers||{}))t.add(c)}catch{}if(s.includes("copilot"))try{let a=await N(e);for(let c of Object.keys(a.servers||{}))t.add(c)}catch{}let r=[];try{let a=await m(e);r=Array.isArray(a.mcp?.servers)?a.mcp.servers:[]}catch{r=[]}let n=new Set(r);return{drifted:[...t].filter(a=>!z.includes(a)&&!n.has(a))}}async function $e(e){let t=Ee(e),s={};try{s=JSON.parse(await G(t,"utf-8"))}catch{s={}}s.permissions||(s.permissions={}),Array.isArray(s.permissions.allow)||(s.permissions.allow=[]);let r=["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"],n=0;for(let i of r)s.permissions.allow.includes(i)||(s.permissions.allow.push(i),n+=1);return gr(s),await Q(Ue(t),{recursive:!0}),await $(t,JSON.stringify(s,null," "),"utf-8"),{configured:n,settingsPath:t}}var Xt=".claude/vesper/",pr=`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){}"`,Qt="worktree bootstrap",fr="command -v vespercli >/dev/null 2>&1 && vespercli worktree bootstrap --quiet || true";function gr(e){e.hooks||(e.hooks={}),Array.isArray(e.hooks.SessionStart)||(e.hooks.SessionStart=[]);let t=s=>e.hooks.SessionStart.some(r=>(r?.hooks||[]).some(n=>typeof n?.command=="string"&&n.command.includes(s)));t(Xt)||e.hooks.SessionStart.push({matcher:"clear",hooks:[{type:"command",command:pr}]}),t(Qt)||e.hooks.SessionStart.push({hooks:[{type:"command",command:fr}]})}function mr(e){Array.isArray(e?.hooks?.SessionStart)&&(e.hooks.SessionStart=e.hooks.SessionStart.filter(t=>!(t?.hooks||[]).some(s=>typeof s?.command=="string"&&(s.command.includes(Xt)||s.command.includes(Qt)))),e.hooks.SessionStart.length===0&&delete e.hooks.SessionStart,e.hooks&&Object.keys(e.hooks).length===0&&delete e.hooks)}async function Zt(e,t){let s=await m(e);return s.claude={...s.claude,...t,updatedAt:new Date().toISOString()},await C(e,s),s.claude}async function Oe(e){let t=Pe(e);await Vt(t,{recursive:!0,force:!0});let s=Wt(e);if(await g(s)){let i=await G(s,"utf-8"),a=lr(i);a.trim()?await $(s,a,"utf-8"):await Vt(s,{force:!0})}await ee(e,!1);let r=Ee(e);if(await g(r))try{let i=JSON.parse(await G(r,"utf-8"));mr(i),await $(r,JSON.stringify(i,null," "),"utf-8")}catch{}let n=await m(e);delete n.claude,await C(e,n)}F();import{resolve as Ke,basename as Er}from"node:path";import{rm as br}from"node:fs/promises";import{confirm as es}from"@inquirer/prompts";import x from"picocolors";function hr(e){console.log(`${x.green("\u2713")} ${e}`)}function wr(e){console.log(`${x.red("\u2717")} ${e}`)}function vr(e){console.log(`${x.yellow("!")} ${e}`)}function yr(e){console.log(`${x.cyan("\u2192")} ${e}`)}function _r(e){console.log(x.dim(e))}function Sr(e){return x.cyan(e)}function kr(e){return x.bold(e)}function xr(e){console.log(),console.log(x.bold(x.underline(e)))}function Cr(e,t=!1){let s=t?x.green("\u25CF"):x.dim("\u25CB");console.log(` ${s} ${e}`)}function Ar(){console.log(),console.log(x.bold(x.magenta("\u{1F3AF} Ready to use Vesper!"))),console.log(x.cyan(' In VS Code Chat, select "Vesper" from the agent dropdown')),console.log(x.cyan(" and start requesting!")),console.log()}function Pr(e){let t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],s=0,r=null,n=e,i=()=>{let a=x.cyan(t[s]);process.stdout.write(`\r${a} ${n}`),s=(s+1)%t.length};return{start(){process.stdout.write(`
25
+ `),r=setInterval(i,80),i()},update(a){n=a},stop(){r&&(clearInterval(r),r=null,process.stdout.write("\r"+" ".repeat(n.length+4)+"\r"))},succeed(a){this.stop(),console.log(`${x.green("\u2713")} ${a||n}`)},fail(a){this.stop(),console.log(`${x.red("\u2717")} ${a||n}`)}}}var o={success:hr,error:wr,warn:vr,info:yr,dim:_r,formatPath:Sr,formatName:kr,header:xr,listItem:Cr,vesperTip:Ar,createSpinner:Pr};async function Tr(e={}){let t=Ke(e.path||process.cwd());if(!(await m(t)).claude){o.warn("Claude Code target is not initialized in this workspace.");return}if(!e.yes&&!await es({message:"Remove the Claude Code target from this project? (the shared plugin catalog at the user level is left untouched)",default:!1})){o.info("Reset cancelled.");return}await Oe(t),console.log(),o.success("Claude Code target reset complete."),o.info("Removed: .claude/vesper/, CLAUDE.md guard block, .mcp.json entry, .vesperrc.claude"),o.info("Left untouched: the shared plugin catalog at ~/.claude/skills/vesper/")}function $r(e){let t=new Set;for(let s of e)s.includes("/agents")&&t.add("Agents"),s.includes("/instructions")&&t.add("Instructions"),s.includes("/prompts")&&t.add("Prompts"),s.includes("/skills")&&t.add("Skills");return Array.from(t)}async function He(e){let t=await m(e);await Pt(e);try{let r=await k(e);if(r[w]){let n=new Set(R),i=!1;for(let a of Object.keys(r[w]))n.has(a)||(delete r[w][a],i=!0);i&&await P(e,r)}}catch{}let s=Ke(e,".vesperrc");try{if(t.claude){let{writeFile:r}=await import("node:fs/promises");await r(s,JSON.stringify({paths:[],addedAt:null,workspaceType:null,settingsPath:null,claude:t.claude},null,2),"utf-8")}else await br(s,{force:!0})}catch{}}async function ts(e={}){try{let t=Ke(e.path||process.cwd());await g(t)||(o.error(`Directory not found: ${o.formatPath(t)}`),process.exit(1));let s=e.target;if(!s){let c=await D(t);if(c.length===0){o.warn("Vesper is not initialized in this workspace.");return}c.length>1&&(o.error("Both Copilot and Claude targets are installed here \u2014 specify which to reset: --target copilot|claude"),process.exit(1)),s=c[0]}if(s==="claude")return await Tr({...e,path:t});if(!await ve(t)){o.warn("Vesper is not initialized in this workspace.");return}let r=await ne(t);if(r.length===0){o.info("Nothing to reset.");return}let n=$r(r);if(!e.yes&&!await es({message:`Remove all Vesper assets (${n.join(", ")})?`,default:!1})){o.info("Reset cancelled.");return}let i=await m(t),a=await _(t);await He(t),i.claude&&o.info("Claude Code target detected \u2014 kept its record in .vesperrc"),console.log(),o.success("Vesper reset complete."),i.workspaceType===E.WORKSPACE_FILE||a.type===E.WORKSPACE_FILE?o.info(`Cleaned: ${Er(a.settingsPath)}`):o.info("Cleaned: .vscode/settings.json"),o.info("Reload VS Code to apply changes")}catch(t){if(t.name==="ExitPromptError"){console.log(),o.info("Reset cancelled.");return}o.error(`Reset failed: ${t.message}`),process.exit(1)}}F();import{execFile as Or}from"node:child_process";import{promisify as Ir}from"node:util";import{randomUUID as Mr}from"node:crypto";import{mkdir as Ie,readdir as Dr,rename as Je,rm as K,stat as Lr}from"node:fs/promises";import{join as te}from"node:path";var jr=Ir(Or),ss=[{url:"https://gitlab.com/gitlab-org/ci-cd/gitlab-ci-skill.git",name:"gitlab-ci-skill"},{url:"https://gitlab.com/gitlab-org/ci-cd/github-actions-to-gitlab-ci.git",name:"github-actions-to-gitlab-ci"}],Fr=new Set(ss.map(e=>e.name)),Rr=5*60*1e3;function ze(e){process.env.VESPER_DEBUG&&o.dim(`[skill-sync] ${e}`)}async function Vr(e,t){if(!Fr.has(t))return o.warn(`skill-sync refused: "${t}" is not in the allow-list`),{synced:!1,skill:t};let s=te(U(),"skills"),r=te(s,t),n=`${r}.bak`,i=te(s,`.tmp-${t}-${Mr().slice(0,8)}`);try{return await Ie(s,{recursive:!0}),await K(i,{recursive:!0,force:!0}),await K(n,{recursive:!0,force:!0}),await jr("git",["clone","--depth","1","--quiet",e,i],{timeout:2e4,env:{...process.env,GIT_HTTP_LOW_SPEED_LIMIT:"1000",GIT_HTTP_LOW_SPEED_TIME:"15"}}),await K(te(i,".git"),{recursive:!0,force:!0}),await g(r)&&await Je(r,n),await Je(i,r),await K(n,{recursive:!0,force:!0}),{synced:!0,skill:t}}catch(a){return ze(`sync of ${t} failed: ${a&&a.message?a.message:a}`),await K(i,{recursive:!0,force:!0}).catch(()=>{}),!await g(r)&&await g(n)&&await Je(n,r).catch(()=>{}),{synced:!1,skill:t}}}async function Nr(e){try{return await Ie(e),!0}catch(t){if(t.code!=="EEXIST")return ze(`could not acquire lock: ${t.message}`),!1;try{let s=await Lr(e);if(Date.now()-s.mtimeMs>Rr)return await K(e,{recursive:!0,force:!0}),await Ie(e),!0}catch{}return!1}}async function Me(){let e=te(U(),"skills"),t=te(e,".sync.lock");try{await Ie(e,{recursive:!0})}catch{return[]}if(!await Nr(t))return ze("skipped: another process holds the sync lock"),[];try{await Gr(e);let r=[];for(let{url:n,name:i}of ss)r.push(await Vr(n,i));return r}finally{await K(t,{recursive:!0,force:!0}).catch(()=>{})}}async function Gr(e){let t;try{t=await Dr(e,{withFileTypes:!0})}catch{return}for(let s of t)s.isDirectory()&&s.name.startsWith(".tmp-")&&await K(te(e,s.name),{recursive:!0,force:!0}).catch(()=>{})}var rs=["copilot","claude"];function ns(e){return e==="claude"?"Claude Code":"GitHub Copilot"}async function zr(e){let t=await m(e),s=[];return Array.isArray(t.paths)&&t.paths.length>0&&s.push("copilot"),t.claude&&s.push("claude"),s}async function Yr(e,t){let s=await zr(t);if(e.target){let n=String(e.target).toLowerCase(),i=n==="all"?[...rs]:n.split(",").map(a=>a.trim()).filter(Boolean);for(let a of i)rs.includes(a)||(o.error(`Unknown target: ${a}. Valid targets: copilot, claude, all`),process.exit(1));return{selected:[...new Set(i)],installed:s}}return process.stdin.isTTY||(o.error("Non-interactive run without --target. Specify the platform(s), e.g. --target copilot,claude (or --target all)."),process.exit(1)),{selected:await Jr({message:s.length?"Platforms to set up (checked = installed; uncheck to remove):":"Which AI platform(s) is this workspace for?",choices:[{name:"GitHub Copilot (VS Code)",value:"copilot",checked:s.includes("copilot")},{name:"Claude Code (CLI / VS Code extension / JetBrains / desktop)",value:"claude",checked:s.includes("claude")}]}),installed:s}}async function Xr(e){return e?"":await Hr({message:"Name Vesper's Claude Code subagents/skills/commands:",choices:[{name:"Plain names (recommended \u2014 matches the Copilot catalog 1:1)",value:""},{name:'Prefix with "vesper-" (avoids collisions with other Claude Code kits)',value:"vesper-"}],default:""})}async function Qr(e,t={}){let s=t.yes||t.forceDefault,r=await Xr(s);console.log(),o.header("Installing Vesper for Claude Code"),console.log();let{pluginDir:n,counts:i}=await be({namePrefix:r,version:t.version||"0.0.0"});o.success(`Specialist catalog installed: ${n}`),o.info(` agents: ${i.agents}, commands: ${i.commands}, skills: ${i.skills}`);let a=await Me(),c=a.filter(p=>p.synced).map(p=>p.skill),d=a.filter(p=>!p.synced).map(p=>p.skill);c.length&&o.success(`GitLab skills synced: ${c.join(", ")}`),d.length&&o.warn(`GitLab skills not synced (continuing): ${d.join(", ")}`);let l=await Te(e);o.success("Project files ready:"),o.info(` .claude/vesper/orchestrator.md (${l.orchestrator})`),o.info(` .claude/vesper/orchestration.md (${l.orchestration})`),o.info(` .claude/vesper/context.md (${l.context})`),o.info(` CLAUDE.md (${l.claudeMd})`);let u=await ee(e,!0);await $e(e),o.success(`MCP servers configured: .mcp.json (${u.servers.join(", ")})`),await Zt(e,{pluginPath:U(),namePrefix:r,mcpConfigPath:Z(e),settingsPath:Ee(e),installedAt:new Date().toISOString()})}async function Zr(e,t,s){console.log(),o.header("Configuring GitHub Copilot"),console.log();let r=await Dt(e);await bt(e,{maxRequests:s.maxRequests,omitBaseAgentInstructions:s.omitBaseAgentInstructions});let n=await Et(e,s.terminalEnableAutoApprove),i=!1;return s.enableMcpServer&&(i=(await X(e,!0)).configured,await Lt(e)),await kt(e),o.success("Core assets ensured: agents, prompts, instructions, skills"),o.info(`Max agent requests: ${s.maxRequests}`),n.configured>0?o.info(`Terminal auto-approval: ${n.configured} safe commands configured`):s.terminalEnableAutoApprove===!1&&o.info("Terminal auto-approval: disabled"),i&&(o.info("MCP servers: vesper-indexing, sequential-thinking, memory (.vscode/mcp.json)"),o.info("MCP tools auto-approval: vesper-indexing + context7 + sequential-thinking + memory")),r.workspaceType===E.WORKSPACE_FILE?o.info(`Settings added to: ${Wr(t.settingsPath)}`):o.info("Settings added to: .vscode/settings.json"),o.info("Tracking file: .vesperrc"),o.info("Worktree bootstrap task: .vscode/tasks.json (runs on folder open)"),{mcpConfigured:i}}async function en(e,t){let s=await xt(e);if(!s.found)return{migrated:!1,from:null};let{paths:r}=s;console.log(),o.warn(`Found .vesperrc in nested folder${r.length>1?"s":""}:`);for(let{folderPath:a}of r)o.info(` \u2192 ${a}`);console.log();let n=r[0],i=!0;if(t||(i=await ie({message:"Migrate .vesperrc to workspace level? (recommended for multi-root workspaces)",default:!0})),i){let a=await Ct(e,n.vesperrcPath,n.tracking);if(a.success){if(o.success("Migrated .vesperrc to workspace level"),o.info(` From: ${n.vesperrcPath}`),o.info(` To: ${a.newPath}`),r.length>1){let{unlink:c}=await import("node:fs/promises");for(let d=1;d<r.length;d++)try{await c(r[d].vesperrcPath),o.info(` Removed: ${r[d].vesperrcPath}`)}catch{}}return console.log(),{migrated:!0,from:n.folderPath}}}else o.info("Migration skipped. .vesperrc will remain in nested folder."),console.log();return{migrated:!1,from:null}}async function tn(e){let{migrated:t,changed:s}=await Mt(e);if(!t)return;let r=(i,a)=>`${i} ${a}${i>1?"s":""}`,n=[];s.assetPaths&&n.push(r(s.assetPaths,"asset path")),s.readAccess&&n.push(r(s.readAccess,"read-access path")),s.commandKeys&&n.push(r(s.commandKeys,"stale command")),s.trackingPaths&&n.push(r(s.trackingPaths,"tracked path")),s.mcpArgs&&n.push("MCP server path"),console.log(),o.info("Detected a workspace set up under the older `vesper-cli` package \u2014 migrating install paths."),o.success(`Migrated: ${n.join(", ")}`),console.log()}async function sn(e,t){let s=e;return t||(s=await qr({message:"Workspace root directory:",default:s})),Ur(s)}async function rn(e,t,s){let r=[];for(let n of t){let i=ns(n),a=s;if(s||(a=await ie({message:`${i} is installed but was unchecked. Remove it from this project?`,default:!1})),!a){o.info(`Kept ${i}.`);continue}n==="claude"?await Oe(e):await He(e),r.push(n),o.success(`Removed ${i} from this project.`)}return r}async function nn(e){if(e)return{maxRequests:M.maxRequests,terminalEnableAutoApprove:M.terminalEnableAutoApprove,omitBaseAgentInstructions:M.omitBaseAgentInstructions,enableMcpServer:M.enableMcpServer};console.log(),o.info("Configure VS Code Chat settings:");let t=await Kr({message:"Max agent requests per session (chat.agent.maxRequests):",default:M.maxRequests,min:1,max:1e3}),s=await ie({message:"Controls whether terminal commands are automatically approved. Enable terminal auto-approval? (chat.tools.terminal.enableAutoApprove)",default:M.terminalEnableAutoApprove});s&&o.info("Terminal auto-approval enabled with safe command whitelist");let r=await ie({message:"Omit base agent instructions for custom agents? (github.copilot.chat.omitBaseAgentInstructions)",default:M.omitBaseAgentInstructions}),n=await ie({message:"Enable vesper-indexing MCP server for fast code search?",default:M.enableMcpServer});return{maxRequests:t||M.maxRequests,terminalEnableAutoApprove:s,omitBaseAgentInstructions:r,enableMcpServer:n}}async function Ye(e,t=!1){let s=B().replace("index.js","cli-index.js");if(!await g(s))return{success:!1,error:"MCP server not built"};t&&(console.log(),o.info("Starting workspace indexing..."));let r=t?null:o.createSpinner("Indexing workspace...");return r&&r.start(),new Promise(n=>{let i=Br("node",[s,e],{stdio:["ignore","pipe","pipe"],env:{...process.env}}),a="",c=0;i.stderr.on("data",d=>{let l=d.toString().trim(),u=l.match(/Indexed (\d+) files/);if(u&&(c=parseInt(u[1],10),r&&r.update(`Indexing workspace... ${c} files`)),t&&l)for(let p of l.split(`
26
+ `))p.trim()&&o.info(p.replace("[vesper-indexing] ",""))}),i.stdout.on("data",d=>{a+=d.toString()}),i.on("close",d=>{try{let l=JSON.parse(a.trim());l.success?r?r.succeed(`Workspace indexed: ${l.filesIndexed} files`):o.success(`Workspace indexed: ${l.filesIndexed} files`):r?r.fail(`Indexing failed: ${l.error}`):o.error(`Indexing failed: ${l.error}`),n(l)}catch{d===0?(r?r.succeed(`Workspace indexed: ${c} files`):o.success(`Workspace indexed: ${c} files`),n({success:!0,filesIndexed:c})):(r?r.fail("Indexing failed"):o.error("Indexing failed"),n({success:!1,error:"Unknown error"}))}}),i.on("error",d=>{r?r.fail(`Indexing failed: ${d.message}`):o.error(`Indexing failed: ${d.message}`),n({success:!1,error:d.message})})})}function on({copilot:e,claude:t,indexingResult:s}){console.log(),o.success("Vesper is ready."),s?.success?o.info(`Code index built: ${s.filesIndexed} files.`):s?.error&&o.info("Code index will be built on first MCP server start."),console.log(),o.header("Next Steps"),console.log(),e&&(o.info("GitHub Copilot \u2014 reload VS Code to activate Vesper:"),o.info(' Cmd+Shift+P (macOS) / Ctrl+Shift+P (Windows/Linux) \u2192 "Developer: Reload Window"')),t&&(o.info("Claude Code \u2014 open a session in this workspace; the orchestrator"),o.info(" activates automatically via CLAUDE.md.")),console.log(),e&&o.vesperTip()}async function os(e={}){try{let t=e.yes||e.forceDefault,s=await sn(e.path||process.cwd(),t);await g(s)||(o.error(`Directory not found: ${o.formatPath(s)}`),process.exit(1));let r=await _(s);r.type===E.WORKSPACE_FILE&&await en(s,t),await tn(s);let{selected:n,installed:i}=await Yr(e,s),a=i.filter(f=>!n.includes(f));if(n.length===0&&a.length===0){o.info("No platforms selected. Nothing to do.");return}if(!t&&i.length===0&&n.length>0&&!await ie({message:`Set up ${n.map(ns).join(" + ")} in ${s}?`,default:!0})){o.info("Initialization cancelled.");return}a.length>0&&await rn(s,a,t);let c=n.includes("copilot"),d=n.includes("claude"),l=null;if(c&&(l=await nn(t)),c&&await Zr(s,r,l),d&&await Qr(s,e),c||d){await he(s);let f=await we(s);f.length>0&&(o.warn(`Local-only file(s) are git-tracked despite .gitignore: ${f.join(", ")}`),o.warn(`Untrack them yourself (Vesper won't touch your git index): git rm --cached ${f.join(" ")}`)),(await ye(s))["pre-commit"]?.hooksDir&&(o.success("Local-only Vesper files gitignored (.vesperrc, .mcp.json, .vesper/index.db)"),o.info("Commit-hygiene git hook installed (pre-commit): keeps team roster/context/history/memory in sync with every commit"),await _e(s),await Se(s),o.info("Merge strategy configured (.gitattributes): history.md unions, memory.jsonl merges entity-aware across worktrees"))}let u=c&&l?.enableMcpServer||d,p=null;u&&(p=await Ye(s,!0)),on({copilot:c,claude:d,indexingResult:p})}catch(t){if(t.name==="ExitPromptError"){console.log(),o.info("Initialization cancelled.");return}o.error(`Initialization failed: ${t.message}`),process.exit(1)}}F();import{resolve as as,basename as an}from"node:path";import{checkbox as cs,select as cn}from"@inquirer/prompts";var is={agents:"agents",prompts:"commands",skills:"skills"};async function ln(e,t){let s=await D(e);if(s.length===1)return s[0];s.length===0&&(o.warn('Vesper is not initialized in this workspace. Run "vespercli init" first.'),process.exit(0)),o.error(`Both Copilot and Claude targets are installed here \u2014 specify which to ${t}: --target copilot|claude`),process.exit(1)}async function dn(e={}){let t=as(e.path||process.cwd());(!e.type||!e.name)&&(o.error("Usage: vesper add <type> <name> --target claude"),o.info("Types: agents, prompts (installed as slash commands), skills"),process.exit(1));let s=is[e.type];s||(o.error(`Unknown asset type for --target claude: ${e.type}`),o.info(`Available types: ${Object.keys(is).join(", ")}`),process.exit(1));let n=(await m(t)).claude?.namePrefix??"";try{let i=await qt(s,e.name,{namePrefix:n});o.success(`Added ${e.type}/${e.name} to the Claude plugin catalog as "${i.installedAs}"`)}catch(i){o.error(i.message),process.exit(1)}}var ge=["agents","prompts","instructions"];async function Xe(e,t){let s=await ne(e);return(await re(t)).filter(n=>{let i=Y(t,n);return!s.includes(i.path)})}async function un(e){let t=[];for(let a of ge){let c=await Xe(e,a);c.length>0&&t.push({name:`${a.charAt(0).toUpperCase()+a.slice(1)} (${c.length} available)`,value:a})}if(t.length===0)return o.info("All extended assets are already added."),[];let s=await cn({message:"Select asset type:",choices:t}),n=(await Xe(e,s)).map(a=>({name:a,value:a,checked:!1}));return(await cs({message:`Select ${s} to add:`,choices:n})).map(a=>({type:s,name:a}))}async function ls(e={}){try{let t=as(e.path||process.cwd());if(await g(t)||(o.error(`Directory not found: ${o.formatPath(t)}`),process.exit(1)),(e.target||await ln(t,"add"))==="claude")return await dn({...e,path:t});if(!await ve(t)){o.warn('Vesper is not initialized. Run "vespercli init" first.');return}let r=[];if(e.type&&e.name){if(e.type==="skills"){o.info("Skills are automatically added during init.");return}ge.includes(e.type)||(o.error(`Unknown asset type: ${e.type}`),o.info(`Available types: ${ge.join(", ")}`),process.exit(1));let l=await re(e.type);l.includes(e.name)||(o.error(`Asset not found: ${e.name}`),o.info(`Available ${e.type}: ${l.join(", ")||"none"}`),process.exit(1)),r=[{type:e.type,name:e.name}]}else if(e.type){if(e.type==="skills"){o.info("Skills are automatically added during init.");return}ge.includes(e.type)||(o.error(`Unknown asset type: ${e.type}`),o.info(`Available types: ${ge.join(", ")}`),process.exit(1));let l=await Xe(t,e.type);if(l.length===0){o.info(`All ${e.type} are already added.`);return}let u=l.map(f=>({name:f,value:f,checked:!1})),p=await cs({message:`Select ${e.type} to add:`,choices:u});if(p.length===0){o.info("Nothing selected.");return}r=p.map(f=>({type:e.type,name:f}))}else if(r=await un(t),r.length===0){o.info("Nothing selected.");return}let n=r.map(({type:l,name:u})=>Y(l,u)),{added:i,skipped:a,workspaceType:c}=await At(t,n),d=r.filter(l=>l.type==="agents"&&i.includes(Y(l.type,l.name).path));for(let{name:l}of d)Ve[l]&&(await jt(t,l),o.info(` Added MCP tools auto-approval for agent: ${l}`));if(i.length>0){let l=await _(t);console.log(),o.success(`Added ${i.length} asset(s):`);for(let{type:u,name:p}of r.filter(f=>i.includes(Y(f.type,f.name).path)))o.info(` ${u}/${p}`);c===E.WORKSPACE_FILE&&o.info(`
27
+ Updated: ${an(l.settingsPath)}`),o.info(`
28
+ Reload VS Code to apply changes`)}else a.length>0&&o.info("All selected assets are already added.")}catch(t){if(t.name==="ExitPromptError"){console.log(),o.info("Cancelled.");return}o.error(`Add failed: ${t.message}`),process.exit(1)}}F();import{resolve as us,join as pn}from"node:path";import{readdir as fn}from"node:fs/promises";import W from"picocolors";async function ds(e={}){let t=us(e.path||process.cwd()),s=await m(t);if(console.log(),console.log(W.bold("Claude Code target")),!s.claude){console.log(),o.warn('Not initialized for Claude Code. Run "vesper init --target claude" first.'),console.log();return}let r=s.claude.pluginPath||U();console.log(W.dim(`Plugin catalog: ${r}`));let n=await Kt();for(let[i,a]of Object.entries(n))console.log(),console.log(W.bold(i.charAt(0).toUpperCase()+i.slice(1))),a.length===0?console.log(W.dim(" (none installed)")):a.forEach(c=>console.log(` ${c}`));console.log(),console.log(W.bold("Project files")),console.log(" CLAUDE.md, .claude/vesper/{orchestrator,orchestration,context}.md, .mcp.json, .claude/settings.json"),console.log()}async function gn(e,t,s=!1){try{let r=await fn(e,{withFileTypes:!0});return s||t.dir==="skills"?r.filter(i=>i.isDirectory()&&!i.name.startsWith(".")).map(i=>i.name):r.filter(i=>i.isFile()&&i.name.endsWith(t.extension)).map(i=>i.name.replace(t.extension,""))}catch{return[]}}async function ps(e={}){try{let t=us(e.path||process.cwd());await g(t)||(o.error(`Directory not found: ${o.formatPath(t)}`),process.exit(1));let s=await D(t);if(e.target==="claude")return await ds({...e,path:t});if(!e.target){if(s.length===0){console.log(),o.warn('Vesper is not initialized. Run "vespercli init" first.'),console.log();return}if(s.length===1&&s[0]==="claude")return await ds({...e,path:t});s.includes("claude")&&o.info("Claude Code target is also installed here \u2014 run `vespercli list --target claude` to see it.")}let r=await ne(t);e.type&&!I[e.type]&&(o.error(`Unknown asset type: ${e.type}`),o.info(`Valid types: ${Object.keys(I).join(", ")}`),process.exit(1));let n=e.type?[e.type]:Object.keys(I);console.log(),console.log(W.bold("Assets"));for(let i of n){let a=I[i],c=i.charAt(0).toUpperCase()+i.slice(1);if(i==="skills"){let f=It("skills");if(r.includes(f.path)){let h=await re("skills");console.log(),console.log(W.bold(`${c}`)),console.log(` ${h.length} skills enabled ${W.dim("(all)")}`)}continue}let d=pn(st,a.dir),l=await gn(d,a,!1),p=(await re(i)).filter(f=>{let h=Y(i,f);return r.includes(h.path)});(l.length>0||p.length>0)&&(console.log(),console.log(W.bold(`${c}`)),l.forEach(f=>{console.log(` ${f} ${W.dim("(core)")}`)}),p.forEach(f=>{console.log(` ${f}`)}))}console.log()}catch(t){o.error(`List failed: ${t.message}`),process.exit(1)}}import{readFileSync as mn,existsSync as hn}from"node:fs";import{join as wn}from"node:path";var fs="catalog.md",vn="mthanhtran",yn="vesper",_n="main";function Sn(){return`https://raw.githubusercontent.com/${vn}/${yn}/${_n}/assets/${fs}`}function kn(){let e=wn(se,"assets",fs);return hn(e)?mn(e,"utf-8"):null}async function xn(){try{let e=Sn(),t=await fetch(e);return t.ok?t.text():null}catch{return null}}async function Cn(){let e=await xn();if(e)return e;let t=kn();if(t)return t;throw new Error("Catalog not available from remote or local")}async function gs(){try{let e=await Cn();console.log(e)}catch(e){console.error(`Error loading catalog: ${e.message}`),process.exit(1)}}F();import{resolve as An,join as _s}from"node:path";import{stat as Pn,readFile as Ss}from"node:fs/promises";import"@inquirer/prompts";import j from"picocolors";async function De(e){let t=await m(e);if(console.log(),o.header("vesper-indexing MCP Server (Claude Code target)"),console.log(),!t.claude){o.info("Claude Code target is not initialized. Run `vesper init --target claude` first.");return}let s=Z(e),r=!1;if(await g(s))try{r=!!JSON.parse(await Ss(s,"utf-8")).mcpServers?.["vesper-indexing"]}catch{r=!1}o.info(`Configured: ${r?"\u2713 yes":"\u2717 no"} (${s})`),o.info(`Server built: ${await xs()?"\u2713 yes":"\u2717 no"}`);let n=Qe(e);o.info(`Index exists: ${await g(n)?"\u2713 yes":"\u2717 no"} (shared with the Copilot target if both are installed)`);try{let{drifted:i}=await Yt(e);i.length&&(console.log(),o.warn(`MCP config drift: ${i.join(", ")} present in the live MCP config but not tracked in .vesperrc mcp.servers.`),o.warn("Run `/reinit` (or re-run workspace-learner) to resync tracking and the generated docs."))}catch{}}async function ae(e,t=!0){await ee(e,t),t&&await $e(e),o.success(`Claude Code target: vesper-indexing ${t?"enabled":"disabled"} in .mcp.json`)}function Qe(e){return _s(e,".vesper","index.db")}function En(e){return _s(e,".vesper","indexing-status.json")}async function ks(e){let t=En(e);try{let s=await Ss(t,"utf-8");return JSON.parse(s)}catch{return null}}async function xs(){let e=B();return await g(e)}async function bn(e){try{let t=await Pn(e),s=t.size,r=`${s} bytes`;return s>1024*1024?r=`${(s/(1024*1024)).toFixed(2)} MB`:s>1024&&(r=`${(s/1024).toFixed(1)} KB`),{dbSize:r,lastModified:t.mtime.toISOString()}}catch{return null}}async function ms(e,t=!1){let s=await Ce(e),r=await xs(),n=Qe(e),i=await g(n),a=await ks(e);if(console.log(),o.header("vesper-indexing MCP Server"),console.log(),o.info(`Configured: ${s?"\u2713 yes":"\u2717 no"}`),o.info(`Server built: ${r?"\u2713 yes":"\u2717 no"}`),o.info(`Index exists: ${i?"\u2713 yes":"\u2717 no"}`),a)if(console.log(),a.status==="indexing")if(t){await Tn(e,a);return}else{let c=a.startedAt?Math.round((Date.now()-new Date(a.startedAt).getTime())/1e3):0;o.info(j.yellow("\u27F3 Indexing in progress...")),o.info(` Files processed: ${j.cyan(a.filesProcessed)}`),o.info(` Elapsed: ${j.dim(`${c}s`)}`),console.log(),o.info("Use --watch to follow indexing progress until completion")}else a.status==="error"&&(o.error(`Indexing error: ${a.error}`),o.info(` Files processed before error: ${a.filesProcessed}`));if(!s){console.log(),o.info("Run `vespercli init` to configure the MCP server");return}if(!r){console.log(),o.warn("MCP server not built. Run: cd src/mcp/vesper-indexing && npm install && npm run build");return}if(i&&!a){let c=await bn(n);c&&(console.log(),o.info(`Index size: ${c.dbSize}`),o.info(`Last modified: ${c.lastModified}`)),o.vesperTip()}else!i&&!a&&(console.log(),o.info("Index not yet created. It will be built when VS Code loads the MCP server."),console.log())}async function Tn(e,t){let s=o.createSpinner(`Indexing... ${t.filesProcessed} files processed`);s.start();let r=500,n=30*60*1e3,i=Date.now();return new Promise(a=>{let c=async()=>{let d=await ks(e);if(!d||d.status!=="indexing"){d?.status==="error"?s.fail(`Indexing failed: ${d.error}`):(s.succeed(`Indexing complete! ${d?.filesProcessed||"All"} files indexed`),o.info(`
29
+ \u2192 Reload VS Code to update MCP tools with the new index`),o.vesperTip()),a();return}let l=d.startedAt?Math.round((Date.now()-new Date(d.startedAt).getTime())/1e3):0;if(s.update(`Indexing... ${d.filesProcessed} files processed (${l}s)`),Date.now()-i>n){s.fail("Indexing watch timed out (30 minutes)"),a();return}setTimeout(c,r)};setTimeout(c,r)})}async function hs(e,t=!1){let s=Qe(e);if(!await g(s))o.info("No index exists. It will be built when VS Code loads the MCP server.");else if(t){let{unlink:n}=await import("node:fs/promises");await n(s),o.success("Index cleared. Reload VS Code to rebuild.")}else o.info("Incremental reindex happens automatically when files change."),o.info("Use --full to clear and rebuild the entire index.")}async function $n(e){let t=await X(e,!0);t.configured&&(o.success("MCP server enabled"),o.info(`Config: ${t.mcpPath}`),o.info("Reload VS Code to start the server"))}async function On(e){await X(e,!1),o.success("MCP server disabled"),o.info("Reload VS Code to apply changes")}async function Cs(e){let t=await _(e),s=await m(e,t);if(!Array.isArray(s.paths))return[];let r=[];for(let n of s.paths){let i=n.match(/agents\/([^/]+)\/?$/);i&&MCP_TOOLS_BY_AGENT[i[1]]&&r.push(i[1])}return r}async function In(e){let t=await _(e),s=await m(e,t),r=await k(e,t),n=await Cs(e),i=r[w]||{},a=new Set(R),c=[],d=[],l=!1;r[w]||(r[w]={});for(let p of R)i[p]||(r[w][p]=!0,c.push(p),l=!0);for(let p of n){let f=MCP_TOOLS_BY_AGENT[p]||[];for(let h of f)i[h]||(r[w][h]=!0,c.push(h),l=!0)}let u=new Set;for(let p of n)for(let f of MCP_TOOLS_BY_AGENT[p]||[])u.add(f);for(let p of Object.keys(i)){if(a.has(p))continue;let f=!1;for(let[h,O]of Object.entries(MCP_TOOLS_BY_AGENT))if(O.includes(p)){f=!0;break}f&&!u.has(p)&&(delete r[w][p],d.push(p),l=!0)}if(s.mcp=s.mcp||{},s.mcp.syncedAt=new Date().toISOString(),s.mcp.approvedAgents=n,s.mcp.toolCount=Object.keys(r[w]).length,l&&await P(e,r),await C(e,s),console.log(),o.header("MCP Tools Sync"),console.log(),c.length===0&&d.length===0)o.success("Already in sync");else{if(c.length>0){o.success(`Added ${c.length} tool(s)`);let p=c.filter(f=>a.has(f));p.length>0&&o.info(` Core: ${p.length} tools`);for(let f of n){let h=c.filter(O=>(MCP_TOOLS_BY_AGENT[f]||[]).includes(O));h.length>0&&o.info(` ${f}: ${h.length} tools`)}}d.length>0&&o.info(`Removed ${d.length} orphaned tool(s)`)}o.info(`
30
+ Total approved tools: ${s.mcp.toolCount}`),n.length>0&&o.info(`Agents with tools: ${n.join(", ")}`),l&&o.info(`
31
+ Reload VS Code to apply changes`)}async function Mn(e){let t=await _(e),s=await m(e,t),n=(await k(e,t))[w]||{},i=Object.keys(n).length,a=await Cs(e);console.log(),o.header("MCP Tool Approval Status"),console.log();let c=R.filter(u=>n[u]);if(o.info(`Core tools: ${c.length}/${R.length} approved`),a.length>0){console.log(),o.info("Agent tools:");for(let u of a){let p=MCP_TOOLS_BY_AGENT[u]||[],f=p.filter(O=>n[O]),h=f.length===p.length?j.green("\u2713"):j.yellow("\u26A0");o.info(` ${h} ${u}: ${f.length}/${p.length} approved`)}}let d=[...R];for(let u of a)d.push(...MCP_TOOLS_BY_AGENT[u]||[]);let l=d.filter(u=>!n[u]);console.log(),o.info(`Total approved: ${i} tools`),l.length>0?(console.log(),o.warn(`${l.length} tools missing approval`),o.info("Run `vespercli mcp sync` to fix")):s.mcp?.syncedAt&&o.info(`Last synced: ${s.mcp.syncedAt}`)}function As(){return Object.keys(V).filter(e=>!z.includes(e))}async function Dn(e,t){t||(o.error("Server name required. Usage: vespercli mcp add <server>"),o.info(`Available servers: ${As().join(", ")}`),process.exit(1)),console.log(),o.header("Add MCP Server"),console.log();let s=await Ft(e,t);if(!s.added){s.error==="Already configured"?o.info(`MCP server '${t}' is already configured`):(o.error(s.error),process.exit(1));return}o.success(`Added MCP server: ${t}`),s.tools.length>0&&o.info(`Approved ${s.tools.length} tool(s) for auto-execution`),o.info(`
32
+ Reload VS Code to activate the MCP server`)}async function Ln(e,t){t||(o.error("Server name required. Usage: vespercli mcp remove <server>"),process.exit(1)),console.log(),o.header("Remove MCP Server"),console.log();let s=await Rt(e,t);if(!s.removed){o.info(`MCP server '${t}' is not configured`);return}o.success(`Removed MCP server: ${t}`),s.tools.length>0&&o.info(`Removed ${s.tools.length} tool(s) from auto-approval`),o.info(`
33
+ Reload VS Code to deactivate the MCP server`)}async function jn(e){let t=await _(e),s=await m(e,t),r=await N(e);console.log(),o.header("MCP Servers"),console.log();let n=s.mcp?.servers||[],i=Object.keys(r.servers||{});o.info("Available servers:");for(let[c,d]of Object.entries(V)){let u=i.includes(c)?j.green("\u2713"):j.dim("\u25CB"),p=d.tools?.length||0;o.info(` ${u} ${c} (${p} tools)`)}let a=i.filter(c=>!V[c]);if(a.length>0){console.log(),o.info("Custom servers:");for(let c of a)o.info(` ${j.blue("\u25C6")} ${c}`)}console.log(),o.info(`Installed: ${i.length} server(s)`)}async function ws(e,t){t||(o.error("Server name required. Usage: vespercli mcp add <server> --target claude"),o.info(`Available servers: ${As().join(", ")}`),process.exit(1));let s=await Ht(e,t);if(!s.added){s.error==="Already configured"?o.info(`MCP server '${t}' is already configured for the Claude Code target`):o.error(s.error);return}o.success(`Added MCP server: ${t} (Claude Code target)`),o.info(`
34
+ Reload the Claude Code session to activate the MCP server`)}async function vs(e,t){t||(o.error("Server name required. Usage: vespercli mcp remove <server> --target claude"),process.exit(1));let s=await Jt(e,t);if(s.error){o.error(s.error);return}if(!s.removed){o.info(`MCP server '${t}' is not configured for the Claude Code target`);return}o.success(`Removed MCP server: ${t} (Claude Code target)`),o.info(`
35
+ Reload the Claude Code session to deactivate the MCP server`)}async function ys(e){let{configured:t,custom:s}=await zt(e);console.log(),o.header("MCP Servers (Claude Code target)"),console.log(),o.info("Available servers:");for(let[r,n]of Object.entries(V)){let a=t.includes(r)?j.green("\u2713"):j.dim("\u25CB"),c=n.tools?.length||0;o.info(` ${a} ${r} (${c} tools)`)}if(s.length>0){console.log(),o.info("Custom servers:");for(let r of s)o.info(` ${j.blue("\u25C6")} ${r}`)}console.log(),o.info(`Installed: ${t.length} server(s)`)}async function Ps(e,t,s={}){let r=An(s.path||process.cwd());await g(r)||(o.error(`Directory not found: ${r}`),process.exit(1));let n=await D(r),i=s.target?[s.target]:n.length?n:["copilot"],a=i.includes("copilot"),c=i.includes("claude");if(c&&!a)switch(e){case"enable":return await ae(r,!0);case"disable":return await ae(r,!1);case"sync":return await ae(r,!0);case"add":return await ws(r,t);case"remove":return await vs(r,t);case"list":return await ys(r);case"status":return await De(r);case"reindex":return await hs(r,s.full);default:return e&&o.warn(`'${e}' is not applicable to the Claude Code target \u2014 showing status instead.`),await De(r)}let d=a&&c;switch(e){case"status":await ms(r,s.watch),d&&await De(r);break;case"add":await Dn(r,t),d&&await ws(r,t);break;case"remove":await Ln(r,t),d&&await vs(r,t);break;case"list":await jn(r),d&&await ys(r);break;case"reindex":await hs(r,s.full);break;case"enable":await $n(r),d&&await ae(r,!0);break;case"disable":await On(r),d&&await ae(r,!1);break;case"sync":await In(r),d&&await ae(r,!0);break;case"approve":await Mn(r);break;default:await ms(r,s.watch),d&&await De(r)}}import{resolve as Fn}from"node:path";async function bs(e,t,s,r={}){let n=Fn(r.path||process.cwd());if(!e){Es();return}switch(e){case"add":await Rn(n,t,s);break;case"remove":await Vn(n,t,s);break;case"list":await Nn(n,t);break;default:o.error(`Unknown subcommand: ${e}`),Es()}}async function Rn(e,t,s){if(!t){o.error("Setting key required"),o.info("Usage: vespercli settings add <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!s){o.error("Path value required"),o.info("Usage: vespercli settings add read-access <path>");return}let r=await Tt(e,s);o.success(`Added "${s}" to additional read access paths`),o.info(`Current paths: ${r.length>0?r.join(", "):"(none)"}`);break;default:o.error(`Unknown setting: ${t}`),o.info("Supported settings:"),o.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function Vn(e,t,s){if(!t){o.error("Setting key required"),o.info("Usage: vespercli settings remove <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!s){o.error("Path value required"),o.info("Usage: vespercli settings remove read-access <path>");return}let r=await $t(e,s);o.success(`Removed "${s}" from additional read access paths`),o.info(`Current paths: ${r.length>0?r.join(", "):"(none)"}`);break;default:o.error(`Unknown setting: ${t}`),o.info("Supported settings:"),o.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function Nn(e,t){if(!t){o.info("Managed settings:"),o.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)"),o.info(""),o.info("Use: vespercli settings list <setting-key>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":let s=await Ot(e);o.info(`${S}:`),s.length===0?o.info(" (empty)"):s.forEach(r=>o.info(` - ${r}`));break;default:o.error(`Unknown setting: ${t}`),o.info("Supported settings:"),o.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}function Es(){o.info("Usage: vespercli settings <subcommand> [setting-key] [value]"),o.info(""),o.info("Subcommands:"),o.info(" add <setting-key> <value> Add a value to an array setting"),o.info(" remove <setting-key> <value> Remove a value from an array setting"),o.info(" list [setting-key] List current values"),o.info(""),o.info("Supported settings:"),o.info(" read-access github.copilot.chat.additionalReadAccessPaths"),o.info(""),o.info("Examples:"),o.info(" vespercli settings add read-access /path/to/external/repo"),o.info(" vespercli settings remove read-access /path/to/external/repo"),o.info(" vespercli settings list read-access")}F();import{resolve as Ts}from"node:path";async function Gn(e={}){let t=Ts(e.path||process.cwd()),s=await m(t);if(!s.claude){o.warn('Claude Code target is not initialized. Run "vesper init --target claude" first.');return}console.log(),o.info("Refreshing Claude Code plugin catalog and orchestrator playbook...");let{pluginDir:r,counts:n}=await be({namePrefix:s.claude.namePrefix||"",version:e.version||"0.0.0"});o.success(`Plugin catalog refreshed: ${r}`),o.info(` agents: ${n.agents}, commands: ${n.commands}, skills: ${n.skills}`);let i=await Te(t);o.success(`Orchestrator playbook refreshed (.claude/vesper/orchestrator.md: ${i.orchestrator})`),o.info("Team roster (.claude/vesper/orchestration.md) and project context (.claude/vesper/context.md) are left alone \u2014 they belong to this project.")}async function $s(e={}){try{let t=Ts(e.path||process.cwd());await g(t)||(o.error(`Directory not found: ${o.formatPath(t)}`),process.exit(1));let s=e.target?[e.target]:await D(t);if(s.length===0){o.warn('Vesper is not initialized. Run "vespercli init" first.');return}s.includes("claude")&&await Gn({...e,path:t}),s.includes("copilot")&&(console.log(),o.info("Copilot assets are linked from the package, not copied."),o.info("Update the vesper package to get the latest assets:"),o.dim(" npm update -g @mthanh/vespercli"),console.log())}catch(t){o.error(`Update failed: ${t.message}`),process.exit(1)}}F();import{resolve as Un,join as Ze}from"node:path";async function Wn(e){let t=await g(Ze(Pe(e),"orchestration.md")),s=await g(Ze(e,".github","copilot-instructions.md"));return{claude:t,copilot:s}}async function Bn(e,t){if(!await g(e))return;let{claude:s,copilot:r}=await Wn(e);if(!s&&!r){t||o.info("Not a vesperized workspace \u2014 nothing to bootstrap. Run `vespercli init` to set up.");return}let n=[];if(s){await ee(e,!0),n.push(".mcp.json regenerated for this worktree (Claude target)");let c=await Me(),d=c.filter(u=>u.synced).map(u=>u.skill),l=c.filter(u=>!u.synced).map(u=>u.skill);if(d.length&&n.push(`GitLab skills synced (${d.join(", ")})`),l.length){let u=`GitLab skills not synced (continuing): ${l.join(", ")}`;n.push(u),o.warn(u)}}r&&await Ce(e)&&(await X(e,!0),n.push(".vscode/mcp.json refreshed (Copilot target)"));let i=Ze(e,".vesper","index.db");if(!await g(i)){let c=await Ye(e,!1);c.success&&n.push(`code index built (${c.filesIndexed} files)`)}await he(e);let a=await we(e);if(a.length>0&&o.warn(`Local-only file(s) git-tracked despite .gitignore: ${a.join(", ")} \u2014 untrack with: git rm --cached ${a.join(" ")}`),await ye(e),await _e(e),await Se(e),n.push("gitignore + git hooks + merge strategy ensured"),!t){o.success("Worktree bootstrap complete");for(let c of n)o.info(` ${c}`)}}async function Os(e,t={}){let s=Un(t.path||process.cwd()),r=!!t.quiet;switch(e){case"bootstrap":case void 0:await Bn(s,r);break;default:o.error(`Unknown subcommand: ${e}. Usage: vespercli worktree bootstrap`),process.exit(1)}}var zn=Jn(import.meta.url),Yn=et(zn);function Xn(e){let t=e;for(;t!==et(t);){let s=Is(t,"package.json");if(Hn(s))return s;t=et(t)}return Is(e,"..","..","package.json")}var Qn=Xn(Yn),tt=JSON.parse(Kn(Qn,"utf-8")),L=new qn;L.name("vespercli").description("Vesper VS Code Agent Suite \u2014 manage GitHub Copilot agents, prompts, instructions, and skills").version(tt.version,"-v, --version","Output the current version");L.command("init").description("Initialize vesper for one or more platforms (GitHub Copilot and/or Claude Code) in this workspace").option("-p, --path <path>","Workspace root directory",process.cwd()).option("-y, --yes","Skip follow-up prompts (not the platform selection)").option("-f, --force","Force re-initialization (skips follow-up prompts)").option("--force-default","Use all default values for follow-up prompts (not the platform selection)").option("--target <targets>","Platform(s) to set up: copilot, claude, a comma list (copilot,claude), or all. Multi-select prompt if omitted.").action(e=>os({...e,version:tt.version}));L.command("add").description("Add extended assets \u2014 to VS Code settings (Copilot) or the Claude Code plugin catalog. Target is auto-detected from the workspace 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()).option("--target <target>","Install target: copilot or claude (auto-detected if omitted)").action((e,t,s)=>ls({type:e,name:t,...s}));L.command("reset").description("Remove the Vesper install \u2014 Copilot settings or the Claude Code target. Target is auto-detected from the workspace when omitted.").option("--path <path>","Workspace root directory",process.cwd()).option("-y, --yes","Skip confirmation prompts").option("--target <target>","Install target: copilot or claude (auto-detected if omitted)").action(ts);L.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()).option("--target <target>","Install target: copilot or claude (omit to see all installed targets)").action((e,t)=>ps({type:e,...t}));L.command("update").description("Refresh installed targets \u2014 the Claude Code plugin catalog + orchestrator playbook, and/or the Copilot package-link note. Auto-detected from the workspace when omitted.").option("--path <path>","Workspace root directory",process.cwd()).option("--target <target>","Install target: copilot or claude (auto-detected if omitted)").action(e=>$s({...e,version:tt.version}));L.command("catalog").description("Show the Vesper catalog (agents, dependencies, requirements)").action(gs);L.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").option("--target <target>","Install target: copilot, claude, or omit for all installed targets").action((e,t,s)=>Ps(e,t,s));L.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,s,r)=>bs(e,t,s,r));L.command("worktree").description("Bootstrap a git worktree with Vesper's local-only artifacts (.mcp.json, code index, gitignore, git hooks)").argument("[subcommand]","Subcommand: bootstrap (default)").option("--path <path>","Workspace root directory",process.cwd()).option("-q, --quiet","Suppress non-error output (used by hooks/tasks)").action((e,t)=>Os(e,t));L.addHelpText("after",`
34
36
  Examples:
35
37
  $ vespercli init Pick platform(s) to set up (multi-select), then initialize
36
38
  $ vespercli init --target copilot,claude Set up both platforms in one run
@@ -65,4 +67,4 @@ Multi-platform notes:
65
67
 
66
68
  Documentation:
67
69
  https://github.com/mthanhtran/vesper
68
- `);D.parse();
70
+ `);L.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mthanh/vespercli",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Vesper Agent Suite — CLI to manage AI agents, prompts, instructions, and skills for GitHub Copilot (VS Code) and Claude Code",
5
5
  "type": "module",
6
6
  "main": "./src/cli/index.js",
@@ -14,12 +14,15 @@
14
14
  "src/mcp/vesper-indexing/package.json",
15
15
  "src/mcp/vesper-indexing/package-lock.json",
16
16
  "assets",
17
- "scripts"
17
+ "scripts",
18
+ "!scripts/readme"
18
19
  ],
19
20
  "scripts": {
20
21
  "start": "node bin/vesper.js",
21
22
  "dev": "VESPER_DEV=true node bin/vesper.js",
22
- "test": "echo \"No tests yet\" && exit 0",
23
+ "test": "vitest run",
24
+ "test:unit": "vitest run",
25
+ "test:watch": "vitest",
23
26
  "build:cli": "esbuild src/cli/index.js --bundle --platform=node --format=esm --minify --outfile=dist/cli.min.js --external:@inquirer/prompts --external:commander --external:picocolors --external:strip-json-comments",
24
27
  "build:mcp": "cd src/mcp/vesper-indexing && npm install && npm run build",
25
28
  "build": "npm run build:cli && npm run build:mcp",
@@ -57,6 +60,7 @@
57
60
  "strip-json-comments": "^5.0.3"
58
61
  },
59
62
  "devDependencies": {
60
- "esbuild": "^0.20.0"
63
+ "esbuild": "^0.20.0",
64
+ "vitest": "^4.1.10"
61
65
  }
62
66
  }