@uzysjung/agent-harness 26.83.0 → 26.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/sisteransi/src/index.js","../src/index.ts","../src/cli.ts","../node_modules/cac/dist/index.js","../package.json","../src/commands/install.ts","../src/cli-targets.ts","../src/types.ts","../src/design.ts","../src/installer.ts","../src/antigravity/opt-in.ts","../src/codex/agents-md.ts","../src/antigravity/transform.ts","../src/codex/skills.ts","../src/fs-ops.ts","../src/codex/opt-in.ts","../src/codex/prompts.ts","../src/codex/trust-entry.ts","../src/codex/transform.ts","../src/codex/config-toml.ts","../src/env-files.ts","../src/external-installer.ts","../src/install-log.ts","../src/manifest.ts","../src/mcp-merge.ts","../src/opencode/transform.ts","../src/opencode/agents-md.ts","../src/opencode/commands.ts","../src/opencode/opencode-json.ts","../src/project-claude-merge.ts","../src/settings-merge.ts","../src/update-mode.ts","../src/commands/install-render.ts","../src/preset-recommend.ts","../src/commands/uninstall.ts","../src/interactive.ts","../src/prompts.ts","../node_modules/fast-wrap-ansi/src/main.ts","../node_modules/fast-string-width/dist/index.js","../node_modules/fast-string-truncated-width/dist/index.js","../node_modules/fast-string-truncated-width/dist/utils.js","../node_modules/@clack/core/src/utils/cursor.ts","../node_modules/@clack/core/src/utils/settings.ts","../node_modules/@clack/core/src/utils/string.ts","../node_modules/@clack/core/src/utils/index.ts","../node_modules/@clack/core/src/prompts/prompt.ts","../node_modules/@clack/core/src/prompts/autocomplete.ts","../node_modules/@clack/core/src/prompts/confirm.ts","../node_modules/@clack/core/src/prompts/date.ts","../node_modules/@clack/core/src/prompts/group-multiselect.ts","../node_modules/@clack/core/src/prompts/multi-line.ts","../node_modules/@clack/core/src/prompts/multi-select.ts","../node_modules/@clack/core/src/prompts/password.ts","../node_modules/@clack/core/src/prompts/select.ts","../node_modules/@clack/core/src/prompts/select-key.ts","../node_modules/@clack/core/src/prompts/text.ts","../node_modules/node_modules/.pnpm/is-unicode-supported@1.3.0/node_modules/is-unicode-supported/index.js","../node_modules/@clack/prompts/src/common.ts","../node_modules/@clack/prompts/src/limit-options.ts","../node_modules/@clack/prompts/src/autocomplete.ts","../node_modules/@clack/prompts/src/box.ts","../node_modules/@clack/prompts/src/confirm.ts","../node_modules/@clack/prompts/src/date.ts","../node_modules/@clack/prompts/src/group.ts","../node_modules/@clack/prompts/src/group-multi-select.ts","../node_modules/@clack/prompts/src/log.ts","../node_modules/@clack/prompts/src/messages.ts","../node_modules/@clack/prompts/src/multi-line.ts","../node_modules/@clack/prompts/src/multi-select.ts","../node_modules/@clack/prompts/src/note.ts","../node_modules/@clack/prompts/src/password.ts","../node_modules/@clack/prompts/src/path.ts","../node_modules/@clack/prompts/src/spinner.ts","../node_modules/@clack/prompts/src/progress-bar.ts","../node_modules/@clack/prompts/src/select.ts","../node_modules/@clack/prompts/src/select-key.ts","../node_modules/@clack/prompts/src/stream.ts","../node_modules/@clack/prompts/src/task.ts","../node_modules/@clack/prompts/src/task-log.ts","../node_modules/@clack/prompts/src/text.ts","../src/router.ts","../src/wizard-steps.ts","../src/state.ts"],"sourcesContent":["'use strict';\n\nconst ESC = '\\x1B';\nconst CSI = `${ESC}[`;\nconst beep = '\\u0007';\n\nconst cursor = {\n to(x, y) {\n if (!y) return `${CSI}${x + 1}G`;\n return `${CSI}${y + 1};${x + 1}H`;\n },\n move(x, y) {\n let ret = '';\n\n if (x < 0) ret += `${CSI}${-x}D`;\n else if (x > 0) ret += `${CSI}${x}C`;\n\n if (y < 0) ret += `${CSI}${-y}A`;\n else if (y > 0) ret += `${CSI}${y}B`;\n\n return ret;\n },\n up: (count = 1) => `${CSI}${count}A`,\n down: (count = 1) => `${CSI}${count}B`,\n forward: (count = 1) => `${CSI}${count}C`,\n backward: (count = 1) => `${CSI}${count}D`,\n nextLine: (count = 1) => `${CSI}E`.repeat(count),\n prevLine: (count = 1) => `${CSI}F`.repeat(count),\n left: `${CSI}G`,\n hide: `${CSI}?25l`,\n show: `${CSI}?25h`,\n save: `${ESC}7`,\n restore: `${ESC}8`\n}\n\nconst scroll = {\n up: (count = 1) => `${CSI}S`.repeat(count),\n down: (count = 1) => `${CSI}T`.repeat(count)\n}\n\nconst erase = {\n screen: `${CSI}2J`,\n up: (count = 1) => `${CSI}1J`.repeat(count),\n down: (count = 1) => `${CSI}J`.repeat(count),\n line: `${CSI}2K`,\n lineEnd: `${CSI}K`,\n lineStart: `${CSI}1K`,\n lines(count) {\n let clear = '';\n for (let i = 0; i < count; i++)\n clear += this.line + (i < count - 1 ? cursor.up() : '');\n if (count)\n clear += cursor.left;\n return clear;\n }\n}\n\nmodule.exports = { cursor, scroll, erase, beep };\n","import { buildCli } from \"./cli.js\";\n\nconst cli = buildCli();\ncli.parse(process.argv);\n","import { cac } from \"cac\";\nimport packageJson from \"../package.json\";\nimport { type ExecuteSpecDeps, executeSpec, registerInstallCommand } from \"./commands/install.js\";\nimport { registerUninstallCommand } from \"./commands/uninstall.js\";\nimport { type InteractiveResult, runInteractive } from \"./interactive.js\";\n\n// v26.72.1 — CalVer 정합 (cli --version / package.json / git tag 단일 버전).\n// v26.82.1 — 하드코딩 → package.json derive. v26.82.0 ship 때 package.json 만 bump 되고\n// 본 상수(26.81.0)가 남아 npm 게시 패키지가 --version 을 거짓 보고 (수동 동기화 주석은\n// 못 막는다는 본 repo 3번째 증명) → 빌드 시 esbuild 가 값 인라인, 동기화 자체를 소멸.\nexport const VERSION: string = packageJson.version;\n\nexport type Cli = ReturnType<typeof cac>;\n\nexport interface DefaultActionDeps {\n log?: (msg: string) => void;\n err?: (msg: string) => void;\n exit?: (code: number) => never;\n run?: (cwd: string) => Promise<InteractiveResult>;\n /** Override the install pipeline + report renderer (used by tests). */\n execute?: (spec: NonNullable<InteractiveResult[\"spec\"]>, deps: ExecuteSpecDeps) => void;\n}\n\n/**\n * Default action — runs the interactive flow, then executes the install\n * pipeline with the captured spec. Mirrors the `install` flag-mode command's\n * post-install report.\n */\nexport async function defaultAction(deps: DefaultActionDeps = {}): Promise<void> {\n const log = deps.log ?? console.log;\n const err = deps.err ?? console.error;\n /* v8 ignore next — process.exit default. tests 는 exit 주입. */\n const exit = deps.exit ?? ((code: number) => process.exit(code) as never);\n const run = deps.run ?? ((cwd: string) => runInteractive(cwd));\n const execute = deps.execute ?? executeSpec;\n\n const result = await run(process.cwd());\n if (!result.ok) {\n if (result.message) {\n err(result.message);\n }\n // exit-code mapping: no-tty=2; cancelled/exit/disabled/declined=0\n exit(result.reason === \"no-tty\" ? 2 : 0);\n return;\n }\n if (!result.spec) {\n err(\"Internal error: interactive returned ok=true without a spec.\");\n exit(1);\n return;\n }\n // v26.63.0 — wizard 모드 표시. install header (TARGET 등) 출력 skip → Step 5 sub-section 으로 자연 흐름.\n const execDeps: import(\"./commands/install.js\").ExecuteSpecDeps = {\n log,\n err,\n exit,\n fromWizard: true,\n };\n if (result.mode) execDeps.mode = result.mode;\n execute(result.spec, execDeps);\n}\n\nexport function buildCli(): Cli {\n const cli = cac(\"agent-harness\");\n\n cli.help();\n cli.version(VERSION);\n\n registerInstallCommand(cli);\n registerUninstallCommand(cli);\n\n cli\n .command(\"\", \"Interactive installer (state detection + prompts)\")\n /* v8 ignore next — cac action callback. defaultAction 자체는 별도 tests 로 검증. */\n .action(() => defaultAction());\n\n return cli;\n}\n","//#region node_modules/.pnpm/mri@1.2.0/node_modules/mri/lib/index.mjs\nfunction toArr(any) {\n\treturn any == null ? [] : Array.isArray(any) ? any : [any];\n}\nfunction toVal(out, key, val, opts) {\n\tvar x, old = out[key], nxt = !!~opts.string.indexOf(key) ? val == null || val === true ? \"\" : String(val) : typeof val === \"boolean\" ? val : !!~opts.boolean.indexOf(key) ? val === \"false\" ? false : val === \"true\" || (out._.push((x = +val, x * 0 === 0) ? x : val), !!val) : (x = +val, x * 0 === 0) ? x : val;\n\tout[key] = old == null ? nxt : Array.isArray(old) ? old.concat(nxt) : [old, nxt];\n}\nfunction lib_default(args, opts) {\n\targs = args || [];\n\topts = opts || {};\n\tvar k, arr, arg, name, val, out = { _: [] };\n\tvar i = 0, j = 0, idx = 0, len = args.length;\n\tconst alibi = opts.alias !== void 0;\n\tconst strict = opts.unknown !== void 0;\n\tconst defaults = opts.default !== void 0;\n\topts.alias = opts.alias || {};\n\topts.string = toArr(opts.string);\n\topts.boolean = toArr(opts.boolean);\n\tif (alibi) for (k in opts.alias) {\n\t\tarr = opts.alias[k] = toArr(opts.alias[k]);\n\t\tfor (i = 0; i < arr.length; i++) (opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);\n\t}\n\tfor (i = opts.boolean.length; i-- > 0;) {\n\t\tarr = opts.alias[opts.boolean[i]] || [];\n\t\tfor (j = arr.length; j-- > 0;) opts.boolean.push(arr[j]);\n\t}\n\tfor (i = opts.string.length; i-- > 0;) {\n\t\tarr = opts.alias[opts.string[i]] || [];\n\t\tfor (j = arr.length; j-- > 0;) opts.string.push(arr[j]);\n\t}\n\tif (defaults) for (k in opts.default) {\n\t\tname = typeof opts.default[k];\n\t\tarr = opts.alias[k] = opts.alias[k] || [];\n\t\tif (opts[name] !== void 0) {\n\t\t\topts[name].push(k);\n\t\t\tfor (i = 0; i < arr.length; i++) opts[name].push(arr[i]);\n\t\t}\n\t}\n\tconst keys = strict ? Object.keys(opts.alias) : [];\n\tfor (i = 0; i < len; i++) {\n\t\targ = args[i];\n\t\tif (arg === \"--\") {\n\t\t\tout._ = out._.concat(args.slice(++i));\n\t\t\tbreak;\n\t\t}\n\t\tfor (j = 0; j < arg.length; j++) if (arg.charCodeAt(j) !== 45) break;\n\t\tif (j === 0) out._.push(arg);\n\t\telse if (arg.substring(j, j + 3) === \"no-\") {\n\t\t\tname = arg.substring(j + 3);\n\t\t\tif (strict && !~keys.indexOf(name)) return opts.unknown(arg);\n\t\t\tout[name] = false;\n\t\t} else {\n\t\t\tfor (idx = j + 1; idx < arg.length; idx++) if (arg.charCodeAt(idx) === 61) break;\n\t\t\tname = arg.substring(j, idx);\n\t\t\tval = arg.substring(++idx) || i + 1 === len || (\"\" + args[i + 1]).charCodeAt(0) === 45 || args[++i];\n\t\t\tarr = j === 2 ? [name] : name;\n\t\t\tfor (idx = 0; idx < arr.length; idx++) {\n\t\t\t\tname = arr[idx];\n\t\t\t\tif (strict && !~keys.indexOf(name)) return opts.unknown(\"-\".repeat(j) + name);\n\t\t\t\ttoVal(out, name, idx + 1 < arr.length || val, opts);\n\t\t\t}\n\t\t}\n\t}\n\tif (defaults) {\n\t\tfor (k in opts.default) if (out[k] === void 0) out[k] = opts.default[k];\n\t}\n\tif (alibi) for (k in out) {\n\t\tarr = opts.alias[k] || [];\n\t\twhile (arr.length > 0) out[arr.shift()] = out[k];\n\t}\n\treturn out;\n}\n\n//#endregion\n//#region src/utils.ts\nfunction removeBrackets(v) {\n\treturn v.replace(/[<[].+/, \"\").trim();\n}\nfunction findAllBrackets(v) {\n\tconst ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;\n\tconst SQUARE_BRACKET_RE_GLOBAL = /\\[([^\\]]+)\\]/g;\n\tconst res = [];\n\tconst parse = (match) => {\n\t\tlet variadic = false;\n\t\tlet value = match[1];\n\t\tif (value.startsWith(\"...\")) {\n\t\t\tvalue = value.slice(3);\n\t\t\tvariadic = true;\n\t\t}\n\t\treturn {\n\t\t\trequired: match[0].startsWith(\"<\"),\n\t\t\tvalue,\n\t\t\tvariadic\n\t\t};\n\t};\n\tlet angledMatch;\n\twhile (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) res.push(parse(angledMatch));\n\tlet squareMatch;\n\twhile (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) res.push(parse(squareMatch));\n\treturn res;\n}\nfunction getMriOptions(options) {\n\tconst result = {\n\t\talias: {},\n\t\tboolean: []\n\t};\n\tfor (const [index, option] of options.entries()) {\n\t\tif (option.names.length > 1) result.alias[option.names[0]] = option.names.slice(1);\n\t\tif (option.isBoolean) if (option.negated) {\n\t\t\tif (!options.some((o, i) => {\n\t\t\t\treturn i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === \"boolean\";\n\t\t\t})) result.boolean.push(option.names[0]);\n\t\t} else result.boolean.push(option.names[0]);\n\t}\n\treturn result;\n}\nfunction findLongest(arr) {\n\treturn arr.sort((a, b) => {\n\t\treturn a.length > b.length ? -1 : 1;\n\t})[0];\n}\nfunction padRight(str, length) {\n\treturn str.length >= length ? str : `${str}${\" \".repeat(length - str.length)}`;\n}\nfunction camelcase(input) {\n\treturn input.replaceAll(/([a-z])-([a-z])/g, (_, p1, p2) => {\n\t\treturn p1 + p2.toUpperCase();\n\t});\n}\nfunction setDotProp(obj, keys, val) {\n\tlet current = obj;\n\tfor (let i = 0; i < keys.length; i++) {\n\t\tconst key = keys[i];\n\t\tif (i === keys.length - 1) {\n\t\t\tcurrent[key] = val;\n\t\t\treturn;\n\t\t}\n\t\tif (current[key] == null) {\n\t\t\tconst nextKeyIsArrayIndex = +keys[i + 1] > -1;\n\t\t\tcurrent[key] = nextKeyIsArrayIndex ? [] : {};\n\t\t}\n\t\tcurrent = current[key];\n\t}\n}\nfunction setByType(obj, transforms) {\n\tfor (const key of Object.keys(transforms)) {\n\t\tconst transform = transforms[key];\n\t\tif (transform.shouldTransform) {\n\t\t\tobj[key] = [obj[key]].flat();\n\t\t\tif (typeof transform.transformFunction === \"function\") obj[key] = obj[key].map(transform.transformFunction);\n\t\t}\n\t}\n}\nfunction getFileName(input) {\n\tconst m = /([^\\\\/]+)$/.exec(input);\n\treturn m ? m[1] : \"\";\n}\nfunction camelcaseOptionName(name) {\n\treturn name.split(\".\").map((v, i) => {\n\t\treturn i === 0 ? camelcase(v) : v;\n\t}).join(\".\");\n}\nvar CACError = class extends Error {\n\tconstructor(message) {\n\t\tsuper(message);\n\t\tthis.name = \"CACError\";\n\t\tif (typeof Error.captureStackTrace !== \"function\") this.stack = new Error(message).stack;\n\t}\n};\n\n//#endregion\n//#region src/option.ts\nvar Option = class {\n\trawName;\n\tdescription;\n\t/** Option name */\n\tname;\n\t/** Option name and aliases */\n\tnames;\n\tisBoolean;\n\trequired;\n\tconfig;\n\tnegated;\n\tconstructor(rawName, description, config) {\n\t\tthis.rawName = rawName;\n\t\tthis.description = description;\n\t\tthis.config = Object.assign({}, config);\n\t\trawName = rawName.replaceAll(\".*\", \"\");\n\t\tthis.negated = false;\n\t\tthis.names = removeBrackets(rawName).split(\",\").map((v) => {\n\t\t\tlet name = v.trim().replace(/^-{1,2}/, \"\");\n\t\t\tif (name.startsWith(\"no-\")) {\n\t\t\t\tthis.negated = true;\n\t\t\t\tname = name.replace(/^no-/, \"\");\n\t\t\t}\n\t\t\treturn camelcaseOptionName(name);\n\t\t}).sort((a, b) => a.length > b.length ? 1 : -1);\n\t\tthis.name = this.names.at(-1);\n\t\tif (this.negated && this.config.default == null) this.config.default = true;\n\t\tif (rawName.includes(\"<\")) this.required = true;\n\t\telse if (rawName.includes(\"[\")) this.required = false;\n\t\telse this.isBoolean = true;\n\t}\n};\n\n//#endregion\n//#region src/runtime.ts\nlet runtimeProcessArgs;\nlet runtimeInfo;\nif (typeof process !== \"undefined\") {\n\tlet runtimeName;\n\tif (typeof Deno !== \"undefined\" && typeof Deno.version?.deno === \"string\") runtimeName = \"deno\";\n\telse if (typeof Bun !== \"undefined\" && typeof Bun.version === \"string\") runtimeName = \"bun\";\n\telse runtimeName = \"node\";\n\truntimeInfo = `${process.platform}-${process.arch} ${runtimeName}-${process.version}`;\n\truntimeProcessArgs = process.argv;\n} else if (typeof navigator === \"undefined\") runtimeInfo = `unknown`;\nelse runtimeInfo = `${navigator.platform} ${navigator.userAgent}`;\n\n//#endregion\n//#region src/command.ts\nvar Command = class {\n\trawName;\n\tdescription;\n\tconfig;\n\tcli;\n\toptions;\n\taliasNames;\n\tname;\n\targs;\n\tcommandAction;\n\tusageText;\n\tversionNumber;\n\texamples;\n\thelpCallback;\n\tglobalCommand;\n\tconstructor(rawName, description, config = {}, cli) {\n\t\tthis.rawName = rawName;\n\t\tthis.description = description;\n\t\tthis.config = config;\n\t\tthis.cli = cli;\n\t\tthis.options = [];\n\t\tthis.aliasNames = [];\n\t\tthis.name = removeBrackets(rawName);\n\t\tthis.args = findAllBrackets(rawName);\n\t\tthis.examples = [];\n\t}\n\tusage(text) {\n\t\tthis.usageText = text;\n\t\treturn this;\n\t}\n\tallowUnknownOptions() {\n\t\tthis.config.allowUnknownOptions = true;\n\t\treturn this;\n\t}\n\tignoreOptionDefaultValue() {\n\t\tthis.config.ignoreOptionDefaultValue = true;\n\t\treturn this;\n\t}\n\tversion(version, customFlags = \"-v, --version\") {\n\t\tthis.versionNumber = version;\n\t\tthis.option(customFlags, \"Display version number\");\n\t\treturn this;\n\t}\n\texample(example) {\n\t\tthis.examples.push(example);\n\t\treturn this;\n\t}\n\t/**\n\t* Add a option for this command\n\t* @param rawName Raw option name(s)\n\t* @param description Option description\n\t* @param config Option config\n\t*/\n\toption(rawName, description, config) {\n\t\tconst option = new Option(rawName, description, config);\n\t\tthis.options.push(option);\n\t\treturn this;\n\t}\n\talias(name) {\n\t\tthis.aliasNames.push(name);\n\t\treturn this;\n\t}\n\taction(callback) {\n\t\tthis.commandAction = callback;\n\t\treturn this;\n\t}\n\t/**\n\t* Check if a command name is matched by this command\n\t* @param name Command name\n\t*/\n\tisMatched(name) {\n\t\treturn this.name === name || this.aliasNames.includes(name);\n\t}\n\tget isDefaultCommand() {\n\t\treturn this.name === \"\" || this.aliasNames.includes(\"!\");\n\t}\n\tget isGlobalCommand() {\n\t\treturn this instanceof GlobalCommand;\n\t}\n\t/**\n\t* Check if an option is registered in this command\n\t* @param name Option name\n\t*/\n\thasOption(name) {\n\t\tname = name.split(\".\")[0];\n\t\treturn this.options.find((option) => {\n\t\t\treturn option.names.includes(name);\n\t\t});\n\t}\n\toutputHelp() {\n\t\tconst { name, commands } = this.cli;\n\t\tconst { versionNumber, options: globalOptions, helpCallback } = this.cli.globalCommand;\n\t\tlet sections = [{ body: `${name}${versionNumber ? `/${versionNumber}` : \"\"}` }];\n\t\tsections.push({\n\t\t\ttitle: \"Usage\",\n\t\t\tbody: ` $ ${name} ${this.usageText || this.rawName}`\n\t\t});\n\t\tif ((this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0) {\n\t\t\tconst longestCommandName = findLongest(commands.map((command) => command.rawName));\n\t\t\tsections.push({\n\t\t\t\ttitle: \"Commands\",\n\t\t\t\tbody: commands.map((command) => {\n\t\t\t\t\treturn ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;\n\t\t\t\t}).join(\"\\n\")\n\t\t\t}, {\n\t\t\t\ttitle: `For more info, run any command with the \\`--help\\` flag`,\n\t\t\t\tbody: commands.map((command) => ` $ ${name}${command.name === \"\" ? \"\" : ` ${command.name}`} --help`).join(\"\\n\")\n\t\t\t});\n\t\t}\n\t\tlet options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];\n\t\tif (!this.isGlobalCommand && !this.isDefaultCommand) options = options.filter((option) => option.name !== \"version\");\n\t\tif (options.length > 0) {\n\t\t\tconst longestOptionName = findLongest(options.map((option) => option.rawName));\n\t\t\tsections.push({\n\t\t\t\ttitle: \"Options\",\n\t\t\t\tbody: options.map((option) => {\n\t\t\t\t\treturn ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === void 0 ? \"\" : `(default: ${option.config.default})`}`;\n\t\t\t\t}).join(\"\\n\")\n\t\t\t});\n\t\t}\n\t\tif (this.examples.length > 0) sections.push({\n\t\t\ttitle: \"Examples\",\n\t\t\tbody: this.examples.map((example) => {\n\t\t\t\tif (typeof example === \"function\") return example(name);\n\t\t\t\treturn example;\n\t\t\t}).join(\"\\n\")\n\t\t});\n\t\tif (helpCallback) sections = helpCallback(sections) || sections;\n\t\tconsole.info(sections.map((section) => {\n\t\t\treturn section.title ? `${section.title}:\\n${section.body}` : section.body;\n\t\t}).join(\"\\n\\n\"));\n\t}\n\toutputVersion() {\n\t\tconst { name } = this.cli;\n\t\tconst { versionNumber } = this.cli.globalCommand;\n\t\tif (versionNumber) console.info(`${name}/${versionNumber} ${runtimeInfo}`);\n\t}\n\tcheckRequiredArgs() {\n\t\tconst minimalArgsCount = this.args.filter((arg) => arg.required).length;\n\t\tif (this.cli.args.length < minimalArgsCount) throw new CACError(`missing required args for command \\`${this.rawName}\\``);\n\t}\n\t/**\n\t* Check if the parsed options contain any unknown options\n\t*\n\t* Exit and output error when true\n\t*/\n\tcheckUnknownOptions() {\n\t\tconst { options, globalCommand } = this.cli;\n\t\tif (!this.config.allowUnknownOptions) {\n\t\t\tfor (const name of Object.keys(options)) if (name !== \"--\" && !this.hasOption(name) && !globalCommand.hasOption(name)) throw new CACError(`Unknown option \\`${name.length > 1 ? `--${name}` : `-${name}`}\\``);\n\t\t}\n\t}\n\t/**\n\t* Check if the required string-type options exist\n\t*/\n\tcheckOptionValue() {\n\t\tconst { options: parsedOptions, globalCommand } = this.cli;\n\t\tconst options = [...globalCommand.options, ...this.options];\n\t\tfor (const option of options) {\n\t\t\tconst value = parsedOptions[option.name.split(\".\")[0]];\n\t\t\tif (option.required) {\n\t\t\t\tconst hasNegated = options.some((o) => o.negated && o.names.includes(option.name));\n\t\t\t\tif (value === true || value === false && !hasNegated) throw new CACError(`option \\`${option.rawName}\\` value is missing`);\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t* Check if the number of args is more than expected\n\t*/\n\tcheckUnusedArgs() {\n\t\tconst maximumArgsCount = this.args.some((arg) => arg.variadic) ? Infinity : this.args.length;\n\t\tif (maximumArgsCount < this.cli.args.length) throw new CACError(`Unused args: ${this.cli.args.slice(maximumArgsCount).map((arg) => `\\`${arg}\\``).join(\", \")}`);\n\t}\n};\nvar GlobalCommand = class extends Command {\n\tconstructor(cli) {\n\t\tsuper(\"@@global@@\", \"\", {}, cli);\n\t}\n};\n\n//#endregion\n//#region src/cac.ts\nvar CAC = class extends EventTarget {\n\t/** The program name to display in help and version message */\n\tname;\n\tcommands;\n\tglobalCommand;\n\tmatchedCommand;\n\tmatchedCommandName;\n\t/**\n\t* Raw CLI arguments\n\t*/\n\trawArgs;\n\t/**\n\t* Parsed CLI arguments\n\t*/\n\targs;\n\t/**\n\t* Parsed CLI options, camelCased\n\t*/\n\toptions;\n\tshowHelpOnExit;\n\tshowVersionOnExit;\n\t/**\n\t* @param name The program name to display in help and version message\n\t*/\n\tconstructor(name = \"\") {\n\t\tsuper();\n\t\tthis.name = name;\n\t\tthis.commands = [];\n\t\tthis.rawArgs = [];\n\t\tthis.args = [];\n\t\tthis.options = {};\n\t\tthis.globalCommand = new GlobalCommand(this);\n\t\tthis.globalCommand.usage(\"<command> [options]\");\n\t}\n\t/**\n\t* Add a global usage text.\n\t*\n\t* This is not used by sub-commands.\n\t*/\n\tusage(text) {\n\t\tthis.globalCommand.usage(text);\n\t\treturn this;\n\t}\n\t/**\n\t* Add a sub-command\n\t*/\n\tcommand(rawName, description, config) {\n\t\tconst command = new Command(rawName, description || \"\", config, this);\n\t\tcommand.globalCommand = this.globalCommand;\n\t\tthis.commands.push(command);\n\t\treturn command;\n\t}\n\t/**\n\t* Add a global CLI option.\n\t*\n\t* Which is also applied to sub-commands.\n\t*/\n\toption(rawName, description, config) {\n\t\tthis.globalCommand.option(rawName, description, config);\n\t\treturn this;\n\t}\n\t/**\n\t* Show help message when `-h, --help` flags appear.\n\t*\n\t*/\n\thelp(callback) {\n\t\tthis.globalCommand.option(\"-h, --help\", \"Display this message\");\n\t\tthis.globalCommand.helpCallback = callback;\n\t\tthis.showHelpOnExit = true;\n\t\treturn this;\n\t}\n\t/**\n\t* Show version number when `-v, --version` flags appear.\n\t*\n\t*/\n\tversion(version, customFlags = \"-v, --version\") {\n\t\tthis.globalCommand.version(version, customFlags);\n\t\tthis.showVersionOnExit = true;\n\t\treturn this;\n\t}\n\t/**\n\t* Add a global example.\n\t*\n\t* This example added here will not be used by sub-commands.\n\t*/\n\texample(example) {\n\t\tthis.globalCommand.example(example);\n\t\treturn this;\n\t}\n\t/**\n\t* Output the corresponding help message\n\t* When a sub-command is matched, output the help message for the command\n\t* Otherwise output the global one.\n\t*\n\t*/\n\toutputHelp() {\n\t\tif (this.matchedCommand) this.matchedCommand.outputHelp();\n\t\telse this.globalCommand.outputHelp();\n\t}\n\t/**\n\t* Output the version number.\n\t*\n\t*/\n\toutputVersion() {\n\t\tthis.globalCommand.outputVersion();\n\t}\n\tsetParsedInfo({ args, options }, matchedCommand, matchedCommandName) {\n\t\tthis.args = args;\n\t\tthis.options = options;\n\t\tif (matchedCommand) this.matchedCommand = matchedCommand;\n\t\tif (matchedCommandName) this.matchedCommandName = matchedCommandName;\n\t\treturn this;\n\t}\n\tunsetMatchedCommand() {\n\t\tthis.matchedCommand = void 0;\n\t\tthis.matchedCommandName = void 0;\n\t}\n\t/**\n\t* Parse argv\n\t*/\n\tparse(argv, { run = true } = {}) {\n\t\tif (!argv) {\n\t\t\tif (!runtimeProcessArgs) throw new Error(\"No argv provided and runtime process argv is not available.\");\n\t\t\targv = runtimeProcessArgs;\n\t\t}\n\t\tthis.rawArgs = argv;\n\t\tif (!this.name) this.name = argv[1] ? getFileName(argv[1]) : \"cli\";\n\t\tlet shouldParse = true;\n\t\tfor (const command of this.commands) {\n\t\t\tconst parsed = this.mri(argv.slice(2), command);\n\t\t\tconst commandName = parsed.args[0];\n\t\t\tif (command.isMatched(commandName)) {\n\t\t\t\tshouldParse = false;\n\t\t\t\tconst parsedInfo = {\n\t\t\t\t\t...parsed,\n\t\t\t\t\targs: parsed.args.slice(1)\n\t\t\t\t};\n\t\t\t\tthis.setParsedInfo(parsedInfo, command, commandName);\n\t\t\t\tthis.dispatchEvent(new CustomEvent(`command:${commandName}`, { detail: command }));\n\t\t\t}\n\t\t}\n\t\tif (shouldParse) {\n\t\t\tfor (const command of this.commands) if (command.isDefaultCommand) {\n\t\t\t\tshouldParse = false;\n\t\t\t\tconst parsed = this.mri(argv.slice(2), command);\n\t\t\t\tthis.setParsedInfo(parsed, command);\n\t\t\t\tthis.dispatchEvent(new CustomEvent(\"command:!\", { detail: command }));\n\t\t\t}\n\t\t}\n\t\tif (shouldParse) {\n\t\t\tconst parsed = this.mri(argv.slice(2));\n\t\t\tthis.setParsedInfo(parsed);\n\t\t}\n\t\tif (this.options.help && this.showHelpOnExit) {\n\t\t\tthis.outputHelp();\n\t\t\trun = false;\n\t\t\tthis.unsetMatchedCommand();\n\t\t}\n\t\tif (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) {\n\t\t\tthis.outputVersion();\n\t\t\trun = false;\n\t\t\tthis.unsetMatchedCommand();\n\t\t}\n\t\tconst parsedArgv = {\n\t\t\targs: this.args,\n\t\t\toptions: this.options\n\t\t};\n\t\tif (run) this.runMatchedCommand();\n\t\tif (!this.matchedCommand && this.args[0]) this.dispatchEvent(new CustomEvent(\"command:*\", { detail: this.args[0] }));\n\t\treturn parsedArgv;\n\t}\n\tmri(argv, command) {\n\t\tconst cliOptions = [...this.globalCommand.options, ...command ? command.options : []];\n\t\tconst mriOptions = getMriOptions(cliOptions);\n\t\tlet argsAfterDoubleDashes = [];\n\t\tconst doubleDashesIndex = argv.indexOf(\"--\");\n\t\tif (doubleDashesIndex !== -1) {\n\t\t\targsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);\n\t\t\targv = argv.slice(0, doubleDashesIndex);\n\t\t}\n\t\tlet parsed = lib_default(argv, mriOptions);\n\t\tparsed = Object.keys(parsed).reduce((res, name) => {\n\t\t\treturn {\n\t\t\t\t...res,\n\t\t\t\t[camelcaseOptionName(name)]: parsed[name]\n\t\t\t};\n\t\t}, { _: [] });\n\t\tconst args = parsed._;\n\t\tconst options = { \"--\": argsAfterDoubleDashes };\n\t\tconst ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;\n\t\tconst transforms = Object.create(null);\n\t\tfor (const cliOption of cliOptions) {\n\t\t\tif (!ignoreDefault && cliOption.config.default !== void 0) for (const name of cliOption.names) options[name] = cliOption.config.default;\n\t\t\tif (Array.isArray(cliOption.config.type) && transforms[cliOption.name] === void 0) {\n\t\t\t\ttransforms[cliOption.name] = Object.create(null);\n\t\t\t\ttransforms[cliOption.name].shouldTransform = true;\n\t\t\t\ttransforms[cliOption.name].transformFunction = cliOption.config.type[0];\n\t\t\t}\n\t\t}\n\t\tfor (const key of Object.keys(parsed)) if (key !== \"_\") {\n\t\t\tsetDotProp(options, key.split(\".\"), parsed[key]);\n\t\t\tsetByType(options, transforms);\n\t\t}\n\t\treturn {\n\t\t\targs,\n\t\t\toptions\n\t\t};\n\t}\n\trunMatchedCommand() {\n\t\tconst { args, options, matchedCommand: command } = this;\n\t\tif (!command || !command.commandAction) return;\n\t\tcommand.checkUnknownOptions();\n\t\tcommand.checkOptionValue();\n\t\tcommand.checkRequiredArgs();\n\t\tcommand.checkUnusedArgs();\n\t\tconst actionArgs = [];\n\t\tcommand.args.forEach((arg, index) => {\n\t\t\tif (arg.variadic) actionArgs.push(args.slice(index));\n\t\t\telse actionArgs.push(args[index]);\n\t\t});\n\t\tactionArgs.push(options);\n\t\treturn command.commandAction.apply(this, actionArgs);\n\t}\n};\n\n//#endregion\n//#region src/index.ts\n/**\n* @param name The program name to display in help and version message\n*/\nconst cac = (name = \"\") => new CAC(name);\n\n//#endregion\nexport { CAC, Command, cac, cac as default };","{\n \"name\": \"@uzysjung/agent-harness\",\n \"version\": \"26.83.0\",\n \"description\": \"One-command installer & curator of vetted, Docker-verified AI-coding workflows across Claude Code, Codex, OpenCode & Antigravity\",\n \"type\": \"module\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"bin\": {\n \"agent-harness\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"templates\",\n \"scripts/prune-ecc.sh\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"gen:compat\": \"npm run build && node scripts/gen-compatibility.mjs\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"biome check src tests\",\n \"lint:fix\": \"biome check --write src tests\",\n \"format\": \"biome format --write src tests\",\n \"ci\": \"npm run typecheck && npm run lint && npm run test:coverage && npm run build\",\n \"prepare\": \"[ -d dist ] || npm run build\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.3.0\",\n \"cac\": \"^7.0.0\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.4.13\",\n \"@types/node\": \"^25.6.0\",\n \"@vitest/coverage-v8\": \"^2.1.0\",\n \"tsup\": \"^8.3.0\",\n \"typescript\": \"^5.6.0\",\n \"vitest\": \"^2.1.0\"\n },\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/uzysjung/uzys-agent-harness.git\"\n }\n}\n","/**\n * `install` subcommand — spec 검증 + 파이프라인 오케스트레이션 (v26.82.0, Phase R).\n * 화면 출력(헤더/Phase rows/산출물/Summary)은 `install-render.ts` 로 분리.\n */\n\nimport { resolve } from \"node:path\";\nimport type { Cli } from \"../cli.js\";\nimport { parseCliTargets } from \"../cli-targets.js\";\nimport { c, status, unifiedSection } from \"../design.js\";\nimport { EXTERNAL_ASSETS } from \"../external-assets.js\";\nimport { type InstallReport, runInstall as runInstallPipeline } from \"../installer.js\";\nimport {\n type CliTargets,\n type InstallScope,\n type InstallSpec,\n isInstallScope,\n isTrack,\n type Track,\n} from \"../types.js\";\nimport {\n createInstallRenderer,\n type PipelineCallbacks,\n renderCliArtifacts,\n renderFinalSummary,\n renderInstallHeader,\n renderUpdateSummary,\n} from \"./install-render.js\";\n\nexport interface InstallOptions {\n track?: string[];\n /** v0.7.0 — repeatable. cac type: [String]. v0.8.0 — legacy alias 'both'/'all' 제거됨. */\n cli?: string | string[];\n /** v26.63.0 — Phase 1 templates 의 files 라인 표시 (default: counts only). */\n verbose?: boolean;\n projectDir?: string;\n // v26.81.0 (ADR-022, BREAKING) — 자산 1:1 플래그 13종(withTauri/withGsd/withEcc/withTob/\n // withAddyAgentSkills/withUzysHarness/withSuperpowers/withWshobsonAgents/withOpenspec/\n // withBmad/withClaudeVideo/withUnderstandAnything/withAgentmemory) 완전 삭제.\n // 자산 선택 = generic `--with <id>` / `--without <id>` 만. 아래는 동작 옵션.\n withPrune?: boolean;\n withCodexSkills?: boolean;\n withCodexTrust?: boolean;\n withKarpathyHook?: boolean;\n /**\n * v0.7.0 — Codex slash 통일 (~/.codex/prompts/uzys-*.md).\n * v26.46.0 — `cli` 에 codex 포함 시 default ON (ADR-012). Opt-out 은 `--no-codex-prompts`.\n * 명시 true: 사용자 explicit (legacy --with-codex-prompts 호환).\n */\n withCodexPrompts?: boolean;\n /**\n * v26.46.0 — Codex slash 통일 opt-out (cli=codex 일 때 default ON 해제).\n * cac negation flag — `--no-codex-prompts` 명시 시 cac 가 `codexPrompts: false` 로 set.\n * v26.51.0 — bug fix: 이전엔 `noCodexPrompts` field 참조 (cac 가 만들지 않음) → 동작 안 함.\n */\n codexPrompts?: boolean;\n /**\n * v26.67.0 — Antigravity global opt-in. `~/.gemini/antigravity/skills/uzys-*` +\n * `~/.gemini/antigravity/global_workflows/uzys-*.md`. scope=global + cli=antigravity 시만 의미.\n */\n withAntigravityGlobal?: boolean;\n /**\n * v26.47.0 (Phase C full) — External Asset 직접 추가 (preset condition 무관 강제 포함).\n * cac repeatable. 예: `--with railway-skills --with impeccable`.\n * 옵션-키 flag (예: `--with-uzys-harness`) 와 별개 — External Asset id 만.\n */\n with?: string | string[];\n /**\n * v26.47.0 (Phase C full) — External Asset 직접 제외 (preset 추천에서 unchecked).\n * cac repeatable. 예: `--without netlify-cli`.\n */\n without?: string | string[];\n /**\n * v26.64.0 (ADR-020) — Installation scope. `project` (default) | `global`.\n * 명시 안 하면 wizard 의 scope prompt → 비대화형은 \"project\".\n */\n scope?: string;\n}\n\nexport interface RunInstallResult {\n ok: boolean;\n cli: CliTargets;\n /** Deprecation warnings (alias 사용 시 emit). caller가 stderr로 출력. */\n warnings: ReadonlyArray<string>;\n message: string;\n report?: InstallReport;\n}\n\n/**\n * Lift raw flag options to a typed InstallSpec.\n * Returns a Result-shaped value so callers can render errors uniformly.\n */\nexport function specFromOptions(options: InstallOptions): RunInstallResult {\n const parsed = parseCliTargets(options.cli);\n if (!parsed.ok) {\n return {\n ok: false,\n cli: [\"claude\"],\n warnings: parsed.warnings,\n message: parsed.error ?? \"Invalid --cli value\",\n };\n }\n const trackInputs = options.track ?? [];\n if (trackInputs.length === 0) {\n return {\n ok: false,\n cli: parsed.targets,\n warnings: parsed.warnings,\n // v26.56.0 (F6) — wizard 진입 안내. `install` subcommand 는 non-interactive.\n message:\n \"At least one --track is required (e.g. --track tooling)\\n Interactive wizard: run without subcommand → `agent-harness` (drop the `install` word)\",\n };\n }\n for (const t of trackInputs) {\n if (!isTrack(t)) {\n return {\n ok: false,\n cli: parsed.targets,\n warnings: parsed.warnings,\n message: `Unknown track: ${t}`,\n };\n }\n }\n return {\n ok: true,\n cli: parsed.targets,\n warnings: parsed.warnings,\n message: \"spec valid\",\n };\n}\n\nexport interface InstallActionDeps {\n log?: (msg: string) => void;\n err?: (msg: string) => void;\n exit?: (code: number) => never;\n /** Override the install pipeline (used by tests to avoid real fs side effects). */\n runPipeline?: (\n spec: InstallSpec,\n harnessRoot: string,\n mode?: import(\"../installer.js\").InstallMode,\n callbacks?: PipelineCallbacks,\n ) => InstallReport;\n /** Override the harness root resolver (defaults to a path relative to this file). */\n resolveHarnessRoot?: () => string;\n}\n\nexport function installAction(options: InstallOptions, deps: InstallActionDeps = {}): void {\n const log = deps.log ?? console.log;\n const err = deps.err ?? console.error;\n const exit = deps.exit ?? ((code: number) => process.exit(code) as never);\n const runPipeline = deps.runPipeline ?? defaultRunPipeline;\n const resolveHarnessRoot = deps.resolveHarnessRoot ?? defaultHarnessRoot;\n\n const validated = specFromOptions(options);\n // Deprecation warnings to stderr (alias 사용 시), regardless of ok/fail.\n for (const w of validated.warnings) {\n err(c.yellow(`[WARN] ${w}`));\n }\n // v26.46.0 — Codex prompts default 화. cli=codex 시 자동. --with-codex-prompts 명시는 호환 유지.\n if (validated.ok && options.withCodexPrompts === true && !validated.cli.includes(\"codex\")) {\n err(\n c.yellow(\n \"[WARN] --with-codex-prompts requires --cli codex. Skipping (no Codex prompts will be installed).\",\n ),\n );\n }\n if (validated.ok && options.codexPrompts === false && !validated.cli.includes(\"codex\")) {\n err(\n c.yellow(\"[WARN] --no-codex-prompts has no effect without --cli codex (already excluded).\"),\n );\n }\n if (!validated.ok) {\n err(status.failure(c.red(`ERROR: ${validated.message}`)));\n exit(1);\n return;\n }\n\n // v26.47.0 — Phase C full: --with/--without repeatable → userOverride.\n const forceInclude = normalizeRepeatable(options.with);\n const forceExclude = normalizeRepeatable(options.without);\n // v26.49.0 — unknown asset id validation (silent ignore 방지).\n const validIds = new Set(EXTERNAL_ASSETS.map((a) => a.id));\n for (const id of [...forceInclude, ...forceExclude]) {\n if (!validIds.has(id)) {\n err(\n c.yellow(\n `[WARN] Unknown asset id '${id}' (--with/--without). Skipping. Use one of: ${[...validIds].sort().join(\", \")}`,\n ),\n );\n }\n }\n const filteredInclude = forceInclude.filter((id) => validIds.has(id));\n const filteredExclude = forceExclude.filter((id) => validIds.has(id));\n const userOverride =\n filteredInclude.length > 0 || filteredExclude.length > 0\n ? { forceInclude: filteredInclude, forceExclude: filteredExclude }\n : undefined;\n\n const spec: InstallSpec = {\n tracks: (options.track as Track[]) ?? [],\n ...(userOverride ? { userOverride } : {}),\n // v26.81.0 (ADR-022, BREAKING) — 자산 1:1 boolean 13종 삭제. 자산 선택은 위\n // userOverride(--with <id>)로 일원화. 잔존 = 설치 동작 옵션 6종만.\n options: {\n withPrune: options.withPrune === true,\n withCodexSkills: options.withCodexSkills === true,\n withCodexTrust: options.withCodexTrust === true,\n withKarpathyHook: options.withKarpathyHook === true,\n // v26.64.0 (ADR-020, BREAKING) — ADR-012/017 supersede. cli=codex 자동 default ON 폐기.\n // withCodexPrompts 는 사용자 명시 `--with-codex-prompts` 시에만 ON.\n // `--no-codex-prompts` 는 backward-compat noop (default 가 이미 false).\n // scope=global 일 때만 ~/.codex/prompts/ 에 실 write (installer.ts 참조).\n withCodexPrompts: options.withCodexPrompts === true && options.codexPrompts !== false,\n withAntigravityGlobal: options.withAntigravityGlobal === true,\n },\n cli: validated.cli,\n projectDir: resolve(options.projectDir ?? process.cwd()),\n scope: resolveScopeOption(options.scope, err),\n };\n\n executeSpec(spec, {\n log,\n err,\n exit,\n runPipeline,\n resolveHarnessRoot,\n verbose: options.verbose === true,\n });\n}\n\nexport interface ExecuteSpecDeps {\n log?: (msg: string) => void;\n err?: (msg: string) => void;\n exit?: (code: number) => never;\n runPipeline?: (\n spec: InstallSpec,\n harnessRoot: string,\n mode?: import(\"../installer.js\").InstallMode,\n callbacks?: PipelineCallbacks,\n ) => InstallReport;\n resolveHarnessRoot?: () => string;\n /** Router action mode (forwarded to runInstall). Default \"fresh\". */\n mode?: import(\"../installer.js\").InstallMode;\n /**\n * v26.63.0 — wizard 모드 (Step 1~4 통과 후 호출) 식별. true 시:\n * - install header (TARGET / TRACKS / CLI / OPTIONS / ASSETS) 출력 skip\n * (Step 3 review + Step 4 confirm 에서 이미 표시)\n * - \"Step 5/5 — Installing\" 흐름에 자연 연결\n */\n fromWizard?: boolean;\n /**\n * v26.63.0 — verbose 출력 (Phase 1 templates 의 files 라인 표시).\n * Default false — 카운트 + use 만 표시 (cognitive load 감소).\n */\n verbose?: boolean;\n}\n\n/**\n * Run the install pipeline for a fully-validated InstallSpec and render the\n * report. Shared by the `install` flag-mode command and the default\n * (interactive) action so both have identical post-install output.\n */\nexport function executeSpec(spec: InstallSpec, deps: ExecuteSpecDeps = {}): void {\n const log = deps.log ?? console.log;\n const err = deps.err ?? console.error;\n const exit = deps.exit ?? ((code: number) => process.exit(code) as never);\n const runPipeline = deps.runPipeline ?? defaultRunPipeline;\n const resolveHarnessRoot = deps.resolveHarnessRoot ?? defaultHarnessRoot;\n\n // v26.63.0 — wizard 모드는 header (TARGET ~ ASSETS) 출력 skip — Step 3/4 에서 이미 표시.\n // non-interactive (--track ...) 모드는 기존 header 유지 — 사용자 spec 확인 cue 필요.\n if (!deps.fromWizard) {\n renderInstallHeader(log, spec, deps.mode);\n }\n\n // v26.63.0 — phaseHeader → unifiedSection. Phase 카운터 (1/2/3) 제거 — 5-step 통합 시\n // wizard step 5/5 안 sub-section 으로 자연 흐름. Update mode 도 동일.\n log(unifiedSection(deps.mode === \"update\" ? \"Update Mode\" : \"Templates\"));\n log(\"\");\n\n // Streaming progress: baseline 완료 시 즉시 Phase 1 rows 출력, external은 per-asset 스트리밍.\n const renderer = createInstallRenderer(log, spec, deps.verbose === true);\n\n let report: InstallReport;\n try {\n report = runPipeline(spec, resolveHarnessRoot(), deps.mode, renderer.callbacks);\n } catch (e: unknown) {\n const detail = e instanceof Error ? e.message : String(e);\n log(\"\");\n err(status.failure(c.red(`install failed — ${detail}`)));\n exit(1);\n return;\n }\n\n // Update mode 단축 출력 — manifest copy / external 모두 skip\n if (report.updateMode) {\n renderUpdateSummary(log, report);\n return;\n }\n\n // Phase 2 trailing newline (if header was printed)\n if (renderer.phase2HeaderPrinted()) {\n log(\"\");\n }\n\n renderCliArtifacts(log, spec, report);\n renderFinalSummary(log, spec, report, deps.fromWizard === true);\n}\n\n/**\n * v26.64.0 (ADR-020) — `--scope` flag 해석. invalid 값은 warn + \"project\" default.\n * 비대화형 (--track 명시) 진입에서만 호출. wizard 는 별도 prompt.\n */\nfunction resolveScopeOption(value: string | undefined, err: (msg: string) => void): InstallScope {\n if (value === undefined) return \"project\";\n if (isInstallScope(value)) return value;\n err(\n c.yellow(`[WARN] Unknown --scope value '${value}' (expected: project, global). Using project.`),\n );\n return \"project\";\n}\n\n/**\n * v26.47.0 — Normalize cac repeatable flag (string | string[] | undefined) → string[].\n * Trim 빈 문자열 + dedup.\n */\nfunction normalizeRepeatable(value: string | string[] | undefined): string[] {\n if (!value) return [];\n const arr = Array.isArray(value) ? value : [value];\n return [...new Set(arr.map((s) => s.trim()).filter((s) => s.length > 0))];\n}\n\n/* v8 ignore start — thin dep-inject defaults. tests 는 항상 runPipeline / resolveHarnessRoot 주입. */\nfunction defaultRunPipeline(\n spec: InstallSpec,\n harnessRoot: string,\n mode?: import(\"../installer.js\").InstallMode,\n callbacks?: PipelineCallbacks,\n): InstallReport {\n const ctx: import(\"../installer.js\").InstallContext = {\n harnessRoot,\n projectDir: spec.projectDir,\n spec,\n };\n if (mode) ctx.mode = mode;\n if (callbacks?.onProgress) ctx.onProgress = callbacks.onProgress;\n if (callbacks?.externalDeps) ctx.externalDeps = callbacks.externalDeps;\n return runInstallPipeline(ctx);\n}\n\nfunction defaultHarnessRoot(): string {\n // The bundled CLI lives at <root>/dist/index.js. import.meta.url + ../ resolves to <root>.\n return resolve(new URL(\".\", import.meta.url).pathname, \"..\");\n}\n\n/* v8 ignore stop */\n\nexport { defaultHarnessRoot };\n\nexport function registerInstallCommand(cli: Cli): void {\n cli\n .command(\"install\", \"Install harness assets into a project\")\n // === Track / CLI / Project ===\n .option(\"--track <name>\", \"[Track] Track to install (repeatable)\", { type: [String] })\n .option(\n \"--cli <target>\",\n \"[CLI] Target CLI (repeatable): claude | codex | opencode | antigravity\",\n {\n type: [String],\n default: \"claude\",\n },\n )\n .option(\"--project-dir <path>\", \"[Project] Target project directory\", {\n default: process.cwd(),\n })\n .option(\n \"--scope <scope>\",\n \"[Scope] Installation scope: project (default) | global. ADR-020 / NORTH_STAR D16\",\n { default: \"project\" },\n )\n // === Asset selection (Phase C full, v26.47.0+) ===\n .option(\n \"--with <asset-id>\",\n \"[Asset] Force-include External Asset id (regardless of preset). Repeatable. v26.47.0+\",\n )\n .option(\n \"--without <asset-id>\",\n \"[Asset] Force-exclude External Asset id (drop from preset recommendation). Repeatable. v26.47.0+\",\n )\n // === Codex global (v26.46.0+) ===\n .option(\n \"--with-codex-prompts\",\n \"[Codex] Unify Codex slash (~/.codex/prompts/uzys-*.md). v26.46.0+ default ON when --cli codex\",\n )\n .option(\n \"--no-codex-prompts\",\n \"[Codex] Disable Codex slash default ON (skip global copy even with --cli codex)\",\n )\n .option(\n \"--with-codex-skills\",\n \"[Codex] Codex global opt-in: copy uzys-* skills to ~/.codex/skills/\",\n )\n .option(\n \"--with-codex-trust\",\n \"[Codex] Codex global opt-in: register trust entry in ~/.codex/config.toml\",\n )\n // v26.81.0 (ADR-022, BREAKING) — 자산 1:1 플래그 13종 삭제. 자산 opt-in 은 전부\n // generic `--with <asset-id>` (위) — 자산 id 목록은 docs/COMPATIBILITY.md 표 참조.\n // 아래는 자산이 아닌 설치 동작 옵션만.\n .option(\n \"--with-antigravity-global\",\n \"[Behavior] Antigravity global opt-in: copy uzys-* to ~/.gemini/antigravity/{skills,global_workflows}/. Requires --cli antigravity + --scope global. (v26.67.0+)\",\n )\n .option(\n \"--with-prune\",\n \"[Behavior] Prune ECC items beyond curated 89 (use with --with ecc-plugin)\",\n )\n .option(\n \"--with-karpathy-hook\",\n \"[Behavior] karpathy-coder pre-commit hook (.claude/settings.json PreToolUse Write|Edit)\",\n )\n // === Misc ===\n .option(\"--verbose\", \"[Misc] Show installed file lists per category (default: counts only)\")\n // === Examples (v26.50.0+) ===\n .example(\"install --track tooling --with uzys-harness\")\n .example(\"install --track csr-supabase --cli claude --cli codex\")\n .example(\"install --track csr-supabase --without netlify-cli --with railway-skills\")\n .example(\"install --track full --no-codex-prompts\")\n /* v8 ignore next — cac action callback. installAction 자체는 별도 tests 로 검증. */\n .action((options: InstallOptions) => installAction(options));\n}\n","/**\n * CLI targets parser — v0.7.0 multi-select.\n *\n * SPEC: docs/specs/cli-multi-select.md F2 (parseCliTargets).\n *\n * Input shapes:\n * - undefined / null / \"\" / [] → [\"claude\"] (default)\n * - \"claude\" / \"codex\" / \"opencode\" / \"antigravity\" → single-element array\n * - [\"claude\", \"codex\"] (cac repeatable) → sorted array\n * - \"both\" / \"all\" (v0.8.0 제거된 legacy alias) → ok=false + 마이그레이션 안내 (throw 아님)\n * - \"invalid\" → ok=false + error (throw 아님)\n *\n * Output:\n * - ok: 유효하면 true, reject 시 false (+ error 메시지, targets=[\"claude\"] default)\n * - targets: sorted ReadonlyArray<CliBase> (claude → codex → opencode → antigravity 순)\n * - warnings: 메시지 배열 (현재 reject-only 정책이라 비어 있음)\n */\n\nimport { CLI_BASES, type CliBase, type CliTargets, isCliBase } from \"./types.js\";\n\n/** SSOT — claude → codex → opencode → antigravity 정렬 순서. prompts.ts에서 import. */\nexport const CLI_BASE_SORT_ORDER: Record<CliBase, number> = {\n claude: 0,\n codex: 1,\n opencode: 2,\n antigravity: 3,\n};\n\nexport interface ParseCliTargetsResult {\n ok: boolean;\n targets: CliTargets;\n warnings: ReadonlyArray<string>;\n /** ok=false 시 reject 사유. */\n error?: string;\n}\n\n/**\n * `--cli` 입력을 sorted CliTargets로 정규화.\n *\n * Default `[\"claude\"]` (비어있거나 undefined일 때).\n * Invalid 모드는 reject (ok=false).\n *\n * v0.8.0 — `both`/`all` legacy alias 제거 (v0.7.0에서 1 release deprecation 거침).\n * `both`/`all` 입력 시 invalid reject + 마이그레이션 안내.\n */\nexport function parseCliTargets(input: string | string[] | undefined): ParseCliTargetsResult {\n const items = normalizeInput(input);\n if (items.length === 0) {\n return { ok: true, targets: [\"claude\"], warnings: [] };\n }\n\n const collected = new Set<CliBase>();\n const warnings: string[] = [];\n\n for (const item of items) {\n if (!isCliBase(item)) {\n // v0.8.0 — alias 제거 마이그레이션 힌트\n let hint = \"\";\n if (item === \"both\") {\n hint = \"\\n v0.8.0 removed 'both' alias. Use --cli claude --cli codex.\";\n } else if (item === \"all\") {\n hint =\n \"\\n v0.8.0 removed 'all' alias. Use --cli claude --cli codex --cli opencode.\";\n } else if (item.includes(\",\")) {\n // v0.7.1 — comma-separated input hint\n hint = \"\\n Tip: comma-separated not supported. Use --cli A --cli B for multiple.\";\n }\n return {\n ok: false,\n targets: [\"claude\"],\n warnings,\n error: `Invalid --cli value: ${item}. Must be one of: ${CLI_BASES.join(\" | \")}${hint}`,\n };\n }\n collected.add(item);\n }\n\n const targets = [...collected].sort((a, b) => CLI_BASE_SORT_ORDER[a] - CLI_BASE_SORT_ORDER[b]);\n return { ok: true, targets, warnings };\n}\n\nfunction normalizeInput(input: string | string[] | undefined): string[] {\n if (input === undefined || input === null) return [];\n if (typeof input === \"string\") {\n const trimmed = input.trim();\n return trimmed === \"\" ? [] : [trimmed];\n }\n return input.filter((s) => typeof s === \"string\" && s.trim() !== \"\").map((s) => s.trim());\n}\n\n/** Targets에 특정 base 포함 여부. has() 패턴. */\nexport function targetsInclude(targets: CliTargets, base: CliBase): boolean {\n return targets.includes(base);\n}\n","/** Available installation tracks. v0.5.0 — 11 Track (PM/Growth Marketing 추가). */\nexport const TRACKS = [\n \"tooling\",\n \"csr-supabase\",\n \"csr-fastify\",\n \"csr-fastapi\",\n \"ssr-htmx\",\n \"ssr-nextjs\",\n \"data\",\n \"executive\",\n \"full\",\n \"project-management\",\n \"growth-marketing\",\n] as const;\nexport type Track = (typeof TRACKS)[number];\n\nexport function isTrack(value: unknown): value is Track {\n return typeof value === \"string\" && (TRACKS as readonly string[]).includes(value);\n}\n\n/**\n * CLI target — multi-select base × combination (v0.8.0 — alias 제거).\n *\n * Base CLI: claude / codex / opencode / antigravity (4 base). 15 combinations possible (2^4 - 1, empty 제외).\n * Legacy `both` / `all` alias는 v0.7.0 deprecation 거쳐 v0.8.0에서 invalid input.\n * Migration: `--cli claude --cli codex` (repeatable) 또는 multiselect 인터랙티브.\n */\nexport const CLI_BASES = [\"claude\", \"codex\", \"opencode\", \"antigravity\"] as const;\nexport type CliBase = (typeof CLI_BASES)[number];\n\nexport function isCliBase(value: unknown): value is CliBase {\n return typeof value === \"string\" && (CLI_BASES as readonly string[]).includes(value);\n}\n\n/** Sorted readonly array of CliBase. install pipeline의 분기 input. */\nexport type CliTargets = ReadonlyArray<CliBase>;\n\n/**\n * v26.64.0 (ADR-020) — Installation scope.\n *\n * - \"project\" (default): claude plugin `--scope project`, npx skills (default), npm `--save-dev`,\n * codex/opencode → 프로젝트 dir (`.codex/`, `.opencode/`). 사용자 명시 동의 없이는 글로벌 미수정.\n * - \"global\" (opt-in): claude plugin `--scope user`, npx skills `-g`, npm `-g`,\n * codex/opencode → `~/.codex/`, `~/.opencode/`. 사용자가 interactive 또는 `--scope global` 로 명시.\n *\n * NORTH_STAR.md D16 본질 — 사용자 무인지 글로벌 write 금지.\n */\nexport const INSTALL_SCOPES = [\"project\", \"global\"] as const;\nexport type InstallScope = (typeof INSTALL_SCOPES)[number];\n\nexport function isInstallScope(value: unknown): value is InstallScope {\n return typeof value === \"string\" && (INSTALL_SCOPES as readonly string[]).includes(value);\n}\n\n/**\n * v26.64.0 (ADR-020) — `InstallSpec.scope` 가 optional 이므로 사용 시 default \"project\" 로 normalize.\n * 모든 분기 코드 (external-installer, codex/*, opencode/*) 는 이 함수로 scope 결정.\n */\nexport function resolveScope(scope: InstallScope | undefined): InstallScope {\n return scope ?? \"project\";\n}\n\n/**\n * Optional opt-in feature flags collected interactively.\n *\n * v26.81.0 (ADR-022, BREAKING) — 자산 1:1 boolean 13종(withGsd/withEcc/withTob/\n * withSuperpowers/withAddyAgentSkills/withWshobsonAgents/withOpenspec/withBmad/\n * withClaudeVideo/withUnderstandAnything/withAgentmemory + withTauri/withUzysHarness)\n * 완전 삭제. 자산 선택은 `userOverride.forceInclude`(wizard 체크 / `--with <id>`)로\n * 일원화 — 자산 추가 시 플래그 코드 0곳. 잔존 6종 = 자산이 아닌 **설치 동작 옵션**만.\n */\nexport interface OptionFlags {\n /** ecc-prune 실행 결합 — prune 은 ecc-plugin 선택을 전제 (installer.ts eccSelected 가 처리). */\n withPrune: boolean;\n /** Codex global opt-in: ~/.codex/skills/uzys-* 복사. D16 — 사용자 명시 동의 필수. */\n withCodexSkills: boolean;\n /** Codex global opt-in: ~/.codex/config.toml [projects.\"...\"] trust entry. D16 동일. */\n withCodexTrust: boolean;\n /**\n * v0.6.0 — karpathy-coder pre-commit hook auto-wire (A 경로).\n * `.claude/settings.json` PreToolUse `Write|Edit` matcher에 hook entry 등록.\n * 활성화는 karpathy-coder plugin install 성공 후 + 사용자 명시 opt-in 시에만.\n */\n withKarpathyHook: boolean;\n /**\n * v0.7.0 — Codex slash 통일 opt-in. `~/.codex/prompts/uzys-*.md` 글로벌 복사.\n * D16 보호 — 글로벌 영역 침범이라 opt-in 강제.\n */\n withCodexPrompts: boolean;\n /**\n * v26.67.0 — Antigravity global opt-in (~/.gemini/antigravity/skills/uzys-* +\n * ~/.gemini/antigravity/global_workflows/uzys-*.md). D16 영역 — `scope=global` +\n * `cli.includes(\"antigravity\")` 시에만 실 write. 사용자 명시 opt-in 필수.\n */\n withAntigravityGlobal: boolean;\n}\n\nexport const DEFAULT_OPTIONS: OptionFlags = {\n withPrune: false,\n withCodexSkills: false,\n withCodexTrust: false,\n withKarpathyHook: false,\n withCodexPrompts: false,\n withAntigravityGlobal: false,\n};\n\n/** Aggregate result of interactive flow — the spec the install pipeline consumes. */\nexport interface InstallSpec {\n tracks: Track[];\n options: OptionFlags;\n /** v0.7.0 — sorted readonly array of CliBase (이전: single CliMode). */\n cli: CliTargets;\n projectDir: string;\n /**\n * v26.64.0 (ADR-020) — Installation scope. Default \"project\" — 사용자 무인지 글로벌 write 방지.\n * Interactive prompt 또는 `--scope global` 명시 시에만 \"global\".\n * Optional + default \"project\" — 명시 안 한 사용처 (기존 tests / wizard non-scope-aware) 안전한 fallback.\n * 사용처는 `resolveScope(spec.scope)` 또는 `scope ?? \"project\"` 로 normalize.\n */\n scope?: InstallScope;\n /**\n * v26.47.0 — User-level override of preset/option condition (Phase C full).\n * `forceInclude`: condition 무관 강제 포함 / `forceExclude`: condition 무관 강제 제외.\n * 우선순위: forceExclude > forceInclude > condition.\n * Optional — 미제공 시 기존 condition 만 평가 (backward compat).\n */\n userOverride?: {\n forceInclude: ReadonlyArray<string>;\n forceExclude: ReadonlyArray<string>;\n };\n}\n","/**\n * design.ts — CLI visual design tokens (color, symbols, layout helpers).\n *\n * Aesthetic direction: **refined ops-report**. Mission control feel without\n * decoration noise. Phase markers + aligned 2-column rows + structured summary.\n *\n * Goals:\n * 1. Make input-wait points visually obvious (handled by @clack/prompts).\n * 2. Make the install pipeline output legible:\n * - phase-segmented progress (━━━ Phase N · Title ━━━)\n * - aligned per-asset rows (✓/⊘/✗ + id + meta)\n * - explicit skipped/failed reporting (no silent skips)\n * - terminal-width responsive (default 78)\n * 3. Zero runtime dependencies — emit raw ANSI escapes.\n *\n * `NO_COLOR` is honored per https://no-color.org.\n */\n\nconst isColorEnabled = (() => {\n if (process.env.NO_COLOR && process.env.NO_COLOR !== \"\") {\n return false;\n }\n // stdout may be missing in some test contexts\n return Boolean(process.stdout?.isTTY);\n})();\n\nfunction wrap(open: number, close: number) {\n return (s: string): string => {\n if (!isColorEnabled) {\n return s;\n }\n return `\\x1b[${open}m${s}\\x1b[${close}m`;\n };\n}\n\nexport const c = {\n bold: wrap(1, 22),\n dim: wrap(2, 22),\n red: wrap(31, 39),\n green: wrap(32, 39),\n yellow: wrap(33, 39),\n cyan: wrap(36, 39),\n gray: wrap(90, 39),\n};\n\nexport const symbol = {\n success: \"✓\",\n failure: \"✗\",\n skip: \"⊘\",\n arrow: \"›\",\n pointer: \"▸\",\n bullet: \"•\",\n warn: \"⚠\",\n /** Heavy horizontal box-drawing — phase dividers. */\n rule: \"━\",\n /** Middle dot — section separator. */\n mid: \"·\",\n};\n\n/** Default width for phase headers / dividers. Terminal default ≥ 78. */\nexport const DEFAULT_WIDTH = 78;\n\n/** Render a legacy section header. Bold cyan with a leading arrow. (kept for backward compat) */\nexport function header(title: string): string {\n return c.bold(c.cyan(`${symbol.arrow} ${title}`));\n}\n\n/**\n * Render a phase header — `━━━ Phase N · Title ━━━━━━━...` (full-width).\n * v26.63.0 (deprecated): kept for non-interactive mode + backward compat.\n * wizard 모드는 unifiedSection() 사용 (5-step 통합 — phase 카운터 무관).\n */\nexport function phaseHeader(n: number | string, title: string, width = DEFAULT_WIDTH): string {\n const label = `${symbol.rule}${symbol.rule}${symbol.rule} Phase ${n} ${symbol.mid} ${title} `;\n const fill = symbol.rule.repeat(Math.max(0, width - visibleLength(label)));\n return c.bold(c.cyan(`${label}${fill}`));\n}\n\n/**\n * v26.63.0 — Step 5 (Installing) 안의 sub-section 헤더.\n * `━━ Templates ━━` / `━━ External assets (n) ━━` / `━━ Codex artifacts ━━`.\n * phaseHeader (3 rule + Phase N + ·) 대비 단순 — 2 rule + title.\n */\nexport function unifiedSection(title: string, width = DEFAULT_WIDTH): string {\n const label = `${symbol.rule}${symbol.rule} ${title} `;\n const fill = symbol.rule.repeat(Math.max(0, width - visibleLength(label)));\n return c.bold(c.cyan(`${label}${fill}`));\n}\n\n/**\n * Render a section header (non-phase) — `━━━ Title ━━━━━━━...`.\n * Used for TARGET / SUMMARY / NEXT etc.\n */\nexport function sectionHeader(title: string, width = DEFAULT_WIDTH): string {\n const label = `${symbol.rule}${symbol.rule}${symbol.rule} ${title} `;\n const fill = symbol.rule.repeat(Math.max(0, width - visibleLength(label)));\n return c.bold(c.cyan(`${label}${fill}`));\n}\n\n/** Plain horizontal divider — `━━━...━━━` (no label). */\nexport function divider(width = DEFAULT_WIDTH): string {\n return c.dim(symbol.rule.repeat(width));\n}\n\n/**\n * Render a `key: value` row with a fixed-width left column for alignment.\n * Used in pre-flight / summary blocks (▸ TRACKS executive, tooling).\n */\nexport function infoRow(key: string, value: string, width = 12): string {\n const label = `${symbol.pointer} ${key}`.padEnd(width + 2, \" \");\n return ` ${c.dim(label)} ${value}`;\n}\n\n/** Backward-compat — `keyValue` (used by older install report). */\nexport function keyValue(key: string, value: string, width = 16): string {\n const padded = `${key}:`.padEnd(width, \" \");\n return ` ${c.dim(padded)} ${value}`;\n}\n\n/**\n * Render an asset row — ` ✓ asset-id meta`.\n * symbol = success/skip/failure. label = stable id (left-pad). meta = dim right column.\n */\nexport function assetRow(\n kind: \"success\" | \"skip\" | \"failure\",\n label: string,\n meta = \"\",\n labelWidth = 40,\n): string {\n const sym = renderSymbol(kind);\n const labelPadded = label.padEnd(labelWidth, \" \");\n const metaText = meta ? c.dim(meta) : \"\";\n return ` ${sym} ${labelPadded} ${metaText}`.trimEnd();\n}\n\nfunction renderSymbol(kind: \"success\" | \"skip\" | \"failure\"): string {\n switch (kind) {\n case \"success\":\n return c.green(symbol.success);\n case \"skip\":\n return c.yellow(symbol.skip);\n case \"failure\":\n return c.red(symbol.failure);\n }\n}\n\nexport const status = {\n success: (msg: string): string => `${c.green(symbol.success)} ${msg}`,\n failure: (msg: string): string => `${c.red(symbol.failure)} ${msg}`,\n warn: (msg: string): string => `${c.yellow(symbol.warn)} ${msg}`,\n info: (msg: string): string => `${c.cyan(symbol.bullet)} ${msg}`,\n};\n\n/**\n * Strip ANSI escape sequences so visible width can be measured (for header padding).\n */\nfunction visibleLength(s: string): number {\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape stripping requires \\x1b\n return s.replace(/\\x1b\\[[0-9;]*m/g, \"\").length;\n}\n\n/**\n * v26.63.2 — Pad to fixed display width (ANSI-aware). spacing scale 정렬 용.\n */\nexport function padDisplay(s: string, width: number): string {\n const visible = visibleLength(s);\n return visible >= width ? s : s + \" \".repeat(width - visible);\n}\n","import {\n chmodSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { type AntigravityOptInReport, runAntigravityOptIn } from \"./antigravity/opt-in.js\";\nimport {\n type AntigravityTransformReport,\n runAntigravityTransform,\n} from \"./antigravity/transform.js\";\nimport { type CodexOptInReport, runCodexOptIn } from \"./codex/opt-in.js\";\nimport { type CodexTransformReport, runCodexTransform } from \"./codex/transform.js\";\nimport {\n addGitignoreEnv,\n addGitignoreNpxSkillsAgents,\n writeEnvExample,\n writeMcpAllowlist,\n} from \"./env-files.js\";\nimport { EXTERNAL_ASSETS, filterApplicableAssets, isAssetSelected } from \"./external-assets.js\";\nimport {\n type ExternalInstallerDeps,\n type ExternalInstallReport,\n runExternalInstall,\n} from \"./external-installer.js\";\nimport { backupDir, copyBackupDir, copyDir, copyFile, ensureProjectSkeleton } from \"./fs-ops.js\";\nimport { buildInstallLog, hashContent, writeInstallLog } from \"./install-log.js\";\nimport { type AssetSpec, buildManifest } from \"./manifest.js\";\nimport { composeMcpJson, writeMcpJson } from \"./mcp-merge.js\";\nimport { type OpencodeTransformReport, runOpencodeTransform } from \"./opencode/transform.js\";\nimport { mergeProjectClaude } from \"./project-claude-merge.js\";\nimport { addPreToolUseHook, type ClaudeSettings } from \"./settings-merge.js\";\nimport { type InstallSpec, type OptionFlags, resolveScope, type Track } from \"./types.js\";\nimport { runUpdateMode, type UpdateModeReport } from \"./update-mode.js\";\n\n/** karpathy-coder hook command — `.claude/settings.json` PreToolUse Write|Edit matcher entry. */\nconst KARPATHY_HOOK_COMMAND = 'bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/karpathy-gate.sh\"';\n\n/**\n * Install mode — Router action 매핑.\n * - \"fresh\" : 첫 설치 (기본값)\n * - \"add\" : 기존 위에 Track union 추가 (backup 없음)\n * - \"update\" : 정책 파일만 templates로 갱신 (backup + orphan prune + stale hook)\n * - \"reinstall\" : 기존 .claude/ backup 후 처음부터 (backup 강제)\n */\nexport type InstallMode = \"fresh\" | \"add\" | \"update\" | \"reinstall\";\n\nexport interface InstallContext {\n /** Path to the harness repo (where `templates/` lives). */\n harnessRoot: string;\n /** Target project directory. */\n projectDir: string;\n spec: InstallSpec;\n /**\n * Router action mode. Defaults to \"fresh\".\n * - \"add\"/\"update\"/\"reinstall\" trigger different install paths.\n * - reinstall + update force backup=true.\n */\n mode?: InstallMode;\n /**\n * When true, an existing .claude/ is renamed to a timestamped backup before install.\n * Auto-true when mode ∈ {update, reinstall}.\n */\n backup?: boolean;\n /**\n * External install (claude plugin / npm -g / npx skills) injection point.\n * Default: real `runExternalInstall`. Tests inject mock to avoid real spawn.\n * Pass `null` to disable external install entirely.\n */\n runExternal?:\n | ((\n // v26.77.0 — projectDir: 외부 설치기 spawn cwd (자산 착지 위치). Bug B fix.\n // v26.81.0 (ADR-022) — userOverride: 자산 opt-in(--with <id>) 전파 (flag 13종 대체).\n ctx: {\n tracks: ReadonlyArray<Track>;\n options: OptionFlags;\n projectDir?: string;\n userOverride?: {\n forceInclude: ReadonlyArray<string>;\n forceExclude: ReadonlyArray<string>;\n };\n },\n deps: ExternalInstallerDeps,\n ) => ExternalInstallReport)\n | null;\n /**\n * Progress callback fired between stages so renderers can stream output\n * (avoids \"Phase 1 header → 5 minutes silence\" UX problem).\n */\n onProgress?: (event: ProgressEvent) => void;\n /** External installer streaming hooks (forwarded to runExternalInstall). */\n externalDeps?: Pick<ExternalInstallerDeps, \"onAssetStart\" | \"onAssetResult\">;\n}\n\n/** Progress event types fired during runInstall. */\nexport type ProgressEvent =\n /** Baseline (manifest copy + mcp + envFiles + Codex/OpenCode transforms) finished. External not yet started. */\n | { type: \"baseline-complete\"; baseline: BaselineReport }\n /** External install phase about to begin. */\n | { type: \"external-start\"; assetCount: number }\n /** External install phase finished (with report). */\n | { type: \"external-complete\"; report: ExternalInstallReport }\n /** v26.64.0 — install log write 실패 (non-fatal). */\n | { type: \"install-log-error\"; message: string };\n\n/** karpathy-coder hook auto-wire 결과 (v0.6.0). */\nexport interface KarpathyHookReport {\n /** withKarpathyHook=true && karpathy-coder install 성공 시 true. */\n wired: boolean;\n /** wired=false 시 사유. */\n reason?:\n | \"opt-out\"\n | \"plugin-install-failed\"\n | \"external-skipped\"\n | \"settings-parse-error\"\n | \"claude-not-selected\";\n /** wired=true 시 settings.json 갱신 여부 (idempotent skip 시 false). */\n settingsUpdated?: boolean;\n /** wired=true 시 hook script 복사 여부. */\n hookScriptCopied?: boolean;\n}\n\n/** karpathy-coder asset ID — SSOT (external-assets.ts entry id와 일치 강제). */\nconst KARPATHY_ASSET_ID = \"karpathy-coder\";\n\n/**\n * v0.6.1 — Phase 1 output 카테고리별 분류. install renderer가 각 카테고리별로 row를 출력한다.\n * Names는 description용 (display only); 빈 배열이면 row 출력 skip.\n */\nexport interface BaselineCategoryCounts {\n /** rule 파일 names (확장자 제외) — git-policy, change-management 등 */\n rules: string[];\n /** agent 파일 names */\n agents: string[];\n /** hook 파일 names (확장자 제외) */\n hooks: string[];\n /** commands 디렉토리 카운트 (uzys + ecc) — names는 디렉토리라 무의미 */\n commands: number;\n /** skill 디렉토리 names */\n skills: string[];\n}\n\n/** Baseline phase result (everything except external assets). */\nexport interface BaselineReport {\n filesCopied: number;\n dirsCopied: number;\n skipped: number;\n backup: string | null;\n installedTracks: string[];\n mcpServers: string[];\n codex: CodexTransformReport | null;\n codexOptIn: CodexOptInReport | null;\n opencode: OpencodeTransformReport | null;\n /** v26.66.0 — Present when spec.cli includes \"antigravity\". */\n antigravity: AntigravityTransformReport | null;\n /** v26.67.0 — Present when antigravity global opt-in fired (scope=global + withAntigravityGlobal). */\n antigravityOptIn: AntigravityOptInReport | null;\n updateMode: UpdateModeReport | null;\n mode: InstallMode;\n envFiles: {\n envExampleCreated: boolean;\n gitignoreEnvAdded: boolean;\n mcpAllowlist: string[] | null;\n /** v0.8.0 — `.gitignore`에 추가된 npx skills agent 디렉토리 패턴 (`.factory/`, `.goose/`). */\n gitignoreNpxSkillsAdded: string[];\n };\n /** v0.6.1 — Phase 1 카테고리별 카운트 + names. Update mode에서는 빈 객체. */\n categories?: BaselineCategoryCounts;\n /** Root CLAUDE.md merged from project-claude fragments. null when claude baseline disabled. */\n rootClaudeMd: { tracks: ReadonlyArray<Track> } | null;\n}\n\nexport interface InstallReport {\n filesCopied: number;\n dirsCopied: number;\n skipped: number;\n backup: string | null;\n installedTracks: string[];\n mcpServers: string[];\n /** Present when spec.cli includes \"codex\". */\n codex: CodexTransformReport | null;\n /** Present when Codex transform ran AND user opted-in to global skills/trust/prompts. null otherwise. */\n codexOptIn: CodexOptInReport | null;\n /** Present when spec.cli includes \"opencode\". */\n opencode: OpencodeTransformReport | null;\n /** v26.66.0 — Present when spec.cli includes \"antigravity\". */\n antigravity: AntigravityTransformReport | null;\n /** v26.67.0 — Present when antigravity global opt-in fired. null otherwise. */\n antigravityOptIn: AntigravityOptInReport | null;\n /** External install report (claude plugin / npm -g / npx skills). null when disabled or empty. */\n external: ExternalInstallReport | null;\n /** Update-mode report (rules/agents/commands/hooks 갱신 + orphan prune + stale hook). null when not update mode. */\n updateMode: UpdateModeReport | null;\n /** karpathy-coder hook auto-wire 결과 (v0.6.0). null when withKarpathyHook=false. */\n karpathyHook: KarpathyHookReport | null;\n /** Install mode dispatched (echo of ctx.mode, default \"fresh\"). */\n mode: InstallMode;\n /** Environment file generation results (always present). */\n envFiles: {\n /** true if .env.example was created (csr-supabase/full only). */\n envExampleCreated: boolean;\n /** true if .gitignore got `.env` line appended. */\n gitignoreEnvAdded: boolean;\n /** Server names written to .mcp-allowlist; null if skipped. */\n mcpAllowlist: string[] | null;\n /** v0.8.0 — `.gitignore`에 추가된 npx skills agent 디렉토리 패턴 (`.factory/`, `.goose/`). */\n gitignoreNpxSkillsAdded: string[];\n };\n}\n\n/**\n * Run the installation pipeline. Pure function modulo filesystem side effects.\n * v26.82.0 (Phase R) — 276줄 단일 함수를 단계별 블록 함수로 분해 (동작 변경 0):\n * update 단축 / claude baseline / CLI transforms / external / install log.\n */\nexport function runInstall(ctx: InstallContext): InstallReport {\n const { harnessRoot, projectDir, spec } = ctx;\n const mode: InstallMode = ctx.mode ?? \"fresh\";\n const templatesDir = join(harnessRoot, \"templates\");\n\n if (!existsSync(templatesDir)) {\n throw new Error(`Templates dir not found: ${templatesDir}`);\n }\n\n const claudeDir = join(projectDir, \".claude\");\n\n // Update mode pre-flight: existing .claude/ 필수. backup 전에 검증.\n if (mode === \"update\" && !existsSync(claudeDir)) {\n throw new Error(`Update mode requires existing .claude/ at ${claudeDir}`);\n }\n\n const backupPath = resolveBackupPath(ctx, mode, claudeDir);\n\n // Update mode 단축 — 정책 파일만 갱신하고 종료 (manifest copy / external 모두 skip)\n if (mode === \"update\") {\n return runUpdateInstall(ctx, templatesDir, backupPath);\n }\n\n const manifestSpec = buildManifestSpec(spec);\n\n // v0.8.0 — `.claude/` baseline은 spec.cli에 \"claude\" 포함 시에만 생성.\n // Codex/OpenCode 단독 사용자는 dead weight 회피.\n const base = spec.cli.includes(\"claude\")\n ? installClaudeBaseline(manifestSpec, harnessRoot, projectDir, templatesDir)\n : emptyClaudeBaseline();\n\n // Compose .mcp.json from template + track-mcp-map.tsv (Codex/OpenCode도 사용 — claude 무관)\n const mcpResult = composeAndWriteMcp(harnessRoot, projectDir, spec);\n\n const baseline: BaselineReport = {\n filesCopied: base.filesCopied,\n dirsCopied: base.dirsCopied,\n skipped: base.skipped,\n backup: backupPath,\n installedTracks: [...spec.tracks].sort(),\n mcpServers: Object.keys(mcpResult.mcpServers).sort(),\n ...runCliTransforms(spec, harnessRoot, projectDir, manifestSpec.withUzysHarness),\n updateMode: null,\n mode,\n envFiles: writeEnvironmentFiles(projectDir, spec.tracks),\n categories: base.categories,\n rootClaudeMd: base.rootClaudeMd,\n };\n\n // ━━━ Baseline complete — emit progress event so renderer can show Phase 1 rows ━━━\n ctx.onProgress?.({ type: \"baseline-complete\", baseline });\n\n // ━━━ External assets (claude plugin / npm -g / npx skills) ━━━\n const external = runExternalPhase(ctx);\n\n // ━━━ karpathy-coder hook auto-wire (v0.6.0) ━━━\n // SPEC: docs/specs/karpathy-hook-autowire.md AC2 — opt-in 강제 + install 성공 후에만.\n // v0.8.0 — `.claude/settings.json` PreToolUse 의존이라 spec.cli에 \"claude\" 포함 시에만 와이어 가능.\n const karpathyHook = wireKarpathyHook(spec, external, harnessRoot, projectDir);\n\n // ━━━ v26.64.0 (ADR-020) — Install log write ━━━\n writeInstallLogSafe(ctx, external, base.rootClaudeMdLog);\n\n return { ...baseline, external, karpathyHook };\n}\n\n/**\n * Backup auto-on for update + reinstall (sourced from router action).\n * Update: copy backup (preserve original .claude/ for in-place update).\n * Reinstall + others: rename backup (move .claude/ aside, then full install).\n */\nfunction resolveBackupPath(\n ctx: InstallContext,\n mode: InstallMode,\n claudeDir: string,\n): string | null {\n const wantBackup = ctx.backup ?? (mode === \"update\" || mode === \"reinstall\");\n if (!wantBackup) return null;\n return mode === \"update\" ? copyBackupDir(claudeDir) : backupDir(claudeDir);\n}\n\n/** Update mode 단축 경로 — 정책 파일만 갱신 (manifest copy / external 모두 skip). */\nfunction runUpdateInstall(\n ctx: InstallContext,\n templatesDir: string,\n backupPath: string | null,\n): InstallReport {\n const updateReport = runUpdateMode(ctx.projectDir, templatesDir);\n const baseline: BaselineReport = {\n filesCopied: 0,\n dirsCopied: 0,\n skipped: 0,\n backup: backupPath,\n installedTracks: [...ctx.spec.tracks].sort(),\n mcpServers: [],\n codex: null,\n codexOptIn: null,\n opencode: null,\n antigravity: null,\n antigravityOptIn: null,\n updateMode: updateReport,\n mode: \"update\",\n envFiles: {\n envExampleCreated: false,\n gitignoreEnvAdded: false,\n mcpAllowlist: null,\n gitignoreNpxSkillsAdded: [],\n },\n rootClaudeMd: null,\n };\n ctx.onProgress?.({ type: \"baseline-complete\", baseline });\n return { ...baseline, external: null, karpathyHook: null };\n}\n\n/**\n * v26.81.0 (ADR-022) — manifest 게이팅 입력. 내부 자산 선택 판정 — 이전\n * OptionFlags.withTauri/withUzysHarness/withEcc boolean 자리를 카탈로그 선택\n * (wizard 체크 / --with <id> → forceInclude)으로 대체 (manifest 필드명은 유지).\n */\nfunction buildManifestSpec(spec: InstallSpec): Required<AssetSpec> {\n const selectionCtx = {\n tracks: spec.tracks,\n options: spec.options,\n ...(spec.userOverride ? { userOverride: spec.userOverride } : {}),\n };\n return {\n tracks: spec.tracks,\n withTauri: isAssetSelected(\"tauri-desktop\", selectionCtx),\n withUzysHarness: isAssetSelected(\"uzys-harness\", selectionCtx),\n // v26.55.0 — withEcc gating (ADR-016). ECC cherry-pick (agents/skills/commands) 항목 토글.\n // withPrune 은 ecc-plugin 사용을 전제 (이전 applyOptionRules `withEcc ||= withPrune` 의미 보존).\n withEcc: isAssetSelected(\"ecc-plugin\", selectionCtx) || spec.options.withPrune,\n };\n}\n\n/** `.claude/` baseline (manifest copy) 결과. claude 미선택 시 emptyClaudeBaseline(). */\ninterface ClaudeBaselineResult {\n filesCopied: number;\n dirsCopied: number;\n skipped: number;\n categories: BaselineCategoryCounts;\n rootClaudeMd: { tracks: ReadonlyArray<Track> } | null;\n /** root CLAUDE.md 무결성 기록 — uninstall 시 사용자 수정 여부 판별 (install 원본과 sha 비교). */\n rootClaudeMdLog: { path: string; sha256: string } | null;\n}\n\nfunction emptyClaudeBaseline(): ClaudeBaselineResult {\n return {\n filesCopied: 0,\n dirsCopied: 0,\n skipped: 0,\n categories: { rules: [], agents: [], hooks: [], commands: 0, skills: [] },\n rootClaudeMd: null,\n rootClaudeMdLog: null,\n };\n}\n\n/** `.claude/` baseline — manifest copy + hook chmod + .installed-tracks + root CLAUDE.md merge. */\nfunction installClaudeBaseline(\n manifestSpec: Required<AssetSpec>,\n harnessRoot: string,\n projectDir: string,\n templatesDir: string,\n): ClaudeBaselineResult {\n ensureProjectSkeleton(projectDir);\n\n const result = emptyClaudeBaseline();\n const manifest = buildManifest(manifestSpec);\n\n for (const entry of manifest) {\n if (!entry.applies(manifestSpec)) {\n continue;\n }\n const source = join(templatesDir, entry.source);\n const target = join(projectDir, entry.target);\n if (!existsSync(source)) {\n result.skipped += 1;\n continue;\n }\n if (entry.type === \"file\") {\n copyFile(source, target);\n result.filesCopied += 1;\n } else {\n copyDir(source, target);\n result.dirsCopied += 1;\n }\n accumulateCategory(result.categories, entry);\n }\n\n // chmod +x on hook scripts (cp does not preserve exec bit when source is non-exec)\n const hookDir = join(projectDir, \".claude/hooks\");\n if (existsSync(hookDir)) {\n chmodHooksSync(hookDir);\n }\n\n // Write metadata file used by detect_install_state on next run (.claude/.installed-tracks)\n writeInstalledTracks(projectDir, manifestSpec.tracks);\n\n // Project root CLAUDE.md — merge from fragments (single/multi/full).\n // Note: overwrites any user customization on re-install. Documented behavior.\n const rootClaudeMdContent = writeRootClaudeMd(harnessRoot, projectDir, manifestSpec.tracks);\n result.rootClaudeMd = { tracks: manifestSpec.tracks };\n result.rootClaudeMdLog = { path: \"CLAUDE.md\", sha256: hashContent(rootClaudeMdContent) };\n return result;\n}\n\n/** Environment files (F7/F8 — bash setup-harness.sh L880~890 + L954~996 등가). */\nfunction writeEnvironmentFiles(\n projectDir: string,\n tracks: ReadonlyArray<Track>,\n): BaselineReport[\"envFiles\"] {\n return {\n envExampleCreated: writeEnvExample(projectDir, tracks),\n gitignoreEnvAdded: addGitignoreEnv(projectDir),\n mcpAllowlist: writeMcpAllowlist(projectDir),\n // v0.8.0 — `.factory/`, `.goose/` ignore (npx skills universal install 사용자 #3)\n gitignoreNpxSkillsAdded: addGitignoreNpxSkillsAgents(projectDir),\n };\n}\n\n/** Codex / OpenCode / Antigravity per-CLI transforms (+ scope=global opt-in) 결과. */\ninterface CliTransformResults {\n codex: CodexTransformReport | null;\n codexOptIn: CodexOptInReport | null;\n opencode: OpencodeTransformReport | null;\n antigravity: AntigravityTransformReport | null;\n antigravityOptIn: AntigravityOptInReport | null;\n}\n\nfunction runCliTransforms(\n spec: InstallSpec,\n harnessRoot: string,\n projectDir: string,\n uzysHarnessSelected: boolean,\n): CliTransformResults {\n // Codex transform when spec.cli includes \"codex\"\n let codex: CodexTransformReport | null = null;\n let codexOptIn: CodexOptInReport | null = null;\n if (spec.cli.includes(\"codex\")) {\n // v26.57.0 (ADR-018) — withUzysHarness gating 을 codex transform 에도 전달.\n // .agents/skills/uzys-* + .codex/prompts/uzys-* 도 uzys-harness 없으면 생성 안 함.\n codex = runCodexTransform({\n harnessRoot,\n projectDir,\n withUzysHarness: uzysHarnessSelected,\n });\n // v26.64.0 (ADR-020) — Codex global opt-in 은 scope=global 일 때만 의미.\n // scope=project (default) 시 ~/.codex/ write skip — transform.ts 가 이미 `.codex/` (project)\n // 에 write 함. withCodex* 옵션은 scope=global 시에만 ~/.codex/ 로 추가 복사.\n const installScope = spec.scope ?? \"project\";\n if (\n installScope === \"global\" &&\n (spec.options.withCodexSkills || spec.options.withCodexTrust || spec.options.withCodexPrompts)\n ) {\n codexOptIn = runCodexOptIn({\n projectDir,\n harnessRoot,\n withCodexSkills: spec.options.withCodexSkills,\n withCodexTrust: spec.options.withCodexTrust,\n withCodexPrompts: spec.options.withCodexPrompts,\n });\n }\n }\n\n // OpenCode transform when spec.cli includes \"opencode\"\n let opencode: OpencodeTransformReport | null = null;\n if (spec.cli.includes(\"opencode\")) {\n opencode = runOpencodeTransform({ harnessRoot, projectDir });\n }\n\n // v26.66.0 — Antigravity transform when spec.cli includes \"antigravity\".\n // `.agents/skills/` (codex 와 공유) + `.agents/workflows/` (신규). withUzysHarness 시만.\n let antigravity: AntigravityTransformReport | null = null;\n let antigravityOptIn: AntigravityOptInReport | null = null;\n if (spec.cli.includes(\"antigravity\")) {\n antigravity = runAntigravityTransform({\n harnessRoot,\n projectDir,\n withUzysHarness: uzysHarnessSelected,\n });\n // v26.67.0 (Phase C) — Antigravity global opt-in. ADR-020 정합 —\n // scope=global + withAntigravityGlobal=true 시에만 ~/.gemini/ 영역 write.\n const installScope = spec.scope ?? \"project\";\n if (installScope === \"global\" && spec.options.withAntigravityGlobal) {\n antigravityOptIn = runAntigravityOptIn({\n projectDir,\n harnessRoot,\n enabled: true,\n });\n }\n }\n\n return { codex, codexOptIn, opencode, antigravity, antigravityOptIn };\n}\n\n/**\n * External assets (claude plugin / npm -g / npx skills) 설치 단계.\n * Default = real runExternalInstall. Tests inject mock or `null` to skip.\n * log/warn은 silent (renderer가 onAssetStart/Result로 스트리밍).\n */\nfunction runExternalPhase(ctx: InstallContext): ExternalInstallReport | null {\n if (ctx.runExternal === null) {\n return null;\n }\n const { harnessRoot, projectDir, spec } = ctx;\n const runExt = ctx.runExternal ?? runExternalInstall;\n const externalDeps: ExternalInstallerDeps = {\n harnessRoot,\n log: () => {},\n warn: () => {},\n };\n if (ctx.externalDeps?.onAssetStart) {\n externalDeps.onAssetStart = ctx.externalDeps.onAssetStart;\n }\n if (ctx.externalDeps?.onAssetResult) {\n externalDeps.onAssetResult = ctx.externalDeps.onAssetResult;\n }\n const filterCtx = {\n tracks: spec.tracks,\n options: spec.options,\n ...(spec.userOverride ? { userOverride: spec.userOverride } : {}),\n };\n const applicableCount = filterApplicableAssets(EXTERNAL_ASSETS, filterCtx).length;\n ctx.onProgress?.({ type: \"external-start\", assetCount: applicableCount });\n const external = runExt(\n { ...filterCtx, cli: spec.cli, projectDir, ...(spec.scope ? { scope: spec.scope } : {}) },\n externalDeps,\n );\n ctx.onProgress?.({ type: \"external-complete\", report: external });\n return external;\n}\n\n/**\n * Install log write — `.claude/.harness-install.json` (자산 list + scope + timestamp,\n * uninstall command 의 source). 실패는 install 자체를 fail 시키지 않음 (D16 — install 성공 우선).\n */\nfunction writeInstallLogSafe(\n ctx: InstallContext,\n external: ExternalInstallReport | null,\n rootClaudeMdLog: { path: string; sha256: string } | null,\n): void {\n try {\n const log = buildInstallLog(ctx.spec, external, resolveScope(ctx.spec.scope), rootClaudeMdLog);\n writeInstallLog(ctx.projectDir, log);\n } catch (e) {\n ctx.onProgress?.({\n type: \"install-log-error\",\n message: e instanceof Error ? e.message : String(e),\n });\n }\n}\n\n/**\n * karpathy-coder pre-commit hook auto-wire (v0.6.0).\n *\n * 활성화 조건 (AND):\n * 1. spec.options.withKarpathyHook === true (opt-in 강제)\n * 2. spec.cli 에 \"claude\" 포함 (v0.8.0 — `.claude/settings.json` 미생성 시 와이어 불가)\n * 3. external.attempted에 karpathy-coder ok=true (plugin install 성공)\n *\n * 동작:\n * - templates/hooks/karpathy-gate.sh → <projectDir>/.claude/hooks/karpathy-gate.sh 복사\n * - .claude/settings.json PreToolUse Write|Edit matcher에 hook entry 추가 (idempotent)\n */\nfunction wireKarpathyHook(\n spec: InstallSpec,\n external: ExternalInstallReport | null,\n harnessRoot: string,\n projectDir: string,\n): KarpathyHookReport | null {\n if (!spec.options.withKarpathyHook) {\n return null;\n }\n // v0.8.0 가드 — `.claude/` baseline 미생성 시 hook 와이어 불가 (silent partial state 방지).\n if (!spec.cli.includes(\"claude\")) {\n return { wired: false, reason: \"claude-not-selected\" };\n }\n if (external === null) {\n return { wired: false, reason: \"external-skipped\" };\n }\n const karpathyResult = external.attempted.find((r) => r.asset.id === KARPATHY_ASSET_ID);\n if (!karpathyResult?.ok) {\n return { wired: false, reason: \"plugin-install-failed\" };\n }\n\n // Hook script 복사 (manifest에 없는 v0.6.0 신규 — opt-in 시에만)\n const sourceHook = join(harnessRoot, \"templates/hooks/karpathy-gate.sh\");\n const targetHook = join(projectDir, \".claude/hooks/karpathy-gate.sh\");\n let hookScriptCopied = false;\n if (existsSync(sourceHook)) {\n copyFile(sourceHook, targetHook);\n try {\n chmodSync(targetHook, 0o755);\n } catch {\n // best-effort\n }\n hookScriptCopied = true;\n }\n\n // settings.json PreToolUse Write|Edit entry 추가 (idempotent)\n // HIGH-2 fix: JSON.parse try/catch — add mode에서 사용자 손상 settings.json 시 install 중단 방지\n const settingsPath = join(projectDir, \".claude/settings.json\");\n let settingsUpdated = false;\n if (existsSync(settingsPath)) {\n const raw = readFileSync(settingsPath, \"utf8\");\n let before: ClaudeSettings;\n try {\n before = JSON.parse(raw);\n } catch {\n return { wired: false, reason: \"settings-parse-error\", hookScriptCopied };\n }\n const after = addPreToolUseHook(before, \"Write|Edit\", KARPATHY_HOOK_COMMAND);\n const beforeStr = JSON.stringify(before);\n const afterStr = JSON.stringify(after);\n if (beforeStr !== afterStr) {\n writeFileSync(settingsPath, `${JSON.stringify(after, null, 2)}\\n`);\n settingsUpdated = true;\n }\n }\n\n return { wired: true, settingsUpdated, hookScriptCopied };\n}\n\nfunction composeAndWriteMcp(\n harnessRoot: string,\n projectDir: string,\n spec: InstallSpec,\n): { mcpServers: Record<string, unknown> } {\n const mcpPath = join(projectDir, \".mcp.json\");\n const composed = composeMcpJson({\n templateMcpPath: join(harnessRoot, \"templates/mcp.json\"),\n trackMapPath: join(harnessRoot, \"templates/track-mcp-map.tsv\"),\n existingPath: mcpPath,\n tracks: spec.tracks,\n });\n writeMcpJson(mcpPath, composed);\n return composed;\n}\n\n/**\n * v0.6.1 — manifest entry를 카테고리별로 누적. install renderer Phase 1 row 출력에 사용.\n * `entry.target` prefix로 분류. file은 basename(.확장자 제거), dir은 dir name.\n */\nfunction accumulateCategory(\n cats: BaselineCategoryCounts,\n entry: import(\"./manifest.js\").AssetEntry,\n): void {\n const target = entry.target;\n if (target.startsWith(\".claude/rules/\") && target.endsWith(\".md\")) {\n const name = target.replace(/^\\.claude\\/rules\\//, \"\").replace(/\\.md$/, \"\");\n cats.rules.push(name);\n } else if (target.startsWith(\".claude/agents/\") && target.endsWith(\".md\")) {\n const name = target.replace(/^\\.claude\\/agents\\//, \"\").replace(/\\.md$/, \"\");\n cats.agents.push(name);\n } else if (target.startsWith(\".claude/hooks/\") && target.endsWith(\".sh\")) {\n const name = target.replace(/^\\.claude\\/hooks\\//, \"\").replace(/\\.sh$/, \"\");\n cats.hooks.push(name);\n } else if (target.startsWith(\".claude/commands/\")) {\n cats.commands += 1;\n } else if (target.startsWith(\".claude/skills/\") && entry.type === \"dir\") {\n const name = target.replace(/^\\.claude\\/skills\\//, \"\").replace(/\\/?$/, \"\");\n cats.skills.push(name);\n }\n}\n\nfunction writeInstalledTracks(projectDir: string, tracks: ReadonlyArray<string>): void {\n const path = join(projectDir, \".claude/.installed-tracks\");\n mkdirSync(dirname(path), { recursive: true });\n const sorted = [...new Set(tracks)].sort().join(\"\\n\");\n writeFileSync(path, `${sorted}\\n`);\n}\n\nfunction writeRootClaudeMd(\n harnessRoot: string,\n projectDir: string,\n tracks: ReadonlyArray<Track>,\n): string {\n const baseDir = join(harnessRoot, \"templates/project-claude\");\n const content = mergeProjectClaude(tracks, { baseDir });\n writeFileSync(join(projectDir, \"CLAUDE.md\"), content);\n return content;\n}\n\nfunction chmodHooksSync(hookDir: string): void {\n for (const file of listHookFiles(hookDir)) {\n try {\n chmodSync(file, 0o755);\n } catch {\n // Best-effort; many platforms (Windows in particular) ignore mode bits.\n }\n }\n}\n\nfunction listHookFiles(hookDir: string): string[] {\n // Hooks are flat shell scripts — avoid pulling glob deps.\n return readdirSync(hookDir, { withFileTypes: true })\n .filter((e) => e.isFile() && e.name.endsWith(\".sh\"))\n .map((e) => resolve(hookDir, e.name));\n}\n","/**\n * Antigravity global opt-in — v26.67.0 (Phase C).\n *\n * `~/.gemini/antigravity/skills/uzys-{phase}/` + `~/.gemini/antigravity/global_workflows/uzys-{phase}.md`\n * 복사. D16 영역 — `scope=global` + `cli.includes(\"antigravity\")` + `withAntigravityGlobal=true`\n * 세 조건 모두 충족 시에만 호출.\n *\n * Codex `runCodexOptIn` 패턴 미러 (D16 동일 보호).\n */\n\nimport { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { renameSlashes } from \"../codex/agents-md.js\";\n\nconst PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"];\n\nexport interface AntigravityOptInReport {\n /** `~/.gemini/antigravity/skills/uzys-<phase>/` 복사 결과 */\n skillsInstalled: {\n enabled: boolean;\n count: number;\n targetDir: string;\n };\n /** `~/.gemini/antigravity/global_workflows/uzys-<phase>.md` 복사 결과 */\n workflowsInstalled: {\n enabled: boolean;\n count: number;\n targetDir: string;\n };\n}\n\nexport interface AntigravityOptInContext {\n /** 사용자 프로젝트 root (`.agents/skills/uzys-*` source). */\n projectDir: string;\n /** harness root (templates/commands/uzys/ source — workflow body 원본). */\n harnessRoot?: string;\n /** 글로벌 `~/.gemini/` 경로 (테스트 override 가능). */\n geminiHome?: string;\n /** `withAntigravityGlobal` opt-in flag. false 시 전체 skip. */\n enabled: boolean;\n}\n\n/**\n * Antigravity 글로벌 opt-in 실행. `enabled=false` 시 skip + empty report.\n */\nexport function runAntigravityOptIn(ctx: AntigravityOptInContext): AntigravityOptInReport {\n const geminiHome = ctx.geminiHome ?? join(homedir(), \".gemini\");\n const skillsTarget = join(geminiHome, \"antigravity\", \"skills\");\n const workflowsTarget = join(geminiHome, \"antigravity\", \"global_workflows\");\n\n if (!ctx.enabled) {\n return {\n skillsInstalled: { enabled: false, count: 0, targetDir: skillsTarget },\n workflowsInstalled: { enabled: false, count: 0, targetDir: workflowsTarget },\n };\n }\n\n // 1. ~/.gemini/antigravity/skills/uzys-{phase}/ 복사\n // Source: projectDir/.agents/skills/uzys-{phase}/ (Phase B 가 만든 산출).\n // Antigravity 가 .agents/skills/ 와 ~/.gemini/antigravity/skills/ 둘 다 native 인식 →\n // 같은 내용을 global 위치에도 복사 (모든 프로젝트에서 보이도록).\n let skillsCount = 0;\n for (const phase of PHASES) {\n const src = join(ctx.projectDir, \".agents\", \"skills\", `uzys-${phase}`);\n if (!existsSync(src)) continue;\n const dst = join(skillsTarget, `uzys-${phase}`);\n mkdirSync(dst, { recursive: true });\n cpSync(src, dst, { recursive: true });\n skillsCount++;\n }\n\n // 2. ~/.gemini/antigravity/global_workflows/uzys-{phase}.md 복사\n // Source: harnessRoot/templates/commands/uzys/<phase>.md\n let workflowsCount = 0;\n if (ctx.harnessRoot) {\n mkdirSync(workflowsTarget, { recursive: true });\n for (const phase of PHASES) {\n const src = join(ctx.harnessRoot, \"templates/commands/uzys\", `${phase}.md`);\n if (!existsSync(src)) continue;\n // Antigravity 파일명 기반 `/uzys-{phase}` dispatch → body 내 `/uzys:` cross-ref 도\n // `/uzys-` 로 rename (project-scope transform.ts:94 와 동일 정합).\n const body = renameSlashes(readFileSync(src, \"utf8\"));\n const dst = join(workflowsTarget, `uzys-${phase}.md`);\n writeFileSync(dst, body);\n workflowsCount++;\n }\n }\n\n return {\n skillsInstalled: { enabled: true, count: skillsCount, targetDir: skillsTarget },\n workflowsInstalled: { enabled: true, count: workflowsCount, targetDir: workflowsTarget },\n };\n}\n","/**\n * AGENTS.md transform — CLAUDE.md → AGENTS.md.\n *\n * v26.70.0 — section 추출(Identity/Direction/Principles) → CLAUDE.md **전문 embed**.\n * 실 `templates/CLAUDE.md` 가 Rule 1~12 구조라 Identity/Direction/Principles 헤딩이 없어\n * extractSection 이 빈 결과 → AGENTS.md 가 빈 섹션으로 shipping 되던 버그 fix.\n * `{PROJECT_RULES}` placeholder 에 CLAUDE.md 본문 전체를 삽입 (heading 구조 의존 0).\n */\n\n/** Rename Claude slash conventions (`/uzys:foo`) to Codex (`/uzys-foo`). */\nexport function renameSlashes(text: string): string {\n return text.replaceAll(\"/uzys:\", \"/uzys-\");\n}\n\nexport interface AgentsMdParams {\n template: string;\n claudeMd: string;\n projectName: string;\n}\n\n/**\n * Render AGENTS.md by embedding the full CLAUDE.md body into the template.\n *\n * Placeholders:\n * - {PROJECT_NAME} — basename of project dir\n * - {PROJECT_RULES} — full CLAUDE.md body (first h1 stripped; template provides its own h1)\n *\n * 마지막에 `/uzys:` → `/uzys-` rename (Codex/Antigravity 는 slash namespace 미지원).\n */\nexport function renderAgentsMd(params: AgentsMdParams): string {\n // CLAUDE.md 의 첫 h1 (# title) 제거 — 템플릿이 자체 h1 보유.\n const body = params.claudeMd.replace(/^#\\s+.*\\r?\\n/, \"\").trim();\n const replaced = params.template\n .replaceAll(\"{PROJECT_NAME}\", params.projectName)\n .replaceAll(\"{PROJECT_RULES}\", body);\n return renameSlashes(replaced);\n}\n","/**\n * Antigravity transform — v26.66.0 (skills/workflows) + v26.69.0 (rules).\n *\n * Google Antigravity 2.0 (I/O 2026-05-19) 공식 spec (codelabs):\n * - Workspace skills: .agents/skills/<name>/SKILL.md (Anthropic skill format — codex 와 공유)\n * - Workspace workflows: .agents/workflows/<name>.md (`/<name>` 슬래시로 호출)\n * - Workspace rules: .agents/rules/<name>.md (디렉토리, plain markdown)\n * - Global rules: ~/.gemini/GEMINI.md (사용자 글로벌 — harness 미터치)\n * - Global skills: ~/.gemini/antigravity/skills/ (Phase C opt-in — antigravity/opt-in.ts)\n *\n * 본 transform 의 책임 (모두 project-scope):\n * 1. `.agents/rules/uzys-harness.md` — project context (CLAUDE.md → Antigravity rule).\n * **withUzysHarness 무관 — 항상 작성** (CLAUDE.md/AGENTS.md 처럼 foundational context).\n * cli=antigravity 단독 선택 시 이게 없으면 Antigravity 가 프로젝트 컨벤션을 모름.\n * 2. `.agents/skills/uzys-{phase}/SKILL.md` — codex 와 idempotent 공유. withUzysHarness 시만.\n * 3. `.agents/workflows/uzys-{phase}.md` — Antigravity native workflow. withUzysHarness 시만.\n * 파일명 기반 `/uzys-{phase}` 호출 → body 의 `/uzys:` 참조도 `/uzys-` 로 rename (정합).\n *\n * SAFETY: `~/.gemini/` 글로벌 write 없음 (Phase C 의 opt-in.ts 가 별도 담당).\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport { renameSlashes, renderAgentsMd } from \"../codex/agents-md.js\";\nimport { renderSkill } from \"../codex/skills.js\";\nimport { ensureDir } from \"../fs-ops.js\";\n\nconst PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"];\n\nexport interface AntigravityTransformParams {\n /** harness root (templates/CLAUDE.md + templates/commands/uzys/ source 위치). */\n harnessRoot: string;\n /** 사용자 프로젝트 root. `.agents/` 가 만들어질 위치. */\n projectDir: string;\n /**\n * withUzysHarness gating. 6-Gate skills/workflows 의 antigravity native 매핑은\n * uzys-harness 활성 시에만. rules (project context) 는 본 flag 무관 — 항상 작성.\n */\n withUzysHarness: boolean;\n}\n\nexport interface AntigravityTransformReport {\n /** v26.69.0 — 작성된 rules 파일 경로 (.agents/rules/uzys-harness.md). null = template 부재. */\n rulesFile: string | null;\n /** 작성된 SKILL.md 경로 list (.agents/skills/uzys-{phase}/SKILL.md). */\n skillFiles: ReadonlyArray<string>;\n /** 작성된 workflow .md 경로 list (.agents/workflows/uzys-{phase}.md). */\n workflowFiles: ReadonlyArray<string>;\n}\n\n/**\n * Antigravity 용 project-scope 자산 생성.\n *\n * rules 는 항상 (cli=antigravity 시), skills/workflows 는 withUzysHarness 시만.\n */\nexport function runAntigravityTransform(\n params: AntigravityTransformParams,\n): AntigravityTransformReport {\n const { harnessRoot, projectDir, withUzysHarness } = params;\n\n // 1. .agents/rules/uzys-harness.md — project context. withUzysHarness 무관 (항상).\n const rulesFile = writeRules(harnessRoot, projectDir);\n\n const skillFiles: string[] = [];\n const workflowFiles: string[] = [];\n\n if (withUzysHarness) {\n for (const phase of PHASES) {\n // 2. .agents/skills/uzys-{phase}/SKILL.md — codex 와 idempotent 공유.\n const skillDir = join(projectDir, \".agents\", \"skills\", `uzys-${phase}`);\n ensureDir(skillDir);\n const cmdSrc = join(harnessRoot, \"templates/commands/uzys\", `${phase}.md`);\n let source = \"\";\n if (existsSync(cmdSrc)) {\n source = readFileSync(cmdSrc, \"utf8\");\n } else {\n // Fallback: bundled stub from templates/codex/skills/<phase>/SKILL.md\n const fallback = join(harnessRoot, \"templates/codex/skills\", `uzys-${phase}/SKILL.md`);\n if (existsSync(fallback)) {\n source = readFileSync(fallback, \"utf8\");\n }\n }\n const skillTarget = join(skillDir, \"SKILL.md\");\n writeFileSync(skillTarget, renderSkill({ source, phase }));\n skillFiles.push(skillTarget);\n\n // 3. .agents/workflows/uzys-{phase}.md — Antigravity native workflow.\n // 파일명 기반 `/uzys-{phase}` 호출 → body 의 `/uzys:` 참조도 `/uzys-` 로 rename (정합).\n // source 가 비어있으면 skip (commands/uzys/ 미설치).\n if (source) {\n const workflowDir = join(projectDir, \".agents\", \"workflows\");\n ensureDir(workflowDir);\n const workflowTarget = join(workflowDir, `uzys-${phase}.md`);\n writeFileSync(workflowTarget, renameSlashes(source));\n workflowFiles.push(workflowTarget);\n }\n }\n }\n\n return { rulesFile, skillFiles, workflowFiles };\n}\n\n/**\n * v26.69.0 — `.agents/rules/uzys-harness.md` 작성. CLAUDE.md → Antigravity workspace rule.\n *\n * Source: templates/CLAUDE.md (전문) + templates/antigravity/AGENTS.md.template.\n * v26.70.0 — renderAgentsMd 재사용 (codex/opencode 와 동일 전문 embed). `{PROJECT_RULES}` 에\n * CLAUDE.md 본문 전체 삽입 + `/uzys:` → `/uzys-` rename.\n *\n * template 또는 CLAUDE.md 부재 시 null (graceful — install 진행).\n */\nfunction writeRules(harnessRoot: string, projectDir: string): string | null {\n const claudeMdPath = join(harnessRoot, \"templates/CLAUDE.md\");\n const templatePath = join(harnessRoot, \"templates/antigravity/AGENTS.md.template\");\n if (!existsSync(claudeMdPath) || !existsSync(templatePath)) {\n return null;\n }\n const claudeMd = readFileSync(claudeMdPath, \"utf8\");\n const template = readFileSync(templatePath, \"utf8\");\n const rulesDir = join(projectDir, \".agents\", \"rules\");\n ensureDir(rulesDir);\n const target = join(rulesDir, \"uzys-harness.md\");\n writeFileSync(target, renderAgentsMd({ template, claudeMd, projectName: basename(projectDir) }));\n return target;\n}\n","/**\n * uzys command → uzys-* SKILL.md transform.\n * Mirrors `claude-to-codex.sh` step 4 (lines 167-205).\n */\nimport { renameSlashes } from \"./agents-md.js\";\n\nexport interface RenderSkillParams {\n /** Original uzys command markdown (frontmatter optional — first line = description if absent). */\n source: string;\n /** Phase identifier (spec, plan, build, test, review, ship). */\n phase: string;\n}\n\n/**\n * Render a Codex SKILL.md from a Claude `.claude/commands/uzys/<phase>.md` source.\n * Slash references inside the body are renamed to the Codex (`uzys-`) form.\n */\nexport function renderSkill(params: RenderSkillParams): string {\n const { description, body } = parseSource(params.source);\n const finalDescription = description || `uzys-${params.phase} phase skill (Codex 포팅)`;\n const escapedDesc = finalDescription.replace(/\"/g, '\\\\\"');\n const renamedBody = renameSlashes(body).trimEnd();\n\n return [\n \"---\",\n `name: uzys-${params.phase}`,\n `description: \"${escapedDesc}\"`,\n \"---\",\n \"\",\n renamedBody,\n \"\",\n ].join(\"\\n\");\n}\n\ninterface ParsedSource {\n description: string;\n body: string;\n}\n\nfunction parseSource(source: string): ParsedSource {\n const lines = source.split(/\\r?\\n/);\n if (lines[0] === \"---\") {\n // YAML frontmatter present\n let descMatch = \"\";\n let secondDelimAt = -1;\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (line === \"---\") {\n secondDelimAt = i;\n break;\n }\n const match = line.match(/^description:\\s*(.*)$/);\n if (match) {\n descMatch = stripQuotes(match[1] ?? \"\");\n }\n }\n const body = secondDelimAt >= 0 ? lines.slice(secondDelimAt + 1).join(\"\\n\") : source;\n return { description: descMatch, body: body.replace(/^\\n+/, \"\") };\n }\n // No frontmatter: first non-empty line = description, rest = body\n const firstLine = lines[0] ?? \"\";\n const body = lines.slice(1).join(\"\\n\");\n return { description: firstLine.trim(), body };\n}\n\nfunction stripQuotes(raw: string): string {\n const trimmed = raw.trim();\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n}\n","import { copyFileSync, cpSync, existsSync, mkdirSync, renameSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\n/** Ensure a directory exists, creating parents as needed. Idempotent. */\nexport function ensureDir(path: string): void {\n mkdirSync(path, { recursive: true });\n}\n\nexport interface CopyResult {\n copied: number;\n skipped: number;\n}\n\n/** Copy a single file, creating parent dirs as needed. Idempotent. */\nexport function copyFile(source: string, target: string): void {\n if (!existsSync(source)) {\n throw new Error(`Source not found: ${source}`);\n }\n mkdirSync(dirname(target), { recursive: true });\n copyFileSync(source, target);\n}\n\n/** Copy a directory recursively. Creates target if missing. */\nexport function copyDir(source: string, target: string): void {\n if (!existsSync(source)) {\n throw new Error(`Source dir not found: ${source}`);\n }\n mkdirSync(target, { recursive: true });\n cpSync(source, target, { recursive: true, force: true });\n}\n\n/**\n * Move an existing directory to a timestamped backup sibling.\n * Returns the backup path, or null when nothing to back up.\n */\nexport function backupDir(target: string, now: Date = new Date()): string | null {\n if (!existsSync(target)) {\n return null;\n }\n const backup = `${target}.backup-${formatStamp(now)}`;\n renameSync(target, backup);\n return backup;\n}\n\n/**\n * Copy backup — original target preserved (for in-place update mode).\n * bash setup-harness.sh L477 `cp -R .claude \"$BACKUP_DIR\"` 등가.\n */\nexport function copyBackupDir(target: string, now: Date = new Date()): string | null {\n if (!existsSync(target)) {\n return null;\n }\n const backup = `${target}.backup-${formatStamp(now)}`;\n cpSync(target, backup, { recursive: true });\n return backup;\n}\n\nfunction formatStamp(now: Date): string {\n return now\n .toISOString()\n .replace(/[-:]/g, \"\")\n .replace(/\\.\\d+Z$/, \"Z\")\n .slice(0, 15);\n}\n\n/** Create a project skeleton: <project>/.claude/{commands/{uzys,ecc},rules,skills,agents,hooks}. */\nexport function ensureProjectSkeleton(projectDir: string): void {\n const dirs = [\n \".claude/commands/uzys\",\n \".claude/commands/ecc\",\n \".claude/rules\",\n \".claude/skills\",\n \".claude/agents\",\n \".claude/hooks\",\n \"docs/decisions\",\n ];\n for (const d of dirs) {\n mkdirSync(join(projectDir, d), { recursive: true });\n }\n}\n","/**\n * Codex global opt-in — ~/.codex/skills/ 복사 + ~/.codex/config.toml trust entry.\n *\n * SPEC: docs/specs/cli-rewrite-completeness.md F10, F11 (Reviewer HIGH-3, HIGH-4)\n * Source: bash setup-harness.sh@911c246~1 L1389~1429\n *\n * SAFETY: 사용자 명시 opt-in 없이 ~/.codex/ 글로벌 수정 금지 (D16 / ADR-002 v2 D4).\n * 호출자(installer)는 OptionFlags.withCodexSkills / withCodexTrust 둘 다 true일 때만 호출.\n */\n\nimport { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { CODEX_PROMPT_PHASES, renderCodexPrompt } from \"./prompts.js\";\nimport { type RegisterTrustResult, registerTrustEntry } from \"./trust-entry.js\";\n\nexport interface CodexOptInReport {\n /** ~/.codex/skills/uzys-{phase}/ 복사 결과 */\n skillsInstalled: {\n enabled: boolean;\n /** 복사된 skill 폴더 갯수 (uzys-spec, uzys-plan, ...) */\n count: number;\n /** 복사 대상 글로벌 경로 (절대 경로) */\n targetDir: string;\n };\n /** ~/.codex/config.toml trust entry 등록 결과 */\n trustEntry: {\n enabled: boolean;\n status: \"registered\" | \"already-present\" | \"error\" | \"skipped\";\n message?: string;\n };\n /** v0.7.0 — ~/.codex/prompts/uzys-*.md 6 file 복사 결과 (Codex slash 통일 opt-in). */\n promptsInstalled: {\n enabled: boolean;\n count: number;\n targetDir: string;\n };\n}\n\nexport interface CodexOptInContext {\n /** 사용자 프로젝트 root (.agents/skills/ 소스, v0.6.4+). */\n projectDir: string;\n /** harness root (templates/commands/uzys/ source 위치, v0.7.0+). */\n harnessRoot?: string;\n /** 글로벌 ~/.codex/ 경로 (테스트 override 가능). */\n codexHome?: string;\n /** ~/.codex/skills/uzys-* 복사 활성? */\n withCodexSkills: boolean;\n /** ~/.codex/config.toml trust entry 등록 활성? */\n withCodexTrust: boolean;\n /** v0.7.0 — ~/.codex/prompts/uzys-*.md slash 등록 활성? */\n withCodexPrompts: boolean;\n}\n\nconst PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"];\n\n/**\n * 세 opt-in 액션 실행 (v0.7.0+: prompts 추가). 비활성 플래그는 skip.\n */\nexport function runCodexOptIn(ctx: CodexOptInContext): CodexOptInReport {\n const codexHome = ctx.codexHome ?? join(homedir(), \".codex\");\n const skillsTarget = join(codexHome, \"skills\");\n const promptsTarget = join(codexHome, \"prompts\");\n const configPath = join(codexHome, \"config.toml\");\n\n // 1. ~/.codex/skills/uzys-* 복사\n let skillsCount = 0;\n if (ctx.withCodexSkills) {\n skillsCount = copyCodexSkills(ctx.projectDir, skillsTarget);\n }\n\n // 2. ~/.codex/config.toml trust entry\n let trustResult: RegisterTrustResult & { enabled: boolean } = {\n enabled: false,\n status: \"registered\",\n };\n if (ctx.withCodexTrust) {\n const result = registerTrustEntry({\n configPath,\n projectDir: ctx.projectDir,\n });\n trustResult = { enabled: true, ...result };\n }\n\n // 3. v0.7.0 — ~/.codex/prompts/uzys-*.md 복사 (slash 통일)\n let promptsCount = 0;\n if (ctx.withCodexPrompts) {\n promptsCount = copyCodexPrompts(ctx.harnessRoot, ctx.projectDir, promptsTarget);\n }\n\n return {\n skillsInstalled: {\n enabled: ctx.withCodexSkills,\n count: skillsCount,\n targetDir: skillsTarget,\n },\n trustEntry: {\n enabled: ctx.withCodexTrust,\n status: trustResult.enabled ? trustResult.status : \"skipped\",\n ...(trustResult.message ? { message: trustResult.message } : {}),\n },\n promptsInstalled: {\n enabled: ctx.withCodexPrompts,\n count: promptsCount,\n targetDir: promptsTarget,\n },\n };\n}\n\n/**\n * v0.7.0 — uzys command md 6 file을 Codex prompt md로 변환 + ~/.codex/prompts/ 복사.\n * Source: harnessRoot의 templates/commands/uzys/<phase>.md (또는 fallback projectDir/.claude/commands/uzys).\n * @returns 복사된 prompt 파일 갯수\n */\nfunction copyCodexPrompts(\n harnessRoot: string | undefined,\n projectDir: string,\n promptsTarget: string,\n): number {\n // Source 후보: harnessRoot/templates → fallback projectDir/.claude/commands/uzys (이미 install된 곳)\n const candidates: string[] = [];\n if (harnessRoot) {\n candidates.push(join(harnessRoot, \"templates/commands/uzys\"));\n }\n candidates.push(join(projectDir, \".claude/commands/uzys\"));\n\n const sourceDir = candidates.find((p) => existsSync(p));\n if (!sourceDir) return 0;\n\n mkdirSync(promptsTarget, { recursive: true });\n\n let count = 0;\n for (const phase of CODEX_PROMPT_PHASES) {\n const src = join(sourceDir, `${phase}.md`);\n if (!existsSync(src)) continue;\n const source = readFileSync(src, \"utf8\");\n const dst = join(promptsTarget, `uzys-${phase}.md`);\n writeFileSync(dst, renderCodexPrompt({ source, phase }));\n count++;\n }\n return count;\n}\n\n/**\n * 프로젝트의 .agents/skills/uzys-{phase}/ 6 폴더를 ~/.codex/skills/ 로 복사.\n * v0.6.4+ — source 디렉토리 .codex-skills → .agents/skills (Codex 공식 표준).\n * @returns 복사된 폴더 갯수\n */\nfunction copyCodexSkills(projectDir: string, skillsTarget: string): number {\n const sourceDir = join(projectDir, \".agents\", \"skills\");\n if (!existsSync(sourceDir)) {\n return 0;\n }\n mkdirSync(skillsTarget, { recursive: true });\n\n let count = 0;\n for (const phase of PHASES) {\n const src = join(sourceDir, `uzys-${phase}`);\n if (!existsSync(src)) continue;\n const dest = join(skillsTarget, `uzys-${phase}`);\n cpSync(src, dest, { recursive: true });\n count++;\n }\n\n // Catch any other uzys-* (forward-compat, in case PHASES expands)\n try {\n for (const entry of readdirSync(sourceDir)) {\n if (!entry.startsWith(\"uzys-\")) continue;\n const phase = entry.slice(\"uzys-\".length);\n if (PHASES.includes(phase)) continue; // already copied\n cpSync(join(sourceDir, entry), join(skillsTarget, entry), { recursive: true });\n count++;\n }\n } catch {\n // best-effort\n }\n\n return count;\n}\n","/**\n * Codex prompts render — v0.7.0 Major CR.\n *\n * SPEC: docs/specs/cli-multi-select.md F13 (Codex slash 통일).\n *\n * Source: `templates/commands/uzys/<phase>.md` (Claude Code uzys command)\n * Target: `~/.codex/prompts/uzys-<phase>.md` (Codex custom prompt)\n *\n * 변환:\n * - frontmatter `name: uzys-<phase>` + `description` 보장\n * - body의 `/uzys:<phase>` slash 참조 → `/uzys-<phase>` Codex 컨벤션 (slash rename)\n * - 코드 자체는 동일 (의미 보존)\n *\n * Codex prompts directory에 markdown 파일 두면 Codex 시작 시 `/uzys-<phase>` slash 등록됨.\n * 참조: https://developers.openai.com/codex/cli/slash-commands\n */\n\nimport { renameSlashes } from \"./agents-md.js\";\n\nexport interface RenderCodexPromptParams {\n /** Original uzys command markdown (frontmatter optional). */\n source: string;\n /** Phase identifier (spec, plan, build, test, review, ship). */\n phase: string;\n}\n\nexport function renderCodexPrompt(params: RenderCodexPromptParams): string {\n const { description, body } = parseSource(params.source);\n const finalDescription = description || `uzys-${params.phase} phase`;\n const escapedDesc = finalDescription.replace(/\"/g, '\\\\\"');\n const renamedBody = renameSlashes(body).trimEnd();\n\n // Codex custom prompt frontmatter\n return [\"---\", `description: \"${escapedDesc}\"`, \"---\", \"\", renamedBody, \"\"].join(\"\\n\");\n}\n\ninterface ParsedSource {\n description: string;\n body: string;\n}\n\nfunction parseSource(source: string): ParsedSource {\n const lines = source.split(/\\r?\\n/);\n if (lines[0] === \"---\") {\n let descMatch = \"\";\n let secondDelimAt = -1;\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (line === \"---\") {\n secondDelimAt = i;\n break;\n }\n const m = line.match(/^description:\\s*\"?(.+?)\"?\\s*$/);\n if (m?.[1]) descMatch = m[1];\n }\n if (secondDelimAt >= 0) {\n return {\n description: descMatch,\n body: lines\n .slice(secondDelimAt + 1)\n .join(\"\\n\")\n .replace(/^\\n+/, \"\"),\n };\n }\n // Malformed frontmatter (no closing `---`) — 첫 라인 `---` 자체를 description으로 쓰지 않음.\n // body는 첫 라인 제외하고 그대로 (renderSkill 동일 패턴).\n return {\n description: \"\",\n body: lines.slice(1).join(\"\\n\"),\n };\n }\n // Frontmatter 부재 — 첫 비공백 라인을 description으로 + body는 첫 라인 제외 (중복 방지).\n // Reviewer HIGH-1 fix: 이전엔 body=source 그대로 → description 라인 중복.\n const firstLine = lines[0] ?? \"\";\n const description = firstLine.replace(/^#+\\s*/, \"\").slice(0, 200);\n const body = lines.slice(1).join(\"\\n\").replace(/^\\n+/, \"\");\n return { description, body };\n}\n\nexport const CODEX_PROMPT_PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"] as const;\n","/**\n * Codex trust entry — `~/.codex/config.toml [projects.\"<dir>\"]` (parity with\n * setup-harness.sh L1404-1422).\n *\n * SAFETY: never modify the global `~/.codex/config.toml` without an explicit\n * opt-in (D16 / ADR-002 v2 D4). Callers must verify user consent first.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nexport interface RegisterTrustResult {\n status: \"registered\" | \"already-present\" | \"error\";\n message?: string;\n}\n\nconst TRUST_BLOCK_REGEX = /\\[projects\\.\"([^\"]+)\"\\]/g;\n\n/** Append a `[projects.\"<projectDir>\"]` block to the user `config.toml` (idempotent). */\nexport function registerTrustEntry(opts: {\n configPath: string;\n projectDir: string;\n}): RegisterTrustResult {\n const { configPath, projectDir } = opts;\n try {\n mkdirSync(dirname(configPath), { recursive: true });\n const existing = existsSync(configPath) ? readFileSync(configPath, \"utf8\") : \"\";\n if (hasTrustEntry(existing, projectDir)) {\n return { status: \"already-present\" };\n }\n const block = `\\n[projects.\"${projectDir}\"]\\ntrust_level = \"trusted\"\\n`;\n writeFileSync(configPath, existing + block);\n return { status: \"registered\" };\n } catch (e: unknown) {\n return {\n status: \"error\",\n message: e instanceof Error ? e.message : String(e),\n };\n }\n}\n\nexport function hasTrustEntry(configContent: string, projectDir: string): boolean {\n const matches = [...configContent.matchAll(TRUST_BLOCK_REGEX)].map((m) => m[1]);\n return matches.includes(projectDir);\n}\n","/**\n * Codex transform orchestrator — wraps the 5-step pipeline.\n *\n * Replaces `scripts/claude-to-codex.sh` (Phase D, OQ4 = TS port).\n *\n * Inputs:\n * - harnessRoot: repository root (templates/ + .mcp.json)\n * - projectDir: target project to receive AGENTS.md + .codex/ + .agents/skills/\n *\n * Outputs (under projectDir):\n * - AGENTS.md\n * - .codex/config.toml\n * - .codex/hooks/*.sh (3 hooks ported from templates/hooks/)\n * - .agents/skills/uzys-{phase}/SKILL.md (6 skills, slash-renamed)\n *\n * v0.6.4 — skill 출력 경로 수정 `.codex-skills/` → `.agents/skills/`.\n * 사유: Codex 공식 표준은 `.agents/skills/<name>/SKILL.md` (repo-level scope).\n * `.codex-skills/`는 비표준 — Codex가 인식 안 함 → /uzys-* slash 동작 안 함.\n * 참조: https://developers.openai.com/codex/skills\n */\n\nimport { chmodSync, existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport { ensureDir } from \"../fs-ops.js\";\nimport type { McpJson } from \"../mcp-merge.js\";\nimport { renderAgentsMd } from \"./agents-md.js\";\nimport { renderConfigToml } from \"./config-toml.js\";\nimport { renderCodexPrompt } from \"./prompts.js\";\nimport { renderSkill } from \"./skills.js\";\n\nexport interface CodexTransformParams {\n harnessRoot: string;\n projectDir: string;\n /**\n * v26.57.0 (ADR-018) — uzys-* skill/prompt 생성 gating.\n * Codex 의 `.agents/skills/uzys-{phase}/SKILL.md` 와 `.codex/prompts/uzys-{phase}.md`\n * 는 본 harness 의 6-Gate 워크플로우 산출물. withUzysHarness=false 면 두 디렉토리에\n * uzys-* 파일 생성 안 함. Claude 쪽 `.claude/commands/uzys/` 와 묶음 (ADR-017 의 확장).\n */\n withUzysHarness?: boolean;\n}\n\nexport interface CodexTransformReport {\n agentsMdPath: string;\n configTomlPath: string;\n hookFiles: string[];\n skillFiles: string[];\n /**\n * v0.7.1 — `<projectDir>/.codex/prompts/uzys-{phase}.md` 6 markdown.\n * 글로벌 영향 0. upstream Codex Issue #9848 (project-scoped prompts) 지원 시 자동 작동.\n */\n promptFiles: string[];\n}\n\nconst PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"];\nconst HOOK_NAMES = [\"session-start\", \"hito-counter\", \"gate-check\"];\n\nconst ENV_VAR_RENAME = /CLAUDE_PROJECT_DIR/g;\n\nexport function runCodexTransform(params: CodexTransformParams): CodexTransformReport {\n const { harnessRoot, projectDir, withUzysHarness = false } = params;\n\n const claudeMd = readRequired(join(harnessRoot, \"templates/CLAUDE.md\"));\n const agentsTemplate = readRequired(join(harnessRoot, \"templates/codex/AGENTS.md.template\"));\n const configTemplate = readRequired(join(harnessRoot, \"templates/codex/config.toml.template\"));\n const projectName = basename(projectDir);\n const mcp = readOptionalJson(join(harnessRoot, \".mcp.json\"));\n\n // 1. AGENTS.md\n const agentsMdPath = join(projectDir, \"AGENTS.md\");\n ensureDir(projectDir);\n writeFileSync(agentsMdPath, renderAgentsMd({ template: agentsTemplate, claudeMd, projectName }));\n\n // 2. .codex/config.toml\n const configTomlPath = join(projectDir, \".codex/config.toml\");\n ensureDir(join(projectDir, \".codex\"));\n writeFileSync(\n configTomlPath,\n renderConfigToml({\n template: configTemplate,\n projectName,\n projectDir,\n mcp,\n }),\n );\n\n // 3. .codex/hooks/{session-start,hito-counter,gate-check}.sh\n const hookDir = join(projectDir, \".codex/hooks\");\n ensureDir(hookDir);\n const hookFiles: string[] = [];\n for (const hook of HOOK_NAMES) {\n const src = join(harnessRoot, \"templates/hooks\", `${hook}.sh`);\n if (!existsSync(src)) {\n continue;\n }\n const ported = readFileSync(src, \"utf8\").replace(ENV_VAR_RENAME, \"CODEX_PROJECT_DIR\");\n const target = join(hookDir, `${hook}.sh`);\n writeFileSync(target, ported);\n chmodSync(target, 0o755);\n hookFiles.push(target);\n }\n\n // 4. .agents/skills/uzys-{phase}/SKILL.md (v0.6.4 — Codex 공식 repo-level skill scope)\n // v26.57.0 (ADR-018) — withUzysHarness gating. uzys 슬래시 미사용 시 skill 디렉토리 생성 X.\n const skillFiles: string[] = [];\n if (withUzysHarness) {\n for (const phase of PHASES) {\n const skillDir = join(projectDir, \".agents\", \"skills\", `uzys-${phase}`);\n ensureDir(skillDir);\n const cmdSrc = join(harnessRoot, \"templates/commands/uzys\", `${phase}.md`);\n let source = \"\";\n if (existsSync(cmdSrc)) {\n source = readFileSync(cmdSrc, \"utf8\");\n } else {\n // Fallback: bundled stub from templates/codex/skills/<phase>/SKILL.md\n const fallback = join(harnessRoot, \"templates/codex/skills\", `uzys-${phase}/SKILL.md`);\n if (existsSync(fallback)) {\n source = readFileSync(fallback, \"utf8\");\n }\n }\n const target = join(skillDir, \"SKILL.md\");\n writeFileSync(target, renderSkill({ source, phase }));\n skillFiles.push(target);\n }\n }\n\n // 5. v0.7.1 — .codex/prompts/uzys-{phase}.md (project-scoped pre-positioning)\n // 글로벌 ~/.codex/prompts/ 영향 0. Codex upstream Issue #9848 지원 시 자동 작동.\n // 현재는 Codex가 project-scoped prompts 미지원 — pre-position만 (free upgrade 패턴).\n // v26.57.0 (ADR-018) — withUzysHarness gating. uzys 슬래시 미사용 시 prompt 생성 X.\n const promptFiles: string[] = [];\n if (withUzysHarness) {\n const promptDir = join(projectDir, \".codex\", \"prompts\");\n ensureDir(promptDir);\n for (const phase of PHASES) {\n const cmdSrc = join(harnessRoot, \"templates/commands/uzys\", `${phase}.md`);\n if (!existsSync(cmdSrc)) {\n continue;\n }\n const source = readFileSync(cmdSrc, \"utf8\");\n const target = join(promptDir, `uzys-${phase}.md`);\n writeFileSync(target, renderCodexPrompt({ source, phase }));\n promptFiles.push(target);\n }\n }\n\n return { agentsMdPath, configTomlPath, hookFiles, skillFiles, promptFiles };\n}\n\nfunction readRequired(path: string): string {\n if (!existsSync(path)) {\n throw new Error(`Codex transform: required source missing: ${path}`);\n }\n return readFileSync(path, \"utf8\");\n}\n\nfunction readOptionalJson(path: string): McpJson | null {\n if (!existsSync(path)) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as McpJson;\n } catch {\n return null;\n }\n}\n","/**\n * config.toml transform — fill placeholders + append [mcp_servers.X] from .mcp.json.\n * Mirrors `claude-to-codex.sh` steps 2 + 5.\n */\n\nimport type { McpJson } from \"../mcp-merge.js\";\n\nexport interface RenderConfigTomlParams {\n template: string;\n projectName: string;\n projectDir: string;\n /** Source `.mcp.json` (parsed). When provided, [mcp_servers.X] blocks replace defaults. */\n mcp?: McpJson | null;\n}\n\nconst DEFAULT_MCP_BLOCK_RE = /\\n# =+\\n# MCP Servers — .*?\\n# =+[\\s\\S]*$/;\n\n/**\n * Substitute placeholders + replace the MCP servers section with blocks\n * derived from the supplied `.mcp.json` (or leave the template default).\n */\nexport function renderConfigToml(params: RenderConfigTomlParams): string {\n const substituted = params.template\n .replaceAll(\"{PROJECT_NAME}\", params.projectName)\n .replaceAll(\"{PROJECT_DIR}\", params.projectDir)\n .replaceAll(\"{GITHUB_TOKEN}\", \"${GITHUB_TOKEN}\");\n\n if (!params.mcp) {\n return substituted;\n }\n\n const stripped = stripExistingMcpSection(substituted);\n const fresh = renderMcpServers(params.mcp);\n return `${stripped.trimEnd()}\\n${fresh}\\n`;\n}\n\nfunction stripExistingMcpSection(toml: string): string {\n // Drop default [mcp_servers.X] blocks shipped in the template (we replace from .mcp.json)\n const lines = toml.split(/\\r?\\n/);\n const out: string[] = [];\n let skipping = false;\n for (const line of lines) {\n if (line.startsWith(\"[mcp_servers.\")) {\n skipping = true;\n continue;\n }\n if (skipping && line.startsWith(\"[\") && !line.startsWith(\"[mcp_servers.\")) {\n skipping = false;\n }\n if (skipping) {\n continue;\n }\n if (\n /^# .*MCP Servers/.test(line) ||\n /^# Railway MCP/.test(line) ||\n /^# github MCP/.test(line)\n ) {\n continue;\n }\n out.push(line);\n }\n return out.join(\"\\n\").replace(DEFAULT_MCP_BLOCK_RE, \"\");\n}\n\nfunction renderMcpServers(mcp: McpJson): string {\n const stamp = new Date().toISOString().slice(0, 10);\n const header = [\n \"# ============================================================\",\n `# MCP Servers — generated from .mcp.json (${stamp})`,\n \"# ============================================================\",\n ].join(\"\\n\");\n\n const blocks = Object.entries(mcp.mcpServers).map(([name, cfg]) => {\n const lines = [`[mcp_servers.${quoteIfNeeded(name)}]`];\n lines.push(`command = ${jsonString(cfg.command)}`);\n lines.push(`args = ${JSON.stringify(cfg.args)}`);\n if (cfg.env && Object.keys(cfg.env).length > 0) {\n const envBody = Object.entries(cfg.env)\n .map(([k, v]) => `${k} = ${jsonString(v)}`)\n .join(\", \");\n lines.push(`env = { ${envBody} }`);\n }\n return lines.join(\"\\n\");\n });\n\n return [header, \"\", ...blocks].join(\"\\n\");\n}\n\nfunction jsonString(s: string): string {\n return JSON.stringify(s);\n}\n\nfunction quoteIfNeeded(name: string): string {\n return /^[A-Za-z0-9_-]+$/.test(name) ? name : `\"${name}\"`;\n}\n","/**\n * env-files.ts — 환경 파일 자동 생성.\n *\n * SPEC: docs/specs/cli-rewrite-completeness.md F7, F8\n * Source: bash setup-harness.sh@911c246~1 L880~890 + L954~996.\n *\n * 3 종 산출:\n * 1. .env.example (csr-supabase / full Track) — Supabase 토큰 가이드\n * 2. .gitignore .env 라인 추가 (없을 때만)\n * 3. .mcp-allowlist (모든 dev Track) — D35 opt-in security gate\n *\n * 모두 idempotent — 이미 있으면 skip.\n */\n\nimport { appendFileSync, existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Track } from \"./types.js\";\n\nconst ENV_EXAMPLE_BODY = `# .env.example — csr-supabase Track\n# Copy to .env (gitignored) and fill in values: cp .env.example .env\n\n# ===== Supabase Management API (MCP server용) =====\n# Personal Access Token — @supabase/mcp-server가 프로젝트 생성/마이그레이션/Edge Functions 배포에 사용\n# 발급: https://supabase.com/dashboard/account/tokens\nSUPABASE_ACCESS_TOKEN=\n\n# 프로젝트 참조 ID (예: \"abcdefghijklmnop\")\n# 위치: Supabase Dashboard → Project Settings → General\nSUPABASE_PROJECT_REF=\n\n# DB 패스워드 (supabase db push 등 직접 DB 접근용)\n# 위치: Supabase Dashboard → Project Settings → Database\nSUPABASE_DB_PASSWORD=\n\n# ===== Frontend (public, 클라이언트 노출 OK) =====\n# 위치: Supabase Dashboard → Project Settings → API\nNEXT_PUBLIC_SUPABASE_URL=\nNEXT_PUBLIC_SUPABASE_ANON_KEY=\n\n# ===== Optional — 앱 측 AI 기능용 =====\n# OPENAI_API_KEY=\n# ANTHROPIC_API_KEY=\n\n# ===== Note =====\n# - Vercel/Netlify는 별도 CLI login 사용 (env 불필요): vercel login / netlify login\n# - Supabase CLI(supabase login)는 OAuth로 ~/.config/supabase/에 토큰 저장 — env 별개\n# - .env는 .gitignore됨 (자동 추가). 절대 commit 금지.\n`;\n\nconst ENV_EXAMPLE_TRACKS: ReadonlyArray<Track> = [\"csr-supabase\", \"full\"];\n\nconst GITIGNORE_ENV_PATTERN = /^\\.env$|^\\.env\\s/m;\n\n/**\n * .env.example 생성 (csr-supabase/full Track 한정, idempotent).\n * @returns true if created, false if skipped (already exists or non-applicable track)\n */\nexport function writeEnvExample(projectDir: string, tracks: ReadonlyArray<Track>): boolean {\n if (!tracks.some((t) => ENV_EXAMPLE_TRACKS.includes(t))) {\n return false;\n }\n const path = join(projectDir, \".env.example\");\n if (existsSync(path)) {\n return false;\n }\n writeFileSync(path, ENV_EXAMPLE_BODY);\n return true;\n}\n\n/**\n * .gitignore에 `.env` 라인 추가. 이미 있으면 skip.\n * @returns true if appended, false if skipped (no .gitignore or .env already listed)\n */\nexport function addGitignoreEnv(projectDir: string): boolean {\n const path = join(projectDir, \".gitignore\");\n if (!existsSync(path)) {\n return false;\n }\n const content = readFileSync(path, \"utf8\");\n if (GITIGNORE_ENV_PATTERN.test(content)) {\n return false;\n }\n // append with separator (avoid double newlines)\n const sep = content.endsWith(\"\\n\") ? \"\" : \"\\n\";\n appendFileSync(path, `${sep}\\n# Secret env (auto-added by agent-harness install)\\n.env\\n`);\n return true;\n}\n\nconst NPX_SKILLS_AGENT_DIRS = [\".factory/\", \".goose/\"];\nconst GITIGNORE_NPX_SKILLS_HEADER =\n \"# npx skills add multi-CLI cache (auto-added by agent-harness)\";\n\n/**\n * v0.8.0 — `.gitignore`에 `.factory/`, `.goose/` 패턴 추가 (사용자 보고 #3).\n *\n * `npx skills add`가 multi-CLI universal install 동작 — Codex 사용자 환경에서\n * `.factory/skills/`, `.goose/skills/` 자동 생성. 사용자 git noise 회피용 ignore.\n *\n * idempotent — 이미 있으면 skip.\n * @returns added pattern list (empty if all already present or no .gitignore)\n */\nexport function addGitignoreNpxSkillsAgents(projectDir: string): string[] {\n const path = join(projectDir, \".gitignore\");\n if (!existsSync(path)) {\n return [];\n }\n const content = readFileSync(path, \"utf8\");\n const missing = NPX_SKILLS_AGENT_DIRS.filter((pattern) => {\n // exact line match (이스케이프 후 줄 단위 비교 — 단순화: 문자열 포함)\n const lineRegex = new RegExp(`^${pattern.replace(/\\./g, \"\\\\.\").replace(/\\//g, \"/\")}\\\\s*$`, \"m\");\n return !lineRegex.test(content);\n });\n if (missing.length === 0) {\n return [];\n }\n const sep = content.endsWith(\"\\n\") ? \"\" : \"\\n\";\n const block = [GITIGNORE_NPX_SKILLS_HEADER, ...missing].join(\"\\n\");\n appendFileSync(path, `${sep}\\n${block}\\n`);\n return [...missing];\n}\n\n/**\n * .mcp-allowlist 생성 from .mcp.json mcpServers keys (D35 opt-in security gate).\n * mcp-pre-exec.sh hook이 참조. 파일 부재 시 gate disabled.\n * @returns server name list written, or null if skipped (already exists or .mcp.json missing)\n */\nexport function writeMcpAllowlist(projectDir: string): string[] | null {\n const allowlistPath = join(projectDir, \".mcp-allowlist\");\n if (existsSync(allowlistPath)) {\n return null;\n }\n const mcpPath = join(projectDir, \".mcp.json\");\n if (!existsSync(mcpPath)) {\n return null;\n }\n let names: string[] = [];\n try {\n const parsed = JSON.parse(readFileSync(mcpPath, \"utf8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n names = Object.keys(parsed.mcpServers ?? {}).sort();\n } catch {\n return null;\n }\n if (names.length === 0) {\n return [];\n }\n const body = [\n \"# MCP Server Allowlist — auto-generated by agent-harness install\",\n \"# Referenced by mcp-pre-exec.sh hook. Remove or '#' comment any server you want to block.\",\n \"# Deleting this file disables the gate (allows all MCP calls).\",\n \"\",\n ...names,\n \"\",\n ].join(\"\\n\");\n writeFileSync(allowlistPath, body);\n return names;\n}\n","/**\n * External installer — `EXTERNAL_ASSETS` 매트릭스를 실제 호출로 변환.\n *\n * SPEC: docs/specs/cli-rewrite-completeness.md F1\n *\n * Decision (OQ1): 실패는 warn-skip. 종료 시 누락 자산 목록 보고.\n * abort는 첫 실행 신뢰성을 깨뜨리므로 채택 안 함 (vibe killer).\n *\n * Spawning은 `child_process.spawnSync` 사용. command/args 분리로 shell injection 차단.\n * stdout/stderr는 captured — 사용자에게 한 줄 요약만 노출 (verbose-log는 별도 옵션 후속).\n */\n\nimport { type SpawnSyncReturns, spawnSync } from \"node:child_process\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { CATEGORIES as CATEGORY_ORDER } from \"./categories.js\";\nimport {\n EXTERNAL_ASSETS,\n type ExternalAsset,\n type ExternalAssetMethod,\n filterApplicableAssets,\n} from \"./external-assets.js\";\nimport {\n type CliTargets,\n type InstallScope,\n type OptionFlags,\n resolveScope,\n type Track,\n} from \"./types.js\";\n\nexport interface ExternalInstallerDeps {\n /** Override `spawnSync` for tests (mock으로 호출 횟수 + args 검증). */\n spawn?: (cmd: string, args: ReadonlyArray<string>, opts: SpawnOpts) => SpawnSyncReturns<string>;\n /** harness root (prune-ecc.sh script 위치 resolve용). */\n harnessRoot?: string;\n /** asset 매트릭스 override (테스트용, 기본 EXTERNAL_ASSETS 전체). */\n assets?: ReadonlyArray<ExternalAsset>;\n /** 진행 상황 로그 stream (기본 console.log). 일반 로그용. */\n log?: (msg: string) => void;\n /** 경고 메시지 stream (기본 console.error). */\n warn?: (msg: string) => void;\n /**\n * 자산 설치 시작 직전 호출 (streaming UI용).\n * Renderer가 \"→ asset (installing...)\" 라인 출력에 사용.\n */\n onAssetStart?: (asset: ExternalAsset) => void;\n /**\n * 자산 설치 완료 후 호출 (streaming UI용).\n * Renderer가 \"✓/⊘ asset meta\" 라인 출력에 사용.\n */\n onAssetResult?: (result: AssetInstallResult) => void;\n}\n\ninterface SpawnOpts {\n encoding: \"utf8\";\n stdio: (\"ignore\" | \"pipe\")[] | \"ignore\" | \"pipe\";\n timeout?: number;\n /** v26.77.0 — 작업 디렉토리. projectDir 로 고정해 자산이 올바른 프로젝트에 착지. */\n cwd?: string;\n}\n\nexport interface AssetInstallResult {\n asset: ExternalAsset;\n ok: boolean;\n /** ok=false 시 user-facing 메시지 */\n message?: string;\n /**\n * v26.59.0 — 설치된 자산 version. install 후 detectVersion 으로 path 기반 추출.\n * plugin: ~/.claude/plugins/cache/<marketplace>/<plugin>/<VERSION>/ 디렉토리명\n * npm-global: <npm root -g>/<pkg>/package.json 의 version\n * 그 외 method (skill, npx-run, shell-script): 표준 metadata 없음 → undefined.\n */\n version?: string;\n}\n\nexport interface ExternalInstallReport {\n /** 적용 시도된 자산 (조건 통과한 것만) */\n attempted: ReadonlyArray<AssetInstallResult>;\n /** 성공 갯수 */\n succeeded: number;\n /** warn-skip 된 갯수 */\n skipped: number;\n}\n\nconst DEFAULT_SPAWN_TIMEOUT_MS = 120_000;\n\n/**\n * spec에 적용 가능한 자산을 모두 시도. 실패는 warn-skip (기본).\n */\nexport function runExternalInstall(\n ctx: {\n tracks: ReadonlyArray<Track>;\n options: OptionFlags;\n cli: CliTargets;\n /** v26.47.0 — Phase C full user override (forceInclude/forceExclude). */\n userOverride?: { forceInclude: ReadonlyArray<string>; forceExclude: ReadonlyArray<string> };\n /** v26.64.0 (ADR-020) — Install scope. undefined → default \"project\". */\n scope?: InstallScope;\n /**\n * v26.77.0 — 외부 설치기 spawn 의 작업 디렉토리.\n * 미지정 시 process.cwd(). 핵심: npm(--save-dev)·npx-run(bmad --directory .)·\n * plugin(--scope project, claude 의 cwd 기반 project 탐지)·skill 이 모두 cwd 기준으로\n * 착지하므로, --project-dir 가 cwd 와 다르면 cwd 를 projectDir 로 맞춰야 자산이 올바른\n * 프로젝트에 떨어진다 (이 누락 = 2026-06-07 probe 가 repo 를 오염시킨 근본 원인).\n */\n projectDir?: string;\n },\n deps: ExternalInstallerDeps = {},\n): ExternalInstallReport {\n const log = deps.log ?? console.log;\n const warn = deps.warn ?? console.error;\n const spawn = deps.spawn ?? defaultSpawn;\n const assets = deps.assets ?? EXTERNAL_ASSETS;\n const harnessRoot = deps.harnessRoot ?? process.cwd();\n const projectDir = ctx.projectDir ?? process.cwd();\n\n // v26.81.0 (ADR-022) — internal 자산(tauri-desktop/uzys-harness)은 Phase 1 의\n // manifest/transform 이 설치 주체 — external(spawn) 단계에서 제외. Phase 1 의\n // templates 행으로 사용자에게 이미 가시화됨 (중복 보고 방지).\n const applicable = filterApplicableAssets(assets, ctx).filter(\n (a) => a.method.kind !== \"internal\",\n );\n // v26.55.0 — Phase 2 grouped progress UX. 카테고리 순서로 정렬 → install.ts 의 onAssetStart\n // callback 이 category 변경 감지로 헤더 출력 가능. ADR-016.\n const sorted = [...applicable].sort((a, b) => {\n const ai = CATEGORY_ORDER.indexOf(a.category);\n const bi = CATEGORY_ORDER.indexOf(b.category);\n return ai - bi;\n });\n const attempted: AssetInstallResult[] = [];\n const cli = ctx.cli;\n const scope = resolveScope(ctx.scope);\n\n for (const asset of sorted) {\n deps.onAssetStart?.(asset);\n log(` → ${asset.description}`);\n const baseResult = installOne(asset, { spawn, harnessRoot, cli, scope, projectDir });\n let result: AssetInstallResult = baseResult;\n if (baseResult.ok) {\n const v = detectVersion(asset.method, spawn);\n if (v) result = { ...baseResult, version: v };\n }\n deps.onAssetResult?.(result);\n\n if (!result.ok) {\n // v26.79.0 — 모든 실패는 warn-skip (abort 는 vibe killer 라 미채택). 죽은\n // failureMode/aborted 메커니즘 제거 (사용 자산 0 + 렌더러 미참조).\n warn(` [warn-skip] ${asset.id}: ${result.message ?? \"failed\"}`);\n }\n\n attempted.push(result);\n }\n\n return {\n attempted,\n succeeded: attempted.filter((r) => r.ok).length,\n skipped: attempted.filter((r) => !r.ok).length,\n };\n}\n\n/**\n * 자산 1개 설치. method.kind 별 적절한 명령 실행.\n */\nfunction installOne(\n asset: ExternalAsset,\n ctx: {\n spawn: NonNullable<ExternalInstallerDeps[\"spawn\"]>;\n harnessRoot: string;\n cli: CliTargets;\n scope: InstallScope;\n /** v26.77.0 — spawn cwd. 자산이 올바른 프로젝트에 착지하도록 projectDir 로 고정. */\n projectDir: string;\n },\n): AssetInstallResult {\n const { method } = asset;\n const cwd = ctx.projectDir;\n switch (method.kind) {\n case \"skill\":\n return runSpawn(asset, ctx.spawn, \"npx\", buildSkillArgs(method, ctx.cli, ctx.scope), cwd);\n case \"plugin\":\n return installPlugin(asset, ctx.spawn, method, ctx.scope, cwd);\n case \"npm\": {\n // v26.64.0 (ADR-020) — scope=project 시 devDep, scope=global 시 -g.\n // v26.68.0 — method.kind \"npm-global\" → \"npm\" rename (scope 분기와 무관 의미).\n // v26.80.0 — pinned 버전 설치 (`pkg@version`). vetting 시점의 코드만 실행 (보안 wedge).\n const pinned = `${method.pkg}@${method.version}`;\n return runSpawn(\n asset,\n ctx.spawn,\n \"npm\",\n ctx.scope === \"global\" ? [\"install\", \"-g\", pinned] : [\"install\", \"--save-dev\", pinned],\n cwd,\n );\n }\n case \"npx-run\":\n // v26.80.0 — pinned 버전 실행 (`cmd@version`). 이전 `cmd` 에 \"@latest\" 인라인이던 것을\n // 구조 필드로 분리 (cmd 는 bare 이름 — drift override/라벨이 이름 그대로 사용).\n return runSpawn(\n asset,\n ctx.spawn,\n \"npx\",\n [`${method.cmd}@${method.version}`, ...(method.args ?? [])],\n cwd,\n );\n case \"shell-script\": {\n const scriptPath = join(ctx.harnessRoot, method.script);\n if (!existsSync(scriptPath)) {\n return {\n asset,\n ok: false,\n message: `script not found: ${scriptPath}`,\n };\n }\n return runSpawn(asset, ctx.spawn, \"bash\", [scriptPath, ...method.args], cwd);\n }\n case \"internal\":\n // v26.81.0 (ADR-022) — 도달 불가 (runExternalInstall 이 사전 필터). exhaustive switch\n // + 방어: 도달해도 spawn 없이 ok (Phase 1 manifest 가 실 설치 주체).\n return { asset, ok: true, message: \"internal template (installed by Phase 1 manifest)\" };\n }\n}\n\n/**\n * v26.39.5 fix — `--agent <list>` 명시 추가 (사용자 보고 #3 진짜 fix).\n *\n * `npx skills add` default 동작은 `*` (all installed agents) → universal install →\n * `.factory/skills/`, `.goose/skills/` 자동 생성. v0.8.0 의 `.gitignore` 패턴 추가만으론\n * git noise 만 차단하고 disk 디렉토리 생성은 막지 못함.\n *\n * 본 fix: `spec.cli` 의 base CLI 만 콤마 구분 명시 → 의도된 agent 만 install.\n *\n * v26.39.6 fix — skills CLI agent name 매핑.\n * skills CLI 1.5.5 valid agent 이름은 `claude-code` 인데 우리 CliBase 는 `claude`.\n * 매핑 누락 시 `Invalid agents: claude` 로 exit 1 → 외부 사용자 (DYLD-GoalTrack\n * reproduce 2026-05-06) 환경에서 7건 skill 자산 100% skip.\n */\nconst SKILLS_CLI_AGENT_MAP: Record<CliTargets[number], string> = {\n claude: \"claude-code\",\n codex: \"codex\",\n opencode: \"opencode\",\n // v26.66.0 — Antigravity (Google) skills agent. `.agents/skills/` 표준 공유 (codex transform 산출과 동일).\n antigravity: \"antigravity\",\n};\n\nfunction buildSkillArgs(\n method: { kind: \"skill\"; source: string; skill?: string },\n cli: CliTargets,\n scope: InstallScope,\n): string[] {\n const args = [\"skills\", \"add\", method.source];\n if (method.skill) {\n args.push(\"--skill\", method.skill);\n }\n if (cli.length > 0) {\n // v26.55.1 — skills cli 1.5.7 부터 multi-agent 는 repeatable `--agent` 만 지원.\n for (const c of cli) {\n args.push(\"--agent\", SKILLS_CLI_AGENT_MAP[c] ?? c);\n }\n }\n // v26.64.0 (ADR-020) — global scope 시 -g. project 는 skills CLI default (project) 따름.\n if (scope === \"global\") {\n args.push(\"-g\");\n }\n args.push(\"--yes\");\n return args;\n}\n\n/**\n * Plugin 은 marketplace add → install 두 단계. marketplace add 실패는 무시 (이미 등록 케이스).\n *\n * v26.64.0 (ADR-020) — `--scope <project|user>` 분기. claude CLI native:\n * - project: --scope project (현재 projectPath 격리, installed_plugins.json 메타 매칭)\n * - global: --scope user (모든 projectPath 에서 활성)\n * fs 적으로는 양쪽 모두 ~/.claude/plugins/cache/ + ~/.claude/plugins/marketplaces/ 에 write\n * (claude CLI 자체 디자인). 격리는 메타데이터.\n */\nfunction installPlugin(\n asset: ExternalAsset,\n spawn: NonNullable<ExternalInstallerDeps[\"spawn\"]>,\n method: { kind: \"plugin\"; marketplace: string; pluginId: string },\n scope: InstallScope,\n cwd: string,\n): AssetInstallResult {\n const claudeScope = scope === \"global\" ? \"user\" : \"project\";\n // v26.77.0 — cwd=projectDir: --scope project 시 claude 가 cwd 기준으로 프로젝트를 탐지하므로\n // installed_plugins.json 의 projectPath 가 올바른 프로젝트로 기록된다.\n spawn(\n \"claude\",\n [\"plugin\", \"marketplace\", \"add\", \"--scope\", claudeScope, method.marketplace],\n spawnOpts(cwd),\n );\n return runSpawn(\n asset,\n spawn,\n \"claude\",\n [\"plugin\", \"install\", \"--scope\", claudeScope, method.pluginId],\n cwd,\n );\n}\n\nfunction runSpawn(\n asset: ExternalAsset,\n spawn: NonNullable<ExternalInstallerDeps[\"spawn\"]>,\n cmd: string,\n args: ReadonlyArray<string>,\n cwd?: string,\n): AssetInstallResult {\n const result = spawn(cmd, args, spawnOpts(cwd));\n if (result.error) {\n return { asset, ok: false, message: result.error.message };\n }\n if ((result.status ?? 1) !== 0) {\n const stderr = (result.stderr ?? \"\").trim();\n const tail = stderr.length > 200 ? `${stderr.slice(0, 200)}…` : stderr;\n return {\n asset,\n ok: false,\n message: `${cmd} exited ${result.status}${tail ? `: ${tail}` : \"\"}`,\n };\n }\n return { asset, ok: true };\n}\n\nfunction spawnOpts(cwd?: string): SpawnOpts {\n return {\n encoding: \"utf8\",\n stdio: \"pipe\",\n timeout: DEFAULT_SPAWN_TIMEOUT_MS,\n ...(cwd ? { cwd } : {}),\n };\n}\n\n/* v8 ignore next 7 — thin dep-inject default. tests 는 항상 spawn 주입. */\nfunction defaultSpawn(\n cmd: string,\n args: ReadonlyArray<string>,\n opts: SpawnOpts,\n): SpawnSyncReturns<string> {\n return spawnSync(cmd, [...args], opts);\n}\n\n/**\n * v26.59.0 — install 후 path 기반 version 추출.\n *\n * 안전 원칙: 실패 시 undefined 반환 (silent). install 성공 자체는 이미 검증됨.\n *\n * - plugin: ~/.claude/plugins/cache/<marketplace>/<plugin>/<VERSION>/ 디렉토리명 (semver-like 만)\n * - npm-global: <npm root -g>/<pkg>/package.json 의 version\n * - skill / npx-run / shell-script: 표준 metadata 위치 없음 → undefined\n */\nfunction detectVersion(\n method: ExternalAssetMethod,\n spawn: NonNullable<ExternalInstallerDeps[\"spawn\"]>,\n): string | undefined {\n try {\n switch (method.kind) {\n case \"plugin\": {\n // pluginId = \"<plugin>@<marketplace-short>\". cache path:\n // ~/.claude/plugins/cache/<marketplace-short>/<plugin>/<VERSION>/\n // method.marketplace 는 GH `<user>/<repo>` (다른 값) 이라 path 에 사용 X.\n const at = method.pluginId.lastIndexOf(\"@\");\n if (at <= 0) return undefined;\n const plugin = method.pluginId.slice(0, at);\n const marketplaceShort = method.pluginId.slice(at + 1);\n const cacheBase = join(homedir(), \".claude/plugins/cache\", marketplaceShort, plugin);\n if (!existsSync(cacheBase)) return undefined;\n const versions = readdirSync(cacheBase)\n .filter((v) => /^\\d/.test(v))\n .sort();\n return versions.at(-1);\n }\n case \"npm\": {\n const npmRoot = getNpmGlobalRoot(spawn);\n if (!npmRoot) return undefined;\n const pkgJson = join(npmRoot, method.pkg, \"package.json\");\n if (!existsSync(pkgJson)) return undefined;\n const parsed = JSON.parse(readFileSync(pkgJson, \"utf8\")) as { version?: string };\n return parsed.version;\n }\n default:\n return undefined;\n }\n } catch {\n return undefined;\n }\n}\n\nlet npmGlobalRootCache: string | undefined;\n\n/* v8 ignore start — npm CLI 실행 + cache. 실 시스템 의존. detectVersion (plugin 외 method) 가 본 함수 호출. */\nfunction getNpmGlobalRoot(spawn: NonNullable<ExternalInstallerDeps[\"spawn\"]>): string | undefined {\n if (npmGlobalRootCache !== undefined) return npmGlobalRootCache || undefined;\n try {\n const r = spawn(\"npm\", [\"root\", \"-g\"], spawnOpts());\n if ((r.status ?? 1) === 0) {\n npmGlobalRootCache = (r.stdout ?? \"\").trim();\n return npmGlobalRootCache || undefined;\n }\n } catch {\n // fallthrough\n }\n npmGlobalRootCache = \"\";\n return undefined;\n}\n/* v8 ignore stop */\n\n/**\n * 누락(skip) 자산 목록을 사용자 보고용 텍스트로 포맷.\n */\nexport function formatSkippedReport(report: ExternalInstallReport): string {\n const failed = report.attempted.filter((r) => !r.ok);\n if (failed.length === 0) return \"\";\n const lines = failed.map((r) => ` • ${r.asset.id} — ${r.message ?? \"failed\"}`);\n return [\n `${failed.length}개 외부 자산이 설치되지 않았습니다 (warn-skip):`,\n ...lines,\n \"\",\n \"Manual install or retry needed. See docs/REFERENCE.md or README.md for details.\",\n ].join(\"\\n\");\n}\n","/**\n * Install log — `.claude/.harness-install.json`.\n *\n * v26.64.0 (ADR-020) — install 종료 시 자산 list + scope + timestamp 기록.\n * uninstall command 가 본 log 를 읽어 정확한 reverse 수행.\n *\n * 글로벌 자산 (scope=global 또는 codexOptIn) 은 log 에 안내용으로만 기록 — uninstall 시 자동 삭제 X (D16).\n */\n\nimport { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { ExternalAsset, ExternalAssetMethod } from \"./external-assets.js\";\nimport type { ExternalInstallReport } from \"./external-installer.js\";\nimport type { InstallScope, InstallSpec } from \"./types.js\";\n\nexport const INSTALL_LOG_FILENAME = \".harness-install.json\";\nexport const INSTALL_LOG_VERSION = 1;\n\nexport interface InstallLogAsset {\n id: string;\n category: string;\n /** External asset method.kind 그대로. uninstall reverse 시 분기 기준. */\n method: ExternalAssetMethod[\"kind\"];\n /** scope=global 자산은 uninstall 시 안내만 (D16 — 글로벌 자동 삭제 금지). */\n scope: InstallScope;\n /** method 별 추가 정보. plugin: marketplace + pluginId. skill: source. npm: pkg. */\n detail: Record<string, string>;\n /** installed 시점 version (detectVersion 결과, 없으면 undefined). */\n version?: string;\n}\n\nexport interface InstallLog {\n /** schema version — backward compat 검출용 */\n schemaVersion: number;\n /** harness 가 install 한 시점 ISO timestamp */\n installedAt: string;\n /** 전체 install scope. 자산 per-asset scope 와 동일 (현재는 single global scope) */\n scope: InstallScope;\n /** install 시 spec 요약 (tracks/cli — uninstall reasoning 용) */\n spec: {\n tracks: ReadonlyArray<string>;\n cli: ReadonlyArray<string>;\n };\n /** templates 출처 — uninstall 시 templates 제거 위치 */\n templates: {\n /** .claude/ project local */\n claudeDir: string;\n /** .codex/ project local (cli=codex 시) */\n codexDir?: string;\n /** .opencode/ project local (cli=opencode 시) */\n opencodeDir?: string;\n /**\n * project root CLAUDE.md (cli=claude 시 생성).\n * uninstall 시 sha256 이 install 시점과 동일할 때만 삭제 — 사용자가 수정했으면 보존.\n */\n rootClaudeMd?: { path: string; sha256: string };\n };\n /** external-installer 가 install 한 자산 (ok=true 만) */\n assets: ReadonlyArray<InstallLogAsset>;\n}\n\n/**\n * external-installer 의 result 를 InstallLogAsset 으로 변환.\n * ok=false 자산은 제외 (실제 install 안 됨 → uninstall 대상 아님).\n */\nexport function buildAssetEntries(\n report: ExternalInstallReport | null,\n scope: InstallScope,\n): InstallLogAsset[] {\n if (!report) return [];\n return report.attempted\n .filter((r) => r.ok)\n .map((r) => assetToLogEntry(r.asset, scope, r.version));\n}\n\nfunction assetToLogEntry(\n asset: ExternalAsset,\n scope: InstallScope,\n version: string | undefined,\n): InstallLogAsset {\n const detail = methodDetail(asset.method);\n const entry: InstallLogAsset = {\n id: asset.id,\n category: asset.category,\n method: asset.method.kind,\n scope,\n detail,\n };\n if (version) entry.version = version;\n return entry;\n}\n\nfunction methodDetail(method: ExternalAssetMethod): Record<string, string> {\n switch (method.kind) {\n case \"plugin\":\n return { marketplace: method.marketplace, pluginId: method.pluginId };\n case \"skill\":\n return { source: method.source, ...(method.skill ? { skill: method.skill } : {}) };\n case \"npm\":\n return { pkg: method.pkg };\n case \"npx-run\":\n return { cmd: method.cmd, args: (method.args ?? []).join(\" \") };\n case \"shell-script\":\n return { script: method.script, args: method.args.join(\" \") };\n case \"internal\":\n // v26.81.0 (ADR-022) — Phase 1 manifest 가 설치 주체. external 단계에선 미기록이 정상.\n return { key: method.key };\n }\n}\n\nexport function buildInstallLog(\n spec: InstallSpec,\n external: ExternalInstallReport | null,\n scope: InstallScope,\n rootClaudeMd?: { path: string; sha256: string } | null,\n): InstallLog {\n const log: InstallLog = {\n schemaVersion: INSTALL_LOG_VERSION,\n installedAt: new Date().toISOString(),\n scope,\n spec: {\n tracks: spec.tracks,\n cli: spec.cli,\n },\n templates: {\n claudeDir: \".claude/\",\n ...(spec.cli.includes(\"codex\") ? { codexDir: \".codex/\" } : {}),\n ...(spec.cli.includes(\"opencode\") ? { opencodeDir: \".opencode/\" } : {}),\n ...(rootClaudeMd ? { rootClaudeMd } : {}),\n },\n assets: buildAssetEntries(external, scope),\n };\n return log;\n}\n\n/** install log + root CLAUDE.md 등 자산 무결성 비교용 sha256 (hex). */\nexport function hashContent(content: string): string {\n return createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\");\n}\n\n/**\n * install log write. 위치: `<projectDir>/.claude/.harness-install.json`.\n *\n * `.claude/` 는 cli=claude 일 때 baseline phase 에서 생성되지만, codex/opencode/antigravity\n * 단독(claude 미포함) 설치 시엔 생성되지 않는다. 그 경우에도 uninstall 이 본 log 를 읽을 수 있도록\n * write 직전 디렉토리를 보장한다 (없으면 install log 누락 → uninstall 불가).\n */\nexport function writeInstallLog(projectDir: string, log: InstallLog): string {\n const path = join(projectDir, \".claude\", INSTALL_LOG_FILENAME);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(log, null, 2)}\\n`, \"utf8\");\n return path;\n}\n\nexport function readInstallLog(projectDir: string): InstallLog | null {\n const path = join(projectDir, \".claude\", INSTALL_LOG_FILENAME);\n if (!existsSync(path)) return null;\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as InstallLog;\n // v26.68.0 — backward compat: method.kind \"npm-global\" → \"npm\" rename.\n // v26.64.0 ~ v26.67.0 시점 install log 가 새 uninstall 에서 작동하도록 normalize.\n if (Array.isArray(parsed.assets)) {\n parsed.assets = parsed.assets.map((a) =>\n (a.method as string) === \"npm-global\" ? { ...a, method: \"npm\" } : a,\n );\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport function installLogPath(projectDir: string): string {\n return join(projectDir, \".claude\", INSTALL_LOG_FILENAME);\n}\n","import { anyTrack, hasDevTrack, hasUiTrack } from \"./track-match.js\";\nimport type { Track } from \"./types.js\";\n\n/**\n * Source-relative paths under `templates/` map to project-relative targets under\n * the project root (typically `.claude/...` or `CLAUDE.md`).\n *\n * Each entry declares an `applies(spec)` predicate based on the selected tracks.\n * Phase C scope: rules + commands + agents + base skills + hooks + project CLAUDE.md.\n * Phase E will extend with the remaining track-specific skills.\n */\n\nexport interface AssetSpec {\n /** Selected tracks (union). */\n tracks: ReadonlyArray<Track>;\n /**\n * Optional opt-in: --with-tauri.\n * Note: copied from `OptionFlags.withTauri` by installer; keep both fields in sync\n * when adding new opt-in flags that affect manifest gating.\n */\n withTauri?: boolean;\n /**\n * v26.44.0 — uzys-harness 6-Gate slash commands opt-in (BREAKING).\n * Note: copied from `OptionFlags.withUzysHarness` by installer; keep both fields in sync.\n * Track-independent: opt-in on ANY track installs `/uzys:*` commands. SPEC R7.\n */\n withUzysHarness?: boolean;\n /**\n * v26.58.0 — withEcc opt-out gating (BREAKING vs v26.55.0). ADR-019 supersedes ADR-016 부분.\n * Note: copied from `OptionFlags.withEcc` by installer; keep both fields in sync.\n *\n * 정책 (cherry-pick × plugin gating):\n * - C1 (단순 중복): 매핑 자체 삭제. 현재 0개.\n * - C2 (plugin OFF fallback): `applies: (s) => !s.withEcc && <track>`. 19개.\n * - C3 (modified or 별개 source): `applies: <track only>` (withEcc 무관 항상 install). 3개.\n *\n * 분류 표 SSOT: docs/PRD/v26-58-cherry-pick-plugin-gating.md §6.\n */\n withEcc?: boolean;\n}\n\nexport interface AssetEntry {\n source: string; // relative to repo `templates/`\n target: string; // relative to project root\n type: \"file\" | \"dir\";\n applies: (spec: AssetSpec) => boolean;\n}\n\nconst all = (): boolean => true;\nconst dev = (s: AssetSpec): boolean => hasDevTrack(s.tracks);\nconst ui = (s: AssetSpec): boolean => hasUiTrack(s.tracks);\nconst onTracks =\n (pattern: string) =>\n (s: AssetSpec): boolean =>\n anyTrack(s.tracks, pattern);\n\nconst COMMON_RULES = [\"git-policy\", \"change-management\", \"gates-taxonomy\"];\nconst DEV_RULES = [\"test-policy\", \"ship-checklist\", \"code-style\", \"error-handling\"];\nconst UI_RULES = [\"design-workflow\", \"playwright-launch\"];\n\nconst TRACK_RULES: Record<Track, string[]> = {\n \"csr-supabase\": [\"shadcn\", \"api-contract\"],\n \"csr-fastify\": [\"shadcn\", \"api-contract\", \"database\"],\n \"csr-fastapi\": [\"shadcn\", \"api-contract\", \"database\"],\n \"ssr-htmx\": [\"htmx\"],\n \"ssr-nextjs\": [\"nextjs\", \"shadcn\"],\n data: [\"pyside6\", \"data-analysis\"],\n executive: [],\n tooling: [\"cli-development\"],\n full: [\n \"shadcn\",\n \"api-contract\",\n \"database\",\n \"htmx\",\n \"nextjs\",\n \"pyside6\",\n \"data-analysis\",\n \"cli-development\",\n ],\n // v0.5.0 — executive-style baselines (no dev rules; common rules only).\n \"project-management\": [],\n \"growth-marketing\": [],\n};\n\n/** Resolve the unique set of rule names to install for the given spec. */\nexport function resolveRules(spec: AssetSpec): string[] {\n const set = new Set<string>(COMMON_RULES);\n if (hasDevTrack(spec.tracks)) {\n for (const r of DEV_RULES) {\n set.add(r);\n }\n }\n if (spec.withTauri && anyTrack(spec.tracks, \"csr-*|full\")) {\n set.add(\"tauri\");\n }\n if (hasUiTrack(spec.tracks)) {\n for (const r of UI_RULES) {\n set.add(r);\n }\n }\n for (const t of spec.tracks) {\n for (const r of TRACK_RULES[t]) {\n set.add(r);\n }\n }\n return [...set].sort();\n}\n\nconst UZYS_COMMANDS = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\", \"auto\"];\n\n// v26.58.0 — ECC cherry-pick × plugin gating. ADR-019.\n// 본 프로젝트 (always): reviewer, data-analyst, strategist\n// ECC cherry-pick C2 (plugin OFF 시 fallback — opt-out gating, !s.withEcc):\n// code-reviewer, security-reviewer, silent-failure-hunter, build-error-resolver\nconst CORE_AGENTS = [\"reviewer\", \"data-analyst\", \"strategist\"];\nconst CORE_AGENTS_ECC = [\"code-reviewer\", \"security-reviewer\"];\n\nconst DEV_AGENTS = [\"plan-checker\"];\nconst DEV_AGENTS_ECC = [\"silent-failure-hunter\", \"build-error-resolver\"];\n\n/** Hooks installed for every project (parity with setup-harness.sh L815-826). */\nconst ALWAYS_HOOKS = [\n \"session-start.sh\",\n \"protect-files.sh\",\n \"gate-check.sh\",\n \"agentshield-gate.sh\",\n \"mcp-pre-exec.sh\",\n \"spec-drift-check.sh\",\n \"checkpoint-snapshot.sh\",\n \"hito-counter.sh\",\n];\n\n// v26.58.0 — ECC cherry-pick × plugin gating. ADR-019.\nconst COMMON_SKILL_DIRS = [\"north-star\", \"gh-issue-workflow\"];\n// C2 (plugin OFF fallback, opt-out): strategic-compact, deep-research.\nconst COMMON_SKILL_DIRS_ECC = [\"strategic-compact\", \"deep-research\"];\n// C3 (modified=true — plugin 으로 갈음 불가, 항상 install): continuous-learning-v2.\nconst MODIFIED_COMMON_SKILL_DIRS = [\"continuous-learning-v2\"];\n\nconst DEV_SKILL_DIRS: string[] = [];\nconst DEV_SKILL_DIRS_ECC = [\"eval-harness\", \"verification-loop\", \"agent-introspection-debugging\"];\n\nconst UI_SKILL_DIRS = [\"ui-visual-review\"];\nconst UI_SKILL_DIRS_ECC = [\"e2e-testing\"];\n\n// python-* skills (data|csr-fastapi|full) — C2 (plugin OFF fallback).\nconst PYTHON_SKILL_DIRS_ECC = [\"python-patterns\", \"python-testing\"];\n\n/** Build the full asset manifest for the given spec. */\nexport function buildManifest(spec: AssetSpec): AssetEntry[] {\n const m: AssetEntry[] = [];\n\n // Rules\n for (const r of resolveRules(spec)) {\n m.push({\n source: `rules/${r}.md`,\n target: `.claude/rules/${r}.md`,\n type: \"file\",\n applies: all,\n });\n }\n\n // uzys: commands (v26.44.0 — opt-in; BREAKING vs prior dev-track auto-install).\n // 본 harness 자체 6-Gate slash commands. Workflow 카테고리의 1 옵션.\n for (const cmd of UZYS_COMMANDS) {\n m.push({\n source: `commands/uzys/${cmd}.md`,\n target: `.claude/commands/uzys/${cmd}.md`,\n type: \"file\",\n applies: (s) => Boolean(s.withUzysHarness),\n });\n }\n\n // ecc: commands — v26.58.0 opt-out gating (BREAKING vs v26.55.0). ADR-019.\n // C2 — plugin OFF 시만 cherry-pick (plugin ON 이면 ecc plugin 의 /ecc:e2e, /ecc:eval, /ecc:harness-audit 사용).\n m.push({\n source: \"commands/ecc\",\n target: \".claude/commands/ecc\",\n type: \"dir\",\n applies: (s) => !s.withEcc,\n });\n\n // Project meta CLAUDE.md\n m.push({\n source: \"CLAUDE.md\",\n target: \".claude/CLAUDE.md\",\n type: \"file\",\n applies: all,\n });\n\n // Agents (본 프로젝트)\n for (const a of CORE_AGENTS) {\n m.push({\n source: `agents/${a}.md`,\n target: `.claude/agents/${a}.md`,\n type: \"file\",\n applies: all,\n });\n }\n for (const a of DEV_AGENTS) {\n m.push({\n source: `agents/${a}.md`,\n target: `.claude/agents/${a}.md`,\n type: \"file\",\n applies: dev,\n });\n }\n // v26.58.0 — Agents (ECC cherry-pick). ADR-019. C2: plugin OFF 시만 install (opt-out).\n for (const a of CORE_AGENTS_ECC) {\n m.push({\n source: `agents/${a}.md`,\n target: `.claude/agents/${a}.md`,\n type: \"file\",\n applies: (s) => !s.withEcc,\n });\n }\n for (const a of DEV_AGENTS_ECC) {\n m.push({\n source: `agents/${a}.md`,\n target: `.claude/agents/${a}.md`,\n type: \"file\",\n applies: (s) => !s.withEcc && hasDevTrack(s.tracks),\n });\n }\n\n // Common skill directories\n for (const sd of COMMON_SKILL_DIRS) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: all,\n });\n }\n // v26.58.0 — Common skill dirs (ECC cherry-pick). ADR-019. C2: plugin OFF 시만 install (opt-out).\n for (const sd of COMMON_SKILL_DIRS_ECC) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: (s) => !s.withEcc,\n });\n }\n // v26.58.0 — C3 (modified=true). plugin 으로 갈음 불가, 항상 install. ADR-019.\n for (const sd of MODIFIED_COMMON_SKILL_DIRS) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: all,\n });\n }\n m.push({\n source: \"skills/spec-scaling/SKILL.md\",\n target: \".claude/skills/spec-scaling/SKILL.md\",\n type: \"file\",\n applies: all,\n });\n m.push({\n source: \"skills/market-research\",\n target: \".claude/skills/market-research\",\n type: \"dir\",\n applies: onTracks(\"executive|full\"),\n });\n for (const sd of [\"investor-materials\", \"investor-outreach\"]) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: onTracks(\"executive|full\"),\n });\n }\n m.push({\n source: \"skills/nextjs-turbopack\",\n target: \".claude/skills/nextjs-turbopack\",\n type: \"dir\",\n applies: onTracks(\"ssr-nextjs|full\"),\n });\n // v26.58.0 — python-* / DEV_SKILL_DIRS / UI_SKILL_DIRS 중 ECC 출처는 opt-out gating. ADR-019. C2.\n for (const sd of PYTHON_SKILL_DIRS_ECC) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: (s) => !s.withEcc && anyTrack(s.tracks, \"data|csr-fastapi|full\"),\n });\n }\n for (const sd of DEV_SKILL_DIRS) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: dev,\n });\n }\n for (const sd of DEV_SKILL_DIRS_ECC) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: (s) => !s.withEcc && hasDevTrack(s.tracks),\n });\n }\n for (const sd of UI_SKILL_DIRS) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: ui,\n });\n }\n for (const sd of UI_SKILL_DIRS_ECC) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: (s) => !s.withEcc && hasUiTrack(s.tracks),\n });\n }\n\n // Hooks\n for (const h of ALWAYS_HOOKS) {\n m.push({\n source: `hooks/${h}`,\n target: `.claude/hooks/${h}`,\n type: \"file\",\n applies: all,\n });\n }\n\n // settings.json\n m.push({\n source: \"settings.json\",\n target: \".claude/settings.json\",\n type: \"file\",\n applies: all,\n });\n\n // Project root CLAUDE.md — handled outside manifest by `mergeProjectClaude`\n // (single/multi/full tracks all merged from fragments in installer.ts).\n\n return m;\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { anyTrack } from \"./track-match.js\";\nimport type { Track } from \"./types.js\";\n\nexport interface McpServerConfig {\n type?: \"stdio\" | \"http\";\n command: string;\n args: string[];\n env?: Record<string, string>;\n}\n\nexport interface McpJson {\n mcpServers: Record<string, McpServerConfig>;\n _comment?: string;\n}\n\nexport interface TrackMcpRow {\n name: string;\n pattern: string;\n command: string;\n args: string[];\n}\n\n/** Parse `templates/track-mcp-map.tsv` (tab-separated, comment-aware). */\nexport function parseTrackMcpMap(raw: string): TrackMcpRow[] {\n const rows: TrackMcpRow[] = [];\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) {\n continue;\n }\n const parts = line.split(\"\\t\");\n if (parts.length < 4) {\n continue;\n }\n const [name, pattern, command, argsJson] = parts;\n if (!name || !pattern || !command) {\n continue;\n }\n let args: unknown;\n try {\n args = JSON.parse(argsJson ?? \"[]\");\n } catch {\n continue;\n }\n if (!Array.isArray(args) || !args.every((a) => typeof a === \"string\")) {\n continue;\n }\n rows.push({ name, pattern, command, args: args as string[] });\n }\n return rows;\n}\n\n/**\n * Apply track-aware MCP rows to a base `.mcp.json` object.\n * Existing entries (including user customizations) are preserved.\n */\nexport function mergeMcpServers(\n base: McpJson,\n rows: ReadonlyArray<TrackMcpRow>,\n tracks: ReadonlyArray<Track>,\n): McpJson {\n const out: McpJson = {\n ...base,\n mcpServers: { ...base.mcpServers },\n };\n for (const row of rows) {\n if (!anyTrack(tracks, row.pattern)) {\n continue;\n }\n if (out.mcpServers[row.name]) {\n // Preserve existing — do not overwrite user customizations.\n continue;\n }\n out.mcpServers[row.name] = {\n type: \"stdio\",\n command: row.command,\n args: row.args,\n };\n }\n // Strip _comment marker (parity with the bash `jq 'del(._comment)'`).\n delete out._comment;\n return out;\n}\n\n/**\n * Compose the final `.mcp.json` for a project install.\n * Read base template + track map, merge with optional existing user file (additive).\n */\nexport function composeMcpJson(opts: {\n templateMcpPath: string;\n trackMapPath: string;\n existingPath?: string;\n tracks: ReadonlyArray<Track>;\n}): McpJson {\n const base = JSON.parse(readFileSync(opts.templateMcpPath, \"utf8\")) as McpJson;\n const merged =\n opts.existingPath && existsSync(opts.existingPath)\n ? mergeUserBase(base, opts.existingPath)\n : base;\n const mapRaw = existsSync(opts.trackMapPath) ? readFileSync(opts.trackMapPath, \"utf8\") : \"\";\n const rows = parseTrackMcpMap(mapRaw);\n return mergeMcpServers(merged, rows, opts.tracks);\n}\n\nfunction mergeUserBase(base: McpJson, existingPath: string): McpJson {\n try {\n const existing = JSON.parse(readFileSync(existingPath, \"utf8\")) as McpJson;\n return {\n ...base,\n mcpServers: { ...base.mcpServers, ...existing.mcpServers },\n };\n } catch {\n return base;\n }\n}\n\n/** Write the composed `.mcp.json` to disk (2-space pretty). */\nexport function writeMcpJson(path: string, mcp: McpJson): void {\n writeFileSync(path, `${JSON.stringify(mcp, null, 2)}\\n`);\n}\n","/**\n * OpenCode transform orchestrator — SSOT (templates/CLAUDE.md, .mcp.json,\n * templates/commands/uzys/*.md) → OpenCode 자산 4종.\n *\n * Inputs:\n * - harnessRoot: repository root (templates/ + .mcp.json)\n * - projectDir: target project to receive AGENTS.md + opencode.json + .opencode/\n *\n * Outputs (under projectDir):\n * - AGENTS.md\n * - opencode.json\n * - .opencode/commands/uzys-{phase}.md (6 commands)\n * - .opencode/plugins/uzys-harness.ts (1 plugin stub, Phase E1에서 본문 작성)\n *\n * SPEC: docs/specs/opencode-compat.md\n * Phase: C1 (transform orchestrator)\n */\n\nimport { copyFileSync, existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport { ensureDir } from \"../fs-ops.js\";\nimport type { McpJson } from \"../mcp-merge.js\";\nimport { renderAgentsMd } from \"./agents-md.js\";\nimport { renderCommand } from \"./commands.js\";\nimport { renderOpencodeJson } from \"./opencode-json.js\";\n\nexport interface OpencodeTransformParams {\n harnessRoot: string;\n projectDir: string;\n}\n\nexport interface OpencodeTransformReport {\n agentsMdPath: string;\n opencodeJsonPath: string;\n commandFiles: string[];\n pluginPath: string;\n}\n\nconst PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"];\n\nexport function runOpencodeTransform(params: OpencodeTransformParams): OpencodeTransformReport {\n const { harnessRoot, projectDir } = params;\n\n const claudeMd = readRequired(join(harnessRoot, \"templates/CLAUDE.md\"));\n const agentsTemplate = readRequired(join(harnessRoot, \"templates/opencode/AGENTS.md.template\"));\n const opencodeTemplate = readRequired(\n join(harnessRoot, \"templates/opencode/opencode.json.template\"),\n );\n const projectName = basename(projectDir);\n const mcp = readOptionalJson(join(harnessRoot, \".mcp.json\"));\n\n // 1. AGENTS.md\n ensureDir(projectDir);\n const agentsMdPath = join(projectDir, \"AGENTS.md\");\n writeFileSync(agentsMdPath, renderAgentsMd({ template: agentsTemplate, claudeMd, projectName }));\n\n // 2. opencode.json\n const opencodeJsonPath = join(projectDir, \"opencode.json\");\n writeFileSync(opencodeJsonPath, renderOpencodeJson({ template: opencodeTemplate, mcp }));\n\n // 3. .opencode/commands/uzys-{phase}.md\n const cmdDir = join(projectDir, \".opencode/commands\");\n ensureDir(cmdDir);\n const commandFiles: string[] = [];\n for (const phase of PHASES) {\n const cmdSrc = join(harnessRoot, \"templates/commands/uzys\", `${phase}.md`);\n let source = \"\";\n if (existsSync(cmdSrc)) {\n source = readFileSync(cmdSrc, \"utf8\");\n } else {\n const fallback = join(\n harnessRoot,\n \"templates/opencode/.opencode/commands\",\n `uzys-${phase}.md`,\n );\n if (existsSync(fallback)) {\n source = readFileSync(fallback, \"utf8\");\n }\n }\n const target = join(cmdDir, `uzys-${phase}.md`);\n writeFileSync(target, renderCommand({ source, phase }));\n commandFiles.push(target);\n }\n\n // 4. .opencode/plugins/uzys-harness.ts (static copy from template; Phase E1 fills body)\n const pluginDir = join(projectDir, \".opencode/plugins\");\n ensureDir(pluginDir);\n const pluginPath = join(pluginDir, \"uzys-harness.ts\");\n const pluginSrc = join(harnessRoot, \"templates/opencode/.opencode/plugins/uzys-harness.ts\");\n if (existsSync(pluginSrc)) {\n copyFileSync(pluginSrc, pluginPath);\n } else {\n writeFileSync(pluginPath, \"// uzys-harness plugin stub (template missing)\\n\");\n }\n\n return { agentsMdPath, opencodeJsonPath, commandFiles, pluginPath };\n}\n\nfunction readRequired(path: string): string {\n if (!existsSync(path)) {\n throw new Error(`OpenCode transform: required source missing: ${path}`);\n }\n return readFileSync(path, \"utf8\");\n}\n\nfunction readOptionalJson(path: string): McpJson | null {\n if (!existsSync(path)) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as McpJson;\n } catch {\n return null;\n }\n}\n","/**\n * AGENTS.md transform — CLAUDE.md → AGENTS.md (OpenCode flavor).\n *\n * Mirrors `src/codex/agents-md.ts` logic (Codex와 OpenCode 둘 다 콜론 namespace\n * 미사용으로 slash rename 동일). 별도 파일로 유지 — 모듈 독립성.\n *\n * v26.70.0 — section 추출 → CLAUDE.md 전문 embed (`{PROJECT_RULES}`). codex/agents-md 와 동일 fix.\n */\n\n/** Rename Claude slash conventions (`/uzys:foo`) to OpenCode (`/uzys-foo`). */\nexport function renameSlashes(text: string): string {\n return text.replaceAll(\"/uzys:\", \"/uzys-\");\n}\n\nexport interface AgentsMdParams {\n template: string;\n claudeMd: string;\n projectName: string;\n}\n\n/**\n * Render the OpenCode AGENTS.md output by embedding the full CLAUDE.md body.\n *\n * Placeholders (matches templates/opencode/AGENTS.md.template):\n * - {PROJECT_NAME} — basename of project dir\n * - {PROJECT_RULES} — full CLAUDE.md body (first h1 stripped)\n */\nexport function renderAgentsMd(params: AgentsMdParams): string {\n const body = params.claudeMd.replace(/^#\\s+.*\\r?\\n/, \"\").trim();\n const replaced = params.template\n .replaceAll(\"{PROJECT_NAME}\", params.projectName)\n .replaceAll(\"{PROJECT_RULES}\", body);\n return renameSlashes(replaced);\n}\n","/**\n * Claude `.claude/commands/uzys/<phase>.md` → OpenCode `.opencode/commands/uzys-<phase>.md`.\n *\n * 차이 (Codex skills.ts와):\n * - OpenCode 파일명 = 슬래시 커맨드명 → `uzys-<phase>.md` 형식\n * - Frontmatter: `description` + `agent` (build/plan), `name` 필드 없음 (filename 자체)\n */\nimport { renameSlashes } from \"./agents-md.js\";\n\nexport interface RenderCommandParams {\n /** Original uzys command markdown (frontmatter optional). */\n source: string;\n /** Phase identifier (spec, plan, build, test, review, ship). */\n phase: string;\n}\n\nconst AGENT_BY_PHASE: Record<string, string> = {\n spec: \"plan\",\n plan: \"plan\",\n build: \"build\",\n test: \"build\",\n review: \"plan\",\n ship: \"build\",\n};\n\n/**\n * Render an OpenCode `.opencode/commands/uzys-<phase>.md` from a Claude\n * `.claude/commands/uzys/<phase>.md` source. Slash references are renamed.\n */\nexport function renderCommand(params: RenderCommandParams): string {\n const { description, body } = parseSource(params.source);\n const finalDescription = description || `uzys-${params.phase} phase command (OpenCode 포팅)`;\n const escapedDesc = finalDescription.replace(/\"/g, '\\\\\"');\n const agent = AGENT_BY_PHASE[params.phase] ?? \"build\";\n const renamedBody = renameSlashes(body).trimEnd();\n\n return [\n \"---\",\n `description: \"${escapedDesc}\"`,\n `agent: ${agent}`,\n \"---\",\n \"\",\n renamedBody,\n \"\",\n ].join(\"\\n\");\n}\n\ninterface ParsedSource {\n description: string;\n body: string;\n}\n\nfunction parseSource(source: string): ParsedSource {\n const lines = source.split(/\\r?\\n/);\n if (lines[0] === \"---\") {\n let descMatch = \"\";\n let secondDelimAt = -1;\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (line === \"---\") {\n secondDelimAt = i;\n break;\n }\n const match = line.match(/^description:\\s*(.*)$/);\n if (match) {\n descMatch = stripQuotes(match[1] ?? \"\");\n }\n }\n const body = secondDelimAt >= 0 ? lines.slice(secondDelimAt + 1).join(\"\\n\") : source;\n return { description: descMatch, body: body.replace(/^\\n+/, \"\") };\n }\n const firstLine = lines[0] ?? \"\";\n const body = lines.slice(1).join(\"\\n\");\n return { description: firstLine.trim(), body };\n}\n\nfunction stripQuotes(raw: string): string {\n const trimmed = raw.trim();\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n}\n","/**\n * opencode.json transform — fill template + merge mcp.<name> from .mcp.json.\n *\n * Output: opencode.json (top-level `mcp.<name>` map; OpenCode 1:1 매핑).\n *\n * Codex `[mcp_servers.X]` TOML과 다르게 OpenCode는 JSON이라 Object spread\n * 만으로 충분 (TOML 직렬화 없음).\n */\n\nimport type { McpJson, McpServerConfig } from \"../mcp-merge.js\";\n\nexport interface RenderOpencodeJsonParams {\n /** Template content (templates/opencode/opencode.json.template). */\n template: string;\n /** Source `.mcp.json` (parsed). When provided, top-level `mcp.<name>` is replaced. */\n mcp?: McpJson | null;\n}\n\ninterface OpencodeConfig {\n $schema?: string;\n instructions?: string[];\n mcp?: Record<string, McpServerConfig>;\n command?: Record<string, unknown>;\n agent?: Record<string, unknown>;\n plugin?: string[];\n permission?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\n/**\n * Substitute `mcp` in the template with entries from `.mcp.json`.\n * Other keys (`agent`, `command`, `plugin`, `permission`, `instructions`,\n * `$schema`) are preserved from the template.\n */\nexport function renderOpencodeJson(params: RenderOpencodeJsonParams): string {\n const config = parseTemplate(params.template);\n\n if (params.mcp) {\n config.mcp = { ...params.mcp.mcpServers };\n }\n\n return `${JSON.stringify(config, null, 2)}\\n`;\n}\n\nfunction parseTemplate(template: string): OpencodeConfig {\n try {\n return JSON.parse(template) as OpencodeConfig;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`opencode.json template invalid JSON: ${message}`);\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Track } from \"./types.js\";\n\nexport const SECTIONS = [\n \"stack\",\n \"workflow\",\n \"active-rules\",\n \"agents\",\n \"skills\",\n \"plugins\",\n \"commands\",\n \"boundaries\",\n \"supabase-auth\",\n] as const;\nexport type Section = (typeof SECTIONS)[number];\n\nconst SECTION_TITLES: Record<Section, string> = {\n stack: \"Stack\",\n workflow: \"Workflow\",\n \"active-rules\": \"Active Rules\",\n agents: \"Agents\",\n skills: \"Skills\",\n plugins: \"Plugins\",\n commands: \"Commands\",\n boundaries: \"Boundaries\",\n \"supabase-auth\": \"Supabase auth configuration\",\n};\n\nexport const TRACK_DISPLAY_NAMES: Record<Track, string> = {\n tooling: \"Tooling\",\n \"csr-supabase\": \"CSR Supabase\",\n \"csr-fastify\": \"CSR Fastify\",\n \"csr-fastapi\": \"CSR FastAPI\",\n \"ssr-htmx\": \"SSR HTMX\",\n \"ssr-nextjs\": \"SSR Next.js\",\n data: \"Data\",\n executive: \"Executive\",\n full: \"Full\",\n \"project-management\": \"Project Management\",\n \"growth-marketing\": \"Growth Marketing\",\n};\n\n/** Tracks expanded when 'full' is selected — every track except 'full' itself. */\nconst FULL_EXPANSION: ReadonlyArray<Track> = [\n \"tooling\",\n \"csr-fastapi\",\n \"csr-fastify\",\n \"csr-supabase\",\n \"ssr-htmx\",\n \"ssr-nextjs\",\n \"data\",\n \"executive\",\n \"project-management\",\n \"growth-marketing\",\n];\n\nexport interface MergeOptions {\n /** Path to `templates/project-claude/` directory. */\n baseDir: string;\n}\n\n/**\n * Build the project root CLAUDE.md by merging `_base.md` with track fragments.\n * - Single track: section bodies inserted verbatim under each `## Section` header.\n * - Multi track: each track's fragment prefixed with `### <Display Name>` subheader.\n * - Section with no fragments from any selected track: section omitted entirely.\n * - 'full' track: expanded to every non-full track.\n */\nexport function mergeProjectClaude(tracks: ReadonlyArray<Track>, opts: MergeOptions): string {\n const expanded = expandTracks(tracks);\n const baseRaw = readFileSync(join(opts.baseDir, \"_base.md\"), \"utf8\");\n\n let output = baseRaw;\n output = output.replace(\"<!-- INSERT: track-list -->\", trackList(expanded));\n output = output.replace(\"<!-- INSERT: tagline -->\", taglineList(expanded, opts.baseDir));\n\n for (const section of SECTIONS) {\n const marker = `<!-- INSERT: ${section} -->`;\n const block = renderSection(section, expanded, opts.baseDir);\n if (block === null) {\n output = stripMarkerLine(output, marker);\n } else {\n output = output.replace(marker, block);\n }\n }\n\n return `${output.replace(/\\n{3,}/g, \"\\n\\n\").trimEnd()}\\n`;\n}\n\nfunction expandTracks(tracks: ReadonlyArray<Track>): ReadonlyArray<Track> {\n if (tracks.includes(\"full\")) {\n return FULL_EXPANSION;\n }\n return tracks;\n}\n\nfunction trackList(tracks: ReadonlyArray<Track>): string {\n return tracks.map((t) => TRACK_DISPLAY_NAMES[t]).join(\", \");\n}\n\nfunction taglineList(tracks: ReadonlyArray<Track>, baseDir: string): string {\n const taglines: string[] = [];\n for (const t of tracks) {\n const path = join(baseDir, \"fragments\", t, \"tagline.md\");\n if (!existsSync(path)) {\n continue;\n }\n const body = readFileSync(path, \"utf8\").trim();\n if (body) {\n taglines.push(body);\n }\n }\n return taglines.join(\" / \");\n}\n\nfunction renderSection(\n section: Section,\n tracks: ReadonlyArray<Track>,\n baseDir: string,\n): string | null {\n const present: { track: Track; body: string }[] = [];\n for (const t of tracks) {\n const path = join(baseDir, \"fragments\", t, `${section}.md`);\n if (!existsSync(path)) {\n continue;\n }\n const body = readFileSync(path, \"utf8\").trim();\n if (body) {\n present.push({ track: t, body });\n }\n }\n if (present.length === 0) {\n return null;\n }\n const title = `## ${SECTION_TITLES[section]}`;\n if (present.length === 1 && present[0]) {\n return `${title}\\n\\n${present[0].body}\\n`;\n }\n const blocks = present.map(({ track, body }) => `### ${TRACK_DISPLAY_NAMES[track]}\\n\\n${body}`);\n return `${title}\\n\\n${blocks.join(\"\\n\\n\")}\\n`;\n}\n\n/** Remove a marker line plus the leading blank line that separates it from the previous block. */\nfunction stripMarkerLine(text: string, marker: string): string {\n const escaped = marker.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const pattern = new RegExp(`\\\\n*${escaped}\\\\n*`);\n return text.replace(pattern, \"\\n\");\n}\n","/**\n * settings.json 부분 머지 — `.claude/settings.json` PreToolUse hook entry 추가.\n *\n * SPEC: docs/specs/karpathy-hook-autowire.md AC2/AC4 — opt-in 시 idempotent 등록.\n *\n * 사용처: karpathy-coder hook auto-wire (v0.6.0). 기존 매처 entry 보존 + 동일 command 중복 X.\n */\n\nexport interface ClaudeHookCommand {\n type: \"command\";\n command: string;\n async?: boolean;\n timeout?: number;\n}\n\nexport interface ClaudeHookMatcher {\n matcher?: string;\n hooks: ClaudeHookCommand[];\n}\n\nexport interface ClaudeSettings {\n // 기타 키 (statusLine, _comment 등) 보존 — 알 필요 없음\n [key: string]: unknown;\n hooks?: {\n [event: string]: ClaudeHookMatcher[];\n };\n}\n\n/**\n * PreToolUse 배열에 hook entry 추가 (idempotent). 기존 settings 객체는 mutation 안 함 (deep clone).\n *\n * 동작:\n * - hooks.PreToolUse 없음 → 생성\n * - matcher 일치하는 entry 없음 → 새 entry 추가\n * - matcher 일치 + command 동일한 hook 있음 → idempotent (변경 없음)\n * - matcher 일치 + command 다름 → hooks 배열에 append\n */\nexport function addPreToolUseHook(\n settings: ClaudeSettings,\n matcher: string,\n command: string,\n): ClaudeSettings {\n const next: ClaudeSettings = JSON.parse(JSON.stringify(settings));\n if (!next.hooks) {\n next.hooks = {};\n }\n if (!next.hooks.PreToolUse) {\n next.hooks.PreToolUse = [];\n }\n const preToolUse = next.hooks.PreToolUse;\n const existing = preToolUse.find((m) => m.matcher === matcher);\n const newHook: ClaudeHookCommand = { type: \"command\", command };\n if (existing) {\n if (existing.hooks.some((h) => h.command === command)) {\n return next; // idempotent — 동일 command 중복 X\n }\n existing.hooks.push(newHook);\n } else {\n preToolUse.push({ matcher, hooks: [newHook] });\n }\n return next;\n}\n","/**\n * update-mode.ts — Update / Add / Reinstall router 액션 처리.\n *\n * SPEC: docs/specs/cli-rewrite-completeness.md F5, F6\n * Source: bash setup-harness.sh@911c246~1 L460~573 (update mode 113 LOC)\n *\n * Update 모드 동작:\n * 1. backup: .claude/ → .claude.backup-<timestamp>/\n * 2. update_dir: target에 이미 존재하는 파일만 templates로 덮어쓰기 (Track 혼입 방지)\n * 3. prune_orphans: templates에 없는데 target에 있는 파일 제거 (예: 폐기된 rule)\n * 4. clean_stale_hook_refs: settings.json hook 참조 중 실존 파일 없는 것 제거\n *\n * 보존: gate-status.json, .mcp.json (사용자 추가 항목), docs/SPEC.md, settings.local.json\n */\n\nimport {\n copyFileSync,\n existsSync,\n readdirSync,\n readFileSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport interface UpdateModeReport {\n /** 덮어쓰기된 파일 갯수 (디렉토리별). */\n updated: Record<string, number>;\n /** 제거된 orphan 파일명 목록 (디렉토리별). */\n pruned: Record<string, string[]>;\n /** 제거된 stale hook ref 파일명 목록. */\n staleHookRefs: string[];\n /** 갱신된 CLAUDE.md (true if updated). */\n claudeMdUpdated: boolean;\n}\n\n/**\n * Update mode 메인 — backup은 caller가 별도 처리.\n *\n * @param projectDir 대상 프로젝트 root\n * @param templatesDir templates/ 디렉토리 (sync source)\n */\nexport function runUpdateMode(projectDir: string, templatesDir: string): UpdateModeReport {\n const claudeDir = join(projectDir, \".claude\");\n const report: UpdateModeReport = {\n updated: {},\n pruned: {},\n staleHookRefs: [],\n claudeMdUpdated: false,\n };\n\n // 1) update_dir × 4 (rules/agents/commands/uzys/hooks)\n const targets = [\n {\n target: join(claudeDir, \"rules\"),\n source: join(templatesDir, \"rules\"),\n pattern: \".md\",\n label: \".claude/rules\",\n },\n {\n target: join(claudeDir, \"agents\"),\n source: join(templatesDir, \"agents\"),\n pattern: \".md\",\n label: \".claude/agents\",\n },\n {\n target: join(claudeDir, \"commands/uzys\"),\n source: join(templatesDir, \"commands/uzys\"),\n pattern: \".md\",\n label: \".claude/commands/uzys\",\n },\n {\n target: join(claudeDir, \"hooks\"),\n source: join(templatesDir, \"hooks\"),\n pattern: \".sh\",\n label: \".claude/hooks\",\n },\n ];\n\n for (const t of targets) {\n report.updated[t.label] = updateDir(t.target, t.source, t.pattern);\n report.pruned[t.label] = pruneOrphans(t.target, t.source, t.pattern);\n }\n\n // 2) .claude/CLAUDE.md\n const claudeMd = join(claudeDir, \"CLAUDE.md\");\n const templateMd = join(templatesDir, \"CLAUDE.md\");\n if (existsSync(claudeMd) && existsSync(templateMd)) {\n copyFileSync(templateMd, claudeMd);\n report.claudeMdUpdated = true;\n }\n\n // 3) settings.json stale hook ref cleanup\n const settingsPath = join(claudeDir, \"settings.json\");\n if (existsSync(settingsPath)) {\n report.staleHookRefs = cleanStaleHookRefs(settingsPath, join(claudeDir, \"hooks\"));\n }\n\n return report;\n}\n\n/**\n * `target`에 이미 존재하는 파일 중 `source`에 동일 이름 있는 것만 덮어쓰기.\n * Track 혼입 방지 (새 파일 추가 X) — bash update_dir 등가.\n */\nexport function updateDir(target: string, source: string, ext: string): number {\n if (!existsSync(target) || !existsSync(source)) return 0;\n let count = 0;\n for (const file of readdirSync(target)) {\n if (!file.endsWith(ext)) continue;\n const targetFile = join(target, file);\n const sourceFile = join(source, file);\n if (existsSync(sourceFile)) {\n copyFileSync(sourceFile, targetFile);\n count++;\n }\n }\n return count;\n}\n\n/**\n * Templates에 없는데 target에 있는 파일 제거 (orphan prune) — bash prune_orphans 등가.\n */\nexport function pruneOrphans(target: string, source: string, ext: string): string[] {\n if (!existsSync(target) || !existsSync(source)) return [];\n const removed: string[] = [];\n for (const file of readdirSync(target)) {\n if (!file.endsWith(ext)) continue;\n const sourceFile = join(source, file);\n if (!existsSync(sourceFile)) {\n const targetFile = join(target, file);\n try {\n unlinkSync(targetFile);\n removed.push(file);\n } catch {\n // best-effort — read-only? 다음 update 시 재시도\n }\n }\n }\n return removed;\n}\n\n/**\n * settings.json의 PreToolUse/PostToolUse hooks 중 실존 파일 없는 hook script 참조 제거.\n * bash clean_stale_hook_refs 등가 (jq 의존 없이 JSON 직접 파싱).\n *\n * @returns 제거된 hook script 파일명 목록\n */\nexport function cleanStaleHookRefs(settingsPath: string, hooksDir: string): string[] {\n let settings: SettingsJson;\n try {\n settings = JSON.parse(readFileSync(settingsPath, \"utf8\")) as SettingsJson;\n } catch {\n return [];\n }\n const hookEvents = settings.hooks ?? {};\n const removed: string[] = [];\n const cleanedHooks: Record<string, HookEntry[]> = {};\n\n for (const [eventName, eventEntries] of Object.entries(hookEvents)) {\n if (!Array.isArray(eventEntries)) {\n cleanedHooks[eventName] = eventEntries; // non-array event — 그대로 보존\n continue;\n }\n cleanedHooks[eventName] = eventEntries\n .filter((entry) => Array.isArray(entry?.hooks))\n .map((entry) => ({\n ...entry,\n hooks: entry.hooks.filter((hook) => keepHookRef(hook, hooksDir, removed)),\n }))\n .filter((entry) => entry.hooks.length > 0); // stale 제거 후 hooks 빈 entry 제거\n }\n\n if (removed.length > 0) {\n const next: SettingsJson = { ...settings, hooks: cleanedHooks };\n writeFileSync(settingsPath, `${JSON.stringify(next, null, 2)}\\n`);\n }\n return removed;\n}\n\n/** hook command 가 실존 `.sh` 참조면 true. stale(파일 부재) 이면 removed 에 fname 수집 후 false. */\nfunction keepHookRef(hook: HookCommand, hooksDir: string, removed: string[]): boolean {\n const refMatch = (hook?.command ?? \"\").match(/\\/\\.claude\\/hooks\\/([^\"\\s/]+\\.sh)/);\n if (!refMatch?.[1]) return true; // hook script 참조 아님 — 보존\n const fname = refMatch[1];\n const exists = existsSync(join(hooksDir, fname));\n if (!exists && !removed.includes(fname)) removed.push(fname);\n return exists;\n}\n\ninterface HookCommand {\n type?: string;\n command?: string;\n}\n\ninterface HookEntry {\n matcher?: string;\n hooks: HookCommand[];\n}\n\ninterface SettingsJson {\n hooks?: Record<string, HookEntry[]>;\n [key: string]: unknown;\n}\n","/**\n * Install 출력 렌더 레이어 (v26.82.0, Phase R).\n *\n * `commands/install.ts` 가 979줄(cap 800 초과 — repo 최대 위반)로 비대해진 원인이\n * 렌더 함수 누적이었음 → 본 파일로 추출. install.ts 는 spec 검증 + 파이프라인\n * 오케스트레이션만, 여기는 화면 출력만. 동작 변경 0 (순수 이동).\n */\n\nimport { CATEGORY_TITLES, type Category } from \"../categories.js\";\nimport { targetsInclude } from \"../cli-targets.js\";\nimport { assetRow, c, infoRow, padDisplay, sectionHeader, unifiedSection } from \"../design.js\";\nimport {\n type ExternalAsset,\n experimentalOptInCandidates,\n isAssetSelected,\n} from \"../external-assets.js\";\nimport type { AssetInstallResult } from \"../external-installer.js\";\nimport type { BaselineReport, InstallMode, InstallReport, ProgressEvent } from \"../installer.js\";\nimport { finalSelectedAssets, groupAssetsByCategory } from \"../preset-recommend.js\";\nimport type { CliBase, CliTargets, InstallSpec, OptionFlags } from \"../types.js\";\n\n/**\n * v26.78.1 — Summary `CLI` 행 라벨 (SSOT). spec.cli 에서 derive → 헤더와 일관.\n * 이전 pairwise if-chain 은 codex/opencode 만 열거해 `--cli antigravity` 가 \"Claude\" 로\n * 잘못 출력 (R2). 4 base 전부 매핑.\n */\nconst CLI_SUMMARY_LABELS: Record<CliBase, string> = {\n claude: \"Claude\",\n codex: \"Codex\",\n opencode: \"OpenCode\",\n antigravity: \"Antigravity\",\n};\n\n/** Callbacks for progressive rendering during runInstall (avoids \"Phase 1 silence\" UX). */\nexport interface PipelineCallbacks {\n onProgress?: (event: ProgressEvent) => void;\n externalDeps?: {\n onAssetStart?: (asset: ExternalAsset) => void;\n onAssetResult?: (result: AssetInstallResult) => void;\n };\n}\n\n/** createInstallRenderer 반환 — 스트리밍 콜백 + 렌더 상태 조회. */\nexport interface InstallRenderer {\n callbacks: PipelineCallbacks;\n /** External assets 헤더 출력 여부 — Summary 직전 trailing newline 판단용. */\n phase2HeaderPrinted(): boolean;\n}\n\n/**\n * install header (TARGET / TRACKS / CLI / SCOPE / OPTIONS / ASSETS) 렌더.\n * wizard 모드는 Step 3 review + Step 4 confirm 에서 이미 표시하므로 호출 안 함.\n */\nexport function renderInstallHeader(\n log: (msg: string) => void,\n spec: InstallSpec,\n mode?: InstallMode,\n): void {\n const headerLabel =\n mode === \"update\"\n ? \"uzys-agent-harness · update\"\n : mode === \"add\"\n ? \"uzys-agent-harness · add\"\n : mode === \"reinstall\"\n ? \"uzys-agent-harness · reinstall\"\n : \"uzys-agent-harness · install\";\n log(\"\");\n log(sectionHeader(headerLabel));\n log(\"\");\n log(infoRow(\"TARGET\", shortenPath(spec.projectDir)));\n log(infoRow(\"TRACKS\", spec.tracks.join(\", \")));\n log(infoRow(\"CLI\", spec.cli.join(\" · \")));\n // v26.64.0 (ADR-020) — SCOPE row. 사용자가 매 install 시 어디에 write 되는지 인지 (D16).\n {\n const effectiveScope = spec.scope ?? \"project\";\n const scopeMsg =\n effectiveScope === \"global\"\n ? \"Global — writes to ~/.claude/, ~/.codex/, npm -g\"\n : \"Project — current directory only (no global write)\";\n log(infoRow(\"SCOPE\", scopeMsg));\n }\n log(infoRow(\"OPTIONS\", formatOptions(spec)));\n // v26.82.0 (Phase R, S6) — merge 는 preset-recommend.ts 단일 구현 (이전 computeFinalAssets 중복).\n const finalAssets = finalSelectedAssets(spec.tracks, spec.userOverride);\n if (finalAssets.length > 0) {\n log(infoRow(\"ASSETS\", `${finalAssets.length} selected`));\n for (const [cat, ids] of groupAssetsByCategory(finalAssets)) {\n log(` ${c.dim(`· ${cat}:`)} ${ids.join(\", \")}`);\n }\n }\n log(\"\");\n}\n\n/**\n * runInstall 스트리밍 렌더 콜백 생성 — baseline 완료 시 즉시 Phase 1 rows 출력,\n * external 은 per-asset 스트리밍 + 카테고리 헤더 (ADR-016 grouped progress UX).\n */\nexport function createInstallRenderer(\n log: (msg: string) => void,\n spec: InstallSpec,\n verbose: boolean,\n): InstallRenderer {\n let phase2HeaderPrinted = false;\n // v26.55.0 — Phase 2 grouped progress UX (ADR-016). category 변경 시 ━━ <Title> ━━ 헤더 출력.\n // external-installer 가 카테고리 순서로 정렬해 호출 → 첫 번째 호출이 category 1 의 첫 자산.\n let currentCategory: Category | null = null;\n const callbacks: PipelineCallbacks = {\n onProgress: (event) => {\n if (event.type === \"baseline-complete\") {\n // v26.81.0 (ADR-022) — withEcc boolean 삭제 → ecc-plugin 자산 선택으로 판정 (hint 게이팅).\n const eccSelected = isAssetSelected(\"ecc-plugin\", spec) || spec.options.withPrune === true;\n renderPhase1Rows(log, event.baseline, verbose, eccSelected);\n } else if (event.type === \"external-start\" && event.assetCount > 0) {\n // v26.63.0 — phaseHeader → unifiedSection. count 헤더에 inline 표시.\n log(unifiedSection(`External assets (${event.assetCount})`));\n log(\"\");\n phase2HeaderPrinted = true;\n }\n },\n externalDeps: {\n onAssetStart: (asset) => {\n // v26.57.0 (F2) — 카테고리 헤더만 출력. 자산 시작 라인 (→) 제거 — ✓ 결과 한 라인으로 1 단위 명확화.\n if (asset.category !== currentCategory) {\n if (currentCategory !== null) log(\"\");\n log(` ${c.bold(`━━ ${CATEGORY_TITLES[asset.category]} ━━`)}`);\n currentCategory = asset.category;\n }\n },\n onAssetResult: (result) => {\n const meta = result.ok\n ? formatAssetMeta(result.asset, result.version)\n : (result.message ?? \"failed\");\n log(` ${assetRow(result.ok ? \"success\" : \"skip\", result.asset.id, meta)}`);\n },\n },\n };\n return { callbacks, phase2HeaderPrinted: () => phase2HeaderPrinted };\n}\n\n/** Update mode 단축 Summary — manifest copy / external 모두 skip 된 경로. */\nexport function renderUpdateSummary(log: (msg: string) => void, report: InstallReport): void {\n log(\"\");\n // v26.63.2 — Summary 도 unifiedSection 으로 통일 (━━ marker). Step 5 안 sub-section 들과 일관.\n log(unifiedSection(\"Summary\"));\n log(\"\");\n log(infoRow(\"STATUS\", c.green(\"Update complete\")));\n log(infoRow(\"MODE\", \"update\"));\n if (report.backup) {\n log(infoRow(\"BACKUP\", shortenPath(report.backup)));\n log(infoRow(\"ROLLBACK\", `rm -rf .claude && mv ${shortenPath(report.backup)} .claude`));\n }\n log(\"\");\n}\n\n/**\n * Codex / OpenCode / Antigravity 산출물 sub-section.\n * v26.78.1 (R2): antigravity 추가 — `--cli antigravity` 시 산출물 invisible 이던 버그 fix.\n * 산출물 report 가 없거나 해당 CLI 미선택 시 출력 없음 (이전 executeSpec 의 게이트 if 이동).\n */\nexport function renderCliArtifacts(\n log: (msg: string) => void,\n spec: InstallSpec,\n report: InstallReport,\n): void {\n const hasArtifacts = Boolean(report.codex || report.opencode || report.antigravity);\n const cliSelected =\n targetsInclude(spec.cli, \"codex\") ||\n targetsInclude(spec.cli, \"opencode\") ||\n targetsInclude(spec.cli, \"antigravity\");\n if (!hasArtifacts || !cliSelected) {\n return;\n }\n log(unifiedSection(formatCliPhaseTitle(spec.cli)));\n log(\"\");\n // AGENTS.md is shared across Codex/OpenCode — render once with shared note\n if (report.codex && report.opencode) {\n log(assetRow(\"success\", \"AGENTS.md\", \"shared (Codex + OpenCode)\"));\n } else if (report.codex || report.opencode) {\n log(assetRow(\"success\", \"AGENTS.md\", \"from .claude/CLAUDE.md\"));\n }\n if (report.codex) {\n log(assetRow(\"success\", \".codex/config.toml\", \"settings + [mcp_servers.*]\"));\n log(assetRow(\"success\", \".codex/hooks/\", `${report.codex.hookFiles.length} files`));\n log(\n assetRow(\n \"success\",\n \".agents/skills/uzys-*/SKILL.md\",\n `${report.codex.skillFiles.length} skills ($uzys-spec mention)`,\n ),\n );\n // v0.7.1 — project-scoped prompts pre-positioning (글로벌 영향 0)\n if (report.codex.promptFiles.length > 0) {\n log(\n assetRow(\n \"success\",\n \".codex/prompts/uzys-*.md\",\n `${report.codex.promptFiles.length} prompts — pre-positioned for upstream #9848 (not active yet; use Global for working ~/.codex/prompts/)`,\n ),\n );\n }\n // Codex global opt-in (D16) — only when explicitly enabled\n if (report.codexOptIn) {\n if (report.codexOptIn.skillsInstalled.enabled) {\n log(\n assetRow(\n \"success\",\n \"~/.codex/skills/uzys-*\",\n `${report.codexOptIn.skillsInstalled.count} copied (global opt-in)`,\n ),\n );\n }\n if (report.codexOptIn.trustEntry.enabled) {\n const trust = report.codexOptIn.trustEntry;\n const kind = trust.status === \"error\" ? \"skip\" : \"success\";\n const meta =\n trust.status === \"registered\"\n ? '[projects.\"<dir>\"] trust_level=\"trusted\"'\n : trust.status === \"already-present\"\n ? \"already present\"\n : (trust.message ?? \"error\");\n log(assetRow(kind, \"~/.codex/config.toml trust entry\", meta));\n }\n // v0.7.0 — Codex prompts (slash 통일) opt-in 결과\n if (report.codexOptIn.promptsInstalled.enabled) {\n const count = report.codexOptIn.promptsInstalled.count;\n log(\n assetRow(\n count > 0 ? \"success\" : \"skip\",\n \"~/.codex/prompts/uzys-*\",\n `${count} markdown copied (/uzys-spec slash 등록)`,\n ),\n );\n }\n }\n }\n if (report.opencode) {\n log(assetRow(\"success\", \"opencode.json\", \"$schema + 5 keys\"));\n log(assetRow(\"success\", \".opencode/commands/\", `${report.opencode.commandFiles.length} files`));\n log(assetRow(\"success\", \".opencode/plugins/uzys-harness.ts\", \"self-contained plugin\"));\n }\n // v26.78.1 (R2) — Antigravity 산출물. rules 항상, skills/workflows 는 uzys-harness 선택 시만.\n if (report.antigravity) {\n if (report.antigravity.rulesFile) {\n log(assetRow(\"success\", \".agents/rules/uzys-harness.md\", \"from .claude/CLAUDE.md\"));\n }\n if (report.antigravity.skillFiles.length > 0) {\n log(\n assetRow(\n \"success\",\n \".agents/skills/uzys-*/SKILL.md\",\n `${report.antigravity.skillFiles.length} skills`,\n ),\n );\n }\n if (report.antigravity.workflowFiles.length > 0) {\n log(\n assetRow(\n \"success\",\n \".agents/workflows/uzys-*.md\",\n `${report.antigravity.workflowFiles.length} workflows`,\n ),\n );\n }\n // Antigravity global opt-in (D16) — only when explicitly enabled.\n if (report.antigravityOptIn) {\n const opt = report.antigravityOptIn;\n if (opt.skillsInstalled.enabled) {\n log(\n assetRow(\n \"success\",\n \"~/.gemini/antigravity/skills/uzys-*\",\n `${opt.skillsInstalled.count} copied (global opt-in)`,\n ),\n );\n }\n if (opt.workflowsInstalled.enabled) {\n log(\n assetRow(\n \"success\",\n \"~/.gemini/antigravity/global_workflows/uzys-*\",\n `${opt.workflowsInstalled.count} copied (global opt-in)`,\n ),\n );\n }\n }\n }\n log(\"\");\n}\n\n/** 최종 Summary (STATUS / TRACKS / CLI / HOOK / WARN / OPT-IN / NEXT). */\nexport function renderFinalSummary(\n log: (msg: string) => void,\n spec: InstallSpec,\n report: InstallReport,\n fromWizard: boolean,\n): void {\n // v26.63.2 — Summary 도 unifiedSection 으로 통일 (━━ marker).\n log(unifiedSection(\"Summary\"));\n log(\"\");\n log(infoRow(\"STATUS\", c.green(\"Install complete\")));\n log(infoRow(\"TRACKS\", report.installedTracks.join(\", \")));\n // v26.63.4 (P3): install header `CLI` 와 Summary `CLIs` 라벨 불일치 → `CLI` 로 통일.\n // v26.78.1 (R2): pairwise if-chain → spec.cli derive. antigravity 누락 + claude 무조건\n // prepend(claude 미선택 시에도 \"Claude\" 표기) 버그 fix. 헤더와 동일 SSOT.\n log(infoRow(\"CLI\", spec.cli.map((b) => CLI_SUMMARY_LABELS[b]).join(\" · \")));\n // v26.78.1 (R1) — karpathy hook opt-in 결과 렌더. null = 미opt-in(표시 안 함).\n // 이전엔 wired=false(plugin install 실패 등)여도 무음 → 사용자가 hook 안 깔린 걸\n // 모른 채 \"Install complete\" 만 봄 (Rule 12 fail-loud 위반).\n if (report.karpathyHook) {\n const kh = report.karpathyHook;\n if (kh.wired) {\n log(infoRow(\"HOOK\", c.green(\"karpathy-coder pre-commit hook wired\")));\n } else {\n log(infoRow(\"HOOK\", c.yellow(`karpathy hook skipped — ${kh.reason ?? \"unknown\"}`)));\n }\n }\n if (report.external && report.external.skipped > 0) {\n log(\"\");\n log(\n infoRow(\n \"WARN\",\n c.yellow(\n `${report.external.skipped} external asset${report.external.skipped > 1 ? \"s\" : \"\"} skipped (see Phase 2 above)`,\n ),\n ),\n );\n }\n // v26.71.1 — experimental(T3) opt-in discoverability (Transparent Defaults — 숨김 0건).\n // 비대화형(--track) 에서 condition 은 맞지만 T3 라 default 제외된 자산을 --with 안내.\n // wizard 모드는 이미 ⚠ 배지로 노출하므로 skip.\n if (!fromWizard) {\n const optIn = experimentalOptInCandidates(spec);\n if (optIn.length > 0) {\n log(\"\");\n log(\n infoRow(\n \"OPT-IN\",\n c.dim(\n `${optIn.length} experimental available — add with --with <id>: ${optIn.map((a) => a.id).join(\", \")}`,\n ),\n ),\n );\n }\n }\n log(\"\");\n log(infoRow(\"NEXT\", `${c.bold(\"claude\")} → ${c.cyan(\"/uzys:spec\")}`));\n log(\"\");\n}\n\nfunction formatAssetMeta(asset: ExternalAsset, version?: string): string {\n // v26.56.0 (F3) — description 제거. onAssetStart 의 → 라인이 이미 description 표시.\n // result row 는 method + source 만 간결하게 → terminal 120 char 안 wrap 방지.\n // v26.59.0 — plugin / npm-global 에 한해 version 표시 (path 기반 추출).\n const m = asset.method;\n const v = version ? ` ${c.dim(`v${version.replace(/^v/, \"\")}`)}` : \"\";\n switch (m.kind) {\n case \"skill\":\n // v26.63.3 (clarify M1): skill name 이 asset id 와 동일하면 중복 segment 생략.\n // \"skill · pbakaus/impeccable · impeccable\" → \"skill · pbakaus/impeccable\"\n if (m.skill && m.skill !== asset.id) return `skill · ${m.source} · ${m.skill}`;\n return `skill · ${m.source}`;\n case \"plugin\":\n return `plugin · ${m.pluginId}${v}`;\n case \"npm\":\n // A2 (Promise audit) — ADR-020 후 npm 자산 default 는 `--save-dev`(project), `-g` 는 global scope 만.\n // 라벨에 \"-g\" 고정은 scope 거짓 표기 → scope-중립 \"npm\" 으로 정정.\n // v26.80.0 — pinned 버전 표기 (Transparent Defaults: 실행되는 정확한 버전 노출).\n return `npm · ${m.pkg}@${m.version}`;\n case \"npx-run\":\n return `npx · ${m.cmd}@${m.version}`;\n case \"shell-script\":\n return `bash · ${m.script}`;\n case \"internal\":\n // v26.81.0 (ADR-022) — 내부 템플릿 자산 (Phase 1 manifest 가 설치 주체).\n return `internal · templates (${m.key})`;\n }\n}\n\n/**\n * Phase 1 rows 출력. baseline-complete progress event에서 호출 — 외부 자산 설치\n * 시작 전 즉시 화면에 표시되어야 한다 (멈춰 보임 방지).\n */\nfunction renderPhase1Rows(\n log: (msg: string) => void,\n baseline: BaselineReport,\n verbose = false,\n withEcc = false,\n): void {\n // Update mode rows\n if (baseline.updateMode) {\n if (baseline.backup) {\n log(assetRow(\"success\", \"backup\", shortenPath(baseline.backup)));\n }\n for (const [dir, count] of Object.entries(baseline.updateMode.updated)) {\n if (count > 0) log(assetRow(\"success\", dir, `${count} files updated`));\n }\n for (const [dir, removed] of Object.entries(baseline.updateMode.pruned)) {\n if (removed.length > 0) {\n log(assetRow(\"skip\", `${dir} orphan prune`, `${removed.length} removed`));\n }\n }\n if (baseline.updateMode.claudeMdUpdated) {\n log(assetRow(\"success\", \".claude/CLAUDE.md\", \"refreshed from template\"));\n }\n if (baseline.updateMode.staleHookRefs.length > 0) {\n log(\n assetRow(\n \"skip\",\n \"settings.json stale hook refs\",\n `${baseline.updateMode.staleHookRefs.length} removed`,\n ),\n );\n }\n return;\n }\n\n // Fresh / add / reinstall — Phase 1 rows\n // v26.57.1 (F2) — multi-line 구조 (header + use + files). visual hierarchy + width-safe.\n // 사용자 image 검증 (2026-05-17): 단일 라인 description 이 width 좁을 때 wrap → 들여쓰기 깨짐.\n const cats = baseline.categories;\n if (cats) {\n // v26.63.0 — files 라인은 verbose 옵션 시만. 기본은 카운트 + use 1 줄.\n // v26.63.2 — polish: label + count 칼럼 fixed-width 정렬 (28 char). spacing scale 일관.\n const phase1Row = (label: string, count: number, useText: string, files?: string[]) => {\n const labelCol = `${c.bold(label)} ${c.dim(`(${count})`)}`;\n const padded = padDisplay(labelCol, 28);\n log(` ${c.green(\"✓\")} ${padded} ${c.dim(useText)}`);\n if (verbose && files && files.length > 0) {\n log(` ${c.dim(\"└ files:\")} ${c.dim(files.join(\", \"))}`);\n }\n };\n\n if (cats.rules.length > 0) {\n phase1Row(\n \"rules\",\n cats.rules.length,\n \"coding · git/PR · tests · ship checklist · MCP policy\",\n cats.rules,\n );\n }\n if (cats.agents.length > 0) {\n // v26.63.3 (clarify H3): SOD jargon 보강 — independent verifier 명시.\n // v26.63.3 (distill H2): \"Without ECC plugin...\" 반복 제거 — section footer 통합.\n phase1Row(\n \"agents\",\n cats.agents.length,\n \"SOD reviewer (opus, independent verifier) + 3 base\",\n cats.agents,\n );\n }\n if (cats.hooks.length > 0) {\n phase1Row(\n \"hooks\",\n cats.hooks.length,\n \"session-start · gate-check (6-Gate order) · spec-drift · agentshield (security)\",\n cats.hooks,\n );\n }\n if (cats.commands > 0) {\n phase1Row(\"commands\", cats.commands, \"uzys-harness option: /uzys:* (7)\");\n }\n if (cats.skills.length > 0) {\n phase1Row(\n \"skills\",\n cats.skills.length,\n \"north-star · gh-issue-workflow · ui-visual-review · cl-v2 (modified)\",\n cats.skills,\n );\n }\n } else {\n // v0.6.0 backwards compat — categories 없는 fakeReport 등\n log(assetRow(\"success\", \"rules + hooks + commands + agents\", `${baseline.filesCopied} files`));\n log(assetRow(\"success\", \"skeleton\", `${baseline.dirsCopied} dirs`));\n }\n // v26.63.4 (P3): Templates section 의 assetRow 호출 labelWidth=28 명시 → phase1Row 와 column 정렬.\n // default 40 은 External assets 의 긴 asset id (architecture-decision-record 등) 용 — 별개.\n const TEMPLATES_COL = 28;\n if (baseline.rootClaudeMd) {\n const n = baseline.rootClaudeMd.tracks.length;\n log(\n assetRow(\n \"success\",\n \"CLAUDE.md (root)\",\n `merged from ${n} track${n > 1 ? \"s\" : \"\"}`,\n TEMPLATES_COL,\n ),\n );\n }\n if (baseline.skipped > 0) {\n log(\n assetRow(\n \"skip\",\n \"manifest entries (applies → false)\",\n `${baseline.skipped} skipped`,\n TEMPLATES_COL,\n ),\n );\n }\n if (baseline.backup) {\n log(assetRow(\"success\", \"backup\", shortenPath(baseline.backup), TEMPLATES_COL));\n }\n const mcpList = baseline.mcpServers.join(\", \") || \"(none)\";\n log(assetRow(\"success\", \".mcp.json\", mcpList, TEMPLATES_COL));\n if (baseline.envFiles.mcpAllowlist) {\n log(\n assetRow(\n \"success\",\n \".mcp-allowlist\",\n `${baseline.envFiles.mcpAllowlist.length} servers (D35 opt-in gate)`,\n TEMPLATES_COL,\n ),\n );\n }\n // v26.63.3 (distill H2): ECC fallback hint — Templates section 마지막에 통합 표시.\n // withEcc=true (ECC plugin opt-in) 사용자에게는 hint 미표시.\n if (!withEcc && baseline.categories) {\n log(\"\");\n log(\n ` ${c.dim(\"·\")} ${c.dim(\"ECC plugin not selected — cherry-pick fallback active (up to 4 agents + 8 skills + 3 commands)\")}`,\n );\n log(` ${c.dim(\"·\")} ${c.dim(\"Use --with-ecc to install ECC plugin instead\")}`);\n }\n if (baseline.envFiles.envExampleCreated) {\n log(assetRow(\"success\", \".env.example\", \"Supabase token guide\"));\n }\n if (baseline.envFiles.gitignoreEnvAdded) {\n log(assetRow(\"success\", \".gitignore\", \"+ .env\"));\n }\n if (baseline.envFiles.gitignoreNpxSkillsAdded.length > 0) {\n log(\n assetRow(\n \"success\",\n \".gitignore\",\n `+ ${baseline.envFiles.gitignoreNpxSkillsAdded.join(\" \")} (npx skills universal install)`,\n ),\n );\n }\n log(\"\");\n}\n\nfunction formatOptions(spec: InstallSpec): string {\n // v26.81.0 (ADR-022) — 자산 플래그 13종 삭제 후 동작 옵션만. 키 순회로 enumeration drift 차단.\n const flags = (Object.keys(spec.options) as Array<keyof OptionFlags>)\n .filter((k) => spec.options[k])\n .map((k) =>\n k\n .replace(/^with/, \"\")\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .toLowerCase(),\n );\n // v26.63.3 (clarify H1): \"(defaults only)\" 모호 → \"(none added)\" 명료.\n return flags.length > 0 ? flags.join(\", \") : c.dim(\"(none added)\");\n}\n\n/**\n * Shorten an absolute path for display:\n * /Users/foo/bar → ~/bar (HOME relative)\n * /private/tmp/x.X → /tmp/x.X\n * /a/very/long/path → …/long/path (≥3 segs from end if > 50 chars)\n *\n * v26.48.0 — export for direct unit test (branch coverage 복구).\n */\nexport function shortenPath(p: string): string {\n if (p.length <= 50) return p;\n const home = process.env.HOME ?? \"\";\n if (home && p.startsWith(home)) {\n const rel = p.slice(home.length);\n return `~${rel.startsWith(\"/\") ? \"\" : \"/\"}${rel}`;\n }\n // private/tmp prefix on macOS — drop /private\n if (p.startsWith(\"/private/tmp/\")) {\n return p.slice(\"/private\".length);\n }\n // Last 3 segments\n const segs = p.split(\"/\").filter(Boolean);\n if (segs.length > 3) {\n return `…/${segs.slice(-3).join(\"/\")}`;\n }\n return p;\n}\n\n/**\n * v0.7.0 — CliTargets에서 codex/opencode 포함 여부에 따라 title 결정.\n * Phase 3는 codex 또는 opencode 1개 이상 포함 시 호출됨.\n * v26.48.0 — export for direct unit test (branch coverage 복구).\n */\nexport function formatCliPhaseTitle(targets: CliTargets): string {\n // v26.78.1 (R2) — antigravity 추가. 누락 시 `--cli antigravity` 산출물 헤더가\n // \"CLI artifacts\" generic 으로만 떠 antigravity 가 invisible 했음.\n const labels: string[] = [];\n if (targets.includes(\"codex\")) labels.push(\"Codex\");\n if (targets.includes(\"opencode\")) labels.push(\"OpenCode\");\n if (targets.includes(\"antigravity\")) labels.push(\"Antigravity\");\n return labels.length > 0 ? `${labels.join(\" + \")} artifacts` : \"CLI artifacts\";\n}\n","/**\n * Preset → Step 2 의 추천 ✓ 자산 매핑 (v26.44.0).\n *\n * Step 1 에서 선택된 preset 들의 condition 을 만족하는 외부 자산(plugin/skill/npm/npx)\n * 의 id 를 반환한다. Step 2 multiselect 의 초기 체크 상태에 사용.\n *\n * Option-gated 자산은 추천에 포함 X — 사용자가 의식적으로 토글해야 함\n * (uzys-harness, superpowers, addy-agent-skills, gsd-orchestrator, ECC suite 등).\n */\n\nimport { assetTrustTier, EXTERNAL_ASSETS, filterApplicableAssets } from \"./external-assets.js\";\nimport { DEFAULT_OPTIONS, type InstallSpec, type Track } from \"./types.js\";\n\n/**\n * preset 1개 또는 N개 선택 시 추천 ✓ 자산 id 의 안정 정렬 배열.\n * - DEFAULT_OPTIONS 로 호출 → option-gated 자산은 모두 false → 추천에서 제외.\n * - v26.71.0 (PRD v26-71 R6) — experimental(T3) 자산은 pre-check 제외 (opt-in). official/vetted 만 추천.\n * - 결과는 자산 id 알파벳 정렬 (deterministic).\n */\nexport function recommendedExternalAssets(presets: ReadonlyArray<Track>): ReadonlyArray<string> {\n if (presets.length === 0) {\n return [];\n }\n const apps = filterApplicableAssets(EXTERNAL_ASSETS, {\n tracks: presets,\n options: DEFAULT_OPTIONS,\n });\n return apps\n .filter((a) => assetTrustTier(a.id) !== \"experimental\")\n .map((a) => a.id)\n .sort();\n}\n\n/**\n * v26.82.0 (Phase R, S6) — preset recommended + userOverride 적용 후 최종 선택 자산 id (정렬).\n * 이전엔 install.ts `computeFinalAssets` ↔ interactive.ts `formatSummary` 에 동일 merge 가\n * 중복 구현 (v26.62.4 주석이 본 위치를 통합 지점으로 지목). 우선순위: forceExclude > forceInclude.\n */\nexport function finalSelectedAssets(\n tracks: ReadonlyArray<Track>,\n userOverride?: InstallSpec[\"userOverride\"],\n): string[] {\n const selected = new Set(recommendedExternalAssets(tracks));\n if (userOverride) {\n for (const id of userOverride.forceExclude) selected.delete(id);\n for (const id of userOverride.forceInclude) selected.add(id);\n }\n return [...selected].sort();\n}\n\n/**\n * v26.82.0 (Phase R, S6) — 자산 id 를 카테고리별로 묶어 정렬된 entries 반환 (출력 hierarchy 용).\n * install header ASSETS row 와 wizard confirm summary 가 공유.\n */\nexport function groupAssetsByCategory(assetIds: ReadonlyArray<string>): Array<[string, string[]]> {\n const map = new Map<string, string[]>();\n for (const id of assetIds) {\n const asset = EXTERNAL_ASSETS.find((a) => a.id === id);\n const cat = asset?.category ?? \"other\";\n const list = map.get(cat) ?? [];\n list.push(id);\n map.set(cat, list);\n }\n return [...map.entries()];\n}\n","/**\n * Uninstall command — v26.64.0 (ADR-020).\n *\n * 동작:\n * 1. `.claude/.harness-install.json` 읽기.\n * 2. assets[] 별 reverse:\n * - scope=project: 실제 reverse (`claude plugin uninstall --scope project`, `npm uninstall`, fs rm).\n * - scope=global: 안내만 (D16 — 글로벌 영역 자동 삭제 금지). 사용자가 직접 명령 실행.\n * 3. templates 폴더 rm (`.claude/`, `.codex/`, `.opencode/`) — `--keep-templates` 시 보존.\n * 4. install log 자체도 함께 제거.\n *\n * 옵션:\n * --dry-run 실제 변경 없이 reverse list 만 출력.\n * --keep-templates `.claude/`, `.codex/`, `.opencode/` 보존.\n *\n * 안전:\n * - log 없으면 명확 에러 + early exit.\n * - scope=global 자산은 절대 자동 삭제 X (D16).\n */\n\nimport { type SpawnSyncReturns, spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync, rmSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { c, status } from \"../design.js\";\nimport {\n hashContent,\n type InstallLog,\n type InstallLogAsset,\n installLogPath,\n readInstallLog,\n} from \"../install-log.js\";\n\nexport interface UninstallOptions {\n projectDir?: string;\n dryRun?: boolean;\n keepTemplates?: boolean;\n}\n\nexport interface UninstallActionDeps {\n log?: (msg: string) => void;\n err?: (msg: string) => void;\n exit?: (code: number) => never;\n spawn?: (cmd: string, args: ReadonlyArray<string>) => SpawnSyncReturns<string>;\n rm?: (path: string) => void;\n}\n\ninterface ReverseStep {\n /** 사람이 읽는 라벨 (한 줄) */\n label: string;\n /** 실제 동작 — dry-run 일 때는 호출 안 함. */\n execute: () => { ok: boolean; message?: string };\n}\n\ninterface GlobalAdvisory {\n asset: InstallLogAsset;\n /** 사용자에게 안내할 reverse 명령 */\n command: string;\n}\n\nexport function uninstallAction(options: UninstallOptions, deps: UninstallActionDeps = {}): void {\n const log = deps.log ?? console.log;\n const err = deps.err ?? console.error;\n const exit = deps.exit ?? ((code: number) => process.exit(code) as never);\n const spawn = deps.spawn ?? defaultSpawn;\n const rm = deps.rm ?? defaultRm;\n\n const projectDir = resolve(options.projectDir ?? process.cwd());\n const installLog = readInstallLog(projectDir);\n if (!installLog) {\n err(status.failure(c.red(`ERROR: install log not found at ${installLogPath(projectDir)}`)));\n err(c.dim(\" Was this project installed by agent-harness? Nothing to uninstall.\"));\n exit(1);\n return;\n }\n\n const { reverseSteps, globalAdvisories } = planReverse(installLog, spawn, rm, projectDir);\n\n log(\"\");\n log(c.bold(\"uzys-agent-harness · uninstall\"));\n log(\"\");\n log(c.dim(` installed: ${installLog.installedAt}`));\n log(c.dim(` scope: ${installLog.scope}`));\n log(c.dim(` assets: ${installLog.assets.length}`));\n log(\"\");\n\n if (options.dryRun) {\n log(c.yellow(\"[DRY RUN] reverse list (실제 변경 없음):\"));\n log(\"\");\n if (reverseSteps.length === 0) {\n log(c.dim(\" (no project-scope assets to reverse)\"));\n }\n for (const step of reverseSteps) {\n log(` ○ ${step.label}`);\n }\n if (!options.keepTemplates) {\n log(` ○ remove templates: ${formatTemplateList(installLog)}`);\n if (installLog.templates.rootClaudeMd) {\n log(\n rootClaudeMdModified(installLog, projectDir)\n ? \" ○ keep CLAUDE.md (modified since install — preserved)\"\n : \" ○ remove CLAUDE.md\",\n );\n }\n }\n if (globalAdvisories.length > 0) {\n log(\"\");\n log(\n c.yellow(\n `[GLOBAL] ${globalAdvisories.length} asset(s) at scope=global — manual removal required (D16):`,\n ),\n );\n for (const adv of globalAdvisories) {\n log(c.dim(` · ${adv.asset.id} (${adv.asset.method}) → ${adv.command}`));\n }\n }\n log(\"\");\n exit(0);\n return;\n }\n\n // Execute reverse steps\n let succeeded = 0;\n let failed = 0;\n for (const step of reverseSteps) {\n const result = step.execute();\n if (result.ok) {\n log(` ${status.success(\"✓\")} ${step.label}`);\n succeeded++;\n } else {\n log(` ${c.yellow(\"⊘\")} ${step.label} (${result.message ?? \"failed\"})`);\n failed++;\n }\n }\n\n if (!options.keepTemplates) {\n const { rootClaudeMdKept } = removeTemplates(installLog, projectDir, rm);\n log(` ${status.success(\"✓\")} templates removed: ${formatTemplateList(installLog)}`);\n if (rootClaudeMdKept) {\n log(\n ` ${c.yellow(\"⊘\")} CLAUDE.md kept — modified since install. Remove manually if intended.`,\n );\n }\n }\n\n // install log 자체도 함께 제거 (templates 제거 시 .claude/ 통째 사라짐 → log 도 자동 사라짐.\n // keepTemplates 시 .claude/ 유지 → log 만 명시 제거).\n if (options.keepTemplates) {\n rm(installLogPath(projectDir));\n log(` ${status.success(\"✓\")} install log removed (templates kept)`);\n }\n\n if (globalAdvisories.length > 0) {\n log(\"\");\n log(\n c.yellow(\n `[GLOBAL] ${globalAdvisories.length} asset(s) at scope=global — manual removal required (D16):`,\n ),\n );\n for (const adv of globalAdvisories) {\n log(c.dim(` · ${adv.asset.id} (${adv.asset.method})`));\n log(c.dim(` ${adv.command}`));\n }\n }\n\n log(\"\");\n log(\n succeeded === reverseSteps.length && failed === 0\n ? status.success(c.green(`uninstall complete (${succeeded} asset(s))`))\n : c.yellow(`uninstall finished with ${failed} skip(s) (${succeeded} ok)`),\n );\n exit(failed === 0 ? 0 : 1);\n}\n\nfunction planReverse(\n log: InstallLog,\n spawn: (cmd: string, args: ReadonlyArray<string>) => SpawnSyncReturns<string>,\n _rm: (path: string) => void,\n _projectDir: string,\n): { reverseSteps: ReverseStep[]; globalAdvisories: GlobalAdvisory[] } {\n const reverseSteps: ReverseStep[] = [];\n const globalAdvisories: GlobalAdvisory[] = [];\n\n for (const asset of log.assets) {\n if (asset.scope === \"global\") {\n globalAdvisories.push({ asset, command: buildGlobalAdvisoryCmd(asset) });\n continue;\n }\n const step = buildProjectReverseStep(asset, spawn);\n if (step) reverseSteps.push(step);\n }\n\n return { reverseSteps, globalAdvisories };\n}\n\nfunction buildProjectReverseStep(\n asset: InstallLogAsset,\n spawn: (cmd: string, args: ReadonlyArray<string>) => SpawnSyncReturns<string>,\n): ReverseStep | null {\n switch (asset.method) {\n case \"plugin\": {\n const pluginId = asset.detail.pluginId ?? asset.id;\n return {\n label: `claude plugin uninstall --scope project ${pluginId}`,\n execute: () => {\n const r = spawn(\"claude\", [\"plugin\", \"uninstall\", \"--scope\", \"project\", pluginId]);\n return r.status === 0 ? { ok: true } : { ok: false, message: (r.stderr || \"\").trim() };\n },\n };\n }\n case \"skill\": {\n // skills CLI default 가 project — `skills remove <source>` (no -g).\n // 일부 source 는 폴더 경로/직접 id — npx skills remove 가 처리.\n const source = asset.detail.source ?? asset.id;\n return {\n label: `npx skills remove ${source}`,\n execute: () => {\n const r = spawn(\"npx\", [\"skills\", \"remove\", source, \"--yes\"]);\n return r.status === 0 ? { ok: true } : { ok: false, message: (r.stderr || \"\").trim() };\n },\n };\n }\n case \"npm\": {\n const pkg = asset.detail.pkg ?? asset.id;\n return {\n label: `npm uninstall --save-dev ${pkg}`,\n execute: () => {\n const r = spawn(\"npm\", [\"uninstall\", \"--save-dev\", pkg]);\n return r.status === 0 ? { ok: true } : { ok: false, message: (r.stderr || \"\").trim() };\n },\n };\n }\n case \"npx-run\":\n // fire-and-forget — reverse 없음 (예: GSD orchestrator).\n return null;\n case \"shell-script\":\n // 로컬 script 호출 — 일반 reverse 없음 (script 별 별도 cleanup 필요).\n return null;\n case \"internal\":\n // v26.81.0 (ADR-022) — 내부 템플릿 — removeTemplates 가 .claude/ 전체로 처리.\n return null;\n }\n}\n\nfunction buildGlobalAdvisoryCmd(asset: InstallLogAsset): string {\n switch (asset.method) {\n case \"plugin\": {\n const pid = asset.detail.pluginId ?? asset.id;\n return `claude plugin uninstall --scope user ${pid}`;\n }\n case \"skill\": {\n const s = asset.detail.source ?? asset.id;\n return `npx skills remove -g ${s}`;\n }\n case \"npm\": {\n const pkg = asset.detail.pkg ?? asset.id;\n return `npm uninstall -g ${pkg}`;\n }\n case \"npx-run\":\n case \"shell-script\":\n case \"internal\":\n return \"(no standard reverse — manual)\";\n }\n}\n\nfunction removeTemplates(\n log: InstallLog,\n projectDir: string,\n rm: (path: string) => void,\n): { rootClaudeMdKept: boolean } {\n rm(join(projectDir, log.templates.claudeDir));\n if (log.templates.codexDir) rm(join(projectDir, log.templates.codexDir));\n if (log.templates.opencodeDir) rm(join(projectDir, log.templates.opencodeDir));\n // root CLAUDE.md — install 원본 그대로일 때만 삭제. 사용자가 수정했으면 보존.\n const rootMd = log.templates.rootClaudeMd;\n if (rootMd) {\n if (rootClaudeMdModified(log, projectDir)) return { rootClaudeMdKept: true };\n rm(join(projectDir, rootMd.path));\n }\n return { rootClaudeMdKept: false };\n}\n\n/** root CLAUDE.md 가 install 이후 수정됐는지. log 에 없거나 파일 부재 시 false (= 삭제 대상). */\nfunction rootClaudeMdModified(log: InstallLog, projectDir: string): boolean {\n const rootMd = log.templates.rootClaudeMd;\n if (!rootMd) return false;\n const path = join(projectDir, rootMd.path);\n if (!existsSync(path)) return false;\n return hashContent(readFileSync(path, \"utf8\")) !== rootMd.sha256;\n}\n\nfunction formatTemplateList(log: InstallLog): string {\n const items: string[] = [log.templates.claudeDir];\n if (log.templates.codexDir) items.push(log.templates.codexDir);\n if (log.templates.opencodeDir) items.push(log.templates.opencodeDir);\n return items.join(\", \");\n}\n\n/* v8 ignore start — thin dep-inject defaults. tests 는 항상 mock 주입. */\nfunction defaultSpawn(cmd: string, args: ReadonlyArray<string>): SpawnSyncReturns<string> {\n return spawnSync(cmd, [...args], { encoding: \"utf8\", stdio: \"pipe\", timeout: 120_000 });\n}\n\nfunction defaultRm(path: string): void {\n if (existsSync(path)) {\n rmSync(path, { recursive: true, force: true });\n }\n}\n/* v8 ignore stop */\n\nexport function registerUninstallCommand(cli: import(\"../cli.js\").Cli): void {\n cli\n .command(\"uninstall\", \"Uninstall harness assets (log-based reverse)\")\n .option(\"--project-dir <path>\", \"[Project] Target project directory\", {\n default: process.cwd(),\n })\n .option(\"--dry-run\", \"[Mode] List reverse steps without executing\")\n .option(\n \"--keep-templates\",\n \"[Mode] Keep `.claude/`, `.codex/`, `.opencode/` templates (remove only external assets)\",\n )\n /* v8 ignore next 3 — cac action callback. uninstallAction 자체는 별도 tests 로 검증. */\n .action((options: UninstallOptions) => {\n uninstallAction(options);\n });\n}\n","import { EXTERNAL_ASSETS } from \"./external-assets.js\";\nimport type { InstallMode } from \"./installer.js\";\nimport {\n finalSelectedAssets,\n groupAssetsByCategory,\n recommendedExternalAssets,\n} from \"./preset-recommend.js\";\nimport {\n defaultPrompts,\n type InstallTargetId,\n type Prompts,\n VISIBLE_OPTION_DEFS,\n} from \"./prompts.js\";\nimport { type DetectedInstall, detectInstallState } from \"./state.js\";\nimport type { InstallSpec, OptionFlags, Track } from \"./types.js\";\nimport { stepLabel, WIZARD } from \"./wizard-steps.js\";\n\n/**\n * v26.54.0 — All-in-one 결과 → option keys + asset id list 분리.\n * `option:<key>` → OptionFlags key\n * `asset:<id>` → EXTERNAL_ASSETS id\n */\nexport function splitInstallTargets(targets: ReadonlyArray<InstallTargetId>): {\n optionKeys: Array<keyof OptionFlags>;\n assetIds: Array<string>;\n} {\n const optionKeys: Array<keyof OptionFlags> = [];\n const assetIds: Array<string> = [];\n for (const t of targets) {\n if (t.startsWith(\"option:\")) {\n optionKeys.push(t.slice(\"option:\".length) as keyof OptionFlags);\n } else if (t.startsWith(\"asset:\")) {\n assetIds.push(t.slice(\"asset:\".length));\n }\n }\n return { optionKeys, assetIds };\n}\n\n/**\n * v26.46.0 — `withCodexPrompts` 는 interactive 옵션 list 에서 제거됨 (CLI 전용 opt-in).\n * v26.81.0 (ADR-022) — 자산 1:1 boolean 13종 삭제 후 잔존 동작 옵션만 매핑.\n * wizard 의 자산 선택은 전부 `asset:<id>` → userOverride.forceInclude 경로.\n */\nexport function toOptionFlags(keys: ReadonlyArray<keyof OptionFlags>): OptionFlags {\n const picked = new Set<keyof OptionFlags>(keys);\n return {\n withPrune: picked.has(\"withPrune\"),\n withCodexSkills: picked.has(\"withCodexSkills\"),\n withCodexTrust: picked.has(\"withCodexTrust\"),\n withKarpathyHook: picked.has(\"withKarpathyHook\"),\n withCodexPrompts: false,\n withAntigravityGlobal: picked.has(\"withAntigravityGlobal\"),\n };\n}\n\nexport interface InteractiveDeps {\n prompts?: Prompts;\n detect?: (projectDir: string) => DetectedInstall;\n isTty?: () => boolean;\n}\n\nexport interface InteractiveResult {\n ok: boolean;\n spec?: InstallSpec;\n mode?: InstallMode;\n reason?: \"no-tty\" | \"cancelled\" | \"disabled-action\" | \"exit\";\n message?: string;\n}\n\n/**\n * v26.54.0 — 3-step wizard. SPEC: docs/specs/v26-54-all-in-one-installer.md\n *\n * Step 1: tracks (ESC = exit + cancel msg)\n * Step 2: cli (ESC = silent back to tracks)\n * Step 3: install-targets all-in-one (ESC = silent back to cli)\n * confirm prompt (ESC = silent back to targets)\n *\n * 이전 5-step 의 options + 2-tier asset navigator 를 step 3 1 화면 group multiselect 로 흡수.\n */\nexport async function runInteractive(\n projectDir: string,\n deps: InteractiveDeps = {},\n): Promise<InteractiveResult> {\n const prompts = deps.prompts ?? defaultPrompts;\n const detect = deps.detect ?? detectInstallState;\n const isTty = deps.isTty ?? (() => Boolean(process.stdin.isTTY));\n\n if (!isTty()) {\n return {\n ok: false,\n reason: \"no-tty\",\n message:\n \"Interactive mode requires a TTY. Use `agent-harness install --track <name>` for non-interactive use.\",\n };\n }\n\n prompts.intro(\"uzys-agent-harness installer\");\n const state = detect(projectDir);\n\n let initialTracks: Track[] | undefined;\n let mode: InstallMode = \"fresh\";\n if (state.state === \"existing\") {\n const action = await prompts.selectAction(state);\n if (action === null) {\n prompts.cancel(\"Cancelled.\");\n return { ok: false, reason: \"cancelled\" };\n }\n if (action === \"exit\") {\n prompts.outro(\"Exiting without changes.\");\n return { ok: false, reason: \"exit\" };\n }\n if (action === \"remove\") {\n prompts.cancel(\"Track removal is not automated — manually edit `.claude/`. Aborting.\");\n return { ok: false, reason: \"disabled-action\" };\n }\n if (action === \"update\") {\n mode = \"update\";\n const summary = formatSummary({\n tracks: state.tracks,\n options: toOptionFlags([]),\n cli: [\"claude\"],\n projectDir,\n });\n const confirmed = await prompts.confirmInstall(`UPDATE policy files only:\\n${summary}`);\n if (!confirmed) {\n prompts.outro(\"Cancelled.\");\n return { ok: false, reason: \"cancelled\" };\n }\n prompts.outro(\"Running update mode...\");\n return {\n ok: true,\n mode: \"update\",\n spec: {\n tracks: state.tracks,\n options: toOptionFlags([]),\n cli: [\"claude\"],\n projectDir,\n },\n };\n }\n if (action === \"add\") {\n mode = \"add\";\n initialTracks = state.tracks;\n } else if (action === \"reinstall\") {\n mode = \"reinstall\";\n }\n }\n\n // v26.64.0 (ADR-020) — scope step 추가. Default \"project\". Step 3.5 (targets 직후, confirm 직전).\n type Step = \"tracks\" | \"cli\" | \"targets\" | \"scope\" | \"confirm\";\n let step: Step = \"tracks\";\n let tracks: Track[] | null = null;\n let cli: import(\"./types.js\").CliTargets | null = null;\n let targetSelections: ReadonlyArray<InstallTargetId> | null = null;\n let scope: import(\"./types.js\").InstallScope = \"project\";\n\n while (true) {\n if (step === \"tracks\") {\n const result = await prompts.selectTracks(tracks ?? initialTracks, WIZARD.TRACKS);\n if (result === null) {\n // Step 1 ESC = exit with cancel message (only step where ESC is \"cancel\")\n prompts.cancel(\"Cancelled.\");\n return { ok: false, reason: \"cancelled\" };\n }\n // preset 변경 감지 → install-targets reset (v26.50 정책 유지)\n if (tracks !== null && !tracksEqual(tracks, result)) {\n targetSelections = null;\n }\n tracks = result;\n step = \"cli\";\n } else if (step === \"cli\") {\n const result = await prompts.selectCli(cli ?? [\"claude\"], WIZARD.CLI);\n if (result === null) {\n step = \"tracks\"; // silent back\n continue;\n }\n cli = result;\n step = \"targets\";\n } else if (step === \"targets\") {\n const initial: InstallTargetId[] =\n targetSelections !== null\n ? [...targetSelections]\n : recommendedExternalAssets(tracks ?? []).map((id) => `asset:${id}` as InstallTargetId);\n // v26.65.0 — step indicator SSOT (wizard-steps.ts). Phase: 3 targets → 4 scope → 5 confirm → 6 install.\n const result = await prompts.selectInstallTargets(initial, WIZARD.TARGETS, {\n tracks: tracks ?? [],\n cli: cli ?? [\"claude\"],\n });\n if (result === null) {\n step = \"cli\"; // silent back\n continue;\n }\n targetSelections = result;\n step = \"scope\";\n } else if (step === \"scope\") {\n // v26.64.0 (ADR-020) — Installation scope select. Default \"project\" (D16).\n const result = await prompts.selectScope(scope, WIZARD.SCOPE);\n if (result === null) {\n step = \"targets\"; // silent back\n continue;\n }\n scope = result;\n step = \"confirm\";\n } else {\n // confirm\n // biome-ignore lint/style/noNonNullAssertion: confirm step 도달 = 모든 이전 step 완료 보장\n const finalTracks = tracks!;\n // biome-ignore lint/style/noNonNullAssertion: same as above\n const finalCli = cli!;\n const { optionKeys, assetIds } = splitInstallTargets(targetSelections ?? []);\n const options = toOptionFlags(optionKeys);\n // v26.64.0 (ADR-020, BREAKING) — ADR-012/017 supersede. cli=codex 자동 default ON 폐기.\n // withCodexPrompts 는 사용자 명시 install target (목록 체크) 시에만 활성. 자동 ON 안 함.\n // scope=global 일 때만 ~/.codex/prompts/ 에 실 write (installer.ts).\n const userOverride =\n targetSelections === null ? undefined : computeUserOverride(finalTracks, assetIds);\n // v26.64.0 (ADR-020) — Confirm summary 에 SCOPE 명시 (사용자 인지 + D16).\n const scopeLabel =\n scope === \"global\"\n ? \"Global (writes to ~/.claude/, ~/.codex/, npm -g)\"\n : \"Project (current directory only)\";\n const summary = `${formatSummary({\n tracks: finalTracks,\n options,\n cli: finalCli,\n projectDir,\n ...(userOverride ? { userOverride } : {}),\n })}\\n SCOPE ${scopeLabel}`;\n const confirmed = await prompts.confirmInstall(\n `${stepLabel(WIZARD.CONFIRM, \"Confirm\")}\\n${summary}`,\n );\n if (confirmed === null) {\n step = \"scope\"; // silent back\n continue;\n }\n if (!confirmed) {\n prompts.outro(\"Cancelled by user.\");\n return { ok: false, reason: \"cancelled\" };\n }\n prompts.outro(stepLabel(WIZARD.INSTALL, \"Installing...\"));\n return {\n ok: true,\n mode,\n spec: {\n tracks: finalTracks,\n options,\n cli: finalCli,\n projectDir,\n scope,\n ...(userOverride ? { userOverride } : {}),\n },\n };\n }\n }\n}\n\n/**\n * Track 배열 동등 비교 (순서 무관). Preset 변경 감지에 사용.\n */\nfunction tracksEqual(a: ReadonlyArray<Track>, b: ReadonlyArray<Track>): boolean {\n if (a.length !== b.length) return false;\n const sortedA = [...a].sort();\n const sortedB = [...b].sort();\n return sortedA.every((t, i) => t === sortedB[i]);\n}\n\n/**\n * v26.54.0 — Asset 선택 결과 (id 만) 와 preset 추천 비교 → forceInclude / forceExclude.\n * - `recommended - selected` → forceExclude (사용자가 unchecked)\n * - `selected - recommended` → forceInclude (사용자가 추가 선택)\n * 둘 다 비어있으면 undefined (no override).\n */\nexport function computeUserOverride(\n tracks: ReadonlyArray<Track>,\n assetIds: ReadonlyArray<string>,\n): { forceInclude: ReadonlyArray<string>; forceExclude: ReadonlyArray<string> } | undefined {\n const recommended = new Set(recommendedExternalAssets(tracks));\n const selected = new Set(assetIds);\n const forceExclude = [...recommended].filter((id) => !selected.has(id)).sort();\n const forceInclude = [...selected].filter((id) => !recommended.has(id)).sort();\n if (forceInclude.length === 0 && forceExclude.length === 0) return undefined;\n return { forceInclude, forceExclude };\n}\n\nexport function formatSummary(spec: InstallSpec): string {\n const opts = (Object.keys(spec.options) as Array<keyof OptionFlags>)\n .filter((k) => spec.options[k])\n .map((k) => k.replace(/^with/, \"\").toLowerCase());\n // v26.63.3 (clarify H1): \"(defaults only)\" 모호 → \"(none added)\" 명료.\n const optsLabel = opts.length > 0 ? opts.join(\", \") : \"(none added)\";\n const lines = [\n `Tracks: ${spec.tracks.join(\", \")}`,\n `Options: ${optsLabel}`,\n `CLI: ${spec.cli.join(\" · \")}`,\n `Target: ${spec.projectDir}`,\n ];\n\n // v26.62.3 — 실제 install 될 자산 list 명시. defaults 만으로는 사용자가\n // Step 3 에서 무엇을 confirm 했는지 알 수 없음. preset recommended +\n // userOverride 적용 후 최종 selected assets list 표시.\n // v26.82.0 (Phase R, S6) — merge/그룹화는 preset-recommend.ts 단일 구현 사용 (중복 제거).\n const finalAssets = finalSelectedAssets(spec.tracks, spec.userOverride);\n if (finalAssets.length > 0) {\n lines.push(`Assets: ${finalAssets.length} selected`);\n for (const [cat, ids] of groupAssetsByCategory(finalAssets)) {\n lines.push(` · ${cat}: ${ids.join(\", \")}`);\n }\n }\n\n if (spec.userOverride) {\n if (spec.userOverride.forceInclude.length > 0) {\n lines.push(` +User added: ${spec.userOverride.forceInclude.join(\", \")}`);\n }\n if (spec.userOverride.forceExclude.length > 0) {\n lines.push(` -User removed: ${spec.userOverride.forceExclude.join(\", \")}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n// v26.54.0 — Re-exports to keep test imports stable (test의 mock 구조 변경 없음)\nexport { EXTERNAL_ASSETS, VISIBLE_OPTION_DEFS };\n","// prompts.ts is a thin adapter over @clack/prompts. It deliberately contains\n// no transformation logic — interactive.ts owns the business rules. This file\n// is excluded from coverage in vitest.config.ts (justification at exclude line).\n\nimport {\n cancel,\n confirm,\n groupMultiselect,\n intro,\n isCancel,\n multiselect,\n outro,\n select,\n} from \"@clack/prompts\";\nimport { CATEGORIES, CATEGORY_TITLES, type Category } from \"./categories.js\";\nimport { CLI_BASE_SORT_ORDER } from \"./cli-targets.js\";\nimport { assetTrustTier, EXTERNAL_ASSETS } from \"./external-assets.js\";\nimport { buildRouterChoices, type RouterAction, summarizeState } from \"./router.js\";\nimport type { DetectedInstall } from \"./state.js\";\nimport {\n type CliBase,\n type CliTargets,\n type InstallScope,\n type OptionFlags,\n TRACKS,\n type Track,\n} from \"./types.js\";\nimport { stepLabel, type WizardStep } from \"./wizard-steps.js\";\n\n/**\n * v26.54.0 — All-in-one install-targets value scheme.\n * groupMultiselect 의 단일 string value 에 두 source 통합:\n * - `option:<key>` → OPTION_DEFS 의 manifest-영향 build option (현재: withTauri, withUzysHarness)\n * - `asset:<id>` → EXTERNAL_ASSETS 의 외부 자산\n * 다른 OptionFlags 항목 (withGsd, withEcc, withPrune, withTob, withKarpathyHook,\n * withAddyAgentSkills, withSuperpowers, withWshobsonAgents, withOpenspec, withBmad) 은\n * EXTERNAL_ASSETS 에 1:1 자산이 있어\n * 자산 체크 → userOverride.forceInclude 로 처리. UI 중복 표시 없음.\n */\nexport type InstallTargetId = `option:${keyof OptionFlags}` | `asset:${string}`;\n\nexport interface Prompts {\n intro: (msg: string) => void;\n outro: (msg: string) => void;\n cancel: (msg: string) => void;\n\n /**\n * v26.65.0 — step optional 두 번째 인자. 호출자가 `WIZARD.TRACKS` 전달 시 message 에\n * \"Step N/M — Select Track(s)\" 형식 indicator 자동 삽입. 미전달 시 prefix 없이 raw label.\n */\n selectTracks: (initial?: Track[], step?: WizardStep) => Promise<Track[] | null>;\n /** v0.7.0 — single select → multiselect (3 base 체크박스). default `[\"claude\"]`. */\n selectCli: (initial?: CliTargets, step?: WizardStep) => Promise<CliTargets | null>;\n selectAction: (state: DetectedInstall) => Promise<RouterAction | null>;\n /**\n * v26.64.0 (ADR-020) — Installation scope 선택. Default = \"project\" (pre-selected).\n * Global 은 사용자 명시 opt-in. null = silent back.\n */\n selectScope: (initial?: InstallScope, step?: WizardStep) => Promise<InstallScope | null>;\n confirmInstall: (summary: string) => Promise<boolean | null>;\n\n /**\n * v26.54.0 — Step 3 (all-in-one). EXTERNAL_ASSETS + 표시-대상 OPTION_DEFS 를\n * 카테고리 그룹화. 추천 ✓ pre-check. ESC → null (silent back).\n * v26.61.0 — recap (tracks/cli) 추가. alt screen 안에서 동작 — terminal scrollback\n * 본질 차단 → wizard scroll 시 cursor highlight 항상 visible.\n */\n selectInstallTargets: (\n initialChecked: ReadonlyArray<InstallTargetId>,\n step: { current: number; total: number },\n recap?: { tracks: ReadonlyArray<Track>; cli: CliTargets },\n ) => Promise<ReadonlyArray<InstallTargetId> | null>;\n}\n\nconst TRACK_LABELS: Record<Track, string> = {\n tooling: \"tooling — Bash + Markdown meta-project\",\n \"csr-supabase\": \"csr-supabase — Vite + React + Supabase\",\n \"csr-fastify\": \"csr-fastify — Vite + React + Fastify\",\n \"csr-fastapi\": \"csr-fastapi — Vite + React + FastAPI\",\n \"ssr-htmx\": \"ssr-htmx — htmx + FastAPI\",\n \"ssr-nextjs\": \"ssr-nextjs — Next.js (App Router)\",\n data: \"data — Python data / DuckDB / PySide6\",\n executive: \"executive — proposals / DD / pitch (no agent-skills)\",\n full: \"full — all dev capabilities\",\n \"project-management\": \"project-management — PM / Scrum / Jira / Confluence\",\n \"growth-marketing\": \"growth-marketing — Growth / Marketing / Content\",\n};\n\ninterface OptionDef {\n key: keyof OptionFlags;\n label: string;\n hint: string;\n category: Category;\n source: string;\n}\n\n/**\n * v26.54.0 — 표시 대상 OPTION_DEFS.\n * v26.81.0 (ADR-022) — **빈 배열로 소멸**. 마지막 2개(withTauri/withUzysHarness)가 내부\n * 자산(tauri-desktop/uzys-harness — EXTERNAL_ASSETS `kind:\"internal\"`)으로 흡수돼 wizard 의\n * `option:` 특례가 사라짐. 자산 선택은 전부 `asset:<id>` 경로. 잔존 동작 옵션(D16 글로벌\n * 4종/karpathy hook/prune)은 wizard 미노출 (CLI `--with-*` 동작 플래그 전용 — 기존과 동일).\n */\nexport const VISIBLE_OPTION_DEFS: ReadonlyArray<OptionDef> = [];\n\nconst CLI_BASE_LABELS: Record<CliBase, string> = {\n claude: \"Claude Code\",\n codex: \"Codex (OpenAI)\",\n opencode: \"OpenCode (anomalyco)\",\n antigravity: \"Antigravity (Google)\",\n};\n\n/**\n * v26.78.1 — Step 3 wizard page layout (SSOT). 카테고리를 페이지로 묶어 clack\n * groupMultiselect 의 maxItems 한계(페이지당 옵션 ≤ ~30)를 우회.\n *\n * ⚠️ drift 가드 (no-false-ship): 모든 Category 는 정확히 한 페이지에 등장해야 한다.\n * 누락 시 해당 카테고리 자산이 wizard 에서 선택 불가가 되어 \"출하 거짓 광고\"가 된다\n * (v26.78.0 understanding 누락 회귀 — pages 가 selectInstallTargets 안에 하드코딩되어\n * CATEGORIES 추가와 drift). 아래 assertPagesCoverAllCategories 가 모듈 로드 시점에\n * 강제 — 신규 카테고리 미배치 시 즉시 throw. (tests/wizard-page-parity.test.ts 가 이중 가드)\n *\n * 페이지 묶음:\n * Page 1: Dev domain — frontend + backend + dev-tools + data + understanding\n * Page 2: Business — business (documents)\n * Page 3: Workflow/ECC — workflow + ecc-suite\n */\nexport interface InstallTargetPage {\n label: string;\n cats: ReadonlyArray<Category>;\n}\n\nexport const INSTALL_TARGET_PAGES: ReadonlyArray<InstallTargetPage> = [\n {\n label: \"Dev (Frontend · Backend · Dev Tools · Data · Understanding)\",\n cats: [\"frontend\", \"backend\", \"dev-tools\", \"data\", \"understanding\"],\n },\n { label: \"Business (PM · Executive · Documents)\", cats: [\"business\"] },\n { label: \"Workflow & ECC Suite\", cats: [\"workflow\", \"ecc-suite\"] },\n];\n\n/**\n * 모든 Category 가 정확히 한 페이지에 등장하는지 모듈 로드 시 검증.\n * 누락(미배치) 또는 중복(2개 페이지)이면 throw — 값싼 fail-loud pre-flight.\n */\nfunction assertPagesCoverAllCategories(pages: ReadonlyArray<InstallTargetPage>): void {\n const counts = new Map<Category, number>();\n for (const page of pages) {\n for (const cat of page.cats) counts.set(cat, (counts.get(cat) ?? 0) + 1);\n }\n const missing = CATEGORIES.filter((c) => !counts.has(c));\n const duplicated = CATEGORIES.filter((c) => (counts.get(c) ?? 0) > 1);\n if (missing.length > 0 || duplicated.length > 0) {\n throw new Error(\n `INSTALL_TARGET_PAGES drift vs CATEGORIES — missing=[${missing.join(\", \")}] ` +\n `duplicated=[${duplicated.join(\", \")}]. 모든 카테고리는 정확히 한 페이지에 배치해야 한다 ` +\n `(no-false-ship: wizard 미노출 = 거짓 광고).`,\n );\n }\n}\n\nassertPagesCoverAllCategories(INSTALL_TARGET_PAGES);\n\n/**\n * v26.58.1 — Wizard viewport size. clack 의 limitOptions 가 maxItems 안에서만\n * cursor follow + ↕ ... indicator. 미지정 시 Infinity → terminal height 초과 시\n * 위 항목이 scrollback 으로 밀려 selected indicator 안 보임 (사용자 보고된 문제).\n *\n * rowPadding 10 = message line + status footer + safety margin.\n * floor 8 = 너무 작아도 최소한의 viewport 보장.\n */\nfunction viewportItems(itemCount: number): number {\n const rows = process.stdout.rows ?? 24;\n return Math.max(8, Math.min(itemCount, rows - 10));\n}\n\nexport const defaultPrompts: Prompts = {\n intro: (msg) => intro(msg),\n outro: (msg) => outro(msg),\n cancel: (msg) => cancel(msg),\n\n selectTracks: async (initial, step) => {\n // v26.65.0 — step indicator SSOT (wizard-steps.ts). 6-step 통합 (1 tracks · 2 cli · 3 targets · 4 scope · 5 confirm · 6 installing).\n const result = await multiselect({\n message: stepLabel(step, \"Select Track(s)\"),\n options: TRACKS.map((t) => ({ value: t, label: TRACK_LABELS[t] })),\n ...(initial ? { initialValues: initial } : {}),\n maxItems: viewportItems(11),\n required: true,\n });\n return isCancel(result) ? null : (result as Track[]);\n },\n\n selectCli: async (initial, step) => {\n const initialValues: CliBase[] = initial && initial.length > 0 ? [...initial] : [\"claude\"];\n const result = await multiselect({\n message: stepLabel(step, \"Target CLI(s)\"),\n options: [\n { value: \"claude\" as const, label: CLI_BASE_LABELS.claude },\n { value: \"codex\" as const, label: CLI_BASE_LABELS.codex },\n { value: \"opencode\" as const, label: CLI_BASE_LABELS.opencode },\n { value: \"antigravity\" as const, label: CLI_BASE_LABELS.antigravity },\n ],\n initialValues,\n required: true,\n });\n if (isCancel(result)) return null;\n return [...(result as CliBase[])].sort(\n (a, b) => CLI_BASE_SORT_ORDER[a] - CLI_BASE_SORT_ORDER[b],\n );\n },\n\n selectAction: async (state) => {\n const result = await select({\n message: summarizeState(state),\n options: buildRouterChoices(state).map((c) => {\n const label = c.enabled ? c.label : `${c.label} [disabled]`;\n // disabled:true → clack 이 cursor skip + strikethrough (선택 자체 차단).\n return {\n value: c.value,\n label,\n ...(c.hint ? { hint: c.hint } : {}),\n ...(c.enabled ? {} : { disabled: true }),\n };\n }),\n });\n return isCancel(result) ? null : (result as RouterAction);\n },\n\n /**\n * v26.64.0 (ADR-020) — Installation scope select. Default Project (D16 — no global write).\n * Global 은 사용자 명시 opt-in 시에만.\n */\n selectScope: async (initial = \"project\", step) => {\n const result = await select({\n message: stepLabel(step, \"Installation scope\"),\n initialValue: initial,\n options: [\n {\n value: \"project\",\n label: \"Project\",\n hint: \"Install in current directory (committed with your project)\",\n },\n {\n value: \"global\",\n label: \"Global\",\n hint: \"Write to ~/.claude/, ~/.codex/, npm -g (shared across all projects)\",\n },\n ],\n });\n return isCancel(result) ? null : (result as InstallScope);\n },\n\n confirmInstall: async (summary) => {\n const result = await confirm({\n message: `${summary}\\n\\nProceed?`,\n initialValue: true,\n });\n return isCancel(result) ? null : result;\n },\n\n selectInstallTargets: async (initialChecked, step, recap) => {\n // v26.62.2 — groupMultiselect 복귀 + page paginate.\n // v26.62.1 에서 multiselect + disabled separator 시도 → clack 가 disabled option 에\n // 체크박스 강제 + dim/strikethrough 효과 → 카테고리 헤더가 \"옵션 같지만 선택 불가\"\n // 처럼 보여 사용자 보고. groupMultiselect 의 group header 는 라이브러리에서 본래\n // 설명 라인 형태로 자연 표시 → 시각 명료.\n //\n // maxItems 한계 (GroupMultiSelectPrompt 미지원) 는 page 묶음으로 cover:\n // 한 page 안 옵션 ≤ ~30 → 사용자 iTerm2 (30+ rows) 환경에서 fit. 매우 작은 terminal\n // (< 25 rows) 한계는 follow-up.\n //\n // 페이지 정의 = 모듈 스코프 INSTALL_TARGET_PAGES (SSOT, 카테고리 전수 가드됨).\n const pages = INSTALL_TARGET_PAGES;\n const initialSet = new Set<string>(initialChecked);\n const collected = new Set<string>(initialChecked);\n\n const buildPageGroups = (cats: ReadonlyArray<Category>) => {\n const groups: Record<string, Array<{ value: string; label: string; hint?: string }>> = {};\n const flatItems: Array<{ value: string; label: string; hint?: string }> = [];\n for (const cat of cats) {\n const items: Array<{ value: string; label: string; hint?: string }> = [];\n for (const o of VISIBLE_OPTION_DEFS.filter((d) => d.category === cat)) {\n items.push({\n value: `option:${o.key}`,\n // v26.62.3 — group header 와 옵션 사이 시각 hierarchy 강화. label prefix 4 space.\n label: ` ${o.label} [${o.source}]`,\n hint: o.hint,\n });\n }\n // v26.71.0 (PRD v26-71) — tier 우선 정렬 (official → vetted → experimental) + 배지.\n const tierOrder = { official: 0, vetted: 1, experimental: 2 } as const;\n const catAssets = [...EXTERNAL_ASSETS.filter((x) => x.category === cat)].sort(\n (a, b) => tierOrder[assetTrustTier(a.id)] - tierOrder[assetTrustTier(b.id)],\n );\n for (const a of catAssets) {\n const tier = assetTrustTier(a.id);\n const badge =\n tier === \"official\"\n ? \" ★ official\"\n : tier === \"experimental\"\n ? \" ⚠ experimental (opt-in)\"\n : \"\";\n items.push({\n value: `asset:${a.id}`,\n label: ` ${a.id} [${a.source}]${badge}`,\n hint: a.description,\n });\n }\n if (items.length === 0) continue;\n const selectedInCat = items.filter((it) => initialSet.has(it.value)).length;\n const header = `${CATEGORY_TITLES[cat]} [${selectedInCat}/${items.length} ✓ default]`;\n groups[header] = items;\n flatItems.push(...items);\n }\n return { groups, flatItems };\n };\n\n const recapLine = recap\n ? `Tracks: ${recap.tracks.join(\", \")} · CLIs: ${recap.cli.join(\", \")}`\n : \"\";\n\n // alt screen for the whole Step 3 loop. page 전환 시 buffer 안에서 redraw.\n process.stdout.write(\"\\x1b[?1049h\");\n let resultIds: ReadonlyArray<InstallTargetId> | null = null;\n let aborted = false;\n try {\n let pageIdx = 0;\n while (pageIdx < pages.length) {\n const page = pages[pageIdx];\n if (!page) break;\n const { groups, flatItems } = buildPageGroups(page.cats);\n const selectedNow = flatItems.filter((it) => collected.has(it.value)).map((it) => it.value);\n const pageDefault = flatItems.filter((it) => initialSet.has(it.value)).length;\n const totalSelected = collected.size;\n const message = [\n `Step ${step.current}/${step.total} · Page ${pageIdx + 1}/${pages.length} · ${page.label}`,\n recapLine ? ` ${recapLine}` : \"\",\n ` Selected so far: ${totalSelected} items · This page default ✓ ${pageDefault}/${flatItems.length}`,\n \" Space toggle · Enter → next · ESC → prev\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n const groupOpts = {\n message,\n options: groups,\n initialValues: selectedNow,\n required: false,\n selectableGroups: false,\n } as Parameters<typeof groupMultiselect>[0];\n const result = await groupMultiselect(groupOpts);\n if (isCancel(result)) {\n if (pageIdx === 0) {\n aborted = true; // first page ESC → Step 2 back\n break;\n }\n pageIdx--; // prev page\n continue;\n }\n // update collected: remove page items + add the new selection\n for (const it of flatItems) collected.delete(it.value);\n for (const v of result as ReadonlyArray<string>) collected.add(v);\n pageIdx++;\n }\n if (!aborted) {\n resultIds = [...collected] as ReadonlyArray<InstallTargetId>;\n }\n } finally {\n process.stdout.write(\"\\x1b[?1049l\");\n }\n // v26.63.1 — alt screen exit 후 main buffer 에 Step 3 완료 라인 출력. alt buffer\n // 안 동작은 main 에 흔적 0 → Step 1·2·4 사이 Step 3 missing → 사용자 보고.\n // clack `◇` marker + `│` line 으로 다른 step 과 시각 일관성 유지.\n if (resultIds !== null) {\n process.stdout.write(\n `◇ Step ${step.current}/${step.total} — Install targets · ${resultIds.length} selected\\n│\\n`,\n );\n }\n return resultIds;\n },\n};\n",null,"/* IMPORT */\nimport fastStringTruncatedWidth from 'fast-string-truncated-width';\n/* HELPERS */\nconst NO_TRUNCATION = {\n limit: Infinity,\n ellipsis: '',\n ellipsisWidth: 0,\n};\n/* MAIN */\nconst fastStringWidth = (input, options = {}) => {\n return fastStringTruncatedWidth(input, NO_TRUNCATION, options).width;\n};\n/* EXPORT */\nexport default fastStringWidth;\n","/* IMPORT */\nimport { getCodePointsLength, isFullWidth, isWideNotCJKTNotEmoji } from './utils.js';\n/* HELPERS */\nconst ANSI_RE = /[\\u001b\\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\\u001b\\]8;[^;]*;.*?(?:\\u0007|\\u001b\\u005c)/y;\nconst CONTROL_RE = /[\\x00-\\x08\\x0A-\\x1F\\x7F-\\x9F]{1,1000}/y;\nconst CJKT_WIDE_RE = /(?:(?![\\uFF61-\\uFF9F\\uFF00-\\uFFEF])[\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\p{Script=Hangul}\\p{Script=Tangut}]){1,1000}/yu;\nconst TAB_RE = /\\t{1,1000}/y;\nconst EMOJI_RE = /[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*/yu;\nconst LATIN_RE = /(?:[\\x20-\\x7E\\xA0-\\xFF](?!\\uFE0F)){1,1000}/y;\nconst MODIFIER_RE = /\\p{M}+/gu;\nconst NO_TRUNCATION = { limit: Infinity, ellipsis: '' };\n/* MAIN */\nconst getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {\n /* CONSTANTS */\n const LIMIT = truncationOptions.limit ?? Infinity;\n const ELLIPSIS = truncationOptions.ellipsis ?? '';\n const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);\n const ANSI_WIDTH = 0;\n const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;\n const TAB_WIDTH = widthOptions.tabWidth ?? 8;\n const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;\n const FULL_WIDTH_WIDTH = 2;\n const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;\n const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;\n const PARSE_BLOCKS = [\n [LATIN_RE, REGULAR_WIDTH],\n [ANSI_RE, ANSI_WIDTH],\n [CONTROL_RE, CONTROL_WIDTH],\n [TAB_RE, TAB_WIDTH],\n [EMOJI_RE, EMOJI_WIDTH],\n [CJKT_WIDE_RE, WIDE_WIDTH],\n ];\n /* STATE */\n let indexPrev = 0;\n let index = 0;\n let length = input.length;\n let lengthExtra = 0;\n let truncationEnabled = false;\n let truncationIndex = length;\n let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);\n let unmatchedStart = 0;\n let unmatchedEnd = 0;\n let width = 0;\n let widthExtra = 0;\n /* PARSE LOOP */\n outer: while (true) {\n /* UNMATCHED */\n if ((unmatchedEnd > unmatchedStart) || (index >= length && index > indexPrev)) {\n const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);\n lengthExtra = 0;\n for (const char of unmatched.replaceAll(MODIFIER_RE, '')) {\n const codePoint = char.codePointAt(0) || 0;\n if (isFullWidth(codePoint)) {\n widthExtra = FULL_WIDTH_WIDTH;\n }\n else if (isWideNotCJKTNotEmoji(codePoint)) {\n widthExtra = WIDE_WIDTH;\n }\n else {\n widthExtra = REGULAR_WIDTH;\n }\n if ((width + widthExtra) > truncationLimit) {\n truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);\n }\n if ((width + widthExtra) > LIMIT) {\n truncationEnabled = true;\n break outer;\n }\n lengthExtra += char.length;\n width += widthExtra;\n }\n unmatchedStart = unmatchedEnd = 0;\n }\n /* EXITING */\n if (index >= length) {\n break outer;\n }\n /* PARSE BLOCKS */\n for (let i = 0, l = PARSE_BLOCKS.length; i < l; i++) {\n const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];\n BLOCK_RE.lastIndex = index;\n if (BLOCK_RE.test(input)) {\n lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;\n widthExtra = lengthExtra * BLOCK_WIDTH;\n if ((width + widthExtra) > truncationLimit) {\n truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));\n }\n if ((width + widthExtra) > LIMIT) {\n truncationEnabled = true;\n break outer;\n }\n width += widthExtra;\n unmatchedStart = indexPrev;\n unmatchedEnd = index;\n index = indexPrev = BLOCK_RE.lastIndex;\n continue outer;\n }\n }\n /* UNMATCHED INDEX */\n index += 1;\n }\n /* RETURN */\n return {\n width: truncationEnabled ? truncationLimit : width,\n index: truncationEnabled ? truncationIndex : length,\n truncated: truncationEnabled,\n ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH\n };\n};\n/* EXPORT */\nexport default getStringTruncatedWidth;\n","/* MAIN */\nconst getCodePointsLength = (() => {\n const SURROGATE_PAIR_RE = /[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g;\n return (input) => {\n let surrogatePairsNr = 0;\n SURROGATE_PAIR_RE.lastIndex = 0;\n while (SURROGATE_PAIR_RE.test(input)) {\n surrogatePairsNr += 1;\n }\n return input.length - surrogatePairsNr;\n };\n})();\nconst isFullWidth = (x) => {\n return x === 0x3000 || x >= 0xFF01 && x <= 0xFF60 || x >= 0xFFE0 && x <= 0xFFE6;\n};\nconst isWideNotCJKTNotEmoji = (x) => {\n return x === 0x231B || x === 0x2329 || x >= 0x2FF0 && x <= 0x2FFF || x >= 0x3001 && x <= 0x303E || x >= 0x3099 && x <= 0x30FF || x >= 0x3105 && x <= 0x312F || x >= 0x3131 && x <= 0x318E || x >= 0x3190 && x <= 0x31E3 || x >= 0x31EF && x <= 0x321E || x >= 0x3220 && x <= 0x3247 || x >= 0x3250 && x <= 0x4DBF || x >= 0xFE10 && x <= 0xFE19 || x >= 0xFE30 && x <= 0xFE52 || x >= 0xFE54 && x <= 0xFE66 || x >= 0xFE68 && x <= 0xFE6B || x >= 0x1F200 && x <= 0x1F202 || x >= 0x1F210 && x <= 0x1F23B || x >= 0x1F240 && x <= 0x1F248 || x >= 0x20000 && x <= 0x2FFFD || x >= 0x30000 && x <= 0x3FFFD;\n};\n/* EXPORT */\nexport { getCodePointsLength, isFullWidth, isWideNotCJKTNotEmoji };\n","export function findCursor<T extends { disabled?: boolean }>(\n\tcursor: number,\n\tdelta: number,\n\toptions: T[]\n) {\n\tconst hasEnabledOptions = options.some((opt) => !opt.disabled);\n\tif (!hasEnabledOptions) {\n\t\treturn cursor;\n\t}\n\tconst newCursor = cursor + delta;\n\tconst maxCursor = Math.max(options.length - 1, 0);\n\tconst clampedCursor = newCursor < 0 ? maxCursor : newCursor > maxCursor ? 0 : newCursor;\n\tconst newOption = options[clampedCursor];\n\tif (newOption.disabled) {\n\t\treturn findCursor(clampedCursor, delta < 0 ? -1 : 1, options);\n\t}\n\treturn clampedCursor;\n}\n\nexport function findTextCursor(\n\tcursor: number,\n\tdeltaX: number,\n\tdeltaY: number,\n\tvalue: string\n): number {\n\tconst lines = value.split('\\n');\n\tlet cursorY = 0;\n\tlet cursorX = cursor;\n\n\tfor (const line of lines) {\n\t\tif (cursorX <= line.length) {\n\t\t\tbreak;\n\t\t}\n\t\tcursorX -= line.length + 1;\n\t\tcursorY++;\n\t}\n\n\tcursorY = Math.max(0, Math.min(lines.length - 1, cursorY + deltaY));\n\n\tcursorX = Math.min(cursorX, lines[cursorY].length) + deltaX;\n\twhile (cursorX < 0 && cursorY > 0) {\n\t\tcursorY--;\n\t\tcursorX += lines[cursorY].length + 1;\n\t}\n\twhile (cursorX > lines[cursorY].length && cursorY < lines.length - 1) {\n\t\tcursorX -= lines[cursorY].length + 1;\n\t\tcursorY++;\n\t}\n\tcursorX = Math.max(0, Math.min(lines[cursorY].length, cursorX));\n\n\tlet newCursor = 0;\n\tfor (let i = 0; i < cursorY; i++) {\n\t\tnewCursor += lines[i].length + 1;\n\t}\n\treturn newCursor + cursorX;\n}\n","const actions = ['up', 'down', 'left', 'right', 'space', 'enter', 'cancel'] as const;\nexport type Action = (typeof actions)[number];\n\nconst DEFAULT_MONTH_NAMES = [\n\t'January',\n\t'February',\n\t'March',\n\t'April',\n\t'May',\n\t'June',\n\t'July',\n\t'August',\n\t'September',\n\t'October',\n\t'November',\n\t'December',\n];\n\n/** Global settings for Clack programs, stored in memory */\ninterface InternalClackSettings {\n\tactions: Set<Action>;\n\taliases: Map<string, Action>;\n\tmessages: {\n\t\tcancel: string;\n\t\terror: string;\n\t};\n\twithGuide: boolean;\n\tdate: {\n\t\tmonthNames: string[];\n\t\tmessages: {\n\t\t\tinvalidMonth: string;\n\t\t\trequired: string;\n\t\t\tinvalidDay: (days: number, month: string) => string;\n\t\t\tafterMin: (min: Date) => string;\n\t\t\tbeforeMax: (max: Date) => string;\n\t\t};\n\t};\n}\n\nexport const settings: InternalClackSettings = {\n\tactions: new Set(actions),\n\taliases: new Map<string, Action>([\n\t\t// vim support\n\t\t['k', 'up'],\n\t\t['j', 'down'],\n\t\t['h', 'left'],\n\t\t['l', 'right'],\n\t\t['\\x03', 'cancel'],\n\t\t// opinionated defaults!\n\t\t['escape', 'cancel'],\n\t]),\n\tmessages: {\n\t\tcancel: 'Canceled',\n\t\terror: 'Something went wrong',\n\t},\n\twithGuide: true,\n\tdate: {\n\t\tmonthNames: [...DEFAULT_MONTH_NAMES],\n\t\tmessages: {\n\t\t\trequired: 'Please enter a valid date',\n\t\t\tinvalidMonth: 'There are only 12 months in a year',\n\t\t\tinvalidDay: (days, month) => `There are only ${days} days in ${month}`,\n\t\t\tafterMin: (min) => `Date must be on or after ${min.toISOString().slice(0, 10)}`,\n\t\t\tbeforeMax: (max) => `Date must be on or before ${max.toISOString().slice(0, 10)}`,\n\t\t},\n\t},\n};\n\nexport interface ClackSettings {\n\t/**\n\t * Set custom global aliases for the default actions.\n\t * This will not overwrite existing aliases, it will only add new ones!\n\t *\n\t * @param aliases - An object that maps aliases to actions\n\t * @default { k: 'up', j: 'down', h: 'left', l: 'right', '\\x03': 'cancel', 'escape': 'cancel' }\n\t */\n\taliases?: Record<string, Action>;\n\n\t/**\n\t * Custom messages for prompts\n\t */\n\tmessages?: {\n\t\t/**\n\t\t * Custom message to display when a spinner is cancelled\n\t\t * @default \"Canceled\"\n\t\t */\n\t\tcancel?: string;\n\t\t/**\n\t\t * Custom message to display when a spinner encounters an error\n\t\t * @default \"Something went wrong\"\n\t\t */\n\t\terror?: string;\n\t};\n\n\twithGuide?: boolean;\n\n\t/**\n\t * Date prompt localization\n\t */\n\tdate?: {\n\t\t/** Month names for validation messages (January, February, ...) */\n\t\tmonthNames?: string[];\n\t\tmessages?: {\n\t\t\t/** Shown when date is missing */\n\t\t\trequired?: string;\n\t\t\t/** Shown when month > 12 */\n\t\t\tinvalidMonth?: string;\n\t\t\t/** (days, monthName) => message for invalid day */\n\t\t\tinvalidDay?: (days: number, month: string) => string;\n\t\t\t/** (min) => message when date is before minDate */\n\t\t\tafterMin?: (min: Date) => string;\n\t\t\t/** (max) => message when date is after maxDate */\n\t\t\tbeforeMax?: (max: Date) => string;\n\t\t};\n\t};\n}\n\nexport function updateSettings(updates: ClackSettings) {\n\t// Handle each property in the updates\n\tif (updates.aliases !== undefined) {\n\t\tconst aliases = updates.aliases;\n\t\tfor (const alias in aliases) {\n\t\t\tif (!Object.hasOwn(aliases, alias)) continue;\n\n\t\t\tconst action = aliases[alias];\n\t\t\tif (!settings.actions.has(action)) continue;\n\n\t\t\tif (!settings.aliases.has(alias)) {\n\t\t\t\tsettings.aliases.set(alias, action);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (updates.messages !== undefined) {\n\t\tconst messages = updates.messages;\n\t\tif (messages.cancel !== undefined) {\n\t\t\tsettings.messages.cancel = messages.cancel;\n\t\t}\n\t\tif (messages.error !== undefined) {\n\t\t\tsettings.messages.error = messages.error;\n\t\t}\n\t}\n\n\tif (updates.withGuide !== undefined) {\n\t\tsettings.withGuide = updates.withGuide !== false;\n\t}\n\n\tif (updates.date !== undefined) {\n\t\tconst date = updates.date;\n\t\tif (date.monthNames !== undefined) {\n\t\t\tsettings.date.monthNames = [...date.monthNames];\n\t\t}\n\t\tif (date.messages !== undefined) {\n\t\t\tif (date.messages.required !== undefined) {\n\t\t\t\tsettings.date.messages.required = date.messages.required;\n\t\t\t}\n\t\t\tif (date.messages.invalidMonth !== undefined) {\n\t\t\t\tsettings.date.messages.invalidMonth = date.messages.invalidMonth;\n\t\t\t}\n\t\t\tif (date.messages.invalidDay !== undefined) {\n\t\t\t\tsettings.date.messages.invalidDay = date.messages.invalidDay;\n\t\t\t}\n\t\t\tif (date.messages.afterMin !== undefined) {\n\t\t\t\tsettings.date.messages.afterMin = date.messages.afterMin;\n\t\t\t}\n\t\t\tif (date.messages.beforeMax !== undefined) {\n\t\t\t\tsettings.date.messages.beforeMax = date.messages.beforeMax;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Check if a key is an alias for a default action\n * @param key - The raw key which might match to an action\n * @param action - The action to match\n * @returns boolean\n */\nexport function isActionKey(key: string | Array<string | undefined>, action: Action) {\n\tif (typeof key === 'string') {\n\t\treturn settings.aliases.get(key) === action;\n\t}\n\n\tfor (const value of key) {\n\t\tif (value === undefined) continue;\n\t\tif (isActionKey(value, action)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n","export function diffLines(a: string, b: string) {\n\tif (a === b) return;\n\n\tconst aLines = a.split('\\n');\n\tconst bLines = b.split('\\n');\n\tconst numLines = Math.max(aLines.length, bLines.length);\n\tconst diff: number[] = [];\n\n\tfor (let i = 0; i < numLines; i++) {\n\t\tif (aLines[i] !== bLines[i]) diff.push(i);\n\t}\n\n\treturn {\n\t\tlines: diff,\n\t\tnumLinesBefore: aLines.length,\n\t\tnumLinesAfter: bLines.length,\n\t\tnumLines,\n\t};\n}\n","import { stdin, stdout } from 'node:process';\nimport type { Key } from 'node:readline';\nimport * as readline from 'node:readline';\nimport type { Readable, Writable } from 'node:stream';\nimport { ReadStream } from 'node:tty';\nimport { wrapAnsi } from 'fast-wrap-ansi';\nimport { cursor } from 'sisteransi';\nimport { isActionKey } from './settings.js';\n\nexport * from './settings.js';\nexport * from './string.js';\n\nconst isWindows = globalThis.process.platform.startsWith('win');\n\nexport const CANCEL_SYMBOL = Symbol('clack:cancel');\n\nexport function isCancel(value: unknown): value is symbol {\n\treturn value === CANCEL_SYMBOL;\n}\n\nexport function setRawMode(input: Readable, value: boolean) {\n\tconst i = input as typeof stdin;\n\n\tif (i.isTTY) i.setRawMode(value);\n}\n\ninterface BlockOptions {\n\tinput?: Readable;\n\toutput?: Writable;\n\toverwrite?: boolean;\n\thideCursor?: boolean;\n}\n\nexport function block({\n\tinput = stdin,\n\toutput = stdout,\n\toverwrite = true,\n\thideCursor = true,\n}: BlockOptions = {}) {\n\tconst rl = readline.createInterface({\n\t\tinput,\n\t\toutput,\n\t\tprompt: '',\n\t\ttabSize: 1,\n\t});\n\treadline.emitKeypressEvents(input, rl);\n\n\tif (input instanceof ReadStream && input.isTTY) {\n\t\tinput.setRawMode(true);\n\t}\n\n\tconst clear = (data: Buffer, { name, sequence }: Key) => {\n\t\tconst str = String(data);\n\t\tif (isActionKey([str, name, sequence], 'cancel')) {\n\t\t\tif (hideCursor) output.write(cursor.show);\n\t\t\tprocess.exit(0);\n\t\t\treturn;\n\t\t}\n\t\tif (!overwrite) return;\n\t\tconst dx = name === 'return' ? 0 : -1;\n\t\tconst dy = name === 'return' ? -1 : 0;\n\n\t\treadline.moveCursor(output, dx, dy, () => {\n\t\t\treadline.clearLine(output, 1, () => {\n\t\t\t\tinput.once('keypress', clear);\n\t\t\t});\n\t\t});\n\t};\n\tif (hideCursor) output.write(cursor.hide);\n\tinput.once('keypress', clear);\n\n\treturn () => {\n\t\tinput.off('keypress', clear);\n\t\tif (hideCursor) output.write(cursor.show);\n\n\t\t// Prevent Windows specific issues: https://github.com/bombshell-dev/clack/issues/176\n\t\tif (input instanceof ReadStream && input.isTTY && !isWindows) {\n\t\t\tinput.setRawMode(false);\n\t\t}\n\n\t\t// @ts-expect-error fix for https://github.com/nodejs/node/issues/31762#issuecomment-1441223907\n\t\trl.terminal = false;\n\t\trl.close();\n\t};\n}\n\nexport const getColumns = (output: Writable): number => {\n\tif ('columns' in output && typeof output.columns === 'number') {\n\t\treturn output.columns;\n\t}\n\treturn 80;\n};\n\nexport const getRows = (output: Writable): number => {\n\tif ('rows' in output && typeof output.rows === 'number') {\n\t\treturn output.rows;\n\t}\n\treturn 20;\n};\n\nexport function wrapTextWithPrefix(\n\toutput: Writable | undefined,\n\ttext: string,\n\tprefix: string,\n\tstartPrefix: string = prefix,\n\tlineFormatter?: (line: string, index: number) => string\n): string {\n\tconst columns = getColumns(output ?? stdout);\n\tconst wrapped = wrapAnsi(text, columns - prefix.length, {\n\t\thard: true,\n\t\ttrim: false,\n\t});\n\tconst lines = wrapped\n\t\t.split('\\n')\n\t\t.map((line, index) => {\n\t\t\tconst lineString = lineFormatter ? lineFormatter(line, index) : line;\n\t\t\treturn `${index === 0 ? startPrefix : prefix}${lineString}`;\n\t\t})\n\t\t.join('\\n');\n\treturn lines;\n}\n","import { stdin, stdout } from 'node:process';\nimport readline, { type Key, type ReadLine } from 'node:readline';\nimport type { Readable, Writable } from 'node:stream';\nimport { wrapAnsi } from 'fast-wrap-ansi';\nimport { cursor, erase } from 'sisteransi';\nimport type { ClackEvents, ClackState } from '../types.js';\nimport type { Action } from '../utils/index.js';\nimport {\n\tCANCEL_SYMBOL,\n\tdiffLines,\n\tgetRows,\n\tisActionKey,\n\tsetRawMode,\n\tsettings,\n} from '../utils/index.js';\n\nexport interface PromptOptions<TValue, Self extends Prompt<TValue>> {\n\trender(this: Omit<Self, 'prompt'>): string | undefined;\n\tinitialValue?: any;\n\tinitialUserInput?: string;\n\tvalidate?: ((value: TValue | undefined) => string | Error | undefined) | undefined;\n\tinput?: Readable;\n\toutput?: Writable;\n\tsignal?: AbortSignal;\n}\n\nexport default class Prompt<TValue> {\n\tprotected input: Readable;\n\tprotected output: Writable;\n\tprivate _abortSignal?: AbortSignal;\n\n\tprivate rl: ReadLine | undefined;\n\tprivate opts: Omit<PromptOptions<TValue, Prompt<TValue>>, 'render' | 'input' | 'output'>;\n\tprivate _render: (context: Omit<Prompt<TValue>, 'prompt'>) => string | undefined;\n\tprivate _track = false;\n\tprivate _prevFrame = '';\n\tprivate _subscribers = new Map<string, { cb: (...args: any) => any; once?: boolean }[]>();\n\tprotected _cursor = 0;\n\n\tpublic state: ClackState = 'initial';\n\tpublic error = '';\n\tpublic value: TValue | undefined;\n\tpublic userInput = '';\n\n\tconstructor(options: PromptOptions<TValue, Prompt<TValue>>, trackValue = true) {\n\t\tconst { input = stdin, output = stdout, render, signal, ...opts } = options;\n\n\t\tthis.opts = opts;\n\t\tthis.onKeypress = this.onKeypress.bind(this);\n\t\tthis.close = this.close.bind(this);\n\t\tthis.render = this.render.bind(this);\n\t\tthis._render = render.bind(this);\n\t\tthis._track = trackValue;\n\t\tthis._abortSignal = signal;\n\n\t\tthis.input = input;\n\t\tthis.output = output;\n\t}\n\n\t/**\n\t * Unsubscribe all listeners\n\t */\n\tprotected unsubscribe() {\n\t\tthis._subscribers.clear();\n\t}\n\n\t/**\n\t * Set a subscriber with opts\n\t * @param event - The event name\n\t */\n\tprivate setSubscriber<T extends keyof ClackEvents<TValue>>(\n\t\tevent: T,\n\t\topts: { cb: ClackEvents<TValue>[T]; once?: boolean }\n\t) {\n\t\tconst params = this._subscribers.get(event) ?? [];\n\t\tparams.push(opts);\n\t\tthis._subscribers.set(event, params);\n\t}\n\n\t/**\n\t * Subscribe to an event\n\t * @param event - The event name\n\t * @param cb - The callback\n\t */\n\tpublic on<T extends keyof ClackEvents<TValue>>(event: T, cb: ClackEvents<TValue>[T]) {\n\t\tthis.setSubscriber(event, { cb });\n\t}\n\n\t/**\n\t * Subscribe to an event once\n\t * @param event - The event name\n\t * @param cb - The callback\n\t */\n\tpublic once<T extends keyof ClackEvents<TValue>>(event: T, cb: ClackEvents<TValue>[T]) {\n\t\tthis.setSubscriber(event, { cb, once: true });\n\t}\n\n\t/**\n\t * Emit an event with data\n\t * @param event - The event name\n\t * @param data - The data to pass to the callback\n\t */\n\tpublic emit<T extends keyof ClackEvents<TValue>>(\n\t\tevent: T,\n\t\t...data: Parameters<ClackEvents<TValue>[T]>\n\t) {\n\t\tconst cbs = this._subscribers.get(event) ?? [];\n\t\tconst cleanup: (() => void)[] = [];\n\n\t\tfor (const subscriber of cbs) {\n\t\t\tsubscriber.cb(...data);\n\n\t\t\tif (subscriber.once) {\n\t\t\t\tcleanup.push(() => cbs.splice(cbs.indexOf(subscriber), 1));\n\t\t\t}\n\t\t}\n\n\t\tfor (const cb of cleanup) {\n\t\t\tcb();\n\t\t}\n\t}\n\n\tpublic prompt() {\n\t\treturn new Promise<TValue | symbol | undefined>((resolve) => {\n\t\t\tif (this._abortSignal) {\n\t\t\t\tif (this._abortSignal.aborted) {\n\t\t\t\t\tthis.state = 'cancel';\n\n\t\t\t\t\tthis.close();\n\t\t\t\t\treturn resolve(CANCEL_SYMBOL);\n\t\t\t\t}\n\n\t\t\t\tthis._abortSignal.addEventListener(\n\t\t\t\t\t'abort',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tthis.state = 'cancel';\n\t\t\t\t\t\tthis.close();\n\t\t\t\t\t},\n\t\t\t\t\t{ once: true }\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.rl = readline.createInterface({\n\t\t\t\tinput: this.input,\n\t\t\t\ttabSize: 2,\n\t\t\t\tprompt: '',\n\t\t\t\tescapeCodeTimeout: 50,\n\t\t\t\tterminal: true,\n\t\t\t});\n\t\t\tthis.rl.prompt();\n\n\t\t\tif (this.opts.initialUserInput !== undefined) {\n\t\t\t\tthis._setUserInput(this.opts.initialUserInput, true);\n\t\t\t}\n\n\t\t\tthis.input.on('keypress', this.onKeypress);\n\t\t\tsetRawMode(this.input, true);\n\t\t\tthis.output.on('resize', this.render);\n\n\t\t\tthis.render();\n\n\t\t\tthis.once('submit', () => {\n\t\t\t\tthis.output.write(cursor.show);\n\t\t\t\tthis.output.off('resize', this.render);\n\t\t\t\tsetRawMode(this.input, false);\n\t\t\t\tresolve(this.value);\n\t\t\t});\n\t\t\tthis.once('cancel', () => {\n\t\t\t\tthis.output.write(cursor.show);\n\t\t\t\tthis.output.off('resize', this.render);\n\t\t\t\tsetRawMode(this.input, false);\n\t\t\t\tresolve(CANCEL_SYMBOL);\n\t\t\t});\n\t\t});\n\t}\n\n\tprotected _isActionKey(char: string | undefined, _key: Key): boolean {\n\t\treturn char === '\\t';\n\t}\n\n\tprotected _shouldSubmit(_char: string | undefined, _key: Key): boolean {\n\t\treturn true;\n\t}\n\n\tprotected _setValue(value: TValue | undefined): void {\n\t\tthis.value = value;\n\t\tthis.emit('value', this.value);\n\t}\n\n\tprotected _setUserInput(value: string | undefined, write?: boolean): void {\n\t\tthis.userInput = value ?? '';\n\t\tthis.emit('userInput', this.userInput);\n\t\tif (write && this._track && this.rl) {\n\t\t\tthis.rl.write(this.userInput);\n\t\t\tthis._cursor = this.rl.cursor;\n\t\t}\n\t}\n\n\tprotected _clearUserInput(): void {\n\t\tthis.rl?.write(null, { ctrl: true, name: 'u' });\n\t\tthis._setUserInput('');\n\t}\n\n\tprivate onKeypress(char: string | undefined, key: Key) {\n\t\tif (this._track && key.name !== 'return') {\n\t\t\tif (key.name && this._isActionKey(char, key)) {\n\t\t\t\tthis.rl?.write(null, { ctrl: true, name: 'h' });\n\t\t\t}\n\t\t\tthis._cursor = this.rl?.cursor ?? 0;\n\t\t\tthis._setUserInput(this.rl?.line);\n\t\t}\n\n\t\tif (this.state === 'error') {\n\t\t\tthis.state = 'active';\n\t\t}\n\t\tif (key?.name) {\n\t\t\tif (!this._track && settings.aliases.has(key.name)) {\n\t\t\t\tthis.emit('cursor', settings.aliases.get(key.name));\n\t\t\t}\n\t\t\tif (settings.actions.has(key.name as Action)) {\n\t\t\t\tthis.emit('cursor', key.name as Action);\n\t\t\t}\n\t\t}\n\t\tif (char && (char.toLowerCase() === 'y' || char.toLowerCase() === 'n')) {\n\t\t\tthis.emit('confirm', char.toLowerCase() === 'y');\n\t\t}\n\n\t\t// Call the key event handler and emit the key event\n\t\tthis.emit('key', char?.toLowerCase(), key);\n\n\t\tif (key?.name === 'return' && this._shouldSubmit(char, key)) {\n\t\t\tif (this.opts.validate) {\n\t\t\t\tconst problem = this.opts.validate(this.value);\n\t\t\t\tif (problem) {\n\t\t\t\t\tthis.error = problem instanceof Error ? problem.message : problem;\n\t\t\t\t\tthis.state = 'error';\n\t\t\t\t\tthis.rl?.write(this.userInput);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.state !== 'error') {\n\t\t\t\tthis.state = 'submit';\n\t\t\t}\n\t\t}\n\n\t\tif (isActionKey([char, key?.name, key?.sequence], 'cancel')) {\n\t\t\tthis.state = 'cancel';\n\t\t}\n\n\t\tif (this.state === 'submit' || this.state === 'cancel') {\n\t\t\tthis.emit('finalize');\n\t\t}\n\t\tthis.render();\n\t\tif (this.state === 'submit' || this.state === 'cancel') {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\tprotected close() {\n\t\tthis.input.unpipe();\n\t\tthis.input.removeListener('keypress', this.onKeypress);\n\t\tthis.output.write('\\n');\n\t\tsetRawMode(this.input, false);\n\t\tthis.rl?.close();\n\t\tthis.rl = undefined;\n\t\tthis.emit(`${this.state}`, this.value);\n\t\tthis.unsubscribe();\n\t}\n\n\tprivate restoreCursor() {\n\t\tconst lines =\n\t\t\twrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split('\\n')\n\t\t\t\t.length - 1;\n\t\tthis.output.write(cursor.move(-999, lines * -1));\n\t}\n\n\tprivate render() {\n\t\tconst frame = wrapAnsi(this._render(this) ?? '', process.stdout.columns, {\n\t\t\thard: true,\n\t\t\ttrim: false,\n\t\t});\n\t\tif (frame === this._prevFrame) return;\n\n\t\tif (this.state === 'initial') {\n\t\t\tthis.output.write(cursor.hide);\n\t\t} else {\n\t\t\tconst diff = diffLines(this._prevFrame, frame);\n\t\t\tconst rows = getRows(this.output);\n\t\t\tthis.restoreCursor();\n\t\t\tif (diff) {\n\t\t\t\tconst diffOffsetAfter = Math.max(0, diff.numLinesAfter - rows);\n\t\t\t\tconst diffOffsetBefore = Math.max(0, diff.numLinesBefore - rows);\n\t\t\t\tlet diffLine = diff.lines.find((line) => line >= diffOffsetAfter);\n\n\t\t\t\tif (diffLine === undefined) {\n\t\t\t\t\tthis._prevFrame = frame;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// If a single line has changed, only update that line\n\t\t\t\tif (diff.lines.length === 1) {\n\t\t\t\t\tthis.output.write(cursor.move(0, diffLine - diffOffsetBefore));\n\t\t\t\t\tthis.output.write(erase.lines(1));\n\t\t\t\t\tconst lines = frame.split('\\n');\n\t\t\t\t\tthis.output.write(lines[diffLine]);\n\t\t\t\t\tthis._prevFrame = frame;\n\t\t\t\t\tthis.output.write(cursor.move(0, lines.length - diffLine - 1));\n\t\t\t\t\treturn;\n\t\t\t\t\t// If many lines have changed, rerender everything past the first line\n\t\t\t\t} else if (diff.lines.length > 1) {\n\t\t\t\t\tif (diffOffsetAfter < diffOffsetBefore) {\n\t\t\t\t\t\tdiffLine = diffOffsetAfter;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst adjustedDiffLine = diffLine - diffOffsetBefore;\n\t\t\t\t\t\tif (adjustedDiffLine > 0) {\n\t\t\t\t\t\t\tthis.output.write(cursor.move(0, adjustedDiffLine));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.output.write(erase.down());\n\t\t\t\t\tconst lines = frame.split('\\n');\n\t\t\t\t\tconst newLines = lines.slice(diffLine);\n\t\t\t\t\tthis.output.write(newLines.join('\\n'));\n\t\t\t\t\tthis._prevFrame = frame;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.output.write(erase.down());\n\t\t}\n\n\t\tthis.output.write(frame);\n\t\tif (this.state === 'initial') {\n\t\t\tthis.state = 'active';\n\t\t}\n\t\tthis._prevFrame = frame;\n\t}\n}\n","import type { Key } from 'node:readline';\nimport { styleText } from 'node:util';\nimport { findCursor } from '../utils/cursor.js';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\ninterface OptionLike {\n\tvalue: unknown;\n\tlabel?: string;\n\tdisabled?: boolean;\n}\n\ntype FilterFunction<T extends OptionLike> = (search: string, opt: T) => boolean;\n\nfunction getCursorForValue<T extends OptionLike>(\n\tselected: T['value'] | undefined,\n\titems: T[]\n): number {\n\tif (selected === undefined) {\n\t\treturn 0;\n\t}\n\n\tconst currLength = items.length;\n\n\t// If filtering changed the available options, update cursor\n\tif (currLength === 0) {\n\t\treturn 0;\n\t}\n\n\t// Try to maintain the same selected item\n\tconst index = items.findIndex((item) => item.value === selected);\n\treturn index !== -1 ? index : 0;\n}\n\nfunction defaultFilter<T extends OptionLike>(input: string, option: T): boolean {\n\tconst label = option.label ?? String(option.value);\n\treturn label.toLowerCase().includes(input.toLowerCase());\n}\n\nfunction normalisedValue<T>(multiple: boolean, values: T[] | undefined): T | T[] | undefined {\n\tif (!values) {\n\t\treturn undefined;\n\t}\n\tif (multiple) {\n\t\treturn values;\n\t}\n\treturn values[0];\n}\n\nexport interface AutocompleteOptions<T extends OptionLike>\n\textends PromptOptions<T['value'] | T['value'][], AutocompletePrompt<T>> {\n\toptions: T[] | ((this: AutocompletePrompt<T>) => T[]);\n\tfilter?: FilterFunction<T>;\n\tmultiple?: boolean;\n\t/**\n\t * When set (non-empty), pressing Tab with no input fills the field with this value\n\t * and runs the normal filter/selection logic so the user can confirm with Enter.\n\t * Tab only fills the input when the placeholder matches at least one option under\n\t * the prompt's filter (so the value remains selectable).\n\t */\n\tplaceholder?: string;\n}\n\nexport default class AutocompletePrompt<T extends OptionLike> extends Prompt<\n\tT['value'] | T['value'][]\n> {\n\tfilteredOptions: T[];\n\tmultiple: boolean;\n\tisNavigating = false;\n\tselectedValues: Array<T['value']> = [];\n\n\tfocusedValue: T['value'] | undefined;\n\t#cursor = 0;\n\t#lastUserInput = '';\n\t#filterFn: FilterFunction<T> | undefined;\n\t#options: T[] | (() => T[]);\n\t#placeholder: string | undefined;\n\n\tget cursor(): number {\n\t\treturn this.#cursor;\n\t}\n\n\tget userInputWithCursor() {\n\t\tif (!this.userInput) {\n\t\t\treturn styleText(['inverse', 'hidden'], '_');\n\t\t}\n\t\tif (this._cursor >= this.userInput.length) {\n\t\t\treturn `${this.userInput}█`;\n\t\t}\n\t\tconst s1 = this.userInput.slice(0, this._cursor);\n\t\tconst [s2, ...s3] = this.userInput.slice(this._cursor);\n\t\treturn `${s1}${styleText('inverse', s2)}${s3.join('')}`;\n\t}\n\n\tget options(): T[] {\n\t\tif (typeof this.#options === 'function') {\n\t\t\treturn this.#options();\n\t\t}\n\t\treturn this.#options;\n\t}\n\n\tconstructor(opts: AutocompleteOptions<T>) {\n\t\tsuper(opts);\n\n\t\tthis.#options = opts.options;\n\t\tthis.#placeholder = opts.placeholder;\n\t\tconst options = this.options;\n\t\tthis.filteredOptions = [...options];\n\t\tthis.multiple = opts.multiple === true;\n\t\tthis.#filterFn =\n\t\t\ttypeof opts.options === 'function' ? opts.filter : (opts.filter ?? defaultFilter);\n\t\tlet initialValues: unknown[] | undefined;\n\t\tif (opts.initialValue && Array.isArray(opts.initialValue)) {\n\t\t\tif (this.multiple) {\n\t\t\t\tinitialValues = opts.initialValue;\n\t\t\t} else {\n\t\t\t\tinitialValues = opts.initialValue.slice(0, 1);\n\t\t\t}\n\t\t} else {\n\t\t\tif (!this.multiple && this.options.length > 0) {\n\t\t\t\tinitialValues = [this.options[0].value];\n\t\t\t}\n\t\t}\n\n\t\tif (initialValues) {\n\t\t\tfor (const selectedValue of initialValues) {\n\t\t\t\tconst selectedIndex = options.findIndex((opt) => opt.value === selectedValue);\n\t\t\t\tif (selectedIndex !== -1) {\n\t\t\t\t\tthis.toggleSelected(selectedValue);\n\t\t\t\t\tthis.#cursor = selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.focusedValue = this.options[this.#cursor]?.value;\n\n\t\tthis.on('key', (char, key) => this.#onKey(char, key));\n\t\tthis.on('userInput', (value) => this.#onUserInputChanged(value));\n\t}\n\n\tprotected override _isActionKey(char: string | undefined, key: Key): boolean {\n\t\treturn (\n\t\t\tchar === '\\t' ||\n\t\t\t(this.multiple &&\n\t\t\t\tthis.isNavigating &&\n\t\t\t\tkey.name === 'space' &&\n\t\t\t\tchar !== undefined &&\n\t\t\t\tchar !== '')\n\t\t);\n\t}\n\n\t#onKey(_char: string | undefined, key: Key): void {\n\t\tconst isUpKey = key.name === 'up';\n\t\tconst isDownKey = key.name === 'down';\n\t\tconst isReturnKey = key.name === 'return';\n\n\t\t// Tab with empty input and placeholder: fill input with placeholder to trigger autocomplete\n\t\t// Only when the placeholder matches at least one (non-disabled) option so the value remains selectable\n\t\tconst isEmptyOrOnlyTab = this.userInput === '' || this.userInput === '\\t';\n\t\tconst placeholder = this.#placeholder;\n\t\tconst options = this.options;\n\t\tconst placeholderMatchesOption =\n\t\t\tplaceholder !== undefined &&\n\t\t\tplaceholder !== '' &&\n\t\t\toptions.some(\n\t\t\t\t(opt) => !opt.disabled && (this.#filterFn ? this.#filterFn(placeholder, opt) : true)\n\t\t\t);\n\t\tif (key.name === 'tab' && isEmptyOrOnlyTab && placeholderMatchesOption) {\n\t\t\tif (this.userInput === '\\t') {\n\t\t\t\tthis._clearUserInput();\n\t\t\t}\n\t\t\tthis._setUserInput(placeholder, true);\n\t\t\tthis.isNavigating = false;\n\t\t\treturn;\n\t\t}\n\n\t\t// Start navigation mode with up/down arrows\n\t\tif (isUpKey || isDownKey) {\n\t\t\tthis.#cursor = findCursor(this.#cursor, isUpKey ? -1 : 1, this.filteredOptions);\n\t\t\tthis.focusedValue = this.filteredOptions[this.#cursor]?.value;\n\t\t\tif (!this.multiple) {\n\t\t\t\tthis.selectedValues = [this.focusedValue];\n\t\t\t}\n\t\t\tthis.isNavigating = true;\n\t\t} else if (isReturnKey) {\n\t\t\tthis.value = normalisedValue(this.multiple, this.selectedValues);\n\t\t} else {\n\t\t\tif (this.multiple) {\n\t\t\t\tif (\n\t\t\t\t\tthis.focusedValue !== undefined &&\n\t\t\t\t\t(key.name === 'tab' || (this.isNavigating && key.name === 'space'))\n\t\t\t\t) {\n\t\t\t\t\tthis.toggleSelected(this.focusedValue);\n\t\t\t\t} else {\n\t\t\t\t\tthis.isNavigating = false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this.focusedValue) {\n\t\t\t\t\tthis.selectedValues = [this.focusedValue];\n\t\t\t\t}\n\t\t\t\tthis.isNavigating = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tdeselectAll() {\n\t\tthis.selectedValues = [];\n\t}\n\n\ttoggleSelected(value: T['value']) {\n\t\tif (this.filteredOptions.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.multiple) {\n\t\t\tif (this.selectedValues.includes(value)) {\n\t\t\t\tthis.selectedValues = this.selectedValues.filter((v) => v !== value);\n\t\t\t} else {\n\t\t\t\tthis.selectedValues = [...this.selectedValues, value];\n\t\t\t}\n\t\t} else {\n\t\t\tthis.selectedValues = [value];\n\t\t}\n\t}\n\n\t#onUserInputChanged(value: string): void {\n\t\tif (value !== this.#lastUserInput) {\n\t\t\tthis.#lastUserInput = value;\n\n\t\t\tconst options = this.options;\n\n\t\t\tif (value && this.#filterFn) {\n\t\t\t\tthis.filteredOptions = options.filter((opt) => this.#filterFn?.(value, opt));\n\t\t\t} else {\n\t\t\t\tthis.filteredOptions = [...options];\n\t\t\t}\n\t\t\tconst valueCursor = getCursorForValue(this.focusedValue, this.filteredOptions);\n\t\t\tthis.#cursor = findCursor(valueCursor, 0, this.filteredOptions);\n\t\t\tconst focusedOption = this.filteredOptions[this.#cursor];\n\t\t\tif (focusedOption && !focusedOption.disabled) {\n\t\t\t\tthis.focusedValue = focusedOption.value;\n\t\t\t} else {\n\t\t\t\tthis.focusedValue = undefined;\n\t\t\t}\n\t\t\tif (!this.multiple) {\n\t\t\t\tif (this.focusedValue !== undefined) {\n\t\t\t\t\tthis.toggleSelected(this.focusedValue);\n\t\t\t\t} else {\n\t\t\t\t\tthis.deselectAll();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n","import { cursor } from 'sisteransi';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface ConfirmOptions extends PromptOptions<boolean, ConfirmPrompt> {\n\tactive: string;\n\tinactive: string;\n\tinitialValue?: boolean;\n}\n\nexport default class ConfirmPrompt extends Prompt<boolean> {\n\tget cursor() {\n\t\treturn this.value ? 0 : 1;\n\t}\n\n\tprivate get _value() {\n\t\treturn this.cursor === 0;\n\t}\n\n\tconstructor(opts: ConfirmOptions) {\n\t\tsuper(opts, false);\n\t\tthis.value = !!opts.initialValue;\n\n\t\tthis.on('userInput', () => {\n\t\t\tthis.value = this._value;\n\t\t});\n\n\t\tthis.on('confirm', (confirm) => {\n\t\t\tthis.output.write(cursor.move(0, -1));\n\t\t\tthis.value = confirm;\n\t\t\tthis.state = 'submit';\n\t\t\tthis.close();\n\t\t});\n\n\t\tthis.on('cursor', () => {\n\t\t\tthis.value = !this.value;\n\t\t});\n\t}\n}\n","import type { Key } from 'node:readline';\nimport { settings } from '../utils/settings.js';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\ninterface SegmentConfig {\n\ttype: 'year' | 'month' | 'day';\n\tlen: number;\n}\n\nexport interface DateParts {\n\tyear: string;\n\tmonth: string;\n\tday: string;\n}\n\nexport type DateFormat = 'YMD' | 'MDY' | 'DMY';\n\nconst SEGMENTS: Record<string, SegmentConfig> = {\n\tY: { type: 'year', len: 4 },\n\tM: { type: 'month', len: 2 },\n\tD: { type: 'day', len: 2 },\n} as const;\n\nfunction segmentsFor(fmt: DateFormat): SegmentConfig[] {\n\treturn [...fmt].map((c) => SEGMENTS[c as keyof typeof SEGMENTS]);\n}\n\nfunction detectLocaleFormat(locale?: string): { segments: SegmentConfig[]; separator: string } {\n\tconst fmt = new Intl.DateTimeFormat(locale, {\n\t\tyear: 'numeric',\n\t\tmonth: '2-digit',\n\t\tday: '2-digit',\n\t});\n\tconst parts = fmt.formatToParts(new Date(2000, 0, 15));\n\tconst segments: SegmentConfig[] = [];\n\tlet separator = '/';\n\tfor (const p of parts) {\n\t\tif (p.type === 'literal') {\n\t\t\tseparator = p.value.trim() || p.value;\n\t\t} else if (p.type === 'year' || p.type === 'month' || p.type === 'day') {\n\t\t\tsegments.push({ type: p.type, len: p.type === 'year' ? 4 : 2 });\n\t\t}\n\t}\n\treturn { segments, separator };\n}\n\n/** Parse string segment values to numbers, treating blanks as 0 */\nfunction parseSegmentToNum(s: string): number {\n\treturn Number.parseInt((s || '0').replace(/_/g, '0'), 10) || 0;\n}\n\nfunction parse(parts: DateParts): { year: number; month: number; day: number } {\n\treturn {\n\t\tyear: parseSegmentToNum(parts.year),\n\t\tmonth: parseSegmentToNum(parts.month),\n\t\tday: parseSegmentToNum(parts.day),\n\t};\n}\n\nfunction daysInMonth(year: number, month: number): number {\n\treturn new Date(year || 2001, month || 1, 0).getDate();\n}\n\n/** Validate and return calendar parts, or undefined if invalid */\nfunction validParts(parts: DateParts): { year: number; month: number; day: number } | undefined {\n\tconst { year, month, day } = parse(parts);\n\tif (!year || year < 0 || year > 9999) return undefined;\n\tif (!month || month < 1 || month > 12) return undefined;\n\tif (!day || day < 1) return undefined;\n\tconst d = new Date(Date.UTC(year, month - 1, day));\n\tif (d.getUTCFullYear() !== year || d.getUTCMonth() !== month - 1 || d.getUTCDate() !== day)\n\t\treturn undefined;\n\treturn { year, month, day };\n}\n\nfunction toDate(parts: DateParts): Date | undefined {\n\tconst p = validParts(parts);\n\treturn p ? new Date(Date.UTC(p.year, p.month - 1, p.day)) : undefined;\n}\n\nfunction segmentBounds(\n\ttype: 'year' | 'month' | 'day',\n\tctx: { year: number; month: number },\n\tminDate: Date | undefined,\n\tmaxDate: Date | undefined\n): { min: number; max: number } {\n\tconst minP = minDate\n\t\t? {\n\t\t\t\tyear: minDate.getUTCFullYear(),\n\t\t\t\tmonth: minDate.getUTCMonth() + 1,\n\t\t\t\tday: minDate.getUTCDate(),\n\t\t\t}\n\t\t: null;\n\tconst maxP = maxDate\n\t\t? {\n\t\t\t\tyear: maxDate.getUTCFullYear(),\n\t\t\t\tmonth: maxDate.getUTCMonth() + 1,\n\t\t\t\tday: maxDate.getUTCDate(),\n\t\t\t}\n\t\t: null;\n\n\tif (type === 'year') {\n\t\treturn { min: minP?.year ?? 1, max: maxP?.year ?? 9999 };\n\t}\n\tif (type === 'month') {\n\t\treturn {\n\t\t\tmin: minP && ctx.year === minP.year ? minP.month : 1,\n\t\t\tmax: maxP && ctx.year === maxP.year ? maxP.month : 12,\n\t\t};\n\t}\n\treturn {\n\t\tmin: minP && ctx.year === minP.year && ctx.month === minP.month ? minP.day : 1,\n\t\tmax:\n\t\t\tmaxP && ctx.year === maxP.year && ctx.month === maxP.month\n\t\t\t\t? maxP.day\n\t\t\t\t: daysInMonth(ctx.year, ctx.month),\n\t};\n}\n\nexport interface DateOptions extends PromptOptions<Date, DatePrompt> {\n\tformat?: DateFormat;\n\tlocale?: string;\n\tseparator?: string;\n\tdefaultValue?: Date;\n\tinitialValue?: Date;\n\tminDate?: Date;\n\tmaxDate?: Date;\n}\n\nexport default class DatePrompt extends Prompt<Date> {\n\t#segments: SegmentConfig[];\n\t#separator: string;\n\t#segmentValues: DateParts;\n\t#minDate: Date | undefined;\n\t#maxDate: Date | undefined;\n\t#cursor = { segmentIndex: 0, positionInSegment: 0 };\n\t#segmentSelected = true;\n\t#pendingTensDigit: string | null = null;\n\n\tinlineError = '';\n\n\tget segmentCursor() {\n\t\treturn { ...this.#cursor };\n\t}\n\n\tget segmentValues(): DateParts {\n\t\treturn { ...this.#segmentValues };\n\t}\n\n\tget segments(): readonly SegmentConfig[] {\n\t\treturn this.#segments;\n\t}\n\n\tget separator(): string {\n\t\treturn this.#separator;\n\t}\n\n\tget formattedValue(): string {\n\t\treturn this.#format(this.#segmentValues);\n\t}\n\n\t#format(parts: DateParts): string {\n\t\treturn this.#segments.map((s) => parts[s.type]).join(this.#separator);\n\t}\n\n\t#refresh() {\n\t\tthis._setUserInput(this.#format(this.#segmentValues));\n\t\tthis._setValue(toDate(this.#segmentValues) ?? undefined);\n\t}\n\n\tconstructor(opts: DateOptions) {\n\t\tconst detected = opts.format\n\t\t\t? { segments: segmentsFor(opts.format), separator: opts.separator ?? '/' }\n\t\t\t: detectLocaleFormat(opts.locale);\n\t\tconst sep = opts.separator ?? detected.separator;\n\t\tconst segments = opts.format ? segmentsFor(opts.format) : detected.segments;\n\n\t\tconst initialDate = opts.initialValue ?? opts.defaultValue;\n\t\tconst segmentValues: DateParts = initialDate\n\t\t\t? {\n\t\t\t\t\tyear: String(initialDate.getUTCFullYear()).padStart(4, '0'),\n\t\t\t\t\tmonth: String(initialDate.getUTCMonth() + 1).padStart(2, '0'),\n\t\t\t\t\tday: String(initialDate.getUTCDate()).padStart(2, '0'),\n\t\t\t\t}\n\t\t\t: { year: '____', month: '__', day: '__' };\n\n\t\tconst initialDisplay = segments.map((s) => segmentValues[s.type]).join(sep);\n\n\t\tsuper({ ...opts, initialUserInput: initialDisplay }, false);\n\t\tthis.#segments = segments;\n\t\tthis.#separator = sep;\n\t\tthis.#segmentValues = segmentValues;\n\t\tthis.#minDate = opts.minDate;\n\t\tthis.#maxDate = opts.maxDate;\n\t\tthis.#refresh();\n\n\t\tthis.on('cursor', (key) => this.#onCursor(key));\n\t\tthis.on('key', (char, key) => this.#onKey(char, key));\n\t\tthis.on('finalize', () => this.#onFinalize(opts));\n\t}\n\n\t#seg(): { segment: SegmentConfig; index: number } | undefined {\n\t\tconst index = Math.max(0, Math.min(this.#cursor.segmentIndex, this.#segments.length - 1));\n\t\tconst segment = this.#segments[index];\n\t\tif (!segment) return undefined;\n\t\tthis.#cursor.positionInSegment = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.#cursor.positionInSegment, segment.len - 1)\n\t\t);\n\t\treturn { segment, index };\n\t}\n\n\t#navigate(direction: 1 | -1) {\n\t\tthis.inlineError = '';\n\t\tthis.#pendingTensDigit = null;\n\t\tconst ctx = this.#seg();\n\t\tif (!ctx) return;\n\t\tthis.#cursor.segmentIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.#segments.length - 1, ctx.index + direction)\n\t\t);\n\t\tthis.#cursor.positionInSegment = 0;\n\t\tthis.#segmentSelected = true;\n\t}\n\n\t#adjust(direction: 1 | -1) {\n\t\tconst ctx = this.#seg();\n\t\tif (!ctx) return;\n\t\tconst { segment } = ctx;\n\t\tconst raw = this.#segmentValues[segment.type];\n\t\tconst isBlank = !raw || raw.replace(/_/g, '') === '';\n\t\tconst num = Number.parseInt((raw || '0').replace(/_/g, '0'), 10) || 0;\n\t\tconst bounds = segmentBounds(\n\t\t\tsegment.type,\n\t\t\tparse(this.#segmentValues),\n\t\t\tthis.#minDate,\n\t\t\tthis.#maxDate\n\t\t);\n\n\t\tlet next: number;\n\t\tif (isBlank) {\n\t\t\tnext = direction === 1 ? bounds.min : bounds.max;\n\t\t} else {\n\t\t\tnext = Math.max(Math.min(bounds.max, num + direction), bounds.min);\n\t\t}\n\n\t\tthis.#segmentValues = {\n\t\t\t...this.#segmentValues,\n\t\t\t[segment.type]: next.toString().padStart(segment.len, '0'),\n\t\t};\n\t\tthis.#segmentSelected = true;\n\t\tthis.#pendingTensDigit = null;\n\t\tthis.#refresh();\n\t}\n\n\t#onCursor(key?: string) {\n\t\tif (!key) return;\n\t\tswitch (key) {\n\t\t\tcase 'right':\n\t\t\t\treturn this.#navigate(1);\n\t\t\tcase 'left':\n\t\t\t\treturn this.#navigate(-1);\n\t\t\tcase 'up':\n\t\t\t\treturn this.#adjust(1);\n\t\t\tcase 'down':\n\t\t\t\treturn this.#adjust(-1);\n\t\t}\n\t}\n\n\t#onKey(char: string | undefined, key: Key) {\n\t\t// Backspace\n\t\tconst isBackspace =\n\t\t\tkey?.name === 'backspace' ||\n\t\t\tkey?.sequence === '\\x7f' ||\n\t\t\tkey?.sequence === '\\b' ||\n\t\t\tchar === '\\x7f' ||\n\t\t\tchar === '\\b';\n\t\tif (isBackspace) {\n\t\t\tthis.inlineError = '';\n\t\t\tconst ctx = this.#seg();\n\t\t\tif (!ctx) return;\n\t\t\tif (!this.#segmentValues[ctx.segment.type].replace(/_/g, '')) {\n\t\t\t\tthis.#navigate(-1);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#segmentValues[ctx.segment.type] = '_'.repeat(ctx.segment.len);\n\t\t\tthis.#segmentSelected = true;\n\t\t\tthis.#cursor.positionInSegment = 0;\n\t\t\tthis.#refresh();\n\t\t\treturn;\n\t\t}\n\n\t\t// Tab navigation\n\t\tif (key?.name === 'tab') {\n\t\t\tthis.inlineError = '';\n\t\t\tconst ctx = this.#seg();\n\t\t\tif (!ctx) return;\n\t\t\tconst dir = key.shift ? -1 : 1;\n\t\t\tconst next = ctx.index + dir;\n\t\t\tif (next >= 0 && next < this.#segments.length) {\n\t\t\t\tthis.#cursor.segmentIndex = next;\n\t\t\t\tthis.#cursor.positionInSegment = 0;\n\t\t\t\tthis.#segmentSelected = true;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Digit input\n\t\tif (char && /^[0-9]$/.test(char)) {\n\t\t\tconst ctx = this.#seg();\n\t\t\tif (!ctx) return;\n\t\t\tconst { segment } = ctx;\n\t\t\tconst isBlank = !this.#segmentValues[segment.type].replace(/_/g, '');\n\n\t\t\t// Pending tens digit: complete the two-digit entry\n\t\t\tif (this.#segmentSelected && this.#pendingTensDigit !== null && !isBlank) {\n\t\t\t\tconst newVal = this.#pendingTensDigit + char;\n\t\t\t\tconst newParts = { ...this.#segmentValues, [segment.type]: newVal };\n\t\t\t\tconst err = this.#validateSegment(newParts, segment);\n\t\t\t\tif (err) {\n\t\t\t\t\tthis.inlineError = err;\n\t\t\t\t\tthis.#pendingTensDigit = null;\n\t\t\t\t\tthis.#segmentSelected = false;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.inlineError = '';\n\t\t\t\tthis.#segmentValues[segment.type] = newVal;\n\t\t\t\tthis.#pendingTensDigit = null;\n\t\t\t\tthis.#segmentSelected = false;\n\t\t\t\tthis.#refresh();\n\t\t\t\tif (ctx.index < this.#segments.length - 1) {\n\t\t\t\t\tthis.#cursor.segmentIndex = ctx.index + 1;\n\t\t\t\t\tthis.#cursor.positionInSegment = 0;\n\t\t\t\t\tthis.#segmentSelected = true;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Clear-on-type: typing into a selected filled segment clears it first\n\t\t\tif (this.#segmentSelected && !isBlank) {\n\t\t\t\tthis.#segmentValues[segment.type] = '_'.repeat(segment.len);\n\t\t\t\tthis.#cursor.positionInSegment = 0;\n\t\t\t}\n\t\t\tthis.#segmentSelected = false;\n\t\t\tthis.#pendingTensDigit = null;\n\n\t\t\tconst display = this.#segmentValues[segment.type];\n\t\t\tconst firstBlank = display.indexOf('_');\n\t\t\tconst pos =\n\t\t\t\tfirstBlank >= 0 ? firstBlank : Math.min(this.#cursor.positionInSegment, segment.len - 1);\n\t\t\tif (pos < 0 || pos >= segment.len) return;\n\n\t\t\tlet newVal = display.slice(0, pos) + char + display.slice(pos + 1);\n\n\t\t\t// Smart digit placement\n\t\t\tlet shouldStaySelected = false;\n\t\t\tif (pos === 0 && display === '__' && (segment.type === 'month' || segment.type === 'day')) {\n\t\t\t\tconst digit = Number.parseInt(char, 10);\n\t\t\t\tnewVal = `0${char}`;\n\t\t\t\tshouldStaySelected = digit <= (segment.type === 'month' ? 1 : 2);\n\t\t\t}\n\t\t\tif (segment.type === 'year') {\n\t\t\t\tconst digits = display.replace(/_/g, '');\n\t\t\t\tnewVal = (digits + char).padStart(segment.len, '_');\n\t\t\t}\n\n\t\t\tif (!newVal.includes('_')) {\n\t\t\t\tconst newParts = { ...this.#segmentValues, [segment.type]: newVal };\n\t\t\t\tconst err = this.#validateSegment(newParts, segment);\n\t\t\t\tif (err) {\n\t\t\t\t\tthis.inlineError = err;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.inlineError = '';\n\n\t\t\tthis.#segmentValues[segment.type] = newVal;\n\n\t\t\t// Clamp only when the current segment is fully entered\n\t\t\tconst parsed = !newVal.includes('_') ? validParts(this.#segmentValues) : undefined;\n\t\t\tif (parsed) {\n\t\t\t\tconst { year, month } = parsed;\n\t\t\t\tconst maxDay = daysInMonth(year, month);\n\t\t\t\tthis.#segmentValues = {\n\t\t\t\t\tyear: String(Math.max(0, Math.min(9999, year))).padStart(4, '0'),\n\t\t\t\t\tmonth: String(Math.max(1, Math.min(12, month))).padStart(2, '0'),\n\t\t\t\t\tday: String(Math.max(1, Math.min(maxDay, parsed.day))).padStart(2, '0'),\n\t\t\t\t};\n\t\t\t}\n\t\t\tthis.#refresh();\n\n\t\t\t// Advance cursor\n\t\t\tconst nextBlank = newVal.indexOf('_');\n\t\t\tif (shouldStaySelected) {\n\t\t\t\tthis.#segmentSelected = true;\n\t\t\t\tthis.#pendingTensDigit = char;\n\t\t\t} else if (nextBlank >= 0) {\n\t\t\t\tthis.#cursor.positionInSegment = nextBlank;\n\t\t\t} else if (firstBlank >= 0 && ctx.index < this.#segments.length - 1) {\n\t\t\t\tthis.#cursor.segmentIndex = ctx.index + 1;\n\t\t\t\tthis.#cursor.positionInSegment = 0;\n\t\t\t\tthis.#segmentSelected = true;\n\t\t\t} else {\n\t\t\t\tthis.#cursor.positionInSegment = Math.min(pos + 1, segment.len - 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t#validateSegment(parts: DateParts, seg: SegmentConfig): string | undefined {\n\t\tconst { month, day } = parse(parts);\n\t\tif (seg.type === 'month' && (month < 0 || month > 12)) {\n\t\t\treturn settings.date.messages.invalidMonth;\n\t\t}\n\t\tif (seg.type === 'day' && (day < 0 || day > 31)) {\n\t\t\treturn settings.date.messages.invalidDay(31, 'any month');\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t#onFinalize(opts: DateOptions) {\n\t\tconst { year, month, day } = parse(this.#segmentValues);\n\t\tif (year && month && day) {\n\t\t\tconst maxDay = daysInMonth(year, month);\n\t\t\tthis.#segmentValues = {\n\t\t\t\t...this.#segmentValues,\n\t\t\t\tday: String(Math.min(day, maxDay)).padStart(2, '0'),\n\t\t\t};\n\t\t}\n\t\tthis.value = toDate(this.#segmentValues) ?? opts.defaultValue ?? undefined;\n\t}\n}\n","import Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface GroupMultiSelectOptions<T extends { value: any }>\n\textends PromptOptions<T['value'][], GroupMultiSelectPrompt<T>> {\n\toptions: Record<string, T[]>;\n\tinitialValues?: T['value'][];\n\trequired?: boolean;\n\tcursorAt?: T['value'];\n\tselectableGroups?: boolean;\n}\nexport default class GroupMultiSelectPrompt<T extends { value: any }> extends Prompt<T['value'][]> {\n\toptions: (T & { group: string | boolean })[];\n\tcursor = 0;\n\t#selectableGroups: boolean;\n\n\tgetGroupItems(group: string): T[] {\n\t\treturn this.options.filter((o) => o.group === group);\n\t}\n\n\tisGroupSelected(group: string) {\n\t\tconst items = this.getGroupItems(group);\n\t\tconst value = this.value;\n\t\tif (value === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\treturn items.every((i) => value.includes(i.value));\n\t}\n\n\tprivate toggleValue() {\n\t\tconst item = this.options[this.cursor];\n\t\tif (this.value === undefined) {\n\t\t\tthis.value = [];\n\t\t}\n\t\tif (item.group === true) {\n\t\t\tconst group = item.value;\n\t\t\tconst groupedItems = this.getGroupItems(group);\n\t\t\tif (this.isGroupSelected(group)) {\n\t\t\t\tthis.value = this.value.filter(\n\t\t\t\t\t(v: string) => groupedItems.findIndex((i) => i.value === v) === -1\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.value = [...this.value, ...groupedItems.map((i) => i.value)];\n\t\t\t}\n\t\t\tthis.value = Array.from(new Set(this.value));\n\t\t} else {\n\t\t\tconst selected = this.value.includes(item.value);\n\t\t\tthis.value = selected\n\t\t\t\t? this.value.filter((v: T['value']) => v !== item.value)\n\t\t\t\t: [...this.value, item.value];\n\t\t}\n\t}\n\n\tconstructor(opts: GroupMultiSelectOptions<T>) {\n\t\tsuper(opts, false);\n\t\tconst { options } = opts;\n\t\tthis.#selectableGroups = opts.selectableGroups !== false;\n\t\tthis.options = Object.entries(options).flatMap(([key, option]) => [\n\t\t\t{ value: key, group: true, label: key },\n\t\t\t...option.map((opt) => ({ ...opt, group: key })),\n\t\t]) as any;\n\t\tthis.value = [...(opts.initialValues ?? [])];\n\t\tthis.cursor = Math.max(\n\t\t\tthis.options.findIndex(({ value }) => value === opts.cursorAt),\n\t\t\tthis.#selectableGroups ? 0 : 1\n\t\t);\n\n\t\tthis.on('cursor', (key) => {\n\t\t\tswitch (key) {\n\t\t\t\tcase 'left':\n\t\t\t\tcase 'up': {\n\t\t\t\t\tthis.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;\n\t\t\t\t\tconst currentIsGroup = this.options[this.cursor]?.group === true;\n\t\t\t\t\tif (!this.#selectableGroups && currentIsGroup) {\n\t\t\t\t\t\tthis.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'down':\n\t\t\t\tcase 'right': {\n\t\t\t\t\tthis.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;\n\t\t\t\t\tconst currentIsGroup = this.options[this.cursor]?.group === true;\n\t\t\t\t\tif (!this.#selectableGroups && currentIsGroup) {\n\t\t\t\t\t\tthis.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'space':\n\t\t\t\t\tthis.toggleValue();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\t}\n}\n","import type { Key } from 'node:readline';\nimport { styleText } from 'node:util';\nimport { findTextCursor } from '../utils/cursor.js';\nimport { type Action, settings } from '../utils/index.js';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface MultiLineOptions extends PromptOptions<string, MultiLinePrompt> {\n\tplaceholder?: string;\n\tdefaultValue?: string;\n\tshowSubmit?: boolean;\n}\n\nexport default class MultiLinePrompt extends Prompt<string> {\n\t#lastKeyWasReturn = false;\n\t#showSubmit: boolean;\n\tpublic focused: 'editor' | 'submit' = 'editor';\n\n\tget userInputWithCursor() {\n\t\tif (this.state === 'submit') {\n\t\t\treturn this.userInput;\n\t\t}\n\t\tconst userInput = this.userInput;\n\t\tif (this.cursor >= userInput.length) {\n\t\t\treturn `${userInput}█`;\n\t\t}\n\t\tconst s1 = userInput.slice(0, this.cursor);\n\t\tconst s2 = userInput[this.cursor];\n\t\tconst s3 = userInput.slice(this.cursor + 1);\n\t\tif (s2 === '\\n') return `${s1}█\\n${s3}`;\n\t\treturn `${s1}${styleText('inverse', s2)}${s3}`;\n\t}\n\tget cursor() {\n\t\treturn this._cursor;\n\t}\n\t#insertAtCursor(char: string) {\n\t\tif (this.userInput.length === 0) {\n\t\t\tthis._setUserInput(char);\n\t\t\treturn;\n\t\t}\n\t\tthis._setUserInput(\n\t\t\tthis.userInput.slice(0, this.cursor) + char + this.userInput.slice(this.cursor)\n\t\t);\n\t}\n\t#handleCursor(key?: Action) {\n\t\tconst text = this.value ?? '';\n\t\tswitch (key) {\n\t\t\tcase 'up':\n\t\t\t\tthis._cursor = findTextCursor(this._cursor, 0, -1, text);\n\t\t\t\treturn;\n\t\t\tcase 'down':\n\t\t\t\tthis._cursor = findTextCursor(this._cursor, 0, 1, text);\n\t\t\t\treturn;\n\t\t\tcase 'left':\n\t\t\t\tthis._cursor = findTextCursor(this._cursor, -1, 0, text);\n\t\t\t\treturn;\n\t\t\tcase 'right':\n\t\t\t\tthis._cursor = findTextCursor(this._cursor, 1, 0, text);\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\tprotected override _shouldSubmit(_char: string | undefined, _key: Key): boolean {\n\t\tif (this.#showSubmit) {\n\t\t\tif (this.focused === 'submit') {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tthis.#insertAtCursor('\\n');\n\t\t\tthis._cursor++;\n\t\t\treturn false;\n\t\t}\n\t\tconst wasReturn = this.#lastKeyWasReturn;\n\t\tthis.#lastKeyWasReturn = true;\n\t\tif (wasReturn) {\n\t\t\tif (this.userInput[this.cursor - 1] === '\\n') {\n\t\t\t\tthis._setUserInput(\n\t\t\t\t\tthis.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)\n\t\t\t\t);\n\t\t\t\tthis._cursor--;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\tthis.#insertAtCursor('\\n');\n\t\tthis._cursor++;\n\t\treturn false;\n\t}\n\n\tconstructor(opts: MultiLineOptions) {\n\t\tsuper(opts, false);\n\t\tthis.#showSubmit = opts.showSubmit ?? false;\n\n\t\tthis.on('key', (char, key) => {\n\t\t\tif (key?.name && settings.actions.has(key.name as Action)) {\n\t\t\t\tthis.#handleCursor(key.name as Action);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (char === '\\t' && this.#showSubmit) {\n\t\t\t\tthis.focused = this.focused === 'editor' ? 'submit' : 'editor';\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (key?.name === 'return') {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#lastKeyWasReturn = false;\n\t\t\tif (key?.name === 'backspace' && this.cursor > 0) {\n\t\t\t\tthis._setUserInput(\n\t\t\t\t\tthis.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)\n\t\t\t\t);\n\t\t\t\tthis._cursor--;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (key?.name === 'delete' && this.cursor < this.userInput.length) {\n\t\t\t\tthis._setUserInput(\n\t\t\t\t\tthis.userInput.slice(0, this.cursor) + this.userInput.slice(this.cursor + 1)\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (char) {\n\t\t\t\tif (this.#showSubmit && this.focused === 'submit') {\n\t\t\t\t\tthis.focused = 'editor';\n\t\t\t\t}\n\t\t\t\tthis.#insertAtCursor(char ?? '');\n\t\t\t\tthis._cursor++;\n\t\t\t}\n\t\t});\n\n\t\tthis.on('userInput', (input) => {\n\t\t\tthis._setValue(input);\n\t\t});\n\t\tthis.on('finalize', () => {\n\t\t\tif (!this.value) {\n\t\t\t\tthis.value = opts.defaultValue;\n\t\t\t}\n\t\t\tif (this.value === undefined) {\n\t\t\t\tthis.value = '';\n\t\t\t}\n\t\t});\n\t}\n}\n","import { findCursor } from '../utils/cursor.js';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\ninterface OptionLike {\n\tvalue: any;\n\tdisabled?: boolean;\n}\n\nexport interface MultiSelectOptions<T extends OptionLike>\n\textends PromptOptions<T['value'][], MultiSelectPrompt<T>> {\n\toptions: T[];\n\tinitialValues?: T['value'][];\n\trequired?: boolean;\n\tcursorAt?: T['value'];\n}\nexport default class MultiSelectPrompt<T extends OptionLike> extends Prompt<T['value'][]> {\n\toptions: T[];\n\tcursor = 0;\n\n\tprivate get _value(): T['value'] {\n\t\treturn this.options[this.cursor].value;\n\t}\n\n\tprivate get _enabledOptions(): T[] {\n\t\treturn this.options.filter((option) => option.disabled !== true);\n\t}\n\n\tprivate toggleAll() {\n\t\tconst enabledOptions = this._enabledOptions;\n\t\tconst allSelected = this.value !== undefined && this.value.length === enabledOptions.length;\n\t\tthis.value = allSelected ? [] : enabledOptions.map((v) => v.value);\n\t}\n\n\tprivate toggleInvert() {\n\t\tconst value = this.value;\n\t\tif (!value) {\n\t\t\treturn;\n\t\t}\n\t\tconst notSelected = this._enabledOptions.filter((v) => !value.includes(v.value));\n\t\tthis.value = notSelected.map((v) => v.value);\n\t}\n\n\tprivate toggleValue() {\n\t\tif (this.value === undefined) {\n\t\t\tthis.value = [];\n\t\t}\n\t\tconst selected = this.value.includes(this._value);\n\t\tthis.value = selected\n\t\t\t? this.value.filter((value) => value !== this._value)\n\t\t\t: [...this.value, this._value];\n\t}\n\n\tconstructor(opts: MultiSelectOptions<T>) {\n\t\tsuper(opts, false);\n\n\t\tthis.options = opts.options;\n\t\tthis.value = [...(opts.initialValues ?? [])];\n\t\tconst cursor = Math.max(\n\t\t\tthis.options.findIndex(({ value }) => value === opts.cursorAt),\n\t\t\t0\n\t\t);\n\t\tthis.cursor = this.options[cursor].disabled ? findCursor<T>(cursor, 1, this.options) : cursor;\n\t\tthis.on('key', (char) => {\n\t\t\tif (char === 'a') {\n\t\t\t\tthis.toggleAll();\n\t\t\t}\n\t\t\tif (char === 'i') {\n\t\t\t\tthis.toggleInvert();\n\t\t\t}\n\t\t});\n\n\t\tthis.on('cursor', (key) => {\n\t\t\tswitch (key) {\n\t\t\t\tcase 'left':\n\t\t\t\tcase 'up':\n\t\t\t\t\tthis.cursor = findCursor<T>(this.cursor, -1, this.options);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'down':\n\t\t\t\tcase 'right':\n\t\t\t\t\tthis.cursor = findCursor<T>(this.cursor, 1, this.options);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'space':\n\t\t\t\t\tthis.toggleValue();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\t}\n}\n","import { styleText } from 'node:util';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface PasswordOptions extends PromptOptions<string, PasswordPrompt> {\n\tmask?: string;\n}\nexport default class PasswordPrompt extends Prompt<string> {\n\tprivate _mask = '•';\n\tget cursor() {\n\t\treturn this._cursor;\n\t}\n\tget masked() {\n\t\treturn this.userInput.replaceAll(/./g, this._mask);\n\t}\n\tget userInputWithCursor() {\n\t\tif (this.state === 'submit' || this.state === 'cancel') {\n\t\t\treturn this.masked;\n\t\t}\n\t\tconst userInput = this.userInput;\n\t\tif (this.cursor >= userInput.length) {\n\t\t\treturn `${this.masked}${styleText(['inverse', 'hidden'], '_')}`;\n\t\t}\n\t\tconst masked = this.masked;\n\t\tconst s1 = masked.slice(0, this.cursor);\n\t\tconst s2 = masked.slice(this.cursor);\n\t\treturn `${s1}${styleText('inverse', s2[0])}${s2.slice(1)}`;\n\t}\n\tclear() {\n\t\tthis._clearUserInput();\n\t}\n\tconstructor({ mask, ...opts }: PasswordOptions) {\n\t\tsuper(opts);\n\t\tthis._mask = mask ?? '•';\n\t\tthis.on('userInput', (input) => {\n\t\t\tthis._setValue(input);\n\t\t});\n\t}\n}\n","import { findCursor } from '../utils/cursor.js';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface SelectOptions<T extends { value: any; disabled?: boolean }>\n\textends PromptOptions<T['value'], SelectPrompt<T>> {\n\toptions: T[];\n\tinitialValue?: T['value'];\n}\nexport default class SelectPrompt<T extends { value: any; disabled?: boolean }> extends Prompt<\n\tT['value']\n> {\n\toptions: T[];\n\tcursor = 0;\n\n\tprivate get _selectedValue() {\n\t\treturn this.options[this.cursor];\n\t}\n\n\tprivate changeValue() {\n\t\tthis.value = this._selectedValue.value;\n\t}\n\n\tconstructor(opts: SelectOptions<T>) {\n\t\tsuper(opts, false);\n\n\t\tthis.options = opts.options;\n\n\t\tconst initialCursor = this.options.findIndex(({ value }) => value === opts.initialValue);\n\t\tconst cursor = initialCursor === -1 ? 0 : initialCursor;\n\t\tthis.cursor = this.options[cursor].disabled ? findCursor<T>(cursor, 1, this.options) : cursor;\n\t\tthis.changeValue();\n\n\t\tthis.on('cursor', (key) => {\n\t\t\tswitch (key) {\n\t\t\t\tcase 'left':\n\t\t\t\tcase 'up':\n\t\t\t\t\tthis.cursor = findCursor<T>(this.cursor, -1, this.options);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'down':\n\t\t\t\tcase 'right':\n\t\t\t\t\tthis.cursor = findCursor<T>(this.cursor, 1, this.options);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.changeValue();\n\t\t});\n\t}\n}\n","import Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface SelectKeyOptions<T extends { value: string }>\n\textends PromptOptions<T['value'], SelectKeyPrompt<T>> {\n\toptions: T[];\n\tcaseSensitive?: boolean;\n}\nexport default class SelectKeyPrompt<T extends { value: string }> extends Prompt<T['value']> {\n\toptions: T[];\n\tcursor = 0;\n\n\tconstructor(opts: SelectKeyOptions<T>) {\n\t\tsuper(opts, false);\n\n\t\tthis.options = opts.options;\n\t\tconst caseSensitive = opts.caseSensitive === true;\n\t\tconst keys = this.options.map(({ value: [initial] }) => {\n\t\t\treturn caseSensitive ? initial : initial?.toLowerCase();\n\t\t});\n\t\tthis.cursor = Math.max(keys.indexOf(opts.initialValue), 0);\n\n\t\tthis.on('key', (key, keyInfo) => {\n\t\t\tif (!key) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst casedKey = caseSensitive && keyInfo.shift ? key.toUpperCase() : key;\n\t\t\tif (!keys.includes(casedKey)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst value = this.options.find(({ value: [initial] }) => {\n\t\t\t\treturn caseSensitive ? initial === casedKey : initial?.toLowerCase() === key;\n\t\t\t});\n\t\t\tif (value) {\n\t\t\t\tthis.value = value.value;\n\t\t\t\tthis.state = 'submit';\n\t\t\t\tthis.emit('submit');\n\t\t\t}\n\t\t});\n\t}\n}\n","import { styleText } from 'node:util';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface TextOptions extends PromptOptions<string, TextPrompt> {\n\tplaceholder?: string;\n\tdefaultValue?: string;\n}\n\nexport default class TextPrompt extends Prompt<string> {\n\tget userInputWithCursor() {\n\t\tif (this.state === 'submit') {\n\t\t\treturn this.userInput;\n\t\t}\n\t\tconst userInput = this.userInput;\n\t\tif (this.cursor >= userInput.length) {\n\t\t\treturn `${this.userInput}█`;\n\t\t}\n\t\tconst s1 = userInput.slice(0, this.cursor);\n\t\tconst [s2, ...s3] = userInput.slice(this.cursor);\n\t\treturn `${s1}${styleText('inverse', s2)}${s3.join('')}`;\n\t}\n\tget cursor() {\n\t\treturn this._cursor;\n\t}\n\tconstructor(opts: TextOptions) {\n\t\tsuper({\n\t\t\t...opts,\n\t\t\tinitialUserInput: opts.initialUserInput ?? opts.initialValue,\n\t\t});\n\n\t\tthis.on('userInput', (input) => {\n\t\t\tthis._setValue(input);\n\t\t});\n\t\tthis.on('finalize', () => {\n\t\t\tif (!this.value) {\n\t\t\t\tthis.value = opts.defaultValue;\n\t\t\t}\n\t\t\tif (this.value === undefined) {\n\t\t\t\tthis.value = '';\n\t\t\t}\n\t\t});\n\t}\n}\n","import process from 'node:process';\n\nexport default function isUnicodeSupported() {\n\tif (process.platform !== 'win32') {\n\t\treturn process.env.TERM !== 'linux'; // Linux console (kernel)\n\t}\n\n\treturn Boolean(process.env.CI)\n\t\t|| Boolean(process.env.WT_SESSION) // Windows Terminal\n\t\t|| Boolean(process.env.TERMINUS_SUBLIME) // Terminus (<0.2.27)\n\t\t|| process.env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder\n\t\t|| process.env.TERM_PROGRAM === 'Terminus-Sublime'\n\t\t|| process.env.TERM_PROGRAM === 'vscode'\n\t\t|| process.env.TERM === 'xterm-256color'\n\t\t|| process.env.TERM === 'alacritty'\n\t\t|| process.env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';\n}\n","import type { Readable, Writable } from 'node:stream';\nimport { styleText } from 'node:util';\nimport type { State } from '@clack/core';\nimport isUnicodeSupported from 'is-unicode-supported';\n\nexport const unicode = isUnicodeSupported();\nexport const isCI = (): boolean => process.env.CI === 'true';\nexport const isTTY = (output: Writable): boolean => {\n\treturn (output as Writable & { isTTY?: boolean }).isTTY === true;\n};\nexport const unicodeOr = (c: string, fallback: string) => (unicode ? c : fallback);\nexport const S_STEP_ACTIVE = unicodeOr('◆', '*');\nexport const S_STEP_CANCEL = unicodeOr('■', 'x');\nexport const S_STEP_ERROR = unicodeOr('▲', 'x');\nexport const S_STEP_SUBMIT = unicodeOr('◇', 'o');\n\nexport const S_BAR_START = unicodeOr('┌', 'T');\nexport const S_BAR = unicodeOr('│', '|');\nexport const S_BAR_END = unicodeOr('└', '—');\nexport const S_BAR_START_RIGHT = unicodeOr('┐', 'T');\nexport const S_BAR_END_RIGHT = unicodeOr('┘', '—');\n\nexport const S_RADIO_ACTIVE = unicodeOr('●', '>');\nexport const S_RADIO_INACTIVE = unicodeOr('○', ' ');\nexport const S_CHECKBOX_ACTIVE = unicodeOr('◻', '[•]');\nexport const S_CHECKBOX_SELECTED = unicodeOr('◼', '[+]');\nexport const S_CHECKBOX_INACTIVE = unicodeOr('◻', '[ ]');\nexport const S_PASSWORD_MASK = unicodeOr('▪', '•');\n\nexport const S_BAR_H = unicodeOr('─', '-');\nexport const S_CORNER_TOP_RIGHT = unicodeOr('╮', '+');\nexport const S_CONNECT_LEFT = unicodeOr('├', '+');\nexport const S_CORNER_BOTTOM_RIGHT = unicodeOr('╯', '+');\nexport const S_CORNER_BOTTOM_LEFT = unicodeOr('╰', '+');\nexport const S_CORNER_TOP_LEFT = unicodeOr('╭', '+');\n\nexport const S_INFO = unicodeOr('●', '•');\nexport const S_SUCCESS = unicodeOr('◆', '*');\nexport const S_WARN = unicodeOr('▲', '!');\nexport const S_ERROR = unicodeOr('■', 'x');\n\nexport const symbol = (state: State) => {\n\tswitch (state) {\n\t\tcase 'initial':\n\t\tcase 'active':\n\t\t\treturn styleText('cyan', S_STEP_ACTIVE);\n\t\tcase 'cancel':\n\t\t\treturn styleText('red', S_STEP_CANCEL);\n\t\tcase 'error':\n\t\t\treturn styleText('yellow', S_STEP_ERROR);\n\t\tcase 'submit':\n\t\t\treturn styleText('green', S_STEP_SUBMIT);\n\t}\n};\n\nexport const symbolBar = (state: State) => {\n\tswitch (state) {\n\t\tcase 'initial':\n\t\tcase 'active':\n\t\t\treturn styleText('cyan', S_BAR);\n\t\tcase 'cancel':\n\t\t\treturn styleText('red', S_BAR);\n\t\tcase 'error':\n\t\t\treturn styleText('yellow', S_BAR);\n\t\tcase 'submit':\n\t\t\treturn styleText('green', S_BAR);\n\t}\n};\n\nexport interface CommonOptions {\n\tinput?: Readable;\n\toutput?: Writable;\n\tsignal?: AbortSignal;\n\twithGuide?: boolean;\n}\n","import { styleText } from 'node:util';\nimport { getColumns, getRows } from '@clack/core';\nimport { wrapAnsi } from 'fast-wrap-ansi';\nimport type { CommonOptions } from './common.js';\n\nexport interface LimitOptionsParams<TOption> extends CommonOptions {\n\toptions: TOption[];\n\tcursor: number;\n\tstyle: (option: TOption, active: boolean) => string;\n\tmaxItems?: number;\n\tcolumnPadding?: number;\n\trowPadding?: number;\n}\n\nconst trimLines = (\n\tgroups: Array<string[]>,\n\tinitialLineCount: number,\n\tstartIndex: number,\n\tendIndex: number,\n\tmaxLines: number\n) => {\n\tlet lineCount = initialLineCount;\n\tlet removals = 0;\n\tfor (let i = startIndex; i < endIndex; i++) {\n\t\tconst group = groups[i];\n\t\tlineCount = lineCount - group.length;\n\t\tremovals++;\n\t\tif (lineCount <= maxLines) {\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn { lineCount, removals };\n};\n\nexport const limitOptions = <TOption>({\n\tcursor,\n\toptions,\n\tstyle,\n\toutput = process.stdout,\n\tmaxItems = Number.POSITIVE_INFINITY,\n\tcolumnPadding = 0,\n\trowPadding = 4,\n}: LimitOptionsParams<TOption>): string[] => {\n\tconst columns = getColumns(output);\n\tconst maxWidth = columns - columnPadding;\n\tconst rows = getRows(output);\n\tconst overflowFormat = styleText('dim', '...');\n\n\tconst outputMaxItems = Math.max(rows - rowPadding, 0);\n\t// We clamp to minimum 5 because anything less doesn't make sense UX wise\n\tconst computedMaxItems = Math.max(Math.min(maxItems, outputMaxItems), 5);\n\tlet slidingWindowLocation = 0;\n\n\tif (cursor >= computedMaxItems - 3) {\n\t\tslidingWindowLocation = Math.max(\n\t\t\tMath.min(cursor - computedMaxItems + 3, options.length - computedMaxItems),\n\t\t\t0\n\t\t);\n\t}\n\n\tlet shouldRenderTopEllipsis = computedMaxItems < options.length && slidingWindowLocation > 0;\n\tlet shouldRenderBottomEllipsis =\n\t\tcomputedMaxItems < options.length && slidingWindowLocation + computedMaxItems < options.length;\n\n\tconst slidingWindowLocationEnd = Math.min(\n\t\tslidingWindowLocation + computedMaxItems,\n\t\toptions.length\n\t);\n\tconst lineGroups: Array<string[]> = [];\n\tlet lineCount = 0;\n\tif (shouldRenderTopEllipsis) {\n\t\tlineCount++;\n\t}\n\tif (shouldRenderBottomEllipsis) {\n\t\tlineCount++;\n\t}\n\n\tconst slidingWindowLocationWithEllipsis =\n\t\tslidingWindowLocation + (shouldRenderTopEllipsis ? 1 : 0);\n\tconst slidingWindowLocationEndWithEllipsis =\n\t\tslidingWindowLocationEnd - (shouldRenderBottomEllipsis ? 1 : 0);\n\n\tfor (let i = slidingWindowLocationWithEllipsis; i < slidingWindowLocationEndWithEllipsis; i++) {\n\t\tconst wrappedLines = wrapAnsi(style(options[i], i === cursor), maxWidth, {\n\t\t\thard: true,\n\t\t\ttrim: false,\n\t\t}).split('\\n');\n\t\tlineGroups.push(wrappedLines);\n\t\tlineCount += wrappedLines.length;\n\t}\n\n\tif (lineCount > outputMaxItems) {\n\t\tlet precedingRemovals = 0;\n\t\tlet followingRemovals = 0;\n\t\tlet newLineCount = lineCount;\n\t\tconst cursorGroupIndex = cursor - slidingWindowLocationWithEllipsis;\n\t\tconst trimLinesLocal = (startIndex: number, endIndex: number) =>\n\t\t\ttrimLines(lineGroups, newLineCount, startIndex, endIndex, outputMaxItems);\n\n\t\tif (shouldRenderTopEllipsis) {\n\t\t\t({ lineCount: newLineCount, removals: precedingRemovals } = trimLinesLocal(\n\t\t\t\t0,\n\t\t\t\tcursorGroupIndex\n\t\t\t));\n\t\t\tif (newLineCount > outputMaxItems) {\n\t\t\t\t({ lineCount: newLineCount, removals: followingRemovals } = trimLinesLocal(\n\t\t\t\t\tcursorGroupIndex + 1,\n\t\t\t\t\tlineGroups.length\n\t\t\t\t));\n\t\t\t}\n\t\t} else {\n\t\t\t({ lineCount: newLineCount, removals: followingRemovals } = trimLinesLocal(\n\t\t\t\tcursorGroupIndex + 1,\n\t\t\t\tlineGroups.length\n\t\t\t));\n\t\t\tif (newLineCount > outputMaxItems) {\n\t\t\t\t({ lineCount: newLineCount, removals: precedingRemovals } = trimLinesLocal(\n\t\t\t\t\t0,\n\t\t\t\t\tcursorGroupIndex\n\t\t\t\t));\n\t\t\t}\n\t\t}\n\n\t\tif (precedingRemovals > 0) {\n\t\t\tshouldRenderTopEllipsis = true;\n\t\t\tlineGroups.splice(0, precedingRemovals);\n\t\t}\n\t\tif (followingRemovals > 0) {\n\t\t\tshouldRenderBottomEllipsis = true;\n\t\t\tlineGroups.splice(lineGroups.length - followingRemovals, followingRemovals);\n\t\t}\n\t}\n\n\tconst result: string[] = [];\n\tif (shouldRenderTopEllipsis) {\n\t\tresult.push(overflowFormat);\n\t}\n\tfor (const lineGroup of lineGroups) {\n\t\tfor (const line of lineGroup) {\n\t\t\tresult.push(line);\n\t\t}\n\t}\n\tif (shouldRenderBottomEllipsis) {\n\t\tresult.push(overflowFormat);\n\t}\n\n\treturn result;\n};\n","import { styleText } from 'node:util';\nimport { AutocompletePrompt, settings } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_CHECKBOX_INACTIVE,\n\tS_CHECKBOX_SELECTED,\n\tS_RADIO_ACTIVE,\n\tS_RADIO_INACTIVE,\n\tsymbol,\n} from './common.js';\nimport { limitOptions } from './limit-options.js';\nimport type { Option } from './select.js';\n\nfunction getLabel<T>(option: Option<T>) {\n\treturn option.label ?? String(option.value ?? '');\n}\n\nfunction getFilteredOption<T>(searchText: string, option: Option<T>): boolean {\n\tif (!searchText) {\n\t\treturn true;\n\t}\n\tconst label = (option.label ?? String(option.value ?? '')).toLowerCase();\n\tconst hint = (option.hint ?? '').toLowerCase();\n\tconst value = String(option.value).toLowerCase();\n\tconst term = searchText.toLowerCase();\n\n\treturn label.includes(term) || hint.includes(term) || value.includes(term);\n}\n\nfunction getSelectedOptions<T>(values: T[], options: Option<T>[]): Option<T>[] {\n\tconst results: Option<T>[] = [];\n\n\tfor (const option of options) {\n\t\tif (values.includes(option.value)) {\n\t\t\tresults.push(option);\n\t\t}\n\t}\n\n\treturn results;\n}\n\ninterface AutocompleteSharedOptions<Value> extends CommonOptions {\n\t/**\n\t * The message to display to the user.\n\t */\n\tmessage: string;\n\t/**\n\t * Available options for the autocomplete prompt.\n\t */\n\toptions: Option<Value>[] | ((this: AutocompletePrompt<Option<Value>>) => Option<Value>[]);\n\t/**\n\t * Maximum number of items to display at once.\n\t */\n\tmaxItems?: number;\n\t/**\n\t * Placeholder text to display when no input is provided.\n\t */\n\tplaceholder?: string;\n\t/**\n\t * Validates the value\n\t */\n\tvalidate?: (value: Value | Value[] | undefined) => string | Error | undefined;\n\t/**\n\t * Custom filter function to match options against search input.\n\t * If not provided, a default filter that matches label, hint, and value is used.\n\t */\n\tfilter?: (search: string, option: Option<Value>) => boolean;\n}\n\nexport interface AutocompleteOptions<Value> extends AutocompleteSharedOptions<Value> {\n\t/**\n\t * The initial selected value.\n\t */\n\tinitialValue?: Value;\n\t/**\n\t * The initial user input\n\t */\n\tinitialUserInput?: string;\n}\n\nexport const autocomplete = <Value>(opts: AutocompleteOptions<Value>) => {\n\tconst prompt = new AutocompletePrompt({\n\t\toptions: opts.options,\n\t\tinitialValue: opts.initialValue ? [opts.initialValue] : undefined,\n\t\tinitialUserInput: opts.initialUserInput,\n\t\tplaceholder: opts.placeholder,\n\t\tfilter:\n\t\t\topts.filter ??\n\t\t\t((search: string, opt: Option<Value>) => {\n\t\t\t\treturn getFilteredOption(search, opt);\n\t\t\t}),\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tvalidate: opts.validate,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\t// Title and message display\n\t\t\tconst headings = hasGuide\n\t\t\t\t? [`${styleText('gray', S_BAR)}`, `${symbol(this.state)} ${opts.message}`]\n\t\t\t\t: [`${symbol(this.state)} ${opts.message}`];\n\t\t\tconst userInput = this.userInput;\n\t\t\tconst options = this.options;\n\t\t\tconst placeholder = opts.placeholder;\n\t\t\tconst showPlaceholder = userInput === '' && placeholder !== undefined;\n\t\t\tconst opt = (option: Option<Value>, state: 'inactive' | 'active' | 'disabled') => {\n\t\t\t\tconst label = getLabel(option);\n\t\t\t\tconst hint =\n\t\t\t\t\toption.hint && option.value === this.focusedValue\n\t\t\t\t\t\t? styleText('dim', ` (${option.hint})`)\n\t\t\t\t\t\t: '';\n\t\t\t\tswitch (state) {\n\t\t\t\t\tcase 'active':\n\t\t\t\t\t\treturn `${styleText('green', S_RADIO_ACTIVE)} ${label}${hint}`;\n\t\t\t\t\tcase 'inactive':\n\t\t\t\t\t\treturn `${styleText('dim', S_RADIO_INACTIVE)} ${styleText('dim', label)}`;\n\t\t\t\t\tcase 'disabled':\n\t\t\t\t\t\treturn `${styleText('gray', S_RADIO_INACTIVE)} ${styleText(['strikethrough', 'gray'], label)}`;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Handle different states\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\t// Show selected value\n\t\t\t\t\tconst selected = getSelectedOptions(this.selectedValues, options);\n\t\t\t\t\tconst label =\n\t\t\t\t\t\tselected.length > 0 ? ` ${styleText('dim', selected.map(getLabel).join(', '))}` : '';\n\t\t\t\t\tconst submitPrefix = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${headings.join('\\n')}\\n${submitPrefix}${label}`;\n\t\t\t\t}\n\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst userInputText = userInput\n\t\t\t\t\t\t? ` ${styleText(['strikethrough', 'dim'], userInput)}`\n\t\t\t\t\t\t: '';\n\t\t\t\t\tconst cancelPrefix = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${headings.join('\\n')}\\n${cancelPrefix}${userInputText}`;\n\t\t\t\t}\n\n\t\t\t\tdefault: {\n\t\t\t\t\tconst barStyle = this.state === 'error' ? 'yellow' : 'cyan';\n\t\t\t\t\tconst guidePrefix = hasGuide ? `${styleText(barStyle, S_BAR)} ` : '';\n\t\t\t\t\tconst guidePrefixEnd = hasGuide ? styleText(barStyle, S_BAR_END) : '';\n\t\t\t\t\t// Display cursor position - show plain text in navigation mode\n\t\t\t\t\tlet searchText = '';\n\t\t\t\t\tif (this.isNavigating || showPlaceholder) {\n\t\t\t\t\t\tconst searchTextValue = showPlaceholder ? placeholder : userInput;\n\t\t\t\t\t\tsearchText = searchTextValue !== '' ? ` ${styleText('dim', searchTextValue)}` : '';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsearchText = ` ${this.userInputWithCursor}`;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Show match count if filtered\n\t\t\t\t\tconst matches =\n\t\t\t\t\t\tthis.filteredOptions.length !== options.length\n\t\t\t\t\t\t\t? styleText(\n\t\t\t\t\t\t\t\t\t'dim',\n\t\t\t\t\t\t\t\t\t` (${this.filteredOptions.length} match${this.filteredOptions.length === 1 ? '' : 'es'})`\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: '';\n\n\t\t\t\t\t// No matches message\n\t\t\t\t\tconst noResults =\n\t\t\t\t\t\tthis.filteredOptions.length === 0 && userInput\n\t\t\t\t\t\t\t? [`${guidePrefix}${styleText('yellow', 'No matches found')}`]\n\t\t\t\t\t\t\t: [];\n\n\t\t\t\t\tconst validationError =\n\t\t\t\t\t\tthis.state === 'error' ? [`${guidePrefix}${styleText('yellow', this.error)}`] : [];\n\n\t\t\t\t\tif (hasGuide) {\n\t\t\t\t\t\theadings.push(`${guidePrefix.trimEnd()}`);\n\t\t\t\t\t}\n\t\t\t\t\theadings.push(\n\t\t\t\t\t\t`${guidePrefix}${styleText('dim', 'Search:')}${searchText}${matches}`,\n\t\t\t\t\t\t...noResults,\n\t\t\t\t\t\t...validationError\n\t\t\t\t\t);\n\n\t\t\t\t\t// Show instructions\n\t\t\t\t\tconst instructions = [\n\t\t\t\t\t\t`${styleText('dim', '↑/↓')} to select`,\n\t\t\t\t\t\t`${styleText('dim', 'Enter:')} confirm`,\n\t\t\t\t\t\t`${styleText('dim', 'Type:')} to search`,\n\t\t\t\t\t];\n\n\t\t\t\t\tconst footers = [`${guidePrefix}${instructions.join(' • ')}`, guidePrefixEnd];\n\n\t\t\t\t\t// Render options with selection\n\t\t\t\t\tconst displayOptions =\n\t\t\t\t\t\tthis.filteredOptions.length === 0\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: limitOptions({\n\t\t\t\t\t\t\t\t\tcursor: this.cursor,\n\t\t\t\t\t\t\t\t\toptions: this.filteredOptions,\n\t\t\t\t\t\t\t\t\tcolumnPadding: hasGuide ? 3 : 0, // for `| ` when guide is shown\n\t\t\t\t\t\t\t\t\trowPadding: headings.length + footers.length,\n\t\t\t\t\t\t\t\t\tstyle: (option, active) => {\n\t\t\t\t\t\t\t\t\t\treturn opt(\n\t\t\t\t\t\t\t\t\t\t\toption,\n\t\t\t\t\t\t\t\t\t\t\toption.disabled ? 'disabled' : active ? 'active' : 'inactive'\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tmaxItems: opts.maxItems,\n\t\t\t\t\t\t\t\t\toutput: opts.output,\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t// Return the formatted prompt\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...headings,\n\t\t\t\t\t\t...displayOptions.map((option) => `${guidePrefix}${option}`),\n\t\t\t\t\t\t...footers,\n\t\t\t\t\t].join('\\n');\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t});\n\n\t// Return the result or cancel symbol\n\treturn prompt.prompt() as Promise<Value | symbol>;\n};\n\n// Type definition for the autocompleteMultiselect component\nexport interface AutocompleteMultiSelectOptions<Value> extends AutocompleteSharedOptions<Value> {\n\t/**\n\t * The initial selected values\n\t */\n\tinitialValues?: Value[];\n\t/**\n\t * If true, at least one option must be selected\n\t */\n\trequired?: boolean;\n}\n\n/**\n * Integrated autocomplete multiselect - combines type-ahead filtering with multiselect in one UI\n */\nexport const autocompleteMultiselect = <Value>(opts: AutocompleteMultiSelectOptions<Value>) => {\n\tconst formatOption = (\n\t\toption: Option<Value>,\n\t\tactive: boolean,\n\t\tselectedValues: Value[],\n\t\tfocusedValue: Value | undefined\n\t) => {\n\t\tconst isSelected = selectedValues.includes(option.value);\n\t\tconst label = option.label ?? String(option.value ?? '');\n\t\tconst hint =\n\t\t\toption.hint && focusedValue !== undefined && option.value === focusedValue\n\t\t\t\t? styleText('dim', ` (${option.hint})`)\n\t\t\t\t: '';\n\t\tconst checkbox = isSelected\n\t\t\t? styleText('green', S_CHECKBOX_SELECTED)\n\t\t\t: styleText('dim', S_CHECKBOX_INACTIVE);\n\n\t\tif (option.disabled) {\n\t\t\treturn `${styleText('gray', S_CHECKBOX_INACTIVE)} ${styleText(['strikethrough', 'gray'], label)}`;\n\t\t}\n\t\tif (active) {\n\t\t\treturn `${checkbox} ${label}${hint}`;\n\t\t}\n\t\treturn `${checkbox} ${styleText('dim', label)}`;\n\t};\n\n\t// Create text prompt which we'll use as foundation\n\tconst prompt = new AutocompletePrompt<Option<Value>>({\n\t\toptions: opts.options,\n\t\tmultiple: true,\n\t\tplaceholder: opts.placeholder,\n\t\tfilter:\n\t\t\topts.filter ??\n\t\t\t((search, opt) => {\n\t\t\t\treturn getFilteredOption(search, opt);\n\t\t\t}),\n\t\tvalidate: () => {\n\t\t\tif (opts.required && prompt.selectedValues.length === 0) {\n\t\t\t\treturn 'Please select at least one item';\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t\tinitialValue: opts.initialValues,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\t// Title and symbol\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} ${\n\t\t\t\topts.message\n\t\t\t}\\n`;\n\n\t\t\t// Selection counter\n\t\t\tconst userInput = this.userInput;\n\t\t\tconst placeholder = opts.placeholder;\n\t\t\tconst showPlaceholder = userInput === '' && placeholder !== undefined;\n\n\t\t\t// Search input display\n\t\t\tconst searchText =\n\t\t\t\tthis.isNavigating || showPlaceholder\n\t\t\t\t\t? styleText('dim', showPlaceholder ? placeholder : userInput) // Just show plain text when in navigation mode\n\t\t\t\t\t: this.userInputWithCursor;\n\n\t\t\tconst options = this.options;\n\n\t\t\tconst matches =\n\t\t\t\tthis.filteredOptions.length !== options.length\n\t\t\t\t\t? styleText(\n\t\t\t\t\t\t\t'dim',\n\t\t\t\t\t\t\t` (${this.filteredOptions.length} match${this.filteredOptions.length === 1 ? '' : 'es'})`\n\t\t\t\t\t\t)\n\t\t\t\t\t: '';\n\n\t\t\t// Render prompt state\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\treturn `${title}${hasGuide ? `${styleText('gray', S_BAR)} ` : ''}${styleText(\n\t\t\t\t\t\t'dim',\n\t\t\t\t\t\t`${this.selectedValues.length} items selected`\n\t\t\t\t\t)}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\treturn `${title}${hasGuide ? `${styleText('gray', S_BAR)} ` : ''}${styleText(\n\t\t\t\t\t\t['strikethrough', 'dim'],\n\t\t\t\t\t\tuserInput\n\t\t\t\t\t)}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst barStyle = this.state === 'error' ? 'yellow' : 'cyan';\n\t\t\t\t\tconst guidePrefix = hasGuide ? `${styleText(barStyle, S_BAR)} ` : '';\n\t\t\t\t\tconst guidePrefixEnd = hasGuide ? styleText(barStyle, S_BAR_END) : '';\n\t\t\t\t\t// Instructions\n\t\t\t\t\tconst instructions = [\n\t\t\t\t\t\t`${styleText('dim', '↑/↓')} to navigate`,\n\t\t\t\t\t\t`${styleText('dim', this.isNavigating ? 'Space/Tab:' : 'Tab:')} select`,\n\t\t\t\t\t\t`${styleText('dim', 'Enter:')} confirm`,\n\t\t\t\t\t\t`${styleText('dim', 'Type:')} to search`,\n\t\t\t\t\t];\n\n\t\t\t\t\t// No results message\n\t\t\t\t\tconst noResults =\n\t\t\t\t\t\tthis.filteredOptions.length === 0 && userInput\n\t\t\t\t\t\t\t? [`${guidePrefix}${styleText('yellow', 'No matches found')}`]\n\t\t\t\t\t\t\t: [];\n\n\t\t\t\t\tconst errorMessage =\n\t\t\t\t\t\tthis.state === 'error' ? [`${guidePrefix}${styleText('yellow', this.error)}`] : [];\n\n\t\t\t\t\t// Calculate header and footer line counts for rowPadding\n\t\t\t\t\tconst headerLines = [\n\t\t\t\t\t\t...`${title}${hasGuide ? styleText(barStyle, S_BAR) : ''}`.split('\\n'),\n\t\t\t\t\t\t`${guidePrefix}${styleText('dim', 'Search:')} ${searchText}${matches}`,\n\t\t\t\t\t\t...noResults,\n\t\t\t\t\t\t...errorMessage,\n\t\t\t\t\t];\n\t\t\t\t\tconst footerLines = [`${guidePrefix}${instructions.join(' • ')}`, guidePrefixEnd];\n\n\t\t\t\t\t// Get limited options for display\n\t\t\t\t\tconst displayOptions = limitOptions({\n\t\t\t\t\t\tcursor: this.cursor,\n\t\t\t\t\t\toptions: this.filteredOptions,\n\t\t\t\t\t\tstyle: (option, active) =>\n\t\t\t\t\t\t\tformatOption(option, active, this.selectedValues, this.focusedValue),\n\t\t\t\t\t\tmaxItems: opts.maxItems,\n\t\t\t\t\t\toutput: opts.output,\n\t\t\t\t\t\trowPadding: headerLines.length + footerLines.length,\n\t\t\t\t\t});\n\n\t\t\t\t\t// Build the prompt display\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...headerLines,\n\t\t\t\t\t\t...displayOptions.map((option) => `${guidePrefix}${option}`),\n\t\t\t\t\t\t...footerLines,\n\t\t\t\t\t].join('\\n');\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t});\n\n\t// Return the result or cancel symbol\n\treturn prompt.prompt() as Promise<Value[] | symbol>;\n};\n","import type { Writable } from 'node:stream';\nimport { getColumns, settings } from '@clack/core';\nimport stringWidth from 'fast-string-width';\nimport { wrapAnsi } from 'fast-wrap-ansi';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_BAR_END_RIGHT,\n\tS_BAR_H,\n\tS_BAR_START,\n\tS_BAR_START_RIGHT,\n\tS_CORNER_BOTTOM_LEFT,\n\tS_CORNER_BOTTOM_RIGHT,\n\tS_CORNER_TOP_LEFT,\n\tS_CORNER_TOP_RIGHT,\n} from './common.js';\n\nexport type BoxAlignment = 'left' | 'center' | 'right';\n\ntype BoxSymbols = [topLeft: string, topRight: string, bottomLeft: string, bottomRight: string];\n\nconst roundedSymbols: BoxSymbols = [\n\tS_CORNER_TOP_LEFT,\n\tS_CORNER_TOP_RIGHT,\n\tS_CORNER_BOTTOM_LEFT,\n\tS_CORNER_BOTTOM_RIGHT,\n];\nconst squareSymbols: BoxSymbols = [S_BAR_START, S_BAR_START_RIGHT, S_BAR_END, S_BAR_END_RIGHT];\n\nexport interface BoxOptions extends CommonOptions {\n\tcontentAlign?: BoxAlignment;\n\ttitleAlign?: BoxAlignment;\n\twidth?: number | 'auto';\n\ttitlePadding?: number;\n\tcontentPadding?: number;\n\trounded?: boolean;\n\tformatBorder?: (text: string) => string;\n}\n\nfunction getPaddingForLine(\n\tlineLength: number,\n\tinnerWidth: number,\n\tpadding: number,\n\tcontentAlign: BoxAlignment | undefined\n): [number, number] {\n\tlet leftPadding = padding;\n\tlet rightPadding = padding;\n\tif (contentAlign === 'center') {\n\t\tleftPadding = Math.floor((innerWidth - lineLength) / 2);\n\t} else if (contentAlign === 'right') {\n\t\tleftPadding = innerWidth - lineLength - padding;\n\t}\n\n\trightPadding = innerWidth - leftPadding - lineLength;\n\n\treturn [leftPadding, rightPadding];\n}\n\nconst defaultFormatBorder = (text: string) => text;\n\nexport const box = (message = '', title = '', opts?: BoxOptions) => {\n\tconst output: Writable = opts?.output ?? process.stdout;\n\tconst columns = getColumns(output);\n\tconst borderWidth = 1;\n\tconst borderTotalWidth = borderWidth * 2;\n\tconst titlePadding = opts?.titlePadding ?? 1;\n\tconst contentPadding = opts?.contentPadding ?? 2;\n\tconst width = opts?.width === undefined || opts.width === 'auto' ? 1 : Math.min(1, opts.width);\n\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\tconst linePrefix = !hasGuide ? '' : `${S_BAR} `;\n\tconst formatBorder = opts?.formatBorder ?? defaultFormatBorder;\n\tconst symbols = (opts?.rounded ? roundedSymbols : squareSymbols).map(formatBorder);\n\tconst hSymbol = formatBorder(S_BAR_H);\n\tconst vSymbol = formatBorder(S_BAR);\n\tconst linePrefixWidth = stringWidth(linePrefix);\n\tconst titleWidth = stringWidth(title);\n\tconst maxBoxWidth = columns - linePrefixWidth;\n\tlet boxWidth = Math.floor(columns * width) - linePrefixWidth;\n\tif (opts?.width === 'auto') {\n\t\tconst lines = message.split('\\n');\n\t\tlet longestLine = titleWidth + titlePadding * 2;\n\t\tfor (const line of lines) {\n\t\t\tconst lineWithPadding = stringWidth(line) + contentPadding * 2;\n\t\t\tif (lineWithPadding > longestLine) {\n\t\t\t\tlongestLine = lineWithPadding;\n\t\t\t}\n\t\t}\n\t\tconst longestLineWidth = longestLine + borderTotalWidth;\n\t\tif (longestLineWidth < boxWidth) {\n\t\t\tboxWidth = longestLineWidth;\n\t\t}\n\t}\n\tif (boxWidth % 2 !== 0) {\n\t\tif (boxWidth < maxBoxWidth) {\n\t\t\tboxWidth++;\n\t\t} else {\n\t\t\tboxWidth--;\n\t\t}\n\t}\n\tconst innerWidth = boxWidth - borderTotalWidth;\n\tconst maxTitleLength = innerWidth - titlePadding * 2;\n\tconst truncatedTitle =\n\t\ttitleWidth > maxTitleLength ? `${title.slice(0, maxTitleLength - 3)}...` : title;\n\tconst [titlePaddingLeft, titlePaddingRight] = getPaddingForLine(\n\t\tstringWidth(truncatedTitle),\n\t\tinnerWidth,\n\t\ttitlePadding,\n\t\topts?.titleAlign\n\t);\n\tconst wrappedMessage = wrapAnsi(message, innerWidth - contentPadding * 2, {\n\t\thard: true,\n\t\ttrim: false,\n\t});\n\toutput.write(\n\t\t`${linePrefix}${symbols[0]}${hSymbol.repeat(titlePaddingLeft)}${truncatedTitle}${hSymbol.repeat(titlePaddingRight)}${symbols[1]}\\n`\n\t);\n\tconst wrappedLines = wrappedMessage.split('\\n');\n\tfor (const line of wrappedLines) {\n\t\tconst [leftLinePadding, rightLinePadding] = getPaddingForLine(\n\t\t\tstringWidth(line),\n\t\t\tinnerWidth,\n\t\t\tcontentPadding,\n\t\t\topts?.contentAlign\n\t\t);\n\t\toutput.write(\n\t\t\t`${linePrefix}${vSymbol}${' '.repeat(leftLinePadding)}${line}${' '.repeat(rightLinePadding)}${vSymbol}\\n`\n\t\t);\n\t}\n\toutput.write(`${linePrefix}${symbols[2]}${hSymbol.repeat(innerWidth)}${symbols[3]}\\n`);\n};\n","import { styleText } from 'node:util';\nimport { ConfirmPrompt, settings, wrapTextWithPrefix } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_RADIO_ACTIVE,\n\tS_RADIO_INACTIVE,\n\tsymbol,\n} from './common.js';\n\nexport interface ConfirmOptions extends CommonOptions {\n\tmessage: string;\n\tactive?: string;\n\tinactive?: string;\n\tinitialValue?: boolean;\n\tvertical?: boolean;\n}\nexport const confirm = (opts: ConfirmOptions) => {\n\tconst active = opts.active ?? 'Yes';\n\tconst inactive = opts.inactive ?? 'No';\n\treturn new ConfirmPrompt({\n\t\tactive,\n\t\tinactive,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tinitialValue: opts.initialValue ?? true,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst titlePrefix = `${symbol(this.state)} `;\n\t\t\tconst titlePrefixBar = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\tconst messageLines = wrapTextWithPrefix(\n\t\t\t\topts.output,\n\t\t\t\topts.message,\n\t\t\t\ttitlePrefixBar,\n\t\t\t\ttitlePrefix\n\t\t\t);\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${messageLines}\\n`;\n\t\t\tconst value = this.value ? active : inactive;\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\treturn `${title}${submitPrefix}${styleText('dim', value)}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst cancelPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\treturn `${title}${cancelPrefix}${styleText(['strikethrough', 'dim'], value)}${\n\t\t\t\t\t\thasGuide ? `\\n${styleText('gray', S_BAR)}` : ''\n\t\t\t\t\t}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst defaultPrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst defaultPrefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\treturn `${title}${defaultPrefix}${\n\t\t\t\t\t\tthis.value\n\t\t\t\t\t\t\t? `${styleText('green', S_RADIO_ACTIVE)} ${active}`\n\t\t\t\t\t\t\t: `${styleText('dim', S_RADIO_INACTIVE)} ${styleText('dim', active)}`\n\t\t\t\t\t}${opts.vertical ? (hasGuide ? `\\n${styleText('cyan', S_BAR)} ` : '\\n') : ` ${styleText('dim', '/')} `}${\n\t\t\t\t\t\t!this.value\n\t\t\t\t\t\t\t? `${styleText('green', S_RADIO_ACTIVE)} ${inactive}`\n\t\t\t\t\t\t\t: `${styleText('dim', S_RADIO_INACTIVE)} ${styleText('dim', inactive)}`\n\t\t\t\t\t}\\n${defaultPrefixEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<boolean | symbol>;\n};\n","import { styleText } from 'node:util';\nimport type { DateFormat, State } from '@clack/core';\nimport { DatePrompt, settings } from '@clack/core';\nimport { type CommonOptions, S_BAR, S_BAR_END, symbol } from './common.js';\n\nexport type { DateFormat };\n\nexport interface DateOptions extends CommonOptions {\n\tmessage: string;\n\tformat?: DateFormat;\n\tlocale?: string;\n\tdefaultValue?: Date;\n\tinitialValue?: Date;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tvalidate?: (value: Date | undefined) => string | Error | undefined;\n}\n\nexport const date = (opts: DateOptions) => {\n\tconst validate = opts.validate;\n\treturn new DatePrompt({\n\t\t...opts,\n\t\tvalidate(value: Date | undefined) {\n\t\t\tif (value === undefined) {\n\t\t\t\tif (opts.defaultValue !== undefined) return undefined;\n\t\t\t\tif (validate) return validate(value);\n\t\t\t\treturn settings.date.messages.required;\n\t\t\t}\n\t\t\tconst iso = (d: Date) => d.toISOString().slice(0, 10);\n\t\t\tif (opts.minDate && iso(value) < iso(opts.minDate)) {\n\t\t\t\treturn settings.date.messages.afterMin(opts.minDate);\n\t\t\t}\n\t\t\tif (opts.maxDate && iso(value) > iso(opts.maxDate)) {\n\t\t\t\treturn settings.date.messages.beforeMax(opts.maxDate);\n\t\t\t}\n\t\t\tif (validate) return validate(value);\n\t\t\treturn undefined;\n\t\t},\n\t\trender() {\n\t\t\tconst hasGuide = (opts?.withGuide ?? settings.withGuide) !== false;\n\t\t\tconst titlePrefix = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} `;\n\t\t\tconst title = `${titlePrefix}${opts.message}\\n`;\n\n\t\t\tconst state = this.state !== 'initial' ? this.state : 'active';\n\n\t\t\tconst userInput = renderDate(this, state);\n\t\t\tconst value = this.value instanceof Date ? this.formattedValue : '';\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst errorText = this.error ? ` ${styleText('yellow', this.error)}` : '';\n\t\t\t\t\tconst bar = hasGuide ? `${styleText('yellow', S_BAR)} ` : '';\n\t\t\t\t\tconst barEnd = hasGuide ? styleText('yellow', S_BAR_END) : '';\n\t\t\t\t\treturn `${title.trim()}\\n${bar}${userInput}\\n${barEnd}${errorText}\\n`;\n\t\t\t\t}\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst valueText = value ? ` ${styleText('dim', value)}` : '';\n\t\t\t\t\tconst bar = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${title}${bar}${valueText}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst valueText = value ? ` ${styleText(['strikethrough', 'dim'], value)}` : '';\n\t\t\t\t\tconst bar = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${title}${bar}${valueText}${value.trim() ? `\\n${bar}` : ''}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst bar = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst barEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\tconst inlineBar = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst inlineError = this.inlineError\n\t\t\t\t\t\t? `\\n${inlineBar}${styleText('yellow', this.inlineError)}`\n\t\t\t\t\t\t: '';\n\t\t\t\t\treturn `${title}${bar}${userInput}${inlineError}\\n${barEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<Date | symbol>;\n};\n\nfunction renderDate(prompt: Omit<InstanceType<typeof DatePrompt>, 'prompt'>, state: State): string {\n\tconst parts = prompt.segmentValues;\n\tconst cursor = prompt.segmentCursor;\n\n\tif (state === 'submit' || state === 'cancel') {\n\t\treturn prompt.formattedValue;\n\t}\n\n\tconst sep = styleText('gray', prompt.separator);\n\treturn prompt.segments\n\t\t.map((seg, i) => {\n\t\t\tconst isActive = i === cursor.segmentIndex && !['submit', 'cancel'].includes(state);\n\t\t\tconst label = DEFAULT_LABELS[seg.type];\n\t\t\treturn renderSegment(parts[seg.type], { isActive, label });\n\t\t})\n\t\t.join(sep);\n}\n\ninterface SegmentOptions {\n\tisActive: boolean;\n\tlabel: string;\n}\nfunction renderSegment(value: string, opts: SegmentOptions): string {\n\tconst isBlank = !value || value.replace(/_/g, '') === '';\n\tif (opts.isActive) return styleText('inverse', isBlank ? opts.label : value.replace(/_/g, ' '));\n\tif (isBlank) return styleText('dim', opts.label);\n\treturn value.replace(/_/g, styleText('dim', ' '));\n}\n\nconst DEFAULT_LABELS: Record<'year' | 'month' | 'day', string> = {\n\tyear: 'yyyy',\n\tmonth: 'mm',\n\tday: 'dd',\n};\n","import { isCancel } from '@clack/core';\n\ntype Prettify<T> = {\n\t[P in keyof T]: T[P];\n} & {};\n\nexport type PromptGroupAwaitedReturn<T> = {\n\t[P in keyof T]: Exclude<Awaited<T[P]>, symbol>;\n};\n\nexport interface PromptGroupOptions<T> {\n\t/**\n\t * Control how the group can be canceled\n\t * if one of the prompts is canceled.\n\t */\n\tonCancel?: (opts: { results: Prettify<Partial<PromptGroupAwaitedReturn<T>>> }) => void;\n}\n\nexport type PromptGroup<T> = {\n\t[P in keyof T]: (opts: {\n\t\tresults: Prettify<Partial<PromptGroupAwaitedReturn<Omit<T, P>>>>;\n\t}) => undefined | Promise<T[P] | undefined>;\n};\n\n/**\n * Define a group of prompts to be displayed\n * and return a results of objects within the group\n */\nexport const group = async <T>(\n\tprompts: PromptGroup<T>,\n\topts?: PromptGroupOptions<T>\n): Promise<Prettify<PromptGroupAwaitedReturn<T>>> => {\n\tconst results = {} as any;\n\tconst promptNames = Object.keys(prompts);\n\n\tfor (const name of promptNames) {\n\t\tconst prompt = prompts[name as keyof T];\n\t\tconst result = await prompt({ results })?.catch((e) => {\n\t\t\tthrow e;\n\t\t});\n\n\t\t// Pass the results to the onCancel function\n\t\t// so the user can decide what to do with the results\n\t\t// TODO: Switch to callback within core to avoid isCancel Fn\n\t\tif (typeof opts?.onCancel === 'function' && isCancel(result)) {\n\t\t\tresults[name] = 'canceled';\n\t\t\topts.onCancel({ results });\n\t\t\tcontinue;\n\t\t}\n\n\t\tresults[name] = result;\n\t}\n\n\treturn results;\n};\n","import { styleText } from 'node:util';\nimport { GroupMultiSelectPrompt, settings } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_CHECKBOX_ACTIVE,\n\tS_CHECKBOX_INACTIVE,\n\tS_CHECKBOX_SELECTED,\n\tsymbol,\n} from './common.js';\nimport type { Option } from './select.js';\n\nexport interface GroupMultiSelectOptions<Value> extends CommonOptions {\n\tmessage: string;\n\toptions: Record<string, Option<Value>[]>;\n\tinitialValues?: Value[];\n\trequired?: boolean;\n\tcursorAt?: Value;\n\tselectableGroups?: boolean;\n\tgroupSpacing?: number;\n}\nexport const groupMultiselect = <Value>(opts: GroupMultiSelectOptions<Value>) => {\n\tconst { selectableGroups = true, groupSpacing = 0 } = opts;\n\tconst opt = (\n\t\toption: Option<Value> & { group: string | boolean },\n\t\tstate:\n\t\t\t| 'inactive'\n\t\t\t| 'active'\n\t\t\t| 'selected'\n\t\t\t| 'active-selected'\n\t\t\t| 'group-active'\n\t\t\t| 'group-active-selected'\n\t\t\t| 'submitted'\n\t\t\t| 'cancelled',\n\t\toptions: (Option<Value> & { group: string | boolean })[] = []\n\t) => {\n\t\tconst label = option.label ?? String(option.value);\n\t\tconst isItem = typeof option.group === 'string';\n\t\tconst next = isItem && (options[options.indexOf(option) + 1] ?? { group: true });\n\t\tconst isLast = isItem && next && next.group === true;\n\t\tconst prefix = isItem ? (selectableGroups ? `${isLast ? S_BAR_END : S_BAR} ` : ' ') : '';\n\t\tlet spacingPrefix = '';\n\t\tif (groupSpacing > 0 && !isItem) {\n\t\t\tconst spacingPrefixText = `\\n${styleText('cyan', S_BAR)}`;\n\t\t\tspacingPrefix = `${spacingPrefixText.repeat(groupSpacing - 1)}${spacingPrefixText} `;\n\t\t}\n\n\t\tif (state === 'active') {\n\t\t\treturn `${spacingPrefix}${styleText('dim', prefix)}${styleText('cyan', S_CHECKBOX_ACTIVE)} ${label}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'group-active') {\n\t\t\treturn `${spacingPrefix}${prefix}${styleText('cyan', S_CHECKBOX_ACTIVE)} ${styleText('dim', label)}`;\n\t\t}\n\t\tif (state === 'group-active-selected') {\n\t\t\treturn `${spacingPrefix}${prefix}${styleText('green', S_CHECKBOX_SELECTED)} ${styleText('dim', label)}`;\n\t\t}\n\t\tif (state === 'selected') {\n\t\t\tconst selectedCheckbox =\n\t\t\t\tisItem || selectableGroups ? styleText('green', S_CHECKBOX_SELECTED) : '';\n\t\t\treturn `${spacingPrefix}${styleText('dim', prefix)}${selectedCheckbox} ${styleText('dim', label)}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'cancelled') {\n\t\t\treturn `${styleText(['strikethrough', 'dim'], label)}`;\n\t\t}\n\t\tif (state === 'active-selected') {\n\t\t\treturn `${spacingPrefix}${styleText('dim', prefix)}${styleText('green', S_CHECKBOX_SELECTED)} ${label}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'submitted') {\n\t\t\treturn `${styleText('dim', label)}`;\n\t\t}\n\t\tconst unselectedCheckbox =\n\t\t\tisItem || selectableGroups ? styleText('dim', S_CHECKBOX_INACTIVE) : '';\n\t\treturn `${spacingPrefix}${styleText('dim', prefix)}${unselectedCheckbox} ${styleText('dim', label)}`;\n\t};\n\tconst required = opts.required ?? true;\n\n\treturn new GroupMultiSelectPrompt({\n\t\toptions: opts.options,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tinitialValues: opts.initialValues,\n\t\trequired,\n\t\tcursorAt: opts.cursorAt,\n\t\tselectableGroups,\n\t\tvalidate(selected: Value[] | undefined) {\n\t\t\tif (required && (selected === undefined || selected.length === 0))\n\t\t\t\treturn `Please select at least one option.\\n${styleText(\n\t\t\t\t\t'reset',\n\t\t\t\t\tstyleText(\n\t\t\t\t\t\t'dim',\n\t\t\t\t\t\t`Press ${styleText(['gray', 'bgWhite', 'inverse'], ' space ')} to select, ${styleText(\n\t\t\t\t\t\t\t'gray',\n\t\t\t\t\t\t\tstyleText(['bgWhite', 'inverse'], ' enter ')\n\t\t\t\t\t\t)} to submit`\n\t\t\t\t\t)\n\t\t\t\t)}`;\n\t\t},\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} ${opts.message}\\n`;\n\t\t\tconst value = this.value ?? [];\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst selectedOptions = this.options\n\t\t\t\t\t\t.filter(({ value: optionValue }) => value.includes(optionValue))\n\t\t\t\t\t\t.map((option) => opt(option, 'submitted'));\n\t\t\t\t\tconst optionsText =\n\t\t\t\t\t\tselectedOptions.length === 0 ? '' : ` ${selectedOptions.join(styleText('dim', ', '))}`;\n\t\t\t\t\treturn `${title}${hasGuide ? styleText('gray', S_BAR) : ''}${optionsText}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst label = this.options\n\t\t\t\t\t\t.filter(({ value: optionValue }) => value.includes(optionValue))\n\t\t\t\t\t\t.map((option) => opt(option, 'cancelled'))\n\t\t\t\t\t\t.join(styleText('dim', ', '));\n\t\t\t\t\treturn `${title}${hasGuide ? `${styleText('gray', S_BAR)} ` : ''}${\n\t\t\t\t\t\tlabel.trim() ? `${label}${hasGuide ? `\\n${styleText('gray', S_BAR)}` : ''}` : ''\n\t\t\t\t\t}`;\n\t\t\t\t}\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst footer = this.error\n\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t.map((ln, i) =>\n\t\t\t\t\t\t\ti === 0\n\t\t\t\t\t\t\t\t? `${hasGuide ? `${styleText('yellow', S_BAR_END)} ` : ''}${styleText('yellow', ln)}`\n\t\t\t\t\t\t\t\t: ` ${ln}`\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join('\\n');\n\t\t\t\t\treturn `${title}${hasGuide ? `${styleText('yellow', S_BAR)} ` : ''}${this.options\n\t\t\t\t\t\t.map((option, i, options) => {\n\t\t\t\t\t\t\tconst selected =\n\t\t\t\t\t\t\t\tvalue.includes(option.value) ||\n\t\t\t\t\t\t\t\t(option.group === true && this.isGroupSelected(`${option.value}`));\n\t\t\t\t\t\t\tconst active = i === this.cursor;\n\t\t\t\t\t\t\tconst groupActive =\n\t\t\t\t\t\t\t\t!active &&\n\t\t\t\t\t\t\t\ttypeof option.group === 'string' &&\n\t\t\t\t\t\t\t\tthis.options[this.cursor].value === option.group;\n\t\t\t\t\t\t\tif (groupActive) {\n\t\t\t\t\t\t\t\treturn opt(option, selected ? 'group-active-selected' : 'group-active', options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (active && selected) {\n\t\t\t\t\t\t\t\treturn opt(option, 'active-selected', options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (selected) {\n\t\t\t\t\t\t\t\treturn opt(option, 'selected', options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn opt(option, active ? 'active' : 'inactive', options);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(`\\n${hasGuide ? `${styleText('yellow', S_BAR)} ` : ''}`)}\\n${footer}\\n`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst optionsText = this.options\n\t\t\t\t\t\t.map((option, i, options) => {\n\t\t\t\t\t\t\tconst selected =\n\t\t\t\t\t\t\t\tvalue.includes(option.value) ||\n\t\t\t\t\t\t\t\t(option.group === true && this.isGroupSelected(`${option.value}`));\n\t\t\t\t\t\t\tconst active = i === this.cursor;\n\t\t\t\t\t\t\tconst groupActive =\n\t\t\t\t\t\t\t\t!active &&\n\t\t\t\t\t\t\t\ttypeof option.group === 'string' &&\n\t\t\t\t\t\t\t\tthis.options[this.cursor].value === option.group;\n\t\t\t\t\t\t\tlet optionText = '';\n\t\t\t\t\t\t\tif (groupActive) {\n\t\t\t\t\t\t\t\toptionText = opt(\n\t\t\t\t\t\t\t\t\toption,\n\t\t\t\t\t\t\t\t\tselected ? 'group-active-selected' : 'group-active',\n\t\t\t\t\t\t\t\t\toptions\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else if (active && selected) {\n\t\t\t\t\t\t\t\toptionText = opt(option, 'active-selected', options);\n\t\t\t\t\t\t\t} else if (selected) {\n\t\t\t\t\t\t\t\toptionText = opt(option, 'selected', options);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\toptionText = opt(option, active ? 'active' : 'inactive', options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst prefix = i !== 0 && !optionText.startsWith('\\n') ? ' ' : '';\n\t\t\t\t\t\t\treturn `${prefix}${optionText}`;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(`\\n${hasGuide ? styleText('cyan', S_BAR) : ''}`);\n\t\t\t\t\tconst optionsPrefix = optionsText.startsWith('\\n') ? '' : ' ';\n\t\t\t\t\treturn `${title}${hasGuide ? styleText('cyan', S_BAR) : ''}${optionsPrefix}${optionsText}\\n${\n\t\t\t\t\t\thasGuide ? styleText('cyan', S_BAR_END) : ''\n\t\t\t\t\t}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<Value[] | symbol>;\n};\n","import { styleText } from 'node:util';\nimport { settings } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_ERROR,\n\tS_INFO,\n\tS_STEP_SUBMIT,\n\tS_SUCCESS,\n\tS_WARN,\n} from './common.js';\n\nexport interface LogMessageOptions extends CommonOptions {\n\tsymbol?: string;\n\tspacing?: number;\n\tsecondarySymbol?: string;\n}\n\nexport const log = {\n\tmessage: (\n\t\tmessage: string | string[] = [],\n\t\t{\n\t\t\tsymbol = styleText('gray', S_BAR),\n\t\t\tsecondarySymbol = styleText('gray', S_BAR),\n\t\t\toutput = process.stdout,\n\t\t\tspacing = 1,\n\t\t\twithGuide,\n\t\t}: LogMessageOptions = {}\n\t) => {\n\t\tconst parts: string[] = [];\n\t\tconst hasGuide = withGuide ?? settings.withGuide;\n\t\tconst spacingString = !hasGuide ? '' : secondarySymbol;\n\t\tconst prefix = !hasGuide ? '' : `${symbol} `;\n\t\tconst secondaryPrefix = !hasGuide ? '' : `${secondarySymbol} `;\n\n\t\tfor (let i = 0; i < spacing; i++) {\n\t\t\tparts.push(spacingString);\n\t\t}\n\n\t\tconst messageParts = Array.isArray(message) ? message : message.split('\\n');\n\t\tif (messageParts.length > 0) {\n\t\t\tconst [firstLine, ...lines] = messageParts;\n\t\t\tif (firstLine.length > 0) {\n\t\t\t\tparts.push(`${prefix}${firstLine}`);\n\t\t\t} else {\n\t\t\t\tparts.push(hasGuide ? symbol : '');\n\t\t\t}\n\t\t\tfor (const ln of lines) {\n\t\t\t\tif (ln.length > 0) {\n\t\t\t\t\tparts.push(`${secondaryPrefix}${ln}`);\n\t\t\t\t} else {\n\t\t\t\t\tparts.push(hasGuide ? secondarySymbol : '');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\toutput.write(`${parts.join('\\n')}\\n`);\n\t},\n\tinfo: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.message(message, { ...opts, symbol: styleText('blue', S_INFO) });\n\t},\n\tsuccess: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.message(message, { ...opts, symbol: styleText('green', S_SUCCESS) });\n\t},\n\tstep: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.message(message, { ...opts, symbol: styleText('green', S_STEP_SUBMIT) });\n\t},\n\twarn: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.message(message, { ...opts, symbol: styleText('yellow', S_WARN) });\n\t},\n\t/** alias for `log.warn()`. */\n\twarning: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.warn(message, opts);\n\t},\n\terror: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.message(message, { ...opts, symbol: styleText('red', S_ERROR) });\n\t},\n};\n","import type { Writable } from 'node:stream';\nimport { styleText } from 'node:util';\nimport { settings } from '@clack/core';\nimport { type CommonOptions, S_BAR, S_BAR_END, S_BAR_START } from './common.js';\n\nexport const cancel = (message = '', opts?: CommonOptions) => {\n\tconst output: Writable = opts?.output ?? process.stdout;\n\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\tconst prefix = hasGuide ? `${styleText('gray', S_BAR_END)} ` : '';\n\toutput.write(`${prefix}${styleText('red', message)}\\n\\n`);\n};\n\nexport const intro = (title = '', opts?: CommonOptions) => {\n\tconst output: Writable = opts?.output ?? process.stdout;\n\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\tconst prefix = hasGuide ? `${styleText('gray', S_BAR_START)} ` : '';\n\toutput.write(`${prefix}${title}\\n`);\n};\n\nexport const outro = (message = '', opts?: CommonOptions) => {\n\tconst output: Writable = opts?.output ?? process.stdout;\n\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\tconst prefix = hasGuide ? `${styleText('gray', S_BAR)}\\n${styleText('gray', S_BAR_END)} ` : '';\n\toutput.write(`${prefix}${message}\\n\\n`);\n};\n","import { styleText } from 'node:util';\nimport { MultiLinePrompt, settings, wrapTextWithPrefix } from '@clack/core';\nimport { S_BAR, S_BAR_END, symbol } from './common.js';\nimport type { TextOptions } from './text.js';\n\nexport interface MultiLineOptions extends TextOptions {\n\tshowSubmit?: boolean;\n}\n\nexport const multiline = (opts: MultiLineOptions) => {\n\treturn new MultiLinePrompt({\n\t\tvalidate: opts.validate,\n\t\tplaceholder: opts.placeholder,\n\t\tdefaultValue: opts.defaultValue,\n\t\tinitialValue: opts.initialValue,\n\t\tshowSubmit: opts.showSubmit,\n\t\toutput: opts.output,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\trender() {\n\t\t\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\t\t\tconst titlePrefix = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} `;\n\t\t\tconst title = `${titlePrefix}${opts.message}\\n`;\n\t\t\tconst placeholder = opts.placeholder\n\t\t\t\t? styleText('inverse', opts.placeholder[0]) + styleText('dim', opts.placeholder.slice(1))\n\t\t\t\t: styleText(['inverse', 'hidden'], '_');\n\t\t\tconst userInput = !this.userInput ? placeholder : this.userInputWithCursor;\n\t\t\tconst value = this.value ?? '';\n\t\t\tconst submitButton = opts.showSubmit\n\t\t\t\t? `\\n ${styleText(this.focused === 'submit' ? 'cyan' : 'dim', '[ submit ]')}`\n\t\t\t\t: '';\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst errorPrefix = `${styleText('yellow', S_BAR)} `;\n\t\t\t\t\tconst lines = hasGuide\n\t\t\t\t\t\t? wrapTextWithPrefix(opts.output, userInput, errorPrefix, undefined)\n\t\t\t\t\t\t: userInput;\n\t\t\t\t\tconst errorPrefixEnd = styleText('yellow', S_BAR_END);\n\t\t\t\t\treturn `${title}${lines}\\n${errorPrefixEnd} ${styleText('yellow', this.error)}${submitButton}\\n`;\n\t\t\t\t}\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitPrefix = `${styleText('gray', S_BAR)} `;\n\t\t\t\t\tconst lines = hasGuide\n\t\t\t\t\t\t? wrapTextWithPrefix(opts.output, value, submitPrefix, undefined, (str) =>\n\t\t\t\t\t\t\t\tstyleText('dim', str)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: value\n\t\t\t\t\t\t\t? styleText('dim', value)\n\t\t\t\t\t\t\t: '';\n\t\t\t\t\treturn `${title}${lines}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst cancelPrefix = `${styleText('gray', S_BAR)} `;\n\t\t\t\t\tconst lines = hasGuide\n\t\t\t\t\t\t? wrapTextWithPrefix(opts.output, value, cancelPrefix, undefined, (str) =>\n\t\t\t\t\t\t\t\tstyleText(['strikethrough', 'dim'], str)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: value\n\t\t\t\t\t\t\t? styleText(['strikethrough', 'dim'], value)\n\t\t\t\t\t\t\t: '';\n\t\t\t\t\treturn `${title}${lines}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst defaultPrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst defaultPrefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\tconst lines = hasGuide\n\t\t\t\t\t\t? wrapTextWithPrefix(opts.output, userInput, defaultPrefix)\n\t\t\t\t\t\t: userInput;\n\t\t\t\t\treturn `${title}${lines}\\n${defaultPrefixEnd}${submitButton}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<string | symbol>;\n};\n","import { styleText } from 'node:util';\nimport { MultiSelectPrompt, settings, wrapTextWithPrefix } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_CHECKBOX_ACTIVE,\n\tS_CHECKBOX_INACTIVE,\n\tS_CHECKBOX_SELECTED,\n\tsymbol,\n\tsymbolBar,\n} from './common.js';\nimport { limitOptions } from './limit-options.js';\nimport type { Option } from './select.js';\n\nexport interface MultiSelectOptions<Value> extends CommonOptions {\n\tmessage: string;\n\toptions: Option<Value>[];\n\tinitialValues?: Value[];\n\tmaxItems?: number;\n\trequired?: boolean;\n\tcursorAt?: Value;\n}\nconst computeLabel = (label: string, format: (text: string) => string) => {\n\treturn label\n\t\t.split('\\n')\n\t\t.map((line) => format(line))\n\t\t.join('\\n');\n};\n\nexport const multiselect = <Value>(opts: MultiSelectOptions<Value>) => {\n\tconst opt = (\n\t\toption: Option<Value>,\n\t\tstate:\n\t\t\t| 'inactive'\n\t\t\t| 'active'\n\t\t\t| 'selected'\n\t\t\t| 'active-selected'\n\t\t\t| 'submitted'\n\t\t\t| 'cancelled'\n\t\t\t| 'disabled'\n\t) => {\n\t\tconst label = option.label ?? String(option.value);\n\t\tif (state === 'disabled') {\n\t\t\treturn `${styleText('gray', S_CHECKBOX_INACTIVE)} ${computeLabel(label, (str) => styleText(['strikethrough', 'gray'], str))}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint ?? 'disabled'})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'active') {\n\t\t\treturn `${styleText('cyan', S_CHECKBOX_ACTIVE)} ${label}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'selected') {\n\t\t\treturn `${styleText('green', S_CHECKBOX_SELECTED)} ${computeLabel(label, (text) => styleText('dim', text))}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'cancelled') {\n\t\t\treturn `${computeLabel(label, (text) => styleText(['strikethrough', 'dim'], text))}`;\n\t\t}\n\t\tif (state === 'active-selected') {\n\t\t\treturn `${styleText('green', S_CHECKBOX_SELECTED)} ${label}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'submitted') {\n\t\t\treturn `${computeLabel(label, (text) => styleText('dim', text))}`;\n\t\t}\n\t\treturn `${styleText('dim', S_CHECKBOX_INACTIVE)} ${computeLabel(label, (text) => styleText('dim', text))}`;\n\t};\n\tconst required = opts.required ?? true;\n\n\treturn new MultiSelectPrompt({\n\t\toptions: opts.options,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tinitialValues: opts.initialValues,\n\t\trequired,\n\t\tcursorAt: opts.cursorAt,\n\t\tvalidate(selected: Value[] | undefined) {\n\t\t\tif (required && (selected === undefined || selected.length === 0))\n\t\t\t\treturn `Please select at least one option.\\n${styleText(\n\t\t\t\t\t'reset',\n\t\t\t\t\tstyleText(\n\t\t\t\t\t\t'dim',\n\t\t\t\t\t\t`Press ${styleText(['gray', 'bgWhite', 'inverse'], ' space ')} to select, ${styleText(\n\t\t\t\t\t\t\t'gray',\n\t\t\t\t\t\t\tstyleText('bgWhite', styleText('inverse', ' enter '))\n\t\t\t\t\t\t)} to submit`\n\t\t\t\t\t)\n\t\t\t\t)}`;\n\t\t},\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst wrappedMessage = wrapTextWithPrefix(\n\t\t\t\topts.output,\n\t\t\t\topts.message,\n\t\t\t\thasGuide ? `${symbolBar(this.state)} ` : '',\n\t\t\t\t`${symbol(this.state)} `\n\t\t\t);\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${wrappedMessage}\\n`;\n\t\t\tconst value = this.value ?? [];\n\n\t\t\tconst styleOption = (option: Option<Value>, active: boolean) => {\n\t\t\t\tif (option.disabled) {\n\t\t\t\t\treturn opt(option, 'disabled');\n\t\t\t\t}\n\t\t\t\tconst selected = value.includes(option.value);\n\t\t\t\tif (active && selected) {\n\t\t\t\t\treturn opt(option, 'active-selected');\n\t\t\t\t}\n\t\t\t\tif (selected) {\n\t\t\t\t\treturn opt(option, 'selected');\n\t\t\t\t}\n\t\t\t\treturn opt(option, active ? 'active' : 'inactive');\n\t\t\t};\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitText =\n\t\t\t\t\t\tthis.options\n\t\t\t\t\t\t\t.filter(({ value: optionValue }) => value.includes(optionValue))\n\t\t\t\t\t\t\t.map((option) => opt(option, 'submitted'))\n\t\t\t\t\t\t\t.join(styleText('dim', ', ')) || styleText('dim', 'none');\n\t\t\t\t\tconst wrappedSubmitText = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\tsubmitText,\n\t\t\t\t\t\thasGuide ? `${styleText('gray', S_BAR)} ` : ''\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrappedSubmitText}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst label = this.options\n\t\t\t\t\t\t.filter(({ value: optionValue }) => value.includes(optionValue))\n\t\t\t\t\t\t.map((option) => opt(option, 'cancelled'))\n\t\t\t\t\t\t.join(styleText('dim', ', '));\n\t\t\t\t\tif (label.trim() === '') {\n\t\t\t\t\t\treturn `${title}${styleText('gray', S_BAR)}`;\n\t\t\t\t\t}\n\t\t\t\t\tconst wrappedLabel = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\tlabel,\n\t\t\t\t\t\thasGuide ? `${styleText('gray', S_BAR)} ` : ''\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrappedLabel}${hasGuide ? `\\n${styleText('gray', S_BAR)}` : ''}`;\n\t\t\t\t}\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst prefix = hasGuide ? `${styleText('yellow', S_BAR)} ` : '';\n\t\t\t\t\tconst footer = this.error\n\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t.map((ln, i) =>\n\t\t\t\t\t\t\ti === 0\n\t\t\t\t\t\t\t\t? `${hasGuide ? `${styleText('yellow', S_BAR_END)} ` : ''}${styleText('yellow', ln)}`\n\t\t\t\t\t\t\t\t: ` ${ln}`\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join('\\n');\n\t\t\t\t\t// Calculate rowPadding: title lines + footer lines (error message + trailing newline)\n\t\t\t\t\tconst titleLineCount = title.split('\\n').length;\n\t\t\t\t\tconst footerLineCount = footer.split('\\n').length + 1; // footer + trailing newline\n\t\t\t\t\treturn `${title}${prefix}${limitOptions({\n\t\t\t\t\t\toutput: opts.output,\n\t\t\t\t\t\toptions: this.options,\n\t\t\t\t\t\tcursor: this.cursor,\n\t\t\t\t\t\tmaxItems: opts.maxItems,\n\t\t\t\t\t\tcolumnPadding: prefix.length,\n\t\t\t\t\t\trowPadding: titleLineCount + footerLineCount,\n\t\t\t\t\t\tstyle: styleOption,\n\t\t\t\t\t}).join(`\\n${prefix}`)}\\n${footer}\\n`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst prefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\t// Calculate rowPadding: title lines + footer lines (S_BAR_END + trailing newline)\n\t\t\t\t\tconst titleLineCount = title.split('\\n').length;\n\t\t\t\t\tconst footerLineCount = hasGuide ? 2 : 1; // S_BAR_END + trailing newline\n\t\t\t\t\treturn `${title}${prefix}${limitOptions({\n\t\t\t\t\t\toutput: opts.output,\n\t\t\t\t\t\toptions: this.options,\n\t\t\t\t\t\tcursor: this.cursor,\n\t\t\t\t\t\tmaxItems: opts.maxItems,\n\t\t\t\t\t\tcolumnPadding: prefix.length,\n\t\t\t\t\t\trowPadding: titleLineCount + footerLineCount,\n\t\t\t\t\t\tstyle: styleOption,\n\t\t\t\t\t}).join(`\\n${prefix}`)}\\n${hasGuide ? styleText('cyan', S_BAR_END) : ''}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<Value[] | symbol>;\n};\n","import process from 'node:process';\nimport type { Writable } from 'node:stream';\nimport { styleText } from 'node:util';\nimport { getColumns, settings } from '@clack/core';\nimport stringWidth from 'fast-string-width';\nimport { type Options as WrapAnsiOptions, wrapAnsi } from 'fast-wrap-ansi';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_H,\n\tS_CONNECT_LEFT,\n\tS_CORNER_BOTTOM_LEFT,\n\tS_CORNER_BOTTOM_RIGHT,\n\tS_CORNER_TOP_RIGHT,\n\tS_STEP_SUBMIT,\n} from './common.js';\n\ntype FormatFn = (line: string) => string;\nexport interface NoteOptions extends CommonOptions {\n\tformat?: FormatFn;\n}\n\nconst defaultNoteFormatter = (line: string): string => styleText('dim', line);\n\nconst wrapWithFormat = (message: string, width: number, format: FormatFn): string => {\n\tconst opts: WrapAnsiOptions = {\n\t\thard: true,\n\t\ttrim: false,\n\t};\n\tconst wrapMsg = wrapAnsi(message, width, opts).split('\\n');\n\tconst maxWidthNormal = wrapMsg.reduce((sum, ln) => Math.max(stringWidth(ln), sum), 0);\n\tconst maxWidthFormat = wrapMsg.map(format).reduce((sum, ln) => Math.max(stringWidth(ln), sum), 0);\n\tconst wrapWidth = width - (maxWidthFormat - maxWidthNormal);\n\treturn wrapAnsi(message, wrapWidth, opts);\n};\n\nexport const note = (message = '', title = '', opts?: NoteOptions) => {\n\tconst output: Writable = opts?.output ?? process.stdout;\n\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\tconst format = opts?.format ?? defaultNoteFormatter;\n\tconst wrapMsg = wrapWithFormat(message, getColumns(output) - 6, format);\n\tconst lines = ['', ...wrapMsg.split('\\n').map(format), ''];\n\tconst titleLen = stringWidth(title);\n\tconst len =\n\t\tMath.max(\n\t\t\tlines.reduce((sum, ln) => {\n\t\t\t\tconst width = stringWidth(ln);\n\t\t\t\treturn width > sum ? width : sum;\n\t\t\t}, 0),\n\t\t\ttitleLen\n\t\t) + 2;\n\tconst msg = lines\n\t\t.map(\n\t\t\t(ln) =>\n\t\t\t\t`${styleText('gray', S_BAR)} ${ln}${' '.repeat(len - stringWidth(ln))}${styleText('gray', S_BAR)}`\n\t\t)\n\t\t.join('\\n');\n\tconst leadingBorder = hasGuide ? `${styleText('gray', S_BAR)}\\n` : '';\n\tconst bottomLeft = hasGuide ? S_CONNECT_LEFT : S_CORNER_BOTTOM_LEFT;\n\toutput.write(\n\t\t`${leadingBorder}${styleText('green', S_STEP_SUBMIT)} ${styleText('reset', title)} ${styleText(\n\t\t\t'gray',\n\t\t\tS_BAR_H.repeat(Math.max(len - titleLen - 1, 1)) + S_CORNER_TOP_RIGHT\n\t\t)}\\n${msg}\\n${styleText('gray', bottomLeft + S_BAR_H.repeat(len + 2) + S_CORNER_BOTTOM_RIGHT)}\\n`\n\t);\n};\n","import { styleText } from 'node:util';\nimport { PasswordPrompt, settings } from '@clack/core';\nimport { type CommonOptions, S_BAR, S_BAR_END, S_PASSWORD_MASK, symbol } from './common.js';\n\nexport interface PasswordOptions extends CommonOptions {\n\tmessage: string;\n\tmask?: string;\n\tvalidate?: (value: string | undefined) => string | Error | undefined;\n\tclearOnError?: boolean;\n}\nexport const password = (opts: PasswordOptions) => {\n\treturn new PasswordPrompt({\n\t\tvalidate: opts.validate,\n\t\tmask: opts.mask ?? S_PASSWORD_MASK,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} ${opts.message}\\n`;\n\t\t\tconst userInput = this.userInputWithCursor;\n\t\t\tconst masked = this.masked;\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst errorPrefix = hasGuide ? `${styleText('yellow', S_BAR)} ` : '';\n\t\t\t\t\tconst errorPrefixEnd = hasGuide ? `${styleText('yellow', S_BAR_END)} ` : '';\n\t\t\t\t\tconst maskedText = masked ?? '';\n\t\t\t\t\tif (opts.clearOnError) {\n\t\t\t\t\t\tthis.clear();\n\t\t\t\t\t}\n\t\t\t\t\treturn `${title.trim()}\\n${errorPrefix}${maskedText}\\n${errorPrefixEnd}${styleText('yellow', this.error)}\\n`;\n\t\t\t\t}\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst maskedText = masked ? styleText('dim', masked) : '';\n\t\t\t\t\treturn `${title}${submitPrefix}${maskedText}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst cancelPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst maskedText = masked ? styleText(['strikethrough', 'dim'], masked) : '';\n\t\t\t\t\treturn `${title}${cancelPrefix}${maskedText}${\n\t\t\t\t\t\tmasked && hasGuide ? `\\n${styleText('gray', S_BAR)}` : ''\n\t\t\t\t\t}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst defaultPrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst defaultPrefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\treturn `${title}${defaultPrefix}${userInput}\\n${defaultPrefixEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<string | symbol>;\n};\n","import { existsSync, lstatSync, readdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { autocomplete } from './autocomplete.js';\nimport type { CommonOptions } from './common.js';\n\nexport interface PathOptions extends CommonOptions {\n\troot?: string;\n\tdirectory?: boolean;\n\tinitialValue?: string;\n\tmessage: string;\n\tvalidate?: (value: string | undefined) => string | Error | undefined;\n}\n\nexport const path = (opts: PathOptions) => {\n\tconst validate = opts.validate;\n\n\treturn autocomplete({\n\t\t...opts,\n\t\tinitialUserInput: opts.initialValue ?? opts.root ?? process.cwd(),\n\t\tmaxItems: 5,\n\t\tvalidate(value) {\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\t// Shouldn't ever happen since we don't enable `multiple: true`\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (!value) {\n\t\t\t\treturn 'Please select a path';\n\t\t\t}\n\t\t\tif (validate) {\n\t\t\t\treturn validate(value);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t\toptions() {\n\t\t\tconst userInput = this.userInput;\n\t\t\tif (userInput === '') {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tlet searchPath: string;\n\n\t\t\t\tif (!existsSync(userInput)) {\n\t\t\t\t\tsearchPath = dirname(userInput);\n\t\t\t\t} else {\n\t\t\t\t\tconst stat = lstatSync(userInput);\n\t\t\t\t\tif (stat.isDirectory() && (!opts.directory || userInput.endsWith('/'))) {\n\t\t\t\t\t\tsearchPath = userInput;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsearchPath = dirname(userInput);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Strip trailing slash so startsWith matches the directory itself among its siblings\n\t\t\t\tconst prefix =\n\t\t\t\t\tuserInput.length > 1 && userInput.endsWith('/') ? userInput.slice(0, -1) : userInput;\n\n\t\t\t\tconst items = readdirSync(searchPath)\n\t\t\t\t\t.map((item) => {\n\t\t\t\t\t\tconst path = join(searchPath, item);\n\t\t\t\t\t\tconst stats = lstatSync(path);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: item,\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\tisDirectory: stats.isDirectory(),\n\t\t\t\t\t\t};\n\t\t\t\t\t})\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t({ path, isDirectory }) => path.startsWith(prefix) && (isDirectory || !opts.directory)\n\t\t\t\t\t);\n\n\t\t\t\treturn items.map((item) => ({\n\t\t\t\t\tvalue: item.path,\n\t\t\t\t}));\n\t\t\t} catch (_e) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\t});\n};\n","import { styleText } from 'node:util';\nimport { block, getColumns, settings } from '@clack/core';\nimport { wrapAnsi } from 'fast-wrap-ansi';\nimport { cursor, erase } from 'sisteransi';\nimport {\n\ttype CommonOptions,\n\tisCI as isCIFn,\n\tS_BAR,\n\tS_STEP_CANCEL,\n\tS_STEP_ERROR,\n\tS_STEP_SUBMIT,\n\tunicode,\n} from './common.js';\n\nexport interface SpinnerOptions extends CommonOptions {\n\tindicator?: 'dots' | 'timer';\n\tonCancel?: () => void;\n\tcancelMessage?: string;\n\terrorMessage?: string;\n\tframes?: string[];\n\tdelay?: number;\n\tstyleFrame?: (frame: string) => string;\n}\n\nexport interface SpinnerResult {\n\tstart(msg?: string): void;\n\tstop(msg?: string): void;\n\tcancel(msg?: string): void;\n\terror(msg?: string): void;\n\tmessage(msg?: string): void;\n\tclear(): void;\n\treadonly isCancelled: boolean;\n}\n\nconst defaultStyleFn: SpinnerOptions['styleFrame'] = (frame) => styleText('magenta', frame);\n\nexport const spinner = ({\n\tindicator = 'dots',\n\tonCancel,\n\toutput = process.stdout,\n\tcancelMessage,\n\terrorMessage,\n\tframes = unicode ? ['◒', '◐', '◓', '◑'] : ['•', 'o', 'O', '0'],\n\tdelay = unicode ? 80 : 120,\n\tsignal,\n\t...opts\n}: SpinnerOptions = {}): SpinnerResult => {\n\tconst isCI = isCIFn();\n\n\tlet unblock: () => void;\n\tlet loop: NodeJS.Timeout;\n\tlet isSpinnerActive = false;\n\tlet isCancelled = false;\n\tlet _message = '';\n\tlet _prevMessage: string | undefined;\n\tlet _origin: number = performance.now();\n\tconst columns = getColumns(output);\n\tconst styleFn = opts?.styleFrame ?? defaultStyleFn;\n\n\tconst handleExit = (code: number) => {\n\t\tconst msg =\n\t\t\tcode > 1\n\t\t\t\t? (errorMessage ?? settings.messages.error)\n\t\t\t\t: (cancelMessage ?? settings.messages.cancel);\n\t\tisCancelled = code === 1;\n\t\tif (isSpinnerActive) {\n\t\t\t_stop(msg, code);\n\t\t\tif (isCancelled && typeof onCancel === 'function') {\n\t\t\t\tonCancel();\n\t\t\t}\n\t\t}\n\t};\n\n\tconst errorEventHandler = () => handleExit(2);\n\tconst signalEventHandler = () => handleExit(1);\n\n\tconst registerHooks = () => {\n\t\t// Reference: https://nodejs.org/api/process.html#event-uncaughtexception\n\t\tprocess.on('uncaughtExceptionMonitor', errorEventHandler);\n\t\t// Reference: https://nodejs.org/api/process.html#event-unhandledrejection\n\t\tprocess.on('unhandledRejection', errorEventHandler);\n\t\t// Reference Signal Events: https://nodejs.org/api/process.html#signal-events\n\t\tprocess.on('SIGINT', signalEventHandler);\n\t\tprocess.on('SIGTERM', signalEventHandler);\n\t\tprocess.on('exit', handleExit);\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', signalEventHandler);\n\t\t}\n\t};\n\n\tconst clearHooks = () => {\n\t\tprocess.removeListener('uncaughtExceptionMonitor', errorEventHandler);\n\t\tprocess.removeListener('unhandledRejection', errorEventHandler);\n\t\tprocess.removeListener('SIGINT', signalEventHandler);\n\t\tprocess.removeListener('SIGTERM', signalEventHandler);\n\t\tprocess.removeListener('exit', handleExit);\n\n\t\tif (signal) {\n\t\t\tsignal.removeEventListener('abort', signalEventHandler);\n\t\t}\n\t};\n\n\tconst clearPrevMessage = () => {\n\t\tif (_prevMessage === undefined) return;\n\t\tif (isCI) output.write('\\n');\n\t\tconst wrapped = wrapAnsi(_prevMessage, columns, {\n\t\t\thard: true,\n\t\t\ttrim: false,\n\t\t});\n\t\tconst prevLines = wrapped.split('\\n');\n\t\tif (prevLines.length > 1) {\n\t\t\toutput.write(cursor.up(prevLines.length - 1));\n\t\t}\n\t\toutput.write(cursor.to(0));\n\t\toutput.write(erase.down());\n\t};\n\n\tconst removeTrailingDots = (msg: string): string => {\n\t\treturn msg.replace(/\\.+$/, '');\n\t};\n\n\tconst formatTimer = (origin: number): string => {\n\t\tconst duration = (performance.now() - origin) / 1000;\n\t\tconst min = Math.floor(duration / 60);\n\t\tconst secs = Math.floor(duration % 60);\n\t\treturn min > 0 ? `[${min}m ${secs}s]` : `[${secs}s]`;\n\t};\n\n\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\n\tconst start = (msg = ''): void => {\n\t\tisSpinnerActive = true;\n\t\tunblock = block({ output });\n\t\t_message = removeTrailingDots(msg);\n\t\t_origin = performance.now();\n\t\tif (hasGuide) {\n\t\t\toutput.write(`${styleText('gray', S_BAR)}\\n`);\n\t\t}\n\t\tlet frameIndex = 0;\n\t\tlet indicatorTimer = 0;\n\t\tregisterHooks();\n\t\tloop = setInterval(() => {\n\t\t\tif (isCI && _message === _prevMessage) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tclearPrevMessage();\n\t\t\t_prevMessage = _message;\n\t\t\tconst frame = styleFn(frames[frameIndex]);\n\t\t\tlet outputMessage: string;\n\n\t\t\tif (isCI) {\n\t\t\t\toutputMessage = `${frame} ${_message}...`;\n\t\t\t} else if (indicator === 'timer') {\n\t\t\t\toutputMessage = `${frame} ${_message} ${formatTimer(_origin)}`;\n\t\t\t} else {\n\t\t\t\tconst loadingDots = '.'.repeat(Math.floor(indicatorTimer)).slice(0, 3);\n\t\t\t\toutputMessage = `${frame} ${_message}${loadingDots}`;\n\t\t\t}\n\n\t\t\tconst wrapped = wrapAnsi(outputMessage, columns, {\n\t\t\t\thard: true,\n\t\t\t\ttrim: false,\n\t\t\t});\n\t\t\toutput.write(wrapped);\n\n\t\t\tframeIndex = frameIndex + 1 < frames.length ? frameIndex + 1 : 0;\n\t\t\t// indicator increase by 1 every 8 frames\n\t\t\tindicatorTimer = indicatorTimer < 4 ? indicatorTimer + 0.125 : 0;\n\t\t}, delay);\n\t};\n\n\tconst _stop = (msg = '', code = 0, silent: boolean = false): void => {\n\t\tif (!isSpinnerActive) return;\n\t\tisSpinnerActive = false;\n\t\tclearInterval(loop);\n\t\tclearPrevMessage();\n\t\tconst step =\n\t\t\tcode === 0\n\t\t\t\t? styleText('green', S_STEP_SUBMIT)\n\t\t\t\t: code === 1\n\t\t\t\t\t? styleText('red', S_STEP_CANCEL)\n\t\t\t\t\t: styleText('red', S_STEP_ERROR);\n\t\t_message = msg ?? _message;\n\t\tif (!silent) {\n\t\t\tif (indicator === 'timer') {\n\t\t\t\toutput.write(`${step} ${_message} ${formatTimer(_origin)}\\n`);\n\t\t\t} else {\n\t\t\t\toutput.write(`${step} ${_message}\\n`);\n\t\t\t}\n\t\t}\n\t\tclearHooks();\n\t\tunblock();\n\t};\n\n\tconst stop = (msg = ''): void => _stop(msg, 0);\n\tconst cancel = (msg = ''): void => _stop(msg, 1);\n\tconst error = (msg = ''): void => _stop(msg, 2);\n\t// TODO (43081j): this will leave the initial S_BAR since we purposely\n\t// don't erase that in `clearPrevMessage`. In future, we may want to treat\n\t// `clear` as a special case and remove the bar too.\n\tconst clear = (): void => _stop('', 0, true);\n\n\tconst message = (msg = ''): void => {\n\t\t_message = removeTrailingDots(msg ?? _message);\n\t};\n\n\treturn {\n\t\tstart,\n\t\tstop,\n\t\tmessage,\n\t\tcancel,\n\t\terror,\n\t\tclear,\n\t\tget isCancelled() {\n\t\t\treturn isCancelled;\n\t\t},\n\t};\n};\n","import { styleText } from 'node:util';\nimport type { State } from '@clack/core';\nimport { unicodeOr } from './common.js';\nimport { type SpinnerOptions, type SpinnerResult, spinner } from './spinner.js';\n\nconst S_PROGRESS_CHAR: Record<NonNullable<ProgressOptions['style']>, string> = {\n\tlight: unicodeOr('─', '-'),\n\theavy: unicodeOr('━', '='),\n\tblock: unicodeOr('█', '#'),\n};\n\nexport interface ProgressOptions extends SpinnerOptions {\n\tstyle?: 'light' | 'heavy' | 'block';\n\tmax?: number;\n\tsize?: number;\n}\n\nexport interface ProgressResult extends SpinnerResult {\n\tadvance(step?: number, msg?: string): void;\n}\n\nexport function progress({\n\tstyle = 'heavy',\n\tmax: userMax = 100,\n\tsize: userSize = 40,\n\t...spinnerOptions\n}: ProgressOptions = {}): ProgressResult {\n\tconst spin = spinner(spinnerOptions);\n\tlet value = 0;\n\tlet previousMessage = '';\n\n\tconst max = Math.max(1, userMax);\n\tconst size = Math.max(1, userSize);\n\n\tconst activeStyle = (state: State) => {\n\t\tswitch (state) {\n\t\t\tcase 'initial':\n\t\t\tcase 'active':\n\t\t\t\treturn (text: string) => styleText('magenta', text);\n\t\t\tcase 'error':\n\t\t\tcase 'cancel':\n\t\t\t\treturn (text: string) => styleText('red', text);\n\t\t\tcase 'submit':\n\t\t\t\treturn (text: string) => styleText('green', text);\n\t\t\tdefault:\n\t\t\t\treturn (text: string) => styleText('magenta', text);\n\t\t}\n\t};\n\tconst drawProgress = (state: State, msg: string) => {\n\t\tconst active = Math.floor((value / max) * size);\n\t\treturn `${activeStyle(state)(S_PROGRESS_CHAR[style].repeat(active))}${styleText('dim', S_PROGRESS_CHAR[style].repeat(size - active))} ${msg}`;\n\t};\n\n\tconst start = (msg = '') => {\n\t\tpreviousMessage = msg;\n\t\tspin.start(drawProgress('initial', msg));\n\t};\n\tconst advance = (step = 1, msg?: string): void => {\n\t\tvalue = Math.min(max, step + value);\n\t\tspin.message(drawProgress('active', msg ?? previousMessage));\n\t\tpreviousMessage = msg ?? previousMessage;\n\t};\n\treturn {\n\t\tstart,\n\t\tstop: spin.stop,\n\t\tcancel: spin.cancel,\n\t\terror: spin.error,\n\t\tclear: spin.clear,\n\t\tadvance,\n\t\tisCancelled: spin.isCancelled,\n\t\tmessage: (msg: string) => advance(0, msg),\n\t};\n}\n","import { styleText } from 'node:util';\nimport { SelectPrompt, settings, wrapTextWithPrefix } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_RADIO_ACTIVE,\n\tS_RADIO_INACTIVE,\n\tsymbol,\n\tsymbolBar,\n} from './common.js';\nimport { limitOptions } from './limit-options.js';\n\ntype Primitive = Readonly<string | boolean | number>;\n\nexport type Option<Value> = Value extends Primitive\n\t? {\n\t\t\t/**\n\t\t\t * Internal data for this option.\n\t\t\t */\n\t\t\tvalue: Value;\n\t\t\t/**\n\t\t\t * The optional, user-facing text for this option.\n\t\t\t *\n\t\t\t * By default, the `value` is converted to a string.\n\t\t\t */\n\t\t\tlabel?: string;\n\t\t\t/**\n\t\t\t * An optional hint to display to the user when\n\t\t\t * this option might be selected.\n\t\t\t *\n\t\t\t * By default, no `hint` is displayed.\n\t\t\t */\n\t\t\thint?: string;\n\t\t\t/**\n\t\t\t * Whether this option is disabled.\n\t\t\t * Disabled options are visible but cannot be selected.\n\t\t\t *\n\t\t\t * By default, options are not disabled.\n\t\t\t */\n\t\t\tdisabled?: boolean;\n\t\t}\n\t: {\n\t\t\t/**\n\t\t\t * Internal data for this option.\n\t\t\t */\n\t\t\tvalue: Value;\n\t\t\t/**\n\t\t\t * Required. The user-facing text for this option.\n\t\t\t */\n\t\t\tlabel: string;\n\t\t\t/**\n\t\t\t * An optional hint to display to the user when\n\t\t\t * this option might be selected.\n\t\t\t *\n\t\t\t * By default, no `hint` is displayed.\n\t\t\t */\n\t\t\thint?: string;\n\t\t\t/**\n\t\t\t * Whether this option is disabled.\n\t\t\t * Disabled options are visible but cannot be selected.\n\t\t\t *\n\t\t\t * By default, options are not disabled.\n\t\t\t */\n\t\t\tdisabled?: boolean;\n\t\t};\n\nexport interface SelectOptions<Value> extends CommonOptions {\n\tmessage: string;\n\toptions: Option<Value>[];\n\tinitialValue?: Value;\n\tmaxItems?: number;\n}\n\nconst computeLabel = (label: string, format: (text: string) => string) => {\n\tif (!label.includes('\\n')) {\n\t\treturn format(label);\n\t}\n\treturn label\n\t\t.split('\\n')\n\t\t.map((line) => format(line))\n\t\t.join('\\n');\n};\n\nexport const select = <Value>(opts: SelectOptions<Value>) => {\n\tconst opt = (\n\t\toption: Option<Value>,\n\t\tstate: 'inactive' | 'active' | 'selected' | 'cancelled' | 'disabled'\n\t) => {\n\t\tconst label = option.label ?? String(option.value);\n\t\tswitch (state) {\n\t\t\tcase 'disabled':\n\t\t\t\treturn `${styleText('gray', S_RADIO_INACTIVE)} ${computeLabel(label, (text) => styleText('gray', text))}${\n\t\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint ?? 'disabled'})`)}` : ''\n\t\t\t\t}`;\n\t\t\tcase 'selected':\n\t\t\t\treturn `${computeLabel(label, (text) => styleText('dim', text))}`;\n\t\t\tcase 'active':\n\t\t\t\treturn `${styleText('green', S_RADIO_ACTIVE)} ${label}${\n\t\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t\t}`;\n\t\t\tcase 'cancelled':\n\t\t\t\treturn `${computeLabel(label, (str) => styleText(['strikethrough', 'dim'], str))}`;\n\t\t\tdefault:\n\t\t\t\treturn `${styleText('dim', S_RADIO_INACTIVE)} ${computeLabel(label, (text) => styleText('dim', text))}`;\n\t\t}\n\t};\n\n\treturn new SelectPrompt({\n\t\toptions: opts.options,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tinitialValue: opts.initialValue,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst titlePrefix = `${symbol(this.state)} `;\n\t\t\tconst titlePrefixBar = `${symbolBar(this.state)} `;\n\t\t\tconst messageLines = wrapTextWithPrefix(\n\t\t\t\topts.output,\n\t\t\t\topts.message,\n\t\t\t\ttitlePrefixBar,\n\t\t\t\ttitlePrefix\n\t\t\t);\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${messageLines}\\n`;\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst wrappedLines = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\topt(this.options[this.cursor], 'selected'),\n\t\t\t\t\t\tsubmitPrefix\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrappedLines}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst cancelPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst wrappedLines = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\topt(this.options[this.cursor], 'cancelled'),\n\t\t\t\t\t\tcancelPrefix\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrappedLines}${hasGuide ? `\\n${styleText('gray', S_BAR)}` : ''}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst prefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst prefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\t// Calculate rowPadding: title lines + footer lines (S_BAR_END + trailing newline)\n\t\t\t\t\tconst titleLineCount = title.split('\\n').length;\n\t\t\t\t\tconst footerLineCount = hasGuide ? 2 : 1; // S_BAR_END + trailing newline (or just trailing newline)\n\t\t\t\t\treturn `${title}${prefix}${limitOptions({\n\t\t\t\t\t\toutput: opts.output,\n\t\t\t\t\t\tcursor: this.cursor,\n\t\t\t\t\t\toptions: this.options,\n\t\t\t\t\t\tmaxItems: opts.maxItems,\n\t\t\t\t\t\tcolumnPadding: prefix.length,\n\t\t\t\t\t\trowPadding: titleLineCount + footerLineCount,\n\t\t\t\t\t\tstyle: (item, active) =>\n\t\t\t\t\t\t\topt(item, item.disabled ? 'disabled' : active ? 'active' : 'inactive'),\n\t\t\t\t\t}).join(`\\n${prefix}`)}\\n${prefixEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<Value | symbol>;\n};\n","import { styleText } from 'node:util';\nimport { SelectKeyPrompt, settings, wrapTextWithPrefix } from '@clack/core';\nimport { type CommonOptions, S_BAR, S_BAR_END, symbol } from './common.js';\nimport type { Option } from './select.js';\n\nexport interface SelectKeyOptions<Value extends string> extends CommonOptions {\n\tmessage: string;\n\toptions: Option<Value>[];\n\tinitialValue?: Value;\n\tcaseSensitive?: boolean;\n}\n\nexport const selectKey = <Value extends string>(opts: SelectKeyOptions<Value>) => {\n\tconst opt = (\n\t\toption: Option<Value>,\n\t\tstate: 'inactive' | 'active' | 'selected' | 'cancelled' = 'inactive'\n\t) => {\n\t\tconst label = option.label ?? String(option.value);\n\t\tif (state === 'selected') {\n\t\t\treturn `${styleText('dim', label)}`;\n\t\t}\n\t\tif (state === 'cancelled') {\n\t\t\treturn `${styleText(['strikethrough', 'dim'], label)}`;\n\t\t}\n\t\tif (state === 'active') {\n\t\t\treturn `${styleText(['bgCyan', 'gray'], ` ${option.value} `)} ${label}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\treturn `${styleText(['gray', 'bgWhite', 'inverse'], ` ${option.value} `)} ${label}${\n\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t}`;\n\t};\n\n\treturn new SelectKeyPrompt({\n\t\toptions: opts.options,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tinitialValue: opts.initialValue,\n\t\tcaseSensitive: opts.caseSensitive,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} ${opts.message}\\n`;\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst selectedOption =\n\t\t\t\t\t\tthis.options.find((opt) => opt.value === this.value) ?? opts.options[0];\n\t\t\t\t\tconst wrapped = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\topt(selectedOption, 'selected'),\n\t\t\t\t\t\tsubmitPrefix\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrapped}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst cancelPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst wrapped = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\topt(this.options[0], 'cancelled'),\n\t\t\t\t\t\tcancelPrefix\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrapped}${hasGuide ? `\\n${styleText('gray', S_BAR)}` : ''}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst defaultPrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst defaultPrefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\tconst wrapped = this.options\n\t\t\t\t\t\t.map((option, i) =>\n\t\t\t\t\t\t\twrapTextWithPrefix(\n\t\t\t\t\t\t\t\topts.output,\n\t\t\t\t\t\t\t\topt(option, i === this.cursor ? 'active' : 'inactive'),\n\t\t\t\t\t\t\t\tdefaultPrefix\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join('\\n');\n\t\t\t\t\treturn `${title}${wrapped}\\n${defaultPrefixEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<Value | symbol>;\n};\n","import { stripVTControlCharacters as strip, styleText } from 'node:util';\nimport { S_BAR, S_ERROR, S_INFO, S_STEP_SUBMIT, S_SUCCESS, S_WARN } from './common.js';\nimport type { LogMessageOptions } from './log.js';\n\nconst prefix = `${styleText('gray', S_BAR)} `;\n\n// TODO (43081j): this currently doesn't support custom `output` writables\n// because we rely on `columns` existing (i.e. `process.stdout.columns).\n//\n// If we want to support `output` being passed in, we will need to use\n// a condition like `if (output insance Writable)` to check if it has columns\nexport const stream = {\n\tmessage: async (\n\t\titerable: Iterable<string> | AsyncIterable<string>,\n\t\t{ symbol = styleText('gray', S_BAR) }: LogMessageOptions = {}\n\t) => {\n\t\tprocess.stdout.write(`${styleText('gray', S_BAR)}\\n${symbol} `);\n\t\tlet lineWidth = 3;\n\t\tfor await (let chunk of iterable) {\n\t\t\tchunk = chunk.replace(/\\n/g, `\\n${prefix}`);\n\t\t\tif (chunk.includes('\\n')) {\n\t\t\t\tlineWidth = 3 + strip(chunk.slice(chunk.lastIndexOf('\\n'))).length;\n\t\t\t}\n\t\t\tconst chunkLen = strip(chunk).length;\n\t\t\tif (lineWidth + chunkLen < process.stdout.columns) {\n\t\t\t\tlineWidth += chunkLen;\n\t\t\t\tprocess.stdout.write(chunk);\n\t\t\t} else {\n\t\t\t\tprocess.stdout.write(`\\n${prefix}${chunk.trimStart()}`);\n\t\t\t\tlineWidth = 3 + strip(chunk.trimStart()).length;\n\t\t\t}\n\t\t}\n\t\tprocess.stdout.write('\\n');\n\t},\n\tinfo: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.message(iterable, { symbol: styleText('blue', S_INFO) });\n\t},\n\tsuccess: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.message(iterable, { symbol: styleText('green', S_SUCCESS) });\n\t},\n\tstep: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.message(iterable, { symbol: styleText('green', S_STEP_SUBMIT) });\n\t},\n\twarn: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.message(iterable, { symbol: styleText('yellow', S_WARN) });\n\t},\n\t/** alias for `log.warn()`. */\n\twarning: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.warn(iterable);\n\t},\n\terror: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.message(iterable, { symbol: styleText('red', S_ERROR) });\n\t},\n};\n","import type { CommonOptions } from './common.js';\nimport { spinner } from './spinner.js';\n\nexport type Task = {\n\t/**\n\t * Task title\n\t */\n\ttitle: string;\n\t/**\n\t * Task function\n\t */\n\ttask: (message: (string: string) => void) => string | Promise<string> | void | Promise<void>;\n\n\t/**\n\t * If enabled === false the task will be skipped\n\t */\n\tenabled?: boolean;\n};\n\n/**\n * Define a group of tasks to be executed\n */\nexport const tasks = async (tasks: Task[], opts?: CommonOptions) => {\n\tfor (const task of tasks) {\n\t\tif (task.enabled === false) continue;\n\n\t\tconst s = spinner(opts);\n\t\ts.start(task.title);\n\t\tconst result = await task.task(s.message);\n\t\ts.stop(result || task.title);\n\t}\n};\n","import type { Writable } from 'node:stream';\nimport { styleText } from 'node:util';\nimport { getColumns } from '@clack/core';\nimport { erase } from 'sisteransi';\nimport {\n\ttype CommonOptions,\n\tisCI as isCIFn,\n\tisTTY as isTTYFn,\n\tS_BAR,\n\tS_STEP_SUBMIT,\n} from './common.js';\nimport { log } from './log.js';\n\nexport interface TaskLogOptions extends CommonOptions {\n\ttitle: string;\n\tlimit?: number;\n\tspacing?: number;\n\tretainLog?: boolean;\n}\n\nexport interface TaskLogMessageOptions {\n\traw?: boolean;\n}\n\nexport interface TaskLogCompletionOptions {\n\tshowLog?: boolean;\n}\n\ninterface BufferEntry {\n\theader?: string;\n\tvalue: string;\n\tfull: string;\n\tresult?: {\n\t\tstatus: 'success' | 'error';\n\t\tmessage: string;\n\t};\n}\n\nconst stripDestructiveANSI = (input: string): string => {\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: intentional\n\treturn input.replace(/\\x1b\\[(?:\\d+;)*\\d*[ABCDEFGHfJKSTsu]|\\x1b\\[(s|u)/g, '');\n};\n\n/**\n * Renders a log which clears on success and remains on failure\n */\nexport const taskLog = (opts: TaskLogOptions) => {\n\tconst output: Writable = opts.output ?? process.stdout;\n\tconst columns = getColumns(output);\n\tconst secondarySymbol = styleText('gray', S_BAR);\n\tconst spacing = opts.spacing ?? 1;\n\tconst barSize = 3;\n\tconst retainLog = opts.retainLog === true;\n\tconst isTTY = !isCIFn() && isTTYFn(output);\n\n\toutput.write(`${secondarySymbol}\\n`);\n\toutput.write(`${styleText('green', S_STEP_SUBMIT)} ${opts.title}\\n`);\n\tfor (let i = 0; i < spacing; i++) {\n\t\toutput.write(`${secondarySymbol}\\n`);\n\t}\n\n\tconst buffers: BufferEntry[] = [\n\t\t{\n\t\t\tvalue: '',\n\t\t\tfull: '',\n\t\t},\n\t];\n\tlet lastMessageWasRaw = false;\n\n\tconst clear = (clearTitle: boolean): void => {\n\t\tif (buffers.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet lines = 0;\n\n\t\tif (clearTitle) {\n\t\t\tlines += spacing + 2;\n\t\t}\n\n\t\tfor (const buffer of buffers) {\n\t\t\tconst { value, result } = buffer;\n\t\t\tlet text = result?.message ?? value;\n\n\t\t\tif (text.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (result === undefined && buffer.header !== undefined && buffer.header !== '') {\n\t\t\t\ttext += `\\n${buffer.header}`;\n\t\t\t}\n\n\t\t\tconst bufferHeight = text.split('\\n').reduce((count, line) => {\n\t\t\t\tif (line === '') {\n\t\t\t\t\treturn count + 1;\n\t\t\t\t}\n\t\t\t\treturn count + Math.ceil((line.length + barSize) / columns);\n\t\t\t}, 0);\n\n\t\t\tlines += bufferHeight;\n\t\t}\n\n\t\tif (lines > 0) {\n\t\t\tlines += 1;\n\t\t\toutput.write(erase.lines(lines));\n\t\t}\n\t};\n\tconst printBuffer = (buffer: BufferEntry, messageSpacing?: number, full?: boolean): void => {\n\t\tconst messages = full ? `${buffer.full}\\n${buffer.value}` : buffer.value;\n\t\tif (buffer.header !== undefined && buffer.header !== '') {\n\t\t\tlog.message(\n\t\t\t\tbuffer.header.split('\\n').map((line) => styleText('bold', line)),\n\t\t\t\t{\n\t\t\t\t\toutput,\n\t\t\t\t\tsecondarySymbol,\n\t\t\t\t\tsymbol: secondarySymbol,\n\t\t\t\t\tspacing: 0,\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t\tlog.message(\n\t\t\tmessages.split('\\n').map((line) => styleText('dim', line)),\n\t\t\t{\n\t\t\t\toutput,\n\t\t\t\tsecondarySymbol,\n\t\t\t\tsymbol: secondarySymbol,\n\t\t\t\tspacing: messageSpacing ?? spacing,\n\t\t\t}\n\t\t);\n\t};\n\tconst renderBuffer = (): void => {\n\t\tfor (const buffer of buffers) {\n\t\t\tconst { header, value, full } = buffer;\n\t\t\tif ((header === undefined || header.length === 0) && value.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tprintBuffer(buffer, undefined, retainLog === true && full.length > 0);\n\t\t}\n\t};\n\tconst message = (buffer: BufferEntry, msg: string, mopts?: TaskLogMessageOptions) => {\n\t\tclear(false);\n\t\tif ((mopts?.raw !== true || !lastMessageWasRaw) && buffer.value !== '') {\n\t\t\tbuffer.value += '\\n';\n\t\t}\n\t\tbuffer.value += stripDestructiveANSI(msg);\n\t\tlastMessageWasRaw = mopts?.raw === true;\n\t\tif (opts.limit !== undefined) {\n\t\t\tconst lines = buffer.value.split('\\n');\n\t\t\tconst linesToRemove = lines.length - opts.limit;\n\t\t\tif (linesToRemove > 0) {\n\t\t\t\tconst removedLines = lines.splice(0, linesToRemove);\n\t\t\t\tif (retainLog) {\n\t\t\t\t\tbuffer.full += (buffer.full === '' ? '' : '\\n') + removedLines.join('\\n');\n\t\t\t\t}\n\t\t\t}\n\t\t\tbuffer.value = lines.join('\\n');\n\t\t}\n\t\tif (isTTY) {\n\t\t\tprintBuffers();\n\t\t}\n\t};\n\tconst printBuffers = (): void => {\n\t\tfor (const buffer of buffers) {\n\t\t\tif (buffer.result) {\n\t\t\t\tif (buffer.result.status === 'error') {\n\t\t\t\t\tlog.error(buffer.result.message, { output, secondarySymbol, spacing: 0 });\n\t\t\t\t} else {\n\t\t\t\t\tlog.success(buffer.result.message, { output, secondarySymbol, spacing: 0 });\n\t\t\t\t}\n\t\t\t} else if (buffer.value !== '') {\n\t\t\t\tprintBuffer(buffer, 0);\n\t\t\t}\n\t\t}\n\t};\n\tconst completeBuffer = (buffer: BufferEntry, result: BufferEntry['result']): void => {\n\t\tclear(false);\n\n\t\tbuffer.result = result;\n\n\t\tif (isTTY) {\n\t\t\tprintBuffers();\n\t\t}\n\t};\n\n\treturn {\n\t\tmessage(msg: string, mopts?: TaskLogMessageOptions) {\n\t\t\tmessage(buffers[0], msg, mopts);\n\t\t},\n\t\tgroup(name: string) {\n\t\t\tconst buffer: BufferEntry = {\n\t\t\t\theader: name,\n\t\t\t\tvalue: '',\n\t\t\t\tfull: '',\n\t\t\t};\n\t\t\tbuffers.push(buffer);\n\t\t\treturn {\n\t\t\t\tmessage(msg: string, mopts?: TaskLogMessageOptions) {\n\t\t\t\t\tmessage(buffer, msg, mopts);\n\t\t\t\t},\n\t\t\t\terror(message: string) {\n\t\t\t\t\tcompleteBuffer(buffer, {\n\t\t\t\t\t\tstatus: 'error',\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tsuccess(message: string) {\n\t\t\t\t\tcompleteBuffer(buffer, {\n\t\t\t\t\t\tstatus: 'success',\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\terror(message: string, opts?: TaskLogCompletionOptions): void {\n\t\t\tclear(true);\n\t\t\tlog.error(message, { output, secondarySymbol, spacing: 1 });\n\t\t\tif (opts?.showLog !== false) {\n\t\t\t\trenderBuffer();\n\t\t\t}\n\t\t\t// clear buffer since error is an end state\n\t\t\tbuffers.splice(1, buffers.length - 1);\n\t\t\tbuffers[0].value = '';\n\t\t\tbuffers[0].full = '';\n\t\t},\n\t\tsuccess(message: string, opts?: TaskLogCompletionOptions): void {\n\t\t\tclear(true);\n\t\t\tlog.success(message, { output, secondarySymbol, spacing: 1 });\n\t\t\tif (opts?.showLog === true) {\n\t\t\t\trenderBuffer();\n\t\t\t}\n\t\t\t// clear buffer since success is an end state\n\t\t\tbuffers.splice(1, buffers.length - 1);\n\t\t\tbuffers[0].value = '';\n\t\t\tbuffers[0].full = '';\n\t\t},\n\t};\n};\n","import { styleText } from 'node:util';\nimport { settings, TextPrompt } from '@clack/core';\nimport { type CommonOptions, S_BAR, S_BAR_END, symbol } from './common.js';\n\nexport interface TextOptions extends CommonOptions {\n\tmessage: string;\n\tplaceholder?: string;\n\tdefaultValue?: string;\n\tinitialValue?: string;\n\tvalidate?: (value: string | undefined) => string | Error | undefined;\n}\n\nexport const text = (opts: TextOptions) => {\n\treturn new TextPrompt({\n\t\tvalidate: opts.validate,\n\t\tplaceholder: opts.placeholder,\n\t\tdefaultValue: opts.defaultValue,\n\t\tinitialValue: opts.initialValue,\n\t\toutput: opts.output,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\trender() {\n\t\t\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\t\t\tconst titlePrefix = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} `;\n\t\t\tconst title = `${titlePrefix}${opts.message}\\n`;\n\t\t\tconst placeholder = opts.placeholder\n\t\t\t\t? styleText('inverse', opts.placeholder[0]) + styleText('dim', opts.placeholder.slice(1))\n\t\t\t\t: styleText(['inverse', 'hidden'], '_');\n\t\t\tconst userInput = !this.userInput ? placeholder : this.userInputWithCursor;\n\t\t\tconst value = this.value ?? '';\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst errorText = this.error ? ` ${styleText('yellow', this.error)}` : '';\n\t\t\t\t\tconst errorPrefix = hasGuide ? `${styleText('yellow', S_BAR)} ` : '';\n\t\t\t\t\tconst errorPrefixEnd = hasGuide ? styleText('yellow', S_BAR_END) : '';\n\t\t\t\t\treturn `${title.trim()}\\n${errorPrefix}${userInput}\\n${errorPrefixEnd}${errorText}\\n`;\n\t\t\t\t}\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst valueText = value ? ` ${styleText('dim', value)}` : '';\n\t\t\t\t\tconst submitPrefix = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${title}${submitPrefix}${valueText}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst valueText = value ? ` ${styleText(['strikethrough', 'dim'], value)}` : '';\n\t\t\t\t\tconst cancelPrefix = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${title}${cancelPrefix}${valueText}${value.trim() ? `\\n${cancelPrefix}` : ''}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst defaultPrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst defaultPrefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\treturn `${title}${defaultPrefix}${userInput}\\n${defaultPrefixEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<string | symbol>;\n};\n","import type { DetectedInstall } from \"./state.js\";\n\nexport type RouterAction = \"add\" | \"update\" | \"remove\" | \"reinstall\" | \"exit\";\n\nexport interface RouterChoice {\n value: RouterAction;\n label: string;\n hint?: string;\n enabled: boolean;\n}\n\n/**\n * 5-action menu for an existing install. Mirrors prompt_action_router (setup-harness.sh:255).\n *\n * \"remove\" is exposed but disabled — no reliable file-ownership mapping yet (would risk data loss).\n */\nexport function buildRouterChoices(state: DetectedInstall): RouterChoice[] {\n const detected = state.tracks.length > 0 ? state.tracks.join(\", \") : \"(none detected)\";\n return [\n {\n value: \"add\",\n label: \"Add a new Track\",\n hint: `Current: ${detected}`,\n enabled: true,\n },\n {\n value: \"update\",\n label: \"Update policy files (auto-backup)\",\n hint: \"Refresh rules / agents / commands / hooks from latest templates\",\n enabled: true,\n },\n {\n value: \"remove\",\n label: \"Remove a Track (unsupported)\",\n hint: \"Manual edit of .claude/ required — not automated\",\n enabled: false,\n },\n {\n value: \"reinstall\",\n label: \"Reinstall (backs up current .claude/ first)\",\n hint: \"Use when state is corrupted\",\n enabled: true,\n },\n {\n value: \"exit\",\n label: \"Exit\",\n enabled: true,\n },\n ];\n}\n\nexport function summarizeState(state: DetectedInstall): string {\n if (state.state === \"new\") {\n return \"No prior install detected — new install flow.\";\n }\n const trackList = state.tracks.length > 0 ? state.tracks.join(\", \") : \"(no tracks resolved)\";\n const sourceLabel =\n state.source === \"metafile\"\n ? \"via .claude/.installed-tracks\"\n : state.source === \"legacy\"\n ? \"via legacy rules/*.md heuristic\"\n : \"via no source\";\n return `Existing install detected ${sourceLabel}. Tracks: ${trackList}.`;\n}\n","/**\n * Wizard step single source of truth — v26.65.0.\n *\n * v26.64.0 에서 wizard 가 5→6 step 으로 변경됐는데 prompts.ts 의 message 가 hardcoded\n * (\"Step 1/5\") 였음 → step indicator drift 가 무성. 본 모듈이 SSOT.\n *\n * 추가 step 도입 시 본 파일만 수정 → message 자동 정합.\n */\n\nexport interface WizardStep {\n current: number;\n total: number;\n}\n\nexport const WIZARD_TOTAL = 6;\n\nexport const WIZARD: {\n TRACKS: WizardStep;\n CLI: WizardStep;\n TARGETS: WizardStep;\n SCOPE: WizardStep;\n CONFIRM: WizardStep;\n INSTALL: WizardStep;\n} = {\n TRACKS: { current: 1, total: WIZARD_TOTAL },\n CLI: { current: 2, total: WIZARD_TOTAL },\n TARGETS: { current: 3, total: WIZARD_TOTAL },\n SCOPE: { current: 4, total: WIZARD_TOTAL },\n CONFIRM: { current: 5, total: WIZARD_TOTAL },\n INSTALL: { current: 6, total: WIZARD_TOTAL },\n};\n\n/**\n * Wizard step header — `Step N/M — <suffix>` 형식.\n *\n * step 미지정 시 suffix 만 반환 (backward compat — tests / non-wizard 호출).\n */\nexport function stepLabel(step: WizardStep | undefined, suffix: string): string {\n if (!step) return suffix;\n return `Step ${step.current}/${step.total} — ${suffix}`;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { isTrack, type Track } from \"./types.js\";\n\nexport type InstallState = \"new\" | \"existing\";\n\nexport interface DetectedInstall {\n state: InstallState;\n tracks: Track[];\n /** Source of the detected tracks: \"metafile\" (v27.17+), \"legacy\" (rules/*.md heuristic), or \"none\". */\n source: \"metafile\" | \"legacy\" | \"none\";\n hasClaudeDir: boolean;\n}\n\nconst META_FILE = \".claude/.installed-tracks\";\n\ninterface LegacySignature {\n rule: string;\n track: Track;\n}\n\nconst LEGACY_SIGNATURES: readonly LegacySignature[] = [\n { rule: \"htmx.md\", track: \"ssr-htmx\" },\n { rule: \"nextjs.md\", track: \"ssr-nextjs\" },\n { rule: \"data-analysis.md\", track: \"data\" },\n { rule: \"pyside6.md\", track: \"data\" },\n { rule: \"cli-development.md\", track: \"tooling\" },\n];\n\n/**\n * Detect what was previously installed in the given project directory.\n * Mirrors the v27.17 detect_install_state shell function (setup-harness.sh:191).\n */\nexport function detectInstallState(projectDir: string): DetectedInstall {\n const claudeDir = join(projectDir, \".claude\");\n const hasClaudeDir = existsSync(claudeDir);\n\n if (!hasClaudeDir) {\n return { state: \"new\", tracks: [], source: \"none\", hasClaudeDir: false };\n }\n\n const metaPath = join(projectDir, META_FILE);\n if (existsSync(metaPath)) {\n const tracks = readMetafile(metaPath);\n return { state: \"existing\", tracks, source: \"metafile\", hasClaudeDir: true };\n }\n\n const tracks = inferFromLegacySignatures(projectDir);\n return { state: \"existing\", tracks, source: \"legacy\", hasClaudeDir: true };\n}\n\nfunction readMetafile(path: string): Track[] {\n const raw = readFileSync(path, \"utf8\");\n const seen = new Set<Track>();\n for (const line of raw.split(/\\s+/)) {\n const trimmed = line.trim();\n if (isTrack(trimmed)) {\n seen.add(trimmed);\n }\n }\n return [...seen].sort();\n}\n\nfunction inferFromLegacySignatures(projectDir: string): Track[] {\n const rulesDir = join(projectDir, \".claude/rules\");\n if (!existsSync(rulesDir)) {\n return [];\n }\n const found = new Set<Track>();\n for (const sig of LEGACY_SIGNATURES) {\n if (existsSync(join(rulesDir, sig.rule))) {\n found.add(sig.track);\n }\n }\n return [...found].sort();\n}\n"],"mappings":"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","names":["ESC","CSI","k","j","v","b","cli","resolve","b","chmodSync","existsSync","mkdirSync","readdirSync","readFileSync","writeFileSync","dirname","join","existsSync","readFileSync","writeFileSync","join","body","cpSync","existsSync","mkdirSync","join","d","PHASES","join","existsSync","readFileSync","writeFileSync","cpSync","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","join","parseSource","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","e","PHASES","join","homedir","p","existsSync","mkdirSync","readFileSync","writeFileSync","cpSync","existsSync","readFileSync","writeFileSync","basename","join","k","v","PHASES","join","basename","writeFileSync","existsSync","readFileSync","existsSync","readFileSync","writeFileSync","join","existsSync","readdirSync","readFileSync","homedir","join","b","cli","v","join","existsSync","c","at","homedir","readdirSync","readFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","h","existsSync","readFileSync","writeFileSync","readFileSync","existsSync","writeFileSync","copyFileSync","existsSync","readFileSync","writeFileSync","basename","join","renameSlashes","renderAgentsMd","parseSource","renameSlashes","stripQuotes","body","PHASES","readRequired","join","basename","readOptionalJson","writeFileSync","renderAgentsMd","existsSync","readFileSync","copyFileSync","existsSync","readFileSync","join","h","copyFileSync","existsSync","readdirSync","readFileSync","writeFileSync","join","join","existsSync","e","chmodSync","readFileSync","writeFileSync","mkdirSync","dirname","readdirSync","b","v","k","p","w","resolve","e","cli","spawnSync","existsSync","readFileSync","join","resolve","defaultSpawn","resolve","join","existsSync","readFileSync","spawnSync","cli","NO_TRUNCATION","dist_default","dist_default","findCursor","cursor","delta","options","opt","newCursor","maxCursor","clampedCursor","actions","DEFAULT_MONTH_NAMES","settings","days","month","min","max","isActionKey","key","action","settings","value","diffLines","a","b","aLines","bLines","numLines","diff","i","isWindows","CANCEL_SYMBOL","isCancel","setRawMode","input","getColumns","output","getRows","wrapTextWithPrefix","text","prefix","startPrefix","lineFormatter","columns","stdout","wrapAnsi","line","index","lineString","g$1","options","trackValue","input","stdin","render","signal","opts","event","params","cb","data","cbs","cleanup","subscriber","resolve","CANCEL_SYMBOL","readline","setRawMode","cursor","char","_key","_char","value","write","key","settings","problem","isActionKey","lines","frame","diff","diffLines","rows","diffOffsetAfter","diffOffsetBefore","diffLine","erase","adjustedDiffLine","newLines","ConfirmPrompt","Prompt","opts","confirm","cursor","GroupMultiSelectPrompt","Prompt","#selectableGroups","group","o","items","value","i","item","groupedItems","v","selected","opts","options","key","option","opt","currentIsGroup","Prompt","option","enabledOptions","allSelected","v","value","notSelected","selected","opts","cursor","findCursor","char","key","SelectPrompt","Prompt","opts","initialCursor","value","cursor","findCursor","key","isUnicodeSupported","process","unicode","unicodeOr","c","fallback","unicode","S_STEP_ACTIVE","S_STEP_CANCEL","S_STEP_ERROR","S_STEP_SUBMIT","S_BAR_START","S_BAR","S_BAR_END","S_BAR_START_RIGHT","S_BAR_END_RIGHT","S_RADIO_ACTIVE","S_RADIO_INACTIVE","S_CHECKBOX_ACTIVE","S_CHECKBOX_SELECTED","S_CHECKBOX_INACTIVE","S_PASSWORD_MASK","S_BAR_H","S_CORNER_TOP_RIGHT","S_CONNECT_LEFT","S_CORNER_BOTTOM_RIGHT","S_CORNER_BOTTOM_LEFT","S_CORNER_TOP_LEFT","S_INFO","S_SUCCESS","S_WARN","S_ERROR","symbol","state","styleText","symbolBar","trimLines","groups","initialLineCount","startIndex","endIndex","maxLines","lineCount","removals","i","group","limitOptions","cursor","options","style","output","maxItems","columnPadding","rowPadding","maxWidth","getColumns","rows","getRows","overflowFormat","outputMaxItems","computedMaxItems","slidingWindowLocation","shouldRenderTopEllipsis","shouldRenderBottomEllipsis","slidingWindowLocationEnd","lineGroups","slidingWindowLocationWithEllipsis","slidingWindowLocationEndWithEllipsis","wrappedLines","wrapAnsi","precedingRemovals","followingRemovals","newLineCount","cursorGroupIndex","trimLinesLocal","result","lineGroup","line","confirm","opts","active","inactive","ConfirmPrompt","hasGuide","settings","titlePrefix","symbol","titlePrefixBar","styleText","S_BAR","messageLines","wrapTextWithPrefix","title","value","submitPrefix","cancelPrefix","defaultPrefix","defaultPrefixEnd","S_BAR_END","S_RADIO_ACTIVE","S_RADIO_INACTIVE","groupMultiselect","opts","selectableGroups","groupSpacing","opt","option","state","options","label","isItem","next","isLast","prefix","S_BAR_END","S_BAR","spacingPrefix","spacingPrefixText","styleText","S_CHECKBOX_ACTIVE","S_CHECKBOX_SELECTED","selectedCheckbox","unselectedCheckbox","S_CHECKBOX_INACTIVE","required","GroupMultiSelectPrompt","selected","hasGuide","settings","title","symbol","value","selectedOptions","optionValue","optionsText","footer","ln","i","active","groupActive","optionText","optionsPrefix","cancel","message","opts","output","prefix","settings","styleText","S_BAR_END","intro","title","S_BAR_START","outro","S_BAR","computeLabel","label","format","line","multiselect","opts","opt","option","state","styleText","S_CHECKBOX_INACTIVE","str","S_CHECKBOX_ACTIVE","S_CHECKBOX_SELECTED","text","required","MultiSelectPrompt","selected","hasGuide","settings","wrappedMessage","wrapTextWithPrefix","symbolBar","symbol","title","S_BAR","value","styleOption","active","submitText","optionValue","wrappedSubmitText","wrappedLabel","prefix","footer","ln","i","S_BAR_END","titleLineCount","footerLineCount","limitOptions","S_PROGRESS_CHAR","unicodeOr","computeLabel","label","format","line","select","opts","opt","option","state","styleText","S_RADIO_INACTIVE","text","S_RADIO_ACTIVE","str","SelectPrompt","hasGuide","settings","titlePrefix","symbol","titlePrefixBar","symbolBar","messageLines","wrapTextWithPrefix","title","S_BAR","submitPrefix","wrappedLines","cancelPrefix","prefix","prefixEnd","S_BAR_END","titleLineCount","footerLineCount","limitOptions","item","active","prefix","styleText","S_BAR","trackList","c","b","d","it","v","existsSync","readFileSync","join","join","existsSync","tracks","readFileSync","cli","b","k","cli"]}
1
+ {"version":3,"sources":["../node_modules/sisteransi/src/index.js","../src/index.ts","../src/cli.ts","../node_modules/cac/dist/index.js","../package.json","../src/commands/install.ts","../src/cli-targets.ts","../src/types.ts","../src/design.ts","../src/installer.ts","../src/antigravity/opt-in.ts","../src/codex/agents-md.ts","../src/antigravity/transform.ts","../src/codex/skills.ts","../src/fs-ops.ts","../src/codex/opt-in.ts","../src/codex/prompts.ts","../src/codex/trust-entry.ts","../src/codex/transform.ts","../src/codex/config-toml.ts","../src/env-files.ts","../src/external-installer.ts","../src/install-log.ts","../src/manifest.ts","../src/mcp-merge.ts","../src/opencode/transform.ts","../src/opencode/agents-md.ts","../src/opencode/commands.ts","../src/opencode/opencode-json.ts","../src/project-claude-merge.ts","../src/settings-merge.ts","../src/update-mode.ts","../src/commands/install-render.ts","../src/preset-recommend.ts","../src/commands/uninstall.ts","../src/interactive.ts","../src/prompts.ts","../node_modules/fast-wrap-ansi/src/main.ts","../node_modules/fast-string-width/dist/index.js","../node_modules/fast-string-truncated-width/dist/index.js","../node_modules/fast-string-truncated-width/dist/utils.js","../node_modules/@clack/core/src/utils/cursor.ts","../node_modules/@clack/core/src/utils/settings.ts","../node_modules/@clack/core/src/utils/string.ts","../node_modules/@clack/core/src/utils/index.ts","../node_modules/@clack/core/src/prompts/prompt.ts","../node_modules/@clack/core/src/prompts/autocomplete.ts","../node_modules/@clack/core/src/prompts/confirm.ts","../node_modules/@clack/core/src/prompts/date.ts","../node_modules/@clack/core/src/prompts/group-multiselect.ts","../node_modules/@clack/core/src/prompts/multi-line.ts","../node_modules/@clack/core/src/prompts/multi-select.ts","../node_modules/@clack/core/src/prompts/password.ts","../node_modules/@clack/core/src/prompts/select.ts","../node_modules/@clack/core/src/prompts/select-key.ts","../node_modules/@clack/core/src/prompts/text.ts","../node_modules/node_modules/.pnpm/is-unicode-supported@1.3.0/node_modules/is-unicode-supported/index.js","../node_modules/@clack/prompts/src/common.ts","../node_modules/@clack/prompts/src/limit-options.ts","../node_modules/@clack/prompts/src/autocomplete.ts","../node_modules/@clack/prompts/src/box.ts","../node_modules/@clack/prompts/src/confirm.ts","../node_modules/@clack/prompts/src/date.ts","../node_modules/@clack/prompts/src/group.ts","../node_modules/@clack/prompts/src/group-multi-select.ts","../node_modules/@clack/prompts/src/log.ts","../node_modules/@clack/prompts/src/messages.ts","../node_modules/@clack/prompts/src/multi-line.ts","../node_modules/@clack/prompts/src/multi-select.ts","../node_modules/@clack/prompts/src/note.ts","../node_modules/@clack/prompts/src/password.ts","../node_modules/@clack/prompts/src/path.ts","../node_modules/@clack/prompts/src/spinner.ts","../node_modules/@clack/prompts/src/progress-bar.ts","../node_modules/@clack/prompts/src/select.ts","../node_modules/@clack/prompts/src/select-key.ts","../node_modules/@clack/prompts/src/stream.ts","../node_modules/@clack/prompts/src/task.ts","../node_modules/@clack/prompts/src/task-log.ts","../node_modules/@clack/prompts/src/text.ts","../src/router.ts","../src/wizard-steps.ts","../src/state.ts"],"sourcesContent":["'use strict';\n\nconst ESC = '\\x1B';\nconst CSI = `${ESC}[`;\nconst beep = '\\u0007';\n\nconst cursor = {\n to(x, y) {\n if (!y) return `${CSI}${x + 1}G`;\n return `${CSI}${y + 1};${x + 1}H`;\n },\n move(x, y) {\n let ret = '';\n\n if (x < 0) ret += `${CSI}${-x}D`;\n else if (x > 0) ret += `${CSI}${x}C`;\n\n if (y < 0) ret += `${CSI}${-y}A`;\n else if (y > 0) ret += `${CSI}${y}B`;\n\n return ret;\n },\n up: (count = 1) => `${CSI}${count}A`,\n down: (count = 1) => `${CSI}${count}B`,\n forward: (count = 1) => `${CSI}${count}C`,\n backward: (count = 1) => `${CSI}${count}D`,\n nextLine: (count = 1) => `${CSI}E`.repeat(count),\n prevLine: (count = 1) => `${CSI}F`.repeat(count),\n left: `${CSI}G`,\n hide: `${CSI}?25l`,\n show: `${CSI}?25h`,\n save: `${ESC}7`,\n restore: `${ESC}8`\n}\n\nconst scroll = {\n up: (count = 1) => `${CSI}S`.repeat(count),\n down: (count = 1) => `${CSI}T`.repeat(count)\n}\n\nconst erase = {\n screen: `${CSI}2J`,\n up: (count = 1) => `${CSI}1J`.repeat(count),\n down: (count = 1) => `${CSI}J`.repeat(count),\n line: `${CSI}2K`,\n lineEnd: `${CSI}K`,\n lineStart: `${CSI}1K`,\n lines(count) {\n let clear = '';\n for (let i = 0; i < count; i++)\n clear += this.line + (i < count - 1 ? cursor.up() : '');\n if (count)\n clear += cursor.left;\n return clear;\n }\n}\n\nmodule.exports = { cursor, scroll, erase, beep };\n","import { buildCli } from \"./cli.js\";\n\nconst cli = buildCli();\ncli.parse(process.argv);\n","import { cac } from \"cac\";\nimport packageJson from \"../package.json\";\nimport { type ExecuteSpecDeps, executeSpec, registerInstallCommand } from \"./commands/install.js\";\nimport { registerUninstallCommand } from \"./commands/uninstall.js\";\nimport { type InteractiveResult, runInteractive } from \"./interactive.js\";\n\n// v26.72.1 — CalVer 정합 (cli --version / package.json / git tag 단일 버전).\n// v26.82.1 — 하드코딩 → package.json derive. v26.82.0 ship 때 package.json 만 bump 되고\n// 본 상수(26.81.0)가 남아 npm 게시 패키지가 --version 을 거짓 보고 (수동 동기화 주석은\n// 못 막는다는 본 repo 3번째 증명) → 빌드 시 esbuild 가 값 인라인, 동기화 자체를 소멸.\nexport const VERSION: string = packageJson.version;\n\nexport type Cli = ReturnType<typeof cac>;\n\nexport interface DefaultActionDeps {\n log?: (msg: string) => void;\n err?: (msg: string) => void;\n exit?: (code: number) => never;\n run?: (cwd: string) => Promise<InteractiveResult>;\n /** Override the install pipeline + report renderer (used by tests). */\n execute?: (spec: NonNullable<InteractiveResult[\"spec\"]>, deps: ExecuteSpecDeps) => void;\n}\n\n/**\n * Default action — runs the interactive flow, then executes the install\n * pipeline with the captured spec. Mirrors the `install` flag-mode command's\n * post-install report.\n */\nexport async function defaultAction(deps: DefaultActionDeps = {}): Promise<void> {\n const log = deps.log ?? console.log;\n const err = deps.err ?? console.error;\n /* v8 ignore next — process.exit default. tests 는 exit 주입. */\n const exit = deps.exit ?? ((code: number) => process.exit(code) as never);\n const run = deps.run ?? ((cwd: string) => runInteractive(cwd));\n const execute = deps.execute ?? executeSpec;\n\n const result = await run(process.cwd());\n if (!result.ok) {\n if (result.message) {\n err(result.message);\n }\n // exit-code mapping: no-tty=2; cancelled/exit/disabled/declined=0\n exit(result.reason === \"no-tty\" ? 2 : 0);\n return;\n }\n if (!result.spec) {\n err(\"Internal error: interactive returned ok=true without a spec.\");\n exit(1);\n return;\n }\n // v26.63.0 — wizard 모드 표시. install header (TARGET 등) 출력 skip → Step 5 sub-section 으로 자연 흐름.\n const execDeps: import(\"./commands/install.js\").ExecuteSpecDeps = {\n log,\n err,\n exit,\n fromWizard: true,\n };\n if (result.mode) execDeps.mode = result.mode;\n execute(result.spec, execDeps);\n}\n\nexport function buildCli(): Cli {\n const cli = cac(\"agent-harness\");\n\n cli.help();\n cli.version(VERSION);\n\n registerInstallCommand(cli);\n registerUninstallCommand(cli);\n\n cli\n .command(\"\", \"Interactive installer (state detection + prompts)\")\n /* v8 ignore next — cac action callback. defaultAction 자체는 별도 tests 로 검증. */\n .action(() => defaultAction());\n\n return cli;\n}\n","//#region node_modules/.pnpm/mri@1.2.0/node_modules/mri/lib/index.mjs\nfunction toArr(any) {\n\treturn any == null ? [] : Array.isArray(any) ? any : [any];\n}\nfunction toVal(out, key, val, opts) {\n\tvar x, old = out[key], nxt = !!~opts.string.indexOf(key) ? val == null || val === true ? \"\" : String(val) : typeof val === \"boolean\" ? val : !!~opts.boolean.indexOf(key) ? val === \"false\" ? false : val === \"true\" || (out._.push((x = +val, x * 0 === 0) ? x : val), !!val) : (x = +val, x * 0 === 0) ? x : val;\n\tout[key] = old == null ? nxt : Array.isArray(old) ? old.concat(nxt) : [old, nxt];\n}\nfunction lib_default(args, opts) {\n\targs = args || [];\n\topts = opts || {};\n\tvar k, arr, arg, name, val, out = { _: [] };\n\tvar i = 0, j = 0, idx = 0, len = args.length;\n\tconst alibi = opts.alias !== void 0;\n\tconst strict = opts.unknown !== void 0;\n\tconst defaults = opts.default !== void 0;\n\topts.alias = opts.alias || {};\n\topts.string = toArr(opts.string);\n\topts.boolean = toArr(opts.boolean);\n\tif (alibi) for (k in opts.alias) {\n\t\tarr = opts.alias[k] = toArr(opts.alias[k]);\n\t\tfor (i = 0; i < arr.length; i++) (opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);\n\t}\n\tfor (i = opts.boolean.length; i-- > 0;) {\n\t\tarr = opts.alias[opts.boolean[i]] || [];\n\t\tfor (j = arr.length; j-- > 0;) opts.boolean.push(arr[j]);\n\t}\n\tfor (i = opts.string.length; i-- > 0;) {\n\t\tarr = opts.alias[opts.string[i]] || [];\n\t\tfor (j = arr.length; j-- > 0;) opts.string.push(arr[j]);\n\t}\n\tif (defaults) for (k in opts.default) {\n\t\tname = typeof opts.default[k];\n\t\tarr = opts.alias[k] = opts.alias[k] || [];\n\t\tif (opts[name] !== void 0) {\n\t\t\topts[name].push(k);\n\t\t\tfor (i = 0; i < arr.length; i++) opts[name].push(arr[i]);\n\t\t}\n\t}\n\tconst keys = strict ? Object.keys(opts.alias) : [];\n\tfor (i = 0; i < len; i++) {\n\t\targ = args[i];\n\t\tif (arg === \"--\") {\n\t\t\tout._ = out._.concat(args.slice(++i));\n\t\t\tbreak;\n\t\t}\n\t\tfor (j = 0; j < arg.length; j++) if (arg.charCodeAt(j) !== 45) break;\n\t\tif (j === 0) out._.push(arg);\n\t\telse if (arg.substring(j, j + 3) === \"no-\") {\n\t\t\tname = arg.substring(j + 3);\n\t\t\tif (strict && !~keys.indexOf(name)) return opts.unknown(arg);\n\t\t\tout[name] = false;\n\t\t} else {\n\t\t\tfor (idx = j + 1; idx < arg.length; idx++) if (arg.charCodeAt(idx) === 61) break;\n\t\t\tname = arg.substring(j, idx);\n\t\t\tval = arg.substring(++idx) || i + 1 === len || (\"\" + args[i + 1]).charCodeAt(0) === 45 || args[++i];\n\t\t\tarr = j === 2 ? [name] : name;\n\t\t\tfor (idx = 0; idx < arr.length; idx++) {\n\t\t\t\tname = arr[idx];\n\t\t\t\tif (strict && !~keys.indexOf(name)) return opts.unknown(\"-\".repeat(j) + name);\n\t\t\t\ttoVal(out, name, idx + 1 < arr.length || val, opts);\n\t\t\t}\n\t\t}\n\t}\n\tif (defaults) {\n\t\tfor (k in opts.default) if (out[k] === void 0) out[k] = opts.default[k];\n\t}\n\tif (alibi) for (k in out) {\n\t\tarr = opts.alias[k] || [];\n\t\twhile (arr.length > 0) out[arr.shift()] = out[k];\n\t}\n\treturn out;\n}\n\n//#endregion\n//#region src/utils.ts\nfunction removeBrackets(v) {\n\treturn v.replace(/[<[].+/, \"\").trim();\n}\nfunction findAllBrackets(v) {\n\tconst ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;\n\tconst SQUARE_BRACKET_RE_GLOBAL = /\\[([^\\]]+)\\]/g;\n\tconst res = [];\n\tconst parse = (match) => {\n\t\tlet variadic = false;\n\t\tlet value = match[1];\n\t\tif (value.startsWith(\"...\")) {\n\t\t\tvalue = value.slice(3);\n\t\t\tvariadic = true;\n\t\t}\n\t\treturn {\n\t\t\trequired: match[0].startsWith(\"<\"),\n\t\t\tvalue,\n\t\t\tvariadic\n\t\t};\n\t};\n\tlet angledMatch;\n\twhile (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) res.push(parse(angledMatch));\n\tlet squareMatch;\n\twhile (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) res.push(parse(squareMatch));\n\treturn res;\n}\nfunction getMriOptions(options) {\n\tconst result = {\n\t\talias: {},\n\t\tboolean: []\n\t};\n\tfor (const [index, option] of options.entries()) {\n\t\tif (option.names.length > 1) result.alias[option.names[0]] = option.names.slice(1);\n\t\tif (option.isBoolean) if (option.negated) {\n\t\t\tif (!options.some((o, i) => {\n\t\t\t\treturn i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === \"boolean\";\n\t\t\t})) result.boolean.push(option.names[0]);\n\t\t} else result.boolean.push(option.names[0]);\n\t}\n\treturn result;\n}\nfunction findLongest(arr) {\n\treturn arr.sort((a, b) => {\n\t\treturn a.length > b.length ? -1 : 1;\n\t})[0];\n}\nfunction padRight(str, length) {\n\treturn str.length >= length ? str : `${str}${\" \".repeat(length - str.length)}`;\n}\nfunction camelcase(input) {\n\treturn input.replaceAll(/([a-z])-([a-z])/g, (_, p1, p2) => {\n\t\treturn p1 + p2.toUpperCase();\n\t});\n}\nfunction setDotProp(obj, keys, val) {\n\tlet current = obj;\n\tfor (let i = 0; i < keys.length; i++) {\n\t\tconst key = keys[i];\n\t\tif (i === keys.length - 1) {\n\t\t\tcurrent[key] = val;\n\t\t\treturn;\n\t\t}\n\t\tif (current[key] == null) {\n\t\t\tconst nextKeyIsArrayIndex = +keys[i + 1] > -1;\n\t\t\tcurrent[key] = nextKeyIsArrayIndex ? [] : {};\n\t\t}\n\t\tcurrent = current[key];\n\t}\n}\nfunction setByType(obj, transforms) {\n\tfor (const key of Object.keys(transforms)) {\n\t\tconst transform = transforms[key];\n\t\tif (transform.shouldTransform) {\n\t\t\tobj[key] = [obj[key]].flat();\n\t\t\tif (typeof transform.transformFunction === \"function\") obj[key] = obj[key].map(transform.transformFunction);\n\t\t}\n\t}\n}\nfunction getFileName(input) {\n\tconst m = /([^\\\\/]+)$/.exec(input);\n\treturn m ? m[1] : \"\";\n}\nfunction camelcaseOptionName(name) {\n\treturn name.split(\".\").map((v, i) => {\n\t\treturn i === 0 ? camelcase(v) : v;\n\t}).join(\".\");\n}\nvar CACError = class extends Error {\n\tconstructor(message) {\n\t\tsuper(message);\n\t\tthis.name = \"CACError\";\n\t\tif (typeof Error.captureStackTrace !== \"function\") this.stack = new Error(message).stack;\n\t}\n};\n\n//#endregion\n//#region src/option.ts\nvar Option = class {\n\trawName;\n\tdescription;\n\t/** Option name */\n\tname;\n\t/** Option name and aliases */\n\tnames;\n\tisBoolean;\n\trequired;\n\tconfig;\n\tnegated;\n\tconstructor(rawName, description, config) {\n\t\tthis.rawName = rawName;\n\t\tthis.description = description;\n\t\tthis.config = Object.assign({}, config);\n\t\trawName = rawName.replaceAll(\".*\", \"\");\n\t\tthis.negated = false;\n\t\tthis.names = removeBrackets(rawName).split(\",\").map((v) => {\n\t\t\tlet name = v.trim().replace(/^-{1,2}/, \"\");\n\t\t\tif (name.startsWith(\"no-\")) {\n\t\t\t\tthis.negated = true;\n\t\t\t\tname = name.replace(/^no-/, \"\");\n\t\t\t}\n\t\t\treturn camelcaseOptionName(name);\n\t\t}).sort((a, b) => a.length > b.length ? 1 : -1);\n\t\tthis.name = this.names.at(-1);\n\t\tif (this.negated && this.config.default == null) this.config.default = true;\n\t\tif (rawName.includes(\"<\")) this.required = true;\n\t\telse if (rawName.includes(\"[\")) this.required = false;\n\t\telse this.isBoolean = true;\n\t}\n};\n\n//#endregion\n//#region src/runtime.ts\nlet runtimeProcessArgs;\nlet runtimeInfo;\nif (typeof process !== \"undefined\") {\n\tlet runtimeName;\n\tif (typeof Deno !== \"undefined\" && typeof Deno.version?.deno === \"string\") runtimeName = \"deno\";\n\telse if (typeof Bun !== \"undefined\" && typeof Bun.version === \"string\") runtimeName = \"bun\";\n\telse runtimeName = \"node\";\n\truntimeInfo = `${process.platform}-${process.arch} ${runtimeName}-${process.version}`;\n\truntimeProcessArgs = process.argv;\n} else if (typeof navigator === \"undefined\") runtimeInfo = `unknown`;\nelse runtimeInfo = `${navigator.platform} ${navigator.userAgent}`;\n\n//#endregion\n//#region src/command.ts\nvar Command = class {\n\trawName;\n\tdescription;\n\tconfig;\n\tcli;\n\toptions;\n\taliasNames;\n\tname;\n\targs;\n\tcommandAction;\n\tusageText;\n\tversionNumber;\n\texamples;\n\thelpCallback;\n\tglobalCommand;\n\tconstructor(rawName, description, config = {}, cli) {\n\t\tthis.rawName = rawName;\n\t\tthis.description = description;\n\t\tthis.config = config;\n\t\tthis.cli = cli;\n\t\tthis.options = [];\n\t\tthis.aliasNames = [];\n\t\tthis.name = removeBrackets(rawName);\n\t\tthis.args = findAllBrackets(rawName);\n\t\tthis.examples = [];\n\t}\n\tusage(text) {\n\t\tthis.usageText = text;\n\t\treturn this;\n\t}\n\tallowUnknownOptions() {\n\t\tthis.config.allowUnknownOptions = true;\n\t\treturn this;\n\t}\n\tignoreOptionDefaultValue() {\n\t\tthis.config.ignoreOptionDefaultValue = true;\n\t\treturn this;\n\t}\n\tversion(version, customFlags = \"-v, --version\") {\n\t\tthis.versionNumber = version;\n\t\tthis.option(customFlags, \"Display version number\");\n\t\treturn this;\n\t}\n\texample(example) {\n\t\tthis.examples.push(example);\n\t\treturn this;\n\t}\n\t/**\n\t* Add a option for this command\n\t* @param rawName Raw option name(s)\n\t* @param description Option description\n\t* @param config Option config\n\t*/\n\toption(rawName, description, config) {\n\t\tconst option = new Option(rawName, description, config);\n\t\tthis.options.push(option);\n\t\treturn this;\n\t}\n\talias(name) {\n\t\tthis.aliasNames.push(name);\n\t\treturn this;\n\t}\n\taction(callback) {\n\t\tthis.commandAction = callback;\n\t\treturn this;\n\t}\n\t/**\n\t* Check if a command name is matched by this command\n\t* @param name Command name\n\t*/\n\tisMatched(name) {\n\t\treturn this.name === name || this.aliasNames.includes(name);\n\t}\n\tget isDefaultCommand() {\n\t\treturn this.name === \"\" || this.aliasNames.includes(\"!\");\n\t}\n\tget isGlobalCommand() {\n\t\treturn this instanceof GlobalCommand;\n\t}\n\t/**\n\t* Check if an option is registered in this command\n\t* @param name Option name\n\t*/\n\thasOption(name) {\n\t\tname = name.split(\".\")[0];\n\t\treturn this.options.find((option) => {\n\t\t\treturn option.names.includes(name);\n\t\t});\n\t}\n\toutputHelp() {\n\t\tconst { name, commands } = this.cli;\n\t\tconst { versionNumber, options: globalOptions, helpCallback } = this.cli.globalCommand;\n\t\tlet sections = [{ body: `${name}${versionNumber ? `/${versionNumber}` : \"\"}` }];\n\t\tsections.push({\n\t\t\ttitle: \"Usage\",\n\t\t\tbody: ` $ ${name} ${this.usageText || this.rawName}`\n\t\t});\n\t\tif ((this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0) {\n\t\t\tconst longestCommandName = findLongest(commands.map((command) => command.rawName));\n\t\t\tsections.push({\n\t\t\t\ttitle: \"Commands\",\n\t\t\t\tbody: commands.map((command) => {\n\t\t\t\t\treturn ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;\n\t\t\t\t}).join(\"\\n\")\n\t\t\t}, {\n\t\t\t\ttitle: `For more info, run any command with the \\`--help\\` flag`,\n\t\t\t\tbody: commands.map((command) => ` $ ${name}${command.name === \"\" ? \"\" : ` ${command.name}`} --help`).join(\"\\n\")\n\t\t\t});\n\t\t}\n\t\tlet options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];\n\t\tif (!this.isGlobalCommand && !this.isDefaultCommand) options = options.filter((option) => option.name !== \"version\");\n\t\tif (options.length > 0) {\n\t\t\tconst longestOptionName = findLongest(options.map((option) => option.rawName));\n\t\t\tsections.push({\n\t\t\t\ttitle: \"Options\",\n\t\t\t\tbody: options.map((option) => {\n\t\t\t\t\treturn ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === void 0 ? \"\" : `(default: ${option.config.default})`}`;\n\t\t\t\t}).join(\"\\n\")\n\t\t\t});\n\t\t}\n\t\tif (this.examples.length > 0) sections.push({\n\t\t\ttitle: \"Examples\",\n\t\t\tbody: this.examples.map((example) => {\n\t\t\t\tif (typeof example === \"function\") return example(name);\n\t\t\t\treturn example;\n\t\t\t}).join(\"\\n\")\n\t\t});\n\t\tif (helpCallback) sections = helpCallback(sections) || sections;\n\t\tconsole.info(sections.map((section) => {\n\t\t\treturn section.title ? `${section.title}:\\n${section.body}` : section.body;\n\t\t}).join(\"\\n\\n\"));\n\t}\n\toutputVersion() {\n\t\tconst { name } = this.cli;\n\t\tconst { versionNumber } = this.cli.globalCommand;\n\t\tif (versionNumber) console.info(`${name}/${versionNumber} ${runtimeInfo}`);\n\t}\n\tcheckRequiredArgs() {\n\t\tconst minimalArgsCount = this.args.filter((arg) => arg.required).length;\n\t\tif (this.cli.args.length < minimalArgsCount) throw new CACError(`missing required args for command \\`${this.rawName}\\``);\n\t}\n\t/**\n\t* Check if the parsed options contain any unknown options\n\t*\n\t* Exit and output error when true\n\t*/\n\tcheckUnknownOptions() {\n\t\tconst { options, globalCommand } = this.cli;\n\t\tif (!this.config.allowUnknownOptions) {\n\t\t\tfor (const name of Object.keys(options)) if (name !== \"--\" && !this.hasOption(name) && !globalCommand.hasOption(name)) throw new CACError(`Unknown option \\`${name.length > 1 ? `--${name}` : `-${name}`}\\``);\n\t\t}\n\t}\n\t/**\n\t* Check if the required string-type options exist\n\t*/\n\tcheckOptionValue() {\n\t\tconst { options: parsedOptions, globalCommand } = this.cli;\n\t\tconst options = [...globalCommand.options, ...this.options];\n\t\tfor (const option of options) {\n\t\t\tconst value = parsedOptions[option.name.split(\".\")[0]];\n\t\t\tif (option.required) {\n\t\t\t\tconst hasNegated = options.some((o) => o.negated && o.names.includes(option.name));\n\t\t\t\tif (value === true || value === false && !hasNegated) throw new CACError(`option \\`${option.rawName}\\` value is missing`);\n\t\t\t}\n\t\t}\n\t}\n\t/**\n\t* Check if the number of args is more than expected\n\t*/\n\tcheckUnusedArgs() {\n\t\tconst maximumArgsCount = this.args.some((arg) => arg.variadic) ? Infinity : this.args.length;\n\t\tif (maximumArgsCount < this.cli.args.length) throw new CACError(`Unused args: ${this.cli.args.slice(maximumArgsCount).map((arg) => `\\`${arg}\\``).join(\", \")}`);\n\t}\n};\nvar GlobalCommand = class extends Command {\n\tconstructor(cli) {\n\t\tsuper(\"@@global@@\", \"\", {}, cli);\n\t}\n};\n\n//#endregion\n//#region src/cac.ts\nvar CAC = class extends EventTarget {\n\t/** The program name to display in help and version message */\n\tname;\n\tcommands;\n\tglobalCommand;\n\tmatchedCommand;\n\tmatchedCommandName;\n\t/**\n\t* Raw CLI arguments\n\t*/\n\trawArgs;\n\t/**\n\t* Parsed CLI arguments\n\t*/\n\targs;\n\t/**\n\t* Parsed CLI options, camelCased\n\t*/\n\toptions;\n\tshowHelpOnExit;\n\tshowVersionOnExit;\n\t/**\n\t* @param name The program name to display in help and version message\n\t*/\n\tconstructor(name = \"\") {\n\t\tsuper();\n\t\tthis.name = name;\n\t\tthis.commands = [];\n\t\tthis.rawArgs = [];\n\t\tthis.args = [];\n\t\tthis.options = {};\n\t\tthis.globalCommand = new GlobalCommand(this);\n\t\tthis.globalCommand.usage(\"<command> [options]\");\n\t}\n\t/**\n\t* Add a global usage text.\n\t*\n\t* This is not used by sub-commands.\n\t*/\n\tusage(text) {\n\t\tthis.globalCommand.usage(text);\n\t\treturn this;\n\t}\n\t/**\n\t* Add a sub-command\n\t*/\n\tcommand(rawName, description, config) {\n\t\tconst command = new Command(rawName, description || \"\", config, this);\n\t\tcommand.globalCommand = this.globalCommand;\n\t\tthis.commands.push(command);\n\t\treturn command;\n\t}\n\t/**\n\t* Add a global CLI option.\n\t*\n\t* Which is also applied to sub-commands.\n\t*/\n\toption(rawName, description, config) {\n\t\tthis.globalCommand.option(rawName, description, config);\n\t\treturn this;\n\t}\n\t/**\n\t* Show help message when `-h, --help` flags appear.\n\t*\n\t*/\n\thelp(callback) {\n\t\tthis.globalCommand.option(\"-h, --help\", \"Display this message\");\n\t\tthis.globalCommand.helpCallback = callback;\n\t\tthis.showHelpOnExit = true;\n\t\treturn this;\n\t}\n\t/**\n\t* Show version number when `-v, --version` flags appear.\n\t*\n\t*/\n\tversion(version, customFlags = \"-v, --version\") {\n\t\tthis.globalCommand.version(version, customFlags);\n\t\tthis.showVersionOnExit = true;\n\t\treturn this;\n\t}\n\t/**\n\t* Add a global example.\n\t*\n\t* This example added here will not be used by sub-commands.\n\t*/\n\texample(example) {\n\t\tthis.globalCommand.example(example);\n\t\treturn this;\n\t}\n\t/**\n\t* Output the corresponding help message\n\t* When a sub-command is matched, output the help message for the command\n\t* Otherwise output the global one.\n\t*\n\t*/\n\toutputHelp() {\n\t\tif (this.matchedCommand) this.matchedCommand.outputHelp();\n\t\telse this.globalCommand.outputHelp();\n\t}\n\t/**\n\t* Output the version number.\n\t*\n\t*/\n\toutputVersion() {\n\t\tthis.globalCommand.outputVersion();\n\t}\n\tsetParsedInfo({ args, options }, matchedCommand, matchedCommandName) {\n\t\tthis.args = args;\n\t\tthis.options = options;\n\t\tif (matchedCommand) this.matchedCommand = matchedCommand;\n\t\tif (matchedCommandName) this.matchedCommandName = matchedCommandName;\n\t\treturn this;\n\t}\n\tunsetMatchedCommand() {\n\t\tthis.matchedCommand = void 0;\n\t\tthis.matchedCommandName = void 0;\n\t}\n\t/**\n\t* Parse argv\n\t*/\n\tparse(argv, { run = true } = {}) {\n\t\tif (!argv) {\n\t\t\tif (!runtimeProcessArgs) throw new Error(\"No argv provided and runtime process argv is not available.\");\n\t\t\targv = runtimeProcessArgs;\n\t\t}\n\t\tthis.rawArgs = argv;\n\t\tif (!this.name) this.name = argv[1] ? getFileName(argv[1]) : \"cli\";\n\t\tlet shouldParse = true;\n\t\tfor (const command of this.commands) {\n\t\t\tconst parsed = this.mri(argv.slice(2), command);\n\t\t\tconst commandName = parsed.args[0];\n\t\t\tif (command.isMatched(commandName)) {\n\t\t\t\tshouldParse = false;\n\t\t\t\tconst parsedInfo = {\n\t\t\t\t\t...parsed,\n\t\t\t\t\targs: parsed.args.slice(1)\n\t\t\t\t};\n\t\t\t\tthis.setParsedInfo(parsedInfo, command, commandName);\n\t\t\t\tthis.dispatchEvent(new CustomEvent(`command:${commandName}`, { detail: command }));\n\t\t\t}\n\t\t}\n\t\tif (shouldParse) {\n\t\t\tfor (const command of this.commands) if (command.isDefaultCommand) {\n\t\t\t\tshouldParse = false;\n\t\t\t\tconst parsed = this.mri(argv.slice(2), command);\n\t\t\t\tthis.setParsedInfo(parsed, command);\n\t\t\t\tthis.dispatchEvent(new CustomEvent(\"command:!\", { detail: command }));\n\t\t\t}\n\t\t}\n\t\tif (shouldParse) {\n\t\t\tconst parsed = this.mri(argv.slice(2));\n\t\t\tthis.setParsedInfo(parsed);\n\t\t}\n\t\tif (this.options.help && this.showHelpOnExit) {\n\t\t\tthis.outputHelp();\n\t\t\trun = false;\n\t\t\tthis.unsetMatchedCommand();\n\t\t}\n\t\tif (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) {\n\t\t\tthis.outputVersion();\n\t\t\trun = false;\n\t\t\tthis.unsetMatchedCommand();\n\t\t}\n\t\tconst parsedArgv = {\n\t\t\targs: this.args,\n\t\t\toptions: this.options\n\t\t};\n\t\tif (run) this.runMatchedCommand();\n\t\tif (!this.matchedCommand && this.args[0]) this.dispatchEvent(new CustomEvent(\"command:*\", { detail: this.args[0] }));\n\t\treturn parsedArgv;\n\t}\n\tmri(argv, command) {\n\t\tconst cliOptions = [...this.globalCommand.options, ...command ? command.options : []];\n\t\tconst mriOptions = getMriOptions(cliOptions);\n\t\tlet argsAfterDoubleDashes = [];\n\t\tconst doubleDashesIndex = argv.indexOf(\"--\");\n\t\tif (doubleDashesIndex !== -1) {\n\t\t\targsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);\n\t\t\targv = argv.slice(0, doubleDashesIndex);\n\t\t}\n\t\tlet parsed = lib_default(argv, mriOptions);\n\t\tparsed = Object.keys(parsed).reduce((res, name) => {\n\t\t\treturn {\n\t\t\t\t...res,\n\t\t\t\t[camelcaseOptionName(name)]: parsed[name]\n\t\t\t};\n\t\t}, { _: [] });\n\t\tconst args = parsed._;\n\t\tconst options = { \"--\": argsAfterDoubleDashes };\n\t\tconst ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;\n\t\tconst transforms = Object.create(null);\n\t\tfor (const cliOption of cliOptions) {\n\t\t\tif (!ignoreDefault && cliOption.config.default !== void 0) for (const name of cliOption.names) options[name] = cliOption.config.default;\n\t\t\tif (Array.isArray(cliOption.config.type) && transforms[cliOption.name] === void 0) {\n\t\t\t\ttransforms[cliOption.name] = Object.create(null);\n\t\t\t\ttransforms[cliOption.name].shouldTransform = true;\n\t\t\t\ttransforms[cliOption.name].transformFunction = cliOption.config.type[0];\n\t\t\t}\n\t\t}\n\t\tfor (const key of Object.keys(parsed)) if (key !== \"_\") {\n\t\t\tsetDotProp(options, key.split(\".\"), parsed[key]);\n\t\t\tsetByType(options, transforms);\n\t\t}\n\t\treturn {\n\t\t\targs,\n\t\t\toptions\n\t\t};\n\t}\n\trunMatchedCommand() {\n\t\tconst { args, options, matchedCommand: command } = this;\n\t\tif (!command || !command.commandAction) return;\n\t\tcommand.checkUnknownOptions();\n\t\tcommand.checkOptionValue();\n\t\tcommand.checkRequiredArgs();\n\t\tcommand.checkUnusedArgs();\n\t\tconst actionArgs = [];\n\t\tcommand.args.forEach((arg, index) => {\n\t\t\tif (arg.variadic) actionArgs.push(args.slice(index));\n\t\t\telse actionArgs.push(args[index]);\n\t\t});\n\t\tactionArgs.push(options);\n\t\treturn command.commandAction.apply(this, actionArgs);\n\t}\n};\n\n//#endregion\n//#region src/index.ts\n/**\n* @param name The program name to display in help and version message\n*/\nconst cac = (name = \"\") => new CAC(name);\n\n//#endregion\nexport { CAC, Command, cac, cac as default };","{\n \"name\": \"@uzysjung/agent-harness\",\n \"version\": \"26.84.0\",\n \"description\": \"One-command installer & curator of vetted, Docker-verified AI-coding workflows across Claude Code, Codex, OpenCode & Antigravity\",\n \"type\": \"module\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"bin\": {\n \"agent-harness\": \"./dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"templates\",\n \"scripts/prune-ecc.sh\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"gen:compat\": \"npm run build && node scripts/gen-compatibility.mjs\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"biome check src tests\",\n \"lint:fix\": \"biome check --write src tests\",\n \"format\": \"biome format --write src tests\",\n \"ci\": \"npm run typecheck && npm run lint && npm run test:coverage && npm run build\",\n \"prepare\": \"[ -d dist ] || npm run build\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.3.0\",\n \"cac\": \"^7.0.0\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.4.13\",\n \"@types/node\": \"^25.6.0\",\n \"@vitest/coverage-v8\": \"^2.1.0\",\n \"tsup\": \"^8.3.0\",\n \"typescript\": \"^5.6.0\",\n \"vitest\": \"^2.1.0\"\n },\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/uzysjung/uzys-agent-harness.git\"\n }\n}\n","/**\n * `install` subcommand — spec 검증 + 파이프라인 오케스트레이션 (v26.82.0, Phase R).\n * 화면 출력(헤더/Phase rows/산출물/Summary)은 `install-render.ts` 로 분리.\n */\n\nimport { resolve } from \"node:path\";\nimport type { Cli } from \"../cli.js\";\nimport { parseCliTargets } from \"../cli-targets.js\";\nimport { c, status, unifiedSection } from \"../design.js\";\nimport { EXTERNAL_ASSETS } from \"../external-assets.js\";\nimport { type InstallReport, runInstall as runInstallPipeline } from \"../installer.js\";\nimport {\n type CliTargets,\n type InstallScope,\n type InstallSpec,\n isInstallScope,\n isTrack,\n type Track,\n} from \"../types.js\";\nimport {\n createInstallRenderer,\n type PipelineCallbacks,\n renderCliArtifacts,\n renderFinalSummary,\n renderInstallHeader,\n renderUpdateSummary,\n} from \"./install-render.js\";\n\nexport interface InstallOptions {\n track?: string[];\n /** v0.7.0 — repeatable. cac type: [String]. v0.8.0 — legacy alias 'both'/'all' 제거됨. */\n cli?: string | string[];\n /** v26.63.0 — Phase 1 templates 의 files 라인 표시 (default: counts only). */\n verbose?: boolean;\n projectDir?: string;\n // v26.81.0 (ADR-022, BREAKING) — 자산 1:1 플래그 13종(withTauri/withGsd/withEcc/withTob/\n // withAddyAgentSkills/withUzysHarness/withSuperpowers/withWshobsonAgents/withOpenspec/\n // withBmad/withClaudeVideo/withUnderstandAnything/withAgentmemory) 완전 삭제.\n // 자산 선택 = generic `--with <id>` / `--without <id>` 만. 아래는 동작 옵션.\n withPrune?: boolean;\n withCodexSkills?: boolean;\n withCodexTrust?: boolean;\n withKarpathyHook?: boolean;\n /**\n * v0.7.0 — Codex slash 통일 (~/.codex/prompts/uzys-*.md).\n * v26.46.0 — `cli` 에 codex 포함 시 default ON (ADR-012). Opt-out 은 `--no-codex-prompts`.\n * 명시 true: 사용자 explicit (legacy --with-codex-prompts 호환).\n */\n withCodexPrompts?: boolean;\n /**\n * v26.46.0 — Codex slash 통일 opt-out (cli=codex 일 때 default ON 해제).\n * cac negation flag — `--no-codex-prompts` 명시 시 cac 가 `codexPrompts: false` 로 set.\n * v26.51.0 — bug fix: 이전엔 `noCodexPrompts` field 참조 (cac 가 만들지 않음) → 동작 안 함.\n */\n codexPrompts?: boolean;\n /**\n * v26.67.0 — Antigravity global opt-in. `~/.gemini/antigravity/skills/uzys-*` +\n * `~/.gemini/antigravity/global_workflows/uzys-*.md`. scope=global + cli=antigravity 시만 의미.\n */\n withAntigravityGlobal?: boolean;\n /**\n * v26.47.0 (Phase C full) — External Asset 직접 추가 (preset condition 무관 강제 포함).\n * cac repeatable. 예: `--with railway-skills --with impeccable`.\n * 옵션-키 flag (예: `--with-uzys-harness`) 와 별개 — External Asset id 만.\n */\n with?: string | string[];\n /**\n * v26.47.0 (Phase C full) — External Asset 직접 제외 (preset 추천에서 unchecked).\n * cac repeatable. 예: `--without netlify-cli`.\n */\n without?: string | string[];\n /**\n * v26.64.0 (ADR-020) — Installation scope. `project` (default) | `global`.\n * 명시 안 하면 wizard 의 scope prompt → 비대화형은 \"project\".\n */\n scope?: string;\n}\n\nexport interface RunInstallResult {\n ok: boolean;\n cli: CliTargets;\n /** Deprecation warnings (alias 사용 시 emit). caller가 stderr로 출력. */\n warnings: ReadonlyArray<string>;\n message: string;\n report?: InstallReport;\n}\n\n/**\n * Lift raw flag options to a typed InstallSpec.\n * Returns a Result-shaped value so callers can render errors uniformly.\n */\nexport function specFromOptions(options: InstallOptions): RunInstallResult {\n const parsed = parseCliTargets(options.cli);\n if (!parsed.ok) {\n return {\n ok: false,\n cli: [\"claude\"],\n warnings: parsed.warnings,\n message: parsed.error ?? \"Invalid --cli value\",\n };\n }\n const trackInputs = options.track ?? [];\n if (trackInputs.length === 0) {\n return {\n ok: false,\n cli: parsed.targets,\n warnings: parsed.warnings,\n // v26.56.0 (F6) — wizard 진입 안내. `install` subcommand 는 non-interactive.\n message:\n \"At least one --track is required (e.g. --track tooling)\\n Interactive wizard: run without subcommand → `agent-harness` (drop the `install` word)\",\n };\n }\n for (const t of trackInputs) {\n if (!isTrack(t)) {\n return {\n ok: false,\n cli: parsed.targets,\n warnings: parsed.warnings,\n message: `Unknown track: ${t}`,\n };\n }\n }\n return {\n ok: true,\n cli: parsed.targets,\n warnings: parsed.warnings,\n message: \"spec valid\",\n };\n}\n\nexport interface InstallActionDeps {\n log?: (msg: string) => void;\n err?: (msg: string) => void;\n exit?: (code: number) => never;\n /** Override the install pipeline (used by tests to avoid real fs side effects). */\n runPipeline?: (\n spec: InstallSpec,\n harnessRoot: string,\n mode?: import(\"../installer.js\").InstallMode,\n callbacks?: PipelineCallbacks,\n ) => InstallReport;\n /** Override the harness root resolver (defaults to a path relative to this file). */\n resolveHarnessRoot?: () => string;\n}\n\nexport function installAction(options: InstallOptions, deps: InstallActionDeps = {}): void {\n const log = deps.log ?? console.log;\n const err = deps.err ?? console.error;\n const exit = deps.exit ?? ((code: number) => process.exit(code) as never);\n const runPipeline = deps.runPipeline ?? defaultRunPipeline;\n const resolveHarnessRoot = deps.resolveHarnessRoot ?? defaultHarnessRoot;\n\n const validated = specFromOptions(options);\n // Deprecation warnings to stderr (alias 사용 시), regardless of ok/fail.\n for (const w of validated.warnings) {\n err(c.yellow(`[WARN] ${w}`));\n }\n // v26.46.0 — Codex prompts default 화. cli=codex 시 자동. --with-codex-prompts 명시는 호환 유지.\n if (validated.ok && options.withCodexPrompts === true && !validated.cli.includes(\"codex\")) {\n err(\n c.yellow(\n \"[WARN] --with-codex-prompts requires --cli codex. Skipping (no Codex prompts will be installed).\",\n ),\n );\n }\n if (validated.ok && options.codexPrompts === false && !validated.cli.includes(\"codex\")) {\n err(\n c.yellow(\"[WARN] --no-codex-prompts has no effect without --cli codex (already excluded).\"),\n );\n }\n if (!validated.ok) {\n err(status.failure(c.red(`ERROR: ${validated.message}`)));\n exit(1);\n return;\n }\n\n // v26.47.0 — Phase C full: --with/--without repeatable → userOverride.\n const forceInclude = normalizeRepeatable(options.with);\n const forceExclude = normalizeRepeatable(options.without);\n // v26.49.0 — unknown asset id validation (silent ignore 방지).\n const validIds = new Set(EXTERNAL_ASSETS.map((a) => a.id));\n for (const id of [...forceInclude, ...forceExclude]) {\n if (!validIds.has(id)) {\n err(\n c.yellow(\n `[WARN] Unknown asset id '${id}' (--with/--without). Skipping. Use one of: ${[...validIds].sort().join(\", \")}`,\n ),\n );\n }\n }\n const filteredInclude = forceInclude.filter((id) => validIds.has(id));\n const filteredExclude = forceExclude.filter((id) => validIds.has(id));\n const userOverride =\n filteredInclude.length > 0 || filteredExclude.length > 0\n ? { forceInclude: filteredInclude, forceExclude: filteredExclude }\n : undefined;\n\n const spec: InstallSpec = {\n tracks: (options.track as Track[]) ?? [],\n ...(userOverride ? { userOverride } : {}),\n // v26.81.0 (ADR-022, BREAKING) — 자산 1:1 boolean 13종 삭제. 자산 선택은 위\n // userOverride(--with <id>)로 일원화. 잔존 = 설치 동작 옵션 6종만.\n options: {\n withPrune: options.withPrune === true,\n withCodexSkills: options.withCodexSkills === true,\n withCodexTrust: options.withCodexTrust === true,\n withKarpathyHook: options.withKarpathyHook === true,\n // v26.64.0 (ADR-020, BREAKING) — ADR-012/017 supersede. cli=codex 자동 default ON 폐기.\n // withCodexPrompts 는 사용자 명시 `--with-codex-prompts` 시에만 ON.\n // `--no-codex-prompts` 는 backward-compat noop (default 가 이미 false).\n // scope=global 일 때만 ~/.codex/prompts/ 에 실 write (installer.ts 참조).\n withCodexPrompts: options.withCodexPrompts === true && options.codexPrompts !== false,\n withAntigravityGlobal: options.withAntigravityGlobal === true,\n },\n cli: validated.cli,\n projectDir: resolve(options.projectDir ?? process.cwd()),\n scope: resolveScopeOption(options.scope, err),\n };\n\n executeSpec(spec, {\n log,\n err,\n exit,\n runPipeline,\n resolveHarnessRoot,\n verbose: options.verbose === true,\n });\n}\n\nexport interface ExecuteSpecDeps {\n log?: (msg: string) => void;\n err?: (msg: string) => void;\n exit?: (code: number) => never;\n runPipeline?: (\n spec: InstallSpec,\n harnessRoot: string,\n mode?: import(\"../installer.js\").InstallMode,\n callbacks?: PipelineCallbacks,\n ) => InstallReport;\n resolveHarnessRoot?: () => string;\n /** Router action mode (forwarded to runInstall). Default \"fresh\". */\n mode?: import(\"../installer.js\").InstallMode;\n /**\n * v26.63.0 — wizard 모드 (Step 1~4 통과 후 호출) 식별. true 시:\n * - install header (TARGET / TRACKS / CLI / OPTIONS / ASSETS) 출력 skip\n * (Step 3 review + Step 4 confirm 에서 이미 표시)\n * - \"Step 5/5 — Installing\" 흐름에 자연 연결\n */\n fromWizard?: boolean;\n /**\n * v26.63.0 — verbose 출력 (Phase 1 templates 의 files 라인 표시).\n * Default false — 카운트 + use 만 표시 (cognitive load 감소).\n */\n verbose?: boolean;\n}\n\n/**\n * Run the install pipeline for a fully-validated InstallSpec and render the\n * report. Shared by the `install` flag-mode command and the default\n * (interactive) action so both have identical post-install output.\n */\nexport function executeSpec(spec: InstallSpec, deps: ExecuteSpecDeps = {}): void {\n const log = deps.log ?? console.log;\n const err = deps.err ?? console.error;\n const exit = deps.exit ?? ((code: number) => process.exit(code) as never);\n const runPipeline = deps.runPipeline ?? defaultRunPipeline;\n const resolveHarnessRoot = deps.resolveHarnessRoot ?? defaultHarnessRoot;\n\n // v26.63.0 — wizard 모드는 header (TARGET ~ ASSETS) 출력 skip — Step 3/4 에서 이미 표시.\n // non-interactive (--track ...) 모드는 기존 header 유지 — 사용자 spec 확인 cue 필요.\n if (!deps.fromWizard) {\n renderInstallHeader(log, spec, deps.mode);\n }\n\n // v26.63.0 — phaseHeader → unifiedSection. Phase 카운터 (1/2/3) 제거 — 5-step 통합 시\n // wizard step 5/5 안 sub-section 으로 자연 흐름. Update mode 도 동일.\n log(unifiedSection(deps.mode === \"update\" ? \"Update Mode\" : \"Templates\"));\n log(\"\");\n\n // Streaming progress: baseline 완료 시 즉시 Phase 1 rows 출력, external은 per-asset 스트리밍.\n const renderer = createInstallRenderer(log, spec, deps.verbose === true);\n\n let report: InstallReport;\n try {\n report = runPipeline(spec, resolveHarnessRoot(), deps.mode, renderer.callbacks);\n } catch (e: unknown) {\n const detail = e instanceof Error ? e.message : String(e);\n log(\"\");\n err(status.failure(c.red(`install failed — ${detail}`)));\n exit(1);\n return;\n }\n\n // Update mode 단축 출력 — manifest copy / external 모두 skip\n if (report.updateMode) {\n renderUpdateSummary(log, report);\n return;\n }\n\n // Phase 2 trailing newline (if header was printed)\n if (renderer.phase2HeaderPrinted()) {\n log(\"\");\n }\n\n renderCliArtifacts(log, spec, report);\n renderFinalSummary(log, spec, report, deps.fromWizard === true);\n}\n\n/**\n * v26.64.0 (ADR-020) — `--scope` flag 해석. invalid 값은 warn + \"project\" default.\n * 비대화형 (--track 명시) 진입에서만 호출. wizard 는 별도 prompt.\n */\nfunction resolveScopeOption(value: string | undefined, err: (msg: string) => void): InstallScope {\n if (value === undefined) return \"project\";\n if (isInstallScope(value)) return value;\n err(\n c.yellow(`[WARN] Unknown --scope value '${value}' (expected: project, global). Using project.`),\n );\n return \"project\";\n}\n\n/**\n * v26.47.0 — Normalize cac repeatable flag (string | string[] | undefined) → string[].\n * Trim 빈 문자열 + dedup.\n */\nfunction normalizeRepeatable(value: string | string[] | undefined): string[] {\n if (!value) return [];\n const arr = Array.isArray(value) ? value : [value];\n return [...new Set(arr.map((s) => s.trim()).filter((s) => s.length > 0))];\n}\n\n/* v8 ignore start — thin dep-inject defaults. tests 는 항상 runPipeline / resolveHarnessRoot 주입. */\nfunction defaultRunPipeline(\n spec: InstallSpec,\n harnessRoot: string,\n mode?: import(\"../installer.js\").InstallMode,\n callbacks?: PipelineCallbacks,\n): InstallReport {\n const ctx: import(\"../installer.js\").InstallContext = {\n harnessRoot,\n projectDir: spec.projectDir,\n spec,\n };\n if (mode) ctx.mode = mode;\n if (callbacks?.onProgress) ctx.onProgress = callbacks.onProgress;\n if (callbacks?.externalDeps) ctx.externalDeps = callbacks.externalDeps;\n return runInstallPipeline(ctx);\n}\n\nfunction defaultHarnessRoot(): string {\n // The bundled CLI lives at <root>/dist/index.js. import.meta.url + ../ resolves to <root>.\n return resolve(new URL(\".\", import.meta.url).pathname, \"..\");\n}\n\n/* v8 ignore stop */\n\nexport { defaultHarnessRoot };\n\nexport function registerInstallCommand(cli: Cli): void {\n cli\n .command(\"install\", \"Install harness assets into a project\")\n // === Track / CLI / Project ===\n .option(\"--track <name>\", \"[Track] Track to install (repeatable)\", { type: [String] })\n .option(\n \"--cli <target>\",\n \"[CLI] Target CLI (repeatable): claude | codex | opencode | antigravity\",\n {\n type: [String],\n default: \"claude\",\n },\n )\n .option(\"--project-dir <path>\", \"[Project] Target project directory\", {\n default: process.cwd(),\n })\n .option(\"--scope <scope>\", \"[Scope] Installation scope: project (default) | global\", {\n default: \"project\",\n })\n // === Asset selection (Phase C full, v26.47.0+) ===\n .option(\n \"--with <asset-id>\",\n \"[Asset] Force-include External Asset id (regardless of preset). Repeatable. v26.47.0+\",\n )\n .option(\n \"--without <asset-id>\",\n \"[Asset] Force-exclude External Asset id (drop from preset recommendation). Repeatable. v26.47.0+\",\n )\n // === Codex global (v26.46.0+) ===\n .option(\n \"--with-codex-prompts\",\n \"[Codex] Unify Codex slash (~/.codex/prompts/uzys-*.md). Requires --cli codex. (v26.46.0+)\",\n )\n .option(\n \"--no-codex-prompts\",\n \"[Codex] Backward-compat noop — Codex slash is opt-in via --with-codex-prompts (v26.64.0 ADR-020)\",\n )\n .option(\n \"--with-codex-skills\",\n \"[Codex] Codex global opt-in: copy uzys-* skills to ~/.codex/skills/\",\n )\n .option(\n \"--with-codex-trust\",\n \"[Codex] Codex global opt-in: register trust entry in ~/.codex/config.toml\",\n )\n // v26.81.0 (ADR-022, BREAKING) — 자산 1:1 플래그 13종 삭제. 자산 opt-in 은 전부\n // generic `--with <asset-id>` (위) — 자산 id 목록은 docs/COMPATIBILITY.md 표 참조.\n // 아래는 자산이 아닌 설치 동작 옵션만.\n .option(\n \"--with-antigravity-global\",\n \"[Behavior] Antigravity global opt-in: copy uzys-* to ~/.gemini/antigravity/{skills,global_workflows}/. Requires --cli antigravity + --scope global. (v26.67.0+)\",\n )\n .option(\n \"--with-prune\",\n \"[Behavior] Prune ECC items beyond curated 89 (use with --with ecc-plugin)\",\n )\n .option(\n \"--with-karpathy-hook\",\n \"[Behavior] karpathy-coder pre-commit hook (.claude/settings.json PreToolUse Write|Edit)\",\n )\n // === Misc ===\n .option(\"--verbose\", \"[Misc] Show installed file lists per category (default: counts only)\")\n // === Examples (v26.50.0+) ===\n .example(\"install --track tooling --with uzys-harness\")\n .example(\"install --track csr-supabase --cli claude --cli codex\")\n .example(\"install --track csr-supabase --without netlify-cli --with railway-skills\")\n .example(\"install --track full --no-codex-prompts\")\n /* v8 ignore next — cac action callback. installAction 자체는 별도 tests 로 검증. */\n .action((options: InstallOptions) => installAction(options));\n}\n","/**\n * CLI targets parser — v0.7.0 multi-select.\n *\n * SPEC: docs/specs/cli-multi-select.md F2 (parseCliTargets).\n *\n * Input shapes:\n * - undefined / null / \"\" / [] → [\"claude\"] (default)\n * - \"claude\" / \"codex\" / \"opencode\" / \"antigravity\" → single-element array\n * - [\"claude\", \"codex\"] (cac repeatable) → sorted array\n * - \"both\" / \"all\" (v0.8.0 제거된 legacy alias) → ok=false + 마이그레이션 안내 (throw 아님)\n * - \"invalid\" → ok=false + error (throw 아님)\n *\n * Output:\n * - ok: 유효하면 true, reject 시 false (+ error 메시지, targets=[\"claude\"] default)\n * - targets: sorted ReadonlyArray<CliBase> (claude → codex → opencode → antigravity 순)\n * - warnings: 메시지 배열 (현재 reject-only 정책이라 비어 있음)\n */\n\nimport { CLI_BASES, type CliBase, type CliTargets, isCliBase } from \"./types.js\";\n\n/** SSOT — claude → codex → opencode → antigravity 정렬 순서. prompts.ts에서 import. */\nexport const CLI_BASE_SORT_ORDER: Record<CliBase, number> = {\n claude: 0,\n codex: 1,\n opencode: 2,\n antigravity: 3,\n};\n\nexport interface ParseCliTargetsResult {\n ok: boolean;\n targets: CliTargets;\n warnings: ReadonlyArray<string>;\n /** ok=false 시 reject 사유. */\n error?: string;\n}\n\n/**\n * `--cli` 입력을 sorted CliTargets로 정규화.\n *\n * Default `[\"claude\"]` (비어있거나 undefined일 때).\n * Invalid 모드는 reject (ok=false).\n *\n * v0.8.0 — `both`/`all` legacy alias 제거 (v0.7.0에서 1 release deprecation 거침).\n * `both`/`all` 입력 시 invalid reject + 마이그레이션 안내.\n */\nexport function parseCliTargets(input: string | string[] | undefined): ParseCliTargetsResult {\n const items = normalizeInput(input);\n if (items.length === 0) {\n return { ok: true, targets: [\"claude\"], warnings: [] };\n }\n\n const collected = new Set<CliBase>();\n const warnings: string[] = [];\n\n for (const item of items) {\n if (!isCliBase(item)) {\n // v0.8.0 — alias 제거 마이그레이션 힌트\n let hint = \"\";\n if (item === \"both\") {\n hint = \"\\n v0.8.0 removed 'both' alias. Use --cli claude --cli codex.\";\n } else if (item === \"all\") {\n hint =\n \"\\n v0.8.0 removed 'all' alias. Use --cli claude --cli codex --cli opencode.\";\n } else if (item.includes(\",\")) {\n // v0.7.1 — comma-separated input hint\n hint = \"\\n Tip: comma-separated not supported. Use --cli A --cli B for multiple.\";\n }\n return {\n ok: false,\n targets: [\"claude\"],\n warnings,\n error: `Invalid --cli value: ${item}. Must be one of: ${CLI_BASES.join(\" | \")}${hint}`,\n };\n }\n collected.add(item);\n }\n\n const targets = [...collected].sort((a, b) => CLI_BASE_SORT_ORDER[a] - CLI_BASE_SORT_ORDER[b]);\n return { ok: true, targets, warnings };\n}\n\nfunction normalizeInput(input: string | string[] | undefined): string[] {\n if (input === undefined || input === null) return [];\n if (typeof input === \"string\") {\n const trimmed = input.trim();\n return trimmed === \"\" ? [] : [trimmed];\n }\n return input.filter((s) => typeof s === \"string\" && s.trim() !== \"\").map((s) => s.trim());\n}\n\n/** Targets에 특정 base 포함 여부. has() 패턴. */\nexport function targetsInclude(targets: CliTargets, base: CliBase): boolean {\n return targets.includes(base);\n}\n","/** Available installation tracks. v0.5.0 — 11 Track (PM/Growth Marketing 추가). */\nexport const TRACKS = [\n \"tooling\",\n \"csr-supabase\",\n \"csr-fastify\",\n \"csr-fastapi\",\n \"ssr-htmx\",\n \"ssr-nextjs\",\n \"data\",\n \"executive\",\n \"full\",\n \"project-management\",\n \"growth-marketing\",\n] as const;\nexport type Track = (typeof TRACKS)[number];\n\nexport function isTrack(value: unknown): value is Track {\n return typeof value === \"string\" && (TRACKS as readonly string[]).includes(value);\n}\n\n/**\n * CLI target — multi-select base × combination (v0.8.0 — alias 제거).\n *\n * Base CLI: claude / codex / opencode / antigravity (4 base). 15 combinations possible (2^4 - 1, empty 제외).\n * Legacy `both` / `all` alias는 v0.7.0 deprecation 거쳐 v0.8.0에서 invalid input.\n * Migration: `--cli claude --cli codex` (repeatable) 또는 multiselect 인터랙티브.\n */\nexport const CLI_BASES = [\"claude\", \"codex\", \"opencode\", \"antigravity\"] as const;\nexport type CliBase = (typeof CLI_BASES)[number];\n\nexport function isCliBase(value: unknown): value is CliBase {\n return typeof value === \"string\" && (CLI_BASES as readonly string[]).includes(value);\n}\n\n/** Sorted readonly array of CliBase. install pipeline의 분기 input. */\nexport type CliTargets = ReadonlyArray<CliBase>;\n\n/**\n * v26.64.0 (ADR-020) — Installation scope.\n *\n * - \"project\" (default): claude plugin `--scope project`, npx skills (default), npm `--save-dev`,\n * codex/opencode → 프로젝트 dir (`.codex/`, `.opencode/`). 사용자 명시 동의 없이는 글로벌 미수정.\n * - \"global\" (opt-in): claude plugin `--scope user`, npx skills `-g`, npm `-g`,\n * codex/opencode → `~/.codex/`, `~/.opencode/`. 사용자가 interactive 또는 `--scope global` 로 명시.\n *\n * NORTH_STAR.md D16 본질 — 사용자 무인지 글로벌 write 금지.\n */\nexport const INSTALL_SCOPES = [\"project\", \"global\"] as const;\nexport type InstallScope = (typeof INSTALL_SCOPES)[number];\n\nexport function isInstallScope(value: unknown): value is InstallScope {\n return typeof value === \"string\" && (INSTALL_SCOPES as readonly string[]).includes(value);\n}\n\n/**\n * v26.64.0 (ADR-020) — `InstallSpec.scope` 가 optional 이므로 사용 시 default \"project\" 로 normalize.\n * 모든 분기 코드 (external-installer, codex/*, opencode/*) 는 이 함수로 scope 결정.\n */\nexport function resolveScope(scope: InstallScope | undefined): InstallScope {\n return scope ?? \"project\";\n}\n\n/**\n * Optional opt-in feature flags collected interactively.\n *\n * v26.81.0 (ADR-022, BREAKING) — 자산 1:1 boolean 13종(withGsd/withEcc/withTob/\n * withSuperpowers/withAddyAgentSkills/withWshobsonAgents/withOpenspec/withBmad/\n * withClaudeVideo/withUnderstandAnything/withAgentmemory + withTauri/withUzysHarness)\n * 완전 삭제. 자산 선택은 `userOverride.forceInclude`(wizard 체크 / `--with <id>`)로\n * 일원화 — 자산 추가 시 플래그 코드 0곳. 잔존 6종 = 자산이 아닌 **설치 동작 옵션**만.\n */\nexport interface OptionFlags {\n /** ecc-prune 실행 결합 — prune 은 ecc-plugin 선택을 전제 (installer.ts eccSelected 가 처리). */\n withPrune: boolean;\n /** Codex global opt-in: ~/.codex/skills/uzys-* 복사. D16 — 사용자 명시 동의 필수. */\n withCodexSkills: boolean;\n /** Codex global opt-in: ~/.codex/config.toml [projects.\"...\"] trust entry. D16 동일. */\n withCodexTrust: boolean;\n /**\n * v0.6.0 — karpathy-coder pre-commit hook auto-wire (A 경로).\n * `.claude/settings.json` PreToolUse `Write|Edit` matcher에 hook entry 등록.\n * 활성화는 karpathy-coder plugin install 성공 후 + 사용자 명시 opt-in 시에만.\n */\n withKarpathyHook: boolean;\n /**\n * v0.7.0 — Codex slash 통일 opt-in. `~/.codex/prompts/uzys-*.md` 글로벌 복사.\n * D16 보호 — 글로벌 영역 침범이라 opt-in 강제.\n */\n withCodexPrompts: boolean;\n /**\n * v26.67.0 — Antigravity global opt-in (~/.gemini/antigravity/skills/uzys-* +\n * ~/.gemini/antigravity/global_workflows/uzys-*.md). D16 영역 — `scope=global` +\n * `cli.includes(\"antigravity\")` 시에만 실 write. 사용자 명시 opt-in 필수.\n */\n withAntigravityGlobal: boolean;\n}\n\nexport const DEFAULT_OPTIONS: OptionFlags = {\n withPrune: false,\n withCodexSkills: false,\n withCodexTrust: false,\n withKarpathyHook: false,\n withCodexPrompts: false,\n withAntigravityGlobal: false,\n};\n\n/** Aggregate result of interactive flow — the spec the install pipeline consumes. */\nexport interface InstallSpec {\n tracks: Track[];\n options: OptionFlags;\n /** v0.7.0 — sorted readonly array of CliBase (이전: single CliMode). */\n cli: CliTargets;\n projectDir: string;\n /**\n * v26.64.0 (ADR-020) — Installation scope. Default \"project\" — 사용자 무인지 글로벌 write 방지.\n * Interactive prompt 또는 `--scope global` 명시 시에만 \"global\".\n * Optional + default \"project\" — 명시 안 한 사용처 (기존 tests / wizard non-scope-aware) 안전한 fallback.\n * 사용처는 `resolveScope(spec.scope)` 또는 `scope ?? \"project\"` 로 normalize.\n */\n scope?: InstallScope;\n /**\n * v26.47.0 — User-level override of preset/option condition (Phase C full).\n * `forceInclude`: condition 무관 강제 포함 / `forceExclude`: condition 무관 강제 제외.\n * 우선순위: forceExclude > forceInclude > condition.\n * Optional — 미제공 시 기존 condition 만 평가 (backward compat).\n */\n userOverride?: {\n forceInclude: ReadonlyArray<string>;\n forceExclude: ReadonlyArray<string>;\n };\n}\n","/**\n * design.ts — CLI visual design tokens (color, symbols, layout helpers).\n *\n * Aesthetic direction: **refined ops-report**. Mission control feel without\n * decoration noise. Phase markers + aligned 2-column rows + structured summary.\n *\n * Goals:\n * 1. Make input-wait points visually obvious (handled by @clack/prompts).\n * 2. Make the install pipeline output legible:\n * - phase-segmented progress (━━━ Phase N · Title ━━━)\n * - aligned per-asset rows (✓/⊘/✗ + id + meta)\n * - explicit skipped/failed reporting (no silent skips)\n * - terminal-width responsive (default 78)\n * 3. Zero runtime dependencies — emit raw ANSI escapes.\n *\n * `NO_COLOR` is honored per https://no-color.org.\n */\n\nconst isColorEnabled = (() => {\n if (process.env.NO_COLOR && process.env.NO_COLOR !== \"\") {\n return false;\n }\n // stdout may be missing in some test contexts\n return Boolean(process.stdout?.isTTY);\n})();\n\nfunction wrap(open: number, close: number) {\n return (s: string): string => {\n if (!isColorEnabled) {\n return s;\n }\n return `\\x1b[${open}m${s}\\x1b[${close}m`;\n };\n}\n\nexport const c = {\n bold: wrap(1, 22),\n dim: wrap(2, 22),\n red: wrap(31, 39),\n green: wrap(32, 39),\n yellow: wrap(33, 39),\n cyan: wrap(36, 39),\n gray: wrap(90, 39),\n};\n\nexport const symbol = {\n success: \"✓\",\n failure: \"✗\",\n skip: \"⊘\",\n arrow: \"›\",\n pointer: \"▸\",\n bullet: \"•\",\n warn: \"⚠\",\n /** Heavy horizontal box-drawing — phase dividers. */\n rule: \"━\",\n /** Middle dot — section separator. */\n mid: \"·\",\n};\n\n/** Default width for phase headers / dividers. Terminal default ≥ 78. */\nexport const DEFAULT_WIDTH = 78;\n\n/** Render a legacy section header. Bold cyan with a leading arrow. (kept for backward compat) */\nexport function header(title: string): string {\n return c.bold(c.cyan(`${symbol.arrow} ${title}`));\n}\n\n/**\n * Render a phase header — `━━━ Phase N · Title ━━━━━━━...` (full-width).\n * v26.63.0 (deprecated): kept for non-interactive mode + backward compat.\n * wizard 모드는 unifiedSection() 사용 (5-step 통합 — phase 카운터 무관).\n */\nexport function phaseHeader(n: number | string, title: string, width = DEFAULT_WIDTH): string {\n const label = `${symbol.rule}${symbol.rule}${symbol.rule} Phase ${n} ${symbol.mid} ${title} `;\n const fill = symbol.rule.repeat(Math.max(0, width - visibleLength(label)));\n return c.bold(c.cyan(`${label}${fill}`));\n}\n\n/**\n * v26.63.0 — Step 5 (Installing) 안의 sub-section 헤더.\n * `━━ Templates ━━` / `━━ External assets (n) ━━` / `━━ Codex artifacts ━━`.\n * phaseHeader (3 rule + Phase N + ·) 대비 단순 — 2 rule + title.\n */\nexport function unifiedSection(title: string, width = DEFAULT_WIDTH): string {\n const label = `${symbol.rule}${symbol.rule} ${title} `;\n const fill = symbol.rule.repeat(Math.max(0, width - visibleLength(label)));\n return c.bold(c.cyan(`${label}${fill}`));\n}\n\n/**\n * Render a section header (non-phase) — `━━━ Title ━━━━━━━...`.\n * Used for TARGET / SUMMARY / NEXT etc.\n */\nexport function sectionHeader(title: string, width = DEFAULT_WIDTH): string {\n const label = `${symbol.rule}${symbol.rule}${symbol.rule} ${title} `;\n const fill = symbol.rule.repeat(Math.max(0, width - visibleLength(label)));\n return c.bold(c.cyan(`${label}${fill}`));\n}\n\n/** Plain horizontal divider — `━━━...━━━` (no label). */\nexport function divider(width = DEFAULT_WIDTH): string {\n return c.dim(symbol.rule.repeat(width));\n}\n\n/**\n * Render a `key: value` row with a fixed-width left column for alignment.\n * Used in pre-flight / summary blocks (▸ TRACKS executive, tooling).\n */\nexport function infoRow(key: string, value: string, width = 12): string {\n const label = `${symbol.pointer} ${key}`.padEnd(width + 2, \" \");\n return ` ${c.dim(label)} ${value}`;\n}\n\n/** Backward-compat — `keyValue` (used by older install report). */\nexport function keyValue(key: string, value: string, width = 16): string {\n const padded = `${key}:`.padEnd(width, \" \");\n return ` ${c.dim(padded)} ${value}`;\n}\n\n/**\n * Render an asset row — ` ✓ asset-id meta`.\n * symbol = success/skip/failure. label = stable id (left-pad). meta = dim right column.\n */\nexport function assetRow(\n kind: \"success\" | \"skip\" | \"failure\",\n label: string,\n meta = \"\",\n labelWidth = 40,\n): string {\n const sym = renderSymbol(kind);\n const labelPadded = label.padEnd(labelWidth, \" \");\n const metaText = meta ? c.dim(meta) : \"\";\n return ` ${sym} ${labelPadded} ${metaText}`.trimEnd();\n}\n\nfunction renderSymbol(kind: \"success\" | \"skip\" | \"failure\"): string {\n switch (kind) {\n case \"success\":\n return c.green(symbol.success);\n case \"skip\":\n return c.yellow(symbol.skip);\n case \"failure\":\n return c.red(symbol.failure);\n }\n}\n\nexport const status = {\n success: (msg: string): string => `${c.green(symbol.success)} ${msg}`,\n failure: (msg: string): string => `${c.red(symbol.failure)} ${msg}`,\n warn: (msg: string): string => `${c.yellow(symbol.warn)} ${msg}`,\n info: (msg: string): string => `${c.cyan(symbol.bullet)} ${msg}`,\n};\n\n/**\n * Strip ANSI escape sequences so visible width can be measured (for header padding).\n */\nfunction visibleLength(s: string): number {\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape stripping requires \\x1b\n return s.replace(/\\x1b\\[[0-9;]*m/g, \"\").length;\n}\n\n/**\n * v26.63.2 — Pad to fixed display width (ANSI-aware). spacing scale 정렬 용.\n */\nexport function padDisplay(s: string, width: number): string {\n const visible = visibleLength(s);\n return visible >= width ? s : s + \" \".repeat(width - visible);\n}\n","import {\n chmodSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { type AntigravityOptInReport, runAntigravityOptIn } from \"./antigravity/opt-in.js\";\nimport {\n type AntigravityTransformReport,\n runAntigravityTransform,\n} from \"./antigravity/transform.js\";\nimport { type CodexOptInReport, runCodexOptIn } from \"./codex/opt-in.js\";\nimport { type CodexTransformReport, runCodexTransform } from \"./codex/transform.js\";\nimport {\n addGitignoreEnv,\n addGitignoreNpxSkillsAgents,\n writeEnvExample,\n writeMcpAllowlist,\n} from \"./env-files.js\";\nimport { EXTERNAL_ASSETS, filterApplicableAssets, isAssetSelected } from \"./external-assets.js\";\nimport {\n type ExternalInstallerDeps,\n type ExternalInstallReport,\n runExternalInstall,\n} from \"./external-installer.js\";\nimport {\n backupDir,\n backupFileIfChanged,\n copyBackupDir,\n copyDir,\n copyFile,\n ensureProjectSkeleton,\n} from \"./fs-ops.js\";\nimport { buildInstallLog, hashContent, writeInstallLog } from \"./install-log.js\";\nimport { type AssetSpec, buildManifest } from \"./manifest.js\";\nimport { composeMcpJson, writeMcpJson } from \"./mcp-merge.js\";\nimport { type OpencodeTransformReport, runOpencodeTransform } from \"./opencode/transform.js\";\nimport { mergeProjectClaude } from \"./project-claude-merge.js\";\nimport { addPreToolUseHook, type ClaudeSettings } from \"./settings-merge.js\";\nimport { type InstallSpec, type OptionFlags, resolveScope, type Track } from \"./types.js\";\nimport { runUpdateMode, type UpdateModeReport } from \"./update-mode.js\";\n\n/** karpathy-coder hook command — `.claude/settings.json` PreToolUse Write|Edit matcher entry. */\nconst KARPATHY_HOOK_COMMAND = 'bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/karpathy-gate.sh\"';\n\n/**\n * Install mode — Router action 매핑.\n * - \"fresh\" : 첫 설치 (기본값)\n * - \"add\" : 기존 위에 Track union 추가 (backup 없음)\n * - \"update\" : 정책 파일만 templates로 갱신 (backup + orphan prune + stale hook)\n * - \"reinstall\" : 기존 .claude/ backup 후 처음부터 (backup 강제)\n */\nexport type InstallMode = \"fresh\" | \"add\" | \"update\" | \"reinstall\";\n\nexport interface InstallContext {\n /** Path to the harness repo (where `templates/` lives). */\n harnessRoot: string;\n /** Target project directory. */\n projectDir: string;\n spec: InstallSpec;\n /**\n * Router action mode. Defaults to \"fresh\".\n * - \"add\"/\"update\"/\"reinstall\" trigger different install paths.\n * - reinstall + update force backup=true.\n */\n mode?: InstallMode;\n /**\n * When true, an existing .claude/ is renamed to a timestamped backup before install.\n * Auto-true when mode ∈ {update, reinstall}.\n */\n backup?: boolean;\n /**\n * External install (claude plugin / npm -g / npx skills) injection point.\n * Default: real `runExternalInstall`. Tests inject mock to avoid real spawn.\n * Pass `null` to disable external install entirely.\n */\n runExternal?:\n | ((\n // v26.77.0 — projectDir: 외부 설치기 spawn cwd (자산 착지 위치). Bug B fix.\n // v26.81.0 (ADR-022) — userOverride: 자산 opt-in(--with <id>) 전파 (flag 13종 대체).\n ctx: {\n tracks: ReadonlyArray<Track>;\n options: OptionFlags;\n projectDir?: string;\n userOverride?: {\n forceInclude: ReadonlyArray<string>;\n forceExclude: ReadonlyArray<string>;\n };\n },\n deps: ExternalInstallerDeps,\n ) => ExternalInstallReport)\n | null;\n /**\n * Progress callback fired between stages so renderers can stream output\n * (avoids \"Phase 1 header → 5 minutes silence\" UX problem).\n */\n onProgress?: (event: ProgressEvent) => void;\n /** External installer streaming hooks (forwarded to runExternalInstall). */\n externalDeps?: Pick<ExternalInstallerDeps, \"onAssetStart\" | \"onAssetResult\">;\n}\n\n/** Progress event types fired during runInstall. */\nexport type ProgressEvent =\n /** Baseline (manifest copy + mcp + envFiles + Codex/OpenCode transforms) finished. External not yet started. */\n | { type: \"baseline-complete\"; baseline: BaselineReport }\n /** External install phase about to begin. */\n | { type: \"external-start\"; assetCount: number }\n /** External install phase finished (with report). */\n | { type: \"external-complete\"; report: ExternalInstallReport }\n /** v26.64.0 — install log write 실패 (non-fatal). */\n | { type: \"install-log-error\"; message: string };\n\n/** karpathy-coder hook auto-wire 결과 (v0.6.0). */\nexport interface KarpathyHookReport {\n /** withKarpathyHook=true && karpathy-coder install 성공 시 true. */\n wired: boolean;\n /** wired=false 시 사유. */\n reason?:\n | \"opt-out\"\n | \"plugin-install-failed\"\n | \"external-skipped\"\n | \"settings-parse-error\"\n | \"claude-not-selected\";\n /** wired=true 시 settings.json 갱신 여부 (idempotent skip 시 false). */\n settingsUpdated?: boolean;\n /** wired=true 시 hook script 복사 여부. */\n hookScriptCopied?: boolean;\n}\n\n/** karpathy-coder asset ID — SSOT (external-assets.ts entry id와 일치 강제). */\nconst KARPATHY_ASSET_ID = \"karpathy-coder\";\n\n/**\n * v0.6.1 — Phase 1 output 카테고리별 분류. install renderer가 각 카테고리별로 row를 출력한다.\n * Names는 description용 (display only); 빈 배열이면 row 출력 skip.\n */\nexport interface BaselineCategoryCounts {\n /** rule 파일 names (확장자 제외) — git-policy, change-management 등 */\n rules: string[];\n /** agent 파일 names */\n agents: string[];\n /** hook 파일 names (확장자 제외) */\n hooks: string[];\n /** commands 디렉토리 카운트 (uzys + ecc) — names는 디렉토리라 무의미 */\n commands: number;\n /** skill 디렉토리 names */\n skills: string[];\n}\n\n/** Baseline phase result (everything except external assets). */\nexport interface BaselineReport {\n filesCopied: number;\n dirsCopied: number;\n skipped: number;\n backup: string | null;\n installedTracks: string[];\n mcpServers: string[];\n codex: CodexTransformReport | null;\n codexOptIn: CodexOptInReport | null;\n opencode: OpencodeTransformReport | null;\n /** v26.66.0 — Present when spec.cli includes \"antigravity\". */\n antigravity: AntigravityTransformReport | null;\n /** v26.67.0 — Present when antigravity global opt-in fired (scope=global + withAntigravityGlobal). */\n antigravityOptIn: AntigravityOptInReport | null;\n updateMode: UpdateModeReport | null;\n mode: InstallMode;\n envFiles: {\n envExampleCreated: boolean;\n gitignoreEnvAdded: boolean;\n mcpAllowlist: string[] | null;\n /** v0.8.0 — `.gitignore`에 추가된 npx skills agent 디렉토리 패턴 (`.factory/`, `.goose/`). */\n gitignoreNpxSkillsAdded: string[];\n };\n /** v0.6.1 — Phase 1 카테고리별 카운트 + names. Update mode에서는 빈 객체. */\n categories?: BaselineCategoryCounts;\n /** Root CLAUDE.md merged from project-claude fragments. null when claude baseline disabled. */\n rootClaudeMd: { tracks: ReadonlyArray<Track> } | null;\n /** 덮어쓰기 전 보존한 사용자 파일 백업 경로 (settings.json·CLAUDE.md, fresh/add 모드). audit SEC-1/CODE-2. */\n backups?: string[];\n}\n\nexport interface InstallReport {\n filesCopied: number;\n dirsCopied: number;\n skipped: number;\n backup: string | null;\n installedTracks: string[];\n mcpServers: string[];\n /** Present when spec.cli includes \"codex\". */\n codex: CodexTransformReport | null;\n /** Present when Codex transform ran AND user opted-in to global skills/trust/prompts. null otherwise. */\n codexOptIn: CodexOptInReport | null;\n /** Present when spec.cli includes \"opencode\". */\n opencode: OpencodeTransformReport | null;\n /** v26.66.0 — Present when spec.cli includes \"antigravity\". */\n antigravity: AntigravityTransformReport | null;\n /** v26.67.0 — Present when antigravity global opt-in fired. null otherwise. */\n antigravityOptIn: AntigravityOptInReport | null;\n /** External install report (claude plugin / npm -g / npx skills). null when disabled or empty. */\n external: ExternalInstallReport | null;\n /** Update-mode report (rules/agents/commands/hooks 갱신 + orphan prune + stale hook). null when not update mode. */\n updateMode: UpdateModeReport | null;\n /** karpathy-coder hook auto-wire 결과 (v0.6.0). null when withKarpathyHook=false. */\n karpathyHook: KarpathyHookReport | null;\n /** Install mode dispatched (echo of ctx.mode, default \"fresh\"). */\n mode: InstallMode;\n /** Environment file generation results (always present). */\n envFiles: {\n /** true if .env.example was created (csr-supabase/full only). */\n envExampleCreated: boolean;\n /** true if .gitignore got `.env` line appended. */\n gitignoreEnvAdded: boolean;\n /** Server names written to .mcp-allowlist; null if skipped. */\n mcpAllowlist: string[] | null;\n /** v0.8.0 — `.gitignore`에 추가된 npx skills agent 디렉토리 패턴 (`.factory/`, `.goose/`). */\n gitignoreNpxSkillsAdded: string[];\n };\n}\n\n/**\n * Run the installation pipeline. Pure function modulo filesystem side effects.\n * v26.82.0 (Phase R) — 276줄 단일 함수를 단계별 블록 함수로 분해 (동작 변경 0):\n * update 단축 / claude baseline / CLI transforms / external / install log.\n */\nexport function runInstall(ctx: InstallContext): InstallReport {\n const { harnessRoot, projectDir, spec } = ctx;\n const mode: InstallMode = ctx.mode ?? \"fresh\";\n const templatesDir = join(harnessRoot, \"templates\");\n\n if (!existsSync(templatesDir)) {\n throw new Error(`Templates dir not found: ${templatesDir}`);\n }\n\n const claudeDir = join(projectDir, \".claude\");\n\n // Update mode pre-flight: existing .claude/ 필수. backup 전에 검증.\n if (mode === \"update\" && !existsSync(claudeDir)) {\n throw new Error(`Update mode requires existing .claude/ at ${claudeDir}`);\n }\n\n const backupPath = resolveBackupPath(ctx, mode, claudeDir);\n\n // Update mode 단축 — 정책 파일만 갱신하고 종료 (manifest copy / external 모두 skip)\n if (mode === \"update\") {\n return runUpdateInstall(ctx, templatesDir, backupPath);\n }\n\n const manifestSpec = buildManifestSpec(spec);\n\n // v0.8.0 — `.claude/` baseline은 spec.cli에 \"claude\" 포함 시에만 생성.\n // Codex/OpenCode 단독 사용자는 dead weight 회피.\n const base = spec.cli.includes(\"claude\")\n ? installClaudeBaseline(manifestSpec, harnessRoot, projectDir, templatesDir)\n : emptyClaudeBaseline();\n\n // Compose .mcp.json from template + track-mcp-map.tsv (Codex/OpenCode도 사용 — claude 무관)\n const mcpResult = composeAndWriteMcp(harnessRoot, projectDir, spec);\n\n const baseline: BaselineReport = {\n filesCopied: base.filesCopied,\n dirsCopied: base.dirsCopied,\n skipped: base.skipped,\n backup: backupPath,\n installedTracks: [...spec.tracks].sort(),\n mcpServers: Object.keys(mcpResult.mcpServers).sort(),\n ...runCliTransforms(spec, harnessRoot, projectDir, manifestSpec.withUzysHarness),\n updateMode: null,\n mode,\n envFiles: writeEnvironmentFiles(projectDir, spec.tracks),\n categories: base.categories,\n rootClaudeMd: base.rootClaudeMd,\n backups: base.backups,\n };\n\n // ━━━ Baseline complete — emit progress event so renderer can show Phase 1 rows ━━━\n ctx.onProgress?.({ type: \"baseline-complete\", baseline });\n\n // ━━━ External assets (claude plugin / npm -g / npx skills) ━━━\n const external = runExternalPhase(ctx);\n\n // ━━━ karpathy-coder hook auto-wire (v0.6.0) ━━━\n // SPEC: docs/specs/karpathy-hook-autowire.md AC2 — opt-in 강제 + install 성공 후에만.\n // v0.8.0 — `.claude/settings.json` PreToolUse 의존이라 spec.cli에 \"claude\" 포함 시에만 와이어 가능.\n const karpathyHook = wireKarpathyHook(spec, external, harnessRoot, projectDir);\n\n // ━━━ v26.64.0 (ADR-020) — Install log write ━━━\n writeInstallLogSafe(ctx, external, base.rootClaudeMdLog);\n\n return { ...baseline, external, karpathyHook };\n}\n\n/**\n * Backup auto-on for update + reinstall (sourced from router action).\n * Update: copy backup (preserve original .claude/ for in-place update).\n * Reinstall + others: rename backup (move .claude/ aside, then full install).\n */\nfunction resolveBackupPath(\n ctx: InstallContext,\n mode: InstallMode,\n claudeDir: string,\n): string | null {\n const wantBackup = ctx.backup ?? (mode === \"update\" || mode === \"reinstall\");\n if (!wantBackup) return null;\n return mode === \"update\" ? copyBackupDir(claudeDir) : backupDir(claudeDir);\n}\n\n/** Update mode 단축 경로 — 정책 파일만 갱신 (manifest copy / external 모두 skip). */\nfunction runUpdateInstall(\n ctx: InstallContext,\n templatesDir: string,\n backupPath: string | null,\n): InstallReport {\n const updateReport = runUpdateMode(ctx.projectDir, templatesDir);\n const baseline: BaselineReport = {\n filesCopied: 0,\n dirsCopied: 0,\n skipped: 0,\n backup: backupPath,\n installedTracks: [...ctx.spec.tracks].sort(),\n mcpServers: [],\n codex: null,\n codexOptIn: null,\n opencode: null,\n antigravity: null,\n antigravityOptIn: null,\n updateMode: updateReport,\n mode: \"update\",\n envFiles: {\n envExampleCreated: false,\n gitignoreEnvAdded: false,\n mcpAllowlist: null,\n gitignoreNpxSkillsAdded: [],\n },\n rootClaudeMd: null,\n };\n ctx.onProgress?.({ type: \"baseline-complete\", baseline });\n return { ...baseline, external: null, karpathyHook: null };\n}\n\n/**\n * v26.81.0 (ADR-022) — manifest 게이팅 입력. 내부 자산 선택 판정 — 이전\n * OptionFlags.withTauri/withUzysHarness/withEcc boolean 자리를 카탈로그 선택\n * (wizard 체크 / --with <id> → forceInclude)으로 대체 (manifest 필드명은 유지).\n */\nfunction buildManifestSpec(spec: InstallSpec): Required<AssetSpec> {\n const selectionCtx = {\n tracks: spec.tracks,\n options: spec.options,\n ...(spec.userOverride ? { userOverride: spec.userOverride } : {}),\n };\n return {\n tracks: spec.tracks,\n withTauri: isAssetSelected(\"tauri-desktop\", selectionCtx),\n withUzysHarness: isAssetSelected(\"uzys-harness\", selectionCtx),\n // v26.55.0 — withEcc gating (ADR-016). ECC cherry-pick (agents/skills/commands) 항목 토글.\n // withPrune 은 ecc-plugin 사용을 전제 (이전 applyOptionRules `withEcc ||= withPrune` 의미 보존).\n withEcc: isAssetSelected(\"ecc-plugin\", selectionCtx) || spec.options.withPrune,\n };\n}\n\n/** `.claude/` baseline (manifest copy) 결과. claude 미선택 시 emptyClaudeBaseline(). */\ninterface ClaudeBaselineResult {\n filesCopied: number;\n dirsCopied: number;\n skipped: number;\n categories: BaselineCategoryCounts;\n rootClaudeMd: { tracks: ReadonlyArray<Track> } | null;\n /** root CLAUDE.md 무결성 기록 — uninstall 시 사용자 수정 여부 판별 (install 원본과 sha 비교). */\n rootClaudeMdLog: { path: string; sha256: string } | null;\n /** 덮어쓰기 전 보존한 사용자 파일 백업 경로 (settings.json·CLAUDE.md). audit SEC-1/CODE-2. */\n backups: string[];\n}\n\nfunction emptyClaudeBaseline(): ClaudeBaselineResult {\n return {\n filesCopied: 0,\n dirsCopied: 0,\n skipped: 0,\n categories: { rules: [], agents: [], hooks: [], commands: 0, skills: [] },\n rootClaudeMd: null,\n rootClaudeMdLog: null,\n backups: [],\n };\n}\n\n/** `.claude/` baseline — manifest copy + hook chmod + .installed-tracks + root CLAUDE.md merge. */\nfunction installClaudeBaseline(\n manifestSpec: Required<AssetSpec>,\n harnessRoot: string,\n projectDir: string,\n templatesDir: string,\n): ClaudeBaselineResult {\n ensureProjectSkeleton(projectDir);\n\n const result = emptyClaudeBaseline();\n const manifest = buildManifest(manifestSpec);\n\n for (const entry of manifest) {\n if (!entry.applies(manifestSpec)) {\n continue;\n }\n const source = join(templatesDir, entry.source);\n const target = join(projectDir, entry.target);\n if (!existsSync(source)) {\n result.skipped += 1;\n continue;\n }\n if (entry.type === \"file\") {\n // 사용자 편집 가능 파일은 덮어쓰기 전 백업 (audit SEC-1 — settings.json hook/statusLine 소실 방지).\n if (entry.target === \".claude/settings.json\") {\n const backup = backupFileIfChanged(target, readFileSync(source, \"utf-8\"));\n if (backup) {\n result.backups.push(backup);\n }\n }\n copyFile(source, target);\n result.filesCopied += 1;\n } else {\n copyDir(source, target);\n result.dirsCopied += 1;\n }\n accumulateCategory(result.categories, entry);\n }\n\n // chmod +x on hook scripts (cp does not preserve exec bit when source is non-exec)\n const hookDir = join(projectDir, \".claude/hooks\");\n if (existsSync(hookDir)) {\n chmodHooksSync(hookDir);\n }\n\n // Write metadata file used by detect_install_state on next run (.claude/.installed-tracks)\n writeInstalledTracks(projectDir, manifestSpec.tracks);\n\n // Project root CLAUDE.md — merge from fragments (single/multi/full).\n // Note: overwrites any user customization on re-install. Documented behavior.\n const rootClaudeMd = writeRootClaudeMd(harnessRoot, projectDir, manifestSpec.tracks);\n result.rootClaudeMd = { tracks: manifestSpec.tracks };\n result.rootClaudeMdLog = { path: \"CLAUDE.md\", sha256: hashContent(rootClaudeMd.content) };\n if (rootClaudeMd.backup) {\n result.backups.push(rootClaudeMd.backup);\n }\n return result;\n}\n\n/** Environment files (F7/F8 — bash setup-harness.sh L880~890 + L954~996 등가). */\nfunction writeEnvironmentFiles(\n projectDir: string,\n tracks: ReadonlyArray<Track>,\n): BaselineReport[\"envFiles\"] {\n return {\n envExampleCreated: writeEnvExample(projectDir, tracks),\n gitignoreEnvAdded: addGitignoreEnv(projectDir),\n mcpAllowlist: writeMcpAllowlist(projectDir),\n // v0.8.0 — `.factory/`, `.goose/` ignore (npx skills universal install 사용자 #3)\n gitignoreNpxSkillsAdded: addGitignoreNpxSkillsAgents(projectDir),\n };\n}\n\n/** Codex / OpenCode / Antigravity per-CLI transforms (+ scope=global opt-in) 결과. */\ninterface CliTransformResults {\n codex: CodexTransformReport | null;\n codexOptIn: CodexOptInReport | null;\n opencode: OpencodeTransformReport | null;\n antigravity: AntigravityTransformReport | null;\n antigravityOptIn: AntigravityOptInReport | null;\n}\n\nfunction runCliTransforms(\n spec: InstallSpec,\n harnessRoot: string,\n projectDir: string,\n uzysHarnessSelected: boolean,\n): CliTransformResults {\n // Codex transform when spec.cli includes \"codex\"\n let codex: CodexTransformReport | null = null;\n let codexOptIn: CodexOptInReport | null = null;\n if (spec.cli.includes(\"codex\")) {\n // v26.57.0 (ADR-018) — withUzysHarness gating 을 codex transform 에도 전달.\n // .agents/skills/uzys-* + .codex/prompts/uzys-* 도 uzys-harness 없으면 생성 안 함.\n codex = runCodexTransform({\n harnessRoot,\n projectDir,\n withUzysHarness: uzysHarnessSelected,\n });\n // v26.64.0 (ADR-020) — Codex global opt-in 은 scope=global 일 때만 의미.\n // scope=project (default) 시 ~/.codex/ write skip — transform.ts 가 이미 `.codex/` (project)\n // 에 write 함. withCodex* 옵션은 scope=global 시에만 ~/.codex/ 로 추가 복사.\n const installScope = spec.scope ?? \"project\";\n if (\n installScope === \"global\" &&\n (spec.options.withCodexSkills || spec.options.withCodexTrust || spec.options.withCodexPrompts)\n ) {\n codexOptIn = runCodexOptIn({\n projectDir,\n harnessRoot,\n withCodexSkills: spec.options.withCodexSkills,\n withCodexTrust: spec.options.withCodexTrust,\n withCodexPrompts: spec.options.withCodexPrompts,\n });\n }\n }\n\n // OpenCode transform when spec.cli includes \"opencode\"\n let opencode: OpencodeTransformReport | null = null;\n if (spec.cli.includes(\"opencode\")) {\n opencode = runOpencodeTransform({ harnessRoot, projectDir });\n }\n\n // v26.66.0 — Antigravity transform when spec.cli includes \"antigravity\".\n // `.agents/skills/` (codex 와 공유) + `.agents/workflows/` (신규). withUzysHarness 시만.\n let antigravity: AntigravityTransformReport | null = null;\n let antigravityOptIn: AntigravityOptInReport | null = null;\n if (spec.cli.includes(\"antigravity\")) {\n antigravity = runAntigravityTransform({\n harnessRoot,\n projectDir,\n withUzysHarness: uzysHarnessSelected,\n });\n // v26.67.0 (Phase C) — Antigravity global opt-in. ADR-020 정합 —\n // scope=global + withAntigravityGlobal=true 시에만 ~/.gemini/ 영역 write.\n const installScope = spec.scope ?? \"project\";\n if (installScope === \"global\" && spec.options.withAntigravityGlobal) {\n antigravityOptIn = runAntigravityOptIn({\n projectDir,\n harnessRoot,\n enabled: true,\n });\n }\n }\n\n return { codex, codexOptIn, opencode, antigravity, antigravityOptIn };\n}\n\n/**\n * External assets (claude plugin / npm -g / npx skills) 설치 단계.\n * Default = real runExternalInstall. Tests inject mock or `null` to skip.\n * log/warn은 silent (renderer가 onAssetStart/Result로 스트리밍).\n */\nfunction runExternalPhase(ctx: InstallContext): ExternalInstallReport | null {\n if (ctx.runExternal === null) {\n return null;\n }\n const { harnessRoot, projectDir, spec } = ctx;\n const runExt = ctx.runExternal ?? runExternalInstall;\n const externalDeps: ExternalInstallerDeps = {\n harnessRoot,\n log: () => {},\n warn: () => {},\n };\n if (ctx.externalDeps?.onAssetStart) {\n externalDeps.onAssetStart = ctx.externalDeps.onAssetStart;\n }\n if (ctx.externalDeps?.onAssetResult) {\n externalDeps.onAssetResult = ctx.externalDeps.onAssetResult;\n }\n const filterCtx = {\n tracks: spec.tracks,\n options: spec.options,\n ...(spec.userOverride ? { userOverride: spec.userOverride } : {}),\n };\n const applicableCount = filterApplicableAssets(EXTERNAL_ASSETS, filterCtx).length;\n ctx.onProgress?.({ type: \"external-start\", assetCount: applicableCount });\n const external = runExt(\n { ...filterCtx, cli: spec.cli, projectDir, ...(spec.scope ? { scope: spec.scope } : {}) },\n externalDeps,\n );\n ctx.onProgress?.({ type: \"external-complete\", report: external });\n return external;\n}\n\n/**\n * Install log write — `.claude/.harness-install.json` (자산 list + scope + timestamp,\n * uninstall command 의 source). 실패는 install 자체를 fail 시키지 않음 (D16 — install 성공 우선).\n */\nfunction writeInstallLogSafe(\n ctx: InstallContext,\n external: ExternalInstallReport | null,\n rootClaudeMdLog: { path: string; sha256: string } | null,\n): void {\n try {\n const log = buildInstallLog(ctx.spec, external, resolveScope(ctx.spec.scope), rootClaudeMdLog);\n writeInstallLog(ctx.projectDir, log);\n } catch (e) {\n ctx.onProgress?.({\n type: \"install-log-error\",\n message: e instanceof Error ? e.message : String(e),\n });\n }\n}\n\n/**\n * karpathy-coder pre-commit hook auto-wire (v0.6.0).\n *\n * 활성화 조건 (AND):\n * 1. spec.options.withKarpathyHook === true (opt-in 강제)\n * 2. spec.cli 에 \"claude\" 포함 (v0.8.0 — `.claude/settings.json` 미생성 시 와이어 불가)\n * 3. external.attempted에 karpathy-coder ok=true (plugin install 성공)\n *\n * 동작:\n * - templates/hooks/karpathy-gate.sh → <projectDir>/.claude/hooks/karpathy-gate.sh 복사\n * - .claude/settings.json PreToolUse Write|Edit matcher에 hook entry 추가 (idempotent)\n */\nfunction wireKarpathyHook(\n spec: InstallSpec,\n external: ExternalInstallReport | null,\n harnessRoot: string,\n projectDir: string,\n): KarpathyHookReport | null {\n if (!spec.options.withKarpathyHook) {\n return null;\n }\n // v0.8.0 가드 — `.claude/` baseline 미생성 시 hook 와이어 불가 (silent partial state 방지).\n if (!spec.cli.includes(\"claude\")) {\n return { wired: false, reason: \"claude-not-selected\" };\n }\n if (external === null) {\n return { wired: false, reason: \"external-skipped\" };\n }\n const karpathyResult = external.attempted.find((r) => r.asset.id === KARPATHY_ASSET_ID);\n if (!karpathyResult?.ok) {\n return { wired: false, reason: \"plugin-install-failed\" };\n }\n\n // Hook script 복사 (manifest에 없는 v0.6.0 신규 — opt-in 시에만)\n const sourceHook = join(harnessRoot, \"templates/hooks/karpathy-gate.sh\");\n const targetHook = join(projectDir, \".claude/hooks/karpathy-gate.sh\");\n let hookScriptCopied = false;\n if (existsSync(sourceHook)) {\n copyFile(sourceHook, targetHook);\n try {\n chmodSync(targetHook, 0o755);\n } catch {\n // best-effort\n }\n hookScriptCopied = true;\n }\n\n // settings.json PreToolUse Write|Edit entry 추가 (idempotent)\n // HIGH-2 fix: JSON.parse try/catch — add mode에서 사용자 손상 settings.json 시 install 중단 방지\n const settingsPath = join(projectDir, \".claude/settings.json\");\n let settingsUpdated = false;\n if (existsSync(settingsPath)) {\n const raw = readFileSync(settingsPath, \"utf8\");\n let before: ClaudeSettings;\n try {\n before = JSON.parse(raw);\n } catch {\n return { wired: false, reason: \"settings-parse-error\", hookScriptCopied };\n }\n const after = addPreToolUseHook(before, \"Write|Edit\", KARPATHY_HOOK_COMMAND);\n const beforeStr = JSON.stringify(before);\n const afterStr = JSON.stringify(after);\n if (beforeStr !== afterStr) {\n writeFileSync(settingsPath, `${JSON.stringify(after, null, 2)}\\n`);\n settingsUpdated = true;\n }\n }\n\n return { wired: true, settingsUpdated, hookScriptCopied };\n}\n\nfunction composeAndWriteMcp(\n harnessRoot: string,\n projectDir: string,\n spec: InstallSpec,\n): { mcpServers: Record<string, unknown> } {\n const mcpPath = join(projectDir, \".mcp.json\");\n const composed = composeMcpJson({\n templateMcpPath: join(harnessRoot, \"templates/mcp.json\"),\n trackMapPath: join(harnessRoot, \"templates/track-mcp-map.tsv\"),\n existingPath: mcpPath,\n tracks: spec.tracks,\n });\n writeMcpJson(mcpPath, composed);\n return composed;\n}\n\n/**\n * v0.6.1 — manifest entry를 카테고리별로 누적. install renderer Phase 1 row 출력에 사용.\n * `entry.target` prefix로 분류. file은 basename(.확장자 제거), dir은 dir name.\n */\nfunction accumulateCategory(\n cats: BaselineCategoryCounts,\n entry: import(\"./manifest.js\").AssetEntry,\n): void {\n const target = entry.target;\n if (target.startsWith(\".claude/rules/\") && target.endsWith(\".md\")) {\n const name = target.replace(/^\\.claude\\/rules\\//, \"\").replace(/\\.md$/, \"\");\n cats.rules.push(name);\n } else if (target.startsWith(\".claude/agents/\") && target.endsWith(\".md\")) {\n const name = target.replace(/^\\.claude\\/agents\\//, \"\").replace(/\\.md$/, \"\");\n cats.agents.push(name);\n } else if (target.startsWith(\".claude/hooks/\") && target.endsWith(\".sh\")) {\n const name = target.replace(/^\\.claude\\/hooks\\//, \"\").replace(/\\.sh$/, \"\");\n cats.hooks.push(name);\n } else if (target.startsWith(\".claude/commands/\")) {\n cats.commands += 1;\n } else if (target.startsWith(\".claude/skills/\") && entry.type === \"dir\") {\n const name = target.replace(/^\\.claude\\/skills\\//, \"\").replace(/\\/?$/, \"\");\n cats.skills.push(name);\n }\n}\n\nfunction writeInstalledTracks(projectDir: string, tracks: ReadonlyArray<string>): void {\n const path = join(projectDir, \".claude/.installed-tracks\");\n mkdirSync(dirname(path), { recursive: true });\n const sorted = [...new Set(tracks)].sort().join(\"\\n\");\n writeFileSync(path, `${sorted}\\n`);\n}\n\nfunction writeRootClaudeMd(\n harnessRoot: string,\n projectDir: string,\n tracks: ReadonlyArray<Track>,\n): { content: string; backup: string | null } {\n const baseDir = join(harnessRoot, \"templates/project-claude\");\n const content = mergeProjectClaude(tracks, { baseDir });\n const target = join(projectDir, \"CLAUDE.md\");\n // 기존 사용자 CLAUDE.md 는 덮어쓰기 전 백업 (audit CODE-2 — 무백업 덮어쓰기 데이터 손실 방지).\n const backup = backupFileIfChanged(target, content);\n writeFileSync(target, content);\n return { content, backup };\n}\n\nfunction chmodHooksSync(hookDir: string): void {\n for (const file of listHookFiles(hookDir)) {\n try {\n chmodSync(file, 0o755);\n } catch {\n // Best-effort; many platforms (Windows in particular) ignore mode bits.\n }\n }\n}\n\nfunction listHookFiles(hookDir: string): string[] {\n // Hooks are flat shell scripts — avoid pulling glob deps.\n return readdirSync(hookDir, { withFileTypes: true })\n .filter((e) => e.isFile() && e.name.endsWith(\".sh\"))\n .map((e) => resolve(hookDir, e.name));\n}\n","/**\n * Antigravity global opt-in — v26.67.0 (Phase C).\n *\n * `~/.gemini/antigravity/skills/uzys-{phase}/` + `~/.gemini/antigravity/global_workflows/uzys-{phase}.md`\n * 복사. D16 영역 — `scope=global` + `cli.includes(\"antigravity\")` + `withAntigravityGlobal=true`\n * 세 조건 모두 충족 시에만 호출.\n *\n * Codex `runCodexOptIn` 패턴 미러 (D16 동일 보호).\n */\n\nimport { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { renameSlashes } from \"../codex/agents-md.js\";\n\nconst PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"];\n\nexport interface AntigravityOptInReport {\n /** `~/.gemini/antigravity/skills/uzys-<phase>/` 복사 결과 */\n skillsInstalled: {\n enabled: boolean;\n count: number;\n targetDir: string;\n };\n /** `~/.gemini/antigravity/global_workflows/uzys-<phase>.md` 복사 결과 */\n workflowsInstalled: {\n enabled: boolean;\n count: number;\n targetDir: string;\n };\n}\n\nexport interface AntigravityOptInContext {\n /** 사용자 프로젝트 root (`.agents/skills/uzys-*` source). */\n projectDir: string;\n /** harness root (templates/commands/uzys/ source — workflow body 원본). */\n harnessRoot?: string;\n /** 글로벌 `~/.gemini/` 경로 (테스트 override 가능). */\n geminiHome?: string;\n /** `withAntigravityGlobal` opt-in flag. false 시 전체 skip. */\n enabled: boolean;\n}\n\n/**\n * Antigravity 글로벌 opt-in 실행. `enabled=false` 시 skip + empty report.\n */\nexport function runAntigravityOptIn(ctx: AntigravityOptInContext): AntigravityOptInReport {\n const geminiHome = ctx.geminiHome ?? join(homedir(), \".gemini\");\n const skillsTarget = join(geminiHome, \"antigravity\", \"skills\");\n const workflowsTarget = join(geminiHome, \"antigravity\", \"global_workflows\");\n\n if (!ctx.enabled) {\n return {\n skillsInstalled: { enabled: false, count: 0, targetDir: skillsTarget },\n workflowsInstalled: { enabled: false, count: 0, targetDir: workflowsTarget },\n };\n }\n\n // 1. ~/.gemini/antigravity/skills/uzys-{phase}/ 복사\n // Source: projectDir/.agents/skills/uzys-{phase}/ (Phase B 가 만든 산출).\n // Antigravity 가 .agents/skills/ 와 ~/.gemini/antigravity/skills/ 둘 다 native 인식 →\n // 같은 내용을 global 위치에도 복사 (모든 프로젝트에서 보이도록).\n let skillsCount = 0;\n for (const phase of PHASES) {\n const src = join(ctx.projectDir, \".agents\", \"skills\", `uzys-${phase}`);\n if (!existsSync(src)) continue;\n const dst = join(skillsTarget, `uzys-${phase}`);\n mkdirSync(dst, { recursive: true });\n cpSync(src, dst, { recursive: true });\n skillsCount++;\n }\n\n // 2. ~/.gemini/antigravity/global_workflows/uzys-{phase}.md 복사\n // Source: harnessRoot/templates/commands/uzys/<phase>.md\n let workflowsCount = 0;\n if (ctx.harnessRoot) {\n mkdirSync(workflowsTarget, { recursive: true });\n for (const phase of PHASES) {\n const src = join(ctx.harnessRoot, \"templates/commands/uzys\", `${phase}.md`);\n if (!existsSync(src)) continue;\n // Antigravity 파일명 기반 `/uzys-{phase}` dispatch → body 내 `/uzys:` cross-ref 도\n // `/uzys-` 로 rename (project-scope transform.ts:94 와 동일 정합).\n const body = renameSlashes(readFileSync(src, \"utf8\"));\n const dst = join(workflowsTarget, `uzys-${phase}.md`);\n writeFileSync(dst, body);\n workflowsCount++;\n }\n }\n\n return {\n skillsInstalled: { enabled: true, count: skillsCount, targetDir: skillsTarget },\n workflowsInstalled: { enabled: true, count: workflowsCount, targetDir: workflowsTarget },\n };\n}\n","/**\n * AGENTS.md transform — CLAUDE.md → AGENTS.md.\n *\n * v26.70.0 — section 추출(Identity/Direction/Principles) → CLAUDE.md **전문 embed**.\n * 실 `templates/CLAUDE.md` 가 Rule 1~12 구조라 Identity/Direction/Principles 헤딩이 없어\n * extractSection 이 빈 결과 → AGENTS.md 가 빈 섹션으로 shipping 되던 버그 fix.\n * `{PROJECT_RULES}` placeholder 에 CLAUDE.md 본문 전체를 삽입 (heading 구조 의존 0).\n */\n\n/** Rename Claude slash conventions (`/uzys:foo`) to Codex (`/uzys-foo`). */\nexport function renameSlashes(text: string): string {\n return text.replaceAll(\"/uzys:\", \"/uzys-\");\n}\n\nexport interface AgentsMdParams {\n template: string;\n claudeMd: string;\n projectName: string;\n}\n\n/**\n * Render AGENTS.md by embedding the full CLAUDE.md body into the template.\n *\n * Placeholders:\n * - {PROJECT_NAME} — basename of project dir\n * - {PROJECT_RULES} — full CLAUDE.md body (first h1 stripped; template provides its own h1)\n *\n * 마지막에 `/uzys:` → `/uzys-` rename (Codex/Antigravity 는 slash namespace 미지원).\n */\nexport function renderAgentsMd(params: AgentsMdParams): string {\n // CLAUDE.md 의 첫 h1 (# title) 제거 — 템플릿이 자체 h1 보유.\n const body = params.claudeMd.replace(/^#\\s+.*\\r?\\n/, \"\").trim();\n const replaced = params.template\n .replaceAll(\"{PROJECT_NAME}\", params.projectName)\n .replaceAll(\"{PROJECT_RULES}\", body);\n return renameSlashes(replaced);\n}\n","/**\n * Antigravity transform — v26.66.0 (skills/workflows) + v26.69.0 (rules).\n *\n * Google Antigravity 2.0 (I/O 2026-05-19) 공식 spec (codelabs):\n * - Workspace skills: .agents/skills/<name>/SKILL.md (Anthropic skill format — codex 와 공유)\n * - Workspace workflows: .agents/workflows/<name>.md (`/<name>` 슬래시로 호출)\n * - Workspace rules: .agents/rules/<name>.md (디렉토리, plain markdown)\n * - Global rules: ~/.gemini/GEMINI.md (사용자 글로벌 — harness 미터치)\n * - Global skills: ~/.gemini/antigravity/skills/ (Phase C opt-in — antigravity/opt-in.ts)\n *\n * 본 transform 의 책임 (모두 project-scope):\n * 1. `.agents/rules/uzys-harness.md` — project context (CLAUDE.md → Antigravity rule).\n * **withUzysHarness 무관 — 항상 작성** (CLAUDE.md/AGENTS.md 처럼 foundational context).\n * cli=antigravity 단독 선택 시 이게 없으면 Antigravity 가 프로젝트 컨벤션을 모름.\n * 2. `.agents/skills/uzys-{phase}/SKILL.md` — codex 와 idempotent 공유. withUzysHarness 시만.\n * 3. `.agents/workflows/uzys-{phase}.md` — Antigravity native workflow. withUzysHarness 시만.\n * 파일명 기반 `/uzys-{phase}` 호출 → body 의 `/uzys:` 참조도 `/uzys-` 로 rename (정합).\n *\n * SAFETY: `~/.gemini/` 글로벌 write 없음 (Phase C 의 opt-in.ts 가 별도 담당).\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport { renameSlashes, renderAgentsMd } from \"../codex/agents-md.js\";\nimport { renderSkill } from \"../codex/skills.js\";\nimport { ensureDir } from \"../fs-ops.js\";\n\nconst PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"];\n\nexport interface AntigravityTransformParams {\n /** harness root (templates/CLAUDE.md + templates/commands/uzys/ source 위치). */\n harnessRoot: string;\n /** 사용자 프로젝트 root. `.agents/` 가 만들어질 위치. */\n projectDir: string;\n /**\n * withUzysHarness gating. 6-Gate skills/workflows 의 antigravity native 매핑은\n * uzys-harness 활성 시에만. rules (project context) 는 본 flag 무관 — 항상 작성.\n */\n withUzysHarness: boolean;\n}\n\nexport interface AntigravityTransformReport {\n /** v26.69.0 — 작성된 rules 파일 경로 (.agents/rules/uzys-harness.md). null = template 부재. */\n rulesFile: string | null;\n /** 작성된 SKILL.md 경로 list (.agents/skills/uzys-{phase}/SKILL.md). */\n skillFiles: ReadonlyArray<string>;\n /** 작성된 workflow .md 경로 list (.agents/workflows/uzys-{phase}.md). */\n workflowFiles: ReadonlyArray<string>;\n}\n\n/**\n * Antigravity 용 project-scope 자산 생성.\n *\n * rules 는 항상 (cli=antigravity 시), skills/workflows 는 withUzysHarness 시만.\n */\nexport function runAntigravityTransform(\n params: AntigravityTransformParams,\n): AntigravityTransformReport {\n const { harnessRoot, projectDir, withUzysHarness } = params;\n\n // 1. .agents/rules/uzys-harness.md — project context. withUzysHarness 무관 (항상).\n const rulesFile = writeRules(harnessRoot, projectDir);\n\n const skillFiles: string[] = [];\n const workflowFiles: string[] = [];\n\n if (withUzysHarness) {\n for (const phase of PHASES) {\n // 2. .agents/skills/uzys-{phase}/SKILL.md — codex 와 idempotent 공유.\n const skillDir = join(projectDir, \".agents\", \"skills\", `uzys-${phase}`);\n ensureDir(skillDir);\n const cmdSrc = join(harnessRoot, \"templates/commands/uzys\", `${phase}.md`);\n let source = \"\";\n if (existsSync(cmdSrc)) {\n source = readFileSync(cmdSrc, \"utf8\");\n } else {\n // Fallback: bundled stub from templates/codex/skills/<phase>/SKILL.md\n const fallback = join(harnessRoot, \"templates/codex/skills\", `uzys-${phase}/SKILL.md`);\n if (existsSync(fallback)) {\n source = readFileSync(fallback, \"utf8\");\n }\n }\n const skillTarget = join(skillDir, \"SKILL.md\");\n writeFileSync(skillTarget, renderSkill({ source, phase }));\n skillFiles.push(skillTarget);\n\n // 3. .agents/workflows/uzys-{phase}.md — Antigravity native workflow.\n // 파일명 기반 `/uzys-{phase}` 호출 → body 의 `/uzys:` 참조도 `/uzys-` 로 rename (정합).\n // source 가 비어있으면 skip (commands/uzys/ 미설치).\n if (source) {\n const workflowDir = join(projectDir, \".agents\", \"workflows\");\n ensureDir(workflowDir);\n const workflowTarget = join(workflowDir, `uzys-${phase}.md`);\n writeFileSync(workflowTarget, renameSlashes(source));\n workflowFiles.push(workflowTarget);\n }\n }\n }\n\n return { rulesFile, skillFiles, workflowFiles };\n}\n\n/**\n * v26.69.0 — `.agents/rules/uzys-harness.md` 작성. CLAUDE.md → Antigravity workspace rule.\n *\n * Source: templates/CLAUDE.md (전문) + templates/antigravity/AGENTS.md.template.\n * v26.70.0 — renderAgentsMd 재사용 (codex/opencode 와 동일 전문 embed). `{PROJECT_RULES}` 에\n * CLAUDE.md 본문 전체 삽입 + `/uzys:` → `/uzys-` rename.\n *\n * template 또는 CLAUDE.md 부재 시 null (graceful — install 진행).\n */\nfunction writeRules(harnessRoot: string, projectDir: string): string | null {\n const claudeMdPath = join(harnessRoot, \"templates/CLAUDE.md\");\n const templatePath = join(harnessRoot, \"templates/antigravity/AGENTS.md.template\");\n if (!existsSync(claudeMdPath) || !existsSync(templatePath)) {\n return null;\n }\n const claudeMd = readFileSync(claudeMdPath, \"utf8\");\n const template = readFileSync(templatePath, \"utf8\");\n const rulesDir = join(projectDir, \".agents\", \"rules\");\n ensureDir(rulesDir);\n const target = join(rulesDir, \"uzys-harness.md\");\n writeFileSync(target, renderAgentsMd({ template, claudeMd, projectName: basename(projectDir) }));\n return target;\n}\n","/**\n * uzys command → uzys-* SKILL.md transform.\n * Mirrors `claude-to-codex.sh` step 4 (lines 167-205).\n */\nimport { renameSlashes } from \"./agents-md.js\";\n\nexport interface RenderSkillParams {\n /** Original uzys command markdown (frontmatter optional — first line = description if absent). */\n source: string;\n /** Phase identifier (spec, plan, build, test, review, ship). */\n phase: string;\n}\n\n/**\n * Render a Codex SKILL.md from a Claude `.claude/commands/uzys/<phase>.md` source.\n * Slash references inside the body are renamed to the Codex (`uzys-`) form.\n */\nexport function renderSkill(params: RenderSkillParams): string {\n const { description, body } = parseSource(params.source);\n const finalDescription = description || `uzys-${params.phase} phase skill (Codex 포팅)`;\n const escapedDesc = finalDescription.replace(/\"/g, '\\\\\"');\n const renamedBody = renameSlashes(body).trimEnd();\n\n return [\n \"---\",\n `name: uzys-${params.phase}`,\n `description: \"${escapedDesc}\"`,\n \"---\",\n \"\",\n renamedBody,\n \"\",\n ].join(\"\\n\");\n}\n\ninterface ParsedSource {\n description: string;\n body: string;\n}\n\nfunction parseSource(source: string): ParsedSource {\n const lines = source.split(/\\r?\\n/);\n if (lines[0] === \"---\") {\n // YAML frontmatter present\n let descMatch = \"\";\n let secondDelimAt = -1;\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (line === \"---\") {\n secondDelimAt = i;\n break;\n }\n const match = line.match(/^description:\\s*(.*)$/);\n if (match) {\n descMatch = stripQuotes(match[1] ?? \"\");\n }\n }\n const body = secondDelimAt >= 0 ? lines.slice(secondDelimAt + 1).join(\"\\n\") : source;\n return { description: descMatch, body: body.replace(/^\\n+/, \"\") };\n }\n // No frontmatter: first non-empty line = description, rest = body\n const firstLine = lines[0] ?? \"\";\n const body = lines.slice(1).join(\"\\n\");\n return { description: firstLine.trim(), body };\n}\n\nfunction stripQuotes(raw: string): string {\n const trimmed = raw.trim();\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n}\n","import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, renameSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\n/** Ensure a directory exists, creating parents as needed. Idempotent. */\nexport function ensureDir(path: string): void {\n mkdirSync(path, { recursive: true });\n}\n\nexport interface CopyResult {\n copied: number;\n skipped: number;\n}\n\n/** Copy a single file, creating parent dirs as needed. Idempotent. */\nexport function copyFile(source: string, target: string): void {\n if (!existsSync(source)) {\n throw new Error(`Source not found: ${source}`);\n }\n mkdirSync(dirname(target), { recursive: true });\n copyFileSync(source, target);\n}\n\n/** Copy a directory recursively. Creates target if missing. */\nexport function copyDir(source: string, target: string): void {\n if (!existsSync(source)) {\n throw new Error(`Source dir not found: ${source}`);\n }\n mkdirSync(target, { recursive: true });\n cpSync(source, target, { recursive: true, force: true });\n}\n\n/**\n * Move an existing directory to a timestamped backup sibling.\n * Returns the backup path, or null when nothing to back up.\n */\nexport function backupDir(target: string, now: Date = new Date()): string | null {\n if (!existsSync(target)) {\n return null;\n }\n const backup = `${target}.backup-${formatStamp(now)}`;\n renameSync(target, backup);\n return backup;\n}\n\n/**\n * Copy backup — original target preserved (for in-place update mode).\n * bash setup-harness.sh L477 `cp -R .claude \"$BACKUP_DIR\"` 등가.\n */\nexport function copyBackupDir(target: string, now: Date = new Date()): string | null {\n if (!existsSync(target)) {\n return null;\n }\n const backup = `${target}.backup-${formatStamp(now)}`;\n cpSync(target, backup, { recursive: true });\n return backup;\n}\n\n/**\n * 사용자 편집 가능 파일(settings.json·CLAUDE.md)을 덮어쓰기 전 보호.\n * 기존 파일이 있고 새 내용과 다르면 timestamp 백업본을 만들고 그 경로를 반환한다.\n * 부재하거나 내용이 동일하면(idempotent 재설치) null — 불필요한 백업을 만들지 않는다.\n * audit SEC-1/CODE-2 — add 모드(.claude/ backup 없음)에서 통째 덮어쓰기로 인한 데이터 손실 방지.\n */\nexport function backupFileIfChanged(\n target: string,\n newContent: string,\n now: Date = new Date(),\n): string | null {\n if (!existsSync(target)) {\n return null;\n }\n if (readFileSync(target, \"utf-8\") === newContent) {\n return null;\n }\n const backup = `${target}.backup-${formatStamp(now)}`;\n copyFileSync(target, backup);\n return backup;\n}\n\nfunction formatStamp(now: Date): string {\n return now\n .toISOString()\n .replace(/[-:]/g, \"\")\n .replace(/\\.\\d+Z$/, \"Z\")\n .slice(0, 15);\n}\n\n/** Create a project skeleton: <project>/.claude/{commands/{uzys,ecc},rules,skills,agents,hooks}. */\nexport function ensureProjectSkeleton(projectDir: string): void {\n const dirs = [\n \".claude/commands/uzys\",\n \".claude/commands/ecc\",\n \".claude/rules\",\n \".claude/skills\",\n \".claude/agents\",\n \".claude/hooks\",\n \"docs/decisions\",\n ];\n for (const d of dirs) {\n mkdirSync(join(projectDir, d), { recursive: true });\n }\n}\n","/**\n * Codex global opt-in — ~/.codex/skills/ 복사 + ~/.codex/config.toml trust entry.\n *\n * SPEC: docs/specs/cli-rewrite-completeness.md F10, F11 (Reviewer HIGH-3, HIGH-4)\n * Source: bash setup-harness.sh@911c246~1 L1389~1429\n *\n * SAFETY: 사용자 명시 opt-in 없이 ~/.codex/ 글로벌 수정 금지 (D16 / ADR-002 v2 D4).\n * 호출자(installer)는 OptionFlags.withCodexSkills / withCodexTrust 둘 다 true일 때만 호출.\n */\n\nimport { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { CODEX_PROMPT_PHASES, renderCodexPrompt } from \"./prompts.js\";\nimport { type RegisterTrustResult, registerTrustEntry } from \"./trust-entry.js\";\n\nexport interface CodexOptInReport {\n /** ~/.codex/skills/uzys-{phase}/ 복사 결과 */\n skillsInstalled: {\n enabled: boolean;\n /** 복사된 skill 폴더 갯수 (uzys-spec, uzys-plan, ...) */\n count: number;\n /** 복사 대상 글로벌 경로 (절대 경로) */\n targetDir: string;\n };\n /** ~/.codex/config.toml trust entry 등록 결과 */\n trustEntry: {\n enabled: boolean;\n status: \"registered\" | \"already-present\" | \"error\" | \"skipped\";\n message?: string;\n };\n /** v0.7.0 — ~/.codex/prompts/uzys-*.md 6 file 복사 결과 (Codex slash 통일 opt-in). */\n promptsInstalled: {\n enabled: boolean;\n count: number;\n targetDir: string;\n };\n}\n\nexport interface CodexOptInContext {\n /** 사용자 프로젝트 root (.agents/skills/ 소스, v0.6.4+). */\n projectDir: string;\n /** harness root (templates/commands/uzys/ source 위치, v0.7.0+). */\n harnessRoot?: string;\n /** 글로벌 ~/.codex/ 경로 (테스트 override 가능). */\n codexHome?: string;\n /** ~/.codex/skills/uzys-* 복사 활성? */\n withCodexSkills: boolean;\n /** ~/.codex/config.toml trust entry 등록 활성? */\n withCodexTrust: boolean;\n /** v0.7.0 — ~/.codex/prompts/uzys-*.md slash 등록 활성? */\n withCodexPrompts: boolean;\n}\n\nconst PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"];\n\n/**\n * 세 opt-in 액션 실행 (v0.7.0+: prompts 추가). 비활성 플래그는 skip.\n */\nexport function runCodexOptIn(ctx: CodexOptInContext): CodexOptInReport {\n const codexHome = ctx.codexHome ?? join(homedir(), \".codex\");\n const skillsTarget = join(codexHome, \"skills\");\n const promptsTarget = join(codexHome, \"prompts\");\n const configPath = join(codexHome, \"config.toml\");\n\n // 1. ~/.codex/skills/uzys-* 복사\n let skillsCount = 0;\n if (ctx.withCodexSkills) {\n skillsCount = copyCodexSkills(ctx.projectDir, skillsTarget);\n }\n\n // 2. ~/.codex/config.toml trust entry\n let trustResult: RegisterTrustResult & { enabled: boolean } = {\n enabled: false,\n status: \"registered\",\n };\n if (ctx.withCodexTrust) {\n const result = registerTrustEntry({\n configPath,\n projectDir: ctx.projectDir,\n });\n trustResult = { enabled: true, ...result };\n }\n\n // 3. v0.7.0 — ~/.codex/prompts/uzys-*.md 복사 (slash 통일)\n let promptsCount = 0;\n if (ctx.withCodexPrompts) {\n promptsCount = copyCodexPrompts(ctx.harnessRoot, ctx.projectDir, promptsTarget);\n }\n\n return {\n skillsInstalled: {\n enabled: ctx.withCodexSkills,\n count: skillsCount,\n targetDir: skillsTarget,\n },\n trustEntry: {\n enabled: ctx.withCodexTrust,\n status: trustResult.enabled ? trustResult.status : \"skipped\",\n ...(trustResult.message ? { message: trustResult.message } : {}),\n },\n promptsInstalled: {\n enabled: ctx.withCodexPrompts,\n count: promptsCount,\n targetDir: promptsTarget,\n },\n };\n}\n\n/**\n * v0.7.0 — uzys command md 6 file을 Codex prompt md로 변환 + ~/.codex/prompts/ 복사.\n * Source: harnessRoot의 templates/commands/uzys/<phase>.md (또는 fallback projectDir/.claude/commands/uzys).\n * @returns 복사된 prompt 파일 갯수\n */\nfunction copyCodexPrompts(\n harnessRoot: string | undefined,\n projectDir: string,\n promptsTarget: string,\n): number {\n // Source 후보: harnessRoot/templates → fallback projectDir/.claude/commands/uzys (이미 install된 곳)\n const candidates: string[] = [];\n if (harnessRoot) {\n candidates.push(join(harnessRoot, \"templates/commands/uzys\"));\n }\n candidates.push(join(projectDir, \".claude/commands/uzys\"));\n\n const sourceDir = candidates.find((p) => existsSync(p));\n if (!sourceDir) return 0;\n\n mkdirSync(promptsTarget, { recursive: true });\n\n let count = 0;\n for (const phase of CODEX_PROMPT_PHASES) {\n const src = join(sourceDir, `${phase}.md`);\n if (!existsSync(src)) continue;\n const source = readFileSync(src, \"utf8\");\n const dst = join(promptsTarget, `uzys-${phase}.md`);\n writeFileSync(dst, renderCodexPrompt({ source, phase }));\n count++;\n }\n return count;\n}\n\n/**\n * 프로젝트의 .agents/skills/uzys-{phase}/ 6 폴더를 ~/.codex/skills/ 로 복사.\n * v0.6.4+ — source 디렉토리 .codex-skills → .agents/skills (Codex 공식 표준).\n * @returns 복사된 폴더 갯수\n */\nfunction copyCodexSkills(projectDir: string, skillsTarget: string): number {\n const sourceDir = join(projectDir, \".agents\", \"skills\");\n if (!existsSync(sourceDir)) {\n return 0;\n }\n mkdirSync(skillsTarget, { recursive: true });\n\n let count = 0;\n for (const phase of PHASES) {\n const src = join(sourceDir, `uzys-${phase}`);\n if (!existsSync(src)) continue;\n const dest = join(skillsTarget, `uzys-${phase}`);\n cpSync(src, dest, { recursive: true });\n count++;\n }\n\n // Catch any other uzys-* (forward-compat, in case PHASES expands)\n try {\n for (const entry of readdirSync(sourceDir)) {\n if (!entry.startsWith(\"uzys-\")) continue;\n const phase = entry.slice(\"uzys-\".length);\n if (PHASES.includes(phase)) continue; // already copied\n cpSync(join(sourceDir, entry), join(skillsTarget, entry), { recursive: true });\n count++;\n }\n } catch {\n // best-effort\n }\n\n return count;\n}\n","/**\n * Codex prompts render — v0.7.0 Major CR.\n *\n * SPEC: docs/specs/cli-multi-select.md F13 (Codex slash 통일).\n *\n * Source: `templates/commands/uzys/<phase>.md` (Claude Code uzys command)\n * Target: `~/.codex/prompts/uzys-<phase>.md` (Codex custom prompt)\n *\n * 변환:\n * - frontmatter `name: uzys-<phase>` + `description` 보장\n * - body의 `/uzys:<phase>` slash 참조 → `/uzys-<phase>` Codex 컨벤션 (slash rename)\n * - 코드 자체는 동일 (의미 보존)\n *\n * Codex prompts directory에 markdown 파일 두면 Codex 시작 시 `/uzys-<phase>` slash 등록됨.\n * 참조: https://developers.openai.com/codex/cli/slash-commands\n */\n\nimport { renameSlashes } from \"./agents-md.js\";\n\nexport interface RenderCodexPromptParams {\n /** Original uzys command markdown (frontmatter optional). */\n source: string;\n /** Phase identifier (spec, plan, build, test, review, ship). */\n phase: string;\n}\n\nexport function renderCodexPrompt(params: RenderCodexPromptParams): string {\n const { description, body } = parseSource(params.source);\n const finalDescription = description || `uzys-${params.phase} phase`;\n const escapedDesc = finalDescription.replace(/\"/g, '\\\\\"');\n const renamedBody = renameSlashes(body).trimEnd();\n\n // Codex custom prompt frontmatter\n return [\"---\", `description: \"${escapedDesc}\"`, \"---\", \"\", renamedBody, \"\"].join(\"\\n\");\n}\n\ninterface ParsedSource {\n description: string;\n body: string;\n}\n\nfunction parseSource(source: string): ParsedSource {\n const lines = source.split(/\\r?\\n/);\n if (lines[0] === \"---\") {\n let descMatch = \"\";\n let secondDelimAt = -1;\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (line === \"---\") {\n secondDelimAt = i;\n break;\n }\n const m = line.match(/^description:\\s*\"?(.+?)\"?\\s*$/);\n if (m?.[1]) descMatch = m[1];\n }\n if (secondDelimAt >= 0) {\n return {\n description: descMatch,\n body: lines\n .slice(secondDelimAt + 1)\n .join(\"\\n\")\n .replace(/^\\n+/, \"\"),\n };\n }\n // Malformed frontmatter (no closing `---`) — 첫 라인 `---` 자체를 description으로 쓰지 않음.\n // body는 첫 라인 제외하고 그대로 (renderSkill 동일 패턴).\n return {\n description: \"\",\n body: lines.slice(1).join(\"\\n\"),\n };\n }\n // Frontmatter 부재 — 첫 비공백 라인을 description으로 + body는 첫 라인 제외 (중복 방지).\n // Reviewer HIGH-1 fix: 이전엔 body=source 그대로 → description 라인 중복.\n const firstLine = lines[0] ?? \"\";\n const description = firstLine.replace(/^#+\\s*/, \"\").slice(0, 200);\n const body = lines.slice(1).join(\"\\n\").replace(/^\\n+/, \"\");\n return { description, body };\n}\n\nexport const CODEX_PROMPT_PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"] as const;\n","/**\n * Codex trust entry — `~/.codex/config.toml [projects.\"<dir>\"]` (parity with\n * setup-harness.sh L1404-1422).\n *\n * SAFETY: never modify the global `~/.codex/config.toml` without an explicit\n * opt-in (D16 / ADR-002 v2 D4). Callers must verify user consent first.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nexport interface RegisterTrustResult {\n status: \"registered\" | \"already-present\" | \"error\";\n message?: string;\n}\n\nconst TRUST_BLOCK_REGEX = /\\[projects\\.\"([^\"]+)\"\\]/g;\n\n/** Append a `[projects.\"<projectDir>\"]` block to the user `config.toml` (idempotent). */\nexport function registerTrustEntry(opts: {\n configPath: string;\n projectDir: string;\n}): RegisterTrustResult {\n const { configPath, projectDir } = opts;\n try {\n mkdirSync(dirname(configPath), { recursive: true });\n const existing = existsSync(configPath) ? readFileSync(configPath, \"utf8\") : \"\";\n if (hasTrustEntry(existing, projectDir)) {\n return { status: \"already-present\" };\n }\n const block = `\\n[projects.\"${projectDir}\"]\\ntrust_level = \"trusted\"\\n`;\n writeFileSync(configPath, existing + block);\n return { status: \"registered\" };\n } catch (e: unknown) {\n return {\n status: \"error\",\n message: e instanceof Error ? e.message : String(e),\n };\n }\n}\n\nexport function hasTrustEntry(configContent: string, projectDir: string): boolean {\n const matches = [...configContent.matchAll(TRUST_BLOCK_REGEX)].map((m) => m[1]);\n return matches.includes(projectDir);\n}\n","/**\n * Codex transform orchestrator — wraps the 5-step pipeline.\n *\n * Replaces `scripts/claude-to-codex.sh` (Phase D, OQ4 = TS port).\n *\n * Inputs:\n * - harnessRoot: repository root (templates/ + .mcp.json)\n * - projectDir: target project to receive AGENTS.md + .codex/ + .agents/skills/\n *\n * Outputs (under projectDir):\n * - AGENTS.md\n * - .codex/config.toml\n * - .codex/hooks/*.sh (3 hooks ported from templates/hooks/)\n * - .agents/skills/uzys-{phase}/SKILL.md (6 skills, slash-renamed)\n *\n * v0.6.4 — skill 출력 경로 수정 `.codex-skills/` → `.agents/skills/`.\n * 사유: Codex 공식 표준은 `.agents/skills/<name>/SKILL.md` (repo-level scope).\n * `.codex-skills/`는 비표준 — Codex가 인식 안 함 → /uzys-* slash 동작 안 함.\n * 참조: https://developers.openai.com/codex/skills\n */\n\nimport { chmodSync, existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport { ensureDir } from \"../fs-ops.js\";\nimport type { McpJson } from \"../mcp-merge.js\";\nimport { renderAgentsMd } from \"./agents-md.js\";\nimport { renderConfigToml } from \"./config-toml.js\";\nimport { renderCodexPrompt } from \"./prompts.js\";\nimport { renderSkill } from \"./skills.js\";\n\nexport interface CodexTransformParams {\n harnessRoot: string;\n projectDir: string;\n /**\n * v26.57.0 (ADR-018) — uzys-* skill/prompt 생성 gating.\n * Codex 의 `.agents/skills/uzys-{phase}/SKILL.md` 와 `.codex/prompts/uzys-{phase}.md`\n * 는 본 harness 의 6-Gate 워크플로우 산출물. withUzysHarness=false 면 두 디렉토리에\n * uzys-* 파일 생성 안 함. Claude 쪽 `.claude/commands/uzys/` 와 묶음 (ADR-017 의 확장).\n */\n withUzysHarness?: boolean;\n}\n\nexport interface CodexTransformReport {\n agentsMdPath: string;\n configTomlPath: string;\n hookFiles: string[];\n skillFiles: string[];\n /**\n * v0.7.1 — `<projectDir>/.codex/prompts/uzys-{phase}.md` 6 markdown.\n * 글로벌 영향 0. upstream Codex Issue #9848 (project-scoped prompts) 지원 시 자동 작동.\n */\n promptFiles: string[];\n}\n\nconst PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"];\nconst HOOK_NAMES = [\"session-start\", \"hito-counter\", \"gate-check\"];\n\nconst ENV_VAR_RENAME = /CLAUDE_PROJECT_DIR/g;\n\nexport function runCodexTransform(params: CodexTransformParams): CodexTransformReport {\n const { harnessRoot, projectDir, withUzysHarness = false } = params;\n\n const claudeMd = readRequired(join(harnessRoot, \"templates/CLAUDE.md\"));\n const agentsTemplate = readRequired(join(harnessRoot, \"templates/codex/AGENTS.md.template\"));\n const configTemplate = readRequired(join(harnessRoot, \"templates/codex/config.toml.template\"));\n const projectName = basename(projectDir);\n const mcp = readOptionalJson(join(harnessRoot, \".mcp.json\"));\n\n // 1. AGENTS.md\n const agentsMdPath = join(projectDir, \"AGENTS.md\");\n ensureDir(projectDir);\n writeFileSync(agentsMdPath, renderAgentsMd({ template: agentsTemplate, claudeMd, projectName }));\n\n // 2. .codex/config.toml\n const configTomlPath = join(projectDir, \".codex/config.toml\");\n ensureDir(join(projectDir, \".codex\"));\n writeFileSync(\n configTomlPath,\n renderConfigToml({\n template: configTemplate,\n projectName,\n projectDir,\n mcp,\n }),\n );\n\n // 3. .codex/hooks/{session-start,hito-counter,gate-check}.sh\n const hookDir = join(projectDir, \".codex/hooks\");\n ensureDir(hookDir);\n const hookFiles: string[] = [];\n for (const hook of HOOK_NAMES) {\n const src = join(harnessRoot, \"templates/hooks\", `${hook}.sh`);\n if (!existsSync(src)) {\n continue;\n }\n const ported = readFileSync(src, \"utf8\").replace(ENV_VAR_RENAME, \"CODEX_PROJECT_DIR\");\n const target = join(hookDir, `${hook}.sh`);\n writeFileSync(target, ported);\n chmodSync(target, 0o755);\n hookFiles.push(target);\n }\n\n // 4. .agents/skills/uzys-{phase}/SKILL.md (v0.6.4 — Codex 공식 repo-level skill scope)\n // v26.57.0 (ADR-018) — withUzysHarness gating. uzys 슬래시 미사용 시 skill 디렉토리 생성 X.\n const skillFiles: string[] = [];\n if (withUzysHarness) {\n for (const phase of PHASES) {\n const skillDir = join(projectDir, \".agents\", \"skills\", `uzys-${phase}`);\n ensureDir(skillDir);\n const cmdSrc = join(harnessRoot, \"templates/commands/uzys\", `${phase}.md`);\n let source = \"\";\n if (existsSync(cmdSrc)) {\n source = readFileSync(cmdSrc, \"utf8\");\n } else {\n // Fallback: bundled stub from templates/codex/skills/<phase>/SKILL.md\n const fallback = join(harnessRoot, \"templates/codex/skills\", `uzys-${phase}/SKILL.md`);\n if (existsSync(fallback)) {\n source = readFileSync(fallback, \"utf8\");\n }\n }\n const target = join(skillDir, \"SKILL.md\");\n writeFileSync(target, renderSkill({ source, phase }));\n skillFiles.push(target);\n }\n }\n\n // 5. v0.7.1 — .codex/prompts/uzys-{phase}.md (project-scoped pre-positioning)\n // 글로벌 ~/.codex/prompts/ 영향 0. Codex upstream Issue #9848 지원 시 자동 작동.\n // 현재는 Codex가 project-scoped prompts 미지원 — pre-position만 (free upgrade 패턴).\n // v26.57.0 (ADR-018) — withUzysHarness gating. uzys 슬래시 미사용 시 prompt 생성 X.\n const promptFiles: string[] = [];\n if (withUzysHarness) {\n const promptDir = join(projectDir, \".codex\", \"prompts\");\n ensureDir(promptDir);\n for (const phase of PHASES) {\n const cmdSrc = join(harnessRoot, \"templates/commands/uzys\", `${phase}.md`);\n if (!existsSync(cmdSrc)) {\n continue;\n }\n const source = readFileSync(cmdSrc, \"utf8\");\n const target = join(promptDir, `uzys-${phase}.md`);\n writeFileSync(target, renderCodexPrompt({ source, phase }));\n promptFiles.push(target);\n }\n }\n\n return { agentsMdPath, configTomlPath, hookFiles, skillFiles, promptFiles };\n}\n\nfunction readRequired(path: string): string {\n if (!existsSync(path)) {\n throw new Error(`Codex transform: required source missing: ${path}`);\n }\n return readFileSync(path, \"utf8\");\n}\n\nfunction readOptionalJson(path: string): McpJson | null {\n if (!existsSync(path)) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as McpJson;\n } catch {\n return null;\n }\n}\n","/**\n * config.toml transform — fill placeholders + append [mcp_servers.X] from .mcp.json.\n * Mirrors `claude-to-codex.sh` steps 2 + 5.\n */\n\nimport type { McpJson } from \"../mcp-merge.js\";\n\nexport interface RenderConfigTomlParams {\n template: string;\n projectName: string;\n projectDir: string;\n /** Source `.mcp.json` (parsed). When provided, [mcp_servers.X] blocks replace defaults. */\n mcp?: McpJson | null;\n}\n\nconst DEFAULT_MCP_BLOCK_RE = /\\n# =+\\n# MCP Servers — .*?\\n# =+[\\s\\S]*$/;\n\n/**\n * Substitute placeholders + replace the MCP servers section with blocks\n * derived from the supplied `.mcp.json` (or leave the template default).\n */\nexport function renderConfigToml(params: RenderConfigTomlParams): string {\n const substituted = params.template\n .replaceAll(\"{PROJECT_NAME}\", params.projectName)\n .replaceAll(\"{PROJECT_DIR}\", params.projectDir)\n .replaceAll(\"{GITHUB_TOKEN}\", \"${GITHUB_TOKEN}\");\n\n if (!params.mcp) {\n return substituted;\n }\n\n const stripped = stripExistingMcpSection(substituted);\n const fresh = renderMcpServers(params.mcp);\n return `${stripped.trimEnd()}\\n${fresh}\\n`;\n}\n\nfunction stripExistingMcpSection(toml: string): string {\n // Drop default [mcp_servers.X] blocks shipped in the template (we replace from .mcp.json)\n const lines = toml.split(/\\r?\\n/);\n const out: string[] = [];\n let skipping = false;\n for (const line of lines) {\n if (line.startsWith(\"[mcp_servers.\")) {\n skipping = true;\n continue;\n }\n if (skipping && line.startsWith(\"[\") && !line.startsWith(\"[mcp_servers.\")) {\n skipping = false;\n }\n if (skipping) {\n continue;\n }\n if (\n /^# .*MCP Servers/.test(line) ||\n /^# Railway MCP/.test(line) ||\n /^# github MCP/.test(line)\n ) {\n continue;\n }\n out.push(line);\n }\n return out.join(\"\\n\").replace(DEFAULT_MCP_BLOCK_RE, \"\");\n}\n\nfunction renderMcpServers(mcp: McpJson): string {\n const stamp = new Date().toISOString().slice(0, 10);\n const header = [\n \"# ============================================================\",\n `# MCP Servers — generated from .mcp.json (${stamp})`,\n \"# ============================================================\",\n ].join(\"\\n\");\n\n const blocks = Object.entries(mcp.mcpServers).map(([name, cfg]) => {\n const lines = [`[mcp_servers.${quoteIfNeeded(name)}]`];\n lines.push(`command = ${jsonString(cfg.command)}`);\n lines.push(`args = ${JSON.stringify(cfg.args)}`);\n if (cfg.env && Object.keys(cfg.env).length > 0) {\n const envBody = Object.entries(cfg.env)\n .map(([k, v]) => `${k} = ${jsonString(v)}`)\n .join(\", \");\n lines.push(`env = { ${envBody} }`);\n }\n return lines.join(\"\\n\");\n });\n\n return [header, \"\", ...blocks].join(\"\\n\");\n}\n\nfunction jsonString(s: string): string {\n return JSON.stringify(s);\n}\n\nfunction quoteIfNeeded(name: string): string {\n return /^[A-Za-z0-9_-]+$/.test(name) ? name : `\"${name}\"`;\n}\n","/**\n * env-files.ts — 환경 파일 자동 생성.\n *\n * SPEC: docs/specs/cli-rewrite-completeness.md F7, F8\n * Source: bash setup-harness.sh@911c246~1 L880~890 + L954~996.\n *\n * 3 종 산출:\n * 1. .env.example (csr-supabase / full Track) — Supabase 토큰 가이드\n * 2. .gitignore .env 라인 추가 (없을 때만)\n * 3. .mcp-allowlist (모든 dev Track) — D35 opt-in security gate\n *\n * 모두 idempotent — 이미 있으면 skip.\n */\n\nimport { appendFileSync, existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Track } from \"./types.js\";\n\nconst ENV_EXAMPLE_BODY = `# .env.example — csr-supabase Track\n# Copy to .env (gitignored) and fill in values: cp .env.example .env\n\n# ===== Supabase Management API (MCP server용) =====\n# Personal Access Token — @supabase/mcp-server가 프로젝트 생성/마이그레이션/Edge Functions 배포에 사용\n# 발급: https://supabase.com/dashboard/account/tokens\nSUPABASE_ACCESS_TOKEN=\n\n# 프로젝트 참조 ID (예: \"abcdefghijklmnop\")\n# 위치: Supabase Dashboard → Project Settings → General\nSUPABASE_PROJECT_REF=\n\n# DB 패스워드 (supabase db push 등 직접 DB 접근용)\n# 위치: Supabase Dashboard → Project Settings → Database\nSUPABASE_DB_PASSWORD=\n\n# ===== Frontend (public, 클라이언트 노출 OK) =====\n# 위치: Supabase Dashboard → Project Settings → API\nNEXT_PUBLIC_SUPABASE_URL=\nNEXT_PUBLIC_SUPABASE_ANON_KEY=\n\n# ===== Optional — 앱 측 AI 기능용 =====\n# OPENAI_API_KEY=\n# ANTHROPIC_API_KEY=\n\n# ===== Note =====\n# - Vercel/Netlify는 별도 CLI login 사용 (env 불필요): vercel login / netlify login\n# - Supabase CLI(supabase login)는 OAuth로 ~/.config/supabase/에 토큰 저장 — env 별개\n# - .env는 .gitignore됨 (자동 추가). 절대 commit 금지.\n`;\n\nconst ENV_EXAMPLE_TRACKS: ReadonlyArray<Track> = [\"csr-supabase\", \"full\"];\n\nconst GITIGNORE_ENV_PATTERN = /^\\.env$|^\\.env\\s/m;\n\n/**\n * .env.example 생성 (csr-supabase/full Track 한정, idempotent).\n * @returns true if created, false if skipped (already exists or non-applicable track)\n */\nexport function writeEnvExample(projectDir: string, tracks: ReadonlyArray<Track>): boolean {\n if (!tracks.some((t) => ENV_EXAMPLE_TRACKS.includes(t))) {\n return false;\n }\n const path = join(projectDir, \".env.example\");\n if (existsSync(path)) {\n return false;\n }\n writeFileSync(path, ENV_EXAMPLE_BODY);\n return true;\n}\n\n/**\n * .gitignore에 `.env` 라인 추가. 이미 있으면 skip.\n * @returns true if appended, false if skipped (no .gitignore or .env already listed)\n */\nexport function addGitignoreEnv(projectDir: string): boolean {\n const path = join(projectDir, \".gitignore\");\n if (!existsSync(path)) {\n return false;\n }\n const content = readFileSync(path, \"utf8\");\n if (GITIGNORE_ENV_PATTERN.test(content)) {\n return false;\n }\n // append with separator (avoid double newlines)\n const sep = content.endsWith(\"\\n\") ? \"\" : \"\\n\";\n appendFileSync(path, `${sep}\\n# Secret env (auto-added by agent-harness install)\\n.env\\n`);\n return true;\n}\n\nconst NPX_SKILLS_AGENT_DIRS = [\".factory/\", \".goose/\"];\nconst GITIGNORE_NPX_SKILLS_HEADER =\n \"# npx skills add multi-CLI cache (auto-added by agent-harness)\";\n\n/**\n * v0.8.0 — `.gitignore`에 `.factory/`, `.goose/` 패턴 추가 (사용자 보고 #3).\n *\n * `npx skills add`가 multi-CLI universal install 동작 — Codex 사용자 환경에서\n * `.factory/skills/`, `.goose/skills/` 자동 생성. 사용자 git noise 회피용 ignore.\n *\n * idempotent — 이미 있으면 skip.\n * @returns added pattern list (empty if all already present or no .gitignore)\n */\nexport function addGitignoreNpxSkillsAgents(projectDir: string): string[] {\n const path = join(projectDir, \".gitignore\");\n if (!existsSync(path)) {\n return [];\n }\n const content = readFileSync(path, \"utf8\");\n const missing = NPX_SKILLS_AGENT_DIRS.filter((pattern) => {\n // exact line match (이스케이프 후 줄 단위 비교 — 단순화: 문자열 포함)\n const lineRegex = new RegExp(`^${pattern.replace(/\\./g, \"\\\\.\").replace(/\\//g, \"/\")}\\\\s*$`, \"m\");\n return !lineRegex.test(content);\n });\n if (missing.length === 0) {\n return [];\n }\n const sep = content.endsWith(\"\\n\") ? \"\" : \"\\n\";\n const block = [GITIGNORE_NPX_SKILLS_HEADER, ...missing].join(\"\\n\");\n appendFileSync(path, `${sep}\\n${block}\\n`);\n return [...missing];\n}\n\n/**\n * .mcp-allowlist 생성 from .mcp.json mcpServers keys (D35 opt-in security gate).\n * mcp-pre-exec.sh hook이 참조. 파일 부재 시 gate disabled.\n * @returns server name list written, or null if skipped (already exists or .mcp.json missing)\n */\nexport function writeMcpAllowlist(projectDir: string): string[] | null {\n const allowlistPath = join(projectDir, \".mcp-allowlist\");\n if (existsSync(allowlistPath)) {\n return null;\n }\n const mcpPath = join(projectDir, \".mcp.json\");\n if (!existsSync(mcpPath)) {\n return null;\n }\n let names: string[] = [];\n try {\n const parsed = JSON.parse(readFileSync(mcpPath, \"utf8\")) as {\n mcpServers?: Record<string, unknown>;\n };\n names = Object.keys(parsed.mcpServers ?? {}).sort();\n } catch {\n return null;\n }\n if (names.length === 0) {\n return [];\n }\n const body = [\n \"# MCP Server Allowlist — auto-generated by agent-harness install\",\n \"# Referenced by mcp-pre-exec.sh hook. Remove or '#' comment any server you want to block.\",\n \"# Deleting this file disables the gate (allows all MCP calls).\",\n \"\",\n ...names,\n \"\",\n ].join(\"\\n\");\n writeFileSync(allowlistPath, body);\n return names;\n}\n","/**\n * External installer — `EXTERNAL_ASSETS` 매트릭스를 실제 호출로 변환.\n *\n * SPEC: docs/specs/cli-rewrite-completeness.md F1\n *\n * Decision (OQ1): 실패는 warn-skip. 종료 시 누락 자산 목록 보고.\n * abort는 첫 실행 신뢰성을 깨뜨리므로 채택 안 함 (vibe killer).\n *\n * Spawning은 `child_process.spawnSync` 사용. command/args 분리로 shell injection 차단.\n * stdout/stderr는 captured — 사용자에게 한 줄 요약만 노출 (verbose-log는 별도 옵션 후속).\n */\n\nimport { type SpawnSyncReturns, spawnSync } from \"node:child_process\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { CATEGORIES as CATEGORY_ORDER } from \"./categories.js\";\nimport {\n EXTERNAL_ASSETS,\n type ExternalAsset,\n type ExternalAssetMethod,\n filterApplicableAssets,\n} from \"./external-assets.js\";\nimport {\n type CliTargets,\n type InstallScope,\n type OptionFlags,\n resolveScope,\n type Track,\n} from \"./types.js\";\n\nexport interface ExternalInstallerDeps {\n /** Override `spawnSync` for tests (mock으로 호출 횟수 + args 검증). */\n spawn?: (cmd: string, args: ReadonlyArray<string>, opts: SpawnOpts) => SpawnSyncReturns<string>;\n /** harness root (prune-ecc.sh script 위치 resolve용). */\n harnessRoot?: string;\n /** asset 매트릭스 override (테스트용, 기본 EXTERNAL_ASSETS 전체). */\n assets?: ReadonlyArray<ExternalAsset>;\n /** 진행 상황 로그 stream (기본 console.log). 일반 로그용. */\n log?: (msg: string) => void;\n /** 경고 메시지 stream (기본 console.error). */\n warn?: (msg: string) => void;\n /**\n * 자산 설치 시작 직전 호출 (streaming UI용).\n * Renderer가 \"→ asset (installing...)\" 라인 출력에 사용.\n */\n onAssetStart?: (asset: ExternalAsset) => void;\n /**\n * 자산 설치 완료 후 호출 (streaming UI용).\n * Renderer가 \"✓/⊘ asset meta\" 라인 출력에 사용.\n */\n onAssetResult?: (result: AssetInstallResult) => void;\n}\n\ninterface SpawnOpts {\n encoding: \"utf8\";\n stdio: (\"ignore\" | \"pipe\")[] | \"ignore\" | \"pipe\";\n timeout?: number;\n /** v26.77.0 — 작업 디렉토리. projectDir 로 고정해 자산이 올바른 프로젝트에 착지. */\n cwd?: string;\n}\n\nexport interface AssetInstallResult {\n asset: ExternalAsset;\n ok: boolean;\n /** ok=false 시 user-facing 메시지 */\n message?: string;\n /**\n * v26.59.0 — 설치된 자산 version. install 후 detectVersion 으로 path 기반 추출.\n * plugin: ~/.claude/plugins/cache/<marketplace>/<plugin>/<VERSION>/ 디렉토리명\n * npm-global: <npm root -g>/<pkg>/package.json 의 version\n * 그 외 method (skill, npx-run, shell-script): 표준 metadata 없음 → undefined.\n */\n version?: string;\n}\n\nexport interface ExternalInstallReport {\n /** 적용 시도된 자산 (조건 통과한 것만) */\n attempted: ReadonlyArray<AssetInstallResult>;\n /** 성공 갯수 */\n succeeded: number;\n /** warn-skip 된 갯수 */\n skipped: number;\n}\n\nconst DEFAULT_SPAWN_TIMEOUT_MS = 120_000;\n\n/**\n * spec에 적용 가능한 자산을 모두 시도. 실패는 warn-skip (기본).\n */\nexport function runExternalInstall(\n ctx: {\n tracks: ReadonlyArray<Track>;\n options: OptionFlags;\n cli: CliTargets;\n /** v26.47.0 — Phase C full user override (forceInclude/forceExclude). */\n userOverride?: { forceInclude: ReadonlyArray<string>; forceExclude: ReadonlyArray<string> };\n /** v26.64.0 (ADR-020) — Install scope. undefined → default \"project\". */\n scope?: InstallScope;\n /**\n * v26.77.0 — 외부 설치기 spawn 의 작업 디렉토리.\n * 미지정 시 process.cwd(). 핵심: npm(--save-dev)·npx-run(bmad --directory .)·\n * plugin(--scope project, claude 의 cwd 기반 project 탐지)·skill 이 모두 cwd 기준으로\n * 착지하므로, --project-dir 가 cwd 와 다르면 cwd 를 projectDir 로 맞춰야 자산이 올바른\n * 프로젝트에 떨어진다 (이 누락 = 2026-06-07 probe 가 repo 를 오염시킨 근본 원인).\n */\n projectDir?: string;\n },\n deps: ExternalInstallerDeps = {},\n): ExternalInstallReport {\n const log = deps.log ?? console.log;\n const warn = deps.warn ?? console.error;\n const spawn = deps.spawn ?? defaultSpawn;\n const assets = deps.assets ?? EXTERNAL_ASSETS;\n const harnessRoot = deps.harnessRoot ?? process.cwd();\n const projectDir = ctx.projectDir ?? process.cwd();\n\n // v26.81.0 (ADR-022) — internal 자산(tauri-desktop/uzys-harness)은 Phase 1 의\n // manifest/transform 이 설치 주체 — external(spawn) 단계에서 제외. Phase 1 의\n // templates 행으로 사용자에게 이미 가시화됨 (중복 보고 방지).\n const applicable = filterApplicableAssets(assets, ctx).filter(\n (a) => a.method.kind !== \"internal\",\n );\n // v26.55.0 — Phase 2 grouped progress UX. 카테고리 순서로 정렬 → install.ts 의 onAssetStart\n // callback 이 category 변경 감지로 헤더 출력 가능. ADR-016.\n const sorted = [...applicable].sort((a, b) => {\n const ai = CATEGORY_ORDER.indexOf(a.category);\n const bi = CATEGORY_ORDER.indexOf(b.category);\n return ai - bi;\n });\n const attempted: AssetInstallResult[] = [];\n const cli = ctx.cli;\n const scope = resolveScope(ctx.scope);\n\n for (const asset of sorted) {\n deps.onAssetStart?.(asset);\n log(` → ${asset.description}`);\n const baseResult = installOne(asset, { spawn, harnessRoot, cli, scope, projectDir });\n let result: AssetInstallResult = baseResult;\n if (baseResult.ok) {\n const v = detectVersion(asset.method, spawn);\n if (v) result = { ...baseResult, version: v };\n }\n deps.onAssetResult?.(result);\n\n if (!result.ok) {\n // v26.79.0 — 모든 실패는 warn-skip (abort 는 vibe killer 라 미채택). 죽은\n // failureMode/aborted 메커니즘 제거 (사용 자산 0 + 렌더러 미참조).\n warn(` [warn-skip] ${asset.id}: ${result.message ?? \"failed\"}`);\n }\n\n attempted.push(result);\n }\n\n return {\n attempted,\n succeeded: attempted.filter((r) => r.ok).length,\n skipped: attempted.filter((r) => !r.ok).length,\n };\n}\n\n/**\n * 자산 1개 설치. method.kind 별 적절한 명령 실행.\n */\nfunction installOne(\n asset: ExternalAsset,\n ctx: {\n spawn: NonNullable<ExternalInstallerDeps[\"spawn\"]>;\n harnessRoot: string;\n cli: CliTargets;\n scope: InstallScope;\n /** v26.77.0 — spawn cwd. 자산이 올바른 프로젝트에 착지하도록 projectDir 로 고정. */\n projectDir: string;\n },\n): AssetInstallResult {\n const { method } = asset;\n const cwd = ctx.projectDir;\n switch (method.kind) {\n case \"skill\":\n return runSpawn(asset, ctx.spawn, \"npx\", buildSkillArgs(method, ctx.cli, ctx.scope), cwd);\n case \"plugin\":\n return installPlugin(asset, ctx.spawn, method, ctx.scope, cwd);\n case \"npm\": {\n // v26.64.0 (ADR-020) — scope=project 시 devDep, scope=global 시 -g.\n // v26.68.0 — method.kind \"npm-global\" → \"npm\" rename (scope 분기와 무관 의미).\n // v26.80.0 — pinned 버전 설치 (`pkg@version`). vetting 시점의 코드만 실행 (보안 wedge).\n const pinned = `${method.pkg}@${method.version}`;\n return runSpawn(\n asset,\n ctx.spawn,\n \"npm\",\n ctx.scope === \"global\" ? [\"install\", \"-g\", pinned] : [\"install\", \"--save-dev\", pinned],\n cwd,\n );\n }\n case \"npx-run\":\n // v26.80.0 — pinned 버전 실행 (`cmd@version`). 이전 `cmd` 에 \"@latest\" 인라인이던 것을\n // 구조 필드로 분리 (cmd 는 bare 이름 — drift override/라벨이 이름 그대로 사용).\n return runSpawn(\n asset,\n ctx.spawn,\n \"npx\",\n [`${method.cmd}@${method.version}`, ...(method.args ?? [])],\n cwd,\n );\n case \"shell-script\": {\n const scriptPath = join(ctx.harnessRoot, method.script);\n if (!existsSync(scriptPath)) {\n return {\n asset,\n ok: false,\n message: `script not found: ${scriptPath}`,\n };\n }\n return runSpawn(asset, ctx.spawn, \"bash\", [scriptPath, ...method.args], cwd);\n }\n case \"internal\":\n // v26.81.0 (ADR-022) — 도달 불가 (runExternalInstall 이 사전 필터). exhaustive switch\n // + 방어: 도달해도 spawn 없이 ok (Phase 1 manifest 가 실 설치 주체).\n return { asset, ok: true, message: \"internal template (installed by Phase 1 manifest)\" };\n }\n}\n\n/**\n * v26.39.5 fix — `--agent <list>` 명시 추가 (사용자 보고 #3 진짜 fix).\n *\n * `npx skills add` default 동작은 `*` (all installed agents) → universal install →\n * `.factory/skills/`, `.goose/skills/` 자동 생성. v0.8.0 의 `.gitignore` 패턴 추가만으론\n * git noise 만 차단하고 disk 디렉토리 생성은 막지 못함.\n *\n * 본 fix: `spec.cli` 의 base CLI 만 콤마 구분 명시 → 의도된 agent 만 install.\n *\n * v26.39.6 fix — skills CLI agent name 매핑.\n * skills CLI 1.5.5 valid agent 이름은 `claude-code` 인데 우리 CliBase 는 `claude`.\n * 매핑 누락 시 `Invalid agents: claude` 로 exit 1 → 외부 사용자 (DYLD-GoalTrack\n * reproduce 2026-05-06) 환경에서 7건 skill 자산 100% skip.\n */\nconst SKILLS_CLI_AGENT_MAP: Record<CliTargets[number], string> = {\n claude: \"claude-code\",\n codex: \"codex\",\n opencode: \"opencode\",\n // v26.66.0 — Antigravity (Google) skills agent. `.agents/skills/` 표준 공유 (codex transform 산출과 동일).\n antigravity: \"antigravity\",\n};\n\n/**\n * `npx skills` CLI 고정 버전 — unpinned 면 upstream breaking 이 설치·검증을 동시에 깬다\n * (1.5.5→1.5.7 multi-agent `--agent` 플래그 파손 전례). bump 시 Docker 시나리오 재검증 필수.\n * audit CODE-4/D-1. scripts/verify-catalog.mjs 와 동일 값 유지 (drift 테스트 가드).\n */\nexport const SKILLS_CLI_VERSION = \"1.5.11\";\n\n/** `npx skills <subcommand>` 의 첫 인자 — 항상 버전 고정. */\nexport function skillsCliSpec(): string {\n return `skills@${SKILLS_CLI_VERSION}`;\n}\n\nfunction buildSkillArgs(\n method: { kind: \"skill\"; source: string; skill?: string },\n cli: CliTargets,\n scope: InstallScope,\n): string[] {\n const args = [skillsCliSpec(), \"add\", method.source];\n if (method.skill) {\n args.push(\"--skill\", method.skill);\n }\n if (cli.length > 0) {\n // v26.55.1 — skills cli 1.5.7 부터 multi-agent 는 repeatable `--agent` 만 지원.\n for (const c of cli) {\n args.push(\"--agent\", SKILLS_CLI_AGENT_MAP[c] ?? c);\n }\n }\n // v26.64.0 (ADR-020) — global scope 시 -g. project 는 skills CLI default (project) 따름.\n if (scope === \"global\") {\n args.push(\"-g\");\n }\n args.push(\"--yes\");\n return args;\n}\n\n/**\n * Plugin 은 marketplace add → install 두 단계. marketplace add 실패는 무시 (이미 등록 케이스).\n *\n * v26.64.0 (ADR-020) — `--scope <project|user>` 분기. claude CLI native:\n * - project: --scope project (현재 projectPath 격리, installed_plugins.json 메타 매칭)\n * - global: --scope user (모든 projectPath 에서 활성)\n * fs 적으로는 양쪽 모두 ~/.claude/plugins/cache/ + ~/.claude/plugins/marketplaces/ 에 write\n * (claude CLI 자체 디자인). 격리는 메타데이터.\n */\nfunction installPlugin(\n asset: ExternalAsset,\n spawn: NonNullable<ExternalInstallerDeps[\"spawn\"]>,\n method: { kind: \"plugin\"; marketplace: string; pluginId: string },\n scope: InstallScope,\n cwd: string,\n): AssetInstallResult {\n const claudeScope = scope === \"global\" ? \"user\" : \"project\";\n // v26.77.0 — cwd=projectDir: --scope project 시 claude 가 cwd 기준으로 프로젝트를 탐지하므로\n // installed_plugins.json 의 projectPath 가 올바른 프로젝트로 기록된다.\n spawn(\n \"claude\",\n [\"plugin\", \"marketplace\", \"add\", \"--scope\", claudeScope, method.marketplace],\n spawnOpts(cwd),\n );\n return runSpawn(\n asset,\n spawn,\n \"claude\",\n [\"plugin\", \"install\", \"--scope\", claudeScope, method.pluginId],\n cwd,\n );\n}\n\nfunction runSpawn(\n asset: ExternalAsset,\n spawn: NonNullable<ExternalInstallerDeps[\"spawn\"]>,\n cmd: string,\n args: ReadonlyArray<string>,\n cwd?: string,\n): AssetInstallResult {\n const result = spawn(cmd, args, spawnOpts(cwd));\n if (result.error) {\n return { asset, ok: false, message: result.error.message };\n }\n if ((result.status ?? 1) !== 0) {\n const stderr = (result.stderr ?? \"\").trim();\n const tail = stderr.length > 200 ? `${stderr.slice(0, 200)}…` : stderr;\n return {\n asset,\n ok: false,\n message: `${cmd} exited ${result.status}${tail ? `: ${tail}` : \"\"}`,\n };\n }\n return { asset, ok: true };\n}\n\nfunction spawnOpts(cwd?: string): SpawnOpts {\n return {\n encoding: \"utf8\",\n stdio: \"pipe\",\n timeout: DEFAULT_SPAWN_TIMEOUT_MS,\n ...(cwd ? { cwd } : {}),\n };\n}\n\n/* v8 ignore next 7 — thin dep-inject default. tests 는 항상 spawn 주입. */\nfunction defaultSpawn(\n cmd: string,\n args: ReadonlyArray<string>,\n opts: SpawnOpts,\n): SpawnSyncReturns<string> {\n return spawnSync(cmd, [...args], opts);\n}\n\n/**\n * v26.59.0 — install 후 path 기반 version 추출.\n *\n * 안전 원칙: 실패 시 undefined 반환 (silent). install 성공 자체는 이미 검증됨.\n *\n * - plugin: ~/.claude/plugins/cache/<marketplace>/<plugin>/<VERSION>/ 디렉토리명 (semver-like 만)\n * - npm-global: <npm root -g>/<pkg>/package.json 의 version\n * - skill / npx-run / shell-script: 표준 metadata 위치 없음 → undefined\n */\nfunction detectVersion(\n method: ExternalAssetMethod,\n spawn: NonNullable<ExternalInstallerDeps[\"spawn\"]>,\n): string | undefined {\n try {\n switch (method.kind) {\n case \"plugin\": {\n // pluginId = \"<plugin>@<marketplace-short>\". cache path:\n // ~/.claude/plugins/cache/<marketplace-short>/<plugin>/<VERSION>/\n // method.marketplace 는 GH `<user>/<repo>` (다른 값) 이라 path 에 사용 X.\n const at = method.pluginId.lastIndexOf(\"@\");\n if (at <= 0) return undefined;\n const plugin = method.pluginId.slice(0, at);\n const marketplaceShort = method.pluginId.slice(at + 1);\n const cacheBase = join(homedir(), \".claude/plugins/cache\", marketplaceShort, plugin);\n if (!existsSync(cacheBase)) return undefined;\n const versions = readdirSync(cacheBase)\n .filter((v) => /^\\d/.test(v))\n .sort();\n return versions.at(-1);\n }\n case \"npm\": {\n const npmRoot = getNpmGlobalRoot(spawn);\n if (!npmRoot) return undefined;\n const pkgJson = join(npmRoot, method.pkg, \"package.json\");\n if (!existsSync(pkgJson)) return undefined;\n const parsed = JSON.parse(readFileSync(pkgJson, \"utf8\")) as { version?: string };\n return parsed.version;\n }\n default:\n return undefined;\n }\n } catch {\n return undefined;\n }\n}\n\nlet npmGlobalRootCache: string | undefined;\n\n/* v8 ignore start — npm CLI 실행 + cache. 실 시스템 의존. detectVersion (plugin 외 method) 가 본 함수 호출. */\nfunction getNpmGlobalRoot(spawn: NonNullable<ExternalInstallerDeps[\"spawn\"]>): string | undefined {\n if (npmGlobalRootCache !== undefined) return npmGlobalRootCache || undefined;\n try {\n const r = spawn(\"npm\", [\"root\", \"-g\"], spawnOpts());\n if ((r.status ?? 1) === 0) {\n npmGlobalRootCache = (r.stdout ?? \"\").trim();\n return npmGlobalRootCache || undefined;\n }\n } catch {\n // fallthrough\n }\n npmGlobalRootCache = \"\";\n return undefined;\n}\n/* v8 ignore stop */\n\n/**\n * 누락(skip) 자산 목록을 사용자 보고용 텍스트로 포맷.\n */\nexport function formatSkippedReport(report: ExternalInstallReport): string {\n const failed = report.attempted.filter((r) => !r.ok);\n if (failed.length === 0) return \"\";\n const lines = failed.map((r) => ` • ${r.asset.id} — ${r.message ?? \"failed\"}`);\n return [\n `${failed.length}개 외부 자산이 설치되지 않았습니다 (warn-skip):`,\n ...lines,\n \"\",\n \"Manual install or retry needed. See docs/REFERENCE.md or README.md for details.\",\n ].join(\"\\n\");\n}\n","/**\n * Install log — `.claude/.harness-install.json`.\n *\n * v26.64.0 (ADR-020) — install 종료 시 자산 list + scope + timestamp 기록.\n * uninstall command 가 본 log 를 읽어 정확한 reverse 수행.\n *\n * 글로벌 자산 (scope=global 또는 codexOptIn) 은 log 에 안내용으로만 기록 — uninstall 시 자동 삭제 X (D16).\n */\n\nimport { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { ExternalAsset, ExternalAssetMethod } from \"./external-assets.js\";\nimport type { ExternalInstallReport } from \"./external-installer.js\";\nimport type { InstallScope, InstallSpec } from \"./types.js\";\n\nexport const INSTALL_LOG_FILENAME = \".harness-install.json\";\nexport const INSTALL_LOG_VERSION = 1;\n\nexport interface InstallLogAsset {\n id: string;\n category: string;\n /** External asset method.kind 그대로. uninstall reverse 시 분기 기준. */\n method: ExternalAssetMethod[\"kind\"];\n /** scope=global 자산은 uninstall 시 안내만 (D16 — 글로벌 자동 삭제 금지). */\n scope: InstallScope;\n /** method 별 추가 정보. plugin: marketplace + pluginId. skill: source. npm: pkg. */\n detail: Record<string, string>;\n /** installed 시점 version (detectVersion 결과, 없으면 undefined). */\n version?: string;\n}\n\nexport interface InstallLog {\n /** schema version — backward compat 검출용 */\n schemaVersion: number;\n /** harness 가 install 한 시점 ISO timestamp */\n installedAt: string;\n /** 전체 install scope. 자산 per-asset scope 와 동일 (현재는 single global scope) */\n scope: InstallScope;\n /** install 시 spec 요약 (tracks/cli — uninstall reasoning 용) */\n spec: {\n tracks: ReadonlyArray<string>;\n cli: ReadonlyArray<string>;\n };\n /** templates 출처 — uninstall 시 templates 제거 위치 */\n templates: {\n /** .claude/ project local */\n claudeDir: string;\n /** .codex/ project local (cli=codex 시) */\n codexDir?: string;\n /** .opencode/ project local (cli=opencode 시) */\n opencodeDir?: string;\n /**\n * project root CLAUDE.md (cli=claude 시 생성).\n * uninstall 시 sha256 이 install 시점과 동일할 때만 삭제 — 사용자가 수정했으면 보존.\n */\n rootClaudeMd?: { path: string; sha256: string };\n };\n /** external-installer 가 install 한 자산 (ok=true 만) */\n assets: ReadonlyArray<InstallLogAsset>;\n}\n\n/**\n * external-installer 의 result 를 InstallLogAsset 으로 변환.\n * ok=false 자산은 제외 (실제 install 안 됨 → uninstall 대상 아님).\n */\nexport function buildAssetEntries(\n report: ExternalInstallReport | null,\n scope: InstallScope,\n): InstallLogAsset[] {\n if (!report) return [];\n return report.attempted\n .filter((r) => r.ok)\n .map((r) => assetToLogEntry(r.asset, scope, r.version));\n}\n\nfunction assetToLogEntry(\n asset: ExternalAsset,\n scope: InstallScope,\n version: string | undefined,\n): InstallLogAsset {\n const detail = methodDetail(asset.method);\n const entry: InstallLogAsset = {\n id: asset.id,\n category: asset.category,\n method: asset.method.kind,\n scope,\n detail,\n };\n if (version) entry.version = version;\n return entry;\n}\n\nfunction methodDetail(method: ExternalAssetMethod): Record<string, string> {\n switch (method.kind) {\n case \"plugin\":\n return { marketplace: method.marketplace, pluginId: method.pluginId };\n case \"skill\":\n return { source: method.source, ...(method.skill ? { skill: method.skill } : {}) };\n case \"npm\":\n return { pkg: method.pkg };\n case \"npx-run\":\n return { cmd: method.cmd, args: (method.args ?? []).join(\" \") };\n case \"shell-script\":\n return { script: method.script, args: method.args.join(\" \") };\n case \"internal\":\n // v26.81.0 (ADR-022) — Phase 1 manifest 가 설치 주체. external 단계에선 미기록이 정상.\n return { key: method.key };\n }\n}\n\nexport function buildInstallLog(\n spec: InstallSpec,\n external: ExternalInstallReport | null,\n scope: InstallScope,\n rootClaudeMd?: { path: string; sha256: string } | null,\n): InstallLog {\n const log: InstallLog = {\n schemaVersion: INSTALL_LOG_VERSION,\n installedAt: new Date().toISOString(),\n scope,\n spec: {\n tracks: spec.tracks,\n cli: spec.cli,\n },\n templates: {\n claudeDir: \".claude/\",\n ...(spec.cli.includes(\"codex\") ? { codexDir: \".codex/\" } : {}),\n ...(spec.cli.includes(\"opencode\") ? { opencodeDir: \".opencode/\" } : {}),\n ...(rootClaudeMd ? { rootClaudeMd } : {}),\n },\n assets: buildAssetEntries(external, scope),\n };\n return log;\n}\n\n/** install log + root CLAUDE.md 등 자산 무결성 비교용 sha256 (hex). */\nexport function hashContent(content: string): string {\n return createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\");\n}\n\n/**\n * install log write. 위치: `<projectDir>/.claude/.harness-install.json`.\n *\n * `.claude/` 는 cli=claude 일 때 baseline phase 에서 생성되지만, codex/opencode/antigravity\n * 단독(claude 미포함) 설치 시엔 생성되지 않는다. 그 경우에도 uninstall 이 본 log 를 읽을 수 있도록\n * write 직전 디렉토리를 보장한다 (없으면 install log 누락 → uninstall 불가).\n */\nexport function writeInstallLog(projectDir: string, log: InstallLog): string {\n const path = join(projectDir, \".claude\", INSTALL_LOG_FILENAME);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(log, null, 2)}\\n`, \"utf8\");\n return path;\n}\n\nexport function readInstallLog(projectDir: string): InstallLog | null {\n const path = join(projectDir, \".claude\", INSTALL_LOG_FILENAME);\n if (!existsSync(path)) return null;\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as InstallLog;\n // v26.68.0 — backward compat: method.kind \"npm-global\" → \"npm\" rename.\n // v26.64.0 ~ v26.67.0 시점 install log 가 새 uninstall 에서 작동하도록 normalize.\n if (Array.isArray(parsed.assets)) {\n parsed.assets = parsed.assets.map((a) =>\n (a.method as string) === \"npm-global\" ? { ...a, method: \"npm\" } : a,\n );\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nexport function installLogPath(projectDir: string): string {\n return join(projectDir, \".claude\", INSTALL_LOG_FILENAME);\n}\n","import { anyTrack, hasDevTrack, hasUiTrack } from \"./track-match.js\";\nimport type { Track } from \"./types.js\";\n\n/**\n * Source-relative paths under `templates/` map to project-relative targets under\n * the project root (typically `.claude/...` or `CLAUDE.md`).\n *\n * Each entry declares an `applies(spec)` predicate based on the selected tracks.\n * Phase C scope: rules + commands + agents + base skills + hooks + project CLAUDE.md.\n * Phase E will extend with the remaining track-specific skills.\n */\n\nexport interface AssetSpec {\n /** Selected tracks (union). */\n tracks: ReadonlyArray<Track>;\n /**\n * Optional opt-in: --with-tauri.\n * Note: copied from `OptionFlags.withTauri` by installer; keep both fields in sync\n * when adding new opt-in flags that affect manifest gating.\n */\n withTauri?: boolean;\n /**\n * v26.44.0 — uzys-harness 6-Gate slash commands opt-in (BREAKING).\n * Note: copied from `OptionFlags.withUzysHarness` by installer; keep both fields in sync.\n * Track-independent: opt-in on ANY track installs `/uzys:*` commands. SPEC R7.\n */\n withUzysHarness?: boolean;\n /**\n * v26.58.0 — withEcc opt-out gating (BREAKING vs v26.55.0). ADR-019 supersedes ADR-016 부분.\n * Note: copied from `OptionFlags.withEcc` by installer; keep both fields in sync.\n *\n * 정책 (cherry-pick × plugin gating):\n * - C1 (단순 중복): 매핑 자체 삭제. 현재 0개.\n * - C2 (plugin OFF fallback): `applies: (s) => !s.withEcc && <track>`. 19개.\n * - C3 (modified or 별개 source): `applies: <track only>` (withEcc 무관 항상 install). 3개.\n *\n * 분류 표 SSOT: docs/PRD/v26-58-cherry-pick-plugin-gating.md §6.\n */\n withEcc?: boolean;\n}\n\nexport interface AssetEntry {\n source: string; // relative to repo `templates/`\n target: string; // relative to project root\n type: \"file\" | \"dir\";\n applies: (spec: AssetSpec) => boolean;\n}\n\nconst all = (): boolean => true;\nconst dev = (s: AssetSpec): boolean => hasDevTrack(s.tracks);\nconst ui = (s: AssetSpec): boolean => hasUiTrack(s.tracks);\nconst onTracks =\n (pattern: string) =>\n (s: AssetSpec): boolean =>\n anyTrack(s.tracks, pattern);\n\nconst COMMON_RULES = [\"git-policy\", \"change-management\", \"gates-taxonomy\"];\nconst DEV_RULES = [\"test-policy\", \"ship-checklist\", \"code-style\", \"error-handling\"];\nconst UI_RULES = [\"design-workflow\", \"playwright-launch\"];\n\nconst TRACK_RULES: Record<Track, string[]> = {\n \"csr-supabase\": [\"shadcn\", \"api-contract\"],\n \"csr-fastify\": [\"shadcn\", \"api-contract\", \"database\"],\n \"csr-fastapi\": [\"shadcn\", \"api-contract\", \"database\"],\n \"ssr-htmx\": [\"htmx\"],\n \"ssr-nextjs\": [\"nextjs\", \"shadcn\"],\n data: [\"pyside6\", \"data-analysis\"],\n executive: [],\n tooling: [\"cli-development\"],\n full: [\n \"shadcn\",\n \"api-contract\",\n \"database\",\n \"htmx\",\n \"nextjs\",\n \"pyside6\",\n \"data-analysis\",\n \"cli-development\",\n ],\n // v0.5.0 — executive-style baselines (no dev rules; common rules only).\n \"project-management\": [],\n \"growth-marketing\": [],\n};\n\n/** Resolve the unique set of rule names to install for the given spec. */\nexport function resolveRules(spec: AssetSpec): string[] {\n const set = new Set<string>(COMMON_RULES);\n if (hasDevTrack(spec.tracks)) {\n for (const r of DEV_RULES) {\n set.add(r);\n }\n }\n if (spec.withTauri && anyTrack(spec.tracks, \"csr-*|full\")) {\n set.add(\"tauri\");\n }\n if (hasUiTrack(spec.tracks)) {\n for (const r of UI_RULES) {\n set.add(r);\n }\n }\n for (const t of spec.tracks) {\n for (const r of TRACK_RULES[t]) {\n set.add(r);\n }\n }\n return [...set].sort();\n}\n\nconst UZYS_COMMANDS = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\", \"auto\"];\n\n// v26.58.0 — ECC cherry-pick × plugin gating. ADR-019.\n// 본 프로젝트 (always): reviewer, data-analyst, strategist\n// ECC cherry-pick C2 (plugin OFF 시 fallback — opt-out gating, !s.withEcc):\n// code-reviewer, security-reviewer, silent-failure-hunter, build-error-resolver\nconst CORE_AGENTS = [\"reviewer\", \"data-analyst\", \"strategist\"];\nconst CORE_AGENTS_ECC = [\"code-reviewer\", \"security-reviewer\"];\n\nconst DEV_AGENTS = [\"plan-checker\"];\nconst DEV_AGENTS_ECC = [\"silent-failure-hunter\", \"build-error-resolver\"];\n\n/** Hooks installed for every project (parity with setup-harness.sh L815-826). */\nconst ALWAYS_HOOKS = [\n \"session-start.sh\",\n \"protect-files.sh\",\n \"gate-check.sh\",\n \"agentshield-gate.sh\",\n \"mcp-pre-exec.sh\",\n \"spec-drift-check.sh\",\n \"checkpoint-snapshot.sh\",\n \"hito-counter.sh\",\n];\n\n// v26.58.0 — ECC cherry-pick × plugin gating. ADR-019.\nconst COMMON_SKILL_DIRS = [\"north-star\", \"gh-issue-workflow\"];\n// C2 (plugin OFF fallback, opt-out): strategic-compact, deep-research.\nconst COMMON_SKILL_DIRS_ECC = [\"strategic-compact\", \"deep-research\"];\n// C3 (modified=true — plugin 으로 갈음 불가, 항상 install): continuous-learning-v2.\nconst MODIFIED_COMMON_SKILL_DIRS = [\"continuous-learning-v2\"];\n\nconst DEV_SKILL_DIRS: string[] = [];\nconst DEV_SKILL_DIRS_ECC = [\"eval-harness\", \"verification-loop\", \"agent-introspection-debugging\"];\n\nconst UI_SKILL_DIRS = [\"ui-visual-review\"];\nconst UI_SKILL_DIRS_ECC = [\"e2e-testing\"];\n\n// python-* skills (data|csr-fastapi|full) — C2 (plugin OFF fallback).\nconst PYTHON_SKILL_DIRS_ECC = [\"python-patterns\", \"python-testing\"];\n\n/** Build the full asset manifest for the given spec. */\nexport function buildManifest(spec: AssetSpec): AssetEntry[] {\n const m: AssetEntry[] = [];\n\n // Rules\n for (const r of resolveRules(spec)) {\n m.push({\n source: `rules/${r}.md`,\n target: `.claude/rules/${r}.md`,\n type: \"file\",\n applies: all,\n });\n }\n\n // uzys: commands (v26.44.0 — opt-in; BREAKING vs prior dev-track auto-install).\n // 본 harness 자체 6-Gate slash commands. Workflow 카테고리의 1 옵션.\n for (const cmd of UZYS_COMMANDS) {\n m.push({\n source: `commands/uzys/${cmd}.md`,\n target: `.claude/commands/uzys/${cmd}.md`,\n type: \"file\",\n applies: (s) => Boolean(s.withUzysHarness),\n });\n }\n\n // ecc: commands — v26.58.0 opt-out gating (BREAKING vs v26.55.0). ADR-019.\n // C2 — plugin OFF 시만 cherry-pick (plugin ON 이면 ecc plugin 의 /ecc:e2e, /ecc:eval, /ecc:harness-audit 사용).\n m.push({\n source: \"commands/ecc\",\n target: \".claude/commands/ecc\",\n type: \"dir\",\n applies: (s) => !s.withEcc,\n });\n\n // Project meta CLAUDE.md\n m.push({\n source: \"CLAUDE.md\",\n target: \".claude/CLAUDE.md\",\n type: \"file\",\n applies: all,\n });\n\n // Agents (본 프로젝트)\n for (const a of CORE_AGENTS) {\n m.push({\n source: `agents/${a}.md`,\n target: `.claude/agents/${a}.md`,\n type: \"file\",\n applies: all,\n });\n }\n for (const a of DEV_AGENTS) {\n m.push({\n source: `agents/${a}.md`,\n target: `.claude/agents/${a}.md`,\n type: \"file\",\n applies: dev,\n });\n }\n // v26.58.0 — Agents (ECC cherry-pick). ADR-019. C2: plugin OFF 시만 install (opt-out).\n for (const a of CORE_AGENTS_ECC) {\n m.push({\n source: `agents/${a}.md`,\n target: `.claude/agents/${a}.md`,\n type: \"file\",\n applies: (s) => !s.withEcc,\n });\n }\n for (const a of DEV_AGENTS_ECC) {\n m.push({\n source: `agents/${a}.md`,\n target: `.claude/agents/${a}.md`,\n type: \"file\",\n applies: (s) => !s.withEcc && hasDevTrack(s.tracks),\n });\n }\n\n // Common skill directories\n for (const sd of COMMON_SKILL_DIRS) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: all,\n });\n }\n // v26.58.0 — Common skill dirs (ECC cherry-pick). ADR-019. C2: plugin OFF 시만 install (opt-out).\n for (const sd of COMMON_SKILL_DIRS_ECC) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: (s) => !s.withEcc,\n });\n }\n // v26.58.0 — C3 (modified=true). plugin 으로 갈음 불가, 항상 install. ADR-019.\n for (const sd of MODIFIED_COMMON_SKILL_DIRS) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: all,\n });\n }\n m.push({\n source: \"skills/spec-scaling/SKILL.md\",\n target: \".claude/skills/spec-scaling/SKILL.md\",\n type: \"file\",\n applies: all,\n });\n m.push({\n source: \"skills/market-research\",\n target: \".claude/skills/market-research\",\n type: \"dir\",\n applies: onTracks(\"executive|full\"),\n });\n for (const sd of [\"investor-materials\", \"investor-outreach\"]) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: onTracks(\"executive|full\"),\n });\n }\n m.push({\n source: \"skills/nextjs-turbopack\",\n target: \".claude/skills/nextjs-turbopack\",\n type: \"dir\",\n applies: onTracks(\"ssr-nextjs|full\"),\n });\n // v26.58.0 — python-* / DEV_SKILL_DIRS / UI_SKILL_DIRS 중 ECC 출처는 opt-out gating. ADR-019. C2.\n for (const sd of PYTHON_SKILL_DIRS_ECC) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: (s) => !s.withEcc && anyTrack(s.tracks, \"data|csr-fastapi|full\"),\n });\n }\n for (const sd of DEV_SKILL_DIRS) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: dev,\n });\n }\n for (const sd of DEV_SKILL_DIRS_ECC) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: (s) => !s.withEcc && hasDevTrack(s.tracks),\n });\n }\n for (const sd of UI_SKILL_DIRS) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: ui,\n });\n }\n for (const sd of UI_SKILL_DIRS_ECC) {\n m.push({\n source: `skills/${sd}`,\n target: `.claude/skills/${sd}`,\n type: \"dir\",\n applies: (s) => !s.withEcc && hasUiTrack(s.tracks),\n });\n }\n\n // Hooks\n for (const h of ALWAYS_HOOKS) {\n m.push({\n source: `hooks/${h}`,\n target: `.claude/hooks/${h}`,\n type: \"file\",\n applies: all,\n });\n }\n\n // settings.json\n m.push({\n source: \"settings.json\",\n target: \".claude/settings.json\",\n type: \"file\",\n applies: all,\n });\n\n // Project root CLAUDE.md — handled outside manifest by `mergeProjectClaude`\n // (single/multi/full tracks all merged from fragments in installer.ts).\n\n return m;\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { anyTrack } from \"./track-match.js\";\nimport type { Track } from \"./types.js\";\n\nexport interface McpServerConfig {\n type?: \"stdio\" | \"http\";\n command: string;\n args: string[];\n env?: Record<string, string>;\n}\n\nexport interface McpJson {\n mcpServers: Record<string, McpServerConfig>;\n _comment?: string;\n}\n\nexport interface TrackMcpRow {\n name: string;\n pattern: string;\n command: string;\n args: string[];\n}\n\n/** Parse `templates/track-mcp-map.tsv` (tab-separated, comment-aware). */\nexport function parseTrackMcpMap(raw: string): TrackMcpRow[] {\n const rows: TrackMcpRow[] = [];\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) {\n continue;\n }\n const parts = line.split(\"\\t\");\n if (parts.length < 4) {\n continue;\n }\n const [name, pattern, command, argsJson] = parts;\n if (!name || !pattern || !command) {\n continue;\n }\n let args: unknown;\n try {\n args = JSON.parse(argsJson ?? \"[]\");\n } catch {\n continue;\n }\n if (!Array.isArray(args) || !args.every((a) => typeof a === \"string\")) {\n continue;\n }\n rows.push({ name, pattern, command, args: args as string[] });\n }\n return rows;\n}\n\n/**\n * Apply track-aware MCP rows to a base `.mcp.json` object.\n * Existing entries (including user customizations) are preserved.\n */\nexport function mergeMcpServers(\n base: McpJson,\n rows: ReadonlyArray<TrackMcpRow>,\n tracks: ReadonlyArray<Track>,\n): McpJson {\n const out: McpJson = {\n ...base,\n mcpServers: { ...base.mcpServers },\n };\n for (const row of rows) {\n if (!anyTrack(tracks, row.pattern)) {\n continue;\n }\n if (out.mcpServers[row.name]) {\n // Preserve existing — do not overwrite user customizations.\n continue;\n }\n out.mcpServers[row.name] = {\n type: \"stdio\",\n command: row.command,\n args: row.args,\n };\n }\n // Strip _comment marker (parity with the bash `jq 'del(._comment)'`).\n delete out._comment;\n return out;\n}\n\n/**\n * Compose the final `.mcp.json` for a project install.\n * Read base template + track map, merge with optional existing user file (additive).\n */\nexport function composeMcpJson(opts: {\n templateMcpPath: string;\n trackMapPath: string;\n existingPath?: string;\n tracks: ReadonlyArray<Track>;\n}): McpJson {\n const base = JSON.parse(readFileSync(opts.templateMcpPath, \"utf8\")) as McpJson;\n const merged =\n opts.existingPath && existsSync(opts.existingPath)\n ? mergeUserBase(base, opts.existingPath)\n : base;\n const mapRaw = existsSync(opts.trackMapPath) ? readFileSync(opts.trackMapPath, \"utf8\") : \"\";\n const rows = parseTrackMcpMap(mapRaw);\n return mergeMcpServers(merged, rows, opts.tracks);\n}\n\nfunction mergeUserBase(base: McpJson, existingPath: string): McpJson {\n try {\n const existing = JSON.parse(readFileSync(existingPath, \"utf8\")) as McpJson;\n return {\n ...base,\n mcpServers: { ...base.mcpServers, ...existing.mcpServers },\n };\n } catch {\n return base;\n }\n}\n\n/** Write the composed `.mcp.json` to disk (2-space pretty). */\nexport function writeMcpJson(path: string, mcp: McpJson): void {\n writeFileSync(path, `${JSON.stringify(mcp, null, 2)}\\n`);\n}\n","/**\n * OpenCode transform orchestrator — SSOT (templates/CLAUDE.md, .mcp.json,\n * templates/commands/uzys/*.md) → OpenCode 자산 4종.\n *\n * Inputs:\n * - harnessRoot: repository root (templates/ + .mcp.json)\n * - projectDir: target project to receive AGENTS.md + opencode.json + .opencode/\n *\n * Outputs (under projectDir):\n * - AGENTS.md\n * - opencode.json\n * - .opencode/commands/uzys-{phase}.md (6 commands)\n * - .opencode/plugins/uzys-harness.ts (1 plugin stub, Phase E1에서 본문 작성)\n *\n * SPEC: docs/specs/opencode-compat.md\n * Phase: C1 (transform orchestrator)\n */\n\nimport { copyFileSync, existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport { ensureDir } from \"../fs-ops.js\";\nimport type { McpJson } from \"../mcp-merge.js\";\nimport { renderAgentsMd } from \"./agents-md.js\";\nimport { renderCommand } from \"./commands.js\";\nimport { renderOpencodeJson } from \"./opencode-json.js\";\n\nexport interface OpencodeTransformParams {\n harnessRoot: string;\n projectDir: string;\n}\n\nexport interface OpencodeTransformReport {\n agentsMdPath: string;\n opencodeJsonPath: string;\n commandFiles: string[];\n pluginPath: string;\n}\n\nconst PHASES = [\"spec\", \"plan\", \"build\", \"test\", \"review\", \"ship\"];\n\nexport function runOpencodeTransform(params: OpencodeTransformParams): OpencodeTransformReport {\n const { harnessRoot, projectDir } = params;\n\n const claudeMd = readRequired(join(harnessRoot, \"templates/CLAUDE.md\"));\n const agentsTemplate = readRequired(join(harnessRoot, \"templates/opencode/AGENTS.md.template\"));\n const opencodeTemplate = readRequired(\n join(harnessRoot, \"templates/opencode/opencode.json.template\"),\n );\n const projectName = basename(projectDir);\n const mcp = readOptionalJson(join(harnessRoot, \".mcp.json\"));\n\n // 1. AGENTS.md\n ensureDir(projectDir);\n const agentsMdPath = join(projectDir, \"AGENTS.md\");\n writeFileSync(agentsMdPath, renderAgentsMd({ template: agentsTemplate, claudeMd, projectName }));\n\n // 2. opencode.json\n const opencodeJsonPath = join(projectDir, \"opencode.json\");\n writeFileSync(opencodeJsonPath, renderOpencodeJson({ template: opencodeTemplate, mcp }));\n\n // 3. .opencode/commands/uzys-{phase}.md\n const cmdDir = join(projectDir, \".opencode/commands\");\n ensureDir(cmdDir);\n const commandFiles: string[] = [];\n for (const phase of PHASES) {\n const cmdSrc = join(harnessRoot, \"templates/commands/uzys\", `${phase}.md`);\n let source = \"\";\n if (existsSync(cmdSrc)) {\n source = readFileSync(cmdSrc, \"utf8\");\n } else {\n const fallback = join(\n harnessRoot,\n \"templates/opencode/.opencode/commands\",\n `uzys-${phase}.md`,\n );\n if (existsSync(fallback)) {\n source = readFileSync(fallback, \"utf8\");\n }\n }\n const target = join(cmdDir, `uzys-${phase}.md`);\n writeFileSync(target, renderCommand({ source, phase }));\n commandFiles.push(target);\n }\n\n // 4. .opencode/plugins/uzys-harness.ts (static copy from template; Phase E1 fills body)\n const pluginDir = join(projectDir, \".opencode/plugins\");\n ensureDir(pluginDir);\n const pluginPath = join(pluginDir, \"uzys-harness.ts\");\n const pluginSrc = join(harnessRoot, \"templates/opencode/.opencode/plugins/uzys-harness.ts\");\n if (existsSync(pluginSrc)) {\n copyFileSync(pluginSrc, pluginPath);\n } else {\n writeFileSync(pluginPath, \"// uzys-harness plugin stub (template missing)\\n\");\n }\n\n return { agentsMdPath, opencodeJsonPath, commandFiles, pluginPath };\n}\n\nfunction readRequired(path: string): string {\n if (!existsSync(path)) {\n throw new Error(`OpenCode transform: required source missing: ${path}`);\n }\n return readFileSync(path, \"utf8\");\n}\n\nfunction readOptionalJson(path: string): McpJson | null {\n if (!existsSync(path)) {\n return null;\n }\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as McpJson;\n } catch {\n return null;\n }\n}\n","/**\n * AGENTS.md transform — CLAUDE.md → AGENTS.md (OpenCode flavor).\n *\n * Mirrors `src/codex/agents-md.ts` logic (Codex와 OpenCode 둘 다 콜론 namespace\n * 미사용으로 slash rename 동일). 별도 파일로 유지 — 모듈 독립성.\n *\n * v26.70.0 — section 추출 → CLAUDE.md 전문 embed (`{PROJECT_RULES}`). codex/agents-md 와 동일 fix.\n */\n\n/** Rename Claude slash conventions (`/uzys:foo`) to OpenCode (`/uzys-foo`). */\nexport function renameSlashes(text: string): string {\n return text.replaceAll(\"/uzys:\", \"/uzys-\");\n}\n\nexport interface AgentsMdParams {\n template: string;\n claudeMd: string;\n projectName: string;\n}\n\n/**\n * Render the OpenCode AGENTS.md output by embedding the full CLAUDE.md body.\n *\n * Placeholders (matches templates/opencode/AGENTS.md.template):\n * - {PROJECT_NAME} — basename of project dir\n * - {PROJECT_RULES} — full CLAUDE.md body (first h1 stripped)\n */\nexport function renderAgentsMd(params: AgentsMdParams): string {\n const body = params.claudeMd.replace(/^#\\s+.*\\r?\\n/, \"\").trim();\n const replaced = params.template\n .replaceAll(\"{PROJECT_NAME}\", params.projectName)\n .replaceAll(\"{PROJECT_RULES}\", body);\n return renameSlashes(replaced);\n}\n","/**\n * Claude `.claude/commands/uzys/<phase>.md` → OpenCode `.opencode/commands/uzys-<phase>.md`.\n *\n * 차이 (Codex skills.ts와):\n * - OpenCode 파일명 = 슬래시 커맨드명 → `uzys-<phase>.md` 형식\n * - Frontmatter: `description` + `agent` (build/plan), `name` 필드 없음 (filename 자체)\n */\nimport { renameSlashes } from \"./agents-md.js\";\n\nexport interface RenderCommandParams {\n /** Original uzys command markdown (frontmatter optional). */\n source: string;\n /** Phase identifier (spec, plan, build, test, review, ship). */\n phase: string;\n}\n\nconst AGENT_BY_PHASE: Record<string, string> = {\n spec: \"plan\",\n plan: \"plan\",\n build: \"build\",\n test: \"build\",\n review: \"plan\",\n ship: \"build\",\n};\n\n/**\n * Render an OpenCode `.opencode/commands/uzys-<phase>.md` from a Claude\n * `.claude/commands/uzys/<phase>.md` source. Slash references are renamed.\n */\nexport function renderCommand(params: RenderCommandParams): string {\n const { description, body } = parseSource(params.source);\n const finalDescription = description || `uzys-${params.phase} phase command (OpenCode 포팅)`;\n const escapedDesc = finalDescription.replace(/\"/g, '\\\\\"');\n const agent = AGENT_BY_PHASE[params.phase] ?? \"build\";\n const renamedBody = renameSlashes(body).trimEnd();\n\n return [\n \"---\",\n `description: \"${escapedDesc}\"`,\n `agent: ${agent}`,\n \"---\",\n \"\",\n renamedBody,\n \"\",\n ].join(\"\\n\");\n}\n\ninterface ParsedSource {\n description: string;\n body: string;\n}\n\nfunction parseSource(source: string): ParsedSource {\n const lines = source.split(/\\r?\\n/);\n if (lines[0] === \"---\") {\n let descMatch = \"\";\n let secondDelimAt = -1;\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (line === \"---\") {\n secondDelimAt = i;\n break;\n }\n const match = line.match(/^description:\\s*(.*)$/);\n if (match) {\n descMatch = stripQuotes(match[1] ?? \"\");\n }\n }\n const body = secondDelimAt >= 0 ? lines.slice(secondDelimAt + 1).join(\"\\n\") : source;\n return { description: descMatch, body: body.replace(/^\\n+/, \"\") };\n }\n const firstLine = lines[0] ?? \"\";\n const body = lines.slice(1).join(\"\\n\");\n return { description: firstLine.trim(), body };\n}\n\nfunction stripQuotes(raw: string): string {\n const trimmed = raw.trim();\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n}\n","/**\n * opencode.json transform — fill template + merge mcp.<name> from .mcp.json.\n *\n * Output: opencode.json (top-level `mcp.<name>` map; OpenCode 1:1 매핑).\n *\n * Codex `[mcp_servers.X]` TOML과 다르게 OpenCode는 JSON이라 Object spread\n * 만으로 충분 (TOML 직렬화 없음).\n */\n\nimport type { McpJson, McpServerConfig } from \"../mcp-merge.js\";\n\nexport interface RenderOpencodeJsonParams {\n /** Template content (templates/opencode/opencode.json.template). */\n template: string;\n /** Source `.mcp.json` (parsed). When provided, top-level `mcp.<name>` is replaced. */\n mcp?: McpJson | null;\n}\n\ninterface OpencodeConfig {\n $schema?: string;\n instructions?: string[];\n mcp?: Record<string, McpServerConfig>;\n command?: Record<string, unknown>;\n agent?: Record<string, unknown>;\n plugin?: string[];\n permission?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\n/**\n * Substitute `mcp` in the template with entries from `.mcp.json`.\n * Other keys (`agent`, `command`, `plugin`, `permission`, `instructions`,\n * `$schema`) are preserved from the template.\n */\nexport function renderOpencodeJson(params: RenderOpencodeJsonParams): string {\n const config = parseTemplate(params.template);\n\n if (params.mcp) {\n config.mcp = { ...params.mcp.mcpServers };\n }\n\n return `${JSON.stringify(config, null, 2)}\\n`;\n}\n\nfunction parseTemplate(template: string): OpencodeConfig {\n try {\n return JSON.parse(template) as OpencodeConfig;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`opencode.json template invalid JSON: ${message}`);\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Track } from \"./types.js\";\n\nexport const SECTIONS = [\n \"stack\",\n \"workflow\",\n \"active-rules\",\n \"agents\",\n \"skills\",\n \"plugins\",\n \"commands\",\n \"boundaries\",\n \"supabase-auth\",\n] as const;\nexport type Section = (typeof SECTIONS)[number];\n\nconst SECTION_TITLES: Record<Section, string> = {\n stack: \"Stack\",\n workflow: \"Workflow\",\n \"active-rules\": \"Active Rules\",\n agents: \"Agents\",\n skills: \"Skills\",\n plugins: \"Plugins\",\n commands: \"Commands\",\n boundaries: \"Boundaries\",\n \"supabase-auth\": \"Supabase auth configuration\",\n};\n\nexport const TRACK_DISPLAY_NAMES: Record<Track, string> = {\n tooling: \"Tooling\",\n \"csr-supabase\": \"CSR Supabase\",\n \"csr-fastify\": \"CSR Fastify\",\n \"csr-fastapi\": \"CSR FastAPI\",\n \"ssr-htmx\": \"SSR HTMX\",\n \"ssr-nextjs\": \"SSR Next.js\",\n data: \"Data\",\n executive: \"Executive\",\n full: \"Full\",\n \"project-management\": \"Project Management\",\n \"growth-marketing\": \"Growth Marketing\",\n};\n\n/** Tracks expanded when 'full' is selected — every track except 'full' itself. */\nconst FULL_EXPANSION: ReadonlyArray<Track> = [\n \"tooling\",\n \"csr-fastapi\",\n \"csr-fastify\",\n \"csr-supabase\",\n \"ssr-htmx\",\n \"ssr-nextjs\",\n \"data\",\n \"executive\",\n \"project-management\",\n \"growth-marketing\",\n];\n\nexport interface MergeOptions {\n /** Path to `templates/project-claude/` directory. */\n baseDir: string;\n}\n\n/**\n * Build the project root CLAUDE.md by merging `_base.md` with track fragments.\n * - Single track: section bodies inserted verbatim under each `## Section` header.\n * - Multi track: each track's fragment prefixed with `### <Display Name>` subheader.\n * - Section with no fragments from any selected track: section omitted entirely.\n * - 'full' track: expanded to every non-full track.\n */\nexport function mergeProjectClaude(tracks: ReadonlyArray<Track>, opts: MergeOptions): string {\n const expanded = expandTracks(tracks);\n const baseRaw = readFileSync(join(opts.baseDir, \"_base.md\"), \"utf8\");\n\n let output = baseRaw;\n output = output.replace(\"<!-- INSERT: track-list -->\", trackList(expanded));\n output = output.replace(\"<!-- INSERT: tagline -->\", taglineList(expanded, opts.baseDir));\n\n for (const section of SECTIONS) {\n const marker = `<!-- INSERT: ${section} -->`;\n const block = renderSection(section, expanded, opts.baseDir);\n if (block === null) {\n output = stripMarkerLine(output, marker);\n } else {\n output = output.replace(marker, block);\n }\n }\n\n return `${output.replace(/\\n{3,}/g, \"\\n\\n\").trimEnd()}\\n`;\n}\n\nfunction expandTracks(tracks: ReadonlyArray<Track>): ReadonlyArray<Track> {\n if (tracks.includes(\"full\")) {\n return FULL_EXPANSION;\n }\n return tracks;\n}\n\nfunction trackList(tracks: ReadonlyArray<Track>): string {\n return tracks.map((t) => TRACK_DISPLAY_NAMES[t]).join(\", \");\n}\n\nfunction taglineList(tracks: ReadonlyArray<Track>, baseDir: string): string {\n const taglines: string[] = [];\n for (const t of tracks) {\n const path = join(baseDir, \"fragments\", t, \"tagline.md\");\n if (!existsSync(path)) {\n continue;\n }\n const body = readFileSync(path, \"utf8\").trim();\n if (body) {\n taglines.push(body);\n }\n }\n return taglines.join(\" / \");\n}\n\nfunction renderSection(\n section: Section,\n tracks: ReadonlyArray<Track>,\n baseDir: string,\n): string | null {\n const present: { track: Track; body: string }[] = [];\n for (const t of tracks) {\n const path = join(baseDir, \"fragments\", t, `${section}.md`);\n if (!existsSync(path)) {\n continue;\n }\n const body = readFileSync(path, \"utf8\").trim();\n if (body) {\n present.push({ track: t, body });\n }\n }\n if (present.length === 0) {\n return null;\n }\n const title = `## ${SECTION_TITLES[section]}`;\n if (present.length === 1 && present[0]) {\n return `${title}\\n\\n${present[0].body}\\n`;\n }\n const blocks = present.map(({ track, body }) => `### ${TRACK_DISPLAY_NAMES[track]}\\n\\n${body}`);\n return `${title}\\n\\n${blocks.join(\"\\n\\n\")}\\n`;\n}\n\n/** Remove a marker line plus the leading blank line that separates it from the previous block. */\nfunction stripMarkerLine(text: string, marker: string): string {\n const escaped = marker.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const pattern = new RegExp(`\\\\n*${escaped}\\\\n*`);\n return text.replace(pattern, \"\\n\");\n}\n","/**\n * settings.json 부분 머지 — `.claude/settings.json` PreToolUse hook entry 추가.\n *\n * SPEC: docs/specs/karpathy-hook-autowire.md AC2/AC4 — opt-in 시 idempotent 등록.\n *\n * 사용처: karpathy-coder hook auto-wire (v0.6.0). 기존 매처 entry 보존 + 동일 command 중복 X.\n */\n\nexport interface ClaudeHookCommand {\n type: \"command\";\n command: string;\n async?: boolean;\n timeout?: number;\n}\n\nexport interface ClaudeHookMatcher {\n matcher?: string;\n hooks: ClaudeHookCommand[];\n}\n\nexport interface ClaudeSettings {\n // 기타 키 (statusLine, _comment 등) 보존 — 알 필요 없음\n [key: string]: unknown;\n hooks?: {\n [event: string]: ClaudeHookMatcher[];\n };\n}\n\n/**\n * PreToolUse 배열에 hook entry 추가 (idempotent). 기존 settings 객체는 mutation 안 함 (deep clone).\n *\n * 동작:\n * - hooks.PreToolUse 없음 → 생성\n * - matcher 일치하는 entry 없음 → 새 entry 추가\n * - matcher 일치 + command 동일한 hook 있음 → idempotent (변경 없음)\n * - matcher 일치 + command 다름 → hooks 배열에 append\n */\nexport function addPreToolUseHook(\n settings: ClaudeSettings,\n matcher: string,\n command: string,\n): ClaudeSettings {\n const next: ClaudeSettings = JSON.parse(JSON.stringify(settings));\n if (!next.hooks) {\n next.hooks = {};\n }\n if (!next.hooks.PreToolUse) {\n next.hooks.PreToolUse = [];\n }\n const preToolUse = next.hooks.PreToolUse;\n const existing = preToolUse.find((m) => m.matcher === matcher);\n const newHook: ClaudeHookCommand = { type: \"command\", command };\n if (existing) {\n if (existing.hooks.some((h) => h.command === command)) {\n return next; // idempotent — 동일 command 중복 X\n }\n existing.hooks.push(newHook);\n } else {\n preToolUse.push({ matcher, hooks: [newHook] });\n }\n return next;\n}\n","/**\n * update-mode.ts — Update / Add / Reinstall router 액션 처리.\n *\n * SPEC: docs/specs/cli-rewrite-completeness.md F5, F6\n * Source: bash setup-harness.sh@911c246~1 L460~573 (update mode 113 LOC)\n *\n * Update 모드 동작:\n * 1. backup: .claude/ → .claude.backup-<timestamp>/\n * 2. update_dir: target에 이미 존재하는 파일만 templates로 덮어쓰기 (Track 혼입 방지)\n * 3. prune_orphans: templates에 없는데 target에 있는 파일 제거 (예: 폐기된 rule)\n * 4. clean_stale_hook_refs: settings.json hook 참조 중 실존 파일 없는 것 제거\n *\n * 보존: gate-status.json, .mcp.json (사용자 추가 항목), docs/SPEC.md, settings.local.json\n */\n\nimport {\n copyFileSync,\n existsSync,\n readdirSync,\n readFileSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport interface UpdateModeReport {\n /** 덮어쓰기된 파일 갯수 (디렉토리별). */\n updated: Record<string, number>;\n /** 제거된 orphan 파일명 목록 (디렉토리별). */\n pruned: Record<string, string[]>;\n /** 제거된 stale hook ref 파일명 목록. */\n staleHookRefs: string[];\n /** 갱신된 CLAUDE.md (true if updated). */\n claudeMdUpdated: boolean;\n}\n\n/**\n * Update mode 메인 — backup은 caller가 별도 처리.\n *\n * @param projectDir 대상 프로젝트 root\n * @param templatesDir templates/ 디렉토리 (sync source)\n */\nexport function runUpdateMode(projectDir: string, templatesDir: string): UpdateModeReport {\n const claudeDir = join(projectDir, \".claude\");\n const report: UpdateModeReport = {\n updated: {},\n pruned: {},\n staleHookRefs: [],\n claudeMdUpdated: false,\n };\n\n // 1) update_dir × 4 (rules/agents/commands/uzys/hooks)\n const targets = [\n {\n target: join(claudeDir, \"rules\"),\n source: join(templatesDir, \"rules\"),\n pattern: \".md\",\n label: \".claude/rules\",\n },\n {\n target: join(claudeDir, \"agents\"),\n source: join(templatesDir, \"agents\"),\n pattern: \".md\",\n label: \".claude/agents\",\n },\n {\n target: join(claudeDir, \"commands/uzys\"),\n source: join(templatesDir, \"commands/uzys\"),\n pattern: \".md\",\n label: \".claude/commands/uzys\",\n },\n {\n target: join(claudeDir, \"hooks\"),\n source: join(templatesDir, \"hooks\"),\n pattern: \".sh\",\n label: \".claude/hooks\",\n },\n ];\n\n for (const t of targets) {\n report.updated[t.label] = updateDir(t.target, t.source, t.pattern);\n report.pruned[t.label] = pruneOrphans(t.target, t.source, t.pattern);\n }\n\n // 2) .claude/CLAUDE.md\n const claudeMd = join(claudeDir, \"CLAUDE.md\");\n const templateMd = join(templatesDir, \"CLAUDE.md\");\n if (existsSync(claudeMd) && existsSync(templateMd)) {\n copyFileSync(templateMd, claudeMd);\n report.claudeMdUpdated = true;\n }\n\n // 3) settings.json stale hook ref cleanup\n const settingsPath = join(claudeDir, \"settings.json\");\n if (existsSync(settingsPath)) {\n report.staleHookRefs = cleanStaleHookRefs(settingsPath, join(claudeDir, \"hooks\"));\n }\n\n return report;\n}\n\n/**\n * `target`에 이미 존재하는 파일 중 `source`에 동일 이름 있는 것만 덮어쓰기.\n * Track 혼입 방지 (새 파일 추가 X) — bash update_dir 등가.\n */\nexport function updateDir(target: string, source: string, ext: string): number {\n if (!existsSync(target) || !existsSync(source)) return 0;\n let count = 0;\n for (const file of readdirSync(target)) {\n if (!file.endsWith(ext)) continue;\n const targetFile = join(target, file);\n const sourceFile = join(source, file);\n if (existsSync(sourceFile)) {\n copyFileSync(sourceFile, targetFile);\n count++;\n }\n }\n return count;\n}\n\n/**\n * Templates에 없는데 target에 있는 파일 제거 (orphan prune) — bash prune_orphans 등가.\n */\nexport function pruneOrphans(target: string, source: string, ext: string): string[] {\n if (!existsSync(target) || !existsSync(source)) return [];\n const removed: string[] = [];\n for (const file of readdirSync(target)) {\n if (!file.endsWith(ext)) continue;\n const sourceFile = join(source, file);\n if (!existsSync(sourceFile)) {\n const targetFile = join(target, file);\n try {\n unlinkSync(targetFile);\n removed.push(file);\n } catch {\n // best-effort — read-only? 다음 update 시 재시도\n }\n }\n }\n return removed;\n}\n\n/**\n * settings.json의 PreToolUse/PostToolUse hooks 중 실존 파일 없는 hook script 참조 제거.\n * bash clean_stale_hook_refs 등가 (jq 의존 없이 JSON 직접 파싱).\n *\n * @returns 제거된 hook script 파일명 목록\n */\nexport function cleanStaleHookRefs(settingsPath: string, hooksDir: string): string[] {\n let settings: SettingsJson;\n try {\n settings = JSON.parse(readFileSync(settingsPath, \"utf8\")) as SettingsJson;\n } catch {\n return [];\n }\n const hookEvents = settings.hooks ?? {};\n const removed: string[] = [];\n const cleanedHooks: Record<string, HookEntry[]> = {};\n\n for (const [eventName, eventEntries] of Object.entries(hookEvents)) {\n if (!Array.isArray(eventEntries)) {\n cleanedHooks[eventName] = eventEntries; // non-array event — 그대로 보존\n continue;\n }\n cleanedHooks[eventName] = eventEntries\n .filter((entry) => Array.isArray(entry?.hooks))\n .map((entry) => ({\n ...entry,\n hooks: entry.hooks.filter((hook) => keepHookRef(hook, hooksDir, removed)),\n }))\n .filter((entry) => entry.hooks.length > 0); // stale 제거 후 hooks 빈 entry 제거\n }\n\n if (removed.length > 0) {\n const next: SettingsJson = { ...settings, hooks: cleanedHooks };\n writeFileSync(settingsPath, `${JSON.stringify(next, null, 2)}\\n`);\n }\n return removed;\n}\n\n/** hook command 가 실존 `.sh` 참조면 true. stale(파일 부재) 이면 removed 에 fname 수집 후 false. */\nfunction keepHookRef(hook: HookCommand, hooksDir: string, removed: string[]): boolean {\n const refMatch = (hook?.command ?? \"\").match(/\\/\\.claude\\/hooks\\/([^\"\\s/]+\\.sh)/);\n if (!refMatch?.[1]) return true; // hook script 참조 아님 — 보존\n const fname = refMatch[1];\n const exists = existsSync(join(hooksDir, fname));\n if (!exists && !removed.includes(fname)) removed.push(fname);\n return exists;\n}\n\ninterface HookCommand {\n type?: string;\n command?: string;\n}\n\ninterface HookEntry {\n matcher?: string;\n hooks: HookCommand[];\n}\n\ninterface SettingsJson {\n hooks?: Record<string, HookEntry[]>;\n [key: string]: unknown;\n}\n","/**\n * Install 출력 렌더 레이어 (v26.82.0, Phase R).\n *\n * `commands/install.ts` 가 979줄(cap 800 초과 — repo 최대 위반)로 비대해진 원인이\n * 렌더 함수 누적이었음 → 본 파일로 추출. install.ts 는 spec 검증 + 파이프라인\n * 오케스트레이션만, 여기는 화면 출력만. 동작 변경 0 (순수 이동).\n */\n\nimport { CATEGORY_TITLES, type Category } from \"../categories.js\";\nimport { targetsInclude } from \"../cli-targets.js\";\nimport { assetRow, c, infoRow, padDisplay, sectionHeader, unifiedSection } from \"../design.js\";\nimport {\n type ExternalAsset,\n experimentalOptInCandidates,\n isAssetSelected,\n} from \"../external-assets.js\";\nimport type { AssetInstallResult } from \"../external-installer.js\";\nimport type { BaselineReport, InstallMode, InstallReport, ProgressEvent } from \"../installer.js\";\nimport { finalSelectedAssets, groupAssetsByCategory } from \"../preset-recommend.js\";\nimport type { CliBase, CliTargets, InstallSpec, OptionFlags } from \"../types.js\";\n\n/**\n * v26.78.1 — Summary `CLI` 행 라벨 (SSOT). spec.cli 에서 derive → 헤더와 일관.\n * 이전 pairwise if-chain 은 codex/opencode 만 열거해 `--cli antigravity` 가 \"Claude\" 로\n * 잘못 출력 (R2). 4 base 전부 매핑.\n */\nconst CLI_SUMMARY_LABELS: Record<CliBase, string> = {\n claude: \"Claude\",\n codex: \"Codex\",\n opencode: \"OpenCode\",\n antigravity: \"Antigravity\",\n};\n\n/** Callbacks for progressive rendering during runInstall (avoids \"Phase 1 silence\" UX). */\nexport interface PipelineCallbacks {\n onProgress?: (event: ProgressEvent) => void;\n externalDeps?: {\n onAssetStart?: (asset: ExternalAsset) => void;\n onAssetResult?: (result: AssetInstallResult) => void;\n };\n}\n\n/** createInstallRenderer 반환 — 스트리밍 콜백 + 렌더 상태 조회. */\nexport interface InstallRenderer {\n callbacks: PipelineCallbacks;\n /** External assets 헤더 출력 여부 — Summary 직전 trailing newline 판단용. */\n phase2HeaderPrinted(): boolean;\n}\n\n/**\n * install header (TARGET / TRACKS / CLI / SCOPE / OPTIONS / ASSETS) 렌더.\n * wizard 모드는 Step 3 review + Step 4 confirm 에서 이미 표시하므로 호출 안 함.\n */\nexport function renderInstallHeader(\n log: (msg: string) => void,\n spec: InstallSpec,\n mode?: InstallMode,\n): void {\n const headerLabel =\n mode === \"update\"\n ? \"uzys-agent-harness · update\"\n : mode === \"add\"\n ? \"uzys-agent-harness · add\"\n : mode === \"reinstall\"\n ? \"uzys-agent-harness · reinstall\"\n : \"uzys-agent-harness · install\";\n log(\"\");\n log(sectionHeader(headerLabel));\n log(\"\");\n log(infoRow(\"TARGET\", shortenPath(spec.projectDir)));\n log(infoRow(\"TRACKS\", spec.tracks.join(\", \")));\n log(infoRow(\"CLI\", spec.cli.join(\" · \")));\n // v26.64.0 (ADR-020) — SCOPE row. 사용자가 매 install 시 어디에 write 되는지 인지 (D16).\n {\n const effectiveScope = spec.scope ?? \"project\";\n const scopeMsg =\n effectiveScope === \"global\"\n ? \"Global — writes to ~/.claude/, ~/.codex/, npm -g\"\n : \"Project — current directory only (no global write)\";\n log(infoRow(\"SCOPE\", scopeMsg));\n }\n log(infoRow(\"OPTIONS\", formatOptions(spec)));\n // v26.82.0 (Phase R, S6) — merge 는 preset-recommend.ts 단일 구현 (이전 computeFinalAssets 중복).\n const finalAssets = finalSelectedAssets(spec.tracks, spec.userOverride);\n if (finalAssets.length > 0) {\n log(infoRow(\"ASSETS\", `${finalAssets.length} selected`));\n for (const [cat, ids] of groupAssetsByCategory(finalAssets)) {\n log(` ${c.dim(`· ${cat}:`)} ${ids.join(\", \")}`);\n }\n }\n log(\"\");\n}\n\n/**\n * runInstall 스트리밍 렌더 콜백 생성 — baseline 완료 시 즉시 Phase 1 rows 출력,\n * external 은 per-asset 스트리밍 + 카테고리 헤더 (ADR-016 grouped progress UX).\n */\nexport function createInstallRenderer(\n log: (msg: string) => void,\n spec: InstallSpec,\n verbose: boolean,\n): InstallRenderer {\n let phase2HeaderPrinted = false;\n // v26.55.0 — Phase 2 grouped progress UX (ADR-016). category 변경 시 ━━ <Title> ━━ 헤더 출력.\n // external-installer 가 카테고리 순서로 정렬해 호출 → 첫 번째 호출이 category 1 의 첫 자산.\n let currentCategory: Category | null = null;\n const callbacks: PipelineCallbacks = {\n onProgress: (event) => {\n if (event.type === \"baseline-complete\") {\n // v26.81.0 (ADR-022) — withEcc boolean 삭제 → ecc-plugin 자산 선택으로 판정 (hint 게이팅).\n const eccSelected = isAssetSelected(\"ecc-plugin\", spec) || spec.options.withPrune === true;\n renderPhase1Rows(log, event.baseline, verbose, eccSelected);\n } else if (event.type === \"external-start\" && event.assetCount > 0) {\n // v26.63.0 — phaseHeader → unifiedSection. count 헤더에 inline 표시.\n log(unifiedSection(`External assets (${event.assetCount})`));\n log(\"\");\n phase2HeaderPrinted = true;\n }\n },\n externalDeps: {\n onAssetStart: (asset) => {\n // v26.57.0 (F2) — 카테고리 헤더만 출력. 자산 시작 라인 (→) 제거 — ✓ 결과 한 라인으로 1 단위 명확화.\n if (asset.category !== currentCategory) {\n if (currentCategory !== null) log(\"\");\n log(` ${c.bold(`━━ ${CATEGORY_TITLES[asset.category]} ━━`)}`);\n currentCategory = asset.category;\n }\n },\n onAssetResult: (result) => {\n const meta = result.ok\n ? formatAssetMeta(result.asset, result.version)\n : (result.message ?? \"failed\");\n log(` ${assetRow(result.ok ? \"success\" : \"skip\", result.asset.id, meta)}`);\n },\n },\n };\n return { callbacks, phase2HeaderPrinted: () => phase2HeaderPrinted };\n}\n\n/** Update mode 단축 Summary — manifest copy / external 모두 skip 된 경로. */\nexport function renderUpdateSummary(log: (msg: string) => void, report: InstallReport): void {\n log(\"\");\n // v26.63.2 — Summary 도 unifiedSection 으로 통일 (━━ marker). Step 5 안 sub-section 들과 일관.\n log(unifiedSection(\"Summary\"));\n log(\"\");\n log(infoRow(\"STATUS\", c.green(\"Update complete\")));\n log(infoRow(\"MODE\", \"update\"));\n if (report.backup) {\n log(infoRow(\"BACKUP\", shortenPath(report.backup)));\n log(infoRow(\"ROLLBACK\", `rm -rf .claude && mv ${shortenPath(report.backup)} .claude`));\n }\n log(\"\");\n}\n\n/**\n * Codex / OpenCode / Antigravity 산출물 sub-section.\n * v26.78.1 (R2): antigravity 추가 — `--cli antigravity` 시 산출물 invisible 이던 버그 fix.\n * 산출물 report 가 없거나 해당 CLI 미선택 시 출력 없음 (이전 executeSpec 의 게이트 if 이동).\n */\nexport function renderCliArtifacts(\n log: (msg: string) => void,\n spec: InstallSpec,\n report: InstallReport,\n): void {\n const hasArtifacts = Boolean(report.codex || report.opencode || report.antigravity);\n const cliSelected =\n targetsInclude(spec.cli, \"codex\") ||\n targetsInclude(spec.cli, \"opencode\") ||\n targetsInclude(spec.cli, \"antigravity\");\n if (!hasArtifacts || !cliSelected) {\n return;\n }\n log(unifiedSection(formatCliPhaseTitle(spec.cli)));\n log(\"\");\n // AGENTS.md is shared across Codex/OpenCode — render once with shared note\n if (report.codex && report.opencode) {\n log(assetRow(\"success\", \"AGENTS.md\", \"shared (Codex + OpenCode)\"));\n } else if (report.codex || report.opencode) {\n log(assetRow(\"success\", \"AGENTS.md\", \"from .claude/CLAUDE.md\"));\n }\n if (report.codex) {\n log(assetRow(\"success\", \".codex/config.toml\", \"settings + [mcp_servers.*]\"));\n log(assetRow(\"success\", \".codex/hooks/\", `${report.codex.hookFiles.length} files`));\n log(\n assetRow(\n \"success\",\n \".agents/skills/uzys-*/SKILL.md\",\n `${report.codex.skillFiles.length} skills ($uzys-spec mention)`,\n ),\n );\n // v0.7.1 — project-scoped prompts pre-positioning (글로벌 영향 0)\n if (report.codex.promptFiles.length > 0) {\n log(\n assetRow(\n \"success\",\n \".codex/prompts/uzys-*.md\",\n `${report.codex.promptFiles.length} prompts — pre-positioned for upstream #9848 (not active yet; use Global for working ~/.codex/prompts/)`,\n ),\n );\n }\n // Codex global opt-in (D16) — only when explicitly enabled\n if (report.codexOptIn) {\n if (report.codexOptIn.skillsInstalled.enabled) {\n log(\n assetRow(\n \"success\",\n \"~/.codex/skills/uzys-*\",\n `${report.codexOptIn.skillsInstalled.count} copied (global opt-in)`,\n ),\n );\n }\n if (report.codexOptIn.trustEntry.enabled) {\n const trust = report.codexOptIn.trustEntry;\n const kind = trust.status === \"error\" ? \"skip\" : \"success\";\n const meta =\n trust.status === \"registered\"\n ? '[projects.\"<dir>\"] trust_level=\"trusted\"'\n : trust.status === \"already-present\"\n ? \"already present\"\n : (trust.message ?? \"error\");\n log(assetRow(kind, \"~/.codex/config.toml trust entry\", meta));\n }\n // v0.7.0 — Codex prompts (slash 통일) opt-in 결과\n if (report.codexOptIn.promptsInstalled.enabled) {\n const count = report.codexOptIn.promptsInstalled.count;\n log(\n assetRow(\n count > 0 ? \"success\" : \"skip\",\n \"~/.codex/prompts/uzys-*\",\n `${count} markdown copied (/uzys-spec slash 등록)`,\n ),\n );\n }\n }\n }\n if (report.opencode) {\n log(assetRow(\"success\", \"opencode.json\", \"$schema + 5 keys\"));\n log(assetRow(\"success\", \".opencode/commands/\", `${report.opencode.commandFiles.length} files`));\n log(assetRow(\"success\", \".opencode/plugins/uzys-harness.ts\", \"self-contained plugin\"));\n }\n // v26.78.1 (R2) — Antigravity 산출물. rules 항상, skills/workflows 는 uzys-harness 선택 시만.\n if (report.antigravity) {\n if (report.antigravity.rulesFile) {\n log(assetRow(\"success\", \".agents/rules/uzys-harness.md\", \"from .claude/CLAUDE.md\"));\n }\n if (report.antigravity.skillFiles.length > 0) {\n log(\n assetRow(\n \"success\",\n \".agents/skills/uzys-*/SKILL.md\",\n `${report.antigravity.skillFiles.length} skills`,\n ),\n );\n }\n if (report.antigravity.workflowFiles.length > 0) {\n log(\n assetRow(\n \"success\",\n \".agents/workflows/uzys-*.md\",\n `${report.antigravity.workflowFiles.length} workflows`,\n ),\n );\n }\n // Antigravity global opt-in (D16) — only when explicitly enabled.\n if (report.antigravityOptIn) {\n const opt = report.antigravityOptIn;\n if (opt.skillsInstalled.enabled) {\n log(\n assetRow(\n \"success\",\n \"~/.gemini/antigravity/skills/uzys-*\",\n `${opt.skillsInstalled.count} copied (global opt-in)`,\n ),\n );\n }\n if (opt.workflowsInstalled.enabled) {\n log(\n assetRow(\n \"success\",\n \"~/.gemini/antigravity/global_workflows/uzys-*\",\n `${opt.workflowsInstalled.count} copied (global opt-in)`,\n ),\n );\n }\n }\n }\n log(\"\");\n}\n\n/** 최종 Summary (STATUS / TRACKS / CLI / HOOK / WARN / OPT-IN / NEXT). */\nexport function renderFinalSummary(\n log: (msg: string) => void,\n spec: InstallSpec,\n report: InstallReport,\n fromWizard: boolean,\n): void {\n // v26.63.2 — Summary 도 unifiedSection 으로 통일 (━━ marker).\n log(unifiedSection(\"Summary\"));\n log(\"\");\n log(infoRow(\"STATUS\", c.green(\"Install complete\")));\n log(infoRow(\"TRACKS\", report.installedTracks.join(\", \")));\n // v26.63.4 (P3): install header `CLI` 와 Summary `CLIs` 라벨 불일치 → `CLI` 로 통일.\n // v26.78.1 (R2): pairwise if-chain → spec.cli derive. antigravity 누락 + claude 무조건\n // prepend(claude 미선택 시에도 \"Claude\" 표기) 버그 fix. 헤더와 동일 SSOT.\n log(infoRow(\"CLI\", spec.cli.map((b) => CLI_SUMMARY_LABELS[b]).join(\" · \")));\n // v26.78.1 (R1) — karpathy hook opt-in 결과 렌더. null = 미opt-in(표시 안 함).\n // 이전엔 wired=false(plugin install 실패 등)여도 무음 → 사용자가 hook 안 깔린 걸\n // 모른 채 \"Install complete\" 만 봄 (Rule 12 fail-loud 위반).\n if (report.karpathyHook) {\n const kh = report.karpathyHook;\n if (kh.wired) {\n log(infoRow(\"HOOK\", c.green(\"karpathy-coder pre-commit hook wired\")));\n } else {\n log(infoRow(\"HOOK\", c.yellow(`karpathy hook skipped — ${kh.reason ?? \"unknown\"}`)));\n }\n }\n if (report.external && report.external.skipped > 0) {\n log(\"\");\n log(\n infoRow(\n \"WARN\",\n c.yellow(\n `${report.external.skipped} external asset${report.external.skipped > 1 ? \"s\" : \"\"} skipped (see Phase 2 above)`,\n ),\n ),\n );\n }\n // v26.71.1 — experimental(T3) opt-in discoverability (Transparent Defaults — 숨김 0건).\n // 비대화형(--track) 에서 condition 은 맞지만 T3 라 default 제외된 자산을 --with 안내.\n // wizard 모드는 이미 ⚠ 배지로 노출하므로 skip.\n if (!fromWizard) {\n const optIn = experimentalOptInCandidates(spec);\n if (optIn.length > 0) {\n log(\"\");\n log(\n infoRow(\n \"OPT-IN\",\n c.dim(\n `${optIn.length} experimental available — add with --with <id>: ${optIn.map((a) => a.id).join(\", \")}`,\n ),\n ),\n );\n }\n }\n log(\"\");\n // v26.84.0 (audit UX-2): /uzys:* 슬래시 명령은 uzys-harness opt-in 시에만 설치된다.\n // 기본 설치(uzys-harness 미선택)·codex/opencode 단독설치에서도 무조건\n // `claude → /uzys:spec` 를 안내하던 것은 존재하지 않는 명령으로 첫 가치를 유도하는\n // dead-end 였다 (no-false-ship \"광고≠실동작\"). 실제 설치 결과로 분기한다.\n const hasUzysHarness = isAssetSelected(\"uzys-harness\", spec);\n const hasClaude = spec.cli.includes(\"claude\");\n if (hasUzysHarness && hasClaude) {\n log(infoRow(\"NEXT\", `${c.bold(\"claude\")} → ${c.cyan(\"/uzys:spec\")}`));\n } else {\n const primary = (hasClaude ? \"claude\" : spec.cli[0]) ?? \"claude\";\n const label = CLI_SUMMARY_LABELS[primary];\n log(infoRow(\"NEXT\", `Open ${c.bold(label)} — installed rules & skills are now active`));\n }\n log(\"\");\n}\n\nfunction formatAssetMeta(asset: ExternalAsset, version?: string): string {\n // v26.56.0 (F3) — description 제거. onAssetStart 의 → 라인이 이미 description 표시.\n // result row 는 method + source 만 간결하게 → terminal 120 char 안 wrap 방지.\n // v26.59.0 — plugin / npm-global 에 한해 version 표시 (path 기반 추출).\n const m = asset.method;\n const v = version ? ` ${c.dim(`v${version.replace(/^v/, \"\")}`)}` : \"\";\n switch (m.kind) {\n case \"skill\":\n // v26.63.3 (clarify M1): skill name 이 asset id 와 동일하면 중복 segment 생략.\n // \"skill · pbakaus/impeccable · impeccable\" → \"skill · pbakaus/impeccable\"\n if (m.skill && m.skill !== asset.id) return `skill · ${m.source} · ${m.skill}`;\n return `skill · ${m.source}`;\n case \"plugin\":\n return `plugin · ${m.pluginId}${v}`;\n case \"npm\":\n // A2 (Promise audit) — ADR-020 후 npm 자산 default 는 `--save-dev`(project), `-g` 는 global scope 만.\n // 라벨에 \"-g\" 고정은 scope 거짓 표기 → scope-중립 \"npm\" 으로 정정.\n // v26.80.0 — pinned 버전 표기 (Transparent Defaults: 실행되는 정확한 버전 노출).\n return `npm · ${m.pkg}@${m.version}`;\n case \"npx-run\":\n return `npx · ${m.cmd}@${m.version}`;\n case \"shell-script\":\n return `bash · ${m.script}`;\n case \"internal\":\n // v26.81.0 (ADR-022) — 내부 템플릿 자산 (Phase 1 manifest 가 설치 주체).\n return `internal · templates (${m.key})`;\n }\n}\n\n/**\n * Phase 1 rows 출력. baseline-complete progress event에서 호출 — 외부 자산 설치\n * 시작 전 즉시 화면에 표시되어야 한다 (멈춰 보임 방지).\n */\nfunction renderPhase1Rows(\n log: (msg: string) => void,\n baseline: BaselineReport,\n verbose = false,\n withEcc = false,\n): void {\n // Update mode rows\n if (baseline.updateMode) {\n if (baseline.backup) {\n log(assetRow(\"success\", \"backup\", shortenPath(baseline.backup)));\n }\n for (const [dir, count] of Object.entries(baseline.updateMode.updated)) {\n if (count > 0) log(assetRow(\"success\", dir, `${count} files updated`));\n }\n for (const [dir, removed] of Object.entries(baseline.updateMode.pruned)) {\n if (removed.length > 0) {\n log(assetRow(\"skip\", `${dir} orphan prune`, `${removed.length} removed`));\n }\n }\n if (baseline.updateMode.claudeMdUpdated) {\n log(assetRow(\"success\", \".claude/CLAUDE.md\", \"refreshed from template\"));\n }\n if (baseline.updateMode.staleHookRefs.length > 0) {\n log(\n assetRow(\n \"skip\",\n \"settings.json stale hook refs\",\n `${baseline.updateMode.staleHookRefs.length} removed`,\n ),\n );\n }\n return;\n }\n\n // Fresh / add / reinstall — Phase 1 rows\n // audit SEC-1/CODE-2 — 기존 settings.json·CLAUDE.md 를 덮어쓰기 전 백업했으면 fail-loud 노출.\n if (baseline.backups) {\n for (const b of baseline.backups) {\n log(assetRow(\"success\", \"backup\", shortenPath(b)));\n }\n }\n // v26.57.1 (F2) — multi-line 구조 (header + use + files). visual hierarchy + width-safe.\n // 사용자 image 검증 (2026-05-17): 단일 라인 description 이 width 좁을 때 wrap → 들여쓰기 깨짐.\n const cats = baseline.categories;\n if (cats) {\n // v26.63.0 — files 라인은 verbose 옵션 시만. 기본은 카운트 + use 1 줄.\n // v26.63.2 — polish: label + count 칼럼 fixed-width 정렬 (28 char). spacing scale 일관.\n const phase1Row = (label: string, count: number, useText: string, files?: string[]) => {\n const labelCol = `${c.bold(label)} ${c.dim(`(${count})`)}`;\n const padded = padDisplay(labelCol, 28);\n log(` ${c.green(\"✓\")} ${padded} ${c.dim(useText)}`);\n if (verbose && files && files.length > 0) {\n log(` ${c.dim(\"└ files:\")} ${c.dim(files.join(\", \"))}`);\n }\n };\n\n if (cats.rules.length > 0) {\n phase1Row(\n \"rules\",\n cats.rules.length,\n \"coding · git/PR · tests · ship checklist · MCP policy\",\n cats.rules,\n );\n }\n if (cats.agents.length > 0) {\n // v26.63.3 (clarify H3): SOD jargon 보강 — independent verifier 명시.\n // v26.63.3 (distill H2): \"Without ECC plugin...\" 반복 제거 — section footer 통합.\n phase1Row(\n \"agents\",\n cats.agents.length,\n \"SOD reviewer (opus, independent verifier) + 3 base\",\n cats.agents,\n );\n }\n if (cats.hooks.length > 0) {\n phase1Row(\n \"hooks\",\n cats.hooks.length,\n \"session-start · gate-check (6-Gate order) · spec-drift · agentshield (security)\",\n cats.hooks,\n );\n }\n if (cats.commands > 0) {\n phase1Row(\"commands\", cats.commands, \"uzys-harness option: /uzys:* (7)\");\n }\n if (cats.skills.length > 0) {\n phase1Row(\n \"skills\",\n cats.skills.length,\n \"north-star · gh-issue-workflow · ui-visual-review · cl-v2 (modified)\",\n cats.skills,\n );\n }\n } else {\n // v0.6.0 backwards compat — categories 없는 fakeReport 등\n log(assetRow(\"success\", \"rules + hooks + commands + agents\", `${baseline.filesCopied} files`));\n log(assetRow(\"success\", \"skeleton\", `${baseline.dirsCopied} dirs`));\n }\n // v26.63.4 (P3): Templates section 의 assetRow 호출 labelWidth=28 명시 → phase1Row 와 column 정렬.\n // default 40 은 External assets 의 긴 asset id (architecture-decision-record 등) 용 — 별개.\n const TEMPLATES_COL = 28;\n if (baseline.rootClaudeMd) {\n const n = baseline.rootClaudeMd.tracks.length;\n log(\n assetRow(\n \"success\",\n \"CLAUDE.md (root)\",\n `merged from ${n} track${n > 1 ? \"s\" : \"\"}`,\n TEMPLATES_COL,\n ),\n );\n }\n if (baseline.skipped > 0) {\n log(\n assetRow(\n \"skip\",\n \"manifest entries (applies → false)\",\n `${baseline.skipped} skipped`,\n TEMPLATES_COL,\n ),\n );\n }\n if (baseline.backup) {\n log(assetRow(\"success\", \"backup\", shortenPath(baseline.backup), TEMPLATES_COL));\n }\n const mcpList = baseline.mcpServers.join(\", \") || \"(none)\";\n log(assetRow(\"success\", \".mcp.json\", mcpList, TEMPLATES_COL));\n if (baseline.envFiles.mcpAllowlist) {\n log(\n assetRow(\n \"success\",\n \".mcp-allowlist\",\n `${baseline.envFiles.mcpAllowlist.length} servers (D35 opt-in gate)`,\n TEMPLATES_COL,\n ),\n );\n }\n // v26.63.3 (distill H2): ECC fallback hint — Templates section 마지막에 통합 표시.\n // withEcc=true (ECC plugin opt-in) 사용자에게는 hint 미표시.\n if (!withEcc && baseline.categories) {\n log(\"\");\n log(\n ` ${c.dim(\"·\")} ${c.dim(\"ECC plugin not selected — cherry-pick fallback active (up to 4 agents + 8 skills + 3 commands)\")}`,\n );\n log(` ${c.dim(\"·\")} ${c.dim(\"Use --with ecc-plugin to install ECC plugin instead\")}`);\n }\n if (baseline.envFiles.envExampleCreated) {\n log(assetRow(\"success\", \".env.example\", \"Supabase token guide\"));\n }\n if (baseline.envFiles.gitignoreEnvAdded) {\n log(assetRow(\"success\", \".gitignore\", \"+ .env\"));\n }\n if (baseline.envFiles.gitignoreNpxSkillsAdded.length > 0) {\n log(\n assetRow(\n \"success\",\n \".gitignore\",\n `+ ${baseline.envFiles.gitignoreNpxSkillsAdded.join(\" \")} (npx skills universal install)`,\n ),\n );\n }\n log(\"\");\n}\n\nfunction formatOptions(spec: InstallSpec): string {\n // v26.81.0 (ADR-022) — 자산 플래그 13종 삭제 후 동작 옵션만. 키 순회로 enumeration drift 차단.\n const flags = (Object.keys(spec.options) as Array<keyof OptionFlags>)\n .filter((k) => spec.options[k])\n .map((k) =>\n k\n .replace(/^with/, \"\")\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .toLowerCase(),\n );\n // v26.63.3 (clarify H1): \"(defaults only)\" 모호 → \"(none added)\" 명료.\n return flags.length > 0 ? flags.join(\", \") : c.dim(\"(none added)\");\n}\n\n/**\n * Shorten an absolute path for display:\n * /Users/foo/bar → ~/bar (HOME relative)\n * /private/tmp/x.X → /tmp/x.X\n * /a/very/long/path → …/long/path (≥3 segs from end if > 50 chars)\n *\n * v26.48.0 — export for direct unit test (branch coverage 복구).\n */\nexport function shortenPath(p: string): string {\n if (p.length <= 50) return p;\n const home = process.env.HOME ?? \"\";\n if (home && p.startsWith(home)) {\n const rel = p.slice(home.length);\n return `~${rel.startsWith(\"/\") ? \"\" : \"/\"}${rel}`;\n }\n // private/tmp prefix on macOS — drop /private\n if (p.startsWith(\"/private/tmp/\")) {\n return p.slice(\"/private\".length);\n }\n // Last 3 segments\n const segs = p.split(\"/\").filter(Boolean);\n if (segs.length > 3) {\n return `…/${segs.slice(-3).join(\"/\")}`;\n }\n return p;\n}\n\n/**\n * v0.7.0 — CliTargets에서 codex/opencode 포함 여부에 따라 title 결정.\n * Phase 3는 codex 또는 opencode 1개 이상 포함 시 호출됨.\n * v26.48.0 — export for direct unit test (branch coverage 복구).\n */\nexport function formatCliPhaseTitle(targets: CliTargets): string {\n // v26.78.1 (R2) — antigravity 추가. 누락 시 `--cli antigravity` 산출물 헤더가\n // \"CLI artifacts\" generic 으로만 떠 antigravity 가 invisible 했음.\n const labels: string[] = [];\n if (targets.includes(\"codex\")) labels.push(\"Codex\");\n if (targets.includes(\"opencode\")) labels.push(\"OpenCode\");\n if (targets.includes(\"antigravity\")) labels.push(\"Antigravity\");\n return labels.length > 0 ? `${labels.join(\" + \")} artifacts` : \"CLI artifacts\";\n}\n","/**\n * Preset → Step 2 의 추천 ✓ 자산 매핑 (v26.44.0).\n *\n * Step 1 에서 선택된 preset 들의 condition 을 만족하는 외부 자산(plugin/skill/npm/npx)\n * 의 id 를 반환한다. Step 2 multiselect 의 초기 체크 상태에 사용.\n *\n * Option-gated 자산은 추천에 포함 X — 사용자가 의식적으로 토글해야 함\n * (uzys-harness, superpowers, addy-agent-skills, gsd-orchestrator, ECC suite 등).\n */\n\nimport { assetTrustTier, EXTERNAL_ASSETS, filterApplicableAssets } from \"./external-assets.js\";\nimport { DEFAULT_OPTIONS, type InstallSpec, type Track } from \"./types.js\";\n\n/**\n * preset 1개 또는 N개 선택 시 추천 ✓ 자산 id 의 안정 정렬 배열.\n * - DEFAULT_OPTIONS 로 호출 → option-gated 자산은 모두 false → 추천에서 제외.\n * - v26.71.0 (PRD v26-71 R6) — experimental(T3) 자산은 pre-check 제외 (opt-in). official/vetted 만 추천.\n * - 결과는 자산 id 알파벳 정렬 (deterministic).\n */\nexport function recommendedExternalAssets(presets: ReadonlyArray<Track>): ReadonlyArray<string> {\n if (presets.length === 0) {\n return [];\n }\n const apps = filterApplicableAssets(EXTERNAL_ASSETS, {\n tracks: presets,\n options: DEFAULT_OPTIONS,\n });\n return apps\n .filter((a) => assetTrustTier(a.id) !== \"experimental\")\n .map((a) => a.id)\n .sort();\n}\n\n/**\n * v26.82.0 (Phase R, S6) — preset recommended + userOverride 적용 후 최종 선택 자산 id (정렬).\n * 이전엔 install.ts `computeFinalAssets` ↔ interactive.ts `formatSummary` 에 동일 merge 가\n * 중복 구현 (v26.62.4 주석이 본 위치를 통합 지점으로 지목). 우선순위: forceExclude > forceInclude.\n */\nexport function finalSelectedAssets(\n tracks: ReadonlyArray<Track>,\n userOverride?: InstallSpec[\"userOverride\"],\n): string[] {\n const selected = new Set(recommendedExternalAssets(tracks));\n if (userOverride) {\n for (const id of userOverride.forceExclude) selected.delete(id);\n for (const id of userOverride.forceInclude) selected.add(id);\n }\n return [...selected].sort();\n}\n\n/**\n * v26.82.0 (Phase R, S6) — 자산 id 를 카테고리별로 묶어 정렬된 entries 반환 (출력 hierarchy 용).\n * install header ASSETS row 와 wizard confirm summary 가 공유.\n */\nexport function groupAssetsByCategory(assetIds: ReadonlyArray<string>): Array<[string, string[]]> {\n const map = new Map<string, string[]>();\n for (const id of assetIds) {\n const asset = EXTERNAL_ASSETS.find((a) => a.id === id);\n const cat = asset?.category ?? \"other\";\n const list = map.get(cat) ?? [];\n list.push(id);\n map.set(cat, list);\n }\n return [...map.entries()];\n}\n","/**\n * Uninstall command — v26.64.0 (ADR-020).\n *\n * 동작:\n * 1. `.claude/.harness-install.json` 읽기.\n * 2. assets[] 별 reverse:\n * - scope=project: 실제 reverse (`claude plugin uninstall --scope project`, `npm uninstall`, fs rm).\n * - scope=global: 안내만 (D16 — 글로벌 영역 자동 삭제 금지). 사용자가 직접 명령 실행.\n * 3. templates 폴더 rm (`.claude/`, `.codex/`, `.opencode/`) — `--keep-templates` 시 보존.\n * 4. install log 자체도 함께 제거.\n *\n * 옵션:\n * --dry-run 실제 변경 없이 reverse list 만 출력.\n * --keep-templates `.claude/`, `.codex/`, `.opencode/` 보존.\n *\n * 안전:\n * - log 없으면 명확 에러 + early exit.\n * - scope=global 자산은 절대 자동 삭제 X (D16).\n */\n\nimport { type SpawnSyncReturns, spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync, rmSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { c, status } from \"../design.js\";\nimport { skillsCliSpec } from \"../external-installer.js\";\nimport {\n hashContent,\n type InstallLog,\n type InstallLogAsset,\n installLogPath,\n readInstallLog,\n} from \"../install-log.js\";\n\nexport interface UninstallOptions {\n projectDir?: string;\n dryRun?: boolean;\n keepTemplates?: boolean;\n}\n\nexport interface UninstallActionDeps {\n log?: (msg: string) => void;\n err?: (msg: string) => void;\n exit?: (code: number) => never;\n spawn?: (cmd: string, args: ReadonlyArray<string>) => SpawnSyncReturns<string>;\n rm?: (path: string) => void;\n}\n\ninterface ReverseStep {\n /** 사람이 읽는 라벨 (한 줄) */\n label: string;\n /** 실제 동작 — dry-run 일 때는 호출 안 함. */\n execute: () => { ok: boolean; message?: string };\n}\n\ninterface GlobalAdvisory {\n asset: InstallLogAsset;\n /** 사용자에게 안내할 reverse 명령 */\n command: string;\n}\n\nexport function uninstallAction(options: UninstallOptions, deps: UninstallActionDeps = {}): void {\n const log = deps.log ?? console.log;\n const err = deps.err ?? console.error;\n const exit = deps.exit ?? ((code: number) => process.exit(code) as never);\n const spawn = deps.spawn ?? defaultSpawn;\n const rm = deps.rm ?? defaultRm;\n\n const projectDir = resolve(options.projectDir ?? process.cwd());\n const installLog = readInstallLog(projectDir);\n if (!installLog) {\n err(status.failure(c.red(`ERROR: install log not found at ${installLogPath(projectDir)}`)));\n err(c.dim(\" Was this project installed by agent-harness? Nothing to uninstall.\"));\n exit(1);\n return;\n }\n\n const { reverseSteps, globalAdvisories } = planReverse(installLog, spawn, rm, projectDir);\n\n log(\"\");\n log(c.bold(\"uzys-agent-harness · uninstall\"));\n log(\"\");\n log(c.dim(` installed: ${installLog.installedAt}`));\n log(c.dim(` scope: ${installLog.scope}`));\n log(c.dim(` assets: ${installLog.assets.length}`));\n log(\"\");\n\n if (options.dryRun) {\n log(c.yellow(\"[DRY RUN] reverse list (실제 변경 없음):\"));\n log(\"\");\n if (reverseSteps.length === 0) {\n log(c.dim(\" (no project-scope assets to reverse)\"));\n }\n for (const step of reverseSteps) {\n log(` ○ ${step.label}`);\n }\n if (!options.keepTemplates) {\n log(` ○ remove templates: ${formatTemplateList(installLog)}`);\n if (installLog.templates.rootClaudeMd) {\n log(\n rootClaudeMdModified(installLog, projectDir)\n ? \" ○ keep CLAUDE.md (modified since install — preserved)\"\n : \" ○ remove CLAUDE.md\",\n );\n }\n }\n if (globalAdvisories.length > 0) {\n log(\"\");\n log(\n c.yellow(\n `[GLOBAL] ${globalAdvisories.length} asset(s) at scope=global — manual removal required (D16):`,\n ),\n );\n for (const adv of globalAdvisories) {\n log(c.dim(` · ${adv.asset.id} (${adv.asset.method}) → ${adv.command}`));\n }\n }\n log(\"\");\n exit(0);\n return;\n }\n\n // Execute reverse steps\n let succeeded = 0;\n let failed = 0;\n for (const step of reverseSteps) {\n const result = step.execute();\n if (result.ok) {\n log(` ${status.success(\"✓\")} ${step.label}`);\n succeeded++;\n } else {\n log(` ${c.yellow(\"⊘\")} ${step.label} (${result.message ?? \"failed\"})`);\n failed++;\n }\n }\n\n if (!options.keepTemplates) {\n const { rootClaudeMdKept } = removeTemplates(installLog, projectDir, rm);\n log(` ${status.success(\"✓\")} templates removed: ${formatTemplateList(installLog)}`);\n if (rootClaudeMdKept) {\n log(\n ` ${c.yellow(\"⊘\")} CLAUDE.md kept — modified since install. Remove manually if intended.`,\n );\n }\n }\n\n // install log 자체도 함께 제거 (templates 제거 시 .claude/ 통째 사라짐 → log 도 자동 사라짐.\n // keepTemplates 시 .claude/ 유지 → log 만 명시 제거).\n if (options.keepTemplates) {\n rm(installLogPath(projectDir));\n log(` ${status.success(\"✓\")} install log removed (templates kept)`);\n }\n\n if (globalAdvisories.length > 0) {\n log(\"\");\n log(\n c.yellow(\n `[GLOBAL] ${globalAdvisories.length} asset(s) at scope=global — manual removal required (D16):`,\n ),\n );\n for (const adv of globalAdvisories) {\n log(c.dim(` · ${adv.asset.id} (${adv.asset.method})`));\n log(c.dim(` ${adv.command}`));\n }\n }\n\n log(\"\");\n log(\n succeeded === reverseSteps.length && failed === 0\n ? status.success(c.green(`uninstall complete (${succeeded} asset(s))`))\n : c.yellow(`uninstall finished with ${failed} skip(s) (${succeeded} ok)`),\n );\n exit(failed === 0 ? 0 : 1);\n}\n\nfunction planReverse(\n log: InstallLog,\n spawn: (cmd: string, args: ReadonlyArray<string>) => SpawnSyncReturns<string>,\n _rm: (path: string) => void,\n _projectDir: string,\n): { reverseSteps: ReverseStep[]; globalAdvisories: GlobalAdvisory[] } {\n const reverseSteps: ReverseStep[] = [];\n const globalAdvisories: GlobalAdvisory[] = [];\n\n for (const asset of log.assets) {\n if (asset.scope === \"global\") {\n globalAdvisories.push({ asset, command: buildGlobalAdvisoryCmd(asset) });\n continue;\n }\n const step = buildProjectReverseStep(asset, spawn);\n if (step) reverseSteps.push(step);\n }\n\n return { reverseSteps, globalAdvisories };\n}\n\nfunction buildProjectReverseStep(\n asset: InstallLogAsset,\n spawn: (cmd: string, args: ReadonlyArray<string>) => SpawnSyncReturns<string>,\n): ReverseStep | null {\n switch (asset.method) {\n case \"plugin\": {\n const pluginId = asset.detail.pluginId ?? asset.id;\n return {\n label: `claude plugin uninstall --scope project ${pluginId}`,\n execute: () => {\n const r = spawn(\"claude\", [\"plugin\", \"uninstall\", \"--scope\", \"project\", pluginId]);\n return r.status === 0 ? { ok: true } : { ok: false, message: (r.stderr || \"\").trim() };\n },\n };\n }\n case \"skill\": {\n // skills CLI default 가 project — `skills remove <source>` (no -g).\n // 일부 source 는 폴더 경로/직접 id — npx skills remove 가 처리.\n const source = asset.detail.source ?? asset.id;\n return {\n label: `npx skills remove ${source}`,\n execute: () => {\n const r = spawn(\"npx\", [skillsCliSpec(), \"remove\", source, \"--yes\"]);\n return r.status === 0 ? { ok: true } : { ok: false, message: (r.stderr || \"\").trim() };\n },\n };\n }\n case \"npm\": {\n const pkg = asset.detail.pkg ?? asset.id;\n return {\n label: `npm uninstall --save-dev ${pkg}`,\n execute: () => {\n const r = spawn(\"npm\", [\"uninstall\", \"--save-dev\", pkg]);\n return r.status === 0 ? { ok: true } : { ok: false, message: (r.stderr || \"\").trim() };\n },\n };\n }\n case \"npx-run\":\n // fire-and-forget — reverse 없음 (예: GSD orchestrator).\n return null;\n case \"shell-script\":\n // 로컬 script 호출 — 일반 reverse 없음 (script 별 별도 cleanup 필요).\n return null;\n case \"internal\":\n // v26.81.0 (ADR-022) — 내부 템플릿 — removeTemplates 가 .claude/ 전체로 처리.\n return null;\n }\n}\n\nfunction buildGlobalAdvisoryCmd(asset: InstallLogAsset): string {\n switch (asset.method) {\n case \"plugin\": {\n const pid = asset.detail.pluginId ?? asset.id;\n return `claude plugin uninstall --scope user ${pid}`;\n }\n case \"skill\": {\n const s = asset.detail.source ?? asset.id;\n return `npx skills remove -g ${s}`;\n }\n case \"npm\": {\n const pkg = asset.detail.pkg ?? asset.id;\n return `npm uninstall -g ${pkg}`;\n }\n case \"npx-run\":\n case \"shell-script\":\n case \"internal\":\n return \"(no standard reverse — manual)\";\n }\n}\n\nfunction removeTemplates(\n log: InstallLog,\n projectDir: string,\n rm: (path: string) => void,\n): { rootClaudeMdKept: boolean } {\n rm(join(projectDir, log.templates.claudeDir));\n if (log.templates.codexDir) rm(join(projectDir, log.templates.codexDir));\n if (log.templates.opencodeDir) rm(join(projectDir, log.templates.opencodeDir));\n // root CLAUDE.md — install 원본 그대로일 때만 삭제. 사용자가 수정했으면 보존.\n const rootMd = log.templates.rootClaudeMd;\n if (rootMd) {\n if (rootClaudeMdModified(log, projectDir)) return { rootClaudeMdKept: true };\n rm(join(projectDir, rootMd.path));\n }\n return { rootClaudeMdKept: false };\n}\n\n/** root CLAUDE.md 가 install 이후 수정됐는지. log 에 없거나 파일 부재 시 false (= 삭제 대상). */\nfunction rootClaudeMdModified(log: InstallLog, projectDir: string): boolean {\n const rootMd = log.templates.rootClaudeMd;\n if (!rootMd) return false;\n const path = join(projectDir, rootMd.path);\n if (!existsSync(path)) return false;\n return hashContent(readFileSync(path, \"utf8\")) !== rootMd.sha256;\n}\n\nfunction formatTemplateList(log: InstallLog): string {\n const items: string[] = [log.templates.claudeDir];\n if (log.templates.codexDir) items.push(log.templates.codexDir);\n if (log.templates.opencodeDir) items.push(log.templates.opencodeDir);\n return items.join(\", \");\n}\n\n/* v8 ignore start — thin dep-inject defaults. tests 는 항상 mock 주입. */\nfunction defaultSpawn(cmd: string, args: ReadonlyArray<string>): SpawnSyncReturns<string> {\n return spawnSync(cmd, [...args], { encoding: \"utf8\", stdio: \"pipe\", timeout: 120_000 });\n}\n\nfunction defaultRm(path: string): void {\n if (existsSync(path)) {\n rmSync(path, { recursive: true, force: true });\n }\n}\n/* v8 ignore stop */\n\nexport function registerUninstallCommand(cli: import(\"../cli.js\").Cli): void {\n cli\n .command(\"uninstall\", \"Uninstall harness assets (log-based reverse)\")\n .option(\"--project-dir <path>\", \"[Project] Target project directory\", {\n default: process.cwd(),\n })\n .option(\"--dry-run\", \"[Mode] List reverse steps without executing\")\n .option(\n \"--keep-templates\",\n \"[Mode] Keep `.claude/`, `.codex/`, `.opencode/` templates (remove only external assets)\",\n )\n /* v8 ignore next 3 — cac action callback. uninstallAction 자체는 별도 tests 로 검증. */\n .action((options: UninstallOptions) => {\n uninstallAction(options);\n });\n}\n","import { EXTERNAL_ASSETS } from \"./external-assets.js\";\nimport type { InstallMode } from \"./installer.js\";\nimport {\n finalSelectedAssets,\n groupAssetsByCategory,\n recommendedExternalAssets,\n} from \"./preset-recommend.js\";\nimport {\n defaultPrompts,\n type InstallTargetId,\n type Prompts,\n VISIBLE_OPTION_DEFS,\n} from \"./prompts.js\";\nimport { type DetectedInstall, detectInstallState } from \"./state.js\";\nimport type { InstallSpec, OptionFlags, Track } from \"./types.js\";\nimport { stepLabel, WIZARD } from \"./wizard-steps.js\";\n\n/**\n * v26.54.0 — All-in-one 결과 → option keys + asset id list 분리.\n * `option:<key>` → OptionFlags key\n * `asset:<id>` → EXTERNAL_ASSETS id\n */\nexport function splitInstallTargets(targets: ReadonlyArray<InstallTargetId>): {\n optionKeys: Array<keyof OptionFlags>;\n assetIds: Array<string>;\n} {\n const optionKeys: Array<keyof OptionFlags> = [];\n const assetIds: Array<string> = [];\n for (const t of targets) {\n if (t.startsWith(\"option:\")) {\n optionKeys.push(t.slice(\"option:\".length) as keyof OptionFlags);\n } else if (t.startsWith(\"asset:\")) {\n assetIds.push(t.slice(\"asset:\".length));\n }\n }\n return { optionKeys, assetIds };\n}\n\n/**\n * v26.46.0 — `withCodexPrompts` 는 interactive 옵션 list 에서 제거됨 (CLI 전용 opt-in).\n * v26.81.0 (ADR-022) — 자산 1:1 boolean 13종 삭제 후 잔존 동작 옵션만 매핑.\n * wizard 의 자산 선택은 전부 `asset:<id>` → userOverride.forceInclude 경로.\n */\nexport function toOptionFlags(keys: ReadonlyArray<keyof OptionFlags>): OptionFlags {\n const picked = new Set<keyof OptionFlags>(keys);\n return {\n withPrune: picked.has(\"withPrune\"),\n withCodexSkills: picked.has(\"withCodexSkills\"),\n withCodexTrust: picked.has(\"withCodexTrust\"),\n withKarpathyHook: picked.has(\"withKarpathyHook\"),\n withCodexPrompts: false,\n withAntigravityGlobal: picked.has(\"withAntigravityGlobal\"),\n };\n}\n\nexport interface InteractiveDeps {\n prompts?: Prompts;\n detect?: (projectDir: string) => DetectedInstall;\n isTty?: () => boolean;\n}\n\nexport interface InteractiveResult {\n ok: boolean;\n spec?: InstallSpec;\n mode?: InstallMode;\n reason?: \"no-tty\" | \"cancelled\" | \"disabled-action\" | \"exit\";\n message?: string;\n}\n\n/**\n * v26.54.0 — 3-step wizard. SPEC: docs/specs/v26-54-all-in-one-installer.md\n *\n * Step 1: tracks (ESC = exit + cancel msg)\n * Step 2: cli (ESC = silent back to tracks)\n * Step 3: install-targets all-in-one (ESC = silent back to cli)\n * confirm prompt (ESC = silent back to targets)\n *\n * 이전 5-step 의 options + 2-tier asset navigator 를 step 3 1 화면 group multiselect 로 흡수.\n */\nexport async function runInteractive(\n projectDir: string,\n deps: InteractiveDeps = {},\n): Promise<InteractiveResult> {\n const prompts = deps.prompts ?? defaultPrompts;\n const detect = deps.detect ?? detectInstallState;\n const isTty = deps.isTty ?? (() => Boolean(process.stdin.isTTY));\n\n if (!isTty()) {\n return {\n ok: false,\n reason: \"no-tty\",\n message:\n \"Interactive mode requires a TTY. Use `agent-harness install --track <name>` for non-interactive use.\",\n };\n }\n\n prompts.intro(\"uzys-agent-harness installer\");\n const state = detect(projectDir);\n\n let initialTracks: Track[] | undefined;\n let mode: InstallMode = \"fresh\";\n if (state.state === \"existing\") {\n const action = await prompts.selectAction(state);\n if (action === null) {\n prompts.cancel(\"Cancelled.\");\n return { ok: false, reason: \"cancelled\" };\n }\n if (action === \"exit\") {\n prompts.outro(\"Exiting without changes.\");\n return { ok: false, reason: \"exit\" };\n }\n if (action === \"remove\") {\n prompts.cancel(\"Track removal is not automated — manually edit `.claude/`. Aborting.\");\n return { ok: false, reason: \"disabled-action\" };\n }\n if (action === \"update\") {\n mode = \"update\";\n const summary = formatSummary({\n tracks: state.tracks,\n options: toOptionFlags([]),\n cli: [\"claude\"],\n projectDir,\n });\n const confirmed = await prompts.confirmInstall(`UPDATE policy files only:\\n${summary}`);\n if (!confirmed) {\n prompts.outro(\"Cancelled.\");\n return { ok: false, reason: \"cancelled\" };\n }\n prompts.outro(\"Running update mode...\");\n return {\n ok: true,\n mode: \"update\",\n spec: {\n tracks: state.tracks,\n options: toOptionFlags([]),\n cli: [\"claude\"],\n projectDir,\n },\n };\n }\n if (action === \"add\") {\n mode = \"add\";\n initialTracks = state.tracks;\n } else if (action === \"reinstall\") {\n mode = \"reinstall\";\n }\n }\n\n // v26.64.0 (ADR-020) — scope step 추가. Default \"project\". Step 3.5 (targets 직후, confirm 직전).\n type Step = \"tracks\" | \"cli\" | \"targets\" | \"scope\" | \"confirm\";\n let step: Step = \"tracks\";\n let tracks: Track[] | null = null;\n let cli: import(\"./types.js\").CliTargets | null = null;\n let targetSelections: ReadonlyArray<InstallTargetId> | null = null;\n let scope: import(\"./types.js\").InstallScope = \"project\";\n\n while (true) {\n if (step === \"tracks\") {\n const result = await prompts.selectTracks(tracks ?? initialTracks, WIZARD.TRACKS);\n if (result === null) {\n // Step 1 ESC = exit with cancel message (only step where ESC is \"cancel\")\n prompts.cancel(\"Cancelled.\");\n return { ok: false, reason: \"cancelled\" };\n }\n // preset 변경 감지 → install-targets reset (v26.50 정책 유지)\n if (tracks !== null && !tracksEqual(tracks, result)) {\n targetSelections = null;\n }\n tracks = result;\n step = \"cli\";\n } else if (step === \"cli\") {\n const result = await prompts.selectCli(cli ?? [\"claude\"], WIZARD.CLI);\n if (result === null) {\n step = \"tracks\"; // silent back\n continue;\n }\n cli = result;\n step = \"targets\";\n } else if (step === \"targets\") {\n const initial: InstallTargetId[] =\n targetSelections !== null\n ? [...targetSelections]\n : recommendedExternalAssets(tracks ?? []).map((id) => `asset:${id}` as InstallTargetId);\n // v26.65.0 — step indicator SSOT (wizard-steps.ts). Phase: 3 targets → 4 scope → 5 confirm → 6 install.\n const result = await prompts.selectInstallTargets(initial, WIZARD.TARGETS, {\n tracks: tracks ?? [],\n cli: cli ?? [\"claude\"],\n });\n if (result === null) {\n step = \"cli\"; // silent back\n continue;\n }\n targetSelections = result;\n step = \"scope\";\n } else if (step === \"scope\") {\n // v26.64.0 (ADR-020) — Installation scope select. Default \"project\" (D16).\n const result = await prompts.selectScope(scope, WIZARD.SCOPE);\n if (result === null) {\n step = \"targets\"; // silent back\n continue;\n }\n scope = result;\n step = \"confirm\";\n } else {\n // confirm\n // biome-ignore lint/style/noNonNullAssertion: confirm step 도달 = 모든 이전 step 완료 보장\n const finalTracks = tracks!;\n // biome-ignore lint/style/noNonNullAssertion: same as above\n const finalCli = cli!;\n const { optionKeys, assetIds } = splitInstallTargets(targetSelections ?? []);\n const options = toOptionFlags(optionKeys);\n // v26.64.0 (ADR-020, BREAKING) — ADR-012/017 supersede. cli=codex 자동 default ON 폐기.\n // withCodexPrompts 는 사용자 명시 install target (목록 체크) 시에만 활성. 자동 ON 안 함.\n // scope=global 일 때만 ~/.codex/prompts/ 에 실 write (installer.ts).\n const userOverride =\n targetSelections === null ? undefined : computeUserOverride(finalTracks, assetIds);\n // v26.64.0 (ADR-020) — Confirm summary 에 SCOPE 명시 (사용자 인지 + D16).\n const scopeLabel =\n scope === \"global\"\n ? \"Global (writes to ~/.claude/, ~/.codex/, npm -g)\"\n : \"Project (current directory only)\";\n const summary = `${formatSummary({\n tracks: finalTracks,\n options,\n cli: finalCli,\n projectDir,\n ...(userOverride ? { userOverride } : {}),\n })}\\n SCOPE ${scopeLabel}`;\n const confirmed = await prompts.confirmInstall(\n `${stepLabel(WIZARD.CONFIRM, \"Confirm\")}\\n${summary}`,\n );\n if (confirmed === null) {\n step = \"scope\"; // silent back\n continue;\n }\n if (!confirmed) {\n prompts.outro(\"Cancelled by user.\");\n return { ok: false, reason: \"cancelled\" };\n }\n prompts.outro(stepLabel(WIZARD.INSTALL, \"Installing...\"));\n return {\n ok: true,\n mode,\n spec: {\n tracks: finalTracks,\n options,\n cli: finalCli,\n projectDir,\n scope,\n ...(userOverride ? { userOverride } : {}),\n },\n };\n }\n }\n}\n\n/**\n * Track 배열 동등 비교 (순서 무관). Preset 변경 감지에 사용.\n */\nfunction tracksEqual(a: ReadonlyArray<Track>, b: ReadonlyArray<Track>): boolean {\n if (a.length !== b.length) return false;\n const sortedA = [...a].sort();\n const sortedB = [...b].sort();\n return sortedA.every((t, i) => t === sortedB[i]);\n}\n\n/**\n * v26.54.0 — Asset 선택 결과 (id 만) 와 preset 추천 비교 → forceInclude / forceExclude.\n * - `recommended - selected` → forceExclude (사용자가 unchecked)\n * - `selected - recommended` → forceInclude (사용자가 추가 선택)\n * 둘 다 비어있으면 undefined (no override).\n */\nexport function computeUserOverride(\n tracks: ReadonlyArray<Track>,\n assetIds: ReadonlyArray<string>,\n): { forceInclude: ReadonlyArray<string>; forceExclude: ReadonlyArray<string> } | undefined {\n const recommended = new Set(recommendedExternalAssets(tracks));\n const selected = new Set(assetIds);\n const forceExclude = [...recommended].filter((id) => !selected.has(id)).sort();\n const forceInclude = [...selected].filter((id) => !recommended.has(id)).sort();\n if (forceInclude.length === 0 && forceExclude.length === 0) return undefined;\n return { forceInclude, forceExclude };\n}\n\nexport function formatSummary(spec: InstallSpec): string {\n const opts = (Object.keys(spec.options) as Array<keyof OptionFlags>)\n .filter((k) => spec.options[k])\n .map((k) => k.replace(/^with/, \"\").toLowerCase());\n // v26.63.3 (clarify H1): \"(defaults only)\" 모호 → \"(none added)\" 명료.\n const optsLabel = opts.length > 0 ? opts.join(\", \") : \"(none added)\";\n const lines = [\n `Tracks: ${spec.tracks.join(\", \")}`,\n `Options: ${optsLabel}`,\n `CLI: ${spec.cli.join(\" · \")}`,\n `Target: ${spec.projectDir}`,\n ];\n\n // v26.62.3 — 실제 install 될 자산 list 명시. defaults 만으로는 사용자가\n // Step 3 에서 무엇을 confirm 했는지 알 수 없음. preset recommended +\n // userOverride 적용 후 최종 selected assets list 표시.\n // v26.82.0 (Phase R, S6) — merge/그룹화는 preset-recommend.ts 단일 구현 사용 (중복 제거).\n const finalAssets = finalSelectedAssets(spec.tracks, spec.userOverride);\n if (finalAssets.length > 0) {\n lines.push(`Assets: ${finalAssets.length} selected`);\n for (const [cat, ids] of groupAssetsByCategory(finalAssets)) {\n lines.push(` · ${cat}: ${ids.join(\", \")}`);\n }\n }\n\n if (spec.userOverride) {\n if (spec.userOverride.forceInclude.length > 0) {\n lines.push(` +User added: ${spec.userOverride.forceInclude.join(\", \")}`);\n }\n if (spec.userOverride.forceExclude.length > 0) {\n lines.push(` -User removed: ${spec.userOverride.forceExclude.join(\", \")}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n// v26.54.0 — Re-exports to keep test imports stable (test의 mock 구조 변경 없음)\nexport { EXTERNAL_ASSETS, VISIBLE_OPTION_DEFS };\n","// prompts.ts is a thin adapter over @clack/prompts. It deliberately contains\n// no transformation logic — interactive.ts owns the business rules. This file\n// is excluded from coverage in vitest.config.ts (justification at exclude line).\n\nimport {\n cancel,\n confirm,\n groupMultiselect,\n intro,\n isCancel,\n multiselect,\n outro,\n select,\n} from \"@clack/prompts\";\nimport { CATEGORIES, CATEGORY_TITLES, type Category } from \"./categories.js\";\nimport { CLI_BASE_SORT_ORDER } from \"./cli-targets.js\";\nimport { assetTrustTier, EXTERNAL_ASSETS } from \"./external-assets.js\";\nimport { buildRouterChoices, type RouterAction, summarizeState } from \"./router.js\";\nimport type { DetectedInstall } from \"./state.js\";\nimport {\n type CliBase,\n type CliTargets,\n type InstallScope,\n type OptionFlags,\n TRACKS,\n type Track,\n} from \"./types.js\";\nimport { stepLabel, type WizardStep } from \"./wizard-steps.js\";\n\n/**\n * v26.54.0 — All-in-one install-targets value scheme.\n * groupMultiselect 의 단일 string value 에 두 source 통합:\n * - `option:<key>` → OPTION_DEFS 의 manifest-영향 build option (현재: withTauri, withUzysHarness)\n * - `asset:<id>` → EXTERNAL_ASSETS 의 외부 자산\n * 다른 OptionFlags 항목 (withGsd, withEcc, withPrune, withTob, withKarpathyHook,\n * withAddyAgentSkills, withSuperpowers, withWshobsonAgents, withOpenspec, withBmad) 은\n * EXTERNAL_ASSETS 에 1:1 자산이 있어\n * 자산 체크 → userOverride.forceInclude 로 처리. UI 중복 표시 없음.\n */\nexport type InstallTargetId = `option:${keyof OptionFlags}` | `asset:${string}`;\n\nexport interface Prompts {\n intro: (msg: string) => void;\n outro: (msg: string) => void;\n cancel: (msg: string) => void;\n\n /**\n * v26.65.0 — step optional 두 번째 인자. 호출자가 `WIZARD.TRACKS` 전달 시 message 에\n * \"Step N/M — Select Track(s)\" 형식 indicator 자동 삽입. 미전달 시 prefix 없이 raw label.\n */\n selectTracks: (initial?: Track[], step?: WizardStep) => Promise<Track[] | null>;\n /** v0.7.0 — single select → multiselect (3 base 체크박스). default `[\"claude\"]`. */\n selectCli: (initial?: CliTargets, step?: WizardStep) => Promise<CliTargets | null>;\n selectAction: (state: DetectedInstall) => Promise<RouterAction | null>;\n /**\n * v26.64.0 (ADR-020) — Installation scope 선택. Default = \"project\" (pre-selected).\n * Global 은 사용자 명시 opt-in. null = silent back.\n */\n selectScope: (initial?: InstallScope, step?: WizardStep) => Promise<InstallScope | null>;\n confirmInstall: (summary: string) => Promise<boolean | null>;\n\n /**\n * v26.54.0 — Step 3 (all-in-one). EXTERNAL_ASSETS + 표시-대상 OPTION_DEFS 를\n * 카테고리 그룹화. 추천 ✓ pre-check. ESC → null (silent back).\n * v26.61.0 — recap (tracks/cli) 추가. alt screen 안에서 동작 — terminal scrollback\n * 본질 차단 → wizard scroll 시 cursor highlight 항상 visible.\n */\n selectInstallTargets: (\n initialChecked: ReadonlyArray<InstallTargetId>,\n step: { current: number; total: number },\n recap?: { tracks: ReadonlyArray<Track>; cli: CliTargets },\n ) => Promise<ReadonlyArray<InstallTargetId> | null>;\n}\n\nconst TRACK_LABELS: Record<Track, string> = {\n tooling: \"tooling — Bash + Markdown meta-project\",\n \"csr-supabase\": \"csr-supabase — Vite + React + Supabase\",\n \"csr-fastify\": \"csr-fastify — Vite + React + Fastify\",\n \"csr-fastapi\": \"csr-fastapi — Vite + React + FastAPI\",\n \"ssr-htmx\": \"ssr-htmx — htmx + FastAPI\",\n \"ssr-nextjs\": \"ssr-nextjs — Next.js (App Router)\",\n data: \"data — Python data / DuckDB / PySide6\",\n executive: \"executive — proposals / DD / pitch (no agent-skills)\",\n full: \"full — all dev capabilities\",\n \"project-management\": \"project-management — PM / Scrum / Jira / Confluence\",\n \"growth-marketing\": \"growth-marketing — Growth / Marketing / Content\",\n};\n\ninterface OptionDef {\n key: keyof OptionFlags;\n label: string;\n hint: string;\n category: Category;\n source: string;\n}\n\n/**\n * v26.54.0 — 표시 대상 OPTION_DEFS.\n * v26.81.0 (ADR-022) — **빈 배열로 소멸**. 마지막 2개(withTauri/withUzysHarness)가 내부\n * 자산(tauri-desktop/uzys-harness — EXTERNAL_ASSETS `kind:\"internal\"`)으로 흡수돼 wizard 의\n * `option:` 특례가 사라짐. 자산 선택은 전부 `asset:<id>` 경로. 잔존 동작 옵션(D16 글로벌\n * 4종/karpathy hook/prune)은 wizard 미노출 (CLI `--with-*` 동작 플래그 전용 — 기존과 동일).\n */\nexport const VISIBLE_OPTION_DEFS: ReadonlyArray<OptionDef> = [];\n\nconst CLI_BASE_LABELS: Record<CliBase, string> = {\n claude: \"Claude Code\",\n codex: \"Codex (OpenAI)\",\n opencode: \"OpenCode (anomalyco)\",\n antigravity: \"Antigravity (Google)\",\n};\n\n/**\n * v26.78.1 — Step 3 wizard page layout (SSOT). 카테고리를 페이지로 묶어 clack\n * groupMultiselect 의 maxItems 한계(페이지당 옵션 ≤ ~30)를 우회.\n *\n * ⚠️ drift 가드 (no-false-ship): 모든 Category 는 정확히 한 페이지에 등장해야 한다.\n * 누락 시 해당 카테고리 자산이 wizard 에서 선택 불가가 되어 \"출하 거짓 광고\"가 된다\n * (v26.78.0 understanding 누락 회귀 — pages 가 selectInstallTargets 안에 하드코딩되어\n * CATEGORIES 추가와 drift). 아래 assertPagesCoverAllCategories 가 모듈 로드 시점에\n * 강제 — 신규 카테고리 미배치 시 즉시 throw. (tests/wizard-page-parity.test.ts 가 이중 가드)\n *\n * 페이지 묶음:\n * Page 1: Dev domain — frontend + backend + dev-tools + data + understanding\n * Page 2: Business — business (documents)\n * Page 3: Workflow/ECC — workflow + ecc-suite\n */\nexport interface InstallTargetPage {\n label: string;\n cats: ReadonlyArray<Category>;\n}\n\nexport const INSTALL_TARGET_PAGES: ReadonlyArray<InstallTargetPage> = [\n {\n label: \"Dev (Frontend · Backend · Dev Tools · Data · Understanding)\",\n cats: [\"frontend\", \"backend\", \"dev-tools\", \"data\", \"understanding\"],\n },\n { label: \"Business (PM · Executive · Documents)\", cats: [\"business\"] },\n { label: \"Workflow & ECC Suite\", cats: [\"workflow\", \"ecc-suite\"] },\n];\n\n/**\n * 모든 Category 가 정확히 한 페이지에 등장하는지 모듈 로드 시 검증.\n * 누락(미배치) 또는 중복(2개 페이지)이면 throw — 값싼 fail-loud pre-flight.\n */\nfunction assertPagesCoverAllCategories(pages: ReadonlyArray<InstallTargetPage>): void {\n const counts = new Map<Category, number>();\n for (const page of pages) {\n for (const cat of page.cats) counts.set(cat, (counts.get(cat) ?? 0) + 1);\n }\n const missing = CATEGORIES.filter((c) => !counts.has(c));\n const duplicated = CATEGORIES.filter((c) => (counts.get(c) ?? 0) > 1);\n if (missing.length > 0 || duplicated.length > 0) {\n throw new Error(\n `INSTALL_TARGET_PAGES drift vs CATEGORIES — missing=[${missing.join(\", \")}] ` +\n `duplicated=[${duplicated.join(\", \")}]. 모든 카테고리는 정확히 한 페이지에 배치해야 한다 ` +\n `(no-false-ship: wizard 미노출 = 거짓 광고).`,\n );\n }\n}\n\nassertPagesCoverAllCategories(INSTALL_TARGET_PAGES);\n\n/**\n * v26.58.1 — Wizard viewport size. clack 의 limitOptions 가 maxItems 안에서만\n * cursor follow + ↕ ... indicator. 미지정 시 Infinity → terminal height 초과 시\n * 위 항목이 scrollback 으로 밀려 selected indicator 안 보임 (사용자 보고된 문제).\n *\n * rowPadding 10 = message line + status footer + safety margin.\n * floor 8 = 너무 작아도 최소한의 viewport 보장.\n */\nfunction viewportItems(itemCount: number): number {\n const rows = process.stdout.rows ?? 24;\n return Math.max(8, Math.min(itemCount, rows - 10));\n}\n\nexport const defaultPrompts: Prompts = {\n intro: (msg) => intro(msg),\n outro: (msg) => outro(msg),\n cancel: (msg) => cancel(msg),\n\n selectTracks: async (initial, step) => {\n // v26.65.0 — step indicator SSOT (wizard-steps.ts). 6-step 통합 (1 tracks · 2 cli · 3 targets · 4 scope · 5 confirm · 6 installing).\n const result = await multiselect({\n message: stepLabel(step, \"Select Track(s)\"),\n options: TRACKS.map((t) => ({ value: t, label: TRACK_LABELS[t] })),\n ...(initial ? { initialValues: initial } : {}),\n maxItems: viewportItems(11),\n required: true,\n });\n return isCancel(result) ? null : (result as Track[]);\n },\n\n selectCli: async (initial, step) => {\n const initialValues: CliBase[] = initial && initial.length > 0 ? [...initial] : [\"claude\"];\n const result = await multiselect({\n message: stepLabel(step, \"Target CLI(s)\"),\n options: [\n { value: \"claude\" as const, label: CLI_BASE_LABELS.claude },\n { value: \"codex\" as const, label: CLI_BASE_LABELS.codex },\n { value: \"opencode\" as const, label: CLI_BASE_LABELS.opencode },\n { value: \"antigravity\" as const, label: CLI_BASE_LABELS.antigravity },\n ],\n initialValues,\n required: true,\n });\n if (isCancel(result)) return null;\n return [...(result as CliBase[])].sort(\n (a, b) => CLI_BASE_SORT_ORDER[a] - CLI_BASE_SORT_ORDER[b],\n );\n },\n\n selectAction: async (state) => {\n const result = await select({\n message: summarizeState(state),\n options: buildRouterChoices(state).map((c) => {\n const label = c.enabled ? c.label : `${c.label} [disabled]`;\n // disabled:true → clack 이 cursor skip + strikethrough (선택 자체 차단).\n return {\n value: c.value,\n label,\n ...(c.hint ? { hint: c.hint } : {}),\n ...(c.enabled ? {} : { disabled: true }),\n };\n }),\n });\n return isCancel(result) ? null : (result as RouterAction);\n },\n\n /**\n * v26.64.0 (ADR-020) — Installation scope select. Default Project (D16 — no global write).\n * Global 은 사용자 명시 opt-in 시에만.\n */\n selectScope: async (initial = \"project\", step) => {\n const result = await select({\n message: stepLabel(step, \"Installation scope\"),\n initialValue: initial,\n options: [\n {\n value: \"project\",\n label: \"Project\",\n hint: \"Install in current directory (committed with your project)\",\n },\n {\n value: \"global\",\n label: \"Global\",\n hint: \"Write to ~/.claude/, ~/.codex/, npm -g (shared across all projects)\",\n },\n ],\n });\n return isCancel(result) ? null : (result as InstallScope);\n },\n\n confirmInstall: async (summary) => {\n const result = await confirm({\n message: `${summary}\\n\\nProceed?`,\n initialValue: true,\n });\n return isCancel(result) ? null : result;\n },\n\n selectInstallTargets: async (initialChecked, step, recap) => {\n // v26.62.2 — groupMultiselect 복귀 + page paginate.\n // v26.62.1 에서 multiselect + disabled separator 시도 → clack 가 disabled option 에\n // 체크박스 강제 + dim/strikethrough 효과 → 카테고리 헤더가 \"옵션 같지만 선택 불가\"\n // 처럼 보여 사용자 보고. groupMultiselect 의 group header 는 라이브러리에서 본래\n // 설명 라인 형태로 자연 표시 → 시각 명료.\n //\n // maxItems 한계 (GroupMultiSelectPrompt 미지원) 는 page 묶음으로 cover:\n // 한 page 안 옵션 ≤ ~30 → 사용자 iTerm2 (30+ rows) 환경에서 fit. 매우 작은 terminal\n // (< 25 rows) 한계는 follow-up.\n //\n // 페이지 정의 = 모듈 스코프 INSTALL_TARGET_PAGES (SSOT, 카테고리 전수 가드됨).\n const pages = INSTALL_TARGET_PAGES;\n const initialSet = new Set<string>(initialChecked);\n const collected = new Set<string>(initialChecked);\n\n const buildPageGroups = (cats: ReadonlyArray<Category>) => {\n const groups: Record<string, Array<{ value: string; label: string; hint?: string }>> = {};\n const flatItems: Array<{ value: string; label: string; hint?: string }> = [];\n for (const cat of cats) {\n const items: Array<{ value: string; label: string; hint?: string }> = [];\n for (const o of VISIBLE_OPTION_DEFS.filter((d) => d.category === cat)) {\n items.push({\n value: `option:${o.key}`,\n // v26.62.3 — group header 와 옵션 사이 시각 hierarchy 강화. label prefix 4 space.\n label: ` ${o.label} [${o.source}]`,\n hint: o.hint,\n });\n }\n // v26.71.0 (PRD v26-71) — tier 우선 정렬 (official → vetted → experimental) + 배지.\n const tierOrder = { official: 0, vetted: 1, experimental: 2 } as const;\n const catAssets = [...EXTERNAL_ASSETS.filter((x) => x.category === cat)].sort(\n (a, b) => tierOrder[assetTrustTier(a.id)] - tierOrder[assetTrustTier(b.id)],\n );\n for (const a of catAssets) {\n const tier = assetTrustTier(a.id);\n const badge =\n tier === \"official\"\n ? \" ★ official\"\n : tier === \"experimental\"\n ? \" ⚠ experimental (opt-in)\"\n : \"\";\n items.push({\n value: `asset:${a.id}`,\n label: ` ${a.id} [${a.source}]${badge}`,\n hint: a.description,\n });\n }\n if (items.length === 0) continue;\n const selectedInCat = items.filter((it) => initialSet.has(it.value)).length;\n const header = `${CATEGORY_TITLES[cat]} [${selectedInCat}/${items.length} ✓ default]`;\n groups[header] = items;\n flatItems.push(...items);\n }\n return { groups, flatItems };\n };\n\n const recapLine = recap\n ? `Tracks: ${recap.tracks.join(\", \")} · CLIs: ${recap.cli.join(\", \")}`\n : \"\";\n\n // alt screen for the whole Step 3 loop. page 전환 시 buffer 안에서 redraw.\n process.stdout.write(\"\\x1b[?1049h\");\n let resultIds: ReadonlyArray<InstallTargetId> | null = null;\n let aborted = false;\n try {\n let pageIdx = 0;\n while (pageIdx < pages.length) {\n const page = pages[pageIdx];\n if (!page) break;\n const { groups, flatItems } = buildPageGroups(page.cats);\n const selectedNow = flatItems.filter((it) => collected.has(it.value)).map((it) => it.value);\n const pageDefault = flatItems.filter((it) => initialSet.has(it.value)).length;\n const totalSelected = collected.size;\n const message = [\n `Step ${step.current}/${step.total} · Page ${pageIdx + 1}/${pages.length} · ${page.label}`,\n recapLine ? ` ${recapLine}` : \"\",\n ` Selected so far: ${totalSelected} items · This page default ✓ ${pageDefault}/${flatItems.length}`,\n \" Space toggle · Enter → next · ESC → prev\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n const groupOpts = {\n message,\n options: groups,\n initialValues: selectedNow,\n required: false,\n selectableGroups: false,\n } as Parameters<typeof groupMultiselect>[0];\n const result = await groupMultiselect(groupOpts);\n if (isCancel(result)) {\n if (pageIdx === 0) {\n aborted = true; // first page ESC → Step 2 back\n break;\n }\n pageIdx--; // prev page\n continue;\n }\n // update collected: remove page items + add the new selection\n for (const it of flatItems) collected.delete(it.value);\n for (const v of result as ReadonlyArray<string>) collected.add(v);\n pageIdx++;\n }\n if (!aborted) {\n resultIds = [...collected] as ReadonlyArray<InstallTargetId>;\n }\n } finally {\n process.stdout.write(\"\\x1b[?1049l\");\n }\n // v26.63.1 — alt screen exit 후 main buffer 에 Step 3 완료 라인 출력. alt buffer\n // 안 동작은 main 에 흔적 0 → Step 1·2·4 사이 Step 3 missing → 사용자 보고.\n // clack `◇` marker + `│` line 으로 다른 step 과 시각 일관성 유지.\n if (resultIds !== null) {\n process.stdout.write(\n `◇ Step ${step.current}/${step.total} — Install targets · ${resultIds.length} selected\\n│\\n`,\n );\n }\n return resultIds;\n },\n};\n",null,"/* IMPORT */\nimport fastStringTruncatedWidth from 'fast-string-truncated-width';\n/* HELPERS */\nconst NO_TRUNCATION = {\n limit: Infinity,\n ellipsis: '',\n ellipsisWidth: 0,\n};\n/* MAIN */\nconst fastStringWidth = (input, options = {}) => {\n return fastStringTruncatedWidth(input, NO_TRUNCATION, options).width;\n};\n/* EXPORT */\nexport default fastStringWidth;\n","/* IMPORT */\nimport { getCodePointsLength, isFullWidth, isWideNotCJKTNotEmoji } from './utils.js';\n/* HELPERS */\nconst ANSI_RE = /[\\u001b\\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\\u001b\\]8;[^;]*;.*?(?:\\u0007|\\u001b\\u005c)/y;\nconst CONTROL_RE = /[\\x00-\\x08\\x0A-\\x1F\\x7F-\\x9F]{1,1000}/y;\nconst CJKT_WIDE_RE = /(?:(?![\\uFF61-\\uFF9F\\uFF00-\\uFFEF])[\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\p{Script=Hangul}\\p{Script=Tangut}]){1,1000}/yu;\nconst TAB_RE = /\\t{1,1000}/y;\nconst EMOJI_RE = /[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*/yu;\nconst LATIN_RE = /(?:[\\x20-\\x7E\\xA0-\\xFF](?!\\uFE0F)){1,1000}/y;\nconst MODIFIER_RE = /\\p{M}+/gu;\nconst NO_TRUNCATION = { limit: Infinity, ellipsis: '' };\n/* MAIN */\nconst getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {\n /* CONSTANTS */\n const LIMIT = truncationOptions.limit ?? Infinity;\n const ELLIPSIS = truncationOptions.ellipsis ?? '';\n const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);\n const ANSI_WIDTH = 0;\n const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;\n const TAB_WIDTH = widthOptions.tabWidth ?? 8;\n const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;\n const FULL_WIDTH_WIDTH = 2;\n const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;\n const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;\n const PARSE_BLOCKS = [\n [LATIN_RE, REGULAR_WIDTH],\n [ANSI_RE, ANSI_WIDTH],\n [CONTROL_RE, CONTROL_WIDTH],\n [TAB_RE, TAB_WIDTH],\n [EMOJI_RE, EMOJI_WIDTH],\n [CJKT_WIDE_RE, WIDE_WIDTH],\n ];\n /* STATE */\n let indexPrev = 0;\n let index = 0;\n let length = input.length;\n let lengthExtra = 0;\n let truncationEnabled = false;\n let truncationIndex = length;\n let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);\n let unmatchedStart = 0;\n let unmatchedEnd = 0;\n let width = 0;\n let widthExtra = 0;\n /* PARSE LOOP */\n outer: while (true) {\n /* UNMATCHED */\n if ((unmatchedEnd > unmatchedStart) || (index >= length && index > indexPrev)) {\n const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);\n lengthExtra = 0;\n for (const char of unmatched.replaceAll(MODIFIER_RE, '')) {\n const codePoint = char.codePointAt(0) || 0;\n if (isFullWidth(codePoint)) {\n widthExtra = FULL_WIDTH_WIDTH;\n }\n else if (isWideNotCJKTNotEmoji(codePoint)) {\n widthExtra = WIDE_WIDTH;\n }\n else {\n widthExtra = REGULAR_WIDTH;\n }\n if ((width + widthExtra) > truncationLimit) {\n truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);\n }\n if ((width + widthExtra) > LIMIT) {\n truncationEnabled = true;\n break outer;\n }\n lengthExtra += char.length;\n width += widthExtra;\n }\n unmatchedStart = unmatchedEnd = 0;\n }\n /* EXITING */\n if (index >= length) {\n break outer;\n }\n /* PARSE BLOCKS */\n for (let i = 0, l = PARSE_BLOCKS.length; i < l; i++) {\n const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];\n BLOCK_RE.lastIndex = index;\n if (BLOCK_RE.test(input)) {\n lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;\n widthExtra = lengthExtra * BLOCK_WIDTH;\n if ((width + widthExtra) > truncationLimit) {\n truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));\n }\n if ((width + widthExtra) > LIMIT) {\n truncationEnabled = true;\n break outer;\n }\n width += widthExtra;\n unmatchedStart = indexPrev;\n unmatchedEnd = index;\n index = indexPrev = BLOCK_RE.lastIndex;\n continue outer;\n }\n }\n /* UNMATCHED INDEX */\n index += 1;\n }\n /* RETURN */\n return {\n width: truncationEnabled ? truncationLimit : width,\n index: truncationEnabled ? truncationIndex : length,\n truncated: truncationEnabled,\n ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH\n };\n};\n/* EXPORT */\nexport default getStringTruncatedWidth;\n","/* MAIN */\nconst getCodePointsLength = (() => {\n const SURROGATE_PAIR_RE = /[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g;\n return (input) => {\n let surrogatePairsNr = 0;\n SURROGATE_PAIR_RE.lastIndex = 0;\n while (SURROGATE_PAIR_RE.test(input)) {\n surrogatePairsNr += 1;\n }\n return input.length - surrogatePairsNr;\n };\n})();\nconst isFullWidth = (x) => {\n return x === 0x3000 || x >= 0xFF01 && x <= 0xFF60 || x >= 0xFFE0 && x <= 0xFFE6;\n};\nconst isWideNotCJKTNotEmoji = (x) => {\n return x === 0x231B || x === 0x2329 || x >= 0x2FF0 && x <= 0x2FFF || x >= 0x3001 && x <= 0x303E || x >= 0x3099 && x <= 0x30FF || x >= 0x3105 && x <= 0x312F || x >= 0x3131 && x <= 0x318E || x >= 0x3190 && x <= 0x31E3 || x >= 0x31EF && x <= 0x321E || x >= 0x3220 && x <= 0x3247 || x >= 0x3250 && x <= 0x4DBF || x >= 0xFE10 && x <= 0xFE19 || x >= 0xFE30 && x <= 0xFE52 || x >= 0xFE54 && x <= 0xFE66 || x >= 0xFE68 && x <= 0xFE6B || x >= 0x1F200 && x <= 0x1F202 || x >= 0x1F210 && x <= 0x1F23B || x >= 0x1F240 && x <= 0x1F248 || x >= 0x20000 && x <= 0x2FFFD || x >= 0x30000 && x <= 0x3FFFD;\n};\n/* EXPORT */\nexport { getCodePointsLength, isFullWidth, isWideNotCJKTNotEmoji };\n","export function findCursor<T extends { disabled?: boolean }>(\n\tcursor: number,\n\tdelta: number,\n\toptions: T[]\n) {\n\tconst hasEnabledOptions = options.some((opt) => !opt.disabled);\n\tif (!hasEnabledOptions) {\n\t\treturn cursor;\n\t}\n\tconst newCursor = cursor + delta;\n\tconst maxCursor = Math.max(options.length - 1, 0);\n\tconst clampedCursor = newCursor < 0 ? maxCursor : newCursor > maxCursor ? 0 : newCursor;\n\tconst newOption = options[clampedCursor];\n\tif (newOption.disabled) {\n\t\treturn findCursor(clampedCursor, delta < 0 ? -1 : 1, options);\n\t}\n\treturn clampedCursor;\n}\n\nexport function findTextCursor(\n\tcursor: number,\n\tdeltaX: number,\n\tdeltaY: number,\n\tvalue: string\n): number {\n\tconst lines = value.split('\\n');\n\tlet cursorY = 0;\n\tlet cursorX = cursor;\n\n\tfor (const line of lines) {\n\t\tif (cursorX <= line.length) {\n\t\t\tbreak;\n\t\t}\n\t\tcursorX -= line.length + 1;\n\t\tcursorY++;\n\t}\n\n\tcursorY = Math.max(0, Math.min(lines.length - 1, cursorY + deltaY));\n\n\tcursorX = Math.min(cursorX, lines[cursorY].length) + deltaX;\n\twhile (cursorX < 0 && cursorY > 0) {\n\t\tcursorY--;\n\t\tcursorX += lines[cursorY].length + 1;\n\t}\n\twhile (cursorX > lines[cursorY].length && cursorY < lines.length - 1) {\n\t\tcursorX -= lines[cursorY].length + 1;\n\t\tcursorY++;\n\t}\n\tcursorX = Math.max(0, Math.min(lines[cursorY].length, cursorX));\n\n\tlet newCursor = 0;\n\tfor (let i = 0; i < cursorY; i++) {\n\t\tnewCursor += lines[i].length + 1;\n\t}\n\treturn newCursor + cursorX;\n}\n","const actions = ['up', 'down', 'left', 'right', 'space', 'enter', 'cancel'] as const;\nexport type Action = (typeof actions)[number];\n\nconst DEFAULT_MONTH_NAMES = [\n\t'January',\n\t'February',\n\t'March',\n\t'April',\n\t'May',\n\t'June',\n\t'July',\n\t'August',\n\t'September',\n\t'October',\n\t'November',\n\t'December',\n];\n\n/** Global settings for Clack programs, stored in memory */\ninterface InternalClackSettings {\n\tactions: Set<Action>;\n\taliases: Map<string, Action>;\n\tmessages: {\n\t\tcancel: string;\n\t\terror: string;\n\t};\n\twithGuide: boolean;\n\tdate: {\n\t\tmonthNames: string[];\n\t\tmessages: {\n\t\t\tinvalidMonth: string;\n\t\t\trequired: string;\n\t\t\tinvalidDay: (days: number, month: string) => string;\n\t\t\tafterMin: (min: Date) => string;\n\t\t\tbeforeMax: (max: Date) => string;\n\t\t};\n\t};\n}\n\nexport const settings: InternalClackSettings = {\n\tactions: new Set(actions),\n\taliases: new Map<string, Action>([\n\t\t// vim support\n\t\t['k', 'up'],\n\t\t['j', 'down'],\n\t\t['h', 'left'],\n\t\t['l', 'right'],\n\t\t['\\x03', 'cancel'],\n\t\t// opinionated defaults!\n\t\t['escape', 'cancel'],\n\t]),\n\tmessages: {\n\t\tcancel: 'Canceled',\n\t\terror: 'Something went wrong',\n\t},\n\twithGuide: true,\n\tdate: {\n\t\tmonthNames: [...DEFAULT_MONTH_NAMES],\n\t\tmessages: {\n\t\t\trequired: 'Please enter a valid date',\n\t\t\tinvalidMonth: 'There are only 12 months in a year',\n\t\t\tinvalidDay: (days, month) => `There are only ${days} days in ${month}`,\n\t\t\tafterMin: (min) => `Date must be on or after ${min.toISOString().slice(0, 10)}`,\n\t\t\tbeforeMax: (max) => `Date must be on or before ${max.toISOString().slice(0, 10)}`,\n\t\t},\n\t},\n};\n\nexport interface ClackSettings {\n\t/**\n\t * Set custom global aliases for the default actions.\n\t * This will not overwrite existing aliases, it will only add new ones!\n\t *\n\t * @param aliases - An object that maps aliases to actions\n\t * @default { k: 'up', j: 'down', h: 'left', l: 'right', '\\x03': 'cancel', 'escape': 'cancel' }\n\t */\n\taliases?: Record<string, Action>;\n\n\t/**\n\t * Custom messages for prompts\n\t */\n\tmessages?: {\n\t\t/**\n\t\t * Custom message to display when a spinner is cancelled\n\t\t * @default \"Canceled\"\n\t\t */\n\t\tcancel?: string;\n\t\t/**\n\t\t * Custom message to display when a spinner encounters an error\n\t\t * @default \"Something went wrong\"\n\t\t */\n\t\terror?: string;\n\t};\n\n\twithGuide?: boolean;\n\n\t/**\n\t * Date prompt localization\n\t */\n\tdate?: {\n\t\t/** Month names for validation messages (January, February, ...) */\n\t\tmonthNames?: string[];\n\t\tmessages?: {\n\t\t\t/** Shown when date is missing */\n\t\t\trequired?: string;\n\t\t\t/** Shown when month > 12 */\n\t\t\tinvalidMonth?: string;\n\t\t\t/** (days, monthName) => message for invalid day */\n\t\t\tinvalidDay?: (days: number, month: string) => string;\n\t\t\t/** (min) => message when date is before minDate */\n\t\t\tafterMin?: (min: Date) => string;\n\t\t\t/** (max) => message when date is after maxDate */\n\t\t\tbeforeMax?: (max: Date) => string;\n\t\t};\n\t};\n}\n\nexport function updateSettings(updates: ClackSettings) {\n\t// Handle each property in the updates\n\tif (updates.aliases !== undefined) {\n\t\tconst aliases = updates.aliases;\n\t\tfor (const alias in aliases) {\n\t\t\tif (!Object.hasOwn(aliases, alias)) continue;\n\n\t\t\tconst action = aliases[alias];\n\t\t\tif (!settings.actions.has(action)) continue;\n\n\t\t\tif (!settings.aliases.has(alias)) {\n\t\t\t\tsettings.aliases.set(alias, action);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (updates.messages !== undefined) {\n\t\tconst messages = updates.messages;\n\t\tif (messages.cancel !== undefined) {\n\t\t\tsettings.messages.cancel = messages.cancel;\n\t\t}\n\t\tif (messages.error !== undefined) {\n\t\t\tsettings.messages.error = messages.error;\n\t\t}\n\t}\n\n\tif (updates.withGuide !== undefined) {\n\t\tsettings.withGuide = updates.withGuide !== false;\n\t}\n\n\tif (updates.date !== undefined) {\n\t\tconst date = updates.date;\n\t\tif (date.monthNames !== undefined) {\n\t\t\tsettings.date.monthNames = [...date.monthNames];\n\t\t}\n\t\tif (date.messages !== undefined) {\n\t\t\tif (date.messages.required !== undefined) {\n\t\t\t\tsettings.date.messages.required = date.messages.required;\n\t\t\t}\n\t\t\tif (date.messages.invalidMonth !== undefined) {\n\t\t\t\tsettings.date.messages.invalidMonth = date.messages.invalidMonth;\n\t\t\t}\n\t\t\tif (date.messages.invalidDay !== undefined) {\n\t\t\t\tsettings.date.messages.invalidDay = date.messages.invalidDay;\n\t\t\t}\n\t\t\tif (date.messages.afterMin !== undefined) {\n\t\t\t\tsettings.date.messages.afterMin = date.messages.afterMin;\n\t\t\t}\n\t\t\tif (date.messages.beforeMax !== undefined) {\n\t\t\t\tsettings.date.messages.beforeMax = date.messages.beforeMax;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Check if a key is an alias for a default action\n * @param key - The raw key which might match to an action\n * @param action - The action to match\n * @returns boolean\n */\nexport function isActionKey(key: string | Array<string | undefined>, action: Action) {\n\tif (typeof key === 'string') {\n\t\treturn settings.aliases.get(key) === action;\n\t}\n\n\tfor (const value of key) {\n\t\tif (value === undefined) continue;\n\t\tif (isActionKey(value, action)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n","export function diffLines(a: string, b: string) {\n\tif (a === b) return;\n\n\tconst aLines = a.split('\\n');\n\tconst bLines = b.split('\\n');\n\tconst numLines = Math.max(aLines.length, bLines.length);\n\tconst diff: number[] = [];\n\n\tfor (let i = 0; i < numLines; i++) {\n\t\tif (aLines[i] !== bLines[i]) diff.push(i);\n\t}\n\n\treturn {\n\t\tlines: diff,\n\t\tnumLinesBefore: aLines.length,\n\t\tnumLinesAfter: bLines.length,\n\t\tnumLines,\n\t};\n}\n","import { stdin, stdout } from 'node:process';\nimport type { Key } from 'node:readline';\nimport * as readline from 'node:readline';\nimport type { Readable, Writable } from 'node:stream';\nimport { ReadStream } from 'node:tty';\nimport { wrapAnsi } from 'fast-wrap-ansi';\nimport { cursor } from 'sisteransi';\nimport { isActionKey } from './settings.js';\n\nexport * from './settings.js';\nexport * from './string.js';\n\nconst isWindows = globalThis.process.platform.startsWith('win');\n\nexport const CANCEL_SYMBOL = Symbol('clack:cancel');\n\nexport function isCancel(value: unknown): value is symbol {\n\treturn value === CANCEL_SYMBOL;\n}\n\nexport function setRawMode(input: Readable, value: boolean) {\n\tconst i = input as typeof stdin;\n\n\tif (i.isTTY) i.setRawMode(value);\n}\n\ninterface BlockOptions {\n\tinput?: Readable;\n\toutput?: Writable;\n\toverwrite?: boolean;\n\thideCursor?: boolean;\n}\n\nexport function block({\n\tinput = stdin,\n\toutput = stdout,\n\toverwrite = true,\n\thideCursor = true,\n}: BlockOptions = {}) {\n\tconst rl = readline.createInterface({\n\t\tinput,\n\t\toutput,\n\t\tprompt: '',\n\t\ttabSize: 1,\n\t});\n\treadline.emitKeypressEvents(input, rl);\n\n\tif (input instanceof ReadStream && input.isTTY) {\n\t\tinput.setRawMode(true);\n\t}\n\n\tconst clear = (data: Buffer, { name, sequence }: Key) => {\n\t\tconst str = String(data);\n\t\tif (isActionKey([str, name, sequence], 'cancel')) {\n\t\t\tif (hideCursor) output.write(cursor.show);\n\t\t\tprocess.exit(0);\n\t\t\treturn;\n\t\t}\n\t\tif (!overwrite) return;\n\t\tconst dx = name === 'return' ? 0 : -1;\n\t\tconst dy = name === 'return' ? -1 : 0;\n\n\t\treadline.moveCursor(output, dx, dy, () => {\n\t\t\treadline.clearLine(output, 1, () => {\n\t\t\t\tinput.once('keypress', clear);\n\t\t\t});\n\t\t});\n\t};\n\tif (hideCursor) output.write(cursor.hide);\n\tinput.once('keypress', clear);\n\n\treturn () => {\n\t\tinput.off('keypress', clear);\n\t\tif (hideCursor) output.write(cursor.show);\n\n\t\t// Prevent Windows specific issues: https://github.com/bombshell-dev/clack/issues/176\n\t\tif (input instanceof ReadStream && input.isTTY && !isWindows) {\n\t\t\tinput.setRawMode(false);\n\t\t}\n\n\t\t// @ts-expect-error fix for https://github.com/nodejs/node/issues/31762#issuecomment-1441223907\n\t\trl.terminal = false;\n\t\trl.close();\n\t};\n}\n\nexport const getColumns = (output: Writable): number => {\n\tif ('columns' in output && typeof output.columns === 'number') {\n\t\treturn output.columns;\n\t}\n\treturn 80;\n};\n\nexport const getRows = (output: Writable): number => {\n\tif ('rows' in output && typeof output.rows === 'number') {\n\t\treturn output.rows;\n\t}\n\treturn 20;\n};\n\nexport function wrapTextWithPrefix(\n\toutput: Writable | undefined,\n\ttext: string,\n\tprefix: string,\n\tstartPrefix: string = prefix,\n\tlineFormatter?: (line: string, index: number) => string\n): string {\n\tconst columns = getColumns(output ?? stdout);\n\tconst wrapped = wrapAnsi(text, columns - prefix.length, {\n\t\thard: true,\n\t\ttrim: false,\n\t});\n\tconst lines = wrapped\n\t\t.split('\\n')\n\t\t.map((line, index) => {\n\t\t\tconst lineString = lineFormatter ? lineFormatter(line, index) : line;\n\t\t\treturn `${index === 0 ? startPrefix : prefix}${lineString}`;\n\t\t})\n\t\t.join('\\n');\n\treturn lines;\n}\n","import { stdin, stdout } from 'node:process';\nimport readline, { type Key, type ReadLine } from 'node:readline';\nimport type { Readable, Writable } from 'node:stream';\nimport { wrapAnsi } from 'fast-wrap-ansi';\nimport { cursor, erase } from 'sisteransi';\nimport type { ClackEvents, ClackState } from '../types.js';\nimport type { Action } from '../utils/index.js';\nimport {\n\tCANCEL_SYMBOL,\n\tdiffLines,\n\tgetRows,\n\tisActionKey,\n\tsetRawMode,\n\tsettings,\n} from '../utils/index.js';\n\nexport interface PromptOptions<TValue, Self extends Prompt<TValue>> {\n\trender(this: Omit<Self, 'prompt'>): string | undefined;\n\tinitialValue?: any;\n\tinitialUserInput?: string;\n\tvalidate?: ((value: TValue | undefined) => string | Error | undefined) | undefined;\n\tinput?: Readable;\n\toutput?: Writable;\n\tsignal?: AbortSignal;\n}\n\nexport default class Prompt<TValue> {\n\tprotected input: Readable;\n\tprotected output: Writable;\n\tprivate _abortSignal?: AbortSignal;\n\n\tprivate rl: ReadLine | undefined;\n\tprivate opts: Omit<PromptOptions<TValue, Prompt<TValue>>, 'render' | 'input' | 'output'>;\n\tprivate _render: (context: Omit<Prompt<TValue>, 'prompt'>) => string | undefined;\n\tprivate _track = false;\n\tprivate _prevFrame = '';\n\tprivate _subscribers = new Map<string, { cb: (...args: any) => any; once?: boolean }[]>();\n\tprotected _cursor = 0;\n\n\tpublic state: ClackState = 'initial';\n\tpublic error = '';\n\tpublic value: TValue | undefined;\n\tpublic userInput = '';\n\n\tconstructor(options: PromptOptions<TValue, Prompt<TValue>>, trackValue = true) {\n\t\tconst { input = stdin, output = stdout, render, signal, ...opts } = options;\n\n\t\tthis.opts = opts;\n\t\tthis.onKeypress = this.onKeypress.bind(this);\n\t\tthis.close = this.close.bind(this);\n\t\tthis.render = this.render.bind(this);\n\t\tthis._render = render.bind(this);\n\t\tthis._track = trackValue;\n\t\tthis._abortSignal = signal;\n\n\t\tthis.input = input;\n\t\tthis.output = output;\n\t}\n\n\t/**\n\t * Unsubscribe all listeners\n\t */\n\tprotected unsubscribe() {\n\t\tthis._subscribers.clear();\n\t}\n\n\t/**\n\t * Set a subscriber with opts\n\t * @param event - The event name\n\t */\n\tprivate setSubscriber<T extends keyof ClackEvents<TValue>>(\n\t\tevent: T,\n\t\topts: { cb: ClackEvents<TValue>[T]; once?: boolean }\n\t) {\n\t\tconst params = this._subscribers.get(event) ?? [];\n\t\tparams.push(opts);\n\t\tthis._subscribers.set(event, params);\n\t}\n\n\t/**\n\t * Subscribe to an event\n\t * @param event - The event name\n\t * @param cb - The callback\n\t */\n\tpublic on<T extends keyof ClackEvents<TValue>>(event: T, cb: ClackEvents<TValue>[T]) {\n\t\tthis.setSubscriber(event, { cb });\n\t}\n\n\t/**\n\t * Subscribe to an event once\n\t * @param event - The event name\n\t * @param cb - The callback\n\t */\n\tpublic once<T extends keyof ClackEvents<TValue>>(event: T, cb: ClackEvents<TValue>[T]) {\n\t\tthis.setSubscriber(event, { cb, once: true });\n\t}\n\n\t/**\n\t * Emit an event with data\n\t * @param event - The event name\n\t * @param data - The data to pass to the callback\n\t */\n\tpublic emit<T extends keyof ClackEvents<TValue>>(\n\t\tevent: T,\n\t\t...data: Parameters<ClackEvents<TValue>[T]>\n\t) {\n\t\tconst cbs = this._subscribers.get(event) ?? [];\n\t\tconst cleanup: (() => void)[] = [];\n\n\t\tfor (const subscriber of cbs) {\n\t\t\tsubscriber.cb(...data);\n\n\t\t\tif (subscriber.once) {\n\t\t\t\tcleanup.push(() => cbs.splice(cbs.indexOf(subscriber), 1));\n\t\t\t}\n\t\t}\n\n\t\tfor (const cb of cleanup) {\n\t\t\tcb();\n\t\t}\n\t}\n\n\tpublic prompt() {\n\t\treturn new Promise<TValue | symbol | undefined>((resolve) => {\n\t\t\tif (this._abortSignal) {\n\t\t\t\tif (this._abortSignal.aborted) {\n\t\t\t\t\tthis.state = 'cancel';\n\n\t\t\t\t\tthis.close();\n\t\t\t\t\treturn resolve(CANCEL_SYMBOL);\n\t\t\t\t}\n\n\t\t\t\tthis._abortSignal.addEventListener(\n\t\t\t\t\t'abort',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tthis.state = 'cancel';\n\t\t\t\t\t\tthis.close();\n\t\t\t\t\t},\n\t\t\t\t\t{ once: true }\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.rl = readline.createInterface({\n\t\t\t\tinput: this.input,\n\t\t\t\ttabSize: 2,\n\t\t\t\tprompt: '',\n\t\t\t\tescapeCodeTimeout: 50,\n\t\t\t\tterminal: true,\n\t\t\t});\n\t\t\tthis.rl.prompt();\n\n\t\t\tif (this.opts.initialUserInput !== undefined) {\n\t\t\t\tthis._setUserInput(this.opts.initialUserInput, true);\n\t\t\t}\n\n\t\t\tthis.input.on('keypress', this.onKeypress);\n\t\t\tsetRawMode(this.input, true);\n\t\t\tthis.output.on('resize', this.render);\n\n\t\t\tthis.render();\n\n\t\t\tthis.once('submit', () => {\n\t\t\t\tthis.output.write(cursor.show);\n\t\t\t\tthis.output.off('resize', this.render);\n\t\t\t\tsetRawMode(this.input, false);\n\t\t\t\tresolve(this.value);\n\t\t\t});\n\t\t\tthis.once('cancel', () => {\n\t\t\t\tthis.output.write(cursor.show);\n\t\t\t\tthis.output.off('resize', this.render);\n\t\t\t\tsetRawMode(this.input, false);\n\t\t\t\tresolve(CANCEL_SYMBOL);\n\t\t\t});\n\t\t});\n\t}\n\n\tprotected _isActionKey(char: string | undefined, _key: Key): boolean {\n\t\treturn char === '\\t';\n\t}\n\n\tprotected _shouldSubmit(_char: string | undefined, _key: Key): boolean {\n\t\treturn true;\n\t}\n\n\tprotected _setValue(value: TValue | undefined): void {\n\t\tthis.value = value;\n\t\tthis.emit('value', this.value);\n\t}\n\n\tprotected _setUserInput(value: string | undefined, write?: boolean): void {\n\t\tthis.userInput = value ?? '';\n\t\tthis.emit('userInput', this.userInput);\n\t\tif (write && this._track && this.rl) {\n\t\t\tthis.rl.write(this.userInput);\n\t\t\tthis._cursor = this.rl.cursor;\n\t\t}\n\t}\n\n\tprotected _clearUserInput(): void {\n\t\tthis.rl?.write(null, { ctrl: true, name: 'u' });\n\t\tthis._setUserInput('');\n\t}\n\n\tprivate onKeypress(char: string | undefined, key: Key) {\n\t\tif (this._track && key.name !== 'return') {\n\t\t\tif (key.name && this._isActionKey(char, key)) {\n\t\t\t\tthis.rl?.write(null, { ctrl: true, name: 'h' });\n\t\t\t}\n\t\t\tthis._cursor = this.rl?.cursor ?? 0;\n\t\t\tthis._setUserInput(this.rl?.line);\n\t\t}\n\n\t\tif (this.state === 'error') {\n\t\t\tthis.state = 'active';\n\t\t}\n\t\tif (key?.name) {\n\t\t\tif (!this._track && settings.aliases.has(key.name)) {\n\t\t\t\tthis.emit('cursor', settings.aliases.get(key.name));\n\t\t\t}\n\t\t\tif (settings.actions.has(key.name as Action)) {\n\t\t\t\tthis.emit('cursor', key.name as Action);\n\t\t\t}\n\t\t}\n\t\tif (char && (char.toLowerCase() === 'y' || char.toLowerCase() === 'n')) {\n\t\t\tthis.emit('confirm', char.toLowerCase() === 'y');\n\t\t}\n\n\t\t// Call the key event handler and emit the key event\n\t\tthis.emit('key', char?.toLowerCase(), key);\n\n\t\tif (key?.name === 'return' && this._shouldSubmit(char, key)) {\n\t\t\tif (this.opts.validate) {\n\t\t\t\tconst problem = this.opts.validate(this.value);\n\t\t\t\tif (problem) {\n\t\t\t\t\tthis.error = problem instanceof Error ? problem.message : problem;\n\t\t\t\t\tthis.state = 'error';\n\t\t\t\t\tthis.rl?.write(this.userInput);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.state !== 'error') {\n\t\t\t\tthis.state = 'submit';\n\t\t\t}\n\t\t}\n\n\t\tif (isActionKey([char, key?.name, key?.sequence], 'cancel')) {\n\t\t\tthis.state = 'cancel';\n\t\t}\n\n\t\tif (this.state === 'submit' || this.state === 'cancel') {\n\t\t\tthis.emit('finalize');\n\t\t}\n\t\tthis.render();\n\t\tif (this.state === 'submit' || this.state === 'cancel') {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\tprotected close() {\n\t\tthis.input.unpipe();\n\t\tthis.input.removeListener('keypress', this.onKeypress);\n\t\tthis.output.write('\\n');\n\t\tsetRawMode(this.input, false);\n\t\tthis.rl?.close();\n\t\tthis.rl = undefined;\n\t\tthis.emit(`${this.state}`, this.value);\n\t\tthis.unsubscribe();\n\t}\n\n\tprivate restoreCursor() {\n\t\tconst lines =\n\t\t\twrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split('\\n')\n\t\t\t\t.length - 1;\n\t\tthis.output.write(cursor.move(-999, lines * -1));\n\t}\n\n\tprivate render() {\n\t\tconst frame = wrapAnsi(this._render(this) ?? '', process.stdout.columns, {\n\t\t\thard: true,\n\t\t\ttrim: false,\n\t\t});\n\t\tif (frame === this._prevFrame) return;\n\n\t\tif (this.state === 'initial') {\n\t\t\tthis.output.write(cursor.hide);\n\t\t} else {\n\t\t\tconst diff = diffLines(this._prevFrame, frame);\n\t\t\tconst rows = getRows(this.output);\n\t\t\tthis.restoreCursor();\n\t\t\tif (diff) {\n\t\t\t\tconst diffOffsetAfter = Math.max(0, diff.numLinesAfter - rows);\n\t\t\t\tconst diffOffsetBefore = Math.max(0, diff.numLinesBefore - rows);\n\t\t\t\tlet diffLine = diff.lines.find((line) => line >= diffOffsetAfter);\n\n\t\t\t\tif (diffLine === undefined) {\n\t\t\t\t\tthis._prevFrame = frame;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// If a single line has changed, only update that line\n\t\t\t\tif (diff.lines.length === 1) {\n\t\t\t\t\tthis.output.write(cursor.move(0, diffLine - diffOffsetBefore));\n\t\t\t\t\tthis.output.write(erase.lines(1));\n\t\t\t\t\tconst lines = frame.split('\\n');\n\t\t\t\t\tthis.output.write(lines[diffLine]);\n\t\t\t\t\tthis._prevFrame = frame;\n\t\t\t\t\tthis.output.write(cursor.move(0, lines.length - diffLine - 1));\n\t\t\t\t\treturn;\n\t\t\t\t\t// If many lines have changed, rerender everything past the first line\n\t\t\t\t} else if (diff.lines.length > 1) {\n\t\t\t\t\tif (diffOffsetAfter < diffOffsetBefore) {\n\t\t\t\t\t\tdiffLine = diffOffsetAfter;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst adjustedDiffLine = diffLine - diffOffsetBefore;\n\t\t\t\t\t\tif (adjustedDiffLine > 0) {\n\t\t\t\t\t\t\tthis.output.write(cursor.move(0, adjustedDiffLine));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.output.write(erase.down());\n\t\t\t\t\tconst lines = frame.split('\\n');\n\t\t\t\t\tconst newLines = lines.slice(diffLine);\n\t\t\t\t\tthis.output.write(newLines.join('\\n'));\n\t\t\t\t\tthis._prevFrame = frame;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.output.write(erase.down());\n\t\t}\n\n\t\tthis.output.write(frame);\n\t\tif (this.state === 'initial') {\n\t\t\tthis.state = 'active';\n\t\t}\n\t\tthis._prevFrame = frame;\n\t}\n}\n","import type { Key } from 'node:readline';\nimport { styleText } from 'node:util';\nimport { findCursor } from '../utils/cursor.js';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\ninterface OptionLike {\n\tvalue: unknown;\n\tlabel?: string;\n\tdisabled?: boolean;\n}\n\ntype FilterFunction<T extends OptionLike> = (search: string, opt: T) => boolean;\n\nfunction getCursorForValue<T extends OptionLike>(\n\tselected: T['value'] | undefined,\n\titems: T[]\n): number {\n\tif (selected === undefined) {\n\t\treturn 0;\n\t}\n\n\tconst currLength = items.length;\n\n\t// If filtering changed the available options, update cursor\n\tif (currLength === 0) {\n\t\treturn 0;\n\t}\n\n\t// Try to maintain the same selected item\n\tconst index = items.findIndex((item) => item.value === selected);\n\treturn index !== -1 ? index : 0;\n}\n\nfunction defaultFilter<T extends OptionLike>(input: string, option: T): boolean {\n\tconst label = option.label ?? String(option.value);\n\treturn label.toLowerCase().includes(input.toLowerCase());\n}\n\nfunction normalisedValue<T>(multiple: boolean, values: T[] | undefined): T | T[] | undefined {\n\tif (!values) {\n\t\treturn undefined;\n\t}\n\tif (multiple) {\n\t\treturn values;\n\t}\n\treturn values[0];\n}\n\nexport interface AutocompleteOptions<T extends OptionLike>\n\textends PromptOptions<T['value'] | T['value'][], AutocompletePrompt<T>> {\n\toptions: T[] | ((this: AutocompletePrompt<T>) => T[]);\n\tfilter?: FilterFunction<T>;\n\tmultiple?: boolean;\n\t/**\n\t * When set (non-empty), pressing Tab with no input fills the field with this value\n\t * and runs the normal filter/selection logic so the user can confirm with Enter.\n\t * Tab only fills the input when the placeholder matches at least one option under\n\t * the prompt's filter (so the value remains selectable).\n\t */\n\tplaceholder?: string;\n}\n\nexport default class AutocompletePrompt<T extends OptionLike> extends Prompt<\n\tT['value'] | T['value'][]\n> {\n\tfilteredOptions: T[];\n\tmultiple: boolean;\n\tisNavigating = false;\n\tselectedValues: Array<T['value']> = [];\n\n\tfocusedValue: T['value'] | undefined;\n\t#cursor = 0;\n\t#lastUserInput = '';\n\t#filterFn: FilterFunction<T> | undefined;\n\t#options: T[] | (() => T[]);\n\t#placeholder: string | undefined;\n\n\tget cursor(): number {\n\t\treturn this.#cursor;\n\t}\n\n\tget userInputWithCursor() {\n\t\tif (!this.userInput) {\n\t\t\treturn styleText(['inverse', 'hidden'], '_');\n\t\t}\n\t\tif (this._cursor >= this.userInput.length) {\n\t\t\treturn `${this.userInput}█`;\n\t\t}\n\t\tconst s1 = this.userInput.slice(0, this._cursor);\n\t\tconst [s2, ...s3] = this.userInput.slice(this._cursor);\n\t\treturn `${s1}${styleText('inverse', s2)}${s3.join('')}`;\n\t}\n\n\tget options(): T[] {\n\t\tif (typeof this.#options === 'function') {\n\t\t\treturn this.#options();\n\t\t}\n\t\treturn this.#options;\n\t}\n\n\tconstructor(opts: AutocompleteOptions<T>) {\n\t\tsuper(opts);\n\n\t\tthis.#options = opts.options;\n\t\tthis.#placeholder = opts.placeholder;\n\t\tconst options = this.options;\n\t\tthis.filteredOptions = [...options];\n\t\tthis.multiple = opts.multiple === true;\n\t\tthis.#filterFn =\n\t\t\ttypeof opts.options === 'function' ? opts.filter : (opts.filter ?? defaultFilter);\n\t\tlet initialValues: unknown[] | undefined;\n\t\tif (opts.initialValue && Array.isArray(opts.initialValue)) {\n\t\t\tif (this.multiple) {\n\t\t\t\tinitialValues = opts.initialValue;\n\t\t\t} else {\n\t\t\t\tinitialValues = opts.initialValue.slice(0, 1);\n\t\t\t}\n\t\t} else {\n\t\t\tif (!this.multiple && this.options.length > 0) {\n\t\t\t\tinitialValues = [this.options[0].value];\n\t\t\t}\n\t\t}\n\n\t\tif (initialValues) {\n\t\t\tfor (const selectedValue of initialValues) {\n\t\t\t\tconst selectedIndex = options.findIndex((opt) => opt.value === selectedValue);\n\t\t\t\tif (selectedIndex !== -1) {\n\t\t\t\t\tthis.toggleSelected(selectedValue);\n\t\t\t\t\tthis.#cursor = selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.focusedValue = this.options[this.#cursor]?.value;\n\n\t\tthis.on('key', (char, key) => this.#onKey(char, key));\n\t\tthis.on('userInput', (value) => this.#onUserInputChanged(value));\n\t}\n\n\tprotected override _isActionKey(char: string | undefined, key: Key): boolean {\n\t\treturn (\n\t\t\tchar === '\\t' ||\n\t\t\t(this.multiple &&\n\t\t\t\tthis.isNavigating &&\n\t\t\t\tkey.name === 'space' &&\n\t\t\t\tchar !== undefined &&\n\t\t\t\tchar !== '')\n\t\t);\n\t}\n\n\t#onKey(_char: string | undefined, key: Key): void {\n\t\tconst isUpKey = key.name === 'up';\n\t\tconst isDownKey = key.name === 'down';\n\t\tconst isReturnKey = key.name === 'return';\n\n\t\t// Tab with empty input and placeholder: fill input with placeholder to trigger autocomplete\n\t\t// Only when the placeholder matches at least one (non-disabled) option so the value remains selectable\n\t\tconst isEmptyOrOnlyTab = this.userInput === '' || this.userInput === '\\t';\n\t\tconst placeholder = this.#placeholder;\n\t\tconst options = this.options;\n\t\tconst placeholderMatchesOption =\n\t\t\tplaceholder !== undefined &&\n\t\t\tplaceholder !== '' &&\n\t\t\toptions.some(\n\t\t\t\t(opt) => !opt.disabled && (this.#filterFn ? this.#filterFn(placeholder, opt) : true)\n\t\t\t);\n\t\tif (key.name === 'tab' && isEmptyOrOnlyTab && placeholderMatchesOption) {\n\t\t\tif (this.userInput === '\\t') {\n\t\t\t\tthis._clearUserInput();\n\t\t\t}\n\t\t\tthis._setUserInput(placeholder, true);\n\t\t\tthis.isNavigating = false;\n\t\t\treturn;\n\t\t}\n\n\t\t// Start navigation mode with up/down arrows\n\t\tif (isUpKey || isDownKey) {\n\t\t\tthis.#cursor = findCursor(this.#cursor, isUpKey ? -1 : 1, this.filteredOptions);\n\t\t\tthis.focusedValue = this.filteredOptions[this.#cursor]?.value;\n\t\t\tif (!this.multiple) {\n\t\t\t\tthis.selectedValues = [this.focusedValue];\n\t\t\t}\n\t\t\tthis.isNavigating = true;\n\t\t} else if (isReturnKey) {\n\t\t\tthis.value = normalisedValue(this.multiple, this.selectedValues);\n\t\t} else {\n\t\t\tif (this.multiple) {\n\t\t\t\tif (\n\t\t\t\t\tthis.focusedValue !== undefined &&\n\t\t\t\t\t(key.name === 'tab' || (this.isNavigating && key.name === 'space'))\n\t\t\t\t) {\n\t\t\t\t\tthis.toggleSelected(this.focusedValue);\n\t\t\t\t} else {\n\t\t\t\t\tthis.isNavigating = false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (this.focusedValue) {\n\t\t\t\t\tthis.selectedValues = [this.focusedValue];\n\t\t\t\t}\n\t\t\t\tthis.isNavigating = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tdeselectAll() {\n\t\tthis.selectedValues = [];\n\t}\n\n\ttoggleSelected(value: T['value']) {\n\t\tif (this.filteredOptions.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.multiple) {\n\t\t\tif (this.selectedValues.includes(value)) {\n\t\t\t\tthis.selectedValues = this.selectedValues.filter((v) => v !== value);\n\t\t\t} else {\n\t\t\t\tthis.selectedValues = [...this.selectedValues, value];\n\t\t\t}\n\t\t} else {\n\t\t\tthis.selectedValues = [value];\n\t\t}\n\t}\n\n\t#onUserInputChanged(value: string): void {\n\t\tif (value !== this.#lastUserInput) {\n\t\t\tthis.#lastUserInput = value;\n\n\t\t\tconst options = this.options;\n\n\t\t\tif (value && this.#filterFn) {\n\t\t\t\tthis.filteredOptions = options.filter((opt) => this.#filterFn?.(value, opt));\n\t\t\t} else {\n\t\t\t\tthis.filteredOptions = [...options];\n\t\t\t}\n\t\t\tconst valueCursor = getCursorForValue(this.focusedValue, this.filteredOptions);\n\t\t\tthis.#cursor = findCursor(valueCursor, 0, this.filteredOptions);\n\t\t\tconst focusedOption = this.filteredOptions[this.#cursor];\n\t\t\tif (focusedOption && !focusedOption.disabled) {\n\t\t\t\tthis.focusedValue = focusedOption.value;\n\t\t\t} else {\n\t\t\t\tthis.focusedValue = undefined;\n\t\t\t}\n\t\t\tif (!this.multiple) {\n\t\t\t\tif (this.focusedValue !== undefined) {\n\t\t\t\t\tthis.toggleSelected(this.focusedValue);\n\t\t\t\t} else {\n\t\t\t\t\tthis.deselectAll();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n","import { cursor } from 'sisteransi';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface ConfirmOptions extends PromptOptions<boolean, ConfirmPrompt> {\n\tactive: string;\n\tinactive: string;\n\tinitialValue?: boolean;\n}\n\nexport default class ConfirmPrompt extends Prompt<boolean> {\n\tget cursor() {\n\t\treturn this.value ? 0 : 1;\n\t}\n\n\tprivate get _value() {\n\t\treturn this.cursor === 0;\n\t}\n\n\tconstructor(opts: ConfirmOptions) {\n\t\tsuper(opts, false);\n\t\tthis.value = !!opts.initialValue;\n\n\t\tthis.on('userInput', () => {\n\t\t\tthis.value = this._value;\n\t\t});\n\n\t\tthis.on('confirm', (confirm) => {\n\t\t\tthis.output.write(cursor.move(0, -1));\n\t\t\tthis.value = confirm;\n\t\t\tthis.state = 'submit';\n\t\t\tthis.close();\n\t\t});\n\n\t\tthis.on('cursor', () => {\n\t\t\tthis.value = !this.value;\n\t\t});\n\t}\n}\n","import type { Key } from 'node:readline';\nimport { settings } from '../utils/settings.js';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\ninterface SegmentConfig {\n\ttype: 'year' | 'month' | 'day';\n\tlen: number;\n}\n\nexport interface DateParts {\n\tyear: string;\n\tmonth: string;\n\tday: string;\n}\n\nexport type DateFormat = 'YMD' | 'MDY' | 'DMY';\n\nconst SEGMENTS: Record<string, SegmentConfig> = {\n\tY: { type: 'year', len: 4 },\n\tM: { type: 'month', len: 2 },\n\tD: { type: 'day', len: 2 },\n} as const;\n\nfunction segmentsFor(fmt: DateFormat): SegmentConfig[] {\n\treturn [...fmt].map((c) => SEGMENTS[c as keyof typeof SEGMENTS]);\n}\n\nfunction detectLocaleFormat(locale?: string): { segments: SegmentConfig[]; separator: string } {\n\tconst fmt = new Intl.DateTimeFormat(locale, {\n\t\tyear: 'numeric',\n\t\tmonth: '2-digit',\n\t\tday: '2-digit',\n\t});\n\tconst parts = fmt.formatToParts(new Date(2000, 0, 15));\n\tconst segments: SegmentConfig[] = [];\n\tlet separator = '/';\n\tfor (const p of parts) {\n\t\tif (p.type === 'literal') {\n\t\t\tseparator = p.value.trim() || p.value;\n\t\t} else if (p.type === 'year' || p.type === 'month' || p.type === 'day') {\n\t\t\tsegments.push({ type: p.type, len: p.type === 'year' ? 4 : 2 });\n\t\t}\n\t}\n\treturn { segments, separator };\n}\n\n/** Parse string segment values to numbers, treating blanks as 0 */\nfunction parseSegmentToNum(s: string): number {\n\treturn Number.parseInt((s || '0').replace(/_/g, '0'), 10) || 0;\n}\n\nfunction parse(parts: DateParts): { year: number; month: number; day: number } {\n\treturn {\n\t\tyear: parseSegmentToNum(parts.year),\n\t\tmonth: parseSegmentToNum(parts.month),\n\t\tday: parseSegmentToNum(parts.day),\n\t};\n}\n\nfunction daysInMonth(year: number, month: number): number {\n\treturn new Date(year || 2001, month || 1, 0).getDate();\n}\n\n/** Validate and return calendar parts, or undefined if invalid */\nfunction validParts(parts: DateParts): { year: number; month: number; day: number } | undefined {\n\tconst { year, month, day } = parse(parts);\n\tif (!year || year < 0 || year > 9999) return undefined;\n\tif (!month || month < 1 || month > 12) return undefined;\n\tif (!day || day < 1) return undefined;\n\tconst d = new Date(Date.UTC(year, month - 1, day));\n\tif (d.getUTCFullYear() !== year || d.getUTCMonth() !== month - 1 || d.getUTCDate() !== day)\n\t\treturn undefined;\n\treturn { year, month, day };\n}\n\nfunction toDate(parts: DateParts): Date | undefined {\n\tconst p = validParts(parts);\n\treturn p ? new Date(Date.UTC(p.year, p.month - 1, p.day)) : undefined;\n}\n\nfunction segmentBounds(\n\ttype: 'year' | 'month' | 'day',\n\tctx: { year: number; month: number },\n\tminDate: Date | undefined,\n\tmaxDate: Date | undefined\n): { min: number; max: number } {\n\tconst minP = minDate\n\t\t? {\n\t\t\t\tyear: minDate.getUTCFullYear(),\n\t\t\t\tmonth: minDate.getUTCMonth() + 1,\n\t\t\t\tday: minDate.getUTCDate(),\n\t\t\t}\n\t\t: null;\n\tconst maxP = maxDate\n\t\t? {\n\t\t\t\tyear: maxDate.getUTCFullYear(),\n\t\t\t\tmonth: maxDate.getUTCMonth() + 1,\n\t\t\t\tday: maxDate.getUTCDate(),\n\t\t\t}\n\t\t: null;\n\n\tif (type === 'year') {\n\t\treturn { min: minP?.year ?? 1, max: maxP?.year ?? 9999 };\n\t}\n\tif (type === 'month') {\n\t\treturn {\n\t\t\tmin: minP && ctx.year === minP.year ? minP.month : 1,\n\t\t\tmax: maxP && ctx.year === maxP.year ? maxP.month : 12,\n\t\t};\n\t}\n\treturn {\n\t\tmin: minP && ctx.year === minP.year && ctx.month === minP.month ? minP.day : 1,\n\t\tmax:\n\t\t\tmaxP && ctx.year === maxP.year && ctx.month === maxP.month\n\t\t\t\t? maxP.day\n\t\t\t\t: daysInMonth(ctx.year, ctx.month),\n\t};\n}\n\nexport interface DateOptions extends PromptOptions<Date, DatePrompt> {\n\tformat?: DateFormat;\n\tlocale?: string;\n\tseparator?: string;\n\tdefaultValue?: Date;\n\tinitialValue?: Date;\n\tminDate?: Date;\n\tmaxDate?: Date;\n}\n\nexport default class DatePrompt extends Prompt<Date> {\n\t#segments: SegmentConfig[];\n\t#separator: string;\n\t#segmentValues: DateParts;\n\t#minDate: Date | undefined;\n\t#maxDate: Date | undefined;\n\t#cursor = { segmentIndex: 0, positionInSegment: 0 };\n\t#segmentSelected = true;\n\t#pendingTensDigit: string | null = null;\n\n\tinlineError = '';\n\n\tget segmentCursor() {\n\t\treturn { ...this.#cursor };\n\t}\n\n\tget segmentValues(): DateParts {\n\t\treturn { ...this.#segmentValues };\n\t}\n\n\tget segments(): readonly SegmentConfig[] {\n\t\treturn this.#segments;\n\t}\n\n\tget separator(): string {\n\t\treturn this.#separator;\n\t}\n\n\tget formattedValue(): string {\n\t\treturn this.#format(this.#segmentValues);\n\t}\n\n\t#format(parts: DateParts): string {\n\t\treturn this.#segments.map((s) => parts[s.type]).join(this.#separator);\n\t}\n\n\t#refresh() {\n\t\tthis._setUserInput(this.#format(this.#segmentValues));\n\t\tthis._setValue(toDate(this.#segmentValues) ?? undefined);\n\t}\n\n\tconstructor(opts: DateOptions) {\n\t\tconst detected = opts.format\n\t\t\t? { segments: segmentsFor(opts.format), separator: opts.separator ?? '/' }\n\t\t\t: detectLocaleFormat(opts.locale);\n\t\tconst sep = opts.separator ?? detected.separator;\n\t\tconst segments = opts.format ? segmentsFor(opts.format) : detected.segments;\n\n\t\tconst initialDate = opts.initialValue ?? opts.defaultValue;\n\t\tconst segmentValues: DateParts = initialDate\n\t\t\t? {\n\t\t\t\t\tyear: String(initialDate.getUTCFullYear()).padStart(4, '0'),\n\t\t\t\t\tmonth: String(initialDate.getUTCMonth() + 1).padStart(2, '0'),\n\t\t\t\t\tday: String(initialDate.getUTCDate()).padStart(2, '0'),\n\t\t\t\t}\n\t\t\t: { year: '____', month: '__', day: '__' };\n\n\t\tconst initialDisplay = segments.map((s) => segmentValues[s.type]).join(sep);\n\n\t\tsuper({ ...opts, initialUserInput: initialDisplay }, false);\n\t\tthis.#segments = segments;\n\t\tthis.#separator = sep;\n\t\tthis.#segmentValues = segmentValues;\n\t\tthis.#minDate = opts.minDate;\n\t\tthis.#maxDate = opts.maxDate;\n\t\tthis.#refresh();\n\n\t\tthis.on('cursor', (key) => this.#onCursor(key));\n\t\tthis.on('key', (char, key) => this.#onKey(char, key));\n\t\tthis.on('finalize', () => this.#onFinalize(opts));\n\t}\n\n\t#seg(): { segment: SegmentConfig; index: number } | undefined {\n\t\tconst index = Math.max(0, Math.min(this.#cursor.segmentIndex, this.#segments.length - 1));\n\t\tconst segment = this.#segments[index];\n\t\tif (!segment) return undefined;\n\t\tthis.#cursor.positionInSegment = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.#cursor.positionInSegment, segment.len - 1)\n\t\t);\n\t\treturn { segment, index };\n\t}\n\n\t#navigate(direction: 1 | -1) {\n\t\tthis.inlineError = '';\n\t\tthis.#pendingTensDigit = null;\n\t\tconst ctx = this.#seg();\n\t\tif (!ctx) return;\n\t\tthis.#cursor.segmentIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.#segments.length - 1, ctx.index + direction)\n\t\t);\n\t\tthis.#cursor.positionInSegment = 0;\n\t\tthis.#segmentSelected = true;\n\t}\n\n\t#adjust(direction: 1 | -1) {\n\t\tconst ctx = this.#seg();\n\t\tif (!ctx) return;\n\t\tconst { segment } = ctx;\n\t\tconst raw = this.#segmentValues[segment.type];\n\t\tconst isBlank = !raw || raw.replace(/_/g, '') === '';\n\t\tconst num = Number.parseInt((raw || '0').replace(/_/g, '0'), 10) || 0;\n\t\tconst bounds = segmentBounds(\n\t\t\tsegment.type,\n\t\t\tparse(this.#segmentValues),\n\t\t\tthis.#minDate,\n\t\t\tthis.#maxDate\n\t\t);\n\n\t\tlet next: number;\n\t\tif (isBlank) {\n\t\t\tnext = direction === 1 ? bounds.min : bounds.max;\n\t\t} else {\n\t\t\tnext = Math.max(Math.min(bounds.max, num + direction), bounds.min);\n\t\t}\n\n\t\tthis.#segmentValues = {\n\t\t\t...this.#segmentValues,\n\t\t\t[segment.type]: next.toString().padStart(segment.len, '0'),\n\t\t};\n\t\tthis.#segmentSelected = true;\n\t\tthis.#pendingTensDigit = null;\n\t\tthis.#refresh();\n\t}\n\n\t#onCursor(key?: string) {\n\t\tif (!key) return;\n\t\tswitch (key) {\n\t\t\tcase 'right':\n\t\t\t\treturn this.#navigate(1);\n\t\t\tcase 'left':\n\t\t\t\treturn this.#navigate(-1);\n\t\t\tcase 'up':\n\t\t\t\treturn this.#adjust(1);\n\t\t\tcase 'down':\n\t\t\t\treturn this.#adjust(-1);\n\t\t}\n\t}\n\n\t#onKey(char: string | undefined, key: Key) {\n\t\t// Backspace\n\t\tconst isBackspace =\n\t\t\tkey?.name === 'backspace' ||\n\t\t\tkey?.sequence === '\\x7f' ||\n\t\t\tkey?.sequence === '\\b' ||\n\t\t\tchar === '\\x7f' ||\n\t\t\tchar === '\\b';\n\t\tif (isBackspace) {\n\t\t\tthis.inlineError = '';\n\t\t\tconst ctx = this.#seg();\n\t\t\tif (!ctx) return;\n\t\t\tif (!this.#segmentValues[ctx.segment.type].replace(/_/g, '')) {\n\t\t\t\tthis.#navigate(-1);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#segmentValues[ctx.segment.type] = '_'.repeat(ctx.segment.len);\n\t\t\tthis.#segmentSelected = true;\n\t\t\tthis.#cursor.positionInSegment = 0;\n\t\t\tthis.#refresh();\n\t\t\treturn;\n\t\t}\n\n\t\t// Tab navigation\n\t\tif (key?.name === 'tab') {\n\t\t\tthis.inlineError = '';\n\t\t\tconst ctx = this.#seg();\n\t\t\tif (!ctx) return;\n\t\t\tconst dir = key.shift ? -1 : 1;\n\t\t\tconst next = ctx.index + dir;\n\t\t\tif (next >= 0 && next < this.#segments.length) {\n\t\t\t\tthis.#cursor.segmentIndex = next;\n\t\t\t\tthis.#cursor.positionInSegment = 0;\n\t\t\t\tthis.#segmentSelected = true;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Digit input\n\t\tif (char && /^[0-9]$/.test(char)) {\n\t\t\tconst ctx = this.#seg();\n\t\t\tif (!ctx) return;\n\t\t\tconst { segment } = ctx;\n\t\t\tconst isBlank = !this.#segmentValues[segment.type].replace(/_/g, '');\n\n\t\t\t// Pending tens digit: complete the two-digit entry\n\t\t\tif (this.#segmentSelected && this.#pendingTensDigit !== null && !isBlank) {\n\t\t\t\tconst newVal = this.#pendingTensDigit + char;\n\t\t\t\tconst newParts = { ...this.#segmentValues, [segment.type]: newVal };\n\t\t\t\tconst err = this.#validateSegment(newParts, segment);\n\t\t\t\tif (err) {\n\t\t\t\t\tthis.inlineError = err;\n\t\t\t\t\tthis.#pendingTensDigit = null;\n\t\t\t\t\tthis.#segmentSelected = false;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.inlineError = '';\n\t\t\t\tthis.#segmentValues[segment.type] = newVal;\n\t\t\t\tthis.#pendingTensDigit = null;\n\t\t\t\tthis.#segmentSelected = false;\n\t\t\t\tthis.#refresh();\n\t\t\t\tif (ctx.index < this.#segments.length - 1) {\n\t\t\t\t\tthis.#cursor.segmentIndex = ctx.index + 1;\n\t\t\t\t\tthis.#cursor.positionInSegment = 0;\n\t\t\t\t\tthis.#segmentSelected = true;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Clear-on-type: typing into a selected filled segment clears it first\n\t\t\tif (this.#segmentSelected && !isBlank) {\n\t\t\t\tthis.#segmentValues[segment.type] = '_'.repeat(segment.len);\n\t\t\t\tthis.#cursor.positionInSegment = 0;\n\t\t\t}\n\t\t\tthis.#segmentSelected = false;\n\t\t\tthis.#pendingTensDigit = null;\n\n\t\t\tconst display = this.#segmentValues[segment.type];\n\t\t\tconst firstBlank = display.indexOf('_');\n\t\t\tconst pos =\n\t\t\t\tfirstBlank >= 0 ? firstBlank : Math.min(this.#cursor.positionInSegment, segment.len - 1);\n\t\t\tif (pos < 0 || pos >= segment.len) return;\n\n\t\t\tlet newVal = display.slice(0, pos) + char + display.slice(pos + 1);\n\n\t\t\t// Smart digit placement\n\t\t\tlet shouldStaySelected = false;\n\t\t\tif (pos === 0 && display === '__' && (segment.type === 'month' || segment.type === 'day')) {\n\t\t\t\tconst digit = Number.parseInt(char, 10);\n\t\t\t\tnewVal = `0${char}`;\n\t\t\t\tshouldStaySelected = digit <= (segment.type === 'month' ? 1 : 2);\n\t\t\t}\n\t\t\tif (segment.type === 'year') {\n\t\t\t\tconst digits = display.replace(/_/g, '');\n\t\t\t\tnewVal = (digits + char).padStart(segment.len, '_');\n\t\t\t}\n\n\t\t\tif (!newVal.includes('_')) {\n\t\t\t\tconst newParts = { ...this.#segmentValues, [segment.type]: newVal };\n\t\t\t\tconst err = this.#validateSegment(newParts, segment);\n\t\t\t\tif (err) {\n\t\t\t\t\tthis.inlineError = err;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.inlineError = '';\n\n\t\t\tthis.#segmentValues[segment.type] = newVal;\n\n\t\t\t// Clamp only when the current segment is fully entered\n\t\t\tconst parsed = !newVal.includes('_') ? validParts(this.#segmentValues) : undefined;\n\t\t\tif (parsed) {\n\t\t\t\tconst { year, month } = parsed;\n\t\t\t\tconst maxDay = daysInMonth(year, month);\n\t\t\t\tthis.#segmentValues = {\n\t\t\t\t\tyear: String(Math.max(0, Math.min(9999, year))).padStart(4, '0'),\n\t\t\t\t\tmonth: String(Math.max(1, Math.min(12, month))).padStart(2, '0'),\n\t\t\t\t\tday: String(Math.max(1, Math.min(maxDay, parsed.day))).padStart(2, '0'),\n\t\t\t\t};\n\t\t\t}\n\t\t\tthis.#refresh();\n\n\t\t\t// Advance cursor\n\t\t\tconst nextBlank = newVal.indexOf('_');\n\t\t\tif (shouldStaySelected) {\n\t\t\t\tthis.#segmentSelected = true;\n\t\t\t\tthis.#pendingTensDigit = char;\n\t\t\t} else if (nextBlank >= 0) {\n\t\t\t\tthis.#cursor.positionInSegment = nextBlank;\n\t\t\t} else if (firstBlank >= 0 && ctx.index < this.#segments.length - 1) {\n\t\t\t\tthis.#cursor.segmentIndex = ctx.index + 1;\n\t\t\t\tthis.#cursor.positionInSegment = 0;\n\t\t\t\tthis.#segmentSelected = true;\n\t\t\t} else {\n\t\t\t\tthis.#cursor.positionInSegment = Math.min(pos + 1, segment.len - 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t#validateSegment(parts: DateParts, seg: SegmentConfig): string | undefined {\n\t\tconst { month, day } = parse(parts);\n\t\tif (seg.type === 'month' && (month < 0 || month > 12)) {\n\t\t\treturn settings.date.messages.invalidMonth;\n\t\t}\n\t\tif (seg.type === 'day' && (day < 0 || day > 31)) {\n\t\t\treturn settings.date.messages.invalidDay(31, 'any month');\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t#onFinalize(opts: DateOptions) {\n\t\tconst { year, month, day } = parse(this.#segmentValues);\n\t\tif (year && month && day) {\n\t\t\tconst maxDay = daysInMonth(year, month);\n\t\t\tthis.#segmentValues = {\n\t\t\t\t...this.#segmentValues,\n\t\t\t\tday: String(Math.min(day, maxDay)).padStart(2, '0'),\n\t\t\t};\n\t\t}\n\t\tthis.value = toDate(this.#segmentValues) ?? opts.defaultValue ?? undefined;\n\t}\n}\n","import Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface GroupMultiSelectOptions<T extends { value: any }>\n\textends PromptOptions<T['value'][], GroupMultiSelectPrompt<T>> {\n\toptions: Record<string, T[]>;\n\tinitialValues?: T['value'][];\n\trequired?: boolean;\n\tcursorAt?: T['value'];\n\tselectableGroups?: boolean;\n}\nexport default class GroupMultiSelectPrompt<T extends { value: any }> extends Prompt<T['value'][]> {\n\toptions: (T & { group: string | boolean })[];\n\tcursor = 0;\n\t#selectableGroups: boolean;\n\n\tgetGroupItems(group: string): T[] {\n\t\treturn this.options.filter((o) => o.group === group);\n\t}\n\n\tisGroupSelected(group: string) {\n\t\tconst items = this.getGroupItems(group);\n\t\tconst value = this.value;\n\t\tif (value === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\treturn items.every((i) => value.includes(i.value));\n\t}\n\n\tprivate toggleValue() {\n\t\tconst item = this.options[this.cursor];\n\t\tif (this.value === undefined) {\n\t\t\tthis.value = [];\n\t\t}\n\t\tif (item.group === true) {\n\t\t\tconst group = item.value;\n\t\t\tconst groupedItems = this.getGroupItems(group);\n\t\t\tif (this.isGroupSelected(group)) {\n\t\t\t\tthis.value = this.value.filter(\n\t\t\t\t\t(v: string) => groupedItems.findIndex((i) => i.value === v) === -1\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthis.value = [...this.value, ...groupedItems.map((i) => i.value)];\n\t\t\t}\n\t\t\tthis.value = Array.from(new Set(this.value));\n\t\t} else {\n\t\t\tconst selected = this.value.includes(item.value);\n\t\t\tthis.value = selected\n\t\t\t\t? this.value.filter((v: T['value']) => v !== item.value)\n\t\t\t\t: [...this.value, item.value];\n\t\t}\n\t}\n\n\tconstructor(opts: GroupMultiSelectOptions<T>) {\n\t\tsuper(opts, false);\n\t\tconst { options } = opts;\n\t\tthis.#selectableGroups = opts.selectableGroups !== false;\n\t\tthis.options = Object.entries(options).flatMap(([key, option]) => [\n\t\t\t{ value: key, group: true, label: key },\n\t\t\t...option.map((opt) => ({ ...opt, group: key })),\n\t\t]) as any;\n\t\tthis.value = [...(opts.initialValues ?? [])];\n\t\tthis.cursor = Math.max(\n\t\t\tthis.options.findIndex(({ value }) => value === opts.cursorAt),\n\t\t\tthis.#selectableGroups ? 0 : 1\n\t\t);\n\n\t\tthis.on('cursor', (key) => {\n\t\t\tswitch (key) {\n\t\t\t\tcase 'left':\n\t\t\t\tcase 'up': {\n\t\t\t\t\tthis.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;\n\t\t\t\t\tconst currentIsGroup = this.options[this.cursor]?.group === true;\n\t\t\t\t\tif (!this.#selectableGroups && currentIsGroup) {\n\t\t\t\t\t\tthis.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'down':\n\t\t\t\tcase 'right': {\n\t\t\t\t\tthis.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;\n\t\t\t\t\tconst currentIsGroup = this.options[this.cursor]?.group === true;\n\t\t\t\t\tif (!this.#selectableGroups && currentIsGroup) {\n\t\t\t\t\t\tthis.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'space':\n\t\t\t\t\tthis.toggleValue();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\t}\n}\n","import type { Key } from 'node:readline';\nimport { styleText } from 'node:util';\nimport { findTextCursor } from '../utils/cursor.js';\nimport { type Action, settings } from '../utils/index.js';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface MultiLineOptions extends PromptOptions<string, MultiLinePrompt> {\n\tplaceholder?: string;\n\tdefaultValue?: string;\n\tshowSubmit?: boolean;\n}\n\nexport default class MultiLinePrompt extends Prompt<string> {\n\t#lastKeyWasReturn = false;\n\t#showSubmit: boolean;\n\tpublic focused: 'editor' | 'submit' = 'editor';\n\n\tget userInputWithCursor() {\n\t\tif (this.state === 'submit') {\n\t\t\treturn this.userInput;\n\t\t}\n\t\tconst userInput = this.userInput;\n\t\tif (this.cursor >= userInput.length) {\n\t\t\treturn `${userInput}█`;\n\t\t}\n\t\tconst s1 = userInput.slice(0, this.cursor);\n\t\tconst s2 = userInput[this.cursor];\n\t\tconst s3 = userInput.slice(this.cursor + 1);\n\t\tif (s2 === '\\n') return `${s1}█\\n${s3}`;\n\t\treturn `${s1}${styleText('inverse', s2)}${s3}`;\n\t}\n\tget cursor() {\n\t\treturn this._cursor;\n\t}\n\t#insertAtCursor(char: string) {\n\t\tif (this.userInput.length === 0) {\n\t\t\tthis._setUserInput(char);\n\t\t\treturn;\n\t\t}\n\t\tthis._setUserInput(\n\t\t\tthis.userInput.slice(0, this.cursor) + char + this.userInput.slice(this.cursor)\n\t\t);\n\t}\n\t#handleCursor(key?: Action) {\n\t\tconst text = this.value ?? '';\n\t\tswitch (key) {\n\t\t\tcase 'up':\n\t\t\t\tthis._cursor = findTextCursor(this._cursor, 0, -1, text);\n\t\t\t\treturn;\n\t\t\tcase 'down':\n\t\t\t\tthis._cursor = findTextCursor(this._cursor, 0, 1, text);\n\t\t\t\treturn;\n\t\t\tcase 'left':\n\t\t\t\tthis._cursor = findTextCursor(this._cursor, -1, 0, text);\n\t\t\t\treturn;\n\t\t\tcase 'right':\n\t\t\t\tthis._cursor = findTextCursor(this._cursor, 1, 0, text);\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\tprotected override _shouldSubmit(_char: string | undefined, _key: Key): boolean {\n\t\tif (this.#showSubmit) {\n\t\t\tif (this.focused === 'submit') {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tthis.#insertAtCursor('\\n');\n\t\t\tthis._cursor++;\n\t\t\treturn false;\n\t\t}\n\t\tconst wasReturn = this.#lastKeyWasReturn;\n\t\tthis.#lastKeyWasReturn = true;\n\t\tif (wasReturn) {\n\t\t\tif (this.userInput[this.cursor - 1] === '\\n') {\n\t\t\t\tthis._setUserInput(\n\t\t\t\t\tthis.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)\n\t\t\t\t);\n\t\t\t\tthis._cursor--;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\tthis.#insertAtCursor('\\n');\n\t\tthis._cursor++;\n\t\treturn false;\n\t}\n\n\tconstructor(opts: MultiLineOptions) {\n\t\tsuper(opts, false);\n\t\tthis.#showSubmit = opts.showSubmit ?? false;\n\n\t\tthis.on('key', (char, key) => {\n\t\t\tif (key?.name && settings.actions.has(key.name as Action)) {\n\t\t\t\tthis.#handleCursor(key.name as Action);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (char === '\\t' && this.#showSubmit) {\n\t\t\t\tthis.focused = this.focused === 'editor' ? 'submit' : 'editor';\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (key?.name === 'return') {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#lastKeyWasReturn = false;\n\t\t\tif (key?.name === 'backspace' && this.cursor > 0) {\n\t\t\t\tthis._setUserInput(\n\t\t\t\t\tthis.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)\n\t\t\t\t);\n\t\t\t\tthis._cursor--;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (key?.name === 'delete' && this.cursor < this.userInput.length) {\n\t\t\t\tthis._setUserInput(\n\t\t\t\t\tthis.userInput.slice(0, this.cursor) + this.userInput.slice(this.cursor + 1)\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (char) {\n\t\t\t\tif (this.#showSubmit && this.focused === 'submit') {\n\t\t\t\t\tthis.focused = 'editor';\n\t\t\t\t}\n\t\t\t\tthis.#insertAtCursor(char ?? '');\n\t\t\t\tthis._cursor++;\n\t\t\t}\n\t\t});\n\n\t\tthis.on('userInput', (input) => {\n\t\t\tthis._setValue(input);\n\t\t});\n\t\tthis.on('finalize', () => {\n\t\t\tif (!this.value) {\n\t\t\t\tthis.value = opts.defaultValue;\n\t\t\t}\n\t\t\tif (this.value === undefined) {\n\t\t\t\tthis.value = '';\n\t\t\t}\n\t\t});\n\t}\n}\n","import { findCursor } from '../utils/cursor.js';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\ninterface OptionLike {\n\tvalue: any;\n\tdisabled?: boolean;\n}\n\nexport interface MultiSelectOptions<T extends OptionLike>\n\textends PromptOptions<T['value'][], MultiSelectPrompt<T>> {\n\toptions: T[];\n\tinitialValues?: T['value'][];\n\trequired?: boolean;\n\tcursorAt?: T['value'];\n}\nexport default class MultiSelectPrompt<T extends OptionLike> extends Prompt<T['value'][]> {\n\toptions: T[];\n\tcursor = 0;\n\n\tprivate get _value(): T['value'] {\n\t\treturn this.options[this.cursor].value;\n\t}\n\n\tprivate get _enabledOptions(): T[] {\n\t\treturn this.options.filter((option) => option.disabled !== true);\n\t}\n\n\tprivate toggleAll() {\n\t\tconst enabledOptions = this._enabledOptions;\n\t\tconst allSelected = this.value !== undefined && this.value.length === enabledOptions.length;\n\t\tthis.value = allSelected ? [] : enabledOptions.map((v) => v.value);\n\t}\n\n\tprivate toggleInvert() {\n\t\tconst value = this.value;\n\t\tif (!value) {\n\t\t\treturn;\n\t\t}\n\t\tconst notSelected = this._enabledOptions.filter((v) => !value.includes(v.value));\n\t\tthis.value = notSelected.map((v) => v.value);\n\t}\n\n\tprivate toggleValue() {\n\t\tif (this.value === undefined) {\n\t\t\tthis.value = [];\n\t\t}\n\t\tconst selected = this.value.includes(this._value);\n\t\tthis.value = selected\n\t\t\t? this.value.filter((value) => value !== this._value)\n\t\t\t: [...this.value, this._value];\n\t}\n\n\tconstructor(opts: MultiSelectOptions<T>) {\n\t\tsuper(opts, false);\n\n\t\tthis.options = opts.options;\n\t\tthis.value = [...(opts.initialValues ?? [])];\n\t\tconst cursor = Math.max(\n\t\t\tthis.options.findIndex(({ value }) => value === opts.cursorAt),\n\t\t\t0\n\t\t);\n\t\tthis.cursor = this.options[cursor].disabled ? findCursor<T>(cursor, 1, this.options) : cursor;\n\t\tthis.on('key', (char) => {\n\t\t\tif (char === 'a') {\n\t\t\t\tthis.toggleAll();\n\t\t\t}\n\t\t\tif (char === 'i') {\n\t\t\t\tthis.toggleInvert();\n\t\t\t}\n\t\t});\n\n\t\tthis.on('cursor', (key) => {\n\t\t\tswitch (key) {\n\t\t\t\tcase 'left':\n\t\t\t\tcase 'up':\n\t\t\t\t\tthis.cursor = findCursor<T>(this.cursor, -1, this.options);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'down':\n\t\t\t\tcase 'right':\n\t\t\t\t\tthis.cursor = findCursor<T>(this.cursor, 1, this.options);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'space':\n\t\t\t\t\tthis.toggleValue();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\t}\n}\n","import { styleText } from 'node:util';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface PasswordOptions extends PromptOptions<string, PasswordPrompt> {\n\tmask?: string;\n}\nexport default class PasswordPrompt extends Prompt<string> {\n\tprivate _mask = '•';\n\tget cursor() {\n\t\treturn this._cursor;\n\t}\n\tget masked() {\n\t\treturn this.userInput.replaceAll(/./g, this._mask);\n\t}\n\tget userInputWithCursor() {\n\t\tif (this.state === 'submit' || this.state === 'cancel') {\n\t\t\treturn this.masked;\n\t\t}\n\t\tconst userInput = this.userInput;\n\t\tif (this.cursor >= userInput.length) {\n\t\t\treturn `${this.masked}${styleText(['inverse', 'hidden'], '_')}`;\n\t\t}\n\t\tconst masked = this.masked;\n\t\tconst s1 = masked.slice(0, this.cursor);\n\t\tconst s2 = masked.slice(this.cursor);\n\t\treturn `${s1}${styleText('inverse', s2[0])}${s2.slice(1)}`;\n\t}\n\tclear() {\n\t\tthis._clearUserInput();\n\t}\n\tconstructor({ mask, ...opts }: PasswordOptions) {\n\t\tsuper(opts);\n\t\tthis._mask = mask ?? '•';\n\t\tthis.on('userInput', (input) => {\n\t\t\tthis._setValue(input);\n\t\t});\n\t}\n}\n","import { findCursor } from '../utils/cursor.js';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface SelectOptions<T extends { value: any; disabled?: boolean }>\n\textends PromptOptions<T['value'], SelectPrompt<T>> {\n\toptions: T[];\n\tinitialValue?: T['value'];\n}\nexport default class SelectPrompt<T extends { value: any; disabled?: boolean }> extends Prompt<\n\tT['value']\n> {\n\toptions: T[];\n\tcursor = 0;\n\n\tprivate get _selectedValue() {\n\t\treturn this.options[this.cursor];\n\t}\n\n\tprivate changeValue() {\n\t\tthis.value = this._selectedValue.value;\n\t}\n\n\tconstructor(opts: SelectOptions<T>) {\n\t\tsuper(opts, false);\n\n\t\tthis.options = opts.options;\n\n\t\tconst initialCursor = this.options.findIndex(({ value }) => value === opts.initialValue);\n\t\tconst cursor = initialCursor === -1 ? 0 : initialCursor;\n\t\tthis.cursor = this.options[cursor].disabled ? findCursor<T>(cursor, 1, this.options) : cursor;\n\t\tthis.changeValue();\n\n\t\tthis.on('cursor', (key) => {\n\t\t\tswitch (key) {\n\t\t\t\tcase 'left':\n\t\t\t\tcase 'up':\n\t\t\t\t\tthis.cursor = findCursor<T>(this.cursor, -1, this.options);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'down':\n\t\t\t\tcase 'right':\n\t\t\t\t\tthis.cursor = findCursor<T>(this.cursor, 1, this.options);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.changeValue();\n\t\t});\n\t}\n}\n","import Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface SelectKeyOptions<T extends { value: string }>\n\textends PromptOptions<T['value'], SelectKeyPrompt<T>> {\n\toptions: T[];\n\tcaseSensitive?: boolean;\n}\nexport default class SelectKeyPrompt<T extends { value: string }> extends Prompt<T['value']> {\n\toptions: T[];\n\tcursor = 0;\n\n\tconstructor(opts: SelectKeyOptions<T>) {\n\t\tsuper(opts, false);\n\n\t\tthis.options = opts.options;\n\t\tconst caseSensitive = opts.caseSensitive === true;\n\t\tconst keys = this.options.map(({ value: [initial] }) => {\n\t\t\treturn caseSensitive ? initial : initial?.toLowerCase();\n\t\t});\n\t\tthis.cursor = Math.max(keys.indexOf(opts.initialValue), 0);\n\n\t\tthis.on('key', (key, keyInfo) => {\n\t\t\tif (!key) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst casedKey = caseSensitive && keyInfo.shift ? key.toUpperCase() : key;\n\t\t\tif (!keys.includes(casedKey)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst value = this.options.find(({ value: [initial] }) => {\n\t\t\t\treturn caseSensitive ? initial === casedKey : initial?.toLowerCase() === key;\n\t\t\t});\n\t\t\tif (value) {\n\t\t\t\tthis.value = value.value;\n\t\t\t\tthis.state = 'submit';\n\t\t\t\tthis.emit('submit');\n\t\t\t}\n\t\t});\n\t}\n}\n","import { styleText } from 'node:util';\nimport Prompt, { type PromptOptions } from './prompt.js';\n\nexport interface TextOptions extends PromptOptions<string, TextPrompt> {\n\tplaceholder?: string;\n\tdefaultValue?: string;\n}\n\nexport default class TextPrompt extends Prompt<string> {\n\tget userInputWithCursor() {\n\t\tif (this.state === 'submit') {\n\t\t\treturn this.userInput;\n\t\t}\n\t\tconst userInput = this.userInput;\n\t\tif (this.cursor >= userInput.length) {\n\t\t\treturn `${this.userInput}█`;\n\t\t}\n\t\tconst s1 = userInput.slice(0, this.cursor);\n\t\tconst [s2, ...s3] = userInput.slice(this.cursor);\n\t\treturn `${s1}${styleText('inverse', s2)}${s3.join('')}`;\n\t}\n\tget cursor() {\n\t\treturn this._cursor;\n\t}\n\tconstructor(opts: TextOptions) {\n\t\tsuper({\n\t\t\t...opts,\n\t\t\tinitialUserInput: opts.initialUserInput ?? opts.initialValue,\n\t\t});\n\n\t\tthis.on('userInput', (input) => {\n\t\t\tthis._setValue(input);\n\t\t});\n\t\tthis.on('finalize', () => {\n\t\t\tif (!this.value) {\n\t\t\t\tthis.value = opts.defaultValue;\n\t\t\t}\n\t\t\tif (this.value === undefined) {\n\t\t\t\tthis.value = '';\n\t\t\t}\n\t\t});\n\t}\n}\n","import process from 'node:process';\n\nexport default function isUnicodeSupported() {\n\tif (process.platform !== 'win32') {\n\t\treturn process.env.TERM !== 'linux'; // Linux console (kernel)\n\t}\n\n\treturn Boolean(process.env.CI)\n\t\t|| Boolean(process.env.WT_SESSION) // Windows Terminal\n\t\t|| Boolean(process.env.TERMINUS_SUBLIME) // Terminus (<0.2.27)\n\t\t|| process.env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder\n\t\t|| process.env.TERM_PROGRAM === 'Terminus-Sublime'\n\t\t|| process.env.TERM_PROGRAM === 'vscode'\n\t\t|| process.env.TERM === 'xterm-256color'\n\t\t|| process.env.TERM === 'alacritty'\n\t\t|| process.env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';\n}\n","import type { Readable, Writable } from 'node:stream';\nimport { styleText } from 'node:util';\nimport type { State } from '@clack/core';\nimport isUnicodeSupported from 'is-unicode-supported';\n\nexport const unicode = isUnicodeSupported();\nexport const isCI = (): boolean => process.env.CI === 'true';\nexport const isTTY = (output: Writable): boolean => {\n\treturn (output as Writable & { isTTY?: boolean }).isTTY === true;\n};\nexport const unicodeOr = (c: string, fallback: string) => (unicode ? c : fallback);\nexport const S_STEP_ACTIVE = unicodeOr('◆', '*');\nexport const S_STEP_CANCEL = unicodeOr('■', 'x');\nexport const S_STEP_ERROR = unicodeOr('▲', 'x');\nexport const S_STEP_SUBMIT = unicodeOr('◇', 'o');\n\nexport const S_BAR_START = unicodeOr('┌', 'T');\nexport const S_BAR = unicodeOr('│', '|');\nexport const S_BAR_END = unicodeOr('└', '—');\nexport const S_BAR_START_RIGHT = unicodeOr('┐', 'T');\nexport const S_BAR_END_RIGHT = unicodeOr('┘', '—');\n\nexport const S_RADIO_ACTIVE = unicodeOr('●', '>');\nexport const S_RADIO_INACTIVE = unicodeOr('○', ' ');\nexport const S_CHECKBOX_ACTIVE = unicodeOr('◻', '[•]');\nexport const S_CHECKBOX_SELECTED = unicodeOr('◼', '[+]');\nexport const S_CHECKBOX_INACTIVE = unicodeOr('◻', '[ ]');\nexport const S_PASSWORD_MASK = unicodeOr('▪', '•');\n\nexport const S_BAR_H = unicodeOr('─', '-');\nexport const S_CORNER_TOP_RIGHT = unicodeOr('╮', '+');\nexport const S_CONNECT_LEFT = unicodeOr('├', '+');\nexport const S_CORNER_BOTTOM_RIGHT = unicodeOr('╯', '+');\nexport const S_CORNER_BOTTOM_LEFT = unicodeOr('╰', '+');\nexport const S_CORNER_TOP_LEFT = unicodeOr('╭', '+');\n\nexport const S_INFO = unicodeOr('●', '•');\nexport const S_SUCCESS = unicodeOr('◆', '*');\nexport const S_WARN = unicodeOr('▲', '!');\nexport const S_ERROR = unicodeOr('■', 'x');\n\nexport const symbol = (state: State) => {\n\tswitch (state) {\n\t\tcase 'initial':\n\t\tcase 'active':\n\t\t\treturn styleText('cyan', S_STEP_ACTIVE);\n\t\tcase 'cancel':\n\t\t\treturn styleText('red', S_STEP_CANCEL);\n\t\tcase 'error':\n\t\t\treturn styleText('yellow', S_STEP_ERROR);\n\t\tcase 'submit':\n\t\t\treturn styleText('green', S_STEP_SUBMIT);\n\t}\n};\n\nexport const symbolBar = (state: State) => {\n\tswitch (state) {\n\t\tcase 'initial':\n\t\tcase 'active':\n\t\t\treturn styleText('cyan', S_BAR);\n\t\tcase 'cancel':\n\t\t\treturn styleText('red', S_BAR);\n\t\tcase 'error':\n\t\t\treturn styleText('yellow', S_BAR);\n\t\tcase 'submit':\n\t\t\treturn styleText('green', S_BAR);\n\t}\n};\n\nexport interface CommonOptions {\n\tinput?: Readable;\n\toutput?: Writable;\n\tsignal?: AbortSignal;\n\twithGuide?: boolean;\n}\n","import { styleText } from 'node:util';\nimport { getColumns, getRows } from '@clack/core';\nimport { wrapAnsi } from 'fast-wrap-ansi';\nimport type { CommonOptions } from './common.js';\n\nexport interface LimitOptionsParams<TOption> extends CommonOptions {\n\toptions: TOption[];\n\tcursor: number;\n\tstyle: (option: TOption, active: boolean) => string;\n\tmaxItems?: number;\n\tcolumnPadding?: number;\n\trowPadding?: number;\n}\n\nconst trimLines = (\n\tgroups: Array<string[]>,\n\tinitialLineCount: number,\n\tstartIndex: number,\n\tendIndex: number,\n\tmaxLines: number\n) => {\n\tlet lineCount = initialLineCount;\n\tlet removals = 0;\n\tfor (let i = startIndex; i < endIndex; i++) {\n\t\tconst group = groups[i];\n\t\tlineCount = lineCount - group.length;\n\t\tremovals++;\n\t\tif (lineCount <= maxLines) {\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn { lineCount, removals };\n};\n\nexport const limitOptions = <TOption>({\n\tcursor,\n\toptions,\n\tstyle,\n\toutput = process.stdout,\n\tmaxItems = Number.POSITIVE_INFINITY,\n\tcolumnPadding = 0,\n\trowPadding = 4,\n}: LimitOptionsParams<TOption>): string[] => {\n\tconst columns = getColumns(output);\n\tconst maxWidth = columns - columnPadding;\n\tconst rows = getRows(output);\n\tconst overflowFormat = styleText('dim', '...');\n\n\tconst outputMaxItems = Math.max(rows - rowPadding, 0);\n\t// We clamp to minimum 5 because anything less doesn't make sense UX wise\n\tconst computedMaxItems = Math.max(Math.min(maxItems, outputMaxItems), 5);\n\tlet slidingWindowLocation = 0;\n\n\tif (cursor >= computedMaxItems - 3) {\n\t\tslidingWindowLocation = Math.max(\n\t\t\tMath.min(cursor - computedMaxItems + 3, options.length - computedMaxItems),\n\t\t\t0\n\t\t);\n\t}\n\n\tlet shouldRenderTopEllipsis = computedMaxItems < options.length && slidingWindowLocation > 0;\n\tlet shouldRenderBottomEllipsis =\n\t\tcomputedMaxItems < options.length && slidingWindowLocation + computedMaxItems < options.length;\n\n\tconst slidingWindowLocationEnd = Math.min(\n\t\tslidingWindowLocation + computedMaxItems,\n\t\toptions.length\n\t);\n\tconst lineGroups: Array<string[]> = [];\n\tlet lineCount = 0;\n\tif (shouldRenderTopEllipsis) {\n\t\tlineCount++;\n\t}\n\tif (shouldRenderBottomEllipsis) {\n\t\tlineCount++;\n\t}\n\n\tconst slidingWindowLocationWithEllipsis =\n\t\tslidingWindowLocation + (shouldRenderTopEllipsis ? 1 : 0);\n\tconst slidingWindowLocationEndWithEllipsis =\n\t\tslidingWindowLocationEnd - (shouldRenderBottomEllipsis ? 1 : 0);\n\n\tfor (let i = slidingWindowLocationWithEllipsis; i < slidingWindowLocationEndWithEllipsis; i++) {\n\t\tconst wrappedLines = wrapAnsi(style(options[i], i === cursor), maxWidth, {\n\t\t\thard: true,\n\t\t\ttrim: false,\n\t\t}).split('\\n');\n\t\tlineGroups.push(wrappedLines);\n\t\tlineCount += wrappedLines.length;\n\t}\n\n\tif (lineCount > outputMaxItems) {\n\t\tlet precedingRemovals = 0;\n\t\tlet followingRemovals = 0;\n\t\tlet newLineCount = lineCount;\n\t\tconst cursorGroupIndex = cursor - slidingWindowLocationWithEllipsis;\n\t\tconst trimLinesLocal = (startIndex: number, endIndex: number) =>\n\t\t\ttrimLines(lineGroups, newLineCount, startIndex, endIndex, outputMaxItems);\n\n\t\tif (shouldRenderTopEllipsis) {\n\t\t\t({ lineCount: newLineCount, removals: precedingRemovals } = trimLinesLocal(\n\t\t\t\t0,\n\t\t\t\tcursorGroupIndex\n\t\t\t));\n\t\t\tif (newLineCount > outputMaxItems) {\n\t\t\t\t({ lineCount: newLineCount, removals: followingRemovals } = trimLinesLocal(\n\t\t\t\t\tcursorGroupIndex + 1,\n\t\t\t\t\tlineGroups.length\n\t\t\t\t));\n\t\t\t}\n\t\t} else {\n\t\t\t({ lineCount: newLineCount, removals: followingRemovals } = trimLinesLocal(\n\t\t\t\tcursorGroupIndex + 1,\n\t\t\t\tlineGroups.length\n\t\t\t));\n\t\t\tif (newLineCount > outputMaxItems) {\n\t\t\t\t({ lineCount: newLineCount, removals: precedingRemovals } = trimLinesLocal(\n\t\t\t\t\t0,\n\t\t\t\t\tcursorGroupIndex\n\t\t\t\t));\n\t\t\t}\n\t\t}\n\n\t\tif (precedingRemovals > 0) {\n\t\t\tshouldRenderTopEllipsis = true;\n\t\t\tlineGroups.splice(0, precedingRemovals);\n\t\t}\n\t\tif (followingRemovals > 0) {\n\t\t\tshouldRenderBottomEllipsis = true;\n\t\t\tlineGroups.splice(lineGroups.length - followingRemovals, followingRemovals);\n\t\t}\n\t}\n\n\tconst result: string[] = [];\n\tif (shouldRenderTopEllipsis) {\n\t\tresult.push(overflowFormat);\n\t}\n\tfor (const lineGroup of lineGroups) {\n\t\tfor (const line of lineGroup) {\n\t\t\tresult.push(line);\n\t\t}\n\t}\n\tif (shouldRenderBottomEllipsis) {\n\t\tresult.push(overflowFormat);\n\t}\n\n\treturn result;\n};\n","import { styleText } from 'node:util';\nimport { AutocompletePrompt, settings } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_CHECKBOX_INACTIVE,\n\tS_CHECKBOX_SELECTED,\n\tS_RADIO_ACTIVE,\n\tS_RADIO_INACTIVE,\n\tsymbol,\n} from './common.js';\nimport { limitOptions } from './limit-options.js';\nimport type { Option } from './select.js';\n\nfunction getLabel<T>(option: Option<T>) {\n\treturn option.label ?? String(option.value ?? '');\n}\n\nfunction getFilteredOption<T>(searchText: string, option: Option<T>): boolean {\n\tif (!searchText) {\n\t\treturn true;\n\t}\n\tconst label = (option.label ?? String(option.value ?? '')).toLowerCase();\n\tconst hint = (option.hint ?? '').toLowerCase();\n\tconst value = String(option.value).toLowerCase();\n\tconst term = searchText.toLowerCase();\n\n\treturn label.includes(term) || hint.includes(term) || value.includes(term);\n}\n\nfunction getSelectedOptions<T>(values: T[], options: Option<T>[]): Option<T>[] {\n\tconst results: Option<T>[] = [];\n\n\tfor (const option of options) {\n\t\tif (values.includes(option.value)) {\n\t\t\tresults.push(option);\n\t\t}\n\t}\n\n\treturn results;\n}\n\ninterface AutocompleteSharedOptions<Value> extends CommonOptions {\n\t/**\n\t * The message to display to the user.\n\t */\n\tmessage: string;\n\t/**\n\t * Available options for the autocomplete prompt.\n\t */\n\toptions: Option<Value>[] | ((this: AutocompletePrompt<Option<Value>>) => Option<Value>[]);\n\t/**\n\t * Maximum number of items to display at once.\n\t */\n\tmaxItems?: number;\n\t/**\n\t * Placeholder text to display when no input is provided.\n\t */\n\tplaceholder?: string;\n\t/**\n\t * Validates the value\n\t */\n\tvalidate?: (value: Value | Value[] | undefined) => string | Error | undefined;\n\t/**\n\t * Custom filter function to match options against search input.\n\t * If not provided, a default filter that matches label, hint, and value is used.\n\t */\n\tfilter?: (search: string, option: Option<Value>) => boolean;\n}\n\nexport interface AutocompleteOptions<Value> extends AutocompleteSharedOptions<Value> {\n\t/**\n\t * The initial selected value.\n\t */\n\tinitialValue?: Value;\n\t/**\n\t * The initial user input\n\t */\n\tinitialUserInput?: string;\n}\n\nexport const autocomplete = <Value>(opts: AutocompleteOptions<Value>) => {\n\tconst prompt = new AutocompletePrompt({\n\t\toptions: opts.options,\n\t\tinitialValue: opts.initialValue ? [opts.initialValue] : undefined,\n\t\tinitialUserInput: opts.initialUserInput,\n\t\tplaceholder: opts.placeholder,\n\t\tfilter:\n\t\t\topts.filter ??\n\t\t\t((search: string, opt: Option<Value>) => {\n\t\t\t\treturn getFilteredOption(search, opt);\n\t\t\t}),\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tvalidate: opts.validate,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\t// Title and message display\n\t\t\tconst headings = hasGuide\n\t\t\t\t? [`${styleText('gray', S_BAR)}`, `${symbol(this.state)} ${opts.message}`]\n\t\t\t\t: [`${symbol(this.state)} ${opts.message}`];\n\t\t\tconst userInput = this.userInput;\n\t\t\tconst options = this.options;\n\t\t\tconst placeholder = opts.placeholder;\n\t\t\tconst showPlaceholder = userInput === '' && placeholder !== undefined;\n\t\t\tconst opt = (option: Option<Value>, state: 'inactive' | 'active' | 'disabled') => {\n\t\t\t\tconst label = getLabel(option);\n\t\t\t\tconst hint =\n\t\t\t\t\toption.hint && option.value === this.focusedValue\n\t\t\t\t\t\t? styleText('dim', ` (${option.hint})`)\n\t\t\t\t\t\t: '';\n\t\t\t\tswitch (state) {\n\t\t\t\t\tcase 'active':\n\t\t\t\t\t\treturn `${styleText('green', S_RADIO_ACTIVE)} ${label}${hint}`;\n\t\t\t\t\tcase 'inactive':\n\t\t\t\t\t\treturn `${styleText('dim', S_RADIO_INACTIVE)} ${styleText('dim', label)}`;\n\t\t\t\t\tcase 'disabled':\n\t\t\t\t\t\treturn `${styleText('gray', S_RADIO_INACTIVE)} ${styleText(['strikethrough', 'gray'], label)}`;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Handle different states\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\t// Show selected value\n\t\t\t\t\tconst selected = getSelectedOptions(this.selectedValues, options);\n\t\t\t\t\tconst label =\n\t\t\t\t\t\tselected.length > 0 ? ` ${styleText('dim', selected.map(getLabel).join(', '))}` : '';\n\t\t\t\t\tconst submitPrefix = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${headings.join('\\n')}\\n${submitPrefix}${label}`;\n\t\t\t\t}\n\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst userInputText = userInput\n\t\t\t\t\t\t? ` ${styleText(['strikethrough', 'dim'], userInput)}`\n\t\t\t\t\t\t: '';\n\t\t\t\t\tconst cancelPrefix = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${headings.join('\\n')}\\n${cancelPrefix}${userInputText}`;\n\t\t\t\t}\n\n\t\t\t\tdefault: {\n\t\t\t\t\tconst barStyle = this.state === 'error' ? 'yellow' : 'cyan';\n\t\t\t\t\tconst guidePrefix = hasGuide ? `${styleText(barStyle, S_BAR)} ` : '';\n\t\t\t\t\tconst guidePrefixEnd = hasGuide ? styleText(barStyle, S_BAR_END) : '';\n\t\t\t\t\t// Display cursor position - show plain text in navigation mode\n\t\t\t\t\tlet searchText = '';\n\t\t\t\t\tif (this.isNavigating || showPlaceholder) {\n\t\t\t\t\t\tconst searchTextValue = showPlaceholder ? placeholder : userInput;\n\t\t\t\t\t\tsearchText = searchTextValue !== '' ? ` ${styleText('dim', searchTextValue)}` : '';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsearchText = ` ${this.userInputWithCursor}`;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Show match count if filtered\n\t\t\t\t\tconst matches =\n\t\t\t\t\t\tthis.filteredOptions.length !== options.length\n\t\t\t\t\t\t\t? styleText(\n\t\t\t\t\t\t\t\t\t'dim',\n\t\t\t\t\t\t\t\t\t` (${this.filteredOptions.length} match${this.filteredOptions.length === 1 ? '' : 'es'})`\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: '';\n\n\t\t\t\t\t// No matches message\n\t\t\t\t\tconst noResults =\n\t\t\t\t\t\tthis.filteredOptions.length === 0 && userInput\n\t\t\t\t\t\t\t? [`${guidePrefix}${styleText('yellow', 'No matches found')}`]\n\t\t\t\t\t\t\t: [];\n\n\t\t\t\t\tconst validationError =\n\t\t\t\t\t\tthis.state === 'error' ? [`${guidePrefix}${styleText('yellow', this.error)}`] : [];\n\n\t\t\t\t\tif (hasGuide) {\n\t\t\t\t\t\theadings.push(`${guidePrefix.trimEnd()}`);\n\t\t\t\t\t}\n\t\t\t\t\theadings.push(\n\t\t\t\t\t\t`${guidePrefix}${styleText('dim', 'Search:')}${searchText}${matches}`,\n\t\t\t\t\t\t...noResults,\n\t\t\t\t\t\t...validationError\n\t\t\t\t\t);\n\n\t\t\t\t\t// Show instructions\n\t\t\t\t\tconst instructions = [\n\t\t\t\t\t\t`${styleText('dim', '↑/↓')} to select`,\n\t\t\t\t\t\t`${styleText('dim', 'Enter:')} confirm`,\n\t\t\t\t\t\t`${styleText('dim', 'Type:')} to search`,\n\t\t\t\t\t];\n\n\t\t\t\t\tconst footers = [`${guidePrefix}${instructions.join(' • ')}`, guidePrefixEnd];\n\n\t\t\t\t\t// Render options with selection\n\t\t\t\t\tconst displayOptions =\n\t\t\t\t\t\tthis.filteredOptions.length === 0\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: limitOptions({\n\t\t\t\t\t\t\t\t\tcursor: this.cursor,\n\t\t\t\t\t\t\t\t\toptions: this.filteredOptions,\n\t\t\t\t\t\t\t\t\tcolumnPadding: hasGuide ? 3 : 0, // for `| ` when guide is shown\n\t\t\t\t\t\t\t\t\trowPadding: headings.length + footers.length,\n\t\t\t\t\t\t\t\t\tstyle: (option, active) => {\n\t\t\t\t\t\t\t\t\t\treturn opt(\n\t\t\t\t\t\t\t\t\t\t\toption,\n\t\t\t\t\t\t\t\t\t\t\toption.disabled ? 'disabled' : active ? 'active' : 'inactive'\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tmaxItems: opts.maxItems,\n\t\t\t\t\t\t\t\t\toutput: opts.output,\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t// Return the formatted prompt\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...headings,\n\t\t\t\t\t\t...displayOptions.map((option) => `${guidePrefix}${option}`),\n\t\t\t\t\t\t...footers,\n\t\t\t\t\t].join('\\n');\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t});\n\n\t// Return the result or cancel symbol\n\treturn prompt.prompt() as Promise<Value | symbol>;\n};\n\n// Type definition for the autocompleteMultiselect component\nexport interface AutocompleteMultiSelectOptions<Value> extends AutocompleteSharedOptions<Value> {\n\t/**\n\t * The initial selected values\n\t */\n\tinitialValues?: Value[];\n\t/**\n\t * If true, at least one option must be selected\n\t */\n\trequired?: boolean;\n}\n\n/**\n * Integrated autocomplete multiselect - combines type-ahead filtering with multiselect in one UI\n */\nexport const autocompleteMultiselect = <Value>(opts: AutocompleteMultiSelectOptions<Value>) => {\n\tconst formatOption = (\n\t\toption: Option<Value>,\n\t\tactive: boolean,\n\t\tselectedValues: Value[],\n\t\tfocusedValue: Value | undefined\n\t) => {\n\t\tconst isSelected = selectedValues.includes(option.value);\n\t\tconst label = option.label ?? String(option.value ?? '');\n\t\tconst hint =\n\t\t\toption.hint && focusedValue !== undefined && option.value === focusedValue\n\t\t\t\t? styleText('dim', ` (${option.hint})`)\n\t\t\t\t: '';\n\t\tconst checkbox = isSelected\n\t\t\t? styleText('green', S_CHECKBOX_SELECTED)\n\t\t\t: styleText('dim', S_CHECKBOX_INACTIVE);\n\n\t\tif (option.disabled) {\n\t\t\treturn `${styleText('gray', S_CHECKBOX_INACTIVE)} ${styleText(['strikethrough', 'gray'], label)}`;\n\t\t}\n\t\tif (active) {\n\t\t\treturn `${checkbox} ${label}${hint}`;\n\t\t}\n\t\treturn `${checkbox} ${styleText('dim', label)}`;\n\t};\n\n\t// Create text prompt which we'll use as foundation\n\tconst prompt = new AutocompletePrompt<Option<Value>>({\n\t\toptions: opts.options,\n\t\tmultiple: true,\n\t\tplaceholder: opts.placeholder,\n\t\tfilter:\n\t\t\topts.filter ??\n\t\t\t((search, opt) => {\n\t\t\t\treturn getFilteredOption(search, opt);\n\t\t\t}),\n\t\tvalidate: () => {\n\t\t\tif (opts.required && prompt.selectedValues.length === 0) {\n\t\t\t\treturn 'Please select at least one item';\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t\tinitialValue: opts.initialValues,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\t// Title and symbol\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} ${\n\t\t\t\topts.message\n\t\t\t}\\n`;\n\n\t\t\t// Selection counter\n\t\t\tconst userInput = this.userInput;\n\t\t\tconst placeholder = opts.placeholder;\n\t\t\tconst showPlaceholder = userInput === '' && placeholder !== undefined;\n\n\t\t\t// Search input display\n\t\t\tconst searchText =\n\t\t\t\tthis.isNavigating || showPlaceholder\n\t\t\t\t\t? styleText('dim', showPlaceholder ? placeholder : userInput) // Just show plain text when in navigation mode\n\t\t\t\t\t: this.userInputWithCursor;\n\n\t\t\tconst options = this.options;\n\n\t\t\tconst matches =\n\t\t\t\tthis.filteredOptions.length !== options.length\n\t\t\t\t\t? styleText(\n\t\t\t\t\t\t\t'dim',\n\t\t\t\t\t\t\t` (${this.filteredOptions.length} match${this.filteredOptions.length === 1 ? '' : 'es'})`\n\t\t\t\t\t\t)\n\t\t\t\t\t: '';\n\n\t\t\t// Render prompt state\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\treturn `${title}${hasGuide ? `${styleText('gray', S_BAR)} ` : ''}${styleText(\n\t\t\t\t\t\t'dim',\n\t\t\t\t\t\t`${this.selectedValues.length} items selected`\n\t\t\t\t\t)}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\treturn `${title}${hasGuide ? `${styleText('gray', S_BAR)} ` : ''}${styleText(\n\t\t\t\t\t\t['strikethrough', 'dim'],\n\t\t\t\t\t\tuserInput\n\t\t\t\t\t)}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst barStyle = this.state === 'error' ? 'yellow' : 'cyan';\n\t\t\t\t\tconst guidePrefix = hasGuide ? `${styleText(barStyle, S_BAR)} ` : '';\n\t\t\t\t\tconst guidePrefixEnd = hasGuide ? styleText(barStyle, S_BAR_END) : '';\n\t\t\t\t\t// Instructions\n\t\t\t\t\tconst instructions = [\n\t\t\t\t\t\t`${styleText('dim', '↑/↓')} to navigate`,\n\t\t\t\t\t\t`${styleText('dim', this.isNavigating ? 'Space/Tab:' : 'Tab:')} select`,\n\t\t\t\t\t\t`${styleText('dim', 'Enter:')} confirm`,\n\t\t\t\t\t\t`${styleText('dim', 'Type:')} to search`,\n\t\t\t\t\t];\n\n\t\t\t\t\t// No results message\n\t\t\t\t\tconst noResults =\n\t\t\t\t\t\tthis.filteredOptions.length === 0 && userInput\n\t\t\t\t\t\t\t? [`${guidePrefix}${styleText('yellow', 'No matches found')}`]\n\t\t\t\t\t\t\t: [];\n\n\t\t\t\t\tconst errorMessage =\n\t\t\t\t\t\tthis.state === 'error' ? [`${guidePrefix}${styleText('yellow', this.error)}`] : [];\n\n\t\t\t\t\t// Calculate header and footer line counts for rowPadding\n\t\t\t\t\tconst headerLines = [\n\t\t\t\t\t\t...`${title}${hasGuide ? styleText(barStyle, S_BAR) : ''}`.split('\\n'),\n\t\t\t\t\t\t`${guidePrefix}${styleText('dim', 'Search:')} ${searchText}${matches}`,\n\t\t\t\t\t\t...noResults,\n\t\t\t\t\t\t...errorMessage,\n\t\t\t\t\t];\n\t\t\t\t\tconst footerLines = [`${guidePrefix}${instructions.join(' • ')}`, guidePrefixEnd];\n\n\t\t\t\t\t// Get limited options for display\n\t\t\t\t\tconst displayOptions = limitOptions({\n\t\t\t\t\t\tcursor: this.cursor,\n\t\t\t\t\t\toptions: this.filteredOptions,\n\t\t\t\t\t\tstyle: (option, active) =>\n\t\t\t\t\t\t\tformatOption(option, active, this.selectedValues, this.focusedValue),\n\t\t\t\t\t\tmaxItems: opts.maxItems,\n\t\t\t\t\t\toutput: opts.output,\n\t\t\t\t\t\trowPadding: headerLines.length + footerLines.length,\n\t\t\t\t\t});\n\n\t\t\t\t\t// Build the prompt display\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...headerLines,\n\t\t\t\t\t\t...displayOptions.map((option) => `${guidePrefix}${option}`),\n\t\t\t\t\t\t...footerLines,\n\t\t\t\t\t].join('\\n');\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t});\n\n\t// Return the result or cancel symbol\n\treturn prompt.prompt() as Promise<Value[] | symbol>;\n};\n","import type { Writable } from 'node:stream';\nimport { getColumns, settings } from '@clack/core';\nimport stringWidth from 'fast-string-width';\nimport { wrapAnsi } from 'fast-wrap-ansi';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_BAR_END_RIGHT,\n\tS_BAR_H,\n\tS_BAR_START,\n\tS_BAR_START_RIGHT,\n\tS_CORNER_BOTTOM_LEFT,\n\tS_CORNER_BOTTOM_RIGHT,\n\tS_CORNER_TOP_LEFT,\n\tS_CORNER_TOP_RIGHT,\n} from './common.js';\n\nexport type BoxAlignment = 'left' | 'center' | 'right';\n\ntype BoxSymbols = [topLeft: string, topRight: string, bottomLeft: string, bottomRight: string];\n\nconst roundedSymbols: BoxSymbols = [\n\tS_CORNER_TOP_LEFT,\n\tS_CORNER_TOP_RIGHT,\n\tS_CORNER_BOTTOM_LEFT,\n\tS_CORNER_BOTTOM_RIGHT,\n];\nconst squareSymbols: BoxSymbols = [S_BAR_START, S_BAR_START_RIGHT, S_BAR_END, S_BAR_END_RIGHT];\n\nexport interface BoxOptions extends CommonOptions {\n\tcontentAlign?: BoxAlignment;\n\ttitleAlign?: BoxAlignment;\n\twidth?: number | 'auto';\n\ttitlePadding?: number;\n\tcontentPadding?: number;\n\trounded?: boolean;\n\tformatBorder?: (text: string) => string;\n}\n\nfunction getPaddingForLine(\n\tlineLength: number,\n\tinnerWidth: number,\n\tpadding: number,\n\tcontentAlign: BoxAlignment | undefined\n): [number, number] {\n\tlet leftPadding = padding;\n\tlet rightPadding = padding;\n\tif (contentAlign === 'center') {\n\t\tleftPadding = Math.floor((innerWidth - lineLength) / 2);\n\t} else if (contentAlign === 'right') {\n\t\tleftPadding = innerWidth - lineLength - padding;\n\t}\n\n\trightPadding = innerWidth - leftPadding - lineLength;\n\n\treturn [leftPadding, rightPadding];\n}\n\nconst defaultFormatBorder = (text: string) => text;\n\nexport const box = (message = '', title = '', opts?: BoxOptions) => {\n\tconst output: Writable = opts?.output ?? process.stdout;\n\tconst columns = getColumns(output);\n\tconst borderWidth = 1;\n\tconst borderTotalWidth = borderWidth * 2;\n\tconst titlePadding = opts?.titlePadding ?? 1;\n\tconst contentPadding = opts?.contentPadding ?? 2;\n\tconst width = opts?.width === undefined || opts.width === 'auto' ? 1 : Math.min(1, opts.width);\n\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\tconst linePrefix = !hasGuide ? '' : `${S_BAR} `;\n\tconst formatBorder = opts?.formatBorder ?? defaultFormatBorder;\n\tconst symbols = (opts?.rounded ? roundedSymbols : squareSymbols).map(formatBorder);\n\tconst hSymbol = formatBorder(S_BAR_H);\n\tconst vSymbol = formatBorder(S_BAR);\n\tconst linePrefixWidth = stringWidth(linePrefix);\n\tconst titleWidth = stringWidth(title);\n\tconst maxBoxWidth = columns - linePrefixWidth;\n\tlet boxWidth = Math.floor(columns * width) - linePrefixWidth;\n\tif (opts?.width === 'auto') {\n\t\tconst lines = message.split('\\n');\n\t\tlet longestLine = titleWidth + titlePadding * 2;\n\t\tfor (const line of lines) {\n\t\t\tconst lineWithPadding = stringWidth(line) + contentPadding * 2;\n\t\t\tif (lineWithPadding > longestLine) {\n\t\t\t\tlongestLine = lineWithPadding;\n\t\t\t}\n\t\t}\n\t\tconst longestLineWidth = longestLine + borderTotalWidth;\n\t\tif (longestLineWidth < boxWidth) {\n\t\t\tboxWidth = longestLineWidth;\n\t\t}\n\t}\n\tif (boxWidth % 2 !== 0) {\n\t\tif (boxWidth < maxBoxWidth) {\n\t\t\tboxWidth++;\n\t\t} else {\n\t\t\tboxWidth--;\n\t\t}\n\t}\n\tconst innerWidth = boxWidth - borderTotalWidth;\n\tconst maxTitleLength = innerWidth - titlePadding * 2;\n\tconst truncatedTitle =\n\t\ttitleWidth > maxTitleLength ? `${title.slice(0, maxTitleLength - 3)}...` : title;\n\tconst [titlePaddingLeft, titlePaddingRight] = getPaddingForLine(\n\t\tstringWidth(truncatedTitle),\n\t\tinnerWidth,\n\t\ttitlePadding,\n\t\topts?.titleAlign\n\t);\n\tconst wrappedMessage = wrapAnsi(message, innerWidth - contentPadding * 2, {\n\t\thard: true,\n\t\ttrim: false,\n\t});\n\toutput.write(\n\t\t`${linePrefix}${symbols[0]}${hSymbol.repeat(titlePaddingLeft)}${truncatedTitle}${hSymbol.repeat(titlePaddingRight)}${symbols[1]}\\n`\n\t);\n\tconst wrappedLines = wrappedMessage.split('\\n');\n\tfor (const line of wrappedLines) {\n\t\tconst [leftLinePadding, rightLinePadding] = getPaddingForLine(\n\t\t\tstringWidth(line),\n\t\t\tinnerWidth,\n\t\t\tcontentPadding,\n\t\t\topts?.contentAlign\n\t\t);\n\t\toutput.write(\n\t\t\t`${linePrefix}${vSymbol}${' '.repeat(leftLinePadding)}${line}${' '.repeat(rightLinePadding)}${vSymbol}\\n`\n\t\t);\n\t}\n\toutput.write(`${linePrefix}${symbols[2]}${hSymbol.repeat(innerWidth)}${symbols[3]}\\n`);\n};\n","import { styleText } from 'node:util';\nimport { ConfirmPrompt, settings, wrapTextWithPrefix } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_RADIO_ACTIVE,\n\tS_RADIO_INACTIVE,\n\tsymbol,\n} from './common.js';\n\nexport interface ConfirmOptions extends CommonOptions {\n\tmessage: string;\n\tactive?: string;\n\tinactive?: string;\n\tinitialValue?: boolean;\n\tvertical?: boolean;\n}\nexport const confirm = (opts: ConfirmOptions) => {\n\tconst active = opts.active ?? 'Yes';\n\tconst inactive = opts.inactive ?? 'No';\n\treturn new ConfirmPrompt({\n\t\tactive,\n\t\tinactive,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tinitialValue: opts.initialValue ?? true,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst titlePrefix = `${symbol(this.state)} `;\n\t\t\tconst titlePrefixBar = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\tconst messageLines = wrapTextWithPrefix(\n\t\t\t\topts.output,\n\t\t\t\topts.message,\n\t\t\t\ttitlePrefixBar,\n\t\t\t\ttitlePrefix\n\t\t\t);\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${messageLines}\\n`;\n\t\t\tconst value = this.value ? active : inactive;\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\treturn `${title}${submitPrefix}${styleText('dim', value)}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst cancelPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\treturn `${title}${cancelPrefix}${styleText(['strikethrough', 'dim'], value)}${\n\t\t\t\t\t\thasGuide ? `\\n${styleText('gray', S_BAR)}` : ''\n\t\t\t\t\t}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst defaultPrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst defaultPrefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\treturn `${title}${defaultPrefix}${\n\t\t\t\t\t\tthis.value\n\t\t\t\t\t\t\t? `${styleText('green', S_RADIO_ACTIVE)} ${active}`\n\t\t\t\t\t\t\t: `${styleText('dim', S_RADIO_INACTIVE)} ${styleText('dim', active)}`\n\t\t\t\t\t}${opts.vertical ? (hasGuide ? `\\n${styleText('cyan', S_BAR)} ` : '\\n') : ` ${styleText('dim', '/')} `}${\n\t\t\t\t\t\t!this.value\n\t\t\t\t\t\t\t? `${styleText('green', S_RADIO_ACTIVE)} ${inactive}`\n\t\t\t\t\t\t\t: `${styleText('dim', S_RADIO_INACTIVE)} ${styleText('dim', inactive)}`\n\t\t\t\t\t}\\n${defaultPrefixEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<boolean | symbol>;\n};\n","import { styleText } from 'node:util';\nimport type { DateFormat, State } from '@clack/core';\nimport { DatePrompt, settings } from '@clack/core';\nimport { type CommonOptions, S_BAR, S_BAR_END, symbol } from './common.js';\n\nexport type { DateFormat };\n\nexport interface DateOptions extends CommonOptions {\n\tmessage: string;\n\tformat?: DateFormat;\n\tlocale?: string;\n\tdefaultValue?: Date;\n\tinitialValue?: Date;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tvalidate?: (value: Date | undefined) => string | Error | undefined;\n}\n\nexport const date = (opts: DateOptions) => {\n\tconst validate = opts.validate;\n\treturn new DatePrompt({\n\t\t...opts,\n\t\tvalidate(value: Date | undefined) {\n\t\t\tif (value === undefined) {\n\t\t\t\tif (opts.defaultValue !== undefined) return undefined;\n\t\t\t\tif (validate) return validate(value);\n\t\t\t\treturn settings.date.messages.required;\n\t\t\t}\n\t\t\tconst iso = (d: Date) => d.toISOString().slice(0, 10);\n\t\t\tif (opts.minDate && iso(value) < iso(opts.minDate)) {\n\t\t\t\treturn settings.date.messages.afterMin(opts.minDate);\n\t\t\t}\n\t\t\tif (opts.maxDate && iso(value) > iso(opts.maxDate)) {\n\t\t\t\treturn settings.date.messages.beforeMax(opts.maxDate);\n\t\t\t}\n\t\t\tif (validate) return validate(value);\n\t\t\treturn undefined;\n\t\t},\n\t\trender() {\n\t\t\tconst hasGuide = (opts?.withGuide ?? settings.withGuide) !== false;\n\t\t\tconst titlePrefix = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} `;\n\t\t\tconst title = `${titlePrefix}${opts.message}\\n`;\n\n\t\t\tconst state = this.state !== 'initial' ? this.state : 'active';\n\n\t\t\tconst userInput = renderDate(this, state);\n\t\t\tconst value = this.value instanceof Date ? this.formattedValue : '';\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst errorText = this.error ? ` ${styleText('yellow', this.error)}` : '';\n\t\t\t\t\tconst bar = hasGuide ? `${styleText('yellow', S_BAR)} ` : '';\n\t\t\t\t\tconst barEnd = hasGuide ? styleText('yellow', S_BAR_END) : '';\n\t\t\t\t\treturn `${title.trim()}\\n${bar}${userInput}\\n${barEnd}${errorText}\\n`;\n\t\t\t\t}\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst valueText = value ? ` ${styleText('dim', value)}` : '';\n\t\t\t\t\tconst bar = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${title}${bar}${valueText}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst valueText = value ? ` ${styleText(['strikethrough', 'dim'], value)}` : '';\n\t\t\t\t\tconst bar = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${title}${bar}${valueText}${value.trim() ? `\\n${bar}` : ''}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst bar = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst barEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\tconst inlineBar = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst inlineError = this.inlineError\n\t\t\t\t\t\t? `\\n${inlineBar}${styleText('yellow', this.inlineError)}`\n\t\t\t\t\t\t: '';\n\t\t\t\t\treturn `${title}${bar}${userInput}${inlineError}\\n${barEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<Date | symbol>;\n};\n\nfunction renderDate(prompt: Omit<InstanceType<typeof DatePrompt>, 'prompt'>, state: State): string {\n\tconst parts = prompt.segmentValues;\n\tconst cursor = prompt.segmentCursor;\n\n\tif (state === 'submit' || state === 'cancel') {\n\t\treturn prompt.formattedValue;\n\t}\n\n\tconst sep = styleText('gray', prompt.separator);\n\treturn prompt.segments\n\t\t.map((seg, i) => {\n\t\t\tconst isActive = i === cursor.segmentIndex && !['submit', 'cancel'].includes(state);\n\t\t\tconst label = DEFAULT_LABELS[seg.type];\n\t\t\treturn renderSegment(parts[seg.type], { isActive, label });\n\t\t})\n\t\t.join(sep);\n}\n\ninterface SegmentOptions {\n\tisActive: boolean;\n\tlabel: string;\n}\nfunction renderSegment(value: string, opts: SegmentOptions): string {\n\tconst isBlank = !value || value.replace(/_/g, '') === '';\n\tif (opts.isActive) return styleText('inverse', isBlank ? opts.label : value.replace(/_/g, ' '));\n\tif (isBlank) return styleText('dim', opts.label);\n\treturn value.replace(/_/g, styleText('dim', ' '));\n}\n\nconst DEFAULT_LABELS: Record<'year' | 'month' | 'day', string> = {\n\tyear: 'yyyy',\n\tmonth: 'mm',\n\tday: 'dd',\n};\n","import { isCancel } from '@clack/core';\n\ntype Prettify<T> = {\n\t[P in keyof T]: T[P];\n} & {};\n\nexport type PromptGroupAwaitedReturn<T> = {\n\t[P in keyof T]: Exclude<Awaited<T[P]>, symbol>;\n};\n\nexport interface PromptGroupOptions<T> {\n\t/**\n\t * Control how the group can be canceled\n\t * if one of the prompts is canceled.\n\t */\n\tonCancel?: (opts: { results: Prettify<Partial<PromptGroupAwaitedReturn<T>>> }) => void;\n}\n\nexport type PromptGroup<T> = {\n\t[P in keyof T]: (opts: {\n\t\tresults: Prettify<Partial<PromptGroupAwaitedReturn<Omit<T, P>>>>;\n\t}) => undefined | Promise<T[P] | undefined>;\n};\n\n/**\n * Define a group of prompts to be displayed\n * and return a results of objects within the group\n */\nexport const group = async <T>(\n\tprompts: PromptGroup<T>,\n\topts?: PromptGroupOptions<T>\n): Promise<Prettify<PromptGroupAwaitedReturn<T>>> => {\n\tconst results = {} as any;\n\tconst promptNames = Object.keys(prompts);\n\n\tfor (const name of promptNames) {\n\t\tconst prompt = prompts[name as keyof T];\n\t\tconst result = await prompt({ results })?.catch((e) => {\n\t\t\tthrow e;\n\t\t});\n\n\t\t// Pass the results to the onCancel function\n\t\t// so the user can decide what to do with the results\n\t\t// TODO: Switch to callback within core to avoid isCancel Fn\n\t\tif (typeof opts?.onCancel === 'function' && isCancel(result)) {\n\t\t\tresults[name] = 'canceled';\n\t\t\topts.onCancel({ results });\n\t\t\tcontinue;\n\t\t}\n\n\t\tresults[name] = result;\n\t}\n\n\treturn results;\n};\n","import { styleText } from 'node:util';\nimport { GroupMultiSelectPrompt, settings } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_CHECKBOX_ACTIVE,\n\tS_CHECKBOX_INACTIVE,\n\tS_CHECKBOX_SELECTED,\n\tsymbol,\n} from './common.js';\nimport type { Option } from './select.js';\n\nexport interface GroupMultiSelectOptions<Value> extends CommonOptions {\n\tmessage: string;\n\toptions: Record<string, Option<Value>[]>;\n\tinitialValues?: Value[];\n\trequired?: boolean;\n\tcursorAt?: Value;\n\tselectableGroups?: boolean;\n\tgroupSpacing?: number;\n}\nexport const groupMultiselect = <Value>(opts: GroupMultiSelectOptions<Value>) => {\n\tconst { selectableGroups = true, groupSpacing = 0 } = opts;\n\tconst opt = (\n\t\toption: Option<Value> & { group: string | boolean },\n\t\tstate:\n\t\t\t| 'inactive'\n\t\t\t| 'active'\n\t\t\t| 'selected'\n\t\t\t| 'active-selected'\n\t\t\t| 'group-active'\n\t\t\t| 'group-active-selected'\n\t\t\t| 'submitted'\n\t\t\t| 'cancelled',\n\t\toptions: (Option<Value> & { group: string | boolean })[] = []\n\t) => {\n\t\tconst label = option.label ?? String(option.value);\n\t\tconst isItem = typeof option.group === 'string';\n\t\tconst next = isItem && (options[options.indexOf(option) + 1] ?? { group: true });\n\t\tconst isLast = isItem && next && next.group === true;\n\t\tconst prefix = isItem ? (selectableGroups ? `${isLast ? S_BAR_END : S_BAR} ` : ' ') : '';\n\t\tlet spacingPrefix = '';\n\t\tif (groupSpacing > 0 && !isItem) {\n\t\t\tconst spacingPrefixText = `\\n${styleText('cyan', S_BAR)}`;\n\t\t\tspacingPrefix = `${spacingPrefixText.repeat(groupSpacing - 1)}${spacingPrefixText} `;\n\t\t}\n\n\t\tif (state === 'active') {\n\t\t\treturn `${spacingPrefix}${styleText('dim', prefix)}${styleText('cyan', S_CHECKBOX_ACTIVE)} ${label}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'group-active') {\n\t\t\treturn `${spacingPrefix}${prefix}${styleText('cyan', S_CHECKBOX_ACTIVE)} ${styleText('dim', label)}`;\n\t\t}\n\t\tif (state === 'group-active-selected') {\n\t\t\treturn `${spacingPrefix}${prefix}${styleText('green', S_CHECKBOX_SELECTED)} ${styleText('dim', label)}`;\n\t\t}\n\t\tif (state === 'selected') {\n\t\t\tconst selectedCheckbox =\n\t\t\t\tisItem || selectableGroups ? styleText('green', S_CHECKBOX_SELECTED) : '';\n\t\t\treturn `${spacingPrefix}${styleText('dim', prefix)}${selectedCheckbox} ${styleText('dim', label)}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'cancelled') {\n\t\t\treturn `${styleText(['strikethrough', 'dim'], label)}`;\n\t\t}\n\t\tif (state === 'active-selected') {\n\t\t\treturn `${spacingPrefix}${styleText('dim', prefix)}${styleText('green', S_CHECKBOX_SELECTED)} ${label}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'submitted') {\n\t\t\treturn `${styleText('dim', label)}`;\n\t\t}\n\t\tconst unselectedCheckbox =\n\t\t\tisItem || selectableGroups ? styleText('dim', S_CHECKBOX_INACTIVE) : '';\n\t\treturn `${spacingPrefix}${styleText('dim', prefix)}${unselectedCheckbox} ${styleText('dim', label)}`;\n\t};\n\tconst required = opts.required ?? true;\n\n\treturn new GroupMultiSelectPrompt({\n\t\toptions: opts.options,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tinitialValues: opts.initialValues,\n\t\trequired,\n\t\tcursorAt: opts.cursorAt,\n\t\tselectableGroups,\n\t\tvalidate(selected: Value[] | undefined) {\n\t\t\tif (required && (selected === undefined || selected.length === 0))\n\t\t\t\treturn `Please select at least one option.\\n${styleText(\n\t\t\t\t\t'reset',\n\t\t\t\t\tstyleText(\n\t\t\t\t\t\t'dim',\n\t\t\t\t\t\t`Press ${styleText(['gray', 'bgWhite', 'inverse'], ' space ')} to select, ${styleText(\n\t\t\t\t\t\t\t'gray',\n\t\t\t\t\t\t\tstyleText(['bgWhite', 'inverse'], ' enter ')\n\t\t\t\t\t\t)} to submit`\n\t\t\t\t\t)\n\t\t\t\t)}`;\n\t\t},\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} ${opts.message}\\n`;\n\t\t\tconst value = this.value ?? [];\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst selectedOptions = this.options\n\t\t\t\t\t\t.filter(({ value: optionValue }) => value.includes(optionValue))\n\t\t\t\t\t\t.map((option) => opt(option, 'submitted'));\n\t\t\t\t\tconst optionsText =\n\t\t\t\t\t\tselectedOptions.length === 0 ? '' : ` ${selectedOptions.join(styleText('dim', ', '))}`;\n\t\t\t\t\treturn `${title}${hasGuide ? styleText('gray', S_BAR) : ''}${optionsText}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst label = this.options\n\t\t\t\t\t\t.filter(({ value: optionValue }) => value.includes(optionValue))\n\t\t\t\t\t\t.map((option) => opt(option, 'cancelled'))\n\t\t\t\t\t\t.join(styleText('dim', ', '));\n\t\t\t\t\treturn `${title}${hasGuide ? `${styleText('gray', S_BAR)} ` : ''}${\n\t\t\t\t\t\tlabel.trim() ? `${label}${hasGuide ? `\\n${styleText('gray', S_BAR)}` : ''}` : ''\n\t\t\t\t\t}`;\n\t\t\t\t}\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst footer = this.error\n\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t.map((ln, i) =>\n\t\t\t\t\t\t\ti === 0\n\t\t\t\t\t\t\t\t? `${hasGuide ? `${styleText('yellow', S_BAR_END)} ` : ''}${styleText('yellow', ln)}`\n\t\t\t\t\t\t\t\t: ` ${ln}`\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join('\\n');\n\t\t\t\t\treturn `${title}${hasGuide ? `${styleText('yellow', S_BAR)} ` : ''}${this.options\n\t\t\t\t\t\t.map((option, i, options) => {\n\t\t\t\t\t\t\tconst selected =\n\t\t\t\t\t\t\t\tvalue.includes(option.value) ||\n\t\t\t\t\t\t\t\t(option.group === true && this.isGroupSelected(`${option.value}`));\n\t\t\t\t\t\t\tconst active = i === this.cursor;\n\t\t\t\t\t\t\tconst groupActive =\n\t\t\t\t\t\t\t\t!active &&\n\t\t\t\t\t\t\t\ttypeof option.group === 'string' &&\n\t\t\t\t\t\t\t\tthis.options[this.cursor].value === option.group;\n\t\t\t\t\t\t\tif (groupActive) {\n\t\t\t\t\t\t\t\treturn opt(option, selected ? 'group-active-selected' : 'group-active', options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (active && selected) {\n\t\t\t\t\t\t\t\treturn opt(option, 'active-selected', options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (selected) {\n\t\t\t\t\t\t\t\treturn opt(option, 'selected', options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn opt(option, active ? 'active' : 'inactive', options);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(`\\n${hasGuide ? `${styleText('yellow', S_BAR)} ` : ''}`)}\\n${footer}\\n`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst optionsText = this.options\n\t\t\t\t\t\t.map((option, i, options) => {\n\t\t\t\t\t\t\tconst selected =\n\t\t\t\t\t\t\t\tvalue.includes(option.value) ||\n\t\t\t\t\t\t\t\t(option.group === true && this.isGroupSelected(`${option.value}`));\n\t\t\t\t\t\t\tconst active = i === this.cursor;\n\t\t\t\t\t\t\tconst groupActive =\n\t\t\t\t\t\t\t\t!active &&\n\t\t\t\t\t\t\t\ttypeof option.group === 'string' &&\n\t\t\t\t\t\t\t\tthis.options[this.cursor].value === option.group;\n\t\t\t\t\t\t\tlet optionText = '';\n\t\t\t\t\t\t\tif (groupActive) {\n\t\t\t\t\t\t\t\toptionText = opt(\n\t\t\t\t\t\t\t\t\toption,\n\t\t\t\t\t\t\t\t\tselected ? 'group-active-selected' : 'group-active',\n\t\t\t\t\t\t\t\t\toptions\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else if (active && selected) {\n\t\t\t\t\t\t\t\toptionText = opt(option, 'active-selected', options);\n\t\t\t\t\t\t\t} else if (selected) {\n\t\t\t\t\t\t\t\toptionText = opt(option, 'selected', options);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\toptionText = opt(option, active ? 'active' : 'inactive', options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst prefix = i !== 0 && !optionText.startsWith('\\n') ? ' ' : '';\n\t\t\t\t\t\t\treturn `${prefix}${optionText}`;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(`\\n${hasGuide ? styleText('cyan', S_BAR) : ''}`);\n\t\t\t\t\tconst optionsPrefix = optionsText.startsWith('\\n') ? '' : ' ';\n\t\t\t\t\treturn `${title}${hasGuide ? styleText('cyan', S_BAR) : ''}${optionsPrefix}${optionsText}\\n${\n\t\t\t\t\t\thasGuide ? styleText('cyan', S_BAR_END) : ''\n\t\t\t\t\t}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<Value[] | symbol>;\n};\n","import { styleText } from 'node:util';\nimport { settings } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_ERROR,\n\tS_INFO,\n\tS_STEP_SUBMIT,\n\tS_SUCCESS,\n\tS_WARN,\n} from './common.js';\n\nexport interface LogMessageOptions extends CommonOptions {\n\tsymbol?: string;\n\tspacing?: number;\n\tsecondarySymbol?: string;\n}\n\nexport const log = {\n\tmessage: (\n\t\tmessage: string | string[] = [],\n\t\t{\n\t\t\tsymbol = styleText('gray', S_BAR),\n\t\t\tsecondarySymbol = styleText('gray', S_BAR),\n\t\t\toutput = process.stdout,\n\t\t\tspacing = 1,\n\t\t\twithGuide,\n\t\t}: LogMessageOptions = {}\n\t) => {\n\t\tconst parts: string[] = [];\n\t\tconst hasGuide = withGuide ?? settings.withGuide;\n\t\tconst spacingString = !hasGuide ? '' : secondarySymbol;\n\t\tconst prefix = !hasGuide ? '' : `${symbol} `;\n\t\tconst secondaryPrefix = !hasGuide ? '' : `${secondarySymbol} `;\n\n\t\tfor (let i = 0; i < spacing; i++) {\n\t\t\tparts.push(spacingString);\n\t\t}\n\n\t\tconst messageParts = Array.isArray(message) ? message : message.split('\\n');\n\t\tif (messageParts.length > 0) {\n\t\t\tconst [firstLine, ...lines] = messageParts;\n\t\t\tif (firstLine.length > 0) {\n\t\t\t\tparts.push(`${prefix}${firstLine}`);\n\t\t\t} else {\n\t\t\t\tparts.push(hasGuide ? symbol : '');\n\t\t\t}\n\t\t\tfor (const ln of lines) {\n\t\t\t\tif (ln.length > 0) {\n\t\t\t\t\tparts.push(`${secondaryPrefix}${ln}`);\n\t\t\t\t} else {\n\t\t\t\t\tparts.push(hasGuide ? secondarySymbol : '');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\toutput.write(`${parts.join('\\n')}\\n`);\n\t},\n\tinfo: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.message(message, { ...opts, symbol: styleText('blue', S_INFO) });\n\t},\n\tsuccess: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.message(message, { ...opts, symbol: styleText('green', S_SUCCESS) });\n\t},\n\tstep: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.message(message, { ...opts, symbol: styleText('green', S_STEP_SUBMIT) });\n\t},\n\twarn: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.message(message, { ...opts, symbol: styleText('yellow', S_WARN) });\n\t},\n\t/** alias for `log.warn()`. */\n\twarning: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.warn(message, opts);\n\t},\n\terror: (message: string, opts?: LogMessageOptions) => {\n\t\tlog.message(message, { ...opts, symbol: styleText('red', S_ERROR) });\n\t},\n};\n","import type { Writable } from 'node:stream';\nimport { styleText } from 'node:util';\nimport { settings } from '@clack/core';\nimport { type CommonOptions, S_BAR, S_BAR_END, S_BAR_START } from './common.js';\n\nexport const cancel = (message = '', opts?: CommonOptions) => {\n\tconst output: Writable = opts?.output ?? process.stdout;\n\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\tconst prefix = hasGuide ? `${styleText('gray', S_BAR_END)} ` : '';\n\toutput.write(`${prefix}${styleText('red', message)}\\n\\n`);\n};\n\nexport const intro = (title = '', opts?: CommonOptions) => {\n\tconst output: Writable = opts?.output ?? process.stdout;\n\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\tconst prefix = hasGuide ? `${styleText('gray', S_BAR_START)} ` : '';\n\toutput.write(`${prefix}${title}\\n`);\n};\n\nexport const outro = (message = '', opts?: CommonOptions) => {\n\tconst output: Writable = opts?.output ?? process.stdout;\n\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\tconst prefix = hasGuide ? `${styleText('gray', S_BAR)}\\n${styleText('gray', S_BAR_END)} ` : '';\n\toutput.write(`${prefix}${message}\\n\\n`);\n};\n","import { styleText } from 'node:util';\nimport { MultiLinePrompt, settings, wrapTextWithPrefix } from '@clack/core';\nimport { S_BAR, S_BAR_END, symbol } from './common.js';\nimport type { TextOptions } from './text.js';\n\nexport interface MultiLineOptions extends TextOptions {\n\tshowSubmit?: boolean;\n}\n\nexport const multiline = (opts: MultiLineOptions) => {\n\treturn new MultiLinePrompt({\n\t\tvalidate: opts.validate,\n\t\tplaceholder: opts.placeholder,\n\t\tdefaultValue: opts.defaultValue,\n\t\tinitialValue: opts.initialValue,\n\t\tshowSubmit: opts.showSubmit,\n\t\toutput: opts.output,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\trender() {\n\t\t\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\t\t\tconst titlePrefix = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} `;\n\t\t\tconst title = `${titlePrefix}${opts.message}\\n`;\n\t\t\tconst placeholder = opts.placeholder\n\t\t\t\t? styleText('inverse', opts.placeholder[0]) + styleText('dim', opts.placeholder.slice(1))\n\t\t\t\t: styleText(['inverse', 'hidden'], '_');\n\t\t\tconst userInput = !this.userInput ? placeholder : this.userInputWithCursor;\n\t\t\tconst value = this.value ?? '';\n\t\t\tconst submitButton = opts.showSubmit\n\t\t\t\t? `\\n ${styleText(this.focused === 'submit' ? 'cyan' : 'dim', '[ submit ]')}`\n\t\t\t\t: '';\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst errorPrefix = `${styleText('yellow', S_BAR)} `;\n\t\t\t\t\tconst lines = hasGuide\n\t\t\t\t\t\t? wrapTextWithPrefix(opts.output, userInput, errorPrefix, undefined)\n\t\t\t\t\t\t: userInput;\n\t\t\t\t\tconst errorPrefixEnd = styleText('yellow', S_BAR_END);\n\t\t\t\t\treturn `${title}${lines}\\n${errorPrefixEnd} ${styleText('yellow', this.error)}${submitButton}\\n`;\n\t\t\t\t}\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitPrefix = `${styleText('gray', S_BAR)} `;\n\t\t\t\t\tconst lines = hasGuide\n\t\t\t\t\t\t? wrapTextWithPrefix(opts.output, value, submitPrefix, undefined, (str) =>\n\t\t\t\t\t\t\t\tstyleText('dim', str)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: value\n\t\t\t\t\t\t\t? styleText('dim', value)\n\t\t\t\t\t\t\t: '';\n\t\t\t\t\treturn `${title}${lines}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst cancelPrefix = `${styleText('gray', S_BAR)} `;\n\t\t\t\t\tconst lines = hasGuide\n\t\t\t\t\t\t? wrapTextWithPrefix(opts.output, value, cancelPrefix, undefined, (str) =>\n\t\t\t\t\t\t\t\tstyleText(['strikethrough', 'dim'], str)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: value\n\t\t\t\t\t\t\t? styleText(['strikethrough', 'dim'], value)\n\t\t\t\t\t\t\t: '';\n\t\t\t\t\treturn `${title}${lines}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst defaultPrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst defaultPrefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\tconst lines = hasGuide\n\t\t\t\t\t\t? wrapTextWithPrefix(opts.output, userInput, defaultPrefix)\n\t\t\t\t\t\t: userInput;\n\t\t\t\t\treturn `${title}${lines}\\n${defaultPrefixEnd}${submitButton}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<string | symbol>;\n};\n","import { styleText } from 'node:util';\nimport { MultiSelectPrompt, settings, wrapTextWithPrefix } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_CHECKBOX_ACTIVE,\n\tS_CHECKBOX_INACTIVE,\n\tS_CHECKBOX_SELECTED,\n\tsymbol,\n\tsymbolBar,\n} from './common.js';\nimport { limitOptions } from './limit-options.js';\nimport type { Option } from './select.js';\n\nexport interface MultiSelectOptions<Value> extends CommonOptions {\n\tmessage: string;\n\toptions: Option<Value>[];\n\tinitialValues?: Value[];\n\tmaxItems?: number;\n\trequired?: boolean;\n\tcursorAt?: Value;\n}\nconst computeLabel = (label: string, format: (text: string) => string) => {\n\treturn label\n\t\t.split('\\n')\n\t\t.map((line) => format(line))\n\t\t.join('\\n');\n};\n\nexport const multiselect = <Value>(opts: MultiSelectOptions<Value>) => {\n\tconst opt = (\n\t\toption: Option<Value>,\n\t\tstate:\n\t\t\t| 'inactive'\n\t\t\t| 'active'\n\t\t\t| 'selected'\n\t\t\t| 'active-selected'\n\t\t\t| 'submitted'\n\t\t\t| 'cancelled'\n\t\t\t| 'disabled'\n\t) => {\n\t\tconst label = option.label ?? String(option.value);\n\t\tif (state === 'disabled') {\n\t\t\treturn `${styleText('gray', S_CHECKBOX_INACTIVE)} ${computeLabel(label, (str) => styleText(['strikethrough', 'gray'], str))}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint ?? 'disabled'})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'active') {\n\t\t\treturn `${styleText('cyan', S_CHECKBOX_ACTIVE)} ${label}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'selected') {\n\t\t\treturn `${styleText('green', S_CHECKBOX_SELECTED)} ${computeLabel(label, (text) => styleText('dim', text))}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'cancelled') {\n\t\t\treturn `${computeLabel(label, (text) => styleText(['strikethrough', 'dim'], text))}`;\n\t\t}\n\t\tif (state === 'active-selected') {\n\t\t\treturn `${styleText('green', S_CHECKBOX_SELECTED)} ${label}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\tif (state === 'submitted') {\n\t\t\treturn `${computeLabel(label, (text) => styleText('dim', text))}`;\n\t\t}\n\t\treturn `${styleText('dim', S_CHECKBOX_INACTIVE)} ${computeLabel(label, (text) => styleText('dim', text))}`;\n\t};\n\tconst required = opts.required ?? true;\n\n\treturn new MultiSelectPrompt({\n\t\toptions: opts.options,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tinitialValues: opts.initialValues,\n\t\trequired,\n\t\tcursorAt: opts.cursorAt,\n\t\tvalidate(selected: Value[] | undefined) {\n\t\t\tif (required && (selected === undefined || selected.length === 0))\n\t\t\t\treturn `Please select at least one option.\\n${styleText(\n\t\t\t\t\t'reset',\n\t\t\t\t\tstyleText(\n\t\t\t\t\t\t'dim',\n\t\t\t\t\t\t`Press ${styleText(['gray', 'bgWhite', 'inverse'], ' space ')} to select, ${styleText(\n\t\t\t\t\t\t\t'gray',\n\t\t\t\t\t\t\tstyleText('bgWhite', styleText('inverse', ' enter '))\n\t\t\t\t\t\t)} to submit`\n\t\t\t\t\t)\n\t\t\t\t)}`;\n\t\t},\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst wrappedMessage = wrapTextWithPrefix(\n\t\t\t\topts.output,\n\t\t\t\topts.message,\n\t\t\t\thasGuide ? `${symbolBar(this.state)} ` : '',\n\t\t\t\t`${symbol(this.state)} `\n\t\t\t);\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${wrappedMessage}\\n`;\n\t\t\tconst value = this.value ?? [];\n\n\t\t\tconst styleOption = (option: Option<Value>, active: boolean) => {\n\t\t\t\tif (option.disabled) {\n\t\t\t\t\treturn opt(option, 'disabled');\n\t\t\t\t}\n\t\t\t\tconst selected = value.includes(option.value);\n\t\t\t\tif (active && selected) {\n\t\t\t\t\treturn opt(option, 'active-selected');\n\t\t\t\t}\n\t\t\t\tif (selected) {\n\t\t\t\t\treturn opt(option, 'selected');\n\t\t\t\t}\n\t\t\t\treturn opt(option, active ? 'active' : 'inactive');\n\t\t\t};\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitText =\n\t\t\t\t\t\tthis.options\n\t\t\t\t\t\t\t.filter(({ value: optionValue }) => value.includes(optionValue))\n\t\t\t\t\t\t\t.map((option) => opt(option, 'submitted'))\n\t\t\t\t\t\t\t.join(styleText('dim', ', ')) || styleText('dim', 'none');\n\t\t\t\t\tconst wrappedSubmitText = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\tsubmitText,\n\t\t\t\t\t\thasGuide ? `${styleText('gray', S_BAR)} ` : ''\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrappedSubmitText}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst label = this.options\n\t\t\t\t\t\t.filter(({ value: optionValue }) => value.includes(optionValue))\n\t\t\t\t\t\t.map((option) => opt(option, 'cancelled'))\n\t\t\t\t\t\t.join(styleText('dim', ', '));\n\t\t\t\t\tif (label.trim() === '') {\n\t\t\t\t\t\treturn `${title}${styleText('gray', S_BAR)}`;\n\t\t\t\t\t}\n\t\t\t\t\tconst wrappedLabel = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\tlabel,\n\t\t\t\t\t\thasGuide ? `${styleText('gray', S_BAR)} ` : ''\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrappedLabel}${hasGuide ? `\\n${styleText('gray', S_BAR)}` : ''}`;\n\t\t\t\t}\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst prefix = hasGuide ? `${styleText('yellow', S_BAR)} ` : '';\n\t\t\t\t\tconst footer = this.error\n\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t.map((ln, i) =>\n\t\t\t\t\t\t\ti === 0\n\t\t\t\t\t\t\t\t? `${hasGuide ? `${styleText('yellow', S_BAR_END)} ` : ''}${styleText('yellow', ln)}`\n\t\t\t\t\t\t\t\t: ` ${ln}`\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join('\\n');\n\t\t\t\t\t// Calculate rowPadding: title lines + footer lines (error message + trailing newline)\n\t\t\t\t\tconst titleLineCount = title.split('\\n').length;\n\t\t\t\t\tconst footerLineCount = footer.split('\\n').length + 1; // footer + trailing newline\n\t\t\t\t\treturn `${title}${prefix}${limitOptions({\n\t\t\t\t\t\toutput: opts.output,\n\t\t\t\t\t\toptions: this.options,\n\t\t\t\t\t\tcursor: this.cursor,\n\t\t\t\t\t\tmaxItems: opts.maxItems,\n\t\t\t\t\t\tcolumnPadding: prefix.length,\n\t\t\t\t\t\trowPadding: titleLineCount + footerLineCount,\n\t\t\t\t\t\tstyle: styleOption,\n\t\t\t\t\t}).join(`\\n${prefix}`)}\\n${footer}\\n`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst prefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\t// Calculate rowPadding: title lines + footer lines (S_BAR_END + trailing newline)\n\t\t\t\t\tconst titleLineCount = title.split('\\n').length;\n\t\t\t\t\tconst footerLineCount = hasGuide ? 2 : 1; // S_BAR_END + trailing newline\n\t\t\t\t\treturn `${title}${prefix}${limitOptions({\n\t\t\t\t\t\toutput: opts.output,\n\t\t\t\t\t\toptions: this.options,\n\t\t\t\t\t\tcursor: this.cursor,\n\t\t\t\t\t\tmaxItems: opts.maxItems,\n\t\t\t\t\t\tcolumnPadding: prefix.length,\n\t\t\t\t\t\trowPadding: titleLineCount + footerLineCount,\n\t\t\t\t\t\tstyle: styleOption,\n\t\t\t\t\t}).join(`\\n${prefix}`)}\\n${hasGuide ? styleText('cyan', S_BAR_END) : ''}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<Value[] | symbol>;\n};\n","import process from 'node:process';\nimport type { Writable } from 'node:stream';\nimport { styleText } from 'node:util';\nimport { getColumns, settings } from '@clack/core';\nimport stringWidth from 'fast-string-width';\nimport { type Options as WrapAnsiOptions, wrapAnsi } from 'fast-wrap-ansi';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_H,\n\tS_CONNECT_LEFT,\n\tS_CORNER_BOTTOM_LEFT,\n\tS_CORNER_BOTTOM_RIGHT,\n\tS_CORNER_TOP_RIGHT,\n\tS_STEP_SUBMIT,\n} from './common.js';\n\ntype FormatFn = (line: string) => string;\nexport interface NoteOptions extends CommonOptions {\n\tformat?: FormatFn;\n}\n\nconst defaultNoteFormatter = (line: string): string => styleText('dim', line);\n\nconst wrapWithFormat = (message: string, width: number, format: FormatFn): string => {\n\tconst opts: WrapAnsiOptions = {\n\t\thard: true,\n\t\ttrim: false,\n\t};\n\tconst wrapMsg = wrapAnsi(message, width, opts).split('\\n');\n\tconst maxWidthNormal = wrapMsg.reduce((sum, ln) => Math.max(stringWidth(ln), sum), 0);\n\tconst maxWidthFormat = wrapMsg.map(format).reduce((sum, ln) => Math.max(stringWidth(ln), sum), 0);\n\tconst wrapWidth = width - (maxWidthFormat - maxWidthNormal);\n\treturn wrapAnsi(message, wrapWidth, opts);\n};\n\nexport const note = (message = '', title = '', opts?: NoteOptions) => {\n\tconst output: Writable = opts?.output ?? process.stdout;\n\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\tconst format = opts?.format ?? defaultNoteFormatter;\n\tconst wrapMsg = wrapWithFormat(message, getColumns(output) - 6, format);\n\tconst lines = ['', ...wrapMsg.split('\\n').map(format), ''];\n\tconst titleLen = stringWidth(title);\n\tconst len =\n\t\tMath.max(\n\t\t\tlines.reduce((sum, ln) => {\n\t\t\t\tconst width = stringWidth(ln);\n\t\t\t\treturn width > sum ? width : sum;\n\t\t\t}, 0),\n\t\t\ttitleLen\n\t\t) + 2;\n\tconst msg = lines\n\t\t.map(\n\t\t\t(ln) =>\n\t\t\t\t`${styleText('gray', S_BAR)} ${ln}${' '.repeat(len - stringWidth(ln))}${styleText('gray', S_BAR)}`\n\t\t)\n\t\t.join('\\n');\n\tconst leadingBorder = hasGuide ? `${styleText('gray', S_BAR)}\\n` : '';\n\tconst bottomLeft = hasGuide ? S_CONNECT_LEFT : S_CORNER_BOTTOM_LEFT;\n\toutput.write(\n\t\t`${leadingBorder}${styleText('green', S_STEP_SUBMIT)} ${styleText('reset', title)} ${styleText(\n\t\t\t'gray',\n\t\t\tS_BAR_H.repeat(Math.max(len - titleLen - 1, 1)) + S_CORNER_TOP_RIGHT\n\t\t)}\\n${msg}\\n${styleText('gray', bottomLeft + S_BAR_H.repeat(len + 2) + S_CORNER_BOTTOM_RIGHT)}\\n`\n\t);\n};\n","import { styleText } from 'node:util';\nimport { PasswordPrompt, settings } from '@clack/core';\nimport { type CommonOptions, S_BAR, S_BAR_END, S_PASSWORD_MASK, symbol } from './common.js';\n\nexport interface PasswordOptions extends CommonOptions {\n\tmessage: string;\n\tmask?: string;\n\tvalidate?: (value: string | undefined) => string | Error | undefined;\n\tclearOnError?: boolean;\n}\nexport const password = (opts: PasswordOptions) => {\n\treturn new PasswordPrompt({\n\t\tvalidate: opts.validate,\n\t\tmask: opts.mask ?? S_PASSWORD_MASK,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} ${opts.message}\\n`;\n\t\t\tconst userInput = this.userInputWithCursor;\n\t\t\tconst masked = this.masked;\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst errorPrefix = hasGuide ? `${styleText('yellow', S_BAR)} ` : '';\n\t\t\t\t\tconst errorPrefixEnd = hasGuide ? `${styleText('yellow', S_BAR_END)} ` : '';\n\t\t\t\t\tconst maskedText = masked ?? '';\n\t\t\t\t\tif (opts.clearOnError) {\n\t\t\t\t\t\tthis.clear();\n\t\t\t\t\t}\n\t\t\t\t\treturn `${title.trim()}\\n${errorPrefix}${maskedText}\\n${errorPrefixEnd}${styleText('yellow', this.error)}\\n`;\n\t\t\t\t}\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst maskedText = masked ? styleText('dim', masked) : '';\n\t\t\t\t\treturn `${title}${submitPrefix}${maskedText}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst cancelPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst maskedText = masked ? styleText(['strikethrough', 'dim'], masked) : '';\n\t\t\t\t\treturn `${title}${cancelPrefix}${maskedText}${\n\t\t\t\t\t\tmasked && hasGuide ? `\\n${styleText('gray', S_BAR)}` : ''\n\t\t\t\t\t}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst defaultPrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst defaultPrefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\treturn `${title}${defaultPrefix}${userInput}\\n${defaultPrefixEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<string | symbol>;\n};\n","import { existsSync, lstatSync, readdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { autocomplete } from './autocomplete.js';\nimport type { CommonOptions } from './common.js';\n\nexport interface PathOptions extends CommonOptions {\n\troot?: string;\n\tdirectory?: boolean;\n\tinitialValue?: string;\n\tmessage: string;\n\tvalidate?: (value: string | undefined) => string | Error | undefined;\n}\n\nexport const path = (opts: PathOptions) => {\n\tconst validate = opts.validate;\n\n\treturn autocomplete({\n\t\t...opts,\n\t\tinitialUserInput: opts.initialValue ?? opts.root ?? process.cwd(),\n\t\tmaxItems: 5,\n\t\tvalidate(value) {\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\t// Shouldn't ever happen since we don't enable `multiple: true`\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (!value) {\n\t\t\t\treturn 'Please select a path';\n\t\t\t}\n\t\t\tif (validate) {\n\t\t\t\treturn validate(value);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t\toptions() {\n\t\t\tconst userInput = this.userInput;\n\t\t\tif (userInput === '') {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tlet searchPath: string;\n\n\t\t\t\tif (!existsSync(userInput)) {\n\t\t\t\t\tsearchPath = dirname(userInput);\n\t\t\t\t} else {\n\t\t\t\t\tconst stat = lstatSync(userInput);\n\t\t\t\t\tif (stat.isDirectory() && (!opts.directory || userInput.endsWith('/'))) {\n\t\t\t\t\t\tsearchPath = userInput;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsearchPath = dirname(userInput);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Strip trailing slash so startsWith matches the directory itself among its siblings\n\t\t\t\tconst prefix =\n\t\t\t\t\tuserInput.length > 1 && userInput.endsWith('/') ? userInput.slice(0, -1) : userInput;\n\n\t\t\t\tconst items = readdirSync(searchPath)\n\t\t\t\t\t.map((item) => {\n\t\t\t\t\t\tconst path = join(searchPath, item);\n\t\t\t\t\t\tconst stats = lstatSync(path);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: item,\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\tisDirectory: stats.isDirectory(),\n\t\t\t\t\t\t};\n\t\t\t\t\t})\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t({ path, isDirectory }) => path.startsWith(prefix) && (isDirectory || !opts.directory)\n\t\t\t\t\t);\n\n\t\t\t\treturn items.map((item) => ({\n\t\t\t\t\tvalue: item.path,\n\t\t\t\t}));\n\t\t\t} catch (_e) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\t});\n};\n","import { styleText } from 'node:util';\nimport { block, getColumns, settings } from '@clack/core';\nimport { wrapAnsi } from 'fast-wrap-ansi';\nimport { cursor, erase } from 'sisteransi';\nimport {\n\ttype CommonOptions,\n\tisCI as isCIFn,\n\tS_BAR,\n\tS_STEP_CANCEL,\n\tS_STEP_ERROR,\n\tS_STEP_SUBMIT,\n\tunicode,\n} from './common.js';\n\nexport interface SpinnerOptions extends CommonOptions {\n\tindicator?: 'dots' | 'timer';\n\tonCancel?: () => void;\n\tcancelMessage?: string;\n\terrorMessage?: string;\n\tframes?: string[];\n\tdelay?: number;\n\tstyleFrame?: (frame: string) => string;\n}\n\nexport interface SpinnerResult {\n\tstart(msg?: string): void;\n\tstop(msg?: string): void;\n\tcancel(msg?: string): void;\n\terror(msg?: string): void;\n\tmessage(msg?: string): void;\n\tclear(): void;\n\treadonly isCancelled: boolean;\n}\n\nconst defaultStyleFn: SpinnerOptions['styleFrame'] = (frame) => styleText('magenta', frame);\n\nexport const spinner = ({\n\tindicator = 'dots',\n\tonCancel,\n\toutput = process.stdout,\n\tcancelMessage,\n\terrorMessage,\n\tframes = unicode ? ['◒', '◐', '◓', '◑'] : ['•', 'o', 'O', '0'],\n\tdelay = unicode ? 80 : 120,\n\tsignal,\n\t...opts\n}: SpinnerOptions = {}): SpinnerResult => {\n\tconst isCI = isCIFn();\n\n\tlet unblock: () => void;\n\tlet loop: NodeJS.Timeout;\n\tlet isSpinnerActive = false;\n\tlet isCancelled = false;\n\tlet _message = '';\n\tlet _prevMessage: string | undefined;\n\tlet _origin: number = performance.now();\n\tconst columns = getColumns(output);\n\tconst styleFn = opts?.styleFrame ?? defaultStyleFn;\n\n\tconst handleExit = (code: number) => {\n\t\tconst msg =\n\t\t\tcode > 1\n\t\t\t\t? (errorMessage ?? settings.messages.error)\n\t\t\t\t: (cancelMessage ?? settings.messages.cancel);\n\t\tisCancelled = code === 1;\n\t\tif (isSpinnerActive) {\n\t\t\t_stop(msg, code);\n\t\t\tif (isCancelled && typeof onCancel === 'function') {\n\t\t\t\tonCancel();\n\t\t\t}\n\t\t}\n\t};\n\n\tconst errorEventHandler = () => handleExit(2);\n\tconst signalEventHandler = () => handleExit(1);\n\n\tconst registerHooks = () => {\n\t\t// Reference: https://nodejs.org/api/process.html#event-uncaughtexception\n\t\tprocess.on('uncaughtExceptionMonitor', errorEventHandler);\n\t\t// Reference: https://nodejs.org/api/process.html#event-unhandledrejection\n\t\tprocess.on('unhandledRejection', errorEventHandler);\n\t\t// Reference Signal Events: https://nodejs.org/api/process.html#signal-events\n\t\tprocess.on('SIGINT', signalEventHandler);\n\t\tprocess.on('SIGTERM', signalEventHandler);\n\t\tprocess.on('exit', handleExit);\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', signalEventHandler);\n\t\t}\n\t};\n\n\tconst clearHooks = () => {\n\t\tprocess.removeListener('uncaughtExceptionMonitor', errorEventHandler);\n\t\tprocess.removeListener('unhandledRejection', errorEventHandler);\n\t\tprocess.removeListener('SIGINT', signalEventHandler);\n\t\tprocess.removeListener('SIGTERM', signalEventHandler);\n\t\tprocess.removeListener('exit', handleExit);\n\n\t\tif (signal) {\n\t\t\tsignal.removeEventListener('abort', signalEventHandler);\n\t\t}\n\t};\n\n\tconst clearPrevMessage = () => {\n\t\tif (_prevMessage === undefined) return;\n\t\tif (isCI) output.write('\\n');\n\t\tconst wrapped = wrapAnsi(_prevMessage, columns, {\n\t\t\thard: true,\n\t\t\ttrim: false,\n\t\t});\n\t\tconst prevLines = wrapped.split('\\n');\n\t\tif (prevLines.length > 1) {\n\t\t\toutput.write(cursor.up(prevLines.length - 1));\n\t\t}\n\t\toutput.write(cursor.to(0));\n\t\toutput.write(erase.down());\n\t};\n\n\tconst removeTrailingDots = (msg: string): string => {\n\t\treturn msg.replace(/\\.+$/, '');\n\t};\n\n\tconst formatTimer = (origin: number): string => {\n\t\tconst duration = (performance.now() - origin) / 1000;\n\t\tconst min = Math.floor(duration / 60);\n\t\tconst secs = Math.floor(duration % 60);\n\t\treturn min > 0 ? `[${min}m ${secs}s]` : `[${secs}s]`;\n\t};\n\n\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\n\tconst start = (msg = ''): void => {\n\t\tisSpinnerActive = true;\n\t\tunblock = block({ output });\n\t\t_message = removeTrailingDots(msg);\n\t\t_origin = performance.now();\n\t\tif (hasGuide) {\n\t\t\toutput.write(`${styleText('gray', S_BAR)}\\n`);\n\t\t}\n\t\tlet frameIndex = 0;\n\t\tlet indicatorTimer = 0;\n\t\tregisterHooks();\n\t\tloop = setInterval(() => {\n\t\t\tif (isCI && _message === _prevMessage) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tclearPrevMessage();\n\t\t\t_prevMessage = _message;\n\t\t\tconst frame = styleFn(frames[frameIndex]);\n\t\t\tlet outputMessage: string;\n\n\t\t\tif (isCI) {\n\t\t\t\toutputMessage = `${frame} ${_message}...`;\n\t\t\t} else if (indicator === 'timer') {\n\t\t\t\toutputMessage = `${frame} ${_message} ${formatTimer(_origin)}`;\n\t\t\t} else {\n\t\t\t\tconst loadingDots = '.'.repeat(Math.floor(indicatorTimer)).slice(0, 3);\n\t\t\t\toutputMessage = `${frame} ${_message}${loadingDots}`;\n\t\t\t}\n\n\t\t\tconst wrapped = wrapAnsi(outputMessage, columns, {\n\t\t\t\thard: true,\n\t\t\t\ttrim: false,\n\t\t\t});\n\t\t\toutput.write(wrapped);\n\n\t\t\tframeIndex = frameIndex + 1 < frames.length ? frameIndex + 1 : 0;\n\t\t\t// indicator increase by 1 every 8 frames\n\t\t\tindicatorTimer = indicatorTimer < 4 ? indicatorTimer + 0.125 : 0;\n\t\t}, delay);\n\t};\n\n\tconst _stop = (msg = '', code = 0, silent: boolean = false): void => {\n\t\tif (!isSpinnerActive) return;\n\t\tisSpinnerActive = false;\n\t\tclearInterval(loop);\n\t\tclearPrevMessage();\n\t\tconst step =\n\t\t\tcode === 0\n\t\t\t\t? styleText('green', S_STEP_SUBMIT)\n\t\t\t\t: code === 1\n\t\t\t\t\t? styleText('red', S_STEP_CANCEL)\n\t\t\t\t\t: styleText('red', S_STEP_ERROR);\n\t\t_message = msg ?? _message;\n\t\tif (!silent) {\n\t\t\tif (indicator === 'timer') {\n\t\t\t\toutput.write(`${step} ${_message} ${formatTimer(_origin)}\\n`);\n\t\t\t} else {\n\t\t\t\toutput.write(`${step} ${_message}\\n`);\n\t\t\t}\n\t\t}\n\t\tclearHooks();\n\t\tunblock();\n\t};\n\n\tconst stop = (msg = ''): void => _stop(msg, 0);\n\tconst cancel = (msg = ''): void => _stop(msg, 1);\n\tconst error = (msg = ''): void => _stop(msg, 2);\n\t// TODO (43081j): this will leave the initial S_BAR since we purposely\n\t// don't erase that in `clearPrevMessage`. In future, we may want to treat\n\t// `clear` as a special case and remove the bar too.\n\tconst clear = (): void => _stop('', 0, true);\n\n\tconst message = (msg = ''): void => {\n\t\t_message = removeTrailingDots(msg ?? _message);\n\t};\n\n\treturn {\n\t\tstart,\n\t\tstop,\n\t\tmessage,\n\t\tcancel,\n\t\terror,\n\t\tclear,\n\t\tget isCancelled() {\n\t\t\treturn isCancelled;\n\t\t},\n\t};\n};\n","import { styleText } from 'node:util';\nimport type { State } from '@clack/core';\nimport { unicodeOr } from './common.js';\nimport { type SpinnerOptions, type SpinnerResult, spinner } from './spinner.js';\n\nconst S_PROGRESS_CHAR: Record<NonNullable<ProgressOptions['style']>, string> = {\n\tlight: unicodeOr('─', '-'),\n\theavy: unicodeOr('━', '='),\n\tblock: unicodeOr('█', '#'),\n};\n\nexport interface ProgressOptions extends SpinnerOptions {\n\tstyle?: 'light' | 'heavy' | 'block';\n\tmax?: number;\n\tsize?: number;\n}\n\nexport interface ProgressResult extends SpinnerResult {\n\tadvance(step?: number, msg?: string): void;\n}\n\nexport function progress({\n\tstyle = 'heavy',\n\tmax: userMax = 100,\n\tsize: userSize = 40,\n\t...spinnerOptions\n}: ProgressOptions = {}): ProgressResult {\n\tconst spin = spinner(spinnerOptions);\n\tlet value = 0;\n\tlet previousMessage = '';\n\n\tconst max = Math.max(1, userMax);\n\tconst size = Math.max(1, userSize);\n\n\tconst activeStyle = (state: State) => {\n\t\tswitch (state) {\n\t\t\tcase 'initial':\n\t\t\tcase 'active':\n\t\t\t\treturn (text: string) => styleText('magenta', text);\n\t\t\tcase 'error':\n\t\t\tcase 'cancel':\n\t\t\t\treturn (text: string) => styleText('red', text);\n\t\t\tcase 'submit':\n\t\t\t\treturn (text: string) => styleText('green', text);\n\t\t\tdefault:\n\t\t\t\treturn (text: string) => styleText('magenta', text);\n\t\t}\n\t};\n\tconst drawProgress = (state: State, msg: string) => {\n\t\tconst active = Math.floor((value / max) * size);\n\t\treturn `${activeStyle(state)(S_PROGRESS_CHAR[style].repeat(active))}${styleText('dim', S_PROGRESS_CHAR[style].repeat(size - active))} ${msg}`;\n\t};\n\n\tconst start = (msg = '') => {\n\t\tpreviousMessage = msg;\n\t\tspin.start(drawProgress('initial', msg));\n\t};\n\tconst advance = (step = 1, msg?: string): void => {\n\t\tvalue = Math.min(max, step + value);\n\t\tspin.message(drawProgress('active', msg ?? previousMessage));\n\t\tpreviousMessage = msg ?? previousMessage;\n\t};\n\treturn {\n\t\tstart,\n\t\tstop: spin.stop,\n\t\tcancel: spin.cancel,\n\t\terror: spin.error,\n\t\tclear: spin.clear,\n\t\tadvance,\n\t\tisCancelled: spin.isCancelled,\n\t\tmessage: (msg: string) => advance(0, msg),\n\t};\n}\n","import { styleText } from 'node:util';\nimport { SelectPrompt, settings, wrapTextWithPrefix } from '@clack/core';\nimport {\n\ttype CommonOptions,\n\tS_BAR,\n\tS_BAR_END,\n\tS_RADIO_ACTIVE,\n\tS_RADIO_INACTIVE,\n\tsymbol,\n\tsymbolBar,\n} from './common.js';\nimport { limitOptions } from './limit-options.js';\n\ntype Primitive = Readonly<string | boolean | number>;\n\nexport type Option<Value> = Value extends Primitive\n\t? {\n\t\t\t/**\n\t\t\t * Internal data for this option.\n\t\t\t */\n\t\t\tvalue: Value;\n\t\t\t/**\n\t\t\t * The optional, user-facing text for this option.\n\t\t\t *\n\t\t\t * By default, the `value` is converted to a string.\n\t\t\t */\n\t\t\tlabel?: string;\n\t\t\t/**\n\t\t\t * An optional hint to display to the user when\n\t\t\t * this option might be selected.\n\t\t\t *\n\t\t\t * By default, no `hint` is displayed.\n\t\t\t */\n\t\t\thint?: string;\n\t\t\t/**\n\t\t\t * Whether this option is disabled.\n\t\t\t * Disabled options are visible but cannot be selected.\n\t\t\t *\n\t\t\t * By default, options are not disabled.\n\t\t\t */\n\t\t\tdisabled?: boolean;\n\t\t}\n\t: {\n\t\t\t/**\n\t\t\t * Internal data for this option.\n\t\t\t */\n\t\t\tvalue: Value;\n\t\t\t/**\n\t\t\t * Required. The user-facing text for this option.\n\t\t\t */\n\t\t\tlabel: string;\n\t\t\t/**\n\t\t\t * An optional hint to display to the user when\n\t\t\t * this option might be selected.\n\t\t\t *\n\t\t\t * By default, no `hint` is displayed.\n\t\t\t */\n\t\t\thint?: string;\n\t\t\t/**\n\t\t\t * Whether this option is disabled.\n\t\t\t * Disabled options are visible but cannot be selected.\n\t\t\t *\n\t\t\t * By default, options are not disabled.\n\t\t\t */\n\t\t\tdisabled?: boolean;\n\t\t};\n\nexport interface SelectOptions<Value> extends CommonOptions {\n\tmessage: string;\n\toptions: Option<Value>[];\n\tinitialValue?: Value;\n\tmaxItems?: number;\n}\n\nconst computeLabel = (label: string, format: (text: string) => string) => {\n\tif (!label.includes('\\n')) {\n\t\treturn format(label);\n\t}\n\treturn label\n\t\t.split('\\n')\n\t\t.map((line) => format(line))\n\t\t.join('\\n');\n};\n\nexport const select = <Value>(opts: SelectOptions<Value>) => {\n\tconst opt = (\n\t\toption: Option<Value>,\n\t\tstate: 'inactive' | 'active' | 'selected' | 'cancelled' | 'disabled'\n\t) => {\n\t\tconst label = option.label ?? String(option.value);\n\t\tswitch (state) {\n\t\t\tcase 'disabled':\n\t\t\t\treturn `${styleText('gray', S_RADIO_INACTIVE)} ${computeLabel(label, (text) => styleText('gray', text))}${\n\t\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint ?? 'disabled'})`)}` : ''\n\t\t\t\t}`;\n\t\t\tcase 'selected':\n\t\t\t\treturn `${computeLabel(label, (text) => styleText('dim', text))}`;\n\t\t\tcase 'active':\n\t\t\t\treturn `${styleText('green', S_RADIO_ACTIVE)} ${label}${\n\t\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t\t}`;\n\t\t\tcase 'cancelled':\n\t\t\t\treturn `${computeLabel(label, (str) => styleText(['strikethrough', 'dim'], str))}`;\n\t\t\tdefault:\n\t\t\t\treturn `${styleText('dim', S_RADIO_INACTIVE)} ${computeLabel(label, (text) => styleText('dim', text))}`;\n\t\t}\n\t};\n\n\treturn new SelectPrompt({\n\t\toptions: opts.options,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tinitialValue: opts.initialValue,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst titlePrefix = `${symbol(this.state)} `;\n\t\t\tconst titlePrefixBar = `${symbolBar(this.state)} `;\n\t\t\tconst messageLines = wrapTextWithPrefix(\n\t\t\t\topts.output,\n\t\t\t\topts.message,\n\t\t\t\ttitlePrefixBar,\n\t\t\t\ttitlePrefix\n\t\t\t);\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${messageLines}\\n`;\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst wrappedLines = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\topt(this.options[this.cursor], 'selected'),\n\t\t\t\t\t\tsubmitPrefix\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrappedLines}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst cancelPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst wrappedLines = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\topt(this.options[this.cursor], 'cancelled'),\n\t\t\t\t\t\tcancelPrefix\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrappedLines}${hasGuide ? `\\n${styleText('gray', S_BAR)}` : ''}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst prefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst prefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\t// Calculate rowPadding: title lines + footer lines (S_BAR_END + trailing newline)\n\t\t\t\t\tconst titleLineCount = title.split('\\n').length;\n\t\t\t\t\tconst footerLineCount = hasGuide ? 2 : 1; // S_BAR_END + trailing newline (or just trailing newline)\n\t\t\t\t\treturn `${title}${prefix}${limitOptions({\n\t\t\t\t\t\toutput: opts.output,\n\t\t\t\t\t\tcursor: this.cursor,\n\t\t\t\t\t\toptions: this.options,\n\t\t\t\t\t\tmaxItems: opts.maxItems,\n\t\t\t\t\t\tcolumnPadding: prefix.length,\n\t\t\t\t\t\trowPadding: titleLineCount + footerLineCount,\n\t\t\t\t\t\tstyle: (item, active) =>\n\t\t\t\t\t\t\topt(item, item.disabled ? 'disabled' : active ? 'active' : 'inactive'),\n\t\t\t\t\t}).join(`\\n${prefix}`)}\\n${prefixEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<Value | symbol>;\n};\n","import { styleText } from 'node:util';\nimport { SelectKeyPrompt, settings, wrapTextWithPrefix } from '@clack/core';\nimport { type CommonOptions, S_BAR, S_BAR_END, symbol } from './common.js';\nimport type { Option } from './select.js';\n\nexport interface SelectKeyOptions<Value extends string> extends CommonOptions {\n\tmessage: string;\n\toptions: Option<Value>[];\n\tinitialValue?: Value;\n\tcaseSensitive?: boolean;\n}\n\nexport const selectKey = <Value extends string>(opts: SelectKeyOptions<Value>) => {\n\tconst opt = (\n\t\toption: Option<Value>,\n\t\tstate: 'inactive' | 'active' | 'selected' | 'cancelled' = 'inactive'\n\t) => {\n\t\tconst label = option.label ?? String(option.value);\n\t\tif (state === 'selected') {\n\t\t\treturn `${styleText('dim', label)}`;\n\t\t}\n\t\tif (state === 'cancelled') {\n\t\t\treturn `${styleText(['strikethrough', 'dim'], label)}`;\n\t\t}\n\t\tif (state === 'active') {\n\t\t\treturn `${styleText(['bgCyan', 'gray'], ` ${option.value} `)} ${label}${\n\t\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t\t}`;\n\t\t}\n\t\treturn `${styleText(['gray', 'bgWhite', 'inverse'], ` ${option.value} `)} ${label}${\n\t\t\toption.hint ? ` ${styleText('dim', `(${option.hint})`)}` : ''\n\t\t}`;\n\t};\n\n\treturn new SelectKeyPrompt({\n\t\toptions: opts.options,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\toutput: opts.output,\n\t\tinitialValue: opts.initialValue,\n\t\tcaseSensitive: opts.caseSensitive,\n\t\trender() {\n\t\t\tconst hasGuide = opts.withGuide ?? settings.withGuide;\n\t\t\tconst title = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} ${opts.message}\\n`;\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst submitPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst selectedOption =\n\t\t\t\t\t\tthis.options.find((opt) => opt.value === this.value) ?? opts.options[0];\n\t\t\t\t\tconst wrapped = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\topt(selectedOption, 'selected'),\n\t\t\t\t\t\tsubmitPrefix\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrapped}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst cancelPrefix = hasGuide ? `${styleText('gray', S_BAR)} ` : '';\n\t\t\t\t\tconst wrapped = wrapTextWithPrefix(\n\t\t\t\t\t\topts.output,\n\t\t\t\t\t\topt(this.options[0], 'cancelled'),\n\t\t\t\t\t\tcancelPrefix\n\t\t\t\t\t);\n\t\t\t\t\treturn `${title}${wrapped}${hasGuide ? `\\n${styleText('gray', S_BAR)}` : ''}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst defaultPrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst defaultPrefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\tconst wrapped = this.options\n\t\t\t\t\t\t.map((option, i) =>\n\t\t\t\t\t\t\twrapTextWithPrefix(\n\t\t\t\t\t\t\t\topts.output,\n\t\t\t\t\t\t\t\topt(option, i === this.cursor ? 'active' : 'inactive'),\n\t\t\t\t\t\t\t\tdefaultPrefix\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join('\\n');\n\t\t\t\t\treturn `${title}${wrapped}\\n${defaultPrefixEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<Value | symbol>;\n};\n","import { stripVTControlCharacters as strip, styleText } from 'node:util';\nimport { S_BAR, S_ERROR, S_INFO, S_STEP_SUBMIT, S_SUCCESS, S_WARN } from './common.js';\nimport type { LogMessageOptions } from './log.js';\n\nconst prefix = `${styleText('gray', S_BAR)} `;\n\n// TODO (43081j): this currently doesn't support custom `output` writables\n// because we rely on `columns` existing (i.e. `process.stdout.columns).\n//\n// If we want to support `output` being passed in, we will need to use\n// a condition like `if (output insance Writable)` to check if it has columns\nexport const stream = {\n\tmessage: async (\n\t\titerable: Iterable<string> | AsyncIterable<string>,\n\t\t{ symbol = styleText('gray', S_BAR) }: LogMessageOptions = {}\n\t) => {\n\t\tprocess.stdout.write(`${styleText('gray', S_BAR)}\\n${symbol} `);\n\t\tlet lineWidth = 3;\n\t\tfor await (let chunk of iterable) {\n\t\t\tchunk = chunk.replace(/\\n/g, `\\n${prefix}`);\n\t\t\tif (chunk.includes('\\n')) {\n\t\t\t\tlineWidth = 3 + strip(chunk.slice(chunk.lastIndexOf('\\n'))).length;\n\t\t\t}\n\t\t\tconst chunkLen = strip(chunk).length;\n\t\t\tif (lineWidth + chunkLen < process.stdout.columns) {\n\t\t\t\tlineWidth += chunkLen;\n\t\t\t\tprocess.stdout.write(chunk);\n\t\t\t} else {\n\t\t\t\tprocess.stdout.write(`\\n${prefix}${chunk.trimStart()}`);\n\t\t\t\tlineWidth = 3 + strip(chunk.trimStart()).length;\n\t\t\t}\n\t\t}\n\t\tprocess.stdout.write('\\n');\n\t},\n\tinfo: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.message(iterable, { symbol: styleText('blue', S_INFO) });\n\t},\n\tsuccess: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.message(iterable, { symbol: styleText('green', S_SUCCESS) });\n\t},\n\tstep: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.message(iterable, { symbol: styleText('green', S_STEP_SUBMIT) });\n\t},\n\twarn: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.message(iterable, { symbol: styleText('yellow', S_WARN) });\n\t},\n\t/** alias for `log.warn()`. */\n\twarning: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.warn(iterable);\n\t},\n\terror: (iterable: Iterable<string> | AsyncIterable<string>) => {\n\t\treturn stream.message(iterable, { symbol: styleText('red', S_ERROR) });\n\t},\n};\n","import type { CommonOptions } from './common.js';\nimport { spinner } from './spinner.js';\n\nexport type Task = {\n\t/**\n\t * Task title\n\t */\n\ttitle: string;\n\t/**\n\t * Task function\n\t */\n\ttask: (message: (string: string) => void) => string | Promise<string> | void | Promise<void>;\n\n\t/**\n\t * If enabled === false the task will be skipped\n\t */\n\tenabled?: boolean;\n};\n\n/**\n * Define a group of tasks to be executed\n */\nexport const tasks = async (tasks: Task[], opts?: CommonOptions) => {\n\tfor (const task of tasks) {\n\t\tif (task.enabled === false) continue;\n\n\t\tconst s = spinner(opts);\n\t\ts.start(task.title);\n\t\tconst result = await task.task(s.message);\n\t\ts.stop(result || task.title);\n\t}\n};\n","import type { Writable } from 'node:stream';\nimport { styleText } from 'node:util';\nimport { getColumns } from '@clack/core';\nimport { erase } from 'sisteransi';\nimport {\n\ttype CommonOptions,\n\tisCI as isCIFn,\n\tisTTY as isTTYFn,\n\tS_BAR,\n\tS_STEP_SUBMIT,\n} from './common.js';\nimport { log } from './log.js';\n\nexport interface TaskLogOptions extends CommonOptions {\n\ttitle: string;\n\tlimit?: number;\n\tspacing?: number;\n\tretainLog?: boolean;\n}\n\nexport interface TaskLogMessageOptions {\n\traw?: boolean;\n}\n\nexport interface TaskLogCompletionOptions {\n\tshowLog?: boolean;\n}\n\ninterface BufferEntry {\n\theader?: string;\n\tvalue: string;\n\tfull: string;\n\tresult?: {\n\t\tstatus: 'success' | 'error';\n\t\tmessage: string;\n\t};\n}\n\nconst stripDestructiveANSI = (input: string): string => {\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: intentional\n\treturn input.replace(/\\x1b\\[(?:\\d+;)*\\d*[ABCDEFGHfJKSTsu]|\\x1b\\[(s|u)/g, '');\n};\n\n/**\n * Renders a log which clears on success and remains on failure\n */\nexport const taskLog = (opts: TaskLogOptions) => {\n\tconst output: Writable = opts.output ?? process.stdout;\n\tconst columns = getColumns(output);\n\tconst secondarySymbol = styleText('gray', S_BAR);\n\tconst spacing = opts.spacing ?? 1;\n\tconst barSize = 3;\n\tconst retainLog = opts.retainLog === true;\n\tconst isTTY = !isCIFn() && isTTYFn(output);\n\n\toutput.write(`${secondarySymbol}\\n`);\n\toutput.write(`${styleText('green', S_STEP_SUBMIT)} ${opts.title}\\n`);\n\tfor (let i = 0; i < spacing; i++) {\n\t\toutput.write(`${secondarySymbol}\\n`);\n\t}\n\n\tconst buffers: BufferEntry[] = [\n\t\t{\n\t\t\tvalue: '',\n\t\t\tfull: '',\n\t\t},\n\t];\n\tlet lastMessageWasRaw = false;\n\n\tconst clear = (clearTitle: boolean): void => {\n\t\tif (buffers.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet lines = 0;\n\n\t\tif (clearTitle) {\n\t\t\tlines += spacing + 2;\n\t\t}\n\n\t\tfor (const buffer of buffers) {\n\t\t\tconst { value, result } = buffer;\n\t\t\tlet text = result?.message ?? value;\n\n\t\t\tif (text.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (result === undefined && buffer.header !== undefined && buffer.header !== '') {\n\t\t\t\ttext += `\\n${buffer.header}`;\n\t\t\t}\n\n\t\t\tconst bufferHeight = text.split('\\n').reduce((count, line) => {\n\t\t\t\tif (line === '') {\n\t\t\t\t\treturn count + 1;\n\t\t\t\t}\n\t\t\t\treturn count + Math.ceil((line.length + barSize) / columns);\n\t\t\t}, 0);\n\n\t\t\tlines += bufferHeight;\n\t\t}\n\n\t\tif (lines > 0) {\n\t\t\tlines += 1;\n\t\t\toutput.write(erase.lines(lines));\n\t\t}\n\t};\n\tconst printBuffer = (buffer: BufferEntry, messageSpacing?: number, full?: boolean): void => {\n\t\tconst messages = full ? `${buffer.full}\\n${buffer.value}` : buffer.value;\n\t\tif (buffer.header !== undefined && buffer.header !== '') {\n\t\t\tlog.message(\n\t\t\t\tbuffer.header.split('\\n').map((line) => styleText('bold', line)),\n\t\t\t\t{\n\t\t\t\t\toutput,\n\t\t\t\t\tsecondarySymbol,\n\t\t\t\t\tsymbol: secondarySymbol,\n\t\t\t\t\tspacing: 0,\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t\tlog.message(\n\t\t\tmessages.split('\\n').map((line) => styleText('dim', line)),\n\t\t\t{\n\t\t\t\toutput,\n\t\t\t\tsecondarySymbol,\n\t\t\t\tsymbol: secondarySymbol,\n\t\t\t\tspacing: messageSpacing ?? spacing,\n\t\t\t}\n\t\t);\n\t};\n\tconst renderBuffer = (): void => {\n\t\tfor (const buffer of buffers) {\n\t\t\tconst { header, value, full } = buffer;\n\t\t\tif ((header === undefined || header.length === 0) && value.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tprintBuffer(buffer, undefined, retainLog === true && full.length > 0);\n\t\t}\n\t};\n\tconst message = (buffer: BufferEntry, msg: string, mopts?: TaskLogMessageOptions) => {\n\t\tclear(false);\n\t\tif ((mopts?.raw !== true || !lastMessageWasRaw) && buffer.value !== '') {\n\t\t\tbuffer.value += '\\n';\n\t\t}\n\t\tbuffer.value += stripDestructiveANSI(msg);\n\t\tlastMessageWasRaw = mopts?.raw === true;\n\t\tif (opts.limit !== undefined) {\n\t\t\tconst lines = buffer.value.split('\\n');\n\t\t\tconst linesToRemove = lines.length - opts.limit;\n\t\t\tif (linesToRemove > 0) {\n\t\t\t\tconst removedLines = lines.splice(0, linesToRemove);\n\t\t\t\tif (retainLog) {\n\t\t\t\t\tbuffer.full += (buffer.full === '' ? '' : '\\n') + removedLines.join('\\n');\n\t\t\t\t}\n\t\t\t}\n\t\t\tbuffer.value = lines.join('\\n');\n\t\t}\n\t\tif (isTTY) {\n\t\t\tprintBuffers();\n\t\t}\n\t};\n\tconst printBuffers = (): void => {\n\t\tfor (const buffer of buffers) {\n\t\t\tif (buffer.result) {\n\t\t\t\tif (buffer.result.status === 'error') {\n\t\t\t\t\tlog.error(buffer.result.message, { output, secondarySymbol, spacing: 0 });\n\t\t\t\t} else {\n\t\t\t\t\tlog.success(buffer.result.message, { output, secondarySymbol, spacing: 0 });\n\t\t\t\t}\n\t\t\t} else if (buffer.value !== '') {\n\t\t\t\tprintBuffer(buffer, 0);\n\t\t\t}\n\t\t}\n\t};\n\tconst completeBuffer = (buffer: BufferEntry, result: BufferEntry['result']): void => {\n\t\tclear(false);\n\n\t\tbuffer.result = result;\n\n\t\tif (isTTY) {\n\t\t\tprintBuffers();\n\t\t}\n\t};\n\n\treturn {\n\t\tmessage(msg: string, mopts?: TaskLogMessageOptions) {\n\t\t\tmessage(buffers[0], msg, mopts);\n\t\t},\n\t\tgroup(name: string) {\n\t\t\tconst buffer: BufferEntry = {\n\t\t\t\theader: name,\n\t\t\t\tvalue: '',\n\t\t\t\tfull: '',\n\t\t\t};\n\t\t\tbuffers.push(buffer);\n\t\t\treturn {\n\t\t\t\tmessage(msg: string, mopts?: TaskLogMessageOptions) {\n\t\t\t\t\tmessage(buffer, msg, mopts);\n\t\t\t\t},\n\t\t\t\terror(message: string) {\n\t\t\t\t\tcompleteBuffer(buffer, {\n\t\t\t\t\t\tstatus: 'error',\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tsuccess(message: string) {\n\t\t\t\t\tcompleteBuffer(buffer, {\n\t\t\t\t\t\tstatus: 'success',\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\terror(message: string, opts?: TaskLogCompletionOptions): void {\n\t\t\tclear(true);\n\t\t\tlog.error(message, { output, secondarySymbol, spacing: 1 });\n\t\t\tif (opts?.showLog !== false) {\n\t\t\t\trenderBuffer();\n\t\t\t}\n\t\t\t// clear buffer since error is an end state\n\t\t\tbuffers.splice(1, buffers.length - 1);\n\t\t\tbuffers[0].value = '';\n\t\t\tbuffers[0].full = '';\n\t\t},\n\t\tsuccess(message: string, opts?: TaskLogCompletionOptions): void {\n\t\t\tclear(true);\n\t\t\tlog.success(message, { output, secondarySymbol, spacing: 1 });\n\t\t\tif (opts?.showLog === true) {\n\t\t\t\trenderBuffer();\n\t\t\t}\n\t\t\t// clear buffer since success is an end state\n\t\t\tbuffers.splice(1, buffers.length - 1);\n\t\t\tbuffers[0].value = '';\n\t\t\tbuffers[0].full = '';\n\t\t},\n\t};\n};\n","import { styleText } from 'node:util';\nimport { settings, TextPrompt } from '@clack/core';\nimport { type CommonOptions, S_BAR, S_BAR_END, symbol } from './common.js';\n\nexport interface TextOptions extends CommonOptions {\n\tmessage: string;\n\tplaceholder?: string;\n\tdefaultValue?: string;\n\tinitialValue?: string;\n\tvalidate?: (value: string | undefined) => string | Error | undefined;\n}\n\nexport const text = (opts: TextOptions) => {\n\treturn new TextPrompt({\n\t\tvalidate: opts.validate,\n\t\tplaceholder: opts.placeholder,\n\t\tdefaultValue: opts.defaultValue,\n\t\tinitialValue: opts.initialValue,\n\t\toutput: opts.output,\n\t\tsignal: opts.signal,\n\t\tinput: opts.input,\n\t\trender() {\n\t\t\tconst hasGuide = opts?.withGuide ?? settings.withGuide;\n\t\t\tconst titlePrefix = `${hasGuide ? `${styleText('gray', S_BAR)}\\n` : ''}${symbol(this.state)} `;\n\t\t\tconst title = `${titlePrefix}${opts.message}\\n`;\n\t\t\tconst placeholder = opts.placeholder\n\t\t\t\t? styleText('inverse', opts.placeholder[0]) + styleText('dim', opts.placeholder.slice(1))\n\t\t\t\t: styleText(['inverse', 'hidden'], '_');\n\t\t\tconst userInput = !this.userInput ? placeholder : this.userInputWithCursor;\n\t\t\tconst value = this.value ?? '';\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase 'error': {\n\t\t\t\t\tconst errorText = this.error ? ` ${styleText('yellow', this.error)}` : '';\n\t\t\t\t\tconst errorPrefix = hasGuide ? `${styleText('yellow', S_BAR)} ` : '';\n\t\t\t\t\tconst errorPrefixEnd = hasGuide ? styleText('yellow', S_BAR_END) : '';\n\t\t\t\t\treturn `${title.trim()}\\n${errorPrefix}${userInput}\\n${errorPrefixEnd}${errorText}\\n`;\n\t\t\t\t}\n\t\t\t\tcase 'submit': {\n\t\t\t\t\tconst valueText = value ? ` ${styleText('dim', value)}` : '';\n\t\t\t\t\tconst submitPrefix = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${title}${submitPrefix}${valueText}`;\n\t\t\t\t}\n\t\t\t\tcase 'cancel': {\n\t\t\t\t\tconst valueText = value ? ` ${styleText(['strikethrough', 'dim'], value)}` : '';\n\t\t\t\t\tconst cancelPrefix = hasGuide ? styleText('gray', S_BAR) : '';\n\t\t\t\t\treturn `${title}${cancelPrefix}${valueText}${value.trim() ? `\\n${cancelPrefix}` : ''}`;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst defaultPrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : '';\n\t\t\t\t\tconst defaultPrefixEnd = hasGuide ? styleText('cyan', S_BAR_END) : '';\n\t\t\t\t\treturn `${title}${defaultPrefix}${userInput}\\n${defaultPrefixEnd}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}).prompt() as Promise<string | symbol>;\n};\n","import type { DetectedInstall } from \"./state.js\";\n\nexport type RouterAction = \"add\" | \"update\" | \"remove\" | \"reinstall\" | \"exit\";\n\nexport interface RouterChoice {\n value: RouterAction;\n label: string;\n hint?: string;\n enabled: boolean;\n}\n\n/**\n * 5-action menu for an existing install. Mirrors prompt_action_router (setup-harness.sh:255).\n *\n * \"remove\" is exposed but disabled — no reliable file-ownership mapping yet (would risk data loss).\n */\nexport function buildRouterChoices(state: DetectedInstall): RouterChoice[] {\n const detected = state.tracks.length > 0 ? state.tracks.join(\", \") : \"(none detected)\";\n return [\n {\n value: \"add\",\n label: \"Add a new Track\",\n hint: `Current: ${detected}`,\n enabled: true,\n },\n {\n value: \"update\",\n label: \"Update policy files (auto-backup)\",\n hint: \"Refresh rules / agents / commands / hooks from latest templates\",\n enabled: true,\n },\n {\n value: \"remove\",\n label: \"Remove a Track (unsupported)\",\n hint: \"Manual edit of .claude/ required — not automated\",\n enabled: false,\n },\n {\n value: \"reinstall\",\n label: \"Reinstall (backs up current .claude/ first)\",\n hint: \"Use when state is corrupted\",\n enabled: true,\n },\n {\n value: \"exit\",\n label: \"Exit\",\n enabled: true,\n },\n ];\n}\n\nexport function summarizeState(state: DetectedInstall): string {\n if (state.state === \"new\") {\n return \"No prior install detected — new install flow.\";\n }\n const trackList = state.tracks.length > 0 ? state.tracks.join(\", \") : \"(no tracks resolved)\";\n const sourceLabel =\n state.source === \"metafile\"\n ? \"via .claude/.installed-tracks\"\n : state.source === \"legacy\"\n ? \"via legacy rules/*.md heuristic\"\n : \"via no source\";\n return `Existing install detected ${sourceLabel}. Tracks: ${trackList}.`;\n}\n","/**\n * Wizard step single source of truth — v26.65.0.\n *\n * v26.64.0 에서 wizard 가 5→6 step 으로 변경됐는데 prompts.ts 의 message 가 hardcoded\n * (\"Step 1/5\") 였음 → step indicator drift 가 무성. 본 모듈이 SSOT.\n *\n * 추가 step 도입 시 본 파일만 수정 → message 자동 정합.\n */\n\nexport interface WizardStep {\n current: number;\n total: number;\n}\n\nexport const WIZARD_TOTAL = 6;\n\nexport const WIZARD: {\n TRACKS: WizardStep;\n CLI: WizardStep;\n TARGETS: WizardStep;\n SCOPE: WizardStep;\n CONFIRM: WizardStep;\n INSTALL: WizardStep;\n} = {\n TRACKS: { current: 1, total: WIZARD_TOTAL },\n CLI: { current: 2, total: WIZARD_TOTAL },\n TARGETS: { current: 3, total: WIZARD_TOTAL },\n SCOPE: { current: 4, total: WIZARD_TOTAL },\n CONFIRM: { current: 5, total: WIZARD_TOTAL },\n INSTALL: { current: 6, total: WIZARD_TOTAL },\n};\n\n/**\n * Wizard step header — `Step N/M — <suffix>` 형식.\n *\n * step 미지정 시 suffix 만 반환 (backward compat — tests / non-wizard 호출).\n */\nexport function stepLabel(step: WizardStep | undefined, suffix: string): string {\n if (!step) return suffix;\n return `Step ${step.current}/${step.total} — ${suffix}`;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { isTrack, type Track } from \"./types.js\";\n\nexport type InstallState = \"new\" | \"existing\";\n\nexport interface DetectedInstall {\n state: InstallState;\n tracks: Track[];\n /** Source of the detected tracks: \"metafile\" (v27.17+), \"legacy\" (rules/*.md heuristic), or \"none\". */\n source: \"metafile\" | \"legacy\" | \"none\";\n hasClaudeDir: boolean;\n}\n\nconst META_FILE = \".claude/.installed-tracks\";\n\ninterface LegacySignature {\n rule: string;\n track: Track;\n}\n\nconst LEGACY_SIGNATURES: readonly LegacySignature[] = [\n { rule: \"htmx.md\", track: \"ssr-htmx\" },\n { rule: \"nextjs.md\", track: \"ssr-nextjs\" },\n { rule: \"data-analysis.md\", track: \"data\" },\n { rule: \"pyside6.md\", track: \"data\" },\n { rule: \"cli-development.md\", track: \"tooling\" },\n];\n\n/**\n * Detect what was previously installed in the given project directory.\n * Mirrors the v27.17 detect_install_state shell function (setup-harness.sh:191).\n */\nexport function detectInstallState(projectDir: string): DetectedInstall {\n const claudeDir = join(projectDir, \".claude\");\n const hasClaudeDir = existsSync(claudeDir);\n\n if (!hasClaudeDir) {\n return { state: \"new\", tracks: [], source: \"none\", hasClaudeDir: false };\n }\n\n const metaPath = join(projectDir, META_FILE);\n if (existsSync(metaPath)) {\n const tracks = readMetafile(metaPath);\n return { state: \"existing\", tracks, source: \"metafile\", hasClaudeDir: true };\n }\n\n const tracks = inferFromLegacySignatures(projectDir);\n return { state: \"existing\", tracks, source: \"legacy\", hasClaudeDir: true };\n}\n\nfunction readMetafile(path: string): Track[] {\n const raw = readFileSync(path, \"utf8\");\n const seen = new Set<Track>();\n for (const line of raw.split(/\\s+/)) {\n const trimmed = line.trim();\n if (isTrack(trimmed)) {\n seen.add(trimmed);\n }\n }\n return [...seen].sort();\n}\n\nfunction inferFromLegacySignatures(projectDir: string): Track[] {\n const rulesDir = join(projectDir, \".claude/rules\");\n if (!existsSync(rulesDir)) {\n return [];\n }\n const found = new Set<Track>();\n for (const sig of LEGACY_SIGNATURES) {\n if (existsSync(join(rulesDir, sig.rule))) {\n found.add(sig.track);\n }\n }\n return [...found].sort();\n}\n"],"mappings":"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","names":["ESC","CSI","k","j","v","b","cli","resolve","b","chmodSync","existsSync","mkdirSync","readdirSync","readFileSync","writeFileSync","dirname","join","existsSync","readFileSync","writeFileSync","join","body","cpSync","existsSync","mkdirSync","readFileSync","join","d","PHASES","join","existsSync","readFileSync","writeFileSync","cpSync","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","join","parseSource","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","e","PHASES","join","homedir","p","existsSync","mkdirSync","readFileSync","writeFileSync","cpSync","existsSync","readFileSync","writeFileSync","basename","join","k","v","PHASES","join","basename","writeFileSync","existsSync","readFileSync","existsSync","readFileSync","writeFileSync","join","existsSync","readdirSync","readFileSync","homedir","join","b","cli","v","join","existsSync","c","at","homedir","readdirSync","readFileSync","existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","h","existsSync","readFileSync","writeFileSync","readFileSync","existsSync","writeFileSync","copyFileSync","existsSync","readFileSync","writeFileSync","basename","join","renameSlashes","renderAgentsMd","parseSource","renameSlashes","stripQuotes","body","PHASES","readRequired","join","basename","readOptionalJson","writeFileSync","renderAgentsMd","existsSync","readFileSync","copyFileSync","existsSync","readFileSync","join","h","copyFileSync","existsSync","readdirSync","readFileSync","writeFileSync","join","join","existsSync","readFileSync","e","chmodSync","writeFileSync","mkdirSync","dirname","readdirSync","b","v","k","p","w","resolve","e","cli","spawnSync","existsSync","readFileSync","join","resolve","defaultSpawn","resolve","join","existsSync","readFileSync","spawnSync","cli","NO_TRUNCATION","dist_default","dist_default","findCursor","cursor","delta","options","opt","newCursor","maxCursor","clampedCursor","actions","DEFAULT_MONTH_NAMES","settings","days","month","min","max","isActionKey","key","action","settings","value","diffLines","a","b","aLines","bLines","numLines","diff","i","isWindows","CANCEL_SYMBOL","isCancel","setRawMode","input","getColumns","output","getRows","wrapTextWithPrefix","text","prefix","startPrefix","lineFormatter","columns","stdout","wrapAnsi","line","index","lineString","g$1","options","trackValue","input","stdin","render","signal","opts","event","params","cb","data","cbs","cleanup","subscriber","resolve","CANCEL_SYMBOL","readline","setRawMode","cursor","char","_key","_char","value","write","key","settings","problem","isActionKey","lines","frame","diff","diffLines","rows","diffOffsetAfter","diffOffsetBefore","diffLine","erase","adjustedDiffLine","newLines","ConfirmPrompt","Prompt","opts","confirm","cursor","GroupMultiSelectPrompt","Prompt","#selectableGroups","group","o","items","value","i","item","groupedItems","v","selected","opts","options","key","option","opt","currentIsGroup","Prompt","option","enabledOptions","allSelected","v","value","notSelected","selected","opts","cursor","findCursor","char","key","SelectPrompt","Prompt","opts","initialCursor","value","cursor","findCursor","key","isUnicodeSupported","process","unicode","unicodeOr","c","fallback","unicode","S_STEP_ACTIVE","S_STEP_CANCEL","S_STEP_ERROR","S_STEP_SUBMIT","S_BAR_START","S_BAR","S_BAR_END","S_BAR_START_RIGHT","S_BAR_END_RIGHT","S_RADIO_ACTIVE","S_RADIO_INACTIVE","S_CHECKBOX_ACTIVE","S_CHECKBOX_SELECTED","S_CHECKBOX_INACTIVE","S_PASSWORD_MASK","S_BAR_H","S_CORNER_TOP_RIGHT","S_CONNECT_LEFT","S_CORNER_BOTTOM_RIGHT","S_CORNER_BOTTOM_LEFT","S_CORNER_TOP_LEFT","S_INFO","S_SUCCESS","S_WARN","S_ERROR","symbol","state","styleText","symbolBar","trimLines","groups","initialLineCount","startIndex","endIndex","maxLines","lineCount","removals","i","group","limitOptions","cursor","options","style","output","maxItems","columnPadding","rowPadding","maxWidth","getColumns","rows","getRows","overflowFormat","outputMaxItems","computedMaxItems","slidingWindowLocation","shouldRenderTopEllipsis","shouldRenderBottomEllipsis","slidingWindowLocationEnd","lineGroups","slidingWindowLocationWithEllipsis","slidingWindowLocationEndWithEllipsis","wrappedLines","wrapAnsi","precedingRemovals","followingRemovals","newLineCount","cursorGroupIndex","trimLinesLocal","result","lineGroup","line","confirm","opts","active","inactive","ConfirmPrompt","hasGuide","settings","titlePrefix","symbol","titlePrefixBar","styleText","S_BAR","messageLines","wrapTextWithPrefix","title","value","submitPrefix","cancelPrefix","defaultPrefix","defaultPrefixEnd","S_BAR_END","S_RADIO_ACTIVE","S_RADIO_INACTIVE","groupMultiselect","opts","selectableGroups","groupSpacing","opt","option","state","options","label","isItem","next","isLast","prefix","S_BAR_END","S_BAR","spacingPrefix","spacingPrefixText","styleText","S_CHECKBOX_ACTIVE","S_CHECKBOX_SELECTED","selectedCheckbox","unselectedCheckbox","S_CHECKBOX_INACTIVE","required","GroupMultiSelectPrompt","selected","hasGuide","settings","title","symbol","value","selectedOptions","optionValue","optionsText","footer","ln","i","active","groupActive","optionText","optionsPrefix","cancel","message","opts","output","prefix","settings","styleText","S_BAR_END","intro","title","S_BAR_START","outro","S_BAR","computeLabel","label","format","line","multiselect","opts","opt","option","state","styleText","S_CHECKBOX_INACTIVE","str","S_CHECKBOX_ACTIVE","S_CHECKBOX_SELECTED","text","required","MultiSelectPrompt","selected","hasGuide","settings","wrappedMessage","wrapTextWithPrefix","symbolBar","symbol","title","S_BAR","value","styleOption","active","submitText","optionValue","wrappedSubmitText","wrappedLabel","prefix","footer","ln","i","S_BAR_END","titleLineCount","footerLineCount","limitOptions","S_PROGRESS_CHAR","unicodeOr","computeLabel","label","format","line","select","opts","opt","option","state","styleText","S_RADIO_INACTIVE","text","S_RADIO_ACTIVE","str","SelectPrompt","hasGuide","settings","titlePrefix","symbol","titlePrefixBar","symbolBar","messageLines","wrapTextWithPrefix","title","S_BAR","submitPrefix","wrappedLines","cancelPrefix","prefix","prefixEnd","S_BAR_END","titleLineCount","footerLineCount","limitOptions","item","active","prefix","styleText","S_BAR","trackList","c","b","d","it","v","existsSync","readFileSync","join","join","existsSync","tracks","readFileSync","cli","b","k","cli"]}