infra-kit 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-5OHTHRS7.js → chunk-6GWRKIZ7.js} +2 -2
- package/dist/chunk-6GWRKIZ7.js.map +7 -0
- package/dist/{chunk-DHYZ6MBU.js → chunk-Q23IJP6D.js} +2 -2
- package/dist/{chunk-LXBIHXUR.js → chunk-X2POR5VH.js} +3 -3
- package/dist/{chunk-LXBIHXUR.js.map → chunk-X2POR5VH.js.map} +3 -3
- package/dist/{chunk-7POMR4QK.js → chunk-XJOY7J3G.js} +1 -1
- package/dist/chunk-XJOY7J3G.js.map +7 -0
- package/dist/{chunk-4ZE5XSVW.js → chunk-Y3FV2BRI.js} +2 -2
- package/dist/cli.js +12 -12
- package/dist/cli.js.map +4 -4
- package/dist/dev-server.js +1 -1
- package/dist/mcp.js +1 -1
- package/dist/update-check.js +1 -1
- package/package.json +2 -2
- package/readme.md +1 -1
- package/dist/chunk-5OHTHRS7.js.map +0 -7
- package/dist/chunk-7POMR4QK.js.map +0 -7
- /package/dist/{chunk-DHYZ6MBU.js.map → chunk-Q23IJP6D.js.map} +0 -0
- /package/dist/{chunk-4ZE5XSVW.js.map → chunk-Y3FV2BRI.js.map} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var D={name:"infra-kit",type:"module",version:"0.5.
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
var D={name:"infra-kit",type:"module",version:"0.5.1",files:["dist"],description:"infra-kit",bin:{"infra-kit":"dist/cli.js",ik:"dist/cli.js"},engines:{node:">=24.x"},scripts:{inspector:"npx @modelcontextprotocol/inspector node ./dist/mcp.js --debug",build:"pnpm run clean-artifacts && node ./scripts/build.js",prepack:"pnpm run build",prepublishOnly:"pnpm run build","infra-kit-check":"pnpm exec infra-kit audit","clean-artifacts":"rm -rf dist","clean-cache":"rm -rf node_modules/.cache .eslintcache tsconfig.tsbuildinfo .turbo .swc","prettier-fix":"pnpm exec prettier **/* --write --no-error-on-unmatched-pattern --log-level silent --ignore-path ../../../.prettierignore","prettier-check":"pnpm exec prettier **/* --check --no-error-on-unmatched-pattern --log-level silent --ignore-path ../../../.prettierignore","eslint-check":"pnpm exec eslint --cache --report-unused-disable-directives ./src","eslint-fix":"pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src --fix","ts-check":"tsc --noEmit",test:"pnpm exec vitest run --reporter=minimal","test-watch":"pnpm exec vitest --watch --silent passed-only","test-ui":"pnpm exec vitest --ui --silent passed-only","test-report":"pnpm exec vitest run --coverage --silent passed-only","qa:pty":"INFRA_KIT_REQUIRE_PTY=1 pnpm exec vitest run --reporter=minimal src/tui/__tests__/stdin-pause-pty.test.ts src/entry/__tests__/quit-keys-pty.test.ts src/entry/__tests__/post-run-pause-pty.test.ts",qa:"pnpm run prettier-check && pnpm run eslint-check && pnpm run ts-check && pnpm run test && echo \u2705 Success",fix:"pnpm run prettier-fix && pnpm run eslint-fix && pnpm run qa"},dependencies:{"@aws-lambda-powertools/logger":"^2.35.0","@inquirer/checkbox":"^5.2.5","@inquirer/confirm":"^6.3.2","@inquirer/input":"^5.1.6","@inquirer/password":"^5.2.2","@inquirer/select":"^5.2.5","@modelcontextprotocol/server":"^2.0.0","@slip-stream-kit/config":"^0.4.0",chalk:"^6.0.0",chokidar:"^5.0.0",commander:"^15.0.0",fastify:"^5.12.3",ink:"^7.1.1",pino:"^10.3.1","pino-pretty":"^13.1.3",portless:"^0.15.6",react:"19.2.8",yaml:"^2.9.0",zod:"^4.5.4",zx:"^8.8.5"},devDependencies:{"@modelcontextprotocol/client":"^2.0.0","@modelcontextprotocol/sdk":"^1.30.0","@slip-stream-kit/eslint-plugin":"workspace:*","@types/aws-lambda":"catalog:","@types/react":"catalog:","@wl/eslint-config":"workspace:*","@wl/vitest-config":"workspace:*",esbuild:"^0.28.2","ink-testing-library":"^4.0.0",typescript:"^6.0.3"}};import a from"node:path";var i="infra-kit",o=`${i}@latest`,m=(e,t,n)=>{let r=a.relative(n(a.resolve(e)),a.resolve(t));return r!==""&&!r.startsWith("..")&&!a.isAbsolute(r)},s=(e,t)=>a.resolve(e).split(a.sep).includes(t),b=(e,t)=>{let n=a.resolve(e).split(a.sep),r=n.indexOf("Cellar");return r!==-1&&n[r+1]===t},M=(e,t)=>{let n=a.resolve(e).split(a.sep),r=n.lastIndexOf("node_modules");return r<2||n[r-1]!=="lib"||n[r+1]!==t?null:n.slice(0,r-1).join(a.sep)||a.sep},w=e=>M(e,i),I=e=>["npm","install","-g","--prefix",e,o],v=e=>e.map(t=>t.includes(" ")?`'${t}'`:t).join(" "),c=(e,t,n,r)=>{let p=e[t];return p!=null&&p!==""&&m(p,n,r)},_=[{manager:"volta",test:({selfRealPath:e,env:t,realpath:n})=>c(t,"VOLTA_HOME",e,n)||s(e,".volta")||s(e,"volta"),updateCommand:["volta","install",i],canSelfSpawn:!0},{manager:"homebrew",test:({selfRealPath:e})=>b(e,i),updateCommand:["brew","upgrade",i],canSelfSpawn:!1}],k=[{manager:"pnpm",test:({selfRealPath:e,env:t,realpath:n})=>c(t,"PNPM_HOME",e,n)||s(e,"pnpm")&&s(e,"global"),updateCommand:["pnpm","add","-g",o],canSelfSpawn:!0},{manager:"bun",test:({selfRealPath:e,env:t,realpath:n})=>c(t,"BUN_INSTALL",e,n)||s(e,".bun"),updateCommand:["bun","add","-g",o],canSelfSpawn:!0},{manager:"yarn",test:({selfRealPath:e})=>s(e,".yarn")||s(e,"yarn")&&s(e,"global"),updateCommand:["yarn","global","add",o],canSelfSpawn:!0},{manager:"npm",test:({selfRealPath:e,env:t,realpath:n})=>c(t,"npm_config_prefix",e,n),updateCommand:["npm","install","-g",o],canSelfSpawn:!0}],S=["npm","install","-g",o],C=e=>{let{selfRealPath:t,env:n,realpath:r,lazyNpmRoot:p}=e,d=l=>({manager:l.manager,updateCommand:l.updateCommand,canSelfSpawn:l.canSelfSpawn}),g=({test:l})=>l({selfRealPath:t,env:n,realpath:r}),f=_.find(g);if(f)return d(f);let x=w(t);if(x!==null)return{manager:"npm",updateCommand:I(x),canSelfSpawn:!0};let h=k.find(g);if(h)return d(h);let u=p?.();return u!=null&&u!==""&&m(u,t,r)?{manager:"npm",updateCommand:S,canSelfSpawn:!0}:{manager:"unknown",updateCommand:S,canSelfSpawn:!1}},E=(e,t,n)=>s(e,"node_modules")&&m(t,e,n);import{realpathSync as R}from"node:fs";import N from"node:path";var A=e=>{try{return R(e)}catch{return N.resolve(e)}};import{execFileSync as P}from"node:child_process";import O from"node:process";var T=3e3,q=()=>{try{let t=P("npm",["root","-g"],{encoding:"utf-8",timeout:T,stdio:["ignore","pipe","ignore"],shell:O.platform==="win32"}).trim();return t===""?void 0:t}catch{return}};export{D as a,i as b,s as c,b as d,M as e,v as f,C as g,E as h,q as i,A as j};
|
|
2
|
+
//# sourceMappingURL=chunk-6GWRKIZ7.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../package.json", "../src/lib/install-manager/install-manager.ts", "../src/lib/install-manager/safe-realpath.ts", "../src/lib/install-manager/npm-root.ts"],
|
|
4
|
+
"sourcesContent": ["{\n \"name\": \"infra-kit\",\n \"type\": \"module\",\n \"version\": \"0.5.1\",\n \"files\": [\n \"dist\"\n ],\n \"description\": \"infra-kit\",\n \"bin\": {\n \"infra-kit\": \"dist/cli.js\",\n \"ik\": \"dist/cli.js\"\n },\n \"engines\": {\n \"node\": \">=24.x\"\n },\n \"scripts\": {\n \"inspector\": \"npx @modelcontextprotocol/inspector node ./dist/mcp.js --debug\",\n \"build\": \"pnpm run clean-artifacts && node ./scripts/build.js\",\n \"prepack\": \"pnpm run build\",\n \"prepublishOnly\": \"pnpm run build\",\n \"infra-kit-check\": \"pnpm exec infra-kit audit\",\n \"clean-artifacts\": \"rm -rf dist\",\n \"clean-cache\": \"rm -rf node_modules/.cache .eslintcache tsconfig.tsbuildinfo .turbo .swc\",\n \"prettier-fix\": \"pnpm exec prettier **/* --write --no-error-on-unmatched-pattern --log-level silent --ignore-path ../../../.prettierignore\",\n \"prettier-check\": \"pnpm exec prettier **/* --check --no-error-on-unmatched-pattern --log-level silent --ignore-path ../../../.prettierignore\",\n \"eslint-check\": \"pnpm exec eslint --cache --report-unused-disable-directives ./src\",\n \"eslint-fix\": \"pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src --fix\",\n \"ts-check\": \"tsc --noEmit\",\n \"test\": \"pnpm exec vitest run --reporter=minimal\",\n \"test-watch\": \"pnpm exec vitest --watch --silent passed-only\",\n \"test-ui\": \"pnpm exec vitest --ui --silent passed-only\",\n \"test-report\": \"pnpm exec vitest run --coverage --silent passed-only\",\n \"qa:pty\": \"INFRA_KIT_REQUIRE_PTY=1 pnpm exec vitest run --reporter=minimal src/tui/__tests__/stdin-pause-pty.test.ts src/entry/__tests__/quit-keys-pty.test.ts src/entry/__tests__/post-run-pause-pty.test.ts\",\n \"qa\": \"pnpm run prettier-check && pnpm run eslint-check && pnpm run ts-check && pnpm run test && echo \u2705 Success\",\n \"fix\": \"pnpm run prettier-fix && pnpm run eslint-fix && pnpm run qa\"\n },\n \"dependencies\": {\n \"@aws-lambda-powertools/logger\": \"^2.35.0\",\n \"@inquirer/checkbox\": \"^5.2.5\",\n \"@inquirer/confirm\": \"^6.3.2\",\n \"@inquirer/input\": \"^5.1.6\",\n \"@inquirer/password\": \"^5.2.2\",\n \"@inquirer/select\": \"^5.2.5\",\n \"@modelcontextprotocol/server\": \"^2.0.0\",\n \"@slip-stream-kit/config\": \"^0.4.0\",\n \"chalk\": \"^6.0.0\",\n \"chokidar\": \"^5.0.0\",\n \"commander\": \"^15.0.0\",\n \"fastify\": \"^5.12.3\",\n \"ink\": \"^7.1.1\",\n \"pino\": \"^10.3.1\",\n \"pino-pretty\": \"^13.1.3\",\n \"portless\": \"^0.15.6\",\n \"react\": \"19.2.8\",\n \"yaml\": \"^2.9.0\",\n \"zod\": \"^4.5.4\",\n \"zx\": \"^8.8.5\"\n },\n \"devDependencies\": {\n \"@modelcontextprotocol/client\": \"^2.0.0\",\n \"@modelcontextprotocol/sdk\": \"^1.30.0\",\n \"@slip-stream-kit/eslint-plugin\": \"workspace:*\",\n \"@types/aws-lambda\": \"catalog:\",\n \"@types/react\": \"catalog:\",\n \"@wl/eslint-config\": \"workspace:*\",\n \"@wl/vitest-config\": \"workspace:*\",\n \"esbuild\": \"^0.28.2\",\n \"ink-testing-library\": \"^4.0.0\",\n \"typescript\": \"^6.0.3\"\n }\n}\n", "/**\n * Pure detection of *how* this CLI was installed, so the background updater knows whether it may act at\n * all, and the advisory it prints can name the one command that will actually work. No fs, no spawn, no `process.env` read \u2014 every input is injected, which is\n * what lets the whole matrix be table-tested.\n *\n * Detection is env-first and LAZY: the only signal that costs a subprocess (`npm root -g`) is passed in\n * as `lazyNpmRoot` and consulted solely when every cheaper matcher has missed.\n */\nimport path from 'node:path'\n\n/** The published package this CLI updates itself to. Single source for every suggested argv. */\nexport const PACKAGE_NAME = 'infra-kit'\n\nconst LATEST = `${PACKAGE_NAME}@latest`\n\nexport type InstallManager = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'volta' | 'homebrew' | 'unknown'\n\nexport interface InstallManagerInfo {\n manager: InstallManager\n /** The command to run. Only safe to spawn ourselves when `canSelfSpawn`; otherwise print it. */\n updateCommand: string[]\n /** False when we must not run the command for the user \u2014 either it needs sudo/a tap, or we guessed. */\n canSelfSpawn: boolean\n}\n\n/**\n * Canonicalises a candidate *root* directory. Required, not optional: `selfRealPath` has already had its\n * symlinks followed, so comparing it against a raw `PNPM_HOME`/`npm root -g`/`cwd` compares a resolved\n * path to an unresolved one and silently never matches. macOS is the everyday proof \u2014 `/var` is a symlink\n * to `/private/var`, so a global install under `/var/...` reports `unknown` unless both sides are resolved.\n * Callers inject the real thing; tests inject a stub.\n */\nexport type RealpathFn = (dir: string) => string\n\nexport interface DetectInstallManagerInput {\n /** Fully-resolved (symlinks followed) path to this CLI's entry file. */\n selfRealPath: string\n env: NodeJS.ProcessEnv\n /** Canonicalises each candidate root before comparison. See {@link RealpathFn}. */\n realpath: RealpathFn\n /** `npm root -g`, deferred: invoked at most once, and only when no cheaper matcher hit. */\n lazyNpmRoot?: () => string | undefined\n}\n\n/**\n * Is `child` inside the `parent` subtree? Boundary-aware: a naive `startsWith` would call\n * `/Users/x/pnpm-ish` a child of `/Users/x/pnpm`. `parent` is canonicalised first because it arrives raw\n * from the environment while `child` is already a realpath.\n */\nexport const isWithin = (parent: string, child: string, realpath: RealpathFn): boolean => {\n const rel = path.relative(realpath(path.resolve(parent)), path.resolve(child))\n\n return rel !== '' && !rel.startsWith('..') && !path.isAbsolute(rel)\n}\n\n/** Does `p` contain `name` as a whole path SEGMENT? `/a/node_modules_backup/b` must not match `node_modules`. */\nexport const hasSegment = (p: string, name: string): boolean => {\n return path.resolve(p).split(path.sep).includes(name)\n}\n\n/**\n * Is `p` inside a Homebrew keg belonging to the `name` FORMULA \u2014 i.e. `.../Cellar/<name>/<version>/...`?\n *\n * The formula name is what makes this sound. A bare `Cellar` segment says only \"somewhere under a keg\",\n * and the keg it lands in is routinely someone else's: when npm's global prefix is a node keg\n * (`npm config set prefix \"$(brew --prefix node)\"`, or any keg-only `node@X`), an `npm i -g` package\n * installs to `Cellar/node/<v>/lib/node_modules/<pkg>/...` \u2014 brew has never heard of it, yet the segment\n * is right there. Requiring `<name>` to sit directly after `Cellar` is what separates \"brew installed\n * THIS\" from \"brew installed the runtime that installed this\".\n *\n * Works for both keg layouts, since each is rooted at the formula: a plain formula\n * (`Cellar/infra-kit/1.2.3/bin/infra-kit`) and brew's node-CLI layout\n * (`Cellar/infra-kit/1.2.3/libexec/lib/node_modules/infra-kit/dist/cli.js`). Do NOT try to tell them\n * apart by excluding `node_modules` \u2014 the second one contains it.\n */\nexport const isBrewKegOf = (p: string, name: string): boolean => {\n const segments = path.resolve(p).split(path.sep)\n const cellar = segments.indexOf('Cellar')\n\n return cellar !== -1 && segments[cellar + 1] === name\n}\n\n/**\n * The npm global prefix that owns `binRealPath`, derived from the path ITSELF, or null when the\n * layout is not an npm global one.\n *\n * Matches `<prefix>/lib/node_modules/<packageName>` \u2014 npm's global layout and no other manager's\n * \u2014 requiring BOTH the `lib` parent and our package as the immediate child. Windows global npm has\n * no `lib` segment (`%APPDATA%\\npm\\node_modules`), so this returns null there and detection falls\n * through to `npm root -g`, which is correct on Windows, where there is normally one npm.\n */\n// This is the one signal that cannot point at the wrong tree. Everything else in this module\n// answers \"is this file somewhere inside tool X's directory?\", and containment is not ownership:\n// - `npm root -g` answers for whichever `npm` is first on PATH, which is routinely a DIFFERENT\n// node than the one that installed us (a pnpm/nvm/fnm-managed node, or a node that has since\n// been removed). It then reports a root that does not contain us, every matcher misses, and\n// detection degrades to `unknown` \u2014 a notice printed forever, on the single most common install\n// method. That is the bug this exists to close.\n// - `PNPM_HOME` containment is satisfied by `<PNPM_HOME>/nodejs/<v>/lib/node_modules/<pkg>` (a\n// plain `npm i -g` under a pnpm-managed node), yet `pnpm add -g` installs to\n// `<PNPM_HOME>/global/<v>/...` \u2014 a different directory. That one is worse than a missed update:\n// the install \"succeeds\" while the binary on PATH stays old, silently, with no notice to show\n// for it.\n//\n// Requiring both segments is what makes the match proof rather than a hint. The `lib` requirement\n// is also what keeps a project-local `<repo>/node_modules/<pkg>` out (it has no `lib`), and nesting\n// cannot spoof it: `.../node_modules/foo/node_modules/<pkg>` fails the `lib` test.\nexport const npmPrefixOfPackage = (binRealPath: string, packageName: string): string | null => {\n const segments = path.resolve(binRealPath).split(path.sep)\n const nodeModules = segments.lastIndexOf('node_modules')\n\n if (nodeModules < 2) return null\n if (segments[nodeModules - 1] !== 'lib') return null\n if (segments[nodeModules + 1] !== packageName) return null\n\n // Drop `lib/node_modules/...`; the empty result of a root-level prefix (`/lib/node_modules/...`) is `/`.\n return segments.slice(0, nodeModules - 1).join(path.sep) || path.sep\n}\n\n// The self-scoped reading, kept as the name every call site below already uses. `dependency-registry`\n// asks the same question about OTHER packages (`portless`), which is why the body moved up one level\n// rather than gaining a defaulted parameter \u2014 a default is how the wrong package silently gets probed.\nconst npmPrefixFromSelfPath = (selfRealPath: string): string | null => {\n return npmPrefixOfPackage(selfRealPath, PACKAGE_NAME)\n}\n\n/**\n * `--prefix` is passed EXPLICITLY rather than trusting the ambient one: the whole point of deriving it is\n * that the `npm` we are about to run may default to a different prefix than the one we are installed in.\n * A command-line flag outranks both `npm_config_prefix` and any `.npmrc`, so this targets the tree we\n * actually run from. With `-g`, npm writes `<prefix>/lib/node_modules` and links bins into `<prefix>/bin`.\n */\nconst npmPrefixInstallCommand = (prefix: string): string[] => {\n return ['npm', 'install', '-g', '--prefix', prefix, LATEST]\n}\n\n/**\n * Render argv as a line the user can paste into a shell.\n *\n * A plain `join(' ')` was fine while every token came from a static table; `--prefix <path>` puts a\n * filesystem path in argv, and `/Users/Ada Lovelace/.nvm/...` pasted unquoted is two arguments and a\n * failed install. Single quotes are sound here without escaping because the callers' validation rejects a\n * token containing a quote \u2014 see `SAFE_COMMAND_TOKEN` in src/lib/update-check/auto-update.ts.\n *\n * @example\n * formatUpdateCommand(['npm', 'install', '-g', '--prefix', '/opt/x y', 'infra-kit@latest'])\n * // => \"npm install -g --prefix '/opt/x y' infra-kit@latest\"\n */\nexport const formatUpdateCommand = (command: string[]): string => {\n return command\n .map((token) => {\n return token.includes(' ') ? `'${token}'` : token\n })\n .join(' ')\n}\n\n/** `env[key]` names a directory that contains `selfRealPath`. Absent/empty env var \u2192 no match. */\nconst underEnvDir = (env: NodeJS.ProcessEnv, key: string, selfRealPath: string, realpath: RealpathFn): boolean => {\n const dir = env[key]\n\n return dir != null && dir !== '' && isWithin(dir, selfRealPath, realpath)\n}\n\ninterface Matcher extends Omit<InstallManagerInfo, 'manager'> {\n manager: InstallManager\n test: (input: Required<Pick<DetectInstallManagerInput, 'selfRealPath' | 'env' | 'realpath'>>) => boolean\n}\n\n/**\n * Consulted FIRST, before {@link npmPrefixFromSelfPath}. Both of these legitimately wrap an npm-shaped\n * `lib/node_modules` tree \u2014 volta at `~/.volta/tools/image/node/<v>/lib/node_modules`, brew at\n * `Cellar/<pkg>/<v>/libexec/lib/node_modules` \u2014 so deriving an npm prefix from the path would hijack\n * installs that a wrapper owns and must keep owning.\n */\nconst WRAPPER_MATCHERS: Matcher[] = [\n {\n manager: 'volta',\n // volta owns the shim; `volta install` is the correct tool, not a workaround \u2014 so we may run it.\n test: ({ selfRealPath, env, realpath }) => {\n return (\n underEnvDir(env, 'VOLTA_HOME', selfRealPath, realpath) ||\n hasSegment(selfRealPath, '.volta') ||\n hasSegment(selfRealPath, 'volta')\n )\n },\n updateCommand: ['volta', 'install', PACKAGE_NAME],\n canSelfSpawn: true,\n },\n {\n manager: 'homebrew',\n // `brew upgrade` can touch the prefix, relink, and prompt \u2014 never ours to run unattended.\n //\n // Our own keg is the ONLY sound signal \u2014 see `isBrewKegOf`. Two broader tests look plausible\n // and are both wrong, because each answers \"did brew put something here?\" when the question is \"does\n // brew own THIS package?\":\n // - `HOMEBREW_PREFIX` containment: when node comes from brew, npm's global prefix IS\n // $HOMEBREW_PREFIX, so EVERY `npm i -g` package lands under it, unknown to brew.\n // - a bare `Cellar` segment: an npm prefix pointed at a node keg puts packages inside that keg.\n // Either misfire tells macOS users to run `brew upgrade infra-kit` \u2014 a formula that does not exist \u2014\n // and, far worse, makes the background auto-updater bail with `cannot-self-spawn` forever, so the\n // very fix for it can never reach them. Detection runs on the realpath, and a linked brew bin always\n // resolves into its own keg, so the narrow test has no false negatives to trade for this.\n test: ({ selfRealPath }) => {\n return isBrewKegOf(selfRealPath, PACKAGE_NAME)\n },\n updateCommand: ['brew', 'upgrade', PACKAGE_NAME],\n canSelfSpawn: false,\n },\n]\n\n/**\n * Consulted LAST, after {@link npmPrefixFromSelfPath} has had its say. Each of these proves only that we\n * live somewhere inside a tool's directory tree, which is weaker than knowing the layout npm itself\n * created \u2014 see the `PNPM_HOME`/`nodejs` case in that helper's doc for a containment hit whose install\n * command targets the wrong directory.\n */\nconst TREE_MATCHERS: Matcher[] = [\n {\n manager: 'pnpm',\n test: ({ selfRealPath, env, realpath }) => {\n return (\n underEnvDir(env, 'PNPM_HOME', selfRealPath, realpath) ||\n (hasSegment(selfRealPath, 'pnpm') && hasSegment(selfRealPath, 'global'))\n )\n },\n updateCommand: ['pnpm', 'add', '-g', LATEST],\n canSelfSpawn: true,\n },\n {\n manager: 'bun',\n test: ({ selfRealPath, env, realpath }) => {\n return underEnvDir(env, 'BUN_INSTALL', selfRealPath, realpath) || hasSegment(selfRealPath, '.bun')\n },\n updateCommand: ['bun', 'add', '-g', LATEST],\n canSelfSpawn: true,\n },\n {\n manager: 'yarn',\n test: ({ selfRealPath }) => {\n return (\n hasSegment(selfRealPath, '.yarn') || (hasSegment(selfRealPath, 'yarn') && hasSegment(selfRealPath, 'global'))\n )\n },\n updateCommand: ['yarn', 'global', 'add', LATEST],\n canSelfSpawn: true,\n },\n {\n manager: 'npm',\n test: ({ selfRealPath, env, realpath }) => {\n return underEnvDir(env, 'npm_config_prefix', selfRealPath, realpath)\n },\n updateCommand: ['npm', 'install', '-g', LATEST],\n canSelfSpawn: true,\n },\n]\n\nconst NPM_UPDATE_COMMAND = ['npm', 'install', '-g', LATEST]\n\n/**\n * Identify the package manager that owns `selfRealPath`.\n *\n * Order, and why it is this one: wrappers that own an npm-shaped tree (volta, brew) first, then the npm\n * prefix DERIVED from our own path, then the env/path containment matchers, then the `npm root -g` probe.\n * The derived prefix sits above containment because it is the only signal that cannot name a directory we\n * do not live in \u2014 see {@link npmPrefixFromSelfPath}.\n *\n * `lazyNpmRoot` is the last resort and is invoked at most once, only after every matcher has missed \u2014 a\n * pnpm or volta install never pays for the subprocess, and neither does any npm global install in the\n * standard layout, which the derived prefix now settles for free. When nothing matches we report `unknown`\n * with an npm command that is a *suggestion only* (`canSelfSpawn: false`): running a guessed global\n * install is worse than printing one.\n *\n * @example\n * detectInstallManager({ selfRealPath: '/Users/x/Library/pnpm/global/5/node_modules/infra-kit/dist/cli.js', env: {} })\n * // => { manager: 'pnpm', updateCommand: ['pnpm', 'add', '-g', 'infra-kit@latest'], canSelfSpawn: true }\n */\nexport const detectInstallManager = (input: DetectInstallManagerInput): InstallManagerInfo => {\n const { selfRealPath, env, realpath, lazyNpmRoot } = input\n const toInfo = (hit: Matcher): InstallManagerInfo => {\n return { manager: hit.manager, updateCommand: hit.updateCommand, canSelfSpawn: hit.canSelfSpawn }\n }\n const matches = ({ test }: Matcher): boolean => {\n return test({ selfRealPath, env, realpath })\n }\n\n const wrapper = WRAPPER_MATCHERS.find(matches)\n\n if (wrapper) return toInfo(wrapper)\n\n const derivedPrefix = npmPrefixFromSelfPath(selfRealPath)\n\n if (derivedPrefix !== null) {\n return { manager: 'npm', updateCommand: npmPrefixInstallCommand(derivedPrefix), canSelfSpawn: true }\n }\n\n const tree = TREE_MATCHERS.find(matches)\n\n if (tree) return toInfo(tree)\n\n const npmRoot = lazyNpmRoot?.()\n\n if (npmRoot != null && npmRoot !== '' && isWithin(npmRoot, selfRealPath, realpath)) {\n return { manager: 'npm', updateCommand: NPM_UPDATE_COMMAND, canSelfSpawn: true }\n }\n\n return { manager: 'unknown', updateCommand: NPM_UPDATE_COMMAND, canSelfSpawn: false }\n}\n\n/**\n * Is this CLI running from a *project-local* `node_modules` (as opposed to a global root)?\n *\n * The cwd clause is what does the distinguishing \u2014 BOTH a project install and a global root contain a\n * `/node_modules/` segment (`pnpm root -g` is `~/Library/pnpm/global/5/node_modules`). Without it we\n * would nag every global pnpm user to stop using a local install they do not have.\n *\n * Accepted false-negative: invoked from a subdirectory (cwd `project/apps/x`, deps at\n * `project/node_modules`) this returns false and the advisory stays silent. Under-warning is the safe\n * direction for a best-effort, never-throwing advisory \u2014 do not \"fix\" it by dropping the cwd clause.\n *\n * `cwd` is canonicalised before comparison for the same reason `detectInstallManager` canonicalises its\n * roots: `selfRealPath` is a realpath, and comparing it to an unresolved cwd never matches.\n *\n * @example\n * isLocalNodeModulesInstall('/repo/node_modules/infra-kit/dist/cli.js', '/repo', (p) => p) // => true\n */\nexport const isLocalNodeModulesInstall = (selfRealPath: string, cwd: string, realpath: RealpathFn): boolean => {\n return hasSegment(selfRealPath, 'node_modules') && isWithin(cwd, selfRealPath, realpath)\n}\n", "import { realpathSync } from 'node:fs'\nimport path from 'node:path'\n\n/**\n * The impure companion to the pure detection module: canonicalise a directory that may not exist.\n *\n * `realpathSync` throws on a missing path, and candidate roots routinely miss \u2014 `PNPM_HOME` can point at a\n * directory the user never created, `npm root -g` can name a prefix that was removed. A throw there would\n * turn \"we could not identify your install\" into a crash, so an unresolvable path falls back to\n * `path.resolve`, which still normalises `.`/`..` and yields a usable, non-matching absolute path.\n */\nexport const safeRealpath = (dir: string): string => {\n try {\n return realpathSync(dir)\n } catch {\n return path.resolve(dir)\n }\n}\n", "/* eslint-disable sonarjs/no-os-command-from-path */\n/**\n * `npm root -g`, the LAZY fallback for {@link detectInstallManager}.\n *\n * Why it is indispensable: the `npm` matcher keys off `npm_config_prefix`, which npm sets only while npm\n * itself is running. A user who ran `npm i -g infra-kit` months ago and now types `ik` has no such var,\n * so every cheap matcher misses and detection reports `unknown` / `canSelfSpawn: false`. Without this\n * probe the single most common install method can never update itself.\n *\n * Read by the background update worker, and by the `doctor` advisory that names the command a human\n * would run by hand \u2014 one probe so the two can never disagree about who owns the install.\n */\nimport { execFileSync } from 'node:child_process'\nimport process from 'node:process'\n\nconst NPM_ROOT_TIMEOUT_MS = 3_000\n\n/**\n * The global npm root, or undefined when npm is absent, slow, or errors. Costs a subprocess, so\n * `detectInstallManager` invokes it at most once and only after every env/path matcher has missed \u2014 a\n * pnpm or volta install never pays for it.\n *\n * Resolving the user's `npm` from PATH is inherent here: we must ask the very package manager that owns\n * this install where its global root is. Pinning an absolute path would defeat the detection.\n *\n * @example\n * defaultLazyNpmRoot() // => '/usr/local/lib/node_modules' | undefined\n */\nexport const defaultLazyNpmRoot = (): string | undefined => {\n try {\n const out = execFileSync('npm', ['root', '-g'], {\n encoding: 'utf-8',\n timeout: NPM_ROOT_TIMEOUT_MS,\n stdio: ['ignore', 'pipe', 'ignore'],\n shell: process.platform === 'win32',\n })\n const trimmed = out.trim()\n\n return trimmed === '' ? undefined : trimmed\n } catch {\n return undefined\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["package_default", "path", "PACKAGE_NAME", "LATEST", "isWithin", "parent", "child", "realpath", "rel", "hasSegment", "p", "name", "isBrewKegOf", "segments", "cellar", "npmPrefixOfPackage", "binRealPath", "packageName", "nodeModules", "npmPrefixFromSelfPath", "selfRealPath", "npmPrefixInstallCommand", "prefix", "formatUpdateCommand", "command", "token", "underEnvDir", "env", "key", "dir", "WRAPPER_MATCHERS", "TREE_MATCHERS", "NPM_UPDATE_COMMAND", "detectInstallManager", "input", "lazyNpmRoot", "toInfo", "hit", "matches", "test", "wrapper", "derivedPrefix", "tree", "npmRoot", "isLocalNodeModulesInstall", "cwd", "realpathSync", "path", "safeRealpath", "dir", "execFileSync", "process", "NPM_ROOT_TIMEOUT_MS", "defaultLazyNpmRoot", "trimmed"]
|
|
7
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as z}from"./chunk-
|
|
1
|
+
import{a as z}from"./chunk-XJOY7J3G.js";import{L as m,X as q,da as H,fa as K,g as U,m as j}from"./chunk-Q4HKBLQG.js";import{execFile as me,execFileSync as de}from"node:child_process";import x from"node:process";var fe=5e3,ge=100,V=2e3,X="/bin/ps",xe=1e3,Y=["-eo","pid=,ppid=,pgid=,lstart="],Z=8<<20,ee=e=>e.split(`
|
|
2
2
|
`).flatMap(r=>{let[t,o,n,...i]=r.trim().split(/\s+/);if(t==null||o==null||n==null)return[];let a=Number(t),c=Number(o),u=Number(n);return!Number.isInteger(a)||!Number.isInteger(c)||!Number.isInteger(u)?[]:[{pid:a,ppid:c,pgid:u,lstart:i.join(" ")}]}),re=e=>{let r=new Map;for(let t of e)t.pid===t.pgid&&r.set(t.pgid,t.lstart);return r},we=(e,r,t)=>{let o=re(r);return oe(e,r,t).flatMap(n=>{let i=o.get(n);return i==null||i===""?[]:[{pgid:n,leaderStart:i}]})},te=(e,r)=>{let t=re(r);return e.flatMap(({pgid:o,leaderStart:n})=>t.get(o)===n?[o]:[])},Q=(e,r)=>te(e,r).flatMap(t=>{try{x.kill(-t,"SIGKILL")}catch{return[]}return[t]}),oe=(e,r,t)=>{let o=new Map;for(let c of r){let u=o.get(c.ppid);u?u.push(c):o.set(c.ppid,[c])}let n=new Set([e]),i=new Set([e]),a=[e];for(let c=0;c<a.length;c+=1)for(let u of o.get(a[c]??-1)??[])i.has(u.pid)||(i.add(u.pid),n.add(u.pgid),a.push(u.pid));return[...n].filter(c=>c>1&&c!==t)},L=()=>{try{return ee(de(X,[...Y],{encoding:"utf8",maxBuffer:Z}))}catch{return[]}},ye=async()=>new Promise(e=>{me(X,[...Y],{encoding:"utf8",maxBuffer:Z},(r,t)=>{e(r?[]:ee(t))})}),Pe=(e,r,t)=>t.some(o=>o.pid===e&&o.ppid===r),A=(e,r)=>{let t=r.find(o=>o.pid===x.pid)?.pgid;return oe(e,r,t)},ne=e=>{try{return x.kill(-e,0),!0}catch{return!1}},I=(e,r)=>{for(let t of e)try{x.kill(-t,r)}catch{}},w=new Set,Se=(e,r,t)=>{let o=A(e,r),n=t.flatMap(i=>te(i,r));return[...new Set([...o,...n])]},se=()=>{let e=L(),r=[...w].map(t=>t());I(Se(x.pid,e,r),"SIGKILL")},be=async e=>new Promise(r=>{setTimeout(r,e)}),N=async(e,r)=>{let t=Date.now()+r,o=e;for(;o.length>0&&Date.now()<t&&(o=o.filter(ne),o.length!==0);)await be(ge);return o};function vr(e,r=fe,t,o=L){e.unref();let n=!1,i=!1,a=[],c=null,u=()=>a;w.add(u);let p=()=>{c&&clearInterval(c),c=null},d=async()=>{await N(a.map(s=>s.pgid),V),w.delete(u)},f=s=>{let l=e.pid;if(l==null||i||n||s.length===0)return;let v=s.find(R=>R.pid===x.pid)?.pgid,h=we(l,s,v);h.length>0&&(a=h)},g=async()=>{e.pid==null||i||n||f(await ye())};f(L()),c=setInterval(()=>{g()},xe),c.unref();let b=s=>{n||t?.(s)};return e.on("exit",(s,l)=>{i=!0,p(),n||(Q(a,o()),d()),b(`exited unexpectedly (code=${s??"null"}, signal=${l??"null"})`)}),e.on("error",s=>{b(`failed to spawn: ${s.message}`)}),{kill:async()=>{n=!0,p();let s=e.pid;if(s==null){w.delete(u);return}if(e.exitCode!==null||e.signalCode!==null){Q(a,o()),await d();return}let l=o();if(l.length>0&&!Pe(s,x.pid,l))return;let v=A(s,l);I(v,"SIGTERM");let h=await N(v,r);if(h.length===0){w.delete(u);return}let R=A(s,o()),J=[...new Set([...h,...R])].filter(ne);I(J,"SIGKILL"),await N(J,V),w.delete(u)}}}import{constants as he}from"node:os";import E from"node:process";var ke=["SIGINT","SIGTERM","SIGHUP"],ve=he.signals,Ee=2,T=e=>128+(ve[e]??Ee),Ce=2e4,Re=e=>{E.exit(e)},Ne=(e,r)=>{E.on(e,r)},Le=(e,r)=>{E.off(e,r)},Ae=(e,r)=>{let t=setTimeout(e,r);return t.unref(),()=>{clearTimeout(t)}},_=e=>{try{E.stderr.write(e)}catch{}},Ie=(e,r)=>{let t=r instanceof Error?`${r.message}
|
|
3
3
|
${r.stack??"(no stack)"}`:String(r);_(`
|
|
4
4
|
\u2717 Teardown failed while handling ${e}: ${t}
|
|
@@ -7,4 +7,4 @@ ${r.stack??"(no stack)"}`:String(r);_(`
|
|
|
7
7
|
`),d?.(),n(),g(),r(T(s));return}p=s,d=a(()=>{let l=`
|
|
8
8
|
\u26A0 Teardown deadline exceeded at stage=${c()} after ${i}ms \u2014 force-quitting.
|
|
9
9
|
`;_(l),u(l),n(),g(),r(T(s))},i),(async()=>{try{await e(s)}catch(l){Ie(s,l)}finally{d?.(),g(),r(T(s))}})()};for(let s of ke){let l=()=>b(s);f.set(s,l),t(s,l)}return g};import Te from"node:process";import{$ as O}from"zx";var _e=async()=>{try{return await O`cmux --version`.quiet(),!0}catch{return!1}},Oe=async e=>{let{cwd:r,title:t,layout:o}=e,n=JSON.stringify(o),a=(await O({env:{...Te.env,CMUX_QUIET:"1"}})`cmux new-workspace --name ${t} --cwd ${r} --focus false --layout ${n}`).stdout;return Me(a)},De=async e=>{try{await O`cmux close-workspace --workspace ${e}`.quiet()}catch(r){m.debug({error:r,ref:e},"cmux: skipped closing dev workspace")}},Me=e=>{let r=e.match(/workspace:\d+/);if(!r)throw new Error("cmux: could not locate workspace ref in new-workspace output");return r[0]};import{$ as Ge}from"zx";import{realpath as $e}from"node:fs/promises";import{$ as ie}from"zx";var C=async e=>{try{return await $e(e)}catch{return e}},D=async()=>{try{let[e,r]=await Promise.all([ie`cmux workspace list --json`.quiet(),ie`cmux workspace-group list --json`.quiet()]),t=JSON.parse(e.stdout).workspaces??[],o=JSON.parse(r.stdout).groups??[],n=new Set(o.map(a=>a.anchor_workspace_ref).filter(a=>typeof a=="string")),i=new Map;for(let a of t)!a.current_directory||n.has(a.ref)||i.set(await C(a.current_directory),a.ref);return i}catch(e){return m.debug({error:e},"cmux: skipped listing workspaces by cwd"),new Map}};var We=async e=>{try{let t=(await D()).get(await C(e));if(!t)return;await Ge`cmux workspace close ${t}`.quiet()}catch(r){m.debug({error:r,cwd:e},"cmux: skipped closing workspace by cwd")}};import{$ as M}from"zx";var ae=async e=>{try{let r=(await M`cmux workspace-group list --json`.quiet()).stdout;return(JSON.parse(r).groups??[]).find(n=>n.name===e)?.ref??null}catch(r){return m.debug({error:r,name:e},"cmux: skipped group lookup"),null}},Be=async(e,r)=>{try{let o=(await M`cmux workspace-group create --name ${e} --from ${r.join(",")}`).stdout.match(/workspace_group:\d+/)?.[0]??await ae(e);return o&&await M`cmux workspace-group pin ${o}`.quiet(),o??null}catch(t){return m.warn({error:t,name:e},"\u26A0\uFE0F cmux: failed to create workspace group"),null}};import{$ as y}from"zx";var Fe=async e=>{let{cwd:r,title:t,group:o}=e,n=H(await K()),i=o?(await y`cmux workspace create --cwd ${r} --group ${o} --group-placement end`).stdout:(await y`cmux workspace create --cwd ${r}`).stdout,a=Ue(i),c=(await y`cmux list-pane-surfaces --workspace ${a}`).stdout,u=Je(c);return await y`cmux new-split right --workspace ${a} --surface ${u}`,n==="three-pane"&&await y`cmux new-split down --workspace ${a} --surface ${u}`,t&&await y`cmux workspace rename --workspace ${a} --title ${t}`,a},Je=e=>{let r=e.match(/surface:\d+/);if(!r)throw new Error("cmux: could not locate initial surface in list-pane-surfaces output");return r[0]},Ue=e=>{let r=e.match(/workspace:\d+/);if(!r)throw new Error("cmux: could not locate workspace ref in workspace create output");return r[0]};var je=e=>{let{branch:r}=e,t=U(r);return t?j(t):r};var qe=new Set(["ExitPromptError","AbortPromptError","PromptCancelledError"]),ce=e=>e instanceof Error&&qe.has(e.name),nt=e=>{if(ce(e))return!0;let r=e?.cause;return ce(r)};import{loadDev as He}from"@slip-stream-kit/config/internal";import Ke from"node:path";var ze=(e,r)=>{let t=new Set;for(let o of Object.values(e))for(let n of Object.keys(q(o,r).proxy))t.add(n);return[...t]},Ve=async(e,r)=>{let t={},o=[];return await Promise.all(r.map(async n=>{try{let a=(await He(Ke.join(e,"apps",n,"ui")))?.proxy?.routes;if(!a)return;t[n]=Object.fromEntries(Object.entries(a).map(([c,u])=>[c,u.packageName]))}catch(i){o.push({app:n,message:i instanceof Error?i.message:String(i)})}})),{routePkg:(n,i)=>t[n]?.[i],loadErrors:o}},ut=async(e,r,t,o)=>{let{routePkg:n,loadErrors:i}=await Ve(e,ze(r,t));return{ctx:{discovered:t,apiPkgByApp:Object.fromEntries(o.map(a=>[a.name,a.packageName])),routePkg:n},loadErrors:i}};import{execFile as Qe}from"node:child_process";import{createHash as Xe}from"node:crypto";import{existsSync as ue,readFileSync as k}from"node:fs";import Ye from"node:http";import Ze from"node:https";import er from"node:net";import{homedir as rr}from"node:os";import{dirname as $,join as P}from"node:path";import S from"node:process";import tr from"node:tls";import{fileURLToPath as or}from"node:url";import{promisify as nr}from"node:util";var sr=nr(Qe),ir=e=>{let r=JSON.parse(k(e,"utf-8")),t=typeof r.bin=="string"?r.bin:r.bin?.portless;return t==null||t===""?null:t},ar=()=>{try{let e=$(or(import.meta.url));for(;;){let r=P(e,"node_modules","portless","package.json");if(ue(r)){let o=ir(r);return o==null?null:P($(r),o)}let t=$(e);if(t===e)return null;e=t}}catch{return null}},G,le=()=>(G===void 0&&(G=ar()),G),cr=/^[\w@%+=:,./-]+$/,ur="'\\''",lr=e=>cr.test(e)?e:`'${e.replaceAll("'",ur)}'`,vt=(e,r)=>{let t=[r.execPath??S.execPath,r.bin,...e];return(r.sudo===!0?"sudo ":"")+t.map(lr).join(" ")},pr=1500,W=1500,mr="x-portless",B="127.0.0.1",dr="localhost",fr="/Library/LaunchDaemons/sh.portless.proxy.plist",gr="/etc/systemd/system/portless.service",xr=(e=ue)=>{try{return S.platform==="darwin"?e(fr)?"yes":"no":S.platform==="linux"?e(gr)?"yes":"no":"unknown"}catch{return"unknown"}},wr=e=>new Promise(r=>{let t=er.connect({host:B,port:e}),o=n=>{t.destroy(),r(n)};t.setTimeout(W),t.once("connect",()=>{o(!0)}),t.once("timeout",()=>{o(!1)}),t.once("error",()=>{o(!1)})}),yr=(e,r)=>new Promise(t=>{let n=(r?Ze.request:Ye.request)({host:B,port:e,method:"HEAD",path:"/",timeout:W,...r?{rejectUnauthorized:!1,servername:dr}:{}},i=>{i.resume(),t(i.headers[mr]==="1")});n.on("error",()=>{t(!1)}),n.on("timeout",()=>{n.destroy(),t(!1)}),n.end()}),Pr=async(e,{timeoutMs:r})=>{let t=le();if(t==null)throw new Error("portless is not installed (not resolvable from node_modules)");await sr(S.execPath,[t,...e],{signal:AbortSignal.timeout(r),encoding:"utf-8",env:z(S.env)})},F=()=>S.env.PORTLESS_STATE_DIR??P(rr(),".portless"),Sr="ca.pem",br="ca.trusted",pe=()=>P(F(),Sr),Et=()=>{try{let e=k(P(F(),br),"utf-8").trim();return e===""?!1:Xe("sha256").update(k(pe())).digest("hex")===e.toLowerCase()}catch{return!1}},Ct=(e,r)=>new Promise(t=>{let o;try{o=k(pe())}catch{t({ok:!1,code:"ENOENT"});return}let n=tr.connect({host:B,port:e,servername:r,ca:[o],rejectUnauthorized:!0},()=>{let i=n.authorizationError,a=n.authorized;n.destroy(),t(a?{ok:!0}:{ok:!1,code:i?.code??i?.message??"UNKNOWN"})});n.setTimeout(W),n.once("timeout",()=>{n.destroy(),t({ok:!1,code:"ETIMEDOUT"})}),n.once("error",i=>{n.destroy(),t({ok:!1,code:i.code??"UNKNOWN"})})}),Rt=()=>{try{let e=JSON.parse(k(P(F(),"routes.json"),"utf-8"));return Array.isArray(e)?e.flatMap(r=>{let{hostname:t,port:o}=r??{};return typeof t!="string"||t===""||typeof o!="number"?[]:[{name:t,port:o}]}):[]}catch{return[]}},Nt=(e={})=>{let r=e.bin===void 0?le():e.bin,t=e.run??Pr,o=e.isListening??wr,n=e.isProxyServing??yr,i=e.isServiceInstalled??xr,a=e.timeoutMs??pr,c=null,u=async s=>{try{return await t(s,{timeoutMs:a}),!0}catch{return!1}},p=async()=>(c??=await u(["--version"]),c);return{binPath:()=>r,isAvailable:p,isProxyServing:async(s,l)=>!await p()||!await o(s)?!1:n(s,l),probeProxy:async(s,l)=>await o(s)?await n(s,l)?"serving":"not-portless":"daemon-down",isServiceInstalled:i,registerAlias:async(s,l)=>await p()?u(["alias",s,String(l)]):!1,removeAlias:async s=>{await p()&&await u(["alias","--remove",s])}}};export{ut as a,ar as b,vt as c,wr as d,yr as e,pe as f,Et as g,Ct as h,Rt as i,Nt as j,se as k,vr as l,T as m,Lr as n,C as o,D as p,We as q,ae as r,Be as s,_e as t,Oe as u,De as v,Fe as w,je as x,nt as y};
|
|
10
|
-
//# sourceMappingURL=chunk-
|
|
10
|
+
//# sourceMappingURL=chunk-Q23IJP6D.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as ic,b as pc,c as Uo,d as $t,e as uc,f as mc,g as fc,h as gc,i as Xn,j as hc,m as bc,o as gr,p as ze,q as en,r as rn,s as tn,w as zr,x as on,y as xe}from"./chunk-
|
|
1
|
+
import{a as ic,b as pc,c as Uo,d as $t,e as uc,f as mc,g as fc,h as gc,i as Xn,j as hc,m as bc,o as gr,p as ze,q as en,r as rn,s as tn,w as zr,x as on,y as xe}from"./chunk-Q23IJP6D.js";import{a as se,c as Qo,d as Qn,e as kc,j as wc}from"./chunk-6GWRKIZ7.js";import{b as dc}from"./chunk-XJOY7J3G.js";import{a as Ho,c as fe,d as b,e as Ot,f as ae,i as h,j as Xo,k as A,l as V}from"./chunk-HXBIE4JP.js";import{$ as He,A as Go,B as It,C as zn,D as Ko,E as Qa,F as ec,G as qn,H as Yn,I as rc,L as l,N as tc,P as oc,W as nc,Z as sc,_ as ac,a as Jo,aa as cc,b as g,ba as Zn,ca as ve,d as J,e as Ka,ea as H,f as Bo,fa as S,g as j,ga as lc,h as me,ha as Br,i as he,j as Ua,k as Hn,l as U,m as L,n as pr,o as Ha,p as Ke,q as ne,r as R,s as Ue,t as Jr,u as za,v as qa,w as Ya,x as Za,y as Xa,z as Vo}from"./chunk-Q4HKBLQG.js";import{a as ie,b as zo,c as Dt,d as vc,e as qo,f as Vr,g as Gr,h as Yo,i as Kr,j as ur,k as Ur,l as Zo,n as Hr,o as yc,p as mr,q as fr,r as Z}from"./chunk-D4UYDBN5.js";import Vc from"node:process";import{z as le}from"zod";import Tc from"node:fs";import qr from"node:path";import{packageConfigSchema as su}from"@slip-stream-kit/config/internal";import Ec from"node:fs/promises";import os from"node:path";import{pathToFileURL as iu}from"node:url";import{z as au}from"zod";import Rc from"node:path";var _t=["frontend","backend","lib","e2e","mobile"],Qp={ui:"frontend",api:"backend",tests:"e2e"},eu="mobile-app",ru=[{type:"e2e",packages:["@playwright/test"]},{type:"mobile",packages:["@capacitor/core","@capacitor/cli"]},{type:"backend",packages:["serverless"]}],tu=(e,r)=>{let t=Rc.relative(r,e).split(Rc.sep).filter(s=>s!==""&&s!=="."),[o,,n]=t;if(t.length===3&&o==="apps"&&n!==void 0){let s=Qp[n];if(s)return s}return t.at(-1)===eu?"mobile":null},ou=e=>{let r=new Set([...Object.keys(e.dependencies??{}),...Object.keys(e.devDependencies??{}),...Object.keys(e.peerDependencies??{})]);for(let o of ru)if(o.packages.some(n=>r.has(n)))return o.type;return r.has("vite")&&r.has("react")&&!!e.scripts?.dev?"frontend":null},es=({packageDir:e,repoRoot:r,pkgJson:t,declaredType:o})=>o??tu(e,r)??ou(t)??"lib";var qe={requiredScripts:["build","ts-check","eslint-check","prettier-check","test"],requiredFiles:["tsconfig.json","eslint.config.js","readme.md"],turboTasks:[]},rs={requiredScripts:["build","dev","test","qa","infra-kit-check","fix"],requiredFiles:["turbo.json","pnpm-workspace.yaml"],turboTasks:["build","test","ts-check","eslint-check","prettier-check","infra-kit-check"]},ts=(e,r=qe)=>({requiredScripts:e.requiredScripts??[...r.requiredScripts],requiredFiles:e.requiredFiles??[...r.requiredFiles],turboTasks:e.turbo?.requiredTasks??[...r.turboTasks]});import nu from"node:fs/promises";var ye=async e=>{try{return await nu.access(e),!0}catch{return!1}};var Se="infra-kit.config.ts",Nt=async e=>{try{let r=await Ec.readFile(os.join(e,"package.json"),"utf-8");return JSON.parse(r)}catch{return{}}},Pc=async e=>{let r=await Ec.stat(e),n=(await import(`${iu(e).href}?mtime=${Number(r.mtimeMs)}`)).default;if(n===void 0)throw new Error(`${Se} at ${e} has no default export`);return typeof n=="function"?await n():n},jt=async e=>{let r=os.join(e,Se);if(await ye(r))try{let o=(await Pc(r))?.type;return _t.find(n=>n===o)}catch{return}},Mt=async(e,r=qe)=>{let t=os.join(e,Se);if(!await ye(t))throw new Error(`${Se} not found at ${t}`);let o=await Pc(t),n=su.safeParse(o);if(!n.success)throw new Error(`Invalid ${Se} at ${t}: ${au.prettifyError(n.error)}`);return ts(n.data,r)};import xc from"node:fs/promises";import nn from"node:path";import cu from"yaml";var lu="pnpm-workspace.yaml",du=async e=>(await xc.readdir(e,{withFileTypes:!0}).catch(()=>[])).filter(t=>t.isDirectory()).map(t=>nn.join(e,t.name)),pu=async(e,r)=>{let t=[];for(let o of e){if(r==="*"){t.push(...await du(o));continue}let n=nn.join(o,r);await ye(n)&&t.push(n)}return t},uu=async(e,r)=>{let t=[e];for(let o of r.split("/"))t=await pu(t,o);return t},Q=async e=>{let r=await xc.readFile(nn.join(e,lu),"utf-8"),o=((cu.parse(r)??{}).packages??[]).filter(s=>!s.startsWith("!")&&!s.startsWith("vendor")),n=new Set;for(let s of o){let i=await uu(e,s);for(let a of i)await ye(nn.join(a,"package.json"))&&n.add(a)}return[...n].sort()};import Ft from"node:path";var Lt=async e=>{let r=Ft.resolve(e);for(;r!==Ft.dirname(r);){if(await ye(Ft.join(r,"package.json")))return r;r=Ft.dirname(r)}if(await ye(Ft.join(r,"package.json")))return r;throw new Error(`No package.json found in or above ${e} \u2014 cd into a package directory, or pass --root to audit a monorepo root`)};var ke=(e,r,t)=>{let o=e.indexOf(r),n=e.indexOf(t);return o!==-1&&n!==-1&&n>=o},Ye=(e,r,t)=>{let o=e.indexOf(r),n=e.indexOf(t);if(o===-1||n===-1||n<o)return null;let s=e.slice(0,o).replace(/\n+$/,""),i=e.slice(n+t.length).replace(/^\n+/,"");return s+(i?`
|
|
2
2
|
${i}`:"")},ns=(e,r)=>{let t=e.indexOf(r);if(t===-1)return null;let n=e.slice(t+r.length).match(/^([^\s>]+)/);return n?n[1]:null},Sc=(e,r,t)=>`${e}
|
|
3
3
|
${r}
|
|
4
4
|
${t}`,Wt=({content:e,body:r,startMarker:t,endMarker:o,placement:n="replace-in-place"})=>{let s=Sc(t,r,o),i=ke(e,t,o);if(n==="replace-in-place"&&i){let d=e.indexOf(t),u=e.indexOf(o)+o.length;return e.slice(0,d)+s+e.slice(u)}let c=(i?Ye(e,t,o)??e:e).replace(/\n+$/,"");return c.length>0?`${c}
|
|
@@ -418,5 +418,5 @@ ${Mn(E)}`);let oe=(await Zi({env:m,project:c,isShared:T,isClean:C,runningEnvs:aw
|
|
|
418
418
|
${e} (${r.length}):`);for(let t of r.slice(0,ja))l.info(` ${t}`);r.length>ja&&l.info(` \u2026and ${r.length-ja} more`)}},Gp=async(e={})=>{let r=e.cwd??await R(),t=Vp.join(r,Je),o={modified:[],added:[],removed:[],fileCount:0};if(!Bp(t)){l.info(`\u2139\uFE0F No ${Je}/ folder found \u2014 nothing to check.`);let u={status:"skipped",ok:!0,...o};return{content:y(JSON.stringify(u,null,2)),structuredContent:u}}if(!Bp(Vp.join(t,Be))){l.error(`\u274C Missing ${Je}/${Be}. Re-run the vendor sync to generate it.`);let u={status:"missing-manifest",ok:!1,...o};return{content:y(JSON.stringify(u,null,2)),structuredContent:u}}let n=_a(t);if(Oa(n)){l.error(`\u274C ${Je}/${Be} has a newer schemaVersion (${String(n.schemaVersion)}) than this CLI supports. Upgrade infra-kit.`);let u={status:"unknown-schema",ok:!1,...o};return{content:y(JSON.stringify(u,null,2)),structuredContent:u}}let{modified:s,added:i,removed:a}=Na(t,n),c=s.length>0||i.length>0||a.length>0;c?(l.error(`\u274C ${Je}/ has drifted from ${Je}/${Be}.`),l.error(" These files are mirrored from the source repo \u2014 edit them upstream, not here."),Ma("Modified",s),Ma("Added (not in manifest)",i),Ma("Removed (in manifest, now missing)",a)):l.info(`\u2705 ${Je}/ matches manifest (${n.fileCount} files).`);let d={status:c?"drift":"clean",ok:!c,fileCount:n.fileCount,modified:s,added:i,removed:a};return{content:y(JSON.stringify(d,null,2)),structuredContent:d}},xw={status:Ve.enum(["clean","drift","skipped","missing-manifest","unknown-schema"]),ok:Ve.boolean().describe("Whether the vendor tree matches its manifest (false \u2192 CI should fail)"),fileCount:Ve.number(),modified:Ve.array(Ve.string()),added:Ve.array(Ve.string()),removed:Ve.array(Ve.string())},Fa=k({name:"vendor-check",description:"Verify that files under vendor/ match the checksums in vendor/.sync-manifest.json. Self-contained (no source repo or config needed). Returns ok=false on drift, missing manifest, or an unknown future schemaVersion; ok=true when clean or when no vendor/ folder exists.",inputSchema:{},outputSchema:xw,handler:()=>Gp({cwd:Pw.cwd()})});import{z as Sw}from"zod";var Kp=async()=>{let e=se.version;l.info(e);let r={version:e};return{content:y(JSON.stringify(r,null,2)),structuredContent:r}},La=k({name:"version",description:"Print the installed infra-kit CLI version",inputSchema:{},outputSchema:{version:Sw.string().describe("Installed infra-kit CLI version (from package.json)")},handler:Kp});import Up from"@inquirer/confirm";import Tw from"node:path";import{z as Ge}from"zod";import{$ as Lo}from"zx";var Cw="feature",Aw="release",zp=async e=>{let{confirmedCommand:r,all:t,versions:o,githubDesktop:n,cmux:s}=e,i=e.ide??e.cursor;await re({operation:"create worktrees"});try{let a=await ne("release"),c=await R(),d=`${c}${Z}`;await Hp(`${d}/${Aw}`),await Hp(`${d}/${Cw}`);let u=[];if(o)u=o.split(",").map(O=>he(me(O.trim())));else{let O=await D(),C=O.map(E=>E.branch);if(C.length===0)return l.info("\u2139\uFE0F No open release branches found"),h.print(),{content:y(JSON.stringify({createdWorktrees:[],count:0},null,2)),structuredContent:{createdWorktrees:[],count:0}};if(t)u=C;else{h.setInteractive();let E=new Map(O.map(oe=>[oe.branch,_(oe.title)])),Pe=await B();u=await Pt(Y({branches:C,descriptions:Pe,types:E}),{required:!0})}}t?h.addOption("--all",!0):h.addOption("--versions",$r(u)),await V(r,"Are you sure you want to proceed with these worktree changes?"),r||h.addOption("--yes",!0);let p=await S(),m=i??(ve(p).length>0?"workspace":"none");h.addOption("--ide",m);let v=n??p.worktrees?.openInGithubDesktop??await A(O=>Up({message:"Open created worktrees in GitHub Desktop?"},O),{whenHeadless:{value:!1}});typeof n>"u"&&p.worktrees?.openInGithubDesktop===void 0&&h.setInteractive(),v?h.addOption("--github-desktop",!0):h.addOption("--no-github-desktop",!0);let f=s??p.worktrees?.openInCmux??await A(O=>Up({message:"Open created worktrees in cmux?"},O),{whenHeadless:{value:!1}});typeof s>"u"&&p.worktrees?.openInCmux===void 0&&h.setInteractive(),f?h.addOption("--cmux",!0):h.addOption("--no-cmux",!0);let{branchesToCreate:w}=Iw({selectedReleaseBranches:u,currentWorktrees:a}),T=await $w(w,d);if(Dw(T),m==="workspace"&&await fa({projectRoot:c,worktreeDir:d,branches:T}),v)for(let O of T)await Lo`github ${d}/${O}`,await Lo`sleep 5`;if(f){let O=Tw.basename(await Ue(c)),C=await ze(),E=await rn(O),Pe=!1;for(let oe of T){let Wr=`${d}/${oe}`;if(C.has(await gr(Wr)))continue;let lr=on({branch:oe});try{if(E)await zr({cwd:Wr,title:lr,group:E});else{let dr=await zr({cwd:Wr,title:lr});Pe||(E=await tn(O,[dr]),Pe=!0)}}catch(dr){l.warn({error:dr,branch:oe},`\u26A0\uFE0F Failed to open cmux workspace for ${oe}`)}}}h.print();let F={createdWorktrees:T,count:T.length};return{content:y(JSON.stringify(F,null,2)),structuredContent:F}}catch(a){throw xe(a)?a:(l.debug({err:a},"Error managing worktrees"),new g(a,{operation:"create worktrees",remediation:"verify branches don't already exist as worktrees: 'git worktree list'"}))}},Hp=async e=>{await Lo`mkdir -p ${e}`},Iw=e=>{let{selectedReleaseBranches:r,currentWorktrees:t}=e,o=t.filter(s=>pr(s));return{branchesToCreate:r.filter(s=>!o.includes(s))}},$w=async(e,r)=>{let t=await Promise.allSettled(e.map(async n=>{let s=`${r}/${n}`;return await Lo`git worktree add ${s} ${n}`,await Lo({cwd:s})`pnpm install`,n})),o=[];for(let[n,s]of t.entries())if(s.status==="fulfilled")o.push(s.value);else{let i=e[n],a=new g(s.reason,{operation:`git worktree add for ${i}`,remediation:"check the branch name and that the parent dir is writable"});l.error({error:s.reason,msg:a.message})}return o},Dw=e=>{if(e.length>0){l.info("\u2705 Created git worktrees:");for(let r of e)l.info(r);l.info("")}else l.info("\u2139\uFE0F No new git worktrees to create")},Wa=k({name:"worktrees-add",description:'Create local git worktrees for release branches under the worktrees directory and run "pnpm install" in each. Mutates the local filesystem. When invoked via MCP, pass either "versions" (comma-separated) or all=true \u2014 the branch picker and "open in Cursor / GitHub Desktop / cmux" follow-up prompts are unreachable without a TTY, and the CLI confirmation is auto-skipped for MCP calls.',inputSchema:{all:Ge.boolean().optional().describe('Add worktrees for every open release branch. Either "all" or "versions" must be provided for MCP calls (the interactive picker is unavailable without a TTY). Ignored if "versions" is provided.'),versions:Ge.string().optional().describe('Comma-separated release versions or names to target (e.g. "1.2.5, 1.2.6" or "checkout-redesign, 1.2.5"). Either "versions" or all=true must be provided for MCP calls. Overrides "all" when set.'),ide:Ge.enum(Bn).optional().describe('Editor open mode for created worktrees, applied to all configured editors (Cursor and/or Zed, per the "ide" config). "workspace" (the only attach style) adds each worktree to every configured editor workspace and opens it. "none" skips the editor. Resolution order: this flag \u2192 "workspace" when at least one "ide" is configured \u2192 "none" otherwise.'),cursor:Ge.enum(Bn).optional().describe('Deprecated alias for "ide". Prefer "ide". Ignored when "ide" is provided.'),githubDesktop:Ge.boolean().optional().describe('Open each created worktree in GitHub Desktop. Resolution order: this flag \u2192 "worktrees.openInGithubDesktop" from infra-kit config \u2192 interactive prompt (CLI) / false (MCP, no TTY).'),cmux:Ge.boolean().optional().describe('Open each created worktree in a new cmux workspace, all rooted at the worktree directory. Pane layout follows "worktrees.cmux.layout" (default "two-columns": left | right; or "three-pane": left split top/bottom + full-height right). Resolution order: this flag \u2192 "worktrees.openInCmux" from infra-kit config \u2192 interactive prompt (CLI) / false (MCP, no TTY).')},outputSchema:{createdWorktrees:Ge.array(Ge.string()).describe("List of created git worktree branches"),count:Ge.number().describe("Number of git worktrees created")},handler:zp});import{z as At}from"zod";var qp=async()=>{await S();let e=await ne("release");if(e.length===0)return l.info("\u2139\uFE0F No active worktrees found"),{content:y(JSON.stringify({worktrees:[],count:0},null,2)),structuredContent:{worktrees:[],count:0}};let[r,t]=await Promise.all([D(),B()]),o=new Map(r.map(c=>[c.branch,_(c.title)])),n=e.flatMap(c=>{let d=j(c);if(!d)return[];let u=L(d),p=o.get(c)||"regular",m=t.get(U(d))||null;return[{version:u,type:p,description:m}]}),s=Math.max(...n.map(c=>c.version.length)),i=n.map(c=>{let d=go(c.version,c.type,s);return c.description?`${d} ${c.description}`:d});l.info(`\u{1F33F} Active worktrees:
|
|
419
419
|
|
|
420
420
|
${i.join(`
|
|
421
|
-
`)}`);let a={worktrees:n,count:n.length};return{content:y(JSON.stringify(a,null,2)),structuredContent:a}},Ja=k({name:"worktrees-list",description:"List existing release-branch worktrees with version, release type (regular / hotfix), and Jira fix-version description. Read-only.",inputSchema:{},outputSchema:{worktrees:At.array(At.object({version:At.string().describe("Release version"),type:At.enum(["regular","hotfix"]).describe("Release type"),description:At.string().nullable().describe("Jira version description")})).describe("List of all worktrees with details"),count:At.number().describe("Number of worktrees")},handler:qp});import{z as Lr}from"zod";var Ow=e=>{if(J()){if(e.all)throw new g(void 0,{operation:"remove worktrees",remediation:'name targets explicitly via "versions"; bulk all=true removal is disabled over MCP',stderrExcerpt:"all=true is not permitted for worktrees-remove over MCP"});if(!e.versions)throw new g(void 0,{operation:"remove worktrees",remediation:'pass "versions" (comma-separated release versions/names); the interactive picker needs a TTY',stderrExcerpt:'worktrees-remove over MCP requires "versions"'})}},_w=(e,r)=>{let t=e.filter(o=>!r.includes(o));if(t.length>0)throw new g(void 0,{operation:"remove worktrees",remediation:`no active worktree for: ${t.join(", ")}. Run 'infra-kit worktrees list' to see current worktrees`,stderrExcerpt:`unmatched worktree target(s): ${t.join(", ")}`})},Yp=async e=>{let{confirmedCommand:r,all:t,versions:o}=e;await re({operation:"remove worktrees"}),await S(),Ow({all:t,versions:o});try{let n=await ne("release");if(n.length===0){l.info("\u2139\uFE0F No active worktrees to remove"),h.print();let u={removedWorktrees:[],failedWorktrees:[],count:0};return{content:y(JSON.stringify(u,null,2)),structuredContent:u}}let s=await R(),i=`${s}${Z}`,a=[];if(t)a=n;else if(o)a=o.split(",").map(u=>he(me(u.trim())));else{h.setInteractive();let[u,p]=await Promise.all([B(),D()]),m=new Map(p.map(v=>[v.branch,_(v.title)]));a=await Pt(Y({branches:n,descriptions:u,types:m}),{required:!0})}_w(a,n);let c=a.length===n.length;c?h.addOption("--all",!0):h.addOption("--versions",$r(a)),await V(r,"Are you sure you want to proceed with these worktree changes?"),r||h.addOption("--yes",!0);let d=await _r({branches:a,worktreeDir:i,projectRoot:s,pruneFolder:c});return await Fr({projectRoot:s,worktreeDir:i,currentWorktrees:n,removedWorktrees:d.removed,allowEditorRelaunch:!r}),ko(d),h.print(),wo({result:d,operation:"remove worktrees"})}catch(n){throw xe(n)||n instanceof g?n:(l.error({error:n},"\u274C Error managing worktrees"),new g(n,{operation:"remove worktrees",remediation:"check 'git worktree list' for the path; uncommitted changes block removal"}))}},Ba=k({name:"worktrees-remove",description:'Remove local git worktrees for the named release branches. Over MCP you MUST pass "versions" (comma-separated); bulk all=true removal is disabled here (it is a one-shot, unconfirmed wipe of every worktree) \u2014 the branch picker and confirmation are unavailable without a TTY. Every named version must be an active worktree, or the call errors without removing anything. What survives: the release branches/commits themselves are never deleted, and the worktrees directory plus its release/feature subfolders are left in place (recreate a worktree with worktrees-add). What is lost: git refuses to remove a worktree with modified tracked files or untracked files, BUT it DOES delete the worktree directory including gitignored contents \u2014 a hydrated .env of Doppler secrets (re-fetch with env-load) and build output such as node_modules/dist (needs reinstall/rebuild). When every worktree is removed it also runs "git worktree prune". A branch git refuses to remove is listed in failedWorktrees and the result carries isError; a leftover that git already unregistered and that holds only tool state (.omc/state, .omc/sessions, .DS_Store) is swept automatically.',requiresHumanConfirm:!0,inputSchema:{versions:Lr.string().describe('Comma-separated release versions or names to remove (e.g. "1.2.5, 1.2.6" or "checkout-redesign, 1.2.5"). Required: each must name an active worktree, or the call errors before removing anything.'),confirm:Lr.boolean().optional().describe("Set true to execute; omit for a dry-run gate that echoes the resolved action.")},outputSchema:{removedWorktrees:Lr.array(Lr.string()).describe("List of removed git worktree branches"),failedWorktrees:Lr.array(Lr.string()).describe("Branches whose worktree could NOT be removed (git refused, or an unsweepable leftover remained)"),count:Lr.number().describe("Number of git worktrees removed")},handler:Yp});import{z as Wo}from"zod";var Zp=async e=>{let{confirmedCommand:r}=e;await re({operation:"sync worktrees"}),await S();try{let t=await ne("release"),o=await R(),n=`${o}${Z}`,s=await Dn();await V(r,"Are you sure you want to proceed with these worktree changes?"),r||h.addOption("--yes",!0);let{branchesToRemove:i}=Nw({releasePRsList:s,currentWorktrees:t}),a=await _r({branches:i,worktreeDir:n,projectRoot:o});return await Fr({projectRoot:o,worktreeDir:n,currentWorktrees:t,removedWorktrees:a.removed,allowEditorRelaunch:!1}),ko(a),h.print(),wo({result:a,operation:"sync worktrees"})}catch(t){throw xe(t)||t instanceof g?t:(l.error({error:t},"\u274C Error managing worktrees"),new g(t,{operation:"sync worktrees with remote",remediation:"ensure 'gh auth status' is ok and you can reach origin"}))}},Nw=e=>{let{releasePRsList:r,currentWorktrees:t}=e;return{branchesToRemove:t.filter(s=>pr(s)).filter(s=>!r.includes(s))}},Va=k({name:"worktrees-sync",description:"Remove worktrees whose release PR is no longer open (stale cleanup). Only removes \u2014 never creates; use worktrees-add to create worktrees for new releases. The CLI confirmation is auto-skipped for MCP calls, so the caller is responsible for gating. A branch git refuses to remove is listed in failedWorktrees and the result carries isError; a leftover that git already unregistered and that holds only tool state (.omc/state, .omc/sessions, .DS_Store) is swept automatically.",inputSchema:{},outputSchema:{removedWorktrees:Wo.array(Wo.string()).describe("List of removed worktree branches"),failedWorktrees:Wo.array(Wo.string()).describe("Branches whose worktree could NOT be removed (git refused, or an unsweepable leftover remained)"),count:Wo.number().describe("Number of worktrees removed during sync")},handler:Zp});var jw=[{key:"develop",label:"Develop"},{key:"release",label:"Release Management"},{key:"worktrees",label:"Worktrees"},{key:"environment",label:"Environment"},{key:"configuration",label:"Configuration"},{key:"vendor",label:"Vendor"},{key:"setup",label:"Setup & Diagnostics"}],Un=[{cliName:"dev",menuGroup:"develop",mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["dev"],longRunning:!0},{cliName:"dev-status",menuGroup:"develop",mcpTool:Ts,mcpExposed:!0,mutating:!1,groupPath:["dev-status"]},{cliName:"merge-dev",menuGroup:"release",mcpTool:_i,mcpExposed:!0,mutating:!0,groupPath:["release","merge-dev"]},{cliName:"release-list",menuGroup:"release",mcpTool:zi,mcpExposed:!0,mutating:!1,groupPath:["release","list"]},{cliName:"release-create",menuGroup:"release",mcpTool:aa,mcpExposed:!0,mutating:!0,groupPath:["release","create"]},{cliName:"release-desc-edit",menuGroup:"release",mcpTool:ca,mcpExposed:!0,mutating:!0,groupPath:["release","desc-edit"]},{cliName:"release-deploy-all",menuGroup:"release",mcpTool:Ki,mcpExposed:!0,mutating:!0,groupPath:["release","deploy-all"]},{cliName:"release-deploy-selected",menuGroup:"release",mcpTool:Hi,mcpExposed:!0,mutating:!0,groupPath:["release","deploy-selected"]},{cliName:"release-deliver",menuGroup:"release",mcpTool:ji,mcpExposed:!1,mutating:!0,groupPath:["release","deliver"]},{cliName:"release-remove",menuGroup:"release",mcpTool:ya,mcpExposed:!0,mutating:!0,groupPath:["release","remove"]},{cliName:"local-deploy-all",menuGroup:null,mcpTool:ta,mcpExposed:!0,mutating:!0,groupPath:["local","deploy-all"]},{cliName:"local-deploy-selected",menuGroup:null,mcpTool:oa,mcpExposed:!0,mutating:!0,groupPath:["local","deploy-selected"]},{cliName:"worktrees-add",menuGroup:"worktrees",mcpTool:Wa,mcpExposed:!0,mutating:!0,groupPath:["worktrees","add"]},{cliName:"worktrees-list",menuGroup:"worktrees",mcpTool:Ja,mcpExposed:!0,mutating:!1,groupPath:["worktrees","list"]},{cliName:"reopen",menuGroup:"worktrees",mcpTool:ba,mcpExposed:!0,mutating:!1,groupPath:["reopen"]},{cliName:"worktrees-remove",menuGroup:"worktrees",mcpTool:Ba,mcpExposed:!0,mutating:!0,groupPath:["worktrees","remove"]},{cliName:"worktrees-sync",menuGroup:"worktrees",mcpTool:Va,mcpExposed:!0,mutating:!0,groupPath:["worktrees","sync"]},{cliName:"env-status",menuGroup:"environment",mcpTool:Si,mcpExposed:!0,mutating:!1,groupPath:["env-status"]},{cliName:"env-list",menuGroup:"environment",mcpTool:xi,mcpExposed:!0,mutating:!1,groupPath:["env-list"]},{cliName:"env-load",menuGroup:"environment",mcpTool:Ls,mcpExposed:!0,mutating:!0,groupPath:["env-load"],sessionEnvNotice:!0},{cliName:"env-clear",menuGroup:"environment",mcpTool:Pi,mcpExposed:!0,mutating:!0,groupPath:["env-clear"],sessionEnvNotice:!0},{cliName:"env-token-list",menuGroup:"environment",mcpTool:Ci,mcpExposed:!0,mutating:!1,groupPath:["env-token-list"]},{cliName:"config-get",menuGroup:"configuration",mcpTool:Ps,mcpExposed:!0,mutating:!1,groupPath:["config-get"]},{cliName:"config-path",menuGroup:"configuration",mcpTool:null,mcpExposed:!1,mutating:!1,groupPath:["config","path"]},{cliName:"config-edit",menuGroup:"configuration",mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["config","edit"],entersAltScreen:!0},{cliName:"vendor-check",menuGroup:"vendor",mcpTool:Fa,mcpExposed:!0,mutating:!1,groupPath:["vendor","check"]},{cliName:"vendor-config",menuGroup:"vendor",mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["vendor","config"]},{cliName:"doctor",menuGroup:"setup",mcpTool:Ri,mcpExposed:!0,mutating:!1,groupPath:["doctor"]},{cliName:"audit",menuGroup:"setup",mcpTool:Es,mcpExposed:!0,mutating:!1,groupPath:["audit"]},{cliName:"version",menuGroup:"setup",mcpTool:La,mcpExposed:!0,mutating:!1,groupPath:["version"]},{cliName:"vendor",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!1,groupPath:["vendor"]},{cliName:"config",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!1,groupPath:["config"]},{cliName:"env-autoload",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["env-autoload"]},{cliName:"env-token-set",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["env-token-set"]},{cliName:"env-token-remove",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["env-token-remove"]},{cliName:"setup",menuGroup:null,mcpTool:Sa,mcpExposed:!0,mutating:!0,groupPath:["setup"]},{cliName:"self-update",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["self-update"]},{cliName:"mcp",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!1,groupPath:["mcp"]}];var Mw={"dev-status":{title:"Dev server status",openWorld:!1},"gh-release-list":{title:"Open releases",openWorld:!0},"worktrees-list":{title:"Release worktrees",openWorld:!0},"env-status":{title:"Loaded environment",openWorld:!1},"env-list":{title:"Available environments",openWorld:!1},"env-token-list":{title:"Doppler service tokens",openWorld:!0},"config-get":{title:"Merged infra-kit config",openWorld:!1},"vendor-check":{title:"Vendor checksum check",openWorld:!1},audit:{title:"Package audit",openWorld:!1},version:{title:"CLI version",openWorld:!1},doctor:{title:"Diagnose this machine",openWorld:!0},setup:{title:"Set up this machine",openWorld:!0},"gh-merge-dev":{title:"Merge dev into release branches",openWorld:!0},"release-create":{title:"Create releases",openWorld:!0},"release-remove":{title:"Remove a release",openWorld:!0},"gh-release-deploy-all":{title:"Deploy all services (CI)",openWorld:!0},"gh-release-deploy-selected":{title:"Deploy selected services (CI)",openWorld:!0},"local-deploy-all":{title:"Deploy all services from this machine",openWorld:!0},"local-deploy-selected":{title:"Deploy selected services from this machine",openWorld:!0},"worktrees-remove":{title:"Remove release worktrees",openWorld:!1},"env-clear":{title:"Clear environment variables",openWorld:!1},"release-desc-edit":{title:"Edit release description",openWorld:!0},"worktrees-add":{title:"Add release worktrees",openWorld:!0},"worktrees-sync":{title:"Prune stale worktrees",openWorld:!0},"env-load":{title:"Load environment variables",openWorld:!0},reopen:{title:"Reopen project windows",openWorld:!1}},Fw=["reopen"],Lw=()=>Un.flatMap(e=>{if(!e.mcpExposed||!e.mcpTool)return[];let r=Mw[e.mcpTool.name];if(!r)throw new Error(`No MCP_TOOL_PRESENTATION entry for exposed tool "${e.mcpTool.name}" \u2014 add a title and an evidence-cited openWorld value in command-catalog.ts.`);let t=!e.mutating&&!Fw.includes(e.mcpTool.name);return[{...e.mcpTool,title:r.title,annotations:{readOnlyHint:t,...t?{}:{destructiveHint:!0},openWorldHint:r.openWorld}}]}),Ww=e=>Un.filter(r=>r.menuGroup===e),Jw=e=>Un.some(r=>r.longRunning===!0&&r.groupPath.join(" ")===e);import Ga from"node:process";var Bw="MODULE_TYPELESS_PACKAGE_JSON",Vw=(e,r)=>typeof e=="object"&&e!==null?e.code:r,Xp=!1,Gw=()=>{if(Xp)return;Xp=!0;let e=Ga.emitWarning.bind(Ga);Ga.emitWarning=((r,...t)=>{Vw(t[0],t[1])!==Bw&&e(r,...t)})};export{y as a,Gc as b,Kc as c,Ss as d,Hc as e,Zm as f,Ht as g,zt as h,wr as i,PP as j,cf as k,fl as l,gl as m,dt as n,hl as o,vl as p,yn as q,kn as r,Nf as s,ti as t,LS as u,WS as v,ni as w,si as x,Ug as y,gd as z,vd as A,wd as B,bd as C,Ti as D,xd as E,Et as F,sv as G,Dd as H,DI as I,Vd as J,Yd as K,Tt as L,iy as M,ay as N,sp as O,ip as P,ap as Q,gp as R,hp as S,Ep as T,Pp as U,Bn as V,Ip as W,Ik as X,Lp as Y,Gp as Z,Kp as _,zp as $,qp as aa,Yp as ba,Zp as ca,jw as da,Un as ea,Lw as fa,Ww as ga,Jw as ha,Gw as ia};
|
|
422
|
-
//# sourceMappingURL=chunk-
|
|
421
|
+
`)}`);let a={worktrees:n,count:n.length};return{content:y(JSON.stringify(a,null,2)),structuredContent:a}},Ja=k({name:"worktrees-list",description:"List existing release-branch worktrees with version, release type (regular / hotfix), and Jira fix-version description. Read-only.",inputSchema:{},outputSchema:{worktrees:At.array(At.object({version:At.string().describe("Release version"),type:At.enum(["regular","hotfix"]).describe("Release type"),description:At.string().nullable().describe("Jira version description")})).describe("List of all worktrees with details"),count:At.number().describe("Number of worktrees")},handler:qp});import{z as Lr}from"zod";var Ow=e=>{if(J()){if(e.all)throw new g(void 0,{operation:"remove worktrees",remediation:'name targets explicitly via "versions"; bulk all=true removal is disabled over MCP',stderrExcerpt:"all=true is not permitted for worktrees-remove over MCP"});if(!e.versions)throw new g(void 0,{operation:"remove worktrees",remediation:'pass "versions" (comma-separated release versions/names); the interactive picker needs a TTY',stderrExcerpt:'worktrees-remove over MCP requires "versions"'})}},_w=(e,r)=>{let t=e.filter(o=>!r.includes(o));if(t.length>0)throw new g(void 0,{operation:"remove worktrees",remediation:`no active worktree for: ${t.join(", ")}. Run 'infra-kit worktrees list' to see current worktrees`,stderrExcerpt:`unmatched worktree target(s): ${t.join(", ")}`})},Yp=async e=>{let{confirmedCommand:r,all:t,versions:o}=e;await re({operation:"remove worktrees"}),await S(),Ow({all:t,versions:o});try{let n=await ne("release");if(n.length===0){l.info("\u2139\uFE0F No active worktrees to remove"),h.print();let u={removedWorktrees:[],failedWorktrees:[],count:0};return{content:y(JSON.stringify(u,null,2)),structuredContent:u}}let s=await R(),i=`${s}${Z}`,a=[];if(t)a=n;else if(o)a=o.split(",").map(u=>he(me(u.trim())));else{h.setInteractive();let[u,p]=await Promise.all([B(),D()]),m=new Map(p.map(v=>[v.branch,_(v.title)]));a=await Pt(Y({branches:n,descriptions:u,types:m}),{required:!0})}_w(a,n);let c=a.length===n.length;c?h.addOption("--all",!0):h.addOption("--versions",$r(a)),await V(r,"Are you sure you want to proceed with these worktree changes?"),r||h.addOption("--yes",!0);let d=await _r({branches:a,worktreeDir:i,projectRoot:s,pruneFolder:c});return await Fr({projectRoot:s,worktreeDir:i,currentWorktrees:n,removedWorktrees:d.removed,allowEditorRelaunch:!r}),ko(d),h.print(),wo({result:d,operation:"remove worktrees"})}catch(n){throw xe(n)||n instanceof g?n:(l.error({error:n},"\u274C Error managing worktrees"),new g(n,{operation:"remove worktrees",remediation:"check 'git worktree list' for the path; uncommitted changes block removal"}))}},Ba=k({name:"worktrees-remove",description:'Remove local git worktrees for the named release branches. Over MCP you MUST pass "versions" (comma-separated); bulk all=true removal is disabled here (it is a one-shot, unconfirmed wipe of every worktree) \u2014 the branch picker and confirmation are unavailable without a TTY. Every named version must be an active worktree, or the call errors without removing anything. What survives: the release branches/commits themselves are never deleted, and the worktrees directory plus its release/feature subfolders are left in place (recreate a worktree with worktrees-add). What is lost: git refuses to remove a worktree with modified tracked files or untracked files, BUT it DOES delete the worktree directory including gitignored contents \u2014 a hydrated .env of Doppler secrets (re-fetch with env-load) and build output such as node_modules/dist (needs reinstall/rebuild). When every worktree is removed it also runs "git worktree prune". A branch git refuses to remove is listed in failedWorktrees and the result carries isError; a leftover that git already unregistered and that holds only tool state (.omc/state, .omc/sessions, .DS_Store) is swept automatically.',requiresHumanConfirm:!0,inputSchema:{versions:Lr.string().describe('Comma-separated release versions or names to remove (e.g. "1.2.5, 1.2.6" or "checkout-redesign, 1.2.5"). Required: each must name an active worktree, or the call errors before removing anything.'),confirm:Lr.boolean().optional().describe("Set true to execute; omit for a dry-run gate that echoes the resolved action.")},outputSchema:{removedWorktrees:Lr.array(Lr.string()).describe("List of removed git worktree branches"),failedWorktrees:Lr.array(Lr.string()).describe("Branches whose worktree could NOT be removed (git refused, or an unsweepable leftover remained)"),count:Lr.number().describe("Number of git worktrees removed")},handler:Yp});import{z as Wo}from"zod";var Zp=async e=>{let{confirmedCommand:r}=e;await re({operation:"sync worktrees"}),await S();try{let t=await ne("release"),o=await R(),n=`${o}${Z}`,s=await Dn();await V(r,"Are you sure you want to proceed with these worktree changes?"),r||h.addOption("--yes",!0);let{branchesToRemove:i}=Nw({releasePRsList:s,currentWorktrees:t}),a=await _r({branches:i,worktreeDir:n,projectRoot:o});return await Fr({projectRoot:o,worktreeDir:n,currentWorktrees:t,removedWorktrees:a.removed,allowEditorRelaunch:!1}),ko(a),h.print(),wo({result:a,operation:"sync worktrees"})}catch(t){throw xe(t)||t instanceof g?t:(l.error({error:t},"\u274C Error managing worktrees"),new g(t,{operation:"sync worktrees with remote",remediation:"ensure 'gh auth status' is ok and you can reach origin"}))}},Nw=e=>{let{releasePRsList:r,currentWorktrees:t}=e;return{branchesToRemove:t.filter(s=>pr(s)).filter(s=>!r.includes(s))}},Va=k({name:"worktrees-sync",description:"Remove worktrees whose release PR is no longer open (stale cleanup). Only removes \u2014 never creates; use worktrees-add to create worktrees for new releases. The CLI confirmation is auto-skipped for MCP calls, so the caller is responsible for gating. A branch git refuses to remove is listed in failedWorktrees and the result carries isError; a leftover that git already unregistered and that holds only tool state (.omc/state, .omc/sessions, .DS_Store) is swept automatically.",inputSchema:{},outputSchema:{removedWorktrees:Wo.array(Wo.string()).describe("List of removed worktree branches"),failedWorktrees:Wo.array(Wo.string()).describe("Branches whose worktree could NOT be removed (git refused, or an unsweepable leftover remained)"),count:Wo.number().describe("Number of worktrees removed during sync")},handler:Zp});var jw=[{key:"develop",label:"Develop"},{key:"release",label:"Release Management"},{key:"worktrees",label:"Worktrees"},{key:"environment",label:"Environment"},{key:"configuration",label:"Configuration"},{key:"vendor",label:"Vendor"},{key:"setup",label:"Setup & Diagnostics"}],Un=[{cliName:"dev",menuGroup:"develop",mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["dev"],longRunning:!0},{cliName:"dev-status",menuGroup:"develop",mcpTool:Ts,mcpExposed:!0,mutating:!1,groupPath:["dev-status"]},{cliName:"merge-dev",menuGroup:"release",mcpTool:_i,mcpExposed:!0,mutating:!0,groupPath:["release","merge-dev"]},{cliName:"release-list",menuGroup:"release",mcpTool:zi,mcpExposed:!0,mutating:!1,groupPath:["release","list"]},{cliName:"release-create",menuGroup:"release",mcpTool:aa,mcpExposed:!0,mutating:!0,groupPath:["release","create"]},{cliName:"release-desc-edit",menuGroup:"release",mcpTool:ca,mcpExposed:!0,mutating:!0,groupPath:["release","desc-edit"]},{cliName:"release-deploy-all",menuGroup:"release",mcpTool:Ki,mcpExposed:!0,mutating:!0,groupPath:["release","deploy-all"]},{cliName:"release-deploy-selected",menuGroup:"release",mcpTool:Hi,mcpExposed:!0,mutating:!0,groupPath:["release","deploy-selected"]},{cliName:"release-deliver",menuGroup:"release",mcpTool:ji,mcpExposed:!1,mutating:!0,groupPath:["release","deliver"]},{cliName:"release-remove",menuGroup:"release",mcpTool:ya,mcpExposed:!0,mutating:!0,groupPath:["release","remove"]},{cliName:"local-deploy-all",menuGroup:null,mcpTool:ta,mcpExposed:!0,mutating:!0,groupPath:["local","deploy-all"]},{cliName:"local-deploy-selected",menuGroup:null,mcpTool:oa,mcpExposed:!0,mutating:!0,groupPath:["local","deploy-selected"]},{cliName:"worktrees-add",menuGroup:"worktrees",mcpTool:Wa,mcpExposed:!0,mutating:!0,groupPath:["worktrees","add"]},{cliName:"worktrees-list",menuGroup:"worktrees",mcpTool:Ja,mcpExposed:!0,mutating:!1,groupPath:["worktrees","list"]},{cliName:"reopen",menuGroup:"worktrees",mcpTool:ba,mcpExposed:!0,mutating:!1,groupPath:["reopen"]},{cliName:"worktrees-remove",menuGroup:"worktrees",mcpTool:Ba,mcpExposed:!0,mutating:!0,groupPath:["worktrees","remove"]},{cliName:"worktrees-sync",menuGroup:"worktrees",mcpTool:Va,mcpExposed:!0,mutating:!0,groupPath:["worktrees","sync"]},{cliName:"env-status",menuGroup:"environment",mcpTool:Si,mcpExposed:!0,mutating:!1,groupPath:["env-status"]},{cliName:"env-list",menuGroup:"environment",mcpTool:xi,mcpExposed:!0,mutating:!1,groupPath:["env-list"]},{cliName:"env-load",menuGroup:"environment",mcpTool:Ls,mcpExposed:!0,mutating:!0,groupPath:["env-load"],sessionEnvNotice:!0},{cliName:"env-clear",menuGroup:"environment",mcpTool:Pi,mcpExposed:!0,mutating:!0,groupPath:["env-clear"],sessionEnvNotice:!0},{cliName:"env-token-list",menuGroup:"environment",mcpTool:Ci,mcpExposed:!0,mutating:!1,groupPath:["env-token-list"]},{cliName:"config-get",menuGroup:"configuration",mcpTool:Ps,mcpExposed:!0,mutating:!1,groupPath:["config-get"]},{cliName:"config-path",menuGroup:"configuration",mcpTool:null,mcpExposed:!1,mutating:!1,groupPath:["config","path"]},{cliName:"config-edit",menuGroup:"configuration",mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["config","edit"],entersAltScreen:!0},{cliName:"vendor-check",menuGroup:"vendor",mcpTool:Fa,mcpExposed:!0,mutating:!1,groupPath:["vendor","check"]},{cliName:"vendor-config",menuGroup:"vendor",mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["vendor","config"]},{cliName:"setup",menuGroup:"setup",mcpTool:Sa,mcpExposed:!0,mutating:!0,groupPath:["setup"]},{cliName:"doctor",menuGroup:"setup",mcpTool:Ri,mcpExposed:!0,mutating:!1,groupPath:["doctor"]},{cliName:"audit",menuGroup:"setup",mcpTool:Es,mcpExposed:!0,mutating:!1,groupPath:["audit"]},{cliName:"version",menuGroup:"setup",mcpTool:La,mcpExposed:!0,mutating:!1,groupPath:["version"]},{cliName:"vendor",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!1,groupPath:["vendor"]},{cliName:"config",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!1,groupPath:["config"]},{cliName:"env-autoload",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["env-autoload"]},{cliName:"env-token-set",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["env-token-set"]},{cliName:"env-token-remove",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!0,groupPath:["env-token-remove"]},{cliName:"mcp",menuGroup:null,mcpTool:null,mcpExposed:!1,mutating:!1,groupPath:["mcp"]}];var Mw={"dev-status":{title:"Dev server status",openWorld:!1},"gh-release-list":{title:"Open releases",openWorld:!0},"worktrees-list":{title:"Release worktrees",openWorld:!0},"env-status":{title:"Loaded environment",openWorld:!1},"env-list":{title:"Available environments",openWorld:!1},"env-token-list":{title:"Doppler service tokens",openWorld:!0},"config-get":{title:"Merged infra-kit config",openWorld:!1},"vendor-check":{title:"Vendor checksum check",openWorld:!1},audit:{title:"Package audit",openWorld:!1},version:{title:"CLI version",openWorld:!1},doctor:{title:"Diagnose this machine",openWorld:!0},setup:{title:"Set up this machine",openWorld:!0},"gh-merge-dev":{title:"Merge dev into release branches",openWorld:!0},"release-create":{title:"Create releases",openWorld:!0},"release-remove":{title:"Remove a release",openWorld:!0},"gh-release-deploy-all":{title:"Deploy all services (CI)",openWorld:!0},"gh-release-deploy-selected":{title:"Deploy selected services (CI)",openWorld:!0},"local-deploy-all":{title:"Deploy all services from this machine",openWorld:!0},"local-deploy-selected":{title:"Deploy selected services from this machine",openWorld:!0},"worktrees-remove":{title:"Remove release worktrees",openWorld:!1},"env-clear":{title:"Clear environment variables",openWorld:!1},"release-desc-edit":{title:"Edit release description",openWorld:!0},"worktrees-add":{title:"Add release worktrees",openWorld:!0},"worktrees-sync":{title:"Prune stale worktrees",openWorld:!0},"env-load":{title:"Load environment variables",openWorld:!0},reopen:{title:"Reopen project windows",openWorld:!1}},Fw=["reopen"],Lw=()=>Un.flatMap(e=>{if(!e.mcpExposed||!e.mcpTool)return[];let r=Mw[e.mcpTool.name];if(!r)throw new Error(`No MCP_TOOL_PRESENTATION entry for exposed tool "${e.mcpTool.name}" \u2014 add a title and an evidence-cited openWorld value in command-catalog.ts.`);let t=!e.mutating&&!Fw.includes(e.mcpTool.name);return[{...e.mcpTool,title:r.title,annotations:{readOnlyHint:t,...t?{}:{destructiveHint:!0},openWorldHint:r.openWorld}}]}),Ww=e=>Un.filter(r=>r.menuGroup===e),Jw=e=>Un.some(r=>r.longRunning===!0&&r.groupPath.join(" ")===e);import Ga from"node:process";var Bw="MODULE_TYPELESS_PACKAGE_JSON",Vw=(e,r)=>typeof e=="object"&&e!==null?e.code:r,Xp=!1,Gw=()=>{if(Xp)return;Xp=!0;let e=Ga.emitWarning.bind(Ga);Ga.emitWarning=((r,...t)=>{Vw(t[0],t[1])!==Bw&&e(r,...t)})};export{y as a,Gc as b,Kc as c,Ss as d,Hc as e,Zm as f,Ht as g,zt as h,wr as i,PP as j,cf as k,fl as l,gl as m,dt as n,hl as o,vl as p,yn as q,kn as r,Nf as s,ti as t,LS as u,WS as v,ni as w,si as x,Ug as y,gd as z,vd as A,wd as B,bd as C,Ti as D,xd as E,Et as F,sv as G,Dd as H,DI as I,Vd as J,Yd as K,Tt as L,iy as M,ay as N,sp as O,ip as P,ap as Q,gp as R,hp as S,Ep as T,Pp as U,Bn as V,Ip as W,Ik as X,Lp as Y,Gp as Z,Kp as _,zp as $,qp as aa,Yp as ba,Zp as ca,jw as da,Un as ea,Lw as fa,Ww as ga,Jw as ha,Gw as ia};
|
|
422
|
+
//# sourceMappingURL=chunk-X2POR5VH.js.map
|