@mthanh/vespercli 1.3.3 → 1.4.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 +15 -8
- package/dist/cli.min.js +20 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,8 +18,8 @@ npx @mthanh/vespercli <command>
|
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
# Initialize Vesper in your project
|
|
21
|
-
# (
|
|
22
|
-
# pass --target copilot
|
|
21
|
+
# (multi-select which platform(s) to set up — GitHub Copilot and/or Claude Code;
|
|
22
|
+
# pass --target copilot,claude or --target all to skip the prompt)
|
|
23
23
|
vespercli init
|
|
24
24
|
|
|
25
25
|
# (Optional) Add local overrides to customize specific assets
|
|
@@ -98,15 +98,22 @@ If Vesper detects a legacy install that previously copied assets into `.vesper/`
|
|
|
98
98
|
|
|
99
99
|
### `vespercli init`
|
|
100
100
|
|
|
101
|
-
Initialize Vesper in your workspace.
|
|
101
|
+
Initialize Vesper in your workspace. Pick one or more platforms (GitHub Copilot
|
|
102
|
+
and/or Claude Code) via a multi-select prompt; the CLI lays down the base setup
|
|
103
|
+
for each, then the Vesper agent handles orchestration.
|
|
102
104
|
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
+
- Copilot: creates/updates `.vscode/settings.json` so VS Code discovers Vesper assets from the installed package.
|
|
106
|
+
- Claude Code: installs the user-level plugin catalog + this project's orchestrator/roster/context and `.mcp.json`.
|
|
107
|
+
- Shared: builds the code index once (both platforms' `vesper-indexing` read the same `.vesper/index.db`).
|
|
108
|
+
|
|
109
|
+
On re-init, currently-installed platforms are pre-checked; **uncheck a platform to remove it** (you'll be asked to confirm). Platform selection is always asked — `-y` / `--force-default` only default the *follow-up* questions, not the platform choice. In non-interactive runs, pass `--target`.
|
|
105
110
|
|
|
106
111
|
```bash
|
|
107
|
-
vespercli init
|
|
108
|
-
vespercli init
|
|
109
|
-
vespercli init --
|
|
112
|
+
vespercli init # Multi-select platform(s), then initialize
|
|
113
|
+
vespercli init --target copilot,claude # Set up both in one run (no prompt)
|
|
114
|
+
vespercli init --target all # Every supported platform
|
|
115
|
+
vespercli init --target claude -y # Non-interactive: Claude with default settings
|
|
116
|
+
vespercli init --path /my/project # Specify workspace path
|
|
110
117
|
```
|
|
111
118
|
|
|
112
119
|
### `vespercli add`
|
package/dist/cli.min.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
var Ht=(e,t)=>()=>(e&&(t=e(e=0)),t);import{access as Xt,constants as Qt,stat as Qn}from"node:fs/promises";async function h(e){try{return await Xt(e,Qt.F_OK),!0}catch{return!1}}var L=Ht(()=>{});import{Command as Wn}from"commander";import{readFileSync as Gn,existsSync as qn}from"node:fs";import{fileURLToPath as Bn}from"node:url";import{dirname as De,join as Yt}from"node:path";L();import{resolve as kt,basename as At,join as $e}from"node:path";import{spawn as Ws}from"node:child_process";import{confirm as K,input as Gs,number as qs,select as Ct}from"@inquirer/prompts";import{readFile as N,writeFile as H,mkdir as Se,readdir as os}from"node:fs/promises";import{join as k,dirname as Q}from"node:path";import{homedir as Ve}from"node:os";import is from"strip-json-comments";import{fileURLToPath as Zt}from"node:url";import{dirname as ye,join as re,resolve as es}from"node:path";import{readdir as ts}from"node:fs/promises";import{existsSync as ss}from"node:fs";var ns=Zt(import.meta.url),rs=ye(ns);function as(e){let t=e;for(;t!==ye(t);){if(ss(re(t,"package.json")))return t;t=ye(t)}return es(e,"..","..","..")}var J=as(rs),I=re(J,"assets"),Fe=re(I,"core");function _e(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 $={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 Y(e){let t=$[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=re(I,t.dir);try{return(await ts(s,{withFileTypes:!0})).filter(a=>a.isDirectory()&&!a.name.startsWith(".")).map(a=>a.name)}catch{return[]}}function Le(e,t){_e(t);let s=$[e];if(!s)throw new Error(`Unknown asset type: ${e}`);return re(I,s.dir,t)}function V(e){let t=Ve();return e.startsWith(t)?"~"+e.slice(t.length).replace(/\\/g,"/"):e.replace(/\\/g,"/")}var cs=/node_modules\/(?:vesper-cli|vespercli)\/(.+)$/;function de(e){if(typeof e!="string")return e;let t=e.match(cs);return t?V(k(J,t[1])):e}function ls(e){return e==="vesper-cli"||e.startsWith("vesper-cli ")||e.endsWith("/vesper-cli")}var X={agents:"chat.agentFilesLocations",instructions:"chat.instructionsFilesLocations",prompts:"chat.promptFilesLocations",skills:"chat.agentSkillsLocations"},ae="chat.tools.terminal.autoApprove",je="chat.tools.terminal.enableAutoApprove",xe="chat.tools.autoApprove",w="chat.tools.eligibleForAutoApproval",Ue="chat.agent.maxRequests",We="chat.includeReferencedInstructions",Ge="chat.customAgentInSubagent.enabled",qe="chat.agent.enabled",Be="github.copilot.chat.omitBaseAgentInstructions",ze="chat.mcp.discovery.enabled",Ke="chat.mcp.autoStart",_="github.copilot.chat.additionalReadAccessPaths",b={maxRequests:300,terminalEnableAutoApprove:!0,omitBaseAgentInstructions:!0,enableMcpServer:!0},ds=[Ue,We,Ge,qe,Be,ze,Ke,je,ae,xe,w],ps=["vesper-indexing","sequential-thinking","memory"],Ne=["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"],M=["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"],ke={"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"]},oe={"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 A={FOLDER:"folder",WORKSPACE_FILE:"workspace"};async function us(e){try{let s=(await os(e,{withFileTypes:!0})).find(n=>n.isFile()&&n.name.endsWith(".code-workspace"));return s?k(e,s.name):null}catch{return null}}async function y(e){let t=await us(e);return t?{type:A.WORKSPACE_FILE,settingsPath:t,workspaceFile:t}:{type:A.FOLDER,settingsPath:k(e,".vscode","settings.json"),workspaceFile:null}}function Ae(e,t=null){return t?.workspaceFile?k(Q(t.workspaceFile),".vesperrc"):k(e,".vesperrc")}function pe(e){let t=is(e,{trailingCommas:!0});return JSON.parse(t)}async function S(e){let t=await y(e);try{let s=await N(t.settingsPath,"utf-8"),n=pe(s);return t.type===A.WORKSPACE_FILE?n.settings||{}:n}catch(s){if(s.code==="ENOENT")return{};if(s instanceof SyntaxError){if(t.type===A.WORKSPACE_FILE)throw new Error(`Failed to parse workspace file: ${t.settingsPath}. ${s.message}`);return{}}throw s}}async function C(e,t){let s=await y(e);if(s.type===A.WORKSPACE_FILE){let n;try{let a=await N(s.settingsPath,"utf-8");n=pe(a)}catch(a){if(a.code==="ENOENT")n={folders:[],settings:{}};else throw new Error(`Failed to read workspace file: ${s.settingsPath}. ${a.message}`)}n.settings=t,await H(s.settingsPath,JSON.stringify(n,null," "),"utf-8")}else{let n=Q(s.settingsPath);await Se(n,{recursive:!0}),await H(s.settingsPath,JSON.stringify(t,null," "),"utf-8")}}function fs(e){return k(e,".vesper","tracking.json")}async function m(e){let t=await y(e),s=Ae(e,t),n=fs(e),a=k(e,".vesperrc");try{let o=await N(s,"utf-8");return JSON.parse(o)}catch{if(s!==a)try{let o=await N(a,"utf-8");return JSON.parse(o)}catch{}try{let o=await N(n,"utf-8");return JSON.parse(o)}catch{return{paths:[],addedAt:null,workspaceType:null,settingsPath:null}}}}async function gs(e){return await Ce(e)}async function Je(e){return await gs(e)}async function ms(e){try{let t=await N(e,"utf-8"),n=pe(t).folders||[],a=Q(e);return n.map(o=>{let i=o.path||o;return i.startsWith("/")||i.startsWith("~")?i.replace(/^~/,Ve()):k(a,i)})}catch{return[]}}async function Ye(e){let t=await y(e);if(t.type!==A.WORKSPACE_FILE)return{found:!1,paths:[]};let s=Q(t.workspaceFile),n=k(s,".vesperrc"),a=await ms(t.workspaceFile),o=[];for(let i of a){let c=k(i,".vesperrc");if(c!==n)try{let l=await N(c,"utf-8"),d=JSON.parse(l);o.push({folderPath:i,vesperrcPath:c,tracking:d})}catch{}}return{found:o.length>0,paths:o}}async function He(e,t,s){let n=await y(e),a=Ae(e,n),o={...s,workspaceType:A.WORKSPACE_FILE,settingsPath:n.settingsPath,migratedFrom:t,migratedAt:new Date().toISOString()};await H(a,JSON.stringify(o,null,2),"utf-8");try{let{unlink:i}=await import("node:fs/promises");await i(t)}catch{}return{success:!0,newPath:a}}async function P(e,t){let s=await y(e),n=Ae(e,s);await H(n,JSON.stringify(t,null,2),"utf-8")}async function Xe(e,t){let s=await y(e),n=await S(e),a=await m(e),o=[],i=[];for(let{path:c,settingKey:l}of t){if(n[l]||(n[l]={}),n[l][c]){i.push(c),a.paths.includes(c)||a.paths.push(c);continue}n[l][c]=!0,o.push(c),a.paths.includes(c)||a.paths.push(c)}return o.length>0&&await C(e,n),a.paths.length>0&&(a.addedAt=a.addedAt||new Date().toISOString(),a.updatedAt=new Date().toISOString(),a.workspaceType=s.type,a.settingsPath=s.settingsPath,await P(e,a)),{added:o,skipped:i,workspaceType:s.type}}async function Ce(e){let t=await S(e),s=await m(e),n={paths:[],settings:[],mcpServers:[],agentTools:[]},a=/vespercli|vesper-cli/;for(let u of Object.values(X))if(t[u]){for(let p of Object.keys(t[u])){let f=s.paths?.includes(p),g=a.test(p);(f||g)&&(delete t[u][p],n.paths.includes(p)||n.paths.push(p))}Object.keys(t[u]).length===0&&delete t[u]}let o=s.readAccessPaths||[];if(o.length>0){let u=t[_]||[],p=u.filter(f=>!o.includes(f));p.length!==u.length&&(p.length>0?t[_]=p:delete t[_],n.settings.push(_))}for(let u of ds)t[u]!==void 0&&(delete t[u],n.settings.push(u));let i=s.mcp?.agentTools||{};for(let[u,p]of Object.entries(i))n.agentTools.push({agent:u,tools:p});(n.paths.length>0||n.settings.length>0)&&await C(e,t);let c=await U(e),l=s.mcp?.servers||[],d=[...new Set([...ps,...l])];if(c.servers){for(let u of d)c.servers[u]&&(delete c.servers[u],n.mcpServers.push(u));if(n.mcpServers.length>0){let u=ue(e),p=Q(u);await Se(p,{recursive:!0}),await H(u,JSON.stringify(c,null," "),"utf-8")}}return await P(e,{paths:[],readAccessPaths:[],addedAt:null,workspaceType:null,settingsPath:null,mcp:null}),{removed:n}}async function Z(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 hs=["agents","prompts","instructions"];function ws(){let e=[];for(let n of hs){let a=$[n],o=X[n];if(o&&a){let i=V(k(I,"core",a.dir));e.push({path:i,settingKey:o,type:n})}}let t=X.skills;if(t){let n=V(k(I,"core","skills"));e.push({path:n,settingKey:t,type:"skills"})}let s=$.skills;if(t&&s){let n=V(k(I,s.dir));e.push({path:n,settingKey:t,type:"skills"})}return e}async function Qe(e,t=!0){let s=await y(e),n=await S(e);if(n[je]=t,t){n[ae]||(n[ae]={});for(let a of Ne)n[ae][a]=!0}return await C(e,n),{configured:t?Ne.length:0,workspaceType:s.type}}async function Ze(e,t={}){let{maxRequests:s=b.maxRequests,omitBaseAgentInstructions:n=b.omitBaseAgentInstructions}=t,a=await S(e);a[Ue]=s,a[We]=!0,a[Ge]=!0,a[qe]=!0,a[Be]=n,a[ze]=!0,a[Ke]="newAndOutdated",a[_]||(a[_]=[]),await C(e,a)}async function et(e,t){let s=await S(e),n=s[_]||[];n.includes(t)||(n.push(t),s[_]=n,await C(e,s));let a=await m(e);return a.readAccessPaths||(a.readAccessPaths=[]),a.readAccessPaths.includes(t)||(a.readAccessPaths.push(t),a.updatedAt=new Date().toISOString(),await P(e,a)),n}async function tt(e,t){let s=await S(e),n=s[_]||[],a=n.indexOf(t);a!==-1&&(n.splice(a,1),s[_]=n,await C(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 P(e,o))}return n}async function st(e){return(await S(e))[_]||[]}function nt(e){let t=$[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=X[e];return{path:V(k(I,t.dir)),settingKey:s,type:e}}function G(e,t){if(_e(t),!$[e])throw new Error(`Unknown asset type: ${e}`);let n=X[e];return{path:V(Le(e,t)),settingKey:n,type:e,name:t}}async function ee(e){return(await m(e)).paths}async function rt(e){let t={assetPaths:0,readAccess:0,commandKeys:0,trackingPaths:0,mcpArgs:0},s=(p,f)=>{let g=[];for(let E of p){let ne=de(E);ne!==E&&t[f]++,g.includes(ne)||g.push(ne)}return g},n=await S(e),a=!1;for(let p of Object.values(X)){let f=n[p];if(!(!f||typeof f!="object"))for(let g of Object.keys(f)){let E=de(g);if(E===g)continue;let ne=f[g];delete f[g],f[E]=f[E]===!0?!0:ne,t.assetPaths++,a=!0}}if(Array.isArray(n[_])){let p=t.readAccess;n[_]=s(n[_],"readAccess"),t.readAccess!==p&&(a=!0)}let o=n[ae];if(o&&typeof o=="object")for(let p of Object.keys(o))ls(p)&&(delete o[p],t.commandKeys++,a=!0);a&&await C(e,n);let i=await m(e),c=!1;if(Array.isArray(i.paths)){let p=t.trackingPaths;i.paths=s(i.paths,"trackingPaths"),t.trackingPaths!==p&&(c=!0)}if(Array.isArray(i.readAccessPaths)){let p=[];for(let f of i.readAccessPaths){let g=de(f);g!==f&&(c=!0),p.includes(g)||p.push(g)}i.readAccessPaths=p}c&&(i.updatedAt=new Date().toISOString(),await P(e,i));let l=await U(e),d=l.servers?.["vesper-indexing"];if(d&&Array.isArray(d.args)){let p=!1;d.args=d.args.map(f=>{let g=de(f);return g!==f&&(t.mcpArgs++,p=!0),g}),p&&await fe(e,l)}return{migrated:t.assetPaths+t.readAccess+t.commandKeys+t.trackingPaths+t.mcpArgs>0,changed:t}}async function at(e){let t=await y(e),s=await S(e),n=await m(e),a=ws(),o=[],i=[];for(let{path:d,settingKey:u}of a)s[u]||(s[u]={}),s[u][d]===!0?i.push(d):(s[u][d]=!0,o.push(d)),n.paths.includes(d)||n.paths.push(d);let c=I,l=s[_]||[];return l.includes(c)||(l.push(c),s[_]=l,o.push(c)),n.readAccessPaths||(n.readAccessPaths=[]),n.readAccessPaths.includes(c)||n.readAccessPaths.push(c),o.length>0&&await C(e,s),n.addedAt=n.addedAt||new Date().toISOString(),n.updatedAt=new Date().toISOString(),n.workspaceType=t.type,n.settingsPath=t.settingsPath,await P(e,n),{added:o,existed:i,workspaceType:t.type}}function ue(e){return k(e,".vscode","mcp.json")}function j(){return k(J,"src","mcp","vesper-indexing","dist","index.js")}async function U(e){let t=ue(e);try{let s=await N(t,"utf-8");return pe(s)}catch(s){if(s.code==="ENOENT")return{servers:{}};if(s instanceof SyntaxError)return{servers:{}};throw s}}async function fe(e,t){let s=ue(e),n=Q(s);await Se(n,{recursive:!0}),await H(s,JSON.stringify(t,null," "),"utf-8")}async function ie(e,t=!0){let s=await U(e),n=V(j()),a=[];if(s.servers||(s.servers={}),t?(s.servers["vesper-indexing"]={type:"stdio",command:"node",args:[n],env:{VESPER_INDEX_ROOT:"${workspaceFolder}"}},a.push("vesper-indexing"),s.servers["sequential-thinking"]={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},a.push("sequential-thinking"),s.servers.memory={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:"${workspaceFolder}/.vesper/memory.jsonl"}},a.push("memory")):(delete s.servers["vesper-indexing"],delete s.servers["sequential-thinking"],delete s.servers.memory),await fe(e,s),t&&a.length>0){let o=await m(e);o.mcp=o.mcp||{},o.mcp.servers=a,o.mcp.updatedAt=new Date().toISOString(),await P(e,o)}return{configured:t,mcpPath:ue(e),servers:a}}async function ot(e){return!!(await U(e)).servers?.["vesper-indexing"]}async function it(e){let t=await y(e),s=await S(e);s[xe]=!1,s[w]||(s[w]={});for(let n of M)s[w][n]=!0;return await C(e,s),{configured:M.length,workspaceType:t.type}}async function ct(e,t){let s=ke[t];if(!s||s.length===0)return{added:[],agentName:t};let n=await S(e),a=await y(e),o=await m(e,a);n[w]||(n[w]={});let i=[];for(let c of s)n[w][c]||(n[w][c]=!0,i.push(c));return i.length>0&&(await C(e,n),o.mcp=o.mcp||{},o.mcp.agentTools=o.mcp.agentTools||{},o.mcp.agentTools[t]=s,o.mcp.updatedAt=new Date().toISOString(),await P(e,o)),{added:i,agentName:t}}async function lt(e,t){let s=oe[t];if(!s)return{added:!1,serverName:t,tools:[],error:`Unknown MCP server: ${t}`};let n=await U(e),a=await S(e),o=await y(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 d=V(j());c.args&&(c.args=c.args.map(u=>u==="${VESPER_INDEXING_PATH}"?d:u))}n.servers[t]=c,await fe(e,n),a[w]||(a[w]={});let l=[];for(let d of s.tools||[])a[w][d]||(a[w][d]=!0,l.push(d));return a[xe]=!1,await C(e,a),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 P(e,i),{added:!0,serverName:t,tools:l}}async function dt(e,t){let s=oe[t],n=await U(e),a=await S(e),o=await y(e),i=await m(e,o),c=!1;n.servers&&n.servers[t]&&(delete n.servers[t],await fe(e,n),c=!0);let l=[];if(s&&a[w]){for(let d of s.tools||[])a[w][d]&&(delete a[w][d],l.push(d));l.length>0&&await C(e,a)}return i.mcp?.servers&&(i.mcp.servers=i.mcp.servers.filter(d=>d!==t),i.mcp.updatedAt=new Date().toISOString(),await P(e,i)),{removed:c,serverName:t,tools:l}}import{readFile as R,writeFile as T,mkdir as q,readdir as ut,rm as pt,cp as ft}from"node:fs/promises";import{join as v,dirname as Pe,basename as vs}from"node:path";import{homedir as ys}from"node:os";L();var te=v(I,"claude"),gt=["agents","commands","skills"],ge="vesper";function B(e=ge){return v(ys(),".claude","skills",e)}function mt(e){return v(e,".claude","vesper")}function ht(e){return v(e,"CLAUDE.md")}function z(e){return v(e,".mcp.json")}function me(e){return v(e,".claude","settings.json")}function wt(e,t){return t?e.replace(/^(name:\s*)([a-z0-9-]+)/m,(s,n,a)=>a.startsWith(t)?s:`${n}${t}${a}`):e}async function _s(e,t,s,n){if(!await h(e))return{copied:0};await q(t,{recursive:!0});let a=await ut(e,{withFileTypes:!0}),o=0;for(let i of a){let c=v(e,i.name);if(i.isDirectory()){await ft(c,v(t,i.name),{recursive:!0}),o+=1;continue}if(!i.name.endsWith(".md"))continue;let l=await R(c,"utf-8"),d=wt(l,s),u=n&&s&&!i.name.startsWith(s)?`${s}${i.name}`:i.name;await T(v(t,u),d,"utf-8"),o+=1}return{copied:o}}async function Ss(e,t,s){let n=v(e,".claude-plugin");await q(n,{recursive:!0});let a={name:t,description:"Vesper specialist catalog \u2014 subagents, slash commands, and skills for AI-orchestrated development.",version:s};await T(v(n,"plugin.json"),JSON.stringify(a,null,2),"utf-8")}async function he({pluginName:e=ge,namePrefix:t="",version:s="0.0.0"}={}){let n=B(e),a={};for(let o of gt){let i=v(te,o),c=v(n,o),d=await _s(i,c,o==="skills"?"":t,o!=="skills");a[o]=d.copied}return await Ss(n,e,s),{pluginDir:n,counts:a}}async function vt(e,t,{pluginName:s=ge,namePrefix:n=""}={}){let a=B(s),o=v(a,e);if(await q(o,{recursive:!0}),e==="skills"){let p=v(te,"skills",t);if(!await h(p))throw new Error(`Skill "${t}" not found in assets/claude/skills/`);return await ft(p,v(o,t),{recursive:!0}),{installedAs:t}}let i=".md",c=v(te,e,`${t}${i}`);if(!await h(c))throw new Error(`${e.slice(0,-1)} "${t}" not found in assets/claude/${e}/`);let l=await R(c,"utf-8"),d=wt(l,n),u=n&&!t.startsWith(n)?`${n}${t}${i}`:`${t}${i}`;return await T(v(o,u),d,"utf-8"),{installedAs:vs(u,i)}}async function yt(e=ge){let t=B(e),s={};for(let n of gt){let a=v(t,n);if(!await h(a)){s[n]=[];continue}let o=await ut(a,{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 Ee="<!-- vesper:start -->",Te="<!-- vesper:end -->";function xs(){return[Ee,"@.claude/vesper/orchestrator.md","@.claude/vesper/orchestration.md","@.claude/vesper/context.md",Te].join(`
|
|
2
|
-
`)}async function
|
|
3
|
-
`,"utf-8"),{created:!0,updated:!1};let
|
|
1
|
+
var Yt=(e,t)=>()=>(e&&(t=e(e=0)),t);import{access as Ht,constants as zt,stat as tr}from"node:fs/promises";async function h(e){try{return await Ht(e,zt.F_OK),!0}catch{return!1}}var N=Yt(()=>{});import{Command as Bn}from"commander";import{readFileSync as Kn,existsSync as Jn}from"node:fs";import{fileURLToPath as Yn}from"node:url";import{dirname as De,join as Jt}from"node:path";N();import{resolve as Gs,basename as qs}from"node:path";import{spawn as Bs}from"node:child_process";import{confirm as ee,input as Ks,number as Js,select as Ys,checkbox as Hs}from"@inquirer/prompts";import{readFile as R,writeFile as H,mkdir as xe,readdir as rs}from"node:fs/promises";import{join as A,dirname as X}from"node:path";import{homedir as je}from"node:os";import os from"strip-json-comments";import{fileURLToPath as Xt}from"node:url";import{dirname as _e,join as ne,resolve as Qt}from"node:path";import{readdir as Zt}from"node:fs/promises";import{existsSync as es}from"node:fs";var ts=Xt(import.meta.url),ss=_e(ts);function ns(e){let t=e;for(;t!==_e(t);){if(es(ne(t,"package.json")))return t;t=_e(t)}return Qt(e,"..","..","..")}var J=ns(ss),O=ne(J,"assets"),Le=ne(O,"core");function Se(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 b={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 Y(e){let t=b[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=ne(O,t.dir);try{return(await Zt(s,{withFileTypes:!0})).filter(o=>o.isDirectory()&&!o.name.startsWith(".")).map(o=>o.name)}catch{return[]}}function Ne(e,t){Se(t);let s=b[e];if(!s)throw new Error(`Unknown asset type: ${e}`);return ne(O,s.dir,t)}function j(e){let t=je();return e.startsWith(t)?"~"+e.slice(t.length).replace(/\\/g,"/"):e.replace(/\\/g,"/")}var as=/node_modules\/(?:vesper-cli|vespercli)\/(.+)$/;function le(e){if(typeof e!="string")return e;let t=e.match(as);return t?j(A(J,t[1])):e}function is(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"},re="chat.tools.terminal.autoApprove",Ve="chat.tools.terminal.enableAutoApprove",Ae="chat.tools.autoApprove",v="chat.tools.eligibleForAutoApproval",Ue="chat.agent.maxRequests",We="chat.includeReferencedInstructions",Ge="chat.customAgentInSubagent.enabled",qe="chat.agent.enabled",Be="github.copilot.chat.omitBaseAgentInstructions",Ke="chat.mcp.discovery.enabled",Je="chat.mcp.autoStart",_="github.copilot.chat.additionalReadAccessPaths",$={maxRequests:300,terminalEnableAutoApprove:!0,omitBaseAgentInstructions:!0,enableMcpServer:!0},cs=[Ue,We,Ge,qe,Be,Ke,Je,Ve,re,Ae,v],ls=["vesper-indexing","sequential-thinking","memory"],Re=["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"],M=["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"],Ce={"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"]},oe={"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 k={FOLDER:"folder",WORKSPACE_FILE:"workspace"};async function ds(e){try{let s=(await rs(e,{withFileTypes:!0})).find(n=>n.isFile()&&n.name.endsWith(".code-workspace"));return s?A(e,s.name):null}catch{return null}}async function y(e){let t=await ds(e);return t?{type:k.WORKSPACE_FILE,settingsPath:t,workspaceFile:t}:{type:k.FOLDER,settingsPath:A(e,".vscode","settings.json"),workspaceFile:null}}function ke(e,t=null){return t?.workspaceFile?A(X(t.workspaceFile),".vesperrc"):A(e,".vesperrc")}function de(e){let t=os(e,{trailingCommas:!0});return JSON.parse(t)}async function S(e){let t=await y(e);try{let s=await R(t.settingsPath,"utf-8"),n=de(s);return t.type===k.WORKSPACE_FILE?n.settings||{}:n}catch(s){if(s.code==="ENOENT")return{};if(s instanceof SyntaxError){if(t.type===k.WORKSPACE_FILE)throw new Error(`Failed to parse workspace file: ${t.settingsPath}. ${s.message}`);return{}}throw s}}async function C(e,t){let s=await y(e);if(s.type===k.WORKSPACE_FILE){let n;try{let o=await R(s.settingsPath,"utf-8");n=de(o)}catch(o){if(o.code==="ENOENT")n={folders:[],settings:{}};else throw new Error(`Failed to read workspace file: ${s.settingsPath}. ${o.message}`)}n.settings=t,await H(s.settingsPath,JSON.stringify(n,null," "),"utf-8")}else{let n=X(s.settingsPath);await xe(n,{recursive:!0}),await H(s.settingsPath,JSON.stringify(t,null," "),"utf-8")}}function ps(e){return A(e,".vesper","tracking.json")}async function g(e){let t=await y(e),s=ke(e,t),n=ps(e),o=A(e,".vesperrc");try{let a=await R(s,"utf-8");return JSON.parse(a)}catch{if(s!==o)try{let a=await R(o,"utf-8");return JSON.parse(a)}catch{}try{let a=await R(n,"utf-8");return JSON.parse(a)}catch{return{paths:[],addedAt:null,workspaceType:null,settingsPath:null}}}}async function us(e){try{let t=await R(e,"utf-8"),n=de(t).folders||[],o=X(e);return n.map(a=>{let i=a.path||a;return i.startsWith("/")||i.startsWith("~")?i.replace(/^~/,je()):A(o,i)})}catch{return[]}}async function Ye(e){let t=await y(e);if(t.type!==k.WORKSPACE_FILE)return{found:!1,paths:[]};let s=X(t.workspaceFile),n=A(s,".vesperrc"),o=await us(t.workspaceFile),a=[];for(let i of o){let c=A(i,".vesperrc");if(c!==n)try{let d=await R(c,"utf-8"),l=JSON.parse(d);a.push({folderPath:i,vesperrcPath:c,tracking:l})}catch{}}return{found:a.length>0,paths:a}}async function He(e,t,s){let n=await y(e),o=ke(e,n),a={...s,workspaceType:k.WORKSPACE_FILE,settingsPath:n.settingsPath,migratedFrom:t,migratedAt:new Date().toISOString()};await H(o,JSON.stringify(a,null,2),"utf-8");try{let{unlink:i}=await import("node:fs/promises");await i(t)}catch{}return{success:!0,newPath:o}}async function P(e,t){let s=await y(e),n=ke(e,s);await H(n,JSON.stringify(t,null,2),"utf-8")}async function ze(e,t){let s=await y(e),n=await S(e),o=await g(e),a=[],i=[];for(let{path:c,settingKey:d}of t){if(n[d]||(n[d]={}),n[d][c]){i.push(c),o.paths.includes(c)||o.paths.push(c);continue}n[d][c]=!0,a.push(c),o.paths.includes(c)||o.paths.push(c)}return a.length>0&&await C(e,n),o.paths.length>0&&(o.addedAt=o.addedAt||new Date().toISOString(),o.updatedAt=new Date().toISOString(),o.workspaceType=s.type,o.settingsPath=s.settingsPath,await P(e,o)),{added:a,skipped:i,workspaceType:s.type}}async function Xe(e){let t=await S(e),s=await g(e),n={paths:[],settings:[],mcpServers:[],agentTools:[]},o=/vespercli|vesper-cli/;for(let u of Object.values(z))if(t[u]){for(let p of Object.keys(t[u])){let f=s.paths?.includes(p),m=o.test(p);(f||m)&&(delete t[u][p],n.paths.includes(p)||n.paths.push(p))}Object.keys(t[u]).length===0&&delete t[u]}let a=s.readAccessPaths||[];if(a.length>0){let u=t[_]||[],p=u.filter(f=>!a.includes(f));p.length!==u.length&&(p.length>0?t[_]=p:delete t[_],n.settings.push(_))}for(let u of cs)t[u]!==void 0&&(delete t[u],n.settings.push(u));let i=s.mcp?.agentTools||{};for(let[u,p]of Object.entries(i))n.agentTools.push({agent:u,tools:p});(n.paths.length>0||n.settings.length>0)&&await C(e,t);let c=await U(e),d=s.mcp?.servers||[],l=[...new Set([...ls,...d])];if(c.servers){for(let u of l)c.servers[u]&&(delete c.servers[u],n.mcpServers.push(u));if(n.mcpServers.length>0){let u=ue(e),p=X(u);await xe(p,{recursive:!0}),await H(u,JSON.stringify(c,null," "),"utf-8")}}return await P(e,{paths:[],readAccessPaths:[],addedAt:null,workspaceType:null,settingsPath:null,mcp:null}),{removed:n}}async function pe(e){return(await g(e)).paths.length>0}async function D(e){let t=await g(e),s=[];return Array.isArray(t.paths)&&t.paths.length>0&&s.push("copilot"),t.claude&&s.push("claude"),s}var fs=["agents","prompts","instructions"];function gs(){let e=[];for(let n of fs){let o=b[n],a=z[n];if(a&&o){let i=j(A(O,"core",o.dir));e.push({path:i,settingKey:a,type:n})}}let t=z.skills;if(t){let n=j(A(O,"core","skills"));e.push({path:n,settingKey:t,type:"skills"})}let s=b.skills;if(t&&s){let n=j(A(O,s.dir));e.push({path:n,settingKey:t,type:"skills"})}return e}async function Qe(e,t=!0){let s=await y(e),n=await S(e);if(n[Ve]=t,t){n[re]||(n[re]={});for(let o of Re)n[re][o]=!0}return await C(e,n),{configured:t?Re.length:0,workspaceType:s.type}}async function Ze(e,t={}){let{maxRequests:s=$.maxRequests,omitBaseAgentInstructions:n=$.omitBaseAgentInstructions}=t,o=await S(e);o[Ue]=s,o[We]=!0,o[Ge]=!0,o[qe]=!0,o[Be]=n,o[Ke]=!0,o[Je]="newAndOutdated",o[_]||(o[_]=[]),await C(e,o)}async function et(e,t){let s=await S(e),n=s[_]||[];n.includes(t)||(n.push(t),s[_]=n,await C(e,s));let o=await g(e);return o.readAccessPaths||(o.readAccessPaths=[]),o.readAccessPaths.includes(t)||(o.readAccessPaths.push(t),o.updatedAt=new Date().toISOString(),await P(e,o)),n}async function tt(e,t){let s=await S(e),n=s[_]||[],o=n.indexOf(t);o!==-1&&(n.splice(o,1),s[_]=n,await C(e,s));let a=await g(e);if(a.readAccessPaths){let i=a.readAccessPaths.indexOf(t);i!==-1&&(a.readAccessPaths.splice(i,1),a.updatedAt=new Date().toISOString(),await P(e,a))}return n}async function st(e){return(await S(e))[_]||[]}function nt(e){let t=b[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=z[e];return{path:j(A(O,t.dir)),settingKey:s,type:e}}function G(e,t){if(Se(t),!b[e])throw new Error(`Unknown asset type: ${e}`);let n=z[e];return{path:j(Ne(e,t)),settingKey:n,type:e,name:t}}async function Q(e){return(await g(e)).paths}async function rt(e){let t={assetPaths:0,readAccess:0,commandKeys:0,trackingPaths:0,mcpArgs:0},s=(p,f)=>{let m=[];for(let T of p){let se=le(T);se!==T&&t[f]++,m.includes(se)||m.push(se)}return m},n=await S(e),o=!1;for(let p of Object.values(z)){let f=n[p];if(!(!f||typeof f!="object"))for(let m of Object.keys(f)){let T=le(m);if(T===m)continue;let se=f[m];delete f[m],f[T]=f[T]===!0?!0:se,t.assetPaths++,o=!0}}if(Array.isArray(n[_])){let p=t.readAccess;n[_]=s(n[_],"readAccess"),t.readAccess!==p&&(o=!0)}let a=n[re];if(a&&typeof a=="object")for(let p of Object.keys(a))is(p)&&(delete a[p],t.commandKeys++,o=!0);o&&await C(e,n);let i=await g(e),c=!1;if(Array.isArray(i.paths)){let p=t.trackingPaths;i.paths=s(i.paths,"trackingPaths"),t.trackingPaths!==p&&(c=!0)}if(Array.isArray(i.readAccessPaths)){let p=[];for(let f of i.readAccessPaths){let m=le(f);m!==f&&(c=!0),p.includes(m)||p.push(m)}i.readAccessPaths=p}c&&(i.updatedAt=new Date().toISOString(),await P(e,i));let d=await U(e),l=d.servers?.["vesper-indexing"];if(l&&Array.isArray(l.args)){let p=!1;l.args=l.args.map(f=>{let m=le(f);return m!==f&&(t.mcpArgs++,p=!0),m}),p&&await fe(e,d)}return{migrated:t.assetPaths+t.readAccess+t.commandKeys+t.trackingPaths+t.mcpArgs>0,changed:t}}async function ot(e){let t=await y(e),s=await S(e),n=await g(e),o=gs(),a=[],i=[];for(let{path:l,settingKey:u}of o)s[u]||(s[u]={}),s[u][l]===!0?i.push(l):(s[u][l]=!0,a.push(l)),n.paths.includes(l)||n.paths.push(l);let c=O,d=s[_]||[];return d.includes(c)||(d.push(c),s[_]=d,a.push(c)),n.readAccessPaths||(n.readAccessPaths=[]),n.readAccessPaths.includes(c)||n.readAccessPaths.push(c),a.length>0&&await C(e,s),n.addedAt=n.addedAt||new Date().toISOString(),n.updatedAt=new Date().toISOString(),n.workspaceType=t.type,n.settingsPath=t.settingsPath,await P(e,n),{added:a,existed:i,workspaceType:t.type}}function ue(e){return A(e,".vscode","mcp.json")}function V(){return A(J,"src","mcp","vesper-indexing","dist","index.js")}async function U(e){let t=ue(e);try{let s=await R(t,"utf-8");return de(s)}catch(s){if(s.code==="ENOENT")return{servers:{}};if(s instanceof SyntaxError)return{servers:{}};throw s}}async function fe(e,t){let s=ue(e),n=X(s);await xe(n,{recursive:!0}),await H(s,JSON.stringify(t,null," "),"utf-8")}async function ae(e,t=!0){let s=await U(e),n=j(V()),o=[];if(s.servers||(s.servers={}),t?(s.servers["vesper-indexing"]={type:"stdio",command:"node",args:[n],env:{VESPER_INDEX_ROOT:"${workspaceFolder}"}},o.push("vesper-indexing"),s.servers["sequential-thinking"]={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},o.push("sequential-thinking"),s.servers.memory={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:"${workspaceFolder}/.vesper/memory.jsonl"}},o.push("memory")):(delete s.servers["vesper-indexing"],delete s.servers["sequential-thinking"],delete s.servers.memory),await fe(e,s),t&&o.length>0){let a=await g(e);a.mcp=a.mcp||{},a.mcp.servers=o,a.mcp.updatedAt=new Date().toISOString(),await P(e,a)}return{configured:t,mcpPath:ue(e),servers:o}}async function at(e){return!!(await U(e)).servers?.["vesper-indexing"]}async function it(e){let t=await y(e),s=await S(e);s[Ae]=!1,s[v]||(s[v]={});for(let n of M)s[v][n]=!0;return await C(e,s),{configured:M.length,workspaceType:t.type}}async function ct(e,t){let s=Ce[t];if(!s||s.length===0)return{added:[],agentName:t};let n=await S(e),o=await y(e),a=await g(e,o);n[v]||(n[v]={});let i=[];for(let c of s)n[v][c]||(n[v][c]=!0,i.push(c));return i.length>0&&(await C(e,n),a.mcp=a.mcp||{},a.mcp.agentTools=a.mcp.agentTools||{},a.mcp.agentTools[t]=s,a.mcp.updatedAt=new Date().toISOString(),await P(e,a)),{added:i,agentName:t}}async function lt(e,t){let s=oe[t];if(!s)return{added:!1,serverName:t,tools:[],error:`Unknown MCP server: ${t}`};let n=await U(e),o=await S(e),a=await y(e),i=await g(e,a);if(n.servers||(n.servers={}),n.servers[t])return{added:!1,serverName:t,tools:[],error:"Already configured"};let c=JSON.parse(JSON.stringify(s.config));if(t==="vesper-indexing"){let l=j(V());c.args&&(c.args=c.args.map(u=>u==="${VESPER_INDEXING_PATH}"?l:u))}n.servers[t]=c,await fe(e,n),o[v]||(o[v]={});let d=[];for(let l of s.tools||[])o[v][l]||(o[v][l]=!0,d.push(l));return o[Ae]=!1,await C(e,o),i.mcp=i.mcp||{},i.mcp.servers=i.mcp.servers||[],i.mcp.servers.includes(t)||i.mcp.servers.push(t),i.mcp.updatedAt=new Date().toISOString(),await P(e,i),{added:!0,serverName:t,tools:d}}async function dt(e,t){let s=oe[t],n=await U(e),o=await S(e),a=await y(e),i=await g(e,a),c=!1;n.servers&&n.servers[t]&&(delete n.servers[t],await fe(e,n),c=!0);let d=[];if(s&&o[v]){for(let l of s.tools||[])o[v][l]&&(delete o[v][l],d.push(l));d.length>0&&await C(e,o)}return i.mcp?.servers&&(i.mcp.servers=i.mcp.servers.filter(l=>l!==t),i.mcp.updatedAt=new Date().toISOString(),await P(e,i)),{removed:c,serverName:t,tools:d}}import{readFile as F,writeFile as E,mkdir as q,readdir as ut,rm as pt,cp as ft}from"node:fs/promises";import{join as w,dirname as Pe,basename as ms}from"node:path";import{homedir as hs}from"node:os";N();var Z=w(O,"claude"),gt=["agents","commands","skills"],ge="vesper";function B(e=ge){return w(hs(),".claude","skills",e)}function mt(e){return w(e,".claude","vesper")}function ht(e){return w(e,"CLAUDE.md")}function K(e){return w(e,".mcp.json")}function me(e){return w(e,".claude","settings.json")}function vt(e,t){return t?e.replace(/^(name:\s*)([a-z0-9-]+)/m,(s,n,o)=>o.startsWith(t)?s:`${n}${t}${o}`):e}async function vs(e,t,s,n){if(!await h(e))return{copied:0};await q(t,{recursive:!0});let o=await ut(e,{withFileTypes:!0}),a=0;for(let i of o){let c=w(e,i.name);if(i.isDirectory()){await ft(c,w(t,i.name),{recursive:!0}),a+=1;continue}if(!i.name.endsWith(".md"))continue;let d=await F(c,"utf-8"),l=vt(d,s),u=n&&s&&!i.name.startsWith(s)?`${s}${i.name}`:i.name;await E(w(t,u),l,"utf-8"),a+=1}return{copied:a}}async function ws(e,t,s){let n=w(e,".claude-plugin");await q(n,{recursive:!0});let o={name:t,description:"Vesper specialist catalog \u2014 subagents, slash commands, and skills for AI-orchestrated development.",version:s};await E(w(n,"plugin.json"),JSON.stringify(o,null,2),"utf-8")}async function he({pluginName:e=ge,namePrefix:t="",version:s="0.0.0"}={}){let n=B(e),o={};for(let a of gt){let i=w(Z,a),c=w(n,a),l=await vs(i,c,a==="skills"?"":t,a!=="skills");o[a]=l.copied}return await ws(n,e,s),{pluginDir:n,counts:o}}async function wt(e,t,{pluginName:s=ge,namePrefix:n=""}={}){let o=B(s),a=w(o,e);if(await q(a,{recursive:!0}),e==="skills"){let p=w(Z,"skills",t);if(!await h(p))throw new Error(`Skill "${t}" not found in assets/claude/skills/`);return await ft(p,w(a,t),{recursive:!0}),{installedAs:t}}let i=".md",c=w(Z,e,`${t}${i}`);if(!await h(c))throw new Error(`${e.slice(0,-1)} "${t}" not found in assets/claude/${e}/`);let d=await F(c,"utf-8"),l=vt(d,n),u=n&&!t.startsWith(n)?`${n}${t}${i}`:`${t}${i}`;return await E(w(a,u),l,"utf-8"),{installedAs:ms(u,i)}}async function yt(e=ge){let t=B(e),s={};for(let n of gt){let o=w(t,n);if(!await h(o)){s[n]=[];continue}let a=await ut(o,{withFileTypes:!0});s[n]=n==="skills"?a.filter(i=>i.isDirectory()).map(i=>i.name).sort():a.filter(i=>i.isFile()&&i.name.endsWith(".md")).map(i=>i.name.replace(/\.md$/,"")).sort()}return s}var Ee="<!-- vesper:start -->",Te="<!-- vesper:end -->";function ys(){return[Ee,"@.claude/vesper/orchestrator.md","@.claude/vesper/orchestration.md","@.claude/vesper/context.md",Te].join(`
|
|
2
|
+
`)}async function _s(e){let t=ht(e),s=ys(),n=new RegExp(`${Ee}[\\s\\S]*?${Te}`);if(!await h(t))return await q(Pe(t),{recursive:!0}),await E(t,`${s}
|
|
3
|
+
`,"utf-8"),{created:!0,updated:!1};let o=await F(t,"utf-8");if(n.test(o)){let i=o.replace(n,s);return i!==o?(await E(t,i,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let a=`${s}
|
|
4
4
|
|
|
5
|
-
${
|
|
6
|
-
`),n=setInterval(
|
|
7
|
-
`))p.trim()&&r.info(p.replace("[vesper-indexing] ",""))}),
|
|
8
|
-
Updated: ${
|
|
9
|
-
Reload VS Code to apply changes`)}else i.length>0&&r.info("All selected assets are already added.")}catch(t){if(t.name==="ExitPromptError"){console.log(),r.info("Cancelled.");return}r.error(`Add failed: ${t.message}`),process.exit(1)}}
|
|
10
|
-
\u2192 Reload VS Code to update MCP tools with the new index`),r.vesperTip()),i();return}let d
|
|
11
|
-
Total approved tools: ${s.mcp.toolCount}`),
|
|
12
|
-
Reload VS Code to apply changes`)}async function
|
|
5
|
+
${o}`;return await E(t,a,"utf-8"),{created:!1,updated:!0}}function Ss(e){let t=new RegExp(`${Ee}[\\s\\S]*?${Te}\\n*`);return e.replace(t,"")}async function ve(e){let t=mt(e);await q(t,{recursive:!0});let s={orchestrator:"refreshed",orchestration:"skipped",context:"skipped"},n=w(Z,"vesper-orchestrator.md"),o=w(t,"orchestrator.md");await E(o,await F(n,"utf-8"),"utf-8");let a=w(t,"orchestration.md");await h(a)||(await E(a,await F(w(Z,"orchestration.md.tpl"),"utf-8"),"utf-8"),s.orchestration="created");let i=w(t,"context.md");await h(i)||(await E(i,await F(w(Z,"context.md.tpl"),"utf-8"),"utf-8"),s.context="created");let c=await _s(e);return s.claudeMd=c.created?"created":c.updated?"updated":"unchanged",s}async function xs(e){let t=K(e);try{let s=await F(t,"utf-8");return JSON.parse(s)}catch(s){return s.code==="ENOENT"?{mcpServers:{}}:{mcpServers:{}}}}async function As(e,t){let s=K(e);await q(Pe(s),{recursive:!0}),await E(s,JSON.stringify(t,null," "),"utf-8")}function Cs(e){return{"vesper-indexing":{command:"node",args:[V()],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:w(e,".vesper","memory.jsonl")}}}}async function ie(e,t=!0){let s=await xs(e);s.mcpServers||(s.mcpServers={});let n=Cs(e),o=Object.keys(n);if(t)for(let[a,i]of Object.entries(n))s.mcpServers[a]=i;else for(let a of o)delete s.mcpServers[a];return await As(e,s),{configured:t,mcpPath:K(e),servers:t?o:[]}}async function we(e){let t=me(e),s={};try{s=JSON.parse(await F(t,"utf-8"))}catch{s={}}s.permissions||(s.permissions={}),Array.isArray(s.permissions.allow)||(s.permissions.allow=[]);let n=["mcp__vesper-indexing__vesper_search","mcp__vesper-indexing__vesper_symbols","mcp__vesper-indexing__vesper_status","mcp__vesper-indexing__vesper_reindex","mcp__sequential-thinking__sequentialthinking","mcp__memory__create_entities","mcp__memory__create_relations","mcp__memory__add_observations","mcp__memory__delete_entities","mcp__memory__delete_observations","mcp__memory__delete_relations","mcp__memory__read_graph","mcp__memory__search_nodes","mcp__memory__open_nodes"],o=0;for(let a of n)s.permissions.allow.includes(a)||(s.permissions.allow.push(a),o+=1);return Ps(s),await q(Pe(t),{recursive:!0}),await E(t,JSON.stringify(s,null," "),"utf-8"),{configured:o,settingsPath:t}}var _t=".claude/vesper/",ks=`node -e "['orchestrator','orchestration','context'].forEach(n=>{try{process.stdout.write(require('fs').readFileSync('.claude/vesper/'+n+'.md','utf8')+'\\n\\n')}catch(e){}})"`;function Ps(e){e.hooks||(e.hooks={}),Array.isArray(e.hooks.SessionStart)||(e.hooks.SessionStart=[]),!e.hooks.SessionStart.some(s=>(s?.hooks||[]).some(n=>typeof n?.command=="string"&&n.command.includes(_t)))&&e.hooks.SessionStart.push({matcher:"clear",hooks:[{type:"command",command:ks}]})}function Es(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(_t))),e.hooks.SessionStart.length===0&&delete e.hooks.SessionStart,e.hooks&&Object.keys(e.hooks).length===0&&delete e.hooks)}async function St(e,t){let s=await g(e);return s.claude={...s.claude,...t,updatedAt:new Date().toISOString()},await P(e,s),s.claude}async function ye(e){let t=mt(e);await pt(t,{recursive:!0,force:!0});let s=ht(e);if(await h(s)){let a=await F(s,"utf-8"),i=Ss(a);i.trim()?await E(s,i,"utf-8"):await pt(s,{force:!0})}await ie(e,!1);let n=me(e);if(await h(n))try{let a=JSON.parse(await F(n,"utf-8"));Es(a),await E(n,JSON.stringify(a,null," "),"utf-8")}catch{}let o=await g(e);delete o.claude,await P(e,o)}N();import{resolve as be,basename as js}from"node:path";import{rm as Vs}from"node:fs/promises";import{confirm as xt}from"@inquirer/prompts";import x from"picocolors";function Ts(e){console.log(`${x.green("\u2713")} ${e}`)}function bs(e){console.log(`${x.red("\u2717")} ${e}`)}function $s(e){console.log(`${x.yellow("!")} ${e}`)}function Os(e){console.log(`${x.cyan("\u2192")} ${e}`)}function Is(e){console.log(x.dim(e))}function Ms(e){return x.cyan(e)}function Ds(e){return x.bold(e)}function Fs(e){console.log(),console.log(x.bold(x.underline(e)))}function Ls(e,t=!1){let s=t?x.green("\u25CF"):x.dim("\u25CB");console.log(` ${s} ${e}`)}function Ns(){console.log(),console.log(x.bold(x.magenta("\u{1F3AF} Ready to use Vesper!"))),console.log(x.cyan(' In VS Code Chat, select "Vesper" from the agent dropdown')),console.log(x.cyan(" and start requesting!")),console.log()}function Rs(e){let t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],s=0,n=null,o=e,a=()=>{let i=x.cyan(t[s]);process.stdout.write(`\r${i} ${o}`),s=(s+1)%t.length};return{start(){process.stdout.write(`
|
|
6
|
+
`),n=setInterval(a,80),a()},update(i){o=i},stop(){n&&(clearInterval(n),n=null,process.stdout.write("\r"+" ".repeat(o.length+4)+"\r"))},succeed(i){this.stop(),console.log(`${x.green("\u2713")} ${i||o}`)},fail(i){this.stop(),console.log(`${x.red("\u2717")} ${i||o}`)}}}var r={success:Ts,error:bs,warn:$s,info:Os,dim:Is,formatPath:Ms,formatName:Ds,header:Fs,listItem:Ls,vesperTip:Ns,createSpinner:Rs};async function Us(e={}){let t=be(e.path||process.cwd());if(!(await g(t)).claude){r.warn("Claude Code target is not initialized in this workspace.");return}if(!e.yes&&!await xt({message:"Remove the Claude Code target from this project? (the shared plugin catalog at the user level is left untouched)",default:!1})){r.info("Reset cancelled.");return}await ye(t),console.log(),r.success("Claude Code target reset complete."),r.info("Removed: .claude/vesper/, CLAUDE.md guard block, .mcp.json entry, .vesperrc.claude"),r.info("Left untouched: the shared plugin catalog at ~/.claude/skills/vesper/")}function Ws(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 $e(e){let t=await g(e);await Xe(e);try{let n=await S(e);if(n[v]){let o=new Set(M),a=!1;for(let i of Object.keys(n[v]))o.has(i)||(delete n[v][i],a=!0);a&&await C(e,n)}}catch{}let s=be(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 Vs(s,{force:!0})}catch{}}async function At(e={}){try{let t=be(e.path||process.cwd());await h(t)||(r.error(`Directory not found: ${r.formatPath(t)}`),process.exit(1));let s=e.target;if(!s){let c=await D(t);if(c.length===0){r.warn("Vesper is not initialized in this workspace.");return}c.length>1&&(r.error("Both Copilot and Claude targets are installed here \u2014 specify which to reset: --target copilot|claude"),process.exit(1)),s=c[0]}if(s==="claude")return await Us({...e,path:t});if(!await pe(t)){r.warn("Vesper is not initialized in this workspace.");return}let n=await Q(t);if(n.length===0){r.info("Nothing to reset.");return}let o=Ws(n);if(!e.yes&&!await xt({message:`Remove all Vesper assets (${o.join(", ")})?`,default:!1})){r.info("Reset cancelled.");return}let a=await g(t),i=await y(t);await $e(t),a.claude&&r.info("Claude Code target detected \u2014 kept its record in .vesperrc"),console.log(),r.success("Vesper reset complete."),a.workspaceType===k.WORKSPACE_FILE||i.type===k.WORKSPACE_FILE?r.info(`Cleaned: ${js(i.settingsPath)}`):r.info("Cleaned: .vscode/settings.json"),r.info("Reload VS Code to apply changes")}catch(t){if(t.name==="ExitPromptError"){console.log(),r.info("Reset cancelled.");return}r.error(`Reset failed: ${t.message}`),process.exit(1)}}var Ct=["copilot","claude"];function kt(e){return e==="claude"?"Claude Code":"GitHub Copilot"}async function zs(e){let t=await g(e),s=[];return Array.isArray(t.paths)&&t.paths.length>0&&s.push("copilot"),t.claude&&s.push("claude"),s}async function Xs(e,t){let s=await zs(t);if(e.target){let o=String(e.target).toLowerCase(),a=o==="all"?[...Ct]:o.split(",").map(i=>i.trim()).filter(Boolean);for(let i of a)Ct.includes(i)||(r.error(`Unknown target: ${i}. Valid targets: copilot, claude, all`),process.exit(1));return{selected:[...new Set(a)],installed:s}}return process.stdin.isTTY||(r.error("Non-interactive run without --target. Specify the platform(s), e.g. --target copilot,claude (or --target all)."),process.exit(1)),{selected:await Hs({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 Qs(e){return e?"":await Ys({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 Zs(e,t={}){let s=t.yes||t.forceDefault,n=await Qs(s);console.log(),r.header("Installing Vesper for Claude Code"),console.log();let{pluginDir:o,counts:a}=await he({namePrefix:n,version:t.version||"0.0.0"});r.success(`Specialist catalog installed: ${o}`),r.info(` agents: ${a.agents}, commands: ${a.commands}, skills: ${a.skills}`);let i=await ve(e);r.success("Project files ready:"),r.info(` .claude/vesper/orchestrator.md (${i.orchestrator})`),r.info(` .claude/vesper/orchestration.md (${i.orchestration})`),r.info(` .claude/vesper/context.md (${i.context})`),r.info(` CLAUDE.md (${i.claudeMd})`);let c=await ie(e,!0);await we(e),r.success(`MCP servers configured: .mcp.json (${c.servers.join(", ")})`),await St(e,{pluginPath:B(),namePrefix:n,mcpConfigPath:K(e),settingsPath:me(e),installedAt:new Date().toISOString()})}async function en(e,t,s){console.log(),r.header("Configuring GitHub Copilot"),console.log();let n=await ot(e);await Ze(e,{maxRequests:s.maxRequests,omitBaseAgentInstructions:s.omitBaseAgentInstructions});let o=await Qe(e,s.terminalEnableAutoApprove),a=!1;return s.enableMcpServer&&(a=(await ae(e,!0)).configured,await it(e)),r.success("Core assets ensured: agents, prompts, instructions, skills"),r.info(`Max agent requests: ${s.maxRequests}`),o.configured>0?r.info(`Terminal auto-approval: ${o.configured} safe commands configured`):s.terminalEnableAutoApprove===!1&&r.info("Terminal auto-approval: disabled"),a&&(r.info("MCP servers: vesper-indexing, sequential-thinking, memory (.vscode/mcp.json)"),r.info("MCP tools auto-approval: vesper-indexing + context7 + sequential-thinking + memory")),n.workspaceType===k.WORKSPACE_FILE?r.info(`Settings added to: ${qs(t.settingsPath)}`):r.info("Settings added to: .vscode/settings.json"),r.info("Tracking file: .vesperrc"),{mcpConfigured:a}}async function tn(e,t){let s=await Ye(e);if(!s.found)return{migrated:!1,from:null};let{paths:n}=s;console.log(),r.warn(`Found .vesperrc in nested folder${n.length>1?"s":""}:`);for(let{folderPath:i}of n)r.info(` \u2192 ${i}`);console.log();let o=n[0],a=!0;if(t||(a=await ee({message:"Migrate .vesperrc to workspace level? (recommended for multi-root workspaces)",default:!0})),a){let i=await He(e,o.vesperrcPath,o.tracking);if(i.success){if(r.success("Migrated .vesperrc to workspace level"),r.info(` From: ${o.vesperrcPath}`),r.info(` To: ${i.newPath}`),n.length>1){let{unlink:c}=await import("node:fs/promises");for(let d=1;d<n.length;d++)try{await c(n[d].vesperrcPath),r.info(` Removed: ${n[d].vesperrcPath}`)}catch{}}return console.log(),{migrated:!0,from:o.folderPath}}}else r.info("Migration skipped. .vesperrc will remain in nested folder."),console.log();return{migrated:!1,from:null}}async function sn(e){let{migrated:t,changed:s}=await rt(e);if(!t)return;let n=(a,i)=>`${a} ${i}${a>1?"s":""}`,o=[];s.assetPaths&&o.push(n(s.assetPaths,"asset path")),s.readAccess&&o.push(n(s.readAccess,"read-access path")),s.commandKeys&&o.push(n(s.commandKeys,"stale command")),s.trackingPaths&&o.push(n(s.trackingPaths,"tracked path")),s.mcpArgs&&o.push("MCP server path"),console.log(),r.info("Detected a workspace set up under the older `vesper-cli` package \u2014 migrating install paths."),r.success(`Migrated: ${o.join(", ")}`),console.log()}async function nn(e,t){let s=e;return t||(s=await Ks({message:"Workspace root directory:",default:s})),Gs(s)}async function rn(e,t,s){let n=[];for(let o of t){let a=kt(o),i=s;if(s||(i=await ee({message:`${a} is installed but was unchecked. Remove it from this project?`,default:!1})),!i){r.info(`Kept ${a}.`);continue}o==="claude"?await ye(e):await $e(e),n.push(o),r.success(`Removed ${a} from this project.`)}return n}async function on(e){if(e)return{maxRequests:$.maxRequests,terminalEnableAutoApprove:$.terminalEnableAutoApprove,omitBaseAgentInstructions:$.omitBaseAgentInstructions,enableMcpServer:$.enableMcpServer};console.log(),r.info("Configure VS Code Chat settings:");let t=await Js({message:"Max agent requests per session (chat.agent.maxRequests):",default:$.maxRequests,min:1,max:1e3}),s=await ee({message:"Controls whether terminal commands are automatically approved. Enable terminal auto-approval? (chat.tools.terminal.enableAutoApprove)",default:$.terminalEnableAutoApprove});s&&r.info("Terminal auto-approval enabled with safe command whitelist");let n=await ee({message:"Omit base agent instructions for custom agents? (github.copilot.chat.omitBaseAgentInstructions)",default:$.omitBaseAgentInstructions}),o=await ee({message:"Enable vesper-indexing MCP server for fast code search?",default:$.enableMcpServer});return{maxRequests:t||$.maxRequests,terminalEnableAutoApprove:s,omitBaseAgentInstructions:n,enableMcpServer:o}}async function an(e,t=!1){let s=V().replace("index.js","cli-index.js");if(!await h(s))return{success:!1,error:"MCP server not built"};t&&(console.log(),r.info("Starting workspace indexing..."));let n=t?null:r.createSpinner("Indexing workspace...");return n&&n.start(),new Promise(o=>{let a=Bs("node",[s,e],{stdio:["ignore","pipe","pipe"],env:{...process.env}}),i="",c=0;a.stderr.on("data",d=>{let l=d.toString().trim(),u=l.match(/Indexed (\d+) files/);if(u&&(c=parseInt(u[1],10),n&&n.update(`Indexing workspace... ${c} files`)),t&&l)for(let p of l.split(`
|
|
7
|
+
`))p.trim()&&r.info(p.replace("[vesper-indexing] ",""))}),a.stdout.on("data",d=>{i+=d.toString()}),a.on("close",d=>{try{let l=JSON.parse(i.trim());l.success?n?n.succeed(`Workspace indexed: ${l.filesIndexed} files`):r.success(`Workspace indexed: ${l.filesIndexed} files`):n?n.fail(`Indexing failed: ${l.error}`):r.error(`Indexing failed: ${l.error}`),o(l)}catch{d===0?(n?n.succeed(`Workspace indexed: ${c} files`):r.success(`Workspace indexed: ${c} files`),o({success:!0,filesIndexed:c})):(n?n.fail("Indexing failed"):r.error("Indexing failed"),o({success:!1,error:"Unknown error"}))}}),a.on("error",d=>{n?n.fail(`Indexing failed: ${d.message}`):r.error(`Indexing failed: ${d.message}`),o({success:!1,error:d.message})})})}function cn({copilot:e,claude:t,indexingResult:s}){console.log(),r.success("Vesper is ready."),s?.success?r.info(`Code index built: ${s.filesIndexed} files.`):s?.error&&r.info("Code index will be built on first MCP server start."),console.log(),r.header("Next Steps"),console.log(),e&&(r.info("GitHub Copilot \u2014 reload VS Code to activate Vesper:"),r.info(' Cmd+Shift+P (macOS) / Ctrl+Shift+P (Windows/Linux) \u2192 "Developer: Reload Window"')),t&&(r.info("Claude Code \u2014 open a session in this workspace; the orchestrator"),r.info(" activates automatically via CLAUDE.md.")),console.log(),e&&r.vesperTip()}async function Pt(e={}){try{let t=e.yes||e.forceDefault,s=await nn(e.path||process.cwd(),t);await h(s)||(r.error(`Directory not found: ${r.formatPath(s)}`),process.exit(1));let n=await y(s);n.type===k.WORKSPACE_FILE&&await tn(s,t),await sn(s);let{selected:o,installed:a}=await Xs(e,s),i=a.filter(f=>!o.includes(f));if(o.length===0&&i.length===0){r.info("No platforms selected. Nothing to do.");return}if(!t&&a.length===0&&o.length>0&&!await ee({message:`Set up ${o.map(kt).join(" + ")} in ${s}?`,default:!0})){r.info("Initialization cancelled.");return}i.length>0&&await rn(s,i,t);let c=o.includes("copilot"),d=o.includes("claude"),l=null;c&&(l=await on(t)),c&&await en(s,n,l),d&&await Zs(s,e);let u=c&&l?.enableMcpServer||d,p=null;u&&(p=await an(s,!0)),cn({copilot:c,claude:d,indexingResult:p})}catch(t){if(t.name==="ExitPromptError"){console.log(),r.info("Initialization cancelled.");return}r.error(`Initialization failed: ${t.message}`),process.exit(1)}}N();import{resolve as Tt,basename as ln}from"node:path";import{checkbox as bt,select as dn}from"@inquirer/prompts";var Et={agents:"agents",prompts:"commands",skills:"skills"};async function pn(e,t){let s=await D(e);if(s.length===1)return s[0];s.length===0&&(r.warn('Vesper is not initialized in this workspace. Run "vespercli init" first.'),process.exit(0)),r.error(`Both Copilot and Claude targets are installed here \u2014 specify which to ${t}: --target copilot|claude`),process.exit(1)}async function un(e={}){let t=Tt(e.path||process.cwd());(!e.type||!e.name)&&(r.error("Usage: vesper add <type> <name> --target claude"),r.info("Types: agents, prompts (installed as slash commands), skills"),process.exit(1));let s=Et[e.type];s||(r.error(`Unknown asset type for --target claude: ${e.type}`),r.info(`Available types: ${Object.keys(Et).join(", ")}`),process.exit(1));let o=(await g(t)).claude?.namePrefix??"";try{let a=await wt(s,e.name,{namePrefix:o});r.success(`Added ${e.type}/${e.name} to the Claude plugin catalog as "${a.installedAs}"`)}catch(a){r.error(a.message),process.exit(1)}}var ce=["agents","prompts","instructions"];async function Oe(e,t){let s=await Q(e);return(await Y(t)).filter(o=>{let a=G(t,o);return!s.includes(a.path)})}async function fn(e){let t=[];for(let i of ce){let c=await Oe(e,i);c.length>0&&t.push({name:`${i.charAt(0).toUpperCase()+i.slice(1)} (${c.length} available)`,value:i})}if(t.length===0)return r.info("All extended assets are already added."),[];let s=await dn({message:"Select asset type:",choices:t}),o=(await Oe(e,s)).map(i=>({name:i,value:i,checked:!1}));return(await bt({message:`Select ${s} to add:`,choices:o})).map(i=>({type:s,name:i}))}async function $t(e={}){try{let t=Tt(e.path||process.cwd());if(await h(t)||(r.error(`Directory not found: ${r.formatPath(t)}`),process.exit(1)),(e.target||await pn(t,"add"))==="claude")return await un({...e,path:t});if(!await pe(t)){r.warn('Vesper is not initialized. Run "vespercli init" first.');return}let n=[];if(e.type&&e.name){if(e.type==="skills"){r.info("Skills are automatically added during init.");return}ce.includes(e.type)||(r.error(`Unknown asset type: ${e.type}`),r.info(`Available types: ${ce.join(", ")}`),process.exit(1));let l=await Y(e.type);l.includes(e.name)||(r.error(`Asset not found: ${e.name}`),r.info(`Available ${e.type}: ${l.join(", ")||"none"}`),process.exit(1)),n=[{type:e.type,name:e.name}]}else if(e.type){if(e.type==="skills"){r.info("Skills are automatically added during init.");return}ce.includes(e.type)||(r.error(`Unknown asset type: ${e.type}`),r.info(`Available types: ${ce.join(", ")}`),process.exit(1));let l=await Oe(t,e.type);if(l.length===0){r.info(`All ${e.type} are already added.`);return}let u=l.map(f=>({name:f,value:f,checked:!1})),p=await bt({message:`Select ${e.type} to add:`,choices:u});if(p.length===0){r.info("Nothing selected.");return}n=p.map(f=>({type:e.type,name:f}))}else if(n=await fn(t),n.length===0){r.info("Nothing selected.");return}let o=n.map(({type:l,name:u})=>G(l,u)),{added:a,skipped:i,workspaceType:c}=await ze(t,o),d=n.filter(l=>l.type==="agents"&&a.includes(G(l.type,l.name).path));for(let{name:l}of d)Ce[l]&&(await ct(t,l),r.info(` Added MCP tools auto-approval for agent: ${l}`));if(a.length>0){let l=await y(t);console.log(),r.success(`Added ${a.length} asset(s):`);for(let{type:u,name:p}of n.filter(f=>a.includes(G(f.type,f.name).path)))r.info(` ${u}/${p}`);c===k.WORKSPACE_FILE&&r.info(`
|
|
8
|
+
Updated: ${ln(l.settingsPath)}`),r.info(`
|
|
9
|
+
Reload VS Code to apply changes`)}else i.length>0&&r.info("All selected assets are already added.")}catch(t){if(t.name==="ExitPromptError"){console.log(),r.info("Cancelled.");return}r.error(`Add failed: ${t.message}`),process.exit(1)}}N();import{resolve as It,join as gn}from"node:path";import{readdir as mn}from"node:fs/promises";import L from"picocolors";async function Ot(e={}){let t=It(e.path||process.cwd()),s=await g(t);if(console.log(),console.log(L.bold("Claude Code target")),!s.claude){console.log(),r.warn('Not initialized for Claude Code. Run "vesper init --target claude" first.'),console.log();return}let n=s.claude.pluginPath||B();console.log(L.dim(`Plugin catalog: ${n}`));let o=await yt();for(let[a,i]of Object.entries(o))console.log(),console.log(L.bold(a.charAt(0).toUpperCase()+a.slice(1))),i.length===0?console.log(L.dim(" (none installed)")):i.forEach(c=>console.log(` ${c}`));console.log(),console.log(L.bold("Project files")),console.log(" CLAUDE.md, .claude/vesper/{orchestrator,orchestration,context}.md, .mcp.json, .claude/settings.json"),console.log()}async function hn(e,t,s=!1){try{let n=await mn(e,{withFileTypes:!0});return s||t.dir==="skills"?n.filter(a=>a.isDirectory()&&!a.name.startsWith(".")).map(a=>a.name):n.filter(a=>a.isFile()&&a.name.endsWith(t.extension)).map(a=>a.name.replace(t.extension,""))}catch{return[]}}async function Mt(e={}){try{let t=It(e.path||process.cwd());await h(t)||(r.error(`Directory not found: ${r.formatPath(t)}`),process.exit(1));let s=await D(t);if(e.target==="claude")return await Ot({...e,path:t});if(!e.target){if(s.length===0){console.log(),r.warn('Vesper is not initialized. Run "vespercli init" first.'),console.log();return}if(s.length===1&&s[0]==="claude")return await Ot({...e,path:t});s.includes("claude")&&r.info("Claude Code target is also installed here \u2014 run `vespercli list --target claude` to see it.")}let n=await Q(t);e.type&&!b[e.type]&&(r.error(`Unknown asset type: ${e.type}`),r.info(`Valid types: ${Object.keys(b).join(", ")}`),process.exit(1));let o=e.type?[e.type]:Object.keys(b);console.log(),console.log(L.bold("Assets"));for(let a of o){let i=b[a],c=a.charAt(0).toUpperCase()+a.slice(1);if(a==="skills"){let f=nt("skills");if(n.includes(f.path)){let m=await Y("skills");console.log(),console.log(L.bold(`${c}`)),console.log(` ${m.length} skills enabled ${L.dim("(all)")}`)}continue}let d=gn(Le,i.dir),l=await hn(d,i,!1),p=(await Y(a)).filter(f=>{let m=G(a,f);return n.includes(m.path)});(l.length>0||p.length>0)&&(console.log(),console.log(L.bold(`${c}`)),l.forEach(f=>{console.log(` ${f} ${L.dim("(core)")}`)}),p.forEach(f=>{console.log(` ${f}`)}))}console.log()}catch(t){r.error(`List failed: ${t.message}`),process.exit(1)}}import{readFileSync as vn,existsSync as wn}from"node:fs";import{join as yn}from"node:path";var Dt="catalog.md",_n="mthanhtran",Sn="vesper",xn="main";function An(){return`https://raw.githubusercontent.com/${_n}/${Sn}/${xn}/assets/${Dt}`}function Cn(){let e=yn(J,"assets",Dt);return wn(e)?vn(e,"utf-8"):null}async function kn(){try{let e=An(),t=await fetch(e);return t.ok?t.text():null}catch{return null}}async function Pn(){let e=await kn();if(e)return e;let t=Cn();if(t)return t;throw new Error("Catalog not available from remote or local")}async function Ft(){try{let e=await Pn();console.log(e)}catch(e){console.error(`Error loading catalog: ${e.message}`),process.exit(1)}}N();import{resolve as En,join as Nt}from"node:path";import{stat as Tn,readFile as Rt}from"node:fs/promises";import"@inquirer/prompts";import W from"picocolors";async function Ie(e){let t=await g(e);if(console.log(),r.header("vesper-indexing MCP Server (Claude Code target)"),console.log(),!t.claude){r.info("Claude Code target is not initialized. Run `vesper init --target claude` first.");return}let s=K(e),n=!1;if(await h(s))try{n=!!JSON.parse(await Rt(s,"utf-8")).mcpServers?.["vesper-indexing"]}catch{n=!1}r.info(`Configured: ${n?"\u2713 yes":"\u2717 no"} (${s})`),r.info(`Server built: ${await Vt()?"\u2713 yes":"\u2717 no"}`);let o=Me(e);r.info(`Index exists: ${await h(o)?"\u2713 yes":"\u2717 no"} (shared with the Copilot target if both are installed)`)}async function te(e,t=!0){await ie(e,t),t&&await we(e),r.success(`Claude Code target: vesper-indexing ${t?"enabled":"disabled"} in .mcp.json`)}function Me(e){return Nt(e,".vesper","index.db")}function bn(e){return Nt(e,".vesper","indexing-status.json")}async function jt(e){let t=bn(e);try{let s=await Rt(t,"utf-8");return JSON.parse(s)}catch{return null}}async function Vt(){let e=V();return await h(e)}async function $n(e){try{let t=await Tn(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 Lt(e,t=!1){let s=await at(e),n=await Vt(),o=Me(e),a=await h(o),i=await jt(e);if(console.log(),r.header("vesper-indexing MCP Server"),console.log(),r.info(`Configured: ${s?"\u2713 yes":"\u2717 no"}`),r.info(`Server built: ${n?"\u2713 yes":"\u2717 no"}`),r.info(`Index exists: ${a?"\u2713 yes":"\u2717 no"}`),i)if(console.log(),i.status==="indexing")if(t){await On(e,i);return}else{let c=i.startedAt?Math.round((Date.now()-new Date(i.startedAt).getTime())/1e3):0;r.info(W.yellow("\u27F3 Indexing in progress...")),r.info(` Files processed: ${W.cyan(i.filesProcessed)}`),r.info(` Elapsed: ${W.dim(`${c}s`)}`),console.log(),r.info("Use --watch to follow indexing progress until completion")}else i.status==="error"&&(r.error(`Indexing error: ${i.error}`),r.info(` Files processed before error: ${i.filesProcessed}`));if(!s){console.log(),r.info("Run `vespercli init` to configure the MCP server");return}if(!n){console.log(),r.warn("MCP server not built. Run: cd src/mcp/vesper-indexing && npm install && npm run build");return}if(a&&!i){let c=await $n(o);c&&(console.log(),r.info(`Index size: ${c.dbSize}`),r.info(`Last modified: ${c.lastModified}`)),r.vesperTip()}else!a&&!i&&(console.log(),r.info("Index not yet created. It will be built when VS Code loads the MCP server."),console.log())}async function On(e,t){let s=r.createSpinner(`Indexing... ${t.filesProcessed} files processed`);s.start();let n=500,o=30*60*1e3,a=Date.now();return new Promise(i=>{let c=async()=>{let d=await jt(e);if(!d||d.status!=="indexing"){d?.status==="error"?s.fail(`Indexing failed: ${d.error}`):(s.succeed(`Indexing complete! ${d?.filesProcessed||"All"} files indexed`),r.info(`
|
|
10
|
+
\u2192 Reload VS Code to update MCP tools with the new index`),r.vesperTip()),i();return}let l=d.startedAt?Math.round((Date.now()-new Date(d.startedAt).getTime())/1e3):0;if(s.update(`Indexing... ${d.filesProcessed} files processed (${l}s)`),Date.now()-a>o){s.fail("Indexing watch timed out (30 minutes)"),i();return}setTimeout(c,n)};setTimeout(c,n)})}async function In(e,t=!1){let s=Me(e);if(!await h(s))r.info("No index exists. It will be built when VS Code loads the MCP server.");else if(t){let{unlink:o}=await import("node:fs/promises");await o(s),r.success("Index cleared. Reload VS Code to rebuild.")}else r.info("Incremental reindex happens automatically when files change."),r.info("Use --full to clear and rebuild the entire index.")}async function Mn(e){let t=await ae(e,!0);t.configured&&(r.success("MCP server enabled"),r.info(`Config: ${t.mcpPath}`),r.info("Reload VS Code to start the server"))}async function Dn(e){await ae(e,!1),r.success("MCP server disabled"),r.info("Reload VS Code to apply changes")}async function Ut(e){let t=await y(e),s=await g(e,t);if(!Array.isArray(s.paths))return[];let n=[];for(let o of s.paths){let a=o.match(/agents\/([^/]+)\/?$/);a&&MCP_TOOLS_BY_AGENT[a[1]]&&n.push(a[1])}return n}async function Fn(e){let t=await y(e),s=await g(e,t),n=await S(e,t),o=await Ut(e),a=n[v]||{},i=new Set(M),c=[],d=[],l=!1;n[v]||(n[v]={});for(let p of M)a[p]||(n[v][p]=!0,c.push(p),l=!0);for(let p of o){let f=MCP_TOOLS_BY_AGENT[p]||[];for(let m of f)a[m]||(n[v][m]=!0,c.push(m),l=!0)}let u=new Set;for(let p of o)for(let f of MCP_TOOLS_BY_AGENT[p]||[])u.add(f);for(let p of Object.keys(a)){if(i.has(p))continue;let f=!1;for(let[m,T]of Object.entries(MCP_TOOLS_BY_AGENT))if(T.includes(p)){f=!0;break}f&&!u.has(p)&&(delete n[v][p],d.push(p),l=!0)}if(s.mcp=s.mcp||{},s.mcp.syncedAt=new Date().toISOString(),s.mcp.approvedAgents=o,s.mcp.toolCount=Object.keys(n[v]).length,l&&await C(e,n),await P(e,s),console.log(),r.header("MCP Tools Sync"),console.log(),c.length===0&&d.length===0)r.success("Already in sync");else{if(c.length>0){r.success(`Added ${c.length} tool(s)`);let p=c.filter(f=>i.has(f));p.length>0&&r.info(` Core: ${p.length} tools`);for(let f of o){let m=c.filter(T=>(MCP_TOOLS_BY_AGENT[f]||[]).includes(T));m.length>0&&r.info(` ${f}: ${m.length} tools`)}}d.length>0&&r.info(`Removed ${d.length} orphaned tool(s)`)}r.info(`
|
|
11
|
+
Total approved tools: ${s.mcp.toolCount}`),o.length>0&&r.info(`Agents with tools: ${o.join(", ")}`),l&&r.info(`
|
|
12
|
+
Reload VS Code to apply changes`)}async function Ln(e){let t=await y(e),s=await g(e,t),o=(await S(e,t))[v]||{},a=Object.keys(o).length,i=await Ut(e);console.log(),r.header("MCP Tool Approval Status"),console.log();let c=M.filter(u=>o[u]);if(r.info(`Core tools: ${c.length}/${M.length} approved`),i.length>0){console.log(),r.info("Agent tools:");for(let u of i){let p=MCP_TOOLS_BY_AGENT[u]||[],f=p.filter(T=>o[T]),m=f.length===p.length?W.green("\u2713"):W.yellow("\u26A0");r.info(` ${m} ${u}: ${f.length}/${p.length} approved`)}}let d=[...M];for(let u of i)d.push(...MCP_TOOLS_BY_AGENT[u]||[]);let l=d.filter(u=>!o[u]);console.log(),r.info(`Total approved: ${a} tools`),l.length>0?(console.log(),r.warn(`${l.length} tools missing approval`),r.info("Run `vespercli mcp sync` to fix")):s.mcp?.syncedAt&&r.info(`Last synced: ${s.mcp.syncedAt}`)}async function Nn(e,t){t||(r.error("Server name required. Usage: vespercli mcp add <server>"),r.info("Available servers: clickup, vesper-indexing, sequential-thinking"),process.exit(1)),console.log(),r.header("Add MCP Server"),console.log();let s=await lt(e,t);if(!s.added){s.error==="Already configured"?r.info(`MCP server '${t}' is already configured`):(r.error(s.error),process.exit(1));return}r.success(`Added MCP server: ${t}`),s.tools.length>0&&r.info(`Approved ${s.tools.length} tool(s) for auto-execution`),r.info(`
|
|
13
13
|
Reload VS Code to activate the MCP server`)}async function Rn(e,t){t||(r.error("Server name required. Usage: vespercli mcp remove <server>"),process.exit(1)),console.log(),r.header("Remove MCP Server"),console.log();let s=await dt(e,t);if(!s.removed){r.info(`MCP server '${t}' is not configured`);return}r.success(`Removed MCP server: ${t}`),s.tools.length>0&&r.info(`Removed ${s.tools.length} tool(s) from auto-approval`),r.info(`
|
|
14
|
-
Reload VS Code to deactivate the MCP server`)}async function
|
|
14
|
+
Reload VS Code to deactivate the MCP server`)}async function jn(e){let t=await y(e),s=await g(e,t),n=await U(e);console.log(),r.header("MCP Servers"),console.log();let o=s.mcp?.servers||[],a=Object.keys(n.servers||{});r.info("Available servers:");for(let[c,d]of Object.entries(oe)){let u=a.includes(c)?W.green("\u2713"):W.dim("\u25CB"),p=d.tools?.length||0;r.info(` ${u} ${c} (${p} tools)`)}let i=a.filter(c=>!oe[c]);if(i.length>0){console.log(),r.info("Custom servers:");for(let c of i)r.info(` ${W.blue("\u25C6")} ${c}`)}console.log(),r.info(`Installed: ${a.length} server(s)`)}async function Wt(e,t,s={}){let n=En(s.path||process.cwd());await h(n)||(r.error(`Directory not found: ${n}`),process.exit(1));let o=await D(n),a=s.target?[s.target]:o.length?o:["copilot"],i=a.includes("copilot"),c=a.includes("claude");if(c&&!i)switch(e){case"enable":return await te(n,!0);case"disable":return await te(n,!1);case"sync":return await te(n,!0);case"status":default:return await Ie(n)}let d=i&&c;switch(e){case"status":await Lt(n,s.watch),d&&await Ie(n);break;case"add":await Nn(n,t);break;case"remove":await Rn(n,t);break;case"list":await jn(n);break;case"reindex":await In(n,s.full);break;case"enable":await Mn(n),d&&await te(n,!0);break;case"disable":await Dn(n),d&&await te(n,!1);break;case"sync":await Fn(n),d&&await te(n,!0);break;case"approve":await Ln(n);break;default:await Lt(n,s.watch),d&&await Ie(n)}}import{resolve as Vn}from"node:path";async function qt(e,t,s,n={}){let o=Vn(n.path||process.cwd());if(!e){Gt();return}switch(e){case"add":await Un(o,t,s);break;case"remove":await Wn(o,t,s);break;case"list":await Gn(o,t);break;default:r.error(`Unknown subcommand: ${e}`),Gt()}}async function Un(e,t,s){if(!t){r.error("Setting key required"),r.info("Usage: vespercli settings add <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!s){r.error("Path value required"),r.info("Usage: vespercli settings add read-access <path>");return}let n=await et(e,s);r.success(`Added "${s}" to additional read access paths`),r.info(`Current paths: ${n.length>0?n.join(", "):"(none)"}`);break;default:r.error(`Unknown setting: ${t}`),r.info("Supported settings:"),r.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function Wn(e,t,s){if(!t){r.error("Setting key required"),r.info("Usage: vespercli settings remove <setting-key> <value>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":if(!s){r.error("Path value required"),r.info("Usage: vespercli settings remove read-access <path>");return}let n=await tt(e,s);r.success(`Removed "${s}" from additional read access paths`),r.info(`Current paths: ${n.length>0?n.join(", "):"(none)"}`);break;default:r.error(`Unknown setting: ${t}`),r.info("Supported settings:"),r.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}async function Gn(e,t){if(!t){r.info("Managed settings:"),r.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)"),r.info(""),r.info("Use: vespercli settings list <setting-key>");return}switch(t){case"github.copilot.chat.additionalReadAccessPaths":case"additionalReadAccessPaths":case"read-access":let s=await st(e);r.info(`${_}:`),s.length===0?r.info(" (empty)"):s.forEach(n=>r.info(` - ${n}`));break;default:r.error(`Unknown setting: ${t}`),r.info("Supported settings:"),r.info(" - read-access (github.copilot.chat.additionalReadAccessPaths)")}}function Gt(){r.info("Usage: vespercli settings <subcommand> [setting-key] [value]"),r.info(""),r.info("Subcommands:"),r.info(" add <setting-key> <value> Add a value to an array setting"),r.info(" remove <setting-key> <value> Remove a value from an array setting"),r.info(" list [setting-key] List current values"),r.info(""),r.info("Supported settings:"),r.info(" read-access github.copilot.chat.additionalReadAccessPaths"),r.info(""),r.info("Examples:"),r.info(" vespercli settings add read-access /path/to/external/repo"),r.info(" vespercli settings remove read-access /path/to/external/repo"),r.info(" vespercli settings list read-access")}N();import{resolve as Bt}from"node:path";async function qn(e={}){let t=Bt(e.path||process.cwd()),s=await g(t);if(!s.claude){r.warn('Claude Code target is not initialized. Run "vesper init --target claude" first.');return}console.log(),r.info("Refreshing Claude Code plugin catalog and orchestrator playbook...");let{pluginDir:n,counts:o}=await he({namePrefix:s.claude.namePrefix||"",version:e.version||"0.0.0"});r.success(`Plugin catalog refreshed: ${n}`),r.info(` agents: ${o.agents}, commands: ${o.commands}, skills: ${o.skills}`);let a=await ve(t);r.success(`Orchestrator playbook refreshed (.claude/vesper/orchestrator.md: ${a.orchestrator})`),r.info("Team roster (.claude/vesper/orchestration.md) and project context (.claude/vesper/context.md) are left alone \u2014 they belong to this project.")}async function Kt(e={}){try{let t=Bt(e.path||process.cwd());await h(t)||(r.error(`Directory not found: ${r.formatPath(t)}`),process.exit(1));let s=e.target?[e.target]:await D(t);if(s.length===0){r.warn('Vesper is not initialized. Run "vespercli init" first.');return}s.includes("claude")&&await qn({...e,path:t}),s.includes("copilot")&&(console.log(),r.info("Copilot assets are linked from the package, not copied."),r.info("Update the vesper package to get the latest assets:"),r.dim(" npm update -g @mthanh/vespercli"),console.log())}catch(t){r.error(`Update failed: ${t.message}`),process.exit(1)}}var Hn=Yn(import.meta.url),zn=De(Hn);function Xn(e){let t=e;for(;t!==De(t);){let s=Jt(t,"package.json");if(Jn(s))return s;t=De(t)}return Jt(e,"..","..","package.json")}var Qn=Xn(zn),Fe=JSON.parse(Kn(Qn,"utf-8")),I=new Bn;I.name("vespercli").description("Vesper VS Code Agent Suite \u2014 manage GitHub Copilot agents, prompts, instructions, and skills").version(Fe.version,"-v, --version","Output the current version");I.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=>Pt({...e,version:Fe.version}));I.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)=>$t({type:e,name:t,...s}));I.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(At);I.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)=>Mt({type:e,...t}));I.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=>Kt({...e,version:Fe.version}));I.command("catalog").description("Show the Vesper catalog (agents, dependencies, requirements)").action(Ft);I.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)=>Wt(e,t,s));I.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)=>qt(e,t,s,n));I.addHelpText("after",`
|
|
15
15
|
Examples:
|
|
16
|
-
$ vespercli init
|
|
17
|
-
$ vespercli init --
|
|
16
|
+
$ vespercli init Pick platform(s) to set up (multi-select), then initialize
|
|
17
|
+
$ vespercli init --target copilot,claude Set up both platforms in one run
|
|
18
|
+
$ vespercli init --target all Set up every supported platform
|
|
19
|
+
$ vespercli init --target claude --force-default Non-interactive: Claude with default settings
|
|
18
20
|
$ vespercli add Interactive asset selection
|
|
19
21
|
$ vespercli add agents Select from available agents
|
|
20
22
|
$ vespercli add agents code-reviewer Add specific agent
|
|
@@ -35,12 +37,12 @@ Examples:
|
|
|
35
37
|
$ vespercli settings list read-access Show read access paths
|
|
36
38
|
$ vespercli reset Remove all Vesper paths from settings
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
$ vespercli init
|
|
40
|
-
$ vespercli add agents code-reviewer Add one subagent (resolves
|
|
40
|
+
Multi-platform notes:
|
|
41
|
+
$ vespercli init On re-init, installed platforms are pre-checked; uncheck to remove
|
|
42
|
+
$ vespercli add agents code-reviewer Add one subagent (resolves per installed target)
|
|
41
43
|
$ vespercli list List what's installed here
|
|
42
44
|
$ vespercli mcp status Show MCP status for the installed target(s)
|
|
43
45
|
|
|
44
46
|
Documentation:
|
|
45
47
|
https://github.com/mthanhtran/vesper
|
|
46
|
-
`);
|
|
48
|
+
`);I.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mthanh/vespercli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.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",
|