@mthanh/vespercli 1.7.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -291,6 +291,14 @@ vespercli mcp sync # Re-sync tool auto-approval (Copilot
291
291
  vespercli mcp reindex --full # Clear and rebuild the shared code index
292
292
  ```
293
293
 
294
+ `mcp status`'s "Server built" line is a tri-state health check, not a simple built/not-built flag — it probes the manifests of the `vesper-indexing` server's two direct runtime dependencies (`@modelcontextprotocol/sdk`, `zod`) rather than just checking that their `node_modules` folders exist, so a corrupted install (present as a directory but missing its own `package.json`, e.g. from an interrupted install) is caught instead of misreported as healthy:
295
+
296
+ - `✓ yes` — built and dependencies verified.
297
+ - `⚠ yes, but dependencies missing — run 'npm install' in src/mcp/vesper-indexing (or reinstall Vesper)` — the build output exists but a dependency is corrupted/missing; the server will crash at startup with `ERR_MODULE_NOT_FOUND` until repaired.
298
+ - `✗ no` — not built yet; run `cd src/mcp/vesper-indexing && npm install && npm run build`.
299
+
300
+ This check is detective, not a repair itself — `npm install`/reinstalling Vesper afterward is still a manual step for an already-corrupted install. `npm install` for the bundled CLI package self-heals this automatically going forward via `postinstall.js`, which uses the same canary to decide whether to skip or re-run its own install.
301
+
294
302
  </details>
295
303
 
296
304
  <details>
@@ -82,13 +82,13 @@ This is a **separate, explicitly-invoked mode** — distinct from your normal ap
82
82
 
83
83
  ### 2. Archive completed tracking stories
84
84
 
85
- 1. List `.vesper/.tracking/stories/completed/`. For story files older than N days (default 30, or as specified), move them (via `Bash mv`, not delete) into `.vesper/.tracking/stories/completed/archive/YYYYMM/`, grouped by the month they were completed.
85
+ 1. List `.vesper/.tracking/stories/completed/`. Move **every** story file found there (via `Bash mv`, not delete) into `.vesper/.tracking/stories/completed/archive/YYYYMM/`, grouped by the month they were completed. There is no age condition — every run archives the entire current contents of `completed/`.
86
86
  2. Never touch `refining/`, `backlog/`, `inprogress/`, or `inreview/` — only `completed/`.
87
87
  3. Report the count moved and where.
88
88
 
89
89
  ### 3. Archive correlated tracking artifacts
90
90
 
91
- For each `stories/completed/<slug>` entry older than the same N-day threshold (default 30), move its correlated tracking artifacts — every `research/`, `plans/`, `details/`, `prompts/`, and `changes/` file whose name contains that `<slug>` — into `.vesper/.tracking/archive/YYYYMM/<slug>/` (grouped by the month the story was completed), via `Bash mv`, never delete.
91
+ For each `stories/completed/<slug>` entry archived in Step 2 (i.e., every completed story, unconditionally — this section no longer applies its own separate age gate; it always runs for whatever Step 2 just archived), move its correlated tracking artifacts — every `research/`, `plans/`, `details/`, `prompts/`, and `changes/` file whose name contains that `<slug>` — into `.vesper/.tracking/archive/YYYYMM/<slug>/` (grouped by the month the story was completed), via `Bash mv`, never delete.
92
92
 
93
93
  1. **Idempotent move**: if the source is already gone and the destination already holds the file, treat it as already done (a concurrent worktree archived it). Never error, never re-move.
94
94
  2. **Archive-with-a-flag fallback**: archive regardless of whether `feature-wrap-document` extracted durable knowledge for the slug first. Check the MCP memory graph (or a recorded wrap marker) for a completed feature-wrap for that slug; if none exists, write an empty `.unwrapped` marker file into the archived `<slug>/` folder so `/revalidate-knowledge` treats it as a **priority re-extraction candidate**. This preserves the non-destructive invariant (nothing is lost — archived, just flagged) without blocking retention indefinitely on a wrap step that may legitimately never run (Lightweight-path tasks have no wrap).
@@ -4,7 +4,7 @@ description: Compact persisted Vesper knowledge (history.md, memory.jsonl, compl
4
4
 
5
5
  Compact persisted Vesper knowledge. Delegate in parallel:
6
6
 
7
- 1. `history-logger` in Compaction Mode: rotate `.vesper/history.md` (archive entries older than the last 30 into `.vesper/history-archive/YYYYMM.md`), archive `.vesper/.tracking/stories/completed/` entries older than 30 days, and archive each completed story's correlated `research/plans/details/prompts/changes` tracking artifacts into `.vesper/.tracking/archive/YYYYMM/<slug>/` (idempotent move; flag any slug with no recorded feature-wrap as `.unwrapped` so `/revalidate-knowledge` re-extracts it).
7
+ 1. `history-logger` in Compaction Mode: rotate `.vesper/history.md` (archive entries older than the last 30 into `.vesper/history-archive/YYYYMM.md`), archive **every** `.vesper/.tracking/stories/completed/` entry unconditionally, and archive each completed story's correlated `research/plans/details/prompts/changes` tracking artifacts into `.vesper/.tracking/archive/YYYYMM/<slug>/` (idempotent move; flag any slug with no recorded feature-wrap as `.unwrapped` so `/revalidate-knowledge` re-extracts it).
8
8
  2. `feature-wrap-document` in Memory Compaction Mode: merge/dedupe stale entities in the MCP memory graph, never touching `current_task` or active entities.
9
9
 
10
10
  Report what was archived/merged from both. Nothing is deleted — only moved to archive files or consolidated within the memory graph.
@@ -83,13 +83,13 @@ This is a **separate, explicitly-invoked mode** — distinct from your normal ap
83
83
 
84
84
  ### 2. Archive completed tracking stories
85
85
 
86
- 1. List `.vesper/.tracking/stories/completed/`. For story files older than N days (default 30, or as specified), move them (via terminal `mv`, not delete) into `.vesper/.tracking/stories/completed/archive/YYYYMM/`, grouped by the month they were completed.
86
+ 1. List `.vesper/.tracking/stories/completed/`. Move **every** story file found there (via terminal `mv`, not delete) into `.vesper/.tracking/stories/completed/archive/YYYYMM/`, grouped by the month they were completed. There is no age condition — every run archives the entire current contents of `completed/`.
87
87
  2. Never touch `refining/`, `backlog/`, `inprogress/`, or `inreview/` — only `completed/`.
88
88
  3. Report the count moved and where.
89
89
 
90
90
  ### 3. Archive correlated tracking artifacts
91
91
 
92
- For each `stories/completed/<slug>` entry older than the same N-day threshold (default 30), move its correlated tracking artifacts — every `research/`, `plans/`, `details/`, `prompts/`, and `changes/` file whose name contains that `<slug>` — into `.vesper/.tracking/archive/YYYYMM/<slug>/` (grouped by the month the story was completed), via terminal `mv`, never delete.
92
+ For each `stories/completed/<slug>` entry archived in Step 2 (i.e., every completed story, unconditionally — this section no longer applies its own separate age gate; it always runs for whatever Step 2 just archived), move its correlated tracking artifacts — every `research/`, `plans/`, `details/`, `prompts/`, and `changes/` file whose name contains that `<slug>` — into `.vesper/.tracking/archive/YYYYMM/<slug>/` (grouped by the month the story was completed), via terminal `mv`, never delete.
93
93
 
94
94
  1. **Idempotent move**: if the source is already gone and the destination already holds the file, treat it as already done (a concurrent worktree archived it). Never error, never re-move.
95
95
  2. **Archive-with-a-flag fallback**: archive regardless of whether `@Feature Wrap and Retrospective Agent` extracted durable knowledge for the slug first. Check the MCP memory graph (or a recorded wrap marker) for a completed feature-wrap for that slug; if none exists, write an empty `.unwrapped` marker file into the archived `<slug>/` folder so `/revalidate-knowledge` treats it as a **priority re-extraction candidate**. This preserves the non-destructive invariant (nothing is lost — archived, just flagged) without blocking retention indefinitely on a wrap step that may legitimately never run (Lightweight-path tasks have no wrap).
@@ -8,7 +8,7 @@ Compact persisted Vesper knowledge — distinct from Claude Code's `/compact` or
8
8
 
9
9
  Delegate:
10
10
 
11
- 1. `@History Logger` in Compaction Mode: rotate `.vesper/history.md` (archive entries older than the last 30 into `.vesper/history-archive/YYYYMM.md`), archive `.vesper/.tracking/stories/completed/` entries older than 30 days, and archive each completed story's correlated `research/plans/details/prompts/changes` tracking artifacts into `.vesper/.tracking/archive/YYYYMM/<slug>/` (idempotent move; flag any slug with no recorded feature-wrap as `.unwrapped` so `/revalidate-knowledge` re-extracts it).
11
+ 1. `@History Logger` in Compaction Mode: rotate `.vesper/history.md` (archive entries older than the last 30 into `.vesper/history-archive/YYYYMM.md`), archive **every** `.vesper/.tracking/stories/completed/` entry unconditionally, and archive each completed story's correlated `research/plans/details/prompts/changes` tracking artifacts into `.vesper/.tracking/archive/YYYYMM/<slug>/` (idempotent move; flag any slug with no recorded feature-wrap as `.unwrapped` so `/revalidate-knowledge` re-extracts it).
12
12
  2. `@Feature Wrap and Retrospective Agent` in Memory Compaction Mode: merge/dedupe stale entities in the MCP memory graph, never touching `current_task` or active entities.
13
13
 
14
14
  Report what was archived/merged from both. Nothing is deleted — only moved to archive files or consolidated within the memory graph.
package/dist/cli.min.js CHANGED
@@ -1,38 +1,38 @@
1
- var Ds=(e,t)=>()=>(e&&(t=e(e=0)),t);import{access as Ls,constants as js,stat as so}from"node:fs/promises";async function g(e){try{return await Ls(e,js.F_OK),!0}catch{return!1}}var F=Ds(()=>{});import{Command as Kn}from"commander";import{readFileSync as Hn,existsSync as Jn}from"node:fs";import{fileURLToPath as zn}from"node:url";import{dirname as tt,join as Ms}from"node:path";F();import{resolve as Wr,basename as Br}from"node:path";import{spawn as qr}from"node:child_process";import{confirm as ae,input as Kr,number as Hr,select as Jr,checkbox as zr}from"@inquirer/prompts";import{readFile as T,writeFile as A,mkdir as pe,readdir as Bs}from"node:fs/promises";import{join as y,dirname as z}from"node:path";import{homedir as gt}from"node:os";import qs from"strip-json-comments";import{fileURLToPath as Fs}from"node:url";import{dirname as je,join as de,resolve as Vs}from"node:path";import{readdir as Rs}from"node:fs/promises";import{existsSync as Ns}from"node:fs";var Gs=Fs(import.meta.url),Us=je(Gs);function Ws(e){let t=e;for(;t!==je(t);){if(Ns(de(t,"package.json")))return t;t=je(t)}return Vs(e,"..","..","..")}var re=Ws(Us),b=de(re,"assets"),rt=de(b,"core");function Fe(e){if(!e||typeof e!="string")throw new Error("Asset name is required");if(e.includes("..")||e.includes("/")||e.includes("\\"))throw new Error(`Invalid asset name: ${e}`)}var I={agents:{dir:"agents",destDir:"agents",extension:".agent.md",isFolder:!0},prompts:{dir:"prompts",destDir:"prompts",extension:".prompt.md",isFolder:!0},instructions:{dir:"instructions",destDir:"instructions",extension:".instructions.md",isFolder:!0},skills:{dir:"skills",destDir:"skills",extension:"",isFolder:!0}};async function ne(e){let t=I[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=de(b,t.dir);try{return(await Rs(s,{withFileTypes:!0})).filter(n=>n.isDirectory()&&!n.name.startsWith(".")).map(n=>n.name)}catch{return[]}}function nt(e,t){Fe(t);let s=I[e];if(!s)throw new Error(`Unknown asset type: ${e}`);return de(b,s.dir,t)}async function V(e,{cwd:t,timeout:s}={}){let{execFile:r}=await import("node:child_process"),{promisify:n}=await import("node:util"),i=n(r);try{let{stdout:a}=await i("git",e,{cwd:t,timeout:s});return a.trim()}catch{return null}}function K(e){let t=gt();return e.startsWith(t)?"~"+e.slice(t.length).replace(/\\/g,"/"):e.replace(/\\/g,"/")}var Ks=/node_modules\/(?:vesper-cli|vespercli)\/(.+)$/;function he(e){if(typeof e!="string")return e;let t=e.match(Ks);return t?K(y(re,t[1])):e}function Hs(e){return e==="vesper-cli"||e.startsWith("vesper-cli ")||e.endsWith("/vesper-cli")}var J={agents:"chat.agentFilesLocations",instructions:"chat.instructionsFilesLocations",prompts:"chat.promptFilesLocations",skills:"chat.agentSkillsLocations"},ue="chat.tools.terminal.autoApprove",mt="chat.tools.terminal.enableAutoApprove",Re="chat.tools.autoApprove",w="chat.tools.eligibleForAutoApproval",ht="chat.agent.maxRequests",wt="chat.includeReferencedInstructions",vt="chat.customAgentInSubagent.enabled",yt="chat.agent.enabled",_t="github.copilot.chat.omitBaseAgentInstructions",St="chat.mcp.discovery.enabled",xt="chat.mcp.autoStart",S="github.copilot.chat.additionalReadAccessPaths",M={maxRequests:300,terminalEnableAutoApprove:!0,omitBaseAgentInstructions:!0,enableMcpServer:!0},Js=[ht,wt,vt,yt,_t,St,xt,mt,ue,Re,w],Y=["vesper-indexing","sequential-thinking","memory"],Ve=[".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 ot="# <!-- vesper:gitignore:start -->",it="# <!-- vesper:gitignore:end -->";async function we(e){let t=y(e,".gitignore"),s=[ot,...Ve,it].join(`
2
- `),r=new RegExp(`${ot}[\\s\\S]*?${it}`),n="";try{n=await T(t,"utf-8")}catch(a){if(a.code!=="ENOENT")throw a;return await A(t,`${s}
1
+ var js=(e,t)=>()=>(e&&(t=e(e=0)),t);import{access as Vs,constants as Fs,stat as no}from"node:fs/promises";async function g(e){try{return await Vs(e,Fs.F_OK),!0}catch{return!1}}var V=js(()=>{});import{Command as Jn}from"commander";import{readFileSync as zn,existsSync as Yn}from"node:fs";import{fileURLToPath as Xn}from"node:url";import{dirname as st,join as Ls}from"node:path";V();import{resolve as qr,basename as Kr}from"node:path";import{spawn as Hr}from"node:child_process";import{confirm as ae,input as Jr,number as zr,select as Yr,checkbox as Xr}from"@inquirer/prompts";import{readFile as T,writeFile as A,mkdir as pe,readdir as Ks}from"node:fs/promises";import{join as y,dirname as z}from"node:path";import{homedir as mt}from"node:os";import Hs from"strip-json-comments";import{fileURLToPath as Rs}from"node:url";import{dirname as Ve,join as de,resolve as Ns}from"node:path";import{readdir as Gs}from"node:fs/promises";import{existsSync as Us}from"node:fs";var Ws=Rs(import.meta.url),Bs=Ve(Ws);function qs(e){let t=e;for(;t!==Ve(t);){if(Us(de(t,"package.json")))return t;t=Ve(t)}return Ns(e,"..","..","..")}var re=qs(Bs),b=de(re,"assets"),nt=de(b,"core");function Fe(e){if(!e||typeof e!="string")throw new Error("Asset name is required");if(e.includes("..")||e.includes("/")||e.includes("\\"))throw new Error(`Invalid asset name: ${e}`)}var I={agents:{dir:"agents",destDir:"agents",extension:".agent.md",isFolder:!0},prompts:{dir:"prompts",destDir:"prompts",extension:".prompt.md",isFolder:!0},instructions:{dir:"instructions",destDir:"instructions",extension:".instructions.md",isFolder:!0},skills:{dir:"skills",destDir:"skills",extension:"",isFolder:!0}};async function ne(e){let t=I[e];if(!t)throw new Error(`Unknown asset type: ${e}`);let s=de(b,t.dir);try{return(await Gs(s,{withFileTypes:!0})).filter(n=>n.isDirectory()&&!n.name.startsWith(".")).map(n=>n.name)}catch{return[]}}function ot(e,t){Fe(t);let s=I[e];if(!s)throw new Error(`Unknown asset type: ${e}`);return de(b,s.dir,t)}async function F(e,{cwd:t,timeout:s}={}){let{execFile:r}=await import("node:child_process"),{promisify:n}=await import("node:util"),i=n(r);try{let{stdout:a}=await i("git",e,{cwd:t,timeout:s});return a.trim()}catch{return null}}function K(e){let t=mt();return e.startsWith(t)?"~"+e.slice(t.length).replace(/\\/g,"/"):e.replace(/\\/g,"/")}var Js=/node_modules\/(?:vesper-cli|vespercli)\/(.+)$/;function he(e){if(typeof e!="string")return e;let t=e.match(Js);return t?K(y(re,t[1])):e}function zs(e){return e==="vesper-cli"||e.startsWith("vesper-cli ")||e.endsWith("/vesper-cli")}var J={agents:"chat.agentFilesLocations",instructions:"chat.instructionsFilesLocations",prompts:"chat.promptFilesLocations",skills:"chat.agentSkillsLocations"},ue="chat.tools.terminal.autoApprove",ht="chat.tools.terminal.enableAutoApprove",Ne="chat.tools.autoApprove",v="chat.tools.eligibleForAutoApproval",vt="chat.agent.maxRequests",wt="chat.includeReferencedInstructions",yt="chat.customAgentInSubagent.enabled",_t="chat.agent.enabled",St="github.copilot.chat.omitBaseAgentInstructions",kt="chat.mcp.discovery.enabled",xt="chat.mcp.autoStart",S="github.copilot.chat.additionalReadAccessPaths",M={maxRequests:300,terminalEnableAutoApprove:!0,omitBaseAgentInstructions:!0,enableMcpServer:!0},Ys=[vt,wt,yt,_t,St,kt,xt,ht,ue,Ne,v],Y=["vesper-indexing","sequential-thinking","memory"],Re=[".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 it="# <!-- vesper:gitignore:start -->",at="# <!-- vesper:gitignore:end -->";async function ve(e){let t=y(e,".gitignore"),s=[it,...Re,at].join(`
2
+ `),r=new RegExp(`${it}[\\s\\S]*?${at}`),n="";try{n=await T(t,"utf-8")}catch(a){if(a.code!=="ENOENT")throw a;return await A(t,`${s}
3
3
  `,"utf-8"),{created:!0,updated:!1}}if(r.test(n)){let a=n.replace(r,s);return a!==n?(await A(t,a,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let i=n.endsWith(`
4
4
  `)?`
5
5
  `:`
6
6
 
7
7
  `;return await A(t,`${n}${i}${s}
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(`
8
+ `,"utf-8"),{created:!1,updated:!0}}async function we(e){let{execFile:t}=await import("node:child_process"),{promisify:s}=await import("node:util"),r=s(t),n=async d=>{try{let{stdout:l}=await r("git",d,{cwd:e});return l}catch{return null}},i=await n(["rev-parse","--is-inside-work-tree"]);if(i===null||i.trim()!=="true")return[];let a=await n(["ls-files","-z","--",...Re]);if(!a)return[];let c=new Set(a.split("\0").filter(Boolean));return Re.filter(d=>c.has(d))}var ct="Vesper: worktree bootstrap";async function Ct(e){let t=y(e,".vscode","tasks.json"),s={label:ct,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===ct);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 lt=["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"],Ge={"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 Xs(e){try{let s=(await Ks(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 Xs(e);return t?{type:E.WORKSPACE_FILE,settingsPath:t,workspaceFile:t}:{type:E.FOLDER,settingsPath:y(e,".vscode","settings.json"),workspaceFile:null}}function Ue(e,t=null){return t?.workspaceFile?y(z(t.workspaceFile),".vesperrc"):y(e,".vesperrc")}function fe(e){let t=Hs(e,{trailingCommas:!0});return JSON.parse(t)}async function k(e){let t=await _(e);try{let s=await T(t.settingsPath,"utf-8"),r=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 Qs(e){return y(e,".vesper","tracking.json")}async function m(e){let t=await _(e),s=Ue(e,t),r=Qs(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 Zs(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(/^~/,mt()):y(n,a)})}catch{return[]}}async function At(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 Zs(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 Pt(e,t,s){let r=await _(e),n=Ue(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=Ue(e,s);await A(r,JSON.stringify(t,null,2),"utf-8")}async function Et(e,t){let s=await _(e),r=await k(e),n=await m(e),i=[],a=[];for(let{path:c,settingKey:d}of t){if(r[d]||(r[d]={}),r[d][c]){a.push(c),n.paths.includes(c)||n.paths.push(c);continue}r[d][c]=!0,i.push(c),n.paths.includes(c)||n.paths.push(c)}return i.length>0&&await P(e,r),n.paths.length>0&&(n.addedAt=n.addedAt||new Date().toISOString(),n.updatedAt=new Date().toISOString(),n.workspaceType=s.type,n.settingsPath=s.settingsPath,await C(e,n)),{added:i,skipped:a,workspaceType:s.type}}async function bt(e){let t=await k(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 Ys)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=xe(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 er=["agents","prompts","instructions"];function tr(){let e=[];for(let n of er){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 Tt(e,t=!0){let s=await _(e),r=await k(e);if(r[ht]=t,t){r[ue]||(r[ue]={});for(let n of lt)r[ue][n]=!0}return await P(e,r),{configured:t?lt.length:0,workspaceType:s.type}}async function $t(e,t={}){let{maxRequests:s=M.maxRequests,omitBaseAgentInstructions:r=M.omitBaseAgentInstructions}=t,n=await k(e);n[vt]=s,n[wt]=!0,n[yt]=!0,n[_t]=!0,n[St]=r,n[kt]=!0,n[xt]="newAndOutdated",n[S]||(n[S]=[]),await P(e,n)}async function Ot(e,t){let s=await k(e),r=s[S]||[];r.includes(t)||(r.push(t),s[S]=r,await P(e,s));let n=await m(e);return n.readAccessPaths||(n.readAccessPaths=[]),n.readAccessPaths.includes(t)||(n.readAccessPaths.push(t),n.updatedAt=new Date().toISOString(),await C(e,n)),r}async function It(e,t){let s=await k(e),r=s[S]||[],n=r.indexOf(t);n!==-1&&(r.splice(n,1),s[S]=r,await P(e,s));let i=await m(e);if(i.readAccessPaths){let a=i.readAccessPaths.indexOf(t);a!==-1&&(i.readAccessPaths.splice(a,1),i.updatedAt=new Date().toISOString(),await C(e,i))}return r}async function Mt(e){return(await k(e))[S]||[]}function Dt(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(ot(e,t)),settingKey:r,type:e,name:t}}async function oe(e){return(await m(e)).paths}async function Lt(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 k(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))zs(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 jt(e){let t=await _(e),s=await k(e),r=await m(e),n=tr(),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 dt="# <!-- vesper:hook:start -->",ut="# <!-- vesper:hook:end -->";async function sr(e){if(await F(["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 F(["config","core.hooksPath"],{cwd:e});if(n)return r(n);let i=await F(["rev-parse","--git-common-dir"],{cwd:e});return i?y(r(i),"hooks"):null}async function rr(e,t){let s=await sr(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(`${dt}[\\s\\S]*?${ut}`));if(!i)throw new Error(`Hook source ${r} is missing its vesper:hook guard markers`);let a=i[0],c=new RegExp(`${dt}[\\s\\S]*?${ut}`);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 pt(d),{installed:!1,updated:!0,hooksDir:s}):{installed:!1,updated:!1,hooksDir:s}}let u=l.endsWith(`
9
9
  `)?`
10
10
  `:`
11
11
 
12
12
  `;return await A(d,`${l}${u}${a}
13
- `,"utf-8"),await ut(d),{installed:!1,updated:!0,hooksDir:s}}async function ut(e){let{chmod:t}=await import("node:fs/promises");try{await t(e,493)}catch{}}var sr=["pre-commit","post-checkout"];async function _e(e){let t={};for(let s of sr)t[s]=await tr(e,s);return t}var pt="# <!-- vesper:gitattributes:start -->",ft="# <!-- vesper:gitattributes:end -->",rr=[".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 Se(e){let t=y(e,".gitattributes"),s=[pt,...rr,ft].join(`
14
- `),r=new RegExp(`${pt}[\\s\\S]*?${ft}`),n="";try{n=await T(t,"utf-8")}catch(a){if(a.code!=="ENOENT")throw a;return await A(t,`${s}
13
+ `,"utf-8"),await pt(d),{installed:!1,updated:!0,hooksDir:s}}async function pt(e){let{chmod:t}=await import("node:fs/promises");try{await t(e,493)}catch{}}var nr=["pre-commit","post-checkout"];async function _e(e){let t={};for(let s of nr)t[s]=await rr(e,s);return t}var ft="# <!-- vesper:gitattributes:start -->",gt="# <!-- vesper:gitattributes:end -->",or=[".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 Se(e){let t=y(e,".gitattributes"),s=[ft,...or,gt].join(`
14
+ `),r=new RegExp(`${ft}[\\s\\S]*?${gt}`),n="";try{n=await T(t,"utf-8")}catch(a){if(a.code!=="ENOENT")throw a;return await A(t,`${s}
15
15
  `,"utf-8"),{created:!0,updated:!1}}if(r.test(n)){let a=n.replace(r,s);return a!==n?(await A(t,a,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let i=n.endsWith(`
16
16
  `)?`
17
17
  `:`
18
18
 
19
19
  `;return await A(t,`${n}${i}${s}
20
- `,"utf-8"),{created:!1,updated:!0}}async function xe(e){if(await V(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{configured:!1};let r=`node "${y(b,"hooks","merge-memory-jsonl.js")}" %O %A %B`;return await V(["config","merge.vesper-memory.name","Vesper memory.jsonl entity-aware merge"],{cwd:e}),{configured:await V(["config","merge.vesper-memory.driver",r],{cwd:e})!==null}}function ke(e){return y(e,".vscode","mcp.json")}function q(){return y(re,"src","mcp","vesper-indexing","dist","index.js")}async function G(e){let t=ke(e);try{let s=await T(t,"utf-8");return fe(s)}catch(s){if(s.code==="ENOENT")return{servers:{}};if(s instanceof SyntaxError)return{servers:{}};throw s}}async function Ce(e,t){let s=ke(e),r=z(s);await pe(r,{recursive:!0}),await A(s,JSON.stringify(t,null," "),"utf-8")}async function Q(e,t=!0){let s=await G(e),r=K(q()),n=[];if(s.servers||(s.servers={}),t?(s.servers["vesper-indexing"]={type:"stdio",command:"node",args:[r],env:{VESPER_INDEX_ROOT:"${workspaceFolder}"}},n.push("vesper-indexing"),s.servers["sequential-thinking"]={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},n.push("sequential-thinking"),s.servers.memory={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:"${workspaceFolder}/.vesper/memory.jsonl"}},n.push("memory")):(delete s.servers["vesper-indexing"],delete s.servers["sequential-thinking"],delete s.servers.memory),await Ce(e,s),t&&n.length>0){let i=await m(e);i.mcp=i.mcp||{},i.mcp.servers=n,i.mcp.updatedAt=new Date().toISOString(),await C(e,i)}return{configured:t,mcpPath:ke(e),servers:n}}async function Ae(e){return!!(await G(e)).servers?.["vesper-indexing"]}async function jt(e){let t=await _(e),s=await x(e);s[Re]=!1,s[w]||(s[w]={});for(let r of R)s[w][r]=!0;return await P(e,s),{configured:R.length,workspaceType:t.type}}async function Ft(e,t){let s=Ne[t];if(!s||s.length===0)return{added:[],agentName:t};let r=await x(e),n=await _(e),i=await m(e,n);r[w]||(r[w]={});let a=[];for(let c of s)r[w][c]||(r[w][c]=!0,a.push(c));return a.length>0&&(await P(e,r),i.mcp=i.mcp||{},i.mcp.agentTools=i.mcp.agentTools||{},i.mcp.agentTools[t]=s,i.mcp.updatedAt=new Date().toISOString(),await C(e,i)),{added:a,agentName:t}}async function Vt(e,t){let s=N[t];if(!s)return{added:!1,serverName:t,tools:[],error:`Unknown MCP server: ${t}`};let r=await G(e),n=await x(e),i=await _(e),a=await m(e,i);if(r.servers||(r.servers={}),r.servers[t])return{added:!1,serverName:t,tools:[],error:"Already configured"};let c=JSON.parse(JSON.stringify(s.config));if(t==="vesper-indexing"){let l=K(q());c.args&&(c.args=c.args.map(f=>f==="${VESPER_INDEXING_PATH}"?l:f))}r.servers[t]=c,await Ce(e,r),n[w]||(n[w]={});let d=[];for(let l of s.tools||[])n[w][l]||(n[w][l]=!0,d.push(l));return n[Re]=!1,await P(e,n),a.mcp=a.mcp||{},a.mcp.servers=a.mcp.servers||[],a.mcp.servers.includes(t)||a.mcp.servers.push(t),a.mcp.updatedAt=new Date().toISOString(),await C(e,a),{added:!0,serverName:t,tools:d}}async function Rt(e,t){let s=N[t],r=await G(e),n=await x(e),i=await _(e),a=await m(e,i),c=!1;r.servers&&r.servers[t]&&(delete r.servers[t],await Ce(e,r),c=!0);let d=[];if(s&&n[w]){for(let l of s.tools||[])n[w][l]&&(delete n[w][l],d.push(l));d.length>0&&await P(e,n)}return a.mcp?.servers&&(a.mcp.servers=a.mcp.servers.filter(l=>l!==t),a.mcp.updatedAt=new Date().toISOString(),await C(e,a)),{removed:c,serverName:t,tools:d}}import{readFile as U,writeFile as $,mkdir as Z,readdir as Gt,rm as Nt,cp as Ut}from"node:fs/promises";import{join as v,dirname as We,basename as nr}from"node:path";import{homedir as or}from"node:os";F();var ie=v(b,"claude"),Wt=["agents","commands","skills"],Pe="vesper";function W(e=Pe){return v(or(),".claude","skills",e)}function Ee(e){return v(e,".claude","vesper")}function Bt(e){return v(e,"CLAUDE.md")}function ee(e){return v(e,".mcp.json")}function be(e){return v(e,".claude","settings.json")}function qt(e,t){return t?e.replace(/^(name:\s*)([a-z0-9-]+)/m,(s,r,n)=>n.startsWith(t)?s:`${r}${t}${n}`):e}async function ir(e,t,s,r){if(!await g(e))return{copied:0};await Z(t,{recursive:!0});let n=await Gt(e,{withFileTypes:!0}),i=0;for(let a of n){let c=v(e,a.name);if(a.isDirectory()){await Ut(c,v(t,a.name),{recursive:!0}),i+=1;continue}if(!a.name.endsWith(".md"))continue;let d=await U(c,"utf-8"),l=qt(d,s),f=r&&s&&!a.name.startsWith(s)?`${s}${a.name}`:a.name;await $(v(t,f),l,"utf-8"),i+=1}return{copied:i}}async function ar(e,t,s){let r=v(e,".claude-plugin");await Z(r,{recursive:!0});let n={name:t,description:"Vesper specialist catalog \u2014 subagents, slash commands, and skills for AI-orchestrated development.",version:s};await $(v(r,"plugin.json"),JSON.stringify(n,null,2),"utf-8")}async function Te({pluginName:e=Pe,namePrefix:t="",version:s="0.0.0"}={}){let r=W(e),n={};for(let i of Wt){let a=v(ie,i),c=v(r,i),l=await ir(a,c,i==="skills"?"":t,i!=="skills");n[i]=l.copied}return await ar(r,e,s),{pluginDir:r,counts:n}}async function Kt(e,t,{pluginName:s=Pe,namePrefix:r=""}={}){let n=W(s),i=v(n,e);if(await Z(i,{recursive:!0}),e==="skills"){let u=v(ie,"skills",t);if(!await g(u))throw new Error(`Skill "${t}" not found in assets/claude/skills/`);return await Ut(u,v(i,t),{recursive:!0}),{installedAs:t}}let a=".md",c=v(ie,e,`${t}${a}`);if(!await g(c))throw new Error(`${e.slice(0,-1)} "${t}" not found in assets/claude/${e}/`);let d=await U(c,"utf-8"),l=qt(d,r),f=r&&!t.startsWith(r)?`${r}${t}${a}`:`${t}${a}`;return await $(v(i,f),l,"utf-8"),{installedAs:nr(f,a)}}async function Ht(e=Pe){let t=W(e),s={};for(let r of Wt){let n=v(t,r);if(!await g(n)){s[r]=[];continue}let i=await Gt(n,{withFileTypes:!0});s[r]=r==="skills"?i.filter(a=>a.isDirectory()).map(a=>a.name).sort():i.filter(a=>a.isFile()&&a.name.endsWith(".md")).map(a=>a.name.replace(/\.md$/,"")).sort()}return s}var Be="<!-- vesper:start -->",qe="<!-- vesper:end -->";function cr(){return[Be,"@.claude/vesper/orchestrator.md","@.claude/vesper/orchestration.md","@.claude/vesper/context.md",qe].join(`
21
- `)}async function lr(e){let t=Bt(e),s=cr(),r=new RegExp(`${Be}[\\s\\S]*?${qe}`);if(!await g(t))return await Z(We(t),{recursive:!0}),await $(t,`${s}
20
+ `,"utf-8"),{created:!1,updated:!0}}async function ke(e){if(await F(["rev-parse","--is-inside-work-tree"],{cwd:e})!=="true")return{configured:!1};let r=`node "${y(b,"hooks","merge-memory-jsonl.js")}" %O %A %B`;return await F(["config","merge.vesper-memory.name","Vesper memory.jsonl entity-aware merge"],{cwd:e}),{configured:await F(["config","merge.vesper-memory.driver",r],{cwd:e})!==null}}function xe(e){return y(e,".vscode","mcp.json")}function q(){return y(re,"src","mcp","vesper-indexing","dist","index.js")}async function G(e){let t=xe(e);try{let s=await T(t,"utf-8");return fe(s)}catch(s){if(s.code==="ENOENT")return{servers:{}};if(s instanceof SyntaxError)return{servers:{}};throw s}}async function Ce(e,t){let s=xe(e),r=z(s);await pe(r,{recursive:!0}),await A(s,JSON.stringify(t,null," "),"utf-8")}async function Q(e,t=!0){let s=await G(e),r=K(q()),n=[];if(s.servers||(s.servers={}),t?(s.servers["vesper-indexing"]={type:"stdio",command:"node",args:[r],env:{VESPER_INDEX_ROOT:"${workspaceFolder}"}},n.push("vesper-indexing"),s.servers["sequential-thinking"]={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},n.push("sequential-thinking"),s.servers.memory={type:"stdio",command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:"${workspaceFolder}/.vesper/memory.jsonl"}},n.push("memory")):(delete s.servers["vesper-indexing"],delete s.servers["sequential-thinking"],delete s.servers.memory),await Ce(e,s),t&&n.length>0){let i=await m(e);i.mcp=i.mcp||{},i.mcp.servers=n,i.mcp.updatedAt=new Date().toISOString(),await C(e,i)}return{configured:t,mcpPath:xe(e),servers:n}}async function Ae(e){return!!(await G(e)).servers?.["vesper-indexing"]}async function Vt(e){let t=await _(e),s=await k(e);s[Ne]=!1,s[v]||(s[v]={});for(let r of R)s[v][r]=!0;return await P(e,s),{configured:R.length,workspaceType:t.type}}async function Ft(e,t){let s=Ge[t];if(!s||s.length===0)return{added:[],agentName:t};let r=await k(e),n=await _(e),i=await m(e,n);r[v]||(r[v]={});let a=[];for(let c of s)r[v][c]||(r[v][c]=!0,a.push(c));return a.length>0&&(await P(e,r),i.mcp=i.mcp||{},i.mcp.agentTools=i.mcp.agentTools||{},i.mcp.agentTools[t]=s,i.mcp.updatedAt=new Date().toISOString(),await C(e,i)),{added:a,agentName:t}}async function Rt(e,t){let s=N[t];if(!s)return{added:!1,serverName:t,tools:[],error:`Unknown MCP server: ${t}`};let r=await G(e),n=await k(e),i=await _(e),a=await m(e,i);if(r.servers||(r.servers={}),r.servers[t])return{added:!1,serverName:t,tools:[],error:"Already configured"};let c=JSON.parse(JSON.stringify(s.config));if(t==="vesper-indexing"){let l=K(q());c.args&&(c.args=c.args.map(f=>f==="${VESPER_INDEXING_PATH}"?l:f))}r.servers[t]=c,await Ce(e,r),n[v]||(n[v]={});let d=[];for(let l of s.tools||[])n[v][l]||(n[v][l]=!0,d.push(l));return n[Ne]=!1,await P(e,n),a.mcp=a.mcp||{},a.mcp.servers=a.mcp.servers||[],a.mcp.servers.includes(t)||a.mcp.servers.push(t),a.mcp.updatedAt=new Date().toISOString(),await C(e,a),{added:!0,serverName:t,tools:d}}async function Nt(e,t){let s=N[t],r=await G(e),n=await k(e),i=await _(e),a=await m(e,i),c=!1;r.servers&&r.servers[t]&&(delete r.servers[t],await Ce(e,r),c=!0);let d=[];if(s&&n[v]){for(let l of s.tools||[])n[v][l]&&(delete n[v][l],d.push(l));d.length>0&&await P(e,n)}return a.mcp?.servers&&(a.mcp.servers=a.mcp.servers.filter(l=>l!==t),a.mcp.updatedAt=new Date().toISOString(),await C(e,a)),{removed:c,serverName:t,tools:d}}import{readFile as U,writeFile as $,mkdir as Z,readdir as Ut,rm as Gt,cp as Wt}from"node:fs/promises";import{join as w,dirname as Be,basename as ir}from"node:path";import{homedir as ar}from"node:os";V();var ie=w(b,"claude"),Bt=["agents","commands","skills"],Pe="vesper";function W(e=Pe){return w(ar(),".claude","skills",e)}function Ee(e){return w(e,".claude","vesper")}function qt(e){return w(e,"CLAUDE.md")}function ee(e){return w(e,".mcp.json")}function be(e){return w(e,".claude","settings.json")}function Kt(e,t){return t?e.replace(/^(name:\s*)([a-z0-9-]+)/m,(s,r,n)=>n.startsWith(t)?s:`${r}${t}${n}`):e}async function cr(e,t,s,r){if(!await g(e))return{copied:0};await Z(t,{recursive:!0});let n=await Ut(e,{withFileTypes:!0}),i=0;for(let a of n){let c=w(e,a.name);if(a.isDirectory()){await Wt(c,w(t,a.name),{recursive:!0}),i+=1;continue}if(!a.name.endsWith(".md"))continue;let d=await U(c,"utf-8"),l=Kt(d,s),f=r&&s&&!a.name.startsWith(s)?`${s}${a.name}`:a.name;await $(w(t,f),l,"utf-8"),i+=1}return{copied:i}}async function lr(e,t,s){let r=w(e,".claude-plugin");await Z(r,{recursive:!0});let n={name:t,description:"Vesper specialist catalog \u2014 subagents, slash commands, and skills for AI-orchestrated development.",version:s};await $(w(r,"plugin.json"),JSON.stringify(n,null,2),"utf-8")}async function Te({pluginName:e=Pe,namePrefix:t="",version:s="0.0.0"}={}){let r=W(e),n={};for(let i of Bt){let a=w(ie,i),c=w(r,i),l=await cr(a,c,i==="skills"?"":t,i!=="skills");n[i]=l.copied}return await lr(r,e,s),{pluginDir:r,counts:n}}async function Ht(e,t,{pluginName:s=Pe,namePrefix:r=""}={}){let n=W(s),i=w(n,e);if(await Z(i,{recursive:!0}),e==="skills"){let u=w(ie,"skills",t);if(!await g(u))throw new Error(`Skill "${t}" not found in assets/claude/skills/`);return await Wt(u,w(i,t),{recursive:!0}),{installedAs:t}}let a=".md",c=w(ie,e,`${t}${a}`);if(!await g(c))throw new Error(`${e.slice(0,-1)} "${t}" not found in assets/claude/${e}/`);let d=await U(c,"utf-8"),l=Kt(d,r),f=r&&!t.startsWith(r)?`${r}${t}${a}`:`${t}${a}`;return await $(w(i,f),l,"utf-8"),{installedAs:ir(f,a)}}async function Jt(e=Pe){let t=W(e),s={};for(let r of Bt){let n=w(t,r);if(!await g(n)){s[r]=[];continue}let i=await Ut(n,{withFileTypes:!0});s[r]=r==="skills"?i.filter(a=>a.isDirectory()).map(a=>a.name).sort():i.filter(a=>a.isFile()&&a.name.endsWith(".md")).map(a=>a.name.replace(/\.md$/,"")).sort()}return s}var qe="<!-- vesper:start -->",Ke="<!-- vesper:end -->";function dr(){return[qe,"@.claude/vesper/orchestrator.md","@.claude/vesper/orchestration.md","@.claude/vesper/context.md",Ke].join(`
21
+ `)}async function ur(e){let t=qt(e),s=dr(),r=new RegExp(`${qe}[\\s\\S]*?${Ke}`);if(!await g(t))return await Z(Be(t),{recursive:!0}),await $(t,`${s}
22
22
  `,"utf-8"),{created:!0,updated:!1};let n=await U(t,"utf-8");if(r.test(n)){let a=n.replace(r,s);return a!==n?(await $(t,a,"utf-8"),{created:!1,updated:!0}):{created:!1,updated:!1}}let i=`${s}
23
23
 
24
- ${n}`;return await $(t,i,"utf-8"),{created:!1,updated:!0}}function dr(e){let t=new RegExp(`${Be}[\\s\\S]*?${qe}\\n*`);return e.replace(t,"")}async function $e(e){let t=Ee(e);await Z(t,{recursive:!0});let s={orchestrator:"refreshed",orchestration:"skipped",context:"skipped"},r=v(ie,"vesper-orchestrator.md"),n=v(t,"orchestrator.md");await $(n,await U(r,"utf-8"),"utf-8");let i=v(t,"orchestration.md");await g(i)||(await $(i,await U(v(ie,"orchestration.md.tpl"),"utf-8"),"utf-8"),s.orchestration="created");let a=v(t,"context.md");await g(a)||(await $(a,await U(v(ie,"context.md.tpl"),"utf-8"),"utf-8"),s.context="created");let c=await lr(e);return s.claudeMd=c.created?"created":c.updated?"updated":"unchanged",s}async function ge(e){let t=ee(e);try{let s=await U(t,"utf-8");return JSON.parse(s)}catch(s){return s.code==="ENOENT"?{mcpServers:{}}:{mcpServers:{}}}}async function Ke(e,t){let s=ee(e);await Z(We(s),{recursive:!0}),await $(s,JSON.stringify(t,null," "),"utf-8")}function ur(e){return{"vesper-indexing":{command:"node",args:[q()],env:{VESPER_INDEX_ROOT:e}},"sequential-thinking":{command:"npx",args:["-y","@modelcontextprotocol/server-sequential-thinking"]},memory:{command:"npx",args:["-y","@modelcontextprotocol/server-memory"],env:{MEMORY_FILE_PATH:v(e,".vesper","memory.jsonl")}}}}async function te(e,t=!0){let s=await ge(e);s.mcpServers||(s.mcpServers={});let r=ur(e),n=Object.keys(r);if(t)for(let[i,a]of Object.entries(r))s.mcpServers[i]=a;else for(let i of n)delete s.mcpServers[i];return await Ke(e,s),{configured:t,mcpPath:ee(e),servers:t?n:[]}}function Ue(e,t){return String(e).replace(/\$\{VESPER_INDEXING_PATH\}/g,q()).replace(/\$\{workspaceFolder\}/g,t).replace(/\$\{env:([^}]+)\}/g,"$${$1}")}function pr(e,{workspaceRoot:t}){let{type:s,...r}=structuredClone(e);if(typeof r.command=="string"&&(r.command=Ue(r.command,t)),Array.isArray(r.args)&&(r.args=r.args.map(n=>Ue(n,t))),r.env&&typeof r.env=="object")for(let[n,i]of Object.entries(r.env))r.env[n]=Ue(i,t);return r}async function Jt(e,t){if(Y.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=N[t];if(!s)return{added:!1,serverName:t,error:`Unknown MCP server: ${t}`};let r=await ge(e);if(r.mcpServers||(r.mcpServers={}),r.mcpServers[t])return{added:!1,serverName:t,error:"Already configured"};r.mcpServers[t]=pr(s.config,{workspaceRoot:e}),await Ke(e,r);let n=await m(e);return n.mcp=n.mcp||{},n.mcp.servers=n.mcp.servers||[],n.mcp.servers.includes(t)||n.mcp.servers.push(t),n.mcp.updatedAt=new Date().toISOString(),await C(e,n),{added:!0,serverName:t}}async function zt(e,t){if(Y.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 ge(e),r=!1;s.mcpServers&&s.mcpServers[t]&&(delete s.mcpServers[t],await Ke(e,s),r=!0);let n=await m(e);return n.mcp?.servers&&(n.mcp.servers=n.mcp.servers.filter(i=>i!==t),n.mcp.updatedAt=new Date().toISOString(),await C(e,n)),{removed:r,serverName:t}}async function Yt(e){let t=await ge(e),s=Object.keys(t.mcpServers||{}),r=s.filter(n=>!N[n]);return{configured:s,custom:r}}async function Xt(e){let t=new Set,s=[];try{s=await D(e)}catch{s=[]}if(s.includes("claude"))try{let a=await ge(e);for(let c of Object.keys(a.mcpServers||{}))t.add(c)}catch{}if(s.includes("copilot"))try{let a=await G(e);for(let c of Object.keys(a.servers||{}))t.add(c)}catch{}let r=[];try{let a=await m(e);r=Array.isArray(a.mcp?.servers)?a.mcp.servers:[]}catch{r=[]}let n=new Set(r);return{drifted:[...t].filter(a=>!Y.includes(a)&&!n.has(a))}}async function Oe(e){let t=be(e),s={};try{s=JSON.parse(await U(t,"utf-8"))}catch{s={}}s.permissions||(s.permissions={}),Array.isArray(s.permissions.allow)||(s.permissions.allow=[]);let r=["mcp__vesper-indexing__vesper_search","mcp__vesper-indexing__vesper_symbols","mcp__vesper-indexing__vesper_status","mcp__vesper-indexing__vesper_reindex","mcp__sequential-thinking__sequentialthinking","mcp__memory__create_entities","mcp__memory__create_relations","mcp__memory__add_observations","mcp__memory__delete_entities","mcp__memory__delete_observations","mcp__memory__delete_relations","mcp__memory__read_graph","mcp__memory__search_nodes","mcp__memory__open_nodes"],n=0;for(let i of r)s.permissions.allow.includes(i)||(s.permissions.allow.push(i),n+=1);return mr(s),await Z(We(t),{recursive:!0}),await $(t,JSON.stringify(s,null," "),"utf-8"),{configured:n,settingsPath:t}}var Qt=".claude/vesper/",fr=`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){}"`,Zt="worktree bootstrap",gr="command -v vespercli >/dev/null 2>&1 && vespercli worktree bootstrap --quiet || true";function mr(e){e.hooks||(e.hooks={}),Array.isArray(e.hooks.SessionStart)||(e.hooks.SessionStart=[]);let t=s=>e.hooks.SessionStart.some(r=>(r?.hooks||[]).some(n=>typeof n?.command=="string"&&n.command.includes(s)));t(Qt)||e.hooks.SessionStart.push({matcher:"clear",hooks:[{type:"command",command:fr}]}),t(Zt)||e.hooks.SessionStart.push({hooks:[{type:"command",command:gr}]})}function hr(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(Qt)||s.command.includes(Zt)))),e.hooks.SessionStart.length===0&&delete e.hooks.SessionStart,e.hooks&&Object.keys(e.hooks).length===0&&delete e.hooks)}async function es(e,t){let s=await m(e);return s.claude={...s.claude,...t,updatedAt:new Date().toISOString()},await C(e,s),s.claude}async function Ie(e){let t=Ee(e);await Nt(t,{recursive:!0,force:!0});let s=Bt(e);if(await g(s)){let i=await U(s,"utf-8"),a=dr(i);a.trim()?await $(s,a,"utf-8"):await Nt(s,{force:!0})}await te(e,!1);let r=be(e);if(await g(r))try{let i=JSON.parse(await U(r,"utf-8"));hr(i),await $(r,JSON.stringify(i,null," "),"utf-8")}catch{}let n=await m(e);delete n.claude,await C(e,n)}F();import{resolve as He,basename as br}from"node:path";import{rm as Tr}from"node:fs/promises";import{confirm as ts}from"@inquirer/prompts";import k from"picocolors";function wr(e){console.log(`${k.green("\u2713")} ${e}`)}function vr(e){console.log(`${k.red("\u2717")} ${e}`)}function yr(e){console.log(`${k.yellow("!")} ${e}`)}function _r(e){console.log(`${k.cyan("\u2192")} ${e}`)}function Sr(e){console.log(k.dim(e))}function xr(e){return k.cyan(e)}function kr(e){return k.bold(e)}function Cr(e){console.log(),console.log(k.bold(k.underline(e)))}function Ar(e,t=!1){let s=t?k.green("\u25CF"):k.dim("\u25CB");console.log(` ${s} ${e}`)}function Pr(){console.log(),console.log(k.bold(k.magenta("\u{1F3AF} Ready to use Vesper!"))),console.log(k.cyan(' In VS Code Chat, select "Vesper" from the agent dropdown')),console.log(k.cyan(" and start requesting!")),console.log()}function Er(e){let t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],s=0,r=null,n=e,i=()=>{let a=k.cyan(t[s]);process.stdout.write(`\r${a} ${n}`),s=(s+1)%t.length};return{start(){process.stdout.write(`
25
- `),r=setInterval(i,80),i()},update(a){n=a},stop(){r&&(clearInterval(r),r=null,process.stdout.write("\r"+" ".repeat(n.length+4)+"\r"))},succeed(a){this.stop(),console.log(`${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
- `))u.trim()&&o.info(u.replace("[vesper-indexing] ",""))}),i.stdout.on("data",d=>{a+=d.toString()}),i.on("close",d=>{try{let l=JSON.parse(a.trim());l.success?r?r.succeed(`Workspace indexed: ${l.filesIndexed} files`):o.success(`Workspace indexed: ${l.filesIndexed} files`):r?r.fail(`Indexing failed: ${l.error}`):o.error(`Indexing failed: ${l.error}`),n(l)}catch{d===0?(r?r.succeed(`Workspace indexed: ${c} files`):o.success(`Workspace indexed: ${c} files`),n({success:!0,filesIndexed:c})):(r?r.fail("Indexing failed"):o.error("Indexing failed"),n({success:!1,error:"Unknown error"}))}}),i.on("error",d=>{r?r.fail(`Indexing failed: ${d.message}`):o.error(`Indexing failed: ${d.message}`),n({success:!1,error:d.message})})})}function an({copilot:e,claude:t,indexingResult:s}){console.log(),o.success("Vesper is ready."),s?.success?o.info(`Code index built: ${s.filesIndexed} files.`):s?.error&&o.info("Code index will be built on first MCP server start."),console.log(),o.header("Next Steps"),console.log(),e&&(o.info("GitHub Copilot \u2014 reload VS Code to activate Vesper:"),o.info(' Cmd+Shift+P (macOS) / Ctrl+Shift+P (Windows/Linux) \u2192 "Developer: Reload Window"')),t&&(o.info("Claude Code \u2014 open a session in this workspace; the orchestrator"),o.info(" activates automatically via CLAUDE.md.")),console.log(),e&&o.vesperTip()}async function is(e={}){try{let t=e.yes||e.forceDefault,s=await rn(e.path||process.cwd(),t);await g(s)||(o.error(`Directory not found: ${o.formatPath(s)}`),process.exit(1));let r=await _(s);r.type===E.WORKSPACE_FILE&&await tn(s,t),await sn(s);let{selected:n,installed:i}=await Xr(e,s),a=i.filter(p=>!n.includes(p));if(n.length===0&&a.length===0){o.info("No platforms selected. Nothing to do.");return}if(!t&&i.length===0&&n.length>0&&!await ae({message:`Set up ${n.map(os).join(" + ")} in ${s}?`,default:!0})){o.info("Initialization cancelled.");return}a.length>0&&await nn(s,a,t);let c=n.includes("copilot"),d=n.includes("claude"),l=null;if(c&&(l=await on(t)),c&&await en(s,r,l),d&&await Zr(s,e),c||d){await we(s);let p=await ve(s);p.length>0&&(o.warn(`Local-only file(s) are git-tracked despite .gitignore: ${p.join(", ")}`),o.warn(`Untrack them yourself (Vesper won't touch your git index): git rm --cached ${p.join(" ")}`)),(await _e(s))["pre-commit"]?.hooksDir&&(o.success("Local-only Vesper files gitignored (.vesperrc, .mcp.json, .vesper/index.db)"),o.info("Commit-hygiene git hook installed (pre-commit): keeps team roster/context/history/memory in sync with every commit"),await Se(s),await xe(s),o.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 Xe(s,!0)),an({copilot:c,claude:d,indexingResult:u})}catch(t){if(t.name==="ExitPromptError"){console.log(),o.info("Initialization cancelled.");return}o.error(`Initialization failed: ${t.message}`),process.exit(1)}}F();import{resolve as cs,basename as cn}from"node:path";import{checkbox as ls,select as ln}from"@inquirer/prompts";var as={agents:"agents",prompts:"commands",skills:"skills"};async function dn(e,t){let s=await D(e);if(s.length===1)return s[0];s.length===0&&(o.warn('Vesper is not initialized in this workspace. Run "vespercli init" first.'),process.exit(0)),o.error(`Both Copilot and Claude targets are installed here \u2014 specify which to ${t}: --target copilot|claude`),process.exit(1)}async function un(e={}){let t=cs(e.path||process.cwd());(!e.type||!e.name)&&(o.error("Usage: vesper add <type> <name> --target claude"),o.info("Types: agents, prompts (installed as slash commands), skills"),process.exit(1));let s=as[e.type];s||(o.error(`Unknown asset type for --target claude: ${e.type}`),o.info(`Available types: ${Object.keys(as).join(", ")}`),process.exit(1));let n=(await m(t)).claude?.namePrefix??"";try{let i=await Kt(s,e.name,{namePrefix:n});o.success(`Added ${e.type}/${e.name} to the Claude plugin catalog as "${i.installedAs}"`)}catch(i){o.error(i.message),process.exit(1)}}var me=["agents","prompts","instructions"];async function Qe(e,t){let s=await oe(e);return(await ne(t)).filter(n=>{let i=X(t,n);return!s.includes(i.path)})}async function pn(e){let t=[];for(let a of me){let c=await Qe(e,a);c.length>0&&t.push({name:`${a.charAt(0).toUpperCase()+a.slice(1)} (${c.length} available)`,value:a})}if(t.length===0)return o.info("All extended assets are already added."),[];let s=await ln({message:"Select asset type:",choices:t}),n=(await Qe(e,s)).map(a=>({name:a,value:a,checked:!1}));return(await ls({message:`Select ${s} to add:`,choices:n})).map(a=>({type:s,name:a}))}async function ds(e={}){try{let t=cs(e.path||process.cwd());if(await g(t)||(o.error(`Directory not found: ${o.formatPath(t)}`),process.exit(1)),(e.target||await dn(t,"add"))==="claude")return await un({...e,path:t});if(!await ye(t)){o.warn('Vesper is not initialized. Run "vespercli init" first.');return}let r=[];if(e.type&&e.name){if(e.type==="skills"){o.info("Skills are automatically added during init.");return}me.includes(e.type)||(o.error(`Unknown asset type: ${e.type}`),o.info(`Available types: ${me.join(", ")}`),process.exit(1));let l=await ne(e.type);l.includes(e.name)||(o.error(`Asset not found: ${e.name}`),o.info(`Available ${e.type}: ${l.join(", ")||"none"}`),process.exit(1)),r=[{type:e.type,name:e.name}]}else if(e.type){if(e.type==="skills"){o.info("Skills are automatically added during init.");return}me.includes(e.type)||(o.error(`Unknown asset type: ${e.type}`),o.info(`Available types: ${me.join(", ")}`),process.exit(1));let l=await Qe(t,e.type);if(l.length===0){o.info(`All ${e.type} are already added.`);return}let f=l.map(p=>({name:p,value:p,checked:!1})),u=await ls({message:`Select ${e.type} to add:`,choices:f});if(u.length===0){o.info("Nothing selected.");return}r=u.map(p=>({type:e.type,name:p}))}else if(r=await pn(t),r.length===0){o.info("Nothing selected.");return}let n=r.map(({type:l,name:f})=>X(l,f)),{added:i,skipped:a,workspaceType:c}=await Pt(t,n),d=r.filter(l=>l.type==="agents"&&i.includes(X(l.type,l.name).path));for(let{name:l}of d)Ne[l]&&(await Ft(t,l),o.info(` Added MCP tools auto-approval for agent: ${l}`));if(i.length>0){let l=await _(t);console.log(),o.success(`Added ${i.length} asset(s):`);for(let{type:f,name:u}of r.filter(p=>i.includes(X(p.type,p.name).path)))o.info(` ${f}/${u}`);c===E.WORKSPACE_FILE&&o.info(`
27
- Updated: ${cn(l.settingsPath)}`),o.info(`
28
- Reload VS Code to apply changes`)}else a.length>0&&o.info("All selected assets are already added.")}catch(t){if(t.name==="ExitPromptError"){console.log(),o.info("Cancelled.");return}o.error(`Add failed: ${t.message}`),process.exit(1)}}F();import{resolve as ps,join as fn}from"node:path";import{readdir as gn}from"node:fs/promises";import B from"picocolors";async function us(e={}){let t=ps(e.path||process.cwd()),s=await m(t);if(console.log(),console.log(B.bold("Claude Code target")),!s.claude){console.log(),o.warn('Not initialized for Claude Code. Run "vesper init --target claude" first.'),console.log();return}let r=s.claude.pluginPath||W();console.log(B.dim(`Plugin catalog: ${r}`));let n=await Ht();for(let[i,a]of Object.entries(n))console.log(),console.log(B.bold(i.charAt(0).toUpperCase()+i.slice(1))),a.length===0?console.log(B.dim(" (none installed)")):a.forEach(c=>console.log(` ${c}`));console.log(),console.log(B.bold("Project files")),console.log(" CLAUDE.md, .claude/vesper/{orchestrator,orchestration,context}.md, .mcp.json, .claude/settings.json"),console.log()}async function mn(e,t,s=!1){try{let r=await gn(e,{withFileTypes:!0});return s||t.dir==="skills"?r.filter(i=>i.isDirectory()&&!i.name.startsWith(".")).map(i=>i.name):r.filter(i=>i.isFile()&&i.name.endsWith(t.extension)).map(i=>i.name.replace(t.extension,""))}catch{return[]}}async function fs(e={}){try{let t=ps(e.path||process.cwd());await g(t)||(o.error(`Directory not found: ${o.formatPath(t)}`),process.exit(1));let s=await D(t);if(e.target==="claude")return await us({...e,path:t});if(!e.target){if(s.length===0){console.log(),o.warn('Vesper is not initialized. Run "vespercli init" first.'),console.log();return}if(s.length===1&&s[0]==="claude")return await us({...e,path:t});s.includes("claude")&&o.info("Claude Code target is also installed here \u2014 run `vespercli list --target claude` to see it.")}let r=await oe(t);e.type&&!I[e.type]&&(o.error(`Unknown asset type: ${e.type}`),o.info(`Valid types: ${Object.keys(I).join(", ")}`),process.exit(1));let n=e.type?[e.type]:Object.keys(I);console.log(),console.log(B.bold("Assets"));for(let i of n){let a=I[i],c=i.charAt(0).toUpperCase()+i.slice(1);if(i==="skills"){let p=Mt("skills");if(r.includes(p.path)){let h=await ne("skills");console.log(),console.log(B.bold(`${c}`)),console.log(` ${h.length} skills enabled ${B.dim("(all)")}`)}continue}let d=fn(rt,a.dir),l=await mn(d,a,!1),u=(await ne(i)).filter(p=>{let h=X(i,p);return r.includes(h.path)});(l.length>0||u.length>0)&&(console.log(),console.log(B.bold(`${c}`)),l.forEach(p=>{console.log(` ${p} ${B.dim("(core)")}`)}),u.forEach(p=>{console.log(` ${p}`)}))}console.log()}catch(t){o.error(`List failed: ${t.message}`),process.exit(1)}}import{readFileSync as hn,existsSync as wn}from"node:fs";import{join as vn}from"node:path";var gs="catalog.md",yn="mthanhtran",_n="vesper",Sn="main";function xn(){return`https://raw.githubusercontent.com/${yn}/${_n}/${Sn}/assets/${gs}`}function kn(){let e=vn(re,"assets",gs);return wn(e)?hn(e,"utf-8"):null}async function Cn(){try{let e=xn(),t=await fetch(e);return t.ok?t.text():null}catch{return null}}async function An(){let e=await Cn();if(e)return e;let t=kn();if(t)return t;throw new Error("Catalog not available from remote or local")}async function ms(){try{let e=await An();console.log(e)}catch(e){console.error(`Error loading catalog: ${e.message}`),process.exit(1)}}F();import{resolve as Pn,join as Ss}from"node:path";import{stat as En,readFile as xs}from"node:fs/promises";import"@inquirer/prompts";import j from"picocolors";async function Le(e){let t=await m(e);if(console.log(),o.header("vesper-indexing MCP Server (Claude Code target)"),console.log(),!t.claude){o.info("Claude Code target is not initialized. Run `vesper init --target claude` first.");return}let s=ee(e),r=!1;if(await g(s))try{r=!!JSON.parse(await xs(s,"utf-8")).mcpServers?.["vesper-indexing"]}catch{r=!1}o.info(`Configured: ${r?"\u2713 yes":"\u2717 no"} (${s})`),o.info(`Server built: ${await Cs()?"\u2713 yes":"\u2717 no"}`);let n=Ze(e);o.info(`Index exists: ${await g(n)?"\u2713 yes":"\u2717 no"} (shared with the Copilot target if both are installed)`);try{let{drifted:i}=await Xt(e);i.length&&(console.log(),o.warn(`MCP config drift: ${i.join(", ")} present in the live MCP config but not tracked in .vesperrc mcp.servers.`),o.warn("Run `/reinit` (or re-run workspace-learner) to resync tracking and the generated docs."))}catch{}}async function ce(e,t=!0){await te(e,t),t&&await Oe(e),o.success(`Claude Code target: vesper-indexing ${t?"enabled":"disabled"} in .mcp.json`)}function Ze(e){return Ss(e,".vesper","index.db")}function bn(e){return Ss(e,".vesper","indexing-status.json")}async function ks(e){let t=bn(e);try{let s=await xs(t,"utf-8");return JSON.parse(s)}catch{return null}}async function Cs(){let e=q();return await g(e)}async function Tn(e){try{let t=await En(e),s=t.size,r=`${s} bytes`;return s>1024*1024?r=`${(s/(1024*1024)).toFixed(2)} MB`:s>1024&&(r=`${(s/1024).toFixed(1)} KB`),{dbSize:r,lastModified:t.mtime.toISOString()}}catch{return null}}async function hs(e,t=!1){let s=await Ae(e),r=await Cs(),n=Ze(e),i=await g(n),a=await ks(e);if(console.log(),o.header("vesper-indexing MCP Server"),console.log(),o.info(`Configured: ${s?"\u2713 yes":"\u2717 no"}`),o.info(`Server built: ${r?"\u2713 yes":"\u2717 no"}`),o.info(`Index exists: ${i?"\u2713 yes":"\u2717 no"}`),a)if(console.log(),a.status==="indexing")if(t){await $n(e,a);return}else{let c=a.startedAt?Math.round((Date.now()-new Date(a.startedAt).getTime())/1e3):0;o.info(j.yellow("\u27F3 Indexing in progress...")),o.info(` Files processed: ${j.cyan(a.filesProcessed)}`),o.info(` Elapsed: ${j.dim(`${c}s`)}`),console.log(),o.info("Use --watch to follow indexing progress until completion")}else a.status==="error"&&(o.error(`Indexing error: ${a.error}`),o.info(` Files processed before error: ${a.filesProcessed}`));if(!s){console.log(),o.info("Run `vespercli init` to configure the MCP server");return}if(!r){console.log(),o.warn("MCP server not built. Run: cd src/mcp/vesper-indexing && npm install && npm run build");return}if(i&&!a){let c=await Tn(n);c&&(console.log(),o.info(`Index size: ${c.dbSize}`),o.info(`Last modified: ${c.lastModified}`)),o.vesperTip()}else!i&&!a&&(console.log(),o.info("Index not yet created. It will be built when VS Code loads the MCP server."),console.log())}async function $n(e,t){let s=o.createSpinner(`Indexing... ${t.filesProcessed} files processed`);s.start();let r=500,n=30*60*1e3,i=Date.now();return new Promise(a=>{let c=async()=>{let d=await ks(e);if(!d||d.status!=="indexing"){d?.status==="error"?s.fail(`Indexing failed: ${d.error}`):(s.succeed(`Indexing complete! ${d?.filesProcessed||"All"} files indexed`),o.info(`
29
- \u2192 Reload VS Code to update MCP tools with the new index`),o.vesperTip()),a();return}let l=d.startedAt?Math.round((Date.now()-new Date(d.startedAt).getTime())/1e3):0;if(s.update(`Indexing... ${d.filesProcessed} files processed (${l}s)`),Date.now()-i>n){s.fail("Indexing watch timed out (30 minutes)"),a();return}setTimeout(c,r)};setTimeout(c,r)})}async function ws(e,t=!1){let s=Ze(e);if(!await g(s))o.info("No index exists. It will be built when VS Code loads the MCP server.");else if(t){let{unlink:n}=await import("node:fs/promises");await n(s),o.success("Index cleared. Reload VS Code to rebuild.")}else o.info("Incremental reindex happens automatically when files change."),o.info("Use --full to clear and rebuild the entire index.")}async function On(e){let t=await Q(e,!0);t.configured&&(o.success("MCP server enabled"),o.info(`Config: ${t.mcpPath}`),o.info("Reload VS Code to start the server"))}async function In(e){await Q(e,!1),o.success("MCP server disabled"),o.info("Reload VS Code to apply changes")}async function As(e){let t=await _(e),s=await m(e,t);if(!Array.isArray(s.paths))return[];let r=[];for(let n of s.paths){let i=n.match(/agents\/([^/]+)\/?$/);i&&MCP_TOOLS_BY_AGENT[i[1]]&&r.push(i[1])}return r}async function Mn(e){let t=await _(e),s=await m(e,t),r=await x(e,t),n=await As(e),i=r[w]||{},a=new Set(R),c=[],d=[],l=!1;r[w]||(r[w]={});for(let u of R)i[u]||(r[w][u]=!0,c.push(u),l=!0);for(let u of n){let p=MCP_TOOLS_BY_AGENT[u]||[];for(let h of p)i[h]||(r[w][h]=!0,c.push(h),l=!0)}let f=new Set;for(let u of n)for(let p of MCP_TOOLS_BY_AGENT[u]||[])f.add(p);for(let u of Object.keys(i)){if(a.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 r[w][u],d.push(u),l=!0)}if(s.mcp=s.mcp||{},s.mcp.syncedAt=new Date().toISOString(),s.mcp.approvedAgents=n,s.mcp.toolCount=Object.keys(r[w]).length,l&&await P(e,r),await C(e,s),console.log(),o.header("MCP Tools Sync"),console.log(),c.length===0&&d.length===0)o.success("Already in sync");else{if(c.length>0){o.success(`Added ${c.length} tool(s)`);let u=c.filter(p=>a.has(p));u.length>0&&o.info(` Core: ${u.length} tools`);for(let p of n){let h=c.filter(O=>(MCP_TOOLS_BY_AGENT[p]||[]).includes(O));h.length>0&&o.info(` ${p}: ${h.length} tools`)}}d.length>0&&o.info(`Removed ${d.length} orphaned tool(s)`)}o.info(`
24
+ ${n}`;return await $(t,i,"utf-8"),{created:!1,updated:!0}}function pr(e){let t=new RegExp(`${qe}[\\s\\S]*?${Ke}\\n*`);return e.replace(t,"")}async function $e(e){let t=Ee(e);await Z(t,{recursive:!0});let s={orchestrator:"refreshed",orchestration:"skipped",context:"skipped"},r=w(ie,"vesper-orchestrator.md"),n=w(t,"orchestrator.md");await $(n,await U(r,"utf-8"),"utf-8");let i=w(t,"orchestration.md");await g(i)||(await $(i,await U(w(ie,"orchestration.md.tpl"),"utf-8"),"utf-8"),s.orchestration="created");let a=w(t,"context.md");await g(a)||(await $(a,await U(w(ie,"context.md.tpl"),"utf-8"),"utf-8"),s.context="created");let c=await ur(e);return s.claudeMd=c.created?"created":c.updated?"updated":"unchanged",s}async function ge(e){let t=ee(e);try{let s=await U(t,"utf-8");return JSON.parse(s)}catch(s){return s.code==="ENOENT"?{mcpServers:{}}:{mcpServers:{}}}}async function He(e,t){let s=ee(e);await Z(Be(s),{recursive:!0}),await $(s,JSON.stringify(t,null," "),"utf-8")}function fr(e){return{"vesper-indexing":{command:"node",args:[q()],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 te(e,t=!0){let s=await ge(e);s.mcpServers||(s.mcpServers={});let r=fr(e),n=Object.keys(r);if(t)for(let[i,a]of Object.entries(r))s.mcpServers[i]=a;else for(let i of n)delete s.mcpServers[i];return await He(e,s),{configured:t,mcpPath:ee(e),servers:t?n:[]}}function We(e,t){return String(e).replace(/\$\{VESPER_INDEXING_PATH\}/g,q()).replace(/\$\{workspaceFolder\}/g,t).replace(/\$\{env:([^}]+)\}/g,"$${$1}")}function gr(e,{workspaceRoot:t}){let{type:s,...r}=structuredClone(e);if(typeof r.command=="string"&&(r.command=We(r.command,t)),Array.isArray(r.args)&&(r.args=r.args.map(n=>We(n,t))),r.env&&typeof r.env=="object")for(let[n,i]of Object.entries(r.env))r.env[n]=We(i,t);return r}async function zt(e,t){if(Y.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=N[t];if(!s)return{added:!1,serverName:t,error:`Unknown MCP server: ${t}`};let r=await ge(e);if(r.mcpServers||(r.mcpServers={}),r.mcpServers[t])return{added:!1,serverName:t,error:"Already configured"};r.mcpServers[t]=gr(s.config,{workspaceRoot:e}),await He(e,r);let n=await m(e);return n.mcp=n.mcp||{},n.mcp.servers=n.mcp.servers||[],n.mcp.servers.includes(t)||n.mcp.servers.push(t),n.mcp.updatedAt=new Date().toISOString(),await C(e,n),{added:!0,serverName:t}}async function Yt(e,t){if(Y.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 ge(e),r=!1;s.mcpServers&&s.mcpServers[t]&&(delete s.mcpServers[t],await He(e,s),r=!0);let n=await m(e);return n.mcp?.servers&&(n.mcp.servers=n.mcp.servers.filter(i=>i!==t),n.mcp.updatedAt=new Date().toISOString(),await C(e,n)),{removed:r,serverName:t}}async function Xt(e){let t=await ge(e),s=Object.keys(t.mcpServers||{}),r=s.filter(n=>!N[n]);return{configured:s,custom:r}}async function Qt(e){let t=new Set,s=[];try{s=await D(e)}catch{s=[]}if(s.includes("claude"))try{let a=await ge(e);for(let c of Object.keys(a.mcpServers||{}))t.add(c)}catch{}if(s.includes("copilot"))try{let a=await G(e);for(let c of Object.keys(a.servers||{}))t.add(c)}catch{}let r=[];try{let a=await m(e);r=Array.isArray(a.mcp?.servers)?a.mcp.servers:[]}catch{r=[]}let n=new Set(r);return{drifted:[...t].filter(a=>!Y.includes(a)&&!n.has(a))}}async function Oe(e){let t=be(e),s={};try{s=JSON.parse(await U(t,"utf-8"))}catch{s={}}s.permissions||(s.permissions={}),Array.isArray(s.permissions.allow)||(s.permissions.allow=[]);let r=["mcp__vesper-indexing__vesper_search","mcp__vesper-indexing__vesper_symbols","mcp__vesper-indexing__vesper_status","mcp__vesper-indexing__vesper_reindex","mcp__sequential-thinking__sequentialthinking","mcp__memory__create_entities","mcp__memory__create_relations","mcp__memory__add_observations","mcp__memory__delete_entities","mcp__memory__delete_observations","mcp__memory__delete_relations","mcp__memory__read_graph","mcp__memory__search_nodes","mcp__memory__open_nodes"],n=0;for(let i of r)s.permissions.allow.includes(i)||(s.permissions.allow.push(i),n+=1);return vr(s),await Z(Be(t),{recursive:!0}),await $(t,JSON.stringify(s,null," "),"utf-8"),{configured:n,settingsPath:t}}var Zt=".claude/vesper/",mr=`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){}"`,es="worktree bootstrap",hr="command -v vespercli >/dev/null 2>&1 && vespercli worktree bootstrap --quiet || true";function vr(e){e.hooks||(e.hooks={}),Array.isArray(e.hooks.SessionStart)||(e.hooks.SessionStart=[]);let t=s=>e.hooks.SessionStart.some(r=>(r?.hooks||[]).some(n=>typeof n?.command=="string"&&n.command.includes(s)));t(Zt)||e.hooks.SessionStart.push({matcher:"clear",hooks:[{type:"command",command:mr}]}),t(es)||e.hooks.SessionStart.push({hooks:[{type:"command",command:hr}]})}function wr(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(Zt)||s.command.includes(es)))),e.hooks.SessionStart.length===0&&delete e.hooks.SessionStart,e.hooks&&Object.keys(e.hooks).length===0&&delete e.hooks)}async function ts(e,t){let s=await m(e);return s.claude={...s.claude,...t,updatedAt:new Date().toISOString()},await C(e,s),s.claude}async function Ie(e){let t=Ee(e);await Gt(t,{recursive:!0,force:!0});let s=qt(e);if(await g(s)){let i=await U(s,"utf-8"),a=pr(i);a.trim()?await $(s,a,"utf-8"):await Gt(s,{force:!0})}await te(e,!1);let r=be(e);if(await g(r))try{let i=JSON.parse(await U(r,"utf-8"));wr(i),await $(r,JSON.stringify(i,null," "),"utf-8")}catch{}let n=await m(e);delete n.claude,await C(e,n)}V();import{resolve as Je,basename as $r}from"node:path";import{rm as Or}from"node:fs/promises";import{confirm as ss}from"@inquirer/prompts";import x from"picocolors";function yr(e){console.log(`${x.green("\u2713")} ${e}`)}function _r(e){console.log(`${x.red("\u2717")} ${e}`)}function Sr(e){console.log(`${x.yellow("!")} ${e}`)}function kr(e){console.log(`${x.cyan("\u2192")} ${e}`)}function xr(e){console.log(x.dim(e))}function Cr(e){return x.cyan(e)}function Ar(e){return x.bold(e)}function Pr(e){console.log(),console.log(x.bold(x.underline(e)))}function Er(e,t=!1){let s=t?x.green("\u25CF"):x.dim("\u25CB");console.log(` ${s} ${e}`)}function br(){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 Tr(e){let t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],s=0,r=null,n=e,i=()=>{let a=x.cyan(t[s]);process.stdout.write(`\r${a} ${n}`),s=(s+1)%t.length};return{start(){process.stdout.write(`
25
+ `),r=setInterval(i,80),i()},update(a){n=a},stop(){r&&(clearInterval(r),r=null,process.stdout.write("\r"+" ".repeat(n.length+4)+"\r"))},succeed(a){this.stop(),console.log(`${x.green("\u2713")} ${a||n}`)},fail(a){this.stop(),console.log(`${x.red("\u2717")} ${a||n}`)}}}var o={success:yr,error:_r,warn:Sr,info:kr,dim:xr,formatPath:Cr,formatName:Ar,header:Pr,listItem:Er,vesperTip:br,createSpinner:Tr};async function Ir(e={}){let t=Je(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 ss({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 Mr(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 ze(e){let t=await m(e);await bt(e);try{let r=await k(e);if(r[v]){let n=new Set(R),i=!1;for(let a of Object.keys(r[v]))n.has(a)||(delete r[v][a],i=!0);i&&await P(e,r)}}catch{}let s=Je(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 Or(s,{force:!0})}catch{}}async function rs(e={}){try{let t=Je(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 Ir({...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=Mr(r);if(!e.yes&&!await ss({message:`Remove all Vesper assets (${n.join(", ")})?`,default:!1})){o.info("Reset cancelled.");return}let i=await m(t),a=await _(t);await ze(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: ${$r(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)}}V();import{execFile as Dr}from"node:child_process";import{promisify as Lr}from"node:util";import{randomUUID as jr}from"node:crypto";import{mkdir as Me,readdir as Vr,rename as Ye,rm as H,stat as Fr}from"node:fs/promises";import{join as se}from"node:path";var Rr=Lr(Dr),ns=[{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"}],Nr=new Set(ns.map(e=>e.name)),Gr=5*60*1e3;function Xe(e){process.env.VESPER_DEBUG&&o.dim(`[skill-sync] ${e}`)}async function Ur(e,t){if(!Nr.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}-${jr().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 Rr("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 Ye(r,n),await Ye(i,r),await H(n,{recursive:!0,force:!0}),{synced:!0,skill:t}}catch(a){return Xe(`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 Ye(n,r).catch(()=>{}),{synced:!1,skill:t}}}async function Wr(e){try{return await Me(e),!0}catch(t){if(t.code!=="EEXIST")return Xe(`could not acquire lock: ${t.message}`),!1;try{let s=await Fr(e);if(Date.now()-s.mtimeMs>Gr)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 Wr(t))return Xe("skipped: another process holds the sync lock"),[];try{await Br(e);let r=[];for(let{url:n,name:i}of ns)r.push(await Ur(n,i));return r}finally{await H(t,{recursive:!0,force:!0}).catch(()=>{})}}async function Br(e){let t;try{t=await Vr(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 os=["copilot","claude"];function is(e){return e==="claude"?"Claude Code":"GitHub Copilot"}async function Qr(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 Zr(e,t){let s=await Qr(t);if(e.target){let n=String(e.target).toLowerCase(),i=n==="all"?[...os]:n.split(",").map(a=>a.trim()).filter(Boolean);for(let a of i)os.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 Xr({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 en(e){return e?"":await Yr({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 tn(e,t={}){let s=t.yes||t.forceDefault,r=await en(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 ts(e,{pluginPath:W(),namePrefix:r,mcpConfigPath:ee(e),settingsPath:be(e),installedAt:new Date().toISOString()})}async function sn(e,t,s){console.log(),o.header("Configuring GitHub Copilot"),console.log();let r=await jt(e);await $t(e,{maxRequests:s.maxRequests,omitBaseAgentInstructions:s.omitBaseAgentInstructions});let n=await Tt(e,s.terminalEnableAutoApprove),i=!1;return s.enableMcpServer&&(i=(await Q(e,!0)).configured,await Vt(e)),await Ct(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: ${Kr(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 rn(e,t){let s=await At(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 Pt(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 nn(e){let{migrated:t,changed:s}=await Lt(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 on(e,t){let s=e;return t||(s=await Jr({message:"Workspace root directory:",default:s})),qr(s)}async function an(e,t,s){let r=[];for(let n of t){let i=is(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 ze(e),r.push(n),o.success(`Removed ${i} from this project.`)}return r}async function cn(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 zr({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 Qe(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=Hr("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
+ `))u.trim()&&o.info(u.replace("[vesper-indexing] ",""))}),i.stdout.on("data",d=>{a+=d.toString()}),i.on("close",d=>{try{let l=JSON.parse(a.trim());l.success?r?r.succeed(`Workspace indexed: ${l.filesIndexed} files`):o.success(`Workspace indexed: ${l.filesIndexed} files`):r?r.fail(`Indexing failed: ${l.error}`):o.error(`Indexing failed: ${l.error}`),n(l)}catch{d===0?(r?r.succeed(`Workspace indexed: ${c} files`):o.success(`Workspace indexed: ${c} files`),n({success:!0,filesIndexed:c})):(r?r.fail("Indexing failed"):o.error("Indexing failed"),n({success:!1,error:"Unknown error"}))}}),i.on("error",d=>{r?r.fail(`Indexing failed: ${d.message}`):o.error(`Indexing failed: ${d.message}`),n({success:!1,error:d.message})})})}function ln({copilot:e,claude:t,indexingResult:s}){console.log(),o.success("Vesper is ready."),s?.success?o.info(`Code index built: ${s.filesIndexed} files.`):s?.error&&o.info("Code index will be built on first MCP server start."),console.log(),o.header("Next Steps"),console.log(),e&&(o.info("GitHub Copilot \u2014 reload VS Code to activate Vesper:"),o.info(' Cmd+Shift+P (macOS) / Ctrl+Shift+P (Windows/Linux) \u2192 "Developer: Reload Window"')),t&&(o.info("Claude Code \u2014 open a session in this workspace; the orchestrator"),o.info(" activates automatically via CLAUDE.md.")),console.log(),e&&o.vesperTip()}async function as(e={}){try{let t=e.yes||e.forceDefault,s=await on(e.path||process.cwd(),t);await g(s)||(o.error(`Directory not found: ${o.formatPath(s)}`),process.exit(1));let r=await _(s);r.type===E.WORKSPACE_FILE&&await rn(s,t),await nn(s);let{selected:n,installed:i}=await Zr(e,s),a=i.filter(p=>!n.includes(p));if(n.length===0&&a.length===0){o.info("No platforms selected. Nothing to do.");return}if(!t&&i.length===0&&n.length>0&&!await ae({message:`Set up ${n.map(is).join(" + ")} in ${s}?`,default:!0})){o.info("Initialization cancelled.");return}a.length>0&&await an(s,a,t);let c=n.includes("copilot"),d=n.includes("claude"),l=null;if(c&&(l=await cn(t)),c&&await sn(s,r,l),d&&await tn(s,e),c||d){await ve(s);let p=await we(s);p.length>0&&(o.warn(`Local-only file(s) are git-tracked despite .gitignore: ${p.join(", ")}`),o.warn(`Untrack them yourself (Vesper won't touch your git index): git rm --cached ${p.join(" ")}`)),(await _e(s))["pre-commit"]?.hooksDir&&(o.success("Local-only Vesper files gitignored (.vesperrc, .mcp.json, .vesper/index.db)"),o.info("Commit-hygiene git hook installed (pre-commit): keeps team roster/context/history/memory in sync with every commit"),await Se(s),await ke(s),o.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 Qe(s,!0)),ln({copilot:c,claude:d,indexingResult:u})}catch(t){if(t.name==="ExitPromptError"){console.log(),o.info("Initialization cancelled.");return}o.error(`Initialization failed: ${t.message}`),process.exit(1)}}V();import{resolve as ls,basename as dn}from"node:path";import{checkbox as ds,select as un}from"@inquirer/prompts";var cs={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&&(o.warn('Vesper is not initialized in this workspace. Run "vespercli init" first.'),process.exit(0)),o.error(`Both Copilot and Claude targets are installed here \u2014 specify which to ${t}: --target copilot|claude`),process.exit(1)}async function fn(e={}){let t=ls(e.path||process.cwd());(!e.type||!e.name)&&(o.error("Usage: vesper add <type> <name> --target claude"),o.info("Types: agents, prompts (installed as slash commands), skills"),process.exit(1));let s=cs[e.type];s||(o.error(`Unknown asset type for --target claude: ${e.type}`),o.info(`Available types: ${Object.keys(cs).join(", ")}`),process.exit(1));let n=(await m(t)).claude?.namePrefix??"";try{let i=await Ht(s,e.name,{namePrefix:n});o.success(`Added ${e.type}/${e.name} to the Claude plugin catalog as "${i.installedAs}"`)}catch(i){o.error(i.message),process.exit(1)}}var me=["agents","prompts","instructions"];async function Ze(e,t){let s=await oe(e);return(await ne(t)).filter(n=>{let i=X(t,n);return!s.includes(i.path)})}async function gn(e){let t=[];for(let a of me){let c=await Ze(e,a);c.length>0&&t.push({name:`${a.charAt(0).toUpperCase()+a.slice(1)} (${c.length} available)`,value:a})}if(t.length===0)return o.info("All extended assets are already added."),[];let s=await un({message:"Select asset type:",choices:t}),n=(await Ze(e,s)).map(a=>({name:a,value:a,checked:!1}));return(await ds({message:`Select ${s} to add:`,choices:n})).map(a=>({type:s,name:a}))}async function us(e={}){try{let t=ls(e.path||process.cwd());if(await g(t)||(o.error(`Directory not found: ${o.formatPath(t)}`),process.exit(1)),(e.target||await pn(t,"add"))==="claude")return await fn({...e,path:t});if(!await ye(t)){o.warn('Vesper is not initialized. Run "vespercli init" first.');return}let r=[];if(e.type&&e.name){if(e.type==="skills"){o.info("Skills are automatically added during init.");return}me.includes(e.type)||(o.error(`Unknown asset type: ${e.type}`),o.info(`Available types: ${me.join(", ")}`),process.exit(1));let l=await ne(e.type);l.includes(e.name)||(o.error(`Asset not found: ${e.name}`),o.info(`Available ${e.type}: ${l.join(", ")||"none"}`),process.exit(1)),r=[{type:e.type,name:e.name}]}else if(e.type){if(e.type==="skills"){o.info("Skills are automatically added during init.");return}me.includes(e.type)||(o.error(`Unknown asset type: ${e.type}`),o.info(`Available types: ${me.join(", ")}`),process.exit(1));let l=await Ze(t,e.type);if(l.length===0){o.info(`All ${e.type} are already added.`);return}let f=l.map(p=>({name:p,value:p,checked:!1})),u=await ds({message:`Select ${e.type} to add:`,choices:f});if(u.length===0){o.info("Nothing selected.");return}r=u.map(p=>({type:e.type,name:p}))}else if(r=await gn(t),r.length===0){o.info("Nothing selected.");return}let n=r.map(({type:l,name:f})=>X(l,f)),{added:i,skipped:a,workspaceType:c}=await Et(t,n),d=r.filter(l=>l.type==="agents"&&i.includes(X(l.type,l.name).path));for(let{name:l}of d)Ge[l]&&(await Ft(t,l),o.info(` Added MCP tools auto-approval for agent: ${l}`));if(i.length>0){let l=await _(t);console.log(),o.success(`Added ${i.length} asset(s):`);for(let{type:f,name:u}of r.filter(p=>i.includes(X(p.type,p.name).path)))o.info(` ${f}/${u}`);c===E.WORKSPACE_FILE&&o.info(`
27
+ Updated: ${dn(l.settingsPath)}`),o.info(`
28
+ Reload VS Code to apply changes`)}else a.length>0&&o.info("All selected assets are already added.")}catch(t){if(t.name==="ExitPromptError"){console.log(),o.info("Cancelled.");return}o.error(`Add failed: ${t.message}`),process.exit(1)}}V();import{resolve as fs,join as mn}from"node:path";import{readdir as hn}from"node:fs/promises";import B from"picocolors";async function ps(e={}){let t=fs(e.path||process.cwd()),s=await m(t);if(console.log(),console.log(B.bold("Claude Code target")),!s.claude){console.log(),o.warn('Not initialized for Claude Code. Run "vesper init --target claude" first.'),console.log();return}let r=s.claude.pluginPath||W();console.log(B.dim(`Plugin catalog: ${r}`));let n=await Jt();for(let[i,a]of Object.entries(n))console.log(),console.log(B.bold(i.charAt(0).toUpperCase()+i.slice(1))),a.length===0?console.log(B.dim(" (none installed)")):a.forEach(c=>console.log(` ${c}`));console.log(),console.log(B.bold("Project files")),console.log(" CLAUDE.md, .claude/vesper/{orchestrator,orchestration,context}.md, .mcp.json, .claude/settings.json"),console.log()}async function vn(e,t,s=!1){try{let r=await hn(e,{withFileTypes:!0});return s||t.dir==="skills"?r.filter(i=>i.isDirectory()&&!i.name.startsWith(".")).map(i=>i.name):r.filter(i=>i.isFile()&&i.name.endsWith(t.extension)).map(i=>i.name.replace(t.extension,""))}catch{return[]}}async function gs(e={}){try{let t=fs(e.path||process.cwd());await g(t)||(o.error(`Directory not found: ${o.formatPath(t)}`),process.exit(1));let s=await D(t);if(e.target==="claude")return await ps({...e,path:t});if(!e.target){if(s.length===0){console.log(),o.warn('Vesper is not initialized. Run "vespercli init" first.'),console.log();return}if(s.length===1&&s[0]==="claude")return await ps({...e,path:t});s.includes("claude")&&o.info("Claude Code target is also installed here \u2014 run `vespercli list --target claude` to see it.")}let r=await oe(t);e.type&&!I[e.type]&&(o.error(`Unknown asset type: ${e.type}`),o.info(`Valid types: ${Object.keys(I).join(", ")}`),process.exit(1));let n=e.type?[e.type]:Object.keys(I);console.log(),console.log(B.bold("Assets"));for(let i of n){let a=I[i],c=i.charAt(0).toUpperCase()+i.slice(1);if(i==="skills"){let p=Dt("skills");if(r.includes(p.path)){let h=await ne("skills");console.log(),console.log(B.bold(`${c}`)),console.log(` ${h.length} skills enabled ${B.dim("(all)")}`)}continue}let d=mn(nt,a.dir),l=await vn(d,a,!1),u=(await ne(i)).filter(p=>{let h=X(i,p);return r.includes(h.path)});(l.length>0||u.length>0)&&(console.log(),console.log(B.bold(`${c}`)),l.forEach(p=>{console.log(` ${p} ${B.dim("(core)")}`)}),u.forEach(p=>{console.log(` ${p}`)}))}console.log()}catch(t){o.error(`List failed: ${t.message}`),process.exit(1)}}import{readFileSync as wn,existsSync as yn}from"node:fs";import{join as _n}from"node:path";var ms="catalog.md",Sn="mthanhtran",kn="vesper",xn="main";function Cn(){return`https://raw.githubusercontent.com/${Sn}/${kn}/${xn}/assets/${ms}`}function An(){let e=_n(re,"assets",ms);return yn(e)?wn(e,"utf-8"):null}async function Pn(){try{let e=Cn(),t=await fetch(e);return t.ok?t.text():null}catch{return null}}async function En(){let e=await Pn();if(e)return e;let t=An();if(t)return t;throw new Error("Catalog not available from remote or local")}async function hs(){try{let e=await En();console.log(e)}catch(e){console.error(`Error loading catalog: ${e.message}`),process.exit(1)}}V();import{resolve as bn,join as je,dirname as vs}from"node:path";import{stat as Tn,readFile as xs}from"node:fs/promises";import"@inquirer/prompts";import j from"picocolors";async function Le(e){let t=await m(e);if(console.log(),o.header("vesper-indexing MCP Server (Claude Code target)"),console.log(),!t.claude){o.info("Claude Code target is not initialized. Run `vesper init --target claude` first.");return}let s=ee(e),r=!1;if(await g(s))try{r=!!JSON.parse(await xs(s,"utf-8")).mcpServers?.["vesper-indexing"]}catch{r=!1}o.info(`Configured: ${r?"\u2713 yes":"\u2717 no"} (${s})`),o.info(`Server built: ${Ps(await As())}`);let n=et(e);o.info(`Index exists: ${await g(n)?"\u2713 yes":"\u2717 no"} (shared with the Copilot target if both are installed)`);try{let{drifted:i}=await Qt(e);i.length&&(console.log(),o.warn(`MCP config drift: ${i.join(", ")} present in the live MCP config but not tracked in .vesperrc mcp.servers.`),o.warn("Run `/reinit` (or re-run workspace-learner) to resync tracking and the generated docs."))}catch{}}async function ce(e,t=!0){await te(e,t),t&&await Oe(e),o.success(`Claude Code target: vesper-indexing ${t?"enabled":"disabled"} in .mcp.json`)}function et(e){return je(e,".vesper","index.db")}function $n(e){return je(e,".vesper","indexing-status.json")}async function Cs(e){let t=$n(e);try{let s=await xs(t,"utf-8");return JSON.parse(s)}catch{return null}}async function As(){let e=q();if(!await g(e))return"missing";let t=vs(vs(e)),s=[je(t,"node_modules","@modelcontextprotocol","sdk","package.json"),je(t,"node_modules","zod","package.json")];for(let r of s)if(!await g(r))return"broken";return"ready"}function Ps(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 On(e){try{let t=await Tn(e),s=t.size,r=`${s} bytes`;return s>1024*1024?r=`${(s/(1024*1024)).toFixed(2)} MB`:s>1024&&(r=`${(s/1024).toFixed(1)} KB`),{dbSize:r,lastModified:t.mtime.toISOString()}}catch{return null}}async function ws(e,t=!1){let s=await Ae(e),r=await As(),n=et(e),i=await g(n),a=await Cs(e);if(console.log(),o.header("vesper-indexing MCP Server"),console.log(),o.info(`Configured: ${s?"\u2713 yes":"\u2717 no"}`),o.info(`Server built: ${Ps(r)}`),o.info(`Index exists: ${i?"\u2713 yes":"\u2717 no"}`),a)if(console.log(),a.status==="indexing")if(t){await In(e,a);return}else{let c=a.startedAt?Math.round((Date.now()-new Date(a.startedAt).getTime())/1e3):0;o.info(j.yellow("\u27F3 Indexing in progress...")),o.info(` Files processed: ${j.cyan(a.filesProcessed)}`),o.info(` Elapsed: ${j.dim(`${c}s`)}`),console.log(),o.info("Use --watch to follow indexing progress until completion")}else a.status==="error"&&(o.error(`Indexing error: ${a.error}`),o.info(` Files processed before error: ${a.filesProcessed}`));if(!s){console.log(),o.info("Run `vespercli init` to configure the MCP server");return}if(r==="missing"){console.log(),o.warn("MCP server not built. Run: cd src/mcp/vesper-indexing && npm install && npm run build");return}if(r==="broken"){console.log(),o.warn("MCP server dependencies are missing/corrupt. Run: cd src/mcp/vesper-indexing && npm install (or reinstall Vesper)");return}if(i&&!a){let c=await On(n);c&&(console.log(),o.info(`Index size: ${c.dbSize}`),o.info(`Last modified: ${c.lastModified}`)),o.vesperTip()}else!i&&!a&&(console.log(),o.info("Index not yet created. It will be built when VS Code loads the MCP server."),console.log())}async function In(e,t){let s=o.createSpinner(`Indexing... ${t.filesProcessed} files processed`);s.start();let r=500,n=30*60*1e3,i=Date.now();return new Promise(a=>{let c=async()=>{let d=await Cs(e);if(!d||d.status!=="indexing"){d?.status==="error"?s.fail(`Indexing failed: ${d.error}`):(s.succeed(`Indexing complete! ${d?.filesProcessed||"All"} files indexed`),o.info(`
29
+ \u2192 Reload VS Code to update MCP tools with the new index`),o.vesperTip()),a();return}let l=d.startedAt?Math.round((Date.now()-new Date(d.startedAt).getTime())/1e3):0;if(s.update(`Indexing... ${d.filesProcessed} files processed (${l}s)`),Date.now()-i>n){s.fail("Indexing watch timed out (30 minutes)"),a();return}setTimeout(c,r)};setTimeout(c,r)})}async function ys(e,t=!1){let s=et(e);if(!await g(s))o.info("No index exists. It will be built when VS Code loads the MCP server.");else if(t){let{unlink:n}=await import("node:fs/promises");await n(s),o.success("Index cleared. Reload VS Code to rebuild.")}else o.info("Incremental reindex happens automatically when files change."),o.info("Use --full to clear and rebuild the entire index.")}async function Mn(e){let t=await Q(e,!0);t.configured&&(o.success("MCP server enabled"),o.info(`Config: ${t.mcpPath}`),o.info("Reload VS Code to start the server"))}async function Dn(e){await Q(e,!1),o.success("MCP server disabled"),o.info("Reload VS Code to apply changes")}async function Es(e){let t=await _(e),s=await m(e,t);if(!Array.isArray(s.paths))return[];let r=[];for(let n of s.paths){let i=n.match(/agents\/([^/]+)\/?$/);i&&MCP_TOOLS_BY_AGENT[i[1]]&&r.push(i[1])}return r}async function Ln(e){let t=await _(e),s=await m(e,t),r=await k(e,t),n=await Es(e),i=r[v]||{},a=new Set(R),c=[],d=[],l=!1;r[v]||(r[v]={});for(let u of R)i[u]||(r[v][u]=!0,c.push(u),l=!0);for(let u of n){let p=MCP_TOOLS_BY_AGENT[u]||[];for(let h of p)i[h]||(r[v][h]=!0,c.push(h),l=!0)}let f=new Set;for(let u of n)for(let p of MCP_TOOLS_BY_AGENT[u]||[])f.add(p);for(let u of Object.keys(i)){if(a.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 r[v][u],d.push(u),l=!0)}if(s.mcp=s.mcp||{},s.mcp.syncedAt=new Date().toISOString(),s.mcp.approvedAgents=n,s.mcp.toolCount=Object.keys(r[v]).length,l&&await P(e,r),await C(e,s),console.log(),o.header("MCP Tools Sync"),console.log(),c.length===0&&d.length===0)o.success("Already in sync");else{if(c.length>0){o.success(`Added ${c.length} tool(s)`);let u=c.filter(p=>a.has(p));u.length>0&&o.info(` Core: ${u.length} tools`);for(let p of n){let h=c.filter(O=>(MCP_TOOLS_BY_AGENT[p]||[]).includes(O));h.length>0&&o.info(` ${p}: ${h.length} tools`)}}d.length>0&&o.info(`Removed ${d.length} orphaned tool(s)`)}o.info(`
30
30
  Total approved tools: ${s.mcp.toolCount}`),n.length>0&&o.info(`Agents with tools: ${n.join(", ")}`),l&&o.info(`
31
- Reload VS Code to apply changes`)}async function Dn(e){let t=await _(e),s=await m(e,t),n=(await x(e,t))[w]||{},i=Object.keys(n).length,a=await As(e);console.log(),o.header("MCP Tool Approval Status"),console.log();let c=R.filter(f=>n[f]);if(o.info(`Core tools: ${c.length}/${R.length} approved`),a.length>0){console.log(),o.info("Agent tools:");for(let f of a){let u=MCP_TOOLS_BY_AGENT[f]||[],p=u.filter(O=>n[O]),h=p.length===u.length?j.green("\u2713"):j.yellow("\u26A0");o.info(` ${h} ${f}: ${p.length}/${u.length} approved`)}}let d=[...R];for(let f of a)d.push(...MCP_TOOLS_BY_AGENT[f]||[]);let l=d.filter(f=>!n[f]);console.log(),o.info(`Total approved: ${i} tools`),l.length>0?(console.log(),o.warn(`${l.length} tools missing approval`),o.info("Run `vespercli mcp sync` to fix")):s.mcp?.syncedAt&&o.info(`Last synced: ${s.mcp.syncedAt}`)}function Ps(){return Object.keys(N).filter(e=>!Y.includes(e))}async function Ln(e,t){t||(o.error("Server name required. Usage: vespercli mcp add <server>"),o.info(`Available servers: ${Ps().join(", ")}`),process.exit(1)),console.log(),o.header("Add MCP Server"),console.log();let s=await Vt(e,t);if(!s.added){s.error==="Already configured"?o.info(`MCP server '${t}' is already configured`):(o.error(s.error),process.exit(1));return}o.success(`Added MCP server: ${t}`),s.tools.length>0&&o.info(`Approved ${s.tools.length} tool(s) for auto-execution`),o.info(`
32
- Reload VS Code to activate the MCP server`)}async function jn(e,t){t||(o.error("Server name required. Usage: vespercli mcp remove <server>"),process.exit(1)),console.log(),o.header("Remove MCP Server"),console.log();let s=await Rt(e,t);if(!s.removed){o.info(`MCP server '${t}' is not configured`);return}o.success(`Removed MCP server: ${t}`),s.tools.length>0&&o.info(`Removed ${s.tools.length} tool(s) from auto-approval`),o.info(`
33
- Reload VS Code to deactivate the MCP server`)}async function Fn(e){let t=await _(e),s=await m(e,t),r=await G(e);console.log(),o.header("MCP Servers"),console.log();let n=s.mcp?.servers||[],i=Object.keys(r.servers||{});o.info("Available servers:");for(let[c,d]of Object.entries(N)){let f=i.includes(c)?j.green("\u2713"):j.dim("\u25CB"),u=d.tools?.length||0;o.info(` ${f} ${c} (${u} tools)`)}let a=i.filter(c=>!N[c]);if(a.length>0){console.log(),o.info("Custom servers:");for(let c of a)o.info(` ${j.blue("\u25C6")} ${c}`)}console.log(),o.info(`Installed: ${i.length} server(s)`)}async function vs(e,t){t||(o.error("Server name required. Usage: vespercli mcp add <server> --target claude"),o.info(`Available servers: ${Ps().join(", ")}`),process.exit(1));let s=await Jt(e,t);if(!s.added){s.error==="Already configured"?o.info(`MCP server '${t}' is already configured for the Claude Code target`):o.error(s.error);return}o.success(`Added MCP server: ${t} (Claude Code target)`),o.info(`
34
- Reload the Claude Code session to activate the MCP server`)}async function ys(e,t){t||(o.error("Server name required. Usage: vespercli mcp remove <server> --target claude"),process.exit(1));let s=await zt(e,t);if(s.error){o.error(s.error);return}if(!s.removed){o.info(`MCP server '${t}' is not configured for the Claude Code target`);return}o.success(`Removed MCP server: ${t} (Claude Code target)`),o.info(`
35
- Reload the Claude Code session to deactivate the MCP server`)}async function _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",`
31
+ Reload VS Code to apply changes`)}async function jn(e){let t=await _(e),s=await m(e,t),n=(await k(e,t))[v]||{},i=Object.keys(n).length,a=await Es(e);console.log(),o.header("MCP Tool Approval Status"),console.log();let c=R.filter(f=>n[f]);if(o.info(`Core tools: ${c.length}/${R.length} approved`),a.length>0){console.log(),o.info("Agent tools:");for(let f of a){let u=MCP_TOOLS_BY_AGENT[f]||[],p=u.filter(O=>n[O]),h=p.length===u.length?j.green("\u2713"):j.yellow("\u26A0");o.info(` ${h} ${f}: ${p.length}/${u.length} approved`)}}let d=[...R];for(let f of a)d.push(...MCP_TOOLS_BY_AGENT[f]||[]);let l=d.filter(f=>!n[f]);console.log(),o.info(`Total approved: ${i} tools`),l.length>0?(console.log(),o.warn(`${l.length} tools missing approval`),o.info("Run `vespercli mcp sync` to fix")):s.mcp?.syncedAt&&o.info(`Last synced: ${s.mcp.syncedAt}`)}function bs(){return Object.keys(N).filter(e=>!Y.includes(e))}async function Vn(e,t){t||(o.error("Server name required. Usage: vespercli mcp add <server>"),o.info(`Available servers: ${bs().join(", ")}`),process.exit(1)),console.log(),o.header("Add MCP Server"),console.log();let s=await Rt(e,t);if(!s.added){s.error==="Already configured"?o.info(`MCP server '${t}' is already configured`):(o.error(s.error),process.exit(1));return}o.success(`Added MCP server: ${t}`),s.tools.length>0&&o.info(`Approved ${s.tools.length} tool(s) for auto-execution`),o.info(`
32
+ Reload VS Code to activate the MCP server`)}async function Fn(e,t){t||(o.error("Server name required. Usage: vespercli mcp remove <server>"),process.exit(1)),console.log(),o.header("Remove MCP Server"),console.log();let s=await Nt(e,t);if(!s.removed){o.info(`MCP server '${t}' is not configured`);return}o.success(`Removed MCP server: ${t}`),s.tools.length>0&&o.info(`Removed ${s.tools.length} tool(s) from auto-approval`),o.info(`
33
+ Reload VS Code to deactivate the MCP server`)}async function Rn(e){let t=await _(e),s=await m(e,t),r=await G(e);console.log(),o.header("MCP Servers"),console.log();let n=s.mcp?.servers||[],i=Object.keys(r.servers||{});o.info("Available servers:");for(let[c,d]of Object.entries(N)){let f=i.includes(c)?j.green("\u2713"):j.dim("\u25CB"),u=d.tools?.length||0;o.info(` ${f} ${c} (${u} tools)`)}let a=i.filter(c=>!N[c]);if(a.length>0){console.log(),o.info("Custom servers:");for(let c of a)o.info(` ${j.blue("\u25C6")} ${c}`)}console.log(),o.info(`Installed: ${i.length} server(s)`)}async function _s(e,t){t||(o.error("Server name required. Usage: vespercli mcp add <server> --target claude"),o.info(`Available servers: ${bs().join(", ")}`),process.exit(1));let s=await zt(e,t);if(!s.added){s.error==="Already configured"?o.info(`MCP server '${t}' is already configured for the Claude Code target`):o.error(s.error);return}o.success(`Added MCP server: ${t} (Claude Code target)`),o.info(`
34
+ Reload the Claude Code session to activate the MCP server`)}async function Ss(e,t){t||(o.error("Server name required. Usage: vespercli mcp remove <server> --target claude"),process.exit(1));let s=await Yt(e,t);if(s.error){o.error(s.error);return}if(!s.removed){o.info(`MCP server '${t}' is not configured for the Claude Code target`);return}o.success(`Removed MCP server: ${t} (Claude Code target)`),o.info(`
35
+ Reload the Claude Code session to deactivate the MCP server`)}async function ks(e){let{configured:t,custom:s}=await Xt(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 Ts(e,t,s={}){let r=bn(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 _s(r,t);case"remove":return await Ss(r,t);case"list":return await ks(r);case"status":return await Le(r);case"reindex":return await ys(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 ws(r,s.watch),d&&await Le(r);break;case"add":await Vn(r,t),d&&await _s(r,t);break;case"remove":await Fn(r,t),d&&await Ss(r,t);break;case"list":await Rn(r),d&&await ks(r);break;case"reindex":await ys(r,s.full);break;case"enable":await Mn(r),d&&await ce(r,!0);break;case"disable":await Dn(r),d&&await ce(r,!1);break;case"sync":await Ln(r),d&&await ce(r,!0);break;case"approve":await jn(r);break;default:await ws(r,s.watch),d&&await Le(r)}}import{resolve as Nn}from"node:path";async function Os(e,t,s,r={}){let n=Nn(r.path||process.cwd());if(!e){$s();return}switch(e){case"add":await Gn(n,t,s);break;case"remove":await Un(n,t,s);break;case"list":await Wn(n,t);break;default:o.error(`Unknown subcommand: ${e}`),$s()}}async function Gn(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 Ot(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 Un(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 It(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 Wn(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 Mt(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 $s(){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")}V();import{resolve as Is}from"node:path";async function Bn(e={}){let t=Is(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 Ms(e={}){try{let t=Is(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 Bn({...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)}}V();import{resolve as qn,join as tt}from"node:path";async function Kn(e){let t=await g(tt(Ee(e),"orchestration.md")),s=await g(tt(e,".github","copilot-instructions.md"));return{claude:t,copilot:s}}async function Hn(e,t){if(!await g(e))return;let{claude:s,copilot:r}=await Kn(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 F(["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 F(["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=tt(e,".vesper","index.db");if(!await g(c)){let l=await Qe(e,!1);l.success&&n.push(`code index built (${l.filesIndexed} files)`)}await ve(e);let d=await we(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 ke(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 Ds(e,t={}){let s=qn(t.path||process.cwd()),r=!!t.quiet;switch(e){case"bootstrap":case void 0:await Hn(s,r);break;default:o.error(`Unknown subcommand: ${e}. Usage: vespercli worktree bootstrap`),process.exit(1)}}var Qn=Xn(import.meta.url),Zn=st(Qn);function eo(e){let t=e;for(;t!==st(t);){let s=Ls(t,"package.json");if(Yn(s))return s;t=st(t)}return Ls(e,"..","..","package.json")}var to=eo(Zn),rt=JSON.parse(zn(to,"utf-8")),L=new Jn;L.name("vespercli").description("Vesper VS Code Agent Suite \u2014 manage GitHub Copilot agents, prompts, instructions, and skills").version(rt.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=>as({...e,version:rt.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)=>us({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(rs);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)=>gs({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=>Ms({...e,version:rt.version}));L.command("catalog").description("Show the Vesper catalog (agents, dependencies, requirements)").action(hs);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)=>Ts(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)=>Os(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)=>Ds(e,t));L.addHelpText("after",`
36
36
  Examples:
37
37
  $ vespercli init Pick platform(s) to set up (multi-select), then initialize
38
38
  $ vespercli init --target copilot,claude Set up both platforms in one run
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mthanh/vespercli",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
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",
@@ -21,7 +21,16 @@ const isDevEnvironment = existsSync(join(packageRoot, '.git'));
21
21
 
22
22
  // Check if MCP server is already built
23
23
  const mcpDistExists = existsSync(join(mcpDir, 'dist', 'index.js'));
24
- const mcpNodeModulesExists = existsSync(join(mcpDir, 'node_modules'));
24
+
25
+ // Integrity canary: presence of `node_modules` alone does NOT prove a healthy
26
+ // install — a corrupted tree missing a critical dep manifest crashes the server
27
+ // with ERR_MODULE_NOT_FOUND yet still has the directory. Check the manifests of
28
+ // the two direct runtime deps (`@modelcontextprotocol/sdk`, `zod`) instead, so a
29
+ // corrupt tree falls through to the `npm install` self-heal below. Same canary set
30
+ // as getMcpServerState() in src/cli/commands/mcp.js — keep them in sync.
31
+ const sdkManifest = join(mcpDir, 'node_modules', '@modelcontextprotocol', 'sdk', 'package.json');
32
+ const zodManifest = join(mcpDir, 'node_modules', 'zod', 'package.json');
33
+ const mcpDepsHealthy = existsSync(sdkManifest) && existsSync(zodManifest);
25
34
 
26
35
  async function runCommand(command, args, cwd) {
27
36
  return new Promise((resolve, reject) => {
@@ -45,7 +54,7 @@ async function runCommand(command, args, cwd) {
45
54
 
46
55
  async function main() {
47
56
  // Skip if already built (common during npm pack/publish)
48
- if (mcpDistExists && mcpNodeModulesExists) {
57
+ if (mcpDistExists && mcpDepsHealthy) {
49
58
  console.log('✓ vesper-indexing MCP server already built');
50
59
  return;
51
60
  }
@@ -63,8 +72,10 @@ async function main() {
63
72
  try {
64
73
  // Install dependencies. When prebuilt dist is shipped (the published
65
74
  // package), skip devDependencies — no TypeScript build is needed, only the
66
- // runtime deps (incl. the native better-sqlite3, built for this platform).
67
- if (!mcpNodeModulesExists) {
75
+ // runtime deps. The store uses the built-in node:sqlite module (migrated off
76
+ // better-sqlite3), so there is no native addon to compile here. `npm install`
77
+ // over a partially-corrupt tree self-heals by reinstalling missing packages.
78
+ if (!mcpDepsHealthy) {
68
79
  console.log('→ Installing dependencies...');
69
80
  const installArgs = ['install', '--no-audit', '--no-fund'];
70
81
  if (mcpDistExists) installArgs.push('--omit=dev');
@@ -3,6 +3,7 @@
3
3
  * vesper-indexing MCP Server
4
4
  * Provides fast full-text search across the codebase
5
5
  */
6
+ import { readFileSync } from 'node:fs';
6
7
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
8
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
9
  import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
@@ -12,6 +13,21 @@ import { FileWatcher } from './watcher.js';
12
13
  import { IndexRunner } from './index-runner.js';
13
14
  import { RECONCILE_INTERVAL_MS } from './constants.js';
14
15
  import { createSearchTool, createSymbolsTool, createStatusTool, createReindexTool, } from './tools/index.js';
16
+ // Read the reported server version from the subpackage package.json at runtime.
17
+ // A static JSON import is deliberately avoided: the emitted dist/index.js would
18
+ // resolve the literal path against dist/, not the subpackage root, and crash with
19
+ // ERR_MODULE_NOT_FOUND. `import.meta.url` is `.../dist/index.js` at runtime, so
20
+ // `../package.json` correctly points at the subpackage root regardless of layout.
21
+ // This runs at module-evaluation time, before main()'s try/catch is in scope, so a
22
+ // missing/corrupt package.json is caught here directly with a fallback version
23
+ // instead of throwing a raw stack trace ahead of the graceful `main().catch(...)` path.
24
+ let SERVER_VERSION = 'unknown';
25
+ try {
26
+ ({ version: SERVER_VERSION } = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8')));
27
+ }
28
+ catch (error) {
29
+ console.error('[vesper-indexing] Could not read package.json version, using fallback:', error);
30
+ }
15
31
  async function main() {
16
32
  // Verify node:sqlite is available before loading the store (which imports it).
17
33
  assertNodeSqlite();
@@ -63,7 +79,7 @@ async function main() {
63
79
  // Create MCP server
64
80
  const server = new Server({
65
81
  name: 'vesper-indexing',
66
- version: '1.2.0',
82
+ version: SERVER_VERSION,
67
83
  }, {
68
84
  capabilities: {
69
85
  tools: {},
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@vesper/indexing",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@vesper/indexing",
9
- "version": "1.4.0",
9
+ "version": "1.4.1",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@modelcontextprotocol/sdk": "^1.12.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vesper/indexing",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "Local MCP server for fast codebase indexing and semantic search",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",