@iceinvein/agent-skills 0.1.21 → 0.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -1,8 +1,199 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
3
  import { createRequire } from "node:module";
4
+ var __create = Object.create;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __defProp = Object.defineProperty;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ function __accessProp(key) {
10
+ return this[key];
11
+ }
12
+ var __toESMCache_node;
13
+ var __toESMCache_esm;
14
+ var __toESM = (mod, isNodeMode, target) => {
15
+ var canCache = mod != null && typeof mod === "object";
16
+ if (canCache) {
17
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
18
+ var cached = cache.get(mod);
19
+ if (cached)
20
+ return cached;
21
+ }
22
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
23
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
24
+ for (let key of __getOwnPropNames(mod))
25
+ if (!__hasOwnProp.call(to, key))
26
+ __defProp(to, key, {
27
+ get: __accessProp.bind(mod, key),
28
+ enumerable: true
29
+ });
30
+ if (canCache)
31
+ cache.set(mod, to);
32
+ return to;
33
+ };
34
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
4
35
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
5
36
 
37
+ // node_modules/cli-width/index.js
38
+ var require_cli_width = __commonJS((exports, module) => {
39
+ module.exports = cliWidth;
40
+ function normalizeOpts(options) {
41
+ const defaultOpts = {
42
+ defaultWidth: 0,
43
+ output: process.stdout,
44
+ tty: __require("tty")
45
+ };
46
+ if (!options) {
47
+ return defaultOpts;
48
+ }
49
+ Object.keys(defaultOpts).forEach(function(key) {
50
+ if (!options[key]) {
51
+ options[key] = defaultOpts[key];
52
+ }
53
+ });
54
+ return options;
55
+ }
56
+ function cliWidth(options) {
57
+ const opts = normalizeOpts(options);
58
+ if (opts.output.getWindowSize) {
59
+ return opts.output.getWindowSize()[0] || opts.defaultWidth;
60
+ }
61
+ if (opts.tty.getWindowSize) {
62
+ return opts.tty.getWindowSize()[1] || opts.defaultWidth;
63
+ }
64
+ if (opts.output.columns) {
65
+ return opts.output.columns;
66
+ }
67
+ if (process.env.CLI_WIDTH) {
68
+ const width = parseInt(process.env.CLI_WIDTH, 10);
69
+ if (!isNaN(width) && width !== 0) {
70
+ return width;
71
+ }
72
+ }
73
+ return opts.defaultWidth;
74
+ }
75
+ });
76
+
77
+ // node_modules/mute-stream/lib/index.js
78
+ var require_lib = __commonJS((exports, module) => {
79
+ var Stream = __require("stream");
80
+
81
+ class MuteStream extends Stream {
82
+ #isTTY = null;
83
+ constructor(opts = {}) {
84
+ super(opts);
85
+ this.writable = this.readable = true;
86
+ this.muted = false;
87
+ this.on("pipe", this._onpipe);
88
+ this.replace = opts.replace;
89
+ this._prompt = opts.prompt || null;
90
+ this._hadControl = false;
91
+ }
92
+ #destSrc(key, def) {
93
+ if (this._dest) {
94
+ return this._dest[key];
95
+ }
96
+ if (this._src) {
97
+ return this._src[key];
98
+ }
99
+ return def;
100
+ }
101
+ #proxy(method, ...args) {
102
+ if (typeof this._dest?.[method] === "function") {
103
+ this._dest[method](...args);
104
+ }
105
+ if (typeof this._src?.[method] === "function") {
106
+ this._src[method](...args);
107
+ }
108
+ }
109
+ get isTTY() {
110
+ if (this.#isTTY !== null) {
111
+ return this.#isTTY;
112
+ }
113
+ return this.#destSrc("isTTY", false);
114
+ }
115
+ set isTTY(val) {
116
+ this.#isTTY = val;
117
+ }
118
+ get rows() {
119
+ return this.#destSrc("rows");
120
+ }
121
+ get columns() {
122
+ return this.#destSrc("columns");
123
+ }
124
+ mute() {
125
+ this.muted = true;
126
+ }
127
+ unmute() {
128
+ this.muted = false;
129
+ }
130
+ _onpipe(src) {
131
+ this._src = src;
132
+ }
133
+ pipe(dest, options) {
134
+ this._dest = dest;
135
+ return super.pipe(dest, options);
136
+ }
137
+ pause() {
138
+ if (this._src) {
139
+ return this._src.pause();
140
+ }
141
+ }
142
+ resume() {
143
+ if (this._src) {
144
+ return this._src.resume();
145
+ }
146
+ }
147
+ write(c) {
148
+ if (this.muted) {
149
+ if (!this.replace) {
150
+ return true;
151
+ }
152
+ if (c.match(/^\u001b/)) {
153
+ if (c.indexOf(this._prompt) === 0) {
154
+ c = c.slice(this._prompt.length);
155
+ c = c.replace(/./g, this.replace);
156
+ c = this._prompt + c;
157
+ }
158
+ this._hadControl = true;
159
+ return this.emit("data", c);
160
+ } else {
161
+ if (this._prompt && this._hadControl && c.indexOf(this._prompt) === 0) {
162
+ this._hadControl = false;
163
+ this.emit("data", this._prompt);
164
+ c = c.slice(this._prompt.length);
165
+ }
166
+ c = c.toString().replace(/./g, this.replace);
167
+ }
168
+ }
169
+ this.emit("data", c);
170
+ }
171
+ end(c) {
172
+ if (this.muted) {
173
+ if (c && this.replace) {
174
+ c = c.toString().replace(/./g, this.replace);
175
+ } else {
176
+ c = null;
177
+ }
178
+ }
179
+ if (c) {
180
+ this.emit("data", c);
181
+ }
182
+ this.emit("end");
183
+ }
184
+ destroy(...args) {
185
+ return this.#proxy("destroy", ...args);
186
+ }
187
+ destroySoon(...args) {
188
+ return this.#proxy("destroySoon", ...args);
189
+ }
190
+ close(...args) {
191
+ return this.#proxy("close", ...args);
192
+ }
193
+ }
194
+ module.exports = MuteStream;
195
+ });
196
+
6
197
  // src/cli/detect.ts
7
198
  import { existsSync } from "node:fs";
8
199
  import { join } from "node:path";
@@ -819,11 +1010,19 @@ function skillVersionChanged(repoRoot, skillName, sinceTag) {
819
1010
  `).some((l) => l.startsWith("+") && !l.startsWith("+++") && l.includes('"version"'));
820
1011
  return hasRemoved && hasAdded;
821
1012
  }
1013
+ function manifestExistedAtTag(repoRoot, skillName, sinceTag) {
1014
+ if (!sinceTag)
1015
+ return false;
1016
+ const result = Bun.spawnSync(["git", "cat-file", "-e", `${sinceTag}:skills/${skillName}/skill.json`], { cwd: repoRoot, stderr: "pipe" });
1017
+ return result.exitCode === 0;
1018
+ }
822
1019
  async function bumpAllChanged(repoRoot, level, dryRun) {
823
1020
  const tag = getLatestTag(repoRoot);
824
1021
  const changed = getChangedSkills(repoRoot, tag);
825
1022
  const results = [];
826
1023
  for (const skillName of changed) {
1024
+ if (!manifestExistedAtTag(repoRoot, skillName, tag))
1025
+ continue;
827
1026
  if (skillVersionChanged(repoRoot, skillName, tag))
828
1027
  continue;
829
1028
  if (dryRun) {
@@ -885,57 +1084,1871 @@ async function checkForUpdates(cwd) {
885
1084
  // src/cli/types.ts
886
1085
  var TOOL_NAMES2 = ["claude", "cursor", "codex", "gemini"];
887
1086
 
888
- // src/cli/prompt.ts
889
- import { createInterface } from "node:readline";
890
- function ask(question) {
891
- const rl = createInterface({ input: process.stdin, output: process.stdout });
892
- return new Promise((resolve) => {
893
- rl.question(question, (answer) => {
894
- rl.close();
895
- resolve(answer.trim());
1087
+ // node_modules/@inquirer/core/dist/lib/key.js
1088
+ var isUpKey = (key, keybindings = []) => key.name === "up" || keybindings.includes("vim") && key.name === "k" || keybindings.includes("emacs") && key.ctrl && key.name === "p";
1089
+ var isDownKey = (key, keybindings = []) => key.name === "down" || keybindings.includes("vim") && key.name === "j" || keybindings.includes("emacs") && key.ctrl && key.name === "n";
1090
+ var isSpaceKey = (key) => key.name === "space";
1091
+ var isBackspaceKey = (key) => key.name === "backspace";
1092
+ var isNumberKey = (key) => "1234567890".includes(key.name);
1093
+ var isEnterKey = (key) => key.name === "enter" || key.name === "return";
1094
+ // node_modules/@inquirer/core/dist/lib/errors.js
1095
+ class AbortPromptError extends Error {
1096
+ name = "AbortPromptError";
1097
+ message = "Prompt was aborted";
1098
+ constructor(options) {
1099
+ super();
1100
+ this.cause = options?.cause;
1101
+ }
1102
+ }
1103
+
1104
+ class CancelPromptError extends Error {
1105
+ name = "CancelPromptError";
1106
+ message = "Prompt was canceled";
1107
+ }
1108
+
1109
+ class ExitPromptError extends Error {
1110
+ name = "ExitPromptError";
1111
+ }
1112
+
1113
+ class HookError extends Error {
1114
+ name = "HookError";
1115
+ }
1116
+
1117
+ class ValidationError extends Error {
1118
+ name = "ValidationError";
1119
+ }
1120
+ // node_modules/@inquirer/core/dist/lib/use-state.js
1121
+ import { AsyncResource as AsyncResource2 } from "node:async_hooks";
1122
+
1123
+ // node_modules/@inquirer/core/dist/lib/hook-engine.js
1124
+ import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
1125
+ var hookStorage = new AsyncLocalStorage;
1126
+ function createStore(rl) {
1127
+ const store = {
1128
+ rl,
1129
+ hooks: [],
1130
+ hooksCleanup: [],
1131
+ hooksEffect: [],
1132
+ index: 0,
1133
+ handleChange() {}
1134
+ };
1135
+ return store;
1136
+ }
1137
+ function withHooks(rl, cb) {
1138
+ const store = createStore(rl);
1139
+ return hookStorage.run(store, () => {
1140
+ function cycle(render) {
1141
+ store.handleChange = () => {
1142
+ store.index = 0;
1143
+ render();
1144
+ };
1145
+ store.handleChange();
1146
+ }
1147
+ return cb(cycle);
1148
+ });
1149
+ }
1150
+ function getStore() {
1151
+ const store = hookStorage.getStore();
1152
+ if (!store) {
1153
+ throw new HookError("[Inquirer] Hook functions can only be called from within a prompt");
1154
+ }
1155
+ return store;
1156
+ }
1157
+ function readline() {
1158
+ return getStore().rl;
1159
+ }
1160
+ function withUpdates(fn) {
1161
+ const wrapped = (...args) => {
1162
+ const store = getStore();
1163
+ let shouldUpdate = false;
1164
+ const oldHandleChange = store.handleChange;
1165
+ store.handleChange = () => {
1166
+ shouldUpdate = true;
1167
+ };
1168
+ const returnValue = fn(...args);
1169
+ if (shouldUpdate) {
1170
+ oldHandleChange();
1171
+ }
1172
+ store.handleChange = oldHandleChange;
1173
+ return returnValue;
1174
+ };
1175
+ return AsyncResource.bind(wrapped);
1176
+ }
1177
+ function withPointer(cb) {
1178
+ const store = getStore();
1179
+ const { index } = store;
1180
+ const pointer = {
1181
+ get() {
1182
+ return store.hooks[index];
1183
+ },
1184
+ set(value) {
1185
+ store.hooks[index] = value;
1186
+ },
1187
+ initialized: index in store.hooks
1188
+ };
1189
+ const returnValue = cb(pointer);
1190
+ store.index++;
1191
+ return returnValue;
1192
+ }
1193
+ function handleChange() {
1194
+ getStore().handleChange();
1195
+ }
1196
+ var effectScheduler = {
1197
+ queue(cb) {
1198
+ const store = getStore();
1199
+ const { index } = store;
1200
+ store.hooksEffect.push(() => {
1201
+ store.hooksCleanup[index]?.();
1202
+ const cleanFn = cb(readline());
1203
+ if (cleanFn != null && typeof cleanFn !== "function") {
1204
+ throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
1205
+ }
1206
+ store.hooksCleanup[index] = cleanFn;
1207
+ });
1208
+ },
1209
+ run() {
1210
+ const store = getStore();
1211
+ withUpdates(() => {
1212
+ store.hooksEffect.forEach((effect) => {
1213
+ effect();
1214
+ });
1215
+ store.hooksEffect.length = 0;
1216
+ })();
1217
+ },
1218
+ clearAll() {
1219
+ const store = getStore();
1220
+ store.hooksCleanup.forEach((cleanFn) => {
1221
+ cleanFn?.();
1222
+ });
1223
+ store.hooksEffect.length = 0;
1224
+ store.hooksCleanup.length = 0;
1225
+ }
1226
+ };
1227
+
1228
+ // node_modules/@inquirer/core/dist/lib/use-state.js
1229
+ function isFactory(value) {
1230
+ return typeof value === "function";
1231
+ }
1232
+ function useState(defaultValue) {
1233
+ return withPointer((pointer) => {
1234
+ const setState = AsyncResource2.bind(function setState2(newValue) {
1235
+ if (pointer.get() !== newValue) {
1236
+ pointer.set(newValue);
1237
+ handleChange();
1238
+ }
896
1239
  });
1240
+ if (pointer.initialized) {
1241
+ return [pointer.get(), setState];
1242
+ }
1243
+ const value = isFactory(defaultValue) ? defaultValue() : defaultValue;
1244
+ pointer.set(value);
1245
+ return [value, setState];
897
1246
  });
898
1247
  }
899
- async function promptSelect(message, options) {
900
- console.log(`
901
- ${message}
902
- `);
903
- for (let i = 0;i < options.length; i++) {
904
- console.log(` ${i + 1}) ${options[i].label}`);
1248
+
1249
+ // node_modules/@inquirer/core/dist/lib/use-effect.js
1250
+ function useEffect(cb, depArray) {
1251
+ withPointer((pointer) => {
1252
+ const oldDeps = pointer.get();
1253
+ const hasChanged = !Array.isArray(oldDeps) || depArray.some((dep, i) => !Object.is(dep, oldDeps[i]));
1254
+ if (hasChanged) {
1255
+ effectScheduler.queue(cb);
1256
+ }
1257
+ pointer.set(depArray);
1258
+ });
1259
+ }
1260
+
1261
+ // node_modules/@inquirer/core/dist/lib/theme.js
1262
+ import { styleText } from "node:util";
1263
+
1264
+ // node_modules/@inquirer/figures/dist/index.js
1265
+ import process2 from "node:process";
1266
+ function isUnicodeSupported() {
1267
+ if (!process2.platform.startsWith("win")) {
1268
+ return process2.env["TERM"] !== "linux";
1269
+ }
1270
+ return Boolean(process2.env["CI"]) || Boolean(process2.env["WT_SESSION"]) || Boolean(process2.env["TERMINUS_SUBLIME"]) || process2.env["ConEmuTask"] === "{cmd::Cmder}" || process2.env["TERM_PROGRAM"] === "Terminus-Sublime" || process2.env["TERM_PROGRAM"] === "vscode" || process2.env["TERM"] === "xterm-256color" || process2.env["TERM"] === "alacritty" || process2.env["TERMINAL_EMULATOR"] === "JetBrains-JediTerm";
1271
+ }
1272
+ var common = {
1273
+ circleQuestionMark: "(?)",
1274
+ questionMarkPrefix: "(?)",
1275
+ square: "█",
1276
+ squareDarkShade: "▓",
1277
+ squareMediumShade: "▒",
1278
+ squareLightShade: "░",
1279
+ squareTop: "▀",
1280
+ squareBottom: "▄",
1281
+ squareLeft: "▌",
1282
+ squareRight: "▐",
1283
+ squareCenter: "■",
1284
+ bullet: "●",
1285
+ dot: "․",
1286
+ ellipsis: "…",
1287
+ pointerSmall: "›",
1288
+ triangleUp: "▲",
1289
+ triangleUpSmall: "▴",
1290
+ triangleDown: "▼",
1291
+ triangleDownSmall: "▾",
1292
+ triangleLeftSmall: "◂",
1293
+ triangleRightSmall: "▸",
1294
+ home: "⌂",
1295
+ heart: "♥",
1296
+ musicNote: "♪",
1297
+ musicNoteBeamed: "♫",
1298
+ arrowUp: "↑",
1299
+ arrowDown: "↓",
1300
+ arrowLeft: "←",
1301
+ arrowRight: "→",
1302
+ arrowLeftRight: "↔",
1303
+ arrowUpDown: "↕",
1304
+ almostEqual: "≈",
1305
+ notEqual: "≠",
1306
+ lessOrEqual: "≤",
1307
+ greaterOrEqual: "≥",
1308
+ identical: "≡",
1309
+ infinity: "∞",
1310
+ subscriptZero: "₀",
1311
+ subscriptOne: "₁",
1312
+ subscriptTwo: "₂",
1313
+ subscriptThree: "₃",
1314
+ subscriptFour: "₄",
1315
+ subscriptFive: "₅",
1316
+ subscriptSix: "₆",
1317
+ subscriptSeven: "₇",
1318
+ subscriptEight: "₈",
1319
+ subscriptNine: "₉",
1320
+ oneHalf: "½",
1321
+ oneThird: "⅓",
1322
+ oneQuarter: "¼",
1323
+ oneFifth: "⅕",
1324
+ oneSixth: "⅙",
1325
+ oneEighth: "⅛",
1326
+ twoThirds: "⅔",
1327
+ twoFifths: "⅖",
1328
+ threeQuarters: "¾",
1329
+ threeFifths: "⅗",
1330
+ threeEighths: "⅜",
1331
+ fourFifths: "⅘",
1332
+ fiveSixths: "⅚",
1333
+ fiveEighths: "⅝",
1334
+ sevenEighths: "⅞",
1335
+ line: "─",
1336
+ lineBold: "━",
1337
+ lineDouble: "═",
1338
+ lineDashed0: "┄",
1339
+ lineDashed1: "┅",
1340
+ lineDashed2: "┈",
1341
+ lineDashed3: "┉",
1342
+ lineDashed4: "╌",
1343
+ lineDashed5: "╍",
1344
+ lineDashed6: "╴",
1345
+ lineDashed7: "╶",
1346
+ lineDashed8: "╸",
1347
+ lineDashed9: "╺",
1348
+ lineDashed10: "╼",
1349
+ lineDashed11: "╾",
1350
+ lineDashed12: "−",
1351
+ lineDashed13: "–",
1352
+ lineDashed14: "‐",
1353
+ lineDashed15: "⁃",
1354
+ lineVertical: "│",
1355
+ lineVerticalBold: "┃",
1356
+ lineVerticalDouble: "║",
1357
+ lineVerticalDashed0: "┆",
1358
+ lineVerticalDashed1: "┇",
1359
+ lineVerticalDashed2: "┊",
1360
+ lineVerticalDashed3: "┋",
1361
+ lineVerticalDashed4: "╎",
1362
+ lineVerticalDashed5: "╏",
1363
+ lineVerticalDashed6: "╵",
1364
+ lineVerticalDashed7: "╷",
1365
+ lineVerticalDashed8: "╹",
1366
+ lineVerticalDashed9: "╻",
1367
+ lineVerticalDashed10: "╽",
1368
+ lineVerticalDashed11: "╿",
1369
+ lineDownLeft: "┐",
1370
+ lineDownLeftArc: "╮",
1371
+ lineDownBoldLeftBold: "┓",
1372
+ lineDownBoldLeft: "┒",
1373
+ lineDownLeftBold: "┑",
1374
+ lineDownDoubleLeftDouble: "╗",
1375
+ lineDownDoubleLeft: "╖",
1376
+ lineDownLeftDouble: "╕",
1377
+ lineDownRight: "┌",
1378
+ lineDownRightArc: "╭",
1379
+ lineDownBoldRightBold: "┏",
1380
+ lineDownBoldRight: "┎",
1381
+ lineDownRightBold: "┍",
1382
+ lineDownDoubleRightDouble: "╔",
1383
+ lineDownDoubleRight: "╓",
1384
+ lineDownRightDouble: "╒",
1385
+ lineUpLeft: "┘",
1386
+ lineUpLeftArc: "╯",
1387
+ lineUpBoldLeftBold: "┛",
1388
+ lineUpBoldLeft: "┚",
1389
+ lineUpLeftBold: "┙",
1390
+ lineUpDoubleLeftDouble: "╝",
1391
+ lineUpDoubleLeft: "╜",
1392
+ lineUpLeftDouble: "╛",
1393
+ lineUpRight: "└",
1394
+ lineUpRightArc: "╰",
1395
+ lineUpBoldRightBold: "┗",
1396
+ lineUpBoldRight: "┖",
1397
+ lineUpRightBold: "┕",
1398
+ lineUpDoubleRightDouble: "╚",
1399
+ lineUpDoubleRight: "╙",
1400
+ lineUpRightDouble: "╘",
1401
+ lineUpDownLeft: "┤",
1402
+ lineUpBoldDownBoldLeftBold: "┫",
1403
+ lineUpBoldDownBoldLeft: "┨",
1404
+ lineUpDownLeftBold: "┥",
1405
+ lineUpBoldDownLeftBold: "┩",
1406
+ lineUpDownBoldLeftBold: "┪",
1407
+ lineUpDownBoldLeft: "┧",
1408
+ lineUpBoldDownLeft: "┦",
1409
+ lineUpDoubleDownDoubleLeftDouble: "╣",
1410
+ lineUpDoubleDownDoubleLeft: "╢",
1411
+ lineUpDownLeftDouble: "╡",
1412
+ lineUpDownRight: "├",
1413
+ lineUpBoldDownBoldRightBold: "┣",
1414
+ lineUpBoldDownBoldRight: "┠",
1415
+ lineUpDownRightBold: "┝",
1416
+ lineUpBoldDownRightBold: "┡",
1417
+ lineUpDownBoldRightBold: "┢",
1418
+ lineUpDownBoldRight: "┟",
1419
+ lineUpBoldDownRight: "┞",
1420
+ lineUpDoubleDownDoubleRightDouble: "╠",
1421
+ lineUpDoubleDownDoubleRight: "╟",
1422
+ lineUpDownRightDouble: "╞",
1423
+ lineDownLeftRight: "┬",
1424
+ lineDownBoldLeftBoldRightBold: "┳",
1425
+ lineDownLeftBoldRightBold: "┯",
1426
+ lineDownBoldLeftRight: "┰",
1427
+ lineDownBoldLeftBoldRight: "┱",
1428
+ lineDownBoldLeftRightBold: "┲",
1429
+ lineDownLeftRightBold: "┮",
1430
+ lineDownLeftBoldRight: "┭",
1431
+ lineDownDoubleLeftDoubleRightDouble: "╦",
1432
+ lineDownDoubleLeftRight: "╥",
1433
+ lineDownLeftDoubleRightDouble: "╤",
1434
+ lineUpLeftRight: "┴",
1435
+ lineUpBoldLeftBoldRightBold: "┻",
1436
+ lineUpLeftBoldRightBold: "┷",
1437
+ lineUpBoldLeftRight: "┸",
1438
+ lineUpBoldLeftBoldRight: "┹",
1439
+ lineUpBoldLeftRightBold: "┺",
1440
+ lineUpLeftRightBold: "┶",
1441
+ lineUpLeftBoldRight: "┵",
1442
+ lineUpDoubleLeftDoubleRightDouble: "╩",
1443
+ lineUpDoubleLeftRight: "╨",
1444
+ lineUpLeftDoubleRightDouble: "╧",
1445
+ lineUpDownLeftRight: "┼",
1446
+ lineUpBoldDownBoldLeftBoldRightBold: "╋",
1447
+ lineUpDownBoldLeftBoldRightBold: "╈",
1448
+ lineUpBoldDownLeftBoldRightBold: "╇",
1449
+ lineUpBoldDownBoldLeftRightBold: "╊",
1450
+ lineUpBoldDownBoldLeftBoldRight: "╉",
1451
+ lineUpBoldDownLeftRight: "╀",
1452
+ lineUpDownBoldLeftRight: "╁",
1453
+ lineUpDownLeftBoldRight: "┽",
1454
+ lineUpDownLeftRightBold: "┾",
1455
+ lineUpBoldDownBoldLeftRight: "╂",
1456
+ lineUpDownLeftBoldRightBold: "┿",
1457
+ lineUpBoldDownLeftBoldRight: "╃",
1458
+ lineUpBoldDownLeftRightBold: "╄",
1459
+ lineUpDownBoldLeftBoldRight: "╅",
1460
+ lineUpDownBoldLeftRightBold: "╆",
1461
+ lineUpDoubleDownDoubleLeftDoubleRightDouble: "╬",
1462
+ lineUpDoubleDownDoubleLeftRight: "╫",
1463
+ lineUpDownLeftDoubleRightDouble: "╪",
1464
+ lineCross: "╳",
1465
+ lineBackslash: "╲",
1466
+ lineSlash: "╱"
1467
+ };
1468
+ var specialMainSymbols = {
1469
+ tick: "✔",
1470
+ info: "ℹ",
1471
+ warning: "⚠",
1472
+ cross: "✘",
1473
+ squareSmall: "◻",
1474
+ squareSmallFilled: "◼",
1475
+ circle: "◯",
1476
+ circleFilled: "◉",
1477
+ circleDotted: "◌",
1478
+ circleDouble: "◎",
1479
+ circleCircle: "ⓞ",
1480
+ circleCross: "ⓧ",
1481
+ circlePipe: "Ⓘ",
1482
+ radioOn: "◉",
1483
+ radioOff: "◯",
1484
+ checkboxOn: "☒",
1485
+ checkboxOff: "☐",
1486
+ checkboxCircleOn: "ⓧ",
1487
+ checkboxCircleOff: "Ⓘ",
1488
+ pointer: "❯",
1489
+ triangleUpOutline: "△",
1490
+ triangleLeft: "◀",
1491
+ triangleRight: "▶",
1492
+ lozenge: "◆",
1493
+ lozengeOutline: "◇",
1494
+ hamburger: "☰",
1495
+ smiley: "㋡",
1496
+ mustache: "෴",
1497
+ star: "★",
1498
+ play: "▶",
1499
+ nodejs: "⬢",
1500
+ oneSeventh: "⅐",
1501
+ oneNinth: "⅑",
1502
+ oneTenth: "⅒"
1503
+ };
1504
+ var specialFallbackSymbols = {
1505
+ tick: "√",
1506
+ info: "i",
1507
+ warning: "‼",
1508
+ cross: "×",
1509
+ squareSmall: "□",
1510
+ squareSmallFilled: "■",
1511
+ circle: "( )",
1512
+ circleFilled: "(*)",
1513
+ circleDotted: "( )",
1514
+ circleDouble: "( )",
1515
+ circleCircle: "(○)",
1516
+ circleCross: "(×)",
1517
+ circlePipe: "(│)",
1518
+ radioOn: "(*)",
1519
+ radioOff: "( )",
1520
+ checkboxOn: "[×]",
1521
+ checkboxOff: "[ ]",
1522
+ checkboxCircleOn: "(×)",
1523
+ checkboxCircleOff: "( )",
1524
+ pointer: ">",
1525
+ triangleUpOutline: "∆",
1526
+ triangleLeft: "◄",
1527
+ triangleRight: "►",
1528
+ lozenge: "♦",
1529
+ lozengeOutline: "◊",
1530
+ hamburger: "≡",
1531
+ smiley: "☺",
1532
+ mustache: "┌─┐",
1533
+ star: "✶",
1534
+ play: "►",
1535
+ nodejs: "♦",
1536
+ oneSeventh: "1/7",
1537
+ oneNinth: "1/9",
1538
+ oneTenth: "1/10"
1539
+ };
1540
+ var mainSymbols = {
1541
+ ...common,
1542
+ ...specialMainSymbols
1543
+ };
1544
+ var fallbackSymbols = {
1545
+ ...common,
1546
+ ...specialFallbackSymbols
1547
+ };
1548
+ var shouldUseMain = isUnicodeSupported();
1549
+ var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
1550
+ var dist_default = figures;
1551
+ var replacements = Object.entries(specialMainSymbols);
1552
+
1553
+ // node_modules/@inquirer/core/dist/lib/theme.js
1554
+ var defaultTheme = {
1555
+ prefix: {
1556
+ idle: styleText("blue", "?"),
1557
+ done: styleText("green", dist_default.tick)
1558
+ },
1559
+ spinner: {
1560
+ interval: 80,
1561
+ frames: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"].map((frame) => styleText("yellow", frame))
1562
+ },
1563
+ style: {
1564
+ answer: (text) => styleText("cyan", text),
1565
+ message: (text) => styleText("bold", text),
1566
+ error: (text) => styleText("red", `> ${text}`),
1567
+ defaultAnswer: (text) => styleText("dim", `(${text})`),
1568
+ help: (text) => styleText("dim", text),
1569
+ highlight: (text) => styleText("cyan", text),
1570
+ key: (text) => styleText("cyan", styleText("bold", `<${text}>`))
905
1571
  }
906
- console.log(` ${options.length + 1}) All of the above`);
907
- const answer = await ask(`
908
- Select (comma-separated numbers, e.g. 1,3): `);
909
- const nums = answer.split(",").map((s) => parseInt(s.trim(), 10));
910
- if (nums.includes(options.length + 1)) {
911
- return options.map((o) => o.value);
1572
+ };
1573
+
1574
+ // node_modules/@inquirer/core/dist/lib/make-theme.js
1575
+ function isPlainObject(value) {
1576
+ if (typeof value !== "object" || value === null)
1577
+ return false;
1578
+ let proto = value;
1579
+ while (Object.getPrototypeOf(proto) !== null) {
1580
+ proto = Object.getPrototypeOf(proto);
912
1581
  }
913
- const selected = nums.filter((n) => n >= 1 && n <= options.length).map((n) => options[n - 1].value);
914
- if (selected.length === 0) {
915
- console.error("No valid selection. Exiting.");
916
- process.exit(1);
1582
+ return Object.getPrototypeOf(value) === proto;
1583
+ }
1584
+ function deepMerge(...objects) {
1585
+ const output = {};
1586
+ for (const obj of objects) {
1587
+ for (const [key, value] of Object.entries(obj)) {
1588
+ const prevValue = output[key];
1589
+ output[key] = isPlainObject(prevValue) && isPlainObject(value) ? deepMerge(prevValue, value) : value;
1590
+ }
917
1591
  }
918
- return selected;
1592
+ return output;
919
1593
  }
920
- async function promptActivation(skillName, modes) {
921
- console.log(`
922
- How should ${skillName} activate in Claude Code?
1594
+ function makeTheme(...themes) {
1595
+ const themesToMerge = [
1596
+ defaultTheme,
1597
+ ...themes.filter((theme) => theme != null)
1598
+ ];
1599
+ return deepMerge(...themesToMerge);
1600
+ }
1601
+
1602
+ // node_modules/@inquirer/core/dist/lib/use-prefix.js
1603
+ function usePrefix({ status = "idle", theme }) {
1604
+ const [showLoader, setShowLoader] = useState(false);
1605
+ const [tick, setTick] = useState(0);
1606
+ const { prefix, spinner } = makeTheme(theme);
1607
+ useEffect(() => {
1608
+ if (status === "loading") {
1609
+ let tickInterval;
1610
+ let inc = -1;
1611
+ const delayTimeout = setTimeout(() => {
1612
+ setShowLoader(true);
1613
+ tickInterval = setInterval(() => {
1614
+ inc = inc + 1;
1615
+ setTick(inc % spinner.frames.length);
1616
+ }, spinner.interval);
1617
+ }, 300);
1618
+ return () => {
1619
+ clearTimeout(delayTimeout);
1620
+ clearInterval(tickInterval);
1621
+ };
1622
+ } else {
1623
+ setShowLoader(false);
1624
+ }
1625
+ }, [status]);
1626
+ if (showLoader) {
1627
+ return spinner.frames[tick];
1628
+ }
1629
+ const iconName = status === "loading" ? "idle" : status;
1630
+ return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
1631
+ }
1632
+ // node_modules/@inquirer/core/dist/lib/use-memo.js
1633
+ function useMemo(fn, dependencies) {
1634
+ return withPointer((pointer) => {
1635
+ const prev = pointer.get();
1636
+ if (!prev || prev.dependencies.length !== dependencies.length || prev.dependencies.some((dep, i) => dep !== dependencies[i])) {
1637
+ const value = fn();
1638
+ pointer.set({ value, dependencies });
1639
+ return value;
1640
+ }
1641
+ return prev.value;
1642
+ });
1643
+ }
1644
+ // node_modules/@inquirer/core/dist/lib/use-ref.js
1645
+ function useRef(val) {
1646
+ return useState({ current: val })[0];
1647
+ }
1648
+ // node_modules/@inquirer/core/dist/lib/use-keypress.js
1649
+ function useKeypress(userHandler) {
1650
+ const signal = useRef(userHandler);
1651
+ signal.current = userHandler;
1652
+ useEffect((rl) => {
1653
+ let ignore = false;
1654
+ const handler = withUpdates((_input, event) => {
1655
+ if (ignore)
1656
+ return;
1657
+ signal.current(event, rl);
1658
+ });
1659
+ rl.input.on("keypress", handler);
1660
+ return () => {
1661
+ ignore = true;
1662
+ rl.input.removeListener("keypress", handler);
1663
+ };
1664
+ }, []);
1665
+ }
1666
+ // node_modules/@inquirer/core/dist/lib/utils.js
1667
+ var import_cli_width = __toESM(require_cli_width(), 1);
1668
+
1669
+ // node_modules/fast-string-truncated-width/dist/utils.js
1670
+ var getCodePointsLength = (() => {
1671
+ const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
1672
+ return (input) => {
1673
+ let surrogatePairsNr = 0;
1674
+ SURROGATE_PAIR_RE.lastIndex = 0;
1675
+ while (SURROGATE_PAIR_RE.test(input)) {
1676
+ surrogatePairsNr += 1;
1677
+ }
1678
+ return input.length - surrogatePairsNr;
1679
+ };
1680
+ })();
1681
+ var isFullWidth = (x) => {
1682
+ return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
1683
+ };
1684
+ var isWideNotCJKTNotEmoji = (x) => {
1685
+ return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || 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 >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
1686
+ };
1687
+
1688
+ // node_modules/fast-string-truncated-width/dist/index.js
1689
+ var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
1690
+ var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
1691
+ var CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
1692
+ var TAB_RE = /\t{1,1000}/y;
1693
+ 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;
1694
+ var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
1695
+ var MODIFIER_RE = /\p{M}+/gu;
1696
+ var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
1697
+ var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
1698
+ const LIMIT = truncationOptions.limit ?? Infinity;
1699
+ const ELLIPSIS = truncationOptions.ellipsis ?? "";
1700
+ const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
1701
+ const ANSI_WIDTH = 0;
1702
+ const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
1703
+ const TAB_WIDTH = widthOptions.tabWidth ?? 8;
1704
+ const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
1705
+ const FULL_WIDTH_WIDTH = 2;
1706
+ const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
1707
+ const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
1708
+ const PARSE_BLOCKS = [
1709
+ [LATIN_RE, REGULAR_WIDTH],
1710
+ [ANSI_RE, ANSI_WIDTH],
1711
+ [CONTROL_RE, CONTROL_WIDTH],
1712
+ [TAB_RE, TAB_WIDTH],
1713
+ [EMOJI_RE, EMOJI_WIDTH],
1714
+ [CJKT_WIDE_RE, WIDE_WIDTH]
1715
+ ];
1716
+ let indexPrev = 0;
1717
+ let index = 0;
1718
+ let length = input.length;
1719
+ let lengthExtra = 0;
1720
+ let truncationEnabled = false;
1721
+ let truncationIndex = length;
1722
+ let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
1723
+ let unmatchedStart = 0;
1724
+ let unmatchedEnd = 0;
1725
+ let width = 0;
1726
+ let widthExtra = 0;
1727
+ outer:
1728
+ while (true) {
1729
+ if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
1730
+ const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
1731
+ lengthExtra = 0;
1732
+ for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
1733
+ const codePoint = char.codePointAt(0) || 0;
1734
+ if (isFullWidth(codePoint)) {
1735
+ widthExtra = FULL_WIDTH_WIDTH;
1736
+ } else if (isWideNotCJKTNotEmoji(codePoint)) {
1737
+ widthExtra = WIDE_WIDTH;
1738
+ } else {
1739
+ widthExtra = REGULAR_WIDTH;
1740
+ }
1741
+ if (width + widthExtra > truncationLimit) {
1742
+ truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
1743
+ }
1744
+ if (width + widthExtra > LIMIT) {
1745
+ truncationEnabled = true;
1746
+ break outer;
1747
+ }
1748
+ lengthExtra += char.length;
1749
+ width += widthExtra;
1750
+ }
1751
+ unmatchedStart = unmatchedEnd = 0;
1752
+ }
1753
+ if (index >= length) {
1754
+ break outer;
1755
+ }
1756
+ for (let i = 0, l = PARSE_BLOCKS.length;i < l; i++) {
1757
+ const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
1758
+ BLOCK_RE.lastIndex = index;
1759
+ if (BLOCK_RE.test(input)) {
1760
+ lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
1761
+ widthExtra = lengthExtra * BLOCK_WIDTH;
1762
+ if (width + widthExtra > truncationLimit) {
1763
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
1764
+ }
1765
+ if (width + widthExtra > LIMIT) {
1766
+ truncationEnabled = true;
1767
+ break outer;
1768
+ }
1769
+ width += widthExtra;
1770
+ unmatchedStart = indexPrev;
1771
+ unmatchedEnd = index;
1772
+ index = indexPrev = BLOCK_RE.lastIndex;
1773
+ continue outer;
1774
+ }
1775
+ }
1776
+ index += 1;
1777
+ }
1778
+ return {
1779
+ width: truncationEnabled ? truncationLimit : width,
1780
+ index: truncationEnabled ? truncationIndex : length,
1781
+ truncated: truncationEnabled,
1782
+ ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
1783
+ };
1784
+ };
1785
+ var dist_default2 = getStringTruncatedWidth;
1786
+
1787
+ // node_modules/fast-string-width/dist/index.js
1788
+ var NO_TRUNCATION2 = {
1789
+ limit: Infinity,
1790
+ ellipsis: "",
1791
+ ellipsisWidth: 0
1792
+ };
1793
+ var fastStringWidth = (input, options = {}) => {
1794
+ return dist_default2(input, NO_TRUNCATION2, options).width;
1795
+ };
1796
+ var dist_default3 = fastStringWidth;
1797
+
1798
+ // node_modules/fast-wrap-ansi/lib/main.js
1799
+ var ESC = "\x1B";
1800
+ var CSI = "›";
1801
+ var END_CODE = 39;
1802
+ var ANSI_ESCAPE_BELL = "\x07";
1803
+ var ANSI_CSI = "[";
1804
+ var ANSI_OSC = "]";
1805
+ var ANSI_SGR_TERMINATOR = "m";
1806
+ var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
1807
+ var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
1808
+ var getClosingCode = (openingCode) => {
1809
+ if (openingCode >= 30 && openingCode <= 37)
1810
+ return 39;
1811
+ if (openingCode >= 90 && openingCode <= 97)
1812
+ return 39;
1813
+ if (openingCode >= 40 && openingCode <= 47)
1814
+ return 49;
1815
+ if (openingCode >= 100 && openingCode <= 107)
1816
+ return 49;
1817
+ if (openingCode === 1 || openingCode === 2)
1818
+ return 22;
1819
+ if (openingCode === 3)
1820
+ return 23;
1821
+ if (openingCode === 4)
1822
+ return 24;
1823
+ if (openingCode === 7)
1824
+ return 27;
1825
+ if (openingCode === 8)
1826
+ return 28;
1827
+ if (openingCode === 9)
1828
+ return 29;
1829
+ if (openingCode === 0)
1830
+ return 0;
1831
+ return;
1832
+ };
1833
+ var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
1834
+ var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
1835
+ var wrapWord = (rows, word, columns) => {
1836
+ const characters = word[Symbol.iterator]();
1837
+ let isInsideEscape = false;
1838
+ let isInsideLinkEscape = false;
1839
+ let lastRow = rows.at(-1);
1840
+ let visible = lastRow === undefined ? 0 : dist_default3(lastRow);
1841
+ let currentCharacter = characters.next();
1842
+ let nextCharacter = characters.next();
1843
+ let rawCharacterIndex = 0;
1844
+ while (!currentCharacter.done) {
1845
+ const character = currentCharacter.value;
1846
+ const characterLength = dist_default3(character);
1847
+ if (visible + characterLength <= columns) {
1848
+ rows[rows.length - 1] += character;
1849
+ } else {
1850
+ rows.push(character);
1851
+ visible = 0;
1852
+ }
1853
+ if (character === ESC || character === CSI) {
1854
+ isInsideEscape = true;
1855
+ isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
1856
+ }
1857
+ if (isInsideEscape) {
1858
+ if (isInsideLinkEscape) {
1859
+ if (character === ANSI_ESCAPE_BELL) {
1860
+ isInsideEscape = false;
1861
+ isInsideLinkEscape = false;
1862
+ }
1863
+ } else if (character === ANSI_SGR_TERMINATOR) {
1864
+ isInsideEscape = false;
1865
+ }
1866
+ } else {
1867
+ visible += characterLength;
1868
+ if (visible === columns && !nextCharacter.done) {
1869
+ rows.push("");
1870
+ visible = 0;
1871
+ }
1872
+ }
1873
+ currentCharacter = nextCharacter;
1874
+ nextCharacter = characters.next();
1875
+ rawCharacterIndex += character.length;
1876
+ }
1877
+ lastRow = rows.at(-1);
1878
+ if (!visible && lastRow !== undefined && lastRow.length && rows.length > 1) {
1879
+ rows[rows.length - 2] += rows.pop();
1880
+ }
1881
+ };
1882
+ var stringVisibleTrimSpacesRight = (string) => {
1883
+ const words = string.split(" ");
1884
+ let last = words.length;
1885
+ while (last) {
1886
+ if (dist_default3(words[last - 1])) {
1887
+ break;
1888
+ }
1889
+ last--;
1890
+ }
1891
+ if (last === words.length) {
1892
+ return string;
1893
+ }
1894
+ return words.slice(0, last).join(" ") + words.slice(last).join("");
1895
+ };
1896
+ var exec = (string, columns, options = {}) => {
1897
+ if (options.trim !== false && string.trim() === "") {
1898
+ return "";
1899
+ }
1900
+ let returnValue = "";
1901
+ let escapeCode;
1902
+ let escapeUrl;
1903
+ const words = string.split(" ");
1904
+ let rows = [""];
1905
+ let rowLength = 0;
1906
+ for (let index = 0;index < words.length; index++) {
1907
+ const word = words[index];
1908
+ if (options.trim !== false) {
1909
+ const row = rows.at(-1) ?? "";
1910
+ const trimmed = row.trimStart();
1911
+ if (row.length !== trimmed.length) {
1912
+ rows[rows.length - 1] = trimmed;
1913
+ rowLength = dist_default3(trimmed);
1914
+ }
1915
+ }
1916
+ if (index !== 0) {
1917
+ if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
1918
+ rows.push("");
1919
+ rowLength = 0;
1920
+ }
1921
+ if (rowLength || options.trim === false) {
1922
+ rows[rows.length - 1] += " ";
1923
+ rowLength++;
1924
+ }
1925
+ }
1926
+ const wordLength = dist_default3(word);
1927
+ if (options.hard && wordLength > columns) {
1928
+ const remainingColumns = columns - rowLength;
1929
+ const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
1930
+ const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
1931
+ if (breaksStartingNextLine < breaksStartingThisLine) {
1932
+ rows.push("");
1933
+ }
1934
+ wrapWord(rows, word, columns);
1935
+ rowLength = dist_default3(rows.at(-1) ?? "");
1936
+ continue;
1937
+ }
1938
+ if (rowLength + wordLength > columns && rowLength && wordLength) {
1939
+ if (options.wordWrap === false && rowLength < columns) {
1940
+ wrapWord(rows, word, columns);
1941
+ rowLength = dist_default3(rows.at(-1) ?? "");
1942
+ continue;
1943
+ }
1944
+ rows.push("");
1945
+ rowLength = 0;
1946
+ }
1947
+ if (rowLength + wordLength > columns && options.wordWrap === false) {
1948
+ wrapWord(rows, word, columns);
1949
+ rowLength = dist_default3(rows.at(-1) ?? "");
1950
+ continue;
1951
+ }
1952
+ rows[rows.length - 1] += word;
1953
+ rowLength += wordLength;
1954
+ }
1955
+ if (options.trim !== false) {
1956
+ rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
1957
+ }
1958
+ const preString = rows.join(`
923
1959
  `);
924
- const labels = {
925
- session: `Per-session - invoke manually with /${skillName}`,
926
- global: "Global - auto-activate every session (adds SessionStart hook)"
1960
+ let inSurrogate = false;
1961
+ for (let i = 0;i < preString.length; i++) {
1962
+ const character = preString[i];
1963
+ returnValue += character;
1964
+ if (!inSurrogate) {
1965
+ inSurrogate = character >= "\uD800" && character <= "\uDBFF";
1966
+ if (inSurrogate) {
1967
+ continue;
1968
+ }
1969
+ } else {
1970
+ inSurrogate = false;
1971
+ }
1972
+ if (character === ESC || character === CSI) {
1973
+ GROUP_REGEX.lastIndex = i + 1;
1974
+ const groupsResult = GROUP_REGEX.exec(preString);
1975
+ const groups = groupsResult?.groups;
1976
+ if (groups?.code !== undefined) {
1977
+ const code = Number.parseFloat(groups.code);
1978
+ escapeCode = code === END_CODE ? undefined : code;
1979
+ } else if (groups?.uri !== undefined) {
1980
+ escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
1981
+ }
1982
+ }
1983
+ if (preString[i + 1] === `
1984
+ `) {
1985
+ if (escapeUrl) {
1986
+ returnValue += wrapAnsiHyperlink("");
1987
+ }
1988
+ const closingCode = escapeCode ? getClosingCode(escapeCode) : undefined;
1989
+ if (escapeCode && closingCode) {
1990
+ returnValue += wrapAnsiCode(closingCode);
1991
+ }
1992
+ } else if (character === `
1993
+ `) {
1994
+ if (escapeCode && getClosingCode(escapeCode)) {
1995
+ returnValue += wrapAnsiCode(escapeCode);
1996
+ }
1997
+ if (escapeUrl) {
1998
+ returnValue += wrapAnsiHyperlink(escapeUrl);
1999
+ }
2000
+ }
2001
+ }
2002
+ return returnValue;
2003
+ };
2004
+ var CRLF_OR_LF = /\r?\n/;
2005
+ function wrapAnsi(string, columns, options) {
2006
+ return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join(`
2007
+ `);
2008
+ }
2009
+
2010
+ // node_modules/@inquirer/core/dist/lib/utils.js
2011
+ function breakLines(content, width) {
2012
+ return content.split(`
2013
+ `).flatMap((line) => wrapAnsi(line, width, { trim: false, hard: true }).split(`
2014
+ `).map((str) => str.trimEnd())).join(`
2015
+ `);
2016
+ }
2017
+ function readlineWidth() {
2018
+ return import_cli_width.default({ defaultWidth: 80, output: readline().output });
2019
+ }
2020
+
2021
+ // node_modules/@inquirer/core/dist/lib/pagination/use-pagination.js
2022
+ function usePointerPosition({ active, renderedItems, pageSize, loop }) {
2023
+ const state = useRef({
2024
+ lastPointer: active,
2025
+ lastActive: undefined
2026
+ });
2027
+ const { lastPointer, lastActive } = state.current;
2028
+ const middle = Math.floor(pageSize / 2);
2029
+ const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
2030
+ const defaultPointerPosition = renderedItems.slice(0, active).reduce((acc, item) => acc + item.length, 0);
2031
+ let pointer = defaultPointerPosition;
2032
+ if (renderedLength > pageSize) {
2033
+ if (loop) {
2034
+ pointer = lastPointer;
2035
+ if (lastActive != null && lastActive < active && active - lastActive < pageSize) {
2036
+ pointer = Math.min(middle, Math.abs(active - lastActive) === 1 ? Math.min(lastPointer + (renderedItems[lastActive]?.length ?? 0), Math.max(defaultPointerPosition, lastPointer)) : lastPointer + active - lastActive);
2037
+ }
2038
+ } else {
2039
+ const spaceUnderActive = renderedItems.slice(active).reduce((acc, item) => acc + item.length, 0);
2040
+ pointer = spaceUnderActive < pageSize - middle ? pageSize - spaceUnderActive : Math.min(defaultPointerPosition, middle);
2041
+ }
2042
+ }
2043
+ state.current.lastPointer = pointer;
2044
+ state.current.lastActive = active;
2045
+ return pointer;
2046
+ }
2047
+ function usePagination({ items, active, renderItem, pageSize, loop = true }) {
2048
+ const width = readlineWidth();
2049
+ const bound = (num) => (num % items.length + items.length) % items.length;
2050
+ const renderedItems = items.map((item, index) => {
2051
+ if (item == null)
2052
+ return [];
2053
+ return breakLines(renderItem({ item, index, isActive: index === active }), width).split(`
2054
+ `);
2055
+ });
2056
+ const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
2057
+ const renderItemAtIndex = (index) => renderedItems[index] ?? [];
2058
+ const pointer = usePointerPosition({ active, renderedItems, pageSize, loop });
2059
+ const activeItem = renderItemAtIndex(active).slice(0, pageSize);
2060
+ const activeItemPosition = pointer + activeItem.length <= pageSize ? pointer : pageSize - activeItem.length;
2061
+ const pageBuffer = Array.from({ length: pageSize });
2062
+ pageBuffer.splice(activeItemPosition, activeItem.length, ...activeItem);
2063
+ const itemVisited = new Set([active]);
2064
+ let bufferPointer = activeItemPosition + activeItem.length;
2065
+ let itemPointer = bound(active + 1);
2066
+ while (bufferPointer < pageSize && !itemVisited.has(itemPointer) && (loop && renderedLength > pageSize ? itemPointer !== active : itemPointer > active)) {
2067
+ const lines = renderItemAtIndex(itemPointer);
2068
+ const linesToAdd = lines.slice(0, pageSize - bufferPointer);
2069
+ pageBuffer.splice(bufferPointer, linesToAdd.length, ...linesToAdd);
2070
+ itemVisited.add(itemPointer);
2071
+ bufferPointer += linesToAdd.length;
2072
+ itemPointer = bound(itemPointer + 1);
2073
+ }
2074
+ bufferPointer = activeItemPosition - 1;
2075
+ itemPointer = bound(active - 1);
2076
+ while (bufferPointer >= 0 && !itemVisited.has(itemPointer) && (loop && renderedLength > pageSize ? itemPointer !== active : itemPointer < active)) {
2077
+ const lines = renderItemAtIndex(itemPointer);
2078
+ const linesToAdd = lines.slice(Math.max(0, lines.length - bufferPointer - 1));
2079
+ pageBuffer.splice(bufferPointer - linesToAdd.length + 1, linesToAdd.length, ...linesToAdd);
2080
+ itemVisited.add(itemPointer);
2081
+ bufferPointer -= linesToAdd.length;
2082
+ itemPointer = bound(itemPointer - 1);
2083
+ }
2084
+ return pageBuffer.filter((line) => typeof line === "string").join(`
2085
+ `);
2086
+ }
2087
+ // node_modules/@inquirer/core/dist/lib/create-prompt.js
2088
+ var import_mute_stream = __toESM(require_lib(), 1);
2089
+ import * as readline2 from "node:readline";
2090
+ import { AsyncResource as AsyncResource3 } from "node:async_hooks";
2091
+
2092
+ // node_modules/signal-exit/dist/mjs/signals.js
2093
+ var signals = [];
2094
+ signals.push("SIGHUP", "SIGINT", "SIGTERM");
2095
+ if (process.platform !== "win32") {
2096
+ signals.push("SIGALRM", "SIGABRT", "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "SIGUSR2", "SIGTRAP", "SIGSYS", "SIGQUIT", "SIGIOT");
2097
+ }
2098
+ if (process.platform === "linux") {
2099
+ signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
2100
+ }
2101
+
2102
+ // node_modules/signal-exit/dist/mjs/index.js
2103
+ var processOk = (process3) => !!process3 && typeof process3 === "object" && typeof process3.removeListener === "function" && typeof process3.emit === "function" && typeof process3.reallyExit === "function" && typeof process3.listeners === "function" && typeof process3.kill === "function" && typeof process3.pid === "number" && typeof process3.on === "function";
2104
+ var kExitEmitter = Symbol.for("signal-exit emitter");
2105
+ var global = globalThis;
2106
+ var ObjectDefineProperty = Object.defineProperty.bind(Object);
2107
+
2108
+ class Emitter {
2109
+ emitted = {
2110
+ afterExit: false,
2111
+ exit: false
2112
+ };
2113
+ listeners = {
2114
+ afterExit: [],
2115
+ exit: []
927
2116
  };
928
- for (let i = 0;i < modes.length; i++) {
929
- console.log(` ${i + 1}) ${labels[modes[i]]}`);
2117
+ count = 0;
2118
+ id = Math.random();
2119
+ constructor() {
2120
+ if (global[kExitEmitter]) {
2121
+ return global[kExitEmitter];
2122
+ }
2123
+ ObjectDefineProperty(global, kExitEmitter, {
2124
+ value: this,
2125
+ writable: false,
2126
+ enumerable: false,
2127
+ configurable: false
2128
+ });
2129
+ }
2130
+ on(ev, fn) {
2131
+ this.listeners[ev].push(fn);
2132
+ }
2133
+ removeListener(ev, fn) {
2134
+ const list = this.listeners[ev];
2135
+ const i = list.indexOf(fn);
2136
+ if (i === -1) {
2137
+ return;
2138
+ }
2139
+ if (i === 0 && list.length === 1) {
2140
+ list.length = 0;
2141
+ } else {
2142
+ list.splice(i, 1);
2143
+ }
2144
+ }
2145
+ emit(ev, code, signal) {
2146
+ if (this.emitted[ev]) {
2147
+ return false;
2148
+ }
2149
+ this.emitted[ev] = true;
2150
+ let ret = false;
2151
+ for (const fn of this.listeners[ev]) {
2152
+ ret = fn(code, signal) === true || ret;
2153
+ }
2154
+ if (ev === "exit") {
2155
+ ret = this.emit("afterExit", code, signal) || ret;
2156
+ }
2157
+ return ret;
930
2158
  }
931
- const answer = await ask(`
932
- Select: `);
933
- const n = parseInt(answer, 10);
934
- if (isNaN(n) || n < 1 || n > modes.length) {
935
- console.error("Invalid selection. Exiting.");
936
- process.exit(1);
2159
+ }
2160
+
2161
+ class SignalExitBase {
2162
+ }
2163
+ var signalExitWrap = (handler) => {
2164
+ return {
2165
+ onExit(cb, opts) {
2166
+ return handler.onExit(cb, opts);
2167
+ },
2168
+ load() {
2169
+ return handler.load();
2170
+ },
2171
+ unload() {
2172
+ return handler.unload();
2173
+ }
2174
+ };
2175
+ };
2176
+
2177
+ class SignalExitFallback extends SignalExitBase {
2178
+ onExit() {
2179
+ return () => {};
937
2180
  }
938
- return modes[n - 1];
2181
+ load() {}
2182
+ unload() {}
2183
+ }
2184
+
2185
+ class SignalExit extends SignalExitBase {
2186
+ #hupSig = process3.platform === "win32" ? "SIGINT" : "SIGHUP";
2187
+ #emitter = new Emitter;
2188
+ #process;
2189
+ #originalProcessEmit;
2190
+ #originalProcessReallyExit;
2191
+ #sigListeners = {};
2192
+ #loaded = false;
2193
+ constructor(process3) {
2194
+ super();
2195
+ this.#process = process3;
2196
+ this.#sigListeners = {};
2197
+ for (const sig of signals) {
2198
+ this.#sigListeners[sig] = () => {
2199
+ const listeners = this.#process.listeners(sig);
2200
+ let { count } = this.#emitter;
2201
+ const p = process3;
2202
+ if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") {
2203
+ count += p.__signal_exit_emitter__.count;
2204
+ }
2205
+ if (listeners.length === count) {
2206
+ this.unload();
2207
+ const ret = this.#emitter.emit("exit", null, sig);
2208
+ const s = sig === "SIGHUP" ? this.#hupSig : sig;
2209
+ if (!ret)
2210
+ process3.kill(process3.pid, s);
2211
+ }
2212
+ };
2213
+ }
2214
+ this.#originalProcessReallyExit = process3.reallyExit;
2215
+ this.#originalProcessEmit = process3.emit;
2216
+ }
2217
+ onExit(cb, opts) {
2218
+ if (!processOk(this.#process)) {
2219
+ return () => {};
2220
+ }
2221
+ if (this.#loaded === false) {
2222
+ this.load();
2223
+ }
2224
+ const ev = opts?.alwaysLast ? "afterExit" : "exit";
2225
+ this.#emitter.on(ev, cb);
2226
+ return () => {
2227
+ this.#emitter.removeListener(ev, cb);
2228
+ if (this.#emitter.listeners["exit"].length === 0 && this.#emitter.listeners["afterExit"].length === 0) {
2229
+ this.unload();
2230
+ }
2231
+ };
2232
+ }
2233
+ load() {
2234
+ if (this.#loaded) {
2235
+ return;
2236
+ }
2237
+ this.#loaded = true;
2238
+ this.#emitter.count += 1;
2239
+ for (const sig of signals) {
2240
+ try {
2241
+ const fn = this.#sigListeners[sig];
2242
+ if (fn)
2243
+ this.#process.on(sig, fn);
2244
+ } catch (_) {}
2245
+ }
2246
+ this.#process.emit = (ev, ...a) => {
2247
+ return this.#processEmit(ev, ...a);
2248
+ };
2249
+ this.#process.reallyExit = (code) => {
2250
+ return this.#processReallyExit(code);
2251
+ };
2252
+ }
2253
+ unload() {
2254
+ if (!this.#loaded) {
2255
+ return;
2256
+ }
2257
+ this.#loaded = false;
2258
+ signals.forEach((sig) => {
2259
+ const listener = this.#sigListeners[sig];
2260
+ if (!listener) {
2261
+ throw new Error("Listener not defined for signal: " + sig);
2262
+ }
2263
+ try {
2264
+ this.#process.removeListener(sig, listener);
2265
+ } catch (_) {}
2266
+ });
2267
+ this.#process.emit = this.#originalProcessEmit;
2268
+ this.#process.reallyExit = this.#originalProcessReallyExit;
2269
+ this.#emitter.count -= 1;
2270
+ }
2271
+ #processReallyExit(code) {
2272
+ if (!processOk(this.#process)) {
2273
+ return 0;
2274
+ }
2275
+ this.#process.exitCode = code || 0;
2276
+ this.#emitter.emit("exit", this.#process.exitCode, null);
2277
+ return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
2278
+ }
2279
+ #processEmit(ev, ...args) {
2280
+ const og = this.#originalProcessEmit;
2281
+ if (ev === "exit" && processOk(this.#process)) {
2282
+ if (typeof args[0] === "number") {
2283
+ this.#process.exitCode = args[0];
2284
+ }
2285
+ const ret = og.call(this.#process, ev, ...args);
2286
+ this.#emitter.emit("exit", this.#process.exitCode, null);
2287
+ return ret;
2288
+ } else {
2289
+ return og.call(this.#process, ev, ...args);
2290
+ }
2291
+ }
2292
+ }
2293
+ var process3 = globalThis.process;
2294
+ var {
2295
+ onExit,
2296
+ load,
2297
+ unload
2298
+ } = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback);
2299
+
2300
+ // node_modules/@inquirer/core/dist/lib/screen-manager.js
2301
+ import { stripVTControlCharacters } from "node:util";
2302
+
2303
+ // node_modules/@inquirer/ansi/dist/index.js
2304
+ var ESC2 = "\x1B[";
2305
+ var cursorLeft = ESC2 + "G";
2306
+ var cursorHide = ESC2 + "?25l";
2307
+ var cursorShow = ESC2 + "?25h";
2308
+ var cursorUp = (rows = 1) => rows > 0 ? `${ESC2}${rows}A` : "";
2309
+ var cursorDown = (rows = 1) => rows > 0 ? `${ESC2}${rows}B` : "";
2310
+ var cursorTo = (x, y) => {
2311
+ if (typeof y === "number" && !Number.isNaN(y)) {
2312
+ return `${ESC2}${y + 1};${x + 1}H`;
2313
+ }
2314
+ return `${ESC2}${x + 1}G`;
2315
+ };
2316
+ var eraseLine = ESC2 + "2K";
2317
+ var eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : "";
2318
+
2319
+ // node_modules/@inquirer/core/dist/lib/screen-manager.js
2320
+ var height = (content) => content.split(`
2321
+ `).length;
2322
+ var lastLine = (content) => content.split(`
2323
+ `).pop() ?? "";
2324
+
2325
+ class ScreenManager {
2326
+ height = 0;
2327
+ extraLinesUnderPrompt = 0;
2328
+ cursorPos;
2329
+ rl;
2330
+ constructor(rl) {
2331
+ this.rl = rl;
2332
+ this.cursorPos = rl.getCursorPos();
2333
+ }
2334
+ write(content) {
2335
+ this.rl.output.unmute();
2336
+ this.rl.output.write(content);
2337
+ this.rl.output.mute();
2338
+ }
2339
+ render(content, bottomContent = "") {
2340
+ const promptLine = lastLine(content);
2341
+ const rawPromptLine = stripVTControlCharacters(promptLine);
2342
+ let prompt = rawPromptLine;
2343
+ if (this.rl.line.length > 0) {
2344
+ prompt = prompt.slice(0, -this.rl.line.length);
2345
+ }
2346
+ this.rl.setPrompt(prompt);
2347
+ this.cursorPos = this.rl.getCursorPos();
2348
+ const width = readlineWidth();
2349
+ content = breakLines(content, width);
2350
+ bottomContent = breakLines(bottomContent, width);
2351
+ if (rawPromptLine.length % width === 0) {
2352
+ content += `
2353
+ `;
2354
+ }
2355
+ let output = content + (bottomContent ? `
2356
+ ` + bottomContent : "");
2357
+ const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - this.cursorPos.rows;
2358
+ const bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
2359
+ if (bottomContentHeight > 0)
2360
+ output += cursorUp(bottomContentHeight);
2361
+ output += cursorTo(this.cursorPos.cols);
2362
+ this.write(cursorDown(this.extraLinesUnderPrompt) + eraseLines(this.height) + output);
2363
+ this.extraLinesUnderPrompt = bottomContentHeight;
2364
+ this.height = height(output);
2365
+ }
2366
+ checkCursorPos() {
2367
+ const cursorPos = this.rl.getCursorPos();
2368
+ if (cursorPos.cols !== this.cursorPos.cols) {
2369
+ this.write(cursorTo(cursorPos.cols));
2370
+ this.cursorPos = cursorPos;
2371
+ }
2372
+ }
2373
+ done({ clearContent }) {
2374
+ this.rl.setPrompt("");
2375
+ let output = cursorDown(this.extraLinesUnderPrompt);
2376
+ output += clearContent ? eraseLines(this.height) : `
2377
+ `;
2378
+ output += cursorShow;
2379
+ this.write(output);
2380
+ this.rl.close();
2381
+ }
2382
+ }
2383
+
2384
+ // node_modules/@inquirer/core/dist/lib/promise-polyfill.js
2385
+ class PromisePolyfill extends Promise {
2386
+ static withResolver() {
2387
+ let resolve;
2388
+ let reject;
2389
+ const promise = new Promise((res, rej) => {
2390
+ resolve = res;
2391
+ reject = rej;
2392
+ });
2393
+ return { promise, resolve, reject };
2394
+ }
2395
+ }
2396
+
2397
+ // node_modules/@inquirer/core/dist/lib/create-prompt.js
2398
+ import path from "node:path";
2399
+ var nativeSetImmediate = globalThis.setImmediate;
2400
+ function getCallSites() {
2401
+ const _prepareStackTrace = Error.prepareStackTrace;
2402
+ let result = [];
2403
+ try {
2404
+ Error.prepareStackTrace = (_, callSites) => {
2405
+ const callSitesWithoutCurrent = callSites.slice(1);
2406
+ result = callSitesWithoutCurrent;
2407
+ return callSitesWithoutCurrent;
2408
+ };
2409
+ new Error().stack;
2410
+ } catch {
2411
+ return result;
2412
+ }
2413
+ Error.prepareStackTrace = _prepareStackTrace;
2414
+ return result;
2415
+ }
2416
+ function createPrompt(view) {
2417
+ const callSites = getCallSites();
2418
+ const prompt = (config, context = {}) => {
2419
+ const { input = process.stdin, signal } = context;
2420
+ const cleanups = new Set;
2421
+ const output = new import_mute_stream.default;
2422
+ output.pipe(context.output ?? process.stdout);
2423
+ const rl = readline2.createInterface({
2424
+ terminal: true,
2425
+ input,
2426
+ output
2427
+ });
2428
+ output.mute();
2429
+ const screen = new ScreenManager(rl);
2430
+ const { promise, resolve, reject } = PromisePolyfill.withResolver();
2431
+ const cancel = () => reject(new CancelPromptError);
2432
+ if (signal) {
2433
+ const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
2434
+ if (signal.aborted) {
2435
+ abort();
2436
+ return Object.assign(promise, { cancel });
2437
+ }
2438
+ signal.addEventListener("abort", abort);
2439
+ cleanups.add(() => signal.removeEventListener("abort", abort));
2440
+ }
2441
+ cleanups.add(onExit((code, signal2) => {
2442
+ reject(new ExitPromptError(`User force closed the prompt with ${code} ${signal2}`));
2443
+ }));
2444
+ const sigint = () => reject(new ExitPromptError(`User force closed the prompt with SIGINT`));
2445
+ rl.on("SIGINT", sigint);
2446
+ cleanups.add(() => rl.removeListener("SIGINT", sigint));
2447
+ return withHooks(rl, (cycle) => {
2448
+ const hooksCleanup = AsyncResource3.bind(() => effectScheduler.clearAll());
2449
+ rl.on("close", hooksCleanup);
2450
+ cleanups.add(() => rl.removeListener("close", hooksCleanup));
2451
+ const startCycle = () => {
2452
+ const checkCursorPos = () => screen.checkCursorPos();
2453
+ rl.input.on("keypress", checkCursorPos);
2454
+ cleanups.add(() => rl.input.removeListener("keypress", checkCursorPos));
2455
+ let pendingDone = null;
2456
+ cycle(() => {
2457
+ let effectsSettled = false;
2458
+ try {
2459
+ const nextView = view(config, (value) => {
2460
+ if (effectsSettled) {
2461
+ resolve(value);
2462
+ } else {
2463
+ pendingDone = { value };
2464
+ }
2465
+ });
2466
+ if (nextView === undefined) {
2467
+ let callerFilename = callSites[1]?.getFileName();
2468
+ if (callerFilename && !callerFilename.startsWith("file://")) {
2469
+ callerFilename = path.resolve(callerFilename);
2470
+ }
2471
+ throw new Error(`Prompt functions must return a string.
2472
+ at ${callerFilename}`);
2473
+ }
2474
+ const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
2475
+ screen.render(content, bottomContent);
2476
+ effectScheduler.run();
2477
+ } catch (error) {
2478
+ reject(error);
2479
+ }
2480
+ effectsSettled = true;
2481
+ if (pendingDone !== null) {
2482
+ const { value } = pendingDone;
2483
+ pendingDone = null;
2484
+ resolve(value);
2485
+ }
2486
+ });
2487
+ };
2488
+ if ("readableFlowing" in input) {
2489
+ nativeSetImmediate(startCycle);
2490
+ } else {
2491
+ startCycle();
2492
+ }
2493
+ return Object.assign(promise.then((answer) => {
2494
+ effectScheduler.clearAll();
2495
+ return answer;
2496
+ }, (error) => {
2497
+ effectScheduler.clearAll();
2498
+ throw error;
2499
+ }).finally(() => {
2500
+ cleanups.forEach((cleanup) => cleanup());
2501
+ screen.done({ clearContent: Boolean(context.clearPromptOnDone) });
2502
+ output.end();
2503
+ }).then(() => promise), { cancel });
2504
+ });
2505
+ };
2506
+ return prompt;
2507
+ }
2508
+ // node_modules/@inquirer/core/dist/lib/Separator.js
2509
+ import { styleText as styleText2 } from "node:util";
2510
+ class Separator {
2511
+ separator = styleText2("dim", Array.from({ length: 15 }).join(dist_default.line));
2512
+ type = "separator";
2513
+ constructor(separator) {
2514
+ if (separator) {
2515
+ this.separator = separator;
2516
+ }
2517
+ }
2518
+ static isSeparator(choice) {
2519
+ return Boolean(choice && typeof choice === "object" && "type" in choice && choice.type === "separator");
2520
+ }
2521
+ }
2522
+ // node_modules/@inquirer/checkbox/dist/index.js
2523
+ import { styleText as styleText3 } from "node:util";
2524
+ var checkboxTheme = {
2525
+ icon: {
2526
+ checked: styleText3("green", dist_default.circleFilled),
2527
+ unchecked: dist_default.circle,
2528
+ cursor: dist_default.pointer,
2529
+ disabledChecked: styleText3("green", dist_default.circleDouble),
2530
+ disabledUnchecked: "-"
2531
+ },
2532
+ style: {
2533
+ disabled: (text) => styleText3("dim", text),
2534
+ renderSelectedChoices: (selectedChoices) => selectedChoices.map((choice) => choice.short).join(", "),
2535
+ description: (text) => styleText3("cyan", text),
2536
+ keysHelpTip: (keys) => keys.map(([key, action]) => `${styleText3("bold", key)} ${styleText3("dim", action)}`).join(styleText3("dim", " • "))
2537
+ },
2538
+ i18n: { disabledError: "This option is disabled and cannot be toggled." },
2539
+ keybindings: []
2540
+ };
2541
+ function isSelectable(item) {
2542
+ return !Separator.isSeparator(item) && !item.disabled;
2543
+ }
2544
+ function isNavigable(item) {
2545
+ return !Separator.isSeparator(item);
2546
+ }
2547
+ function isChecked(item) {
2548
+ return !Separator.isSeparator(item) && item.checked;
2549
+ }
2550
+ function toggle(item) {
2551
+ return isSelectable(item) ? { ...item, checked: !item.checked } : item;
2552
+ }
2553
+ function check(checked) {
2554
+ return function(item) {
2555
+ return isSelectable(item) ? { ...item, checked } : item;
2556
+ };
2557
+ }
2558
+ function normalizeChoices(choices) {
2559
+ return choices.map((choice) => {
2560
+ if (Separator.isSeparator(choice))
2561
+ return choice;
2562
+ if (typeof choice !== "object" || choice === null || !("value" in choice)) {
2563
+ const name2 = String(choice);
2564
+ return {
2565
+ value: choice,
2566
+ name: name2,
2567
+ short: name2,
2568
+ checkedName: name2,
2569
+ disabled: false,
2570
+ checked: false
2571
+ };
2572
+ }
2573
+ const name = choice.name ?? String(choice.value);
2574
+ const normalizedChoice = {
2575
+ value: choice.value,
2576
+ name,
2577
+ short: choice.short ?? name,
2578
+ checkedName: choice.checkedName ?? name,
2579
+ disabled: choice.disabled ?? false,
2580
+ checked: choice.checked ?? false
2581
+ };
2582
+ if (choice.description) {
2583
+ normalizedChoice.description = choice.description;
2584
+ }
2585
+ return normalizedChoice;
2586
+ });
2587
+ }
2588
+ var dist_default4 = createPrompt((config, done) => {
2589
+ const { pageSize = 7, loop = true, required, validate = () => true } = config;
2590
+ const shortcuts = { all: "a", invert: "i", ...config.shortcuts };
2591
+ const theme = makeTheme(checkboxTheme, config.theme);
2592
+ const { keybindings } = theme;
2593
+ const [status, setStatus] = useState("idle");
2594
+ const prefix = usePrefix({ status, theme });
2595
+ const [items, setItems] = useState(normalizeChoices(config.choices));
2596
+ const bounds = useMemo(() => {
2597
+ const first = items.findIndex(isNavigable);
2598
+ const last = items.findLastIndex(isNavigable);
2599
+ if (first === -1) {
2600
+ throw new ValidationError("[checkbox prompt] No selectable choices. All choices are disabled.");
2601
+ }
2602
+ return { first, last };
2603
+ }, [items]);
2604
+ const [active, setActive] = useState(bounds.first);
2605
+ const [errorMsg, setError] = useState();
2606
+ useKeypress(async (key) => {
2607
+ if (isEnterKey(key)) {
2608
+ const selection = items.filter(isChecked);
2609
+ const isValid = await validate([...selection]);
2610
+ if (required && !selection.length) {
2611
+ setError("At least one choice must be selected");
2612
+ } else if (isValid === true) {
2613
+ setStatus("done");
2614
+ done(selection.map((choice) => choice.value));
2615
+ } else {
2616
+ setError(isValid || "You must select a valid value");
2617
+ }
2618
+ } else if (isUpKey(key, keybindings) || isDownKey(key, keybindings)) {
2619
+ if (errorMsg) {
2620
+ setError(undefined);
2621
+ }
2622
+ if (loop || isUpKey(key, keybindings) && active !== bounds.first || isDownKey(key, keybindings) && active !== bounds.last) {
2623
+ const offset = isUpKey(key, keybindings) ? -1 : 1;
2624
+ let next = active;
2625
+ do {
2626
+ next = (next + offset + items.length) % items.length;
2627
+ } while (!isNavigable(items[next]));
2628
+ setActive(next);
2629
+ }
2630
+ } else if (isSpaceKey(key)) {
2631
+ const activeItem = items[active];
2632
+ if (activeItem && !Separator.isSeparator(activeItem)) {
2633
+ if (activeItem.disabled) {
2634
+ setError(theme.i18n.disabledError);
2635
+ } else {
2636
+ setError(undefined);
2637
+ setItems(items.map((choice, i) => i === active ? toggle(choice) : choice));
2638
+ }
2639
+ }
2640
+ } else if (key.name === shortcuts.all) {
2641
+ const selectAll = items.some((choice) => isSelectable(choice) && !choice.checked);
2642
+ setItems(items.map(check(selectAll)));
2643
+ } else if (key.name === shortcuts.invert) {
2644
+ setItems(items.map(toggle));
2645
+ } else if (isNumberKey(key)) {
2646
+ const selectedIndex = Number(key.name) - 1;
2647
+ let selectableIndex = -1;
2648
+ const position = items.findIndex((item) => {
2649
+ if (Separator.isSeparator(item))
2650
+ return false;
2651
+ selectableIndex++;
2652
+ return selectableIndex === selectedIndex;
2653
+ });
2654
+ const selectedItem = items[position];
2655
+ if (selectedItem && isSelectable(selectedItem)) {
2656
+ setActive(position);
2657
+ setItems(items.map((choice, i) => i === position ? toggle(choice) : choice));
2658
+ }
2659
+ }
2660
+ });
2661
+ const message = theme.style.message(config.message, status);
2662
+ let description;
2663
+ const page = usePagination({
2664
+ items,
2665
+ active,
2666
+ renderItem({ item, isActive }) {
2667
+ if (Separator.isSeparator(item)) {
2668
+ return ` ${item.separator}`;
2669
+ }
2670
+ const cursor = isActive ? theme.icon.cursor : " ";
2671
+ if (item.disabled) {
2672
+ const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
2673
+ const checkbox2 = item.checked ? theme.icon.disabledChecked : theme.icon.disabledUnchecked;
2674
+ return theme.style.disabled(`${cursor}${checkbox2} ${item.name} ${disabledLabel}`);
2675
+ }
2676
+ if (isActive) {
2677
+ description = item.description;
2678
+ }
2679
+ const checkbox = item.checked ? theme.icon.checked : theme.icon.unchecked;
2680
+ const name = item.checked ? item.checkedName : item.name;
2681
+ const color = isActive ? theme.style.highlight : (x) => x;
2682
+ return color(`${cursor}${checkbox} ${name}`);
2683
+ },
2684
+ pageSize,
2685
+ loop
2686
+ });
2687
+ if (status === "done") {
2688
+ const selection = items.filter(isChecked);
2689
+ const answer = theme.style.answer(theme.style.renderSelectedChoices(selection, items));
2690
+ return [prefix, message, answer].filter(Boolean).join(" ");
2691
+ }
2692
+ const keys = [
2693
+ ["↑↓", "navigate"],
2694
+ ["space", "select"]
2695
+ ];
2696
+ if (shortcuts.all)
2697
+ keys.push([shortcuts.all, "all"]);
2698
+ if (shortcuts.invert)
2699
+ keys.push([shortcuts.invert, "invert"]);
2700
+ keys.push(["⏎", "submit"]);
2701
+ const helpLine = theme.style.keysHelpTip(keys);
2702
+ const lines = [
2703
+ [prefix, message].filter(Boolean).join(" "),
2704
+ page,
2705
+ " ",
2706
+ description ? theme.style.description(description) : "",
2707
+ errorMsg ? theme.style.error(errorMsg) : "",
2708
+ helpLine
2709
+ ].filter(Boolean).join(`
2710
+ `).trimEnd();
2711
+ return `${lines}${cursorHide}`;
2712
+ });
2713
+ // node_modules/@inquirer/select/dist/index.js
2714
+ import { styleText as styleText4 } from "node:util";
2715
+ var selectTheme = {
2716
+ icon: { cursor: dist_default.pointer },
2717
+ style: {
2718
+ disabled: (text) => styleText4("dim", text),
2719
+ description: (text) => styleText4("cyan", text),
2720
+ keysHelpTip: (keys) => keys.map(([key, action]) => `${styleText4("bold", key)} ${styleText4("dim", action)}`).join(styleText4("dim", " • "))
2721
+ },
2722
+ i18n: { disabledError: "This option is disabled and cannot be selected." },
2723
+ indexMode: "hidden",
2724
+ keybindings: []
2725
+ };
2726
+ function isSelectable2(item) {
2727
+ return !Separator.isSeparator(item) && !item.disabled;
2728
+ }
2729
+ function isNavigable2(item) {
2730
+ return !Separator.isSeparator(item);
2731
+ }
2732
+ function normalizeChoices2(choices) {
2733
+ return choices.map((choice) => {
2734
+ if (Separator.isSeparator(choice))
2735
+ return choice;
2736
+ if (typeof choice !== "object" || choice === null || !("value" in choice)) {
2737
+ const name2 = String(choice);
2738
+ return {
2739
+ value: choice,
2740
+ name: name2,
2741
+ short: name2,
2742
+ disabled: false
2743
+ };
2744
+ }
2745
+ const name = choice.name ?? String(choice.value);
2746
+ const normalizedChoice = {
2747
+ value: choice.value,
2748
+ name,
2749
+ short: choice.short ?? name,
2750
+ disabled: choice.disabled ?? false
2751
+ };
2752
+ if (choice.description) {
2753
+ normalizedChoice.description = choice.description;
2754
+ }
2755
+ return normalizedChoice;
2756
+ });
2757
+ }
2758
+ var dist_default5 = createPrompt((config, done) => {
2759
+ const { loop = true, pageSize = 7 } = config;
2760
+ const theme = makeTheme(selectTheme, config.theme);
2761
+ const { keybindings } = theme;
2762
+ const [status, setStatus] = useState("idle");
2763
+ const prefix = usePrefix({ status, theme });
2764
+ const searchTimeoutRef = useRef();
2765
+ const searchEnabled = !keybindings.includes("vim");
2766
+ const items = useMemo(() => normalizeChoices2(config.choices), [config.choices]);
2767
+ const bounds = useMemo(() => {
2768
+ const first = items.findIndex(isNavigable2);
2769
+ const last = items.findLastIndex(isNavigable2);
2770
+ if (first === -1) {
2771
+ throw new ValidationError("[select prompt] No selectable choices. All choices are disabled.");
2772
+ }
2773
+ return { first, last };
2774
+ }, [items]);
2775
+ const defaultItemIndex = useMemo(() => {
2776
+ if (!("default" in config))
2777
+ return -1;
2778
+ return items.findIndex((item) => isSelectable2(item) && item.value === config.default);
2779
+ }, [config.default, items]);
2780
+ const [active, setActive] = useState(defaultItemIndex === -1 ? bounds.first : defaultItemIndex);
2781
+ const selectedChoice = items[active];
2782
+ if (selectedChoice == null || Separator.isSeparator(selectedChoice)) {
2783
+ throw new Error("Active index does not point to a choice");
2784
+ }
2785
+ const [errorMsg, setError] = useState();
2786
+ useKeypress((key, rl) => {
2787
+ clearTimeout(searchTimeoutRef.current);
2788
+ if (errorMsg) {
2789
+ setError(undefined);
2790
+ }
2791
+ if (isEnterKey(key)) {
2792
+ if (selectedChoice.disabled) {
2793
+ setError(theme.i18n.disabledError);
2794
+ } else {
2795
+ setStatus("done");
2796
+ done(selectedChoice.value);
2797
+ }
2798
+ } else if (isUpKey(key, keybindings) || isDownKey(key, keybindings)) {
2799
+ rl.clearLine(0);
2800
+ if (loop || isUpKey(key, keybindings) && active !== bounds.first || isDownKey(key, keybindings) && active !== bounds.last) {
2801
+ const offset = isUpKey(key, keybindings) ? -1 : 1;
2802
+ let next = active;
2803
+ do {
2804
+ next = (next + offset + items.length) % items.length;
2805
+ } while (!isNavigable2(items[next]));
2806
+ setActive(next);
2807
+ }
2808
+ } else if (isNumberKey(key) && !Number.isNaN(Number(rl.line))) {
2809
+ const selectedIndex = Number(rl.line) - 1;
2810
+ let selectableIndex = -1;
2811
+ const position = items.findIndex((item2) => {
2812
+ if (Separator.isSeparator(item2))
2813
+ return false;
2814
+ selectableIndex++;
2815
+ return selectableIndex === selectedIndex;
2816
+ });
2817
+ const item = items[position];
2818
+ if (item != null && isSelectable2(item)) {
2819
+ setActive(position);
2820
+ }
2821
+ searchTimeoutRef.current = setTimeout(() => {
2822
+ rl.clearLine(0);
2823
+ }, 700);
2824
+ } else if (isBackspaceKey(key)) {
2825
+ rl.clearLine(0);
2826
+ } else if (searchEnabled) {
2827
+ const searchTerm = rl.line.toLowerCase();
2828
+ const matchIndex = items.findIndex((item) => {
2829
+ if (Separator.isSeparator(item) || !isSelectable2(item))
2830
+ return false;
2831
+ return item.name.toLowerCase().startsWith(searchTerm);
2832
+ });
2833
+ if (matchIndex !== -1) {
2834
+ setActive(matchIndex);
2835
+ }
2836
+ searchTimeoutRef.current = setTimeout(() => {
2837
+ rl.clearLine(0);
2838
+ }, 700);
2839
+ }
2840
+ });
2841
+ useEffect(() => () => {
2842
+ clearTimeout(searchTimeoutRef.current);
2843
+ }, []);
2844
+ const message = theme.style.message(config.message, status);
2845
+ const helpLine = theme.style.keysHelpTip([
2846
+ ["↑↓", "navigate"],
2847
+ ["⏎", "select"]
2848
+ ]);
2849
+ let separatorCount = 0;
2850
+ const page = usePagination({
2851
+ items,
2852
+ active,
2853
+ renderItem({ item, isActive, index }) {
2854
+ if (Separator.isSeparator(item)) {
2855
+ separatorCount++;
2856
+ return ` ${item.separator}`;
2857
+ }
2858
+ const cursor = isActive ? theme.icon.cursor : " ";
2859
+ const indexLabel = theme.indexMode === "number" ? `${index + 1 - separatorCount}. ` : "";
2860
+ if (item.disabled) {
2861
+ const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
2862
+ const disabledCursor = isActive ? theme.icon.cursor : "-";
2863
+ return theme.style.disabled(`${disabledCursor} ${indexLabel}${item.name} ${disabledLabel}`);
2864
+ }
2865
+ const color = isActive ? theme.style.highlight : (x) => x;
2866
+ return color(`${cursor} ${indexLabel}${item.name}`);
2867
+ },
2868
+ pageSize,
2869
+ loop
2870
+ });
2871
+ if (status === "done") {
2872
+ return [prefix, message, theme.style.answer(selectedChoice.short)].filter(Boolean).join(" ");
2873
+ }
2874
+ const { description } = selectedChoice;
2875
+ const lines = [
2876
+ [prefix, message].filter(Boolean).join(" "),
2877
+ page,
2878
+ " ",
2879
+ description ? theme.style.description(description) : "",
2880
+ errorMsg ? theme.style.error(errorMsg) : "",
2881
+ helpLine
2882
+ ].filter(Boolean).join(`
2883
+ `).trimEnd();
2884
+ return `${lines}${cursorHide}`;
2885
+ });
2886
+ // src/cli/tui.ts
2887
+ import { emitKeypressEvents } from "node:readline";
2888
+ var TYPE_TAGS = {
2889
+ prompt: "[prompt]",
2890
+ code: "[code] ",
2891
+ hybrid: "[hybrid]"
2892
+ };
2893
+ var TOOL_LABELS = {
2894
+ claude: "Claude Code",
2895
+ cursor: "Cursor",
2896
+ codex: "Codex",
2897
+ gemini: "Gemini CLI"
2898
+ };
2899
+ function formatChoice(skill) {
2900
+ const tag = TYPE_TAGS[skill.type] ?? "[other] ";
2901
+ return {
2902
+ name: `${tag} ${skill.name.padEnd(34)} v${skill.version}`,
2903
+ value: skill.name,
2904
+ description: skill.description
2905
+ };
2906
+ }
2907
+ async function withEscape(fn) {
2908
+ const controller = new AbortController;
2909
+ emitKeypressEvents(process.stdin);
2910
+ const onKeypress = (_str, key) => {
2911
+ if (key?.name === "escape")
2912
+ controller.abort();
2913
+ };
2914
+ process.stdin.on("keypress", onKeypress);
2915
+ try {
2916
+ return await fn(controller.signal);
2917
+ } finally {
2918
+ process.stdin.off("keypress", onKeypress);
2919
+ }
2920
+ }
2921
+ async function browseAndSelect(skills) {
2922
+ return withEscape(async (signal) => {
2923
+ const picked = await dist_default4({
2924
+ message: `Select skills to install (${skills.length} available, Esc to cancel):`,
2925
+ choices: skills.map(formatChoice),
2926
+ pageSize: 15,
2927
+ loop: false
2928
+ }, { signal });
2929
+ return { picked };
2930
+ });
2931
+ }
2932
+ async function pickTools(message, allowed) {
2933
+ const choices = TOOL_NAMES.filter((t) => !allowed || allowed.includes(t)).map((t) => ({
2934
+ name: TOOL_LABELS[t],
2935
+ value: t
2936
+ }));
2937
+ return withEscape(async (signal) => dist_default4({
2938
+ message: `${message} (Esc to cancel)`,
2939
+ choices,
2940
+ required: true
2941
+ }, { signal }));
2942
+ }
2943
+ async function pickActivation(skillName, modes) {
2944
+ const labels = {
2945
+ session: `Per-session: invoke manually with /${skillName}`,
2946
+ global: "Global: auto-activate every session (adds SessionStart hook)"
2947
+ };
2948
+ return withEscape(async (signal) => dist_default5({
2949
+ message: `How should ${skillName} activate in Claude Code? (Esc to cancel)`,
2950
+ choices: modes.map((m) => ({ name: labels[m], value: m }))
2951
+ }, { signal }));
939
2952
  }
940
2953
 
941
2954
  // src/cli/index.ts
@@ -978,7 +2991,9 @@ function printHelp() {
978
2991
  @iceinvein/agent-skills \u2014 Install agent skills into AI coding tools
979
2992
 
980
2993
  Usage:
981
- agent-skills install <skill> [--tool <tool>] [--activation <session|global>] [-g] Install a skill
2994
+ agent-skills install <skill> [<skill> ...] [--tool <tool>] [--activation <mode>] [-g] Install one or more skills
2995
+ agent-skills install [--tool <tool>] [-g] No args: opens interactive picker
2996
+ agent-skills browse [--tool <tool>] [-g] Alias for 'install' with picker
982
2997
  agent-skills remove <skill> [-g] Remove a skill
983
2998
  agent-skills update <skill> [-g] Update a skill
984
2999
  agent-skills update --all [-g] Update all installed skills
@@ -1005,84 +3020,122 @@ function printInstalled(result, skipped) {
1005
3020
  console.log(` \u2298 ${tool} (skill does not support this tool)`);
1006
3021
  }
1007
3022
  }
3023
+ var TOOL_DIRS = {
3024
+ claude: ".claude",
3025
+ cursor: ".cursor",
3026
+ gemini: ".gemini"
3027
+ };
3028
+ async function resolveTargetTools(installDir, isGlobal, flags) {
3029
+ if (flags.tool) {
3030
+ if (!TOOL_NAMES2.includes(flags.tool)) {
3031
+ console.error(`Error: unknown tool '${flags.tool}'. Must be one of: ${TOOL_NAMES2.join(", ")}`);
3032
+ return null;
3033
+ }
3034
+ return [flags.tool];
3035
+ }
3036
+ const detected = await detectTools(installDir);
3037
+ if (detected.length > 0) {
3038
+ console.log(`Detected tools: ${detected.join(", ")}`);
3039
+ return detected;
3040
+ }
3041
+ if (!process.stdin.isTTY) {
3042
+ console.error("Error: no tools detected and no TTY for prompting. Pass --tool <claude|cursor|codex|gemini>.");
3043
+ return null;
3044
+ }
3045
+ const picked = await pickTools(isGlobal ? "Which tools do you use?" : "No tools detected in this directory. Which tools do you use?");
3046
+ for (const tool of picked) {
3047
+ const dir = TOOL_DIRS[tool];
3048
+ if (dir)
3049
+ mkdirSync4(join8(installDir, dir), { recursive: true });
3050
+ }
3051
+ return picked;
3052
+ }
3053
+ async function installOne(skillName, installDir, isGlobal, targetTools, flags) {
3054
+ console.log(`Fetching skill '${skillName}'...`);
3055
+ const manifestResult = await fetchSkillManifest(skillName);
3056
+ if (!manifestResult.ok) {
3057
+ console.error(`Error: ${manifestResult.error}`);
3058
+ return false;
3059
+ }
3060
+ const filesResult = await fetchAllSkillFiles(skillName, manifestResult.manifest);
3061
+ if ("error" in filesResult) {
3062
+ console.error(`Error: ${filesResult.error}`);
3063
+ return false;
3064
+ }
3065
+ const manifest = manifestResult.manifest;
3066
+ let activation;
3067
+ if (manifest.activation && targetTools.includes("claude")) {
3068
+ const validModes = manifest.activation.modes;
3069
+ if (flags.activation) {
3070
+ if (!validModes.includes(flags.activation)) {
3071
+ console.error(`Error: activation mode '${flags.activation}' not supported. Must be one of: ${validModes.join(", ")}`);
3072
+ return false;
3073
+ }
3074
+ activation = flags.activation;
3075
+ } else if (process.stdin.isTTY) {
3076
+ activation = await pickActivation(manifest.name, validModes);
3077
+ } else {
3078
+ activation = manifest.activation.default;
3079
+ }
3080
+ }
3081
+ const result = await installSkill(installDir, manifest, filesResult, targetTools, activation);
3082
+ if (!result.ok) {
3083
+ console.error(`Error: ${result.error}`);
3084
+ return false;
3085
+ }
3086
+ console.log(`
3087
+ \u2713 Installed '${skillName}' v${manifest.version}${isGlobal ? " (global)" : ""}:`);
3088
+ printInstalled(result.installed, result.skipped);
3089
+ return true;
3090
+ }
1008
3091
  async function main() {
1009
3092
  const { command, args, flags } = parseArgs(process.argv.slice(2));
1010
3093
  switch (command) {
1011
- case "install": {
1012
- const skillName = args[0];
1013
- if (!skillName) {
1014
- console.error("Error: skill name required. Usage: agent-skills install <skill>");
1015
- process.exit(1);
1016
- }
3094
+ case "install":
3095
+ case "browse": {
1017
3096
  const installDir = resolveInstallDir(flags);
1018
3097
  const isGlobal = installDir === homedir();
1019
- if (isGlobal)
1020
- console.log(`Installing globally to ${installDir}`);
1021
- console.log(`Fetching skill '${skillName}'...`);
1022
- const manifestResult = await fetchSkillManifest(skillName);
1023
- if (!manifestResult.ok) {
1024
- console.error(`Error: ${manifestResult.error}`);
1025
- process.exit(1);
1026
- }
1027
- const filesResult = await fetchAllSkillFiles(skillName, manifestResult.manifest);
1028
- if ("error" in filesResult) {
1029
- console.error(`Error: ${filesResult.error}`);
1030
- process.exit(1);
1031
- }
1032
- let tools;
1033
- if (flags.tool) {
1034
- if (!TOOL_NAMES2.includes(flags.tool)) {
1035
- console.error(`Error: unknown tool '${flags.tool}'. Must be one of: ${TOOL_NAMES2.join(", ")}`);
3098
+ let names = args;
3099
+ if (names.length === 0 || command === "browse") {
3100
+ if (!process.stdin.isTTY) {
3101
+ console.error("Error: skill name required. Usage: agent-skills install <skill> [<skill> ...]");
1036
3102
  process.exit(1);
1037
3103
  }
1038
- tools = [flags.tool];
1039
- } else {
1040
- tools = await detectTools(installDir);
1041
- if (tools.length === 0) {
1042
- const supportedTools = manifestResult.manifest.tools;
1043
- const selected = await promptSelect(isGlobal ? "Which tools do you use?" : "No tools detected in this directory. Which tools do you use?", supportedTools.map((t) => ({
1044
- label: { claude: "Claude Code", cursor: "Cursor", codex: "Codex", gemini: "Gemini CLI" }[t],
1045
- value: t
1046
- })));
1047
- tools = selected;
1048
- for (const tool of tools) {
1049
- const dirs = {
1050
- claude: ".claude",
1051
- cursor: ".cursor",
1052
- gemini: ".gemini"
1053
- };
1054
- if (dirs[tool]) {
1055
- mkdirSync4(join8(installDir, dirs[tool]), { recursive: true });
1056
- }
1057
- }
1058
- } else {
1059
- console.log(`Detected tools: ${tools.join(", ")}`);
3104
+ if (isGlobal)
3105
+ console.log(`Browsing for global install (${installDir})`);
3106
+ console.log(`Fetching skill index...
3107
+ `);
3108
+ const indexResult = await listSkills();
3109
+ if (!indexResult.ok) {
3110
+ console.error(`Error: ${indexResult.error}`);
3111
+ process.exit(1);
1060
3112
  }
1061
- }
1062
- let activation;
1063
- const manifest = manifestResult.manifest;
1064
- if (manifest.activation && tools.includes("claude")) {
1065
- const validModes = manifest.activation.modes;
1066
- if (flags.activation) {
1067
- if (!validModes.includes(flags.activation)) {
1068
- console.error(`Error: activation mode '${flags.activation}' not supported. Must be one of: ${validModes.join(", ")}`);
1069
- process.exit(1);
1070
- }
1071
- activation = flags.activation;
1072
- } else if (process.stdin.isTTY) {
1073
- activation = await promptActivation(manifest.name, validModes);
1074
- } else {
1075
- activation = manifest.activation.default;
3113
+ const { picked } = await browseAndSelect(indexResult.skills);
3114
+ if (picked.length === 0) {
3115
+ console.log(`
3116
+ Nothing selected.`);
3117
+ break;
1076
3118
  }
3119
+ names = picked;
3120
+ } else if (isGlobal) {
3121
+ console.log(`Installing globally to ${installDir}`);
1077
3122
  }
1078
- const result = await installSkill(installDir, manifestResult.manifest, filesResult, tools, activation);
1079
- if (!result.ok) {
1080
- console.error(`Error: ${result.error}`);
3123
+ const targetTools = await resolveTargetTools(installDir, isGlobal, flags);
3124
+ if (!targetTools)
1081
3125
  process.exit(1);
3126
+ if (names.length > 1) {
3127
+ console.log(`
3128
+ Installing ${names.length} skills...
3129
+ `);
1082
3130
  }
1083
- console.log(`
1084
- \u2713 Installed '${skillName}' v${manifestResult.manifest.version}${isGlobal ? " (global)" : ""}:`);
1085
- printInstalled(result.installed, result.skipped);
3131
+ let failures = 0;
3132
+ for (const name of names) {
3133
+ const ok = await installOne(name, installDir, isGlobal, targetTools, flags);
3134
+ if (!ok)
3135
+ failures++;
3136
+ }
3137
+ if (failures > 0)
3138
+ process.exit(1);
1086
3139
  break;
1087
3140
  }
1088
3141
  case "remove": {
@@ -1240,7 +3293,14 @@ ${m.name} v${m.version}`);
1240
3293
  }
1241
3294
  }
1242
3295
  }
3296
+ var CANCEL_ERRORS = new Set(["ExitPromptError", "AbortPromptError", "CancelPromptError"]);
1243
3297
  main().catch((err) => {
3298
+ const name = err?.name ?? err?.constructor?.name;
3299
+ if (CANCEL_ERRORS.has(name)) {
3300
+ console.log(`
3301
+ Cancelled.`);
3302
+ process.exit(130);
3303
+ }
1244
3304
  console.error("Fatal:", err.message);
1245
3305
  process.exit(1);
1246
3306
  });