@mthanh/vespercli 1.7.0 → 1.8.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.
- package/README.md +46 -0
- package/assets/claude/agents/clickup-agent.md +1 -1
- package/assets/claude/agents/context7.md +1 -1
- package/assets/claude/agents/history-logger.md +2 -2
- package/assets/claude/agents/modernization.md +1 -0
- package/assets/claude/commands/compact-knowledge.md +1 -1
- package/assets/claude/skills/java/SKILL.md +1 -1
- package/assets/claude/skills/nextjs-tailwind/SKILL.md +1 -1
- package/assets/claude/skills/reactjs/SKILL.md +1 -1
- package/assets/claude/skills/self-explanatory-code-commenting/SKILL.md +1 -1
- package/assets/claude/skills/tailwind-v4-vite/SKILL.md +1 -1
- package/assets/claude/skills/task-implementation/SKILL.md +1 -1
- package/assets/claude/skills/vesper-catalog-editing-safety/SKILL.md +2 -1
- package/assets/claude/vesper-orchestrator.md +2 -0
- package/assets/core/agents/history-logger.agent.md +2 -2
- package/assets/core/prompts/compact-knowledge.prompt.md +1 -1
- package/assets/instructions/flutter/dart-n-flutter.instructions.md +447 -0
- package/assets/instructions/self-explanatory-code-commenting/self-explanatory-code-commenting.instructions.md +1 -1
- package/assets/skills/vesper-catalog-editing-safety/SKILL.md +2 -1
- package/assets/vendor/i-have-adhd/LICENSE +21 -0
- package/assets/vendor/i-have-adhd/SKILL.md +142 -0
- package/assets/vendor/i-have-adhd/VENDOR.md +56 -0
- package/assets/vendor/ponytail/LICENSE +21 -0
- package/assets/vendor/ponytail/SKILL.md +120 -0
- package/assets/vendor/ponytail/VENDOR.md +115 -0
- package/dist/cli.min.js +62 -26
- package/package.json +1 -1
- package/scripts/generate-claude-assets.js +273 -20
- package/scripts/generate-claude-assets.test.js +228 -0
- package/scripts/postinstall.js +15 -4
- package/src/mcp/vesper-indexing/dist/index.js +17 -1
- package/src/mcp/vesper-indexing/dist/index.js.map +1 -1
- package/src/mcp/vesper-indexing/package-lock.json +2 -2
- package/src/mcp/vesper-indexing/package.json +1 -1
package/dist/cli.min.js
CHANGED
|
@@ -1,38 +1,74 @@
|
|
|
1
|
-
var
|
|
2
|
-
`),
|
|
3
|
-
`,"utf-8"),{created:!0,updated:!1}}if(
|
|
1
|
+
var Qs=(e,t)=>()=>(e&&(t=e(e=0)),t);import{access as Zs,constants as en,stat as $a}from"node:fs/promises";async function g(e){try{return await Zs(e,en.F_OK),!0}catch{return!1}}var F=Qs(()=>{});import{Command as _a}from"commander";import{readFileSync as Sa,existsSync as xa}from"node:fs";import{fileURLToPath as ka}from"node:url";import{dirname as dt,join as Xs}from"node:path";F();import{resolve as wr,basename as vr}from"node:path";import{spawn as _r}from"node:child_process";import{confirm as re,input as Sr,number as xr,select as kr,checkbox as Ar}from"@inquirer/prompts";import{readFile as I,writeFile as P,mkdir as ge,readdir as ln}from"node:fs/promises";import{join as v,dirname as X}from"node:path";import{homedir as kt}from"node:os";import dn from"strip-json-comments";import{fileURLToPath as tn}from"node:url";import{dirname as Ue,join as pe,resolve as sn}from"node:path";import{readdir as nn}from"node:fs/promises";import{existsSync as rn}from"node:fs";var an=tn(import.meta.url),on=Ue(an);function cn(e){let t=e;for(;t!==Ue(t);){if(rn(pe(t,"package.json")))return t;t=Ue(t)}return sn(e,"..","..","..")}var ae=cn(on),b=pe(ae,"assets"),pt=pe(b,"core");function We(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 M={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 oe(e){let t=M[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=pe(b,t.dir);try{return(await nn(s,{withFileTypes:!0})).filter(r=>r.isDirectory()&&!r.name.startsWith(".")).map(r=>r.name)}catch{return[]}}function ft(e,t){We(t);let s=M[e];if(!s)throw new Error(`Unknown asset type: ${e}`);return pe(b,s.dir,t)}async function N(e,{cwd:t,timeout:s}={}){let{execFile:n}=await import("node:child_process"),{promisify:r}=await import("node:util"),o=r(n);try{let{stdout:i}=await o("git",e,{cwd:t,timeout:s});return i.trim()}catch{return null}}function J(e){let t=kt();return e.startsWith(t)?"~"+e.slice(t.length).replace(/\\/g,"/"):e.replace(/\\/g,"/")}var un=/node_modules\/(?:vesper-cli|vespercli)\/(.+)$/;function ve(e){if(typeof e!="string")return e;let t=e.match(un);return t?J(v(ae,t[1])):e}function pn(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"},fe="chat.tools.terminal.autoApprove",At="chat.tools.terminal.enableAutoApprove",Ke="chat.tools.autoApprove",w="chat.tools.eligibleForAutoApproval",Ct="chat.agent.maxRequests",Pt="chat.includeReferencedInstructions",Et="chat.customAgentInSubagent.enabled",bt="chat.agent.enabled",Tt="github.copilot.chat.omitBaseAgentInstructions",$t="chat.mcp.discovery.enabled",It="chat.mcp.autoStart",x="github.copilot.chat.additionalReadAccessPaths",D={maxRequests:300,terminalEnableAutoApprove:!0,omitBaseAgentInstructions:!0,enableMcpServer:!0},fn=[Ct,Pt,Et,bt,Tt,$t,It,At,fe,Ke,w],Q=["vesper-indexing","sequential-thinking","memory"],Be=[".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 gt="# <!-- vesper:gitignore:start -->",mt="# <!-- vesper:gitignore:end -->";async function _e(e){let t=v(e,".gitignore"),s=[gt,...Be,mt].join(`
|
|
2
|
+
`),n=new RegExp(`${gt}[\\s\\S]*?${mt}`),r="";try{r=await I(t,"utf-8")}catch(i){if(i.code!=="ENOENT")throw i;return await P(t,`${s}
|
|
3
|
+
`,"utf-8"),{created:!0,updated:!1}}if(n.test(r)){let i=r.replace(n,s);return i!==r?(await P(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=r.endsWith(`
|
|
4
4
|
`)?`
|
|
5
5
|
`:`
|
|
6
6
|
|
|
7
|
-
`;return await
|
|
8
|
-
`,"utf-8"),{created:!1,updated:!0}}async function ve(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","--",...Ve]);if(!a)return[];let c=new Set(a.split("\0").filter(Boolean));return Ve.filter(d=>c.has(d))}var at="Vesper: worktree bootstrap";async function kt(e){let t=y(e,".vscode","tasks.json"),s={label:at,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=fe(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===at);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 pe(z(t),{recursive:!0}),await A(t,JSON.stringify(r,null," "),"utf-8"),{created:!n,updated:n}}var ct=["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"],Ne={"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"]},N={"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 zs(e){try{let s=(await Bs(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 zs(e);return t?{type:E.WORKSPACE_FILE,settingsPath:t,workspaceFile:t}:{type:E.FOLDER,settingsPath:y(e,".vscode","settings.json"),workspaceFile:null}}function Ge(e,t=null){return t?.workspaceFile?y(z(t.workspaceFile),".vesperrc"):y(e,".vesperrc")}function fe(e){let t=qs(e,{trailingCommas:!0});return JSON.parse(t)}async function x(e){let t=await _(e);try{let s=await T(t.settingsPath,"utf-8"),r=fe(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=fe(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=z(s.settingsPath);await pe(r,{recursive:!0}),await A(s.settingsPath,JSON.stringify(t,null," "),"utf-8")}}function Ys(e){return y(e,".vesper","tracking.json")}async function m(e){let t=await _(e),s=Ge(e,t),r=Ys(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 Xs(e){try{let t=await T(e,"utf-8"),r=fe(t).folders||[],n=z(e);return r.map(i=>{let a=i.path||i;return a.startsWith("/")||a.startsWith("~")?a.replace(/^~/,gt()):y(n,a)})}catch{return[]}}async function Ct(e){let t=await _(e);if(t.type!==E.WORKSPACE_FILE)return{found:!1,paths:[]};let s=z(t.workspaceFile),r=y(s,".vesperrc"),n=await Xs(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 At(e,t,s){let r=await _(e),n=Ge(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=Ge(e,s);await A(r,JSON.stringify(t,null,2),"utf-8")}async function Pt(e,t){let s=await _(e),r=await x(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 Et(e){let t=await x(e),s=await m(e),r={paths:[],settings:[],mcpServers:[],agentTools:[]},n=/vespercli|vesper-cli/;for(let f of Object.values(J))if(t[f]){for(let u of Object.keys(t[f])){let p=s.paths?.includes(u),h=n.test(u);(p||h)&&(delete t[f][u],r.paths.includes(u)||r.paths.push(u))}Object.keys(t[f]).length===0&&delete t[f]}let i=s.readAccessPaths||[];if(i.length>0){let f=t[S]||[],u=f.filter(p=>!i.includes(p));u.length!==f.length&&(u.length>0?t[S]=u:delete t[S],r.settings.push(S))}for(let f of Js)t[f]!==void 0&&(delete t[f],r.settings.push(f));let a=s.mcp?.agentTools||{};for(let[f,u]of Object.entries(a))r.agentTools.push({agent:f,tools:u});(r.paths.length>0||r.settings.length>0)&&await P(e,t);let c=await G(e),d=s.mcp?.servers||[],l=[...new Set([...Y,...d])];if(c.servers){for(let f of l)c.servers[f]&&(delete c.servers[f],r.mcpServers.push(f));if(r.mcpServers.length>0){let f=ke(e),u=z(f);await pe(u,{recursive:!0}),await A(f,JSON.stringify(c,null," "),"utf-8")}}return await C(e,{paths:[],readAccessPaths:[],addedAt:null,workspaceType:null,settingsPath:null,mcp:null}),{removed:r}}async function ye(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 Qs=["agents","prompts","instructions"];function Zs(){let e=[];for(let n of Qs){let i=I[n],a=J[n];if(a&&i){let c=K(y(b,"core",i.dir));e.push({path:c,settingKey:a,type:n})}}let t=J.skills;if(t){let n=K(y(b,"core","skills"));e.push({path:n,settingKey:t,type:"skills"})}let s=I.skills;if(t&&s){let n=K(y(b,s.dir));e.push({path:n,settingKey:t,type:"skills"})}let r=J.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 bt(e,t=!0){let s=await _(e),r=await x(e);if(r[mt]=t,t){r[ue]||(r[ue]={});for(let n of ct)r[ue][n]=!0}return await P(e,r),{configured:t?ct.length:0,workspaceType:s.type}}async function Tt(e,t={}){let{maxRequests:s=M.maxRequests,omitBaseAgentInstructions:r=M.omitBaseAgentInstructions}=t,n=await x(e);n[ht]=s,n[wt]=!0,n[vt]=!0,n[yt]=!0,n[_t]=r,n[St]=!0,n[xt]="newAndOutdated",n[S]||(n[S]=[]),await P(e,n)}async function $t(e,t){let s=await x(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 Ot(e,t){let s=await x(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 It(e){return(await x(e))[S]||[]}function Mt(e){let t=I[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=J[e];return{path:K(y(b,t.dir)),settingKey:s,type:e}}function X(e,t){if(Fe(t),!I[e])throw new Error(`Unknown asset type: ${e}`);let r=J[e];return{path:K(nt(e,t)),settingKey:r,type:e,name:t}}async function oe(e){return(await m(e)).paths}async function Dt(e){let t={assetPaths:0,readAccess:0,commandKeys:0,trackingPaths:0,mcpArgs:0},s=(u,p)=>{let h=[];for(let O of u){let le=he(O);le!==O&&t[p]++,h.includes(le)||h.push(le)}return h},r=await x(e),n=!1;for(let u of Object.values(J)){let p=r[u];if(!(!p||typeof p!="object"))for(let h of Object.keys(p)){let O=he(h);if(O===h)continue;let le=p[h];delete p[h],p[O]=p[O]===!0?!0:le,t.assetPaths++,n=!0}}if(Array.isArray(r[S])){let u=t.readAccess;r[S]=s(r[S],"readAccess"),t.readAccess!==u&&(n=!0)}let i=r[ue];if(i&&typeof i=="object")for(let u of Object.keys(i))Hs(u)&&(delete i[u],t.commandKeys++,n=!0);n&&await P(e,r);let a=await m(e),c=!1;if(Array.isArray(a.paths)){let u=t.trackingPaths;a.paths=s(a.paths,"trackingPaths"),t.trackingPaths!==u&&(c=!0)}if(Array.isArray(a.readAccessPaths)){let u=[];for(let p of a.readAccessPaths){let h=he(p);h!==p&&(c=!0),u.includes(h)||u.push(h)}a.readAccessPaths=u}c&&(a.updatedAt=new Date().toISOString(),await C(e,a));let d=await G(e),l=d.servers?.["vesper-indexing"];if(l&&Array.isArray(l.args)){let u=!1;l.args=l.args.map(p=>{let h=he(p);return h!==p&&(t.mcpArgs++,u=!0),h}),u&&await Ce(e,d)}return{migrated:t.assetPaths+t.readAccess+t.commandKeys+t.trackingPaths+t.mcpArgs>0,changed:t}}async function Lt(e){let t=await _(e),s=await x(e),r=await m(e),n=Zs(),i=[],a=[];for(let{path:l,settingKey:f}of n)s[f]||(s[f]={}),s[f][l]===!0?a.push(l):(s[f][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 lt="# <!-- vesper:hook:start -->",dt="# <!-- vesper:hook:end -->";async function er(e){if(await V(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return null;let{isAbsolute:s}=await import("node:path"),r=a=>s(a)?a:y(e,a),n=await V(["config","core.hooksPath"],{cwd:e});if(n)return r(n);let i=await V(["rev-parse","--git-common-dir"],{cwd:e});return i?y(r(i),"hooks"):null}async function tr(e,t){let s=await er(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(`${lt}[\\s\\S]*?${dt}`));if(!i)throw new Error(`Hook source ${r} is missing its vesper:hook guard markers`);let a=i[0],c=new RegExp(`${lt}[\\s\\S]*?${dt}`);await pe(s,{recursive:!0});let d=y(s,t),l="",f=!0;try{l=await T(d,"utf-8")}catch(p){if(p.code!=="ENOENT")throw p;f=!1}if(!f)return await A(d,n,{encoding:"utf-8",mode:493}),{installed:!0,updated:!1,hooksDir:s};if(c.test(l)){let p=l.replace(c,a);return p!==l?(await A(d,p,"utf-8"),await ut(d),{installed:!1,updated:!0,hooksDir:s}):{installed:!1,updated:!1,hooksDir:s}}let u=l.endsWith(`
|
|
7
|
+
`;return await P(t,`${r}${o}${s}
|
|
8
|
+
`,"utf-8"),{created:!1,updated:!0}}async function Se(e){let{execFile:t}=await import("node:child_process"),{promisify:s}=await import("node:util"),n=s(t),r=async d=>{try{let{stdout:l}=await n("git",d,{cwd:e});return l}catch{return null}},o=await r(["rev-parse","--is-inside-work-tree"]);if(o===null||o.trim()!=="true")return[];let i=await r(["ls-files","-z","--",...Be]);if(!i)return[];let c=new Set(i.split("\0").filter(Boolean));return Be.filter(d=>c.has(d))}var ht="Vesper: worktree bootstrap";async function Ot(e){let t=v(e,".vscode","tasks.json"),s={label:ht,type:"shell",command:"vespercli worktree bootstrap --quiet",presentation:{reveal:"silent",panel:"shared"},problemMatcher:[],runOptions:{runOn:"folderOpen"}},n={version:"2.0.0",tasks:[]},r=!1;try{let i=await I(t,"utf-8");n=me(i),Array.isArray(n.tasks)||(n.tasks=[]),r=!0}catch(i){if(i.code!=="ENOENT")throw i}let o=n.tasks.findIndex(i=>i?.label===ht);if(o===-1)n.tasks.push(s);else if(JSON.stringify(n.tasks[o])!==JSON.stringify(s))n.tasks[o]=s;else return{created:!1,updated:!1};return await ge(X(t),{recursive:!0}),await P(t,JSON.stringify(n,null," "),"utf-8"),{created:!r,updated:r}}var yt=["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"],qe={"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"]},G={"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 T={FOLDER:"folder",WORKSPACE_FILE:"workspace"};async function gn(e){try{let s=(await ln(e,{withFileTypes:!0})).find(n=>n.isFile()&&n.name.endsWith(".code-workspace"));return s?v(e,s.name):null}catch{return null}}async function _(e){let t=await gn(e);return t?{type:T.WORKSPACE_FILE,settingsPath:t,workspaceFile:t}:{type:T.FOLDER,settingsPath:v(e,".vscode","settings.json"),workspaceFile:null}}function He(e,t=null){return t?.workspaceFile?v(X(t.workspaceFile),".vesperrc"):v(e,".vesperrc")}function me(e){let t=dn(e,{trailingCommas:!0});return JSON.parse(t)}async function k(e){let t=await _(e);try{let s=await I(t.settingsPath,"utf-8"),n=me(s);return t.type===T.WORKSPACE_FILE?n.settings||{}:n}catch(s){if(s.code==="ENOENT")return{};if(s instanceof SyntaxError){if(t.type===T.WORKSPACE_FILE)throw new Error(`Failed to parse workspace file: ${t.settingsPath}. ${s.message}`);return{}}throw s}}async function E(e,t){let s=await _(e);if(s.type===T.WORKSPACE_FILE){let n;try{let r=await I(s.settingsPath,"utf-8");n=me(r)}catch(r){if(r.code==="ENOENT")n={folders:[],settings:{}};else throw new Error(`Failed to read workspace file: ${s.settingsPath}. ${r.message}`)}n.settings=t,await P(s.settingsPath,JSON.stringify(n,null," "),"utf-8")}else{let n=X(s.settingsPath);await ge(n,{recursive:!0}),await P(s.settingsPath,JSON.stringify(t,null," "),"utf-8")}}function mn(e){return v(e,".vesper","tracking.json")}async function m(e){let t=await _(e),s=He(e,t),n=mn(e),r=v(e,".vesperrc");try{let o=await I(s,"utf-8");return JSON.parse(o)}catch{if(s!==r)try{let o=await I(r,"utf-8");return JSON.parse(o)}catch{}try{let o=await I(n,"utf-8");return JSON.parse(o)}catch{return{paths:[],addedAt:null,workspaceType:null,settingsPath:null}}}}async function hn(e){try{let t=await I(e,"utf-8"),n=me(t).folders||[],r=X(e);return n.map(o=>{let i=o.path||o;return i.startsWith("/")||i.startsWith("~")?i.replace(/^~/,kt()):v(r,i)})}catch{return[]}}async function Mt(e){let t=await _(e);if(t.type!==T.WORKSPACE_FILE)return{found:!1,paths:[]};let s=X(t.workspaceFile),n=v(s,".vesperrc"),r=await hn(t.workspaceFile),o=[];for(let i of r){let c=v(i,".vesperrc");if(c!==n)try{let d=await I(c,"utf-8"),l=JSON.parse(d);o.push({folderPath:i,vesperrcPath:c,tracking:l})}catch{}}return{found:o.length>0,paths:o}}async function Dt(e,t,s){let n=await _(e),r=He(e,n),o={...s,workspaceType:T.WORKSPACE_FILE,settingsPath:n.settingsPath,migratedFrom:t,migratedAt:new Date().toISOString()};await P(r,JSON.stringify(o,null,2),"utf-8");try{let{unlink:i}=await import("node:fs/promises");await i(t)}catch{}return{success:!0,newPath:r}}async function A(e,t){let s=await _(e),n=He(e,s);await P(n,JSON.stringify(t,null,2),"utf-8")}async function Lt(e,t){let s=await _(e),n=await k(e),r=await m(e),o=[],i=[];for(let{path:c,settingKey:d}of t){if(n[d]||(n[d]={}),n[d][c]){i.push(c),r.paths.includes(c)||r.paths.push(c);continue}n[d][c]=!0,o.push(c),r.paths.includes(c)||r.paths.push(c)}return o.length>0&&await E(e,n),r.paths.length>0&&(r.addedAt=r.addedAt||new Date().toISOString(),r.updatedAt=new Date().toISOString(),r.workspaceType=s.type,r.settingsPath=s.settingsPath,await A(e,r)),{added:o,skipped:i,workspaceType:s.type}}async function Vt(e){let t=await k(e),s=await m(e),n={paths:[],settings:[],mcpServers:[],agentTools:[]},r=/vespercli|vesper-cli/;for(let f of Object.values(z))if(t[f]){for(let u of Object.keys(t[f])){let p=s.paths?.includes(u),h=r.test(u);(p||h)&&(delete t[f][u],n.paths.includes(u)||n.paths.push(u))}Object.keys(t[f]).length===0&&delete t[f]}let o=s.readAccessPaths||[];if(o.length>0){let f=t[x]||[],u=f.filter(p=>!o.includes(p));u.length!==f.length&&(u.length>0?t[x]=u:delete t[x],n.settings.push(x))}for(let f of fn)t[f]!==void 0&&(delete t[f],n.settings.push(f));let i=s.mcp?.agentTools||{};for(let[f,u]of Object.entries(i))n.agentTools.push({agent:f,tools:u});(n.paths.length>0||n.settings.length>0)&&await E(e,t);let c=await U(e),d=s.mcp?.servers||[],l=[...new Set([...Q,...d])];if(c.servers){for(let f of l)c.servers[f]&&(delete c.servers[f],n.mcpServers.push(f));if(n.mcpServers.length>0){let f=Pe(e),u=X(f);await ge(u,{recursive:!0}),await P(f,JSON.stringify(c,null," "),"utf-8")}}return await A(e,{paths:[],readAccessPaths:[],addedAt:null,workspaceType:null,settingsPath:null,mcp:null}),{removed:n}}async function xe(e){return(await m(e)).paths.length>0}async function L(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 yn=["agents","prompts","instructions"];function wn(){let e=[];for(let r of yn){let o=M[r],i=z[r];if(i&&o){let c=J(v(b,"core",o.dir));e.push({path:c,settingKey:i,type:r})}}let t=z.skills;if(t){let r=J(v(b,"core","skills"));e.push({path:r,settingKey:t,type:"skills"})}let s=M.skills;if(t&&s){let r=J(v(b,s.dir));e.push({path:r,settingKey:t,type:"skills"})}let n=z.instructions;return n&&e.push({path:"${workspaceFolder}/.vesper/instructions",settingKey:n,type:"instructions"}),t&&e.push({path:"${workspaceFolder}/.vesper/skills",settingKey:t,type:"skills"}),e}async function jt(e,t=!0){let s=await _(e),n=await k(e);if(n[At]=t,t){n[fe]||(n[fe]={});for(let r of yt)n[fe][r]=!0}return await E(e,n),{configured:t?yt.length:0,workspaceType:s.type}}async function Ft(e,t={}){let{maxRequests:s=D.maxRequests,omitBaseAgentInstructions:n=D.omitBaseAgentInstructions}=t,r=await k(e);r[Ct]=s,r[Pt]=!0,r[Et]=!0,r[bt]=!0,r[Tt]=n,r[$t]=!0,r[It]="newAndOutdated",r[x]||(r[x]=[]),await E(e,r)}async function Nt(e,t){let s=await k(e),n=s[x]||[];n.includes(t)||(n.push(t),s[x]=n,await E(e,s));let r=await m(e);return r.readAccessPaths||(r.readAccessPaths=[]),r.readAccessPaths.includes(t)||(r.readAccessPaths.push(t),r.updatedAt=new Date().toISOString(),await A(e,r)),n}async function Rt(e,t){let s=await k(e),n=s[x]||[],r=n.indexOf(t);r!==-1&&(n.splice(r,1),s[x]=n,await E(e,s));let o=await m(e);if(o.readAccessPaths){let i=o.readAccessPaths.indexOf(t);i!==-1&&(o.readAccessPaths.splice(i,1),o.updatedAt=new Date().toISOString(),await A(e,o))}return n}async function Gt(e){return(await k(e))[x]||[]}function Ut(e){let t=M[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=z[e];return{path:J(v(b,t.dir)),settingKey:s,type:e}}function Z(e,t){if(We(t),!M[e])throw new Error(`Unknown asset type: ${e}`);let n=z[e];return{path:J(ft(e,t)),settingKey:n,type:e,name:t}}async function ie(e){return(await m(e)).paths}async function Wt(e){let t={assetPaths:0,readAccess:0,commandKeys:0,trackingPaths:0,mcpArgs:0},s=(u,p)=>{let h=[];for(let O of u){let ue=ve(O);ue!==O&&t[p]++,h.includes(ue)||h.push(ue)}return h},n=await k(e),r=!1;for(let u of Object.values(z)){let p=n[u];if(!(!p||typeof p!="object"))for(let h of Object.keys(p)){let O=ve(h);if(O===h)continue;let ue=p[h];delete p[h],p[O]=p[O]===!0?!0:ue,t.assetPaths++,r=!0}}if(Array.isArray(n[x])){let u=t.readAccess;n[x]=s(n[x],"readAccess"),t.readAccess!==u&&(r=!0)}let o=n[fe];if(o&&typeof o=="object")for(let u of Object.keys(o))pn(u)&&(delete o[u],t.commandKeys++,r=!0);r&&await E(e,n);let i=await m(e),c=!1;if(Array.isArray(i.paths)){let u=t.trackingPaths;i.paths=s(i.paths,"trackingPaths"),t.trackingPaths!==u&&(c=!0)}if(Array.isArray(i.readAccessPaths)){let u=[];for(let p of i.readAccessPaths){let h=ve(p);h!==p&&(c=!0),u.includes(h)||u.push(h)}i.readAccessPaths=u}c&&(i.updatedAt=new Date().toISOString(),await A(e,i));let d=await U(e),l=d.servers?.["vesper-indexing"];if(l&&Array.isArray(l.args)){let u=!1;l.args=l.args.map(p=>{let h=ve(p);return h!==p&&(t.mcpArgs++,u=!0),h}),u&&await Ee(e,d)}return{migrated:t.assetPaths+t.readAccess+t.commandKeys+t.trackingPaths+t.mcpArgs>0,changed:t}}async function Bt(e){let t=await _(e),s=await k(e),n=await m(e),r=wn(),o=[],i=[];for(let{path:l,settingKey:f}of r)s[f]||(s[f]={}),s[f][l]===!0?i.push(l):(s[f][l]=!0,o.push(l)),n.paths.includes(l)||n.paths.push(l);let c=b,d=s[x]||[];return d.includes(c)||(d.push(c),s[x]=d,o.push(c)),n.readAccessPaths||(n.readAccessPaths=[]),n.readAccessPaths.includes(c)||n.readAccessPaths.push(c),o.length>0&&await E(e,s),n.addedAt=n.addedAt||new Date().toISOString(),n.updatedAt=new Date().toISOString(),n.workspaceType=t.type,n.settingsPath=t.settingsPath,await A(e,n),{added:o,existed:i,workspaceType:t.type}}var wt="# <!-- vesper:hook:start -->",vt="# <!-- vesper:hook:end -->";async function vn(e){if(await N(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return null;let{isAbsolute:s}=await import("node:path"),n=i=>s(i)?i:v(e,i),r=await N(["config","core.hooksPath"],{cwd:e});if(r)return n(r);let o=await N(["rev-parse","--git-common-dir"],{cwd:e});return o?v(n(o),"hooks"):null}async function _n(e,t){let s=await vn(e);if(!s)return{installed:!1,updated:!1,hooksDir:null};let n=v(b,"hooks",t),r=await I(n,"utf-8"),o=r.match(new RegExp(`${wt}[\\s\\S]*?${vt}`));if(!o)throw new Error(`Hook source ${n} is missing its vesper:hook guard markers`);let i=o[0],c=new RegExp(`${wt}[\\s\\S]*?${vt}`);await ge(s,{recursive:!0});let d=v(s,t),l="",f=!0;try{l=await I(d,"utf-8")}catch(p){if(p.code!=="ENOENT")throw p;f=!1}if(!f)return await P(d,r,{encoding:"utf-8",mode:493}),{installed:!0,updated:!1,hooksDir:s};if(c.test(l)){let p=l.replace(c,i);return p!==l?(await P(d,p,"utf-8"),await _t(d),{installed:!1,updated:!0,hooksDir:s}):{installed:!1,updated:!1,hooksDir:s}}let u=l.endsWith(`
|
|
9
9
|
`)?`
|
|
10
10
|
`:`
|
|
11
11
|
|
|
12
|
-
`;return await
|
|
13
|
-
`,"utf-8"),await
|
|
14
|
-
`),
|
|
15
|
-
`,"utf-8"),{created:!0,updated:!1}}if(
|
|
12
|
+
`;return await P(d,`${l}${u}${i}
|
|
13
|
+
`,"utf-8"),await _t(d),{installed:!1,updated:!0,hooksDir:s}}async function _t(e){let{chmod:t}=await import("node:fs/promises");try{await t(e,493)}catch{}}var Sn=["pre-commit","post-checkout"];async function ke(e){let t={};for(let s of Sn)t[s]=await _n(e,s);return t}var St="# <!-- vesper:gitattributes:start -->",xt="# <!-- vesper:gitattributes:end -->",xn=[".vesper/history.md merge=union",".vesper/memory.jsonl merge=vesper-memory",".claude/vesper/context/recent-decisions.md merge=union",".vesper/history-archive/*.md merge=union"];async function Ae(e){let t=v(e,".gitattributes"),s=[St,...xn,xt].join(`
|
|
14
|
+
`),n=new RegExp(`${St}[\\s\\S]*?${xt}`),r="";try{r=await I(t,"utf-8")}catch(i){if(i.code!=="ENOENT")throw i;return await P(t,`${s}
|
|
15
|
+
`,"utf-8"),{created:!0,updated:!1}}if(n.test(r)){let i=r.replace(n,s);return i!==r?(await P(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=r.endsWith(`
|
|
16
16
|
`)?`
|
|
17
17
|
`:`
|
|
18
18
|
|
|
19
|
-
`;return await
|
|
20
|
-
`,"utf-8"),{created:!1,updated:!0}}async function
|
|
21
|
-
`)}async function
|
|
22
|
-
`,"utf-8"),{created:!0,updated:!1};let
|
|
19
|
+
`;return await P(t,`${r}${o}${s}
|
|
20
|
+
`,"utf-8"),{created:!1,updated:!0}}async function Ce(e){if(await N(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{configured:!1};let n=`node "${v(b,"hooks","merge-memory-jsonl.js")}" %O %A %B`;return await N(["config","merge.vesper-memory.name","Vesper memory.jsonl entity-aware merge"],{cwd:e}),{configured:await N(["config","merge.vesper-memory.driver",n],{cwd:e})!==null}}function Pe(e){return v(e,".vscode","mcp.json")}function H(){return v(ae,"src","mcp","vesper-indexing","dist","index.js")}async function U(e){let t=Pe(e);try{let s=await I(t,"utf-8");return me(s)}catch(s){if(s.code==="ENOENT")return{servers:{}};if(s instanceof SyntaxError)return{servers:{}};throw s}}async function Ee(e,t){let s=Pe(e),n=X(s);await ge(n,{recursive:!0}),await P(s,JSON.stringify(t,null," "),"utf-8")}async function ee(e,t=!0){let s=await U(e),n=J(H()),r=[];if(s.servers||(s.servers={}),t?(s.servers["vesper-indexing"]={type:"stdio",command:"node",args:[n],env:{VESPER_INDEX_ROOT:"${workspaceFolder}"}},r.push("vesper-indexing"),s.servers["sequential-thinking"]={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},r.push("sequential-thinking"),s.servers.memory={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:"${workspaceFolder}/.vesper/memory.jsonl"}},r.push("memory")):(delete s.servers["vesper-indexing"],delete s.servers["sequential-thinking"],delete s.servers.memory),await Ee(e,s),t&&r.length>0){let o=await m(e);o.mcp=o.mcp||{},o.mcp.servers=r,o.mcp.updatedAt=new Date().toISOString(),await A(e,o)}return{configured:t,mcpPath:Pe(e),servers:r}}async function be(e){return!!(await U(e)).servers?.["vesper-indexing"]}async function Kt(e){let t=await _(e),s=await k(e);s[Ke]=!1,s[w]||(s[w]={});for(let n of R)s[w][n]=!0;return await E(e,s),{configured:R.length,workspaceType:t.type}}async function qt(e,t){let s=qe[t];if(!s||s.length===0)return{added:[],agentName:t};let n=await k(e),r=await _(e),o=await m(e,r);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 E(e,n),o.mcp=o.mcp||{},o.mcp.agentTools=o.mcp.agentTools||{},o.mcp.agentTools[t]=s,o.mcp.updatedAt=new Date().toISOString(),await A(e,o)),{added:i,agentName:t}}async function Ht(e,t){let s=G[t];if(!s)return{added:!1,serverName:t,tools:[],error:`Unknown MCP server: ${t}`};let n=await U(e),r=await k(e),o=await _(e),i=await m(e,o);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(H());c.args&&(c.args=c.args.map(f=>f==="${VESPER_INDEXING_PATH}"?l:f))}n.servers[t]=c,await Ee(e,n),r[w]||(r[w]={});let d=[];for(let l of s.tools||[])r[w][l]||(r[w][l]=!0,d.push(l));return r[Ke]=!1,await E(e,r),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 A(e,i),{added:!0,serverName:t,tools:d}}async function Jt(e,t){let s=G[t],n=await U(e),r=await k(e),o=await _(e),i=await m(e,o),c=!1;n.servers&&n.servers[t]&&(delete n.servers[t],await Ee(e,n),c=!0);let d=[];if(s&&r[w]){for(let l of s.tools||[])r[w][l]&&(delete r[w][l],d.push(l));d.length>0&&await E(e,r)}return i.mcp?.servers&&(i.mcp.servers=i.mcp.servers.filter(l=>l!==t),i.mcp.updatedAt=new Date().toISOString(),await A(e,i)),{removed:c,serverName:t,tools:d}}import{readFile as $,writeFile as S,mkdir as B,readdir as Xt,rm as Te,cp as Qt}from"node:fs/promises";import{join as y,dirname as le,basename as kn}from"node:path";import{homedir as Zt}from"node:os";F();var ce=y(b,"claude"),An=y(b,"vendor","i-have-adhd"),Cn=y(b,"vendor","ponytail"),Ye="i-have-adhd",ze="ponytail",es=["agents","commands","skills"],$e="vesper";function K(e=$e){return y(Zt(),".claude","skills",e)}function Ie(e){return y(e,".claude","vesper")}function Qe(e){return y(e,"CLAUDE.md")}function te(e){return y(e,".mcp.json")}function Oe(e){return y(e,".claude","settings.json")}function ts(e,t){return t?e.replace(/^(name:\s*)([a-z0-9-]+)/m,(s,n,r)=>r.startsWith(t)?s:`${n}${t}${r}`):e}async function Pn(e,t,s,n){if(!await g(e))return{copied:0};await B(t,{recursive:!0});let r=await Xt(e,{withFileTypes:!0}),o=0;for(let i of r){let c=y(e,i.name);if(i.isDirectory()){await Qt(c,y(t,i.name),{recursive:!0}),o+=1;continue}if(!i.name.endsWith(".md"))continue;let d=await $(c,"utf-8"),l=ts(d,s),f=n&&s&&!i.name.startsWith(s)?`${s}${i.name}`:i.name;await S(y(t,f),l,"utf-8"),o+=1}return{copied:o}}async function En(e,t,s){let n=y(e,".claude-plugin");await B(n,{recursive:!0});let r={name:t,description:"Vesper specialist catalog \u2014 subagents, slash commands, and skills for AI-orchestrated development.",version:s};await S(y(n,"plugin.json"),JSON.stringify(r,null,2),"utf-8")}async function Me({pluginName:e=$e,namePrefix:t="",version:s="0.0.0"}={}){let n=K(e),r={};for(let o of es){let i=y(ce,o),c=y(n,o),l=await Pn(i,c,o==="skills"?"":t,o!=="skills");r[o]=l.copied}return await En(n,e,s),{pluginDir:n,counts:r}}async function ss(e,t,{pluginName:s=$e,namePrefix:n=""}={}){let r=K(s),o=y(r,e);if(await B(o,{recursive:!0}),e==="skills"){let u=y(ce,"skills",t);if(!await g(u))throw new Error(`Skill "${t}" not found in assets/claude/skills/`);return await Qt(u,y(o,t),{recursive:!0}),{installedAs:t}}let i=".md",c=y(ce,e,`${t}${i}`);if(!await g(c))throw new Error(`${e.slice(0,-1)} "${t}" not found in assets/claude/${e}/`);let d=await $(c,"utf-8"),l=ts(d,n),f=n&&!t.startsWith(n)?`${n}${t}${i}`:`${t}${i}`;return await S(y(o,f),l,"utf-8"),{installedAs:kn(f,i)}}async function ns(e=$e){let t=K(e),s={};for(let n of es){let r=y(t,n);if(!await g(r)){s[n]=[];continue}let o=await Xt(r,{withFileTypes:!0});s[n]=n==="skills"?o.filter(i=>i.isDirectory()).map(i=>i.name).sort():o.filter(i=>i.isFile()&&i.name.endsWith(".md")).map(i=>i.name.replace(/\.md$/,"")).sort()}return s}var Ze="<!-- vesper:start -->",et="<!-- vesper:end -->";function bn(){return[Ze,"@.claude/vesper/orchestrator.md","@.claude/vesper/orchestration.md","@.claude/vesper/context.md",et].join(`
|
|
21
|
+
`)}async function Tn(e){let t=Qe(e),s=bn(),n=new RegExp(`${Ze}[\\s\\S]*?${et}`);if(!await g(t))return await B(le(t),{recursive:!0}),await S(t,`${s}
|
|
22
|
+
`,"utf-8"),{created:!0,updated:!1};let r=await $(t,"utf-8");if(n.test(r)){let i=r.replace(n,s);return i!==r?(await S(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let o=`${s}
|
|
23
23
|
|
|
24
|
-
${
|
|
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(`${k.green("\u2713")} ${a||n}`)},fail(a){this.stop(),console.log(`${k.red("\u2717")} ${a||n}`)}}}var o={success:wr,error:vr,warn:yr,info:_r,dim:Sr,formatPath:xr,formatName:kr,header:Cr,listItem:Ar,vesperTip:Pr,createSpinner:Er};async function $r(e={}){let t=He(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 ts({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 Ie(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 Or(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 Je(e){let t=await m(e);await Et(e);try{let r=await x(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=He(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 Tr(s,{force:!0})}catch{}}async function ss(e={}){try{let t=He(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 $r({...e,path:t});if(!await ye(t)){o.warn("Vesper is not initialized in this workspace.");return}let r=await oe(t);if(r.length===0){o.info("Nothing to reset.");return}let n=Or(r);if(!e.yes&&!await ts({message:`Remove all Vesper assets (${n.join(", ")})?`,default:!1})){o.info("Reset cancelled.");return}let i=await m(t),a=await _(t);await Je(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: ${br(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 Ir}from"node:child_process";import{promisify as Mr}from"node:util";import{randomUUID as Dr}from"node:crypto";import{mkdir as Me,readdir as Lr,rename as ze,rm as H,stat as jr}from"node:fs/promises";import{join as se}from"node:path";var Fr=Mr(Ir),rs=[{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"}],Vr=new Set(rs.map(e=>e.name)),Rr=5*60*1e3;function Ye(e){process.env.VESPER_DEBUG&&o.dim(`[skill-sync] ${e}`)}async function Nr(e,t){if(!Vr.has(t))return o.warn(`skill-sync refused: "${t}" is not in the allow-list`),{synced:!1,skill:t};let s=se(W(),"skills"),r=se(s,t),n=`${r}.bak`,i=se(s,`.tmp-${t}-${Dr().slice(0,8)}`);try{return await Me(s,{recursive:!0}),await H(i,{recursive:!0,force:!0}),await H(n,{recursive:!0,force:!0}),await Fr("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 H(se(i,".git"),{recursive:!0,force:!0}),await g(r)&&await ze(r,n),await ze(i,r),await H(n,{recursive:!0,force:!0}),{synced:!0,skill:t}}catch(a){return Ye(`sync of ${t} failed: ${a&&a.message?a.message:a}`),await H(i,{recursive:!0,force:!0}).catch(()=>{}),!await g(r)&&await g(n)&&await ze(n,r).catch(()=>{}),{synced:!1,skill:t}}}async function Gr(e){try{return await Me(e),!0}catch(t){if(t.code!=="EEXIST")return Ye(`could not acquire lock: ${t.message}`),!1;try{let s=await jr(e);if(Date.now()-s.mtimeMs>Rr)return await H(e,{recursive:!0,force:!0}),await Me(e),!0}catch{}return!1}}async function De(){let e=se(W(),"skills"),t=se(e,".sync.lock");try{await Me(e,{recursive:!0})}catch{return[]}if(!await Gr(t))return Ye("skipped: another process holds the sync lock"),[];try{await Ur(e);let r=[];for(let{url:n,name:i}of rs)r.push(await Nr(n,i));return r}finally{await H(t,{recursive:!0,force:!0}).catch(()=>{})}}async function Ur(e){let t;try{t=await Lr(e,{withFileTypes:!0})}catch{return}for(let s of t)s.isDirectory()&&s.name.startsWith(".tmp-")&&await H(se(e,s.name),{recursive:!0,force:!0}).catch(()=>{})}var ns=["copilot","claude"];function os(e){return e==="claude"?"Claude Code":"GitHub Copilot"}async function Yr(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 Xr(e,t){let s=await Yr(t);if(e.target){let n=String(e.target).toLowerCase(),i=n==="all"?[...ns]:n.split(",").map(a=>a.trim()).filter(Boolean);for(let a of i)ns.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 zr({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 Qr(e){return e?"":await Jr({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 Zr(e,t={}){let s=t.yes||t.forceDefault,r=await Qr(s);console.log(),o.header("Installing Vesper for Claude Code"),console.log();let{pluginDir:n,counts:i}=await Te({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 De(),c=a.filter(u=>u.synced).map(u=>u.skill),d=a.filter(u=>!u.synced).map(u=>u.skill);c.length&&o.success(`GitLab skills synced: ${c.join(", ")}`),d.length&&o.warn(`GitLab skills not synced (continuing): ${d.join(", ")}`);let l=await $e(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 f=await te(e,!0);await Oe(e),o.success(`MCP servers configured: .mcp.json (${f.servers.join(", ")})`),await es(e,{pluginPath:W(),namePrefix:r,mcpConfigPath:ee(e),settingsPath:be(e),installedAt:new Date().toISOString()})}async function en(e,t,s){console.log(),o.header("Configuring GitHub Copilot"),console.log();let r=await Lt(e);await Tt(e,{maxRequests:s.maxRequests,omitBaseAgentInstructions:s.omitBaseAgentInstructions});let n=await bt(e,s.terminalEnableAutoApprove),i=!1;return s.enableMcpServer&&(i=(await Q(e,!0)).configured,await jt(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: ${Br(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 tn(e,t){let s=await Ct(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 ae({message:"Migrate .vesperrc to workspace level? (recommended for multi-root workspaces)",default:!0})),i){let a=await At(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 sn(e){let{migrated:t,changed:s}=await Dt(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 rn(e,t){let s=e;return t||(s=await Kr({message:"Workspace root directory:",default:s})),Wr(s)}async function nn(e,t,s){let r=[];for(let n of t){let i=os(n),a=s;if(s||(a=await ae({message:`${i} is installed but was unchecked. Remove it from this project?`,default:!1})),!a){o.info(`Kept ${i}.`);continue}n==="claude"?await Ie(e):await Je(e),r.push(n),o.success(`Removed ${i} from this project.`)}return r}async function on(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 Hr({message:"Max agent requests per session (chat.agent.maxRequests):",default:M.maxRequests,min:1,max:1e3}),s=await ae({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 ae({message:"Omit base agent instructions for custom agents? (github.copilot.chat.omitBaseAgentInstructions)",default:M.omitBaseAgentInstructions}),n=await ae({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 Xe(e,t=!1){let s=q().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=qr("node",[s,e],{stdio:["ignore","pipe","pipe"],env:{...process.env}}),a="",c=0;i.stderr.on("data",d=>{let l=d.toString().trim(),f=l.match(/Indexed (\d+) files/);if(f&&(c=parseInt(f[1],10),r&&r.update(`Indexing workspace... ${c} files`)),t&&l)for(let u of l.split(`
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Reload the Claude Code session to deactivate the MCP server`)}async function _s(e){let{configured:t,custom:s}=await Yt(e);console.log(),o.header("MCP Servers (Claude Code target)"),console.log(),o.info("Available servers:");for(let[r,n]of Object.entries(N)){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 Es(e,t,s={}){let r=Pn(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 ce(r,!0);case"disable":return await ce(r,!1);case"sync":return await ce(r,!0);case"add":return await vs(r,t);case"remove":return await ys(r,t);case"list":return await _s(r);case"status":return await Le(r);case"reindex":return await ws(r,s.full);default:return e&&o.warn(`'${e}' is not applicable to the Claude Code target \u2014 showing status instead.`),await Le(r)}let d=a&&c;switch(e){case"status":await hs(r,s.watch),d&&await Le(r);break;case"add":await Ln(r,t),d&&await vs(r,t);break;case"remove":await jn(r,t),d&&await ys(r,t);break;case"list":await Fn(r),d&&await _s(r);break;case"reindex":await ws(r,s.full);break;case"enable":await On(r),d&&await ce(r,!0);break;case"disable":await In(r),d&&await ce(r,!1);break;case"sync":await Mn(r),d&&await ce(r,!0);break;case"approve":await Dn(r);break;default:await hs(r,s.watch),d&&await Le(r)}}import{resolve as Vn}from"node:path";async function Ts(e,t,s,r={}){let n=Vn(r.path||process.cwd());if(!e){bs();return}switch(e){case"add":await Rn(n,t,s);break;case"remove":await Nn(n,t,s);break;case"list":await Gn(n,t);break;default:o.error(`Unknown subcommand: ${e}`),bs()}}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 $t(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 Nn(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 Ot(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 Gn(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 It(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 bs(){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 $s}from"node:path";async function Un(e={}){let t=$s(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 Te({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 $e(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 Os(e={}){try{let t=$s(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 Un({...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 Wn,join as et}from"node:path";async function Bn(e){let t=await g(et(Ee(e),"orchestration.md")),s=await g(et(e,".github","copilot-instructions.md"));return{claude:t,copilot:s}}async function qn(e,t){if(!await g(e))return;let{claude:s,copilot:r}=await Bn(e);if(!s&&!r){t||o.info("Not a vesperized workspace \u2014 nothing to bootstrap. Run `vespercli init` to set up.");return}let n=[],i=await V(["rev-parse","--abbrev-ref","origin/HEAD"],{cwd:e}),a=i===null?-1:i.indexOf("/");if(a===-1)t||o.info("No base branch remote to refresh (origin/HEAD unset or no remote).");else{let l=i.slice(0,a),f=i.slice(a+1);await V(["fetch",l,f],{cwd:e,timeout:15e3})===null?o.warn(`Could not fetch latest ${l}/${f} (network or auth) \u2014 continuing with existing local refs.`):n.push(`origin/${f} fetched (latest base branch ref)`)}if(s){await te(e,!0),n.push(".mcp.json regenerated for this worktree (Claude target)");let l=await De(),f=l.filter(p=>p.synced).map(p=>p.skill),u=l.filter(p=>!p.synced).map(p=>p.skill);if(f.length&&n.push(`GitLab skills synced (${f.join(", ")})`),u.length){let p=`GitLab skills not synced (continuing): ${u.join(", ")}`;n.push(p),o.warn(p)}}r&&await Ae(e)&&(await Q(e,!0),n.push(".vscode/mcp.json refreshed (Copilot target)"));let c=et(e,".vesper","index.db");if(!await g(c)){let l=await Xe(e,!1);l.success&&n.push(`code index built (${l.filesIndexed} files)`)}await we(e);let d=await ve(e);if(d.length>0&&o.warn(`Local-only file(s) git-tracked despite .gitignore: ${d.join(", ")} \u2014 untrack with: git rm --cached ${d.join(" ")}`),await _e(e),await Se(e),await xe(e),n.push("gitignore + git hooks + merge strategy ensured"),!t){o.success("Worktree bootstrap complete");for(let l of n)o.info(` ${l}`)}}async function Is(e,t={}){let s=Wn(t.path||process.cwd()),r=!!t.quiet;switch(e){case"bootstrap":case void 0:await qn(s,r);break;default:o.error(`Unknown subcommand: ${e}. Usage: vespercli worktree bootstrap`),process.exit(1)}}var Yn=zn(import.meta.url),Xn=tt(Yn);function Qn(e){let t=e;for(;t!==tt(t);){let s=Ms(t,"package.json");if(Jn(s))return s;t=tt(t)}return Ms(e,"..","..","package.json")}var Zn=Qn(Xn),st=JSON.parse(Hn(Zn,"utf-8")),L=new Kn;L.name("vespercli").description("Vesper VS Code Agent Suite \u2014 manage GitHub Copilot agents, prompts, instructions, and skills").version(st.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=>is({...e,version:st.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)=>ds({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(ss);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)=>fs({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=>Os({...e,version:st.version}));L.command("catalog").description("Show the Vesper catalog (agents, dependencies, requirements)").action(ms);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)=>Es(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)=>Ts(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)=>Is(e,t));L.addHelpText("after",`
|
|
24
|
+
${r}`;return await S(t,o,"utf-8"),{created:!1,updated:!0}}function $n(e){let t=new RegExp(`${Ze}[\\s\\S]*?${et}\\n*`);return e.replace(t,"")}async function De(e){let t=Ie(e);await B(t,{recursive:!0});let s={orchestrator:"refreshed",orchestration:"skipped",context:"skipped"},n=y(ce,"vesper-orchestrator.md"),r=y(t,"orchestrator.md");await S(r,await $(n,"utf-8"),"utf-8");let o=y(t,"orchestration.md");await g(o)||(await S(o,await $(y(ce,"orchestration.md.tpl"),"utf-8"),"utf-8"),s.orchestration="created");let i=y(t,"context.md");await g(i)||(await S(i,await $(y(ce,"context.md.tpl"),"utf-8"),"utf-8"),s.context="created");let c=await Tn(e);return s.claudeMd=c.created?"created":c.updated?"updated":"unchanged",s}var In="<!-- vesper:adhd:start -->",On="<!-- vesper:adhd:end -->",Mn="<!-- vesper:ponytail:start -->",Dn="<!-- vesper:ponytail:end -->";function rs(){return y(Zt(),".vesperrc")}async function Yt(e,t){return await g(e)?await $(e,"utf-8")===t?"unchanged":(await S(e,t,"utf-8"),"updated"):(await B(le(e),{recursive:!0}),await S(e,t,"utf-8"),"created")}function Ln(){return`# ADHD-friendly output (always on)
|
|
25
|
+
|
|
26
|
+
Shape every response so a reader with ADHD can act on it: lead with the next
|
|
27
|
+
concrete action (a command, path, or snippet \u2014 not preamble), keep it brief and
|
|
28
|
+
scannable, and make progress and completed work visible. Safety and correctness
|
|
29
|
+
always win over brevity, and the harness/system prompt always outranks this rule.
|
|
30
|
+
|
|
31
|
+
Follow the full \`${Ye}\` skill for the specifics
|
|
32
|
+
(\`.claude/skills/${Ye}/SKILL.md\`). It stays in effect for the whole
|
|
33
|
+
session until the reader says "stop adhd mode" or "normal mode".
|
|
34
|
+
`}function Vn(){return`# Ponytail: the laziest solution that works (always on)
|
|
35
|
+
|
|
36
|
+
Prefer the simplest, shortest, most minimal solution \u2014 but only after you
|
|
37
|
+
understand the problem and trace the flow. Climb the ladder, stop at the first
|
|
38
|
+
rung that holds: (1) does this need to exist at all? (YAGNI) (2) already in this
|
|
39
|
+
codebase \u2014 reuse it, (3) stdlib, (4) native platform feature, (5) an
|
|
40
|
+
already-installed dependency, (6) one line, (7) only then the minimum code that
|
|
41
|
+
works. A bug fix targets the root cause in the shared function, not the symptom
|
|
42
|
+
in one caller. No unrequested abstractions.
|
|
43
|
+
|
|
44
|
+
Never lazy about understanding, correctness, or safety: keep input validation,
|
|
45
|
+
error handling, security, and accessibility. Anything the user explicitly asks
|
|
46
|
+
for \u2014 build it in full, no re-arguing. Intensity: \`/ponytail lite|full|ultra\`
|
|
47
|
+
(default full).
|
|
48
|
+
|
|
49
|
+
Follow the full \`${ze}\` skill for the specifics
|
|
50
|
+
(\`.claude/skills/${ze}/SKILL.md\`). It stays in effect for the
|
|
51
|
+
whole session until the user says "stop ponytail" or "normal mode".
|
|
52
|
+
`}var W=[{id:"adhd",vendorDir:An,assetName:Ye,promptText:"Install the third-party i-have-adhd output-style skill? (MIT, reviewed snapshot, added to this repo)",guardStart:In,guardEnd:On,buildRule:Ln,legacyOptIn:e=>e?.adhd?.optIn,legacyInstalled:e=>e?.adhd?.installed===!0,clearLegacy:e=>{delete e.adhd}},{id:"ponytail",vendorDir:Cn,assetName:ze,promptText:"Install the third-party ponytail decision-ladder skill? (MIT, reviewed snapshot, rule-text only, added to this repo)",guardStart:Mn,guardEnd:Dn,buildRule:Vn}];function he(e){let t=W.find(s=>s.id===e);if(!t)throw new Error(`Unknown vendored asset: ${e}`);return t}function as(e,t){return y(t,".claude","skills",e.assetName)}function os(e,t){return y(t,".claude","rules",`${e.assetName}.md`)}async function is(e,{userConfigPath:t}={}){let s=he(e);try{let n=JSON.parse(await $(t||rs(),"utf-8")),r=n?.vendored?.[e]?.optIn;if(typeof r=="boolean")return r;if(s.legacyOptIn){let o=s.legacyOptIn(n);if(typeof o=="boolean")return o}return null}catch{return null}}async function zt(e,t,{userConfigPath:s}={}){he(e);let n=s||rs(),r={};try{r=JSON.parse(await $(n,"utf-8"))||{}}catch{r={}}r.vendored={...r.vendored},r.vendored[e]={...r.vendored[e],optIn:t===!0},await B(le(n),{recursive:!0}),await S(n,JSON.stringify(r,null,2),"utf-8")}async function cs(e,{flag:t,skipPrompts:s,interactive:n,promptFn:r,userConfigPath:o}={}){if(typeof t=="boolean")return await zt(e,t,{userConfigPath:o}),{optIn:t,source:"flag"};let i=await is(e,{userConfigPath:o});if(i!==null)return{optIn:i,source:"stored"};if(s||!n)return{optIn:!1,source:"headless-skip"};let c=await r()===!0;return await zt(e,c,{userConfigPath:o}),{optIn:c,source:"prompt"}}async function ls(e,t){let s=he(e);try{let n=await m(t);return!!(n.vendored?.[e]?.installed===!0||s.legacyInstalled&&s.legacyInstalled(n))}catch{return!1}}async function jn(e,t,s){let n=he(e),r=await m(t);s?(r.vendored={...r.vendored},r.vendored[e]={...r.vendored?.[e],installed:!0,updatedAt:new Date().toISOString()}):(r.vendored&&delete r.vendored[e],n.clearLegacy&&n.clearLegacy(r)),await A(t,r)}async function Fn(e,t){let s=Qe(t),n=[e.guardStart,`@.claude/rules/${e.assetName}.md`,e.guardEnd].join(`
|
|
53
|
+
`),r=new RegExp(`${e.guardStart}[\\s\\S]*?${e.guardEnd}`);if(!await g(s))return await B(le(s),{recursive:!0}),await S(s,`${n}
|
|
54
|
+
`,"utf-8"),"created";let o=await $(s,"utf-8");if(r.test(o)){let c=o.replace(r,n);return c!==o?(await S(s,c,"utf-8"),"updated"):"unchanged"}let i=o.endsWith(`
|
|
55
|
+
`)?`
|
|
56
|
+
`:`
|
|
57
|
+
|
|
58
|
+
`;return await S(s,`${o}${i}${n}
|
|
59
|
+
`,"utf-8"),"updated"}function Nn(e,t){let s=new RegExp(`\\n*${e.guardStart}[\\s\\S]*?${e.guardEnd}\\n*`);return t.replace(s,`
|
|
60
|
+
`)}async function Xe(e,t){let s=he(e),n=await $(y(s.vendorDir,"SKILL.md"),"utf-8"),r=await Yt(y(as(s,t),"SKILL.md"),n),o=await Yt(os(s,t),s.buildRule()),i=await Fn(s,t);return{skill:r,rule:o,claudeMd:i}}async function ds(e,t,s={}){if(await is(e,s)===!0){let n=await Xe(e,t);return await jn(e,t,!0),{action:"introduced",result:n}}return await ls(e,t)?{action:"maintained",result:await Xe(e,t)}:{action:"skipped"}}async function Le(e,t){return await ls(e,t)?{action:"maintained",result:await Xe(e,t)}:{action:"skipped"}}async function ye(e){let t=te(e);try{let s=await $(t,"utf-8");return JSON.parse(s)}catch(s){return s.code==="ENOENT"?{mcpServers:{}}:{mcpServers:{}}}}async function tt(e,t){let s=te(e);await B(le(s),{recursive:!0}),await S(s,JSON.stringify(t,null," "),"utf-8")}function Rn(e){return{"vesper-indexing":{command:"node",args:[H()],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:y(e,".vesper","memory.jsonl")}}}}async function se(e,t=!0){let s=await ye(e);s.mcpServers||(s.mcpServers={});let n=Rn(e),r=Object.keys(n);if(t)for(let[o,i]of Object.entries(n))s.mcpServers[o]=i;else for(let o of r)delete s.mcpServers[o];return await tt(e,s),{configured:t,mcpPath:te(e),servers:t?r:[]}}function Je(e,t){return String(e).replace(/\$\{VESPER_INDEXING_PATH\}/g,H()).replace(/\$\{workspaceFolder\}/g,t).replace(/\$\{env:([^}]+)\}/g,"$${$1}")}function Gn(e,{workspaceRoot:t}){let{type:s,...n}=structuredClone(e);if(typeof n.command=="string"&&(n.command=Je(n.command,t)),Array.isArray(n.args)&&(n.args=n.args.map(r=>Je(r,t))),n.env&&typeof n.env=="object")for(let[r,o]of Object.entries(n.env))n.env[r]=Je(o,t);return n}async function us(e,t){if(Q.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=G[t];if(!s)return{added:!1,serverName:t,error:`Unknown MCP server: ${t}`};let n=await ye(e);if(n.mcpServers||(n.mcpServers={}),n.mcpServers[t])return{added:!1,serverName:t,error:"Already configured"};n.mcpServers[t]=Gn(s.config,{workspaceRoot:e}),await tt(e,n);let r=await m(e);return r.mcp=r.mcp||{},r.mcp.servers=r.mcp.servers||[],r.mcp.servers.includes(t)||r.mcp.servers.push(t),r.mcp.updatedAt=new Date().toISOString(),await A(e,r),{added:!0,serverName:t}}async function ps(e,t){if(Q.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 ye(e),n=!1;s.mcpServers&&s.mcpServers[t]&&(delete s.mcpServers[t],await tt(e,s),n=!0);let r=await m(e);return r.mcp?.servers&&(r.mcp.servers=r.mcp.servers.filter(o=>o!==t),r.mcp.updatedAt=new Date().toISOString(),await A(e,r)),{removed:n,serverName:t}}async function fs(e){let t=await ye(e),s=Object.keys(t.mcpServers||{}),n=s.filter(r=>!G[r]);return{configured:s,custom:n}}async function gs(e){let t=new Set,s=[];try{s=await L(e)}catch{s=[]}if(s.includes("claude"))try{let i=await ye(e);for(let c of Object.keys(i.mcpServers||{}))t.add(c)}catch{}if(s.includes("copilot"))try{let i=await U(e);for(let c of Object.keys(i.servers||{}))t.add(c)}catch{}let n=[];try{let i=await m(e);n=Array.isArray(i.mcp?.servers)?i.mcp.servers:[]}catch{n=[]}let r=new Set(n);return{drifted:[...t].filter(i=>!Q.includes(i)&&!r.has(i))}}async function Ve(e){let t=Oe(e),s={};try{s=JSON.parse(await $(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"],r=0;for(let o of n)s.permissions.allow.includes(o)||(s.permissions.allow.push(o),r+=1);return Bn(s),await B(le(t),{recursive:!0}),await S(t,JSON.stringify(s,null," "),"utf-8"),{configured:r,settingsPath:t}}var ms=".claude/vesper/",Un=`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){}"`,hs="worktree bootstrap",Wn="command -v vespercli >/dev/null 2>&1 && vespercli worktree bootstrap --quiet || true";function Bn(e){e.hooks||(e.hooks={}),Array.isArray(e.hooks.SessionStart)||(e.hooks.SessionStart=[]);let t=s=>e.hooks.SessionStart.some(n=>(n?.hooks||[]).some(r=>typeof r?.command=="string"&&r.command.includes(s)));t(ms)||e.hooks.SessionStart.push({matcher:"clear",hooks:[{type:"command",command:Un}]}),t(hs)||e.hooks.SessionStart.push({hooks:[{type:"command",command:Wn}]})}function Kn(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(ms)||s.command.includes(hs)))),e.hooks.SessionStart.length===0&&delete e.hooks.SessionStart,e.hooks&&Object.keys(e.hooks).length===0&&delete e.hooks)}async function ys(e,t){let s=await m(e);return s.claude={...s.claude,...t,updatedAt:new Date().toISOString()},await A(e,s),s.claude}async function je(e){let t=Ie(e);await Te(t,{recursive:!0,force:!0});for(let o of W)await Te(as(o,e),{recursive:!0,force:!0}),await Te(os(o,e),{force:!0});let s=Qe(e);if(await g(s)){let o=await $(s,"utf-8"),i=W.reduce((c,d)=>Nn(d,c),$n(o));i.trim()?await S(s,i,"utf-8"):await Te(s,{force:!0})}await se(e,!1);let n=Oe(e);if(await g(n))try{let o=JSON.parse(await $(n,"utf-8"));Kn(o),await S(n,JSON.stringify(o,null," "),"utf-8")}catch{}let r=await m(e);delete r.claude,delete r.vendored;for(let o of W)o.clearLegacy&&o.clearLegacy(r);await A(e,r)}F();import{resolve as st,basename as nr}from"node:path";import{rm as rr}from"node:fs/promises";import{confirm as ws}from"@inquirer/prompts";import C from"picocolors";function qn(e){console.log(`${C.green("\u2713")} ${e}`)}function Hn(e){console.log(`${C.red("\u2717")} ${e}`)}function Jn(e){console.log(`${C.yellow("!")} ${e}`)}function Yn(e){console.log(`${C.cyan("\u2192")} ${e}`)}function zn(e){console.log(C.dim(e))}function Xn(e){return C.cyan(e)}function Qn(e){return C.bold(e)}function Zn(e){console.log(),console.log(C.bold(C.underline(e)))}function er(e,t=!1){let s=t?C.green("\u25CF"):C.dim("\u25CB");console.log(` ${s} ${e}`)}function tr(){console.log(),console.log(C.bold(C.magenta("\u{1F3AF} Ready to use Vesper!"))),console.log(C.cyan(' In VS Code Chat, select "Vesper" from the agent dropdown')),console.log(C.cyan(" and start requesting!")),console.log()}function sr(e){let t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],s=0,n=null,r=e,o=()=>{let i=C.cyan(t[s]);process.stdout.write(`\r${i} ${r}`),s=(s+1)%t.length};return{start(){process.stdout.write(`
|
|
61
|
+
`),n=setInterval(o,80),o()},update(i){r=i},stop(){n&&(clearInterval(n),n=null,process.stdout.write("\r"+" ".repeat(r.length+4)+"\r"))},succeed(i){this.stop(),console.log(`${C.green("\u2713")} ${i||r}`)},fail(i){this.stop(),console.log(`${C.red("\u2717")} ${i||r}`)}}}var a={success:qn,error:Hn,warn:Jn,info:Yn,dim:zn,formatPath:Xn,formatName:Qn,header:Zn,listItem:er,vesperTip:tr,createSpinner:sr};async function ar(e={}){let t=st(e.path||process.cwd());if(!(await m(t)).claude){a.warn("Claude Code target is not initialized in this workspace.");return}if(!e.yes&&!await ws({message:"Remove the Claude Code target from this project? (the shared plugin catalog at the user level is left untouched)",default:!1})){a.info("Reset cancelled.");return}await je(t),console.log(),a.success("Claude Code target reset complete."),a.info("Removed: .claude/vesper/, CLAUDE.md guard block, .mcp.json entry, .vesperrc.claude"),a.info("Left untouched: the shared plugin catalog at ~/.claude/skills/vesper/")}function or(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 nt(e){let t=await m(e);await Vt(e);try{let n=await k(e);if(n[w]){let r=new Set(R),o=!1;for(let i of Object.keys(n[w]))r.has(i)||(delete n[w][i],o=!0);o&&await E(e,n)}}catch{}let s=st(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 rr(s,{force:!0})}catch{}}async function vs(e={}){try{let t=st(e.path||process.cwd());await g(t)||(a.error(`Directory not found: ${a.formatPath(t)}`),process.exit(1));let s=e.target;if(!s){let c=await L(t);if(c.length===0){a.warn("Vesper is not initialized in this workspace.");return}c.length>1&&(a.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 ar({...e,path:t});if(!await xe(t)){a.warn("Vesper is not initialized in this workspace.");return}let n=await ie(t);if(n.length===0){a.info("Nothing to reset.");return}let r=or(n);if(!e.yes&&!await ws({message:`Remove all Vesper assets (${r.join(", ")})?`,default:!1})){a.info("Reset cancelled.");return}let o=await m(t),i=await _(t);await nt(t),o.claude&&a.info("Claude Code target detected \u2014 kept its record in .vesperrc"),console.log(),a.success("Vesper reset complete."),o.workspaceType===T.WORKSPACE_FILE||i.type===T.WORKSPACE_FILE?a.info(`Cleaned: ${nr(i.settingsPath)}`):a.info("Cleaned: .vscode/settings.json"),a.info("Reload VS Code to apply changes")}catch(t){if(t.name==="ExitPromptError"){console.log(),a.info("Reset cancelled.");return}a.error(`Reset failed: ${t.message}`),process.exit(1)}}F();import{execFile as ir}from"node:child_process";import{promisify as cr}from"node:util";import{randomUUID as lr}from"node:crypto";import{mkdir as Fe,readdir as dr,rename as rt,rm as Y,stat as ur}from"node:fs/promises";import{join as ne}from"node:path";var pr=cr(ir),_s=[{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(_s.map(e=>e.name)),gr=5*60*1e3;function at(e){process.env.VESPER_DEBUG&&a.dim(`[skill-sync] ${e}`)}async function mr(e,t){if(!fr.has(t))return a.warn(`skill-sync refused: "${t}" is not in the allow-list`),{synced:!1,skill:t};let s=ne(K(),"skills"),n=ne(s,t),r=`${n}.bak`,o=ne(s,`.tmp-${t}-${lr().slice(0,8)}`);try{return await Fe(s,{recursive:!0}),await Y(o,{recursive:!0,force:!0}),await Y(r,{recursive:!0,force:!0}),await pr("git",["clone","--depth","1","--quiet",e,o],{timeout:2e4,env:{...process.env,GIT_HTTP_LOW_SPEED_LIMIT:"1000",GIT_HTTP_LOW_SPEED_TIME:"15"}}),await Y(ne(o,".git"),{recursive:!0,force:!0}),await g(n)&&await rt(n,r),await rt(o,n),await Y(r,{recursive:!0,force:!0}),{synced:!0,skill:t}}catch(i){return at(`sync of ${t} failed: ${i&&i.message?i.message:i}`),await Y(o,{recursive:!0,force:!0}).catch(()=>{}),!await g(n)&&await g(r)&&await rt(r,n).catch(()=>{}),{synced:!1,skill:t}}}async function hr(e){try{return await Fe(e),!0}catch(t){if(t.code!=="EEXIST")return at(`could not acquire lock: ${t.message}`),!1;try{let s=await ur(e);if(Date.now()-s.mtimeMs>gr)return await Y(e,{recursive:!0,force:!0}),await Fe(e),!0}catch{}return!1}}async function Ne(){let e=ne(K(),"skills"),t=ne(e,".sync.lock");try{await Fe(e,{recursive:!0})}catch{return[]}if(!await hr(t))return at("skipped: another process holds the sync lock"),[];try{await yr(e);let n=[];for(let{url:r,name:o}of _s)n.push(await mr(r,o));return n}finally{await Y(t,{recursive:!0,force:!0}).catch(()=>{})}}async function yr(e){let t;try{t=await dr(e,{withFileTypes:!0})}catch{return}for(let s of t)s.isDirectory()&&s.name.startsWith(".tmp-")&&await Y(ne(e,s.name),{recursive:!0,force:!0}).catch(()=>{})}var Ss=["copilot","claude"];function xs(e){return e==="claude"?"Claude Code":"GitHub Copilot"}async function Cr(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 Pr(e,t){let s=await Cr(t);if(e.target){let r=String(e.target).toLowerCase(),o=r==="all"?[...Ss]:r.split(",").map(i=>i.trim()).filter(Boolean);for(let i of o)Ss.includes(i)||(a.error(`Unknown target: ${i}. Valid targets: copilot, claude, all`),process.exit(1));return{selected:[...new Set(o)],installed:s}}return process.stdin.isTTY||(a.error("Non-interactive run without --target. Specify the platform(s), e.g. --target copilot,claude (or --target all)."),process.exit(1)),{selected:await Ar({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 Er(e){return e?"":await kr({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 br(e,t={}){let s=t.yes||t.forceDefault,n=await Er(s);console.log(),a.header("Installing Vesper for Claude Code"),console.log();let{pluginDir:r,counts:o}=await Me({namePrefix:n,version:t.version||"0.0.0"});a.success(`Specialist catalog installed: ${r}`),a.info(` agents: ${o.agents}, commands: ${o.commands}, skills: ${o.skills}`);let i=await Ne(),c=i.filter(u=>u.synced).map(u=>u.skill),d=i.filter(u=>!u.synced).map(u=>u.skill);c.length&&a.success(`GitLab skills synced: ${c.join(", ")}`),d.length&&a.warn(`GitLab skills not synced (continuing): ${d.join(", ")}`);let l=await De(e);a.success("Project files ready:"),a.info(` .claude/vesper/orchestrator.md (${l.orchestrator})`),a.info(` .claude/vesper/orchestration.md (${l.orchestration})`),a.info(` .claude/vesper/context.md (${l.context})`),a.info(` CLAUDE.md (${l.claudeMd})`);let f=await se(e,!0);await Ve(e),a.success(`MCP servers configured: .mcp.json (${f.servers.join(", ")})`);for(let u of W){let p=await cs(u.id,{flag:typeof t[u.id]=="boolean"?t[u.id]:void 0,skipPrompts:s,interactive:!!process.stdin.isTTY,promptFn:()=>re({message:u.promptText,default:!0})}),h=await ds(u.id,e);h.action==="introduced"?a.success(`${u.assetName} skill installed: .claude/skills/${u.assetName}/ + .claude/rules/${u.assetName}.md + CLAUDE.md import`):h.action==="maintained"?a.info(`${u.assetName} asset maintained (already installed in this project).`):p.source==="stored"&&p.optIn===!1&&a.info(`${u.assetName} skill skipped (remembered choice; re-enable with --${u.id}).`)}await ys(e,{pluginPath:K(),namePrefix:n,mcpConfigPath:te(e),settingsPath:Oe(e),installedAt:new Date().toISOString()})}async function Tr(e,t,s){console.log(),a.header("Configuring GitHub Copilot"),console.log();let n=await Bt(e);await Ft(e,{maxRequests:s.maxRequests,omitBaseAgentInstructions:s.omitBaseAgentInstructions});let r=await jt(e,s.terminalEnableAutoApprove),o=!1;return s.enableMcpServer&&(o=(await ee(e,!0)).configured,await Kt(e)),await Ot(e),a.success("Core assets ensured: agents, prompts, instructions, skills"),a.info(`Max agent requests: ${s.maxRequests}`),r.configured>0?a.info(`Terminal auto-approval: ${r.configured} safe commands configured`):s.terminalEnableAutoApprove===!1&&a.info("Terminal auto-approval: disabled"),o&&(a.info("MCP servers: vesper-indexing, sequential-thinking, memory (.vscode/mcp.json)"),a.info("MCP tools auto-approval: vesper-indexing + context7 + sequential-thinking + memory")),n.workspaceType===T.WORKSPACE_FILE?a.info(`Settings added to: ${vr(t.settingsPath)}`):a.info("Settings added to: .vscode/settings.json"),a.info("Tracking file: .vesperrc"),a.info("Worktree bootstrap task: .vscode/tasks.json (runs on folder open)"),{mcpConfigured:o}}async function $r(e,t){let s=await Mt(e);if(!s.found)return{migrated:!1,from:null};let{paths:n}=s;console.log(),a.warn(`Found .vesperrc in nested folder${n.length>1?"s":""}:`);for(let{folderPath:i}of n)a.info(` \u2192 ${i}`);console.log();let r=n[0],o=!0;if(t||(o=await re({message:"Migrate .vesperrc to workspace level? (recommended for multi-root workspaces)",default:!0})),o){let i=await Dt(e,r.vesperrcPath,r.tracking);if(i.success){if(a.success("Migrated .vesperrc to workspace level"),a.info(` From: ${r.vesperrcPath}`),a.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),a.info(` Removed: ${n[d].vesperrcPath}`)}catch{}}return console.log(),{migrated:!0,from:r.folderPath}}}else a.info("Migration skipped. .vesperrc will remain in nested folder."),console.log();return{migrated:!1,from:null}}async function Ir(e){let{migrated:t,changed:s}=await Wt(e);if(!t)return;let n=(o,i)=>`${o} ${i}${o>1?"s":""}`,r=[];s.assetPaths&&r.push(n(s.assetPaths,"asset path")),s.readAccess&&r.push(n(s.readAccess,"read-access path")),s.commandKeys&&r.push(n(s.commandKeys,"stale command")),s.trackingPaths&&r.push(n(s.trackingPaths,"tracked path")),s.mcpArgs&&r.push("MCP server path"),console.log(),a.info("Detected a workspace set up under the older `vesper-cli` package \u2014 migrating install paths."),a.success(`Migrated: ${r.join(", ")}`),console.log()}async function Or(e,t){let s=e;return t||(s=await Sr({message:"Workspace root directory:",default:s})),wr(s)}async function Mr(e,t,s){let n=[];for(let r of t){let o=xs(r),i=s;if(s||(i=await re({message:`${o} is installed but was unchecked. Remove it from this project?`,default:!1})),!i){a.info(`Kept ${o}.`);continue}r==="claude"?await je(e):await nt(e),n.push(r),a.success(`Removed ${o} from this project.`)}return n}async function Dr(e){if(e)return{maxRequests:D.maxRequests,terminalEnableAutoApprove:D.terminalEnableAutoApprove,omitBaseAgentInstructions:D.omitBaseAgentInstructions,enableMcpServer:D.enableMcpServer};console.log(),a.info("Configure VS Code Chat settings:");let t=await xr({message:"Max agent requests per session (chat.agent.maxRequests):",default:D.maxRequests,min:1,max:1e3}),s=await re({message:"Controls whether terminal commands are automatically approved. Enable terminal auto-approval? (chat.tools.terminal.enableAutoApprove)",default:D.terminalEnableAutoApprove});s&&a.info("Terminal auto-approval enabled with safe command whitelist");let n=await re({message:"Omit base agent instructions for custom agents? (github.copilot.chat.omitBaseAgentInstructions)",default:D.omitBaseAgentInstructions}),r=await re({message:"Enable vesper-indexing MCP server for fast code search?",default:D.enableMcpServer});return{maxRequests:t||D.maxRequests,terminalEnableAutoApprove:s,omitBaseAgentInstructions:n,enableMcpServer:r}}async function ot(e,t=!1){let s=H().replace("index.js","cli-index.js");if(!await g(s))return{success:!1,error:"MCP server not built"};t&&(console.log(),a.info("Starting workspace indexing..."));let n=t?null:a.createSpinner("Indexing workspace...");return n&&n.start(),new Promise(r=>{let o=_r("node",[s,e],{stdio:["ignore","pipe","pipe"],env:{...process.env}}),i="",c=0;o.stderr.on("data",d=>{let l=d.toString().trim(),f=l.match(/Indexed (\d+) files/);if(f&&(c=parseInt(f[1],10),n&&n.update(`Indexing workspace... ${c} files`)),t&&l)for(let u of l.split(`
|
|
62
|
+
`))u.trim()&&a.info(u.replace("[vesper-indexing] ",""))}),o.stdout.on("data",d=>{i+=d.toString()}),o.on("close",d=>{try{let l=JSON.parse(i.trim());l.success?n?n.succeed(`Workspace indexed: ${l.filesIndexed} files`):a.success(`Workspace indexed: ${l.filesIndexed} files`):n?n.fail(`Indexing failed: ${l.error}`):a.error(`Indexing failed: ${l.error}`),r(l)}catch{d===0?(n?n.succeed(`Workspace indexed: ${c} files`):a.success(`Workspace indexed: ${c} files`),r({success:!0,filesIndexed:c})):(n?n.fail("Indexing failed"):a.error("Indexing failed"),r({success:!1,error:"Unknown error"}))}}),o.on("error",d=>{n?n.fail(`Indexing failed: ${d.message}`):a.error(`Indexing failed: ${d.message}`),r({success:!1,error:d.message})})})}function Lr({copilot:e,claude:t,indexingResult:s}){console.log(),a.success("Vesper is ready."),s?.success?a.info(`Code index built: ${s.filesIndexed} files.`):s?.error&&a.info("Code index will be built on first MCP server start."),console.log(),a.header("Next Steps"),console.log(),e&&(a.info("GitHub Copilot \u2014 reload VS Code to activate Vesper:"),a.info(' Cmd+Shift+P (macOS) / Ctrl+Shift+P (Windows/Linux) \u2192 "Developer: Reload Window"')),t&&(a.info("Claude Code \u2014 open a session in this workspace; the orchestrator"),a.info(" activates automatically via CLAUDE.md.")),console.log(),e&&a.vesperTip()}async function ks(e={}){try{let t=e.yes||e.forceDefault,s=await Or(e.path||process.cwd(),t);await g(s)||(a.error(`Directory not found: ${a.formatPath(s)}`),process.exit(1));let n=await _(s);n.type===T.WORKSPACE_FILE&&await $r(s,t),await Ir(s);let{selected:r,installed:o}=await Pr(e,s),i=o.filter(p=>!r.includes(p));if(r.length===0&&i.length===0){a.info("No platforms selected. Nothing to do.");return}if(!t&&o.length===0&&r.length>0&&!await re({message:`Set up ${r.map(xs).join(" + ")} in ${s}?`,default:!0})){a.info("Initialization cancelled.");return}i.length>0&&await Mr(s,i,t);let c=r.includes("copilot"),d=r.includes("claude"),l=null;if(c&&(l=await Dr(t)),c&&await Tr(s,n,l),d&&await br(s,e),c||d){await _e(s);let p=await Se(s);p.length>0&&(a.warn(`Local-only file(s) are git-tracked despite .gitignore: ${p.join(", ")}`),a.warn(`Untrack them yourself (Vesper won't touch your git index): git rm --cached ${p.join(" ")}`)),(await ke(s))["pre-commit"]?.hooksDir&&(a.success("Local-only Vesper files gitignored (.vesperrc, .mcp.json, .vesper/index.db)"),a.info("Commit-hygiene git hook installed (pre-commit): keeps team roster/context/history/memory in sync with every commit"),await Ae(s),await Ce(s),a.info("Merge strategy configured (.gitattributes): history.md unions, memory.jsonl merges entity-aware across worktrees"))}let f=c&&l?.enableMcpServer||d,u=null;f&&(u=await ot(s,!0)),Lr({copilot:c,claude:d,indexingResult:u})}catch(t){if(t.name==="ExitPromptError"){console.log(),a.info("Initialization cancelled.");return}a.error(`Initialization failed: ${t.message}`),process.exit(1)}}F();import{resolve as Cs,basename as Vr}from"node:path";import{checkbox as Ps,select as jr}from"@inquirer/prompts";var As={agents:"agents",prompts:"commands",skills:"skills"};async function Fr(e,t){let s=await L(e);if(s.length===1)return s[0];s.length===0&&(a.warn('Vesper is not initialized in this workspace. Run "vespercli init" first.'),process.exit(0)),a.error(`Both Copilot and Claude targets are installed here \u2014 specify which to ${t}: --target copilot|claude`),process.exit(1)}async function Nr(e={}){let t=Cs(e.path||process.cwd());(!e.type||!e.name)&&(a.error("Usage: vesper add <type> <name> --target claude"),a.info("Types: agents, prompts (installed as slash commands), skills"),process.exit(1));let s=As[e.type];s||(a.error(`Unknown asset type for --target claude: ${e.type}`),a.info(`Available types: ${Object.keys(As).join(", ")}`),process.exit(1));let r=(await m(t)).claude?.namePrefix??"";try{let o=await ss(s,e.name,{namePrefix:r});a.success(`Added ${e.type}/${e.name} to the Claude plugin catalog as "${o.installedAs}"`)}catch(o){a.error(o.message),process.exit(1)}}var we=["agents","prompts","instructions"];async function it(e,t){let s=await ie(e);return(await oe(t)).filter(r=>{let o=Z(t,r);return!s.includes(o.path)})}async function Rr(e){let t=[];for(let i of we){let c=await it(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 a.info("All extended assets are already added."),[];let s=await jr({message:"Select asset type:",choices:t}),r=(await it(e,s)).map(i=>({name:i,value:i,checked:!1}));return(await Ps({message:`Select ${s} to add:`,choices:r})).map(i=>({type:s,name:i}))}async function Es(e={}){try{let t=Cs(e.path||process.cwd());if(await g(t)||(a.error(`Directory not found: ${a.formatPath(t)}`),process.exit(1)),(e.target||await Fr(t,"add"))==="claude")return await Nr({...e,path:t});if(!await xe(t)){a.warn('Vesper is not initialized. Run "vespercli init" first.');return}let n=[];if(e.type&&e.name){if(e.type==="skills"){a.info("Skills are automatically added during init.");return}we.includes(e.type)||(a.error(`Unknown asset type: ${e.type}`),a.info(`Available types: ${we.join(", ")}`),process.exit(1));let l=await oe(e.type);l.includes(e.name)||(a.error(`Asset not found: ${e.name}`),a.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"){a.info("Skills are automatically added during init.");return}we.includes(e.type)||(a.error(`Unknown asset type: ${e.type}`),a.info(`Available types: ${we.join(", ")}`),process.exit(1));let l=await it(t,e.type);if(l.length===0){a.info(`All ${e.type} are already added.`);return}let f=l.map(p=>({name:p,value:p,checked:!1})),u=await Ps({message:`Select ${e.type} to add:`,choices:f});if(u.length===0){a.info("Nothing selected.");return}n=u.map(p=>({type:e.type,name:p}))}else if(n=await Rr(t),n.length===0){a.info("Nothing selected.");return}let r=n.map(({type:l,name:f})=>Z(l,f)),{added:o,skipped:i,workspaceType:c}=await Lt(t,r),d=n.filter(l=>l.type==="agents"&&o.includes(Z(l.type,l.name).path));for(let{name:l}of d)qe[l]&&(await qt(t,l),a.info(` Added MCP tools auto-approval for agent: ${l}`));if(o.length>0){let l=await _(t);console.log(),a.success(`Added ${o.length} asset(s):`);for(let{type:f,name:u}of n.filter(p=>o.includes(Z(p.type,p.name).path)))a.info(` ${f}/${u}`);c===T.WORKSPACE_FILE&&a.info(`
|
|
63
|
+
Updated: ${Vr(l.settingsPath)}`),a.info(`
|
|
64
|
+
Reload VS Code to apply changes`)}else i.length>0&&a.info("All selected assets are already added.")}catch(t){if(t.name==="ExitPromptError"){console.log(),a.info("Cancelled.");return}a.error(`Add failed: ${t.message}`),process.exit(1)}}F();import{resolve as Ts,join as Gr}from"node:path";import{readdir as Ur}from"node:fs/promises";import q from"picocolors";async function bs(e={}){let t=Ts(e.path||process.cwd()),s=await m(t);if(console.log(),console.log(q.bold("Claude Code target")),!s.claude){console.log(),a.warn('Not initialized for Claude Code. Run "vesper init --target claude" first.'),console.log();return}let n=s.claude.pluginPath||K();console.log(q.dim(`Plugin catalog: ${n}`));let r=await ns();for(let[o,i]of Object.entries(r))console.log(),console.log(q.bold(o.charAt(0).toUpperCase()+o.slice(1))),i.length===0?console.log(q.dim(" (none installed)")):i.forEach(c=>console.log(` ${c}`));console.log(),console.log(q.bold("Project files")),console.log(" CLAUDE.md, .claude/vesper/{orchestrator,orchestration,context}.md, .mcp.json, .claude/settings.json"),console.log()}async function Wr(e,t,s=!1){try{let n=await Ur(e,{withFileTypes:!0});return s||t.dir==="skills"?n.filter(o=>o.isDirectory()&&!o.name.startsWith(".")).map(o=>o.name):n.filter(o=>o.isFile()&&o.name.endsWith(t.extension)).map(o=>o.name.replace(t.extension,""))}catch{return[]}}async function $s(e={}){try{let t=Ts(e.path||process.cwd());await g(t)||(a.error(`Directory not found: ${a.formatPath(t)}`),process.exit(1));let s=await L(t);if(e.target==="claude")return await bs({...e,path:t});if(!e.target){if(s.length===0){console.log(),a.warn('Vesper is not initialized. Run "vespercli init" first.'),console.log();return}if(s.length===1&&s[0]==="claude")return await bs({...e,path:t});s.includes("claude")&&a.info("Claude Code target is also installed here \u2014 run `vespercli list --target claude` to see it.")}let n=await ie(t);e.type&&!M[e.type]&&(a.error(`Unknown asset type: ${e.type}`),a.info(`Valid types: ${Object.keys(M).join(", ")}`),process.exit(1));let r=e.type?[e.type]:Object.keys(M);console.log(),console.log(q.bold("Assets"));for(let o of r){let i=M[o],c=o.charAt(0).toUpperCase()+o.slice(1);if(o==="skills"){let p=Ut("skills");if(n.includes(p.path)){let h=await oe("skills");console.log(),console.log(q.bold(`${c}`)),console.log(` ${h.length} skills enabled ${q.dim("(all)")}`)}continue}let d=Gr(pt,i.dir),l=await Wr(d,i,!1),u=(await oe(o)).filter(p=>{let h=Z(o,p);return n.includes(h.path)});(l.length>0||u.length>0)&&(console.log(),console.log(q.bold(`${c}`)),l.forEach(p=>{console.log(` ${p} ${q.dim("(core)")}`)}),u.forEach(p=>{console.log(` ${p}`)}))}console.log()}catch(t){a.error(`List failed: ${t.message}`),process.exit(1)}}import{readFileSync as Br,existsSync as Kr}from"node:fs";import{join as qr}from"node:path";var Is="catalog.md",Hr="mthanhtran",Jr="vesper",Yr="main";function zr(){return`https://raw.githubusercontent.com/${Hr}/${Jr}/${Yr}/assets/${Is}`}function Xr(){let e=qr(ae,"assets",Is);return Kr(e)?Br(e,"utf-8"):null}async function Qr(){try{let e=zr(),t=await fetch(e);return t.ok?t.text():null}catch{return null}}async function Zr(){let e=await Qr();if(e)return e;let t=Xr();if(t)return t;throw new Error("Catalog not available from remote or local")}async function Os(){try{let e=await Zr();console.log(e)}catch(e){console.error(`Error loading catalog: ${e.message}`),process.exit(1)}}F();import{resolve as ea,join as Ge,dirname as Ms}from"node:path";import{stat as ta,readFile as Ns}from"node:fs/promises";import"@inquirer/prompts";import j from"picocolors";async function Re(e){let t=await m(e);if(console.log(),a.header("vesper-indexing MCP Server (Claude Code target)"),console.log(),!t.claude){a.info("Claude Code target is not initialized. Run `vesper init --target claude` first.");return}let s=te(e),n=!1;if(await g(s))try{n=!!JSON.parse(await Ns(s,"utf-8")).mcpServers?.["vesper-indexing"]}catch{n=!1}a.info(`Configured: ${n?"\u2713 yes":"\u2717 no"} (${s})`),a.info(`Server built: ${Us(await Gs())}`);let r=ct(e);a.info(`Index exists: ${await g(r)?"\u2713 yes":"\u2717 no"} (shared with the Copilot target if both are installed)`);try{let{drifted:o}=await gs(e);o.length&&(console.log(),a.warn(`MCP config drift: ${o.join(", ")} present in the live MCP config but not tracked in .vesperrc mcp.servers.`),a.warn("Run `/reinit` (or re-run workspace-learner) to resync tracking and the generated docs."))}catch{}}async function de(e,t=!0){await se(e,t),t&&await Ve(e),a.success(`Claude Code target: vesper-indexing ${t?"enabled":"disabled"} in .mcp.json`)}function ct(e){return Ge(e,".vesper","index.db")}function sa(e){return Ge(e,".vesper","indexing-status.json")}async function Rs(e){let t=sa(e);try{let s=await Ns(t,"utf-8");return JSON.parse(s)}catch{return null}}async function Gs(){let e=H();if(!await g(e))return"missing";let t=Ms(Ms(e)),s=[Ge(t,"node_modules","@modelcontextprotocol","sdk","package.json"),Ge(t,"node_modules","zod","package.json")];for(let n of s)if(!await g(n))return"broken";return"ready"}function Us(e){switch(e){case"ready":return"\u2713 yes";case"broken":return"\u26A0 yes, but dependencies missing \u2014 run 'npm install' in src/mcp/vesper-indexing (or reinstall Vesper)";default:return"\u2717 no"}}async function na(e){try{let t=await ta(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 Ds(e,t=!1){let s=await be(e),n=await Gs(),r=ct(e),o=await g(r),i=await Rs(e);if(console.log(),a.header("vesper-indexing MCP Server"),console.log(),a.info(`Configured: ${s?"\u2713 yes":"\u2717 no"}`),a.info(`Server built: ${Us(n)}`),a.info(`Index exists: ${o?"\u2713 yes":"\u2717 no"}`),i)if(console.log(),i.status==="indexing")if(t){await ra(e,i);return}else{let c=i.startedAt?Math.round((Date.now()-new Date(i.startedAt).getTime())/1e3):0;a.info(j.yellow("\u27F3 Indexing in progress...")),a.info(` Files processed: ${j.cyan(i.filesProcessed)}`),a.info(` Elapsed: ${j.dim(`${c}s`)}`),console.log(),a.info("Use --watch to follow indexing progress until completion")}else i.status==="error"&&(a.error(`Indexing error: ${i.error}`),a.info(` Files processed before error: ${i.filesProcessed}`));if(!s){console.log(),a.info("Run `vespercli init` to configure the MCP server");return}if(n==="missing"){console.log(),a.warn("MCP server not built. Run: cd src/mcp/vesper-indexing && npm install && npm run build");return}if(n==="broken"){console.log(),a.warn("MCP server dependencies are missing/corrupt. Run: cd src/mcp/vesper-indexing && npm install (or reinstall Vesper)");return}if(o&&!i){let c=await na(r);c&&(console.log(),a.info(`Index size: ${c.dbSize}`),a.info(`Last modified: ${c.lastModified}`)),a.vesperTip()}else!o&&!i&&(console.log(),a.info("Index not yet created. It will be built when VS Code loads the MCP server."),console.log())}async function ra(e,t){let s=a.createSpinner(`Indexing... ${t.filesProcessed} files processed`);s.start();let n=500,r=30*60*1e3,o=Date.now();return new Promise(i=>{let c=async()=>{let d=await Rs(e);if(!d||d.status!=="indexing"){d?.status==="error"?s.fail(`Indexing failed: ${d.error}`):(s.succeed(`Indexing complete! ${d?.filesProcessed||"All"} files indexed`),a.info(`
|
|
65
|
+
\u2192 Reload VS Code to update MCP tools with the new index`),a.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()-o>r){s.fail("Indexing watch timed out (30 minutes)"),i();return}setTimeout(c,n)};setTimeout(c,n)})}async function Ls(e,t=!1){let s=ct(e);if(!await g(s))a.info("No index exists. It will be built when VS Code loads the MCP server.");else if(t){let{unlink:r}=await import("node:fs/promises");await r(s),a.success("Index cleared. Reload VS Code to rebuild.")}else a.info("Incremental reindex happens automatically when files change."),a.info("Use --full to clear and rebuild the entire index.")}async function aa(e){let t=await ee(e,!0);t.configured&&(a.success("MCP server enabled"),a.info(`Config: ${t.mcpPath}`),a.info("Reload VS Code to start the server"))}async function oa(e){await ee(e,!1),a.success("MCP server disabled"),a.info("Reload VS Code to apply changes")}async function Ws(e){let t=await _(e),s=await m(e,t);if(!Array.isArray(s.paths))return[];let n=[];for(let r of s.paths){let o=r.match(/agents\/([^/]+)\/?$/);o&&MCP_TOOLS_BY_AGENT[o[1]]&&n.push(o[1])}return n}async function ia(e){let t=await _(e),s=await m(e,t),n=await k(e,t),r=await Ws(e),o=n[w]||{},i=new Set(R),c=[],d=[],l=!1;n[w]||(n[w]={});for(let u of R)o[u]||(n[w][u]=!0,c.push(u),l=!0);for(let u of r){let p=MCP_TOOLS_BY_AGENT[u]||[];for(let h of p)o[h]||(n[w][h]=!0,c.push(h),l=!0)}let f=new Set;for(let u of r)for(let p of MCP_TOOLS_BY_AGENT[u]||[])f.add(p);for(let u of Object.keys(o)){if(i.has(u))continue;let p=!1;for(let[h,O]of Object.entries(MCP_TOOLS_BY_AGENT))if(O.includes(u)){p=!0;break}p&&!f.has(u)&&(delete n[w][u],d.push(u),l=!0)}if(s.mcp=s.mcp||{},s.mcp.syncedAt=new Date().toISOString(),s.mcp.approvedAgents=r,s.mcp.toolCount=Object.keys(n[w]).length,l&&await E(e,n),await A(e,s),console.log(),a.header("MCP Tools Sync"),console.log(),c.length===0&&d.length===0)a.success("Already in sync");else{if(c.length>0){a.success(`Added ${c.length} tool(s)`);let u=c.filter(p=>i.has(p));u.length>0&&a.info(` Core: ${u.length} tools`);for(let p of r){let h=c.filter(O=>(MCP_TOOLS_BY_AGENT[p]||[]).includes(O));h.length>0&&a.info(` ${p}: ${h.length} tools`)}}d.length>0&&a.info(`Removed ${d.length} orphaned tool(s)`)}a.info(`
|
|
66
|
+
Total approved tools: ${s.mcp.toolCount}`),r.length>0&&a.info(`Agents with tools: ${r.join(", ")}`),l&&a.info(`
|
|
67
|
+
Reload VS Code to apply changes`)}async function ca(e){let t=await _(e),s=await m(e,t),r=(await k(e,t))[w]||{},o=Object.keys(r).length,i=await Ws(e);console.log(),a.header("MCP Tool Approval Status"),console.log();let c=R.filter(f=>r[f]);if(a.info(`Core tools: ${c.length}/${R.length} approved`),i.length>0){console.log(),a.info("Agent tools:");for(let f of i){let u=MCP_TOOLS_BY_AGENT[f]||[],p=u.filter(O=>r[O]),h=p.length===u.length?j.green("\u2713"):j.yellow("\u26A0");a.info(` ${h} ${f}: ${p.length}/${u.length} approved`)}}let d=[...R];for(let f of i)d.push(...MCP_TOOLS_BY_AGENT[f]||[]);let l=d.filter(f=>!r[f]);console.log(),a.info(`Total approved: ${o} tools`),l.length>0?(console.log(),a.warn(`${l.length} tools missing approval`),a.info("Run `vespercli mcp sync` to fix")):s.mcp?.syncedAt&&a.info(`Last synced: ${s.mcp.syncedAt}`)}function Bs(){return Object.keys(G).filter(e=>!Q.includes(e))}async function la(e,t){t||(a.error("Server name required. Usage: vespercli mcp add <server>"),a.info(`Available servers: ${Bs().join(", ")}`),process.exit(1)),console.log(),a.header("Add MCP Server"),console.log();let s=await Ht(e,t);if(!s.added){s.error==="Already configured"?a.info(`MCP server '${t}' is already configured`):(a.error(s.error),process.exit(1));return}a.success(`Added MCP server: ${t}`),s.tools.length>0&&a.info(`Approved ${s.tools.length} tool(s) for auto-execution`),a.info(`
|
|
68
|
+
Reload VS Code to activate the MCP server`)}async function da(e,t){t||(a.error("Server name required. Usage: vespercli mcp remove <server>"),process.exit(1)),console.log(),a.header("Remove MCP Server"),console.log();let s=await Jt(e,t);if(!s.removed){a.info(`MCP server '${t}' is not configured`);return}a.success(`Removed MCP server: ${t}`),s.tools.length>0&&a.info(`Removed ${s.tools.length} tool(s) from auto-approval`),a.info(`
|
|
69
|
+
Reload VS Code to deactivate the MCP server`)}async function ua(e){let t=await _(e),s=await m(e,t),n=await U(e);console.log(),a.header("MCP Servers"),console.log();let r=s.mcp?.servers||[],o=Object.keys(n.servers||{});a.info("Available servers:");for(let[c,d]of Object.entries(G)){let f=o.includes(c)?j.green("\u2713"):j.dim("\u25CB"),u=d.tools?.length||0;a.info(` ${f} ${c} (${u} tools)`)}let i=o.filter(c=>!G[c]);if(i.length>0){console.log(),a.info("Custom servers:");for(let c of i)a.info(` ${j.blue("\u25C6")} ${c}`)}console.log(),a.info(`Installed: ${o.length} server(s)`)}async function Vs(e,t){t||(a.error("Server name required. Usage: vespercli mcp add <server> --target claude"),a.info(`Available servers: ${Bs().join(", ")}`),process.exit(1));let s=await us(e,t);if(!s.added){s.error==="Already configured"?a.info(`MCP server '${t}' is already configured for the Claude Code target`):a.error(s.error);return}a.success(`Added MCP server: ${t} (Claude Code target)`),a.info(`
|
|
70
|
+
Reload the Claude Code session to activate the MCP server`)}async function js(e,t){t||(a.error("Server name required. Usage: vespercli mcp remove <server> --target claude"),process.exit(1));let s=await ps(e,t);if(s.error){a.error(s.error);return}if(!s.removed){a.info(`MCP server '${t}' is not configured for the Claude Code target`);return}a.success(`Removed MCP server: ${t} (Claude Code target)`),a.info(`
|
|
71
|
+
Reload the Claude Code session to deactivate the MCP server`)}async function Fs(e){let{configured:t,custom:s}=await fs(e);console.log(),a.header("MCP Servers (Claude Code target)"),console.log(),a.info("Available servers:");for(let[n,r]of Object.entries(G)){let i=t.includes(n)?j.green("\u2713"):j.dim("\u25CB"),c=r.tools?.length||0;a.info(` ${i} ${n} (${c} tools)`)}if(s.length>0){console.log(),a.info("Custom servers:");for(let n of s)a.info(` ${j.blue("\u25C6")} ${n}`)}console.log(),a.info(`Installed: ${t.length} server(s)`)}async function Ks(e,t,s={}){let n=ea(s.path||process.cwd());await g(n)||(a.error(`Directory not found: ${n}`),process.exit(1));let r=await L(n),o=s.target?[s.target]:r.length?r:["copilot"],i=o.includes("copilot"),c=o.includes("claude");if(c&&!i)switch(e){case"enable":return await de(n,!0);case"disable":return await de(n,!1);case"sync":return await de(n,!0);case"add":return await Vs(n,t);case"remove":return await js(n,t);case"list":return await Fs(n);case"status":return await Re(n);case"reindex":return await Ls(n,s.full);default:return e&&a.warn(`'${e}' is not applicable to the Claude Code target \u2014 showing status instead.`),await Re(n)}let d=i&&c;switch(e){case"status":await Ds(n,s.watch),d&&await Re(n);break;case"add":await la(n,t),d&&await Vs(n,t);break;case"remove":await da(n,t),d&&await js(n,t);break;case"list":await ua(n),d&&await Fs(n);break;case"reindex":await Ls(n,s.full);break;case"enable":await aa(n),d&&await de(n,!0);break;case"disable":await oa(n),d&&await de(n,!1);break;case"sync":await ia(n),d&&await de(n,!0);break;case"approve":await ca(n);break;default:await Ds(n,s.watch),d&&await Re(n)}}import{resolve as pa}from"node:path";async function Hs(e,t,s,n={}){let r=pa(n.path||process.cwd());if(!e){qs();return}switch(e){case"add":await fa(r,t,s);break;case"remove":await ga(r,t,s);break;case"list":await ma(r,t);break;default:a.error(`Unknown subcommand: ${e}`),qs()}}async function fa(e,t,s){if(!t){a.error("Setting key required"),a.info("Usage: vespercli settings add <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!s){a.error("Path value required"),a.info("Usage: vespercli settings add read-access <path>");return}let n=await Nt(e,s);a.success(`Added "${s}" to additional read access paths`),a.info(`Current paths: ${n.length>0?n.join(", "):"(none)"}`);break;default:a.error(`Unknown setting: ${t}`),a.info("Supported settings:"),a.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function ga(e,t,s){if(!t){a.error("Setting key required"),a.info("Usage: vespercli settings remove <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!s){a.error("Path value required"),a.info("Usage: vespercli settings remove read-access <path>");return}let n=await Rt(e,s);a.success(`Removed "${s}" from additional read access paths`),a.info(`Current paths: ${n.length>0?n.join(", "):"(none)"}`);break;default:a.error(`Unknown setting: ${t}`),a.info("Supported settings:"),a.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function ma(e,t){if(!t){a.info("Managed settings:"),a.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)"),a.info(""),a.info("Use: vespercli settings list <setting-key>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":let s=await Gt(e);a.info(`${x}:`),s.length===0?a.info(" (empty)"):s.forEach(n=>a.info(` - ${n}`));break;default:a.error(`Unknown setting: ${t}`),a.info("Supported settings:"),a.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}function qs(){a.info("Usage: vespercli settings <subcommand> [setting-key] [value]"),a.info(""),a.info("Subcommands:"),a.info(" add <setting-key> <value> Add a value to an array setting"),a.info(" remove <setting-key> <value> Remove a value from an array setting"),a.info(" list [setting-key] List current values"),a.info(""),a.info("Supported settings:"),a.info(" read-access github.copilot.chat.additionalReadAccessPaths"),a.info(""),a.info("Examples:"),a.info(" vespercli settings add read-access /path/to/external/repo"),a.info(" vespercli settings remove read-access /path/to/external/repo"),a.info(" vespercli settings list read-access")}F();import{resolve as Js}from"node:path";async function ha(e={}){let t=Js(e.path||process.cwd()),s=await m(t);if(!s.claude){a.warn('Claude Code target is not initialized. Run "vesper init --target claude" first.');return}console.log(),a.info("Refreshing Claude Code plugin catalog and orchestrator playbook...");let{pluginDir:n,counts:r}=await Me({namePrefix:s.claude.namePrefix||"",version:e.version||"0.0.0"});a.success(`Plugin catalog refreshed: ${n}`),a.info(` agents: ${r.agents}, commands: ${r.commands}, skills: ${r.skills}`);let o=await De(t);a.success(`Orchestrator playbook refreshed (.claude/vesper/orchestrator.md: ${o.orchestrator})`),a.info("Team roster (.claude/vesper/orchestration.md) and project context (.claude/vesper/context.md) are left alone \u2014 they belong to this project.");for(let i of W)(await Le(i.id,t)).action==="maintained"&&a.info(`${i.assetName} asset refreshed (already opted in for this project).`)}async function Ys(e={}){try{let t=Js(e.path||process.cwd());await g(t)||(a.error(`Directory not found: ${a.formatPath(t)}`),process.exit(1));let s=e.target?[e.target]:await L(t);if(s.length===0){a.warn('Vesper is not initialized. Run "vespercli init" first.');return}s.includes("claude")&&await ha({...e,path:t}),s.includes("copilot")&&(console.log(),a.info("Copilot assets are linked from the package, not copied."),a.info("Update the vesper package to get the latest assets:"),a.dim(" npm update -g @mthanh/vespercli"),console.log())}catch(t){a.error(`Update failed: ${t.message}`),process.exit(1)}}F();import{resolve as ya,join as lt}from"node:path";async function wa(e){let t=await g(lt(Ie(e),"orchestration.md")),s=await g(lt(e,".github","copilot-instructions.md"));return{claude:t,copilot:s}}async function va(e,t){if(!await g(e))return;let{claude:s,copilot:n}=await wa(e);if(!s&&!n){t||a.info("Not a vesperized workspace \u2014 nothing to bootstrap. Run `vespercli init` to set up.");return}let r=[],o=await N(["rev-parse","--abbrev-ref","origin/HEAD"],{cwd:e}),i=o===null?-1:o.indexOf("/");if(i===-1)t||a.info("No base branch remote to refresh (origin/HEAD unset or no remote).");else{let l=o.slice(0,i),f=o.slice(i+1);await N(["fetch",l,f],{cwd:e,timeout:15e3})===null?a.warn(`Could not fetch latest ${l}/${f} (network or auth) \u2014 continuing with existing local refs.`):r.push(`origin/${f} fetched (latest base branch ref)`)}if(s){await se(e,!0),r.push(".mcp.json regenerated for this worktree (Claude target)");let l=await Ne(),f=l.filter(p=>p.synced).map(p=>p.skill),u=l.filter(p=>!p.synced).map(p=>p.skill);if(f.length&&r.push(`GitLab skills synced (${f.join(", ")})`),u.length){let p=`GitLab skills not synced (continuing): ${u.join(", ")}`;r.push(p),a.warn(p)}for(let p of W)(await Le(p.id,e)).action==="maintained"&&r.push(`${p.assetName} asset maintained (project-level)`)}n&&await be(e)&&(await ee(e,!0),r.push(".vscode/mcp.json refreshed (Copilot target)"));let c=lt(e,".vesper","index.db");if(!await g(c)){let l=await ot(e,!1);l.success&&r.push(`code index built (${l.filesIndexed} files)`)}await _e(e);let d=await Se(e);if(d.length>0&&a.warn(`Local-only file(s) git-tracked despite .gitignore: ${d.join(", ")} \u2014 untrack with: git rm --cached ${d.join(" ")}`),await ke(e),await Ae(e),await Ce(e),r.push("gitignore + git hooks + merge strategy ensured"),!t){a.success("Worktree bootstrap complete");for(let l of r)a.info(` ${l}`)}}async function zs(e,t={}){let s=ya(t.path||process.cwd()),n=!!t.quiet;switch(e){case"bootstrap":case void 0:await va(s,n);break;default:a.error(`Unknown subcommand: ${e}. Usage: vespercli worktree bootstrap`),process.exit(1)}}var Aa=ka(import.meta.url),Ca=dt(Aa);function Pa(e){let t=e;for(;t!==dt(t);){let s=Xs(t,"package.json");if(xa(s))return s;t=dt(t)}return Xs(e,"..","..","package.json")}var Ea=Pa(Ca),ut=JSON.parse(Sa(Ea,"utf-8")),V=new _a;V.name("vespercli").description("Vesper VS Code Agent Suite \u2014 manage GitHub Copilot agents, prompts, instructions, and skills").version(ut.version,"-v, --version","Output the current version");V.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.").option("--adhd","Install the third-party i-have-adhd output-style skill (Claude target); remembers the choice").option("--no-adhd","Do not install the i-have-adhd skill (Claude target); remembers the choice").option("--ponytail","Install the third-party ponytail decision-ladder skill (Claude target); remembers the choice").option("--no-ponytail","Do not install the ponytail skill (Claude target); remembers the choice").action(e=>ks({...e,version:ut.version}));V.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)=>Es({type:e,name:t,...s}));V.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(vs);V.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)=>$s({type:e,...t}));V.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=>Ys({...e,version:ut.version}));V.command("catalog").description("Show the Vesper catalog (agents, dependencies, requirements)").action(Os);V.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)=>Ks(e,t,s));V.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)=>Hs(e,t,s,n));V.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)=>zs(e,t));V.addHelpText("after",`
|
|
36
72
|
Examples:
|
|
37
73
|
$ vespercli init Pick platform(s) to set up (multi-select), then initialize
|
|
38
74
|
$ vespercli init --target copilot,claude Set up both platforms in one run
|
|
@@ -67,4 +103,4 @@ Multi-platform notes:
|
|
|
67
103
|
|
|
68
104
|
Documentation:
|
|
69
105
|
https://github.com/mthanhtran/vesper
|
|
70
|
-
`);
|
|
106
|
+
`);V.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mthanh/vespercli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.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",
|