@docker-doctor/cli 0.3.1 → 0.3.3
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/README.md +1 -5
- package/dist/cli.cjs +167 -95
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +1 -1
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +167 -95
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{src-BOzcDwm-.mjs → src-BjT5tN_H.mjs} +3 -70
- package/dist/{src-BOzcDwm-.mjs.map → src-BjT5tN_H.mjs.map} +1 -1
- package/dist/{src-38C8Tk2b.cjs → src-DfNUTuMC.cjs} +8 -75
- package/dist/{src-38C8Tk2b.cjs.map → src-DfNUTuMC.cjs.map} +1 -1
- package/package.json +5 -5
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.cjs","names":["styles","process","os","tty","path","fs","findRule","path","fs","path","fs","SKILL_MANIFEST_FILE","border","findRule","path","fs","runDockerfileRules","parseDockerfile","runComposeRules","parseCompose","findRule","Command","packageJson","loadConfig","discoverProject","calculateScore","os","toJsonReport","allRules"],"sources":["../../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js","../../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/supports-color/index.js","../../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/utilities.js","../../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/index.js","../src/agents/clipboard.ts","../src/agents/diagnostics-dir.ts","../src/agents/handoff-payload.ts","../src/agents/is-command-available.ts","../src/agents/launchable-agents.ts","../src/agents/launch-agent.ts","../src/agents/skill-install.ts","../src/formatters/terminal.ts","../src/cli.ts"],"sourcesContent":["const ANSI_BACKGROUND_OFFSET = 10;\n\nconst wrapAnsi16 = (offset = 0) => code => `\\u001B[${code + offset}m`;\n\nconst wrapAnsi256 = (offset = 0) => code => `\\u001B[${38 + offset};5;${code}m`;\n\nconst wrapAnsi16m = (offset = 0) => (red, green, blue) => `\\u001B[${38 + offset};2;${red};${green};${blue}m`;\n\nconst styles = {\n\tmodifier: {\n\t\treset: [0, 0],\n\t\t// 21 isn't widely supported and 22 does the same thing\n\t\tbold: [1, 22],\n\t\tdim: [2, 22],\n\t\titalic: [3, 23],\n\t\tunderline: [4, 24],\n\t\toverline: [53, 55],\n\t\tinverse: [7, 27],\n\t\thidden: [8, 28],\n\t\tstrikethrough: [9, 29],\n\t},\n\tcolor: {\n\t\tblack: [30, 39],\n\t\tred: [31, 39],\n\t\tgreen: [32, 39],\n\t\tyellow: [33, 39],\n\t\tblue: [34, 39],\n\t\tmagenta: [35, 39],\n\t\tcyan: [36, 39],\n\t\twhite: [37, 39],\n\n\t\t// Bright color\n\t\tblackBright: [90, 39],\n\t\tgray: [90, 39], // Alias of `blackBright`\n\t\tgrey: [90, 39], // Alias of `blackBright`\n\t\tredBright: [91, 39],\n\t\tgreenBright: [92, 39],\n\t\tyellowBright: [93, 39],\n\t\tblueBright: [94, 39],\n\t\tmagentaBright: [95, 39],\n\t\tcyanBright: [96, 39],\n\t\twhiteBright: [97, 39],\n\t},\n\tbgColor: {\n\t\tbgBlack: [40, 49],\n\t\tbgRed: [41, 49],\n\t\tbgGreen: [42, 49],\n\t\tbgYellow: [43, 49],\n\t\tbgBlue: [44, 49],\n\t\tbgMagenta: [45, 49],\n\t\tbgCyan: [46, 49],\n\t\tbgWhite: [47, 49],\n\n\t\t// Bright color\n\t\tbgBlackBright: [100, 49],\n\t\tbgGray: [100, 49], // Alias of `bgBlackBright`\n\t\tbgGrey: [100, 49], // Alias of `bgBlackBright`\n\t\tbgRedBright: [101, 49],\n\t\tbgGreenBright: [102, 49],\n\t\tbgYellowBright: [103, 49],\n\t\tbgBlueBright: [104, 49],\n\t\tbgMagentaBright: [105, 49],\n\t\tbgCyanBright: [106, 49],\n\t\tbgWhiteBright: [107, 49],\n\t},\n};\n\nexport const modifierNames = Object.keys(styles.modifier);\nexport const foregroundColorNames = Object.keys(styles.color);\nexport const backgroundColorNames = Object.keys(styles.bgColor);\nexport const colorNames = [...foregroundColorNames, ...backgroundColorNames];\n\nfunction assembleStyles() {\n\tconst codes = new Map();\n\n\tfor (const [groupName, group] of Object.entries(styles)) {\n\t\tfor (const [styleName, style] of Object.entries(group)) {\n\t\t\tstyles[styleName] = {\n\t\t\t\topen: `\\u001B[${style[0]}m`,\n\t\t\t\tclose: `\\u001B[${style[1]}m`,\n\t\t\t};\n\n\t\t\tgroup[styleName] = styles[styleName];\n\n\t\t\tcodes.set(style[0], style[1]);\n\t\t}\n\n\t\tObject.defineProperty(styles, groupName, {\n\t\t\tvalue: group,\n\t\t\tenumerable: false,\n\t\t});\n\t}\n\n\tObject.defineProperty(styles, 'codes', {\n\t\tvalue: codes,\n\t\tenumerable: false,\n\t});\n\n\tstyles.color.close = '\\u001B[39m';\n\tstyles.bgColor.close = '\\u001B[49m';\n\n\tstyles.color.ansi = wrapAnsi16();\n\tstyles.color.ansi256 = wrapAnsi256();\n\tstyles.color.ansi16m = wrapAnsi16m();\n\tstyles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);\n\n\t// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js\n\tObject.defineProperties(styles, {\n\t\trgbToAnsi256: {\n\t\t\tvalue(red, green, blue) {\n\t\t\t\t// We use the extended greyscale palette here, with the exception of\n\t\t\t\t// black and white. normal palette only has 4 greyscale shades.\n\t\t\t\tif (red === green && green === blue) {\n\t\t\t\t\tif (red < 8) {\n\t\t\t\t\t\treturn 16;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (red > 248) {\n\t\t\t\t\t\treturn 231;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn Math.round(((red - 8) / 247) * 24) + 232;\n\t\t\t\t}\n\n\t\t\t\treturn 16\n\t\t\t\t\t+ (36 * Math.round(red / 255 * 5))\n\t\t\t\t\t+ (6 * Math.round(green / 255 * 5))\n\t\t\t\t\t+ Math.round(blue / 255 * 5);\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToRgb: {\n\t\t\tvalue(hex) {\n\t\t\t\tconst matches = /[a-f\\d]{6}|[a-f\\d]{3}/i.exec(hex.toString(16));\n\t\t\t\tif (!matches) {\n\t\t\t\t\treturn [0, 0, 0];\n\t\t\t\t}\n\n\t\t\t\tlet [colorString] = matches;\n\n\t\t\t\tif (colorString.length === 3) {\n\t\t\t\t\tcolorString = [...colorString].map(character => character + character).join('');\n\t\t\t\t}\n\n\t\t\t\tconst integer = Number.parseInt(colorString, 16);\n\n\t\t\t\treturn [\n\t\t\t\t\t/* eslint-disable no-bitwise */\n\t\t\t\t\t(integer >> 16) & 0xFF,\n\t\t\t\t\t(integer >> 8) & 0xFF,\n\t\t\t\t\tinteger & 0xFF,\n\t\t\t\t\t/* eslint-enable no-bitwise */\n\t\t\t\t];\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi256: {\n\t\t\tvalue: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t\tansi256ToAnsi: {\n\t\t\tvalue(code) {\n\t\t\t\tif (code < 8) {\n\t\t\t\t\treturn 30 + code;\n\t\t\t\t}\n\n\t\t\t\tif (code < 16) {\n\t\t\t\t\treturn 90 + (code - 8);\n\t\t\t\t}\n\n\t\t\t\tlet red;\n\t\t\t\tlet green;\n\t\t\t\tlet blue;\n\n\t\t\t\tif (code >= 232) {\n\t\t\t\t\tred = (((code - 232) * 10) + 8) / 255;\n\t\t\t\t\tgreen = red;\n\t\t\t\t\tblue = red;\n\t\t\t\t} else {\n\t\t\t\t\tcode -= 16;\n\n\t\t\t\t\tconst remainder = code % 36;\n\n\t\t\t\t\tred = Math.floor(code / 36) / 5;\n\t\t\t\t\tgreen = Math.floor(remainder / 6) / 5;\n\t\t\t\t\tblue = (remainder % 6) / 5;\n\t\t\t\t}\n\n\t\t\t\tconst value = Math.max(red, green, blue) * 2;\n\n\t\t\t\tif (value === 0) {\n\t\t\t\t\treturn 30;\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\t\tlet result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));\n\n\t\t\t\tif (value === 2) {\n\t\t\t\t\tresult += 60;\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\trgbToAnsi: {\n\t\t\tvalue: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi: {\n\t\t\tvalue: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t});\n\n\treturn styles;\n}\n\nconst ansiStyles = assembleStyles();\n\nexport default ansiStyles;\n","import process from 'node:process';\nimport os from 'node:os';\nimport tty from 'node:tty';\n\n// From: https://github.com/sindresorhus/has-flag/blob/main/index.js\n/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {\nfunction hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {\n\tconst prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');\n\tconst position = argv.indexOf(prefix + flag);\n\tconst terminatorPosition = argv.indexOf('--');\n\treturn position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);\n}\n\nconst {env} = process;\n\nlet flagForceColor;\nif (\n\thasFlag('no-color')\n\t|| hasFlag('no-colors')\n\t|| hasFlag('color=false')\n\t|| hasFlag('color=never')\n) {\n\tflagForceColor = 0;\n} else if (\n\thasFlag('color')\n\t|| hasFlag('colors')\n\t|| hasFlag('color=true')\n\t|| hasFlag('color=always')\n) {\n\tflagForceColor = 1;\n}\n\nfunction envForceColor() {\n\tif ('FORCE_COLOR' in env) {\n\t\tif (env.FORCE_COLOR === 'true') {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (env.FORCE_COLOR === 'false') {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);\n\t}\n}\n\nfunction translateLevel(level) {\n\tif (level === 0) {\n\t\treturn false;\n\t}\n\n\treturn {\n\t\tlevel,\n\t\thasBasic: true,\n\t\thas256: level >= 2,\n\t\thas16m: level >= 3,\n\t};\n}\n\nfunction _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {\n\tconst noFlagForceColor = envForceColor();\n\tif (noFlagForceColor !== undefined) {\n\t\tflagForceColor = noFlagForceColor;\n\t}\n\n\tconst forceColor = sniffFlags ? flagForceColor : noFlagForceColor;\n\n\tif (forceColor === 0) {\n\t\treturn 0;\n\t}\n\n\tif (sniffFlags) {\n\t\tif (hasFlag('color=16m')\n\t\t\t|| hasFlag('color=full')\n\t\t\t|| hasFlag('color=truecolor')) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (hasFlag('color=256')) {\n\t\t\treturn 2;\n\t\t}\n\t}\n\n\t// Check for Azure DevOps pipelines.\n\t// Has to be above the `!streamIsTTY` check.\n\tif ('TF_BUILD' in env && 'AGENT_NAME' in env) {\n\t\treturn 1;\n\t}\n\n\tif (haveStream && !streamIsTTY && forceColor === undefined) {\n\t\treturn 0;\n\t}\n\n\tconst min = forceColor || 0;\n\n\tif (env.TERM === 'dumb') {\n\t\treturn min;\n\t}\n\n\tif (process.platform === 'win32') {\n\t\t// Windows 10 build 10586 is the first Windows release that supports 256 colors.\n\t\t// Windows 10 build 14931 is the first release that supports 16m/TrueColor.\n\t\tconst osRelease = os.release().split('.');\n\t\tif (\n\t\t\tNumber(osRelease[0]) >= 10\n\t\t\t&& Number(osRelease[2]) >= 10_586\n\t\t) {\n\t\t\treturn Number(osRelease[2]) >= 14_931 ? 3 : 2;\n\t\t}\n\n\t\treturn 1;\n\t}\n\n\tif ('CI' in env) {\n\t\tif (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn min;\n\t}\n\n\tif ('TEAMCITY_VERSION' in env) {\n\t\treturn /^(9\\.(0*[1-9]\\d*)\\.|\\d{2,}\\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;\n\t}\n\n\tif (env.COLORTERM === 'truecolor') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'xterm-kitty') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'xterm-ghostty') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'wezterm') {\n\t\treturn 3;\n\t}\n\n\tif ('TERM_PROGRAM' in env) {\n\t\tconst version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);\n\n\t\tswitch (env.TERM_PROGRAM) {\n\t\t\tcase 'iTerm.app': {\n\t\t\t\treturn version >= 3 ? 3 : 2;\n\t\t\t}\n\n\t\t\tcase 'Apple_Terminal': {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\t// No default\n\t\t}\n\t}\n\n\tif (/-256(color)?$/i.test(env.TERM)) {\n\t\treturn 2;\n\t}\n\n\tif (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {\n\t\treturn 1;\n\t}\n\n\tif ('COLORTERM' in env) {\n\t\treturn 1;\n\t}\n\n\treturn min;\n}\n\nexport function createSupportsColor(stream, options = {}) {\n\tconst level = _supportsColor(stream, {\n\t\tstreamIsTTY: stream && stream.isTTY,\n\t\t...options,\n\t});\n\n\treturn translateLevel(level);\n}\n\nconst supportsColor = {\n\tstdout: createSupportsColor({isTTY: tty.isatty(1)}),\n\tstderr: createSupportsColor({isTTY: tty.isatty(2)}),\n};\n\nexport default supportsColor;\n","// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`.\nexport function stringReplaceAll(string, substring, replacer) {\n\tlet index = string.indexOf(substring);\n\tif (index === -1) {\n\t\treturn string;\n\t}\n\n\tconst substringLength = substring.length;\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\treturnValue += string.slice(endIndex, index) + substring + replacer;\n\t\tendIndex = index + substringLength;\n\t\tindex = string.indexOf(substring, endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n\nexport function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\tconst gotCR = string[index - 1] === '\\r';\n\t\treturnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\\r\\n' : '\\n') + postfix;\n\t\tendIndex = index + 1;\n\t\tindex = string.indexOf('\\n', endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n","import ansiStyles from '#ansi-styles';\nimport supportsColor from '#supports-color';\nimport { // eslint-disable-line import/order\n\tstringReplaceAll,\n\tstringEncaseCRLFWithFirstIndex,\n} from './utilities.js';\n\nconst {stdout: stdoutColor, stderr: stderrColor} = supportsColor;\n\nconst GENERATOR = Symbol('GENERATOR');\nconst STYLER = Symbol('STYLER');\nconst IS_EMPTY = Symbol('IS_EMPTY');\n\n// `supportsColor.level` → `ansiStyles.color[name]` mapping\nconst levelMapping = [\n\t'ansi',\n\t'ansi',\n\t'ansi256',\n\t'ansi16m',\n];\n\nconst styles = Object.create(null);\n\nconst applyOptions = (object, options = {}) => {\n\tif (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {\n\t\tthrow new Error('The `level` option should be an integer from 0 to 3');\n\t}\n\n\t// Detect level if not set manually\n\tconst colorLevel = stdoutColor ? stdoutColor.level : 0;\n\tobject.level = options.level === undefined ? colorLevel : options.level;\n};\n\nexport class Chalk {\n\tconstructor(options) {\n\t\t// eslint-disable-next-line no-constructor-return\n\t\treturn chalkFactory(options);\n\t}\n}\n\nconst chalkFactory = options => {\n\tconst chalk = (...strings) => strings.join(' ');\n\tapplyOptions(chalk, options);\n\n\tObject.setPrototypeOf(chalk, createChalk.prototype);\n\n\treturn chalk;\n};\n\nfunction createChalk(options) {\n\treturn chalkFactory(options);\n}\n\nObject.setPrototypeOf(createChalk.prototype, Function.prototype);\n\nfor (const [styleName, style] of Object.entries(ansiStyles)) {\n\tstyles[styleName] = {\n\t\tget() {\n\t\t\tconst builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);\n\t\t\tObject.defineProperty(this, styleName, {value: builder});\n\t\t\treturn builder;\n\t\t},\n\t};\n}\n\nstyles.visible = {\n\tget() {\n\t\tconst builder = createBuilder(this, this[STYLER], true);\n\t\tObject.defineProperty(this, 'visible', {value: builder});\n\t\treturn builder;\n\t},\n};\n\nconst getModelAnsi = (model, level, type, ...arguments_) => {\n\tif (model === 'rgb') {\n\t\tif (level === 'ansi16m') {\n\t\t\treturn ansiStyles[type].ansi16m(...arguments_);\n\t\t}\n\n\t\tif (level === 'ansi256') {\n\t\t\treturn ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));\n\t\t}\n\n\t\treturn ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));\n\t}\n\n\tif (model === 'hex') {\n\t\treturn getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_));\n\t}\n\n\treturn ansiStyles[type][model](...arguments_);\n};\n\nconst usedModels = ['rgb', 'hex', 'ansi256'];\n\nfor (const model of usedModels) {\n\tstyles[model] = {\n\t\tget() {\n\t\t\tconst {level} = this;\n\t\t\treturn function (...arguments_) {\n\t\t\t\tconst styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]);\n\t\t\t\treturn createBuilder(this, styler, this[IS_EMPTY]);\n\t\t\t};\n\t\t},\n\t};\n\n\tconst bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);\n\tstyles[bgModel] = {\n\t\tget() {\n\t\t\tconst {level} = this;\n\t\t\treturn function (...arguments_) {\n\t\t\t\tconst styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]);\n\t\t\t\treturn createBuilder(this, styler, this[IS_EMPTY]);\n\t\t\t};\n\t\t},\n\t};\n}\n\nconst proto = Object.defineProperties(() => {}, {\n\t...styles,\n\tlevel: {\n\t\tenumerable: true,\n\t\tget() {\n\t\t\treturn this[GENERATOR].level;\n\t\t},\n\t\tset(level) {\n\t\t\tthis[GENERATOR].level = level;\n\t\t},\n\t},\n});\n\nconst createStyler = (open, close, parent) => {\n\tlet openAll;\n\tlet closeAll;\n\tif (parent === undefined) {\n\t\topenAll = open;\n\t\tcloseAll = close;\n\t} else {\n\t\topenAll = parent.openAll + open;\n\t\tcloseAll = close + parent.closeAll;\n\t}\n\n\treturn {\n\t\topen,\n\t\tclose,\n\t\topenAll,\n\t\tcloseAll,\n\t\tparent,\n\t};\n};\n\nconst createBuilder = (self, _styler, _isEmpty) => {\n\t// Single argument is hot path, implicit coercion is faster than anything\n\t// eslint-disable-next-line no-implicit-coercion\n\tconst builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));\n\n\t// We alter the prototype because we must return a function, but there is\n\t// no way to create a function with a different prototype\n\tObject.setPrototypeOf(builder, proto);\n\n\tbuilder[GENERATOR] = self;\n\tbuilder[STYLER] = _styler;\n\tbuilder[IS_EMPTY] = _isEmpty;\n\n\treturn builder;\n};\n\nconst applyStyle = (self, string) => {\n\tif (self.level <= 0 || !string) {\n\t\treturn self[IS_EMPTY] ? '' : string;\n\t}\n\n\tlet styler = self[STYLER];\n\n\tif (styler === undefined) {\n\t\treturn string;\n\t}\n\n\tconst {openAll, closeAll} = styler;\n\tif (string.includes('\\u001B')) {\n\t\twhile (styler !== undefined) {\n\t\t\t// Replace any instances already present with a re-opening code\n\t\t\t// otherwise only the part of the string until said closing code\n\t\t\t// will be colored, and the rest will simply be 'plain'.\n\t\t\tstring = stringReplaceAll(string, styler.close, styler.open);\n\n\t\t\tstyler = styler.parent;\n\t\t}\n\t}\n\n\t// We can move both next actions out of loop, because remaining actions in loop won't have\n\t// any/visible effect on parts we add here. Close the styling before a linebreak and reopen\n\t// after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92\n\tconst lfIndex = string.indexOf('\\n');\n\tif (lfIndex !== -1) {\n\t\tstring = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);\n\t}\n\n\treturn openAll + string + closeAll;\n};\n\nObject.defineProperties(createChalk.prototype, styles);\n\nconst chalk = createChalk();\nexport const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0});\n\nexport {\n\tmodifierNames,\n\tforegroundColorNames,\n\tbackgroundColorNames,\n\tcolorNames,\n\n\t// TODO: Remove these aliases in the next major version\n\tmodifierNames as modifiers,\n\tforegroundColorNames as foregroundColors,\n\tbackgroundColorNames as backgroundColors,\n\tcolorNames as colors,\n} from './vendor/ansi-styles/index.js';\n\nexport {\n\tstdoutColor as supportsColor,\n\tstderrColor as supportsColorStderr,\n};\n\nexport default chalk;\n","import { spawn } from \"node:child_process\";\n\ninterface ClipboardCommand {\n command: string;\n args: string[];\n}\n\nconst getClipboardCommands = (): ClipboardCommand[] => {\n if (process.platform === \"darwin\") {\n return [{ args: [], command: \"pbcopy\" }];\n }\n if (process.platform === \"win32\") {\n return [{ args: [], command: \"clip\" }];\n }\n return [\n { args: [], command: \"wl-copy\" },\n { args: [\"-selection\", \"clipboard\"], command: \"xclip\" },\n { args: [\"--clipboard\", \"--input\"], command: \"xsel\" },\n ];\n};\n\nconst tryCopy = ({ command, args }: ClipboardCommand, text: string) =>\n /* eslint-disable promise/avoid-new */\n new Promise<boolean>((resolve) => {\n const child = spawn(command, args, {\n stdio: [\"pipe\", \"ignore\", \"ignore\"],\n });\n child.once(\"error\", () => {\n resolve(false);\n });\n child.once(\"exit\", (code) => {\n resolve(code === 0);\n });\n child.stdin.end(text);\n });\n/* eslint-enable promise/avoid-new */\n\nconst tryCommands = async (\n commands: ClipboardCommand[],\n text: string\n): Promise<boolean> => {\n const [first, ...rest] = commands;\n if (!first) {\n return false;\n }\n if (await tryCopy(first, text)) {\n return true;\n }\n return tryCommands(rest, text);\n};\n\n// Best-effort: tries each platform clipboard tool in order (they're fallbacks,\n// so the attempts are sequential). Returns false when none worked — the\n// caller prints the payload instead.\nexport const copyToClipboard = (text: string): Promise<boolean> =>\n tryCommands(getClipboardCommands(), text);\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { Diagnostic, JsonReport } from \"@docker-doctor/core\";\n\nexport const DIAGNOSTICS_DIR_NAME = \".docker-doctor\";\n\nconst UNSAFE_FILE_CHARS = /[^a-z0-9-]+/giu;\n\nconst ruleFileName = (rule: string): string => {\n const shortKey = rule.split(\"/\").at(-1) ?? rule;\n return `${shortKey.replace(UNSAFE_FILE_CHARS, \"-\")}.txt`;\n};\n\nexport const groupDiagnosticsByRule = (\n diagnostics: Diagnostic[]\n): Map<string, Diagnostic[]> => {\n const groups = new Map<string, Diagnostic[]>();\n for (const diagnostic of diagnostics) {\n const group = groups.get(diagnostic.rule);\n if (group) {\n group.push(diagnostic);\n } else {\n groups.set(diagnostic.rule, [diagnostic]);\n }\n }\n return groups;\n};\n\n// Writes the full scan results into <root>/.docker-doctor/ — diagnostics.json\n// (the same shape as `--json`) plus one .txt per rule — so the handed-off\n// agent can read past the inline prompt. Recreated fresh on every handoff.\nexport const writeDiagnosticsDirectory = async (\n diagnostics: Diagnostic[],\n report: JsonReport,\n rootDir: string\n): Promise<void> => {\n const dir = path.join(rootDir, DIAGNOSTICS_DIR_NAME);\n await fs.rm(dir, { force: true, recursive: true });\n await fs.mkdir(dir, { recursive: true });\n\n await fs.writeFile(\n path.join(dir, \"diagnostics.json\"),\n JSON.stringify(report, null, 2),\n \"utf-8\"\n );\n\n const writes: Promise<void>[] = [];\n for (const [rule, ruleDiagnostics] of groupDiagnosticsByRule(diagnostics)) {\n const [first] = ruleDiagnostics;\n const lines = [\n `${rule} (${first.severity})`,\n first.message,\n `Fix: ${first.help}`,\n \"\",\n ...ruleDiagnostics.map(\n (d) => `${d.file}${d.line === undefined ? \"\" : `:${d.line}`}`\n ),\n \"\",\n ];\n writes.push(\n fs.writeFile(\n path.join(dir, ruleFileName(rule)),\n lines.join(\"\\n\"),\n \"utf-8\"\n )\n );\n }\n await Promise.all(writes);\n};\n\n// Keeps the scan output out of version control: appends `.docker-doctor/` to\n// the project's .gitignore when it isn't covered yet. Only creates a new\n// .gitignore when the project is actually a git repository.\nexport const ensureGitignoreEntry = async (rootDir: string): Promise<void> => {\n const gitignorePath = path.join(rootDir, \".gitignore\");\n\n let existing: string | null = null;\n try {\n existing = await fs.readFile(gitignorePath, \"utf-8\");\n } catch {\n existing = null;\n }\n\n if (existing !== null) {\n const isIgnored = existing\n .split(/\\r?\\n/u)\n .some((line) =>\n [\n DIAGNOSTICS_DIR_NAME,\n `${DIAGNOSTICS_DIR_NAME}/`,\n `/${DIAGNOSTICS_DIR_NAME}`,\n `/${DIAGNOSTICS_DIR_NAME}/`,\n ].includes(line.trim())\n );\n if (isIgnored) {\n return;\n }\n const separator = existing.endsWith(\"\\n\") || existing === \"\" ? \"\" : \"\\n\";\n await fs.writeFile(\n gitignorePath,\n `${existing}${separator}${DIAGNOSTICS_DIR_NAME}/\\n`,\n \"utf-8\"\n );\n return;\n }\n\n try {\n await fs.access(path.join(rootDir, \".git\"));\n } catch {\n return;\n }\n await fs.writeFile(gitignorePath, `${DIAGNOSTICS_DIR_NAME}/\\n`, \"utf-8\");\n};\n","import type { Diagnostic } from \"@docker-doctor/core\";\nimport { findRule } from \"@docker-doctor/core\";\n\nimport {\n DIAGNOSTICS_DIR_NAME,\n groupDiagnosticsByRule,\n} from \"./diagnostics-dir\";\n\nconst MAX_FILES_PER_RULE = 5;\n\nconst SEVERITY_RANK: Record<Diagnostic[\"severity\"], number> = {\n error: 0,\n info: 2,\n warning: 1,\n};\n\nconst SEVERITY_LABEL: Record<Diagnostic[\"severity\"], string> = {\n error: \"ERROR\",\n info: \"INFO\",\n warning: \"WARN\",\n};\n\nexport interface HandoffPayloadInput {\n diagnostics: Diagnostic[];\n projectName: string;\n}\n\n// The prompt handed to the chosen agent: every rule group inline (docker\n// projects rarely have hundreds of findings), errors first, each with its fix\n// recipe and affected files, plus a pointer to the full on-disk report.\nexport const buildHandoffPayload = (input: HandoffPayloadInput): string => {\n const groups = [\n ...groupDiagnosticsByRule(input.diagnostics).entries(),\n ].toSorted(([, a], [, b]) => {\n const rankDelta =\n SEVERITY_RANK[a[0].severity] - SEVERITY_RANK[b[0].severity];\n return rankDelta === 0 ? b.length - a.length : rankDelta;\n });\n\n const issueWord = groups.length === 1 ? \"issue\" : \"issues\";\n const lines: string[] = [\n `Fix the ${groups.length} Docker Doctor ${issueWord} in ${input.projectName}.`,\n \"\",\n ];\n\n for (const [index, [rule, ruleDiagnostics]] of groups.entries()) {\n const [first] = ruleDiagnostics;\n const category = findRule(rule)?.category ?? \"General\";\n const countBadge =\n ruleDiagnostics.length > 1 ? ` (×${ruleDiagnostics.length})` : \"\";\n lines.push(\n `${index + 1}. ${SEVERITY_LABEL[first.severity]} ${category}: ${first.message} [${rule}]${countBadge}`,\n ` Fix: ${first.help}`\n );\n const files = [...new Set(ruleDiagnostics.map((d) => d.file))];\n for (const file of files.slice(0, MAX_FILES_PER_RULE)) {\n const firstSite = ruleDiagnostics.find(\n (d) => d.file === file && d.line !== undefined\n );\n lines.push(` - ${file}${firstSite ? `:${firstSite.line}` : \"\"}`);\n }\n const remaining = files.length - MAX_FILES_PER_RULE;\n if (remaining > 0) {\n lines.push(` - +${remaining} more files`);\n }\n }\n\n lines.push(\n \"\",\n `Full report (diagnostics.json + a .txt per rule): ${DIAGNOSTICS_DIR_NAME}/`,\n \"\",\n \"Read each file and fix the root cause — don't suppress or silence the rule.\",\n \"When you're done, re-run `npx @docker-doctor/cli@latest .` and confirm the score improved and no errors remain.\"\n );\n\n return lines.join(\"\\n\");\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst WINDOWS_EXTENSIONS = [\".exe\", \".cmd\", \".bat\"];\n\nexport const isCommandAvailable = (command: string): boolean => {\n const pathValue = process.env.PATH ?? \"\";\n const extensions = process.platform === \"win32\" ? WINDOWS_EXTENSIONS : [\"\"];\n\n for (const dir of pathValue.split(path.delimiter)) {\n if (dir === \"\") {\n continue;\n }\n for (const extension of extensions) {\n try {\n fs.accessSync(path.join(dir, command + extension), fs.constants.X_OK);\n return true;\n } catch {\n // Not in this directory — keep looking.\n }\n }\n }\n return false;\n};\n","import { isCommandAvailable } from \"./is-command-available\";\n\nexport type LaunchableAgentId = \"claude-code\" | \"codex\" | \"cursor\";\n\nexport const LAUNCHABLE_AGENT_IDS: readonly LaunchableAgentId[] = [\n \"claude-code\",\n \"codex\",\n \"cursor\",\n];\n\n// CLI agents we can hand off to by launching their binary with the prompt as\n// the initial argument, inheriting this terminal — the agent takes over the\n// TTY and control returns here when it exits.\nexport const AGENT_BINARIES: Record<LaunchableAgentId, string> = {\n \"claude-code\": \"claude\",\n codex: \"codex\",\n cursor: \"cursor-agent\",\n};\n\n// Each agent's skip-approvals flag. The handoff exists so the agent can fix\n// the issues end-to-end; the user opted in by picking it from the menu.\nexport const AGENT_AUTO_FLAGS: Record<LaunchableAgentId, readonly string[]> = {\n \"claude-code\": [\"--dangerously-skip-permissions\"],\n codex: [\"--yolo\"],\n cursor: [\"--force\"],\n};\n\n// Launchable = the agent's CLI binary is on PATH. Windows is excluded: npm\n// installs .cmd shims there that `spawn` can only run through a shell, and a\n// shell mangles the multi-line prompt — those users get the clipboard path.\nexport const detectLaunchableAgents = (): LaunchableAgentId[] => {\n if (process.platform === \"win32\") {\n return [];\n }\n return LAUNCHABLE_AGENT_IDS.filter((agentId) =>\n isCommandAvailable(AGENT_BINARIES[agentId])\n );\n};\n","import { spawn } from \"node:child_process\";\n\nimport type { LaunchableAgentId } from \"./launchable-agents\";\nimport { AGENT_AUTO_FLAGS, AGENT_BINARIES } from \"./launchable-agents\";\n\n// Launches the agent's CLI with the prompt as its initial argument, handing it\n// this terminal. Resolves true when the agent process exits normally, false\n// when it could not be started (caller falls back to the clipboard path).\nexport const launchAgent = (\n agentId: LaunchableAgentId,\n prompt: string\n): Promise<boolean> =>\n /* eslint-disable promise/avoid-new */\n new Promise((resolve) => {\n const child = spawn(\n AGENT_BINARIES[agentId],\n [...AGENT_AUTO_FLAGS[agentId], prompt],\n { stdio: \"inherit\" }\n );\n child.once(\"error\", () => {\n resolve(false);\n });\n child.once(\"exit\", () => {\n resolve(true);\n });\n });\n/* eslint-enable promise/avoid-new */\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { SkillAgentType, SkillInstallResult } from \"agent-install\";\nimport { SKILL_MANIFEST_FILE, installSkillsFromSource } from \"agent-install\";\n\nconst moduleDir = import.meta.dirname;\n\n// The published package ships the skill at <package root>/skill (copied from\n// skills/docker-doctor at build time); when running from the repo the source\n// itself is the fallback. Returns null when neither exists.\nexport const getSkillSourceDirectory = (): string | null => {\n const candidates = [\n // dist/cli.mjs → package root/skill/docker-doctor\n path.resolve(moduleDir, \"../skill/docker-doctor\"),\n // src/agents/*.ts in the monorepo → repo root/skills/docker-doctor\n path.resolve(moduleDir, \"../../../../skills/docker-doctor\"),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(path.join(candidate, SKILL_MANIFEST_FILE))) {\n return candidate;\n }\n }\n return null;\n};\n\n// Copies the bundled docker-doctor skill into each agent's project-level\n// skills dir so the agent already knows the /docker-doctor triage workflow.\n// Best-effort: returns null when the bundled skill is missing or the install\n// throws — callers treat that as \"skill not installed\", never as a failure.\nexport const installSkillForAgents = async (\n agents: SkillAgentType[],\n projectRoot: string\n): Promise<SkillInstallResult | null> => {\n const source = getSkillSourceDirectory();\n if (!source) {\n return null;\n }\n try {\n return await installSkillsFromSource({\n agents,\n cwd: projectRoot,\n mode: \"copy\",\n source,\n });\n } catch {\n return null;\n }\n};\n","import { setTimeout } from \"node:timers/promises\";\n\nimport type { Diagnostic, ProjectInfo } from \"@docker-doctor/core\";\nimport { findRule } from \"@docker-doctor/core\";\nimport chalk from \"chalk\";\n\nconst printCodeFrame = (\n content: string | undefined,\n line: number | undefined,\n severityColor: (msg: string) => string\n): void => {\n if (!content || !line) {\n return;\n }\n const lines = content.split(/\\r?\\n/u);\n const start = Math.max(1, line - 1);\n const end = Math.min(lines.length, line + 1);\n\n for (let i = start; i <= end; i += 1) {\n const rawLine = lines[i - 1];\n const isTarget = i === line;\n const lineNumberStr = String(i).padStart(5, \" \");\n if (isTarget) {\n console.log(\n ` ${severityColor(\">\")} ${chalk.bold(lineNumberStr)} │ ${chalk.white(rawLine)}`\n );\n } else {\n console.log(` ${chalk.dim(lineNumberStr)} │ ${chalk.dim(rawLine)}`);\n }\n }\n console.log();\n};\n\nconst printDiscoveredFiles = (project: ProjectInfo): void => {\n console.log(`\\nDiscovered Files:`);\n console.log(\n ` Dockerfile(s): ${project.dockerfiles.length ? project.dockerfiles.map((f) => chalk.cyan(f)).join(\", \") : chalk.dim(\"None\")}`\n );\n console.log(\n ` Compose file(s): ${project.composeFiles.length ? project.composeFiles.map((f) => chalk.cyan(f)).join(\", \") : chalk.dim(\"None\")}`\n );\n};\n\nconst printDiagnostics = (\n diagnostics: Diagnostic[],\n verbose: boolean,\n fileContents: Record<string, string>,\n categoryIssueCounts: Record<string, number>\n): void => {\n if (diagnostics.length === 0) {\n console.log(\n `\\n${chalk.green.bold(\"✔ No issues found! Your Docker setup looks healthy.\")}`\n );\n return;\n }\n\n if (!verbose) {\n console.log(`\\n All ${chalk.bold(diagnostics.length)} issues\\n`);\n\n const categories = [\n \"Security\",\n \"Performance\",\n \"Best Practices\",\n \"Compose\",\n \"Image Size\",\n ];\n\n for (const cat of categories) {\n const count = categoryIssueCounts[cat];\n const issueLabel = count === 1 ? \"1 issue\" : `${count} issues`;\n console.log(` ${cat} › ${chalk.dim(issueLabel)}`);\n }\n\n console.log(\n `\\n Run ${chalk.cyan(\"docker-doctor --verbose\")} to list every error and warning`\n );\n\n // Migration-scale checks\n const ruleCounts: Record<string, number> = {};\n for (const d of diagnostics) {\n ruleCounts[d.rule] = (ruleCounts[d.rule] || 0) + 1;\n }\n const migrationRules = Object.entries(ruleCounts).filter(\n ([_, count]) => count >= 5\n );\n if (migrationRules.length > 0) {\n console.log();\n console.log(\n ` ${chalk.yellow(\"⚠ Migration-scale change: sample before you sweep\")}`\n );\n for (const [rule, count] of migrationRules) {\n console.log(` ${chalk.cyan(rule)} ×${count} across ${count} files`);\n }\n console.log(\n ` Fixing all of them at once is hard to review and prone to`\n );\n console.log(\n ` subtle mistakes across the whole repo. Fix a representative`\n );\n console.log(\n ` few first and confirm the recipe holds. Then get the code`\n );\n console.log(` owner's sign-off before changing the rest.`);\n console.log(` Scope it down one area at a time: docker-doctor <path>`);\n }\n return;\n }\n\n console.log(`\\nFound ${chalk.bold(diagnostics.length)} issue(s):`);\n\n // Group by file\n const filesGrouped: Record<string, Diagnostic[]> = {};\n for (const d of diagnostics) {\n if (!filesGrouped[d.file]) {\n filesGrouped[d.file] = [];\n }\n filesGrouped[d.file].push(d);\n }\n\n for (const [file, fileDiags] of Object.entries(filesGrouped)) {\n console.log(`\\n${chalk.underline.bold(file)}`);\n for (const d of fileDiags) {\n let sevColor = chalk.cyan;\n let prefix = \"ℹ INFO\";\n if (d.severity === \"error\") {\n sevColor = chalk.red.bold;\n prefix = \"✖ ERROR\";\n } else if (d.severity === \"warning\") {\n sevColor = chalk.yellow;\n prefix = \"⚠ WARN\";\n }\n\n const lineInfo = d.line ? `:${d.line}` : \"\";\n console.log(` ${sevColor(prefix)} [${chalk.dim(d.rule)}]${lineInfo}`);\n\n // Print Code Frame\n const content = fileContents[file];\n printCodeFrame(content, d.line, sevColor);\n\n console.log(` ${chalk.white(d.message)}`);\n console.log(` ${chalk.dim(\"Help:\")} ${d.help}`);\n console.log();\n }\n }\n};\n\nconst getWhaleMascot = (\n score: number,\n border: (text: string) => string\n): string[] => {\n let eyes = \"x x\";\n let spout = \" \";\n if (score >= 75) {\n eyes = \"◠ ◠\";\n spout = chalk.cyan(' \":\" ');\n } else if (score >= 50) {\n eyes = \"• •\";\n spout = chalk.cyan(\" . \");\n }\n\n return [\n spout,\n border(\" .---. \"),\n border(`( ${eyes} )>`),\n border(\" \\\\___/ \"),\n ];\n};\n\nconst easeOutCubic = (x: number): number => 1 - (1 - x) ** 3;\n\nconst printScoreBox = async (\n score: number,\n label: string,\n categoryIssueCounts: Record<string, number>,\n warningsCount: number,\n errorsCount: number\n): Promise<void> => {\n const { isTTY } = process.stdout;\n const shouldAnimate =\n isTTY &&\n !process.env.CI &&\n !process.env.NO_ANIMATION &&\n process.env.TERM !== \"dumb\" &&\n process.env.NODE_ENV !== \"test\";\n\n let scoreColor = chalk.red.bold;\n if (score >= 90) {\n scoreColor = chalk.green.bold;\n } else if (score >= 75) {\n scoreColor = chalk.yellow.bold;\n } else if (score >= 50) {\n scoreColor = chalk.magenta.bold;\n }\n const border = scoreColor;\n const whaleLines = getWhaleMascot(score, border);\n\n const shareUrl = `https://docker-doctor.vercel.app/share?s=${score}&w=${warningsCount}&e=${errorsCount}`;\n\n if (shouldAnimate) {\n const frameCount = 20;\n const frameDelay = 15;\n\n // Hide cursor\n process.stdout.write(\"\\u001B[?25l\");\n try {\n for (let frame = 0; frame <= frameCount; frame += 1) {\n const progress = easeOutCubic(frame / frameCount);\n const currentScore = Math.round(score * progress);\n const filledBlocks = Math.round(currentScore / 2);\n const emptyBlocks = 50 - filledBlocks;\n\n const bar =\n scoreColor(\"█\".repeat(filledBlocks)) +\n chalk.dim(\"░\".repeat(emptyBlocks));\n\n if (frame > 0) {\n // Move cursor up 4 lines and carriage return\n process.stdout.write(\"\\u001B[4A\\r\");\n } else {\n // print an extra newline first to start\n console.log();\n }\n\n process.stdout.write(\n ` ${whaleLines[0]} ${scoreColor(`${currentScore} / 100`)} ${scoreColor(label)}\\n` +\n ` ${whaleLines[1]} ${bar}\\n` +\n ` ${whaleLines[2]} ${chalk.dim(\"Docker Doctor (https://docker-doctor.vercel.app)\")}\\n` +\n ` ${whaleLines[3]}\\n`\n );\n\n if (frame < frameCount) {\n // eslint-disable-next-line no-await-in-loop\n await setTimeout(frameDelay);\n }\n }\n } finally {\n // Show cursor\n process.stdout.write(\"\\u001B[?25h\");\n }\n } else {\n // Non-TTY fall back to static print\n const filledBlocks = Math.round(score / 2);\n const emptyBlocks = 50 - filledBlocks;\n const bar =\n scoreColor(\"█\".repeat(filledBlocks)) + chalk.dim(\"░\".repeat(emptyBlocks));\n\n console.log(\n `\\n ${whaleLines[0]} ${scoreColor(`${score} / 100`)} ${scoreColor(label)}`\n );\n console.log(` ${whaleLines[1]} ${bar}`);\n console.log(\n ` ${whaleLines[2]} ${chalk.dim(\"Docker Doctor (https://docker-doctor.vercel.app)\")}`\n );\n console.log(` ${whaleLines[3]}`);\n }\n\n console.log(\n `\\n ${chalk.dim(\"────────────────────────────────────────────────────────────\")}\\n`\n );\n console.log(` Share: ${chalk.cyan(shareUrl)}`);\n console.log(` Tell others how you did on socials\\n`);\n console.log(` Docs: ${chalk.cyan(\"https://docker-doctor.vercel.app\")}`);\n console.log(` Learn more about fixing issues, setting up CI/CD, and`);\n console.log(` configuring rules with a config file\\n`);\n console.log(\n ` GitHub: ${chalk.cyan(\"https://github.com/PunGrumpy/docker-doctor\")}`\n );\n console.log(` Report issues and star the repository!`);\n};\n\nexport const formatTerminal = async (\n diagnostics: Diagnostic[],\n score: number,\n label: string,\n project: ProjectInfo,\n verbose = false,\n fileContents: Record<string, string> = {}\n): Promise<void> => {\n if (verbose) {\n console.log(`\\n${chalk.bold(\"Docker Doctor Diagnostics\")}`);\n console.log(`=================================`);\n printDiscoveredFiles(project);\n }\n\n // Calculate scores per category once\n const categoryIssueCounts: Record<string, number> = {\n \"Best Practices\": 0,\n Compose: 0,\n \"Image Size\": 0,\n Performance: 0,\n Security: 0,\n };\n\n let warningsCount = 0;\n let errorsCount = 0;\n\n for (const d of diagnostics) {\n const ruleDef = findRule(d.rule);\n const category = ruleDef?.category || \"Best Practices\";\n categoryIssueCounts[category] = (categoryIssueCounts[category] || 0) + 1;\n\n if (d.severity === \"warning\") {\n warningsCount += 1;\n } else if (d.severity === \"error\") {\n errorsCount += 1;\n }\n }\n\n printDiagnostics(diagnostics, verbose, fileContents, categoryIssueCounts);\n\n await printScoreBox(\n score,\n label,\n categoryIssueCounts,\n warningsCount,\n errorsCount\n );\n};\n","import fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport readline from \"node:readline\";\nimport { setTimeout } from \"node:timers/promises\";\n\nimport type { Diagnostic, JsonReport, RuleSeverity } from \"@docker-doctor/core\";\nimport {\n discoverProject,\n parseDockerfile,\n parseCompose,\n runDockerfileRules,\n runComposeRules,\n calculateScore,\n loadConfig,\n allRules,\n findRule,\n toJsonReport,\n} from \"@docker-doctor/core\";\nimport type { SkillAgentType } from \"agent-install\";\nimport {\n detectInstalledSkillAgents,\n getSkillAgentConfig,\n getSkillAgentTypes,\n isSkillAgentType,\n} from \"agent-install\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport packageJson from \"../package.json\" with { type: \"json\" };\nimport { copyToClipboard } from \"./agents/clipboard\";\nimport {\n ensureGitignoreEntry,\n writeDiagnosticsDirectory,\n} from \"./agents/diagnostics-dir\";\nimport { buildHandoffPayload } from \"./agents/handoff-payload\";\nimport { launchAgent } from \"./agents/launch-agent\";\nimport {\n AGENT_BINARIES,\n detectLaunchableAgents,\n} from \"./agents/launchable-agents\";\nimport {\n getSkillSourceDirectory,\n installSkillForAgents,\n} from \"./agents/skill-install\";\nimport { formatTerminal } from \"./formatters/terminal\";\n\ninterface KeypressKey {\n name?: string;\n ctrl?: boolean;\n meta?: boolean;\n shift?: boolean;\n}\n\nconst askConfirm = (question: string, defaultYes = false): Promise<boolean> => {\n const isRaw = process.stdin.isTTY;\n if (!isRaw) {\n return Promise.resolve(defaultYes);\n }\n\n /* eslint-disable promise/avoid-new */\n return new Promise((resolve) => {\n let value = defaultYes;\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n // Hide cursor during prompt\n process.stdout.write(\"\\u001B[?25l\");\n\n const render = (firstTime = false) => {\n if (!firstTime) {\n process.stdout.write(\"\\u001B[3A\\r\");\n }\n\n process.stdout.write(\n `\\r\\u001B[K ${chalk.green(\"✔\")} ${chalk.bold(question)}\\n`\n );\n\n // Print options vertically\n const yesPrefix = value ? chalk.cyan(\"❯ \") : \" \";\n const yesText = value ? chalk.cyan.bold(\"Yes\") : chalk.dim(\"Yes\");\n process.stdout.write(`\\r\\u001B[K${yesPrefix}${yesText}\\n`);\n\n const noPrefix = value ? \" \" : chalk.cyan(\"❯ \");\n const noText = value ? chalk.dim(\"No\") : chalk.cyan.bold(\"No\");\n process.stdout.write(`\\r\\u001B[K${noPrefix}${noText}\\n`);\n };\n\n render(true);\n\n const handleKeypress = (str: string, key: KeypressKey) => {\n const cleanup = () => {\n process.stdin.removeListener(\"keypress\", handleKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.pause();\n process.stdout.write(\"\\u001B[?25h\");\n };\n\n if (\n key.name === \"left\" ||\n key.name === \"right\" ||\n key.name === \"up\" ||\n key.name === \"down\" ||\n key.name === \"h\" ||\n key.name === \"l\" ||\n key.name === \"j\" ||\n key.name === \"k\"\n ) {\n value = !value;\n render();\n } else if (str === \"y\" || str === \"Y\") {\n value = true;\n render();\n } else if (str === \"n\" || str === \"N\") {\n value = false;\n render();\n } else if (\n key.name === \"return\" ||\n key.name === \"enter\" ||\n str === \"\\r\" ||\n str === \"\\n\"\n ) {\n cleanup();\n // Overwrite and resolve vertical layout cleanly\n process.stdout.write(\"\\u001B[3A\\r\\u001B[K\");\n process.stdout.write(\n ` ${chalk.green(\"✔\")} ${chalk.bold(question)} › ${value ? chalk.cyan(\"Yes\") : chalk.dim(\"No\")}\\n`\n );\n process.stdout.write(\"\\r\\u001B[K\\n\");\n process.stdout.write(\"\\r\\u001B[K\\n\");\n process.stdout.write(\"\\u001B[2A\");\n resolve(value);\n } else if (key.ctrl && key.name === \"c\") {\n cleanup();\n process.stdout.write(\"\\n\");\n process.exit(130);\n }\n };\n\n process.stdin.on(\"keypress\", handleKeypress);\n });\n /* eslint-enable promise/avoid-new */\n};\n\nconst askSelect = (\n question: string,\n options: string[],\n defaultIndex = 0\n): Promise<number> => {\n const isRaw = process.stdin.isTTY;\n if (!isRaw) {\n return Promise.resolve(defaultIndex);\n }\n\n /* eslint-disable promise/avoid-new */\n return new Promise((resolve) => {\n let index = defaultIndex;\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n // Hide cursor during prompt\n process.stdout.write(\"\\u001B[?25l\");\n\n const render = (firstTime = false) => {\n if (!firstTime) {\n // Move back up to overwrite previous render\n process.stdout.write(`\\u001B[${options.length + 1}A\\r`);\n }\n\n process.stdout.write(\n `\\r\\u001B[K ${chalk.green(\"✔\")} ${chalk.bold(question)}\\n`\n );\n\n // Print options\n let i = 0;\n for (const option of options) {\n const isSelected = i === index;\n const prefix = isSelected ? chalk.cyan(\"❯ \") : \" \";\n const text = isSelected ? chalk.cyan.bold(option) : chalk.dim(option);\n process.stdout.write(`\\r\\u001B[K${prefix}${text}\\n`);\n i += 1;\n }\n };\n\n render(true);\n\n const handleKeypress = (str: string, key: KeypressKey) => {\n const cleanup = () => {\n process.stdin.removeListener(\"keypress\", handleKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.pause();\n process.stdout.write(\"\\u001B[?25h\");\n };\n\n if (key.name === \"up\" || key.name === \"k\") {\n index = (index - 1 + options.length) % options.length;\n render();\n } else if (key.name === \"down\" || key.name === \"j\") {\n index = (index + 1) % options.length;\n render();\n } else if (\n key.name === \"return\" ||\n key.name === \"enter\" ||\n str === \"\\r\" ||\n str === \"\\n\"\n ) {\n cleanup();\n // Overwrite and resolve\n process.stdout.write(`\\u001B[${options.length + 1}A\\r\\u001B[K`);\n process.stdout.write(\n ` ${chalk.green(\"✔\")} ${chalk.bold(question)} › ${chalk.cyan(options[index])}\\n`\n );\n for (const _ of options) {\n process.stdout.write(\"\\r\\u001B[K\\n\");\n }\n process.stdout.write(`\\u001B[${options.length}A`);\n resolve(index);\n } else if (key.ctrl && key.name === \"c\") {\n cleanup();\n process.stdout.write(\"\\n\");\n process.exit(130);\n }\n };\n\n process.stdin.on(\"keypress\", handleKeypress);\n });\n /* eslint-enable promise/avoid-new */\n};\n\ninterface MultiSelectOption {\n label: string;\n selected: boolean;\n}\n\nconst askMultiSelect = (\n question: string,\n options: MultiSelectOption[]\n): Promise<number[]> => {\n const isRaw = process.stdin.isTTY;\n if (!isRaw) {\n return Promise.resolve(\n options.flatMap((option, i) => (option.selected ? [i] : []))\n );\n }\n\n /* eslint-disable promise/avoid-new */\n return new Promise((resolve) => {\n let index = 0;\n const selected = options.map((option) => option.selected);\n const lineCount = options.length + 2;\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n // Hide cursor during prompt\n process.stdout.write(\"\\u001B[?25l\");\n\n const render = (firstTime = false) => {\n if (!firstTime) {\n process.stdout.write(`\\u001B[${lineCount}A\\r`);\n }\n\n process.stdout.write(\n `\\r\\u001B[K ${chalk.green(\"✔\")} ${chalk.bold(question)}\\n`\n );\n\n let i = 0;\n for (const option of options) {\n const isCursor = i === index;\n const cursor = isCursor ? chalk.cyan(\"❯ \") : \" \";\n const box = selected[i] ? chalk.cyan(\"[x]\") : chalk.dim(\"[ ]\");\n let text = chalk.dim(option.label);\n if (isCursor) {\n text = chalk.cyan.bold(option.label);\n } else if (selected[i]) {\n text = option.label;\n }\n process.stdout.write(`\\r\\u001B[K${cursor}${box} ${text}\\n`);\n i += 1;\n }\n process.stdout.write(\n `\\r\\u001B[K ${chalk.dim(\"space to toggle · enter to confirm\")}\\n`\n );\n };\n\n render(true);\n\n const handleKeypress = (str: string, key: KeypressKey) => {\n const cleanup = () => {\n process.stdin.removeListener(\"keypress\", handleKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.pause();\n process.stdout.write(\"\\u001B[?25h\");\n };\n\n if (key.name === \"up\" || key.name === \"k\") {\n index = (index - 1 + options.length) % options.length;\n render();\n } else if (key.name === \"down\" || key.name === \"j\") {\n index = (index + 1) % options.length;\n render();\n } else if (key.name === \"space\" || str === \" \") {\n selected[index] = !selected[index];\n render();\n } else if (\n key.name === \"return\" ||\n key.name === \"enter\" ||\n str === \"\\r\" ||\n str === \"\\n\"\n ) {\n cleanup();\n const chosen = options.flatMap((option, i) =>\n selected[i] ? [option.label] : []\n );\n // Overwrite the prompt with a one-line summary\n process.stdout.write(`\\u001B[${lineCount}A\\r\\u001B[K`);\n process.stdout.write(\n ` ${chalk.green(\"✔\")} ${chalk.bold(question)} › ${chosen.length > 0 ? chalk.cyan(chosen.join(\", \")) : chalk.dim(\"none\")}\\n`\n );\n for (let i = 0; i < lineCount - 1; i += 1) {\n process.stdout.write(\"\\r\\u001B[K\\n\");\n }\n process.stdout.write(`\\u001B[${lineCount - 1}A`);\n resolve(options.flatMap((_, i) => (selected[i] ? [i] : [])));\n } else if (key.ctrl && key.name === \"c\") {\n cleanup();\n process.stdout.write(\"\\n\");\n process.exit(130);\n }\n };\n\n process.stdin.on(\"keypress\", handleKeypress);\n });\n /* eslint-enable promise/avoid-new */\n};\n\nconst printAgentPrompt = (payload: string): void => {\n console.log(`\\n${chalk.dim(\"──── Agent prompt ────\")}`);\n console.log(payload);\n console.log(chalk.dim(\"──────────────────────\"));\n};\n\ninterface WizardContext {\n diagnostics: Diagnostic[];\n report: JsonReport;\n rootDir: string;\n}\n\n// getSkillAgentConfig rejects the synthetic \"universal\" id at the type level.\nconst agentDisplayName = (agent: SkillAgentType): string =>\n agent === \"universal\" ? \"Universal\" : getSkillAgentConfig(agent).displayName;\n\n// Post-scan handoff: offer to send the findings to a coding agent detected on\n// this machine (launching it with the issues as its prompt), or copy the\n// prompt for any other agent. Only reached when the scan found something.\nconst runAgentHandoff = async (context: WizardContext): Promise<void> => {\n const launchable = detectLaunchableAgents();\n const options = [\n ...launchable.map((agentId) => agentDisplayName(agentId)),\n \"Copy prompt to clipboard\",\n \"Skip\",\n ];\n const skipIndex = options.length - 1;\n const clipboardIndex = options.length - 2;\n\n const choice = await askSelect(\"What would you like to do next?\", options);\n if (choice === skipIndex) {\n return;\n }\n\n await writeDiagnosticsDirectory(\n context.diagnostics,\n context.report,\n context.rootDir\n );\n await ensureGitignoreEntry(context.rootDir);\n\n const payload = buildHandoffPayload({\n diagnostics: context.diagnostics,\n projectName: path.basename(context.rootDir),\n });\n\n if (choice === clipboardIndex) {\n const copied = await copyToClipboard(payload);\n if (copied) {\n console.log(\n `\\n ${chalk.green(\"✔\")} Prompt copied — paste it into any agent or chat.`\n );\n } else {\n printAgentPrompt(payload);\n }\n return;\n }\n\n const agentId = launchable[choice];\n const installResult = await installSkillForAgents([agentId], context.rootDir);\n if (installResult && installResult.installed.length > 0) {\n console.log(\n `\\n ${chalk.green(\"✔\")} Installed the docker-doctor skill for ${agentDisplayName(agentId)}`\n );\n }\n console.log(`\\n Handing off to ${agentDisplayName(agentId)}...\\n`);\n const launched = await launchAgent(agentId, payload);\n if (!launched) {\n console.log(\n ` ${chalk.yellow(\"⚠\")} Couldn't launch ${AGENT_BINARIES[agentId]}. Here's the prompt instead:`\n );\n printAgentPrompt(payload);\n }\n};\n\nconst runInteractiveWizard = async (context: WizardContext): Promise<void> => {\n try {\n const addGhActions = await askConfirm(\n \"Add Docker Doctor to GitHub Actions?\"\n );\n if (addGhActions) {\n const workflowDir = path.resolve(\".github/workflows\");\n await fs.mkdir(workflowDir, { recursive: true });\n const workflowPath = path.join(workflowDir, \"docker-doctor.yml\");\n const workflowYaml = `name: Docker Doctor Scan\non:\n push:\n branches: [ main, master ]\n pull_request:\n branches: [ main, master ]\njobs:\n docker-doctor:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - name: Setup Bun\n uses: oven-sh/setup-bun@v2\n - name: Install dependencies\n run: bun install\n - name: Run docker-doctor\n run: bunx docker-doctor .\n`;\n await fs.writeFile(workflowPath, workflowYaml, \"utf-8\");\n console.log(\n `\\n ${chalk.green(\"✨\")} Created ${chalk.cyan(\".github/workflows/docker-doctor.yml\")}!`\n );\n console.log(\n ` Scan every pull request to prevent new Docker issues while you fix the backlog.`\n );\n }\n\n if (context.diagnostics.length === 0) {\n return;\n }\n await runAgentHandoff(context);\n } catch {\n // Ignore prompt errors\n }\n};\n\nconst runRulesEngine = async (\n rootDir: string,\n project: { dockerfiles: string[]; composeFiles: string[] },\n rulesConfig: Record<string, RuleSeverity> | undefined,\n projectFilesList: string[],\n fileContents: Record<string, string>,\n options: { score?: boolean; json?: boolean },\n setStatus: (text: string) => void\n): Promise<Diagnostic[]> => {\n const diagnostics: Diagnostic[] = [];\n\n const isSilent = options.score || options.json;\n\n if (process.stdout.isTTY && !isSilent) {\n setStatus(`Analyzing ${project.dockerfiles.length} Dockerfile(s)...`);\n await setTimeout(100);\n }\n\n // 1. Scan Dockerfiles in parallel\n const dockerfileResults = await Promise.all(\n project.dockerfiles.map(async (df) => {\n const fullPath = path.join(rootDir, df);\n try {\n const content = await fs.readFile(fullPath, \"utf-8\");\n fileContents[df] = content;\n const instructions = parseDockerfile(content);\n return runDockerfileRules(\n instructions,\n df,\n projectFilesList,\n rulesConfig\n );\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error(`Failed to analyze Dockerfile ${df}: ${msg}`);\n return [];\n }\n })\n );\n for (const diags of dockerfileResults) {\n diagnostics.push(...diags);\n }\n\n if (process.stdout.isTTY && !isSilent) {\n setStatus(`Analyzing ${project.composeFiles.length} Compose file(s)...`);\n await setTimeout(100);\n }\n\n // 2. Scan Compose files in parallel\n const composeResults = await Promise.all(\n project.composeFiles.map(async (cf) => {\n const fullPath = path.join(rootDir, cf);\n try {\n const content = await fs.readFile(fullPath, \"utf-8\");\n fileContents[cf] = content;\n const composeObj = parseCompose(content, cf);\n return runComposeRules(composeObj, cf, rulesConfig);\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error(`Failed to analyze Compose file ${cf}: ${msg}`);\n return [];\n }\n })\n );\n for (const diags of composeResults) {\n diagnostics.push(...diags);\n }\n\n return diagnostics;\n};\n\nconst filterDiagnostics = (\n diagnostics: Diagnostic[],\n categories?: Record<string, RuleSeverity>\n): Diagnostic[] => {\n if (!categories) {\n return diagnostics;\n }\n return diagnostics.filter((d) => {\n const ruleDef = findRule(d.rule);\n if (ruleDef) {\n const catSeverity = categories[ruleDef.category];\n if (catSeverity === \"off\") {\n return false;\n }\n }\n return true;\n });\n};\n\nconst program = new Command();\n\nprogram\n .name(\"docker-doctor\")\n .description(\"Static analysis for Dockerfile and Docker Compose files\")\n .version(packageJson.version, \"-V, --version\", \"display the version number\");\n\n// Default scan command\nprogram\n .argument(\"[dir]\", \"directory to scan\", \".\")\n .option(\"-v, --verbose\", \"show verbose diagnostics description\", false)\n .option(\"-s, --score\", \"only output numeric health score\", false)\n .option(\"-j, --json\", \"output results as JSON report\", false)\n .option(\"-c, --config <path>\", \"custom config file path\")\n .action(async (dir, options) => {\n const isSilent = options.score || options.json;\n\n // Helper to safely show terminal cursor\n const restoreCursor = (): void => {\n if (process.stdout.isTTY && !isSilent) {\n process.stdout.write(\"\\u001B[?25h\");\n }\n };\n\n // Set signal handlers to restore cursor on aborts\n process.on(\"exit\", restoreCursor);\n process.once(\"SIGINT\", () => {\n restoreCursor();\n process.exit(130);\n });\n process.once(\"SIGTERM\", () => {\n restoreCursor();\n process.exit(143);\n });\n\n try {\n const rootDir = path.resolve(dir);\n const startTime = Date.now();\n\n let statusText = \"Discovering workspace...\";\n const spinnerFrames = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\n let frameIndex = 0;\n let spinnerInterval: NodeJS.Timeout | null = null;\n\n const setStatus = (text: string) => {\n statusText = text;\n };\n\n if (process.stdout.isTTY && !isSilent) {\n // Hide cursor during progress/spinner\n process.stdout.write(\"\\u001B[?25l\");\n process.stdout.write(`${chalk.cyan(spinnerFrames[0])} ${statusText}`);\n spinnerInterval = setInterval(() => {\n process.stdout.write(\n `\\r\\u001B[K${chalk.cyan(spinnerFrames[frameIndex])} ${statusText}`\n );\n frameIndex = (frameIndex + 1) % spinnerFrames.length;\n }, 80);\n }\n\n try {\n if (process.stdout.isTTY && !isSilent) {\n await setTimeout(150);\n }\n\n setStatus(\"Loading configuration...\");\n // Load config first\n const config = await loadConfig(rootDir, options.config);\n\n setStatus(\"Scanning workspace files...\");\n // Project discovery\n const project = await discoverProject(rootDir);\n\n // Collect all diagnostics\n const fileContents: Record<string, string> = {};\n\n const projectFilesList = [\n ...project.dockerfiles,\n ...project.composeFiles,\n ...(project.dockerignores || []),\n ];\n\n const diagnostics = await runRulesEngine(\n rootDir,\n project,\n config.rules,\n projectFilesList,\n fileContents,\n options,\n setStatus\n );\n\n // Filter by category config if needed\n const filteredDiagnostics = filterDiagnostics(\n diagnostics,\n config.categories\n );\n\n // Calculate score\n const { score, label } = calculateScore(filteredDiagnostics);\n\n const duration = ((Date.now() - startTime) / 1000).toFixed(1);\n const concurrency = os.cpus().length;\n\n if (spinnerInterval !== null) {\n clearInterval(spinnerInterval);\n spinnerInterval = null;\n // Clear spinner line and restore cursor\n process.stdout.write(\"\\r\\u001B[K\\u001B[?25h\");\n }\n\n if (process.stdout.isTTY && !isSilent) {\n console.log(\n `${chalk.green(\"✔\")} Scanned ${projectFilesList.length} files in ${duration}s [~${concurrency} workers]`\n );\n }\n\n if (options.score) {\n console.log(score);\n process.exitCode = score < 50 ? 1 : 0;\n return;\n } else if (options.json) {\n const report = toJsonReport(\n filteredDiagnostics,\n score,\n label,\n project\n );\n console.log(JSON.stringify(report, null, 2));\n const hasErrors = filteredDiagnostics.some(\n (d) => d.severity === \"error\"\n );\n process.exitCode = hasErrors ? 1 : 0;\n return;\n }\n await formatTerminal(\n filteredDiagnostics,\n score,\n label,\n project,\n options.verbose,\n fileContents\n );\n\n // Exit with non-zero code if there are any error severity diagnostics\n const hasErrors = filteredDiagnostics.some(\n (d) => d.severity === \"error\"\n );\n\n if (process.stdout.isTTY && process.stdin.isTTY) {\n await runInteractiveWizard({\n diagnostics: filteredDiagnostics,\n report: toJsonReport(filteredDiagnostics, score, label, project),\n rootDir,\n });\n }\n process.exitCode = hasErrors ? 1 : 0;\n } finally {\n if (spinnerInterval !== null) {\n clearInterval(spinnerInterval);\n process.stdout.write(\"\\r\\u001B[K\\u001B[?25h\");\n }\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error(`Error: ${msg}`);\n process.exit(1);\n }\n });\n\n// Curated picker entries shown alongside whatever agents are detected on this\n// machine — any other agent-install id still works via --agent.\nconst CURATED_INSTALL_AGENTS: SkillAgentType[] = [\n \"claude-code\",\n \"codex\",\n \"cursor\",\n \"opencode\",\n];\n\nconst resolveInstallAgents = async (\n requested: string[] | undefined\n): Promise<SkillAgentType[] | null> => {\n if (requested && requested.length > 0) {\n const invalid = requested.filter((agent) => !isSkillAgentType(agent));\n if (invalid.length > 0) {\n console.error(`Unknown agent id(s): ${invalid.join(\", \")}`);\n console.error(\n `Valid ids: ${getSkillAgentTypes()\n .filter((agent) => agent !== \"universal\")\n .join(\", \")}`\n );\n return null;\n }\n return requested.filter((agent) => isSkillAgentType(agent));\n }\n\n if (!(process.stdin.isTTY && process.stdout.isTTY)) {\n console.error(\n \"Non-interactive run: pass --agent <id...> (e.g. --agent claude-code cursor).\"\n );\n return null;\n }\n\n const installedAgents = await detectInstalledSkillAgents();\n const detected = installedAgents.filter((agent) => agent !== \"universal\");\n const choices = [...new Set([...detected, ...CURATED_INSTALL_AGENTS])];\n const detectedSet = new Set<SkillAgentType>(detected);\n const picked = await askMultiSelect(\n \"Which coding agents should get the docker-doctor skill?\",\n choices.map((agent) => ({\n label: agentDisplayName(agent),\n selected: detectedSet.has(agent),\n }))\n );\n return picked.map((i) => choices[i]);\n};\n\nprogram\n .command(\"install\")\n .description(\"install the Docker Doctor agent skill for your coding agents\")\n .option(\n \"-a, --agent <agents...>\",\n \"agent id(s) to install for (e.g. claude-code codex cursor)\"\n )\n .action(async (options: { agent?: string[] }) => {\n const source = getSkillSourceDirectory();\n if (!source) {\n console.error(\n \"Bundled skill not found — this looks like a broken installation.\"\n );\n process.exit(1);\n }\n\n const agents = await resolveInstallAgents(options.agent);\n if (agents === null) {\n process.exit(1);\n }\n if (agents.length === 0) {\n console.log(\"Nothing selected — skipped.\");\n return;\n }\n\n const result = await installSkillForAgents(agents, process.cwd());\n if (!result) {\n console.error(\"Failed to install the skill.\");\n process.exit(1);\n }\n for (const installed of result.installed) {\n console.log(\n ` ${chalk.green(\"✔\")} ${agentDisplayName(installed.agent)} → ${installed.path}`\n );\n }\n for (const failed of result.failed) {\n console.log(\n ` ${chalk.red(\"✖\")} ${agentDisplayName(failed.agent)}: ${failed.error}`\n );\n }\n if (result.installed.length > 0) {\n console.log(\n `\\n The agent can now run ${chalk.cyan(\"/docker-doctor\")} to scan and triage this project.`\n );\n }\n process.exitCode = result.failed.length > 0 ? 1 : 0;\n });\n\n// Rules subcommand group\nconst rules = program\n .command(\"rules\")\n .description(\"manage and list configuration rules\");\n\nrules\n .command(\"list\")\n .description(\"list all available rules\")\n .action(() => {\n console.log(\"\\nAvailable Rules:\");\n console.log(\"================\\n\");\n for (const rule of allRules) {\n console.log(`- ${rule.key} (${rule.category})`);\n console.log(` Default Severity: ${rule.defaultSeverity}`);\n console.log(` Description: ${rule.message}\\n`);\n }\n });\n\nrules\n .command(\"explain <rule>\")\n .description(\"explain a specific rule in detail\")\n .action((ruleKey) => {\n const rule = findRule(ruleKey);\n if (!rule) {\n console.error(`Rule '${ruleKey}' not found.`);\n process.exit(1);\n }\n console.log(`\\nRule: ${rule.key}`);\n console.log(`Category: ${rule.category}`);\n console.log(`Default Severity: ${rule.defaultSeverity}`);\n console.log(`Description: ${rule.message}`);\n console.log(`Help / Fix: ${rule.help}\\n`);\n });\n\nprogram.parse(process.argv);\n"],"x_google_ignoreList":[0,1,2,3],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.cjs","names":["styles","process","os","tty","path","fs","findRule","path","fs","path","fs","SKILL_MANIFEST_FILE","border","findRule","path","fs","runDockerfileRules","parseDockerfile","runComposeRules","parseCompose","findRule","Command","loadConfig","discoverProject","calculateScore","os","toJsonReport","allRules"],"sources":["../../../node_modules/.bun/chalk@6.0.0/node_modules/chalk/source/utilities.js","../../../node_modules/.bun/chalk@6.0.0/node_modules/chalk/source/vendor/ansi-styles/index.js","../../../node_modules/.bun/chalk@6.0.0/node_modules/chalk/source/vendor/supports-color/index.js","../../../node_modules/.bun/chalk@6.0.0/node_modules/chalk/source/index.js","../src/agents/clipboard.ts","../src/agents/diagnostics-dir.ts","../src/agents/handoff-payload.ts","../src/agents/is-command-available.ts","../src/agents/launchable-agents.ts","../src/agents/launch-agent.ts","../src/agents/skill-install.ts","../src/formatters/terminal.ts","../src/cli.ts"],"sourcesContent":["// Note: Each match is kept and `postfix` is inserted after it. `String#replaceAll(substring, substring + postfix)` does the same, but it has to scan the replacement for `$` patterns and it is several times slower on the no-match path that most calls take.\nexport function stringReplaceAll(string, substring, postfix) {\n\tlet index = string.indexOf(substring);\n\tif (index === -1) {\n\t\treturn string;\n\t}\n\n\tconst substringLength = substring.length;\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\treturnValue += string.slice(endIndex, index) + substring + postfix;\n\t\tendIndex = index + substringLength;\n\t\tindex = string.indexOf(substring, endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n\nexport function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\tconst isGotCR = string[index - 1] === '\\r';\n\t\treturnValue += string.slice(endIndex, (isGotCR ? index - 1 : index)) + prefix + (isGotCR ? '\\r\\n' : '\\n') + postfix;\n\t\tendIndex = index + 1;\n\t\tindex = string.indexOf('\\n', endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n","const ANSI_BACKGROUND_OFFSET = 10;\nconst ANSI_UNDERLINE_OFFSET = 20;\n\nconst wrapAnsi16 = (offset = 0) => code => `\\u{1B}[${code + offset}m`;\n\nconst wrapAnsi256 = (offset = 0) => code => `\\u{1B}[${38 + offset};5;${code}m`;\n\nconst wrapAnsi16m = (offset = 0) => (red, green, blue) => `\\u{1B}[${38 + offset};2;${red};${green};${blue}m`;\n\n// `SGR 58` has no basic 16-color form, so the basic color code is mapped to its palette index instead.\nconst wrapUnderlineAnsi = code => `\\u{1B}[58;5;${code < 90 ? code - 30 : code - 90 + 8}m`;\n\nconst styles = {\n\tmodifier: {\n\t\treset: [0, 0],\n\t\t// 21 isn't widely supported and 22 does the same thing\n\t\tbold: [1, 22],\n\t\tdim: [2, 22],\n\t\titalic: [3, 23],\n\t\tunderline: [4, 24],\n\t\t// Extended underline styles (`SGR 4:x` sub-parameters). Not in upstream `ansi-styles`.\n\t\tunderlineDouble: ['4:2', 24],\n\t\tunderlineCurly: ['4:3', 24],\n\t\tunderlineDotted: ['4:4', 24],\n\t\tunderlineDashed: ['4:5', 24],\n\t\toverline: [53, 55],\n\t\tinverse: [7, 27],\n\t\thidden: [8, 28],\n\t\tstrikethrough: [9, 29],\n\t},\n\tcolor: {\n\t\tblack: [30, 39],\n\t\tred: [31, 39],\n\t\tgreen: [32, 39],\n\t\tyellow: [33, 39],\n\t\tblue: [34, 39],\n\t\tmagenta: [35, 39],\n\t\tcyan: [36, 39],\n\t\twhite: [37, 39],\n\n\t\t// Bright color\n\t\tblackBright: [90, 39],\n\t\tgray: [90, 39], // Alias of `blackBright`\n\t\tgrey: [90, 39], // Alias of `blackBright`\n\t\tredBright: [91, 39],\n\t\tgreenBright: [92, 39],\n\t\tyellowBright: [93, 39],\n\t\tblueBright: [94, 39],\n\t\tmagentaBright: [95, 39],\n\t\tcyanBright: [96, 39],\n\t\twhiteBright: [97, 39],\n\t},\n\tbgColor: {\n\t\tbgBlack: [40, 49],\n\t\tbgRed: [41, 49],\n\t\tbgGreen: [42, 49],\n\t\tbgYellow: [43, 49],\n\t\tbgBlue: [44, 49],\n\t\tbgMagenta: [45, 49],\n\t\tbgCyan: [46, 49],\n\t\tbgWhite: [47, 49],\n\n\t\t// Bright color\n\t\tbgBlackBright: [100, 49],\n\t\tbgGray: [100, 49], // Alias of `bgBlackBright`\n\t\tbgGrey: [100, 49], // Alias of `bgBlackBright`\n\t\tbgRedBright: [101, 49],\n\t\tbgGreenBright: [102, 49],\n\t\tbgYellowBright: [103, 49],\n\t\tbgBlueBright: [104, 49],\n\t\tbgMagentaBright: [105, 49],\n\t\tbgCyanBright: [106, 49],\n\t\tbgWhiteBright: [107, 49],\n\t},\n\t// Underline color (`SGR 58`/`59`). Not in upstream `ansi-styles`.\n\tunderlineColor: {\n\t\tunderlineBlack: ['58;5;0', 59],\n\t\tunderlineRed: ['58;5;1', 59],\n\t\tunderlineGreen: ['58;5;2', 59],\n\t\tunderlineYellow: ['58;5;3', 59],\n\t\tunderlineBlue: ['58;5;4', 59],\n\t\tunderlineMagenta: ['58;5;5', 59],\n\t\tunderlineCyan: ['58;5;6', 59],\n\t\tunderlineWhite: ['58;5;7', 59],\n\n\t\t// Bright color\n\t\tunderlineBlackBright: ['58;5;8', 59],\n\t\tunderlineGray: ['58;5;8', 59], // Alias of `underlineBlackBright`\n\t\tunderlineGrey: ['58;5;8', 59], // Alias of `underlineBlackBright`\n\t\tunderlineRedBright: ['58;5;9', 59],\n\t\tunderlineGreenBright: ['58;5;10', 59],\n\t\tunderlineYellowBright: ['58;5;11', 59],\n\t\tunderlineBlueBright: ['58;5;12', 59],\n\t\tunderlineMagentaBright: ['58;5;13', 59],\n\t\tunderlineCyanBright: ['58;5;14', 59],\n\t\tunderlineWhiteBright: ['58;5;15', 59],\n\t},\n};\n\nexport const modifierNames = Object.keys(styles.modifier);\nexport const foregroundColorNames = Object.keys(styles.color);\nexport const backgroundColorNames = Object.keys(styles.bgColor);\nexport const underlineColorNames = Object.keys(styles.underlineColor);\nexport const colorNames = [...foregroundColorNames, ...backgroundColorNames];\n\nfunction assembleStyles() {\n\tconst codes = new Map();\n\n\tfor (const [groupName, group] of Object.entries(styles)) {\n\t\tfor (const [styleName, style] of Object.entries(group)) {\n\t\t\tstyles[styleName] = {\n\t\t\t\topen: `\\u{1B}[${style[0]}m`,\n\t\t\t\tclose: `\\u{1B}[${style[1]}m`,\n\t\t\t};\n\n\t\t\tgroup[styleName] = styles[styleName];\n\n\t\t\t// Only the leading SGR parameter identifies a style, so `4:3` and `58;5;1` are keyed as `4` and `58`.\n\t\t\tcodes.set(Number.parseInt(style[0], 10), style[1]);\n\t\t}\n\n\t\tObject.defineProperty(styles, groupName, {\n\t\t\tvalue: group,\n\t\t\tenumerable: false,\n\t\t});\n\t}\n\n\tObject.defineProperty(styles, 'codes', {\n\t\tvalue: codes,\n\t\tenumerable: false,\n\t});\n\n\tstyles.color.close = '\\u{1B}[39m';\n\tstyles.bgColor.close = '\\u{1B}[49m';\n\tstyles.underlineColor.close = '\\u{1B}[59m';\n\n\tstyles.color.ansi = wrapAnsi16();\n\tstyles.color.ansi256 = wrapAnsi256();\n\tstyles.color.ansi16m = wrapAnsi16m();\n\tstyles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);\n\tstyles.underlineColor.ansi = wrapUnderlineAnsi;\n\tstyles.underlineColor.ansi256 = wrapAnsi256(ANSI_UNDERLINE_OFFSET);\n\tstyles.underlineColor.ansi16m = wrapAnsi16m(ANSI_UNDERLINE_OFFSET);\n\n\t// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js\n\tObject.defineProperties(styles, {\n\t\trgbToAnsi256: {\n\t\t\tvalue(red, green, blue) {\n\t\t\t\t// We use the extended greyscale palette here, with the exception of\n\t\t\t\t// black and white. normal palette only has 4 greyscale shades.\n\t\t\t\tif (red === green && green === blue) {\n\t\t\t\t\tif (red < 8) {\n\t\t\t\t\t\treturn 16;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (red > 248) {\n\t\t\t\t\t\treturn 231;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn Math.round(((red - 8) / 247) * 24) + 232;\n\t\t\t\t}\n\n\t\t\t\treturn 16\n\t\t\t\t\t+ (36 * Math.round(red / 255 * 5))\n\t\t\t\t\t+ (6 * Math.round(green / 255 * 5))\n\t\t\t\t\t+ Math.round(blue / 255 * 5);\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToRgb: {\n\t\t\tvalue(hex) {\n\t\t\t\tconst matches = /[\\da-f]{6}|[\\da-f]{3}/i.exec(hex.toString(16));\n\t\t\t\tif (!matches) {\n\t\t\t\t\treturn [0, 0, 0];\n\t\t\t\t}\n\n\t\t\t\tlet [colorString] = matches;\n\n\t\t\t\tif (colorString.length === 3) {\n\t\t\t\t\tcolorString = [...colorString].map(character => character + character).join('');\n\t\t\t\t}\n\n\t\t\t\tconst integer = Number.parseInt(colorString, 16);\n\n\t\t\t\treturn [\n\t\t\t\t\t/* eslint-disable no-bitwise -- We need the speed */\n\t\t\t\t\t(integer >> 16) & 0xFF,\n\t\t\t\t\t(integer >> 8) & 0xFF,\n\t\t\t\t\tinteger & 0xFF,\n\t\t\t\t\t/* eslint-enable no-bitwise */\n\t\t\t\t];\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi256: {\n\t\t\tvalue: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t\tansi256ToAnsi: {\n\t\t\tvalue(code) {\n\t\t\t\tif (code < 8) {\n\t\t\t\t\treturn 30 + code;\n\t\t\t\t}\n\n\t\t\t\tif (code < 16) {\n\t\t\t\t\treturn 90 + (code - 8);\n\t\t\t\t}\n\n\t\t\t\tlet red;\n\t\t\t\tlet green;\n\t\t\t\tlet blue;\n\n\t\t\t\tif (code >= 232) {\n\t\t\t\t\tred = (((code - 232) * 10) + 8) / 255;\n\t\t\t\t\tgreen = red;\n\t\t\t\t\tblue = red;\n\t\t\t\t} else {\n\t\t\t\t\tcode -= 16;\n\n\t\t\t\t\tconst remainder = code % 36;\n\n\t\t\t\t\tred = Math.floor(code / 36) / 5;\n\t\t\t\t\tgreen = Math.floor(remainder / 6) / 5;\n\t\t\t\t\tblue = (remainder % 6) / 5;\n\t\t\t\t}\n\n\t\t\t\tconst value = Math.max(red, green, blue) * 2;\n\n\t\t\t\tif (value === 0) {\n\t\t\t\t\treturn 30;\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\t\tlet result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));\n\n\t\t\t\tif (value === 2) {\n\t\t\t\t\tresult += 60;\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\trgbToAnsi: {\n\t\t\tvalue: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi: {\n\t\t\tvalue: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t});\n\n\treturn styles;\n}\n\nconst ansiStyles = assembleStyles();\n\nexport default ansiStyles;\n","import process from 'node:process';\nimport os from 'node:os';\nimport tty from 'node:tty';\n\n// From: https://github.com/sindresorhus/has-flag/blob/main/index.js\n/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {\nfunction hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {\n\tconst prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');\n\tconst position = argv.indexOf(prefix + flag);\n\tconst terminatorPosition = argv.indexOf('--');\n\treturn position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);\n}\n\nconst {env} = process;\n\nlet flagForceColor;\nif (\n\thasFlag('no-color')\n\t|| hasFlag('no-colors')\n\t|| hasFlag('color=false')\n\t|| hasFlag('color=never')\n) {\n\tflagForceColor = 0;\n} else if (\n\thasFlag('color')\n\t|| hasFlag('colors')\n\t|| hasFlag('color=true')\n\t|| hasFlag('color=always')\n) {\n\tflagForceColor = 1;\n}\n\n// Whether `FORCE_COLOR` names a level. Shared with the exact-level check below so that the two cannot disagree on what counts as numeric.\nfunction hasNumericForceColor() {\n\treturn /^\\d+$/.test(env.FORCE_COLOR);\n}\n\nfunction envForceColor() {\n\tif (!('FORCE_COLOR' in env)) {\n\t\treturn;\n\t}\n\n\tif (env.FORCE_COLOR === 'false') {\n\t\treturn 0;\n\t}\n\n\tif (env.FORCE_COLOR === 'true' || env.FORCE_COLOR.length === 0) {\n\t\treturn 1;\n\t}\n\n\tif (!hasNumericForceColor()) {\n\t\treturn;\n\t}\n\n\treturn Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);\n}\n\nfunction translateLevel(level) {\n\tif (level === 0) {\n\t\treturn false;\n\t}\n\n\treturn {\n\t\tlevel,\n\t\thasBasic: true,\n\t\thas256: level >= 2,\n\t\thas16m: level >= 3,\n\t};\n}\n\nfunction _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {\n\tconst noFlagForceColor = envForceColor();\n\tif (noFlagForceColor !== undefined) {\n\t\tflagForceColor = noFlagForceColor;\n\t}\n\n\tconst forceColor = sniffFlags ? flagForceColor : noFlagForceColor;\n\n\tif (forceColor === 0) {\n\t\treturn 0;\n\t}\n\n\tif (sniffFlags) {\n\t\tif (hasFlag('color=16m')\n\t\t\t|| hasFlag('color=full')\n\t\t\t|| hasFlag('color=truecolor')) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (hasFlag('color=256')) {\n\t\t\treturn 2;\n\t\t}\n\t}\n\n\t// A numeric `FORCE_COLOR` requests an exact level, while `FORCE_COLOR=true` and `FORCE_COLOR=` only enable color and let the level be detected.\n\tif (forceColor !== undefined && hasNumericForceColor()) {\n\t\treturn forceColor;\n\t}\n\n\t// Check for Azure DevOps pipelines.\n\t// Has to be above the `!streamIsTTY` check.\n\tif ('TF_BUILD' in env && 'AGENT_NAME' in env) {\n\t\treturn 1;\n\t}\n\n\tif (haveStream && !streamIsTTY && forceColor === undefined) {\n\t\treturn 0;\n\t}\n\n\tconst min = forceColor || 0;\n\n\tif (env.TERM === 'dumb') {\n\t\treturn min;\n\t}\n\n\tif (process.platform === 'win32') {\n\t\t// Windows 10 build 10586 is the first Windows release that supports 256 colors.\n\t\t// Windows 10 build 14931 is the first release that supports 16m/TrueColor.\n\t\tconst osRelease = os.release().split('.');\n\t\tif (\n\t\t\tNumber(osRelease[0]) >= 10\n\t\t\t&& Number(osRelease[2]) >= 10_586\n\t\t) {\n\t\t\treturn Number(osRelease[2]) >= 14_931 ? 3 : 2;\n\t\t}\n\n\t\treturn 1;\n\t}\n\n\tif ('CI' in env) {\n\t\tif (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn min;\n\t}\n\n\tif ('TEAMCITY_VERSION' in env) {\n\t\treturn /^(?:9\\.0*[1-9]\\d*\\.|\\d{2,}\\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;\n\t}\n\n\tif (env.COLORTERM === 'truecolor') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'xterm-kitty') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'xterm-ghostty') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'wezterm') {\n\t\treturn 3;\n\t}\n\n\tif ('TERM_PROGRAM' in env) {\n\t\tconst version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.', 1)[0], 10);\n\n\t\tswitch (env.TERM_PROGRAM) {\n\t\t\tcase 'iTerm.app': {\n\t\t\t\treturn version >= 3 ? 3 : 2;\n\t\t\t}\n\n\t\t\tcase 'Apple_Terminal': {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\t// No default\n\t\t}\n\t}\n\n\tif (/-256(?:color)?$/i.test(env.TERM)) {\n\t\treturn 2;\n\t}\n\n\tif (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {\n\t\treturn 1;\n\t}\n\n\tif ('COLORTERM' in env) {\n\t\treturn 1;\n\t}\n\n\treturn min;\n}\n\nexport function createSupportsColor(stream, options = {}) {\n\tconst level = _supportsColor(stream, {\n\t\tstreamIsTTY: stream && stream.isTTY,\n\t\t...options,\n\t});\n\n\treturn translateLevel(level);\n}\n\nconst supportsColor = {\n\tstdout: createSupportsColor({isTTY: tty.isatty(1)}),\n\tstderr: createSupportsColor({isTTY: tty.isatty(2)}),\n};\n\nexport default supportsColor;\n","import {\n\tstringReplaceAll,\n\tstringEncaseCRLFWithFirstIndex,\n} from './utilities.js';\nimport ansiStyles from '#ansi-styles';\nimport supportsColor from '#supports-color';\n\nconst {stdout: stdoutColor, stderr: stderrColor} = supportsColor;\n\nconst GENERATOR = Symbol('GENERATOR');\nconst STYLER = Symbol('STYLER');\nconst IS_EMPTY = Symbol('IS_EMPTY');\nconst LEVEL = Symbol('LEVEL');\n\nconst styles = Object.create(null);\n\nconst assertValidLevel = level => {\n\tif (!Number.isSafeInteger(level) || level < 0 || level > 3) {\n\t\tthrow new Error('The `level` should be an integer from 0 to 3');\n\t}\n};\n\n// The level is stored under a symbol so the hot path can read it as a plain property, while `level` itself is an accessor that rejects values the rest of the code could not handle.\nconst levelDescriptor = {\n\tenumerable: true,\n\tget() {\n\t\treturn this[LEVEL];\n\t},\n\tset(level) {\n\t\tassertValidLevel(level);\n\t\tthis[LEVEL] = level;\n\t},\n};\n\nconst applyOptions = (object, options = {}) => {\n\tif (options.level !== undefined) {\n\t\tassertValidLevel(options.level);\n\t}\n\n\t// Detect level if not set manually. Written under the symbol rather than through `level`, as the prototype carrying that accessor is not installed until after this runs.\n\tconst colorLevel = stdoutColor ? stdoutColor.level : 0;\n\tobject[LEVEL] = options.level === undefined ? colorLevel : options.level;\n};\n\nexport class Chalk {\n\tconstructor(options) {\n\t\t// eslint-disable-next-line no-constructor-return\n\t\treturn chalkFactory(options);\n\t}\n}\n\nconst chalkFactory = options => {\n\tconst chalk = (...strings) => strings.join(' ');\n\tapplyOptions(chalk, options);\n\n\tObject.setPrototypeOf(chalk, createChalk.prototype);\n\n\treturn chalk;\n};\n\nfunction createChalk(options) {\n\treturn chalkFactory(options);\n}\n\n// eslint-disable-next-line unicorn/no-top-level-side-effects -- The prototype chain must be set up at module load.\nObject.setPrototypeOf(createChalk.prototype, Function.prototype);\n\nfor (const [styleName, style] of Object.entries(ansiStyles)) {\n\tstyles[styleName] = {\n\t\tget() {\n\t\t\tconst builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);\n\t\t\tObject.defineProperty(this, styleName, {value: builder});\n\t\t\treturn builder;\n\t\t},\n\t};\n}\n\nstyles.visible = {\n\tget() {\n\t\tconst builder = createBuilder(this, this[STYLER], true);\n\t\tObject.defineProperty(this, 'visible', {value: builder});\n\t\treturn builder;\n\t},\n};\n\n// Resolve a color model to one converter per `level`, so that a call only has to look up the converter for the current level instead of re-deciding the model and level every time.\nconst createModelConverters = (model, type) => {\n\tconst style = ansiStyles[type];\n\n\tif (model === 'rgb') {\n\t\tconst ansi = (red, green, blue) => style.ansi(ansiStyles.rgbToAnsi(red, green, blue));\n\t\tconst ansi256 = (red, green, blue) => style.ansi256(ansiStyles.rgbToAnsi256(red, green, blue));\n\t\treturn [ansi, ansi, ansi256, style.ansi16m];\n\t}\n\n\tif (model === 'hex') {\n\t\tconst ansi = hex => style.ansi(ansiStyles.hexToAnsi(hex));\n\t\tconst ansi256 = hex => style.ansi256(ansiStyles.hexToAnsi256(hex));\n\t\treturn [ansi, ansi, ansi256, hex => style.ansi16m(...ansiStyles.hexToRgb(hex))];\n\t}\n\n\t// `ansi256` is already the native form, so only the 16-color levels need converting.\n\tconst ansi = code => style.ansi(ansiStyles.ansi256ToAnsi(code));\n\treturn [ansi, ansi, style.ansi256, style.ansi256];\n};\n\nconst usedModels = ['rgb', 'hex', 'ansi256'];\n\nfor (const model of usedModels) {\n\tconst capitalizedModel = model[0].toUpperCase() + model.slice(1);\n\n\tfor (const [styleName, type] of [\n\t\t[model, 'color'],\n\t\t['bg' + capitalizedModel, 'bgColor'],\n\t\t['underline' + capitalizedModel, 'underlineColor'],\n\t]) {\n\t\tconst {close} = ansiStyles[type];\n\t\tconst converters = createModelConverters(model, type);\n\n\t\tstyles[styleName] = {\n\t\t\tget() {\n\t\t\t\t// The level is read on call rather than captured here so the function can be cached on the instance instead of being reallocated on every property access.\n\t\t\t\t// `rgb` is the widest model, so naming the three parameters avoids a rest array.\n\t\t\t\tconst styleFunction = function (first, second, third) {\n\t\t\t\t\tconst open = converters[this.level](first, second, third);\n\t\t\t\t\treturn createBuilder(this, createStyler(open, close, this[STYLER]), this[IS_EMPTY]);\n\t\t\t\t};\n\n\t\t\t\tObject.defineProperty(this, styleName, {value: styleFunction});\n\t\t\t\treturn styleFunction;\n\t\t\t},\n\t\t};\n\t}\n}\n\nconst proto = Object.defineProperties(\n\t() => {},\n\t{\n\t\t...styles,\n\t\tlevel: {\n\t\t\tenumerable: true,\n\t\t\tget() {\n\t\t\t\treturn this[GENERATOR].level;\n\t\t\t},\n\t\t\tset(level) {\n\t\t\t\tthis[GENERATOR].level = level;\n\t\t\t},\n\t\t},\n\t},\n);\n\nconst createStyler = (open, close, parent) => {\n\tlet openAll;\n\tlet closeAll;\n\tif (parent === undefined) {\n\t\topenAll = open;\n\t\tcloseAll = close;\n\t} else {\n\t\topenAll = parent.openAll + open;\n\t\tcloseAll = close + parent.closeAll;\n\t}\n\n\treturn {\n\t\topen,\n\t\tclose,\n\t\topenAll,\n\t\tcloseAll,\n\t\tparent,\n\t};\n};\n\nconst createBuilder = (self, _styler, _isEmpty) => {\n\t// Single argument is hot path, implicit coercion is faster than anything\n\tconst builder = (...arguments_) => {\n\t\tif (arguments_.length === 1) {\n\t\t\t// eslint-disable-next-line no-implicit-coercion\n\t\t\treturn applyStyle(builder, '' + arguments_[0]);\n\t\t}\n\n\t\tif (arguments_.length === 2) {\n\t\t\treturn applyStyle(builder, arguments_[0] + ' ' + arguments_[1]);\n\t\t}\n\n\t\treturn applyStyle(builder, arguments_.join(' '));\n\t};\n\n\t// We alter the prototype because we must return a function, but there is\n\t// no way to create a function with a different prototype\n\tObject.setPrototypeOf(builder, proto);\n\n\t// Point every builder at the root generator instead of its immediate parent, so reading the level costs one property load rather than walking a `level` getter per link of the chain.\n\tbuilder[GENERATOR] = self[GENERATOR] ?? self;\n\tbuilder[STYLER] = _styler;\n\tbuilder[IS_EMPTY] = _isEmpty;\n\n\treturn builder;\n};\n\nconst applyStyle = (self, string) => {\n\t// Read the level directly off the generator to skip the `level` getter dispatch on this hot path\n\tif (self[GENERATOR][LEVEL] <= 0 || !string) {\n\t\t// eslint-disable-next-line unicorn/no-computed-property-existence-check -- Reads the boolean value, not a property existence check.\n\t\treturn self[IS_EMPTY] ? '' : string;\n\t}\n\n\tlet styler = self[STYLER];\n\n\tif (styler === undefined) {\n\t\treturn string;\n\t}\n\n\tconst {openAll, closeAll} = styler;\n\tif (string.includes('\\u{1B}')) {\n\t\twhile (styler !== undefined) {\n\t\t\t// Replace any instances already present with a re-opening code\n\t\t\t// otherwise only the part of the string until said closing code\n\t\t\t// will be colored, and the rest will simply be 'plain'.\n\t\t\tstring = stringReplaceAll(string, styler.close, styler.open);\n\n\t\t\tstyler = styler.parent;\n\t\t}\n\t}\n\n\t// We can move both next actions out of loop, because remaining actions in loop won't have\n\t// any/visible effect on parts we add here. Close the styling before a linebreak and reopen\n\t// after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92\n\tconst lfIndex = string.indexOf('\\n');\n\tif (lfIndex !== -1) {\n\t\tstring = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);\n\t}\n\n\treturn openAll + string + closeAll;\n};\n\n// `level` lives on the prototype rather than on each instance, so it costs nothing to construct an instance and matches how builders already expose it. It is inherited rather than own, so it does not show up in `Object.keys()`, same as for a builder.\n// eslint-disable-next-line unicorn/no-top-level-side-effects -- The style getters must be installed at module load.\nObject.defineProperties(createChalk.prototype, {...styles, level: levelDescriptor});\n\nconst chalk = createChalk();\nexport const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0});\n\nexport {\n\tmodifierNames,\n\tforegroundColorNames,\n\tbackgroundColorNames,\n\tunderlineColorNames,\n\tcolorNames,\n\n\t// TODO: Remove these aliases in the next major version\n\tmodifierNames as modifiers,\n\tforegroundColorNames as foregroundColors,\n\tbackgroundColorNames as backgroundColors,\n\tcolorNames as colors,\n} from './vendor/ansi-styles/index.js';\n\nexport {\n\tstdoutColor as supportsColor,\n\tstderrColor as supportsColorStderr,\n};\n\nexport default chalk;\n","import { spawn } from \"node:child_process\";\n\ninterface ClipboardCommand {\n command: string;\n args: string[];\n}\n\nconst getClipboardCommands = (): ClipboardCommand[] => {\n if (process.platform === \"darwin\") {\n return [{ args: [], command: \"pbcopy\" }];\n }\n if (process.platform === \"win32\") {\n return [{ args: [], command: \"clip\" }];\n }\n return [\n { args: [], command: \"wl-copy\" },\n { args: [\"-selection\", \"clipboard\"], command: \"xclip\" },\n { args: [\"--clipboard\", \"--input\"], command: \"xsel\" },\n ];\n};\n\nconst tryCopy = ({ command, args }: ClipboardCommand, text: string) =>\n /* eslint-disable promise/avoid-new */\n new Promise<boolean>((resolve) => {\n const child = spawn(command, args, {\n stdio: [\"pipe\", \"ignore\", \"ignore\"],\n });\n child.once(\"error\", () => {\n resolve(false);\n });\n child.once(\"exit\", (code) => {\n resolve(code === 0);\n });\n child.stdin.end(text);\n });\n/* eslint-enable promise/avoid-new */\n\nconst tryCommands = async (\n commands: ClipboardCommand[],\n text: string\n): Promise<boolean> => {\n const [first, ...rest] = commands;\n if (!first) {\n return false;\n }\n if (await tryCopy(first, text)) {\n return true;\n }\n return tryCommands(rest, text);\n};\n\n// Best-effort: tries each platform clipboard tool in order (they're fallbacks,\n// so the attempts are sequential). Returns false when none worked — the\n// caller prints the payload instead.\nexport const copyToClipboard = (text: string): Promise<boolean> =>\n tryCommands(getClipboardCommands(), text);\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { Diagnostic, JsonReport } from \"@docker-doctor/core\";\n\nexport const DIAGNOSTICS_DIR_NAME = \".docker-doctor\";\n\nconst UNSAFE_FILE_CHARS = /[^a-z0-9-]+/giu;\n\nconst ruleFileName = (rule: string): string => {\n const shortKey = rule.split(\"/\").at(-1) ?? rule;\n return `${shortKey.replace(UNSAFE_FILE_CHARS, \"-\")}.txt`;\n};\n\nexport const groupDiagnosticsByRule = (\n diagnostics: Diagnostic[]\n): Map<string, Diagnostic[]> => {\n const groups = new Map<string, Diagnostic[]>();\n for (const diagnostic of diagnostics) {\n const group = groups.get(diagnostic.rule);\n if (group) {\n group.push(diagnostic);\n } else {\n groups.set(diagnostic.rule, [diagnostic]);\n }\n }\n return groups;\n};\n\n// Writes the full scan results into <root>/.docker-doctor/ — diagnostics.json\n// (the same shape as `--json`) plus one .txt per rule — so the handed-off\n// agent can read past the inline prompt. Recreated fresh on every handoff.\nexport const writeDiagnosticsDirectory = async (\n diagnostics: Diagnostic[],\n report: JsonReport,\n rootDir: string\n): Promise<void> => {\n const dir = path.join(rootDir, DIAGNOSTICS_DIR_NAME);\n await fs.rm(dir, { force: true, recursive: true });\n await fs.mkdir(dir, { recursive: true });\n\n await fs.writeFile(\n path.join(dir, \"diagnostics.json\"),\n JSON.stringify(report, null, 2),\n \"utf-8\"\n );\n\n const writes: Promise<void>[] = [];\n for (const [rule, ruleDiagnostics] of groupDiagnosticsByRule(diagnostics)) {\n const [first] = ruleDiagnostics;\n const lines = [\n `${rule} (${first.severity})`,\n first.message,\n `Fix: ${first.help}`,\n \"\",\n ...ruleDiagnostics.map(\n (d) => `${d.file}${d.line === undefined ? \"\" : `:${d.line}`}`\n ),\n \"\",\n ];\n writes.push(\n fs.writeFile(\n path.join(dir, ruleFileName(rule)),\n lines.join(\"\\n\"),\n \"utf-8\"\n )\n );\n }\n await Promise.all(writes);\n};\n\n// Keeps the scan output out of version control: appends `.docker-doctor/` to\n// the project's .gitignore when it isn't covered yet. Only creates a new\n// .gitignore when the project is actually a git repository.\nexport const ensureGitignoreEntry = async (rootDir: string): Promise<void> => {\n const gitignorePath = path.join(rootDir, \".gitignore\");\n\n let existing: string | null = null;\n try {\n existing = await fs.readFile(gitignorePath, \"utf-8\");\n } catch {\n existing = null;\n }\n\n if (existing !== null) {\n const isIgnored = existing\n .split(/\\r?\\n/u)\n .some((line) =>\n [\n DIAGNOSTICS_DIR_NAME,\n `${DIAGNOSTICS_DIR_NAME}/`,\n `/${DIAGNOSTICS_DIR_NAME}`,\n `/${DIAGNOSTICS_DIR_NAME}/`,\n ].includes(line.trim())\n );\n if (isIgnored) {\n return;\n }\n const separator = existing.endsWith(\"\\n\") || existing === \"\" ? \"\" : \"\\n\";\n await fs.writeFile(\n gitignorePath,\n `${existing}${separator}${DIAGNOSTICS_DIR_NAME}/\\n`,\n \"utf-8\"\n );\n return;\n }\n\n try {\n await fs.access(path.join(rootDir, \".git\"));\n } catch {\n return;\n }\n await fs.writeFile(gitignorePath, `${DIAGNOSTICS_DIR_NAME}/\\n`, \"utf-8\");\n};\n","import type { Diagnostic } from \"@docker-doctor/core\";\nimport { findRule } from \"@docker-doctor/core\";\n\nimport {\n DIAGNOSTICS_DIR_NAME,\n groupDiagnosticsByRule,\n} from \"./diagnostics-dir\";\n\nconst MAX_FILES_PER_RULE = 5;\n\nconst SEVERITY_RANK: Record<Diagnostic[\"severity\"], number> = {\n error: 0,\n info: 2,\n warning: 1,\n};\n\nconst SEVERITY_LABEL: Record<Diagnostic[\"severity\"], string> = {\n error: \"ERROR\",\n info: \"INFO\",\n warning: \"WARN\",\n};\n\nexport interface HandoffPayloadInput {\n diagnostics: Diagnostic[];\n projectName: string;\n}\n\n// The prompt handed to the chosen agent: every rule group inline (docker\n// projects rarely have hundreds of findings), errors first, each with its fix\n// recipe and affected files, plus a pointer to the full on-disk report.\nexport const buildHandoffPayload = (input: HandoffPayloadInput): string => {\n const groups = [\n ...groupDiagnosticsByRule(input.diagnostics).entries(),\n ].toSorted(([, a], [, b]) => {\n const rankDelta =\n SEVERITY_RANK[a[0].severity] - SEVERITY_RANK[b[0].severity];\n return rankDelta === 0 ? b.length - a.length : rankDelta;\n });\n\n const issueWord = groups.length === 1 ? \"issue\" : \"issues\";\n const lines: string[] = [\n `Fix the ${groups.length} Docker Doctor ${issueWord} in ${input.projectName}.`,\n \"\",\n ];\n\n for (const [index, [rule, ruleDiagnostics]] of groups.entries()) {\n const [first] = ruleDiagnostics;\n const category = findRule(rule)?.category ?? \"General\";\n const countBadge =\n ruleDiagnostics.length > 1 ? ` (×${ruleDiagnostics.length})` : \"\";\n lines.push(\n `${index + 1}. ${SEVERITY_LABEL[first.severity]} ${category}: ${first.message} [${rule}]${countBadge}`,\n ` Fix: ${first.help}`\n );\n const files = [...new Set(ruleDiagnostics.map((d) => d.file))];\n for (const file of files.slice(0, MAX_FILES_PER_RULE)) {\n const firstSite = ruleDiagnostics.find(\n (d) => d.file === file && d.line !== undefined\n );\n lines.push(` - ${file}${firstSite ? `:${firstSite.line}` : \"\"}`);\n }\n const remaining = files.length - MAX_FILES_PER_RULE;\n if (remaining > 0) {\n lines.push(` - +${remaining} more files`);\n }\n }\n\n lines.push(\n \"\",\n `Full report (diagnostics.json + a .txt per rule): ${DIAGNOSTICS_DIR_NAME}/`,\n \"\",\n \"Read each file and fix the root cause — don't suppress or silence the rule.\",\n \"When you're done, re-run `npx @docker-doctor/cli@latest .` and confirm the score improved and no errors remain.\"\n );\n\n return lines.join(\"\\n\");\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst WINDOWS_EXTENSIONS = [\".exe\", \".cmd\", \".bat\"];\n\nexport const isCommandAvailable = (command: string): boolean => {\n const pathValue = process.env.PATH ?? \"\";\n const extensions = process.platform === \"win32\" ? WINDOWS_EXTENSIONS : [\"\"];\n\n for (const dir of pathValue.split(path.delimiter)) {\n if (dir === \"\") {\n continue;\n }\n for (const extension of extensions) {\n try {\n fs.accessSync(path.join(dir, command + extension), fs.constants.X_OK);\n return true;\n } catch {\n // Not in this directory — keep looking.\n }\n }\n }\n return false;\n};\n","import { isCommandAvailable } from \"./is-command-available\";\n\nexport type LaunchableAgentId = \"claude-code\" | \"codex\" | \"cursor\";\n\nexport const LAUNCHABLE_AGENT_IDS: readonly LaunchableAgentId[] = [\n \"claude-code\",\n \"codex\",\n \"cursor\",\n];\n\n// CLI agents we can hand off to by launching their binary with the prompt as\n// the initial argument, inheriting this terminal — the agent takes over the\n// TTY and control returns here when it exits.\nexport const AGENT_BINARIES: Record<LaunchableAgentId, string> = {\n \"claude-code\": \"claude\",\n codex: \"codex\",\n cursor: \"cursor-agent\",\n};\n\n// Each agent's skip-approvals flag. The handoff exists so the agent can fix\n// the issues end-to-end; the user opted in by picking it from the menu.\nexport const AGENT_AUTO_FLAGS: Record<LaunchableAgentId, readonly string[]> = {\n \"claude-code\": [\"--dangerously-skip-permissions\"],\n codex: [\"--yolo\"],\n cursor: [\"--force\"],\n};\n\n// Launchable = the agent's CLI binary is on PATH. Windows is excluded: npm\n// installs .cmd shims there that `spawn` can only run through a shell, and a\n// shell mangles the multi-line prompt — those users get the clipboard path.\nexport const detectLaunchableAgents = (): LaunchableAgentId[] => {\n if (process.platform === \"win32\") {\n return [];\n }\n return LAUNCHABLE_AGENT_IDS.filter((agentId) =>\n isCommandAvailable(AGENT_BINARIES[agentId])\n );\n};\n","import { spawn } from \"node:child_process\";\n\nimport type { LaunchableAgentId } from \"./launchable-agents\";\nimport { AGENT_AUTO_FLAGS, AGENT_BINARIES } from \"./launchable-agents\";\n\n// Launches the agent's CLI with the prompt as its initial argument, handing it\n// this terminal. Resolves true when the agent process exits normally, false\n// when it could not be started (caller falls back to the clipboard path).\nexport const launchAgent = (\n agentId: LaunchableAgentId,\n prompt: string\n): Promise<boolean> =>\n /* eslint-disable promise/avoid-new */\n new Promise((resolve) => {\n const child = spawn(\n AGENT_BINARIES[agentId],\n [...AGENT_AUTO_FLAGS[agentId], prompt],\n { stdio: \"inherit\" }\n );\n child.once(\"error\", () => {\n resolve(false);\n });\n child.once(\"exit\", () => {\n resolve(true);\n });\n });\n/* eslint-enable promise/avoid-new */\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { SkillAgentType, SkillInstallResult } from \"agent-install\";\nimport { SKILL_MANIFEST_FILE, installSkillsFromSource } from \"agent-install\";\n\nconst moduleDir = import.meta.dirname;\n\n// The published package ships the skill at <package root>/skill (copied from\n// skills/docker-doctor at build time); when running from the repo the source\n// itself is the fallback. Returns null when neither exists.\nexport const getSkillSourceDirectory = (): string | null => {\n const candidates = [\n // dist/cli.mjs → package root/skill/docker-doctor\n path.resolve(moduleDir, \"../skill/docker-doctor\"),\n // src/agents/*.ts in the monorepo → repo root/skills/docker-doctor\n path.resolve(moduleDir, \"../../../../skills/docker-doctor\"),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(path.join(candidate, SKILL_MANIFEST_FILE))) {\n return candidate;\n }\n }\n return null;\n};\n\n// Copies the bundled docker-doctor skill into each agent's project-level\n// skills dir so the agent already knows the /docker-doctor triage workflow.\n// Best-effort: returns null when the bundled skill is missing or the install\n// throws — callers treat that as \"skill not installed\", never as a failure.\nexport const installSkillForAgents = async (\n agents: SkillAgentType[],\n projectRoot: string\n): Promise<SkillInstallResult | null> => {\n const source = getSkillSourceDirectory();\n if (!source) {\n return null;\n }\n try {\n return await installSkillsFromSource({\n agents,\n cwd: projectRoot,\n mode: \"copy\",\n source,\n });\n } catch {\n return null;\n }\n};\n","import { setTimeout } from \"node:timers/promises\";\n\nimport type { Diagnostic, ProjectInfo } from \"@docker-doctor/core\";\nimport { findRule } from \"@docker-doctor/core\";\nimport chalk from \"chalk\";\n\nconst printCodeFrame = (\n content: string | undefined,\n line: number | undefined,\n severityColor: (msg: string) => string\n): void => {\n if (!content || !line) {\n return;\n }\n const lines = content.split(/\\r?\\n/u);\n const start = Math.max(1, line - 1);\n const end = Math.min(lines.length, line + 1);\n\n for (let i = start; i <= end; i += 1) {\n const rawLine = lines[i - 1];\n const isTarget = i === line;\n const lineNumberStr = String(i).padStart(5, \" \");\n if (isTarget) {\n console.log(\n ` ${severityColor(\">\")} ${chalk.bold(lineNumberStr)} │ ${chalk.white(rawLine)}`\n );\n } else {\n console.log(` ${chalk.dim(lineNumberStr)} │ ${chalk.dim(rawLine)}`);\n }\n }\n console.log();\n};\n\nconst printDiscoveredFiles = (project: ProjectInfo): void => {\n console.log(`\\nDiscovered Files:`);\n console.log(\n ` Dockerfile(s): ${project.dockerfiles.length ? project.dockerfiles.map((f) => chalk.cyan(f)).join(\", \") : chalk.dim(\"None\")}`\n );\n console.log(\n ` Compose file(s): ${project.composeFiles.length ? project.composeFiles.map((f) => chalk.cyan(f)).join(\", \") : chalk.dim(\"None\")}`\n );\n};\n\nconst printDiagnostics = (\n diagnostics: Diagnostic[],\n verbose: boolean,\n fileContents: Record<string, string>,\n categoryIssueCounts: Record<string, number>\n): void => {\n if (diagnostics.length === 0) {\n console.log(\n `\\n${chalk.green.bold(\"✔ No issues found! Your Docker setup looks healthy.\")}`\n );\n return;\n }\n\n if (!verbose) {\n console.log(`\\n All ${chalk.bold(diagnostics.length)} issues\\n`);\n\n const categories = [\n \"Security\",\n \"Performance\",\n \"Best Practices\",\n \"Compose\",\n \"Image Size\",\n ];\n\n for (const cat of categories) {\n const count = categoryIssueCounts[cat];\n const issueLabel = count === 1 ? \"1 issue\" : `${count} issues`;\n console.log(` ${cat} › ${chalk.dim(issueLabel)}`);\n }\n\n console.log(\n `\\n Run ${chalk.cyan(\"docker-doctor --verbose\")} to list every error and warning`\n );\n\n // Migration-scale checks\n const ruleCounts: Record<string, number> = {};\n for (const d of diagnostics) {\n ruleCounts[d.rule] = (ruleCounts[d.rule] || 0) + 1;\n }\n const migrationRules = Object.entries(ruleCounts).filter(\n ([_, count]) => count >= 5\n );\n if (migrationRules.length > 0) {\n console.log();\n console.log(\n ` ${chalk.yellow(\"⚠ Migration-scale change: sample before you sweep\")}`\n );\n for (const [rule, count] of migrationRules) {\n console.log(` ${chalk.cyan(rule)} ×${count} across ${count} files`);\n }\n console.log(\n ` Fixing all of them at once is hard to review and prone to`\n );\n console.log(\n ` subtle mistakes across the whole repo. Fix a representative`\n );\n console.log(\n ` few first and confirm the recipe holds. Then get the code`\n );\n console.log(` owner's sign-off before changing the rest.`);\n console.log(` Scope it down one area at a time: docker-doctor <path>`);\n }\n return;\n }\n\n console.log(`\\nFound ${chalk.bold(diagnostics.length)} issue(s):`);\n\n // Group by file\n const filesGrouped: Record<string, Diagnostic[]> = {};\n for (const d of diagnostics) {\n if (!filesGrouped[d.file]) {\n filesGrouped[d.file] = [];\n }\n filesGrouped[d.file].push(d);\n }\n\n for (const [file, fileDiags] of Object.entries(filesGrouped)) {\n console.log(`\\n${chalk.underline.bold(file)}`);\n for (const d of fileDiags) {\n let sevColor = chalk.cyan;\n let prefix = \"ℹ INFO\";\n if (d.severity === \"error\") {\n sevColor = chalk.red.bold;\n prefix = \"✖ ERROR\";\n } else if (d.severity === \"warning\") {\n sevColor = chalk.yellow;\n prefix = \"⚠ WARN\";\n }\n\n const lineInfo = d.line ? `:${d.line}` : \"\";\n console.log(` ${sevColor(prefix)} [${chalk.dim(d.rule)}]${lineInfo}`);\n\n // Print Code Frame\n const content = fileContents[file];\n printCodeFrame(content, d.line, sevColor);\n\n console.log(` ${chalk.white(d.message)}`);\n console.log(` ${chalk.dim(\"Help:\")} ${d.help}`);\n console.log();\n }\n }\n};\n\nconst getWhaleMascot = (\n score: number,\n border: (text: string) => string\n): string[] => {\n let eyes = \"x x\";\n let spout = \" \";\n if (score >= 75) {\n eyes = \"◠ ◠\";\n spout = chalk.cyan(' \":\" ');\n } else if (score >= 50) {\n eyes = \"• •\";\n spout = chalk.cyan(\" . \");\n }\n\n return [\n spout,\n border(\" .---. \"),\n border(`( ${eyes} )>`),\n border(\" \\\\___/ \"),\n ];\n};\n\nconst easeOutCubic = (x: number): number => 1 - (1 - x) ** 3;\n\nconst printScoreBox = async (\n score: number,\n label: string,\n categoryIssueCounts: Record<string, number>,\n warningsCount: number,\n errorsCount: number\n): Promise<void> => {\n const { isTTY } = process.stdout;\n const shouldAnimate =\n isTTY &&\n !process.env.CI &&\n !process.env.NO_ANIMATION &&\n process.env.TERM !== \"dumb\" &&\n process.env.NODE_ENV !== \"test\";\n\n let scoreColor = chalk.red.bold;\n if (score >= 90) {\n scoreColor = chalk.green.bold;\n } else if (score >= 75) {\n scoreColor = chalk.yellow.bold;\n } else if (score >= 50) {\n scoreColor = chalk.magenta.bold;\n }\n const border = scoreColor;\n const whaleLines = getWhaleMascot(score, border);\n\n const shareUrl = `https://docker-doctor.vercel.app/share?s=${score}&w=${warningsCount}&e=${errorsCount}`;\n\n if (shouldAnimate) {\n const frameCount = 20;\n const frameDelay = 15;\n\n // Hide cursor\n process.stdout.write(\"\\u001B[?25l\");\n try {\n for (let frame = 0; frame <= frameCount; frame += 1) {\n const progress = easeOutCubic(frame / frameCount);\n const currentScore = Math.round(score * progress);\n const filledBlocks = Math.round(currentScore / 2);\n const emptyBlocks = 50 - filledBlocks;\n\n const bar =\n scoreColor(\"█\".repeat(filledBlocks)) +\n chalk.dim(\"░\".repeat(emptyBlocks));\n\n if (frame > 0) {\n // Move cursor up 4 lines and carriage return\n process.stdout.write(\"\\u001B[4A\\r\");\n } else {\n // print an extra newline first to start\n console.log();\n }\n\n process.stdout.write(\n ` ${whaleLines[0]} ${scoreColor(`${currentScore} / 100`)} ${scoreColor(label)}\\n` +\n ` ${whaleLines[1]} ${bar}\\n` +\n ` ${whaleLines[2]} ${chalk.dim(\"Docker Doctor (https://docker-doctor.vercel.app)\")}\\n` +\n ` ${whaleLines[3]}\\n`\n );\n\n if (frame < frameCount) {\n // eslint-disable-next-line no-await-in-loop\n await setTimeout(frameDelay);\n }\n }\n } finally {\n // Show cursor\n process.stdout.write(\"\\u001B[?25h\");\n }\n } else {\n // Non-TTY fall back to static print\n const filledBlocks = Math.round(score / 2);\n const emptyBlocks = 50 - filledBlocks;\n const bar =\n scoreColor(\"█\".repeat(filledBlocks)) + chalk.dim(\"░\".repeat(emptyBlocks));\n\n console.log(\n `\\n ${whaleLines[0]} ${scoreColor(`${score} / 100`)} ${scoreColor(label)}`\n );\n console.log(` ${whaleLines[1]} ${bar}`);\n console.log(\n ` ${whaleLines[2]} ${chalk.dim(\"Docker Doctor (https://docker-doctor.vercel.app)\")}`\n );\n console.log(` ${whaleLines[3]}`);\n }\n\n console.log(\n `\\n ${chalk.dim(\"────────────────────────────────────────────────────────────\")}\\n`\n );\n console.log(` Share: ${chalk.cyan(shareUrl)}`);\n console.log(` Tell others how you did on socials\\n`);\n console.log(` Docs: ${chalk.cyan(\"https://docker-doctor.vercel.app\")}`);\n console.log(` Learn more about fixing issues, setting up CI/CD, and`);\n console.log(` configuring rules with a config file\\n`);\n console.log(\n ` GitHub: ${chalk.cyan(\"https://github.com/PunGrumpy/docker-doctor\")}`\n );\n console.log(` Report issues and star the repository!`);\n};\n\nexport const formatTerminal = async (\n diagnostics: Diagnostic[],\n score: number,\n label: string,\n project: ProjectInfo,\n verbose = false,\n fileContents: Record<string, string> = {}\n): Promise<void> => {\n if (verbose) {\n console.log(`\\n${chalk.bold(\"Docker Doctor Diagnostics\")}`);\n console.log(`=================================`);\n printDiscoveredFiles(project);\n }\n\n // Calculate scores per category once\n const categoryIssueCounts: Record<string, number> = {\n \"Best Practices\": 0,\n Compose: 0,\n \"Image Size\": 0,\n Performance: 0,\n Security: 0,\n };\n\n let warningsCount = 0;\n let errorsCount = 0;\n\n for (const d of diagnostics) {\n const ruleDef = findRule(d.rule);\n const category = ruleDef?.category || \"Best Practices\";\n categoryIssueCounts[category] = (categoryIssueCounts[category] || 0) + 1;\n\n if (d.severity === \"warning\") {\n warningsCount += 1;\n } else if (d.severity === \"error\") {\n errorsCount += 1;\n }\n }\n\n printDiagnostics(diagnostics, verbose, fileContents, categoryIssueCounts);\n\n await printScoreBox(\n score,\n label,\n categoryIssueCounts,\n warningsCount,\n errorsCount\n );\n};\n","import fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport readline from \"node:readline\";\nimport { setTimeout } from \"node:timers/promises\";\n\nimport type { Diagnostic, JsonReport, RuleSeverity } from \"@docker-doctor/core\";\nimport {\n discoverProject,\n parseDockerfile,\n parseCompose,\n runDockerfileRules,\n runComposeRules,\n calculateScore,\n loadConfig,\n allRules,\n findRule,\n toJsonReport,\n} from \"@docker-doctor/core\";\nimport type { SkillAgentType } from \"agent-install\";\nimport {\n detectInstalledSkillAgents,\n getSkillAgentConfig,\n getSkillAgentTypes,\n isSkillAgentType,\n} from \"agent-install\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\n\nimport packageJson from \"../package.json\" with { type: \"json\" };\nimport { copyToClipboard } from \"./agents/clipboard\";\nimport {\n ensureGitignoreEntry,\n writeDiagnosticsDirectory,\n} from \"./agents/diagnostics-dir\";\nimport { buildHandoffPayload } from \"./agents/handoff-payload\";\nimport { launchAgent } from \"./agents/launch-agent\";\nimport {\n AGENT_BINARIES,\n detectLaunchableAgents,\n} from \"./agents/launchable-agents\";\nimport {\n getSkillSourceDirectory,\n installSkillForAgents,\n} from \"./agents/skill-install\";\nimport { formatTerminal } from \"./formatters/terminal\";\n\ninterface KeypressKey {\n name?: string;\n ctrl?: boolean;\n meta?: boolean;\n shift?: boolean;\n}\n\n// The GitHub Action is versioned independently of the CLI: this floating\n// major tag moves whenever the action itself changes, so scaffolded\n// workflows keep picking up action fixes. Bump it here when the action\n// releases a breaking major.\nconst ACTION_REF = \"PunGrumpy/docker-doctor@v1\";\n\nconst askConfirm = (question: string, defaultYes = false): Promise<boolean> => {\n const isRaw = process.stdin.isTTY;\n if (!isRaw) {\n return Promise.resolve(defaultYes);\n }\n\n /* eslint-disable promise/avoid-new */\n return new Promise((resolve) => {\n let value = defaultYes;\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n // Hide cursor during prompt\n process.stdout.write(\"\\u001B[?25l\");\n\n const render = (firstTime = false) => {\n if (!firstTime) {\n process.stdout.write(\"\\u001B[3A\\r\");\n }\n\n process.stdout.write(\n `\\r\\u001B[K ${chalk.green(\"✔\")} ${chalk.bold(question)}\\n`\n );\n\n // Print options vertically\n const yesPrefix = value ? chalk.cyan(\"❯ \") : \" \";\n const yesText = value ? chalk.cyan.bold(\"Yes\") : chalk.dim(\"Yes\");\n process.stdout.write(`\\r\\u001B[K${yesPrefix}${yesText}\\n`);\n\n const noPrefix = value ? \" \" : chalk.cyan(\"❯ \");\n const noText = value ? chalk.dim(\"No\") : chalk.cyan.bold(\"No\");\n process.stdout.write(`\\r\\u001B[K${noPrefix}${noText}\\n`);\n };\n\n render(true);\n\n const handleKeypress = (str: string, key: KeypressKey) => {\n const cleanup = () => {\n process.stdin.removeListener(\"keypress\", handleKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.pause();\n process.stdout.write(\"\\u001B[?25h\");\n };\n\n if (\n key.name === \"left\" ||\n key.name === \"right\" ||\n key.name === \"up\" ||\n key.name === \"down\" ||\n key.name === \"h\" ||\n key.name === \"l\" ||\n key.name === \"j\" ||\n key.name === \"k\"\n ) {\n value = !value;\n render();\n } else if (str === \"y\" || str === \"Y\") {\n value = true;\n render();\n } else if (str === \"n\" || str === \"N\") {\n value = false;\n render();\n } else if (\n key.name === \"return\" ||\n key.name === \"enter\" ||\n str === \"\\r\" ||\n str === \"\\n\"\n ) {\n cleanup();\n // Overwrite and resolve vertical layout cleanly\n process.stdout.write(\"\\u001B[3A\\r\\u001B[K\");\n process.stdout.write(\n ` ${chalk.green(\"✔\")} ${chalk.bold(question)} › ${value ? chalk.cyan(\"Yes\") : chalk.dim(\"No\")}\\n`\n );\n process.stdout.write(\"\\r\\u001B[K\\n\");\n process.stdout.write(\"\\r\\u001B[K\\n\");\n process.stdout.write(\"\\u001B[2A\");\n resolve(value);\n } else if (key.ctrl && key.name === \"c\") {\n cleanup();\n process.stdout.write(\"\\n\");\n process.exit(130);\n }\n };\n\n process.stdin.on(\"keypress\", handleKeypress);\n });\n /* eslint-enable promise/avoid-new */\n};\n\nconst askSelect = (\n question: string,\n options: string[],\n defaultIndex = 0\n): Promise<number> => {\n const isRaw = process.stdin.isTTY;\n if (!isRaw) {\n return Promise.resolve(defaultIndex);\n }\n\n /* eslint-disable promise/avoid-new */\n return new Promise((resolve) => {\n let index = defaultIndex;\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n // Hide cursor during prompt\n process.stdout.write(\"\\u001B[?25l\");\n\n const render = (firstTime = false) => {\n if (!firstTime) {\n // Move back up to overwrite previous render\n process.stdout.write(`\\u001B[${options.length + 1}A\\r`);\n }\n\n process.stdout.write(\n `\\r\\u001B[K ${chalk.green(\"✔\")} ${chalk.bold(question)}\\n`\n );\n\n // Print options\n let i = 0;\n for (const option of options) {\n const isSelected = i === index;\n const prefix = isSelected ? chalk.cyan(\"❯ \") : \" \";\n const text = isSelected ? chalk.cyan.bold(option) : chalk.dim(option);\n process.stdout.write(`\\r\\u001B[K${prefix}${text}\\n`);\n i += 1;\n }\n };\n\n render(true);\n\n const handleKeypress = (str: string, key: KeypressKey) => {\n const cleanup = () => {\n process.stdin.removeListener(\"keypress\", handleKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.pause();\n process.stdout.write(\"\\u001B[?25h\");\n };\n\n if (key.name === \"up\" || key.name === \"k\") {\n index = (index - 1 + options.length) % options.length;\n render();\n } else if (key.name === \"down\" || key.name === \"j\") {\n index = (index + 1) % options.length;\n render();\n } else if (\n key.name === \"return\" ||\n key.name === \"enter\" ||\n str === \"\\r\" ||\n str === \"\\n\"\n ) {\n cleanup();\n // Overwrite and resolve\n process.stdout.write(`\\u001B[${options.length + 1}A\\r\\u001B[K`);\n process.stdout.write(\n ` ${chalk.green(\"✔\")} ${chalk.bold(question)} › ${chalk.cyan(options[index])}\\n`\n );\n for (const _ of options) {\n process.stdout.write(\"\\r\\u001B[K\\n\");\n }\n process.stdout.write(`\\u001B[${options.length}A`);\n resolve(index);\n } else if (key.ctrl && key.name === \"c\") {\n cleanup();\n process.stdout.write(\"\\n\");\n process.exit(130);\n }\n };\n\n process.stdin.on(\"keypress\", handleKeypress);\n });\n /* eslint-enable promise/avoid-new */\n};\n\ninterface MultiSelectOption {\n label: string;\n selected: boolean;\n}\n\nconst askMultiSelect = (\n question: string,\n options: MultiSelectOption[]\n): Promise<number[]> => {\n const isRaw = process.stdin.isTTY;\n if (!isRaw) {\n return Promise.resolve(\n options.flatMap((option, i) => (option.selected ? [i] : []))\n );\n }\n\n /* eslint-disable promise/avoid-new */\n return new Promise((resolve) => {\n let index = 0;\n const selected = options.map((option) => option.selected);\n const lineCount = options.length + 2;\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n // Hide cursor during prompt\n process.stdout.write(\"\\u001B[?25l\");\n\n const render = (firstTime = false) => {\n if (!firstTime) {\n process.stdout.write(`\\u001B[${lineCount}A\\r`);\n }\n\n process.stdout.write(\n `\\r\\u001B[K ${chalk.green(\"✔\")} ${chalk.bold(question)}\\n`\n );\n\n let i = 0;\n for (const option of options) {\n const isCursor = i === index;\n const cursor = isCursor ? chalk.cyan(\"❯ \") : \" \";\n const box = selected[i] ? chalk.cyan(\"[x]\") : chalk.dim(\"[ ]\");\n let text = chalk.dim(option.label);\n if (isCursor) {\n text = chalk.cyan.bold(option.label);\n } else if (selected[i]) {\n text = option.label;\n }\n process.stdout.write(`\\r\\u001B[K${cursor}${box} ${text}\\n`);\n i += 1;\n }\n process.stdout.write(\n `\\r\\u001B[K ${chalk.dim(\"space to toggle · enter to confirm\")}\\n`\n );\n };\n\n render(true);\n\n const handleKeypress = (str: string, key: KeypressKey) => {\n const cleanup = () => {\n process.stdin.removeListener(\"keypress\", handleKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.pause();\n process.stdout.write(\"\\u001B[?25h\");\n };\n\n if (key.name === \"up\" || key.name === \"k\") {\n index = (index - 1 + options.length) % options.length;\n render();\n } else if (key.name === \"down\" || key.name === \"j\") {\n index = (index + 1) % options.length;\n render();\n } else if (key.name === \"space\" || str === \" \") {\n selected[index] = !selected[index];\n render();\n } else if (\n key.name === \"return\" ||\n key.name === \"enter\" ||\n str === \"\\r\" ||\n str === \"\\n\"\n ) {\n cleanup();\n const chosen = options.flatMap((option, i) =>\n selected[i] ? [option.label] : []\n );\n // Overwrite the prompt with a one-line summary\n process.stdout.write(`\\u001B[${lineCount}A\\r\\u001B[K`);\n process.stdout.write(\n ` ${chalk.green(\"✔\")} ${chalk.bold(question)} › ${chosen.length > 0 ? chalk.cyan(chosen.join(\", \")) : chalk.dim(\"none\")}\\n`\n );\n for (let i = 0; i < lineCount - 1; i += 1) {\n process.stdout.write(\"\\r\\u001B[K\\n\");\n }\n process.stdout.write(`\\u001B[${lineCount - 1}A`);\n resolve(options.flatMap((_, i) => (selected[i] ? [i] : [])));\n } else if (key.ctrl && key.name === \"c\") {\n cleanup();\n process.stdout.write(\"\\n\");\n process.exit(130);\n }\n };\n\n process.stdin.on(\"keypress\", handleKeypress);\n });\n /* eslint-enable promise/avoid-new */\n};\n\nconst printAgentPrompt = (payload: string): void => {\n console.log(`\\n${chalk.dim(\"──── Agent prompt ────\")}`);\n console.log(payload);\n console.log(chalk.dim(\"──────────────────────\"));\n};\n\ninterface WizardContext {\n diagnostics: Diagnostic[];\n report: JsonReport;\n rootDir: string;\n}\n\n// getSkillAgentConfig rejects the synthetic \"universal\" id at the type level.\nconst agentDisplayName = (agent: SkillAgentType): string =>\n agent === \"universal\" ? \"Universal\" : getSkillAgentConfig(agent).displayName;\n\n// Post-scan handoff: offer to send the findings to a coding agent detected on\n// this machine (launching it with the issues as its prompt), or copy the\n// prompt for any other agent. Only reached when the scan found something.\nconst runAgentHandoff = async (context: WizardContext): Promise<void> => {\n const launchable = detectLaunchableAgents();\n const options = [\n ...launchable.map((agentId) => agentDisplayName(agentId)),\n \"Copy prompt to clipboard\",\n \"Skip\",\n ];\n const skipIndex = options.length - 1;\n const clipboardIndex = options.length - 2;\n\n const choice = await askSelect(\"What would you like to do next?\", options);\n if (choice === skipIndex) {\n return;\n }\n\n await writeDiagnosticsDirectory(\n context.diagnostics,\n context.report,\n context.rootDir\n );\n await ensureGitignoreEntry(context.rootDir);\n\n const payload = buildHandoffPayload({\n diagnostics: context.diagnostics,\n projectName: path.basename(context.rootDir),\n });\n\n if (choice === clipboardIndex) {\n const copied = await copyToClipboard(payload);\n if (copied) {\n console.log(\n `\\n ${chalk.green(\"✔\")} Prompt copied — paste it into any agent or chat.`\n );\n } else {\n printAgentPrompt(payload);\n }\n return;\n }\n\n const agentId = launchable[choice];\n const installResult = await installSkillForAgents([agentId], context.rootDir);\n if (installResult && installResult.installed.length > 0) {\n console.log(\n `\\n ${chalk.green(\"✔\")} Installed the docker-doctor skill for ${agentDisplayName(agentId)}`\n );\n }\n console.log(`\\n Handing off to ${agentDisplayName(agentId)}...\\n`);\n const launched = await launchAgent(agentId, payload);\n if (!launched) {\n console.log(\n ` ${chalk.yellow(\"⚠\")} Couldn't launch ${AGENT_BINARIES[agentId]}. Here's the prompt instead:`\n );\n printAgentPrompt(payload);\n }\n};\n\nconst runInteractiveWizard = async (context: WizardContext): Promise<void> => {\n try {\n const addGhActions = await askConfirm(\n \"Add Docker Doctor to GitHub Actions?\"\n );\n if (addGhActions) {\n const workflowDir = path.resolve(\".github/workflows\");\n await fs.mkdir(workflowDir, { recursive: true });\n const workflowPath = path.join(workflowDir, \"docker-doctor.yml\");\n const workflowYaml = `name: Docker Doctor\non:\n pull_request:\npermissions:\n contents: read\n pull-requests: write\n issues: write\njobs:\n docker-doctor:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v5\n - uses: ${ACTION_REF}\n`;\n await fs.writeFile(workflowPath, workflowYaml, \"utf-8\");\n console.log(\n `\\n ${chalk.green(\"✨\")} Created ${chalk.cyan(\".github/workflows/docker-doctor.yml\")}!`\n );\n console.log(\n ` Every pull request gets a scan and a sticky summary comment — advisory by default.`\n );\n console.log(\n ` Inputs and gating: ${chalk.cyan(\"https://docker-doctor.vercel.app/docs/guides/github-actions\")}`\n );\n }\n\n if (context.diagnostics.length === 0) {\n return;\n }\n await runAgentHandoff(context);\n } catch {\n // Ignore prompt errors\n }\n};\n\nconst runRulesEngine = async (\n rootDir: string,\n project: { dockerfiles: string[]; composeFiles: string[] },\n rulesConfig: Record<string, RuleSeverity> | undefined,\n projectFilesList: string[],\n fileContents: Record<string, string>,\n options: { score?: boolean; json?: boolean },\n setStatus: (text: string) => void\n): Promise<Diagnostic[]> => {\n const diagnostics: Diagnostic[] = [];\n\n const isSilent = options.score || options.json;\n\n if (process.stdout.isTTY && !isSilent) {\n setStatus(`Analyzing ${project.dockerfiles.length} Dockerfile(s)...`);\n await setTimeout(100);\n }\n\n // 1. Scan Dockerfiles in parallel\n const dockerfileResults = await Promise.all(\n project.dockerfiles.map(async (df) => {\n const fullPath = path.join(rootDir, df);\n try {\n const content = await fs.readFile(fullPath, \"utf-8\");\n fileContents[df] = content;\n const instructions = parseDockerfile(content);\n return runDockerfileRules(\n instructions,\n df,\n projectFilesList,\n rulesConfig\n );\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error(`Failed to analyze Dockerfile ${df}: ${msg}`);\n return [];\n }\n })\n );\n for (const diags of dockerfileResults) {\n diagnostics.push(...diags);\n }\n\n if (process.stdout.isTTY && !isSilent) {\n setStatus(`Analyzing ${project.composeFiles.length} Compose file(s)...`);\n await setTimeout(100);\n }\n\n // 2. Scan Compose files in parallel\n const composeResults = await Promise.all(\n project.composeFiles.map(async (cf) => {\n const fullPath = path.join(rootDir, cf);\n try {\n const content = await fs.readFile(fullPath, \"utf-8\");\n fileContents[cf] = content;\n const composeObj = parseCompose(content, cf);\n return runComposeRules(composeObj, cf, rulesConfig);\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error(`Failed to analyze Compose file ${cf}: ${msg}`);\n return [];\n }\n })\n );\n for (const diags of composeResults) {\n diagnostics.push(...diags);\n }\n\n return diagnostics;\n};\n\nconst filterDiagnostics = (\n diagnostics: Diagnostic[],\n categories?: Record<string, RuleSeverity>\n): Diagnostic[] => {\n if (!categories) {\n return diagnostics;\n }\n return diagnostics.filter((d) => {\n const ruleDef = findRule(d.rule);\n if (ruleDef) {\n const catSeverity = categories[ruleDef.category];\n if (catSeverity === \"off\") {\n return false;\n }\n }\n return true;\n });\n};\n\nconst program = new Command();\n\nprogram\n .name(\"docker-doctor\")\n .description(\"Static analysis for Dockerfile and Docker Compose files\")\n .version(packageJson.version, \"-V, --version\", \"display the version number\");\n\n// Default scan command\nprogram\n .argument(\"[dir]\", \"directory to scan\", \".\")\n .option(\"-v, --verbose\", \"show verbose diagnostics description\", false)\n .option(\"-s, --score\", \"only output numeric health score\", false)\n .option(\"-j, --json\", \"output results as JSON report\", false)\n .option(\"-c, --config <path>\", \"custom config file path\")\n .action(async (dir, options) => {\n const isSilent = options.score || options.json;\n\n // Helper to safely show terminal cursor\n const restoreCursor = (): void => {\n if (process.stdout.isTTY && !isSilent) {\n process.stdout.write(\"\\u001B[?25h\");\n }\n };\n\n // Set signal handlers to restore cursor on aborts\n process.on(\"exit\", restoreCursor);\n process.once(\"SIGINT\", () => {\n restoreCursor();\n process.exit(130);\n });\n process.once(\"SIGTERM\", () => {\n restoreCursor();\n process.exit(143);\n });\n\n try {\n const rootDir = path.resolve(dir);\n const startTime = Date.now();\n\n let statusText = \"Discovering workspace...\";\n const spinnerFrames = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\n let frameIndex = 0;\n let spinnerInterval: NodeJS.Timeout | null = null;\n\n const setStatus = (text: string) => {\n statusText = text;\n };\n\n if (process.stdout.isTTY && !isSilent) {\n // Hide cursor during progress/spinner\n process.stdout.write(\"\\u001B[?25l\");\n process.stdout.write(`${chalk.cyan(spinnerFrames[0])} ${statusText}`);\n spinnerInterval = setInterval(() => {\n process.stdout.write(\n `\\r\\u001B[K${chalk.cyan(spinnerFrames[frameIndex])} ${statusText}`\n );\n frameIndex = (frameIndex + 1) % spinnerFrames.length;\n }, 80);\n }\n\n try {\n if (process.stdout.isTTY && !isSilent) {\n await setTimeout(150);\n }\n\n setStatus(\"Loading configuration...\");\n // Load config first\n const config = await loadConfig(rootDir, options.config);\n\n setStatus(\"Scanning workspace files...\");\n // Project discovery\n const project = await discoverProject(rootDir);\n\n // Collect all diagnostics\n const fileContents: Record<string, string> = {};\n\n const projectFilesList = [\n ...project.dockerfiles,\n ...project.composeFiles,\n ...(project.dockerignores || []),\n ];\n\n const diagnostics = await runRulesEngine(\n rootDir,\n project,\n config.rules,\n projectFilesList,\n fileContents,\n options,\n setStatus\n );\n\n // Filter by category config if needed\n const filteredDiagnostics = filterDiagnostics(\n diagnostics,\n config.categories\n );\n\n // Calculate score\n const { score, label } = calculateScore(filteredDiagnostics);\n\n const duration = ((Date.now() - startTime) / 1000).toFixed(1);\n const concurrency = os.cpus().length;\n\n if (spinnerInterval !== null) {\n clearInterval(spinnerInterval);\n spinnerInterval = null;\n // Clear spinner line and restore cursor\n process.stdout.write(\"\\r\\u001B[K\\u001B[?25h\");\n }\n\n if (process.stdout.isTTY && !isSilent) {\n console.log(\n `${chalk.green(\"✔\")} Scanned ${projectFilesList.length} files in ${duration}s [~${concurrency} workers]`\n );\n }\n\n if (options.score) {\n console.log(score);\n process.exitCode = score < 50 ? 1 : 0;\n return;\n } else if (options.json) {\n const report = toJsonReport(\n filteredDiagnostics,\n score,\n label,\n project\n );\n console.log(JSON.stringify(report, null, 2));\n const hasErrors = filteredDiagnostics.some(\n (d) => d.severity === \"error\"\n );\n process.exitCode = hasErrors ? 1 : 0;\n return;\n }\n await formatTerminal(\n filteredDiagnostics,\n score,\n label,\n project,\n options.verbose,\n fileContents\n );\n\n // Exit with non-zero code if there are any error severity diagnostics\n const hasErrors = filteredDiagnostics.some(\n (d) => d.severity === \"error\"\n );\n\n if (process.stdout.isTTY && process.stdin.isTTY) {\n await runInteractiveWizard({\n diagnostics: filteredDiagnostics,\n report: toJsonReport(filteredDiagnostics, score, label, project),\n rootDir,\n });\n }\n process.exitCode = hasErrors ? 1 : 0;\n } finally {\n if (spinnerInterval !== null) {\n clearInterval(spinnerInterval);\n process.stdout.write(\"\\r\\u001B[K\\u001B[?25h\");\n }\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error(`Error: ${msg}`);\n process.exit(1);\n }\n });\n\n// Curated picker entries shown alongside whatever agents are detected on this\n// machine — any other agent-install id still works via --agent.\nconst CURATED_INSTALL_AGENTS: SkillAgentType[] = [\n \"claude-code\",\n \"codex\",\n \"cursor\",\n \"opencode\",\n];\n\nconst resolveInstallAgents = async (\n requested: string[] | undefined\n): Promise<SkillAgentType[] | null> => {\n if (requested && requested.length > 0) {\n const invalid = requested.filter((agent) => !isSkillAgentType(agent));\n if (invalid.length > 0) {\n console.error(`Unknown agent id(s): ${invalid.join(\", \")}`);\n console.error(\n `Valid ids: ${getSkillAgentTypes()\n .filter((agent) => agent !== \"universal\")\n .join(\", \")}`\n );\n return null;\n }\n return requested.filter((agent) => isSkillAgentType(agent));\n }\n\n if (!(process.stdin.isTTY && process.stdout.isTTY)) {\n console.error(\n \"Non-interactive run: pass --agent <id...> (e.g. --agent claude-code cursor).\"\n );\n return null;\n }\n\n const installedAgents = await detectInstalledSkillAgents();\n const detected = installedAgents.filter((agent) => agent !== \"universal\");\n const choices = [...new Set([...detected, ...CURATED_INSTALL_AGENTS])];\n const detectedSet = new Set<SkillAgentType>(detected);\n const picked = await askMultiSelect(\n \"Which coding agents should get the docker-doctor skill?\",\n choices.map((agent) => ({\n label: agentDisplayName(agent),\n selected: detectedSet.has(agent),\n }))\n );\n return picked.map((i) => choices[i]);\n};\n\nprogram\n .command(\"install\")\n .description(\"install the Docker Doctor agent skill for your coding agents\")\n .option(\n \"-a, --agent <agents...>\",\n \"agent id(s) to install for (e.g. claude-code codex cursor)\"\n )\n .action(async (options: { agent?: string[] }) => {\n const source = getSkillSourceDirectory();\n if (!source) {\n console.error(\n \"Bundled skill not found — this looks like a broken installation.\"\n );\n process.exit(1);\n }\n\n const agents = await resolveInstallAgents(options.agent);\n if (agents === null) {\n process.exit(1);\n }\n if (agents.length === 0) {\n console.log(\"Nothing selected — skipped.\");\n return;\n }\n\n const result = await installSkillForAgents(agents, process.cwd());\n if (!result) {\n console.error(\"Failed to install the skill.\");\n process.exit(1);\n }\n for (const installed of result.installed) {\n console.log(\n ` ${chalk.green(\"✔\")} ${agentDisplayName(installed.agent)} → ${installed.path}`\n );\n }\n for (const failed of result.failed) {\n console.log(\n ` ${chalk.red(\"✖\")} ${agentDisplayName(failed.agent)}: ${failed.error}`\n );\n }\n if (result.installed.length > 0) {\n console.log(\n `\\n The agent can now run ${chalk.cyan(\"/docker-doctor\")} to scan and triage this project.`\n );\n }\n process.exitCode = result.failed.length > 0 ? 1 : 0;\n });\n\n// Rules subcommand group\nconst rules = program\n .command(\"rules\")\n .description(\"manage and list configuration rules\");\n\nrules\n .command(\"list\")\n .description(\"list all available rules\")\n .action(() => {\n console.log(\"\\nAvailable Rules:\");\n console.log(\"================\\n\");\n for (const rule of allRules) {\n console.log(`- ${rule.key} (${rule.category})`);\n console.log(` Default Severity: ${rule.defaultSeverity}`);\n console.log(` Description: ${rule.message}\\n`);\n }\n });\n\nrules\n .command(\"explain <rule>\")\n .description(\"explain a specific rule in detail\")\n .action((ruleKey) => {\n const rule = findRule(ruleKey);\n if (!rule) {\n console.error(`Rule '${ruleKey}' not found.`);\n process.exit(1);\n }\n console.log(`\\nRule: ${rule.key}`);\n console.log(`Category: ${rule.category}`);\n console.log(`Default Severity: ${rule.defaultSeverity}`);\n console.log(`Description: ${rule.message}`);\n console.log(`Help / Fix: ${rule.help}\\n`);\n });\n\nprogram.parse(process.argv);\n"],"x_google_ignoreList":[0,1,2,3],"mappings":"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"}
|
package/dist/cli.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
|
|
2
|
-
export {
|
|
2
|
+
export {}
|
package/dist/cli.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
|
|
2
|
-
export {
|
|
2
|
+
export {}
|