infra-kit 0.1.115 → 0.1.120

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.
@@ -1 +1,3 @@
1
1
  $ pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src
2
+ Dependency "react" could not be resolved for catalog "default"
3
+ Dependency "@types/react" could not be resolved for catalog "default"
@@ -3,32 +3,6 @@
3
3
   RUN  v4.1.9 /Users/arthur/projects/infra-kit/apps/infra-kit/cli
4
4
 
5
5
  Sourcemap for "/Users/arthur/Library/pnpm/store/v11/links/@/ink-testing-library/4.0.0/990ef278cd16926ca8f94e3d73dd86da3c7d702a314086dabc7217c3d9b139d2/node_modules/ink-testing-library/build/index.js" points to missing source files
6
- INFO:  created CLAUDE.md
7
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
8
- INFO:  updated CLAUDE.md
9
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
10
- INFO:  created CLAUDE.md
11
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
12
- INFO:  unchanged CLAUDE.md
13
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
14
- INFO: Skipped agent-instruction files — no infra-kit.json at the repo root
15
- INFO:  updated CLAUDE.md
16
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
17
- INFO:  updated CLAUDE.md
18
- INFO:  removed AGENTS.md
19
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
20
- INFO:  updated CLAUDE.md
21
- INFO:  updated AGENTS.md
22
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
23
- INFO:  created CLAUDE.md
24
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
25
- INFO:  updated CLAUDE.md
26
- INFO:  removed AGENTS.md
27
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
28
- INFO:  unchanged CLAUDE.md
29
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
30
- INFO:  created CLAUDE.md
31
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
32
6
  INFO: ✓ Migrated ~/infra-kit.yml → ~/infra-kit.json
33
7
  INFO: ⚠ Skipped ~/infra-kit.yml — ~/infra-kit.json already exists (remove the stale .yml manually)
34
8
  INFO: ✓ Migrated ~/infra-kit.yml → ~/infra-kit.json
@@ -41,52 +15,81 @@ Sourcemap for "/Users/arthur/Library/pnpm/store/v11/links/@/ink-testing-library/
41
15
  
42
16
  INFO: ✓ Migrated ~/infra-kit.yml → ~/infra-kit.json
43
17
  INFO: ✓ Migrated ~/.infra-kit/config.yml → ~/.infra-kit/infra-kit.json
18
+ INFO: ✓ Migrated ~/.infra-kit/projects/infra-kit-init-migrate-test-dC9SjH/infra-kit.yml → ~/.infra-kit/projects/infra-kit-init-migrate-test-dC9SjH/infra-kit.json
19
+ INFO: ✓ Normalized ide config in ~/infra-kit.json (removed legacy "mode")
20
+ INFO: ✓ Normalized ide config in ~/infra-kit.json (removed legacy "mode")
21
+ INFO: ✓ Normalized ide config in ~/.infra-kit/infra-kit.json (removed legacy "mode")
22
+ INFO: ✓ Normalized ide config in ~/.infra-kit/projects/infra-kit-init-migrate-test-vlGJyA/infra-kit.json (removed legacy "mode")
23
+ INFO: ⚠ Skipped normalizing ~/infra-kit.json — Expected property name or '}' in JSON at position 2 (line 1 column 3)
24
+ INFO: ✓ Renamed ~/.infra-kit/config.json → ~/.infra-kit/infra-kit.json
25
+ INFO: ✓ Renamed ~/.infra-kit/config.example.jsonc → ~/.infra-kit/infra-kit.example.jsonc
26
+ INFO: ⚠ Skipped ~/.infra-kit/config.json — ~/.infra-kit/infra-kit.json already exists (remove the stale file manually)
27
+ INFO: ✓ Renamed ~/.infra-kit/config.example.jsonc → ~/.infra-kit/infra-kit.example.jsonc
44
28
  INFO: Factory config: ~/.infra-kit/vendor.json [ ]
45
29
  INFO: 
46
30
  Not found — run `infra-kit vendor-config --init` to scaffold it.
47
31
  INFO: Factory config: ~/.infra-kit/vendor.json [✓]
48
- INFO: workspaceDir: /tmp/vendor-config-home-1leOPd/projects (resolved: /tmp/vendor-config-home-1leOPd/projects) [✓ exists]
32
+ INFO: ✓ Migrated ~/.infra-kit/config.yml → ~/.infra-kit/infra-kit.json
33
+ INFO: workspaceDir: /tmp/vendor-config-home-L0d1PR/projects (resolved: /tmp/vendor-config-home-L0d1PR/projects) [✓ exists]
49
34
  INFO: Targets:
50
35
  INFO:  [✓] repo-a ~/projects/repo-a
51
36
  INFO: Factory config: ~/.infra-kit/vendor.json [✓]
52
- INFO: workspaceDir: /tmp/vendor-config-home-ggiYiu/projects (resolved: /tmp/vendor-config-home-ggiYiu/projects) [✓ exists]
37
+ INFO: workspaceDir: /tmp/vendor-config-home-CVd2s7/projects (resolved: /tmp/vendor-config-home-CVd2s7/projects) [✓ exists]
53
38
  INFO: Targets:
54
39
  INFO:  [ ] missing-repo ~/projects/missing-repo (not found — clone or remove)
40
+ INFO: ✓ Migrated ~/.infra-kit/config.yml → ~/.infra-kit/infra-kit.json
41
+ INFO: ⚠ Skipped ~/.infra-kit/config.json — ~/.infra-kit/infra-kit.json already exists (remove the stale file manually)
55
42
  INFO: ✓ Created ~/.infra-kit/vendor.json
56
43
  INFO:  Edit `workspaceDir` (placeholder: ~/projects) to point at where your repos live.
57
44
  INFO:  Add at least one repo name to `targets` before running vendor sync/manifest/diff.
58
- INFO: ✓ Migrated ~/.infra-kit/projects/infra-kit-init-migrate-test-QB1hTw/infra-kit.yml → ~/.infra-kit/projects/infra-kit-init-migrate-test-QB1hTw/infra-kit.json
59
45
  INFO: ✓ Created ~/.infra-kit/vendor.json
60
46
  INFO:  Seeded 2 target(s) from the source vendor.config.ts.
61
47
  INFO:  Edit `workspaceDir` (placeholder: ~/projects) to point at where your repos live.
62
- INFO: ✓ Normalized ide config in ~/infra-kit.json (removed legacy "mode")
63
48
  INFO: Factory config already exists at ~/.infra-kit/vendor.json — leaving it untouched.
64
- INFO: ✓ Normalized ide config in ~/infra-kit.json (removed legacy "mode")
65
- INFO: ✓ Normalized ide config in ~/.infra-kit/infra-kit.json (removed legacy "mode")
66
- INFO: ✓ Normalized ide config in ~/.infra-kit/projects/infra-kit-init-migrate-test-kdR8XZ/infra-kit.json (removed legacy "mode")
67
- INFO: ⚠ Skipped normalizing ~/infra-kit.json — Expected property name or '}' in JSON at position 2 (line 1 column 3)
68
- INFO: ✓ Renamed ~/.infra-kit/config.json → ~/.infra-kit/infra-kit.json
69
- INFO: ✓ Renamed ~/.infra-kit/config.example.jsonc → ~/.infra-kit/infra-kit.example.jsonc
70
- INFO: ⚠ Skipped ~/.infra-kit/config.json — ~/.infra-kit/infra-kit.json already exists (remove the stale file manually)
71
- INFO: ✓ Renamed ~/.infra-kit/config.example.jsonc → ~/.infra-kit/infra-kit.example.jsonc
72
- INFO: ✓ Migrated ~/.infra-kit/config.yml → ~/.infra-kit/infra-kit.json
73
- INFO: ✓ Migrated ~/.infra-kit/config.yml → ~/.infra-kit/infra-kit.json
74
- INFO: ⚠ Skipped ~/.infra-kit/config.json — ~/.infra-kit/infra-kit.json already exists (remove the stale file manually)
75
49
  INFO: ❌ target-repo → vendor/configs (1 change(s)):
76
50
  INFO:  >f.st..... configs/a.js
77
51
  INFO: ✅ target-repo: copied 1/1 items + manifest
52
+ INFO: 🎉 No drift detected.
53
+ INFO: ⚠️ target-repo: target does not exist — skipped
78
54
  INFO: 
79
55
  @x/ok — PASS
80
56
  INFO:  [PASS] infra-kit.config.ts: present and valid
81
57
  INFO: 
82
58
  ✅ All valid (1 checked)
83
- INFO: 🎉 No drift detected.
84
59
  INFO: 
85
60
  @x/no-config — FAIL
86
- INFO:  [FAIL] infra-kit.config.ts: infra-kit.config.ts not found at /tmp/audit-cmd-LG37cx/infra-kit.config.ts
61
+ INFO:  [FAIL] infra-kit.config.ts: infra-kit.config.ts not found at /tmp/audit-cmd-GDNU3r/infra-kit.config.ts
87
62
  INFO: 
88
63
  ❌ Audit failed (1 checked)
89
- INFO: ⚠️ target-repo: target does not exist — skipped
64
+ INFO:  created CLAUDE.md
65
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
66
+ INFO:  updated CLAUDE.md
67
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
68
+ INFO:  created CLAUDE.md
69
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
70
+ INFO:  unchanged CLAUDE.md
71
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
72
+ INFO: Skipped agent-instruction files — no infra-kit.json at the repo root
73
+ INFO:  updated CLAUDE.md
74
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
75
+ INFO:  updated CLAUDE.md
76
+ INFO:  removed AGENTS.md
77
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
78
+ INFO:  updated CLAUDE.md
79
+ INFO:  updated AGENTS.md
80
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
81
+ INFO:  created CLAUDE.md
82
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
83
+ INFO:  updated CLAUDE.md
84
+ INFO:  removed AGENTS.md
85
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
86
+ INFO:  unchanged CLAUDE.md
87
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
88
+ INFO:  created CLAUDE.md
89
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
90
+ INFO: Wrote user-global config to /tmp/seed-user-global-test-OnnbjR/.infra-kit/infra-kit.json (see the sibling .example.jsonc files for reference)
91
+ INFO: Wrote user-global config to /tmp/seed-user-global-test-0SuzJu/.infra-kit/infra-kit.json (see the sibling .example.jsonc files for reference)
92
+ INFO: User-global config already present at /tmp/seed-user-global-test-zWpSCj/.infra-kit/infra-kit.json (refreshed reference examples)
90
93
  INFO: ✅ vendor/ matches manifest (1 files).
91
94
  ERROR: ❌ vendor/ has drifted from vendor/.sync-manifest.json.
92
95
  ERROR:  These files are mirrored from the source repo — edit them upstream, not here.
@@ -109,19 +112,16 @@ Removed (in manifest, now missing) (1):
109
112
  INFO:  b.js
110
113
  ERROR: ❌ vendor/.sync-manifest.json has a newer schemaVersion (2) than this CLI supports. Upgrade infra-kit.
111
114
  INFO:  created CLAUDE.md
112
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
115
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
113
116
  INFO:  created CLAUDE.md
114
- INFO: Agent-instruction files synced (infra-kit 0.1.114)
115
- INFO: Wrote user-global config to /tmp/seed-user-global-test-bhoQdQ/.infra-kit/infra-kit.json (see the sibling .example.jsonc files for reference)
116
- INFO: Wrote user-global config to /tmp/seed-user-global-test-nxcGED/.infra-kit/infra-kit.json (see the sibling .example.jsonc files for reference)
117
- INFO: User-global config already present at /tmp/seed-user-global-test-a2bUF5/.infra-kit/infra-kit.json (refreshed reference examples)
117
+ INFO: Agent-instruction files synced (infra-kit 0.1.115)
118
118
  WARN: ⚠️ Failed to reopen cmux workspace for release/v1.48.0
119
119
  title: "hulyo-monorepo 1.48.0"
120
120
  error: {}
121
121
 
122
122
   Test Files  56 passed (56)
123
123
   Tests  529 passed (529)
124
-  Start at  23:25:55
125
-  Duration  2.63s (transform 6.74s, setup 1.42s, import 15.02s, tests 2.47s, environment 15ms)
124
+  Start at  15:58:49
125
+  Duration  1.84s (transform 4.57s, setup 754ms, import 9.46s, tests 2.13s, environment 21ms)
126
126
 
127
127
  [?25h
@@ -1,4 +1,4 @@
1
- import{b as Pe,c as Tt,d as $t,e as dr,f as fn}from"./chunk-RTSP2FCA.js";import hn from"node:process";import It from"pino";import si from"pino-pretty";var gn="/tmp/mcp-infra-kit.log",vp=()=>{let e=hn.argv.includes("--debug")?"debug":"info",r=It({level:e},It.destination({dest:gn}));return r.info(`Logger initialized with level: ${e}. Logging to: ${gn}`),r},ii=()=>{let e=hn.argv.includes("--debug")?"debug":"info",r=["time","pid","hostname"];return e==="debug"&&r.push("level"),It({level:e},si({destination:2,ignore:r.join(","),colorize:!0}))},a=ii();import fr from"node:path";import Ti from"node:process";import{z as L}from"zod";import bn from"node:path";import{$ as X}from"zx";var ai=/^v?(\d+)\.(\d+)\.(\d+)$/,ci=/^(\d+)\.(\d+)\.(\d+)$/,li=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,qr="release/",Pt="release/v",wn="refs/heads/",pi="next";var vn=new Set(["dev","main","next","hotfix","regular","release"]),ae=class extends Error{constructor(r){super(r),this.name="InvalidReleaseNameError"}},Ue=class extends Error{constructor(r){super(r),this.name="InvalidReleaseRefError"}},kn=e=>e.startsWith(wn)?e.slice(wn.length):e,Rn=(e,r,t)=>({kind:"version",semver:{major:e,minor:r,patch:t},raw:`${e}.${r}.${t}`}),Se=e=>{if(e.length===0)throw new ae('Release name is empty. Provide a kebab-case name like "checkout-redesign".');if(e.length>50)throw new ae(`Release name "${e}" is ${e.length} characters; the maximum is 50.`);if(!li.test(e))throw new ae(`Release name "${e}" is not kebab-case. Use lowercase letters, digits, and single hyphens, e.g. "checkout-redesign".`);if(vn.has(e))throw new ae(`Release name "${e}" is reserved. Reserved names: ${[...vn].join(", ")}.`)},C=e=>{let r=kn(e.trim());if(!r.startsWith(qr))return null;if(r.startsWith(Pt)){let o=r.slice(Pt.length),n=ci.exec(o);if(n)return Rn(Number(n[1]),Number(n[2]),Number(n[3]))}let t=r.slice(qr.length);try{Se(t)}catch{return null}return{kind:"name",name:t,raw:t}},Z=e=>{let r=e.trim();if(kn(r).startsWith(qr)){let n=C(r);if(!n)throw new Ue(`"${e}" looks like a release branch but is not a valid release/v<semver> or release/<name> ref.`);return n}let o=ai.exec(r);if(o)return Rn(Number(o[1]),Number(o[2]),Number(o[3]));if(r.toLowerCase()===pi)throw new Ue('The "next" token must be resolved to a concrete version (via computeNextVersion) before parsing a release ref.');try{Se(r)}catch(n){let s=n instanceof Error?n.message:String(n);throw new Ue(`Cannot parse "${e}" as a release ref: ${s}`)}return{kind:"name",name:r,raw:r}},ce=e=>e.kind==="version"?`${Pt}${e.raw}`:`${qr}${e.name}`,St=(e,r)=>{let t=r==="hotfix"?"Hotfix":"Release";return e.kind==="version"?`${t} v${e.raw}`:`${t} ${e.name}`},Hr=e=>e.kind==="version"?`Release v${e.raw} (RC)`:`Release ${e.name} (RC)`,M=e=>e.kind==="version"?`v${e.raw}`:e.name,I=e=>e.raw,Ae=e=>e==null?!1:C(e)!==null,yn=e=>{if(e===void 0)return null;let r=e instanceof Date?e.getTime():new Date(e).getTime();return Number.isNaN(r)?null:r},At=(e,r,t)=>{if(e.kind==="version"&&r.kind==="version")return e.semver.major!==r.semver.major?e.semver.major-r.semver.major:e.semver.minor!==r.semver.minor?e.semver.minor-r.semver.minor:e.semver.patch-r.semver.patch;if(e.kind==="version")return-1;if(r.kind==="version")return 1;let o=yn(t?.a),n=yn(t?.b);return o!==null&&n!==null&&o!==n?o-n:e.name<r.name?-1:e.name>r.name?1:0};var F=async e=>{let t=(await X`git worktree list`).stdout.split(`
1
+ import{b as Pe,c as Tt,d as $t,e as dr,f as fn}from"./chunk-WA4BQRDC.js";import hn from"node:process";import It from"pino";import si from"pino-pretty";var gn="/tmp/mcp-infra-kit.log",vp=()=>{let e=hn.argv.includes("--debug")?"debug":"info",r=It({level:e},It.destination({dest:gn}));return r.info(`Logger initialized with level: ${e}. Logging to: ${gn}`),r},ii=()=>{let e=hn.argv.includes("--debug")?"debug":"info",r=["time","pid","hostname"];return e==="debug"&&r.push("level"),It({level:e},si({destination:2,ignore:r.join(","),colorize:!0}))},a=ii();import fr from"node:path";import Ti from"node:process";import{z as L}from"zod";import bn from"node:path";import{$ as X}from"zx";var ai=/^v?(\d+)\.(\d+)\.(\d+)$/,ci=/^(\d+)\.(\d+)\.(\d+)$/,li=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,qr="release/",Pt="release/v",wn="refs/heads/",pi="next";var vn=new Set(["dev","main","next","hotfix","regular","release"]),ae=class extends Error{constructor(r){super(r),this.name="InvalidReleaseNameError"}},Ue=class extends Error{constructor(r){super(r),this.name="InvalidReleaseRefError"}},kn=e=>e.startsWith(wn)?e.slice(wn.length):e,Rn=(e,r,t)=>({kind:"version",semver:{major:e,minor:r,patch:t},raw:`${e}.${r}.${t}`}),Se=e=>{if(e.length===0)throw new ae('Release name is empty. Provide a kebab-case name like "checkout-redesign".');if(e.length>50)throw new ae(`Release name "${e}" is ${e.length} characters; the maximum is 50.`);if(!li.test(e))throw new ae(`Release name "${e}" is not kebab-case. Use lowercase letters, digits, and single hyphens, e.g. "checkout-redesign".`);if(vn.has(e))throw new ae(`Release name "${e}" is reserved. Reserved names: ${[...vn].join(", ")}.`)},C=e=>{let r=kn(e.trim());if(!r.startsWith(qr))return null;if(r.startsWith(Pt)){let o=r.slice(Pt.length),n=ci.exec(o);if(n)return Rn(Number(n[1]),Number(n[2]),Number(n[3]))}let t=r.slice(qr.length);try{Se(t)}catch{return null}return{kind:"name",name:t,raw:t}},Z=e=>{let r=e.trim();if(kn(r).startsWith(qr)){let n=C(r);if(!n)throw new Ue(`"${e}" looks like a release branch but is not a valid release/v<semver> or release/<name> ref.`);return n}let o=ai.exec(r);if(o)return Rn(Number(o[1]),Number(o[2]),Number(o[3]));if(r.toLowerCase()===pi)throw new Ue('The "next" token must be resolved to a concrete version (via computeNextVersion) before parsing a release ref.');try{Se(r)}catch(n){let s=n instanceof Error?n.message:String(n);throw new Ue(`Cannot parse "${e}" as a release ref: ${s}`)}return{kind:"name",name:r,raw:r}},ce=e=>e.kind==="version"?`${Pt}${e.raw}`:`${qr}${e.name}`,St=(e,r)=>{let t=r==="hotfix"?"Hotfix":"Release";return e.kind==="version"?`${t} v${e.raw}`:`${t} ${e.name}`},Hr=e=>e.kind==="version"?`Release v${e.raw} (RC)`:`Release ${e.name} (RC)`,M=e=>e.kind==="version"?`v${e.raw}`:e.name,I=e=>e.raw,Ae=e=>e==null?!1:C(e)!==null,yn=e=>{if(e===void 0)return null;let r=e instanceof Date?e.getTime():new Date(e).getTime();return Number.isNaN(r)?null:r},At=(e,r,t)=>{if(e.kind==="version"&&r.kind==="version")return e.semver.major!==r.semver.major?e.semver.major-r.semver.major:e.semver.minor!==r.semver.minor?e.semver.minor-r.semver.minor:e.semver.patch-r.semver.patch;if(e.kind==="version")return-1;if(r.kind==="version")return 1;let o=yn(t?.a),n=yn(t?.b);return o!==null&&n!==null&&o!==n?o-n:e.name<r.name?-1:e.name>r.name?1:0};var F=async e=>{let t=(await X`git worktree list`).stdout.split(`
2
2
  `).filter(Boolean),o={release:di,feature:mi};return t.map(o[e]).filter(n=>n!==null)},xn=e=>{let r=e.trimEnd();if(!r.endsWith("]"))return null;let t=r.lastIndexOf("[");if(t===-1)return null;let o=r.slice(t+1,-1);return o.length>0?o:null},di=e=>{let r=xn(e);return Ae(r)?r:null},mi=e=>{let r=xn(e);return r?.startsWith("feature/")?r:null},k=async()=>(await X`git rev-parse --show-toplevel`).stdout.trim(),Zr=async()=>(await X`git rev-parse --abbrev-ref HEAD`).stdout.trim(),Nt=async()=>(await X`git status --porcelain`).stdout.trim().length===0,_t=async()=>{let e=await k(),[r,t]=await Promise.all([X({cwd:e})`git rev-parse --absolute-git-dir`,X({cwd:e})`git rev-parse --git-common-dir`]),o=r.stdout.trim(),n=bn.resolve(e,t.stdout.trim());return o!==n},J=async()=>{let e=await k();return bn.basename(e)},Ot=async e=>{(await X`git branch --list ${e}`).stdout.trim().length!==0&&await Zr()!==e&&await X`git branch -D ${e}`},Ft=async e=>{(await X`git ls-remote --heads origin ${e}`).stdout.trim().length!==0&&await X`git push origin --delete ${e}`};import{z as he}from"zod";var Dt=he.strictObject({requiredScripts:he.array(he.string().min(1)).optional(),requiredFiles:he.array(he.string().min(1)).optional(),turbo:he.strictObject({requiredTasks:he.array(he.string().min(1)).optional()}).optional()});import ui from"node:fs/promises";var le=async e=>{try{return await ui.access(e),!0}catch{return!1}};import Ei from"node:path";import Cn from"node:fs/promises";import En from"node:path";import{pathToFileURL as fi}from"node:url";import{z as gi}from"zod";var we="infra-kit.config.ts",jt=async e=>{try{let r=await Cn.readFile(En.join(e,"package.json"),"utf-8");return JSON.parse(r)}catch{return{}}},mr=async(e,r=Pe)=>{let t=En.join(e,we);if(!await le(t))throw new Error(`${we} not found at ${t}`);let o=await Cn.stat(t),i=(await import(`${fi(t).href}?mtime=${Number(o.mtimeMs)}`)).default;if(i===void 0)throw new Error(`${we} at ${t} has no default export`);let l=typeof i=="function"?await i():i,c=Dt.safeParse(l);if(!c.success)throw new Error(`Invalid ${we} at ${t}: ${gi.prettifyError(c.error)}`);return $t(c.data,r)};import Tn from"node:fs/promises";import Xr from"node:path";import hi from"yaml";var wi="pnpm-workspace.yaml",vi=async e=>(await Tn.readdir(e,{withFileTypes:!0}).catch(()=>[])).filter(t=>t.isDirectory()).map(t=>Xr.join(e,t.name)),yi=async(e,r)=>{let t=[];for(let o of e){if(r==="*"){t.push(...await vi(o));continue}let n=Xr.join(o,r);await le(n)&&t.push(n)}return t},ki=async(e,r)=>{let t=[e];for(let o of r.split("/"))t=await yi(t,o);return t},ur=async e=>{let r=await Tn.readFile(Xr.join(e,wi),"utf-8"),o=((hi.parse(r)??{}).packages??[]).filter(s=>!s.startsWith("!")&&!s.startsWith("vendor")),n=new Set;for(let s of o){let i=await ki(e,s);for(let l of i)await le(Xr.join(l,"package.json"))&&n.add(l)}return[...n].sort()};var Mt=async(e,r=Pe)=>{try{let t=await mr(e,r);return{check:{name:we,status:"pass",message:"present and valid"},rules:t}}catch(t){return{check:{name:we,status:"fail",message:t.message},rules:null}}};import Ri from"node:fs/promises";import bi from"node:path";var Lt=async(e,r)=>Promise.all(r.map(async t=>{let o=await Ri.stat(bi.join(e,t)).catch(()=>null);return o?o.isFile()?{name:`file:${t}`,status:"pass",message:"exists"}:{name:`file:${t}`,status:"fail",message:`not a file: ${t} (found a directory)`}:{name:`file:${t}`,status:"fail",message:`missing file: ${t}`}}));var Wt=(e,r)=>r.map(t=>{let o=e[t];return typeof o!="string"?{name:`script:${t}`,status:"fail",message:`missing "${t}" in package.json scripts`}:o.trim().length===0?{name:`script:${t}`,status:"fail",message:`"${t}" is empty in package.json scripts`}:{name:`script:${t}`,status:"pass",message:"defined"}});import xi from"node:fs/promises";import Ci from"node:path";var qe="turbo.json",Vt=async(e,r)=>{if(r.length===0)return[];let t;try{let n=await xi.readFile(Ci.join(e,qe),"utf-8");t=JSON.parse(n)}catch(n){return[{name:qe,status:"fail",message:`cannot read/parse ${qe}: ${n.message}`}]}let o=t.tasks;return o===null||typeof o!="object"?[{name:qe,status:"fail",message:`no "tasks" object defined in ${qe}`}]:r.map(n=>{let s=n in o||`//#${n}`in o;return{name:`turbo:${n}`,status:s?"pass":"fail",message:s?"defined":`missing turbo task "${n}" in ${qe}`}})};var Bt=async(e,r=Pe)=>{let t=await jt(e),o=t.name??Ei.basename(e),{check:n,rules:s}=await Mt(e,r),i=[n];s&&(i.push(...Wt(t.scripts??{},s.requiredScripts)),i.push(...await Lt(e,s.requiredFiles)),i.push(...await Vt(e,s.turboTasks)));let l=i.every(c=>c.status==="pass");return{packageDir:e,packageName:o,checks:i,passed:l}};var g=e=>[{type:"text",text:e}],w=e=>e;var $i=async e=>{let r=fr.resolve(e);for(;r!==fr.dirname(r);){if(await le(fr.join(r,"package.json")))return r;r=fr.dirname(r)}if(await le(fr.join(r,"package.json")))return r;throw new Error(`No package.json found in or above ${e}`)},Ii=async e=>e.root?[{dir:await k(),baseline:Tt}]:e.all?(await ur(await k())).map(t=>({dir:t})):[{dir:await $i(e.cwd??Ti.cwd())}],Pi=e=>{let r=e.passed?"PASS":"FAIL";a.info(`
3
3
  ${e.packageName} \u2014 ${r}`);for(let t of e.checks){let o=t.status==="pass"?"[PASS]":"[FAIL]";a.info(` ${o} ${t.name}: ${t.message}`)}},$n=async(e={})=>{let r=await Ii(e),t=[];for(let s of r)t.push(await Bt(s.dir,s.baseline));for(let s of t)Pi(s);let o=t.every(s=>s.passed);a.info(`
4
4
  ${o?"\u2705 All valid":"\u274C Audit failed"} (${t.length} checked)`);let n={allPassed:o,packages:t.map(s=>({name:s.packageName,passed:s.passed,checks:s.checks}))};return{content:g(JSON.stringify(n,null,2)),structuredContent:n}},Si={all:L.boolean().optional().describe("Audit every non-vendor workspace package"),root:L.boolean().optional().describe("Audit the monorepo root (turbo pipeline + root commands)")},Ai={allPassed:L.boolean().describe("Whether every audited package passed all checks"),packages:L.array(L.object({name:L.string(),passed:L.boolean(),checks:L.array(L.object({name:L.string(),status:L.enum(["pass","fail"]),message:L.string()}))})).describe("Per-package check results")},Jt=w({name:"audit",description:"Audit packages against infra-kit.config.ts rules (config present and valid, required scripts, required files, and turbo tasks for the root). Defaults to the current package; all=true audits every non-vendor workspace package; root=true audits the monorepo root.",inputSchema:Si,outputSchema:Ai,handler:e=>$n({all:e.all,root:e.root})});import ke from"node:fs";import Kn from"node:os";import Rr from"node:path";import ha from"node:process";var He=(e,r,t)=>{let o=e.indexOf(r),n=e.indexOf(t);return o!==-1&&n!==-1&&n>=o},ve=(e,r,t)=>{let o=e.indexOf(r),n=e.indexOf(t);if(o===-1||n===-1||n<o)return null;let s=e.slice(0,o).replace(/\n+$/,""),i=e.slice(n+t.length).replace(/^\n+/,"");return s+(i?`
@@ -7,7 +7,7 @@ ${r}
7
7
  ${t}`,gr=({content:e,body:r,startMarker:t,endMarker:o,placement:n="replace-in-place"})=>{let s=In(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 Gt from"node:fs/promises";import Ni from"node:os";import hr from"node:path";import{z as y}from"zod";var Pn="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}),Sn=y.discriminatedUnion("provider",[Mi,Wi]),Vi=y.union([Sn,y.array(Sn).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(),An=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=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)}}),wr=An.partial(),K=e=>{let r=e.ide;return r?Array.isArray(r)?r:[r]:[]},qi="two-columns",zt=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,Pn),userGlobal:hr.join(t,_i),userProject:hr.join(t,Oi,r,Pn),projectName:r}},x=async()=>{let e=await W(),r;try{r=await Gt.stat(e.main)}catch{Ze=null;let c=e.main.replace(/\.json$/,".yml");throw await Kt(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([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&&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},Kt=async e=>{try{return await Gt.stat(e)}catch{return null}},Hi=async e=>{try{return await Gt.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.115",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 Gt from"node:fs/promises";import Ni from"node:os";import hr from"node:path";import{z as y}from"zod";var Pn="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}),Sn=y.discriminatedUnion("provider",[Mi,Wi]),Vi=y.union([Sn,y.array(Sn).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(),An=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=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)}}),wr=An.partial(),K=e=>{let r=e.ide;return r?Array.isArray(r)?r:[r]:[]},qi="two-columns",zt=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,Pn),userGlobal:hr.join(t,_i),userProject:hr.join(t,Oi,r,Pn),projectName:r}},x=async()=>{let e=await W(),r;try{r=await Gt.stat(e.main)}catch{Ze=null;let c=e.main.replace(/\.json$/,".yml");throw await Kt(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([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&&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},Kt=async e=>{try{return await Gt.stat(e)}catch{return null}},Hi=async e=>{try{return await Gt.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.120",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(`
11
11
  `),Nn=e=>{if(O.existsSync(e)&&O.lstatSync(e).isSymbolicLink())throw new Error(`Refusing to write ${e} because the destination is a symlink`)},_n=e=>{let r=new Date().toISOString().replace(/[:.]/g,"-");O.copyFileSync(e,`${e}.backup.${r}`)},On=(e,r)=>{Nn(e);let t=O.existsSync(e);return(t?O.readFileSync(e,"utf-8"):null)===r?"unchanged":(t&&_n(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";Nn(e);let r=O.readFileSync(e,"utf-8"),t=ve(r,yr,kr);return t===null?"unchanged":t.trim()===""?(_n(e),O.rmSync(e),"removed"):On(e,t)},Fn=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:On(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 Ln}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 Ut from"node:os";import qt from"node:path";import{z as ma}from"zod";import{z as rt}from"zod";var Dn="vendor.json",tt=rt.object({workspaceDir:rt.string().min(1),targets:rt.array(rt.string()).min(1)}).strict();var Ht=()=>qt.join(Ut.homedir(),Yr,Dn),jn=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 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}},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: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([tn({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=>on(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")},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: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")},ln=w({name:"worktrees-remove",description:'Remove local git worktrees for release branches. When everything is removed, also runs "git worktree prune" and deletes the worktrees directory. 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 pn}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")},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:ni});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}],up=()=>mn.flatMap(e=>e.mcpExposed&&e.mcpTool?[e.mcpTool]:[]),fp=e=>mn.flatMap(r=>r.menuGroup===e?[r.cliName]:[]);export{k as a,gn as b,vp as c,a as d,$n as e,W as f,x as g,ye as h,pe as i,R as j,Ht as k,jn as l,Xe as m,_m as n,Xn as o,Oe as p,oo as q,Tr as r,Fe as s,De as t,Re as u,Me as v,Le as w,ts as x,os as y,ss as z,is as A,as as B,ms 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,bt 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-VPBZR2PY.js.map
166
+ //# sourceMappingURL=chunk-RAAKYDVP.js.map