infra-kit 0.5.6 → 0.7.0

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 (42) hide show
  1. package/dist/chunk-63VNUKUS.js +8 -0
  2. package/dist/chunk-63VNUKUS.js.map +7 -0
  3. package/dist/chunk-7YE5QKKB.js +444 -0
  4. package/dist/chunk-7YE5QKKB.js.map +7 -0
  5. package/dist/chunk-GYPVEWUV.js +2 -0
  6. package/dist/chunk-GYPVEWUV.js.map +7 -0
  7. package/dist/chunk-KXQQUBGV.js +10 -0
  8. package/dist/{chunk-744Y674Y.js.map → chunk-KXQQUBGV.js.map} +4 -4
  9. package/dist/chunk-MFLYORUJ.js +2 -0
  10. package/dist/chunk-MFLYORUJ.js.map +7 -0
  11. package/dist/chunk-NFIFWIO6.js +4 -0
  12. package/dist/chunk-NFIFWIO6.js.map +7 -0
  13. package/dist/chunk-QS4JZKF2.js +2 -0
  14. package/dist/{chunk-YYEUJYC7.js.map → chunk-QS4JZKF2.js.map} +1 -1
  15. package/dist/chunk-UI2MUEVR.js +2 -0
  16. package/dist/chunk-UI2MUEVR.js.map +7 -0
  17. package/dist/{chunk-QUXDC3A3.js → chunk-YKCY657C.js} +4 -4
  18. package/dist/cli.js +11 -10
  19. package/dist/cli.js.map +3 -3
  20. package/dist/dev-server.js +22 -22
  21. package/dist/dev-server.js.map +3 -3
  22. package/dist/{dev-wizard-run-DWDA5R3A.js → dev-wizard-run-MCUYV6IN.js} +2 -2
  23. package/dist/mcp-proxy.js +9 -9
  24. package/dist/mcp-proxy.js.map +3 -3
  25. package/dist/mcp.js +2 -2
  26. package/dist/mcp.js.map +4 -4
  27. package/dist/update-check.js +1 -1
  28. package/package.json +2 -2
  29. package/dist/chunk-744Y674Y.js +0 -10
  30. package/dist/chunk-LCNORKDV.js +0 -8
  31. package/dist/chunk-LCNORKDV.js.map +0 -7
  32. package/dist/chunk-PQG63EIV.js +0 -4
  33. package/dist/chunk-PQG63EIV.js.map +0 -7
  34. package/dist/chunk-XJOY7J3G.js +0 -2
  35. package/dist/chunk-XJOY7J3G.js.map +0 -7
  36. package/dist/chunk-XN7VHD7P.js +0 -445
  37. package/dist/chunk-XN7VHD7P.js.map +0 -7
  38. package/dist/chunk-Y5TLBGZT.js +0 -2
  39. package/dist/chunk-Y5TLBGZT.js.map +0 -7
  40. package/dist/chunk-YYEUJYC7.js +0 -2
  41. /package/dist/{chunk-QUXDC3A3.js.map → chunk-YKCY657C.js.map} +0 -0
  42. /package/dist/{dev-wizard-run-DWDA5R3A.js.map → dev-wizard-run-MCUYV6IN.js.map} +0 -0
@@ -1,2 +0,0 @@
1
- var j={name:"infra-kit",type:"module",version:"0.5.6",files:["dist"],description:"infra-kit",bin:{"infra-kit":"dist/cli.js",ik:"dist/cli.js","ik-mcp":"dist/mcp-proxy.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","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.5.6",chalk:"^6.0.0",chokidar:"^5.0.0",commander:"^15.0.0",fastify:"^5.12.4",ink:"^7.1.1",pino:"^10.3.1","pino-pretty":"^13.1.3",portless:"^0.15.6",react:"19.3.0",yaml:"^2.9.1",zod:"^4.6.2",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 p="infra-kit",i=`${p}@latest`,v=(e,t)=>t===void 0?e:e.map(n=>n===i?`${p}@${t}`:n),d=(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),M=(e,t)=>{let n=a.resolve(e).split(a.sep),r=n.indexOf("Cellar");return r!==-1&&n[r+1]===t},S=(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},b=e=>S(e,p),w=e=>["npm","install","-g","--prefix",e,i],_=e=>e.map(t=>t.includes(" ")?`'${t}'`:t).join(" "),u=(e,t,n,r)=>{let o=e[t];return o!=null&&o!==""&&d(o,n,r)},k=[{manager:"volta",test:({selfRealPath:e,env:t,realpath:n})=>u(t,"VOLTA_HOME",e,n)||s(e,".volta")||s(e,"volta"),updateCommand:["volta","install",p],canSelfSpawn:!0},{manager:"homebrew",test:({selfRealPath:e})=>M(e,p),updateCommand:["brew","upgrade",p],canSelfSpawn:!1}],C=[{manager:"pnpm",test:({selfRealPath:e,env:t,realpath:n})=>u(t,"PNPM_HOME",e,n)||s(e,"pnpm")&&s(e,"global"),updateCommand:["pnpm","add","-g",i],canSelfSpawn:!0},{manager:"bun",test:({selfRealPath:e,env:t,realpath:n})=>u(t,"BUN_INSTALL",e,n)||s(e,".bun"),updateCommand:["bun","add","-g",i],canSelfSpawn:!0},{manager:"yarn",test:({selfRealPath:e})=>s(e,".yarn")||s(e,"yarn")&&s(e,"global"),updateCommand:["yarn","global","add",i],canSelfSpawn:!0},{manager:"npm",test:({selfRealPath:e,env:t,realpath:n})=>u(t,"npm_config_prefix",e,n),updateCommand:["npm","install","-g",i],canSelfSpawn:!0}],I=["npm","install","-g",i],E=e=>{let{selfRealPath:t,env:n,realpath:r,lazyNpmRoot:o,version:m}=e,l=R({selfRealPath:t,env:n,realpath:r,lazyNpmRoot:o});return{...l,updateCommand:v(l.updateCommand,m)}},R=e=>{let{selfRealPath:t,env:n,realpath:r,lazyNpmRoot:o}=e,m=c=>({manager:c.manager,updateCommand:c.updateCommand,canSelfSpawn:c.canSelfSpawn}),l=({test:c})=>c({selfRealPath:t,env:n,realpath:r}),f=k.find(l);if(f)return m(f);let x=b(t);if(x!==null)return{manager:"npm",updateCommand:w(x),canSelfSpawn:!0};let h=C.find(l);if(h)return m(h);let g=o?.();return g!=null&&g!==""&&d(g,t,r)?{manager:"npm",updateCommand:I,canSelfSpawn:!0}:{manager:"unknown",updateCommand:I,canSelfSpawn:!1}},N=(e,t,n)=>s(e,"node_modules")&&d(t,e,n);import{realpathSync as P}from"node:fs";import A from"node:path";var O=e=>{try{return P(e)}catch{return A.resolve(e)}};import{execFileSync as T}from"node:child_process";import q from"node:process";var D=3e3,F=()=>{try{let t=T("npm",["root","-g"],{encoding:"utf-8",timeout:D,stdio:["ignore","pipe","ignore"],shell:q.platform==="win32"}).trim();return t===""?void 0:t}catch{return}};export{j as a,p as b,d as c,s as d,M as e,S as f,_ as g,E as h,N as i,F as j,O as k};
2
- //# sourceMappingURL=chunk-Y5TLBGZT.js.map
@@ -1,7 +0,0 @@
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.6\",\n \"files\": [\n \"dist\"\n ],\n \"description\": \"infra-kit\",\n \"bin\": {\n \"infra-kit\": \"dist/cli.js\",\n \"ik\": \"dist/cli.js\",\n \"ik-mcp\": \"dist/mcp-proxy.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 \"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.5.6\",\n \"chalk\": \"^6.0.0\",\n \"chokidar\": \"^5.0.0\",\n \"commander\": \"^15.0.0\",\n \"fastify\": \"^5.12.4\",\n \"ink\": \"^7.1.1\",\n \"pino\": \"^10.3.1\",\n \"pino-pretty\": \"^13.1.3\",\n \"portless\": \"^0.15.6\",\n \"react\": \"19.3.0\",\n \"yaml\": \"^2.9.1\",\n \"zod\": \"^4.6.2\",\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 * The exact version to install, when the caller has already resolved it. Omitted, the command targets\n * the `latest` dist-tag \u2014 fine to PRINT, unsafe to RUN: see {@link pinSpec}.\n */\n version?: string\n}\n\n/**\n * Swap the `@latest` token for `@<version>`.\n *\n * `pnpm add -g infra-kit@latest` resolves the tag from pnpm's on-disk metadata cache and does not\n * revalidate it when a cached version already satisfies the tag (pnpm 12.3.4, measured: two runs 90+\n * minutes after a publish both reinstalled the stale `latest` while `pnpm view` already reported the new\n * one). The updater had fetched the real latest itself moments earlier, ran the tag command, got exit 0\n * \u2014 nothing was reinstalled \u2014 and recorded `installed`, so the stale binary looked up to date until the\n * next cycle repeated the same no-op. A concrete version the cache has never seen forces the fetch.\n */\nconst pinSpec = (command: string[], version: string | undefined): string[] => {\n if (version === undefined) return command\n\n return command.map((token) => {\n return token === LATEST ? `${PACKAGE_NAME}@${version}` : token\n })\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 * detectInstallManager({ selfRealPath: '/Users/x/Library/pnpm/global/5/node_modules/infra-kit/dist/cli.js', env: {}, version: '0.5.5' })\n * // => { manager: 'pnpm', updateCommand: ['pnpm', 'add', '-g', 'infra-kit@0.5.5'], canSelfSpawn: true }\n */\nexport const detectInstallManager = (input: DetectInstallManagerInput): InstallManagerInfo => {\n const { selfRealPath, env, realpath, lazyNpmRoot, version } = input\n const detected = detectUnpinned({ selfRealPath, env, realpath, lazyNpmRoot })\n\n return { ...detected, updateCommand: pinSpec(detected.updateCommand, version) }\n}\n\nconst detectUnpinned = (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", "pinSpec", "command", "version", "token", "isWithin", "parent", "child", "realpath", "rel", "hasSegment", "p", "name", "isBrewKegOf", "segments", "cellar", "npmPrefixOfPackage", "binRealPath", "packageName", "nodeModules", "npmPrefixFromSelfPath", "selfRealPath", "npmPrefixInstallCommand", "prefix", "formatUpdateCommand", "underEnvDir", "env", "key", "dir", "WRAPPER_MATCHERS", "TREE_MATCHERS", "NPM_UPDATE_COMMAND", "detectInstallManager", "input", "lazyNpmRoot", "detected", "detectUnpinned", "toInfo", "hit", "matches", "test", "wrapper", "derivedPrefix", "tree", "npmRoot", "isLocalNodeModulesInstall", "cwd", "realpathSync", "path", "safeRealpath", "dir", "execFileSync", "process", "NPM_ROOT_TIMEOUT_MS", "defaultLazyNpmRoot", "trimmed"]
7
- }
@@ -1,2 +0,0 @@
1
- import{b as f,h as k,j as P,k as S}from"./chunk-Y5TLBGZT.js";import{b as w}from"./chunk-XJOY7J3G.js";import{n as m,r as C}from"./chunk-PQG63EIV.js";import{spawnSync as L}from"node:child_process";import{homedir as I}from"node:os";import h from"node:process";import l from"node:fs";import b from"node:path";import D from"node:process";var J="update-check.lock",q=1800*1e3,G=()=>b.join(m(),J),H=(t,e)=>{try{e-l.statSync(t).mtimeMs>q&&l.rmSync(t,{force:!0})}catch{}},E=(t={})=>{let e=t.nowMs??Date.now(),n=t.lockPath??G();try{l.mkdirSync(b.dirname(n),{recursive:!0})}catch{return null}let r=()=>{try{return l.openSync(n,"wx",384)}catch{return null}},o=r();if(o===null&&(H(n,e),o=r()),o===null)return null;try{l.writeFileSync(o,String(D.pid))}catch{}return()=>{try{l.closeSync(o)}catch{}try{l.rmSync(n,{force:!0})}catch{}}};var K="https://registry.npmjs.org",$=5e3,z=t=>Object.entries(t).find(([n,r])=>/^npm_config_registry$/i.test(n)&&r!=null&&r!=="")?.[1],W=t=>{let e=z(t),n=e!=null&&e!==""?e:K;for(;n.endsWith("/");)n=n.slice(0,-1);return n},v=async(t,e=fetch)=>{let n=new AbortController,r=setTimeout(()=>{n.abort()},$);try{let o=await e(`${W(t)}/${f}/latest`,{signal:n.signal,headers:{accept:"application/json"}});if(!o.ok)return null;let s=(await o.json())?.version;return typeof s=="string"&&s!==""?s:null}catch{return null}finally{clearTimeout(r)}};var B=/^(\d+)\.(\d+)\.(\d+)$/,N=t=>{let[e=""]=t.trim().split("+"),[n="",...r]=e.split("-"),o=B.exec(n);if(!o)return null;let[c,s,u]=[o[1],o[2],o[3]].map(Number);return{release:[c,s,u],prerelease:r.length>0?r.join("-").split("."):[]}},U=/^\d+$/,Y=(t,e)=>{let n=U.test(t),r=U.test(e);return n&&r?Number(t)-Number(e):n!==r?n?-1:1:t<e?-1:1},Q=(t,e)=>{for(let n=0;n<Math.max(t.length,e.length);n+=1){let r=t[n],o=e[n];if(r===void 0)return-1;if(o===void 0)return 1;if(r!==o)return Y(r,o)}return 0},M=(t,e)=>{let n=N(t),r=N(e);if(!n||!r)return!1;for(let s=0;s<3;s+=1){let u=n.release[s],d=r.release[s];if(u!==d)return u>d}let o=n.prerelease.length===0,c=r.prerelease.length===0;return o!==c?o:Q(n.prerelease,r.prerelease)>0};import x from"node:fs";import A from"node:path";var R="update-check.json",X=1200*1e3,Z=()=>A.join(m(),R),ee=t=>Array.isArray(t)&&t.every(e=>typeof e=="string"),te=t=>{if(typeof t!="object"||t===null)return!1;let{lastCheckMs:e,latestVersion:n,updateCommand:r,outcome:o}=t;return typeof e=="number"&&Number.isFinite(e)&&(n===null||typeof n=="string")&&(r===null||ee(r))&&(o==null||typeof o=="string")},be=(t=e=>x.readFileSync(e,"utf8"))=>{try{let e=JSON.parse(t(Z()));return te(e)?e:null}catch{return null}},_=t=>{let e=m();x.mkdirSync(e,{recursive:!0}),C(A.join(e,R),JSON.stringify(t),384)},Ee=(t,e)=>{if(!t)return!0;let n=e-t.lastCheckMs;return n<0?!0:n>=X};var ne=200,re=300*1e3,oe=15e3,se=t=>{let e=L(f,["version","--json"],{stdio:["ignore","pipe","ignore"],shell:h.platform==="win32",cwd:I(),env:t,timeout:oe,windowsHide:!0,encoding:"utf8"});if(e.error||e.signal||e.status!==0)return null;try{let r=JSON.parse(e.stdout)?.version;return typeof r=="string"&&r!==""?r:null}catch{return null}},ie=t=>{try{return h.kill(t,0),!0}catch{return!1}},ae=t=>new Promise(e=>{setTimeout(e,t)}),ce=async(t,e)=>{let n=e.clock()+re;for(;e.clock()<n;){if(!e.isProcessAlive(t))return!0;await e.sleep(ne)}return!e.isProcessAlive(t)},Te=async(t,e)=>{let r=(e.acquireLock??E)();if(!r)return"already-running";try{return await le(t,e)}finally{r()}},le=async(t,e)=>{let n=e.env??h.env,r=e.nowMs??Date.now(),o=e.fetchLatest??v,c=e.writeCache??_,s=e.isProcessAlive??ie,u=e.sleep??ae,d=e.clock??Date.now,T=e.lazyNpmRoot??P,O=e.spawnSync??L,V=e.installedVersion??se,i=await o(n),a=(y,j)=>(c({lastCheckMs:r,...j,outcome:y}),y);if(i===null)return a("fetch-failed",{latestVersion:null,updateCommand:null});if(!M(i,t))return a("up-to-date",{latestVersion:i,updateCommand:null});let{canSelfSpawn:F,updateCommand:p}=k({selfRealPath:e.selfRealPath,env:n,realpath:S,lazyNpmRoot:T,version:i});if(!F)return a("cannot-self-spawn",{latestVersion:i,updateCommand:p});if(e.parentPid==null)return a("parent-unknown",{latestVersion:i,updateCommand:null});if(c({lastCheckMs:r,latestVersion:i,updateCommand:null,outcome:"installing"}),!await ce(e.parentPid,{isProcessAlive:s,sleep:u,clock:d}))return a("parent-still-running",{latestVersion:i,updateCommand:null});let g=O(p[0],p.slice(1),{stdio:"ignore",shell:h.platform==="win32",cwd:I(),env:w(n),windowsHide:!0});return g.error||g.signal||g.status!==0?a("install-failed",{latestVersion:i,updateCommand:p}):V(n)!==i?a("install-stale",{latestVersion:i,updateCommand:p}):a("installed",{latestVersion:null,updateCommand:null})};export{M as a,be as b,Ee as c,Te as d};
2
- //# sourceMappingURL=chunk-YYEUJYC7.js.map