infra-kit 0.1.123 → 0.1.125

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.
Files changed (46) hide show
  1. package/.eslintcache +1 -0
  2. package/.omc/state/agent-replay-2ccbd177-0d5d-4d4a-ab94-a22464786221.jsonl +1 -0
  3. package/.omc/state/agent-replay-eb44055b-c2fa-4e66-b491-a1d9b44f51c7.jsonl +1 -0
  4. package/.omc/state/idle-notif-cooldown.json +1 -1
  5. package/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/pre-tool-advisory-throttle.json +18 -0
  6. package/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/subagent-tracking-state.json +17 -0
  7. package/.omc/state/sessions/6be1264f-8069-4412-8119-86118ed1943e/pre-tool-advisory-throttle.json +5 -5
  8. package/.omc/state/sessions/eb44055b-c2fa-4e66-b491-a1d9b44f51c7/last-tool-error-state.json +7 -0
  9. package/.omc/state/sessions/eb44055b-c2fa-4e66-b491-a1d9b44f51c7/pre-tool-advisory-throttle.json +18 -0
  10. package/.omc/state/sessions/eb44055b-c2fa-4e66-b491-a1d9b44f51c7/subagent-tracking-state.json +17 -0
  11. package/.turbo/turbo-build.log +6 -6
  12. package/.turbo/turbo-eslint-check.log +1 -1
  13. package/.turbo/turbo-prettier-check.log +1 -1
  14. package/.turbo/turbo-test.log +128 -127
  15. package/.turbo/turbo-ts-check.log +1 -1
  16. package/dist/chunk-VI7TEWVJ.js +164 -0
  17. package/dist/chunk-VI7TEWVJ.js.map +7 -0
  18. package/dist/cli.js +6 -6
  19. package/dist/cli.js.map +3 -3
  20. package/dist/mcp.js +1 -1
  21. package/package.json +1 -1
  22. package/src/.omc/state/agent-replay-2ccbd177-0d5d-4d4a-ab94-a22464786221.jsonl +2 -0
  23. package/src/.omc/state/idle-notif-cooldown.json +1 -1
  24. package/src/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/last-tool-error-state.json +7 -0
  25. package/src/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/mission-state.json +53 -0
  26. package/src/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/pre-tool-advisory-throttle.json +22 -0
  27. package/src/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/subagent-tracking-state.json +17 -0
  28. package/src/commands/env-clear/env-clear.ts +4 -1
  29. package/src/commands/env-load/__tests__/env-load.test.ts +99 -66
  30. package/src/commands/env-load/env-load.ts +87 -35
  31. package/src/commands/init/__tests__/shell-body.test.ts +4 -4
  32. package/src/commands/init/init.ts +23 -24
  33. package/src/commands/worktrees-add/worktrees-add.ts +6 -0
  34. package/src/commands/worktrees-remove/worktrees-remove.ts +6 -0
  35. package/src/commands/worktrees-sync/worktrees-sync.ts +6 -0
  36. package/src/entry/cli.ts +60 -45
  37. package/src/lib/constants/__tests__/constants.test.ts +22 -0
  38. package/src/lib/constants/constants.ts +40 -4
  39. package/src/lib/constants/index.ts +1 -0
  40. package/src/lib/env-autoload/__tests__/env-autoload.test.ts +15 -1
  41. package/src/lib/env-autoload/env-autoload.ts +54 -6
  42. package/src/lib/errors/__tests__/is-prompt-cancellation.test.ts +48 -0
  43. package/src/lib/errors/is-prompt-cancellation.ts +38 -0
  44. package/tsconfig.tsbuildinfo +1 -1
  45. package/dist/chunk-YMXDO43V.js +0 -166
  46. package/dist/chunk-YMXDO43V.js.map +0 -7
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
- import{A as de,B as me,C as le,D as pe,E as fe,F as ue,G as ge,H as ve,I as ye,J as he,K as we,L as ke,M as Ce,N as Ae,O as xe,P as _,Q as Ee,R as Se,S as Re,T as Le,U as be,W as j,a as U,d as a,e as B,f as T,g as z,h as Y,i as h,j as u,k as D,l as q,m as Q,n as I,o as X,p as Z,q as ee,r as oe,s as te,t as re,u as ne,v as ie,w as C,x as ae,y as se,z as ce}from"./chunk-YMXDO43V.js";import{e as $}from"./chunk-WA4BQRDC.js";import vo,{Separator as x}from"@inquirer/select";import{Command as yo}from"commander";import w from"node:process";import N from"node:fs/promises";import Xe from"node:path";import je from"node:process";import{$ as Ze}from"zx";var O=async()=>{let e=await T(),o=await Promise.all([{label:"project (committed)",path:e.main},{label:"user global",path:e.userGlobal},{label:"user project",path:e.userProject}].map(async r=>({...r,exists:await h(r.path)})));a.info(`Project name: ${e.projectName}
1
+ import{A as me,B as le,C as pe,D as fe,E as ue,F as ge,G as ve,H as ye,I as he,J as we,K as ke,L as Ce,M as Ae,N as xe,O as Ee,P as M,Q as O,R as Se,S as Le,T as Re,U as be,V as je,X as P,a as Y,d as a,e as q,f as I,g as Q,h as X,i as w,j as u,k as D,l as Z,m as ee,n as _,o as oe,p as j,q as te,r as re,s as ne,t as ie,u as $,v as ae,w as k,x as se,y as ce,z as de}from"./chunk-VI7TEWVJ.js";import{e as N}from"./chunk-WA4BQRDC.js";import ko,{Separator as x}from"@inquirer/select";import{Command as Co}from"commander";import h from"node:process";import F from"node:fs/promises";import eo from"node:path";import Pe from"node:process";import{$ as oo}from"zx";var V=async()=>{let e=await I(),o=await Promise.all([{label:"project (committed)",path:e.main},{label:"user global",path:e.userGlobal},{label:"user project",path:e.userProject}].map(async r=>({...r,exists:await w(r.path)})));a.info(`Project name: ${e.projectName}
2
2
  `),a.info(`Config merge chain (later overrides earlier):
3
- `);for(let r of o){let c=r.exists?" [\u2713]":" [ ]";a.info(`${c} ${r.label.padEnd(22)} ${u(r.path)}`)}let t={projectName:e.projectName,layers:o.map(r=>({label:r.label,path:r.path,exists:r.exists}))};return{content:[{type:"text",text:JSON.stringify(t,null,2)}],structuredContent:t}},M=async()=>{let e=await T(),o=je.env.EDITOR||je.env.VISUAL||"vi";if(await N.mkdir(Xe.dirname(e.userProject),{recursive:!0}),!await h(e.userProject)){let r=eo(e.userProject);await N.writeFile(e.userProject,`{}
4
- `,"utf-8"),await N.writeFile(r,oo(e.projectName),"utf-8"),a.info(`Created ${u(e.userProject)} \u2014 see ${u(r)} for the annotated reference.`)}a.info(`Opening ${u(e.userProject)} in ${o}`),await Ze({stdio:"inherit"})`${o} ${e.userProject}`,Y();let t={path:e.userProject,editor:o};return{content:[{type:"text",text:JSON.stringify(t,null,2)}],structuredContent:t}},eo=e=>e.replace(/\.json$/,".example.jsonc"),oo=e=>`// infra-kit user override for ${e} \u2014 ~/.infra-kit/projects/${e}/infra-kit.json
3
+ `);for(let r of o){let d=r.exists?" [\u2713]":" [ ]";a.info(`${d} ${r.label.padEnd(22)} ${u(r.path)}`)}let t={projectName:e.projectName,layers:o.map(r=>({label:r.label,path:r.path,exists:r.exists}))};return{content:[{type:"text",text:JSON.stringify(t,null,2)}],structuredContent:t}},G=async()=>{let e=await I(),o=Pe.env.EDITOR||Pe.env.VISUAL||"vi";if(await F.mkdir(eo.dirname(e.userProject),{recursive:!0}),!await w(e.userProject)){let r=to(e.userProject);await F.writeFile(e.userProject,`{}
4
+ `,"utf-8"),await F.writeFile(r,ro(e.projectName),"utf-8"),a.info(`Created ${u(e.userProject)} \u2014 see ${u(r)} for the annotated reference.`)}a.info(`Opening ${u(e.userProject)} in ${o}`),await oo({stdio:"inherit"})`${o} ${e.userProject}`,X();let t={path:e.userProject,editor:o};return{content:[{type:"text",text:JSON.stringify(t,null,2)}],structuredContent:t}},to=e=>e.replace(/\.json$/,".example.jsonc"),ro=e=>`// infra-kit user override for ${e} \u2014 ~/.infra-kit/projects/${e}/infra-kit.json
5
5
  //
6
6
  // Layer 3 (highest precedence) of the config merge chain. Shallow-merged on top
7
7
  // of <repo>/infra-kit.json and ~/.infra-kit/infra-kit.json \u2014 top-level keys
@@ -14,7 +14,7 @@ import{A as de,B as me,C as le,D as pe,E as fe,F as ue,G as ge,H as ve,I as ye,J
14
14
  // // Auto-load Doppler env here. trigger (pick one): shell-startup | cli-invocation; config: an environment name.
15
15
  // "envAutoLoad": { "trigger": "shell-startup", "config": "dev" }
16
16
  }
17
- `;import f from"node:fs";import A from"node:path";import E from"node:process";var to="autoload-warn.flag",F="autoload-fail.flag",ro=3e4,Pe=async(e=!0)=>{let o;try{o=await z()}catch{return null}let t=o.envAutoLoad;return t?o.environments.includes(t.config)?{trigger:t.trigger,config:t.config,project:o.envManagement.config.name}:(e&&De(`infra-kit: envAutoLoad.config "${t.config}" is not one of environments [${o.environments.join(", ")}] \u2014 env auto-load disabled.`),null):null},Te=e=>{let{trigger:o,expectedTrigger:t,targetConfig:r,targetProject:c,env:s}=e;return o!==t||!s.session||s.cleared||s.currentConfig&&!s.autoLoadedMarker||s.autoLoadedMarker&&s.currentConfig===r&&s.currentProject===c?"skip":"load"},S=async({expectedTrigger:e})=>{let o=e==="cli-invocation";try{let t=await Pe(o);if(!t||Te({trigger:t.trigger,expectedTrigger:e,targetConfig:t.config,targetProject:t.project,env:no()})==="skip"||io()||ao())return null;let c=await ae({config:t.config,autoLoaded:!0});return co(),c.filePath}catch(t){let r=t.message;return so(),o?De(`infra-kit: env auto-load failed \u2014 ${r} (will retry later)`):a.debug(`env auto-load skipped: ${r}`),null}},no=()=>({session:E.env[oe],cleared:E.env[ie],currentConfig:E.env[te],currentProject:E.env[re],autoLoadedMarker:E.env[ne]}),io=()=>{try{let e=C(),o=A.join(e,ee);if(!f.existsSync(o))return!1;let t=A.join(e,Z);return f.existsSync(t)?f.statSync(o).mtimeMs>=f.statSync(t).mtimeMs:!0}catch{return!1}},ao=()=>{try{let e=A.join(C(),F);return f.existsSync(e)?Date.now()-f.statSync(e).mtimeMs<ro:!1}catch{return!1}},so=()=>{try{let e=C();f.mkdirSync(e,{recursive:!0,mode:448}),f.writeFileSync(A.join(e,F),"",{mode:384})}catch{}},co=()=>{try{f.rmSync(A.join(C(),F),{force:!0})}catch{}},De=e=>{try{let o=C(),t=A.join(o,to);if(f.existsSync(t))return;f.mkdirSync(o,{recursive:!0,mode:448}),f.writeFileSync(t,"",{mode:384})}catch{}a.warn(e)};var V=async()=>{await S({expectedTrigger:"shell-startup"})};import G from"node:fs/promises";import J from"node:path";import Ie from"node:process";import{pathToFileURL as mo}from"node:url";var $e="~/projects",W=async(e={})=>{if(e.init){await po(e.cwd);return}await lo()},lo=async()=>{let e=D(),o=await h(e);if(a.info(`Factory config: ${u(e)} ${o?"[\u2713]":"[ ]"}`),!o){a.info("\nNot found \u2014 run `infra-kit vendor-config --init` to scaffold it."),Ie.exitCode=1;return}let{workspaceDir:t,targets:r}=await Q(),c=q(t),s=await h(c);a.info(`workspaceDir: ${t} (resolved: ${c}) ${s?"[\u2713 exists]":"[ ] not found"}`),a.info("Targets:");let l=s;for(let d of r){let g=J.join(c,d),p=await h(g);p||(l=!1);let v=p?"[\u2713]":"[ ]",y=p?"":" (not found \u2014 clone or remove)";a.info(` ${v} ${d} ${u(g)}${y}`)}l||(Ie.exitCode=1)},po=async e=>{let o=D();if(await h(o)){a.info(`Factory config already exists at ${u(o)} \u2014 leaving it untouched.`);return}let t=e??await U(),r=await fo(t);await G.mkdir(J.dirname(o),{recursive:!0}),await G.writeFile(o,uo(r),"utf-8"),a.info(`\u2713 Created ${u(o)}`),r.length>0&&a.info(` Seeded ${r.length} target(s) from the source ${$}.`),a.info(` Edit \`workspaceDir\` (placeholder: ${$e}) to point at where your repos live.`),r.length===0&&a.info(" Add at least one repo name to `targets` before running vendor sync/manifest/diff.")},fo=async e=>{try{let o=J.join(e,$),t=await G.stat(o),s=(await import(`${mo(o).href}?mtime=${Number(t.mtimeMs)}`)).default,l=typeof s=="function"?await s():s;if(l&&typeof l=="object"&&"targets"in l){let d=l.targets;if(Array.isArray(d)&&d.every(g=>typeof g=="string"))return d}}catch{}return[]},uo=e=>`${JSON.stringify({workspaceDir:$e,targets:e},null,2)}
18
- `;import go from"node:process";var R={enabled:!1},i=(e,o=t=>{go.stdout.write(t)})=>(R.enabled&&e&&e.structuredContent!=null&&o(`${JSON.stringify(e.structuredContent,null,2)}
19
- `),e),P=e=>{e.options.some(t=>t.long==="--json")||e.option("--json","Output the structured result as JSON on stdout (human logs stay on stderr)"),e.commands.forEach(P)};var K=(e,o=" ")=>{let t=e.reduce((r,[c])=>Math.max(r,c.length),0);return e.map(([r,c])=>`${r.padEnd(t)}${o}${c}`)};var n=new yo,ho=(e,o)=>[...o,e],H=e=>typeof e=="string"?e.split(",").filter(Boolean):void 0,_e=(e,o)=>{if(!(typeof e>"u")){if(e===!0)return"workspace";if(e===!1)return"none";if(typeof e=="string"&&_.includes(e))return e;throw new Error(`Invalid ${o} value "${String(e)}". Expected one of: ${_.join(", ")}.`)}},Ne=async e=>{try{e?await n.parseAsync(e):await n.parseAsync()}catch(o){let t=o instanceof Error?o.message:String(o);a.error(t),w.exit(1)}},Oe={value:!1},m=(e,o)=>e.hook("preAction",()=>{Oe.value||a.warn(`"${e.name()}" is a deprecated alias; use "${o}" instead.`)}),Me=e=>e.description("Merge dev branch into every release branch").option("-a, --all","Select all active release branches").option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await le({all:o.all,confirmedCommand:o.yes}))}),Fe=e=>e.description("List all release branches").action(async()=>{i(await ge())}),Ve=e=>e.description("Create one or more release branches (each entry can mix regular/hotfix and its own description)").option("-r, --release <spec>",'Release spec "<version|next|name>[:type[:description]]" (repeatable). The token is a semver ("1.2.5"), the literal "next", or a kebab-case name ("checkout-redesign"). Type is regular|hotfix (default regular). Examples: "1.2.5", "1.2.5:hotfix", "next:regular:Holiday backend", "checkout-redesign:regular:Q3 redesign".',ho,[]).option("-y, --yes","Skip confirmation prompt").action(async o=>{let r=o.release.map(ve),c=r.length>0?r:void 0;i(await ye({releases:c,confirmedCommand:o.yes}))}),Ge=e=>e.description("Edit a release's description in Jira and in the matching GitHub PR body").option("-v, --version <version>","Release version (e.g. 1.2.5) or release name (e.g. checkout-redesign)").option("-d, --description <description>",'New description (use "" to clear)').option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await he({version:o.version,description:o.description,confirmedCommand:o.yes}))}),Je=e=>e.description("Deploy any release branch to any environment").option("-v, --version <version>",'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deploy; "dev" deploys from the dev branch').option("-e, --env <env>","Specify the environment to deploy to, e.g. dev").option("--skip-terraform","Skip terraform deployment step").option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await fe({version:o.version,env:o.env,skipTerraform:o.skipTerraform,confirmedCommand:o.yes}))}),We=e=>e.description("Deploy selected services from release branch to any environment").option("-v, --version <version>",'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deploy; "dev" deploys from the dev branch').option("-e, --env <env>","Specify the environment to deploy to, e.g. dev").option("-s, --services <services...>","Specify services to deploy, e.g. client-be client-fe").option("--skip-terraform","Skip terraform deployment step").option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await ue({version:o.version,env:o.env,services:o.services,skipTerraform:o.skipTerraform,confirmedCommand:o.yes}))}),Ke=e=>e.description("Release a new version to production").option("-v, --version <version>","Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deliver").option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await pe({version:o.version,confirmedCommand:o.yes}))}),He=e=>e.description("Remove release worktrees whose PRs are no longer open").option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await be({confirmedCommand:o.yes}))}),Ue=e=>e.description("Add git worktrees for release branches").option("-y, --yes","Skip confirmation prompt").option("-a, --all","Select all active release branches").option("-v, --versions <versions>","Specify versions by comma, e.g. 1.2.5, 1.2.6").option("-i, --ide [mode]","Editor mode for created worktrees: workspace (default) | none").option("--no-ide","Skip the editor (alias for --ide none)").option("-c, --cursor [mode]","Deprecated alias for --ide").option("--no-cursor","Deprecated alias for --no-ide").option("-g, --github-desktop","Open created worktrees in GitHub Desktop").option("--no-github-desktop","Skip GitHub Desktop prompt").option("-m, --cmux","Open created worktrees in cmux (3-pane layout)").option("--no-cmux","Skip cmux prompt").action(async o=>{let t=_e(o.ide,"--ide")??_e(o.cursor,"--cursor");i(await Ee({confirmedCommand:o.yes,all:o.all,versions:o.versions,ide:t,githubDesktop:o.githubDesktop,cmux:o.cmux}))}),Be=e=>e.description("List all git worktrees with detailed information").action(async()=>{i(await Se())}),ze=e=>e.description("Remove git worktrees for release branches").option("-y, --yes","Skip confirmation prompt").option("-a, --all","Select all active release branches").option("-v, --versions <versions>","Specify versions by comma, e.g. 1.2.5, 1.2.6").action(async o=>{i(await Le({confirmedCommand:o.yes,all:o.all,versions:o.versions}))}),Ye=e=>e.description("Close all cmux/editor worktree windows, then reopen the current release worktrees (also cold-start restore)").action(async()=>{i(await Re())}),qe=e=>e.description("Show the machine-local factory config (~/.infra-kit/vendor.json) or scaffold it with --init").option("--init","Scaffold ~/.infra-kit/vendor.json (skips if it already exists)").action(async o=>{i(await W({init:o.init}))}),k=n.command("release").description("Release management commands");Me(k.command("merge-dev"));Fe(k.command("list"));Ve(k.command("create"));Ge(k.command("desc-edit"));Je(k.command("deploy-all"));We(k.command("deploy-selected"));Ke(k.command("deliver"));var L=n.command("worktrees").description("Git worktree management commands");Ue(L.command("add"));Be(L.command("list"));ze(L.command("remove"));He(L.command("sync"));Ye(L.command("reload"));m(Me(n.command("merge-dev")),"release merge-dev");m(Fe(n.command("release-list")),"release list");m(Ve(n.command("release-create")),"release create");m(Ge(n.command("release-desc-edit")),"release desc-edit");m(Je(n.command("release-deploy-all")),"release deploy-all");m(We(n.command("release-deploy-selected")),"release deploy-selected");m(Ke(n.command("release-deliver")),"release deliver");m(Ue(n.command("worktrees-add")),"worktrees add");m(Be(n.command("worktrees-list")),"worktrees list");m(ze(n.command("worktrees-remove")),"worktrees remove");m(He(n.command("worktrees-sync")),"worktrees sync");m(Ye(n.command("worktrees-reload")),"worktrees reload");var Qe=n.command("config").description("Manage infra-kit configuration files");Qe.command("path").description("Show the resolved config merge chain and file paths").action(async()=>{i(await O())});Qe.command("edit").description("Open the user-scope per-project override file in $EDITOR").action(async()=>{i(await M())});n.command("audit").description("Audit against infra-kit.config.ts rules (--all for every package, --root for the monorepo root)").option("-a, --all","Audit every non-vendor workspace package").option("-r, --root","Audit the monorepo root (turbo pipeline + root commands)").action(async e=>{let o=await B({all:e.all,root:e.root});i(o),o.structuredContent.allPassed||(w.exitCode=1)});var b=n.command("vendor").description("Verify and sync the mirrored vendor/ tree");b.command("check").description("Verify vendor/ matches vendor/.sync-manifest.json (self-contained; for any consumer repo)").action(async()=>{let e=await we();i(e),e.structuredContent.ok||(w.exitCode=1)});b.command("sync").description("Copy vendored files from the source repo into each target and regenerate manifests").option("-y, --yes","Skip confirmation prompt").option("-r, --repos <repos>","Restrict to comma-separated target repo names").action(async e=>{i(await Ae({confirmedCommand:e.yes,repos:H(e.repos)}))});b.command("manifest").description("Regenerate each target vendor/.sync-manifest.json + README from current content (no copy)").option("-r, --repos <repos>","Restrict to comma-separated target repo names").action(async e=>{i(await Ce({confirmedCommand:!0,repos:H(e.repos)}))});b.command("diff").description("Source-aware drift check (rsync dry-run) of each target vendored subtree vs the source").option("-r, --repos <repos>","Restrict to comma-separated target repo names").action(async e=>{let o=await ke({repos:H(e.repos)});i(o),o.structuredContent.ok||(w.exitCode=1)});qe(b.command("config"));m(qe(n.command("vendor-config")),"vendor config");n.command("doctor").description("Check installation and authentication status of gh and doppler CLIs").action(async()=>{i(await X())});n.command("version").description("Print the installed infra-kit CLI version").action(async()=>{i(await xe())});n.command("env-status").description("Show which env is loaded in this session (local introspection; no Doppler call)").action(async()=>{i(await me())});n.command("env-list").description("List available Doppler configs for the detected project").action(async()=>{i(await de())});n.command("init").description("Inject shell integration into .zshrc and sync repo agent-instruction files").action(async()=>{i(await I())});n.command("env-load").description("Load Doppler env vars for a config. Source the returned file path to apply.").option("-c, --config <config>","Environment config name to load (e.g. dev, arthur)").action(async e=>{i(await se({config:e.config}))});n.command("env-clear").description("Clear loaded env vars. Source the returned file path to apply.").action(async()=>{i(await ce())});n.command("env-autoload",{hidden:!0}).description("Internal: prime env for the shell-startup auto-load trigger").action(async()=>{await V()});n.commands.forEach(P);var wo=e=>e.startsWith("env-")||e==="init"||e==="doctor"||e==="version";n.hook("preAction",async(e,o)=>{R.enabled=!!o.optsWithGlobals().json,R.enabled&&(a.level="warn"),wo(o.name())||await S({expectedTrigger:"cli-invocation"})});if(w.argv.length<=2){let e=j("release"),o=j("worktrees"),t=j("environment"),r=new Map(n.commands.map(d=>[d.name(),d])),s=[{label:"Release Management",names:e},{label:"Worktrees",names:o},{label:"Environment",names:t}].flatMap(({label:d,names:g})=>g.filter(p=>r.has(p)).map(p=>({name:p,description:r.get(p).description(),group:d}))),l;if(w.stdout.isTTY&&w.stdin.isTTY){let{runCommandPalette:d}=await import("./boot-SGM5RVLJ.js");l=await d(s)}else{let d=K(s.map(v=>[v.name,v.description])),g=new Map;s.forEach((v,y)=>{g.set(v.name,d[y]??v.name)});let p=v=>v.filter(y=>r.has(y)).map(y=>({name:g.get(y)??y,value:y}));l=await vo({message:"Select a command to run",choices:[new x(" "),new x("\u2014 Release Management \u2014"),...p(e),new x(" "),new x("\u2014 Worktrees \u2014"),...p(o),new x(" "),new x("\u2014 Environment \u2014"),...p(t)]},{output:w.stderr})}l&&(Oe.value=!0,await Ne(["node","infra-kit",l]))}else await Ne();
17
+ `;import m from"node:fs";import C from"node:path";import E from"node:process";var no="autoload-warn-misconfig.flag",io="autoload-warn-fail.flag",W="autoload-fail.flag",ao=3e4,Ie=async(e=!0)=>{let o;try{o=await Q()}catch{return null}let t=o.envAutoLoad;return t?o.environments.includes(t.config)?{trigger:t.trigger,config:t.config,project:o.envManagement.config.name}:(e&&_e(`infra-kit: envAutoLoad.config "${t.config}" is not one of environments [${o.environments.join(", ")}] \u2014 env auto-load disabled.`,no),null):null},De=e=>{let{trigger:o,expectedTrigger:t,targetConfig:r,targetProject:d,env:s}=e;return o!==t||!s.session||s.cleared||s.currentConfig&&!s.autoLoadedMarker||s.autoLoadedMarker&&s.currentConfig===r&&s.currentProject===d?"skip":"load"},S=async({expectedTrigger:e})=>{let o=e==="cli-invocation";try{let t=await Ie(o);if(!t||De({trigger:t.trigger,expectedTrigger:e,targetConfig:t.config,targetProject:t.project,env:so()})==="skip"||Te()||lo())return null;let d=co(),s=await se({config:t.config,autoLoaded:!0,beforeWrite:()=>!Te()&&!mo(d)});return s?(fo(),s.filePath):null}catch(t){let r=t.message;return po(),o?_e(`infra-kit: env auto-load failed \u2014 ${r} (will retry later)`,io):a.debug(`env auto-load skipped: ${r}`),null}},so=()=>({session:E.env[re],cleared:E.env[ae],currentConfig:E.env[ne],currentProject:E.env[ie],autoLoadedMarker:E.env[$]}),co=()=>{try{return m.statSync(C.join(k(),j)).mtimeMs}catch{return null}},mo=e=>{try{let o=C.join(k(),j);if(!m.existsSync(o))return!1;let t=m.statSync(o).mtimeMs;return e!==null&&t<=e?!1:new RegExp(`^unset ${$}$`,"m").test(m.readFileSync(o,"utf-8"))}catch{return!1}},Te=()=>{try{let e=k(),o=C.join(e,te);if(!m.existsSync(o))return!1;let t=C.join(e,j);return m.existsSync(t)?m.statSync(o).mtimeMs>=m.statSync(t).mtimeMs:!0}catch{return!1}},lo=()=>{try{let e=C.join(k(),W);return m.existsSync(e)?Date.now()-m.statSync(e).mtimeMs<ao:!1}catch{return!1}},po=()=>{try{let e=k();m.mkdirSync(e,{recursive:!0,mode:448}),m.writeFileSync(C.join(e,W),"",{mode:384})}catch{}},fo=()=>{try{m.rmSync(C.join(k(),W),{force:!0})}catch{}},_e=(e,o)=>{try{let t=k(),r=C.join(t,o);if(m.existsSync(r))return;m.mkdirSync(t,{recursive:!0,mode:448}),m.writeFileSync(r,"",{mode:384})}catch{}a.warn(e)};var J=async()=>{await S({expectedTrigger:"shell-startup"})};import K from"node:fs/promises";import H from"node:path";import $e from"node:process";import{pathToFileURL as uo}from"node:url";var Ne="~/projects",U=async(e={})=>{if(e.init){await vo(e.cwd);return}await go()},go=async()=>{let e=D(),o=await w(e);if(a.info(`Factory config: ${u(e)} ${o?"[\u2713]":"[ ]"}`),!o){a.info("\nNot found \u2014 run `infra-kit vendor-config --init` to scaffold it."),$e.exitCode=1;return}let{workspaceDir:t,targets:r}=await ee(),d=Z(t),s=await w(d);a.info(`workspaceDir: ${t} (resolved: ${d}) ${s?"[\u2713 exists]":"[ ] not found"}`),a.info("Targets:");let p=s;for(let c of r){let g=H.join(d,c),f=await w(g);f||(p=!1);let v=f?"[\u2713]":"[ ]",y=f?"":" (not found \u2014 clone or remove)";a.info(` ${v} ${c} ${u(g)}${y}`)}p||($e.exitCode=1)},vo=async e=>{let o=D();if(await w(o)){a.info(`Factory config already exists at ${u(o)} \u2014 leaving it untouched.`);return}let t=e??await Y(),r=await yo(t);await K.mkdir(H.dirname(o),{recursive:!0}),await K.writeFile(o,ho(r),"utf-8"),a.info(`\u2713 Created ${u(o)}`),r.length>0&&a.info(` Seeded ${r.length} target(s) from the source ${N}.`),a.info(` Edit \`workspaceDir\` (placeholder: ${Ne}) to point at where your repos live.`),r.length===0&&a.info(" Add at least one repo name to `targets` before running vendor sync/manifest/diff.")},yo=async e=>{try{let o=H.join(e,N),t=await K.stat(o),s=(await import(`${uo(o).href}?mtime=${Number(t.mtimeMs)}`)).default,p=typeof s=="function"?await s():s;if(p&&typeof p=="object"&&"targets"in p){let c=p.targets;if(Array.isArray(c)&&c.every(g=>typeof g=="string"))return c}}catch{}return[]},ho=e=>`${JSON.stringify({workspaceDir:Ne,targets:e},null,2)}
18
+ `;import wo from"node:process";var L={enabled:!1},i=(e,o=t=>{wo.stdout.write(t)})=>(L.enabled&&e&&e.structuredContent!=null&&o(`${JSON.stringify(e.structuredContent,null,2)}
19
+ `),e),T=e=>{e.options.some(t=>t.long==="--json")||e.option("--json","Output the structured result as JSON on stdout (human logs stay on stderr)"),e.commands.forEach(T)};var B=(e,o=" ")=>{let t=e.reduce((r,[d])=>Math.max(r,d.length),0);return e.map(([r,d])=>`${r.padEnd(t)}${o}${d}`)};var n=new Co,Ao=(e,o)=>[...o,e],z=e=>typeof e=="string"?e.split(",").filter(Boolean):void 0,Me=(e,o)=>{if(!(typeof e>"u")){if(e===!0)return"workspace";if(e===!1)return"none";if(typeof e=="string"&&M.includes(e))return e;throw new Error(`Invalid ${o} value "${String(e)}". Expected one of: ${M.join(", ")}.`)}},Oe=async e=>{try{e?await n.parseAsync(e):await n.parseAsync()}catch(o){O(o)&&(a.info("Operation cancelled."),h.exit(0));let t=o instanceof Error?o.message:String(o);a.error(t),h.exit(1)}},Fe={value:!1},l=(e,o)=>e.hook("preAction",()=>{Fe.value||a.warn(`"${e.name()}" is a deprecated alias; use "${o}" instead.`)}),Ve=e=>e.description("Merge dev branch into every release branch").option("-a, --all","Select all active release branches").option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await pe({all:o.all,confirmedCommand:o.yes}))}),Ge=e=>e.description("List all release branches").action(async()=>{i(await ve())}),We=e=>e.description("Create one or more release branches (each entry can mix regular/hotfix and its own description)").option("-r, --release <spec>",'Release spec "<version|next|name>[:type[:description]]" (repeatable). The token is a semver ("1.2.5"), the literal "next", or a kebab-case name ("checkout-redesign"). Type is regular|hotfix (default regular). Examples: "1.2.5", "1.2.5:hotfix", "next:regular:Holiday backend", "checkout-redesign:regular:Q3 redesign".',Ao,[]).option("-y, --yes","Skip confirmation prompt").action(async o=>{let r=o.release.map(ye),d=r.length>0?r:void 0;i(await he({releases:d,confirmedCommand:o.yes}))}),Je=e=>e.description("Edit a release's description in Jira and in the matching GitHub PR body").option("-v, --version <version>","Release version (e.g. 1.2.5) or release name (e.g. checkout-redesign)").option("-d, --description <description>",'New description (use "" to clear)').option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await we({version:o.version,description:o.description,confirmedCommand:o.yes}))}),Ke=e=>e.description("Deploy any release branch to any environment").option("-v, --version <version>",'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deploy; "dev" deploys from the dev branch').option("-e, --env <env>","Specify the environment to deploy to, e.g. dev").option("--skip-terraform","Skip terraform deployment step").option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await ue({version:o.version,env:o.env,skipTerraform:o.skipTerraform,confirmedCommand:o.yes}))}),He=e=>e.description("Deploy selected services from release branch to any environment").option("-v, --version <version>",'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deploy; "dev" deploys from the dev branch').option("-e, --env <env>","Specify the environment to deploy to, e.g. dev").option("-s, --services <services...>","Specify services to deploy, e.g. client-be client-fe").option("--skip-terraform","Skip terraform deployment step").option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await ge({version:o.version,env:o.env,services:o.services,skipTerraform:o.skipTerraform,confirmedCommand:o.yes}))}),Ue=e=>e.description("Release a new version to production").option("-v, --version <version>","Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deliver").option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await fe({version:o.version,confirmedCommand:o.yes}))}),Be=e=>e.description("Remove release worktrees whose PRs are no longer open").option("-y, --yes","Skip confirmation prompt").action(async o=>{i(await je({confirmedCommand:o.yes}))}),ze=e=>e.description("Add git worktrees for release branches").option("-y, --yes","Skip confirmation prompt").option("-a, --all","Select all active release branches").option("-v, --versions <versions>","Specify versions by comma, e.g. 1.2.5, 1.2.6").option("-i, --ide [mode]","Editor mode for created worktrees: workspace (default) | none").option("--no-ide","Skip the editor (alias for --ide none)").option("-c, --cursor [mode]","Deprecated alias for --ide").option("--no-cursor","Deprecated alias for --no-ide").option("-g, --github-desktop","Open created worktrees in GitHub Desktop").option("--no-github-desktop","Skip GitHub Desktop prompt").option("-m, --cmux","Open created worktrees in cmux (3-pane layout)").option("--no-cmux","Skip cmux prompt").action(async o=>{let t=Me(o.ide,"--ide")??Me(o.cursor,"--cursor");i(await Se({confirmedCommand:o.yes,all:o.all,versions:o.versions,ide:t,githubDesktop:o.githubDesktop,cmux:o.cmux}))}),Ye=e=>e.description("List all git worktrees with detailed information").action(async()=>{i(await Le())}),qe=e=>e.description("Remove git worktrees for release branches").option("-y, --yes","Skip confirmation prompt").option("-a, --all","Select all active release branches").option("-v, --versions <versions>","Specify versions by comma, e.g. 1.2.5, 1.2.6").action(async o=>{i(await be({confirmedCommand:o.yes,all:o.all,versions:o.versions}))}),Qe=e=>e.description("Close all cmux/editor worktree windows, then reopen the current release worktrees (also cold-start restore)").action(async()=>{i(await Re())}),Xe=e=>e.description("Show the machine-local factory config (~/.infra-kit/vendor.json) or scaffold it with --init").option("--init","Scaffold ~/.infra-kit/vendor.json (skips if it already exists)").action(async o=>{i(await U({init:o.init}))}),A=n.command("release").description("Release management commands");Ve(A.command("merge-dev"));Ge(A.command("list"));We(A.command("create"));Je(A.command("desc-edit"));Ke(A.command("deploy-all"));He(A.command("deploy-selected"));Ue(A.command("deliver"));var R=n.command("worktrees").description("Git worktree management commands");ze(R.command("add"));Ye(R.command("list"));qe(R.command("remove"));Be(R.command("sync"));Qe(R.command("reload"));l(Ve(n.command("merge-dev")),"release merge-dev");l(Ge(n.command("release-list")),"release list");l(We(n.command("release-create")),"release create");l(Je(n.command("release-desc-edit")),"release desc-edit");l(Ke(n.command("release-deploy-all")),"release deploy-all");l(He(n.command("release-deploy-selected")),"release deploy-selected");l(Ue(n.command("release-deliver")),"release deliver");l(ze(n.command("worktrees-add")),"worktrees add");l(Ye(n.command("worktrees-list")),"worktrees list");l(qe(n.command("worktrees-remove")),"worktrees remove");l(Be(n.command("worktrees-sync")),"worktrees sync");l(Qe(n.command("worktrees-reload")),"worktrees reload");var Ze=n.command("config").description("Manage infra-kit configuration files");Ze.command("path").description("Show the resolved config merge chain and file paths").action(async()=>{i(await V())});Ze.command("edit").description("Open the user-scope per-project override file in $EDITOR").action(async()=>{i(await G())});n.command("audit").description("Audit against infra-kit.config.ts rules (--all for every package, --root for the monorepo root)").option("-a, --all","Audit every non-vendor workspace package").option("-r, --root","Audit the monorepo root (turbo pipeline + root commands)").action(async e=>{let o=await q({all:e.all,root:e.root});i(o),o.structuredContent.allPassed||(h.exitCode=1)});var b=n.command("vendor").description("Verify and sync the mirrored vendor/ tree");b.command("check").description("Verify vendor/ matches vendor/.sync-manifest.json (self-contained; for any consumer repo)").action(async()=>{let e=await ke();i(e),e.structuredContent.ok||(h.exitCode=1)});b.command("sync").description("Copy vendored files from the source repo into each target and regenerate manifests").option("-y, --yes","Skip confirmation prompt").option("-r, --repos <repos>","Restrict to comma-separated target repo names").action(async e=>{i(await xe({confirmedCommand:e.yes,repos:z(e.repos)}))});b.command("manifest").description("Regenerate each target vendor/.sync-manifest.json + README from current content (no copy)").option("-r, --repos <repos>","Restrict to comma-separated target repo names").action(async e=>{i(await Ae({confirmedCommand:!0,repos:z(e.repos)}))});b.command("diff").description("Source-aware drift check (rsync dry-run) of each target vendored subtree vs the source").option("-r, --repos <repos>","Restrict to comma-separated target repo names").action(async e=>{let o=await Ce({repos:z(e.repos)});i(o),o.structuredContent.ok||(h.exitCode=1)});Xe(b.command("config"));l(Xe(n.command("vendor-config")),"vendor config");n.command("doctor").description("Check installation and authentication status of gh and doppler CLIs").action(async()=>{i(await oe())});n.command("version").description("Print the installed infra-kit CLI version").action(async()=>{i(await Ee())});n.command("env-status").description("Show which env is loaded in this session (local introspection; no Doppler call)").action(async()=>{i(await le())});n.command("env-list").description("List available Doppler configs for the detected project").action(async()=>{i(await me())});n.command("init").description("Inject shell integration into .zshrc and sync repo agent-instruction files").action(async()=>{i(await _())});n.command("env-load").description("Load Doppler env vars for a config. Source the returned file path to apply.").option("-c, --config <config>","Environment config name to load (e.g. dev, arthur)").action(async e=>{i(await ce({config:e.config}))});n.command("env-clear").description("Clear loaded env vars. Source the returned file path to apply.").action(async()=>{i(await de())});n.command("env-autoload",{hidden:!0}).description("Internal: prime env for the shell-startup auto-load trigger").action(async()=>{await J()});n.commands.forEach(T);var xo=e=>e.startsWith("env-")||e==="init"||e==="doctor"||e==="version";n.hook("preAction",async(e,o)=>{L.enabled=!!o.optsWithGlobals().json,L.enabled&&(a.level="warn"),xo(o.name())||await S({expectedTrigger:"cli-invocation"})});if(h.argv.length<=2){let e=P("release"),o=P("worktrees"),t=P("environment"),r=new Map(n.commands.map(c=>[c.name(),c])),s=[{label:"Release Management",names:e},{label:"Worktrees",names:o},{label:"Environment",names:t}].flatMap(({label:c,names:g})=>g.filter(f=>r.has(f)).map(f=>({name:f,description:r.get(f).description(),group:c}))),p=null;try{if(h.stdout.isTTY&&h.stdin.isTTY){let{runCommandPalette:c}=await import("./boot-SGM5RVLJ.js");p=await c(s)}else{let c=B(s.map(v=>[v.name,v.description])),g=new Map;s.forEach((v,y)=>{g.set(v.name,c[y]??v.name)});let f=v=>v.filter(y=>r.has(y)).map(y=>({name:g.get(y)??y,value:y}));p=await ko({message:"Select a command to run",choices:[new x(" "),new x("\u2014 Release Management \u2014"),...f(e),new x(" "),new x("\u2014 Worktrees \u2014"),...f(o),new x(" "),new x("\u2014 Environment \u2014"),...f(t)]},{output:h.stderr})}}catch(c){if(!O(c))throw c}p&&(Fe.value=!0,await Oe(["node","infra-kit",p]))}else await Oe();
20
20
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/entry/cli.ts", "../src/commands/config/config.ts", "../src/lib/env-autoload/env-autoload.ts", "../src/commands/env-autoload/env-autoload.ts", "../src/commands/vendor-config/vendor-config.ts", "../src/lib/json-output/json-output.ts", "../src/lib/render/render.ts"],
4
- "sourcesContent": ["import select, { Separator } from '@inquirer/select'\nimport { Command } from 'commander'\nimport process from 'node:process'\n\nimport { audit } from 'src/commands/audit'\nimport { configEdit, configPath } from 'src/commands/config'\nimport { doctor } from 'src/commands/doctor'\nimport { envAutoload } from 'src/commands/env-autoload'\nimport { envClear } from 'src/commands/env-clear'\nimport { envList } from 'src/commands/env-list'\nimport { envLoad } from 'src/commands/env-load'\nimport { envStatus } from 'src/commands/env-status'\nimport { ghMergeDev } from 'src/commands/gh-merge-dev'\nimport { ghReleaseDeliver } from 'src/commands/gh-release-deliver'\nimport { ghReleaseDeployAll } from 'src/commands/gh-release-deploy-all'\nimport { ghReleaseDeploySelected } from 'src/commands/gh-release-deploy-selected'\nimport { ghReleaseList } from 'src/commands/gh-release-list'\nimport { init } from 'src/commands/init'\nimport { releaseCreate } from 'src/commands/release-create'\nimport { releaseDescEdit } from 'src/commands/release-desc-edit'\nimport { vendorCheck } from 'src/commands/vendor-check'\nimport { vendorConfig } from 'src/commands/vendor-config'\nimport { vendorDiff } from 'src/commands/vendor-diff'\nimport { vendorManifest } from 'src/commands/vendor-manifest'\nimport { vendorSync } from 'src/commands/vendor-sync'\nimport { version } from 'src/commands/version'\nimport { worktreesAdd } from 'src/commands/worktrees-add'\nimport { worktreesList } from 'src/commands/worktrees-list'\nimport { worktreesReload } from 'src/commands/worktrees-reload'\nimport { worktreesRemove } from 'src/commands/worktrees-remove'\nimport { worktreesSync } from 'src/commands/worktrees-sync'\nimport { IDE_MODES } from 'src/integrations/ide'\nimport type { IdeMode } from 'src/integrations/ide'\nimport { getMenuGroupCommands } from 'src/lib/command-catalog'\nimport { runEnvAutoLoad } from 'src/lib/env-autoload'\nimport { addJsonOption, emit, jsonOutput } from 'src/lib/json-output'\nimport { logger } from 'src/lib/logger'\nimport { formatAlignedRows } from 'src/lib/render'\nimport { parseReleaseSpec } from 'src/lib/version-utils'\nimport type { ReleaseInput } from 'src/lib/version-utils'\n\nconst program = new Command()\n\nconst collectReleaseSpec = (value: string, prev: string[]): string[] => {\n return [...prev, value]\n}\n\n/** Parse a `--repos a,b,c` option into a target-name list (undefined = all). */\nconst parseRepos = (value: unknown): string[] | undefined => {\n return typeof value === 'string' ? value.split(',').filter(Boolean) : undefined\n}\n\nconst normalizeIdeMode = (value: unknown, flagName: '--ide' | '--cursor'): IdeMode | undefined => {\n if (typeof value === 'undefined') {\n return undefined\n }\n\n if (value === true) {\n return 'workspace'\n }\n\n if (value === false) {\n return 'none'\n }\n\n if (typeof value === 'string' && (IDE_MODES as readonly string[]).includes(value)) {\n return value as IdeMode\n }\n\n throw new Error(`Invalid ${flagName} value \"${String(value)}\". Expected one of: ${IDE_MODES.join(', ')}.`)\n}\n\nconst runProgram = async (argv?: string[]): Promise<void> => {\n try {\n if (argv) {\n await program.parseAsync(argv)\n } else {\n await program.parseAsync()\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n\n logger.error(message)\n process.exit(1)\n }\n}\n\n// --- Deprecation support for flat command aliases (Phase 3 grouping) ---\n// Flat names (`release-create`, `worktrees-add`, `vendor-config`, ...) are kept\n// as working aliases of the grouped forms (`release create`, ...) for one\n// release cycle. They warn once when invoked directly, but stay silent when the\n// interactive no-arg menu drives them (the menu is a guided surface).\nconst invokedViaMenu = { value: false }\n\nconst deprecatedAlias = (cmd: Command, preferred: string): Command => {\n return cmd.hook('preAction', () => {\n if (!invokedViaMenu.value) {\n logger.warn(`\"${cmd.name()}\" is a deprecated alias; use \"${preferred}\" instead.`)\n }\n })\n}\n\n// --- Command configurators (one source of options + action, shared by the\n// grouped form and its flat alias so the two can never diverge) ---\nconst configureMergeDev = (cmd: Command): Command => {\n return cmd\n .description('Merge dev branch into every release branch')\n .option('-a, --all', 'Select all active release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(await ghMergeDev({ all: options.all, confirmedCommand: options.yes }))\n })\n}\n\nconst configureReleaseList = (cmd: Command): Command => {\n return cmd.description('List all release branches').action(async () => {\n emit(await ghReleaseList())\n })\n}\n\nconst configureReleaseCreate = (cmd: Command): Command => {\n return cmd\n .description('Create one or more release branches (each entry can mix regular/hotfix and its own description)')\n .option(\n '-r, --release <spec>',\n 'Release spec \"<version|next|name>[:type[:description]]\" (repeatable). The token is a semver (\"1.2.5\"), the literal \"next\", or a kebab-case name (\"checkout-redesign\"). Type is regular|hotfix (default regular). Examples: \"1.2.5\", \"1.2.5:hotfix\", \"next:regular:Holiday backend\", \"checkout-redesign:regular:Q3 redesign\".',\n collectReleaseSpec,\n [],\n )\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n const specs = options.release as string[]\n const inputs: ReleaseInput[] = specs.map(parseReleaseSpec)\n const releases = inputs.length > 0 ? inputs : undefined\n\n emit(\n await releaseCreate({\n releases,\n confirmedCommand: options.yes,\n }),\n )\n })\n}\n\nconst configureReleaseDescEdit = (cmd: Command): Command => {\n return cmd\n .description(\"Edit a release's description in Jira and in the matching GitHub PR body\")\n .option('-v, --version <version>', 'Release version (e.g. 1.2.5) or release name (e.g. checkout-redesign)')\n .option('-d, --description <description>', 'New description (use \"\" to clear)')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(\n await releaseDescEdit({\n version: options.version,\n description: options.description,\n confirmedCommand: options.yes,\n }),\n )\n })\n}\n\nconst configureReleaseDeployAll = (cmd: Command): Command => {\n return cmd\n .description('Deploy any release branch to any environment')\n .option(\n '-v, --version <version>',\n 'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deploy; \"dev\" deploys from the dev branch',\n )\n .option('-e, --env <env>', 'Specify the environment to deploy to, e.g. dev')\n .option('--skip-terraform', 'Skip terraform deployment step')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(\n await ghReleaseDeployAll({\n version: options.version,\n env: options.env,\n skipTerraform: options.skipTerraform,\n confirmedCommand: options.yes,\n }),\n )\n })\n}\n\nconst configureReleaseDeploySelected = (cmd: Command): Command => {\n return cmd\n .description('Deploy selected services from release branch to any environment')\n .option(\n '-v, --version <version>',\n 'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deploy; \"dev\" deploys from the dev branch',\n )\n .option('-e, --env <env>', 'Specify the environment to deploy to, e.g. dev')\n .option('-s, --services <services...>', 'Specify services to deploy, e.g. client-be client-fe')\n .option('--skip-terraform', 'Skip terraform deployment step')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(\n await ghReleaseDeploySelected({\n version: options.version,\n env: options.env,\n services: options.services,\n skipTerraform: options.skipTerraform,\n confirmedCommand: options.yes,\n }),\n )\n })\n}\n\nconst configureReleaseDeliver = (cmd: Command): Command => {\n return cmd\n .description('Release a new version to production')\n .option('-v, --version <version>', 'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deliver')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(await ghReleaseDeliver({ version: options.version, confirmedCommand: options.yes }))\n })\n}\n\nconst configureWorktreesSync = (cmd: Command): Command => {\n return cmd\n .description('Remove release worktrees whose PRs are no longer open')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(await worktreesSync({ confirmedCommand: options.yes }))\n })\n}\n\nconst configureWorktreesAdd = (cmd: Command): Command => {\n return cmd\n .description('Add git worktrees for release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-a, --all', 'Select all active release branches')\n .option('-v, --versions <versions>', 'Specify versions by comma, e.g. 1.2.5, 1.2.6')\n .option('-i, --ide [mode]', 'Editor mode for created worktrees: workspace (default) | none')\n .option('--no-ide', 'Skip the editor (alias for --ide none)')\n .option('-c, --cursor [mode]', 'Deprecated alias for --ide')\n .option('--no-cursor', 'Deprecated alias for --no-ide')\n .option('-g, --github-desktop', 'Open created worktrees in GitHub Desktop')\n .option('--no-github-desktop', 'Skip GitHub Desktop prompt')\n .option('-m, --cmux', 'Open created worktrees in cmux (3-pane layout)')\n .option('--no-cmux', 'Skip cmux prompt')\n .action(async (options) => {\n // `--ide` wins over the deprecated `--cursor` alias when both are provided.\n const ide = normalizeIdeMode(options.ide, '--ide') ?? normalizeIdeMode(options.cursor, '--cursor')\n\n emit(\n await worktreesAdd({\n confirmedCommand: options.yes,\n all: options.all,\n versions: options.versions,\n ide,\n githubDesktop: options.githubDesktop,\n cmux: options.cmux,\n }),\n )\n })\n}\n\nconst configureWorktreesList = (cmd: Command): Command => {\n return cmd.description('List all git worktrees with detailed information').action(async () => {\n emit(await worktreesList())\n })\n}\n\nconst configureWorktreesRemove = (cmd: Command): Command => {\n return cmd\n .description('Remove git worktrees for release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-a, --all', 'Select all active release branches')\n .option('-v, --versions <versions>', 'Specify versions by comma, e.g. 1.2.5, 1.2.6')\n .action(async (options) => {\n emit(await worktreesRemove({ confirmedCommand: options.yes, all: options.all, versions: options.versions }))\n })\n}\n\nconst configureWorktreesReload = (cmd: Command): Command => {\n return cmd\n .description(\n 'Close all cmux/editor worktree windows, then reopen the current release worktrees (also cold-start restore)',\n )\n .action(async () => {\n emit(await worktreesReload())\n })\n}\n\nconst configureVendorConfig = (cmd: Command): Command => {\n return cmd\n .description('Show the machine-local factory config (~/.infra-kit/vendor.json) or scaffold it with --init')\n .option('--init', 'Scaffold ~/.infra-kit/vendor.json (skips if it already exists)')\n .action(async (options) => {\n emit(await vendorConfig({ init: options.init }))\n })\n}\n\n// --- Grouped command surface (preferred form) ---\nconst releaseGroup = program.command('release').description('Release management commands')\n\nconfigureMergeDev(releaseGroup.command('merge-dev'))\nconfigureReleaseList(releaseGroup.command('list'))\nconfigureReleaseCreate(releaseGroup.command('create'))\nconfigureReleaseDescEdit(releaseGroup.command('desc-edit'))\nconfigureReleaseDeployAll(releaseGroup.command('deploy-all'))\nconfigureReleaseDeploySelected(releaseGroup.command('deploy-selected'))\nconfigureReleaseDeliver(releaseGroup.command('deliver'))\n\nconst worktreesGroup = program.command('worktrees').description('Git worktree management commands')\n\nconfigureWorktreesAdd(worktreesGroup.command('add'))\nconfigureWorktreesList(worktreesGroup.command('list'))\nconfigureWorktreesRemove(worktreesGroup.command('remove'))\nconfigureWorktreesSync(worktreesGroup.command('sync'))\nconfigureWorktreesReload(worktreesGroup.command('reload'))\n\n// --- Deprecated flat aliases (kept one release cycle; warn when used directly) ---\ndeprecatedAlias(configureMergeDev(program.command('merge-dev')), 'release merge-dev')\ndeprecatedAlias(configureReleaseList(program.command('release-list')), 'release list')\ndeprecatedAlias(configureReleaseCreate(program.command('release-create')), 'release create')\ndeprecatedAlias(configureReleaseDescEdit(program.command('release-desc-edit')), 'release desc-edit')\ndeprecatedAlias(configureReleaseDeployAll(program.command('release-deploy-all')), 'release deploy-all')\ndeprecatedAlias(configureReleaseDeploySelected(program.command('release-deploy-selected')), 'release deploy-selected')\ndeprecatedAlias(configureReleaseDeliver(program.command('release-deliver')), 'release deliver')\ndeprecatedAlias(configureWorktreesAdd(program.command('worktrees-add')), 'worktrees add')\ndeprecatedAlias(configureWorktreesList(program.command('worktrees-list')), 'worktrees list')\ndeprecatedAlias(configureWorktreesRemove(program.command('worktrees-remove')), 'worktrees remove')\ndeprecatedAlias(configureWorktreesSync(program.command('worktrees-sync')), 'worktrees sync')\ndeprecatedAlias(configureWorktreesReload(program.command('worktrees-reload')), 'worktrees reload')\n\nconst configCmd = program.command('config').description('Manage infra-kit configuration files')\n\nconfigCmd\n .command('path')\n .description('Show the resolved config merge chain and file paths')\n .action(async () => {\n emit(await configPath())\n })\n\nconfigCmd\n .command('edit')\n .description('Open the user-scope per-project override file in $EDITOR')\n .action(async () => {\n emit(await configEdit())\n })\n\nprogram\n .command('audit')\n .description('Audit against infra-kit.config.ts rules (--all for every package, --root for the monorepo root)')\n .option('-a, --all', 'Audit every non-vendor workspace package')\n .option('-r, --root', 'Audit the monorepo root (turbo pipeline + root commands)')\n .action(async (options) => {\n const result = await audit({ all: options.all, root: options.root })\n\n emit(result)\n\n if (!result.structuredContent.allPassed) {\n process.exitCode = 1\n }\n })\n\nconst vendorCmd = program.command('vendor').description('Verify and sync the mirrored vendor/ tree')\n\nvendorCmd\n .command('check')\n .description('Verify vendor/ matches vendor/.sync-manifest.json (self-contained; for any consumer repo)')\n .action(async () => {\n const result = await vendorCheck()\n\n emit(result)\n\n if (!result.structuredContent.ok) {\n process.exitCode = 1\n }\n })\n\nvendorCmd\n .command('sync')\n .description('Copy vendored files from the source repo into each target and regenerate manifests')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-r, --repos <repos>', 'Restrict to comma-separated target repo names')\n .action(async (options) => {\n emit(await vendorSync({ confirmedCommand: options.yes, repos: parseRepos(options.repos) }))\n })\n\nvendorCmd\n .command('manifest')\n .description('Regenerate each target vendor/.sync-manifest.json + README from current content (no copy)')\n .option('-r, --repos <repos>', 'Restrict to comma-separated target repo names')\n .action(async (options) => {\n emit(await vendorManifest({ confirmedCommand: true, repos: parseRepos(options.repos) }))\n })\n\nvendorCmd\n .command('diff')\n .description('Source-aware drift check (rsync dry-run) of each target vendored subtree vs the source')\n .option('-r, --repos <repos>', 'Restrict to comma-separated target repo names')\n .action(async (options) => {\n const result = await vendorDiff({ repos: parseRepos(options.repos) })\n\n emit(result)\n\n if (!result.structuredContent.ok) {\n process.exitCode = 1\n }\n })\n\n// Grouped form (preferred); the flat `vendor-config` below is a deprecated alias.\nconfigureVendorConfig(vendorCmd.command('config'))\n\ndeprecatedAlias(configureVendorConfig(program.command('vendor-config')), 'vendor config')\n\nprogram\n .command('doctor')\n .description('Check installation and authentication status of gh and doppler CLIs')\n .action(async () => {\n emit(await doctor())\n })\n\nprogram\n .command('version')\n .description('Print the installed infra-kit CLI version')\n .action(async () => {\n emit(await version())\n })\n\nprogram\n .command('env-status')\n .description('Show which env is loaded in this session (local introspection; no Doppler call)')\n .action(async () => {\n emit(await envStatus())\n })\n\nprogram\n .command('env-list')\n .description('List available Doppler configs for the detected project')\n .action(async () => {\n emit(await envList())\n })\n\nprogram\n .command('init')\n .description('Inject shell integration into .zshrc and sync repo agent-instruction files')\n .action(async () => {\n emit(await init())\n })\n\nprogram\n .command('env-load')\n .description('Load Doppler env vars for a config. Source the returned file path to apply.')\n .option('-c, --config <config>', 'Environment config name to load (e.g. dev, arthur)')\n .action(async (options) => {\n emit(await envLoad({ config: options.config }))\n })\n\nprogram\n .command('env-clear')\n .description('Clear loaded env vars. Source the returned file path to apply.')\n .action(async () => {\n emit(await envClear())\n })\n\n// Internal: driven by the init shell-startup integration (backgrounded). Writes\n// env-load.sh when envAutoLoad is configured + eligible; the precmd hook sources\n// it. Hidden + no stdout output so it never pollutes the shell or the menu.\nprogram\n .command('env-autoload', { hidden: true })\n .description('Internal: prime env for the shell-startup auto-load trigger')\n .action(async () => {\n await envAutoload()\n })\n\n// Register `--json` on every command, then resolve the flag before each action\n// runs. In JSON mode we lower the logger to `warn` so the human-oriented info\n// lines stop cluttering stderr while errors still surface; the structured\n// payload is written to stdout by `emit`. No handler logic is affected.\nprogram.commands.forEach(addJsonOption)\n\n// Commands excluded from the cli-invocation auto-load trigger: the env-* family\n// (avoids recursion \u2014 `env-autoload`/`env-load` would re-enter), plus the\n// host-inspecting / meta commands where priming Doppler env would be surprising\n// (`init` bootstraps the shell block, `doctor` inspects auth, `version` prints a\n// string). `--help`/`--version`/the bare-arg menu don't fire preAction at all.\nconst isAutoLoadExcludedCommand = (name: string): boolean => {\n return name.startsWith('env-') || name === 'init' || name === 'doctor' || name === 'version'\n}\n\nprogram.hook('preAction', async (_thisCommand, actionCommand) => {\n // `optsWithGlobals` (not `opts`) so `--json` is seen on grouped subcommands:\n // for `release list --json` Commander binds the post-subcommand flag to the\n // parent `release` group, so the leaf's own `opts()` would not carry it.\n jsonOutput.enabled = Boolean(actionCommand.optsWithGlobals().json)\n\n if (jsonOutput.enabled) {\n logger.level = 'warn'\n }\n\n // cli-invocation auto-load: primes the shell env for SUBSEQUENT commands. The\n // current command does NOT see these vars \u2014 a child process can't mutate its\n // parent shell; the precmd hook sources the written file on the next prompt.\n // runEnvAutoLoad self-gates on config trigger and swallows transient failures,\n // so this is a no-op unless configured for cli-invocation and never blocks.\n if (!isAutoLoadExcludedCommand(actionCommand.name())) {\n await runEnvAutoLoad({ expectedTrigger: 'cli-invocation' })\n }\n})\n\nif (process.argv.length <= 2) {\n // Menu groups derive from the single command catalog (no hand-maintained\n // name arrays). Membership and order live in src/lib/command-catalog.\n const releaseCommands = getMenuGroupCommands('release')\n const worktreeCommands = getMenuGroupCommands('worktrees')\n const envCommands = getMenuGroupCommands('environment')\n\n const commandMap = new Map(\n program.commands.map((cmd) => {\n return [cmd.name(), cmd]\n }),\n )\n\n const groups = [\n { label: 'Release Management', names: releaseCommands },\n { label: 'Worktrees', names: worktreeCommands },\n { label: 'Environment', names: envCommands },\n ]\n\n // Flat {name, description, group} list shared by both the Ink palette and the\n // Inquirer fallback; descriptions come from Commander (single source).\n const paletteItems = groups.flatMap(({ label, names }) => {\n return names\n .filter((name) => {\n return commandMap.has(name)\n })\n .map((name) => {\n return { name, description: commandMap.get(name)!.description(), group: label }\n })\n })\n\n let selected: string | null\n\n // Interactive TTY \u2192 Ink command palette, loaded lazily via dynamic import so\n // React/Ink never touch the MCP / `--json` / non-TTY code paths. Otherwise fall\n // back to the Inquirer menu (scripts, pipes, CI).\n if (process.stdout.isTTY && process.stdin.isTTY) {\n const { runCommandPalette } = await import('src/tui/boot')\n\n selected = await runCommandPalette(paletteItems)\n } else {\n const alignedLabels = formatAlignedRows(\n paletteItems.map((item) => {\n return [item.name, item.description] as const\n }),\n )\n const labelByName = new Map<string, string>()\n\n paletteItems.forEach((item, index) => {\n labelByName.set(item.name, alignedLabels[index] ?? item.name)\n })\n\n const toChoices = (names: string[]) => {\n return names\n .filter((name) => {\n return commandMap.has(name)\n })\n .map((name) => {\n return {\n name: labelByName.get(name) ?? name,\n value: name,\n }\n })\n }\n\n selected = await select(\n {\n message: 'Select a command to run',\n choices: [\n new Separator(' '),\n new Separator('\u2014 Release Management \u2014'),\n ...toChoices(releaseCommands),\n new Separator(' '),\n new Separator('\u2014 Worktrees \u2014'),\n ...toChoices(worktreeCommands),\n new Separator(' '),\n new Separator('\u2014 Environment \u2014'),\n ...toChoices(envCommands),\n ],\n },\n { output: process.stderr },\n )\n }\n\n // The menu is a guided surface; don't nag about deprecated flat names here.\n if (selected) {\n invokedViaMenu.value = true\n\n await runProgram(['node', 'infra-kit', selected])\n }\n} else {\n await runProgram()\n}\n", "import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { $ } from 'zx'\n\nimport { getInfraKitConfigPaths, resetInfraKitConfigCache } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport { fileExists, tildify } from 'src/lib/path-display'\nimport type { ToolsExecutionResult } from 'src/types'\n\n/**\n * Print the file paths that participate in the config merge chain along with\n * existence markers, so the user can see at a glance which override layers\n * are active.\n *\n * @example\n * // CLI: `infra-kit config path`\n * // INFO: Project name: api\n * // INFO: Config merge chain (later overrides earlier):\n * // INFO: [\u2713] project (committed) ~/projects/api/infra-kit.json\n * // INFO: [ ] user global ~/.infra-kit/infra-kit.json\n * // INFO: [\u2713] user project ~/.infra-kit/projects/api/infra-kit.json\n */\nexport const configPath = async (): Promise<ToolsExecutionResult> => {\n const paths = await getInfraKitConfigPaths()\n\n const rows: { label: string; path: string; exists: boolean }[] = await Promise.all(\n [\n { label: 'project (committed)', path: paths.main },\n { label: 'user global', path: paths.userGlobal },\n { label: 'user project', path: paths.userProject },\n ].map(async (row) => {\n return { ...row, exists: await fileExists(row.path) }\n }),\n )\n\n logger.info(`Project name: ${paths.projectName}\\n`)\n logger.info('Config merge chain (later overrides earlier):\\n')\n\n for (const row of rows) {\n const marker = row.exists ? ' [\u2713]' : ' [ ]'\n\n logger.info(`${marker} ${row.label.padEnd(22)} ${tildify(row.path)}`)\n }\n\n const structuredContent = {\n projectName: paths.projectName,\n layers: rows.map((r) => {\n return { label: r.label, path: r.path, exists: r.exists }\n }),\n }\n\n return {\n content: [{ type: 'text', text: JSON.stringify(structuredContent, null, 2) }],\n structuredContent,\n }\n}\n\n/**\n * Open the user-scope per-project override file in $EDITOR, creating the\n * parent directory and a stub file on first use. Resets the config cache\n * after the editor exits so subsequent reads pick up edits without a restart.\n *\n * @example\n * // CLI: `infra-kit config edit`\n * // first run \u2014 creates ~/.infra-kit/projects/api/infra-kit.json ({}) + a sibling\n * // infra-kit.example.jsonc reference, then $EDITOR opens the .json\n * // subsequent runs \u2014 opens the existing file as-is\n */\nexport const configEdit = async (): Promise<ToolsExecutionResult> => {\n const paths = await getInfraKitConfigPaths()\n const editor = process.env.EDITOR || process.env.VISUAL || 'vi'\n\n await fs.mkdir(path.dirname(paths.userProject), { recursive: true })\n\n if (!(await fileExists(paths.userProject))) {\n // JSON can't carry comments, so seed an empty-but-valid config and drop the\n // annotated guidance next to it in a non-loaded .example.jsonc the loader\n // never reads (it only globs the three exact `infra-kit.json` filenames).\n const examplePath = exampleSiblingPath(paths.userProject)\n\n await fs.writeFile(paths.userProject, '{}\\n', 'utf-8')\n await fs.writeFile(examplePath, buildUserProjectExample(paths.projectName), 'utf-8')\n\n logger.info(`Created ${tildify(paths.userProject)} \u2014 see ${tildify(examplePath)} for the annotated reference.`)\n }\n\n logger.info(`Opening ${tildify(paths.userProject)} in ${editor}`)\n\n await $({ stdio: 'inherit' })`${editor} ${paths.userProject}`\n\n resetInfraKitConfigCache()\n\n const structuredContent = { path: paths.userProject, editor }\n\n return {\n content: [{ type: 'text', text: JSON.stringify(structuredContent, null, 2) }],\n structuredContent,\n }\n}\n\n/**\n * Derive the non-loaded `.example.jsonc` sibling for a config path.\n *\n * @example\n * exampleSiblingPath('/u/.infra-kit/projects/api/infra-kit.json')\n * // => '/u/.infra-kit/projects/api/infra-kit.example.jsonc'\n */\nconst exampleSiblingPath = (jsonPath: string): string => {\n return jsonPath.replace(/\\.json$/, '.example.jsonc')\n}\n\n/**\n * Annotated JSONC reference for the user-scope per-project override layer.\n * Written alongside the real `{}` config so the guidance the old YAML stub\n * carried in comments survives the move to JSON.\n *\n * @example\n * buildUserProjectExample('api')\n * // => '// infra-kit user override for api \u2026\\n{ \u2026 }\\n'\n */\nconst buildUserProjectExample = (projectName: string): string => {\n return `// infra-kit user override for ${projectName} \u2014 ~/.infra-kit/projects/${projectName}/infra-kit.json\n//\n// Layer 3 (highest precedence) of the config merge chain. Shallow-merged on top\n// of <repo>/infra-kit.json and ~/.infra-kit/infra-kit.json \u2014 top-level keys\n// (environments, envManagement, ide, taskManager, worktrees, envAutoLoad) replace wholesale.\n//\n// This .example.jsonc is reference only \u2014 it is NOT loaded. Put real overrides\n// in the sibling infra-kit.json (strict JSON: no comments, double-quoted keys).\n{\n // \"worktrees\": { \"openInGithubDesktop\": false, \"openInCmux\": true, \"cmux\": { \"layout\": \"two-columns\" } },\n // // Auto-load Doppler env here. trigger (pick one): shell-startup | cli-invocation; config: an environment name.\n // \"envAutoLoad\": { \"trigger\": \"shell-startup\", \"config\": \"dev\" }\n}\n`\n}\n", "import fs from 'node:fs'\nimport path from 'node:path'\nimport process from 'node:process'\n\nimport { writeEnvLoadFile } from 'src/commands/env-load'\nimport {\n ENV_CLEAR_FILE,\n ENV_LOAD_FILE,\n INFRA_KIT_ENV_AUTOLOADED_VAR,\n INFRA_KIT_ENV_CLEARED_VAR,\n INFRA_KIT_ENV_CONFIG_VAR,\n INFRA_KIT_ENV_PROJECT_VAR,\n INFRA_KIT_SESSION_VAR,\n getSessionCacheDir,\n} from 'src/lib/constants'\nimport type { EnvAutoLoadConfig } from 'src/lib/infra-kit-config'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\n\n/** Which moment a concrete callsite represents. Matches the config `trigger`. */\nexport type AutoLoadTrigger = EnvAutoLoadConfig['trigger']\n\n/** Per-session flag file that de-dups the auto-load warning (misconfig or failure). */\nconst WARN_SENTINEL_FILE = 'autoload-warn.flag'\n\n/** Per-session marker recording the last auto-load failure (mtime = when). */\nconst FAIL_SENTINEL_FILE = 'autoload-fail.flag'\n\n/**\n * After a failed auto-load, suppress retries for this long so a down/unauthenticated\n * Doppler isn't re-probed on every cli-invocation. A new shell starts a fresh\n * session cache dir, so this only throttles within one session.\n */\nconst FAIL_BACKOFF_MS = 30_000\n\n/** Resolved auto-load inputs: the chosen trigger + the env config and Doppler project to load. */\nexport interface ResolvedEnvAutoLoad {\n trigger: AutoLoadTrigger\n config: string\n project: string\n}\n\n/**\n * Read the resolved + validated env auto-load inputs, or `null` when auto-load\n * should not run. Returns `null` (never throws) when:\n * - we're not inside an infra-kit project (getInfraKitConfig throws), or config is unreadable;\n * - `envAutoLoad` is absent (feature off);\n * - `envAutoLoad.config` is not one of `environments` \u2014 warns once per session, then disables.\n *\n * Validation lives here (not in the schema) so a typo only disables this optional\n * feature instead of throwing inside the merged-config parse and breaking every command.\n * Resolves the Doppler project from the SAME config read (no second getInfraKitConfig),\n * so the skip path stays cheap.\n *\n * `canWarn` gates the misconfig warning: the shell-startup callsite runs backgrounded\n * with stderr discarded, so warning there is invisible AND would write the dedup flag,\n * poisoning the only channel (cli-invocation / interactive) that can actually surface\n * it. So shell-startup passes `false`; interactive callsites pass `true`.\n */\nexport const resolveEnvAutoLoad = async (canWarn = true): Promise<ResolvedEnvAutoLoad | null> => {\n let config\n\n try {\n config = await getInfraKitConfig()\n } catch {\n return null\n }\n\n const autoLoad = config.envAutoLoad\n\n if (!autoLoad) return null\n\n if (!config.environments.includes(autoLoad.config)) {\n if (canWarn) {\n warnOnce(\n `infra-kit: envAutoLoad.config \"${autoLoad.config}\" is not one of environments [${config.environments.join(\n ', ',\n )}] \u2014 env auto-load disabled.`,\n )\n }\n\n return null\n }\n\n return {\n trigger: autoLoad.trigger,\n config: autoLoad.config,\n project: config.envManagement.config.name,\n }\n}\n\n/** The env-var snapshot the freshness/suppression guards read. */\nexport interface AutoLoadEnvSnapshot {\n session?: string\n cleared?: string\n currentConfig?: string\n currentProject?: string\n autoLoadedMarker?: string\n}\n\nexport interface AutoLoadDecisionInput {\n /** The configured trigger. */\n trigger: AutoLoadTrigger\n /** Which trigger this callsite represents. */\n expectedTrigger: AutoLoadTrigger\n targetConfig: string\n targetProject: string\n env: AutoLoadEnvSnapshot\n}\n\nexport type AutoLoadDecision = 'load' | 'skip'\n\n/**\n * Pure decision: should this callsite (auto-)load env right now? Encodes the full\n * guard matrix so it is exhaustively unit-testable without Doppler or a shell:\n * - the configured trigger must match this callsite;\n * - a session must exist (the cache dir is session-scoped);\n * - an explicit clear suppresses auto-load (M2);\n * - a MANUAL load (config set, no auto marker) is never clobbered (C1);\n * - an auto-load already fresh for the same config AND project is a no-op\n * (project-aware so two same-named configs across different-repo worktrees\n * sharing one session don't leak each other's secrets).\n */\nexport const decideAutoLoad = (input: AutoLoadDecisionInput): AutoLoadDecision => {\n const { trigger, expectedTrigger, targetConfig, targetProject, env } = input\n\n if (trigger !== expectedTrigger) return 'skip'\n\n if (!env.session) return 'skip'\n\n if (env.cleared) return 'skip'\n\n // Manual load present (a config is loaded but it wasn't auto-loaded) \u2014 leave it.\n if (env.currentConfig && !env.autoLoadedMarker) return 'skip'\n\n // Our own auto-load already matches the target config+project \u2014 nothing to do.\n if (env.autoLoadedMarker && env.currentConfig === targetConfig && env.currentProject === targetProject) {\n return 'skip'\n }\n\n return 'load'\n}\n\nexport interface RunEnvAutoLoadArgs {\n expectedTrigger: AutoLoadTrigger\n}\n\n/**\n * Resolve config, evaluate the guards, and (if it should) produce env-load.sh with\n * the auto-load marker. Returns the written file path, or `null` when auto-load was\n * skipped or failed. NEVER throws. Transient failures (Doppler offline / not\n * authenticated / network) record a backoff marker so they aren't re-probed on every\n * command, and are surfaced once per session on the interactive (cli-invocation)\n * channel. No producer-side lock \u2014 a rare cold-shell double-fetch is tolerated (the\n * second write is atomic and idempotent).\n */\nexport const runEnvAutoLoad = async ({ expectedTrigger }: RunEnvAutoLoadArgs): Promise<string | null> => {\n // Only the cli-invocation / interactive callsite reaches a TTY; the shell-startup\n // spawn discards stderr, so warning there is invisible and would poison the dedup.\n const canWarn = expectedTrigger === 'cli-invocation'\n\n try {\n const resolved = await resolveEnvAutoLoad(canWarn)\n\n if (!resolved) return null\n\n const decision = decideAutoLoad({\n trigger: resolved.trigger,\n expectedTrigger,\n targetConfig: resolved.config,\n targetProject: resolved.project,\n env: readAutoLoadEnvSnapshot(),\n })\n\n if (decision === 'skip') return null\n\n // Disk-level clear signal: a clear that hasn't yet been sourced into this\n // process's env still suppresses auto-load (clear file newer than load file).\n if (isClearedOnDisk()) return null\n\n // Back off after a recent failure so a down/unauthenticated Doppler isn't\n // re-probed on every command in the same session.\n if (recentlyFailed()) return null\n\n const result = await writeEnvLoadFile({ config: resolved.config, autoLoaded: true })\n\n clearFailure()\n\n return result.filePath\n } catch (error) {\n const reason = (error as Error).message\n\n recordFailure()\n\n // Surface the failure once per session on the interactive channel; stay silent\n // (debug only) on the backgrounded shell-startup path.\n if (canWarn) {\n warnOnce(`infra-kit: env auto-load failed \u2014 ${reason} (will retry later)`)\n } else {\n logger.debug(`env auto-load skipped: ${reason}`)\n }\n\n return null\n }\n}\n\n/** Snapshot the env vars the guards depend on. */\nconst readAutoLoadEnvSnapshot = (): AutoLoadEnvSnapshot => {\n return {\n session: process.env[INFRA_KIT_SESSION_VAR],\n cleared: process.env[INFRA_KIT_ENV_CLEARED_VAR],\n currentConfig: process.env[INFRA_KIT_ENV_CONFIG_VAR],\n currentProject: process.env[INFRA_KIT_ENV_PROJECT_VAR],\n autoLoadedMarker: process.env[INFRA_KIT_ENV_AUTOLOADED_VAR],\n }\n}\n\n/**\n * True when a clear is pending on disk: an env-clear.sh exists and is at least as\n * new as env-load.sh (or no load file remains). Belt-and-suspenders next to the\n * INFRA_KIT_ENV_CLEARED env guard for the window before the shell sources the clear.\n */\nconst isClearedOnDisk = (): boolean => {\n try {\n const dir = getSessionCacheDir()\n const clearPath = path.join(dir, ENV_CLEAR_FILE)\n\n if (!fs.existsSync(clearPath)) return false\n\n const loadPath = path.join(dir, ENV_LOAD_FILE)\n\n if (!fs.existsSync(loadPath)) return true\n\n return fs.statSync(clearPath).mtimeMs >= fs.statSync(loadPath).mtimeMs\n } catch {\n return false\n }\n}\n\n/** True when an auto-load failed within the backoff window (suppress retries). */\nconst recentlyFailed = (): boolean => {\n try {\n const flagPath = path.join(getSessionCacheDir(), FAIL_SENTINEL_FILE)\n\n if (!fs.existsSync(flagPath)) return false\n\n return Date.now() - fs.statSync(flagPath).mtimeMs < FAIL_BACKOFF_MS\n } catch {\n return false\n }\n}\n\n/** Record an auto-load failure (refreshes the backoff window). */\nconst recordFailure = (): void => {\n try {\n const dir = getSessionCacheDir()\n\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 })\n fs.writeFileSync(path.join(dir, FAIL_SENTINEL_FILE), '', { mode: 0o600 })\n } catch {\n // No session cache dir \u2014 nothing to back off against.\n }\n}\n\n/** Clear the failure marker after a successful load. */\nconst clearFailure = (): void => {\n try {\n fs.rmSync(path.join(getSessionCacheDir(), FAIL_SENTINEL_FILE), { force: true })\n } catch {\n // No session cache dir \u2014 nothing to clear.\n }\n}\n\n/**\n * Emit a warning at most once per shell session. Keyed on a flag file in the\n * session cache dir so a misconfigured `envAutoLoad.config` (or a repeated failure)\n * does not spam a warning on every cli-invocation. Falls back to a plain warn when\n * no session cache dir is available.\n */\nconst warnOnce = (message: string): void => {\n try {\n const dir = getSessionCacheDir()\n const flagPath = path.join(dir, WARN_SENTINEL_FILE)\n\n if (fs.existsSync(flagPath)) return\n\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 })\n fs.writeFileSync(flagPath, '', { mode: 0o600 })\n } catch {\n // No session cache dir (e.g. INFRA_KIT_SESSION unset) \u2014 warn without de-dup.\n }\n\n logger.warn(message)\n}\n", "import { runEnvAutoLoad } from 'src/lib/env-autoload'\n\n/**\n * Internal command invoked (backgrounded) by the `infra-kit init` shell-startup\n * integration. Runs the 'shell-startup' trigger, writing env-load.sh when\n * envAutoLoad is configured for it + eligible; the shell precmd hook sources it on\n * a subsequent prompt. Intentionally writes NOTHING to stdout and never throws \u2014\n * auto-load must never disrupt shell startup.\n */\nexport const envAutoload = async (): Promise<void> => {\n await runEnvAutoLoad({ expectedTrigger: 'shell-startup' })\n}\n", "import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { pathToFileURL } from 'node:url'\n\nimport { getProjectRoot } from 'src/lib/git-utils'\nimport { logger } from 'src/lib/logger'\nimport { fileExists, tildify } from 'src/lib/path-display'\nimport { VENDOR_CONFIG_FILE } from 'src/lib/vendor/config-schema'\nimport { expandTilde, getFactoryConfigPath, loadFactoryConfig } from 'src/lib/vendor/factory-config'\n\ninterface VendorConfigOptions {\n /** Scaffold `~/.infra-kit/vendor.json` instead of printing the current one. */\n init?: boolean\n /** Source repo root used for legacy `targets` auto-seeding. Defaults to the git toplevel. */\n cwd?: string\n}\n\n/** Placeholder workspace dir written by `--init`; the user edits it to their layout. */\nconst PLACEHOLDER_WORKSPACE_DIR = '~/projects'\n\n/**\n * Surface or scaffold the machine-local factory config\n * (`~/.infra-kit/vendor.json`). CLI-only \u2014 NOT an MCP tool; returns nothing\n * and signals problems via `process.exitCode`.\n *\n * Without `--init`: prints the factory file path + existence, the resolved\n * `workspaceDir` + existence, and per-target reachability (`[\u2713]`/`[ ]`). Exits\n * non-zero if the file is missing, the workspace dir is missing, or any target\n * is unreachable, so it is usable as a doctor check.\n *\n * With `--init`: scaffolds the file (skipping if it already exists), seeding\n * `targets` from a legacy source `vendor.config.ts` when one is readable.\n */\nexport const vendorConfig = async (options: VendorConfigOptions = {}): Promise<void> => {\n if (options.init) {\n await initFactoryConfig(options.cwd)\n\n return\n }\n\n await printFactoryConfig()\n}\n\n/** Render the factory config chain with `[\u2713]`/`[ ]` reachability markers. */\nconst printFactoryConfig = async (): Promise<void> => {\n const factoryPath = getFactoryConfigPath()\n const exists = await fileExists(factoryPath)\n\n logger.info(`Factory config: ${tildify(factoryPath)} ${exists ? '[\u2713]' : '[ ]'}`)\n\n if (!exists) {\n logger.info('\\nNot found \u2014 run `infra-kit vendor-config --init` to scaffold it.')\n process.exitCode = 1\n\n return\n }\n\n const { workspaceDir, targets } = await loadFactoryConfig()\n const resolvedWorkspace = expandTilde(workspaceDir)\n const workspaceExists = await fileExists(resolvedWorkspace)\n\n logger.info(\n `workspaceDir: ${workspaceDir} (resolved: ${resolvedWorkspace}) ${workspaceExists ? '[\u2713 exists]' : '[ ] not found'}`,\n )\n logger.info('Targets:')\n\n let allReachable = workspaceExists\n\n for (const repo of targets) {\n const targetPath = path.join(resolvedWorkspace, repo)\n const reachable = await fileExists(targetPath)\n\n if (!reachable) {\n allReachable = false\n }\n\n const marker = reachable ? '[\u2713]' : '[ ]'\n const suffix = reachable ? '' : ' (not found \u2014 clone or remove)'\n\n logger.info(` ${marker} ${repo} ${tildify(targetPath)}${suffix}`)\n }\n\n if (!allReachable) {\n process.exitCode = 1\n }\n}\n\n/** Scaffold `~/.infra-kit/vendor.json`, skipping if it already exists. */\nconst initFactoryConfig = async (cwd?: string): Promise<void> => {\n const factoryPath = getFactoryConfigPath()\n\n if (await fileExists(factoryPath)) {\n logger.info(`Factory config already exists at ${tildify(factoryPath)} \u2014 leaving it untouched.`)\n\n return\n }\n\n const sourceRoot = cwd ?? (await getProjectRoot())\n const seededTargets = await readLegacyTargets(sourceRoot)\n\n await fs.mkdir(path.dirname(factoryPath), { recursive: true })\n await fs.writeFile(factoryPath, buildScaffold(seededTargets), 'utf-8')\n\n logger.info(`\u2713 Created ${tildify(factoryPath)}`)\n\n if (seededTargets.length > 0) {\n logger.info(` Seeded ${seededTargets.length} target(s) from the source ${VENDOR_CONFIG_FILE}.`)\n }\n\n logger.info(` Edit \\`workspaceDir\\` (placeholder: ${PLACEHOLDER_WORKSPACE_DIR}) to point at where your repos live.`)\n\n if (seededTargets.length === 0) {\n logger.info(' Add at least one repo name to `targets` before running vendor sync/manifest/diff.')\n }\n}\n\n/**\n * Best-effort read of a legacy `targets` array from the source repo's\n * `vendor.config.ts`. The current schema no longer accepts `targets`, so this\n * reads the raw default export directly (bypassing validation). Returns `[]` on\n * any failure \u2014 seeding is a convenience, never a hard requirement.\n */\nconst readLegacyTargets = async (sourceRoot: string): Promise<string[]> => {\n try {\n const configPath = path.join(sourceRoot, VENDOR_CONFIG_FILE)\n const stat = await fs.stat(configPath)\n const moduleUrl = `${pathToFileURL(configPath).href}?mtime=${Number(stat.mtimeMs)}`\n const imported = (await import(moduleUrl)) as { default?: unknown }\n const raw = imported.default\n const resolved = typeof raw === 'function' ? await (raw as () => unknown)() : raw\n\n if (resolved && typeof resolved === 'object' && 'targets' in resolved) {\n const targets = (resolved as { targets?: unknown }).targets\n\n if (\n Array.isArray(targets) &&\n targets.every((t) => {\n return typeof t === 'string'\n })\n ) {\n return targets as string[]\n }\n }\n } catch {\n // Absent or unreadable source config \u2014 fall through to an empty placeholder.\n }\n\n return []\n}\n\n/**\n * Render the scaffold file body as strict JSON (`vendor.json`). The factory config\n * is static JSON, loaded with `JSON.parse` \u2014 no comments, no executable code. When\n * `targets` is empty the stub writes `\"targets\": []`, which fails the schema's\n * `targets.min(1)` on load: this is intentional \u2014 `--init` produces an incomplete\n * stub the user must edit before running vendor sync/manifest/diff. The annotated\n * guidance lives in the sibling `vendor.example.jsonc` (seeded by `infra-kit init`).\n */\nconst buildScaffold = (targets: string[]): string => {\n return `${JSON.stringify({ workspaceDir: PLACEHOLDER_WORKSPACE_DIR, targets }, null, 2)}\\n`\n}\n", "import type { Command } from 'commander'\nimport process from 'node:process'\n\n/**\n * `--json` output mode for the CLI. This is a presentation concern only: every\n * command handler already returns a `structuredContent` payload (the same one\n * the MCP surface consumes). Human/log output goes to stderr (see lib/logger),\n * so writing the structured payload to stdout never collides with it.\n */\n\nexport interface CommandResult {\n structuredContent?: unknown\n}\n\n/** Mutable holder (object so `prefer-const` holds while the flag toggles per run). */\nexport const jsonOutput = { enabled: false }\n\n/**\n * In `--json` mode, write a command result's `structuredContent` to stdout as\n * pretty JSON and return the result unchanged. Outside `--json` mode it is a\n * no-op pass-through. The writer is injectable for testing.\n */\nexport const emit = <T extends CommandResult | void>(\n result: T,\n write: (text: string) => void = (text) => {\n process.stdout.write(text)\n },\n): T => {\n if (jsonOutput.enabled && result && result.structuredContent != null) {\n write(`${JSON.stringify(result.structuredContent, null, 2)}\\n`)\n }\n\n return result\n}\n\n/** Register `--json` on a command and every nested subcommand (idempotent). */\nexport const addJsonOption = (cmd: Command): void => {\n const alreadyHasJson = cmd.options.some((option) => {\n return option.long === '--json'\n })\n\n if (!alreadyHasJson) {\n cmd.option('--json', 'Output the structured result as JSON on stdout (human logs stay on stderr)')\n }\n\n cmd.commands.forEach(addJsonOption)\n}\n", "/**\n * Small shared rendering helpers for aligned terminal output. These replace\n * the ad-hoc \"compute the max width, then padEnd each row\" pattern that the\n * interactive menu (and similar list views) hand-rolled. Pure string helpers \u2014\n * no I/O, no color \u2014 so they are trivially testable and reusable.\n */\n\n/**\n * Align a list of two-column rows: pad every left cell to the widest left cell,\n * then join the two cells with `gap`. Returns one rendered line per row.\n *\n * @example\n * formatAlignedRows([['a', 'x'], ['bbb', 'y']])\n * // ['a x', 'bbb y'] (left padded to width 3, default 2-space gap)\n */\nexport const formatAlignedRows = (rows: ReadonlyArray<readonly [string, string]>, gap = ' '): string[] => {\n const width = rows.reduce((max, [left]) => {\n return Math.max(max, left.length)\n }, 0)\n\n return rows.map(([left, right]) => {\n return `${left.padEnd(width)}${gap}${right}`\n })\n}\n"],
5
- "mappings": "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",
6
- "names": ["select", "Separator", "Command", "process", "fs", "path", "process", "$", "configPath", "paths", "getInfraKitConfigPaths", "rows", "row", "fileExists", "logger", "marker", "tildify", "structuredContent", "configEdit", "editor", "process", "fs", "path", "examplePath", "exampleSiblingPath", "buildUserProjectExample", "$", "resetInfraKitConfigCache", "jsonPath", "projectName", "fs", "path", "process", "WARN_SENTINEL_FILE", "FAIL_SENTINEL_FILE", "FAIL_BACKOFF_MS", "resolveEnvAutoLoad", "canWarn", "config", "getInfraKitConfig", "autoLoad", "warnOnce", "decideAutoLoad", "input", "trigger", "expectedTrigger", "targetConfig", "targetProject", "env", "runEnvAutoLoad", "resolved", "readAutoLoadEnvSnapshot", "isClearedOnDisk", "recentlyFailed", "result", "writeEnvLoadFile", "clearFailure", "error", "reason", "recordFailure", "logger", "process", "INFRA_KIT_SESSION_VAR", "INFRA_KIT_ENV_CLEARED_VAR", "INFRA_KIT_ENV_CONFIG_VAR", "INFRA_KIT_ENV_PROJECT_VAR", "INFRA_KIT_ENV_AUTOLOADED_VAR", "dir", "getSessionCacheDir", "clearPath", "path", "ENV_CLEAR_FILE", "fs", "loadPath", "ENV_LOAD_FILE", "flagPath", "message", "envAutoload", "runEnvAutoLoad", "fs", "path", "process", "pathToFileURL", "PLACEHOLDER_WORKSPACE_DIR", "vendorConfig", "options", "initFactoryConfig", "printFactoryConfig", "factoryPath", "getFactoryConfigPath", "exists", "fileExists", "logger", "tildify", "process", "workspaceDir", "targets", "loadFactoryConfig", "resolvedWorkspace", "expandTilde", "workspaceExists", "allReachable", "repo", "targetPath", "path", "reachable", "marker", "suffix", "cwd", "sourceRoot", "getProjectRoot", "seededTargets", "readLegacyTargets", "fs", "buildScaffold", "VENDOR_CONFIG_FILE", "configPath", "stat", "raw", "pathToFileURL", "resolved", "t", "process", "jsonOutput", "emit", "result", "write", "text", "addJsonOption", "cmd", "option", "formatAlignedRows", "rows", "gap", "width", "max", "left", "right", "program", "Command", "collectReleaseSpec", "value", "prev", "parseRepos", "normalizeIdeMode", "flagName", "IDE_MODES", "runProgram", "argv", "error", "message", "logger", "process", "invokedViaMenu", "deprecatedAlias", "cmd", "preferred", "configureMergeDev", "options", "emit", "ghMergeDev", "configureReleaseList", "ghReleaseList", "configureReleaseCreate", "inputs", "parseReleaseSpec", "releases", "releaseCreate", "configureReleaseDescEdit", "releaseDescEdit", "configureReleaseDeployAll", "ghReleaseDeployAll", "configureReleaseDeploySelected", "ghReleaseDeploySelected", "configureReleaseDeliver", "ghReleaseDeliver", "configureWorktreesSync", "worktreesSync", "configureWorktreesAdd", "ide", "worktreesAdd", "configureWorktreesList", "worktreesList", "configureWorktreesRemove", "worktreesRemove", "configureWorktreesReload", "worktreesReload", "configureVendorConfig", "vendorConfig", "releaseGroup", "worktreesGroup", "configCmd", "configPath", "configEdit", "result", "audit", "vendorCmd", "vendorCheck", "vendorSync", "vendorManifest", "vendorDiff", "doctor", "version", "envStatus", "envList", "init", "envLoad", "envClear", "envAutoload", "addJsonOption", "isAutoLoadExcludedCommand", "name", "_thisCommand", "actionCommand", "jsonOutput", "runEnvAutoLoad", "releaseCommands", "getMenuGroupCommands", "worktreeCommands", "envCommands", "commandMap", "paletteItems", "label", "names", "selected", "runCommandPalette", "alignedLabels", "formatAlignedRows", "item", "labelByName", "index", "toChoices", "select", "Separator"]
4
+ "sourcesContent": ["import select, { Separator } from '@inquirer/select'\nimport { Command } from 'commander'\nimport process from 'node:process'\n\nimport { audit } from 'src/commands/audit'\nimport { configEdit, configPath } from 'src/commands/config'\nimport { doctor } from 'src/commands/doctor'\nimport { envAutoload } from 'src/commands/env-autoload'\nimport { envClear } from 'src/commands/env-clear'\nimport { envList } from 'src/commands/env-list'\nimport { envLoad } from 'src/commands/env-load'\nimport { envStatus } from 'src/commands/env-status'\nimport { ghMergeDev } from 'src/commands/gh-merge-dev'\nimport { ghReleaseDeliver } from 'src/commands/gh-release-deliver'\nimport { ghReleaseDeployAll } from 'src/commands/gh-release-deploy-all'\nimport { ghReleaseDeploySelected } from 'src/commands/gh-release-deploy-selected'\nimport { ghReleaseList } from 'src/commands/gh-release-list'\nimport { init } from 'src/commands/init'\nimport { releaseCreate } from 'src/commands/release-create'\nimport { releaseDescEdit } from 'src/commands/release-desc-edit'\nimport { vendorCheck } from 'src/commands/vendor-check'\nimport { vendorConfig } from 'src/commands/vendor-config'\nimport { vendorDiff } from 'src/commands/vendor-diff'\nimport { vendorManifest } from 'src/commands/vendor-manifest'\nimport { vendorSync } from 'src/commands/vendor-sync'\nimport { version } from 'src/commands/version'\nimport { worktreesAdd } from 'src/commands/worktrees-add'\nimport { worktreesList } from 'src/commands/worktrees-list'\nimport { worktreesReload } from 'src/commands/worktrees-reload'\nimport { worktreesRemove } from 'src/commands/worktrees-remove'\nimport { worktreesSync } from 'src/commands/worktrees-sync'\nimport { IDE_MODES } from 'src/integrations/ide'\nimport type { IdeMode } from 'src/integrations/ide'\nimport { getMenuGroupCommands } from 'src/lib/command-catalog'\nimport { runEnvAutoLoad } from 'src/lib/env-autoload'\nimport { isPromptCancellation } from 'src/lib/errors/is-prompt-cancellation'\nimport { addJsonOption, emit, jsonOutput } from 'src/lib/json-output'\nimport { logger } from 'src/lib/logger'\nimport { formatAlignedRows } from 'src/lib/render'\nimport { parseReleaseSpec } from 'src/lib/version-utils'\nimport type { ReleaseInput } from 'src/lib/version-utils'\n\nconst program = new Command()\n\nconst collectReleaseSpec = (value: string, prev: string[]): string[] => {\n return [...prev, value]\n}\n\n/** Parse a `--repos a,b,c` option into a target-name list (undefined = all). */\nconst parseRepos = (value: unknown): string[] | undefined => {\n return typeof value === 'string' ? value.split(',').filter(Boolean) : undefined\n}\n\nconst normalizeIdeMode = (value: unknown, flagName: '--ide' | '--cursor'): IdeMode | undefined => {\n if (typeof value === 'undefined') {\n return undefined\n }\n\n if (value === true) {\n return 'workspace'\n }\n\n if (value === false) {\n return 'none'\n }\n\n if (typeof value === 'string' && (IDE_MODES as readonly string[]).includes(value)) {\n return value as IdeMode\n }\n\n throw new Error(`Invalid ${flagName} value \"${String(value)}\". Expected one of: ${IDE_MODES.join(', ')}.`)\n}\n\nconst runProgram = async (argv?: string[]): Promise<void> => {\n try {\n if (argv) {\n await program.parseAsync(argv)\n } else {\n await program.parseAsync()\n }\n } catch (error) {\n // Ctrl-C / Esc out of any prompt is a deliberate back-out, not a failure:\n // exit quietly with success so it matches the explicit \"Operation cancelled.\"\n // decline path and never trips scripts/CI into treating a cancel as an error.\n if (isPromptCancellation(error)) {\n logger.info('Operation cancelled.')\n process.exit(0)\n }\n\n const message = error instanceof Error ? error.message : String(error)\n\n logger.error(message)\n process.exit(1)\n }\n}\n\n// --- Deprecation support for flat command aliases (Phase 3 grouping) ---\n// Flat names (`release-create`, `worktrees-add`, `vendor-config`, ...) are kept\n// as working aliases of the grouped forms (`release create`, ...) for one\n// release cycle. They warn once when invoked directly, but stay silent when the\n// interactive no-arg menu drives them (the menu is a guided surface).\nconst invokedViaMenu = { value: false }\n\nconst deprecatedAlias = (cmd: Command, preferred: string): Command => {\n return cmd.hook('preAction', () => {\n if (!invokedViaMenu.value) {\n logger.warn(`\"${cmd.name()}\" is a deprecated alias; use \"${preferred}\" instead.`)\n }\n })\n}\n\n// --- Command configurators (one source of options + action, shared by the\n// grouped form and its flat alias so the two can never diverge) ---\nconst configureMergeDev = (cmd: Command): Command => {\n return cmd\n .description('Merge dev branch into every release branch')\n .option('-a, --all', 'Select all active release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(await ghMergeDev({ all: options.all, confirmedCommand: options.yes }))\n })\n}\n\nconst configureReleaseList = (cmd: Command): Command => {\n return cmd.description('List all release branches').action(async () => {\n emit(await ghReleaseList())\n })\n}\n\nconst configureReleaseCreate = (cmd: Command): Command => {\n return cmd\n .description('Create one or more release branches (each entry can mix regular/hotfix and its own description)')\n .option(\n '-r, --release <spec>',\n 'Release spec \"<version|next|name>[:type[:description]]\" (repeatable). The token is a semver (\"1.2.5\"), the literal \"next\", or a kebab-case name (\"checkout-redesign\"). Type is regular|hotfix (default regular). Examples: \"1.2.5\", \"1.2.5:hotfix\", \"next:regular:Holiday backend\", \"checkout-redesign:regular:Q3 redesign\".',\n collectReleaseSpec,\n [],\n )\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n const specs = options.release as string[]\n const inputs: ReleaseInput[] = specs.map(parseReleaseSpec)\n const releases = inputs.length > 0 ? inputs : undefined\n\n emit(\n await releaseCreate({\n releases,\n confirmedCommand: options.yes,\n }),\n )\n })\n}\n\nconst configureReleaseDescEdit = (cmd: Command): Command => {\n return cmd\n .description(\"Edit a release's description in Jira and in the matching GitHub PR body\")\n .option('-v, --version <version>', 'Release version (e.g. 1.2.5) or release name (e.g. checkout-redesign)')\n .option('-d, --description <description>', 'New description (use \"\" to clear)')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(\n await releaseDescEdit({\n version: options.version,\n description: options.description,\n confirmedCommand: options.yes,\n }),\n )\n })\n}\n\nconst configureReleaseDeployAll = (cmd: Command): Command => {\n return cmd\n .description('Deploy any release branch to any environment')\n .option(\n '-v, --version <version>',\n 'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deploy; \"dev\" deploys from the dev branch',\n )\n .option('-e, --env <env>', 'Specify the environment to deploy to, e.g. dev')\n .option('--skip-terraform', 'Skip terraform deployment step')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(\n await ghReleaseDeployAll({\n version: options.version,\n env: options.env,\n skipTerraform: options.skipTerraform,\n confirmedCommand: options.yes,\n }),\n )\n })\n}\n\nconst configureReleaseDeploySelected = (cmd: Command): Command => {\n return cmd\n .description('Deploy selected services from release branch to any environment')\n .option(\n '-v, --version <version>',\n 'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deploy; \"dev\" deploys from the dev branch',\n )\n .option('-e, --env <env>', 'Specify the environment to deploy to, e.g. dev')\n .option('-s, --services <services...>', 'Specify services to deploy, e.g. client-be client-fe')\n .option('--skip-terraform', 'Skip terraform deployment step')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(\n await ghReleaseDeploySelected({\n version: options.version,\n env: options.env,\n services: options.services,\n skipTerraform: options.skipTerraform,\n confirmedCommand: options.yes,\n }),\n )\n })\n}\n\nconst configureReleaseDeliver = (cmd: Command): Command => {\n return cmd\n .description('Release a new version to production')\n .option('-v, --version <version>', 'Version (e.g. 1.2.5) or release name (e.g. checkout-redesign) to deliver')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(await ghReleaseDeliver({ version: options.version, confirmedCommand: options.yes }))\n })\n}\n\nconst configureWorktreesSync = (cmd: Command): Command => {\n return cmd\n .description('Remove release worktrees whose PRs are no longer open')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n emit(await worktreesSync({ confirmedCommand: options.yes }))\n })\n}\n\nconst configureWorktreesAdd = (cmd: Command): Command => {\n return cmd\n .description('Add git worktrees for release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-a, --all', 'Select all active release branches')\n .option('-v, --versions <versions>', 'Specify versions by comma, e.g. 1.2.5, 1.2.6')\n .option('-i, --ide [mode]', 'Editor mode for created worktrees: workspace (default) | none')\n .option('--no-ide', 'Skip the editor (alias for --ide none)')\n .option('-c, --cursor [mode]', 'Deprecated alias for --ide')\n .option('--no-cursor', 'Deprecated alias for --no-ide')\n .option('-g, --github-desktop', 'Open created worktrees in GitHub Desktop')\n .option('--no-github-desktop', 'Skip GitHub Desktop prompt')\n .option('-m, --cmux', 'Open created worktrees in cmux (3-pane layout)')\n .option('--no-cmux', 'Skip cmux prompt')\n .action(async (options) => {\n // `--ide` wins over the deprecated `--cursor` alias when both are provided.\n const ide = normalizeIdeMode(options.ide, '--ide') ?? normalizeIdeMode(options.cursor, '--cursor')\n\n emit(\n await worktreesAdd({\n confirmedCommand: options.yes,\n all: options.all,\n versions: options.versions,\n ide,\n githubDesktop: options.githubDesktop,\n cmux: options.cmux,\n }),\n )\n })\n}\n\nconst configureWorktreesList = (cmd: Command): Command => {\n return cmd.description('List all git worktrees with detailed information').action(async () => {\n emit(await worktreesList())\n })\n}\n\nconst configureWorktreesRemove = (cmd: Command): Command => {\n return cmd\n .description('Remove git worktrees for release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-a, --all', 'Select all active release branches')\n .option('-v, --versions <versions>', 'Specify versions by comma, e.g. 1.2.5, 1.2.6')\n .action(async (options) => {\n emit(await worktreesRemove({ confirmedCommand: options.yes, all: options.all, versions: options.versions }))\n })\n}\n\nconst configureWorktreesReload = (cmd: Command): Command => {\n return cmd\n .description(\n 'Close all cmux/editor worktree windows, then reopen the current release worktrees (also cold-start restore)',\n )\n .action(async () => {\n emit(await worktreesReload())\n })\n}\n\nconst configureVendorConfig = (cmd: Command): Command => {\n return cmd\n .description('Show the machine-local factory config (~/.infra-kit/vendor.json) or scaffold it with --init')\n .option('--init', 'Scaffold ~/.infra-kit/vendor.json (skips if it already exists)')\n .action(async (options) => {\n emit(await vendorConfig({ init: options.init }))\n })\n}\n\n// --- Grouped command surface (preferred form) ---\nconst releaseGroup = program.command('release').description('Release management commands')\n\nconfigureMergeDev(releaseGroup.command('merge-dev'))\nconfigureReleaseList(releaseGroup.command('list'))\nconfigureReleaseCreate(releaseGroup.command('create'))\nconfigureReleaseDescEdit(releaseGroup.command('desc-edit'))\nconfigureReleaseDeployAll(releaseGroup.command('deploy-all'))\nconfigureReleaseDeploySelected(releaseGroup.command('deploy-selected'))\nconfigureReleaseDeliver(releaseGroup.command('deliver'))\n\nconst worktreesGroup = program.command('worktrees').description('Git worktree management commands')\n\nconfigureWorktreesAdd(worktreesGroup.command('add'))\nconfigureWorktreesList(worktreesGroup.command('list'))\nconfigureWorktreesRemove(worktreesGroup.command('remove'))\nconfigureWorktreesSync(worktreesGroup.command('sync'))\nconfigureWorktreesReload(worktreesGroup.command('reload'))\n\n// --- Deprecated flat aliases (kept one release cycle; warn when used directly) ---\ndeprecatedAlias(configureMergeDev(program.command('merge-dev')), 'release merge-dev')\ndeprecatedAlias(configureReleaseList(program.command('release-list')), 'release list')\ndeprecatedAlias(configureReleaseCreate(program.command('release-create')), 'release create')\ndeprecatedAlias(configureReleaseDescEdit(program.command('release-desc-edit')), 'release desc-edit')\ndeprecatedAlias(configureReleaseDeployAll(program.command('release-deploy-all')), 'release deploy-all')\ndeprecatedAlias(configureReleaseDeploySelected(program.command('release-deploy-selected')), 'release deploy-selected')\ndeprecatedAlias(configureReleaseDeliver(program.command('release-deliver')), 'release deliver')\ndeprecatedAlias(configureWorktreesAdd(program.command('worktrees-add')), 'worktrees add')\ndeprecatedAlias(configureWorktreesList(program.command('worktrees-list')), 'worktrees list')\ndeprecatedAlias(configureWorktreesRemove(program.command('worktrees-remove')), 'worktrees remove')\ndeprecatedAlias(configureWorktreesSync(program.command('worktrees-sync')), 'worktrees sync')\ndeprecatedAlias(configureWorktreesReload(program.command('worktrees-reload')), 'worktrees reload')\n\nconst configCmd = program.command('config').description('Manage infra-kit configuration files')\n\nconfigCmd\n .command('path')\n .description('Show the resolved config merge chain and file paths')\n .action(async () => {\n emit(await configPath())\n })\n\nconfigCmd\n .command('edit')\n .description('Open the user-scope per-project override file in $EDITOR')\n .action(async () => {\n emit(await configEdit())\n })\n\nprogram\n .command('audit')\n .description('Audit against infra-kit.config.ts rules (--all for every package, --root for the monorepo root)')\n .option('-a, --all', 'Audit every non-vendor workspace package')\n .option('-r, --root', 'Audit the monorepo root (turbo pipeline + root commands)')\n .action(async (options) => {\n const result = await audit({ all: options.all, root: options.root })\n\n emit(result)\n\n if (!result.structuredContent.allPassed) {\n process.exitCode = 1\n }\n })\n\nconst vendorCmd = program.command('vendor').description('Verify and sync the mirrored vendor/ tree')\n\nvendorCmd\n .command('check')\n .description('Verify vendor/ matches vendor/.sync-manifest.json (self-contained; for any consumer repo)')\n .action(async () => {\n const result = await vendorCheck()\n\n emit(result)\n\n if (!result.structuredContent.ok) {\n process.exitCode = 1\n }\n })\n\nvendorCmd\n .command('sync')\n .description('Copy vendored files from the source repo into each target and regenerate manifests')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-r, --repos <repos>', 'Restrict to comma-separated target repo names')\n .action(async (options) => {\n emit(await vendorSync({ confirmedCommand: options.yes, repos: parseRepos(options.repos) }))\n })\n\nvendorCmd\n .command('manifest')\n .description('Regenerate each target vendor/.sync-manifest.json + README from current content (no copy)')\n .option('-r, --repos <repos>', 'Restrict to comma-separated target repo names')\n .action(async (options) => {\n emit(await vendorManifest({ confirmedCommand: true, repos: parseRepos(options.repos) }))\n })\n\nvendorCmd\n .command('diff')\n .description('Source-aware drift check (rsync dry-run) of each target vendored subtree vs the source')\n .option('-r, --repos <repos>', 'Restrict to comma-separated target repo names')\n .action(async (options) => {\n const result = await vendorDiff({ repos: parseRepos(options.repos) })\n\n emit(result)\n\n if (!result.structuredContent.ok) {\n process.exitCode = 1\n }\n })\n\n// Grouped form (preferred); the flat `vendor-config` below is a deprecated alias.\nconfigureVendorConfig(vendorCmd.command('config'))\n\ndeprecatedAlias(configureVendorConfig(program.command('vendor-config')), 'vendor config')\n\nprogram\n .command('doctor')\n .description('Check installation and authentication status of gh and doppler CLIs')\n .action(async () => {\n emit(await doctor())\n })\n\nprogram\n .command('version')\n .description('Print the installed infra-kit CLI version')\n .action(async () => {\n emit(await version())\n })\n\nprogram\n .command('env-status')\n .description('Show which env is loaded in this session (local introspection; no Doppler call)')\n .action(async () => {\n emit(await envStatus())\n })\n\nprogram\n .command('env-list')\n .description('List available Doppler configs for the detected project')\n .action(async () => {\n emit(await envList())\n })\n\nprogram\n .command('init')\n .description('Inject shell integration into .zshrc and sync repo agent-instruction files')\n .action(async () => {\n emit(await init())\n })\n\nprogram\n .command('env-load')\n .description('Load Doppler env vars for a config. Source the returned file path to apply.')\n .option('-c, --config <config>', 'Environment config name to load (e.g. dev, arthur)')\n .action(async (options) => {\n emit(await envLoad({ config: options.config }))\n })\n\nprogram\n .command('env-clear')\n .description('Clear loaded env vars. Source the returned file path to apply.')\n .action(async () => {\n emit(await envClear())\n })\n\n// Internal: driven by the init shell-startup integration (backgrounded). Writes\n// env-load.sh when envAutoLoad is configured + eligible; the precmd hook sources\n// it. Hidden + no stdout output so it never pollutes the shell or the menu.\nprogram\n .command('env-autoload', { hidden: true })\n .description('Internal: prime env for the shell-startup auto-load trigger')\n .action(async () => {\n await envAutoload()\n })\n\n// Register `--json` on every command, then resolve the flag before each action\n// runs. In JSON mode we lower the logger to `warn` so the human-oriented info\n// lines stop cluttering stderr while errors still surface; the structured\n// payload is written to stdout by `emit`. No handler logic is affected.\nprogram.commands.forEach(addJsonOption)\n\n// Commands excluded from the cli-invocation auto-load trigger: the env-* family\n// (avoids recursion \u2014 `env-autoload`/`env-load` would re-enter), plus the\n// host-inspecting / meta commands where priming Doppler env would be surprising\n// (`init` bootstraps the shell block, `doctor` inspects auth, `version` prints a\n// string). `--help`/`--version`/the bare-arg menu don't fire preAction at all.\nconst isAutoLoadExcludedCommand = (name: string): boolean => {\n return name.startsWith('env-') || name === 'init' || name === 'doctor' || name === 'version'\n}\n\nprogram.hook('preAction', async (_thisCommand, actionCommand) => {\n // `optsWithGlobals` (not `opts`) so `--json` is seen on grouped subcommands:\n // for `release list --json` Commander binds the post-subcommand flag to the\n // parent `release` group, so the leaf's own `opts()` would not carry it.\n jsonOutput.enabled = Boolean(actionCommand.optsWithGlobals().json)\n\n if (jsonOutput.enabled) {\n logger.level = 'warn'\n }\n\n // cli-invocation auto-load: primes the shell env for SUBSEQUENT commands. The\n // current command does NOT see these vars \u2014 a child process can't mutate its\n // parent shell; the precmd hook sources the written file on the next prompt.\n // runEnvAutoLoad self-gates on config trigger and swallows transient failures,\n // so this is a no-op unless configured for cli-invocation and never blocks.\n if (!isAutoLoadExcludedCommand(actionCommand.name())) {\n await runEnvAutoLoad({ expectedTrigger: 'cli-invocation' })\n }\n})\n\nif (process.argv.length <= 2) {\n // Menu groups derive from the single command catalog (no hand-maintained\n // name arrays). Membership and order live in src/lib/command-catalog.\n const releaseCommands = getMenuGroupCommands('release')\n const worktreeCommands = getMenuGroupCommands('worktrees')\n const envCommands = getMenuGroupCommands('environment')\n\n const commandMap = new Map(\n program.commands.map((cmd) => {\n return [cmd.name(), cmd]\n }),\n )\n\n const groups = [\n { label: 'Release Management', names: releaseCommands },\n { label: 'Worktrees', names: worktreeCommands },\n { label: 'Environment', names: envCommands },\n ]\n\n // Flat {name, description, group} list shared by both the Ink palette and the\n // Inquirer fallback; descriptions come from Commander (single source).\n const paletteItems = groups.flatMap(({ label, names }) => {\n return names\n .filter((name) => {\n return commandMap.has(name)\n })\n .map((name) => {\n return { name, description: commandMap.get(name)!.description(), group: label }\n })\n })\n\n let selected: string | null = null\n\n // Interactive TTY \u2192 Ink command palette, loaded lazily via dynamic import so\n // React/Ink never touch the MCP / `--json` / non-TTY code paths. Otherwise fall\n // back to the Inquirer menu (scripts, pipes, CI). Ctrl-C / Esc at the menu\n // throws from the Inquirer fallback; treat it as a clean exit (nothing picked).\n try {\n if (process.stdout.isTTY && process.stdin.isTTY) {\n const { runCommandPalette } = await import('src/tui/boot')\n\n selected = await runCommandPalette(paletteItems)\n } else {\n const alignedLabels = formatAlignedRows(\n paletteItems.map((item) => {\n return [item.name, item.description] as const\n }),\n )\n const labelByName = new Map<string, string>()\n\n paletteItems.forEach((item, index) => {\n labelByName.set(item.name, alignedLabels[index] ?? item.name)\n })\n\n const toChoices = (names: string[]) => {\n return names\n .filter((name) => {\n return commandMap.has(name)\n })\n .map((name) => {\n return {\n name: labelByName.get(name) ?? name,\n value: name,\n }\n })\n }\n\n selected = await select(\n {\n message: 'Select a command to run',\n choices: [\n new Separator(' '),\n new Separator('\u2014 Release Management \u2014'),\n ...toChoices(releaseCommands),\n new Separator(' '),\n new Separator('\u2014 Worktrees \u2014'),\n ...toChoices(worktreeCommands),\n new Separator(' '),\n new Separator('\u2014 Environment \u2014'),\n ...toChoices(envCommands),\n ],\n },\n { output: process.stderr },\n )\n }\n } catch (error) {\n // Ctrl-C / Esc at the menu is a clean back-out; leave `selected` as null.\n if (!isPromptCancellation(error)) throw error\n }\n\n // The menu is a guided surface; don't nag about deprecated flat names here.\n if (selected) {\n invokedViaMenu.value = true\n\n await runProgram(['node', 'infra-kit', selected])\n }\n} else {\n await runProgram()\n}\n", "import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { $ } from 'zx'\n\nimport { getInfraKitConfigPaths, resetInfraKitConfigCache } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport { fileExists, tildify } from 'src/lib/path-display'\nimport type { ToolsExecutionResult } from 'src/types'\n\n/**\n * Print the file paths that participate in the config merge chain along with\n * existence markers, so the user can see at a glance which override layers\n * are active.\n *\n * @example\n * // CLI: `infra-kit config path`\n * // INFO: Project name: api\n * // INFO: Config merge chain (later overrides earlier):\n * // INFO: [\u2713] project (committed) ~/projects/api/infra-kit.json\n * // INFO: [ ] user global ~/.infra-kit/infra-kit.json\n * // INFO: [\u2713] user project ~/.infra-kit/projects/api/infra-kit.json\n */\nexport const configPath = async (): Promise<ToolsExecutionResult> => {\n const paths = await getInfraKitConfigPaths()\n\n const rows: { label: string; path: string; exists: boolean }[] = await Promise.all(\n [\n { label: 'project (committed)', path: paths.main },\n { label: 'user global', path: paths.userGlobal },\n { label: 'user project', path: paths.userProject },\n ].map(async (row) => {\n return { ...row, exists: await fileExists(row.path) }\n }),\n )\n\n logger.info(`Project name: ${paths.projectName}\\n`)\n logger.info('Config merge chain (later overrides earlier):\\n')\n\n for (const row of rows) {\n const marker = row.exists ? ' [\u2713]' : ' [ ]'\n\n logger.info(`${marker} ${row.label.padEnd(22)} ${tildify(row.path)}`)\n }\n\n const structuredContent = {\n projectName: paths.projectName,\n layers: rows.map((r) => {\n return { label: r.label, path: r.path, exists: r.exists }\n }),\n }\n\n return {\n content: [{ type: 'text', text: JSON.stringify(structuredContent, null, 2) }],\n structuredContent,\n }\n}\n\n/**\n * Open the user-scope per-project override file in $EDITOR, creating the\n * parent directory and a stub file on first use. Resets the config cache\n * after the editor exits so subsequent reads pick up edits without a restart.\n *\n * @example\n * // CLI: `infra-kit config edit`\n * // first run \u2014 creates ~/.infra-kit/projects/api/infra-kit.json ({}) + a sibling\n * // infra-kit.example.jsonc reference, then $EDITOR opens the .json\n * // subsequent runs \u2014 opens the existing file as-is\n */\nexport const configEdit = async (): Promise<ToolsExecutionResult> => {\n const paths = await getInfraKitConfigPaths()\n const editor = process.env.EDITOR || process.env.VISUAL || 'vi'\n\n await fs.mkdir(path.dirname(paths.userProject), { recursive: true })\n\n if (!(await fileExists(paths.userProject))) {\n // JSON can't carry comments, so seed an empty-but-valid config and drop the\n // annotated guidance next to it in a non-loaded .example.jsonc the loader\n // never reads (it only globs the three exact `infra-kit.json` filenames).\n const examplePath = exampleSiblingPath(paths.userProject)\n\n await fs.writeFile(paths.userProject, '{}\\n', 'utf-8')\n await fs.writeFile(examplePath, buildUserProjectExample(paths.projectName), 'utf-8')\n\n logger.info(`Created ${tildify(paths.userProject)} \u2014 see ${tildify(examplePath)} for the annotated reference.`)\n }\n\n logger.info(`Opening ${tildify(paths.userProject)} in ${editor}`)\n\n await $({ stdio: 'inherit' })`${editor} ${paths.userProject}`\n\n resetInfraKitConfigCache()\n\n const structuredContent = { path: paths.userProject, editor }\n\n return {\n content: [{ type: 'text', text: JSON.stringify(structuredContent, null, 2) }],\n structuredContent,\n }\n}\n\n/**\n * Derive the non-loaded `.example.jsonc` sibling for a config path.\n *\n * @example\n * exampleSiblingPath('/u/.infra-kit/projects/api/infra-kit.json')\n * // => '/u/.infra-kit/projects/api/infra-kit.example.jsonc'\n */\nconst exampleSiblingPath = (jsonPath: string): string => {\n return jsonPath.replace(/\\.json$/, '.example.jsonc')\n}\n\n/**\n * Annotated JSONC reference for the user-scope per-project override layer.\n * Written alongside the real `{}` config so the guidance the old YAML stub\n * carried in comments survives the move to JSON.\n *\n * @example\n * buildUserProjectExample('api')\n * // => '// infra-kit user override for api \u2026\\n{ \u2026 }\\n'\n */\nconst buildUserProjectExample = (projectName: string): string => {\n return `// infra-kit user override for ${projectName} \u2014 ~/.infra-kit/projects/${projectName}/infra-kit.json\n//\n// Layer 3 (highest precedence) of the config merge chain. Shallow-merged on top\n// of <repo>/infra-kit.json and ~/.infra-kit/infra-kit.json \u2014 top-level keys\n// (environments, envManagement, ide, taskManager, worktrees, envAutoLoad) replace wholesale.\n//\n// This .example.jsonc is reference only \u2014 it is NOT loaded. Put real overrides\n// in the sibling infra-kit.json (strict JSON: no comments, double-quoted keys).\n{\n // \"worktrees\": { \"openInGithubDesktop\": false, \"openInCmux\": true, \"cmux\": { \"layout\": \"two-columns\" } },\n // // Auto-load Doppler env here. trigger (pick one): shell-startup | cli-invocation; config: an environment name.\n // \"envAutoLoad\": { \"trigger\": \"shell-startup\", \"config\": \"dev\" }\n}\n`\n}\n", "import fs from 'node:fs'\nimport path from 'node:path'\nimport process from 'node:process'\n\nimport { writeEnvLoadFile } from 'src/commands/env-load'\nimport {\n ENV_CLEAR_FILE,\n ENV_LOAD_FILE,\n INFRA_KIT_ENV_AUTOLOADED_VAR,\n INFRA_KIT_ENV_CLEARED_VAR,\n INFRA_KIT_ENV_CONFIG_VAR,\n INFRA_KIT_ENV_PROJECT_VAR,\n INFRA_KIT_SESSION_VAR,\n getSessionCacheDir,\n} from 'src/lib/constants'\nimport type { EnvAutoLoadConfig } from 'src/lib/infra-kit-config'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\n\n/** Which moment a concrete callsite represents. Matches the config `trigger`. */\nexport type AutoLoadTrigger = EnvAutoLoadConfig['trigger']\n\n/** Per-session flag de-duping the MISCONFIG warning (bad envAutoLoad.config). */\nconst WARN_MISCONFIG_SENTINEL_FILE = 'autoload-warn-misconfig.flag'\n/** Per-session flag de-duping the transient-FAILURE warning (Doppler down/unauth). */\nconst WARN_FAIL_SENTINEL_FILE = 'autoload-warn-fail.flag'\n\n/** Per-session marker recording the last auto-load failure (mtime = when). */\nconst FAIL_SENTINEL_FILE = 'autoload-fail.flag'\n\n/**\n * After a failed auto-load, suppress retries for this long so a down/unauthenticated\n * Doppler isn't re-probed on every cli-invocation. A new shell starts a fresh\n * session cache dir, so this only throttles within one session.\n */\nconst FAIL_BACKOFF_MS = 30_000\n\n/** Resolved auto-load inputs: the chosen trigger + the env config and Doppler project to load. */\nexport interface ResolvedEnvAutoLoad {\n trigger: AutoLoadTrigger\n config: string\n project: string\n}\n\n/**\n * Read the resolved + validated env auto-load inputs, or `null` when auto-load\n * should not run. Returns `null` (never throws) when:\n * - we're not inside an infra-kit project (getInfraKitConfig throws), or config is unreadable;\n * - `envAutoLoad` is absent (feature off);\n * - `envAutoLoad.config` is not one of `environments` \u2014 warns once per session, then disables.\n *\n * Validation lives here (not in the schema) so a typo only disables this optional\n * feature instead of throwing inside the merged-config parse and breaking every command.\n * Resolves the Doppler project from the SAME config read (no second getInfraKitConfig),\n * so the skip path stays cheap.\n *\n * `canWarn` gates the misconfig warning: the shell-startup callsite runs backgrounded\n * with stderr discarded, so warning there is invisible AND would write the dedup flag,\n * poisoning the only channel (cli-invocation / interactive) that can actually surface\n * it. So shell-startup passes `false`; interactive callsites pass `true`.\n */\nexport const resolveEnvAutoLoad = async (canWarn = true): Promise<ResolvedEnvAutoLoad | null> => {\n let config\n\n try {\n config = await getInfraKitConfig()\n } catch {\n return null\n }\n\n const autoLoad = config.envAutoLoad\n\n if (!autoLoad) return null\n\n if (!config.environments.includes(autoLoad.config)) {\n if (canWarn) {\n warnOnce(\n `infra-kit: envAutoLoad.config \"${autoLoad.config}\" is not one of environments [${config.environments.join(\n ', ',\n )}] \u2014 env auto-load disabled.`,\n WARN_MISCONFIG_SENTINEL_FILE,\n )\n }\n\n return null\n }\n\n return {\n trigger: autoLoad.trigger,\n config: autoLoad.config,\n project: config.envManagement.config.name,\n }\n}\n\n/** The env-var snapshot the freshness/suppression guards read. */\nexport interface AutoLoadEnvSnapshot {\n session?: string\n cleared?: string\n currentConfig?: string\n currentProject?: string\n autoLoadedMarker?: string\n}\n\nexport interface AutoLoadDecisionInput {\n /** The configured trigger. */\n trigger: AutoLoadTrigger\n /** Which trigger this callsite represents. */\n expectedTrigger: AutoLoadTrigger\n targetConfig: string\n targetProject: string\n env: AutoLoadEnvSnapshot\n}\n\nexport type AutoLoadDecision = 'load' | 'skip'\n\n/**\n * Pure decision: should this callsite (auto-)load env right now? Encodes the full\n * guard matrix so it is exhaustively unit-testable without Doppler or a shell:\n * - the configured trigger must match this callsite;\n * - a session must exist (the cache dir is session-scoped);\n * - an explicit clear suppresses auto-load (M2);\n * - a MANUAL load (config set, no auto marker) is never clobbered (C1);\n * - an auto-load already fresh for the same config AND project is a no-op\n * (project-aware so two same-named configs across different-repo worktrees\n * sharing one session don't leak each other's secrets).\n */\nexport const decideAutoLoad = (input: AutoLoadDecisionInput): AutoLoadDecision => {\n const { trigger, expectedTrigger, targetConfig, targetProject, env } = input\n\n if (trigger !== expectedTrigger) return 'skip'\n\n if (!env.session) return 'skip'\n\n if (env.cleared) return 'skip'\n\n // Manual load present (a config is loaded but it wasn't auto-loaded) \u2014 leave it.\n if (env.currentConfig && !env.autoLoadedMarker) return 'skip'\n\n // Our own auto-load already matches the target config+project \u2014 nothing to do.\n if (env.autoLoadedMarker && env.currentConfig === targetConfig && env.currentProject === targetProject) {\n return 'skip'\n }\n\n return 'load'\n}\n\nexport interface RunEnvAutoLoadArgs {\n expectedTrigger: AutoLoadTrigger\n}\n\n/**\n * Resolve config, evaluate the guards, and (if it should) produce env-load.sh with\n * the auto-load marker. Returns the written file path, or `null` when auto-load was\n * skipped or failed. NEVER throws. Transient failures (Doppler offline / not\n * authenticated / network) record a backoff marker so they aren't re-probed on every\n * command, and are surfaced once per session on the interactive (cli-invocation)\n * channel. No producer-side lock \u2014 a rare cold-shell double-fetch is tolerated (the\n * second write is atomic and idempotent).\n */\nexport const runEnvAutoLoad = async ({ expectedTrigger }: RunEnvAutoLoadArgs): Promise<string | null> => {\n // Only the cli-invocation / interactive callsite reaches a TTY; the shell-startup\n // spawn discards stderr, so warning there is invisible and would poison the dedup.\n const canWarn = expectedTrigger === 'cli-invocation'\n\n try {\n const resolved = await resolveEnvAutoLoad(canWarn)\n\n if (!resolved) return null\n\n const decision = decideAutoLoad({\n trigger: resolved.trigger,\n expectedTrigger,\n targetConfig: resolved.config,\n targetProject: resolved.project,\n env: readAutoLoadEnvSnapshot(),\n })\n\n if (decision === 'skip') return null\n\n // Disk-level clear signal: a clear that hasn't yet been sourced into this\n // process's env still suppresses auto-load (clear file newer than load file).\n if (isClearedOnDisk()) return null\n\n // Back off after a recent failure so a down/unauthenticated Doppler isn't\n // re-probed on every command in the same session.\n if (recentlyFailed()) return null\n\n const preWriteMtime = readLoadFileMtime()\n const result = await writeEnvLoadFile({\n config: resolved.config,\n autoLoaded: true,\n // Re-check after the slow Doppler download: abort if a clear or a manual load\n // landed meanwhile, so a backgrounded auto-load never clobbers a deliberate action.\n beforeWrite: () => {\n return !isClearedOnDisk() && !manualLoadLandedSince(preWriteMtime)\n },\n })\n\n if (!result) return null\n\n clearFailure()\n\n return result.filePath\n } catch (error) {\n const reason = (error as Error).message\n\n recordFailure()\n\n // Surface the failure once per session on the interactive channel; stay silent\n // (debug only) on the backgrounded shell-startup path.\n if (canWarn) {\n warnOnce(`infra-kit: env auto-load failed \u2014 ${reason} (will retry later)`, WARN_FAIL_SENTINEL_FILE)\n } else {\n logger.debug(`env auto-load skipped: ${reason}`)\n }\n\n return null\n }\n}\n\n/** Snapshot the env vars the guards depend on. */\nconst readAutoLoadEnvSnapshot = (): AutoLoadEnvSnapshot => {\n return {\n session: process.env[INFRA_KIT_SESSION_VAR],\n cleared: process.env[INFRA_KIT_ENV_CLEARED_VAR],\n currentConfig: process.env[INFRA_KIT_ENV_CONFIG_VAR],\n currentProject: process.env[INFRA_KIT_ENV_PROJECT_VAR],\n autoLoadedMarker: process.env[INFRA_KIT_ENV_AUTOLOADED_VAR],\n }\n}\n\n/** mtime of the on-disk env-load.sh, or null if absent/unreadable. */\nconst readLoadFileMtime = (): number | null => {\n try {\n return fs.statSync(path.join(getSessionCacheDir(), ENV_LOAD_FILE)).mtimeMs\n } catch {\n return null\n }\n}\n\n/**\n * True when a MANUAL env-load landed on disk after `sinceMtime` (the file now\n * exists, is newer, and carries the manual-load `unset INFRA_KIT_ENV_AUTOLOADED`\n * line). Used to abort an in-flight auto-load so it never clobbers a deliberate load.\n */\nconst manualLoadLandedSince = (sinceMtime: number | null): boolean => {\n try {\n const p = path.join(getSessionCacheDir(), ENV_LOAD_FILE)\n\n if (!fs.existsSync(p)) return false\n\n const mtime = fs.statSync(p).mtimeMs\n\n if (sinceMtime !== null && mtime <= sinceMtime) return false\n\n // Anchor to a whole line so the marker can't match inside a single-quoted\n // secret value that happens to contain this literal text.\n const manualMarker = new RegExp(`^unset ${INFRA_KIT_ENV_AUTOLOADED_VAR}$`, 'm')\n\n return manualMarker.test(fs.readFileSync(p, 'utf-8'))\n } catch {\n return false\n }\n}\n\n/**\n * True when a clear is pending on disk: an env-clear.sh exists and is at least as\n * new as env-load.sh (or no load file remains). Belt-and-suspenders next to the\n * INFRA_KIT_ENV_CLEARED env guard for the window before the shell sources the clear.\n */\nconst isClearedOnDisk = (): boolean => {\n try {\n const dir = getSessionCacheDir()\n const clearPath = path.join(dir, ENV_CLEAR_FILE)\n\n if (!fs.existsSync(clearPath)) return false\n\n const loadPath = path.join(dir, ENV_LOAD_FILE)\n\n if (!fs.existsSync(loadPath)) return true\n\n return fs.statSync(clearPath).mtimeMs >= fs.statSync(loadPath).mtimeMs\n } catch {\n return false\n }\n}\n\n/** True when an auto-load failed within the backoff window (suppress retries). */\nconst recentlyFailed = (): boolean => {\n try {\n const flagPath = path.join(getSessionCacheDir(), FAIL_SENTINEL_FILE)\n\n if (!fs.existsSync(flagPath)) return false\n\n return Date.now() - fs.statSync(flagPath).mtimeMs < FAIL_BACKOFF_MS\n } catch {\n return false\n }\n}\n\n/** Record an auto-load failure (refreshes the backoff window). */\nconst recordFailure = (): void => {\n try {\n const dir = getSessionCacheDir()\n\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 })\n fs.writeFileSync(path.join(dir, FAIL_SENTINEL_FILE), '', { mode: 0o600 })\n } catch {\n // No session cache dir \u2014 nothing to back off against.\n }\n}\n\n/** Clear the failure marker after a successful load. */\nconst clearFailure = (): void => {\n try {\n fs.rmSync(path.join(getSessionCacheDir(), FAIL_SENTINEL_FILE), { force: true })\n } catch {\n // No session cache dir \u2014 nothing to clear.\n }\n}\n\n/**\n * Emit a warning at most once per shell session. Keyed on a flag file in the\n * session cache dir so a misconfigured `envAutoLoad.config` (or a repeated failure)\n * does not spam a warning on every cli-invocation. Falls back to a plain warn when\n * no session cache dir is available.\n */\nconst warnOnce = (message: string, sentinelFile: string): void => {\n try {\n const dir = getSessionCacheDir()\n const flagPath = path.join(dir, sentinelFile)\n\n if (fs.existsSync(flagPath)) return\n\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 })\n fs.writeFileSync(flagPath, '', { mode: 0o600 })\n } catch {\n // No session cache dir (e.g. INFRA_KIT_SESSION unset) \u2014 warn without de-dup.\n }\n\n logger.warn(message)\n}\n", "import { runEnvAutoLoad } from 'src/lib/env-autoload'\n\n/**\n * Internal command invoked (backgrounded) by the `infra-kit init` shell-startup\n * integration. Runs the 'shell-startup' trigger, writing env-load.sh when\n * envAutoLoad is configured for it + eligible; the shell precmd hook sources it on\n * a subsequent prompt. Intentionally writes NOTHING to stdout and never throws \u2014\n * auto-load must never disrupt shell startup.\n */\nexport const envAutoload = async (): Promise<void> => {\n await runEnvAutoLoad({ expectedTrigger: 'shell-startup' })\n}\n", "import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { pathToFileURL } from 'node:url'\n\nimport { getProjectRoot } from 'src/lib/git-utils'\nimport { logger } from 'src/lib/logger'\nimport { fileExists, tildify } from 'src/lib/path-display'\nimport { VENDOR_CONFIG_FILE } from 'src/lib/vendor/config-schema'\nimport { expandTilde, getFactoryConfigPath, loadFactoryConfig } from 'src/lib/vendor/factory-config'\n\ninterface VendorConfigOptions {\n /** Scaffold `~/.infra-kit/vendor.json` instead of printing the current one. */\n init?: boolean\n /** Source repo root used for legacy `targets` auto-seeding. Defaults to the git toplevel. */\n cwd?: string\n}\n\n/** Placeholder workspace dir written by `--init`; the user edits it to their layout. */\nconst PLACEHOLDER_WORKSPACE_DIR = '~/projects'\n\n/**\n * Surface or scaffold the machine-local factory config\n * (`~/.infra-kit/vendor.json`). CLI-only \u2014 NOT an MCP tool; returns nothing\n * and signals problems via `process.exitCode`.\n *\n * Without `--init`: prints the factory file path + existence, the resolved\n * `workspaceDir` + existence, and per-target reachability (`[\u2713]`/`[ ]`). Exits\n * non-zero if the file is missing, the workspace dir is missing, or any target\n * is unreachable, so it is usable as a doctor check.\n *\n * With `--init`: scaffolds the file (skipping if it already exists), seeding\n * `targets` from a legacy source `vendor.config.ts` when one is readable.\n */\nexport const vendorConfig = async (options: VendorConfigOptions = {}): Promise<void> => {\n if (options.init) {\n await initFactoryConfig(options.cwd)\n\n return\n }\n\n await printFactoryConfig()\n}\n\n/** Render the factory config chain with `[\u2713]`/`[ ]` reachability markers. */\nconst printFactoryConfig = async (): Promise<void> => {\n const factoryPath = getFactoryConfigPath()\n const exists = await fileExists(factoryPath)\n\n logger.info(`Factory config: ${tildify(factoryPath)} ${exists ? '[\u2713]' : '[ ]'}`)\n\n if (!exists) {\n logger.info('\\nNot found \u2014 run `infra-kit vendor-config --init` to scaffold it.')\n process.exitCode = 1\n\n return\n }\n\n const { workspaceDir, targets } = await loadFactoryConfig()\n const resolvedWorkspace = expandTilde(workspaceDir)\n const workspaceExists = await fileExists(resolvedWorkspace)\n\n logger.info(\n `workspaceDir: ${workspaceDir} (resolved: ${resolvedWorkspace}) ${workspaceExists ? '[\u2713 exists]' : '[ ] not found'}`,\n )\n logger.info('Targets:')\n\n let allReachable = workspaceExists\n\n for (const repo of targets) {\n const targetPath = path.join(resolvedWorkspace, repo)\n const reachable = await fileExists(targetPath)\n\n if (!reachable) {\n allReachable = false\n }\n\n const marker = reachable ? '[\u2713]' : '[ ]'\n const suffix = reachable ? '' : ' (not found \u2014 clone or remove)'\n\n logger.info(` ${marker} ${repo} ${tildify(targetPath)}${suffix}`)\n }\n\n if (!allReachable) {\n process.exitCode = 1\n }\n}\n\n/** Scaffold `~/.infra-kit/vendor.json`, skipping if it already exists. */\nconst initFactoryConfig = async (cwd?: string): Promise<void> => {\n const factoryPath = getFactoryConfigPath()\n\n if (await fileExists(factoryPath)) {\n logger.info(`Factory config already exists at ${tildify(factoryPath)} \u2014 leaving it untouched.`)\n\n return\n }\n\n const sourceRoot = cwd ?? (await getProjectRoot())\n const seededTargets = await readLegacyTargets(sourceRoot)\n\n await fs.mkdir(path.dirname(factoryPath), { recursive: true })\n await fs.writeFile(factoryPath, buildScaffold(seededTargets), 'utf-8')\n\n logger.info(`\u2713 Created ${tildify(factoryPath)}`)\n\n if (seededTargets.length > 0) {\n logger.info(` Seeded ${seededTargets.length} target(s) from the source ${VENDOR_CONFIG_FILE}.`)\n }\n\n logger.info(` Edit \\`workspaceDir\\` (placeholder: ${PLACEHOLDER_WORKSPACE_DIR}) to point at where your repos live.`)\n\n if (seededTargets.length === 0) {\n logger.info(' Add at least one repo name to `targets` before running vendor sync/manifest/diff.')\n }\n}\n\n/**\n * Best-effort read of a legacy `targets` array from the source repo's\n * `vendor.config.ts`. The current schema no longer accepts `targets`, so this\n * reads the raw default export directly (bypassing validation). Returns `[]` on\n * any failure \u2014 seeding is a convenience, never a hard requirement.\n */\nconst readLegacyTargets = async (sourceRoot: string): Promise<string[]> => {\n try {\n const configPath = path.join(sourceRoot, VENDOR_CONFIG_FILE)\n const stat = await fs.stat(configPath)\n const moduleUrl = `${pathToFileURL(configPath).href}?mtime=${Number(stat.mtimeMs)}`\n const imported = (await import(moduleUrl)) as { default?: unknown }\n const raw = imported.default\n const resolved = typeof raw === 'function' ? await (raw as () => unknown)() : raw\n\n if (resolved && typeof resolved === 'object' && 'targets' in resolved) {\n const targets = (resolved as { targets?: unknown }).targets\n\n if (\n Array.isArray(targets) &&\n targets.every((t) => {\n return typeof t === 'string'\n })\n ) {\n return targets as string[]\n }\n }\n } catch {\n // Absent or unreadable source config \u2014 fall through to an empty placeholder.\n }\n\n return []\n}\n\n/**\n * Render the scaffold file body as strict JSON (`vendor.json`). The factory config\n * is static JSON, loaded with `JSON.parse` \u2014 no comments, no executable code. When\n * `targets` is empty the stub writes `\"targets\": []`, which fails the schema's\n * `targets.min(1)` on load: this is intentional \u2014 `--init` produces an incomplete\n * stub the user must edit before running vendor sync/manifest/diff. The annotated\n * guidance lives in the sibling `vendor.example.jsonc` (seeded by `infra-kit init`).\n */\nconst buildScaffold = (targets: string[]): string => {\n return `${JSON.stringify({ workspaceDir: PLACEHOLDER_WORKSPACE_DIR, targets }, null, 2)}\\n`\n}\n", "import type { Command } from 'commander'\nimport process from 'node:process'\n\n/**\n * `--json` output mode for the CLI. This is a presentation concern only: every\n * command handler already returns a `structuredContent` payload (the same one\n * the MCP surface consumes). Human/log output goes to stderr (see lib/logger),\n * so writing the structured payload to stdout never collides with it.\n */\n\nexport interface CommandResult {\n structuredContent?: unknown\n}\n\n/** Mutable holder (object so `prefer-const` holds while the flag toggles per run). */\nexport const jsonOutput = { enabled: false }\n\n/**\n * In `--json` mode, write a command result's `structuredContent` to stdout as\n * pretty JSON and return the result unchanged. Outside `--json` mode it is a\n * no-op pass-through. The writer is injectable for testing.\n */\nexport const emit = <T extends CommandResult | void>(\n result: T,\n write: (text: string) => void = (text) => {\n process.stdout.write(text)\n },\n): T => {\n if (jsonOutput.enabled && result && result.structuredContent != null) {\n write(`${JSON.stringify(result.structuredContent, null, 2)}\\n`)\n }\n\n return result\n}\n\n/** Register `--json` on a command and every nested subcommand (idempotent). */\nexport const addJsonOption = (cmd: Command): void => {\n const alreadyHasJson = cmd.options.some((option) => {\n return option.long === '--json'\n })\n\n if (!alreadyHasJson) {\n cmd.option('--json', 'Output the structured result as JSON on stdout (human logs stay on stderr)')\n }\n\n cmd.commands.forEach(addJsonOption)\n}\n", "/**\n * Small shared rendering helpers for aligned terminal output. These replace\n * the ad-hoc \"compute the max width, then padEnd each row\" pattern that the\n * interactive menu (and similar list views) hand-rolled. Pure string helpers \u2014\n * no I/O, no color \u2014 so they are trivially testable and reusable.\n */\n\n/**\n * Align a list of two-column rows: pad every left cell to the widest left cell,\n * then join the two cells with `gap`. Returns one rendered line per row.\n *\n * @example\n * formatAlignedRows([['a', 'x'], ['bbb', 'y']])\n * // ['a x', 'bbb y'] (left padded to width 3, default 2-space gap)\n */\nexport const formatAlignedRows = (rows: ReadonlyArray<readonly [string, string]>, gap = ' '): string[] => {\n const width = rows.reduce((max, [left]) => {\n return Math.max(max, left.length)\n }, 0)\n\n return rows.map(([left, right]) => {\n return `${left.padEnd(width)}${gap}${right}`\n })\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["select", "Separator", "Command", "process", "fs", "path", "process", "$", "configPath", "paths", "getInfraKitConfigPaths", "rows", "row", "fileExists", "logger", "marker", "tildify", "structuredContent", "configEdit", "editor", "process", "fs", "path", "examplePath", "exampleSiblingPath", "buildUserProjectExample", "$", "resetInfraKitConfigCache", "jsonPath", "projectName", "fs", "path", "process", "WARN_MISCONFIG_SENTINEL_FILE", "WARN_FAIL_SENTINEL_FILE", "FAIL_SENTINEL_FILE", "FAIL_BACKOFF_MS", "resolveEnvAutoLoad", "canWarn", "config", "getInfraKitConfig", "autoLoad", "warnOnce", "decideAutoLoad", "input", "trigger", "expectedTrigger", "targetConfig", "targetProject", "env", "runEnvAutoLoad", "resolved", "readAutoLoadEnvSnapshot", "isClearedOnDisk", "recentlyFailed", "preWriteMtime", "readLoadFileMtime", "result", "writeEnvLoadFile", "manualLoadLandedSince", "clearFailure", "error", "reason", "recordFailure", "logger", "process", "INFRA_KIT_SESSION_VAR", "INFRA_KIT_ENV_CLEARED_VAR", "INFRA_KIT_ENV_CONFIG_VAR", "INFRA_KIT_ENV_PROJECT_VAR", "INFRA_KIT_ENV_AUTOLOADED_VAR", "fs", "path", "getSessionCacheDir", "ENV_LOAD_FILE", "sinceMtime", "p", "mtime", "dir", "clearPath", "ENV_CLEAR_FILE", "loadPath", "flagPath", "message", "sentinelFile", "envAutoload", "runEnvAutoLoad", "fs", "path", "process", "pathToFileURL", "PLACEHOLDER_WORKSPACE_DIR", "vendorConfig", "options", "initFactoryConfig", "printFactoryConfig", "factoryPath", "getFactoryConfigPath", "exists", "fileExists", "logger", "tildify", "process", "workspaceDir", "targets", "loadFactoryConfig", "resolvedWorkspace", "expandTilde", "workspaceExists", "allReachable", "repo", "targetPath", "path", "reachable", "marker", "suffix", "cwd", "sourceRoot", "getProjectRoot", "seededTargets", "readLegacyTargets", "fs", "buildScaffold", "VENDOR_CONFIG_FILE", "configPath", "stat", "raw", "pathToFileURL", "resolved", "t", "process", "jsonOutput", "emit", "result", "write", "text", "addJsonOption", "cmd", "option", "formatAlignedRows", "rows", "gap", "width", "max", "left", "right", "program", "Command", "collectReleaseSpec", "value", "prev", "parseRepos", "normalizeIdeMode", "flagName", "IDE_MODES", "runProgram", "argv", "error", "isPromptCancellation", "logger", "process", "message", "invokedViaMenu", "deprecatedAlias", "cmd", "preferred", "configureMergeDev", "options", "emit", "ghMergeDev", "configureReleaseList", "ghReleaseList", "configureReleaseCreate", "inputs", "parseReleaseSpec", "releases", "releaseCreate", "configureReleaseDescEdit", "releaseDescEdit", "configureReleaseDeployAll", "ghReleaseDeployAll", "configureReleaseDeploySelected", "ghReleaseDeploySelected", "configureReleaseDeliver", "ghReleaseDeliver", "configureWorktreesSync", "worktreesSync", "configureWorktreesAdd", "ide", "worktreesAdd", "configureWorktreesList", "worktreesList", "configureWorktreesRemove", "worktreesRemove", "configureWorktreesReload", "worktreesReload", "configureVendorConfig", "vendorConfig", "releaseGroup", "worktreesGroup", "configCmd", "configPath", "configEdit", "result", "audit", "vendorCmd", "vendorCheck", "vendorSync", "vendorManifest", "vendorDiff", "doctor", "version", "envStatus", "envList", "init", "envLoad", "envClear", "envAutoload", "addJsonOption", "isAutoLoadExcludedCommand", "name", "_thisCommand", "actionCommand", "jsonOutput", "runEnvAutoLoad", "releaseCommands", "getMenuGroupCommands", "worktreeCommands", "envCommands", "commandMap", "paletteItems", "label", "names", "selected", "runCommandPalette", "alignedLabels", "formatAlignedRows", "item", "labelByName", "index", "toChoices", "select", "Separator"]
7
7
  }
package/dist/mcp.js CHANGED
@@ -1,2 +1,2 @@
1
- import{V as m,b as s,c as p,d as c}from"./chunk-YMXDO43V.js";import"./chunk-WA4BQRDC.js";import{StdioServerTransport as g}from"@modelcontextprotocol/sdk/server/stdio.js";import h from"node:process";import o from"node:process";var l=r=>{o.on("SIGINT",()=>{r.info({msg:"Received SIGINT. Shutting down..."}),o.exit(0)}),o.on("SIGTERM",()=>{r.info({msg:"Received SIGTERM. Shutting down..."}),o.exit(0)}),o.on("uncaughtException",e=>{r.fatal({err:e,msg:"Uncaught Exception"}),r.error(`Uncaught Exception! Check ${s}. Shutting down...`),r.flush(),o.exit(1)}),o.on("unhandledRejection",(e,n)=>{r.fatal({reason:e,promise:n,msg:"Unhandled Rejection"}),r.error(`Unhandled Rejection! Check ${s}. Shutting down...`),r.flush(),o.exit(1)})};import{McpServer as x}from"@modelcontextprotocol/sdk/server/mcp.js";var d=async r=>{};var u=async r=>{};var a=r=>async e=>{let{toolName:n,handler:S}=r;c.info({msg:`Tool execution started: ${n}`,params:e});try{let i=await S({...e,confirmedCommand:!0});return c.info({msg:`Tool execution successful: ${n}`}),i}catch(i){throw c.error({err:i,params:e,msg:`Tool execution failed: ${n}`}),i}};var f=async r=>{for(let e of m())r.registerTool(e.name,{description:e.description,inputSchema:e.inputSchema,outputSchema:e.outputSchema},a({toolName:e.name,handler:e.handler}))};async function v(){let r=new x({name:"infra-kit",version:"1.0.0"},{capabilities:{resources:{},tools:{},prompts:{}}});return await d(r),await u(r),await f(r),r}var t=p(),T=async()=>{let r;try{r=await v(),t.info("MCP Server instance created")}catch(e){t.error({err:e,msg:"Failed to create MCP server"}),t.error("Fatal error during server creation."),h.exit(1)}try{let e=new g;await r.connect(e),t.info({msg:"Server connected to transport. Ready."})}catch(e){t.error({err:e,msg:"Failed to initialize server"}),t.error("Fatal error during server transport init."),h.exit(1)}};l(t);T();
1
+ import{W as m,b as s,c as p,d as c}from"./chunk-VI7TEWVJ.js";import"./chunk-WA4BQRDC.js";import{StdioServerTransport as g}from"@modelcontextprotocol/sdk/server/stdio.js";import h from"node:process";import o from"node:process";var l=r=>{o.on("SIGINT",()=>{r.info({msg:"Received SIGINT. Shutting down..."}),o.exit(0)}),o.on("SIGTERM",()=>{r.info({msg:"Received SIGTERM. Shutting down..."}),o.exit(0)}),o.on("uncaughtException",e=>{r.fatal({err:e,msg:"Uncaught Exception"}),r.error(`Uncaught Exception! Check ${s}. Shutting down...`),r.flush(),o.exit(1)}),o.on("unhandledRejection",(e,n)=>{r.fatal({reason:e,promise:n,msg:"Unhandled Rejection"}),r.error(`Unhandled Rejection! Check ${s}. Shutting down...`),r.flush(),o.exit(1)})};import{McpServer as x}from"@modelcontextprotocol/sdk/server/mcp.js";var d=async r=>{};var u=async r=>{};var a=r=>async e=>{let{toolName:n,handler:S}=r;c.info({msg:`Tool execution started: ${n}`,params:e});try{let i=await S({...e,confirmedCommand:!0});return c.info({msg:`Tool execution successful: ${n}`}),i}catch(i){throw c.error({err:i,params:e,msg:`Tool execution failed: ${n}`}),i}};var f=async r=>{for(let e of m())r.registerTool(e.name,{description:e.description,inputSchema:e.inputSchema,outputSchema:e.outputSchema},a({toolName:e.name,handler:e.handler}))};async function v(){let r=new x({name:"infra-kit",version:"1.0.0"},{capabilities:{resources:{},tools:{},prompts:{}}});return await d(r),await u(r),await f(r),r}var t=p(),T=async()=>{let r;try{r=await v(),t.info("MCP Server instance created")}catch(e){t.error({err:e,msg:"Failed to create MCP server"}),t.error("Fatal error during server creation."),h.exit(1)}try{let e=new g;await r.connect(e),t.info({msg:"Server connected to transport. Ready."})}catch(e){t.error({err:e,msg:"Failed to initialize server"}),t.error("Fatal error during server transport init."),h.exit(1)}};l(t);T();
2
2
  //# sourceMappingURL=mcp.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "infra-kit",
3
3
  "type": "module",
4
- "version": "0.1.123",
4
+ "version": "0.1.125",
5
5
  "description": "infra-kit",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -0,0 +1,2 @@
1
+ {"t":0,"agent":"aa0bc24","agent_type":"executor","event":"agent_start","parent_mode":"none"}
2
+ {"t":0,"agent":"aa0bc24","agent_type":"executor","event":"agent_stop","success":true,"duration_ms":563456}
@@ -1,3 +1,3 @@
1
1
  {
2
- "lastSentAt": "2026-06-22T13:44:36.933Z"
2
+ "lastSentAt": "2026-06-30T11:04:25.633Z"
3
3
  }
@@ -0,0 +1,7 @@
1
+ {
2
+ "tool_name": "Bash",
3
+ "tool_input_preview": "{\"command\":\"cd /Users/arthur/projects/infra-kit/apps/infra-kit/cli && rtk read vitest.config.* 2>/dev/null; echo \\\"---\\\"; rtk grep -rn \\\"clearMocks\\\\|mockReset\\\\|restoreMocks\\\" vitest.config.* vite.co...",
4
+ "error": "Exit code 1\nimport { resolve } from 'node:path'\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig(() => {\n return {\n plugins: [],\n resolve: {\n alias: {\n '#root': resolve(__dirname, './src'),\n src: resolve(__dirname, './src'),\n },\n },\n test: {\n environment: 'node',\n setupFiles: ['./vitest.setup.ts'],\n server: {\n deps: {\n // ink-testing-library imports `ink` without declaring it as a dep, so\n // pn...",
5
+ "timestamp": "2026-06-30T11:09:32.462Z",
6
+ "retry_count": 1
7
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "updatedAt": "2026-06-30T11:13:43.458Z",
3
+ "missions": [
4
+ {
5
+ "id": "session:2ccbd177-0d5d-4d4a-ab94-a22464786221:none",
6
+ "source": "session",
7
+ "name": "none",
8
+ "objective": "Session mission",
9
+ "createdAt": "2026-06-30T11:04:20.002Z",
10
+ "updatedAt": "2026-06-30T11:13:43.458Z",
11
+ "status": "done",
12
+ "workerCount": 1,
13
+ "taskCounts": {
14
+ "total": 1,
15
+ "pending": 0,
16
+ "blocked": 0,
17
+ "inProgress": 0,
18
+ "completed": 1,
19
+ "failed": 0
20
+ },
21
+ "agents": [
22
+ {
23
+ "name": "executor:aa0bc24",
24
+ "role": "executor",
25
+ "ownership": "aa0bc2493749f11ee",
26
+ "status": "done",
27
+ "currentStep": null,
28
+ "latestUpdate": "completed",
29
+ "completedSummary": null,
30
+ "updatedAt": "2026-06-30T11:13:43.458Z"
31
+ }
32
+ ],
33
+ "timeline": [
34
+ {
35
+ "id": "session-start:aa0bc2493749f11ee:2026-06-30T11:04:20.002Z",
36
+ "at": "2026-06-30T11:04:20.002Z",
37
+ "kind": "update",
38
+ "agent": "executor:aa0bc24",
39
+ "detail": "started executor:aa0bc24",
40
+ "sourceKey": "session-start:aa0bc2493749f11ee"
41
+ },
42
+ {
43
+ "id": "session-stop:aa0bc2493749f11ee:2026-06-30T11:13:43.458Z",
44
+ "at": "2026-06-30T11:13:43.458Z",
45
+ "kind": "completion",
46
+ "agent": "executor:aa0bc24",
47
+ "detail": "completed",
48
+ "sourceKey": "session-stop:aa0bc2493749f11ee"
49
+ }
50
+ ]
51
+ }
52
+ ]
53
+ }