infra-kit 0.1.125 → 0.1.126
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}`,wr=({content:e,body:r,startMarker:t,endMarker:o,placement:n="replace-in-place"})=>{let s=Pn(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 a=(i?ve(e,t,o)??e:e).replace(/\n+$/,"");return a.length>0?`${a}
|
|
8
8
|
${s}
|
|
9
9
|
`:`${s}
|
|
10
|
-
`};import O from"node:fs";import kr from"node:path";import Gt from"node:fs/promises";import Fi from"node:os";import vr from"node:path";import{z as y}from"zod";var In="infra-kit.json",et=".infra-kit",ji="infra-kit.json",Di="projects",Mi=y.object({provider:y.literal("doppler"),config:y.object({name:y.string().min(1)})}),Li=y.discriminatedUnion("provider",[Mi]),Wi=y.object({workspaceConfigPath:y.string().min(1)}),Vi=y.object({provider:y.literal("cursor"),config:Wi}),Bi=y.object({}),Ji=y.object({provider:y.literal("zed"),config:Bi}),Sn=y.discriminatedUnion("provider",[Vi,Ji]),Ki=y.union([Sn,y.array(Sn).min(1)]),Gi=y.object({provider:y.literal("jira"),config:y.object({baseUrl:y.string().url(),projectId:y.number().int().positive()})}),zi=y.discriminatedUnion("provider",[Gi]),Ui=["two-columns","three-pane"],qi=y.object({layout:y.enum(Ui).optional()}),Hi=y.object({openInGithubDesktop:y.boolean().optional(),openInCmux:y.boolean().optional(),cmux:qi.optional()}),Zi=y.object({trigger:y.enum(["shell-startup","cli-invocation"]),config:y.string().min(1)}).strict(),An=y.object({environments:y.array(y.string().min(1)).min(1),envManagement:Li,ide:Ki.optional(),taskManager:zi.optional(),worktrees:Hi.optional(),envAutoLoad:Zi.optional()}),rt=An.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)}}),yr=An.partial(),K=e=>{let r=e.ide;return r?Array.isArray(r)?r:[r]:[]},Xi="two-columns",zt=e=>e.worktrees?.cmux?.layout??Xi,Ze=null,W=async()=>{let e=await k(),r=vr.basename(e),t=vr.join(Fi.homedir(),et);return{main:vr.join(e,In),userGlobal:vr.join(t,ji),userProject:vr.join(t,Di,r,In),projectName:r}},x=async()=>{let e=await W(),r;try{r=await Gt.stat(e.main)}catch{Ze=null;let a=e.main.replace(/\.json$/,".yml");throw await Kt(a)?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([Kt(e.userGlobal),Kt(e.userProject)]),n={main:Number(r.mtimeMs),userGlobal:t?Number(t.mtimeMs):null,userProject:o?Number(o.mtimeMs):null};if(Ze&&Qi(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 a of s){let p=await ea(a);p!==null&&(i={...i,...p})}let l=rt.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},Kt=async e=>{try{return await Gt.stat(e)}catch{return null}},Yi=async e=>{try{return await Gt.readFile(e,"utf-8")}catch{return null}},Qi=(e,r)=>{let t=Object.keys(e);return t.length!==Object.keys(r).length?!1:t.every(o=>e[o]===r[o])},ea=async e=>{let r=await Yi(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=yr.safeParse(t);if(!o.success)throw new Error(`Invalid ${e.label} at ${e.path}: ${y.prettifyError(o.error)}`);return o.data};var tt={name:"infra-kit",type:"module",version:"0.1.
|
|
10
|
+
`};import O from"node:fs";import kr from"node:path";import Gt from"node:fs/promises";import Fi from"node:os";import vr from"node:path";import{z as y}from"zod";var In="infra-kit.json",et=".infra-kit",ji="infra-kit.json",Di="projects",Mi=y.object({provider:y.literal("doppler"),config:y.object({name:y.string().min(1)})}),Li=y.discriminatedUnion("provider",[Mi]),Wi=y.object({workspaceConfigPath:y.string().min(1)}),Vi=y.object({provider:y.literal("cursor"),config:Wi}),Bi=y.object({}),Ji=y.object({provider:y.literal("zed"),config:Bi}),Sn=y.discriminatedUnion("provider",[Vi,Ji]),Ki=y.union([Sn,y.array(Sn).min(1)]),Gi=y.object({provider:y.literal("jira"),config:y.object({baseUrl:y.string().url(),projectId:y.number().int().positive()})}),zi=y.discriminatedUnion("provider",[Gi]),Ui=["two-columns","three-pane"],qi=y.object({layout:y.enum(Ui).optional()}),Hi=y.object({openInGithubDesktop:y.boolean().optional(),openInCmux:y.boolean().optional(),cmux:qi.optional()}),Zi=y.object({trigger:y.enum(["shell-startup","cli-invocation"]),config:y.string().min(1)}).strict(),An=y.object({environments:y.array(y.string().min(1)).min(1),envManagement:Li,ide:Ki.optional(),taskManager:zi.optional(),worktrees:Hi.optional(),envAutoLoad:Zi.optional()}),rt=An.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)}}),yr=An.partial(),K=e=>{let r=e.ide;return r?Array.isArray(r)?r:[r]:[]},Xi="two-columns",zt=e=>e.worktrees?.cmux?.layout??Xi,Ze=null,W=async()=>{let e=await k(),r=vr.basename(e),t=vr.join(Fi.homedir(),et);return{main:vr.join(e,In),userGlobal:vr.join(t,ji),userProject:vr.join(t,Di,r,In),projectName:r}},x=async()=>{let e=await W(),r;try{r=await Gt.stat(e.main)}catch{Ze=null;let a=e.main.replace(/\.json$/,".yml");throw await Kt(a)?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([Kt(e.userGlobal),Kt(e.userProject)]),n={main:Number(r.mtimeMs),userGlobal:t?Number(t.mtimeMs):null,userProject:o?Number(o.mtimeMs):null};if(Ze&&Qi(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 a of s){let p=await ea(a);p!==null&&(i={...i,...p})}let l=rt.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},Kt=async e=>{try{return await Gt.stat(e)}catch{return null}},Yi=async e=>{try{return await Gt.readFile(e,"utf-8")}catch{return null}},Qi=(e,r)=>{let t=Object.keys(e);return t.length!==Object.keys(r).length?!1:t.every(o=>e[o]===r[o])},ea=async e=>{let r=await Yi(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=yr.safeParse(t);if(!o.success)throw new Error(`Invalid ${e.label} at ${e.path}: ${y.prettifyError(o.error)}`);return o.data};var tt={name:"infra-kit",type:"module",version:"0.1.126",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 Rr="<!-- infra-kit:begin -->",br="<!-- infra-kit:end -->",ta="<!-- infra-kit:version ",oa="<!-- infra-kit:import:begin -->",na="<!-- infra-kit:import:end -->",sa="AGENTS.md",ia="CLAUDE.md",aa=e=>`${ta}${e} -->`,ca=e=>[aa(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
|
`),_n=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}`)},On=(e,r)=>{_n(e);let t=O.existsSync(e);return(t?O.readFileSync(e,"utf-8"):null)===r?"unchanged":(t&&Nn(e),O.mkdirSync(kr.dirname(e),{recursive:!0}),O.writeFileSync(e,r,"utf-8"),t?"updated":"created")},la=(e,r)=>O.existsSync(e)?O.readFileSync(e,"utf-8"):r,pa=(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}`)},da=e=>{if(!O.existsSync(e))return"unchanged";_n(e);let r=O.readFileSync(e,"utf-8"),t=ve(r,Rr,br);return t===null?"unchanged":t.trim()===""?(Nn(e),O.rmSync(e),"removed"):On(e,t)},Fn=async()=>{let e;try{e=(await W()).main}catch{return c.info("Skipped agent-instruction files \u2014 not inside an infra-kit repo"),{skipped:!0,root:null,written:[]}}if(!O.existsSync(e))return c.info("Skipped agent-instruction files \u2014 no infra-kit.json at the repo root"),{skipped:!0,root:null,written:[]};let r=kr.dirname(e),t=tt.version,o=ca(t),n=kr.join(r,sa),s=kr.join(r,ia),i=la(s,"");i=ve(i,oa,na)??i,i=wr({content:i,body:o,startMarker:Rr,endMarker:br,placement:"replace-in-place"});let l=[{path:s,action:On(s,i)},{path:n,action:da(n)}];pa(s,Rr,br);for(let a of l)a.action==="unchanged"&&a.path!==s||c.info(` ${a.action.padEnd(9)} ${kr.relative(r,a.path)}`);return c.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 ha}from"node:url";import wa from"yaml";import{z as Ln}from"zod";import ma from"node:fs/promises";import ua from"node:os";var pe=async e=>{try{return await ma.access(e),!0}catch{return!1}},R=e=>{let r=ua.homedir();return e.startsWith(r)?`~${e.slice(r.length)}`:e};import fa from"node:fs/promises";import Ut from"node:os";import qt from"node:path";import{z as ga}from"zod";import{z as ot}from"zod";var jn="vendor.json",nt=ot.object({workspaceDir:ot.string().min(1),targets:ot.array(ot.string()).min(1)}).strict();var Ht=()=>qt.join(Ut.homedir(),et,jn),Dn=e=>{if(e==="~")return Ut.homedir();if(e.startsWith("~/"))return qt.join(Ut.homedir(),e.slice(2));if(qt.isAbsolute(e))return e;throw new Error(`workspaceDir must be absolute or ~-prefixed, got: ${e}`)},Xe=async()=>{let e=Ht(),r;try{r=await fa.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
|
{
|
|
@@ -161,4 +161,4 @@ See \`.sync-manifest.json\` for the source commit and per-file checksums.
|
|
|
161
161
|
${i.join(`
|
|
162
162
|
`)}
|
|
163
163
|
`);let l={worktrees:n,count:n.length};return{content:g(JSON.stringify(l,null,2)),structuredContent:l}},an=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:dr.array(dr.object({version:dr.string().describe("Release version"),type:dr.enum(["regular","hotfix"]).describe("Release type"),description:dr.string().nullable().describe("Jira version description")})).describe("List of all worktrees with details"),count:dr.number().describe("Number of worktrees")},handler:ni});import{z as $e}from"zod";var si=async()=>{m.start("worktrees-reload");try{let e=await k(),r=`${e}${G}`,t=await F("release"),o=await J(),n=await sp({currentBranches:t,repoName:o}),[s,{opened:i}]=await Promise.all([tn({projectRoot:e,worktreeDir:r,currentBranches:t}),ip({worktreeDir:r,currentBranches:t,repoName:o})]),l={closedCmux:n,openedCmux:i,ideProviders:s.filter(a=>a.ran).map(a=>a.provider),ideFoldersAdded:s.reduce((a,p)=>a+p.added,0),ideFoldersRemoved:s.reduce((a,p)=>a+p.removed,0)};return ap(l,{ideRan:s.some(a=>a.ran)}),m.print(),{content:g(JSON.stringify(l,null,2)),structuredContent:{...l}}}catch(e){throw c.error({error:e},"\u274C Error reloading worktrees"),new f(e,{operation:"reload worktrees",remediation:"run 'worktrees-list' to confirm the branches exist"})}},sp=async e=>{let{currentBranches:r,repoName:t}=e;if(r.length===0)return[];let o=await Dr(),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},ip=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 Lr({cwd:`${r}/${s}`,title:i}),n.push(i)}catch(l){c.warn({error:l,title:i},`\u26A0\uFE0F Failed to reopen cmux workspace for ${s}`)}}return{opened:n}},ap=(e,r)=>{if(e.closedCmux.length>0&&c.info(`\u{1F9F9} Closed ${e.closedCmux.length} cmux workspace(s)`),r.ideRan){let t=e.ideProviders.map(o=>on(o)).join(", ");e.ideFoldersAdded>0&&c.info(`\u2705 Added ${e.ideFoldersAdded} folder(s) to ${t} workspace(s)`),e.ideFoldersRemoved>0&&c.info(`\u{1F9F9} Removed ${e.ideFoldersRemoved} dangling folder(s) from ${t} workspace(s)`)}if(e.openedCmux.length>0){c.info("\u2705 Reopened cmux workspaces:");for(let t of e.openedCmux)c.info(t)}!r.ideRan&&e.closedCmux.length===0&&e.openedCmux.length===0&&e.ideFoldersAdded===0&&e.ideFoldersRemoved===0&&c.info("\u2139\uFE0F Nothing to reload")},cn=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:si});import cp from"@inquirer/checkbox";import lp from"@inquirer/confirm";import pp from"node:process";import{z as qr}from"zod";var ii=async e=>{let{confirmedCommand:r,all:t,versions:o}=e;m.start("worktrees-remove"),await j({operation:"remove worktrees",requiredBranch:"dev"});try{let n=await F("release");if(n.length===0)return c.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([I(),T()]),S=new Map(v.map(N=>[N.branch,E(N.title)]));l=await cp({required:!0,message:"\u{1F33F} Select release branches",choices:A({branches:n,descriptions:b,types:S})})}let a=l.length===n.length;a?m.addOption("--all",!0):m.addOption("--versions",Be(l));let p=r?!0:await lp({message:"Are you sure you want to proceed with these worktree changes?"});r||m.setInteractive(),p||(c.info("Operation cancelled. Exiting..."),pp.exit(0)),r||m.addOption("--yes",!0);let d=await J(),u=await Wr({branches:l,worktreeDir:i,repoName:d,pruneFolder:a});await zr({projectRoot:s,worktreeDir:i,currentWorktrees:n,removedWorktrees:u,allowEditorRelaunch:!r}),dp(u),m.print();let h={removedWorktrees:u,count:u.length};return{content:g(JSON.stringify(h,null,2)),structuredContent:h}}catch(n){throw pr(n)?n:(c.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"}))}},dp=e=>{if(e.length>0){c.info("\u274C Removed worktrees:");for(let r of e)c.info(r);c.info("")}else c.info("\u2139\uFE0F No unused worktrees to remove")},ln=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:qr.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:qr.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:qr.array(qr.string()).describe("List of removed git worktree branches"),count:qr.number().describe("Number of git worktrees removed")},handler:ii});import mp from"@inquirer/confirm";import up from"node:process";import{z as pn}from"zod";import{$ as fp}from"zx";var ai=async e=>{let{confirmedCommand:r}=e;m.start("worktrees-sync"),await j({operation:"sync worktrees",requiredBranch:"dev"});try{let t=await F("release"),o=await k(),n=`${o}${G}`,s=await dt(),i=r?!0:await mp({message:"Are you sure you want to proceed with these worktree changes?"});r||m.setInteractive(),i||(c.info("Operation cancelled. Exiting..."),up.exit(0)),r||m.addOption("--yes",!0);let{branchesToRemove:l}=gp({releasePRsList:s,currentWorktrees:t}),a=await J(),p=await hp({branches:l,worktreeDir:n,repoName:a});await zr({projectRoot:o,worktreeDir:n,currentWorktrees:t,removedWorktrees:p,allowEditorRelaunch:!1}),wp(p),m.print();let d={removedWorktrees:p,count:p.length};return{content:g(JSON.stringify(d,null,2)),structuredContent:d}}catch(t){throw pr(t)?t:(c.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"}))}},gp=e=>{let{releasePRsList:r,currentWorktrees:t}=e;return{branchesToRemove:t.filter(s=>Ae(s)).filter(s=>!r.includes(s))}},hp=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 fp`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"});c.error({error:i,branch:s,msg:l.message})}return n},wp=e=>{if(e.length>0){c.info("\u274C Removed worktrees:");for(let r of e)c.info(r);c.info("")}else c.info("\u2139\uFE0F No unused worktrees to remove")},dn=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:pn.array(pn.string()).describe("List of removed worktree branches"),count:pn.number().describe("Number of worktrees removed during sync")},handler:ai});var mn=[{cliName:"merge-dev",menuGroup:"release",mcpTool:ho,mcpExposed:!0},{cliName:"release-list",menuGroup:"release",mcpTool:bo,mcpExposed:!0},{cliName:"release-create",menuGroup:"release",mcpTool:Oo,mcpExposed:!0},{cliName:"release-desc-edit",menuGroup:"release",mcpTool:Fo,mcpExposed:!0},{cliName:"release-deploy-all",menuGroup:"release",mcpTool:yo,mcpExposed:!0},{cliName:"release-deploy-selected",menuGroup:"release",mcpTool:Ro,mcpExposed:!0},{cliName:"release-deliver",menuGroup:"release",mcpTool:wo,mcpExposed:!1},{cliName:"worktrees-add",menuGroup:"worktrees",mcpTool:sn,mcpExposed:!0},{cliName:"worktrees-list",menuGroup:"worktrees",mcpTool:an,mcpExposed:!0},{cliName:"worktrees-reload",menuGroup:"worktrees",mcpTool:cn,mcpExposed:!0},{cliName:"worktrees-remove",menuGroup:"worktrees",mcpTool:ln,mcpExposed:!1},{cliName:"worktrees-sync",menuGroup:"worktrees",mcpTool:dn,mcpExposed:!0},{cliName:"audit",menuGroup:"environment",mcpTool:Jt,mcpExposed:!0},{cliName:"vendor",menuGroup:"environment",mcpTool:null,mcpExposed:!1},{cliName:"vendor-config",menuGroup:"environment",mcpTool:null,mcpExposed:!1},{cliName:"doctor",menuGroup:"environment",mcpTool:eo,mcpExposed:!1},{cliName:"init",menuGroup:"environment",mcpTool:null,mcpExposed:!1},{cliName:"version",menuGroup:"environment",mcpTool:Ho,mcpExposed:!0},{cliName:"config",menuGroup:"environment",mcpTool:null,mcpExposed:!1},{cliName:"env-status",menuGroup:"environment",mcpTool:po,mcpExposed:!0},{cliName:"env-list",menuGroup:"environment",mcpTool:lo,mcpExposed:!0},{cliName:"env-load",menuGroup:"environment",mcpTool:so,mcpExposed:!0},{cliName:"env-clear",menuGroup:"environment",mcpTool:ao,mcpExposed:!0},{cliName:"env-autoload",menuGroup:null,mcpTool:null,mcpExposed:!1},{cliName:"vendor-check",menuGroup:null,mcpTool:Jo,mcpExposed:!0},{cliName:"vendor-diff",menuGroup:null,mcpTool:zo,mcpExposed:!0},{cliName:"vendor-manifest",menuGroup:null,mcpTool:Uo,mcpExposed:!1},{cliName:"vendor-sync",menuGroup:null,mcpTool:qo,mcpExposed:!1}],vp=()=>mn.flatMap(e=>e.mcpExposed&&e.mcpTool?[e.mcpTool]:[]),yp=e=>mn.flatMap(r=>r.menuGroup===e?[r.cliName]:[]);export{k as a,gn as b,xp as c,c as d,$n as e,W as f,x as g,ye as h,pe as i,R as j,Ht as k,Dn as l,Xe as m,Mm as n,Xn as o,Oe as p,oo as q,Pr as r,Fe as s,je as t,Re as u,Me as v,Le as w,os as x,ns as y,is as z,as as A,cs as B,us as C,ys as D,Rs as E,xs as F,Cs as G,Gc as H,As as I,Ns as J,Ls as K,zs as L,Us as M,Zs as N,Xs as O,bt as P,pr as Q,oi as R,ni as S,si as T,ii as U,ai as V,vp as W,yp as X};
|
|
164
|
-
//# sourceMappingURL=chunk-
|
|
164
|
+
//# sourceMappingURL=chunk-EY5LDHXC.js.map
|