infra-kit 0.1.121 → 0.1.122

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.
@@ -7,7 +7,7 @@ ${r}
7
7
  ${t}`,gr=({content:e,body:r,startMarker:t,endMarker:o,placement:n="replace-in-place"})=>{let s=$n(t,r,o),i=He(e,t,o);if(n==="replace-in-place"&&i){let p=e.indexOf(t),d=e.indexOf(o)+o.length;return e.slice(0,p)+s+e.slice(d)}let c=(i?ve(e,t,o)??e:e).replace(/\n+$/,"");return c.length>0?`${c}
8
8
  ${s}
9
9
  `:`${s}
10
- `};import O from"node:fs";import vr from"node:path";import Kt from"node:fs/promises";import Ni from"node:os";import hr from"node:path";import{z as y}from"zod";var In="infra-kit.json",Yr=".infra-kit",_i="infra-kit.json",Oi="projects",Fi=y.object({provider:y.literal("doppler"),config:y.object({name:y.string().min(1)})}),Di=y.discriminatedUnion("provider",[Fi]),ji=y.object({workspaceConfigPath:y.string().min(1)}),Mi=y.object({provider:y.literal("cursor"),config:ji}),Li=y.object({}),Wi=y.object({provider:y.literal("zed"),config:Li}),Pn=y.discriminatedUnion("provider",[Mi,Wi]),Vi=y.union([Pn,y.array(Pn).min(1)]),Bi=y.object({provider:y.literal("jira"),config:y.object({baseUrl:y.string().url(),projectId:y.number().int().positive()})}),Ji=y.discriminatedUnion("provider",[Bi]),Ki=["two-columns","three-pane"],Gi=y.object({layout:y.enum(Ki).optional()}),zi=y.object({openInGithubDesktop:y.boolean().optional(),openInCmux:y.boolean().optional(),cmux:Gi.optional()}),Ui=y.object({trigger:y.enum(["shell-startup","cli-invocation"]),config:y.string().min(1)}).strict(),Sn=y.object({environments:y.array(y.string().min(1)).min(1),envManagement:Di,ide:Vi.optional(),taskManager:Ji.optional(),worktrees:zi.optional(),envAutoLoad:Ui.optional()}),Qr=Sn.superRefine((e,r)=>{if(!Array.isArray(e.ide))return;let t=new Set;for(let o of e.ide){if(t.has(o.provider)){r.addIssue({code:"custom",message:"each IDE provider may appear at most once",path:["ide"]});return}t.add(o.provider)}}),wr=Sn.partial(),K=e=>{let r=e.ide;return r?Array.isArray(r)?r:[r]:[]},qi="two-columns",Gt=e=>e.worktrees?.cmux?.layout??qi,Ze=null,W=async()=>{let e=await k(),r=hr.basename(e),t=hr.join(Ni.homedir(),Yr);return{main:hr.join(e,In),userGlobal:hr.join(t,_i),userProject:hr.join(t,Oi,r,In),projectName:r}},x=async()=>{let e=await W(),r;try{r=await Kt.stat(e.main)}catch{Ze=null;let c=e.main.replace(/\.json$/,".yml");throw await Jt(c)?new Error(`infra-kit.json not found at ${e.main}. A legacy infra-kit.yml exists \u2014 run \`infra-kit init\` to convert it.`):new Error(`infra-kit.json not found at ${e.main}`)}let[t,o]=await Promise.all([Jt(e.userGlobal),Jt(e.userProject)]),n={main:Number(r.mtimeMs),userGlobal:t?Number(t.mtimeMs):null,userProject:o?Number(o.mtimeMs):null};if(Ze&&Zi(Ze.mtimes,n))return Ze.value;let s=[{label:"infra-kit.json",path:e.main,required:!0},{label:"~/.infra-kit/infra-kit.json",path:e.userGlobal,required:!1},{label:`~/.infra-kit/projects/${e.projectName}/infra-kit.json`,path:e.userProject,required:!1}],i={};for(let c of s){let p=await Xi(c);p!==null&&(i={...i,...p})}let l=Qr.safeParse(i);if(!l.success)throw new Error(`Invalid merged infra-kit config: ${y.prettifyError(l.error)}`);return Ze={mtimes:n,value:l.data},l.data},ye=()=>{Ze=null},Jt=async e=>{try{return await Kt.stat(e)}catch{return null}},Hi=async e=>{try{return await Kt.readFile(e,"utf-8")}catch{return null}},Zi=(e,r)=>{let t=Object.keys(e);return t.length!==Object.keys(r).length?!1:t.every(o=>e[o]===r[o])},Xi=async e=>{let r=await Hi(e.path);if(r===null){if(e.required)throw new Error(`${e.label} not found at ${e.path}`);return null}let t;try{t=r.trim()===""?{}:JSON.parse(r)}catch(n){throw new Error(`Invalid JSON in ${e.label} at ${e.path}: ${n.message}`)}let o=wr.safeParse(t);if(!o.success)throw new Error(`Invalid ${e.label} at ${e.path}: ${y.prettifyError(o.error)}`);return o.data};var et={name:"infra-kit",type:"module",version:"0.1.121",description:"infra-kit",main:"dist/index.js",module:"dist/index.js",types:"dist/entry/index.d.ts",exports:{".":{types:"./dist/entry/index.d.ts",import:"./dist/index.js"}},bin:{"infra-kit":"dist/cli.js"},engines:{node:">=24.x"},scripts:{inspector:"npx @modelcontextprotocol/inspector node ./dist/mcp.js --debug",build:"pnpm run clean-artifacts && node ./scripts/build.js",check:"node ./dist/cli.js check","clean-artifacts":"rm -rf dist","clean-cache":"rm -rf node_modules/.cache .eslintcache tsconfig.tsbuildinfo .turbo .swc","prettier-fix":"pnpm exec prettier **/* --write --no-error-on-unmatched-pattern --log-level silent --ignore-path ../../../.prettierignore","prettier-check":"pnpm exec prettier **/* --check --no-error-on-unmatched-pattern --log-level silent --ignore-path ../../../.prettierignore","eslint-check":"pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src","eslint-fix":"pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src --fix","ts-check":"tsc --noEmit",test:"pnpm exec vitest run --reporter=minimal","test-watch":"pnpm exec vitest --watch --silent passed-only","test-ui":"pnpm exec vitest --ui --silent passed-only","test-report":"pnpm exec vitest run --coverage --silent passed-only",qa:"pnpm run prettier-check && pnpm run eslint-check && pnpm run ts-check && pnpm run test && echo \u2705 Success",fix:"pnpm run prettier-fix && pnpm run eslint-fix && pnpm run qa"},dependencies:{"@inquirer/checkbox":"^5.2.1","@inquirer/confirm":"^6.1.1","@inquirer/select":"^5.2.1","@modelcontextprotocol/sdk":"^1.29.0",commander:"^15.0.0",ink:"^7.1.0",pino:"^10.3.1","pino-pretty":"^13.1.3",react:"catalog:",yaml:"^2.9.0",zod:"^4.4.3",zx:"^8.8.5"},devDependencies:{"@types/react":"catalog:","@wl/eslint-config":"workspace:*","@wl/vitest-config":"workspace:*",esbuild:"^0.28.1","ink-testing-library":"^4.0.0",typescript:"^6.0.3"}};var yr="<!-- infra-kit:begin -->",kr="<!-- infra-kit:end -->",Qi="<!-- infra-kit:version ",ea="<!-- infra-kit:import:begin -->",ra="<!-- infra-kit:import:end -->",ta="AGENTS.md",oa="CLAUDE.md",na=e=>`${Qi}${e} -->`,sa=e=>[na(e),"","# infra-kit","","This repository uses the **infra-kit** CLI for environment, worktree, and release workflows.","This block is generated by `infra-kit init` \u2014 edit text *outside* the markers, never inside.","","## Commands (`ik` = `pnpm exec infra-kit`)","","- `ik env-load -c <config>` / `ik env-clear` / `ik env-status` \u2014 load, clear, or inspect Doppler env vars for a config (e.g. `dev`). Source the returned file to apply.","- `ik worktrees add` / `worktrees list` / `worktrees reload` / `worktrees remove` / `worktrees sync` \u2014 manage release and feature git worktrees.","- `ik release create` / `release list` / `release deploy-all` / `release deploy-selected` / `release deliver` / `release desc-edit` \u2014 release-branch and deploy flow.","- `ik release merge-dev` \u2014 merge the dev branch into every release branch.","- `ik audit` \u2014 audit packages against `infra-kit.config.ts` rules.","- `ik doctor` \u2014 check gh / doppler / aws / rtk install + auth and repo setup.","- `ik init` \u2014 (re)install shell integration and regenerate these agent-instruction files.","","## Conventions","","- Tickets are prefixed by area: `[FE]` frontend, `[BE]` backend, `[DO]` DevOps/infra, `[APP]` mobile app, `[IDEA]` proposal, `[ROOT]` cross-cutting. Pick the single dominant area.","- Environment variables are managed through Doppler via `ik env-load` \u2014 never commit secrets."].join(`
10
+ `};import O from"node:fs";import vr from"node:path";import Kt from"node:fs/promises";import Ni from"node:os";import hr from"node:path";import{z as y}from"zod";var In="infra-kit.json",Yr=".infra-kit",_i="infra-kit.json",Oi="projects",Fi=y.object({provider:y.literal("doppler"),config:y.object({name:y.string().min(1)})}),Di=y.discriminatedUnion("provider",[Fi]),ji=y.object({workspaceConfigPath:y.string().min(1)}),Mi=y.object({provider:y.literal("cursor"),config:ji}),Li=y.object({}),Wi=y.object({provider:y.literal("zed"),config:Li}),Pn=y.discriminatedUnion("provider",[Mi,Wi]),Vi=y.union([Pn,y.array(Pn).min(1)]),Bi=y.object({provider:y.literal("jira"),config:y.object({baseUrl:y.string().url(),projectId:y.number().int().positive()})}),Ji=y.discriminatedUnion("provider",[Bi]),Ki=["two-columns","three-pane"],Gi=y.object({layout:y.enum(Ki).optional()}),zi=y.object({openInGithubDesktop:y.boolean().optional(),openInCmux:y.boolean().optional(),cmux:Gi.optional()}),Ui=y.object({trigger:y.enum(["shell-startup","cli-invocation"]),config:y.string().min(1)}).strict(),Sn=y.object({environments:y.array(y.string().min(1)).min(1),envManagement:Di,ide:Vi.optional(),taskManager:Ji.optional(),worktrees:zi.optional(),envAutoLoad:Ui.optional()}),Qr=Sn.superRefine((e,r)=>{if(!Array.isArray(e.ide))return;let t=new Set;for(let o of e.ide){if(t.has(o.provider)){r.addIssue({code:"custom",message:"each IDE provider may appear at most once",path:["ide"]});return}t.add(o.provider)}}),wr=Sn.partial(),K=e=>{let r=e.ide;return r?Array.isArray(r)?r:[r]:[]},qi="two-columns",Gt=e=>e.worktrees?.cmux?.layout??qi,Ze=null,W=async()=>{let e=await k(),r=hr.basename(e),t=hr.join(Ni.homedir(),Yr);return{main:hr.join(e,In),userGlobal:hr.join(t,_i),userProject:hr.join(t,Oi,r,In),projectName:r}},x=async()=>{let e=await W(),r;try{r=await Kt.stat(e.main)}catch{Ze=null;let c=e.main.replace(/\.json$/,".yml");throw await Jt(c)?new Error(`infra-kit.json not found at ${e.main}. A legacy infra-kit.yml exists \u2014 run \`infra-kit init\` to convert it.`):new Error(`infra-kit.json not found at ${e.main}`)}let[t,o]=await Promise.all([Jt(e.userGlobal),Jt(e.userProject)]),n={main:Number(r.mtimeMs),userGlobal:t?Number(t.mtimeMs):null,userProject:o?Number(o.mtimeMs):null};if(Ze&&Zi(Ze.mtimes,n))return Ze.value;let s=[{label:"infra-kit.json",path:e.main,required:!0},{label:"~/.infra-kit/infra-kit.json",path:e.userGlobal,required:!1},{label:`~/.infra-kit/projects/${e.projectName}/infra-kit.json`,path:e.userProject,required:!1}],i={};for(let c of s){let p=await Xi(c);p!==null&&(i={...i,...p})}let l=Qr.safeParse(i);if(!l.success)throw new Error(`Invalid merged infra-kit config: ${y.prettifyError(l.error)}`);return Ze={mtimes:n,value:l.data},l.data},ye=()=>{Ze=null},Jt=async e=>{try{return await Kt.stat(e)}catch{return null}},Hi=async e=>{try{return await Kt.readFile(e,"utf-8")}catch{return null}},Zi=(e,r)=>{let t=Object.keys(e);return t.length!==Object.keys(r).length?!1:t.every(o=>e[o]===r[o])},Xi=async e=>{let r=await Hi(e.path);if(r===null){if(e.required)throw new Error(`${e.label} not found at ${e.path}`);return null}let t;try{t=r.trim()===""?{}:JSON.parse(r)}catch(n){throw new Error(`Invalid JSON in ${e.label} at ${e.path}: ${n.message}`)}let o=wr.safeParse(t);if(!o.success)throw new Error(`Invalid ${e.label} at ${e.path}: ${y.prettifyError(o.error)}`);return o.data};var et={name:"infra-kit",type:"module",version:"0.1.122",description:"infra-kit",main:"dist/index.js",module:"dist/index.js",types:"dist/entry/index.d.ts",exports:{".":{types:"./dist/entry/index.d.ts",import:"./dist/index.js"}},bin:{"infra-kit":"dist/cli.js"},engines:{node:">=24.x"},scripts:{inspector:"npx @modelcontextprotocol/inspector node ./dist/mcp.js --debug",build:"pnpm run clean-artifacts && node ./scripts/build.js",check:"node ./dist/cli.js check","clean-artifacts":"rm -rf dist","clean-cache":"rm -rf node_modules/.cache .eslintcache tsconfig.tsbuildinfo .turbo .swc","prettier-fix":"pnpm exec prettier **/* --write --no-error-on-unmatched-pattern --log-level silent --ignore-path ../../../.prettierignore","prettier-check":"pnpm exec prettier **/* --check --no-error-on-unmatched-pattern --log-level silent --ignore-path ../../../.prettierignore","eslint-check":"pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src","eslint-fix":"pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src --fix","ts-check":"tsc --noEmit",test:"pnpm exec vitest run --reporter=minimal","test-watch":"pnpm exec vitest --watch --silent passed-only","test-ui":"pnpm exec vitest --ui --silent passed-only","test-report":"pnpm exec vitest run --coverage --silent passed-only",qa:"pnpm run prettier-check && pnpm run eslint-check && pnpm run ts-check && pnpm run test && echo \u2705 Success",fix:"pnpm run prettier-fix && pnpm run eslint-fix && pnpm run qa"},dependencies:{"@inquirer/checkbox":"^5.2.1","@inquirer/confirm":"^6.1.1","@inquirer/select":"^5.2.1","@modelcontextprotocol/sdk":"^1.29.0",commander:"^15.0.0",ink:"^7.1.0",pino:"^10.3.1","pino-pretty":"^13.1.3",react:"19.2.7",yaml:"^2.9.0",zod:"^4.4.3",zx:"^8.8.5"},devDependencies:{"@types/react":"catalog:","@wl/eslint-config":"workspace:*","@wl/vitest-config":"workspace:*",esbuild:"^0.28.1","ink-testing-library":"^4.0.0",typescript:"^6.0.3"}};var yr="<!-- infra-kit:begin -->",kr="<!-- infra-kit:end -->",Qi="<!-- infra-kit:version ",ea="<!-- infra-kit:import:begin -->",ra="<!-- infra-kit:import:end -->",ta="AGENTS.md",oa="CLAUDE.md",na=e=>`${Qi}${e} -->`,sa=e=>[na(e),"","# infra-kit","","This repository uses the **infra-kit** CLI for environment, worktree, and release workflows.","This block is generated by `infra-kit init` \u2014 edit text *outside* the markers, never inside.","","## Commands (`ik` = `pnpm exec infra-kit`)","","- `ik env-load -c <config>` / `ik env-clear` / `ik env-status` \u2014 load, clear, or inspect Doppler env vars for a config (e.g. `dev`). Source the returned file to apply.","- `ik worktrees add` / `worktrees list` / `worktrees reload` / `worktrees remove` / `worktrees sync` \u2014 manage release and feature git worktrees.","- `ik release create` / `release list` / `release deploy-all` / `release deploy-selected` / `release deliver` / `release desc-edit` \u2014 release-branch and deploy flow.","- `ik release merge-dev` \u2014 merge the dev branch into every release branch.","- `ik audit` \u2014 audit packages against `infra-kit.config.ts` rules.","- `ik doctor` \u2014 check gh / doppler / aws / rtk install + auth and repo setup.","- `ik init` \u2014 (re)install shell integration and regenerate these agent-instruction files.","","## Conventions","","- Tickets are prefixed by area: `[FE]` frontend, `[BE]` backend, `[DO]` DevOps/infra, `[APP]` mobile app, `[IDEA]` proposal, `[ROOT]` cross-cutting. Pick the single dominant area.","- Environment variables are managed through Doppler via `ik env-load` \u2014 never commit secrets."].join(`
11
11
  `),An=e=>{if(O.existsSync(e)&&O.lstatSync(e).isSymbolicLink())throw new Error(`Refusing to write ${e} because the destination is a symlink`)},Nn=e=>{let r=new Date().toISOString().replace(/[:.]/g,"-");O.copyFileSync(e,`${e}.backup.${r}`)},_n=(e,r)=>{An(e);let t=O.existsSync(e);return(t?O.readFileSync(e,"utf-8"):null)===r?"unchanged":(t&&Nn(e),O.mkdirSync(vr.dirname(e),{recursive:!0}),O.writeFileSync(e,r,"utf-8"),t?"updated":"created")},ia=(e,r)=>O.existsSync(e)?O.readFileSync(e,"utf-8"):r,aa=(e,r,t)=>{let o=O.readFileSync(e,"utf-8");if(!He(o,r,t))throw new Error(`Post-write validation failed: managed block missing from ${e}`)},ca=e=>{if(!O.existsSync(e))return"unchanged";An(e);let r=O.readFileSync(e,"utf-8"),t=ve(r,yr,kr);return t===null?"unchanged":t.trim()===""?(Nn(e),O.rmSync(e),"removed"):_n(e,t)},On=async()=>{let e;try{e=(await W()).main}catch{return a.info("Skipped agent-instruction files \u2014 not inside an infra-kit repo"),{skipped:!0,root:null,written:[]}}if(!O.existsSync(e))return a.info("Skipped agent-instruction files \u2014 no infra-kit.json at the repo root"),{skipped:!0,root:null,written:[]};let r=vr.dirname(e),t=et.version,o=sa(t),n=vr.join(r,ta),s=vr.join(r,oa),i=ia(s,"");i=ve(i,ea,ra)??i,i=gr({content:i,body:o,startMarker:yr,endMarker:kr,placement:"replace-in-place"});let l=[{path:s,action:_n(s,i)},{path:n,action:ca(n)}];aa(s,yr,kr);for(let c of l)c.action==="unchanged"&&c.path!==s||a.info(` ${c.action.padEnd(9)} ${vr.relative(r,c.path)}`);return a.info(`Agent-instruction files synced (infra-kit ${t})`),{skipped:!1,root:r,written:l}};import V from"node:fs/promises";import Y from"node:path";import{pathToFileURL as ua}from"node:url";import fa from"yaml";import{z as Mn}from"zod";import la from"node:fs/promises";import pa from"node:os";var pe=async e=>{try{return await la.access(e),!0}catch{return!1}},R=e=>{let r=pa.homedir();return e.startsWith(r)?`~${e.slice(r.length)}`:e};import da from"node:fs/promises";import zt from"node:os";import Ut from"node:path";import{z as ma}from"zod";import{z as rt}from"zod";var Fn="vendor.json",tt=rt.object({workspaceDir:rt.string().min(1),targets:rt.array(rt.string()).min(1)}).strict();var qt=()=>Ut.join(zt.homedir(),Yr,Fn),Dn=e=>{if(e==="~")return zt.homedir();if(e.startsWith("~/"))return Ut.join(zt.homedir(),e.slice(2));if(Ut.isAbsolute(e))return e;throw new Error(`workspaceDir must be absolute or ~-prefixed, got: ${e}`)},Xe=async()=>{let e=qt(),r;try{r=await da.readFile(e,"utf-8")}catch{throw new Error(`Factory config not found at ${e}. infra-kit needs a machine-local factory registry to know where your project repos live and which to stamp. Run \`infra-kit vendor-config --init\` to scaffold it, or create it manually as JSON:
12
12
 
13
13
  {
@@ -163,4 +163,4 @@ See \`.sync-manifest.json\` for the source commit and per-file checksums.
163
163
  ${i.join(`
164
164
  `)}
165
165
  `);let l={worktrees:n,count:n.length};return{content:g(JSON.stringify(l,null,2)),structuredContent:l}},sn=w({name:"worktrees-list",description:"List existing release-branch worktrees with version, release type (regular / hotfix), and Jira fix-version description. Read-only.",inputSchema:{},outputSchema:{worktrees:lr.array(lr.object({version:lr.string().describe("Release version"),type:lr.enum(["regular","hotfix"]).describe("Release type"),description:lr.string().nullable().describe("Jira version description")})).describe("List of all worktrees with details"),count:lr.number().describe("Number of worktrees")},handler:ri});import{z as $e}from"zod";var ti=async()=>{m.start("worktrees-reload");try{let e=await k(),r=`${e}${G}`,t=await F("release"),o=await J(),n=await ep({currentBranches:t,repoName:o}),[s,{opened:i}]=await Promise.all([rn({projectRoot:e,worktreeDir:r,currentBranches:t}),rp({worktreeDir:r,currentBranches:t,repoName:o})]),l={closedCmux:n,openedCmux:i,ideProviders:s.filter(c=>c.ran).map(c=>c.provider),ideFoldersAdded:s.reduce((c,p)=>c+p.added,0),ideFoldersRemoved:s.reduce((c,p)=>c+p.removed,0)};return tp(l,{ideRan:s.some(c=>c.ran)}),m.print(),{content:g(JSON.stringify(l,null,2)),structuredContent:{...l}}}catch(e){throw a.error({error:e},"\u274C Error reloading worktrees"),new f(e,{operation:"reload worktrees",remediation:"run 'worktrees-list' to confirm the branches exist"})}},ep=async e=>{let{currentBranches:r,repoName:t}=e;if(r.length===0)return[];let o=await Fr(),n=[];for(let s of r){let i=re({repoName:t,branch:s});o.has(ee(i))&&(await Je(i),n.push(i))}return n},rp=async e=>{let{worktreeDir:r,currentBranches:t,repoName:o}=e,n=[];for(let s of t){let i=re({repoName:o,branch:s});try{await jr({cwd:`${r}/${s}`,title:i}),n.push(i)}catch(l){a.warn({error:l,title:i},`\u26A0\uFE0F Failed to reopen cmux workspace for ${s}`)}}return{opened:n}},tp=(e,r)=>{if(e.closedCmux.length>0&&a.info(`\u{1F9F9} Closed ${e.closedCmux.length} cmux workspace(s)`),r.ideRan){let t=e.ideProviders.map(o=>tn(o)).join(", ");e.ideFoldersAdded>0&&a.info(`\u2705 Added ${e.ideFoldersAdded} folder(s) to ${t} workspace(s)`),e.ideFoldersRemoved>0&&a.info(`\u{1F9F9} Removed ${e.ideFoldersRemoved} dangling folder(s) from ${t} workspace(s)`)}if(e.openedCmux.length>0){a.info("\u2705 Reopened cmux workspaces:");for(let t of e.openedCmux)a.info(t)}!r.ideRan&&e.closedCmux.length===0&&e.openedCmux.length===0&&e.ideFoldersAdded===0&&e.ideFoldersRemoved===0&&a.info("\u2139\uFE0F Nothing to reload")},an=w({name:"worktrees-reload",description:"Close all open cmux workspaces for the current release worktrees, then reopen the full set \u2014 the single window-restore command. Every configured editor (Cursor and/or Zed) is reconciled + relaunched (no per-window close). Disruptive: closes live cmux windows first. Safe to run from any branch. Use to refresh stale windows or to restore everything after a cold start (editor + cmux closed).",inputSchema:{},outputSchema:{closedCmux:$e.array($e.string()).describe("Titles of cmux workspaces a close was attempted for (best-effort)"),openedCmux:$e.array($e.string()).describe("Titles of cmux workspaces reopened during this run"),ideProviders:$e.array($e.string()).describe("Configured IDE providers that were reloaded (cursor | zed); empty if none configured"),ideFoldersAdded:$e.number().describe("Total worktree folders added across all configured editor workspaces"),ideFoldersRemoved:$e.number().describe("Total dangling worktree folders removed across all configured editor workspaces")},handler:ti});import op from"@inquirer/checkbox";import np from"@inquirer/confirm";import sp from"node:process";import{z as zr}from"zod";var oi=async e=>{let{confirmedCommand:r,all:t,versions:o}=e;m.start("worktrees-remove"),await D({operation:"remove worktrees",requiredBranch:"dev"});try{let n=await F("release");if(n.length===0)return a.info("\u2139\uFE0F No active worktrees to remove"),m.print(),{content:g(JSON.stringify({removedWorktrees:[],count:0},null,2)),structuredContent:{removedWorktrees:[],count:0}};let s=await k(),i=`${s}${G}`,l=[];if(t)l=n;else if(o)l=o.split(",").map(b=>ce(Z(b.trim())));else{m.setInteractive();let[b,v]=await Promise.all([P(),T()]),S=new Map(v.map(_=>[_.branch,E(_.title)]));l=await op({required:!0,message:"\u{1F33F} Select release branches",choices:A({branches:n,descriptions:b,types:S})})}let c=l.length===n.length;c?m.addOption("--all",!0):m.addOption("--versions",Be(l));let p=r?!0:await np({message:"Are you sure you want to proceed with these worktree changes?"});r||m.setInteractive(),p||(a.info("Operation cancelled. Exiting..."),sp.exit(0)),r||m.addOption("--yes",!0);let d=await J(),u=await Mr({branches:l,worktreeDir:i,repoName:d,pruneFolder:c});await Kr({projectRoot:s,worktreeDir:i,currentWorktrees:n,removedWorktrees:u,allowEditorRelaunch:!r}),ip(u),m.print();let h={removedWorktrees:u,count:u.length};return{content:g(JSON.stringify(h,null,2)),structuredContent:h}}catch(n){throw a.error({error:n},"\u274C Error managing worktrees"),new f(n,{operation:"remove worktrees",remediation:"check 'git worktree list' for the path; uncommitted changes block removal"})}},ip=e=>{if(e.length>0){a.info("\u274C Removed worktrees:");for(let r of e)a.info(r);a.info("")}else a.info("\u2139\uFE0F No unused worktrees to remove")},cn=w({name:"worktrees-remove",description:'Remove local git worktrees for release branches. When everything is removed, also runs "git worktree prune" to clear stale metadata; the worktrees directory and its release/feature subfolders are left in place. When invoked via MCP, pass either "versions" (comma-separated) or all=true \u2014 the branch picker is unreachable without a TTY, and the CLI confirmation is auto-skipped for MCP calls, so the caller is responsible for gating.',inputSchema:{all:zr.boolean().optional().describe('Remove every existing worktree. Either "all" or "versions" must be provided for MCP calls (the interactive picker is unavailable without a TTY). Ignored if "versions" is provided.'),versions:zr.string().optional().describe('Comma-separated release versions or names to target (e.g. "1.2.5, 1.2.6" or "checkout-redesign, 1.2.5"). Either "versions" or all=true must be provided for MCP calls. Overrides "all" when set.')},outputSchema:{removedWorktrees:zr.array(zr.string()).describe("List of removed git worktree branches"),count:zr.number().describe("Number of git worktrees removed")},handler:oi});import ap from"@inquirer/confirm";import cp from"node:process";import{z as ln}from"zod";import{$ as lp}from"zx";var ni=async e=>{let{confirmedCommand:r}=e;m.start("worktrees-sync"),await D({operation:"sync worktrees",requiredBranch:"dev"});try{let t=await F("release"),o=await k(),n=`${o}${G}`,s=await pt(),i=r?!0:await ap({message:"Are you sure you want to proceed with these worktree changes?"});r||m.setInteractive(),i||(a.info("Operation cancelled. Exiting..."),cp.exit(0)),r||m.addOption("--yes",!0);let{branchesToRemove:l}=pp({releasePRsList:s,currentWorktrees:t}),c=await J(),p=await dp({branches:l,worktreeDir:n,repoName:c});await Kr({projectRoot:o,worktreeDir:n,currentWorktrees:t,removedWorktrees:p,allowEditorRelaunch:!1}),mp(p),m.print();let d={removedWorktrees:p,count:p.length};return{content:g(JSON.stringify(d,null,2)),structuredContent:d}}catch(t){throw a.error({error:t},"\u274C Error managing worktrees"),new f(t,{operation:"sync worktrees with remote",remediation:"ensure 'gh auth status' is ok and you can reach origin"})}},pp=e=>{let{releasePRsList:r,currentWorktrees:t}=e;return{branchesToRemove:t.filter(s=>Ae(s)).filter(s=>!r.includes(s))}},dp=async e=>{let{branches:r,worktreeDir:t,repoName:o}=e,n=[];for(let s of r)try{let i=`${t}/${s}`,l=re({repoName:o,branch:s});await Je(l),await lp`git worktree remove ${i}`,n.push(s)}catch(i){let l=new f(i,{operation:`remove stale worktree for ${s}`,remediation:"inspect the worktree dir manually; rerun with the branch checked out elsewhere"});a.error({error:i,branch:s,msg:l.message})}return n},mp=e=>{if(e.length>0){a.info("\u274C Removed worktrees:");for(let r of e)a.info(r);a.info("")}else a.info("\u2139\uFE0F No unused worktrees to remove")},pn=w({name:"worktrees-sync",description:"Remove worktrees whose release PR is no longer open (stale cleanup). Only removes \u2014 never creates; use worktrees-add to create worktrees for new releases. The CLI confirmation is auto-skipped for MCP calls, so the caller is responsible for gating.",inputSchema:{},outputSchema:{removedWorktrees:ln.array(ln.string()).describe("List of removed worktree branches"),count:ln.number().describe("Number of worktrees removed during sync")},handler:ni});var dn=[{cliName:"merge-dev",menuGroup:"release",mcpTool:go,mcpExposed:!0},{cliName:"release-list",menuGroup:"release",mcpTool:Ro,mcpExposed:!0},{cliName:"release-create",menuGroup:"release",mcpTool:_o,mcpExposed:!0},{cliName:"release-desc-edit",menuGroup:"release",mcpTool:Oo,mcpExposed:!0},{cliName:"release-deploy-all",menuGroup:"release",mcpTool:vo,mcpExposed:!0},{cliName:"release-deploy-selected",menuGroup:"release",mcpTool:ko,mcpExposed:!0},{cliName:"release-deliver",menuGroup:"release",mcpTool:ho,mcpExposed:!1},{cliName:"worktrees-add",menuGroup:"worktrees",mcpTool:nn,mcpExposed:!0},{cliName:"worktrees-list",menuGroup:"worktrees",mcpTool:sn,mcpExposed:!0},{cliName:"worktrees-reload",menuGroup:"worktrees",mcpTool:an,mcpExposed:!0},{cliName:"worktrees-remove",menuGroup:"worktrees",mcpTool:cn,mcpExposed:!1},{cliName:"worktrees-sync",menuGroup:"worktrees",mcpTool:pn,mcpExposed:!0},{cliName:"audit",menuGroup:"environment",mcpTool:Bt,mcpExposed:!0},{cliName:"vendor",menuGroup:"environment",mcpTool:null,mcpExposed:!1},{cliName:"vendor-config",menuGroup:"environment",mcpTool:null,mcpExposed:!1},{cliName:"doctor",menuGroup:"environment",mcpTool:Qt,mcpExposed:!1},{cliName:"init",menuGroup:"environment",mcpTool:null,mcpExposed:!1},{cliName:"version",menuGroup:"environment",mcpTool:qo,mcpExposed:!0},{cliName:"config",menuGroup:"environment",mcpTool:null,mcpExposed:!1},{cliName:"env-status",menuGroup:"environment",mcpTool:lo,mcpExposed:!0},{cliName:"env-list",menuGroup:"environment",mcpTool:co,mcpExposed:!0},{cliName:"env-load",menuGroup:"environment",mcpTool:no,mcpExposed:!0},{cliName:"env-clear",menuGroup:"environment",mcpTool:io,mcpExposed:!0},{cliName:"env-autoload",menuGroup:null,mcpTool:null,mcpExposed:!1},{cliName:"vendor-check",menuGroup:null,mcpTool:Bo,mcpExposed:!0},{cliName:"vendor-diff",menuGroup:null,mcpTool:Go,mcpExposed:!0},{cliName:"vendor-manifest",menuGroup:null,mcpTool:zo,mcpExposed:!1},{cliName:"vendor-sync",menuGroup:null,mcpTool:Uo,mcpExposed:!1}],up=()=>dn.flatMap(e=>e.mcpExposed&&e.mcpTool?[e.mcpTool]:[]),fp=e=>dn.flatMap(r=>r.menuGroup===e?[r.cliName]:[]);export{k as a,fn as b,vp as c,a as d,Tn as e,W as f,x as g,ye as h,pe as i,R as j,qt as k,Dn as l,Xe as m,_m as n,Zn as o,Oe as p,to as q,Tr as r,Fe as s,De as t,Re as u,Me as v,Le as w,rs as x,ts as y,ns as z,ss as A,is as B,ds as C,ws as D,ys as E,Rs as F,bs as G,Vc as H,Ps as I,As as J,js as K,Ks as L,Gs as M,qs as N,Hs as O,Rt as P,ei as Q,ri as R,ti as S,oi as T,ni as U,up as V,fp as W};
166
- //# sourceMappingURL=chunk-PWOX6B3T.js.map
166
+ //# sourceMappingURL=chunk-WSQZ4MOQ.js.map