agent-ctrl-cli 0.1.6 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +2804 -318
  2. package/package.json +10 -8
package/dist/index.js CHANGED
@@ -2126,6 +2126,134 @@ var require_commander = __commonJS((exports) => {
2126
2126
  exports.InvalidOptionArgumentError = InvalidArgumentError;
2127
2127
  });
2128
2128
 
2129
+ // node_modules/sisteransi/src/index.js
2130
+ var require_src = __commonJS((exports, module) => {
2131
+ var ESC2 = "\x1B";
2132
+ var CSI2 = `${ESC2}[`;
2133
+ var beep = "\x07";
2134
+ var cursor = {
2135
+ to(x, y) {
2136
+ if (!y)
2137
+ return `${CSI2}${x + 1}G`;
2138
+ return `${CSI2}${y + 1};${x + 1}H`;
2139
+ },
2140
+ move(x, y) {
2141
+ let ret = "";
2142
+ if (x < 0)
2143
+ ret += `${CSI2}${-x}D`;
2144
+ else if (x > 0)
2145
+ ret += `${CSI2}${x}C`;
2146
+ if (y < 0)
2147
+ ret += `${CSI2}${-y}A`;
2148
+ else if (y > 0)
2149
+ ret += `${CSI2}${y}B`;
2150
+ return ret;
2151
+ },
2152
+ up: (count = 1) => `${CSI2}${count}A`,
2153
+ down: (count = 1) => `${CSI2}${count}B`,
2154
+ forward: (count = 1) => `${CSI2}${count}C`,
2155
+ backward: (count = 1) => `${CSI2}${count}D`,
2156
+ nextLine: (count = 1) => `${CSI2}E`.repeat(count),
2157
+ prevLine: (count = 1) => `${CSI2}F`.repeat(count),
2158
+ left: `${CSI2}G`,
2159
+ hide: `${CSI2}?25l`,
2160
+ show: `${CSI2}?25h`,
2161
+ save: `${ESC2}7`,
2162
+ restore: `${ESC2}8`
2163
+ };
2164
+ var scroll = {
2165
+ up: (count = 1) => `${CSI2}S`.repeat(count),
2166
+ down: (count = 1) => `${CSI2}T`.repeat(count)
2167
+ };
2168
+ var erase = {
2169
+ screen: `${CSI2}2J`,
2170
+ up: (count = 1) => `${CSI2}1J`.repeat(count),
2171
+ down: (count = 1) => `${CSI2}J`.repeat(count),
2172
+ line: `${CSI2}2K`,
2173
+ lineEnd: `${CSI2}K`,
2174
+ lineStart: `${CSI2}1K`,
2175
+ lines(count) {
2176
+ let clear = "";
2177
+ for (let i = 0;i < count; i++)
2178
+ clear += this.line + (i < count - 1 ? cursor.up() : "");
2179
+ if (count)
2180
+ clear += cursor.left;
2181
+ return clear;
2182
+ }
2183
+ };
2184
+ module.exports = { cursor, scroll, erase, beep };
2185
+ });
2186
+
2187
+ // node_modules/picocolors/picocolors.js
2188
+ var require_picocolors = __commonJS((exports, module) => {
2189
+ var p2 = process || {};
2190
+ var argv = p2.argv || [];
2191
+ var env = p2.env || {};
2192
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p2.platform === "win32" || (p2.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
2193
+ var formatter = (open, close, replace = open) => (input) => {
2194
+ let string = "" + input, index = string.indexOf(close, open.length);
2195
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
2196
+ };
2197
+ var replaceClose = (string, close, replace, index) => {
2198
+ let result = "", cursor = 0;
2199
+ do {
2200
+ result += string.substring(cursor, index) + replace;
2201
+ cursor = index + close.length;
2202
+ index = string.indexOf(close, cursor);
2203
+ } while (~index);
2204
+ return result + string.substring(cursor);
2205
+ };
2206
+ var createColors = (enabled = isColorSupported) => {
2207
+ let f = enabled ? formatter : () => String;
2208
+ return {
2209
+ isColorSupported: enabled,
2210
+ reset: f("\x1B[0m", "\x1B[0m"),
2211
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
2212
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
2213
+ italic: f("\x1B[3m", "\x1B[23m"),
2214
+ underline: f("\x1B[4m", "\x1B[24m"),
2215
+ inverse: f("\x1B[7m", "\x1B[27m"),
2216
+ hidden: f("\x1B[8m", "\x1B[28m"),
2217
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
2218
+ black: f("\x1B[30m", "\x1B[39m"),
2219
+ red: f("\x1B[31m", "\x1B[39m"),
2220
+ green: f("\x1B[32m", "\x1B[39m"),
2221
+ yellow: f("\x1B[33m", "\x1B[39m"),
2222
+ blue: f("\x1B[34m", "\x1B[39m"),
2223
+ magenta: f("\x1B[35m", "\x1B[39m"),
2224
+ cyan: f("\x1B[36m", "\x1B[39m"),
2225
+ white: f("\x1B[37m", "\x1B[39m"),
2226
+ gray: f("\x1B[90m", "\x1B[39m"),
2227
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
2228
+ bgRed: f("\x1B[41m", "\x1B[49m"),
2229
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
2230
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
2231
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
2232
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
2233
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
2234
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
2235
+ blackBright: f("\x1B[90m", "\x1B[39m"),
2236
+ redBright: f("\x1B[91m", "\x1B[39m"),
2237
+ greenBright: f("\x1B[92m", "\x1B[39m"),
2238
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
2239
+ blueBright: f("\x1B[94m", "\x1B[39m"),
2240
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
2241
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
2242
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
2243
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
2244
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
2245
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
2246
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
2247
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
2248
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
2249
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
2250
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
2251
+ };
2252
+ };
2253
+ module.exports = createColors();
2254
+ module.exports.createColors = createColors;
2255
+ });
2256
+
2129
2257
  // node_modules/commander/esm.mjs
2130
2258
  var import__ = __toESM(require_commander(), 1);
2131
2259
  var {
@@ -2142,6 +2270,1423 @@ var {
2142
2270
  Help
2143
2271
  } = import__.default;
2144
2272
 
2273
+ // node_modules/@clack/core/dist/index.mjs
2274
+ import { styleText as y } from "node:util";
2275
+ import { stdout as S, stdin as $ } from "node:process";
2276
+ import * as _ from "node:readline";
2277
+ import P from "node:readline";
2278
+
2279
+ // node_modules/fast-string-truncated-width/dist/utils.js
2280
+ var isAmbiguous = (x) => {
2281
+ return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109;
2282
+ };
2283
+ var isFullWidth = (x) => {
2284
+ return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
2285
+ };
2286
+ var isWide = (x) => {
2287
+ return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9800 && x <= 9811 || x === 9855 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 19968 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x === 94192 || x === 94193 || x >= 94208 && x <= 100343 || x >= 100352 && x <= 101589 || x >= 101632 && x <= 101640 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128727 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129672 || x >= 129680 && x <= 129725 || x >= 129727 && x <= 129733 || x >= 129742 && x <= 129755 || x >= 129760 && x <= 129768 || x >= 129776 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
2288
+ };
2289
+
2290
+ // node_modules/fast-string-truncated-width/dist/index.js
2291
+ var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/y;
2292
+ var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
2293
+ var TAB_RE = /\t{1,1000}/y;
2294
+ var 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;
2295
+ var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
2296
+ var MODIFIER_RE = /\p{M}+/gu;
2297
+ var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
2298
+ var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
2299
+ const LIMIT = truncationOptions.limit ?? Infinity;
2300
+ const ELLIPSIS = truncationOptions.ellipsis ?? "";
2301
+ const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
2302
+ const ANSI_WIDTH = widthOptions.ansiWidth ?? 0;
2303
+ const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
2304
+ const TAB_WIDTH = widthOptions.tabWidth ?? 8;
2305
+ const AMBIGUOUS_WIDTH = widthOptions.ambiguousWidth ?? 1;
2306
+ const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
2307
+ const FULL_WIDTH_WIDTH = widthOptions.fullWidthWidth ?? 2;
2308
+ const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
2309
+ const WIDE_WIDTH = widthOptions.wideWidth ?? 2;
2310
+ let indexPrev = 0;
2311
+ let index = 0;
2312
+ let length = input.length;
2313
+ let lengthExtra = 0;
2314
+ let truncationEnabled = false;
2315
+ let truncationIndex = length;
2316
+ let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
2317
+ let unmatchedStart = 0;
2318
+ let unmatchedEnd = 0;
2319
+ let width = 0;
2320
+ let widthExtra = 0;
2321
+ outer:
2322
+ while (true) {
2323
+ if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
2324
+ const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
2325
+ lengthExtra = 0;
2326
+ for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
2327
+ const codePoint = char.codePointAt(0) || 0;
2328
+ if (isFullWidth(codePoint)) {
2329
+ widthExtra = FULL_WIDTH_WIDTH;
2330
+ } else if (isWide(codePoint)) {
2331
+ widthExtra = WIDE_WIDTH;
2332
+ } else if (AMBIGUOUS_WIDTH !== REGULAR_WIDTH && isAmbiguous(codePoint)) {
2333
+ widthExtra = AMBIGUOUS_WIDTH;
2334
+ } else {
2335
+ widthExtra = REGULAR_WIDTH;
2336
+ }
2337
+ if (width + widthExtra > truncationLimit) {
2338
+ truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
2339
+ }
2340
+ if (width + widthExtra > LIMIT) {
2341
+ truncationEnabled = true;
2342
+ break outer;
2343
+ }
2344
+ lengthExtra += char.length;
2345
+ width += widthExtra;
2346
+ }
2347
+ unmatchedStart = unmatchedEnd = 0;
2348
+ }
2349
+ if (index >= length)
2350
+ break;
2351
+ LATIN_RE.lastIndex = index;
2352
+ if (LATIN_RE.test(input)) {
2353
+ lengthExtra = LATIN_RE.lastIndex - index;
2354
+ widthExtra = lengthExtra * REGULAR_WIDTH;
2355
+ if (width + widthExtra > truncationLimit) {
2356
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / REGULAR_WIDTH));
2357
+ }
2358
+ if (width + widthExtra > LIMIT) {
2359
+ truncationEnabled = true;
2360
+ break;
2361
+ }
2362
+ width += widthExtra;
2363
+ unmatchedStart = indexPrev;
2364
+ unmatchedEnd = index;
2365
+ index = indexPrev = LATIN_RE.lastIndex;
2366
+ continue;
2367
+ }
2368
+ ANSI_RE.lastIndex = index;
2369
+ if (ANSI_RE.test(input)) {
2370
+ if (width + ANSI_WIDTH > truncationLimit) {
2371
+ truncationIndex = Math.min(truncationIndex, index);
2372
+ }
2373
+ if (width + ANSI_WIDTH > LIMIT) {
2374
+ truncationEnabled = true;
2375
+ break;
2376
+ }
2377
+ width += ANSI_WIDTH;
2378
+ unmatchedStart = indexPrev;
2379
+ unmatchedEnd = index;
2380
+ index = indexPrev = ANSI_RE.lastIndex;
2381
+ continue;
2382
+ }
2383
+ CONTROL_RE.lastIndex = index;
2384
+ if (CONTROL_RE.test(input)) {
2385
+ lengthExtra = CONTROL_RE.lastIndex - index;
2386
+ widthExtra = lengthExtra * CONTROL_WIDTH;
2387
+ if (width + widthExtra > truncationLimit) {
2388
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / CONTROL_WIDTH));
2389
+ }
2390
+ if (width + widthExtra > LIMIT) {
2391
+ truncationEnabled = true;
2392
+ break;
2393
+ }
2394
+ width += widthExtra;
2395
+ unmatchedStart = indexPrev;
2396
+ unmatchedEnd = index;
2397
+ index = indexPrev = CONTROL_RE.lastIndex;
2398
+ continue;
2399
+ }
2400
+ TAB_RE.lastIndex = index;
2401
+ if (TAB_RE.test(input)) {
2402
+ lengthExtra = TAB_RE.lastIndex - index;
2403
+ widthExtra = lengthExtra * TAB_WIDTH;
2404
+ if (width + widthExtra > truncationLimit) {
2405
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / TAB_WIDTH));
2406
+ }
2407
+ if (width + widthExtra > LIMIT) {
2408
+ truncationEnabled = true;
2409
+ break;
2410
+ }
2411
+ width += widthExtra;
2412
+ unmatchedStart = indexPrev;
2413
+ unmatchedEnd = index;
2414
+ index = indexPrev = TAB_RE.lastIndex;
2415
+ continue;
2416
+ }
2417
+ EMOJI_RE.lastIndex = index;
2418
+ if (EMOJI_RE.test(input)) {
2419
+ if (width + EMOJI_WIDTH > truncationLimit) {
2420
+ truncationIndex = Math.min(truncationIndex, index);
2421
+ }
2422
+ if (width + EMOJI_WIDTH > LIMIT) {
2423
+ truncationEnabled = true;
2424
+ break;
2425
+ }
2426
+ width += EMOJI_WIDTH;
2427
+ unmatchedStart = indexPrev;
2428
+ unmatchedEnd = index;
2429
+ index = indexPrev = EMOJI_RE.lastIndex;
2430
+ continue;
2431
+ }
2432
+ index += 1;
2433
+ }
2434
+ return {
2435
+ width: truncationEnabled ? truncationLimit : width,
2436
+ index: truncationEnabled ? truncationIndex : length,
2437
+ truncated: truncationEnabled,
2438
+ ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
2439
+ };
2440
+ };
2441
+ var dist_default = getStringTruncatedWidth;
2442
+
2443
+ // node_modules/fast-string-width/dist/index.js
2444
+ var NO_TRUNCATION2 = {
2445
+ limit: Infinity,
2446
+ ellipsis: "",
2447
+ ellipsisWidth: 0
2448
+ };
2449
+ var fastStringWidth = (input, options = {}) => {
2450
+ return dist_default(input, NO_TRUNCATION2, options).width;
2451
+ };
2452
+ var dist_default2 = fastStringWidth;
2453
+
2454
+ // node_modules/fast-wrap-ansi/lib/main.js
2455
+ var ESC = "\x1B";
2456
+ var CSI = "›";
2457
+ var END_CODE = 39;
2458
+ var ANSI_ESCAPE_BELL = "\x07";
2459
+ var ANSI_CSI = "[";
2460
+ var ANSI_OSC = "]";
2461
+ var ANSI_SGR_TERMINATOR = "m";
2462
+ var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
2463
+ var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
2464
+ var getClosingCode = (openingCode) => {
2465
+ if (openingCode >= 30 && openingCode <= 37)
2466
+ return 39;
2467
+ if (openingCode >= 90 && openingCode <= 97)
2468
+ return 39;
2469
+ if (openingCode >= 40 && openingCode <= 47)
2470
+ return 49;
2471
+ if (openingCode >= 100 && openingCode <= 107)
2472
+ return 49;
2473
+ if (openingCode === 1 || openingCode === 2)
2474
+ return 22;
2475
+ if (openingCode === 3)
2476
+ return 23;
2477
+ if (openingCode === 4)
2478
+ return 24;
2479
+ if (openingCode === 7)
2480
+ return 27;
2481
+ if (openingCode === 8)
2482
+ return 28;
2483
+ if (openingCode === 9)
2484
+ return 29;
2485
+ if (openingCode === 0)
2486
+ return 0;
2487
+ return;
2488
+ };
2489
+ var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
2490
+ var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
2491
+ var wrapWord = (rows, word, columns) => {
2492
+ const characters = word[Symbol.iterator]();
2493
+ let isInsideEscape = false;
2494
+ let isInsideLinkEscape = false;
2495
+ let lastRow = rows.at(-1);
2496
+ let visible = lastRow === undefined ? 0 : dist_default2(lastRow);
2497
+ let currentCharacter = characters.next();
2498
+ let nextCharacter = characters.next();
2499
+ let rawCharacterIndex = 0;
2500
+ while (!currentCharacter.done) {
2501
+ const character = currentCharacter.value;
2502
+ const characterLength = dist_default2(character);
2503
+ if (visible + characterLength <= columns) {
2504
+ rows[rows.length - 1] += character;
2505
+ } else {
2506
+ rows.push(character);
2507
+ visible = 0;
2508
+ }
2509
+ if (character === ESC || character === CSI) {
2510
+ isInsideEscape = true;
2511
+ isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
2512
+ }
2513
+ if (isInsideEscape) {
2514
+ if (isInsideLinkEscape) {
2515
+ if (character === ANSI_ESCAPE_BELL) {
2516
+ isInsideEscape = false;
2517
+ isInsideLinkEscape = false;
2518
+ }
2519
+ } else if (character === ANSI_SGR_TERMINATOR) {
2520
+ isInsideEscape = false;
2521
+ }
2522
+ } else {
2523
+ visible += characterLength;
2524
+ if (visible === columns && !nextCharacter.done) {
2525
+ rows.push("");
2526
+ visible = 0;
2527
+ }
2528
+ }
2529
+ currentCharacter = nextCharacter;
2530
+ nextCharacter = characters.next();
2531
+ rawCharacterIndex += character.length;
2532
+ }
2533
+ lastRow = rows.at(-1);
2534
+ if (!visible && lastRow !== undefined && lastRow.length && rows.length > 1) {
2535
+ rows[rows.length - 2] += rows.pop();
2536
+ }
2537
+ };
2538
+ var stringVisibleTrimSpacesRight = (string) => {
2539
+ const words = string.split(" ");
2540
+ let last = words.length;
2541
+ while (last) {
2542
+ if (dist_default2(words[last - 1])) {
2543
+ break;
2544
+ }
2545
+ last--;
2546
+ }
2547
+ if (last === words.length) {
2548
+ return string;
2549
+ }
2550
+ return words.slice(0, last).join(" ") + words.slice(last).join("");
2551
+ };
2552
+ var exec = (string, columns, options = {}) => {
2553
+ if (options.trim !== false && string.trim() === "") {
2554
+ return "";
2555
+ }
2556
+ let returnValue = "";
2557
+ let escapeCode;
2558
+ let escapeUrl;
2559
+ const words = string.split(" ");
2560
+ let rows = [""];
2561
+ let rowLength = 0;
2562
+ for (let index = 0;index < words.length; index++) {
2563
+ const word = words[index];
2564
+ if (options.trim !== false) {
2565
+ const row = rows.at(-1) ?? "";
2566
+ const trimmed = row.trimStart();
2567
+ if (row.length !== trimmed.length) {
2568
+ rows[rows.length - 1] = trimmed;
2569
+ rowLength = dist_default2(trimmed);
2570
+ }
2571
+ }
2572
+ if (index !== 0) {
2573
+ if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
2574
+ rows.push("");
2575
+ rowLength = 0;
2576
+ }
2577
+ if (rowLength || options.trim === false) {
2578
+ rows[rows.length - 1] += " ";
2579
+ rowLength++;
2580
+ }
2581
+ }
2582
+ const wordLength = dist_default2(word);
2583
+ if (options.hard && wordLength > columns) {
2584
+ const remainingColumns = columns - rowLength;
2585
+ const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
2586
+ const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
2587
+ if (breaksStartingNextLine < breaksStartingThisLine) {
2588
+ rows.push("");
2589
+ }
2590
+ wrapWord(rows, word, columns);
2591
+ rowLength = dist_default2(rows.at(-1) ?? "");
2592
+ continue;
2593
+ }
2594
+ if (rowLength + wordLength > columns && rowLength && wordLength) {
2595
+ if (options.wordWrap === false && rowLength < columns) {
2596
+ wrapWord(rows, word, columns);
2597
+ rowLength = dist_default2(rows.at(-1) ?? "");
2598
+ continue;
2599
+ }
2600
+ rows.push("");
2601
+ rowLength = 0;
2602
+ }
2603
+ if (rowLength + wordLength > columns && options.wordWrap === false) {
2604
+ wrapWord(rows, word, columns);
2605
+ rowLength = dist_default2(rows.at(-1) ?? "");
2606
+ continue;
2607
+ }
2608
+ rows[rows.length - 1] += word;
2609
+ rowLength += wordLength;
2610
+ }
2611
+ if (options.trim !== false) {
2612
+ rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
2613
+ }
2614
+ const preString = rows.join(`
2615
+ `);
2616
+ let inSurrogate = false;
2617
+ for (let i = 0;i < preString.length; i++) {
2618
+ const character = preString[i];
2619
+ returnValue += character;
2620
+ if (!inSurrogate) {
2621
+ inSurrogate = character >= "\uD800" && character <= "\uDBFF";
2622
+ } else {
2623
+ continue;
2624
+ }
2625
+ if (character === ESC || character === CSI) {
2626
+ GROUP_REGEX.lastIndex = i + 1;
2627
+ const groupsResult = GROUP_REGEX.exec(preString);
2628
+ const groups = groupsResult?.groups;
2629
+ if (groups?.code !== undefined) {
2630
+ const code = Number.parseFloat(groups.code);
2631
+ escapeCode = code === END_CODE ? undefined : code;
2632
+ } else if (groups?.uri !== undefined) {
2633
+ escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
2634
+ }
2635
+ }
2636
+ if (preString[i + 1] === `
2637
+ `) {
2638
+ if (escapeUrl) {
2639
+ returnValue += wrapAnsiHyperlink("");
2640
+ }
2641
+ const closingCode = escapeCode ? getClosingCode(escapeCode) : undefined;
2642
+ if (escapeCode && closingCode) {
2643
+ returnValue += wrapAnsiCode(closingCode);
2644
+ }
2645
+ } else if (character === `
2646
+ `) {
2647
+ if (escapeCode && getClosingCode(escapeCode)) {
2648
+ returnValue += wrapAnsiCode(escapeCode);
2649
+ }
2650
+ if (escapeUrl) {
2651
+ returnValue += wrapAnsiHyperlink(escapeUrl);
2652
+ }
2653
+ }
2654
+ }
2655
+ return returnValue;
2656
+ };
2657
+ var CRLF_OR_LF = /\r?\n/;
2658
+ function wrapAnsi(string, columns, options) {
2659
+ return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join(`
2660
+ `);
2661
+ }
2662
+
2663
+ // node_modules/@clack/core/dist/index.mjs
2664
+ var import_sisteransi = __toESM(require_src(), 1);
2665
+ import { ReadStream as D } from "node:tty";
2666
+ function d(r, t, e) {
2667
+ if (!e.some((o) => !o.disabled))
2668
+ return r;
2669
+ const s = r + t, i = Math.max(e.length - 1, 0), n = s < 0 ? i : s > i ? 0 : s;
2670
+ return e[n].disabled ? d(n, t < 0 ? -1 : 1, e) : n;
2671
+ }
2672
+ var E = ["up", "down", "left", "right", "space", "enter", "cancel"];
2673
+ var G = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
2674
+ var u = { actions: new Set(E), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]), messages: { cancel: "Canceled", error: "Something went wrong" }, withGuide: true, date: { monthNames: [...G], messages: { required: "Please enter a valid date", invalidMonth: "There are only 12 months in a year", invalidDay: (r, t) => `There are only ${r} days in ${t}`, afterMin: (r) => `Date must be on or after ${r.toISOString().slice(0, 10)}`, beforeMax: (r) => `Date must be on or before ${r.toISOString().slice(0, 10)}` } } };
2675
+ function V(r, t) {
2676
+ if (typeof r == "string")
2677
+ return u.aliases.get(r) === t;
2678
+ for (const e of r)
2679
+ if (e !== undefined && V(e, t))
2680
+ return true;
2681
+ return false;
2682
+ }
2683
+ function j(r, t) {
2684
+ if (r === t)
2685
+ return;
2686
+ const e = r.split(`
2687
+ `), s = t.split(`
2688
+ `), i = Math.max(e.length, s.length), n = [];
2689
+ for (let o = 0;o < i; o++)
2690
+ e[o] !== s[o] && n.push(o);
2691
+ return { lines: n, numLinesBefore: e.length, numLinesAfter: s.length, numLines: i };
2692
+ }
2693
+ var Y = globalThis.process.platform.startsWith("win");
2694
+ var C = Symbol("clack:cancel");
2695
+ function q(r) {
2696
+ return r === C;
2697
+ }
2698
+ function w(r, t) {
2699
+ const e = r;
2700
+ e.isTTY && e.setRawMode(t);
2701
+ }
2702
+ function z({ input: r = $, output: t = S, overwrite: e = true, hideCursor: s = true } = {}) {
2703
+ const i = _.createInterface({ input: r, output: t, prompt: "", tabSize: 1 });
2704
+ _.emitKeypressEvents(r, i), r instanceof D && r.isTTY && r.setRawMode(true);
2705
+ const n = (o, { name: a, sequence: h }) => {
2706
+ const l = String(o);
2707
+ if (V([l, a, h], "cancel")) {
2708
+ s && t.write(import_sisteransi.cursor.show), process.exit(0);
2709
+ return;
2710
+ }
2711
+ if (!e)
2712
+ return;
2713
+ const f = a === "return" ? 0 : -1, v = a === "return" ? -1 : 0;
2714
+ _.moveCursor(t, f, v, () => {
2715
+ _.clearLine(t, 1, () => {
2716
+ r.once("keypress", n);
2717
+ });
2718
+ });
2719
+ };
2720
+ return s && t.write(import_sisteransi.cursor.hide), r.once("keypress", n), () => {
2721
+ r.off("keypress", n), s && t.write(import_sisteransi.cursor.show), r instanceof D && r.isTTY && !Y && r.setRawMode(false), i.terminal = false, i.close();
2722
+ };
2723
+ }
2724
+ var O = (r) => ("columns" in r) && typeof r.columns == "number" ? r.columns : 80;
2725
+ var A = (r) => ("rows" in r) && typeof r.rows == "number" ? r.rows : 20;
2726
+ function R(r, t, e, s = e) {
2727
+ const i = O(r ?? S);
2728
+ return wrapAnsi(t, i - e.length, { hard: true, trim: false }).split(`
2729
+ `).map((n, o) => `${o === 0 ? s : e}${n}`).join(`
2730
+ `);
2731
+ }
2732
+ var p = class {
2733
+ input;
2734
+ output;
2735
+ _abortSignal;
2736
+ rl;
2737
+ opts;
2738
+ _render;
2739
+ _track = false;
2740
+ _prevFrame = "";
2741
+ _subscribers = new Map;
2742
+ _cursor = 0;
2743
+ state = "initial";
2744
+ error = "";
2745
+ value;
2746
+ userInput = "";
2747
+ constructor(t, e = true) {
2748
+ const { input: s = $, output: i = S, render: n, signal: o, ...a } = t;
2749
+ this.opts = a, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = n.bind(this), this._track = e, this._abortSignal = o, this.input = s, this.output = i;
2750
+ }
2751
+ unsubscribe() {
2752
+ this._subscribers.clear();
2753
+ }
2754
+ setSubscriber(t, e) {
2755
+ const s = this._subscribers.get(t) ?? [];
2756
+ s.push(e), this._subscribers.set(t, s);
2757
+ }
2758
+ on(t, e) {
2759
+ this.setSubscriber(t, { cb: e });
2760
+ }
2761
+ once(t, e) {
2762
+ this.setSubscriber(t, { cb: e, once: true });
2763
+ }
2764
+ emit(t, ...e) {
2765
+ const s = this._subscribers.get(t) ?? [], i = [];
2766
+ for (const n of s)
2767
+ n.cb(...e), n.once && i.push(() => s.splice(s.indexOf(n), 1));
2768
+ for (const n of i)
2769
+ n();
2770
+ }
2771
+ prompt() {
2772
+ return new Promise((t) => {
2773
+ if (this._abortSignal) {
2774
+ if (this._abortSignal.aborted)
2775
+ return this.state = "cancel", this.close(), t(C);
2776
+ this._abortSignal.addEventListener("abort", () => {
2777
+ this.state = "cancel", this.close();
2778
+ }, { once: true });
2779
+ }
2780
+ this.rl = P.createInterface({ input: this.input, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), this.rl.prompt(), this.opts.initialUserInput !== undefined && this._setUserInput(this.opts.initialUserInput, true), this.input.on("keypress", this.onKeypress), w(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
2781
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w(this.input, false), t(this.value);
2782
+ }), this.once("cancel", () => {
2783
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w(this.input, false), t(C);
2784
+ });
2785
+ });
2786
+ }
2787
+ _isActionKey(t, e) {
2788
+ return t === "\t";
2789
+ }
2790
+ _setValue(t) {
2791
+ this.value = t, this.emit("value", this.value);
2792
+ }
2793
+ _setUserInput(t, e) {
2794
+ this.userInput = t ?? "", this.emit("userInput", this.userInput), e && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
2795
+ }
2796
+ _clearUserInput() {
2797
+ this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
2798
+ }
2799
+ onKeypress(t, e) {
2800
+ if (this._track && e.name !== "return" && (e.name && this._isActionKey(t, e) && this.rl?.write(null, { ctrl: true, name: "h" }), this._cursor = this.rl?.cursor ?? 0, this._setUserInput(this.rl?.line)), this.state === "error" && (this.state = "active"), e?.name && (!this._track && u.aliases.has(e.name) && this.emit("cursor", u.aliases.get(e.name)), u.actions.has(e.name) && this.emit("cursor", e.name)), t && (t.toLowerCase() === "y" || t.toLowerCase() === "n") && this.emit("confirm", t.toLowerCase() === "y"), this.emit("key", t?.toLowerCase(), e), e?.name === "return") {
2801
+ if (this.opts.validate) {
2802
+ const s = this.opts.validate(this.value);
2803
+ s && (this.error = s instanceof Error ? s.message : s, this.state = "error", this.rl?.write(this.userInput));
2804
+ }
2805
+ this.state !== "error" && (this.state = "submit");
2806
+ }
2807
+ V([t, e?.name, e?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
2808
+ }
2809
+ close() {
2810
+ this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
2811
+ `), w(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
2812
+ }
2813
+ restoreCursor() {
2814
+ const t = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
2815
+ `).length - 1;
2816
+ this.output.write(import_sisteransi.cursor.move(-999, t * -1));
2817
+ }
2818
+ render() {
2819
+ const t = wrapAnsi(this._render(this) ?? "", process.stdout.columns, { hard: true, trim: false });
2820
+ if (t !== this._prevFrame) {
2821
+ if (this.state === "initial")
2822
+ this.output.write(import_sisteransi.cursor.hide);
2823
+ else {
2824
+ const e = j(this._prevFrame, t), s = A(this.output);
2825
+ if (this.restoreCursor(), e) {
2826
+ const i = Math.max(0, e.numLinesAfter - s), n = Math.max(0, e.numLinesBefore - s);
2827
+ let o = e.lines.find((a) => a >= i);
2828
+ if (o === undefined) {
2829
+ this._prevFrame = t;
2830
+ return;
2831
+ }
2832
+ if (e.lines.length === 1) {
2833
+ this.output.write(import_sisteransi.cursor.move(0, o - n)), this.output.write(import_sisteransi.erase.lines(1));
2834
+ const a = t.split(`
2835
+ `);
2836
+ this.output.write(a[o]), this._prevFrame = t, this.output.write(import_sisteransi.cursor.move(0, a.length - o - 1));
2837
+ return;
2838
+ } else if (e.lines.length > 1) {
2839
+ if (i < n)
2840
+ o = i;
2841
+ else {
2842
+ const h = o - n;
2843
+ h > 0 && this.output.write(import_sisteransi.cursor.move(0, h));
2844
+ }
2845
+ this.output.write(import_sisteransi.erase.down());
2846
+ const a = t.split(`
2847
+ `).slice(o);
2848
+ this.output.write(a.join(`
2849
+ `)), this._prevFrame = t;
2850
+ return;
2851
+ }
2852
+ }
2853
+ this.output.write(import_sisteransi.erase.down());
2854
+ }
2855
+ this.output.write(t), this.state === "initial" && (this.state = "active"), this._prevFrame = t;
2856
+ }
2857
+ }
2858
+ };
2859
+ function W(r, t) {
2860
+ if (r === undefined || t.length === 0)
2861
+ return 0;
2862
+ const e = t.findIndex((s) => s.value === r);
2863
+ return e !== -1 ? e : 0;
2864
+ }
2865
+ function B(r, t) {
2866
+ return (t.label ?? String(t.value)).toLowerCase().includes(r.toLowerCase());
2867
+ }
2868
+ function J(r, t) {
2869
+ if (t)
2870
+ return r ? t : t[0];
2871
+ }
2872
+ var H = class extends p {
2873
+ filteredOptions;
2874
+ multiple;
2875
+ isNavigating = false;
2876
+ selectedValues = [];
2877
+ focusedValue;
2878
+ #e = 0;
2879
+ #o = "";
2880
+ #t;
2881
+ #n;
2882
+ #a;
2883
+ get cursor() {
2884
+ return this.#e;
2885
+ }
2886
+ get userInputWithCursor() {
2887
+ if (!this.userInput)
2888
+ return y(["inverse", "hidden"], "_");
2889
+ if (this._cursor >= this.userInput.length)
2890
+ return `${this.userInput}█`;
2891
+ const t = this.userInput.slice(0, this._cursor), [e, ...s] = this.userInput.slice(this._cursor);
2892
+ return `${t}${y("inverse", e)}${s.join("")}`;
2893
+ }
2894
+ get options() {
2895
+ return typeof this.#n == "function" ? this.#n() : this.#n;
2896
+ }
2897
+ constructor(t) {
2898
+ super(t), this.#n = t.options, this.#a = t.placeholder;
2899
+ const e = this.options;
2900
+ this.filteredOptions = [...e], this.multiple = t.multiple === true, this.#t = typeof t.options == "function" ? t.filter : t.filter ?? B;
2901
+ let s;
2902
+ if (t.initialValue && Array.isArray(t.initialValue) ? this.multiple ? s = t.initialValue : s = t.initialValue.slice(0, 1) : !this.multiple && this.options.length > 0 && (s = [this.options[0].value]), s)
2903
+ for (const i of s) {
2904
+ const n = e.findIndex((o) => o.value === i);
2905
+ n !== -1 && (this.toggleSelected(i), this.#e = n);
2906
+ }
2907
+ this.focusedValue = this.options[this.#e]?.value, this.on("key", (i, n) => this.#s(i, n)), this.on("userInput", (i) => this.#i(i));
2908
+ }
2909
+ _isActionKey(t, e) {
2910
+ return t === "\t" || this.multiple && this.isNavigating && e.name === "space" && t !== undefined && t !== "";
2911
+ }
2912
+ #s(t, e) {
2913
+ const s = e.name === "up", i = e.name === "down", n = e.name === "return", o = this.userInput === "" || this.userInput === "\t", a = this.#a, h = this.options, l = a !== undefined && a !== "" && h.some((f) => !f.disabled && (this.#t ? this.#t(a, f) : true));
2914
+ if (e.name === "tab" && o && l) {
2915
+ this.userInput === "\t" && this._clearUserInput(), this._setUserInput(a, true), this.isNavigating = false;
2916
+ return;
2917
+ }
2918
+ s || i ? (this.#e = d(this.#e, s ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#e]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = J(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== undefined && (e.name === "tab" || this.isNavigating && e.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
2919
+ }
2920
+ deselectAll() {
2921
+ this.selectedValues = [];
2922
+ }
2923
+ toggleSelected(t) {
2924
+ this.filteredOptions.length !== 0 && (this.multiple ? this.selectedValues.includes(t) ? this.selectedValues = this.selectedValues.filter((e) => e !== t) : this.selectedValues = [...this.selectedValues, t] : this.selectedValues = [t]);
2925
+ }
2926
+ #i(t) {
2927
+ if (t !== this.#o) {
2928
+ this.#o = t;
2929
+ const e = this.options;
2930
+ t && this.#t ? this.filteredOptions = e.filter((n) => this.#t?.(t, n)) : this.filteredOptions = [...e];
2931
+ const s = W(this.focusedValue, this.filteredOptions);
2932
+ this.#e = d(s, 0, this.filteredOptions);
2933
+ const i = this.filteredOptions[this.#e];
2934
+ i && !i.disabled ? this.focusedValue = i.value : this.focusedValue = undefined, this.multiple || (this.focusedValue !== undefined ? this.toggleSelected(this.focusedValue) : this.deselectAll());
2935
+ }
2936
+ }
2937
+ };
2938
+
2939
+ class Q extends p {
2940
+ get cursor() {
2941
+ return this.value ? 0 : 1;
2942
+ }
2943
+ get _value() {
2944
+ return this.cursor === 0;
2945
+ }
2946
+ constructor(t) {
2947
+ super(t, false), this.value = !!t.initialValue, this.on("userInput", () => {
2948
+ this.value = this._value;
2949
+ }), this.on("confirm", (e) => {
2950
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = e, this.state = "submit", this.close();
2951
+ }), this.on("cursor", () => {
2952
+ this.value = !this.value;
2953
+ });
2954
+ }
2955
+ }
2956
+ var X = { Y: { type: "year", len: 4 }, M: { type: "month", len: 2 }, D: { type: "day", len: 2 } };
2957
+ function L(r) {
2958
+ return [...r].map((t) => X[t]);
2959
+ }
2960
+ function Z(r) {
2961
+ const t = new Intl.DateTimeFormat(r, { year: "numeric", month: "2-digit", day: "2-digit" }).formatToParts(new Date(2000, 0, 15)), e = [];
2962
+ let s = "/";
2963
+ for (const i of t)
2964
+ i.type === "literal" ? s = i.value.trim() || i.value : (i.type === "year" || i.type === "month" || i.type === "day") && e.push({ type: i.type, len: i.type === "year" ? 4 : 2 });
2965
+ return { segments: e, separator: s };
2966
+ }
2967
+ function k(r) {
2968
+ return Number.parseInt((r || "0").replace(/_/g, "0"), 10) || 0;
2969
+ }
2970
+ function I(r) {
2971
+ return { year: k(r.year), month: k(r.month), day: k(r.day) };
2972
+ }
2973
+ function T(r, t) {
2974
+ return new Date(r || 2001, t || 1, 0).getDate();
2975
+ }
2976
+ function F(r) {
2977
+ const { year: t, month: e, day: s } = I(r);
2978
+ if (!t || t < 0 || t > 9999 || !e || e < 1 || e > 12 || !s || s < 1)
2979
+ return;
2980
+ const i = new Date(Date.UTC(t, e - 1, s));
2981
+ if (!(i.getUTCFullYear() !== t || i.getUTCMonth() !== e - 1 || i.getUTCDate() !== s))
2982
+ return { year: t, month: e, day: s };
2983
+ }
2984
+ function N(r) {
2985
+ const t = F(r);
2986
+ return t ? new Date(Date.UTC(t.year, t.month - 1, t.day)) : undefined;
2987
+ }
2988
+ function tt(r, t, e, s) {
2989
+ const i = e ? { year: e.getUTCFullYear(), month: e.getUTCMonth() + 1, day: e.getUTCDate() } : null, n = s ? { year: s.getUTCFullYear(), month: s.getUTCMonth() + 1, day: s.getUTCDate() } : null;
2990
+ return r === "year" ? { min: i?.year ?? 1, max: n?.year ?? 9999 } : r === "month" ? { min: i && t.year === i.year ? i.month : 1, max: n && t.year === n.year ? n.month : 12 } : { min: i && t.year === i.year && t.month === i.month ? i.day : 1, max: n && t.year === n.year && t.month === n.month ? n.day : T(t.year, t.month) };
2991
+ }
2992
+
2993
+ class et extends p {
2994
+ #e;
2995
+ #o;
2996
+ #t;
2997
+ #n;
2998
+ #a;
2999
+ #s = { segmentIndex: 0, positionInSegment: 0 };
3000
+ #i = true;
3001
+ #r = null;
3002
+ inlineError = "";
3003
+ get segmentCursor() {
3004
+ return { ...this.#s };
3005
+ }
3006
+ get segmentValues() {
3007
+ return { ...this.#t };
3008
+ }
3009
+ get segments() {
3010
+ return this.#e;
3011
+ }
3012
+ get separator() {
3013
+ return this.#o;
3014
+ }
3015
+ get formattedValue() {
3016
+ return this.#c(this.#t);
3017
+ }
3018
+ #c(t) {
3019
+ return this.#e.map((e) => t[e.type]).join(this.#o);
3020
+ }
3021
+ #h() {
3022
+ this._setUserInput(this.#c(this.#t)), this._setValue(N(this.#t) ?? undefined);
3023
+ }
3024
+ constructor(t) {
3025
+ const e = t.format ? { segments: L(t.format), separator: t.separator ?? "/" } : Z(t.locale), s = t.separator ?? e.separator, i = t.format ? L(t.format) : e.segments, n = t.initialValue ?? t.defaultValue, o = n ? { year: String(n.getUTCFullYear()).padStart(4, "0"), month: String(n.getUTCMonth() + 1).padStart(2, "0"), day: String(n.getUTCDate()).padStart(2, "0") } : { year: "____", month: "__", day: "__" }, a = i.map((h) => o[h.type]).join(s);
3026
+ super({ ...t, initialUserInput: a }, false), this.#e = i, this.#o = s, this.#t = o, this.#n = t.minDate, this.#a = t.maxDate, this.#h(), this.on("cursor", (h) => this.#d(h)), this.on("key", (h, l) => this.#f(h, l)), this.on("finalize", () => this.#g(t));
3027
+ }
3028
+ #u() {
3029
+ const t = Math.max(0, Math.min(this.#s.segmentIndex, this.#e.length - 1)), e = this.#e[t];
3030
+ if (e)
3031
+ return this.#s.positionInSegment = Math.max(0, Math.min(this.#s.positionInSegment, e.len - 1)), { segment: e, index: t };
3032
+ }
3033
+ #l(t) {
3034
+ this.inlineError = "", this.#r = null;
3035
+ const e = this.#u();
3036
+ e && (this.#s.segmentIndex = Math.max(0, Math.min(this.#e.length - 1, e.index + t)), this.#s.positionInSegment = 0, this.#i = true);
3037
+ }
3038
+ #p(t) {
3039
+ const e = this.#u();
3040
+ if (!e)
3041
+ return;
3042
+ const { segment: s } = e, i = this.#t[s.type], n = !i || i.replace(/_/g, "") === "", o = Number.parseInt((i || "0").replace(/_/g, "0"), 10) || 0, a = tt(s.type, I(this.#t), this.#n, this.#a);
3043
+ let h;
3044
+ n ? h = t === 1 ? a.min : a.max : h = Math.max(Math.min(a.max, o + t), a.min), this.#t = { ...this.#t, [s.type]: h.toString().padStart(s.len, "0") }, this.#i = true, this.#r = null, this.#h();
3045
+ }
3046
+ #d(t) {
3047
+ if (t)
3048
+ switch (t) {
3049
+ case "right":
3050
+ return this.#l(1);
3051
+ case "left":
3052
+ return this.#l(-1);
3053
+ case "up":
3054
+ return this.#p(1);
3055
+ case "down":
3056
+ return this.#p(-1);
3057
+ }
3058
+ }
3059
+ #f(t, e) {
3060
+ if (e?.name === "backspace" || e?.sequence === "" || e?.sequence === "\b" || t === "" || t === "\b") {
3061
+ this.inlineError = "";
3062
+ const s = this.#u();
3063
+ if (!s)
3064
+ return;
3065
+ if (!this.#t[s.segment.type].replace(/_/g, "")) {
3066
+ this.#l(-1);
3067
+ return;
3068
+ }
3069
+ this.#t[s.segment.type] = "_".repeat(s.segment.len), this.#i = true, this.#s.positionInSegment = 0, this.#h();
3070
+ return;
3071
+ }
3072
+ if (e?.name === "tab") {
3073
+ this.inlineError = "";
3074
+ const s = this.#u();
3075
+ if (!s)
3076
+ return;
3077
+ const i = e.shift ? -1 : 1, n = s.index + i;
3078
+ n >= 0 && n < this.#e.length && (this.#s.segmentIndex = n, this.#s.positionInSegment = 0, this.#i = true);
3079
+ return;
3080
+ }
3081
+ if (t && /^[0-9]$/.test(t)) {
3082
+ const s = this.#u();
3083
+ if (!s)
3084
+ return;
3085
+ const { segment: i } = s, n = !this.#t[i.type].replace(/_/g, "");
3086
+ if (this.#i && this.#r !== null && !n) {
3087
+ const m = this.#r + t, g = { ...this.#t, [i.type]: m }, b = this.#m(g, i);
3088
+ if (b) {
3089
+ this.inlineError = b, this.#r = null, this.#i = false;
3090
+ return;
3091
+ }
3092
+ this.inlineError = "", this.#t[i.type] = m, this.#r = null, this.#i = false, this.#h(), s.index < this.#e.length - 1 && (this.#s.segmentIndex = s.index + 1, this.#s.positionInSegment = 0, this.#i = true);
3093
+ return;
3094
+ }
3095
+ this.#i && !n && (this.#t[i.type] = "_".repeat(i.len), this.#s.positionInSegment = 0), this.#i = false, this.#r = null;
3096
+ const o = this.#t[i.type], a = o.indexOf("_"), h = a >= 0 ? a : Math.min(this.#s.positionInSegment, i.len - 1);
3097
+ if (h < 0 || h >= i.len)
3098
+ return;
3099
+ let l = o.slice(0, h) + t + o.slice(h + 1), f = false;
3100
+ if (h === 0 && o === "__" && (i.type === "month" || i.type === "day")) {
3101
+ const m = Number.parseInt(t, 10);
3102
+ l = `0${t}`, f = m <= (i.type === "month" ? 1 : 2);
3103
+ }
3104
+ if (i.type === "year" && (l = (o.replace(/_/g, "") + t).padStart(i.len, "_")), !l.includes("_")) {
3105
+ const m = { ...this.#t, [i.type]: l }, g = this.#m(m, i);
3106
+ if (g) {
3107
+ this.inlineError = g;
3108
+ return;
3109
+ }
3110
+ }
3111
+ this.inlineError = "", this.#t[i.type] = l;
3112
+ const v = l.includes("_") ? undefined : F(this.#t);
3113
+ if (v) {
3114
+ const { year: m, month: g } = v, b = T(m, g);
3115
+ this.#t = { year: String(Math.max(0, Math.min(9999, m))).padStart(4, "0"), month: String(Math.max(1, Math.min(12, g))).padStart(2, "0"), day: String(Math.max(1, Math.min(b, v.day))).padStart(2, "0") };
3116
+ }
3117
+ this.#h();
3118
+ const U = l.indexOf("_");
3119
+ f ? (this.#i = true, this.#r = t) : U >= 0 ? this.#s.positionInSegment = U : a >= 0 && s.index < this.#e.length - 1 ? (this.#s.segmentIndex = s.index + 1, this.#s.positionInSegment = 0, this.#i = true) : this.#s.positionInSegment = Math.min(h + 1, i.len - 1);
3120
+ }
3121
+ }
3122
+ #m(t, e) {
3123
+ const { month: s, day: i } = I(t);
3124
+ if (e.type === "month" && (s < 0 || s > 12))
3125
+ return u.date.messages.invalidMonth;
3126
+ if (e.type === "day" && (i < 0 || i > 31))
3127
+ return u.date.messages.invalidDay(31, "any month");
3128
+ }
3129
+ #g(t) {
3130
+ const { year: e, month: s, day: i } = I(this.#t);
3131
+ if (e && s && i) {
3132
+ const n = T(e, s);
3133
+ this.#t = { ...this.#t, day: String(Math.min(i, n)).padStart(2, "0") };
3134
+ }
3135
+ this.value = N(this.#t) ?? t.defaultValue ?? undefined;
3136
+ }
3137
+ }
3138
+
3139
+ class st extends p {
3140
+ options;
3141
+ cursor = 0;
3142
+ #e;
3143
+ getGroupItems(t) {
3144
+ return this.options.filter((e) => e.group === t);
3145
+ }
3146
+ isGroupSelected(t) {
3147
+ const e = this.getGroupItems(t), s = this.value;
3148
+ return s === undefined ? false : e.every((i) => s.includes(i.value));
3149
+ }
3150
+ toggleValue() {
3151
+ const t = this.options[this.cursor];
3152
+ if (this.value === undefined && (this.value = []), t.group === true) {
3153
+ const e = t.value, s = this.getGroupItems(e);
3154
+ this.isGroupSelected(e) ? this.value = this.value.filter((i) => s.findIndex((n) => n.value === i) === -1) : this.value = [...this.value, ...s.map((i) => i.value)], this.value = Array.from(new Set(this.value));
3155
+ } else {
3156
+ const e = this.value.includes(t.value);
3157
+ this.value = e ? this.value.filter((s) => s !== t.value) : [...this.value, t.value];
3158
+ }
3159
+ }
3160
+ constructor(t) {
3161
+ super(t, false);
3162
+ const { options: e } = t;
3163
+ this.#e = t.selectableGroups !== false, this.options = Object.entries(e).flatMap(([s, i]) => [{ value: s, group: true, label: s }, ...i.map((n) => ({ ...n, group: s }))]), this.value = [...t.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: s }) => s === t.cursorAt), this.#e ? 0 : 1), this.on("cursor", (s) => {
3164
+ switch (s) {
3165
+ case "left":
3166
+ case "up": {
3167
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
3168
+ const i = this.options[this.cursor]?.group === true;
3169
+ !this.#e && i && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
3170
+ break;
3171
+ }
3172
+ case "down":
3173
+ case "right": {
3174
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
3175
+ const i = this.options[this.cursor]?.group === true;
3176
+ !this.#e && i && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
3177
+ break;
3178
+ }
3179
+ case "space":
3180
+ this.toggleValue();
3181
+ break;
3182
+ }
3183
+ });
3184
+ }
3185
+ }
3186
+ var it = class extends p {
3187
+ options;
3188
+ cursor = 0;
3189
+ get _value() {
3190
+ return this.options[this.cursor].value;
3191
+ }
3192
+ get _enabledOptions() {
3193
+ return this.options.filter((t) => t.disabled !== true);
3194
+ }
3195
+ toggleAll() {
3196
+ const t = this._enabledOptions, e = this.value !== undefined && this.value.length === t.length;
3197
+ this.value = e ? [] : t.map((s) => s.value);
3198
+ }
3199
+ toggleInvert() {
3200
+ const t = this.value;
3201
+ if (!t)
3202
+ return;
3203
+ const e = this._enabledOptions.filter((s) => !t.includes(s.value));
3204
+ this.value = e.map((s) => s.value);
3205
+ }
3206
+ toggleValue() {
3207
+ this.value === undefined && (this.value = []);
3208
+ const t = this.value.includes(this._value);
3209
+ this.value = t ? this.value.filter((e) => e !== this._value) : [...this.value, this._value];
3210
+ }
3211
+ constructor(t) {
3212
+ super(t, false), this.options = t.options, this.value = [...t.initialValues ?? []];
3213
+ const e = Math.max(this.options.findIndex(({ value: s }) => s === t.cursorAt), 0);
3214
+ this.cursor = this.options[e].disabled ? d(e, 1, this.options) : e, this.on("key", (s) => {
3215
+ s === "a" && this.toggleAll(), s === "i" && this.toggleInvert();
3216
+ }), this.on("cursor", (s) => {
3217
+ switch (s) {
3218
+ case "left":
3219
+ case "up":
3220
+ this.cursor = d(this.cursor, -1, this.options);
3221
+ break;
3222
+ case "down":
3223
+ case "right":
3224
+ this.cursor = d(this.cursor, 1, this.options);
3225
+ break;
3226
+ case "space":
3227
+ this.toggleValue();
3228
+ break;
3229
+ }
3230
+ });
3231
+ }
3232
+ };
3233
+ class nt extends p {
3234
+ options;
3235
+ cursor = 0;
3236
+ get _selectedValue() {
3237
+ return this.options[this.cursor];
3238
+ }
3239
+ changeValue() {
3240
+ this.value = this._selectedValue.value;
3241
+ }
3242
+ constructor(t) {
3243
+ super(t, false), this.options = t.options;
3244
+ const e = this.options.findIndex(({ value: i }) => i === t.initialValue), s = e === -1 ? 0 : e;
3245
+ this.cursor = this.options[s].disabled ? d(s, 1, this.options) : s, this.changeValue(), this.on("cursor", (i) => {
3246
+ switch (i) {
3247
+ case "left":
3248
+ case "up":
3249
+ this.cursor = d(this.cursor, -1, this.options);
3250
+ break;
3251
+ case "down":
3252
+ case "right":
3253
+ this.cursor = d(this.cursor, 1, this.options);
3254
+ break;
3255
+ }
3256
+ this.changeValue();
3257
+ });
3258
+ }
3259
+ }
3260
+ class at extends p {
3261
+ get userInputWithCursor() {
3262
+ if (this.state === "submit")
3263
+ return this.userInput;
3264
+ const t = this.userInput;
3265
+ if (this.cursor >= t.length)
3266
+ return `${this.userInput}█`;
3267
+ const e = t.slice(0, this.cursor), [s, ...i] = t.slice(this.cursor);
3268
+ return `${e}${y("inverse", s)}${i.join("")}`;
3269
+ }
3270
+ get cursor() {
3271
+ return this._cursor;
3272
+ }
3273
+ constructor(t) {
3274
+ super({ ...t, initialUserInput: t.initialUserInput ?? t.initialValue }), this.on("userInput", (e) => {
3275
+ this._setValue(e);
3276
+ }), this.on("finalize", () => {
3277
+ this.value || (this.value = t.defaultValue), this.value === undefined && (this.value = "");
3278
+ });
3279
+ }
3280
+ }
3281
+
3282
+ // node_modules/@clack/prompts/dist/index.mjs
3283
+ import { styleText as t, stripVTControlCharacters as ne } from "node:util";
3284
+ import P2 from "node:process";
3285
+ var import_sisteransi2 = __toESM(require_src(), 1);
3286
+ function Ze() {
3287
+ return P2.platform !== "win32" ? P2.env.TERM !== "linux" : !!P2.env.CI || !!P2.env.WT_SESSION || !!P2.env.TERMINUS_SUBLIME || P2.env.ConEmuTask === "{cmd::Cmder}" || P2.env.TERM_PROGRAM === "Terminus-Sublime" || P2.env.TERM_PROGRAM === "vscode" || P2.env.TERM === "xterm-256color" || P2.env.TERM === "alacritty" || P2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
3288
+ }
3289
+ var ee = Ze();
3290
+ var ae = () => process.env.CI === "true";
3291
+ var w2 = (e, i) => ee ? e : i;
3292
+ var _e = w2("◆", "*");
3293
+ var oe = w2("■", "x");
3294
+ var ue = w2("▲", "x");
3295
+ var F2 = w2("◇", "o");
3296
+ var le = w2("┌", "T");
3297
+ var d2 = w2("│", "|");
3298
+ var E2 = w2("└", "—");
3299
+ var Ie = w2("┐", "T");
3300
+ var Ee = w2("┘", "—");
3301
+ var z2 = w2("●", ">");
3302
+ var H2 = w2("○", " ");
3303
+ var te = w2("◻", "[•]");
3304
+ var U = w2("◼", "[+]");
3305
+ var J2 = w2("◻", "[ ]");
3306
+ var xe = w2("▪", "•");
3307
+ var se = w2("─", "-");
3308
+ var ce = w2("╮", "+");
3309
+ var Ge = w2("├", "+");
3310
+ var $e = w2("╯", "+");
3311
+ var de = w2("╰", "+");
3312
+ var Oe = w2("╭", "+");
3313
+ var he = w2("●", "•");
3314
+ var pe = w2("◆", "*");
3315
+ var me = w2("▲", "!");
3316
+ var ge = w2("■", "x");
3317
+ var V2 = (e) => {
3318
+ switch (e) {
3319
+ case "initial":
3320
+ case "active":
3321
+ return t("cyan", _e);
3322
+ case "cancel":
3323
+ return t("red", oe);
3324
+ case "error":
3325
+ return t("yellow", ue);
3326
+ case "submit":
3327
+ return t("green", F2);
3328
+ }
3329
+ };
3330
+ var ye = (e) => {
3331
+ switch (e) {
3332
+ case "initial":
3333
+ case "active":
3334
+ return t("cyan", d2);
3335
+ case "cancel":
3336
+ return t("red", d2);
3337
+ case "error":
3338
+ return t("yellow", d2);
3339
+ case "submit":
3340
+ return t("green", d2);
3341
+ }
3342
+ };
3343
+ var et2 = (e, i, s, r, u2) => {
3344
+ let n = i, o = 0;
3345
+ for (let c2 = s;c2 < r; c2++) {
3346
+ const a = e[c2];
3347
+ if (n = n - a.length, o++, n <= u2)
3348
+ break;
3349
+ }
3350
+ return { lineCount: n, removals: o };
3351
+ };
3352
+ var Y2 = ({ cursor: e, options: i, style: s, output: r = process.stdout, maxItems: u2 = Number.POSITIVE_INFINITY, columnPadding: n = 0, rowPadding: o = 4 }) => {
3353
+ const c2 = O(r) - n, a = A(r), l = t("dim", "..."), $2 = Math.max(a - o, 0), y2 = Math.max(Math.min(u2, $2), 5);
3354
+ let p2 = 0;
3355
+ e >= y2 - 3 && (p2 = Math.max(Math.min(e - y2 + 3, i.length - y2), 0));
3356
+ let m = y2 < i.length && p2 > 0, g = y2 < i.length && p2 + y2 < i.length;
3357
+ const S2 = Math.min(p2 + y2, i.length), h = [];
3358
+ let f = 0;
3359
+ m && f++, g && f++;
3360
+ const v = p2 + (m ? 1 : 0), T2 = S2 - (g ? 1 : 0);
3361
+ for (let b = v;b < T2; b++) {
3362
+ const x = wrapAnsi(s(i[b], b === e), c2, { hard: true, trim: false }).split(`
3363
+ `);
3364
+ h.push(x), f += x.length;
3365
+ }
3366
+ if (f > $2) {
3367
+ let b = 0, x = 0, G2 = f;
3368
+ const M2 = e - v, R2 = (j2, D2) => et2(h, G2, j2, D2, $2);
3369
+ m ? ({ lineCount: G2, removals: b } = R2(0, M2), G2 > $2 && ({ lineCount: G2, removals: x } = R2(M2 + 1, h.length))) : ({ lineCount: G2, removals: x } = R2(M2 + 1, h.length), G2 > $2 && ({ lineCount: G2, removals: b } = R2(0, M2))), b > 0 && (m = true, h.splice(0, b)), x > 0 && (g = true, h.splice(h.length - x, x));
3370
+ }
3371
+ const C2 = [];
3372
+ m && C2.push(l);
3373
+ for (const b of h)
3374
+ for (const x of b)
3375
+ C2.push(x);
3376
+ return g && C2.push(l), C2;
3377
+ };
3378
+ var ot2 = (e) => {
3379
+ const i = e.active ?? "Yes", s = e.inactive ?? "No";
3380
+ return new Q({ active: i, inactive: s, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue ?? true, render() {
3381
+ const r = e.withGuide ?? u.withGuide, u2 = `${V2(this.state)} `, n = r ? `${t("gray", d2)} ` : "", o = R(e.output, e.message, n, u2), c2 = `${r ? `${t("gray", d2)}
3382
+ ` : ""}${o}
3383
+ `, a = this.value ? i : s;
3384
+ switch (this.state) {
3385
+ case "submit": {
3386
+ const l = r ? `${t("gray", d2)} ` : "";
3387
+ return `${c2}${l}${t("dim", a)}`;
3388
+ }
3389
+ case "cancel": {
3390
+ const l = r ? `${t("gray", d2)} ` : "";
3391
+ return `${c2}${l}${t(["strikethrough", "dim"], a)}${r ? `
3392
+ ${t("gray", d2)}` : ""}`;
3393
+ }
3394
+ default: {
3395
+ const l = r ? `${t("cyan", d2)} ` : "", $2 = r ? t("cyan", E2) : "";
3396
+ return `${c2}${l}${this.value ? `${t("green", z2)} ${i}` : `${t("dim", H2)} ${t("dim", i)}`}${e.vertical ? r ? `
3397
+ ${t("cyan", d2)} ` : `
3398
+ ` : ` ${t("dim", "/")} `}${this.value ? `${t("dim", H2)} ${t("dim", s)}` : `${t("green", z2)} ${s}`}
3399
+ ${$2}
3400
+ `;
3401
+ }
3402
+ }
3403
+ } }).prompt();
3404
+ };
3405
+ var O2 = { message: (e = [], { symbol: i = t("gray", d2), secondarySymbol: s = t("gray", d2), output: r = process.stdout, spacing: u2 = 1, withGuide: n } = {}) => {
3406
+ const o = [], c2 = n ?? u.withGuide, a = c2 ? s : "", l = c2 ? `${i} ` : "", $2 = c2 ? `${s} ` : "";
3407
+ for (let p2 = 0;p2 < u2; p2++)
3408
+ o.push(a);
3409
+ const y2 = Array.isArray(e) ? e : e.split(`
3410
+ `);
3411
+ if (y2.length > 0) {
3412
+ const [p2, ...m] = y2;
3413
+ p2.length > 0 ? o.push(`${l}${p2}`) : o.push(c2 ? i : "");
3414
+ for (const g of m)
3415
+ g.length > 0 ? o.push(`${$2}${g}`) : o.push(c2 ? s : "");
3416
+ }
3417
+ r.write(`${o.join(`
3418
+ `)}
3419
+ `);
3420
+ }, info: (e, i) => {
3421
+ O2.message(e, { ...i, symbol: t("blue", he) });
3422
+ }, success: (e, i) => {
3423
+ O2.message(e, { ...i, symbol: t("green", pe) });
3424
+ }, step: (e, i) => {
3425
+ O2.message(e, { ...i, symbol: t("green", F2) });
3426
+ }, warn: (e, i) => {
3427
+ O2.message(e, { ...i, symbol: t("yellow", me) });
3428
+ }, warning: (e, i) => {
3429
+ O2.warn(e, i);
3430
+ }, error: (e, i) => {
3431
+ O2.message(e, { ...i, symbol: t("red", ge) });
3432
+ } };
3433
+ var pt = (e = "", i) => {
3434
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? u.withGuide ? `${t("gray", E2)} ` : "";
3435
+ s.write(`${r}${t("red", e)}
3436
+
3437
+ `);
3438
+ };
3439
+ var mt = (e = "", i) => {
3440
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? u.withGuide ? `${t("gray", le)} ` : "";
3441
+ s.write(`${r}${e}
3442
+ `);
3443
+ };
3444
+ var gt = (e = "", i) => {
3445
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? u.withGuide ? `${t("gray", d2)}
3446
+ ${t("gray", E2)} ` : "";
3447
+ s.write(`${r}${e}
3448
+
3449
+ `);
3450
+ };
3451
+ var Q2 = (e, i) => e.split(`
3452
+ `).map((s) => i(s)).join(`
3453
+ `);
3454
+ var yt = (e) => {
3455
+ const i = (r, u2) => {
3456
+ const n = r.label ?? String(r.value);
3457
+ return u2 === "disabled" ? `${t("gray", J2)} ${Q2(n, (o) => t(["strikethrough", "gray"], o))}${r.hint ? ` ${t("dim", `(${r.hint ?? "disabled"})`)}` : ""}` : u2 === "active" ? `${t("cyan", te)} ${n}${r.hint ? ` ${t("dim", `(${r.hint})`)}` : ""}` : u2 === "selected" ? `${t("green", U)} ${Q2(n, (o) => t("dim", o))}${r.hint ? ` ${t("dim", `(${r.hint})`)}` : ""}` : u2 === "cancelled" ? `${Q2(n, (o) => t(["strikethrough", "dim"], o))}` : u2 === "active-selected" ? `${t("green", U)} ${n}${r.hint ? ` ${t("dim", `(${r.hint})`)}` : ""}` : u2 === "submitted" ? `${Q2(n, (o) => t("dim", o))}` : `${t("dim", J2)} ${Q2(n, (o) => t("dim", o))}`;
3458
+ }, s = e.required ?? true;
3459
+ return new it({ options: e.options, signal: e.signal, input: e.input, output: e.output, initialValues: e.initialValues, required: s, cursorAt: e.cursorAt, validate(r) {
3460
+ if (s && (r === undefined || r.length === 0))
3461
+ return `Please select at least one option.
3462
+ ${t("reset", t("dim", `Press ${t(["gray", "bgWhite", "inverse"], " space ")} to select, ${t("gray", t("bgWhite", t("inverse", " enter ")))} to submit`))}`;
3463
+ }, render() {
3464
+ const r = e.withGuide ?? u.withGuide, u2 = R(e.output, e.message, r ? `${ye(this.state)} ` : "", `${V2(this.state)} `), n = `${r ? `${t("gray", d2)}
3465
+ ` : ""}${u2}
3466
+ `, o = this.value ?? [], c2 = (a, l) => {
3467
+ if (a.disabled)
3468
+ return i(a, "disabled");
3469
+ const $2 = o.includes(a.value);
3470
+ return l && $2 ? i(a, "active-selected") : $2 ? i(a, "selected") : i(a, l ? "active" : "inactive");
3471
+ };
3472
+ switch (this.state) {
3473
+ case "submit": {
3474
+ const a = this.options.filter(({ value: $2 }) => o.includes($2)).map(($2) => i($2, "submitted")).join(t("dim", ", ")) || t("dim", "none"), l = R(e.output, a, r ? `${t("gray", d2)} ` : "");
3475
+ return `${n}${l}`;
3476
+ }
3477
+ case "cancel": {
3478
+ const a = this.options.filter(({ value: $2 }) => o.includes($2)).map(($2) => i($2, "cancelled")).join(t("dim", ", "));
3479
+ if (a.trim() === "")
3480
+ return `${n}${t("gray", d2)}`;
3481
+ const l = R(e.output, a, r ? `${t("gray", d2)} ` : "");
3482
+ return `${n}${l}${r ? `
3483
+ ${t("gray", d2)}` : ""}`;
3484
+ }
3485
+ case "error": {
3486
+ const a = r ? `${t("yellow", d2)} ` : "", l = this.error.split(`
3487
+ `).map((p2, m) => m === 0 ? `${r ? `${t("yellow", E2)} ` : ""}${t("yellow", p2)}` : ` ${p2}`).join(`
3488
+ `), $2 = n.split(`
3489
+ `).length, y2 = l.split(`
3490
+ `).length + 1;
3491
+ return `${n}${a}${Y2({ output: e.output, options: this.options, cursor: this.cursor, maxItems: e.maxItems, columnPadding: a.length, rowPadding: $2 + y2, style: c2 }).join(`
3492
+ ${a}`)}
3493
+ ${l}
3494
+ `;
3495
+ }
3496
+ default: {
3497
+ const a = r ? `${t("cyan", d2)} ` : "", l = n.split(`
3498
+ `).length, $2 = r ? 2 : 1;
3499
+ return `${n}${a}${Y2({ output: e.output, options: this.options, cursor: this.cursor, maxItems: e.maxItems, columnPadding: a.length, rowPadding: l + $2, style: c2 }).join(`
3500
+ ${a}`)}
3501
+ ${r ? t("cyan", E2) : ""}
3502
+ `;
3503
+ }
3504
+ }
3505
+ } }).prompt();
3506
+ };
3507
+ var ft = (e) => t("dim", e);
3508
+ var vt = (e, i, s) => {
3509
+ const r = { hard: true, trim: false }, u2 = wrapAnsi(e, i, r).split(`
3510
+ `), n = u2.reduce((a, l) => Math.max(dist_default2(l), a), 0), o = u2.map(s).reduce((a, l) => Math.max(dist_default2(l), a), 0), c2 = i - (o - n);
3511
+ return wrapAnsi(e, c2, r);
3512
+ };
3513
+ var wt = (e = "", i = "", s) => {
3514
+ const r = s?.output ?? P2.stdout, u2 = s?.withGuide ?? u.withGuide, n = s?.format ?? ft, o = ["", ...vt(e, O(r) - 6, n).split(`
3515
+ `).map(n), ""], c2 = dist_default2(i), a = Math.max(o.reduce((p2, m) => {
3516
+ const g = dist_default2(m);
3517
+ return g > p2 ? g : p2;
3518
+ }, 0), c2) + 2, l = o.map((p2) => `${t("gray", d2)} ${p2}${" ".repeat(a - dist_default2(p2))}${t("gray", d2)}`).join(`
3519
+ `), $2 = u2 ? `${t("gray", d2)}
3520
+ ` : "", y2 = u2 ? Ge : de;
3521
+ r.write(`${$2}${t("green", F2)} ${t("reset", i)} ${t("gray", se.repeat(Math.max(a - c2 - 1, 1)) + ce)}
3522
+ ${l}
3523
+ ${t("gray", y2 + se.repeat(a + 2) + $e)}
3524
+ `);
3525
+ };
3526
+ var Ct = (e) => t("magenta", e);
3527
+ var fe = ({ indicator: e = "dots", onCancel: i, output: s = process.stdout, cancelMessage: r, errorMessage: u2, frames: n = ee ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], delay: o = ee ? 80 : 120, signal: c2, ...a } = {}) => {
3528
+ const l = ae();
3529
+ let $2, y2, p2 = false, m = false, g = "", S2, h = performance.now();
3530
+ const f = O(s), v = a?.styleFrame ?? Ct, T2 = (_2) => {
3531
+ const A2 = _2 > 1 ? u2 ?? u.messages.error : r ?? u.messages.cancel;
3532
+ m = _2 === 1, p2 && (W2(A2, _2), m && typeof i == "function" && i());
3533
+ }, C2 = () => T2(2), b = () => T2(1), x = () => {
3534
+ process.on("uncaughtExceptionMonitor", C2), process.on("unhandledRejection", C2), process.on("SIGINT", b), process.on("SIGTERM", b), process.on("exit", T2), c2 && c2.addEventListener("abort", b);
3535
+ }, G2 = () => {
3536
+ process.removeListener("uncaughtExceptionMonitor", C2), process.removeListener("unhandledRejection", C2), process.removeListener("SIGINT", b), process.removeListener("SIGTERM", b), process.removeListener("exit", T2), c2 && c2.removeEventListener("abort", b);
3537
+ }, M2 = () => {
3538
+ if (S2 === undefined)
3539
+ return;
3540
+ l && s.write(`
3541
+ `);
3542
+ const _2 = wrapAnsi(S2, f, { hard: true, trim: false }).split(`
3543
+ `);
3544
+ _2.length > 1 && s.write(import_sisteransi2.cursor.up(_2.length - 1)), s.write(import_sisteransi2.cursor.to(0)), s.write(import_sisteransi2.erase.down());
3545
+ }, R2 = (_2) => _2.replace(/\.+$/, ""), j2 = (_2) => {
3546
+ const A2 = (performance.now() - _2) / 1000, k2 = Math.floor(A2 / 60), L2 = Math.floor(A2 % 60);
3547
+ return k2 > 0 ? `[${k2}m ${L2}s]` : `[${L2}s]`;
3548
+ }, D2 = a.withGuide ?? u.withGuide, ie = (_2 = "") => {
3549
+ p2 = true, $2 = z({ output: s }), g = R2(_2), h = performance.now(), D2 && s.write(`${t("gray", d2)}
3550
+ `);
3551
+ let A2 = 0, k2 = 0;
3552
+ x(), y2 = setInterval(() => {
3553
+ if (l && g === S2)
3554
+ return;
3555
+ M2(), S2 = g;
3556
+ const L2 = v(n[A2]);
3557
+ let Z2;
3558
+ if (l)
3559
+ Z2 = `${L2} ${g}...`;
3560
+ else if (e === "timer")
3561
+ Z2 = `${L2} ${g} ${j2(h)}`;
3562
+ else {
3563
+ const Be = ".".repeat(Math.floor(k2)).slice(0, 3);
3564
+ Z2 = `${L2} ${g}${Be}`;
3565
+ }
3566
+ const Ne = wrapAnsi(Z2, f, { hard: true, trim: false });
3567
+ s.write(Ne), A2 = A2 + 1 < n.length ? A2 + 1 : 0, k2 = k2 < 4 ? k2 + 0.125 : 0;
3568
+ }, o);
3569
+ }, W2 = (_2 = "", A2 = 0, k2 = false) => {
3570
+ if (!p2)
3571
+ return;
3572
+ p2 = false, clearInterval(y2), M2();
3573
+ const L2 = A2 === 0 ? t("green", F2) : A2 === 1 ? t("red", oe) : t("red", ue);
3574
+ g = _2 ?? g, k2 || (e === "timer" ? s.write(`${L2} ${g} ${j2(h)}
3575
+ `) : s.write(`${L2} ${g}
3576
+ `)), G2(), $2();
3577
+ };
3578
+ return { start: ie, stop: (_2 = "") => W2(_2, 0), message: (_2 = "") => {
3579
+ g = R2(_2 ?? g);
3580
+ }, cancel: (_2 = "") => W2(_2, 1), error: (_2 = "") => W2(_2, 2), clear: () => W2("", 0, true), get isCancelled() {
3581
+ return m;
3582
+ } };
3583
+ };
3584
+ var Ve = { light: w2("─", "-"), heavy: w2("━", "="), block: w2("█", "#") };
3585
+ function Tt({ style: e = "heavy", max: i = 100, size: s = 40, ...r } = {}) {
3586
+ const u2 = fe(r);
3587
+ let n = 0, o = "";
3588
+ const c2 = Math.max(1, i), a = Math.max(1, s), l = (m) => {
3589
+ switch (m) {
3590
+ case "initial":
3591
+ case "active":
3592
+ return (g) => t("magenta", g);
3593
+ case "error":
3594
+ case "cancel":
3595
+ return (g) => t("red", g);
3596
+ case "submit":
3597
+ return (g) => t("green", g);
3598
+ default:
3599
+ return (g) => t("magenta", g);
3600
+ }
3601
+ }, $2 = (m, g) => {
3602
+ const S2 = Math.floor(n / c2 * a);
3603
+ return `${l(m)(Ve[e].repeat(S2))}${t("dim", Ve[e].repeat(a - S2))} ${g}`;
3604
+ }, y2 = (m = "") => {
3605
+ o = m, u2.start($2("initial", m));
3606
+ }, p2 = (m = 1, g) => {
3607
+ n = Math.min(c2, m + n), u2.message($2("active", g ?? o)), o = g ?? o;
3608
+ };
3609
+ return { start: y2, stop: u2.stop, cancel: u2.cancel, error: u2.error, clear: u2.clear, advance: p2, isCancelled: u2.isCancelled, message: (m) => p2(0, m) };
3610
+ }
3611
+ var re = (e, i) => e.includes(`
3612
+ `) ? e.split(`
3613
+ `).map((s) => i(s)).join(`
3614
+ `) : i(e);
3615
+ var _t = (e) => {
3616
+ const i = (s, r) => {
3617
+ const u2 = s.label ?? String(s.value);
3618
+ switch (r) {
3619
+ case "disabled":
3620
+ return `${t("gray", H2)} ${re(u2, (n) => t("gray", n))}${s.hint ? ` ${t("dim", `(${s.hint ?? "disabled"})`)}` : ""}`;
3621
+ case "selected":
3622
+ return `${re(u2, (n) => t("dim", n))}`;
3623
+ case "active":
3624
+ return `${t("green", z2)} ${u2}${s.hint ? ` ${t("dim", `(${s.hint})`)}` : ""}`;
3625
+ case "cancelled":
3626
+ return `${re(u2, (n) => t(["strikethrough", "dim"], n))}`;
3627
+ default:
3628
+ return `${t("dim", H2)} ${re(u2, (n) => t("dim", n))}`;
3629
+ }
3630
+ };
3631
+ return new nt({ options: e.options, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue, render() {
3632
+ const s = e.withGuide ?? u.withGuide, r = `${V2(this.state)} `, u2 = `${ye(this.state)} `, n = R(e.output, e.message, u2, r), o = `${s ? `${t("gray", d2)}
3633
+ ` : ""}${n}
3634
+ `;
3635
+ switch (this.state) {
3636
+ case "submit": {
3637
+ const c2 = s ? `${t("gray", d2)} ` : "", a = R(e.output, i(this.options[this.cursor], "selected"), c2);
3638
+ return `${o}${a}`;
3639
+ }
3640
+ case "cancel": {
3641
+ const c2 = s ? `${t("gray", d2)} ` : "", a = R(e.output, i(this.options[this.cursor], "cancelled"), c2);
3642
+ return `${o}${a}${s ? `
3643
+ ${t("gray", d2)}` : ""}`;
3644
+ }
3645
+ default: {
3646
+ const c2 = s ? `${t("cyan", d2)} ` : "", a = s ? t("cyan", E2) : "", l = o.split(`
3647
+ `).length, $2 = s ? 2 : 1;
3648
+ return `${o}${c2}${Y2({ output: e.output, cursor: this.cursor, options: this.options, maxItems: e.maxItems, columnPadding: c2.length, rowPadding: l + $2, style: (y2, p2) => i(y2, y2.disabled ? "disabled" : p2 ? "active" : "inactive") }).join(`
3649
+ ${c2}`)}
3650
+ ${a}
3651
+ `;
3652
+ }
3653
+ }
3654
+ } }).prompt();
3655
+ };
3656
+ var je = `${t("gray", d2)} `;
3657
+ var Ot = (e) => new at({ validate: e.validate, placeholder: e.placeholder, defaultValue: e.defaultValue, initialValue: e.initialValue, output: e.output, signal: e.signal, input: e.input, render() {
3658
+ const i = e?.withGuide ?? u.withGuide, s = `${`${i ? `${t("gray", d2)}
3659
+ ` : ""}${V2(this.state)} `}${e.message}
3660
+ `, r = e.placeholder ? t("inverse", e.placeholder[0]) + t("dim", e.placeholder.slice(1)) : t(["inverse", "hidden"], "_"), u2 = this.userInput ? this.userInputWithCursor : r, n = this.value ?? "";
3661
+ switch (this.state) {
3662
+ case "error": {
3663
+ const o = this.error ? ` ${t("yellow", this.error)}` : "", c2 = i ? `${t("yellow", d2)} ` : "", a = i ? t("yellow", E2) : "";
3664
+ return `${s.trim()}
3665
+ ${c2}${u2}
3666
+ ${a}${o}
3667
+ `;
3668
+ }
3669
+ case "submit": {
3670
+ const o = n ? ` ${t("dim", n)}` : "", c2 = i ? t("gray", d2) : "";
3671
+ return `${s}${c2}${o}`;
3672
+ }
3673
+ case "cancel": {
3674
+ const o = n ? ` ${t(["strikethrough", "dim"], n)}` : "", c2 = i ? t("gray", d2) : "";
3675
+ return `${s}${c2}${o}${n.trim() ? `
3676
+ ${c2}` : ""}`;
3677
+ }
3678
+ default: {
3679
+ const o = i ? `${t("cyan", d2)} ` : "", c2 = i ? t("cyan", E2) : "";
3680
+ return `${s}${o}${u2}
3681
+ ${c2}
3682
+ `;
3683
+ }
3684
+ }
3685
+ } }).prompt();
3686
+
3687
+ // src/presentation/cli/index.ts
3688
+ var import_picocolors2 = __toESM(require_picocolors(), 1);
3689
+
2145
3690
  // src/presentation/cli/features/init/commands/init.ts
2146
3691
  import { homedir as homedir2 } from "node:os";
2147
3692
  import { resolve as resolve2 } from "node:path";
@@ -2543,54 +4088,214 @@ function validateUserPath(path, optionName) {
2543
4088
  } else {
2544
4089
  isInHome = normalizedPath.startsWith(normalizedHome);
2545
4090
  }
2546
- if (!isInHome) {
2547
- console.warn(`Warning: ${optionName} is an absolute path outside the home directory. Ensure this is intentional.`);
4091
+ if (!isInHome) {
4092
+ console.warn(`Warning: ${optionName} is an absolute path outside the home directory. Ensure this is intentional.`);
4093
+ }
4094
+ }
4095
+ return;
4096
+ }
4097
+
4098
+ // src/presentation/cli/shared/utils/LogService.ts
4099
+ var import_picocolors = __toESM(require_picocolors(), 1);
4100
+
4101
+ class LogService {
4102
+ static intro(message) {
4103
+ O2.message(import_picocolors.default.cyan(message));
4104
+ }
4105
+ static outro(message) {
4106
+ gt(message);
4107
+ }
4108
+ static log(message) {
4109
+ O2.message(message);
4110
+ }
4111
+ static unstyled(message) {
4112
+ process.stdout.write(message + `
4113
+ `);
4114
+ }
4115
+ static step(message) {
4116
+ O2.step(message);
4117
+ }
4118
+ static success(message) {
4119
+ O2.success(message);
4120
+ }
4121
+ static warn(message) {
4122
+ O2.warn(message);
4123
+ }
4124
+ static error(message) {
4125
+ O2.error(message);
4126
+ }
4127
+ static info(message) {
4128
+ O2.info(message);
4129
+ }
4130
+ static note(message, title) {
4131
+ const lines = message.split(`
4132
+ `);
4133
+ const resetMessage = lines.map((line) => import_picocolors.default.reset(line)).join(`
4134
+ `);
4135
+ wt(resetMessage, title);
4136
+ }
4137
+ static section(message) {
4138
+ O2.info(`
4139
+ ${message}`);
4140
+ }
4141
+ static items(label, values) {
4142
+ O2.info(label);
4143
+ for (const v of values) {
4144
+ O2.info(` ${v}`);
4145
+ }
4146
+ }
4147
+ }
4148
+
4149
+ // src/presentation/cli/shared/utils/PromptService.ts
4150
+ class PromptService {
4151
+ static activeSpinner = null;
4152
+ static activeProgress = null;
4153
+ static intro(message) {
4154
+ mt(message);
4155
+ }
4156
+ static outro(message) {
4157
+ gt(message);
4158
+ }
4159
+ static cancel(message) {
4160
+ this.stopTask();
4161
+ this.stopProgress();
4162
+ pt(message ?? "Operation cancelled.");
4163
+ }
4164
+ static isCancelled(value) {
4165
+ return q(value);
4166
+ }
4167
+ static startTask(message) {
4168
+ this.activeSpinner = fe();
4169
+ this.activeSpinner.start(message);
4170
+ }
4171
+ static stopTask(message) {
4172
+ if (this.activeSpinner) {
4173
+ this.activeSpinner.stop(message ?? "Done");
4174
+ this.activeSpinner = null;
4175
+ } else {
4176
+ LogService.warn("PromptService.stopTask called without active spinner");
4177
+ }
4178
+ }
4179
+ static startProgress(message) {
4180
+ this.activeProgress = Tt();
4181
+ this.activeProgress.start(message);
4182
+ }
4183
+ static advanceProgress(by, message) {
4184
+ if (this.activeProgress) {
4185
+ this.activeProgress.advance(by, message);
4186
+ }
4187
+ }
4188
+ static stopProgress(message) {
4189
+ if (this.activeProgress) {
4190
+ this.activeProgress.stop(message ?? "Complete");
4191
+ this.activeProgress = null;
4192
+ }
4193
+ }
4194
+ static async input(options) {
4195
+ const result = await Ot({
4196
+ message: options.message,
4197
+ defaultValue: options.default
4198
+ });
4199
+ return result;
4200
+ }
4201
+ static async confirm(options) {
4202
+ const result = await ot2({
4203
+ message: options.message,
4204
+ initialValue: options.initial
4205
+ });
4206
+ return result;
4207
+ }
4208
+ static async choose(options) {
4209
+ const result = await _t({
4210
+ message: options.message,
4211
+ options: options.options.map((o) => ({ value: o.value, label: o.label, hint: o.hint })),
4212
+ initialValue: options.initial
4213
+ });
4214
+ return result;
4215
+ }
4216
+ static async selectMany(options) {
4217
+ if (options.options.length === 0) {
4218
+ throw new Error("selectMany requires at least one option");
4219
+ }
4220
+ const result = await yt({
4221
+ message: options.message,
4222
+ options: options.options.map((o) => ({ value: o.value, label: o.label, hint: o.hint })),
4223
+ required: options.required
4224
+ });
4225
+ return result;
4226
+ }
4227
+ static handleCancellation(message) {
4228
+ this.cancel(message);
4229
+ process.exit(0);
4230
+ }
4231
+ static async withCancellation(handler, onCancel) {
4232
+ try {
4233
+ return await handler();
4234
+ } catch (error) {
4235
+ if (q(error)) {
4236
+ if (onCancel)
4237
+ onCancel();
4238
+ else
4239
+ this.handleCancellation();
4240
+ return null;
4241
+ }
4242
+ throw error;
2548
4243
  }
2549
4244
  }
2550
- return;
2551
4245
  }
2552
4246
 
2553
4247
  // src/presentation/cli/features/init/commands/init.ts
2554
4248
  function createInitCommand() {
2555
- const command = new Command("init").description("Initialize the agent-ctrl global configuration structure").argument("[path]", "Target configuration root path (default: ~/.agent-ctrl)").option("-o, --override", "Initialize even when the target directory already contains files", false).action(async (targetPath, options) => {
4249
+ const command = new Command("init").description("Initialize the agent-ctrl global configuration structure").argument("[path]", "Target configuration root path (default: ~/.agent-ctrl)").option("-o, --override", "Initialize even when the target directory already contains files", false).option("-d, --dry-run", "Preview what would be created without creating it", false).action(async (targetPath, options) => {
4250
+ LogService.intro("Initializing agent-ctrl");
2556
4251
  if (targetPath) {
2557
4252
  const pathError = validateUserPath(targetPath, "[path]");
2558
4253
  if (pathError) {
2559
- console.error(`✗ ${pathError}`);
4254
+ PromptService.cancel(pathError);
2560
4255
  process.exit(1);
2561
4256
  }
2562
4257
  }
2563
4258
  const initCommand = new InitCommand(new NodeFileSystem);
2564
4259
  const resolvedTargetPath = targetPath ? resolve2(targetPath) : resolve2(homedir2(), ".agent-ctrl");
2565
4260
  try {
4261
+ if (options.dryRun) {
4262
+ LogService.log(`Would create at: ${resolvedTargetPath}`);
4263
+ LogService.log("Directories: rules/, skills/, agents/, commands/, mcps/");
4264
+ LogService.log("Files: rules/.gitkeep, skills/.gitkeep, agents/.gitkeep, commands/.gitkeep, mcps/.gitkeep, README.md");
4265
+ LogService.outro("No changes made");
4266
+ return;
4267
+ }
4268
+ PromptService.startTask("Creating configuration structure");
2566
4269
  const result = await initCommand.execute({
2567
4270
  targetPath: resolvedTargetPath,
2568
4271
  override: options.override
2569
4272
  });
2570
4273
  if (result.success) {
4274
+ PromptService.stopTask("Configuration created");
2571
4275
  for (const dir of result.data.createdDirectories) {
2572
- console.log(`✓ Created ${dir}/`);
4276
+ LogService.log(`Created ${dir}/`);
2573
4277
  }
2574
4278
  for (const file of result.data.createdFiles) {
2575
- console.log(`✓ Created ${file}`);
2576
- }
2577
- console.log(`
2578
- Configuration root: ${resolvedTargetPath}`);
2579
- console.log("Configuration initialized.");
2580
- console.log("Next steps:");
2581
- console.log(" 1. Add your files in the related folders: rules, skills, agents, commands and mcps.");
2582
- console.log(" - You can add from remote registries:");
2583
- console.log(" agent-ctrl skill add skillsmp:code-review");
2584
- console.log(" agent-ctrl mcp add smithery:github");
2585
- console.log(" (Add credentials to .agent-ctrl/.env if you plan to use SkillsMP or Smithery.)");
2586
- console.log(" 2. Inspect your configuration:");
2587
- console.log(" agent-ctrl rule ls");
2588
- console.log(" agent-ctrl skill ls");
2589
- console.log(" agent-ctrl agent ls");
2590
- console.log(" agent-ctrl command ls");
2591
- console.log(" agent-ctrl mcp ls");
2592
- console.log(" 3. Apply the platforms:");
2593
- console.log(" agent-ctrl apply claude");
4279
+ LogService.log(`Created ${file}`);
4280
+ }
4281
+ LogService.log("");
4282
+ LogService.log(`Configuration root: ${resolvedTargetPath}`);
4283
+ LogService.log("");
4284
+ LogService.log("Next steps:");
4285
+ LogService.log("1. Add your files in the related folders: rules, skills, agents, commands and mcps.");
4286
+ LogService.log(" - You can add from remote registries:");
4287
+ LogService.log(" agent-ctrl skill add skillsmp:code-review");
4288
+ LogService.log(" agent-ctrl mcp add smithery:github");
4289
+ LogService.log(" (Add credentials to .agent-ctrl/.env if you plan to use SkillsMP or Smithery.)");
4290
+ LogService.log("2. Inspect your configuration:");
4291
+ LogService.log(" agent-ctrl rule ls");
4292
+ LogService.log(" agent-ctrl skill ls");
4293
+ LogService.log(" agent-ctrl agent ls");
4294
+ LogService.log(" agent-ctrl command ls");
4295
+ LogService.log(" agent-ctrl mcp ls");
4296
+ LogService.log("3. Apply the platforms:");
4297
+ LogService.log(" agent-ctrl apply claude");
4298
+ LogService.outro("Configuration initialized!");
2594
4299
  } else {
2595
4300
  handleInitError(result.error);
2596
4301
  }
@@ -2601,17 +4306,18 @@ Configuration root: ${resolvedTargetPath}`);
2601
4306
  return command;
2602
4307
  }
2603
4308
  function handleInitError(error) {
4309
+ PromptService.stopTask();
2604
4310
  if (error instanceof UserError) {
2605
- console.error(`✗ ${error.message}`);
4311
+ LogService.error(error.message);
2606
4312
  process.exit(error.exitCode);
2607
4313
  } else if (error instanceof SystemError) {
2608
- console.error(`✗ ${error.message}`);
4314
+ LogService.error(error.message);
2609
4315
  process.exit(error.exitCode);
2610
4316
  } else if (error instanceof Error) {
2611
- console.error(`✗ Unexpected error: ${error.message}`);
4317
+ LogService.error(`Unexpected error: ${error.message}`);
2612
4318
  process.exit(2);
2613
4319
  } else {
2614
- console.error("Unknown error occurred");
4320
+ LogService.error("Unknown error occurred");
2615
4321
  process.exit(2);
2616
4322
  }
2617
4323
  }
@@ -2759,7 +4465,7 @@ function createRuleListCommand() {
2759
4465
  if (targetPath) {
2760
4466
  const pathError = validateUserPath(targetPath, "--path");
2761
4467
  if (pathError) {
2762
- console.error(`✗ ${pathError}`);
4468
+ LogService.error(pathError);
2763
4469
  process.exit(1);
2764
4470
  }
2765
4471
  }
@@ -2767,7 +4473,7 @@ function createRuleListCommand() {
2767
4473
  const rulesPath = resolve4(configRootPath, "rules");
2768
4474
  const accessResult = await handleDirectoryAccess(rulesPath, "rules/");
2769
4475
  if (!accessResult.success) {
2770
- console.error(`✗ ${accessResult.error}`);
4476
+ LogService.error(accessResult.error ?? "Directory access failed");
2771
4477
  process.exit(1);
2772
4478
  }
2773
4479
  const listRulesQuery = new ListRulesQuery;
@@ -2778,23 +4484,20 @@ function createRuleListCommand() {
2778
4484
  }
2779
4485
  const { artifacts, warnings } = result.data;
2780
4486
  if (options.json) {
2781
- console.log(JSON.stringify({ artifacts, warnings }, null, 2));
4487
+ LogService.unstyled(JSON.stringify({ artifacts, warnings }, null, 2));
2782
4488
  return;
2783
4489
  }
4490
+ LogService.intro("Listing rules");
2784
4491
  if (artifacts.length === 0) {
2785
- console.log("No rules found in rules/ directory");
4492
+ LogService.info("No rules found in rules/ directory");
2786
4493
  } else {
2787
- console.log(`Rules (${artifacts.length}):`);
2788
- for (const artifact of artifacts) {
2789
- console.log(` ${artifact.id}`);
2790
- }
4494
+ const list = artifacts.map((a) => a.id).join(`
4495
+ `);
4496
+ LogService.note(list, `Rules (${artifacts.length}):`);
2791
4497
  }
2792
4498
  if (warnings.length > 0 && !options.json) {
2793
- console.log(`
2794
- Warnings:`);
2795
- for (const warning of warnings) {
2796
- console.log(` - ${warning}`);
2797
- }
4499
+ LogService.note(warnings.join(`
4500
+ `), "Warnings:");
2798
4501
  }
2799
4502
  });
2800
4503
  }
@@ -2984,7 +4687,7 @@ function createSkillListCommand() {
2984
4687
  if (targetPath) {
2985
4688
  const pathError = validateUserPath(targetPath, "--path");
2986
4689
  if (pathError) {
2987
- console.error(`✗ ${pathError}`);
4690
+ LogService.error(pathError);
2988
4691
  process.exit(1);
2989
4692
  }
2990
4693
  }
@@ -2992,7 +4695,7 @@ function createSkillListCommand() {
2992
4695
  const skillsPath = resolve7(configRootPath, "skills");
2993
4696
  const accessResult = await handleDirectoryAccess(skillsPath, "skills/");
2994
4697
  if (!accessResult.success) {
2995
- console.error(`✗ ${accessResult.error}`);
4698
+ LogService.error(accessResult.error ?? "Directory access failed");
2996
4699
  process.exit(1);
2997
4700
  }
2998
4701
  const listSkillsQuery = new ListSkillsQuery;
@@ -3004,7 +4707,7 @@ function createSkillListCommand() {
3004
4707
  const { artifacts, warnings, catalogState } = result.data;
3005
4708
  const { managedById, catalogById } = catalogState;
3006
4709
  if (options.json) {
3007
- console.log(JSON.stringify({
4710
+ LogService.unstyled(JSON.stringify({
3008
4711
  artifacts,
3009
4712
  warnings,
3010
4713
  managed: artifacts.map((artifact) => ({
@@ -3015,11 +4718,11 @@ function createSkillListCommand() {
3015
4718
  }, null, 2));
3016
4719
  return;
3017
4720
  }
4721
+ LogService.intro("Listing skills");
3018
4722
  if (artifacts.length === 0) {
3019
- console.log("No skills found in skills/ directory");
4723
+ LogService.info("No skills found in skills/ directory");
3020
4724
  } else {
3021
- console.log(`Skills (${artifacts.length}):`);
3022
- for (const artifact of artifacts) {
4725
+ const list = artifacts.map((artifact) => {
3023
4726
  const managed = managedById.get(artifact.id);
3024
4727
  const catalog = catalogById.get(artifact.id);
3025
4728
  const details = [
@@ -3027,15 +4730,14 @@ function createSkillListCommand() {
3027
4730
  catalog?.compatibilityState,
3028
4731
  catalog?.sourceVersion ? `v${catalog.sourceVersion}` : undefined
3029
4732
  ].filter(Boolean).join(" | ");
3030
- console.log(` ${artifact.id}${details ? ` (${details})` : ""}`);
3031
- }
4733
+ return ` ${artifact.id}${details ? ` (${details})` : ""}`;
4734
+ }).join(`
4735
+ `);
4736
+ LogService.note(list, `Skills (${artifacts.length}):`);
3032
4737
  }
3033
4738
  if (warnings.length > 0 && !options.json) {
3034
- console.log(`
3035
- Warnings:`);
3036
- for (const warning of warnings) {
3037
- console.log(` - ${warning}`);
3038
- }
4739
+ LogService.note(warnings.join(`
4740
+ `), "Warnings:");
3039
4741
  }
3040
4742
  });
3041
4743
  }
@@ -4442,7 +6144,8 @@ function resolveConfigRoot(targetPath) {
4442
6144
 
4443
6145
  // src/presentation/cli/features/skill/commands/skill_search.ts
4444
6146
  function createSkillSearchCommand() {
4445
- return new Command("search").description("Search synchronized SkillsMP catalog entries").argument("<query>", "Search query").option("-j, --json", "Output as JSON").option("--capability <value>", "Filter by capability").option("--status <value>", "Filter by activation, compatibility, or availability status").option("--refresh", "Refresh source data before searching").option("--ai", "Use AI search when supported by the source").option("--api-key <value>", "Override the SkillsMP API key for this command").option("--path <value>", "Configuration root path").action(async (query, options) => {
6147
+ return new Command("search").description("Search synchronized SkillsMP catalog entries").argument("<query>", "Search query").option("-j, --json", "Output as JSON").option("--capability <value>", "Filter by capability").option("--status <value>", "Filter by activation, compatibility, or availability status").option("--refresh", "Refresh source data before searching").option("--ai", "Use AI search when supported by the source").option("--api-key <value>", "Override the SkillsMP API key for this command").option("--path <value>", "Configuration root path").option("--no-prompt", "Disable interactive selection", false).action(async (query, options) => {
6148
+ PromptService.startTask("Searching catalog");
4446
6149
  const command = new SearchSkillsQuery;
4447
6150
  const result = await command.execute({
4448
6151
  configRoot: resolveConfigRoot(options.path),
@@ -4453,18 +6156,47 @@ function createSkillSearchCommand() {
4453
6156
  ai: Boolean(options.ai),
4454
6157
  apiKey: options.apiKey
4455
6158
  });
4456
- handleQueryResult(result);
4457
6159
  if (!result.success) {
6160
+ PromptService.stopTask();
6161
+ handleQueryResult(result);
4458
6162
  return;
4459
6163
  }
6164
+ PromptService.stopTask("Search complete");
4460
6165
  const { items, registry, report } = result.data;
4461
6166
  if (options.json) {
4462
- console.log(JSON.stringify({ items, registry, report }, null, 2));
6167
+ LogService.unstyled(JSON.stringify({ items, registry, report }, null, 2));
6168
+ return;
6169
+ }
6170
+ const interactive = options["prompt"] !== false;
6171
+ if (!interactive) {
6172
+ for (const line of renderCatalogSearchResults(items)) {
6173
+ LogService.log(line);
6174
+ }
4463
6175
  return;
4464
6176
  }
6177
+ LogService.intro("Select skills to activate");
4465
6178
  for (const line of renderCatalogSearchResults(items)) {
4466
- console.log(line);
6179
+ LogService.log(line);
6180
+ }
6181
+ if (items.length === 0) {
6182
+ LogService.outro("No results");
6183
+ return;
4467
6184
  }
6185
+ const selected = await PromptService.selectMany({
6186
+ message: "Select skills to activate",
6187
+ options: items.map((item) => ({
6188
+ value: item.sourceItemId,
6189
+ label: item.displayName
6190
+ })),
6191
+ required: false
6192
+ });
6193
+ if (PromptService.isCancelled(selected)) {
6194
+ PromptService.cancel();
6195
+ process.exit(0);
6196
+ }
6197
+ LogService.log(`
6198
+ Selected: ${selected.join(", ")}`);
6199
+ LogService.outro(`${selected.length} skill(s) selected`);
4468
6200
  });
4469
6201
  }
4470
6202
 
@@ -4489,8 +6221,16 @@ class SyncSkillsCommand {
4489
6221
 
4490
6222
  // src/presentation/cli/features/skill/commands/skill_sync.ts
4491
6223
  function createSkillSyncCommand() {
4492
- return new Command("sync").description("Refresh tracked SkillsMP discovery scopes").option("-j, --json", "Output as JSON").option("--query <value>", "Refresh or seed a query-based discovery scope").option("--category <value>", "Refresh or seed a category-based discovery scope").option("--ai", "Use AI search when supported by the source").option("--refresh", "Force a refresh even if cache is still fresh").option("--api-key <value>", "Override the SkillsMP API key for this command").option("--path <value>", "Configuration root path").action(async (options) => {
6224
+ return new Command("sync").description("Refresh tracked SkillsMP discovery scopes").option("-j, --json", "Output as JSON").option("--query <value>", "Refresh or seed a query-based discovery scope").option("--category <value>", "Refresh or seed a category-based discovery scope").option("--ai", "Use AI search when supported by the source").option("--refresh", "Force a refresh even if cache is still fresh").option("--api-key <value>", "Override the SkillsMP API key for this command").option("--path <value>", "Configuration root path").option("-d, --dry-run", "Preview what would be synced without syncing", false).action(async (options) => {
4493
6225
  const command = new SyncSkillsCommand;
6226
+ if (options.dryRun) {
6227
+ LogService.intro("Syncing skills");
6228
+ LogService.log("Would sync skills from SkillsMP catalog");
6229
+ LogService.log("Note: Use without --dry-run to sync");
6230
+ return;
6231
+ }
6232
+ LogService.intro("Syncing skills");
6233
+ PromptService.startTask("Syncing skills");
4494
6234
  const result = await command.execute({
4495
6235
  configRoot: resolveConfigRoot(options.path),
4496
6236
  query: options.query,
@@ -4499,19 +6239,20 @@ function createSkillSyncCommand() {
4499
6239
  force: Boolean(options.refresh),
4500
6240
  apiKey: options.apiKey
4501
6241
  });
6242
+ PromptService.stopTask("Sync complete");
4502
6243
  handleQueryResult(result);
4503
6244
  if (!result.success) {
4504
6245
  return;
4505
6246
  }
4506
6247
  if (options.json) {
4507
- console.log(JSON.stringify(result.data, null, 2));
6248
+ LogService.unstyled(JSON.stringify(result.data, null, 2));
4508
6249
  return;
4509
6250
  }
4510
6251
  for (const line of renderSyncReport(result.data.report)) {
4511
- console.log(line);
6252
+ LogService.log(line);
4512
6253
  }
4513
6254
  for (const line of renderCatalogItems(result.data.items)) {
4514
- console.log(line);
6255
+ LogService.log(line);
4515
6256
  }
4516
6257
  });
4517
6258
  }
@@ -4732,8 +6473,16 @@ class AddSkillCommand {
4732
6473
 
4733
6474
  // src/presentation/cli/features/skill/commands/skill_add.ts
4734
6475
  function createSkillAddCommand() {
4735
- return new Command("add").description("Activate a skill from the synchronized catalog").argument("<ref>", "Skill reference such as skillsmp:code-review").option("-j, --json", "Output as JSON").option("--refresh", "Refresh source data before activation").option("--version <value>", "Request a specific version when supported").option("--api-key <value>", "Override the SkillsMP API key for this command").option("--path <value>", "Configuration root path").action(async (ref, options) => {
6476
+ return new Command("add").description("Activate a skill from the synchronized catalog").argument("<ref>", "Skill reference such as skillsmp:code-review").option("-j, --json", "Output as JSON").option("--refresh", "Refresh source data before activation").option("--version <value>", "Request a specific version when supported").option("--api-key <value>", "Override the SkillsMP API key for this command").option("--path <value>", "Configuration root path").option("-d, --dry-run", "Preview what would be activated without activating", false).action(async (ref, options) => {
4736
6477
  const command = new AddSkillCommand;
6478
+ if (options.dryRun) {
6479
+ LogService.intro("Activating skill");
6480
+ LogService.log(`Would activate skill: ${ref}`);
6481
+ LogService.log("Note: Use without --dry-run to activate");
6482
+ return;
6483
+ }
6484
+ LogService.intro("Activating skill");
6485
+ PromptService.startTask(`Activating skill ${ref}`);
4737
6486
  const result = await command.execute({
4738
6487
  configRoot: resolveConfigRoot(options.path),
4739
6488
  ref,
@@ -4741,15 +6490,18 @@ function createSkillAddCommand() {
4741
6490
  version: options.version,
4742
6491
  apiKey: options.apiKey
4743
6492
  });
4744
- handleQueryResult(result);
4745
6493
  if (!result.success) {
6494
+ PromptService.stopTask();
6495
+ handleQueryResult(result);
4746
6496
  return;
4747
6497
  }
6498
+ PromptService.stopTask("Skill activated");
4748
6499
  if (options.json) {
4749
- console.log(JSON.stringify(result.data, null, 2));
6500
+ LogService.unstyled(JSON.stringify(result.data, null, 2));
4750
6501
  return;
4751
6502
  }
4752
- console.log(`Activated skill ${result.data.item.displayName} at ${result.data.managedIntegration.localPath}`);
6503
+ LogService.success(`Skill ${result.data.item.displayName} activated at ${result.data.managedIntegration.localPath}`);
6504
+ LogService.outro(`Activated ${result.data.item.displayName}`);
4753
6505
  });
4754
6506
  }
4755
6507
 
@@ -4815,6 +6567,7 @@ class RemoveSkillCommand {
4815
6567
  // src/presentation/cli/features/skill/commands/skill_rm.ts
4816
6568
  function createSkillRemoveCommand() {
4817
6569
  return new Command("rm").description("Deactivate a managed skill").argument("<ref>", "Managed skill identifier").option("-j, --json", "Output as JSON").option("--path <value>", "Configuration root path").action(async (ref, options) => {
6570
+ LogService.intro("Deactivating skill");
4818
6571
  const command = new RemoveSkillCommand;
4819
6572
  const result = await command.execute({
4820
6573
  configRoot: resolveConfigRoot(options.path),
@@ -4825,10 +6578,10 @@ function createSkillRemoveCommand() {
4825
6578
  return;
4826
6579
  }
4827
6580
  if (options.json) {
4828
- console.log(JSON.stringify(result.data, null, 2));
4829
- return;
6581
+ LogService.unstyled(JSON.stringify(result.data, null, 2));
6582
+ } else {
6583
+ LogService.success(`Deactivated skill ${result.data.managedIntegration.managedId}`);
4830
6584
  }
4831
- console.log(`Deactivated skill ${result.data.managedIntegration.managedId}`);
4832
6585
  });
4833
6586
  }
4834
6587
 
@@ -4998,6 +6751,7 @@ class UpdateSkillCommand {
4998
6751
  // src/presentation/cli/features/skill/commands/skill_update.ts
4999
6752
  function createSkillUpdateCommand() {
5000
6753
  return new Command("update").description("Update one or more managed skills").argument("[ref]", "Managed skill identifier").option("--all", "Update all managed skills").option("--refresh", "Refresh source data before updating").option("-j, --json", "Output as JSON").option("--api-key <value>", "Override the SkillsMP API key for this command").option("--path <value>", "Configuration root path").action(async (ref, options) => {
6754
+ LogService.intro("Updating skills");
5001
6755
  const command = new UpdateSkillCommand;
5002
6756
  const result = await command.execute({
5003
6757
  configRoot: resolveConfigRoot(options.path),
@@ -5011,12 +6765,13 @@ function createSkillUpdateCommand() {
5011
6765
  return;
5012
6766
  }
5013
6767
  if (options.json) {
5014
- console.log(JSON.stringify(result.data, null, 2));
5015
- return;
5016
- }
5017
- for (const line of renderLifecycleSummary(result.data)) {
5018
- console.log(line);
6768
+ LogService.unstyled(JSON.stringify(result.data, null, 2));
6769
+ } else {
6770
+ for (const line of renderLifecycleSummary(result.data)) {
6771
+ LogService.log(line);
6772
+ }
5019
6773
  }
6774
+ LogService.outro("Update complete");
5020
6775
  });
5021
6776
  }
5022
6777
 
@@ -5090,7 +6845,7 @@ function createAgentListCommand() {
5090
6845
  if (targetPath) {
5091
6846
  const pathError = validateUserPath(targetPath, "--path");
5092
6847
  if (pathError) {
5093
- console.error(`✗ ${pathError}`);
6848
+ LogService.error(pathError);
5094
6849
  process.exit(1);
5095
6850
  }
5096
6851
  }
@@ -5098,7 +6853,7 @@ function createAgentListCommand() {
5098
6853
  const agentsPath = resolve12(configRootPath, "agents");
5099
6854
  const accessResult = await handleDirectoryAccess(agentsPath, "agents/");
5100
6855
  if (!accessResult.success) {
5101
- console.error(`✗ ${accessResult.error}`);
6856
+ LogService.error(accessResult.error ?? "Directory access failed");
5102
6857
  process.exit(1);
5103
6858
  }
5104
6859
  const listAgentsQuery = new ListAgentsQuery(new AgentScanner);
@@ -5109,23 +6864,20 @@ function createAgentListCommand() {
5109
6864
  }
5110
6865
  const { artifacts, warnings } = result.data;
5111
6866
  if (options.json) {
5112
- console.log(JSON.stringify({ artifacts, warnings }, null, 2));
6867
+ LogService.unstyled(JSON.stringify({ artifacts, warnings }, null, 2));
5113
6868
  return;
5114
6869
  }
6870
+ LogService.intro("Listing agents");
5115
6871
  if (artifacts.length === 0) {
5116
- console.log("No agents found in agents/ directory");
6872
+ LogService.info("No agents found in agents/ directory");
5117
6873
  } else {
5118
- console.log(`Agents (${artifacts.length}):`);
5119
- for (const artifact of artifacts) {
5120
- console.log(` ${artifact.id}`);
5121
- }
6874
+ const list = artifacts.map((a) => a.id).join(`
6875
+ `);
6876
+ LogService.note(list, `Agents (${artifacts.length}):`);
5122
6877
  }
5123
6878
  if (warnings.length > 0 && !options.json) {
5124
- console.log(`
5125
- Warnings:`);
5126
- for (const warning of warnings) {
5127
- console.log(` - ${warning}`);
5128
- }
6879
+ LogService.note(warnings.join(`
6880
+ `), "Warnings:");
5129
6881
  }
5130
6882
  });
5131
6883
  }
@@ -5257,7 +7009,7 @@ function createCommandListCommand() {
5257
7009
  if (targetPath) {
5258
7010
  const pathError = validateUserPath(targetPath, "--path");
5259
7011
  if (pathError) {
5260
- console.error(`✗ ${pathError}`);
7012
+ LogService.error(pathError);
5261
7013
  process.exit(1);
5262
7014
  }
5263
7015
  }
@@ -5265,7 +7017,7 @@ function createCommandListCommand() {
5265
7017
  const commandsPath = resolve14(configRootPath, "commands");
5266
7018
  const accessResult = await handleDirectoryAccess(commandsPath, "commands/");
5267
7019
  if (!accessResult.success) {
5268
- console.error(`✗ ${accessResult.error}`);
7020
+ LogService.error(accessResult.error ?? "Directory access failed");
5269
7021
  process.exit(1);
5270
7022
  }
5271
7023
  const listCommandsQuery = new ListCommandsQuery;
@@ -5276,23 +7028,20 @@ function createCommandListCommand() {
5276
7028
  }
5277
7029
  const { artifacts, warnings } = result.data;
5278
7030
  if (options.json) {
5279
- console.log(JSON.stringify({ artifacts, warnings }, null, 2));
7031
+ LogService.unstyled(JSON.stringify({ artifacts, warnings }, null, 2));
5280
7032
  return;
5281
7033
  }
7034
+ LogService.intro("Listing commands");
5282
7035
  if (artifacts.length === 0) {
5283
- console.log("No commands found in commands/ directory");
7036
+ LogService.info("No commands found in commands/ directory");
5284
7037
  } else {
5285
- console.log(`Commands (${artifacts.length}):`);
5286
- for (const artifact of artifacts) {
5287
- console.log(` ${artifact.id}`);
5288
- }
7038
+ const list = artifacts.map((a) => a.id).join(`
7039
+ `);
7040
+ LogService.note(list, `Commands (${artifacts.length}):`);
5289
7041
  }
5290
7042
  if (warnings.length > 0) {
5291
- console.log(`
5292
- Warnings:`);
5293
- for (const warning of warnings) {
5294
- console.log(` - ${warning}`);
5295
- }
7043
+ LogService.note(warnings.join(`
7044
+ `), "Warnings:");
5296
7045
  }
5297
7046
  });
5298
7047
  }
@@ -5436,7 +7185,7 @@ class McpServerEnvComposer {
5436
7185
  checkForRefs(command);
5437
7186
  args?.forEach(checkForRefs);
5438
7187
  if (serverEnv) {
5439
- Object.keys(serverEnv).forEach((k) => neededVars.add(k));
7188
+ Object.keys(serverEnv).forEach((k2) => neededVars.add(k2));
5440
7189
  }
5441
7190
  const result = {};
5442
7191
  for (const key of neededVars) {
@@ -6054,7 +7803,7 @@ function createMcpListCommand() {
6054
7803
  if (targetPath) {
6055
7804
  const pathError = validateUserPath(targetPath, "--path");
6056
7805
  if (pathError) {
6057
- console.error(`✗ ${pathError}`);
7806
+ LogService.error(pathError);
6058
7807
  process.exit(1);
6059
7808
  }
6060
7809
  }
@@ -6062,7 +7811,7 @@ function createMcpListCommand() {
6062
7811
  const mcpDir = resolve17(configRootPath, "mcps");
6063
7812
  const accessResult = await handleDirectoryAccess(mcpDir, "mcps/");
6064
7813
  if (!accessResult.success) {
6065
- console.error(`✗ ${accessResult.error}`);
7814
+ LogService.error(accessResult.error ?? "Directory access failed");
6066
7815
  process.exit(1);
6067
7816
  }
6068
7817
  const listMcpServersQuery = new ListMcpServersQuery;
@@ -6081,7 +7830,7 @@ function createMcpListCommand() {
6081
7830
  managed: managedById.get(server.serverId),
6082
7831
  catalog: catalogById.get(server.serverId)
6083
7832
  }));
6084
- console.log(JSON.stringify({
7833
+ LogService.unstyled(JSON.stringify({
6085
7834
  configRoot: configRootPath,
6086
7835
  mcpDir,
6087
7836
  servers: safeServers,
@@ -6089,11 +7838,11 @@ function createMcpListCommand() {
6089
7838
  }, null, 2));
6090
7839
  return;
6091
7840
  }
7841
+ LogService.intro("Listing MCP servers");
6092
7842
  if (servers.length === 0) {
6093
- console.log(`No MCP servers found in ${mcpDir}`);
7843
+ LogService.info(`No MCP servers found in ${mcpDir}`);
6094
7844
  } else {
6095
- console.log(`MCP servers (${servers.length}):`);
6096
- for (const server of servers) {
7845
+ const list = servers.map((server) => {
6097
7846
  const managed = managedById.get(server.serverId);
6098
7847
  const catalog = catalogById.get(server.serverId);
6099
7848
  const details = [
@@ -6101,16 +7850,17 @@ function createMcpListCommand() {
6101
7850
  catalog?.compatibilityState,
6102
7851
  catalog?.sourceVersion ? `v${catalog.sourceVersion}` : undefined
6103
7852
  ].filter(Boolean).join(" | ");
6104
- console.log(` ${server.serverId}${details ? ` (${details})` : ""}`);
6105
- }
7853
+ return ` ${server.serverId}${details ? ` (${details})` : ""}`;
7854
+ }).join(`
7855
+ `);
7856
+ LogService.note(list, `MCP servers (${servers.length}):`);
6106
7857
  }
6107
7858
  if (issues.length > 0) {
6108
- console.log(`
6109
- Issues:`);
6110
- for (const issue of issues) {
7859
+ LogService.note(issues.map((issue) => {
6111
7860
  const scope = issue.serverId ? `${issue.serverId}: ` : "";
6112
- console.log(` - [${issue.severity}] ${scope}${issue.message}`);
6113
- }
7861
+ return `[${issue.severity}] ${scope}${issue.message}`;
7862
+ }).join(`
7863
+ `), "Issues:");
6114
7864
  }
6115
7865
  });
6116
7866
  }
@@ -6574,7 +8324,8 @@ class SearchMcpCatalogQuery {
6574
8324
 
6575
8325
  // src/presentation/cli/features/mcp/commands/mcp_search.ts
6576
8326
  function createMcpSearchCommand() {
6577
- return new Command("search").description("Search synchronized Smithery MCP catalog entries").argument("<query>", "Search query").option("-j, --json", "Output as JSON").option("--capability <value>", "Filter by capability").option("--status <value>", "Filter by activation, compatibility, or availability status").option("--refresh", "Refresh source data before searching").option("--api-key <value>", "Override the Smithery API key for this command").option("--path <value>", "Configuration root path").action(async (query, options) => {
8327
+ return new Command("search").description("Search synchronized Smithery MCP catalog entries").argument("<query>", "Search query").option("-j, --json", "Output as JSON").option("--capability <value>", "Filter by capability").option("--status <value>", "Filter by activation, compatibility, or availability status").option("--refresh", "Refresh source data before searching").option("--api-key <value>", "Override the Smithery API key for this command").option("--path <value>", "Configuration root path").option("--no-prompt", "Disable interactive selection", false).action(async (query, options) => {
8328
+ PromptService.startTask("Searching MCP catalog");
6578
8329
  const command = new SearchMcpCatalogQuery;
6579
8330
  const result = await command.execute({
6580
8331
  configRoot: resolveConfigRoot(options.path),
@@ -6584,18 +8335,47 @@ function createMcpSearchCommand() {
6584
8335
  refresh: Boolean(options.refresh),
6585
8336
  apiKey: options.apiKey
6586
8337
  });
6587
- handleQueryResult(result);
6588
8338
  if (!result.success) {
8339
+ PromptService.stopTask();
8340
+ handleQueryResult(result);
6589
8341
  return;
6590
8342
  }
8343
+ PromptService.stopTask("Search complete");
6591
8344
  const { items, registry, report } = result.data;
6592
8345
  if (options.json) {
6593
- console.log(JSON.stringify({ items, registry, report }, null, 2));
8346
+ LogService.unstyled(JSON.stringify({ items, registry, report }, null, 2));
8347
+ return;
8348
+ }
8349
+ const interactive = options["prompt"] !== false;
8350
+ if (!interactive) {
8351
+ for (const line of renderCatalogSearchResults(items)) {
8352
+ LogService.log(line);
8353
+ }
6594
8354
  return;
6595
8355
  }
8356
+ LogService.intro("Select MCPs to activate");
6596
8357
  for (const line of renderCatalogSearchResults(items)) {
6597
- console.log(line);
8358
+ LogService.log(line);
8359
+ }
8360
+ if (items.length === 0) {
8361
+ LogService.outro("No results");
8362
+ return;
6598
8363
  }
8364
+ const selected = await PromptService.selectMany({
8365
+ message: "Select MCPs to activate",
8366
+ options: items.map((item) => ({
8367
+ value: item.sourceItemId,
8368
+ label: item.displayName
8369
+ })),
8370
+ required: false
8371
+ });
8372
+ if (PromptService.isCancelled(selected)) {
8373
+ PromptService.cancel();
8374
+ process.exit(0);
8375
+ }
8376
+ LogService.log(`
8377
+ Selected: ${selected.join(", ")}`);
8378
+ LogService.outro(`${selected.length} MCP(s) selected`);
6599
8379
  });
6600
8380
  }
6601
8381
 
@@ -6620,7 +8400,14 @@ class SyncMcpCatalogCommand {
6620
8400
 
6621
8401
  // src/presentation/cli/features/mcp/commands/mcp_sync.ts
6622
8402
  function createMcpSyncCommand() {
6623
- return new Command("sync").description("Refresh the synchronized Smithery catalog").option("-j, --json", "Output as JSON").option("--query <value>", "Refresh with a scoped query").option("--refresh", "Force a refresh even if cache is still fresh").option("--api-key <value>", "Override the Smithery API key for this command").option("--path <value>", "Configuration root path").action(async (options) => {
8403
+ return new Command("sync").description("Refresh the synchronized Smithery catalog").option("-j, --json", "Output as JSON").option("--query <value>", "Refresh with a scoped query").option("--refresh", "Force a refresh even if cache is still fresh").option("--api-key <value>", "Override the Smithery API key for this command").option("--path <value>", "Configuration root path").option("-d, --dry-run", "Preview what would be synced without syncing", false).action(async (options) => {
8404
+ if (options.dryRun) {
8405
+ LogService.intro("Syncing MCPs");
8406
+ LogService.log("Would sync MCPs from Smithery catalog");
8407
+ LogService.log("Note: Use without --dry-run to sync");
8408
+ return;
8409
+ }
8410
+ PromptService.startTask("Syncing MCPs");
6624
8411
  const command = new SyncMcpCatalogCommand;
6625
8412
  const result = await command.execute({
6626
8413
  configRoot: resolveConfigRoot(options.path),
@@ -6628,19 +8415,20 @@ function createMcpSyncCommand() {
6628
8415
  force: Boolean(options.refresh),
6629
8416
  apiKey: options.apiKey
6630
8417
  });
8418
+ PromptService.stopTask("Sync complete");
6631
8419
  handleQueryResult(result);
6632
8420
  if (!result.success) {
6633
8421
  return;
6634
8422
  }
6635
8423
  if (options.json) {
6636
- console.log(JSON.stringify(result.data, null, 2));
8424
+ LogService.unstyled(JSON.stringify(result.data, null, 2));
6637
8425
  return;
6638
8426
  }
6639
8427
  for (const line of renderSyncReport(result.data.report)) {
6640
- console.log(line);
8428
+ LogService.log(line);
6641
8429
  }
6642
8430
  for (const line of renderCatalogItems(result.data.items)) {
6643
- console.log(line);
8431
+ LogService.log(line);
6644
8432
  }
6645
8433
  });
6646
8434
  }
@@ -6827,7 +8615,15 @@ class AddMcpCommand {
6827
8615
 
6828
8616
  // src/presentation/cli/features/mcp/commands/mcp_add.ts
6829
8617
  function createMcpAddCommand() {
6830
- return new Command("add").description("Activate an MCP from the synchronized catalog").argument("<ref>", "MCP reference such as smithery:namespace/server").option("-j, --json", "Output as JSON").option("--refresh", "Refresh source data before activation").option("--version <value>", "Request a specific version when supported").option("--api-key <value>", "Override the Smithery API key for this command").option("--path <value>", "Configuration root path").action(async (ref, options) => {
8618
+ return new Command("add").description("Activate an MCP from the synchronized catalog").argument("<ref>", "MCP reference such as smithery:namespace/server").option("-j, --json", "Output as JSON").option("--refresh", "Refresh source data before activation").option("--version <value>", "Request a specific version when supported").option("--api-key <value>", "Override the Smithery API key for this command").option("--path <value>", "Configuration root path").option("-d, --dry-run", "Preview what would be activated without activating", false).action(async (ref, options) => {
8619
+ if (options.dryRun) {
8620
+ LogService.intro("Activating MCP");
8621
+ LogService.log(`Would activate MCP: ${ref}`);
8622
+ LogService.log("Note: Use without --dry-run to activate");
8623
+ return;
8624
+ }
8625
+ LogService.intro("Activating MCP");
8626
+ PromptService.startTask(`Activating MCP ${ref}`);
6831
8627
  const command = new AddMcpCommand;
6832
8628
  const result = await command.execute({
6833
8629
  configRoot: resolveConfigRoot(options.path),
@@ -6836,15 +8632,18 @@ function createMcpAddCommand() {
6836
8632
  version: options.version,
6837
8633
  apiKey: options.apiKey
6838
8634
  });
6839
- handleQueryResult(result);
6840
8635
  if (!result.success) {
8636
+ PromptService.stopTask();
8637
+ handleQueryResult(result);
6841
8638
  return;
6842
8639
  }
8640
+ PromptService.stopTask("MCP activated");
6843
8641
  if (options.json) {
6844
- console.log(JSON.stringify(result.data, null, 2));
8642
+ LogService.unstyled(JSON.stringify(result.data, null, 2));
6845
8643
  return;
6846
8644
  }
6847
- console.log(`Activated MCP ${result.data.item.displayName} at ${result.data.managedIntegration.localPath}`);
8645
+ LogService.success(`MCP ${result.data.item.displayName} activated at ${result.data.managedIntegration.localPath}`);
8646
+ LogService.outro(`Activated ${result.data.item.displayName}`);
6848
8647
  });
6849
8648
  }
6850
8649
 
@@ -6910,6 +8709,7 @@ class RemoveMcpCommand {
6910
8709
  // src/presentation/cli/features/mcp/commands/mcp_rm.ts
6911
8710
  function createMcpRemoveCommand() {
6912
8711
  return new Command("rm").description("Deactivate a managed MCP").argument("<ref>", "Managed MCP identifier").option("-j, --json", "Output as JSON").option("--path <value>", "Configuration root path").action(async (ref, options) => {
8712
+ LogService.intro("Deactivating MCP");
6913
8713
  const command = new RemoveMcpCommand;
6914
8714
  const result = await command.execute({
6915
8715
  configRoot: resolveConfigRoot(options.path),
@@ -6920,10 +8720,10 @@ function createMcpRemoveCommand() {
6920
8720
  return;
6921
8721
  }
6922
8722
  if (options.json) {
6923
- console.log(JSON.stringify(result.data, null, 2));
6924
- return;
8723
+ LogService.unstyled(JSON.stringify(result.data, null, 2));
8724
+ } else {
8725
+ LogService.success(`Deactivated MCP ${result.data.managedIntegration.managedId}`);
6925
8726
  }
6926
- console.log(`Deactivated MCP ${result.data.managedIntegration.managedId}`);
6927
8727
  });
6928
8728
  }
6929
8729
 
@@ -7043,6 +8843,7 @@ class UpdateMcpCommand {
7043
8843
  // src/presentation/cli/features/mcp/commands/mcp_update.ts
7044
8844
  function createMcpUpdateCommand() {
7045
8845
  return new Command("update").description("Update one or more managed MCPs").argument("[ref]", "Managed MCP identifier").option("--all", "Update all managed MCPs").option("--refresh", "Refresh source data before updating").option("-j, --json", "Output as JSON").option("--api-key <value>", "Override the Smithery API key for this command").option("--path <value>", "Configuration root path").action(async (ref, options) => {
8846
+ LogService.intro("Updating MCPs");
7046
8847
  const command = new UpdateMcpCommand;
7047
8848
  const result = await command.execute({
7048
8849
  configRoot: resolveConfigRoot(options.path),
@@ -7056,12 +8857,13 @@ function createMcpUpdateCommand() {
7056
8857
  return;
7057
8858
  }
7058
8859
  if (options.json) {
7059
- console.log(JSON.stringify(result.data, null, 2));
7060
- return;
7061
- }
7062
- for (const line of renderLifecycleSummary(result.data)) {
7063
- console.log(line);
8860
+ LogService.unstyled(JSON.stringify(result.data, null, 2));
8861
+ } else {
8862
+ for (const line of renderLifecycleSummary(result.data)) {
8863
+ LogService.log(line);
8864
+ }
7064
8865
  }
8866
+ LogService.outro("Update complete");
7065
8867
  });
7066
8868
  }
7067
8869
 
@@ -7071,7 +8873,7 @@ function createMcpCommand() {
7071
8873
  }
7072
8874
 
7073
8875
  // src/presentation/cli/features/apply/commands/apply.ts
7074
- import { resolve as resolve31 } from "node:path";
8876
+ import { resolve as resolve32 } from "node:path";
7075
8877
 
7076
8878
  // src/core/domain/shared/types/SupportedApplyPlatform.ts
7077
8879
  var SUPPORTED_APPLY_PLATFORMS = [
@@ -7079,12 +8881,31 @@ var SUPPORTED_APPLY_PLATFORMS = [
7079
8881
  "claude",
7080
8882
  "codex",
7081
8883
  "cursor",
8884
+ "forgecode",
7082
8885
  "gemini",
7083
8886
  "kilo",
7084
8887
  "opencode",
7085
8888
  "qwen",
7086
8889
  "windsurf"
7087
8890
  ];
8891
+ var PLATFORM_DISPLAY_NAMES = {
8892
+ antigravity: "Antigravity",
8893
+ claude: "Claude Desktop",
8894
+ codex: "Codex",
8895
+ cursor: "Cursor",
8896
+ forgecode: "ForgeCode",
8897
+ gemini: "Gemini",
8898
+ kilo: "Kilo",
8899
+ opencode: "OpenCode",
8900
+ qwen: "Qwen",
8901
+ windsurf: "Windsurf"
8902
+ };
8903
+ function getPlatformDisplayName(platform) {
8904
+ if (isSupportedApplyPlatform(platform)) {
8905
+ return PLATFORM_DISPLAY_NAMES[platform];
8906
+ }
8907
+ return platform.charAt(0).toUpperCase() + platform.slice(1);
8908
+ }
7088
8909
  function isSupportedApplyPlatform(value) {
7089
8910
  return SUPPORTED_APPLY_PLATFORMS.includes(value);
7090
8911
  }
@@ -7207,8 +9028,8 @@ class ApplySourceLoader {
7207
9028
  import { dirname as dirname4, relative as relative2, resolve as resolve20 } from "node:path";
7208
9029
  import { mkdir as mkdir6, readFile as readFile5, readdir as readdir7, writeFile as writeFile5 } from "node:fs/promises";
7209
9030
 
7210
- // src/infrastructure/features/apply/adapters/AppyMergePolicy.ts
7211
- function normalizeAppyContent(content) {
9031
+ // src/infrastructure/features/apply/adapters/ApplyMergePolicy.ts
9032
+ function normalizeApplyContent(content) {
7212
9033
  return content.replace(/\r\n/g, `
7213
9034
  `).trimEnd();
7214
9035
  }
@@ -7218,7 +9039,7 @@ function mergeManagedTextSection(existingContent, sectionBody, markers) {
7218
9039
  const nextContent = upsertManagedTextSection(existingContent, sectionBody, markers);
7219
9040
  const currentContent = existingContent ?? "";
7220
9041
  return {
7221
- status: normalizeAppyContent(currentContent) === normalizeAppyContent(nextContent) ? "unchanged" : "success",
9042
+ status: normalizeApplyContent(currentContent) === normalizeApplyContent(nextContent) ? "unchanged" : "success",
7222
9043
  content: nextContent
7223
9044
  };
7224
9045
  }
@@ -7356,49 +9177,276 @@ class GeminiCommandRenderer extends BaseCommandRenderer {
7356
9177
  renderCommand(source, id) {
7357
9178
  const parsed = this.parseMarkdownPrompt(source, id);
7358
9179
  return [
7359
- `description = ${JSON.stringify(parsed.description)}`,
7360
- 'prompt = """',
7361
- parsed.body.replace(/"""/g, "\\\"\\\"\\\""),
7362
- '"""'
9180
+ `description = ${JSON.stringify(parsed.description)}`,
9181
+ 'prompt = """',
9182
+ parsed.body.replace(/"""/g, "\\\"\\\"\\\""),
9183
+ '"""'
9184
+ ].join(`
9185
+ `);
9186
+ }
9187
+ }
9188
+
9189
+ // src/infrastructure/features/apply/adapters/WorkflowCommandRenderer.ts
9190
+ class WorkflowCommandRenderer extends BaseCommandRenderer {
9191
+ fileExtension = ".md";
9192
+ constructor() {
9193
+ super();
9194
+ }
9195
+ renderCommand(source, _id) {
9196
+ return source.trimEnd();
9197
+ }
9198
+ }
9199
+
9200
+ // src/infrastructure/features/apply/adapters/ForgeCodeCommandRenderer.ts
9201
+ class ForgeCodeCommandRenderer extends BaseCommandRenderer {
9202
+ fileExtension = ".md";
9203
+ renderCommand(source, id) {
9204
+ const trimmed = source.trimStart();
9205
+ const lines = trimmed.split(/\r?\n/);
9206
+ const name = this.idToName(id);
9207
+ if (trimmed.startsWith("---")) {
9208
+ return this.renderWithExistingFrontmatter(lines, id, name);
9209
+ }
9210
+ const firstLine = lines[0] || "";
9211
+ if (this.isYamlPropertyLine(firstLine)) {
9212
+ return this.renderWithMalformedFrontmatter(lines, name);
9213
+ }
9214
+ const parsed = this.parseMarkdownPrompt(source, id);
9215
+ return ["---", `name: ${name}`, `description: ${parsed.description}`, "---", "", parsed.body].join(`
9216
+ `);
9217
+ }
9218
+ isYamlPropertyLine(line) {
9219
+ return line.includes(":") && !line.startsWith("#") && !line.startsWith("-");
9220
+ }
9221
+ renderWithExistingFrontmatter(lines, _id, name) {
9222
+ let frontmatterEnd = -1;
9223
+ for (let i = 1;i < lines.length; i++) {
9224
+ if (lines[i].trim() === "---") {
9225
+ frontmatterEnd = i;
9226
+ break;
9227
+ }
9228
+ }
9229
+ if (frontmatterEnd === -1) {
9230
+ const parsed = this.parseMarkdownPrompt(lines.join(`
9231
+ `), _id);
9232
+ return ["---", `name: ${name}`, `description: ${parsed.description}`, "---", "", parsed.body].join(`
9233
+ `);
9234
+ }
9235
+ const frontmatterLines = lines.slice(1, frontmatterEnd);
9236
+ const bodyLines = lines.slice(frontmatterEnd + 1);
9237
+ const updatedFrontmatter = this.updateFrontmatterName(frontmatterLines, name);
9238
+ return ["---", ...updatedFrontmatter, "---", ...bodyLines].join(`
9239
+ `);
9240
+ }
9241
+ renderWithMalformedFrontmatter(lines, name) {
9242
+ let frontmatterEnd = -1;
9243
+ for (let i = 0;i < lines.length; i++) {
9244
+ if (lines[i].trim() === "---") {
9245
+ frontmatterEnd = i;
9246
+ break;
9247
+ }
9248
+ }
9249
+ if (frontmatterEnd > 0) {
9250
+ const frontmatterLines = lines.slice(0, frontmatterEnd);
9251
+ const bodyLines = lines.slice(frontmatterEnd + 1);
9252
+ const updatedFrontmatter = this.updateFrontmatterName(frontmatterLines, name);
9253
+ return ["---", ...updatedFrontmatter, "---", ...bodyLines].join(`
9254
+ `);
9255
+ }
9256
+ const id = name.replace(/:/g, "/");
9257
+ const parsed = this.parseMarkdownPrompt(lines.join(`
9258
+ `), id);
9259
+ return ["---", `name: ${name}`, `description: ${parsed.description}`, "---", "", parsed.body].join(`
9260
+ `);
9261
+ }
9262
+ updateFrontmatterName(frontmatterLines, name) {
9263
+ const result = [...frontmatterLines];
9264
+ let nameFound = false;
9265
+ for (let i = 0;i < result.length; i++) {
9266
+ const line = result[i];
9267
+ if (line.match(/^name:\s*/)) {
9268
+ result[i] = `name: ${name}`;
9269
+ nameFound = true;
9270
+ break;
9271
+ }
9272
+ }
9273
+ if (!nameFound) {
9274
+ result.unshift(`name: ${name}`);
9275
+ }
9276
+ return result;
9277
+ }
9278
+ }
9279
+
9280
+ // src/infrastructure/features/apply/adapters/CommandRendererFactory.ts
9281
+ class CommandRendererFactory {
9282
+ static renderers = CommandRendererFactory.createDefaultRenderers();
9283
+ static createDefaultRenderers() {
9284
+ return new Map([
9285
+ ["forgecode", new ForgeCodeCommandRenderer],
9286
+ ["gemini", new GeminiCommandRenderer],
9287
+ ["opencode", new OpenCodeCommandRenderer],
9288
+ ["workflow", new WorkflowCommandRenderer]
9289
+ ]);
9290
+ }
9291
+ static reset() {
9292
+ this.renderers = CommandRendererFactory.createDefaultRenderers();
9293
+ }
9294
+ static getRenderer(platform) {
9295
+ const renderer = this.renderers.get(platform);
9296
+ if (!renderer) {
9297
+ throw new Error(`No command renderer registered for platform: ${platform}`);
9298
+ }
9299
+ return renderer;
9300
+ }
9301
+ static registerRenderer(platform, renderer) {
9302
+ this.renderers.set(platform, renderer);
9303
+ }
9304
+ }
9305
+
9306
+ // src/infrastructure/features/apply/adapters/BaseAgentRenderer.ts
9307
+ class BaseAgentRenderer {
9308
+ parseMarkdownPrompt(source, id) {
9309
+ const trimmed = source.trim();
9310
+ const lines = trimmed.split(/\r?\n/);
9311
+ const firstLine = lines[0] ?? "";
9312
+ const title = firstLine.startsWith("# ") ? firstLine.replace(/^#\s+/, "").trim() : this.humanizeSegment(id);
9313
+ const body = firstLine.startsWith("# ") ? lines.slice(1).join(`
9314
+ `).trim() || trimmed : trimmed;
9315
+ const description = title.replace(/\b(command|workflow|agent|skill)\b/gi, "").replace(/\s+/g, " ").trim() || this.humanizeSegment(id);
9316
+ return {
9317
+ title,
9318
+ description,
9319
+ body
9320
+ };
9321
+ }
9322
+ humanizeSegment(value) {
9323
+ return value.split(/[-_]/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
9324
+ }
9325
+ }
9326
+
9327
+ // src/infrastructure/features/apply/adapters/ForgeCodeAgentRenderer.ts
9328
+ class ForgeCodeAgentRenderer extends BaseAgentRenderer {
9329
+ fileExtension = ".md";
9330
+ renderAgent(source, id) {
9331
+ const trimmed = source.trimStart();
9332
+ const lines = trimmed.split(/\r?\n/);
9333
+ const parsed = this.parseMarkdownPrompt(source, id);
9334
+ if (trimmed.startsWith("---")) {
9335
+ return this.renderWithExistingFrontmatter(lines, id, parsed);
9336
+ }
9337
+ const firstLine = lines[0] || "";
9338
+ if (this.isYamlPropertyLine(firstLine)) {
9339
+ return this.renderWithMalformedFrontmatter(lines, id, parsed);
9340
+ }
9341
+ return [
9342
+ "---",
9343
+ `id: ${id}`,
9344
+ `title: ${parsed.title}`,
9345
+ `description: ${parsed.description}`,
9346
+ "---",
9347
+ "",
9348
+ parsed.body
9349
+ ].join(`
9350
+ `);
9351
+ }
9352
+ isYamlPropertyLine(line) {
9353
+ return line.includes(":") && !line.startsWith("#") && !line.startsWith("-");
9354
+ }
9355
+ renderWithExistingFrontmatter(lines, id, parsed) {
9356
+ let frontmatterEnd = -1;
9357
+ for (let i = 1;i < lines.length; i++) {
9358
+ if (lines[i].trim() === "---") {
9359
+ frontmatterEnd = i;
9360
+ break;
9361
+ }
9362
+ }
9363
+ if (frontmatterEnd === -1) {
9364
+ return [
9365
+ "---",
9366
+ `id: ${id}`,
9367
+ `title: ${parsed.title}`,
9368
+ `description: ${parsed.description}`,
9369
+ "---",
9370
+ "",
9371
+ parsed.body
9372
+ ].join(`
9373
+ `);
9374
+ }
9375
+ const frontmatterLines = lines.slice(1, frontmatterEnd);
9376
+ const bodyLines = lines.slice(frontmatterEnd + 1);
9377
+ const updatedFrontmatter = this.updateAgentFrontmatter(frontmatterLines, id, parsed);
9378
+ return ["---", ...updatedFrontmatter, "---", ...bodyLines].join(`
9379
+ `);
9380
+ }
9381
+ renderWithMalformedFrontmatter(lines, id, parsed) {
9382
+ let frontmatterEnd = -1;
9383
+ for (let i = 1;i < lines.length; i++) {
9384
+ if (lines[i].trim() === "---") {
9385
+ frontmatterEnd = i;
9386
+ break;
9387
+ }
9388
+ }
9389
+ if (frontmatterEnd > 0) {
9390
+ const frontmatterLines = lines.slice(0, frontmatterEnd);
9391
+ const bodyLines = lines.slice(frontmatterEnd + 1);
9392
+ const updatedFrontmatter = this.updateAgentFrontmatter(frontmatterLines, id, parsed);
9393
+ return ["---", ...updatedFrontmatter, "---", ...bodyLines].join(`
9394
+ `);
9395
+ }
9396
+ return [
9397
+ "---",
9398
+ `id: ${id}`,
9399
+ `title: ${parsed.title}`,
9400
+ `description: ${parsed.description}`,
9401
+ "---",
9402
+ "",
9403
+ parsed.body
7363
9404
  ].join(`
7364
9405
  `);
7365
9406
  }
7366
- }
7367
-
7368
- // src/infrastructure/features/apply/adapters/WorkflowCommandRenderer.ts
7369
- class WorkflowCommandRenderer extends BaseCommandRenderer {
7370
- fileExtension = ".md";
7371
- constructor() {
7372
- super();
7373
- }
7374
- renderCommand(source, _id) {
7375
- return source.trimEnd();
9407
+ updateAgentFrontmatter(frontmatterLines, id, parsed) {
9408
+ const result = [...frontmatterLines];
9409
+ let idFound = false;
9410
+ let titleFound = false;
9411
+ let descriptionFound = false;
9412
+ for (let i = 0;i < result.length; i++) {
9413
+ const line = result[i];
9414
+ if (line.match(/^id:\s*/)) {
9415
+ result[i] = `id: ${id}`;
9416
+ idFound = true;
9417
+ } else if (line.match(/^title:\s*/)) {
9418
+ result[i] = `title: ${parsed.title}`;
9419
+ titleFound = true;
9420
+ } else if (line.match(/^description:\s*/)) {
9421
+ result[i] = `description: ${parsed.description}`;
9422
+ descriptionFound = true;
9423
+ }
9424
+ }
9425
+ if (!idFound) {
9426
+ result.unshift(`id: ${id}`);
9427
+ }
9428
+ if (!titleFound) {
9429
+ result.unshift(`title: ${parsed.title}`);
9430
+ }
9431
+ if (!descriptionFound) {
9432
+ result.unshift(`description: ${parsed.description}`);
9433
+ }
9434
+ return result;
7376
9435
  }
7377
9436
  }
7378
9437
 
7379
- // src/infrastructure/features/apply/adapters/CommandRendererFactory.ts
7380
- class CommandRendererFactory {
7381
- static renderers = CommandRendererFactory.createDefaultRenderers();
7382
- static createDefaultRenderers() {
7383
- return new Map([
7384
- ["opencode", new OpenCodeCommandRenderer],
7385
- ["gemini", new GeminiCommandRenderer],
7386
- ["workflow", new WorkflowCommandRenderer]
7387
- ]);
7388
- }
7389
- static reset() {
7390
- this.renderers = CommandRendererFactory.createDefaultRenderers();
7391
- }
9438
+ // src/infrastructure/features/apply/adapters/AgentRendererFactory.ts
9439
+ class AgentRendererFactory {
9440
+ static renderers = {
9441
+ forgecode: new ForgeCodeAgentRenderer
9442
+ };
7392
9443
  static getRenderer(platform) {
7393
- const renderer = this.renderers.get(platform);
9444
+ const renderer = this.renderers[platform];
7394
9445
  if (!renderer) {
7395
- throw new Error(`No command renderer registered for platform: ${platform}`);
9446
+ throw new Error(`No agent renderer found for platform: ${platform}`);
7396
9447
  }
7397
9448
  return renderer;
7398
9449
  }
7399
- static registerRenderer(platform, renderer) {
7400
- this.renderers.set(platform, renderer);
7401
- }
7402
9450
  }
7403
9451
 
7404
9452
  // src/infrastructure/features/apply/adapters/BaseMcpConfigRenderer.ts
@@ -7406,6 +9454,9 @@ class BaseMcpConfigRenderer {
7406
9454
  filterStdioServers(servers) {
7407
9455
  return servers.filter((s) => s.transport === "stdio");
7408
9456
  }
9457
+ filterHttpServers(servers) {
9458
+ return servers.filter((s) => s.transport === "http");
9459
+ }
7409
9460
  isObject(value) {
7410
9461
  return typeof value === "object" && value !== null && !Array.isArray(value);
7411
9462
  }
@@ -7501,14 +9552,51 @@ class CodexMcpConfigRenderer extends BaseMcpConfigRenderer {
7501
9552
  }
7502
9553
  }
7503
9554
 
9555
+ // src/infrastructure/features/apply/adapters/ForgeCodeMcpConfigRenderer.ts
9556
+ class ForgeCodeMcpConfigRenderer extends BaseMcpConfigRenderer {
9557
+ constructor() {
9558
+ super();
9559
+ }
9560
+ renderConfig(existing, servers) {
9561
+ const stdioServers = this.filterStdioServers(servers);
9562
+ const httpServers = this.filterHttpServers(servers);
9563
+ const currentMcp = this.isObject(existing.mcpServers) ? existing.mcpServers : {};
9564
+ const stdioConfig = Object.fromEntries(stdioServers.map((server) => [
9565
+ server.name,
9566
+ {
9567
+ command: server.command,
9568
+ args: server.args,
9569
+ ...server.cwd ? { cwd: server.cwd } : {},
9570
+ ...server.env && Object.keys(server.env).length > 0 ? { env: server.env } : {}
9571
+ }
9572
+ ]));
9573
+ const httpConfig = Object.fromEntries(httpServers.map((server) => [
9574
+ server.name,
9575
+ {
9576
+ url: server.url,
9577
+ ...server.env && Object.keys(server.env).length > 0 ? { env: server.env } : {}
9578
+ }
9579
+ ]));
9580
+ return {
9581
+ ...existing,
9582
+ mcpServers: {
9583
+ ...currentMcp,
9584
+ ...stdioConfig,
9585
+ ...httpConfig
9586
+ }
9587
+ };
9588
+ }
9589
+ }
9590
+
7504
9591
  // src/infrastructure/features/apply/adapters/McpConfigRendererFactory.ts
7505
9592
  class McpConfigRendererFactory {
7506
9593
  static renderers = McpConfigRendererFactory.createDefaultRenderers();
7507
9594
  static createDefaultRenderers() {
7508
9595
  return new Map([
9596
+ ["codex", new CodexMcpConfigRenderer],
9597
+ ["forgecode", new ForgeCodeMcpConfigRenderer],
7509
9598
  ["opencode", new OpenCodeMcpConfigRenderer],
7510
- ["settings", new SettingsMcpConfigRenderer],
7511
- ["codex", new CodexMcpConfigRenderer]
9599
+ ["settings", new SettingsMcpConfigRenderer]
7512
9600
  ]);
7513
9601
  }
7514
9602
  static reset() {
@@ -7575,6 +9663,18 @@ async function syncCommandsAsMarkdown(commands, targetRoot, dryRun, renderer, fl
7575
9663
  }));
7576
9664
  return syncRenderedFiles(targetRoot, rendered, dryRun);
7577
9665
  }
9666
+ async function syncCommandsAsMarkdownFlattened(commands, targetRoot, dryRun, renderer) {
9667
+ const commandRenderer = renderer ?? CommandRendererFactory.getRenderer("opencode");
9668
+ const rendered = await Promise.all(commands.map(async (command) => {
9669
+ const source = await readFile5(command.path, "utf-8");
9670
+ const relativePath = `${command.id.split("/").pop()}${commandRenderer.fileExtension}`;
9671
+ return {
9672
+ relativePath,
9673
+ content: commandRenderer.renderCommand(source, command.id)
9674
+ };
9675
+ }));
9676
+ return syncRenderedFiles(targetRoot, rendered, dryRun);
9677
+ }
7578
9678
  async function syncCommandsAsToml(commands, targetRoot, dryRun, renderer) {
7579
9679
  const commandRenderer = renderer ?? CommandRendererFactory.getRenderer("gemini");
7580
9680
  const rendered = await Promise.all(commands.map(async (command) => {
@@ -7652,13 +9752,13 @@ async function syncAgentsAsCodexToml(agents, targetRoot, dryRun) {
7652
9752
  }
7653
9753
  return { changed, paths };
7654
9754
  }
7655
- async function syncAgentsAsMarkdown(agents, targetRoot, dryRun, withFrontmatter, renderer) {
7656
- const commandRenderer = renderer ?? CommandRendererFactory.getRenderer("opencode");
9755
+ async function syncAgentsAsMarkdown(agents, targetRoot, dryRun, withFrontmatter, agentRenderer) {
9756
+ const renderer = agentRenderer ?? AgentRendererFactory.getRenderer("forgecode");
7657
9757
  const rendered = await Promise.all(agents.map(async (agent) => {
7658
9758
  const source = await readFile5(agent.path, "utf-8");
7659
9759
  return {
7660
- relativePath: `${agent.id}${commandRenderer.fileExtension}`,
7661
- content: withFrontmatter ? commandRenderer.renderCommand(source, agent.id) : source.trimEnd()
9760
+ relativePath: `${agent.id}${renderer.fileExtension}`,
9761
+ content: withFrontmatter ? renderer.renderAgent(source, agent.id) : source.trimEnd()
7662
9762
  };
7663
9763
  }));
7664
9764
  return syncRenderedFiles(targetRoot, rendered, dryRun);
@@ -7693,6 +9793,10 @@ function renderOpencodeMcpConfig(existing, servers) {
7693
9793
  const renderer = McpConfigRendererFactory.getRenderer("opencode");
7694
9794
  return renderer.renderConfig(existing, servers);
7695
9795
  }
9796
+ function renderForgeCodeMcpConfig(existing, servers) {
9797
+ const renderer = McpConfigRendererFactory.getRenderer("forgecode");
9798
+ return renderer.renderConfig(existing, servers);
9799
+ }
7696
9800
  function renderSettingsMcpConfig(existing, servers) {
7697
9801
  const renderer = McpConfigRendererFactory.getRenderer("settings");
7698
9802
  return renderer.renderConfig(existing, servers);
@@ -7841,6 +9945,8 @@ function isObject(value) {
7841
9945
  }
7842
9946
 
7843
9947
  // src/infrastructure/features/opencode/adapters/OpenCodeAdapter.ts
9948
+ import { rm as rm3 } from "node:fs/promises";
9949
+
7844
9950
  class OpenCodeAdapter {
7845
9951
  platformName = "opencode";
7846
9952
  sourceLoader = new ApplySourceLoader;
@@ -7857,7 +9963,7 @@ class OpenCodeAdapter {
7857
9963
  surface: "agents-md-commands-skills-agents-mcp"
7858
9964
  };
7859
9965
  }
7860
- async applyAppyIntegration(request) {
9966
+ async applyApplyIntegration(request) {
7861
9967
  const target = await this.resolveTarget(request.projectPath, request);
7862
9968
  const userRoot = request.userConfigRootPath ? resolve21(request.userConfigRootPath) : resolve21(homedir10(), ".config", "opencode");
7863
9969
  const commandRoot = target.scope === "project" ? resolve21(request.projectPath, ".opencode", "commands") : resolve21(userRoot, "commands");
@@ -7867,6 +9973,28 @@ class OpenCodeAdapter {
7867
9973
  const source = await this.sourceLoader.load(request.projectPath);
7868
9974
  let changed = false;
7869
9975
  const fileChanges = [];
9976
+ if (request.override) {
9977
+ const commandsPath = resolve21(userRoot, "commands");
9978
+ const skillsPath = resolve21(userRoot, "skills");
9979
+ const agentsPath = resolve21(userRoot, "agents");
9980
+ await Promise.all([
9981
+ rm3(commandsPath, { recursive: true, force: true }).catch((error) => {
9982
+ if (error.code !== "ENOENT") {
9983
+ throw error;
9984
+ }
9985
+ }),
9986
+ rm3(skillsPath, { recursive: true, force: true }).catch((error) => {
9987
+ if (error.code !== "ENOENT") {
9988
+ throw error;
9989
+ }
9990
+ }),
9991
+ rm3(agentsPath, { recursive: true, force: true }).catch((error) => {
9992
+ if (error.code !== "ENOENT") {
9993
+ throw error;
9994
+ }
9995
+ })
9996
+ ]);
9997
+ }
7870
9998
  const rulesResult = await upsertManagedRuleDocument(target.configPath, source.rules, OpenCodeAdapter.markers, "No managed OpenCode rules were found.", Boolean(request.dryRun));
7871
9999
  changed = rulesResult.changed || changed;
7872
10000
  fileChanges.push(...rulesResult.paths);
@@ -7903,7 +10031,7 @@ import { relative as relative4, resolve as resolve23 } from "node:path";
7903
10031
  // src/infrastructure/features/claude/adapters/ClaudeAdapter.ts
7904
10032
  import { homedir as homedir11 } from "node:os";
7905
10033
  import { dirname as dirname5, resolve as resolve22, relative as relative3, extname as extname5 } from "node:path";
7906
- import { readFile as readFile6, writeFile as writeFile6, access as access4, mkdir as mkdir7, cp, readdir as readdir8, rm as rm3 } from "node:fs/promises";
10034
+ import { readFile as readFile6, writeFile as writeFile6, access as access4, mkdir as mkdir7, cp, readdir as readdir8, rm as rm4 } from "node:fs/promises";
7907
10035
  class ClaudeAdapter {
7908
10036
  platformName = "claude";
7909
10037
  configPath;
@@ -7968,10 +10096,13 @@ class ClaudeAdapter {
7968
10096
  const existingContent = await readFile6(this.configPath, "utf-8").catch(() => "");
7969
10097
  const mergedContent = this.upsertManagedSection(existingContent, config, await this.loadRuleContents(config));
7970
10098
  await writeFile6(this.configPath, mergedContent, "utf-8");
7971
- await this.writeClaudeMcpConfig(config, options?.cleanExistingArtifacts);
10099
+ if (options?.cleanExistingArtifacts) {
10100
+ await this.cleanManagedArtifacts();
10101
+ }
7972
10102
  await this.syncSkills(config);
7973
10103
  await this.syncAgents(config);
7974
10104
  await this.syncCommands();
10105
+ await this.writeClaudeMcpConfig(config, options?.cleanExistingArtifacts);
7975
10106
  return ok(undefined);
7976
10107
  } catch (error) {
7977
10108
  const nodeErr = error;
@@ -8095,9 +10226,21 @@ class ClaudeAdapter {
8095
10226
  }
8096
10227
  async cleanManagedArtifacts() {
8097
10228
  await Promise.all([
8098
- rm3(resolve22(this.claudeRoot, "skills"), { recursive: true, force: true }),
8099
- rm3(resolve22(this.claudeRoot, "agents"), { recursive: true, force: true }),
8100
- rm3(resolve22(this.claudeRoot, "commands"), { recursive: true, force: true })
10229
+ rm4(resolve22(this.claudeRoot, "skills"), { recursive: true, force: true }).catch((error) => {
10230
+ if (error.code !== "ENOENT") {
10231
+ throw error;
10232
+ }
10233
+ }),
10234
+ rm4(resolve22(this.claudeRoot, "agents"), { recursive: true, force: true }).catch((error) => {
10235
+ if (error.code !== "ENOENT") {
10236
+ throw error;
10237
+ }
10238
+ }),
10239
+ rm4(resolve22(this.claudeRoot, "commands"), { recursive: true, force: true }).catch((error) => {
10240
+ if (error.code !== "ENOENT") {
10241
+ throw error;
10242
+ }
10243
+ })
8101
10244
  ]);
8102
10245
  }
8103
10246
  async writeClaudeMcpConfig(config, cleanExistingMcp) {
@@ -8229,7 +10372,7 @@ class ClaudeApplyAdapter {
8229
10372
  surface: "memory-skills-agents-commands-mcp"
8230
10373
  };
8231
10374
  }
8232
- async applyAppyIntegration(request) {
10375
+ async applyApplyIntegration(request) {
8233
10376
  const target = await this.resolveTarget(request.projectPath, request);
8234
10377
  const adapter = new ClaudeAdapter(request.projectPath, target.scope === "project" ? request.projectPath : process.env.AGENT_CTRL_CLAUDE_HOME || homedir12());
8235
10378
  const source = await this.sourceLoader.load(request.projectPath);
@@ -8242,7 +10385,7 @@ class ClaudeApplyAdapter {
8242
10385
  ...desiredConfig.data,
8243
10386
  mcpServers: source.mcpServers
8244
10387
  }, {
8245
- cleanExistingArtifacts: Boolean(request.override)
10388
+ cleanExistingArtifacts: request.override
8246
10389
  });
8247
10390
  if (!writeResult.success) {
8248
10391
  throw writeResult.error;
@@ -8293,6 +10436,7 @@ async function collectFiles2(root) {
8293
10436
  // src/infrastructure/features/gemini/adapters/GeminiAdapter.ts
8294
10437
  import { homedir as homedir13 } from "node:os";
8295
10438
  import { resolve as resolve24 } from "node:path";
10439
+ import { rm as rm5 } from "node:fs/promises";
8296
10440
  class GeminiAdapter {
8297
10441
  platformName = "gemini";
8298
10442
  sourceLoader = new ApplySourceLoader;
@@ -8309,7 +10453,7 @@ class GeminiAdapter {
8309
10453
  surface: "gemini-md-commands-skills-settings"
8310
10454
  };
8311
10455
  }
8312
- async applyAppyIntegration(request) {
10456
+ async applyApplyIntegration(request) {
8313
10457
  const target = await this.resolveTarget(request.projectPath, request);
8314
10458
  const userRoot = request.userConfigRootPath ? resolve24(request.userConfigRootPath) : resolve24(homedir13(), ".gemini");
8315
10459
  const userAgentsRoot = request.userConfigRootPath ? resolve24(request.userConfigRootPath, "..", ".agents") : resolve24(homedir13(), ".agents");
@@ -8318,6 +10462,34 @@ class GeminiAdapter {
8318
10462
  const source = await this.sourceLoader.load(request.projectPath);
8319
10463
  let changed = false;
8320
10464
  const fileChanges = [];
10465
+ if (request.override) {
10466
+ const commandsPath = resolve24(scopeRoot, "commands");
10467
+ const skillsPath = resolve24(scopeRoot, "skills");
10468
+ const agentsPath = scopeAgentsRoot;
10469
+ const mcpConfigPath = resolve24(scopeRoot, ".mcp.json");
10470
+ await Promise.all([
10471
+ rm5(commandsPath, { recursive: true, force: true }).catch((error) => {
10472
+ if (error.code !== "ENOENT") {
10473
+ throw error;
10474
+ }
10475
+ }),
10476
+ rm5(skillsPath, { recursive: true, force: true }).catch((error) => {
10477
+ if (error.code !== "ENOENT") {
10478
+ throw error;
10479
+ }
10480
+ }),
10481
+ rm5(agentsPath, { recursive: true, force: true }).catch((error) => {
10482
+ if (error.code !== "ENOENT") {
10483
+ throw error;
10484
+ }
10485
+ }),
10486
+ rm5(mcpConfigPath, { recursive: true, force: true }).catch((error) => {
10487
+ if (error.code !== "ENOENT") {
10488
+ throw error;
10489
+ }
10490
+ })
10491
+ ]);
10492
+ }
8321
10493
  const rulesResult = await upsertManagedRuleDocument(target.configPath, source.rules, GeminiAdapter.markers, "No managed Gemini rules were found.", Boolean(request.dryRun));
8322
10494
  changed = rulesResult.changed || changed;
8323
10495
  fileChanges.push(...rulesResult.paths);
@@ -8348,6 +10520,7 @@ class GeminiAdapter {
8348
10520
  // src/infrastructure/features/qwen/adapters/QwenAdapter.ts
8349
10521
  import { homedir as homedir14 } from "node:os";
8350
10522
  import { resolve as resolve25 } from "node:path";
10523
+ import { rm as rm6 } from "node:fs/promises";
8351
10524
  class QwenAdapter {
8352
10525
  platformName = "qwen";
8353
10526
  sourceLoader = new ApplySourceLoader;
@@ -8364,7 +10537,7 @@ class QwenAdapter {
8364
10537
  surface: "qwen-md-commands-skills-settings"
8365
10538
  };
8366
10539
  }
8367
- async applyAppyIntegration(request) {
10540
+ async applyApplyIntegration(request) {
8368
10541
  const target = await this.resolveTarget(request.projectPath, request);
8369
10542
  const userRoot = request.userConfigRootPath ? resolve25(request.userConfigRootPath) : resolve25(homedir14(), ".qwen");
8370
10543
  const userAgentsRoot = request.userConfigRootPath ? resolve25(request.userConfigRootPath, "..", ".agents") : resolve25(homedir14(), ".agents");
@@ -8373,6 +10546,34 @@ class QwenAdapter {
8373
10546
  const source = await this.sourceLoader.load(request.projectPath);
8374
10547
  let changed = false;
8375
10548
  const fileChanges = [];
10549
+ if (request.override) {
10550
+ const commandsPath = resolve25(scopeRoot, "commands");
10551
+ const skillsPath = resolve25(scopeRoot, "skills");
10552
+ const agentsPath = scopeAgentsRoot;
10553
+ const mcpConfigPath = resolve25(scopeRoot, ".mcp.json");
10554
+ await Promise.all([
10555
+ rm6(commandsPath, { recursive: true, force: true }).catch((error) => {
10556
+ if (error.code !== "ENOENT") {
10557
+ throw error;
10558
+ }
10559
+ }),
10560
+ rm6(skillsPath, { recursive: true, force: true }).catch((error) => {
10561
+ if (error.code !== "ENOENT") {
10562
+ throw error;
10563
+ }
10564
+ }),
10565
+ rm6(agentsPath, { recursive: true, force: true }).catch((error) => {
10566
+ if (error.code !== "ENOENT") {
10567
+ throw error;
10568
+ }
10569
+ }),
10570
+ rm6(mcpConfigPath, { recursive: true, force: true }).catch((error) => {
10571
+ if (error.code !== "ENOENT") {
10572
+ throw error;
10573
+ }
10574
+ })
10575
+ ]);
10576
+ }
8376
10577
  const rulesResult = await upsertManagedRuleDocument(target.configPath, source.rules, QwenAdapter.markers, "No managed Qwen rules were found.", Boolean(request.dryRun));
8377
10578
  changed = rulesResult.changed || changed;
8378
10579
  fileChanges.push(...rulesResult.paths);
@@ -8403,45 +10604,86 @@ class QwenAdapter {
8403
10604
  // src/infrastructure/features/kilo/adapters/KiloAdapter.ts
8404
10605
  import { homedir as homedir15 } from "node:os";
8405
10606
  import { resolve as resolve26 } from "node:path";
10607
+ import { mkdir as mkdir8, rm as rm7 } from "node:fs/promises";
10608
+ var KILO_VSCODE_DIR = ".kilo";
10609
+ var KILO_CLI_DIR = ".kilocode";
10610
+ function getKiloConfigRoots(basePath) {
10611
+ return [resolve26(basePath, KILO_VSCODE_DIR), resolve26(basePath, KILO_CLI_DIR)];
10612
+ }
10613
+ async function ensureDirExists(path) {
10614
+ await mkdir8(path, { recursive: true });
10615
+ }
10616
+
8406
10617
  class KiloAdapter {
8407
10618
  platformName = "kilo";
8408
10619
  sourceLoader = new ApplySourceLoader;
8409
10620
  async resolveTarget(projectPath, request) {
8410
10621
  const scope = resolveApplyScope(request?.targetScope, "user", true);
8411
- const userRoot = request?.userConfigRootPath ? resolve26(request.userConfigRootPath) : resolve26(homedir15(), ".kilocode");
10622
+ const targetPath = scope === "project" ? projectPath : request?.userConfigRootPath ?? resolve26(homedir15());
10623
+ const [vscodeRoot, cliRoot] = getKiloConfigRoots(targetPath);
10624
+ await ensureDirExists(vscodeRoot);
10625
+ await ensureDirExists(cliRoot);
8412
10626
  return {
8413
- configPath: scope === "project" ? resolve26(projectPath, ".kilocode") : userRoot,
10627
+ configPath: vscodeRoot,
8414
10628
  scope,
8415
10629
  surface: "rules-workflows-skills-agents-mcp"
8416
10630
  };
8417
10631
  }
8418
- async applyAppyIntegration(request) {
8419
- const target = await this.resolveTarget(request.projectPath, request);
10632
+ async applyApplyIntegration(request) {
10633
+ const scope = resolveApplyScope(request?.targetScope, "user", true);
10634
+ const targetPath = scope === "project" ? request.projectPath : request?.userConfigRootPath ?? resolve26(homedir15());
10635
+ const targetRoots = getKiloConfigRoots(targetPath);
8420
10636
  const source = await this.sourceLoader.load(request.projectPath);
8421
10637
  let changed = false;
8422
10638
  const fileChanges = [];
8423
- const rulesResult = await syncRulesAsFiles(source.rules, resolve26(target.configPath, "rules"), (rule, content) => ({ relativePath: `${rule.id}.md`, content: content.trimEnd() }), Boolean(request.dryRun));
8424
- changed = rulesResult.changed || changed;
8425
- fileChanges.push(...rulesResult.paths);
8426
- const workflowsResult = await syncCommandsAsMarkdown(source.commands, resolve26(target.configPath, "workflows"), Boolean(request.dryRun), CommandRendererFactory.getRenderer("workflow"), "-");
8427
- changed = workflowsResult.changed || changed;
8428
- fileChanges.push(...workflowsResult.paths);
8429
- const skillsResult = await syncSkills(source.skills, resolve26(target.configPath, "skills"), Boolean(request.dryRun));
8430
- changed = skillsResult.changed || changed;
8431
- fileChanges.push(...skillsResult.paths);
8432
- const agentsResult = await syncAgentsAsMarkdown(source.agents, resolve26(target.configPath, "agents"), Boolean(request.dryRun), true);
8433
- changed = agentsResult.changed || changed;
8434
- fileChanges.push(...agentsResult.paths);
8435
- const mcpResult = await mergeJsonObjectFile(resolve26(target.configPath, "kilo.json"), (existing) => renderOpencodeMcpConfig(existing, source.mcpServers), Boolean(request.dryRun));
8436
- changed = mcpResult.changed || changed;
8437
- fileChanges.push(...mcpResult.paths);
10639
+ if (request.override) {
10640
+ for (const targetRoot of targetRoots) {
10641
+ const commandsPath = resolve26(targetRoot, "commands");
10642
+ const skillsPath = resolve26(targetRoot, "skills");
10643
+ const agentsPath = resolve26(targetRoot, "agents");
10644
+ await Promise.all([
10645
+ rm7(commandsPath, { recursive: true, force: true }).catch((error) => {
10646
+ if (error.code !== "ENOENT") {
10647
+ throw error;
10648
+ }
10649
+ }),
10650
+ rm7(skillsPath, { recursive: true, force: true }).catch((error) => {
10651
+ if (error.code !== "ENOENT") {
10652
+ throw error;
10653
+ }
10654
+ }),
10655
+ rm7(agentsPath, { recursive: true, force: true }).catch((error) => {
10656
+ if (error.code !== "ENOENT") {
10657
+ throw error;
10658
+ }
10659
+ })
10660
+ ]);
10661
+ }
10662
+ }
10663
+ for (const targetRoot of targetRoots) {
10664
+ const rulesResult = await syncRulesAsFiles(source.rules, resolve26(targetRoot, "rules"), (rule, content) => ({ relativePath: `${rule.id}.md`, content: content.trimEnd() }), Boolean(request.dryRun));
10665
+ changed = rulesResult.changed || changed;
10666
+ fileChanges.push(...rulesResult.paths);
10667
+ const workflowsResult = await syncCommandsAsMarkdown(source.commands, resolve26(targetRoot, "commands"), Boolean(request.dryRun), CommandRendererFactory.getRenderer("workflow"), ":");
10668
+ changed = workflowsResult.changed || changed;
10669
+ fileChanges.push(...workflowsResult.paths);
10670
+ const skillsResult = await syncSkills(source.skills, resolve26(targetRoot, "skills"), Boolean(request.dryRun));
10671
+ changed = skillsResult.changed || changed;
10672
+ fileChanges.push(...skillsResult.paths);
10673
+ const agentsResult = await syncAgentsAsMarkdown(source.agents, resolve26(targetRoot, "agents"), Boolean(request.dryRun), true);
10674
+ changed = agentsResult.changed || changed;
10675
+ fileChanges.push(...agentsResult.paths);
10676
+ const mcpResult = await mergeJsonObjectFile(resolve26(targetRoot, "kilo.json"), (existing) => renderOpencodeMcpConfig(existing, source.mcpServers), Boolean(request.dryRun));
10677
+ changed = mcpResult.changed || changed;
10678
+ fileChanges.push(...mcpResult.paths);
10679
+ }
8438
10680
  return {
8439
10681
  platform: this.platformName,
8440
- configPath: target.configPath,
8441
- scope: target.scope,
8442
- surface: target.surface,
10682
+ configPath: targetRoots.join(", "),
10683
+ scope,
10684
+ surface: "rules-workflows-skills-agents-mcp",
8443
10685
  status: toStatus(changed),
8444
- message: "Applied Kilo rules, workflows, skills, agents, and MCP servers.",
10686
+ message: "Applied Kilo rules, workflows, skills, agents, and MCP servers to both .kilo and .kilocode directories.",
8445
10687
  fileChanges,
8446
10688
  warnings: source.warnings
8447
10689
  };
@@ -8451,6 +10693,7 @@ class KiloAdapter {
8451
10693
  // src/infrastructure/features/antigravity/adapters/AntigravityAdapter.ts
8452
10694
  import { homedir as homedir16 } from "node:os";
8453
10695
  import { resolve as resolve27 } from "node:path";
10696
+ import { rm as rm8 } from "node:fs/promises";
8454
10697
  class AntigravityAdapter {
8455
10698
  platformName = "antigravity";
8456
10699
  sourceLoader = new ApplySourceLoader;
@@ -8467,12 +10710,46 @@ class AntigravityAdapter {
8467
10710
  surface: scope === "project" ? "rules-workflows-skills-mcp" : "gemini-md-skills-mcp"
8468
10711
  };
8469
10712
  }
8470
- async applyAppyIntegration(request) {
10713
+ async applyApplyIntegration(request) {
8471
10714
  const target = await this.resolveTarget(request.projectPath, request);
8472
10715
  const userRoot = request.userConfigRootPath ? resolve27(request.userConfigRootPath) : resolve27(homedir16(), ".gemini");
10716
+ const projectRoot = request.projectPath;
8473
10717
  const source = await this.sourceLoader.load(request.projectPath);
8474
10718
  let changed = false;
8475
10719
  const fileChanges = [];
10720
+ if (request.override) {
10721
+ if (target.scope === "project") {
10722
+ const projectScopeSkillsPath = resolve27(projectRoot, ".agent", "skills");
10723
+ const projectScopeRulesPath = resolve27(projectRoot, ".agent", "rules");
10724
+ const projectScopeWorkflowsPath = resolve27(projectRoot, ".agent", "workflows");
10725
+ await Promise.all([
10726
+ rm8(projectScopeSkillsPath, { recursive: true, force: true }).catch((error) => {
10727
+ if (error.code !== "ENOENT") {
10728
+ throw error;
10729
+ }
10730
+ }),
10731
+ rm8(projectScopeRulesPath, { recursive: true, force: true }).catch((error) => {
10732
+ if (error.code !== "ENOENT") {
10733
+ throw error;
10734
+ }
10735
+ }),
10736
+ rm8(projectScopeWorkflowsPath, { recursive: true, force: true }).catch((error) => {
10737
+ if (error.code !== "ENOENT") {
10738
+ throw error;
10739
+ }
10740
+ })
10741
+ ]);
10742
+ } else {
10743
+ const userScopeSkillsPath = resolve27(userRoot, "antigravity", "skills");
10744
+ await Promise.all([
10745
+ rm8(userScopeSkillsPath, { recursive: true, force: true }).catch((error) => {
10746
+ if (error.code !== "ENOENT") {
10747
+ throw error;
10748
+ }
10749
+ })
10750
+ ]);
10751
+ }
10752
+ }
8476
10753
  if (target.scope === "project") {
8477
10754
  const rulesResult = await syncRulesAsFiles(source.rules, target.configPath, (rule, content) => ({ relativePath: `${rule.id}.md`, content: content.trimEnd() }), Boolean(request.dryRun));
8478
10755
  changed = rulesResult.changed || changed;
@@ -8513,6 +10790,7 @@ class AntigravityAdapter {
8513
10790
  // src/infrastructure/features/codex/adapters/CodexAdapter.ts
8514
10791
  import { homedir as homedir17 } from "node:os";
8515
10792
  import { resolve as resolve28 } from "node:path";
10793
+ import { rm as rm9 } from "node:fs/promises";
8516
10794
  class CodexAdapter {
8517
10795
  platformName = "codex";
8518
10796
  sourceLoader = new ApplySourceLoader;
@@ -8533,7 +10811,7 @@ class CodexAdapter {
8533
10811
  surface: "agents-md-skills-config-toml"
8534
10812
  };
8535
10813
  }
8536
- async applyAppyIntegration(request) {
10814
+ async applyApplyIntegration(request) {
8537
10815
  const target = await this.resolveTarget(request.projectPath, request);
8538
10816
  const userRoot = request.userConfigRootPath ? resolve28(request.userConfigRootPath) : resolve28(homedir17(), ".codex");
8539
10817
  const skillRoot = target.scope === "project" ? resolve28(request.projectPath, ".agents", "skills") : resolve28(userRoot, "skills");
@@ -8541,6 +10819,22 @@ class CodexAdapter {
8541
10819
  const source = await this.sourceLoader.load(request.projectPath);
8542
10820
  let changed = false;
8543
10821
  const fileChanges = [];
10822
+ if (request.override) {
10823
+ const skillsPath = skillRoot;
10824
+ const agentsPath = target.scope === "project" ? resolve28(request.projectPath, ".codex", "agents") : resolve28(userRoot, "agents");
10825
+ await Promise.all([
10826
+ rm9(skillsPath, { recursive: true, force: true }).catch((error) => {
10827
+ if (error.code !== "ENOENT") {
10828
+ throw error;
10829
+ }
10830
+ }),
10831
+ rm9(agentsPath, { recursive: true, force: true }).catch((error) => {
10832
+ if (error.code !== "ENOENT") {
10833
+ throw error;
10834
+ }
10835
+ })
10836
+ ]);
10837
+ }
8544
10838
  const rulesResult = await upsertManagedRuleDocument(target.configPath, source.rules, CodexAdapter.ruleMarkers, "No managed Codex rules were found.", Boolean(request.dryRun));
8545
10839
  changed = rulesResult.changed || changed;
8546
10840
  fileChanges.push(...rulesResult.paths);
@@ -8582,6 +10876,7 @@ class CodexAdapter {
8582
10876
  // src/infrastructure/features/cursor/adapters/CursorAdapter.ts
8583
10877
  import { homedir as homedir18 } from "node:os";
8584
10878
  import { resolve as resolve29 } from "node:path";
10879
+ import { rm as rm10 } from "node:fs/promises";
8585
10880
  class CursorAdapter {
8586
10881
  platformName = "cursor";
8587
10882
  sourceLoader = new ApplySourceLoader;
@@ -8594,11 +10889,35 @@ class CursorAdapter {
8594
10889
  surface: "rules-skills-commands-agents-mcp"
8595
10890
  };
8596
10891
  }
8597
- async applyAppyIntegration(request) {
10892
+ async applyApplyIntegration(request) {
8598
10893
  const target = await this.resolveTarget(request.projectPath, request);
8599
10894
  const source = await this.sourceLoader.load(request.projectPath);
8600
10895
  let changed = false;
8601
10896
  const fileChanges = [];
10897
+ if (request.override) {
10898
+ await Promise.all([
10899
+ rm10(resolve29(target.configPath, "rules"), { recursive: true, force: true }).catch((error) => {
10900
+ if (error.code !== "ENOENT") {
10901
+ throw error;
10902
+ }
10903
+ }),
10904
+ rm10(resolve29(target.configPath, "skills"), { recursive: true, force: true }).catch((error) => {
10905
+ if (error.code !== "ENOENT") {
10906
+ throw error;
10907
+ }
10908
+ }),
10909
+ rm10(resolve29(target.configPath, "commands"), { recursive: true, force: true }).catch((error) => {
10910
+ if (error.code !== "ENOENT") {
10911
+ throw error;
10912
+ }
10913
+ }),
10914
+ rm10(resolve29(target.configPath, "agents"), { recursive: true, force: true }).catch((error) => {
10915
+ if (error.code !== "ENOENT") {
10916
+ throw error;
10917
+ }
10918
+ })
10919
+ ]);
10920
+ }
8602
10921
  const rulesResult = await syncRulesAsFiles(source.rules, resolve29(target.configPath, "rules"), (rule, content) => ({
8603
10922
  relativePath: `${rule.id}.mdc`,
8604
10923
  content: ["---", `description: ${rule.id}`, "---", "", content.trimEnd()].join(`
@@ -8634,6 +10953,7 @@ class CursorAdapter {
8634
10953
  // src/infrastructure/features/windsurf/adapters/WindsurfAdapter.ts
8635
10954
  import { homedir as homedir19 } from "node:os";
8636
10955
  import { resolve as resolve30 } from "node:path";
10956
+ import { rm as rm11 } from "node:fs/promises";
8637
10957
  class WindsurfAdapter {
8638
10958
  platformName = "windsurf";
8639
10959
  sourceLoader = new ApplySourceLoader;
@@ -8650,15 +10970,38 @@ class WindsurfAdapter {
8650
10970
  surface: scope === "project" ? "agents-md-workflows-skills-mcp" : "global-rules-workflows-skills-mcp"
8651
10971
  };
8652
10972
  }
8653
- async applyAppyIntegration(request) {
10973
+ async applyApplyIntegration(request) {
8654
10974
  const target = await this.resolveTarget(request.projectPath, request);
8655
10975
  const userRoot = request.userConfigRootPath ? resolve30(request.userConfigRootPath) : resolve30(homedir19(), ".codeium", "windsurf");
8656
10976
  const workflowsRoot = target.scope === "project" ? resolve30(request.projectPath, ".windsurf", "workflows") : resolve30(userRoot, "workflows");
8657
10977
  const skillsRoot = target.scope === "project" ? resolve30(request.projectPath, ".windsurf", "skills") : resolve30(userRoot, "skills");
10978
+ const agentsRoot = target.scope === "project" ? resolve30(request.projectPath, ".windsurf", "agents") : resolve30(userRoot, "agents");
8658
10979
  const mcpPath = target.scope === "project" ? resolve30(request.projectPath, ".windsurf", "mcp_config.json") : resolve30(userRoot, "mcp_config.json");
8659
10980
  const source = await this.sourceLoader.load(request.projectPath);
8660
10981
  let changed = false;
8661
10982
  const fileChanges = [];
10983
+ if (request.override) {
10984
+ const workflowsPath = workflowsRoot;
10985
+ const skillsPath = skillsRoot;
10986
+ const agentsPath = agentsRoot;
10987
+ await Promise.all([
10988
+ rm11(workflowsPath, { recursive: true, force: true }).catch((error) => {
10989
+ if (error.code !== "ENOENT") {
10990
+ throw error;
10991
+ }
10992
+ }),
10993
+ rm11(skillsPath, { recursive: true, force: true }).catch((error) => {
10994
+ if (error.code !== "ENOENT") {
10995
+ throw error;
10996
+ }
10997
+ }),
10998
+ rm11(agentsPath, { recursive: true, force: true }).catch((error) => {
10999
+ if (error.code !== "ENOENT") {
11000
+ throw error;
11001
+ }
11002
+ })
11003
+ ]);
11004
+ }
8662
11005
  const rulesResult = await upsertManagedRuleDocument(target.configPath, source.rules, WindsurfAdapter.markers, "No managed Windsurf rules were found.", Boolean(request.dryRun));
8663
11006
  changed = rulesResult.changed || changed;
8664
11007
  fileChanges.push(...rulesResult.paths);
@@ -8668,7 +11011,6 @@ class WindsurfAdapter {
8668
11011
  const skillsResult = await syncSkills(source.skills, skillsRoot, Boolean(request.dryRun));
8669
11012
  changed = skillsResult.changed || changed;
8670
11013
  fileChanges.push(...skillsResult.paths);
8671
- const agentsRoot = target.scope === "project" ? resolve30(request.projectPath, ".windsurf", "agents") : resolve30(userRoot, "agents");
8672
11014
  const agentsResult = await syncAgentsAsMarkdown(source.agents, agentsRoot, Boolean(request.dryRun), true);
8673
11015
  changed = agentsResult.changed || changed;
8674
11016
  fileChanges.push(...agentsResult.paths);
@@ -8688,6 +11030,96 @@ class WindsurfAdapter {
8688
11030
  }
8689
11031
  }
8690
11032
 
11033
+ // src/infrastructure/features/forgecode/adapters/ForgeCodeAdapter.ts
11034
+ import { homedir as homedir20 } from "node:os";
11035
+ import { resolve as resolve31 } from "node:path";
11036
+ import { rm as rm12 } from "node:fs/promises";
11037
+
11038
+ class ForgeCodeAdapter {
11039
+ platformName = "forgecode";
11040
+ sourceLoader = new ApplySourceLoader;
11041
+ commandRenderer = CommandRendererFactory.getRenderer("forgecode");
11042
+ agentRenderer = AgentRendererFactory.getRenderer("forgecode");
11043
+ static markers = {
11044
+ start: "<!-- agent-ctrl:forgecode:start -->",
11045
+ end: "<!-- agent-ctrl:forgecode:end -->"
11046
+ };
11047
+ async resolveTarget(projectPath, request) {
11048
+ const scope = resolveApplyScope(request?.targetScope, "user", true);
11049
+ const userRoot = request?.userConfigRootPath ? resolve31(request.userConfigRootPath) : resolve31(homedir20(), ".forge");
11050
+ return {
11051
+ configPath: scope === "project" ? resolve31(projectPath, "AGENTS.md") : resolve31(userRoot, "AGENTS.md"),
11052
+ scope,
11053
+ surface: "agents-md-commands-skills-agents-mcp"
11054
+ };
11055
+ }
11056
+ async applyApplyIntegration(request) {
11057
+ const target = await this.resolveTarget(request.projectPath, request);
11058
+ const userRoot = request?.userConfigRootPath ? resolve31(request.userConfigRootPath) : resolve31(homedir20(), ".forge");
11059
+ const commandRoot = target.scope === "project" ? resolve31(request.projectPath, ".forge", "commands") : resolve31(userRoot, "commands");
11060
+ const skillRoot = target.scope === "project" ? resolve31(request.projectPath, ".forge", "skills") : resolve31(userRoot, "skills");
11061
+ const agentRoot = target.scope === "project" ? resolve31(request.projectPath, ".forge", "agents") : resolve31(userRoot, "agents");
11062
+ const mcpConfigPath = target.scope === "project" ? resolve31(request.projectPath, ".mcp.json") : resolve31(userRoot, ".mcp.json");
11063
+ const source = await this.sourceLoader.load(request.projectPath);
11064
+ let changed = false;
11065
+ const fileChanges = [];
11066
+ if (request.override) {
11067
+ const commandsPath = commandRoot;
11068
+ const skillsPath = skillRoot;
11069
+ const agentsPath = agentRoot;
11070
+ await Promise.all([
11071
+ rm12(commandsPath, { recursive: true, force: true }).catch((error) => {
11072
+ if (error.code !== "ENOENT") {
11073
+ throw error;
11074
+ }
11075
+ }),
11076
+ rm12(skillsPath, { recursive: true, force: true }).catch((error) => {
11077
+ if (error.code !== "ENOENT") {
11078
+ throw error;
11079
+ }
11080
+ }),
11081
+ rm12(agentsPath, { recursive: true, force: true }).catch((error) => {
11082
+ if (error.code !== "ENOENT") {
11083
+ throw error;
11084
+ }
11085
+ })
11086
+ ]);
11087
+ }
11088
+ const rulesResult = await upsertManagedRuleDocument(target.configPath, source.rules, ForgeCodeAdapter.markers, "No managed ForgeCode rules were found.", Boolean(request.dryRun));
11089
+ changed = rulesResult.changed || changed;
11090
+ fileChanges.push(...rulesResult.paths);
11091
+ const commandsResult = await syncCommandsAsMarkdownFlattened(source.commands, commandRoot, Boolean(request.dryRun), this.commandRenderer);
11092
+ changed = commandsResult.changed || changed;
11093
+ fileChanges.push(...commandsResult.paths);
11094
+ const skillsResult = await syncSkills(source.skills, skillRoot, Boolean(request.dryRun), "forgecode");
11095
+ changed = skillsResult.changed || changed;
11096
+ fileChanges.push(...skillsResult.paths);
11097
+ const agentsResult = await syncAgentsAsMarkdown(source.agents, agentRoot, Boolean(request.dryRun), true, this.agentRenderer);
11098
+ changed = agentsResult.changed || changed;
11099
+ fileChanges.push(...agentsResult.paths);
11100
+ const mcpResult = await mergeJsonObjectFile(mcpConfigPath, (existing) => renderForgeCodeMcpConfig(existing, source.mcpServers), Boolean(request.dryRun));
11101
+ changed = mcpResult.changed || changed;
11102
+ fileChanges.push(...mcpResult.paths);
11103
+ return {
11104
+ platform: this.platformName,
11105
+ configPath: target.configPath,
11106
+ scope: target.scope,
11107
+ surface: target.surface,
11108
+ status: toStatus(changed),
11109
+ message: "Applied ForgeCode AGENTS.md, commands, skills, agents, and MCP servers.",
11110
+ artifactCounts: {
11111
+ rules: source.rules.length,
11112
+ commands: source.commands.length,
11113
+ skills: source.skills.length,
11114
+ agents: source.agents.length,
11115
+ mcpServers: source.mcpServers.length
11116
+ },
11117
+ fileChanges,
11118
+ warnings: source.warnings
11119
+ };
11120
+ }
11121
+ }
11122
+
8691
11123
  // src/infrastructure/features/apply/adapters/PlatformAdapterRegistry.ts
8692
11124
  class PlatformAdapterRegistry {
8693
11125
  registry = new Map;
@@ -8696,6 +11128,7 @@ class PlatformAdapterRegistry {
8696
11128
  claude: () => new ClaudeApplyAdapter,
8697
11129
  codex: () => new CodexAdapter,
8698
11130
  cursor: () => new CursorAdapter,
11131
+ forgecode: () => new ForgeCodeAdapter,
8699
11132
  gemini: () => new GeminiAdapter,
8700
11133
  kilo: () => new KiloAdapter,
8701
11134
  opencode: () => new OpenCodeAdapter,
@@ -8745,7 +11178,7 @@ class ApplyCommand {
8745
11178
  const adapter = this.adapterRegistry.resolve(selectedPlatform);
8746
11179
  const startedAt = Date.now();
8747
11180
  try {
8748
- const applyResult = await adapter.applyAppyIntegration({
11181
+ const applyResult = await adapter.applyApplyIntegration({
8749
11182
  projectPath,
8750
11183
  dryRun,
8751
11184
  override,
@@ -8764,6 +11197,7 @@ class ApplyCommand {
8764
11197
  scope: applyResult.scope,
8765
11198
  surface: applyResult.surface,
8766
11199
  message: applyResult.message,
11200
+ artifactCounts: applyResult.artifactCounts,
8767
11201
  durationMs,
8768
11202
  fileChanges: [...applyResult.fileChanges ?? []],
8769
11203
  warnings
@@ -8799,22 +11233,80 @@ function getLegacyGlobalOptions() {
8799
11233
  // src/presentation/cli/features/apply/commands/apply.ts
8800
11234
  function createApplyCommand() {
8801
11235
  const supportedPlatformsDisplay = getSupportedApplyPlatformsDisplay();
8802
- return new Command("apply").description("Sync .agent-ctrl artifacts into one selected platform's native configuration").argument("<platform>", `Target platform. Supported platforms: ${supportedPlatformsDisplay}`).option("-d, --dry-run", "Show selected-platform changes without writing files", false).option("-o, --override", "Replace conflicting managed configuration with agent-ctrl state", false).addOption(new Option("-p, --project", "Apply to project-based configuration instead of the default global user scope").default(false).conflicts("user").conflicts("path")).option("-u, --user", "Apply to global user configuration when the platform documents a file-backed user scope", false).option("--path <path>", "Custom platform user configuration root path").action(async (platform, options) => {
8803
- if (options.path) {
8804
- const pathError = validateUserPath(options.path, "--path");
8805
- if (pathError) {
8806
- console.error(`✗ ${pathError}`);
8807
- process.exit(1);
11236
+ return new Command("apply").description("Sync .agent-ctrl artifacts into one selected platform's native configuration").argument("[platform]", `Target platform. Supported platforms: ${supportedPlatformsDisplay}`).option("-d, --dry-run", "Show selected-platform changes without writing files", false).option("-o, --override", "Replace conflicting managed configuration with agent-ctrl state", false).option("-v, --verbose", "Show detailed output including warnings", false).addOption(new Option("-p, --project", "Apply to project-based configuration instead of the default global user scope").default(false).conflicts("user").conflicts("path")).option("-u, --user", "Apply to global user configuration when the platform documents a file-backed user scope", false).option("--path <path>", "Custom platform user configuration root path").option("--no-prompt", "Skip confirmation prompt", false).action(async (platform, options) => {
11237
+ if (options.verbose) {
11238
+ process.env.DEBUG = "true";
11239
+ }
11240
+ if (!platform) {
11241
+ const selected = await PromptService.selectMany({
11242
+ message: "Select platforms to apply configuration to",
11243
+ options: SUPPORTED_APPLY_PLATFORMS.map((p2) => ({ value: p2, label: getPlatformDisplayName(p2) })),
11244
+ required: true
11245
+ });
11246
+ if (selected === null || typeof selected === "symbol") {
11247
+ PromptService.handleCancellation();
11248
+ }
11249
+ const platforms = selected;
11250
+ for (let i = 0;i < platforms.length; i++) {
11251
+ await applyToPlatform(platforms[i], options);
8808
11252
  }
11253
+ LogService.info(`Applied to ${platforms.length} platform(s)`);
11254
+ return;
8809
11255
  }
8810
- const globalConfigRoot = resolveConfigRoot();
8811
- const isGlobalConfig = !options.path;
8812
- const sourcePath = isGlobalConfig ? resolve31(globalConfigRoot, "..") : resolve31(options.path);
8813
- const applyCommand = new ApplyCommand;
8814
- const userConfigRootPath = options.path ? resolve31(options.path) : undefined;
8815
- const targetScope = options.project ? "project" : options.user ? "user" : undefined;
8816
- try {
8817
- const result = await applyCommand.execute({
11256
+ await applyToPlatform(platform, options);
11257
+ });
11258
+ }
11259
+ function displayArtifactCounts(counts) {
11260
+ const items = [];
11261
+ if (counts.rules !== undefined)
11262
+ items.push(`${counts.rules} rules`);
11263
+ if (counts.commands !== undefined)
11264
+ items.push(`${counts.commands} commands`);
11265
+ if (counts.skills !== undefined)
11266
+ items.push(`${counts.skills} skills`);
11267
+ if (counts.agents !== undefined)
11268
+ items.push(`${counts.agents} agents`);
11269
+ if (counts.mcpServers !== undefined)
11270
+ items.push(`${counts.mcpServers} MCP servers`);
11271
+ if (items.length > 0) {
11272
+ LogService.note(items.join(", "), "Artifacts:");
11273
+ }
11274
+ }
11275
+ async function applyToPlatform(platform, options) {
11276
+ if (options.path) {
11277
+ const pathError = validateUserPath(options.path, "--path");
11278
+ if (pathError) {
11279
+ PromptService.cancel(pathError);
11280
+ process.exit(1);
11281
+ }
11282
+ }
11283
+ const globalConfigRoot = resolveConfigRoot();
11284
+ const isGlobalConfig = !options.path;
11285
+ const sourcePath = isGlobalConfig ? resolve32(globalConfigRoot, "..") : resolve32(options.path);
11286
+ const applyCommand = new ApplyCommand;
11287
+ const userConfigRootPath = options.path ? resolve32(options.path) : undefined;
11288
+ const targetScope = options.project ? "project" : options.user ? "user" : undefined;
11289
+ const usePrompt = options.prompt !== false;
11290
+ const platformDisplay = getPlatformDisplayName(platform);
11291
+ if (usePrompt) {
11292
+ LogService.intro(`Applying to ${platformDisplay}`);
11293
+ const confirmed = await PromptService.confirm({
11294
+ message: `Apply configuration to ${platformDisplay}?`,
11295
+ initial: true
11296
+ });
11297
+ if (confirmed === false || confirmed === null) {
11298
+ PromptService.handleCancellation("Apply cancelled by user");
11299
+ }
11300
+ if (typeof confirmed === "symbol") {
11301
+ PromptService.handleCancellation();
11302
+ }
11303
+ }
11304
+ try {
11305
+ const result = await PromptService.withCancellation(async () => {
11306
+ if (usePrompt) {
11307
+ PromptService.startTask("Syncing configuration");
11308
+ }
11309
+ return await applyCommand.execute({
8818
11310
  projectPath: sourcePath,
8819
11311
  platform,
8820
11312
  dryRun: options.dryRun,
@@ -8822,88 +11314,82 @@ function createApplyCommand() {
8822
11314
  targetScope,
8823
11315
  userConfigRootPath
8824
11316
  });
8825
- if (!result.success) {
8826
- if (result.error instanceof UserError || result.error instanceof SystemError) {
8827
- console.error(`✗ ${result.error.message}`);
8828
- process.exit(result.error.exitCode);
8829
- }
8830
- console.error(`✗ Unexpected error: ${result.error}`);
8831
- process.exit(2);
8832
- }
8833
- const { verbose } = getLegacyGlobalOptions();
8834
- const {
8835
- platform: selectedPlatform,
8836
- status,
8837
- configPath,
8838
- scope,
8839
- surface,
8840
- fileChanges,
8841
- warnings,
8842
- durationMs
8843
- } = result.data;
8844
- if (options.dryRun) {
8845
- console.log(`[Dry run] Selected platform: ${selectedPlatform}`);
8846
- console.log(`[Dry run] Result: ${status}`);
8847
- console.log(`[Dry run] Scope: ${scope}`);
8848
- console.log(`[Dry run] Surface: ${surface}`);
8849
- console.log(`[Dry run] Target path: ${configPath}`);
8850
- if (scope === "user" && userConfigRootPath) {
8851
- console.log(`[Dry run] User configuration root: ${userConfigRootPath}`);
8852
- }
8853
- if (fileChanges.length > 0) {
8854
- console.log("[Dry run] Files:");
8855
- for (const filePath of fileChanges) {
8856
- console.log(` - ${filePath}`);
8857
- }
8858
- }
8859
- console.log(`[Dry run] Estimated duration: ${durationMs}ms`);
8860
- } else {
8861
- if (status === "unchanged") {
8862
- console.log(`✓ ${selectedPlatform}: unchanged`);
8863
- } else {
8864
- console.log(`✓ ${selectedPlatform}: success`);
8865
- }
8866
- console.log(`Scope: ${scope}`);
8867
- console.log(`Surface: ${surface}`);
8868
- if (scope === "user" && userConfigRootPath) {
8869
- console.log(`User configuration root: ${userConfigRootPath}`);
8870
- }
8871
- console.log(`Configuration path: ${configPath}`);
8872
- if (fileChanges.length > 0) {
8873
- console.log("Files:");
8874
- for (const filePath of fileChanges) {
8875
- console.log(` - ${filePath}`);
8876
- }
8877
- }
8878
- console.log(`Duration: ${durationMs}ms`);
8879
- }
8880
- const criticalWarnings = warnings.filter((w) => w.includes("does not have a documented apply target for"));
8881
- const noiseWarnings = warnings.filter((w) => !w.includes("does not have a documented apply target for"));
8882
- if (criticalWarnings.length > 0) {
8883
- console.log(`
8884
- Warnings:`);
8885
- for (const warning of criticalWarnings) {
8886
- console.log(` - ${warning}`);
8887
- }
8888
- }
8889
- if (verbose && noiseWarnings.length > 0) {
8890
- const filteredNoiseWarnings = noiseWarnings.filter((w) => !w.includes("Skipped .gitkeep") && !w.includes("invalid extension"));
8891
- if (filteredNoiseWarnings.length > 0) {
8892
- if (criticalWarnings.length === 0) {
8893
- console.log(`
8894
- Warnings:`);
8895
- }
8896
- for (const warning of filteredNoiseWarnings) {
8897
- console.log(` - ${warning}`);
8898
- }
8899
- }
11317
+ });
11318
+ if (!result) {
11319
+ return;
11320
+ }
11321
+ if (!result.success) {
11322
+ const platformDisplay2 = getPlatformDisplayName(platform);
11323
+ if (result.error instanceof UserError || result.error instanceof SystemError) {
11324
+ LogService.error(`[${platformDisplay2}] ${result.error.message} (Path: ${sourcePath})`);
11325
+ process.exit(result.error.exitCode);
8900
11326
  }
8901
- } catch (error) {
8902
- const errorMessage = error instanceof Error ? error.message : String(error);
8903
- console.error(`✗ Unexpected error applying to '${platform}': ${errorMessage}`);
11327
+ LogService.error(`[${platformDisplay2}] Unexpected error: ${result.error} (Path: ${sourcePath})`);
8904
11328
  process.exit(2);
8905
11329
  }
8906
- });
11330
+ const verbose = options.verbose ?? getLegacyGlobalOptions().verbose;
11331
+ const {
11332
+ platform: selectedPlatform,
11333
+ status,
11334
+ configPath,
11335
+ scope,
11336
+ surface,
11337
+ artifactCounts,
11338
+ fileChanges,
11339
+ warnings,
11340
+ durationMs
11341
+ } = result.data;
11342
+ if (options.dryRun) {
11343
+ if (usePrompt)
11344
+ PromptService.stopTask("Dry run complete");
11345
+ LogService.info(`Selected platform: ${selectedPlatform}`);
11346
+ LogService.info(`Result: ${status}`);
11347
+ LogService.info(`Scope: ${scope}`);
11348
+ LogService.info(`Surface: ${surface}`);
11349
+ LogService.info(`Target path: ${configPath}`);
11350
+ if (scope === "user" && userConfigRootPath)
11351
+ LogService.info(`User configuration root: ${userConfigRootPath}`);
11352
+ if (artifactCounts)
11353
+ displayArtifactCounts(artifactCounts);
11354
+ if (verbose && fileChanges.length > 0)
11355
+ LogService.note(fileChanges.join(`
11356
+ `), "Files:");
11357
+ LogService.info(`Estimated duration: ${durationMs}ms`);
11358
+ } else {
11359
+ if (status === "unchanged")
11360
+ LogService.info(`${selectedPlatform}: unchanged`);
11361
+ else
11362
+ LogService.info(`${selectedPlatform}: success`);
11363
+ LogService.info(`Scope: ${scope}`);
11364
+ LogService.info(`Surface: ${surface}`);
11365
+ if (scope === "user" && userConfigRootPath)
11366
+ LogService.info(`User configuration root: ${userConfigRootPath}`);
11367
+ LogService.info(`Configuration path: ${configPath}`);
11368
+ if (artifactCounts)
11369
+ displayArtifactCounts(artifactCounts);
11370
+ if (verbose && fileChanges.length > 0)
11371
+ LogService.note(fileChanges.join(`
11372
+ `), "Files:");
11373
+ LogService.info(`Duration: ${durationMs}ms`);
11374
+ if (usePrompt)
11375
+ LogService.outro(`Applied to ${selectedPlatform}`);
11376
+ }
11377
+ const criticalWarnings = warnings.filter((w3) => w3.includes("does not have a documented apply target for"));
11378
+ const noiseWarnings = warnings.filter((w3) => !w3.includes("does not have a documented apply target for"));
11379
+ if (criticalWarnings.length > 0)
11380
+ LogService.note(criticalWarnings.join(`
11381
+ `), "Warnings:");
11382
+ if (verbose && noiseWarnings.length > 0) {
11383
+ const filteredNoiseWarnings = noiseWarnings.filter((w3) => !w3.includes("Skipped .gitkeep") && !w3.includes("invalid extension"));
11384
+ if (filteredNoiseWarnings.length > 0 && criticalWarnings.length === 0)
11385
+ LogService.note(filteredNoiseWarnings.join(`
11386
+ `), "Warnings:");
11387
+ }
11388
+ } catch (error) {
11389
+ const errorMessage = error instanceof Error ? error.message : String(error);
11390
+ LogService.error(`Error: ${errorMessage}`);
11391
+ process.exit(2);
11392
+ }
8907
11393
  }
8908
11394
 
8909
11395
  // src/presentation/cli/shared/middleware/errorHandler.ts
@@ -8923,27 +11409,27 @@ class ErrorHandler {
8923
11409
  }
8924
11410
  handleBaseError(error) {
8925
11411
  if (!this.options.quiet) {
8926
- console.error(`✗ ${error.message}`);
11412
+ LogService.error(error.message);
8927
11413
  if (this.options.verbose && error.stack) {
8928
- console.error(error.stack);
11414
+ LogService.error(error.stack);
8929
11415
  }
8930
11416
  }
8931
11417
  process.exit(error.exitCode);
8932
11418
  }
8933
11419
  handleGenericError(error) {
8934
11420
  if (!this.options.quiet) {
8935
- console.error(`✗ Unexpected error: ${error.message}`);
11421
+ LogService.error(`Unexpected error: ${error.message}`);
8936
11422
  if (this.options.verbose && error.stack) {
8937
- console.error(error.stack);
11423
+ LogService.error(error.stack);
8938
11424
  }
8939
11425
  }
8940
11426
  process.exit(2);
8941
11427
  }
8942
11428
  handleUnknownError(error) {
8943
11429
  if (!this.options.quiet) {
8944
- console.error(`✗ Unknown error occurred`);
11430
+ LogService.error("Unknown error occurred");
8945
11431
  if (this.options.verbose) {
8946
- console.error(error);
11432
+ LogService.error(String(error));
8947
11433
  }
8948
11434
  }
8949
11435
  process.exit(2);
@@ -8969,9 +11455,9 @@ process.on("unhandledRejection", (reason) => {
8969
11455
  errorHandler.handle(reason);
8970
11456
  });
8971
11457
  process.on("SIGINT", () => {
8972
- console.log(`
8973
-
8974
- Operation cancelled by user`);
11458
+ gt(import_picocolors2.default.yellow("Operation cancelled by user"));
8975
11459
  process.exit(0);
8976
11460
  });
11461
+ mt(import_picocolors2.default.inverse(" agent-ctrl "));
8977
11462
  await program2.parseAsync(process.argv);
11463
+ gt(import_picocolors2.default.cyan("Execution completed"));