agentinit 1.18.2 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -8347,6 +8347,159 @@ var require_prompts3 = __commonJS((exports, module) => {
8347
8347
  module.exports = isNodeLT("8.6.0") ? require_dist() : require_lib();
8348
8348
  });
8349
8349
 
8350
+ // node_modules/kleur/colors.mjs
8351
+ var init, FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY, $, reset, bold, dim, italic, underline, inverse, hidden, strikethrough, black, red, green, yellow, blue, magenta, cyan, white, gray, grey, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite;
8352
+ var init_colors = __esm(() => {
8353
+ init = function(x, y) {
8354
+ let rgx = new RegExp(`\\x1b\\[${y}m`, "g");
8355
+ let open = `\x1B[${x}m`, close = `\x1B[${y}m`;
8356
+ return function(txt) {
8357
+ if (!$.enabled || txt == null)
8358
+ return txt;
8359
+ return open + (~("" + txt).indexOf(close) ? txt.replace(rgx, close + open) : txt) + close;
8360
+ };
8361
+ };
8362
+ isTTY = true;
8363
+ if (typeof process !== "undefined") {
8364
+ ({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
8365
+ isTTY = process.stdout && process.stdout.isTTY;
8366
+ }
8367
+ $ = {
8368
+ enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY)
8369
+ };
8370
+ reset = init(0, 0);
8371
+ bold = init(1, 22);
8372
+ dim = init(2, 22);
8373
+ italic = init(3, 23);
8374
+ underline = init(4, 24);
8375
+ inverse = init(7, 27);
8376
+ hidden = init(8, 28);
8377
+ strikethrough = init(9, 29);
8378
+ black = init(30, 39);
8379
+ red = init(31, 39);
8380
+ green = init(32, 39);
8381
+ yellow = init(33, 39);
8382
+ blue = init(34, 39);
8383
+ magenta = init(35, 39);
8384
+ cyan = init(36, 39);
8385
+ white = init(37, 39);
8386
+ gray = init(90, 39);
8387
+ grey = init(90, 39);
8388
+ bgBlack = init(40, 49);
8389
+ bgRed = init(41, 49);
8390
+ bgGreen = init(42, 49);
8391
+ bgYellow = init(43, 49);
8392
+ bgBlue = init(44, 49);
8393
+ bgMagenta = init(45, 49);
8394
+ bgCyan = init(46, 49);
8395
+ bgWhite = init(47, 49);
8396
+ });
8397
+
8398
+ // dist/utils/symbols.js
8399
+ var STATUS, TREE, BOX;
8400
+ var init_symbols = __esm(() => {
8401
+ STATUS = {
8402
+ success: "\u2713",
8403
+ error: "\u2717",
8404
+ warning: "\u26A0",
8405
+ info: "\u2139",
8406
+ debug: "\u2022"
8407
+ };
8408
+ TREE = {
8409
+ branch: "\u251C\u2500",
8410
+ last: "\u2514\u2500"
8411
+ };
8412
+ BOX = {
8413
+ topLeft: "\u250C",
8414
+ topRight: "\u2510",
8415
+ bottomLeft: "\u2514",
8416
+ bottomRight: "\u2518",
8417
+ horizontal: "\u2500",
8418
+ vertical: "\u2502"
8419
+ };
8420
+ });
8421
+
8422
+ // dist/utils/logger.js
8423
+ class Logger {
8424
+ static instance;
8425
+ static getInstance() {
8426
+ if (!Logger.instance) {
8427
+ Logger.instance = new Logger;
8428
+ }
8429
+ return Logger.instance;
8430
+ }
8431
+ info(message) {
8432
+ console.log(cyan(STATUS.info), message);
8433
+ }
8434
+ success(message) {
8435
+ console.log(green(STATUS.success), message);
8436
+ }
8437
+ warning(message) {
8438
+ console.log(yellow(STATUS.warning), message);
8439
+ }
8440
+ warn(message) {
8441
+ this.warning(message);
8442
+ }
8443
+ error(message) {
8444
+ console.log(red(STATUS.error), message);
8445
+ }
8446
+ debug(message) {
8447
+ console.log(dim(STATUS.debug), dim(message));
8448
+ }
8449
+ title(message) {
8450
+ console.log(bold(cyan(message)));
8451
+ }
8452
+ subtitle(message) {
8453
+ console.log(bold(message));
8454
+ }
8455
+ titleBox(message) {
8456
+ const w = getTerminalWidth();
8457
+ if (w < 8) {
8458
+ console.log(bold(cyan(truncateText(message, w))));
8459
+ return;
8460
+ }
8461
+ const maxInner = Math.max(4, w - 2);
8462
+ const inner = Math.min(Math.max(message.length + 4, 40), maxInner);
8463
+ const visibleMessage = truncateText(message, inner - 2);
8464
+ const padR = Math.max(0, inner - visibleMessage.length - 2);
8465
+ console.log(dim(BOX.topLeft + BOX.horizontal.repeat(inner) + BOX.topRight));
8466
+ console.log(dim(BOX.vertical) + " " + bold(cyan(visibleMessage)) + " ".repeat(padR) + " " + dim(BOX.vertical));
8467
+ console.log(dim(BOX.bottomLeft + BOX.horizontal.repeat(inner) + BOX.bottomRight));
8468
+ }
8469
+ section(title) {
8470
+ const w = getTerminalWidth();
8471
+ const lineLen = Math.max(0, w - title.length - 5);
8472
+ console.log("");
8473
+ console.log(bold(`${BOX.horizontal}${BOX.horizontal} ${title} ${BOX.horizontal.repeat(lineLen)}`));
8474
+ }
8475
+ tree(message, isLast) {
8476
+ const connector = isLast ? TREE.last : TREE.branch;
8477
+ console.log(`${connector} ${message}`);
8478
+ }
8479
+ }
8480
+ var getTerminalWidth, truncateText, logger;
8481
+ var init_logger = __esm(() => {
8482
+ init_colors();
8483
+ init_symbols();
8484
+ getTerminalWidth = function() {
8485
+ const columns = process.stdout.columns;
8486
+ return typeof columns === "number" && columns > 0 ? columns : 80;
8487
+ };
8488
+ truncateText = function(text, maxLength) {
8489
+ if (maxLength <= 0) {
8490
+ return "";
8491
+ }
8492
+ if (text.length <= maxLength) {
8493
+ return text;
8494
+ }
8495
+ if (maxLength <= 3) {
8496
+ return ".".repeat(maxLength);
8497
+ }
8498
+ return `${text.slice(0, maxLength - 3)}...`;
8499
+ };
8500
+ logger = Logger.getInstance();
8501
+ });
8502
+
8350
8503
  // dist/utils/fs.js
8351
8504
  import {promises as fs} from "fs";
8352
8505
  import {platform} from "os";
@@ -16952,6 +17105,280 @@ var init_skills = __esm(() => {
16952
17105
  SHARED_SKILLS_TARGET_NAME = "AGENTS.md ecosystem";
16953
17106
  });
16954
17107
 
17108
+ // dist/core/installLock.js
17109
+ import {promises as fs22} from "fs";
17110
+ import {homedir as homedir4} from "os";
17111
+ import {dirname as dirname2, join as join4, resolve as resolve7} from "path";
17112
+ import {createHash, randomUUID} from "crypto";
17113
+ function getLockEntryTargetLabel(entry) {
17114
+ return entry.scope === "global" ? "Global scope" : entry.projectPath;
17115
+ }
17116
+ function logLockWriteWarning(context, error) {
17117
+ const detail = error instanceof Error ? error.message : "unknown error";
17118
+ logger.warn(`${context}, but failed to update the install lock: ${detail}`);
17119
+ }
17120
+ async function hashDirectory(rootPath) {
17121
+ if (!await fileExists(rootPath))
17122
+ return null;
17123
+ const hash = createHash("sha256");
17124
+ const walk = async (currentPath, relativePath) => {
17125
+ const stat = await fs22.stat(currentPath);
17126
+ if (stat.isDirectory()) {
17127
+ hash.update(`dir:${relativePath}\n`);
17128
+ const entries = await fs22.readdir(currentPath);
17129
+ entries.sort();
17130
+ for (const entry of entries) {
17131
+ await walk(join4(currentPath, entry), `${relativePath}/${entry}`);
17132
+ }
17133
+ } else {
17134
+ const content = await fs22.readFile(currentPath);
17135
+ hash.update(`file:${relativePath}\n`);
17136
+ hash.update(content);
17137
+ hash.update("\n");
17138
+ }
17139
+ };
17140
+ await walk(rootPath, ".");
17141
+ return hash.digest("hex");
17142
+ }
17143
+
17144
+ class InstallLock {
17145
+ state = null;
17146
+ async load() {
17147
+ if (this.state)
17148
+ return this.state;
17149
+ const content = await readFileIfExists(getLockPath());
17150
+ if (!content) {
17151
+ this.state = { version: 1, entries: [] };
17152
+ return this.state;
17153
+ }
17154
+ try {
17155
+ const parsed = JSON.parse(content);
17156
+ if (parsed?.version === 1 && Array.isArray(parsed.entries)) {
17157
+ this.state = parsed;
17158
+ } else {
17159
+ this.state = { version: 1, entries: [] };
17160
+ }
17161
+ } catch {
17162
+ this.state = { version: 1, entries: [] };
17163
+ }
17164
+ return this.state;
17165
+ }
17166
+ async save() {
17167
+ if (!this.state)
17168
+ return;
17169
+ const lockPath = getLockPath();
17170
+ await fs22.mkdir(dirname2(lockPath), { recursive: true });
17171
+ await fs22.writeFile(lockPath, JSON.stringify(this.state, null, 2) + "\n", {
17172
+ encoding: "utf8",
17173
+ mode: 384
17174
+ });
17175
+ await fs22.chmod(lockPath, 384).catch(() => {
17176
+ });
17177
+ }
17178
+ async recordSkill(params) {
17179
+ const state = await this.load();
17180
+ const metadata = {
17181
+ kind: "skill",
17182
+ installPath: params.installPath,
17183
+ ...params.canonicalPath ? { canonicalPath: params.canonicalPath } : {},
17184
+ mode: params.mode
17185
+ };
17186
+ const entry = createEntry({
17187
+ kind: "skill",
17188
+ action: params.action,
17189
+ name: params.name,
17190
+ projectPath: resolve7(params.projectPath),
17191
+ agents: params.agents,
17192
+ scope: params.scope,
17193
+ source: params.source,
17194
+ ...params.contentHash ? { contentHash: params.contentHash } : {},
17195
+ metadata
17196
+ });
17197
+ state.entries.push(entry);
17198
+ await this.save();
17199
+ return entry;
17200
+ }
17201
+ async recordMcp(params) {
17202
+ const state = await this.load();
17203
+ const metadata = {
17204
+ kind: "mcp",
17205
+ configPath: params.configPath,
17206
+ serverType: params.serverType,
17207
+ ...params.command ? { command: params.command } : {},
17208
+ ...params.url ? { url: sanitizeUrlForLock(params.url) } : {}
17209
+ };
17210
+ const entry = createEntry({
17211
+ kind: "mcp",
17212
+ action: params.action,
17213
+ name: params.name,
17214
+ projectPath: resolve7(params.projectPath),
17215
+ agents: params.agents,
17216
+ scope: params.scope,
17217
+ source: params.source,
17218
+ metadata
17219
+ });
17220
+ state.entries.push(entry);
17221
+ await this.save();
17222
+ return entry;
17223
+ }
17224
+ async recordRules(params) {
17225
+ const state = await this.load();
17226
+ const metadata = {
17227
+ kind: "rules",
17228
+ configPath: params.configPath,
17229
+ templateIds: params.templateIds,
17230
+ ruleCount: params.ruleCount
17231
+ };
17232
+ const entry = createEntry({
17233
+ kind: "rules",
17234
+ action: params.action,
17235
+ name: params.name,
17236
+ projectPath: resolve7(params.projectPath),
17237
+ agents: params.agents,
17238
+ scope: params.scope,
17239
+ source: params.source,
17240
+ metadata
17241
+ });
17242
+ state.entries.push(entry);
17243
+ await this.save();
17244
+ return entry;
17245
+ }
17246
+ async query(options2 = {}) {
17247
+ const state = await this.load();
17248
+ return state.entries.filter((entry) => {
17249
+ if (options2.kind && entry.kind !== options2.kind)
17250
+ return false;
17251
+ if (options2.name && entry.name.toLowerCase() !== options2.name.toLowerCase())
17252
+ return false;
17253
+ if (options2.projectPath && entry.projectPath !== resolve7(options2.projectPath))
17254
+ return false;
17255
+ if (options2.agent && !entry.agents.includes(options2.agent))
17256
+ return false;
17257
+ if (options2.scope && entry.scope !== options2.scope)
17258
+ return false;
17259
+ if (options2.action && entry.action !== options2.action)
17260
+ return false;
17261
+ return true;
17262
+ });
17263
+ }
17264
+ async getCurrentState(options2 = {}) {
17265
+ const entries = await this.query(options2);
17266
+ const groups = new Map;
17267
+ for (const entry of entries) {
17268
+ const key = this.getCurrentStateKey(entry);
17269
+ groups.set(key, entry);
17270
+ }
17271
+ return [...groups.values()].filter((e) => e.action !== "remove");
17272
+ }
17273
+ getCurrentStateKey(entry) {
17274
+ const agents = [...entry.agents].sort().join(",");
17275
+ return [
17276
+ entry.kind,
17277
+ entry.name.toLowerCase(),
17278
+ getEntryTargetKey(entry),
17279
+ entry.scope,
17280
+ agents,
17281
+ this.getLocationKey(entry)
17282
+ ].join(":");
17283
+ }
17284
+ getLocationKey(entry) {
17285
+ switch (entry.metadata.kind) {
17286
+ case "skill":
17287
+ return entry.metadata.canonicalPath || entry.metadata.installPath;
17288
+ case "mcp":
17289
+ return entry.metadata.configPath;
17290
+ case "rules":
17291
+ return `${entry.metadata.configPath}:${entry.metadata.templateIds.join(",")}`;
17292
+ }
17293
+ }
17294
+ async getProjectPaths() {
17295
+ const state = await this.load();
17296
+ return [...new Set(state.entries.filter((entry) => entry.scope === "project").map((entry) => entry.projectPath))];
17297
+ }
17298
+ async findProjectsWithSkill(skillName) {
17299
+ return this.getCurrentState({ kind: "skill", name: skillName });
17300
+ }
17301
+ async findStaleProjects() {
17302
+ const projectPaths = await this.getProjectPaths();
17303
+ const stale = [];
17304
+ for (const projectPath of projectPaths) {
17305
+ if (!await fileExists(projectPath)) {
17306
+ stale.push(projectPath);
17307
+ }
17308
+ }
17309
+ return stale;
17310
+ }
17311
+ async pruneStaleEntries() {
17312
+ const stale = await this.findStaleProjects();
17313
+ let entriesRemoved = 0;
17314
+ if (stale.length === 0) {
17315
+ return { prunedProjects: [], entriesRemoved: 0 };
17316
+ }
17317
+ const state = await this.load();
17318
+ const staleSet = new Set(stale);
17319
+ const before = state.entries.length;
17320
+ state.entries = state.entries.filter((e) => !staleSet.has(e.projectPath));
17321
+ entriesRemoved = before - state.entries.length;
17322
+ if (entriesRemoved > 0) {
17323
+ await this.save();
17324
+ }
17325
+ return { prunedProjects: stale, entriesRemoved };
17326
+ }
17327
+ async checkDrift(entry) {
17328
+ if (!entry.contentHash) {
17329
+ return { entry, status: "match" };
17330
+ }
17331
+ if (entry.metadata.kind !== "skill") {
17332
+ return { entry, status: "match" };
17333
+ }
17334
+ const installPath = entry.metadata.installPath;
17335
+ if (!await fileExists(installPath)) {
17336
+ return { entry, status: "missing" };
17337
+ }
17338
+ const currentHash = await hashDirectory(installPath);
17339
+ if (!currentHash) {
17340
+ return { entry, status: "missing" };
17341
+ }
17342
+ return {
17343
+ entry,
17344
+ status: currentHash === entry.contentHash ? "match" : "drift",
17345
+ currentHash
17346
+ };
17347
+ }
17348
+ }
17349
+ var getLockPath, getEntryTargetKey, createEntry, sanitizeUrlForLock, LOCK_FILE, GLOBAL_TARGET_KEY;
17350
+ var init_installLock = __esm(() => {
17351
+ init_fs();
17352
+ init_logger();
17353
+ getLockPath = function() {
17354
+ return join4(homedir4(), ".agentinit", LOCK_FILE);
17355
+ };
17356
+ getEntryTargetKey = function(entry) {
17357
+ return entry.scope === "global" ? GLOBAL_TARGET_KEY : entry.projectPath;
17358
+ };
17359
+ createEntry = function(base) {
17360
+ return {
17361
+ id: randomUUID(),
17362
+ timestamp: new Date().toISOString(),
17363
+ ...base
17364
+ };
17365
+ };
17366
+ sanitizeUrlForLock = function(url) {
17367
+ try {
17368
+ const parsed = new URL(url);
17369
+ parsed.username = "";
17370
+ parsed.password = "";
17371
+ parsed.search = "";
17372
+ parsed.hash = "";
17373
+ return parsed.toString();
17374
+ } catch {
17375
+ return url.split(/[?#]/)[0] || url;
17376
+ }
17377
+ };
17378
+ LOCK_FILE = "lock.json";
17379
+ GLOBAL_TARGET_KEY = "__agentinit_global__";
17380
+ });
17381
+
16955
17382
  // dist/core/mcpFilter.js
16956
17383
  class MCPFilter {
16957
17384
  static filterForAgent(agent, servers) {
@@ -17066,9 +17493,9 @@ __export(exports_pluginManager, {
17066
17493
  }
17067
17494
  }
17068
17495
  });
17069
- import {resolve as resolve7, join as join4, basename as basename2, relative as relative2, dirname as dirname2} from "path";
17070
- import {promises as fs22} from "fs";
17071
- import {homedir as homedir4} from "os";
17496
+ import {resolve as resolve8, join as join5, basename as basename2, relative as relative2, dirname as dirname3} from "path";
17497
+ import {promises as fs24} from "fs";
17498
+ import {homedir as homedir5} from "os";
17072
17499
 
17073
17500
  class MultipleBundlePluginsError extends Error {
17074
17501
  entries;
@@ -17112,7 +17539,7 @@ class PluginManager {
17112
17539
  }
17113
17540
  async cleanupLoadedPluginContext(context) {
17114
17541
  if (context?.tempDir) {
17115
- await fs22.rm(context.tempDir, { recursive: true, force: true }).catch(() => {
17542
+ await fs24.rm(context.tempDir, { recursive: true, force: true }).catch(() => {
17116
17543
  });
17117
17544
  }
17118
17545
  }
@@ -17190,7 +17617,7 @@ class PluginManager {
17190
17617
  return "unverified";
17191
17618
  }
17192
17619
  async resolvePreparedPluginDir(pluginDir, source) {
17193
- const claudeMarketplaceManifestPath = join4(pluginDir, ".claude-plugin", "marketplace.json");
17620
+ const claudeMarketplaceManifestPath = join5(pluginDir, ".claude-plugin", "marketplace.json");
17194
17621
  if (!await fileExists(claudeMarketplaceManifestPath)) {
17195
17622
  return { pluginDir, warnings: [] };
17196
17623
  }
@@ -17225,8 +17652,8 @@ class PluginManager {
17225
17652
  }
17226
17653
  selectedEntry = matched;
17227
17654
  }
17228
- const selectedPluginDir = resolve7(pluginDir, selectedEntry.source);
17229
- const relativePath = relative2(resolve7(pluginDir), selectedPluginDir);
17655
+ const selectedPluginDir = resolve8(pluginDir, selectedEntry.source);
17656
+ const relativePath = relative2(resolve8(pluginDir), selectedPluginDir);
17230
17657
  if (relativePath.startsWith("..") || relativePath.includes("/../") || relativePath.includes("\\..\\")) {
17231
17658
  throw new Error(`Invalid bundled plugin source path "${selectedEntry.source}" in ${claudeMarketplaceManifestPath}`);
17232
17659
  }
@@ -17293,7 +17720,7 @@ class PluginManager {
17293
17720
  tempDir = await this.skillsManager.cloneRepo(resolved.url);
17294
17721
  pluginDir = tempDir;
17295
17722
  } else {
17296
- pluginDir = resolve7(resolved.path || source);
17723
+ pluginDir = resolve8(resolved.path || source);
17297
17724
  if (!await fileExists(pluginDir)) {
17298
17725
  throw new Error(`Local path not found: ${pluginDir}`);
17299
17726
  }
@@ -17338,15 +17765,15 @@ class PluginManager {
17338
17765
  }
17339
17766
  async getClaudeNativeFeatureKinds(pluginDir, manifest) {
17340
17767
  const featureChecks = await Promise.all([
17341
- (async () => !!manifest.commands || await isDirectory(join4(pluginDir, "commands")))(),
17342
- (async () => !!manifest.hooks || await isDirectory(join4(pluginDir, "hooks")))(),
17343
- (async () => !!manifest.agents || await isDirectory(join4(pluginDir, "agents")))(),
17344
- isDirectory(join4(pluginDir, "skills")),
17345
- (async () => !!manifest.mcpServers || await fileExists(join4(pluginDir, ".mcp.json")))(),
17346
- isDirectory(join4(pluginDir, "prompts")),
17347
- isDirectory(join4(pluginDir, "schemas")),
17348
- isDirectory(join4(pluginDir, "scripts")),
17349
- isDirectory(join4(pluginDir, "templates"))
17768
+ (async () => !!manifest.commands || await isDirectory(join5(pluginDir, "commands")))(),
17769
+ (async () => !!manifest.hooks || await isDirectory(join5(pluginDir, "hooks")))(),
17770
+ (async () => !!manifest.agents || await isDirectory(join5(pluginDir, "agents")))(),
17771
+ isDirectory(join5(pluginDir, "skills")),
17772
+ (async () => !!manifest.mcpServers || await fileExists(join5(pluginDir, ".mcp.json")))(),
17773
+ isDirectory(join5(pluginDir, "prompts")),
17774
+ isDirectory(join5(pluginDir, "schemas")),
17775
+ isDirectory(join5(pluginDir, "scripts")),
17776
+ isDirectory(join5(pluginDir, "templates"))
17350
17777
  ]);
17351
17778
  return [
17352
17779
  ...featureChecks[0] ? ["commands"] : [],
@@ -17364,7 +17791,7 @@ class PluginManager {
17364
17791
  if (plugin.format !== "claude") {
17365
17792
  return null;
17366
17793
  }
17367
- const manifestContent = await readFileIfExists(join4(pluginDir, ".claude-plugin", "plugin.json"));
17794
+ const manifestContent = await readFileIfExists(join5(pluginDir, ".claude-plugin", "plugin.json"));
17368
17795
  if (!manifestContent) {
17369
17796
  return null;
17370
17797
  }
@@ -17384,7 +17811,7 @@ class PluginManager {
17384
17811
  return {
17385
17812
  namespace,
17386
17813
  pluginKey: `${plugin.name}@${namespace}`,
17387
- installPath: join4(homedir4(), ".claude", "plugins", "cache", namespace, plugin.name, versionDir),
17814
+ installPath: join5(homedir5(), ".claude", "plugins", "cache", namespace, plugin.name, versionDir),
17388
17815
  marketplacePath: getClaudeMarketplaceInstallPath(namespace),
17389
17816
  features
17390
17817
  };
@@ -17448,12 +17875,12 @@ class PluginManager {
17448
17875
  await writeFile(getClaudeSettingsPath(), JSON.stringify(state, null, 2));
17449
17876
  }
17450
17877
  async findClaudeMarketplaceRoot(pluginDir) {
17451
- let currentDir = resolve7(pluginDir);
17878
+ let currentDir = resolve8(pluginDir);
17452
17879
  while (true) {
17453
- if (await fileExists(join4(currentDir, ".claude-plugin", "marketplace.json"))) {
17880
+ if (await fileExists(join5(currentDir, ".claude-plugin", "marketplace.json"))) {
17454
17881
  return currentDir;
17455
17882
  }
17456
- const parentDir = dirname2(currentDir);
17883
+ const parentDir = dirname3(currentDir);
17457
17884
  if (parentDir === currentDir) {
17458
17885
  return null;
17459
17886
  }
@@ -17461,7 +17888,7 @@ class PluginManager {
17461
17888
  }
17462
17889
  }
17463
17890
  async readClaudeMarketplaceManifest(marketplaceDir) {
17464
- const manifestContent = await readFileIfExists(join4(marketplaceDir, ".claude-plugin", "marketplace.json"));
17891
+ const manifestContent = await readFileIfExists(join5(marketplaceDir, ".claude-plugin", "marketplace.json"));
17465
17892
  if (!manifestContent) {
17466
17893
  return null;
17467
17894
  }
@@ -17480,19 +17907,19 @@ class PluginManager {
17480
17907
  }
17481
17908
  }
17482
17909
  async saveClaudeMarketplaceManifest(marketplaceDir, manifest) {
17483
- await fs22.mkdir(join4(marketplaceDir, ".claude-plugin"), { recursive: true });
17484
- await writeFile(join4(marketplaceDir, ".claude-plugin", "marketplace.json"), JSON.stringify(manifest, null, 2));
17910
+ await fs24.mkdir(join5(marketplaceDir, ".claude-plugin"), { recursive: true });
17911
+ await writeFile(join5(marketplaceDir, ".claude-plugin", "marketplace.json"), JSON.stringify(manifest, null, 2));
17485
17912
  }
17486
17913
  resolveMarketplaceSourcePath(baseDir, relativePath) {
17487
- const resolvedPath = resolve7(baseDir, relativePath);
17488
- const relativePathFromBase = relative2(resolve7(baseDir), resolvedPath);
17914
+ const resolvedPath = resolve8(baseDir, relativePath);
17915
+ const relativePathFromBase = relative2(resolve8(baseDir), resolvedPath);
17489
17916
  if (relativePathFromBase.startsWith("..") || relativePathFromBase.includes("/../") || relativePathFromBase.includes("\\..\\")) {
17490
17917
  throw new Error(`Invalid marketplace source path "${relativePath}" in ${baseDir}`);
17491
17918
  }
17492
17919
  return resolvedPath;
17493
17920
  }
17494
17921
  async readClaudePluginMetadata(pluginDir) {
17495
- const manifestContent = await readFileIfExists(join4(pluginDir, ".claude-plugin", "plugin.json"));
17922
+ const manifestContent = await readFileIfExists(join5(pluginDir, ".claude-plugin", "plugin.json"));
17496
17923
  if (!manifestContent) {
17497
17924
  return {};
17498
17925
  }
@@ -17508,11 +17935,11 @@ class PluginManager {
17508
17935
  }
17509
17936
  }
17510
17937
  async copyClaudeMarketplacePlugin(sourcePluginDir, marketplacePath, pluginName) {
17511
- const marketplacePluginPath = join4(marketplacePath, "plugins", pluginName);
17512
- await fs22.mkdir(dirname2(marketplacePluginPath), { recursive: true });
17513
- await fs22.rm(marketplacePluginPath, { recursive: true, force: true }).catch(() => {
17938
+ const marketplacePluginPath = join5(marketplacePath, "plugins", pluginName);
17939
+ await fs24.mkdir(dirname3(marketplacePluginPath), { recursive: true });
17940
+ await fs24.rm(marketplacePluginPath, { recursive: true, force: true }).catch(() => {
17514
17941
  });
17515
- await fs22.cp(sourcePluginDir, marketplacePluginPath, { recursive: true, dereference: true });
17942
+ await fs24.cp(sourcePluginDir, marketplacePluginPath, { recursive: true, dereference: true });
17516
17943
  return marketplacePluginPath;
17517
17944
  }
17518
17945
  getClaudeMarketplaceSource(plugin, marketplaceRoot, marketplacePath) {
@@ -17533,7 +17960,7 @@ class PluginManager {
17533
17960
  if (plugin.source.type === "local") {
17534
17961
  return {
17535
17962
  source: "directory",
17536
- path: resolve7(marketplaceRoot || plugin.source.path || marketplacePath)
17963
+ path: resolve8(marketplaceRoot || plugin.source.path || marketplacePath)
17537
17964
  };
17538
17965
  }
17539
17966
  return {
@@ -17544,7 +17971,7 @@ class PluginManager {
17544
17971
  async materializeClaudeMarketplace(plugin, pluginDir, target) {
17545
17972
  const marketplaceRoot = await this.findClaudeMarketplaceRoot(pluginDir);
17546
17973
  const marketplaceSource = this.getClaudeMarketplaceSource(plugin, marketplaceRoot, target.marketplacePath);
17547
- await fs22.mkdir(target.marketplacePath, { recursive: true });
17974
+ await fs24.mkdir(target.marketplacePath, { recursive: true });
17548
17975
  const existingManifest = await this.readClaudeMarketplaceManifest(target.marketplacePath);
17549
17976
  const sourceManifest = marketplaceRoot ? await this.readClaudeMarketplaceManifest(marketplaceRoot) : null;
17550
17977
  const mergedManifest = {
@@ -17616,10 +18043,10 @@ class PluginManager {
17616
18043
  warnings.push(`Skipped native Claude plugin install because Claude already has "${plugin.name}" installed as ${conflictingKey}.`);
17617
18044
  return { installed, skipped, warnings };
17618
18045
  }
17619
- await fs22.rm(nativeTarget.installPath, { recursive: true, force: true }).catch(() => {
18046
+ await fs24.rm(nativeTarget.installPath, { recursive: true, force: true }).catch(() => {
17620
18047
  });
17621
- await fs22.mkdir(dirname2(nativeTarget.installPath), { recursive: true });
17622
- await fs22.cp(pluginDir, nativeTarget.installPath, { recursive: true, dereference: true });
18048
+ await fs24.mkdir(dirname3(nativeTarget.installPath), { recursive: true });
18049
+ await fs24.cp(pluginDir, nativeTarget.installPath, { recursive: true, dereference: true });
17623
18050
  const marketplace = await this.materializeClaudeMarketplace(plugin, pluginDir, nativeTarget);
17624
18051
  const now = new Date().toISOString();
17625
18052
  claudeInstalled.plugins[nativeTarget.pluginKey] = [{
@@ -17659,7 +18086,7 @@ class PluginManager {
17659
18086
  };
17660
18087
  await this.saveClaudeKnownMarketplaces(knownMarketplaces);
17661
18088
  for (const entry of legacyEntries) {
17662
- await fs22.rm(entry.installPath, { recursive: true, force: true }).catch(() => {
18089
+ await fs24.rm(entry.installPath, { recursive: true, force: true }).catch(() => {
17663
18090
  });
17664
18091
  }
17665
18092
  for (const legacyKey of legacyKeys) {
@@ -17707,7 +18134,7 @@ class PluginManager {
17707
18134
  delete knownMarketplaces[marketplaceNamespace];
17708
18135
  await this.saveClaudeKnownMarketplaces(knownMarketplaces);
17709
18136
  }
17710
- await fs22.rm(getClaudeMarketplaceInstallPath(marketplaceNamespace), { recursive: true, force: true }).catch(() => {
18137
+ await fs24.rm(getClaudeMarketplaceInstallPath(marketplaceNamespace), { recursive: true, force: true }).catch(() => {
17711
18138
  });
17712
18139
  } else if (marketplaceNamespace) {
17713
18140
  const pluginName = component.pluginKey.split("@")[0] || "";
@@ -17715,14 +18142,14 @@ class PluginManager {
17715
18142
  const manifest = await this.readClaudeMarketplaceManifest(marketplacePath);
17716
18143
  if (pluginName && manifest) {
17717
18144
  manifest.plugins = (manifest.plugins || []).filter((entry) => entry.name !== pluginName);
17718
- const marketplacePluginPath = join4(marketplacePath, "plugins", pluginName);
17719
- await fs22.rm(marketplacePluginPath, { recursive: true, force: true }).catch(() => {
18145
+ const marketplacePluginPath = join5(marketplacePath, "plugins", pluginName);
18146
+ await fs24.rm(marketplacePluginPath, { recursive: true, force: true }).catch(() => {
17720
18147
  });
17721
18148
  await this.saveClaudeMarketplaceManifest(marketplacePath, manifest);
17722
18149
  }
17723
18150
  }
17724
18151
  await this.saveClaudeSettings(claudeSettings);
17725
- await fs22.rm(component.installPath, { recursive: true, force: true }).catch(() => {
18152
+ await fs24.rm(component.installPath, { recursive: true, force: true }).catch(() => {
17726
18153
  });
17727
18154
  return true;
17728
18155
  }
@@ -17795,7 +18222,7 @@ class PluginManager {
17795
18222
  throw new Error(`Unknown marketplace: ${registryId}. Available: ${this.getMarketplaceIds().join(", ")}`);
17796
18223
  }
17797
18224
  const cacheDir = getMarketplaceCacheDir(registryId);
17798
- const cacheMetaPath = join4(cacheDir, ".agentinit-cache-meta.json");
18225
+ const cacheMetaPath = join5(cacheDir, ".agentinit-cache-meta.json");
17799
18226
  const cacheMeta = await this.readMarketplaceCacheMeta(cacheMetaPath);
17800
18227
  if (cacheMeta?.repoUrl === registry.repoUrl) {
17801
18228
  const age = Date.now() - cacheMeta.fetchedAt;
@@ -17803,10 +18230,10 @@ class PluginManager {
17803
18230
  return cacheDir;
17804
18231
  }
17805
18232
  }
17806
- if (await fileExists(join4(cacheDir, ".git"))) {
18233
+ if (await fileExists(join5(cacheDir, ".git"))) {
17807
18234
  const originUrl = await this.getMarketplaceCacheOriginUrl(cacheDir);
17808
18235
  if (originUrl !== registry.repoUrl) {
17809
- await fs22.rm(cacheDir, { recursive: true, force: true });
18236
+ await fs24.rm(cacheDir, { recursive: true, force: true });
17810
18237
  await this.cloneMarketplace(registry.repoUrl, cacheDir);
17811
18238
  } else {
17812
18239
  const { execFile } = await import("child_process");
@@ -17815,15 +18242,15 @@ class PluginManager {
17815
18242
  try {
17816
18243
  await exec("git", ["pull", "--ff-only"], { cwd: cacheDir, timeout: 30000 });
17817
18244
  } catch {
17818
- await fs22.rm(cacheDir, { recursive: true, force: true });
18245
+ await fs24.rm(cacheDir, { recursive: true, force: true });
17819
18246
  await this.cloneMarketplace(registry.repoUrl, cacheDir);
17820
18247
  }
17821
18248
  }
17822
18249
  } else {
17823
18250
  await this.cloneMarketplace(registry.repoUrl, cacheDir);
17824
18251
  }
17825
- await fs22.mkdir(cacheDir, { recursive: true });
17826
- await fs22.writeFile(cacheMetaPath, JSON.stringify({
18252
+ await fs24.mkdir(cacheDir, { recursive: true });
18253
+ await fs24.writeFile(cacheMetaPath, JSON.stringify({
17827
18254
  fetchedAt: Date.now(),
17828
18255
  repoUrl: registry.repoUrl
17829
18256
  }));
@@ -17834,7 +18261,7 @@ class PluginManager {
17834
18261
  return null;
17835
18262
  }
17836
18263
  try {
17837
- const meta = JSON.parse(await fs22.readFile(cacheMetaPath, "utf8"));
18264
+ const meta = JSON.parse(await fs24.readFile(cacheMetaPath, "utf8"));
17838
18265
  if (typeof meta.fetchedAt !== "number") {
17839
18266
  return null;
17840
18267
  }
@@ -17862,11 +18289,11 @@ class PluginManager {
17862
18289
  }
17863
18290
  }
17864
18291
  async cloneMarketplace(repoUrl, dest) {
17865
- await fs22.mkdir(dest, { recursive: true });
18292
+ await fs24.mkdir(dest, { recursive: true });
17866
18293
  const { execFile } = await import("child_process");
17867
18294
  const { promisify } = await import("util");
17868
18295
  const exec = promisify(execFile);
17869
- await fs22.rm(dest, { recursive: true, force: true }).catch(() => {
18296
+ await fs24.rm(dest, { recursive: true, force: true }).catch(() => {
17870
18297
  });
17871
18298
  await exec("git", ["clone", "--depth", "1", repoUrl, dest], { timeout: 60000 });
17872
18299
  }
@@ -17876,7 +18303,7 @@ class PluginManager {
17876
18303
  throw new Error(`Unknown marketplace: ${registryId}`);
17877
18304
  const cacheDir = await this.ensureMarketplaceCache(registryId);
17878
18305
  for (const dir of registry.pluginDirs) {
17879
- const pluginPath = join4(cacheDir, dir, name);
18306
+ const pluginPath = join5(cacheDir, dir, name);
17880
18307
  if (await isDirectory(pluginPath)) {
17881
18308
  return pluginPath;
17882
18309
  }
@@ -17892,7 +18319,7 @@ class PluginManager {
17892
18319
  const cacheDir = await this.ensureMarketplaceCache(registryId);
17893
18320
  const results = [];
17894
18321
  for (const dir of registry.pluginDirs) {
17895
- const fullDir = join4(cacheDir, dir);
18322
+ const fullDir = join5(cacheDir, dir);
17896
18323
  if (!await isDirectory(fullDir))
17897
18324
  continue;
17898
18325
  const cat = getMarketplaceCategoryForDir(dir);
@@ -17902,26 +18329,26 @@ class PluginManager {
17902
18329
  for (const entry of entries) {
17903
18330
  if (entry.startsWith("."))
17904
18331
  continue;
17905
- const entryPath = join4(fullDir, entry);
18332
+ const entryPath = join5(fullDir, entry);
17906
18333
  if (!await isDirectory(entryPath))
17907
18334
  continue;
17908
- const manifestPath = join4(entryPath, ".claude-plugin", "plugin.json");
18335
+ const manifestPath = join5(entryPath, ".claude-plugin", "plugin.json");
17909
18336
  let name = entry;
17910
18337
  let description = "";
17911
18338
  let version = "0.0.0";
17912
18339
  if (await fileExists(manifestPath)) {
17913
18340
  try {
17914
- const manifest = JSON.parse(await fs22.readFile(manifestPath, "utf8"));
18341
+ const manifest = JSON.parse(await fs24.readFile(manifestPath, "utf8"));
17915
18342
  name = manifest.name || entry;
17916
18343
  description = manifest.description || "";
17917
18344
  version = manifest.version || "0.0.0";
17918
18345
  } catch {
17919
18346
  }
17920
18347
  } else {
17921
- const skillMdPath = join4(entryPath, "SKILL.md");
18348
+ const skillMdPath = join5(entryPath, "SKILL.md");
17922
18349
  if (await fileExists(skillMdPath)) {
17923
18350
  try {
17924
- const parsed = import_gray_matter.default(await fs22.readFile(skillMdPath, "utf8"));
18351
+ const parsed = import_gray_matter.default(await fs24.readFile(skillMdPath, "utf8"));
17925
18352
  if (parsed.data.name)
17926
18353
  name = parsed.data.name;
17927
18354
  if (parsed.data.description)
@@ -17929,10 +18356,10 @@ class PluginManager {
17929
18356
  } catch {
17930
18357
  }
17931
18358
  } else {
17932
- const mcpPath = join4(entryPath, ".mcp.json");
18359
+ const mcpPath = join5(entryPath, ".mcp.json");
17933
18360
  if (await fileExists(mcpPath)) {
17934
18361
  try {
17935
- const mcpConfig = JSON.parse(await fs22.readFile(mcpPath, "utf8"));
18362
+ const mcpConfig = JSON.parse(await fs24.readFile(mcpPath, "utf8"));
17936
18363
  const serverNames = Object.keys(mcpConfig.mcpServers || mcpConfig);
17937
18364
  if (serverNames.length > 0) {
17938
18365
  description = `MCP server(s): ${serverNames.join(", ")}`;
@@ -17954,10 +18381,10 @@ class PluginManager {
17954
18381
  return results.sort((a, b) => a.name.localeCompare(b.name));
17955
18382
  }
17956
18383
  async detectFormat(pluginDir) {
17957
- if (await fileExists(join4(pluginDir, ".claude-plugin", "plugin.json"))) {
18384
+ if (await fileExists(join5(pluginDir, ".claude-plugin", "plugin.json"))) {
17958
18385
  return "claude";
17959
18386
  }
17960
- if (await fileExists(join4(pluginDir, ".cursor-plugin", "plugin.json"))) {
18387
+ if (await fileExists(join5(pluginDir, ".cursor-plugin", "plugin.json"))) {
17961
18388
  return "cursor";
17962
18389
  }
17963
18390
  return "generic";
@@ -17974,7 +18401,7 @@ class PluginManager {
17974
18401
  }
17975
18402
  }
17976
18403
  async parseClaudePlugin(pluginDir, source) {
17977
- const manifestPath = join4(pluginDir, ".claude-plugin", "plugin.json");
18404
+ const manifestPath = join5(pluginDir, ".claude-plugin", "plugin.json");
17978
18405
  const manifestContent = await readFileIfExists(manifestPath);
17979
18406
  if (!manifestContent) {
17980
18407
  throw new Error(`Missing .claude-plugin/plugin.json in ${pluginDir}`);
@@ -17985,10 +18412,10 @@ class PluginManager {
17985
18412
  const convertedSkills = await this.convertCommandsToSkills(pluginDir, manifest);
17986
18413
  skills.push(...convertedSkills);
17987
18414
  const mcpServers = await this.parseMcpJson(pluginDir);
17988
- if (await isDirectory(join4(pluginDir, "hooks")) || manifest.hooks) {
18415
+ if (await isDirectory(join5(pluginDir, "hooks")) || manifest.hooks) {
17989
18416
  warnings.push("Hooks (hooks/) are Claude Code-specific");
17990
18417
  }
17991
- if (await isDirectory(join4(pluginDir, "agents")) || manifest.agents) {
18418
+ if (await isDirectory(join5(pluginDir, "agents")) || manifest.agents) {
17992
18419
  warnings.push("Agent definitions (agents/) are Claude Code-specific");
17993
18420
  }
17994
18421
  return {
@@ -18003,7 +18430,7 @@ class PluginManager {
18003
18430
  };
18004
18431
  }
18005
18432
  async parseCursorPlugin(pluginDir, source) {
18006
- const manifestPath = join4(pluginDir, ".cursor-plugin", "plugin.json");
18433
+ const manifestPath = join5(pluginDir, ".cursor-plugin", "plugin.json");
18007
18434
  const manifestContent = await readFileIfExists(manifestPath);
18008
18435
  if (!manifestContent) {
18009
18436
  throw new Error(`Missing .cursor-plugin/plugin.json in ${pluginDir}`);
@@ -18042,7 +18469,7 @@ class PluginManager {
18042
18469
  };
18043
18470
  }
18044
18471
  async parseMcpJson(pluginDir) {
18045
- const mcpPath = join4(pluginDir, ".mcp.json");
18472
+ const mcpPath = join5(pluginDir, ".mcp.json");
18046
18473
  const content = await readFileIfExists(mcpPath);
18047
18474
  if (!content)
18048
18475
  return [];
@@ -18086,10 +18513,10 @@ class PluginManager {
18086
18513
  if (manifest.commands) {
18087
18514
  const cmds = Array.isArray(manifest.commands) ? manifest.commands : [manifest.commands];
18088
18515
  for (const cmd of cmds) {
18089
- commandsDirs.push(resolve7(pluginDir, cmd));
18516
+ commandsDirs.push(resolve8(pluginDir, cmd));
18090
18517
  }
18091
18518
  } else {
18092
- commandsDirs.push(join4(pluginDir, "commands"));
18519
+ commandsDirs.push(join5(pluginDir, "commands"));
18093
18520
  }
18094
18521
  for (const commandsDir of commandsDirs) {
18095
18522
  if (!await isDirectory(commandsDir))
@@ -18098,7 +18525,7 @@ class PluginManager {
18098
18525
  for (const entry of entries) {
18099
18526
  if (!entry.endsWith(".md"))
18100
18527
  continue;
18101
- const cmdPath = join4(commandsDir, entry);
18528
+ const cmdPath = join5(commandsDir, entry);
18102
18529
  const skill = await this.convertSingleCommandToSkill(cmdPath, manifest.name);
18103
18530
  if (skill)
18104
18531
  skills.push(skill);
@@ -18412,7 +18839,7 @@ ${body.trim()}
18412
18839
  }
18413
18840
  if (!removedSkillPaths.has(skill.path)) {
18414
18841
  try {
18415
- await fs22.rm(skill.path, { recursive: true, force: true });
18842
+ await fs24.rm(skill.path, { recursive: true, force: true });
18416
18843
  removedSkillPaths.add(skill.path);
18417
18844
  } catch {
18418
18845
  details.push(`Could not remove skill path: ${skill.path}`);
@@ -18421,7 +18848,7 @@ ${body.trim()}
18421
18848
  }
18422
18849
  if (skill.canonicalPath && skill.canonicalPath !== skill.path && !removedCanonicalPaths.has(skill.canonicalPath) && !sharedCanonicalPath) {
18423
18850
  try {
18424
- await fs22.rm(skill.canonicalPath, { recursive: true, force: true });
18851
+ await fs24.rm(skill.canonicalPath, { recursive: true, force: true });
18425
18852
  removedCanonicalPaths.add(skill.canonicalPath);
18426
18853
  } catch {
18427
18854
  details.push(`Could not remove canonical skill path: ${skill.canonicalPath}`);
@@ -18527,34 +18954,34 @@ var init_pluginManager = __esm(() => {
18527
18954
  init_skillsManager();
18528
18955
  init_userConfig();
18529
18956
  getMarketplaceCacheDir = function(registryId) {
18530
- return join4(homedir4(), ".agentinit", "marketplace-cache", registryId);
18957
+ return join5(homedir5(), ".agentinit", "marketplace-cache", registryId);
18531
18958
  };
18532
18959
  getRegistryPath = function(projectPath, global3) {
18533
18960
  if (global3) {
18534
- return join4(homedir4(), ".agentinit", "plugins.json");
18961
+ return join5(homedir5(), ".agentinit", "plugins.json");
18535
18962
  }
18536
- return join4(projectPath, ".agentinit", "plugins.json");
18963
+ return join5(projectPath, ".agentinit", "plugins.json");
18537
18964
  };
18538
18965
  getClaudeInstalledPluginsPath = function() {
18539
- return join4(homedir4(), ".claude", "plugins", "installed_plugins.json");
18966
+ return join5(homedir5(), ".claude", "plugins", "installed_plugins.json");
18540
18967
  };
18541
18968
  getClaudeKnownMarketplacesPath = function() {
18542
- return join4(homedir4(), ".claude", "plugins", "known_marketplaces.json");
18969
+ return join5(homedir5(), ".claude", "plugins", "known_marketplaces.json");
18543
18970
  };
18544
18971
  getClaudeMarketplaceInstallPath = function(namespace) {
18545
- return join4(homedir4(), ".claude", "plugins", "marketplaces", namespace);
18972
+ return join5(homedir5(), ".claude", "plugins", "marketplaces", namespace);
18546
18973
  };
18547
18974
  getClaudeSettingsPath = function() {
18548
- return join4(homedir4(), ".claude", "settings.json");
18975
+ return join5(homedir5(), ".claude", "settings.json");
18549
18976
  };
18550
18977
  });
18551
18978
 
18552
18979
  // dist/core/skillsManager.js
18553
- import {resolve as resolve8, join as join5, relative as relative3, basename as basename3, dirname as dirname3} from "path";
18554
- import {promises as fs24} from "fs";
18555
- import {homedir as homedir5, tmpdir} from "os";
18980
+ import {resolve as resolve9, join as join6, relative as relative3, basename as basename3, dirname as dirname4} from "path";
18981
+ import {promises as fs26} from "fs";
18982
+ import {homedir as homedir6, tmpdir} from "os";
18556
18983
  import {execFile} from "child_process";
18557
- import {createHash} from "crypto";
18984
+ import {createHash as createHash2} from "crypto";
18558
18985
  import {promisify} from "util";
18559
18986
 
18560
18987
  class SkillsManager {
@@ -18705,34 +19132,34 @@ class SkillsManager {
18705
19132
  const skills2 = [];
18706
19133
  const seen = new Set;
18707
19134
  for (const searchDir of SKILL_SEARCH_DIRS) {
18708
- const fullDir = resolve8(repoPath, searchDir);
19135
+ const fullDir = resolve9(repoPath, searchDir);
18709
19136
  if (!await fileExists(fullDir))
18710
19137
  continue;
18711
- const directSkillMd = join5(fullDir, "SKILL.md");
19138
+ const directSkillMd = join6(fullDir, "SKILL.md");
18712
19139
  if (await fileExists(directSkillMd)) {
18713
19140
  const parsed = await this.parseSkillMd(directSkillMd);
18714
19141
  if (parsed && !seen.has(parsed.name)) {
18715
19142
  seen.add(parsed.name);
18716
- skills2.push({ ...parsed, path: resolve8(fullDir) });
19143
+ skills2.push({ ...parsed, path: resolve9(fullDir) });
18717
19144
  }
18718
19145
  }
18719
- const directSkillMdLower = join5(fullDir, "skill.md");
19146
+ const directSkillMdLower = join6(fullDir, "skill.md");
18720
19147
  if (await fileExists(directSkillMdLower)) {
18721
19148
  const parsed = await this.parseSkillMd(directSkillMdLower);
18722
19149
  if (parsed && !seen.has(parsed.name)) {
18723
19150
  seen.add(parsed.name);
18724
- skills2.push({ ...parsed, path: resolve8(fullDir) });
19151
+ skills2.push({ ...parsed, path: resolve9(fullDir) });
18725
19152
  }
18726
19153
  }
18727
19154
  if (!await isDirectory(fullDir))
18728
19155
  continue;
18729
19156
  const entries = await listFiles(fullDir);
18730
19157
  for (const entry of entries) {
18731
- const entryPath = join5(fullDir, entry);
19158
+ const entryPath = join6(fullDir, entry);
18732
19159
  if (!await isDirectory(entryPath))
18733
19160
  continue;
18734
- const skillMdPath = join5(entryPath, "SKILL.md");
18735
- const skillMdPathLower = join5(entryPath, "skill.md");
19161
+ const skillMdPath = join6(entryPath, "SKILL.md");
19162
+ const skillMdPathLower = join6(entryPath, "skill.md");
18736
19163
  const skillFile = await fileExists(skillMdPath) ? skillMdPath : await fileExists(skillMdPathLower) ? skillMdPathLower : null;
18737
19164
  if (!skillFile)
18738
19165
  continue;
@@ -18746,14 +19173,14 @@ class SkillsManager {
18746
19173
  return skills2;
18747
19174
  }
18748
19175
  async cloneRepo(url) {
18749
- const tempDir = await fs24.mkdtemp(join5(tmpdir(), "agentinit-skills-"));
18750
- await fs24.rm(tempDir, { recursive: true, force: true });
19176
+ const tempDir = await fs26.mkdtemp(join6(tmpdir(), "agentinit-skills-"));
19177
+ await fs26.rm(tempDir, { recursive: true, force: true });
18751
19178
  try {
18752
19179
  await execFileAsync("git", ["clone", "--depth", "1", url, tempDir], {
18753
19180
  timeout: 60000
18754
19181
  });
18755
19182
  } catch (error) {
18756
- await fs24.rm(tempDir, { recursive: true, force: true }).catch(() => {
19183
+ await fs26.rm(tempDir, { recursive: true, force: true }).catch(() => {
18757
19184
  });
18758
19185
  throw new Error(`Failed to clone ${url}: ${error.message}`);
18759
19186
  }
@@ -18811,15 +19238,15 @@ class SkillsManager {
18811
19238
  if (!tempDir) {
18812
19239
  return;
18813
19240
  }
18814
- await fs24.rm(tempDir, { recursive: true, force: true }).catch(() => {
19241
+ await fs26.rm(tempDir, { recursive: true, force: true }).catch(() => {
18815
19242
  });
18816
19243
  }
18817
19244
  async resolveDiscoveryRoot(repoPath, source, sourceLabel) {
18818
- const resolvedRepoPath = resolve8(repoPath);
19245
+ const resolvedRepoPath = resolve9(repoPath);
18819
19246
  if (source.type !== "github" || !source.subpath) {
18820
19247
  return resolvedRepoPath;
18821
19248
  }
18822
- const discoveryRoot = resolve8(resolvedRepoPath, source.subpath);
19249
+ const discoveryRoot = resolve9(resolvedRepoPath, source.subpath);
18823
19250
  if (!this.isWithinPath(resolvedRepoPath, discoveryRoot)) {
18824
19251
  throw new Error(`Invalid GitHub source path "${source.subpath}" in ${sourceLabel}`);
18825
19252
  }
@@ -18837,7 +19264,7 @@ class SkillsManager {
18837
19264
  return realDiscoveryRoot;
18838
19265
  }
18839
19266
  if (basename3(realDiscoveryRoot).toLowerCase() === "skill.md") {
18840
- return dirname3(realDiscoveryRoot);
19267
+ return dirname4(realDiscoveryRoot);
18841
19268
  }
18842
19269
  throw new Error(`GitHub source must reference a skill directory or SKILL.md: ${sourceLabel}`);
18843
19270
  }
@@ -18868,7 +19295,7 @@ class SkillsManager {
18868
19295
  tempDir = await this.cloneRepo(resolved.url);
18869
19296
  repoPath = tempDir;
18870
19297
  } else {
18871
- repoPath = resolve8(resolved.path || source);
19298
+ repoPath = resolve9(resolved.path || source);
18872
19299
  if (!await fileExists(repoPath)) {
18873
19300
  throw this.getMissingLocalPathError(source, repoPath);
18874
19301
  }
@@ -18955,30 +19382,30 @@ class SkillsManager {
18955
19382
  async installSkill(skillPath, skillName, targetDir, copy = false) {
18956
19383
  const normalizedSkillName = this.normalizeSkillName(skillName);
18957
19384
  const destPath = this.resolveInstallPath(targetDir, normalizedSkillName);
18958
- await fs24.mkdir(resolve8(targetDir), { recursive: true });
19385
+ await fs26.mkdir(resolve9(targetDir), { recursive: true });
18959
19386
  if (await fileExists(destPath)) {
18960
- await fs24.rm(destPath, { recursive: true, force: true });
19387
+ await fs26.rm(destPath, { recursive: true, force: true });
18961
19388
  }
18962
19389
  if (copy) {
18963
19390
  await this.copyDir(skillPath, destPath);
18964
19391
  } else {
18965
- await fs24.symlink(skillPath, destPath, "dir");
19392
+ await fs26.symlink(skillPath, destPath, "dir");
18966
19393
  }
18967
19394
  return destPath;
18968
19395
  }
18969
19396
  async installSkillFromContent(skillName, skillContent, targetDir) {
18970
19397
  const normalizedSkillName = this.normalizeSkillName(skillName);
18971
19398
  const destPath = this.resolveInstallPath(targetDir, normalizedSkillName);
18972
- await fs24.mkdir(resolve8(targetDir), { recursive: true });
19399
+ await fs26.mkdir(resolve9(targetDir), { recursive: true });
18973
19400
  if (await fileExists(destPath)) {
18974
- await fs24.rm(destPath, { recursive: true, force: true });
19401
+ await fs26.rm(destPath, { recursive: true, force: true });
18975
19402
  }
18976
- await fs24.mkdir(destPath, { recursive: true });
18977
- await fs24.writeFile(join5(destPath, "SKILL.md"), skillContent, "utf8");
19403
+ await fs26.mkdir(destPath, { recursive: true });
19404
+ await fs26.writeFile(join6(destPath, "SKILL.md"), skillContent, "utf8");
18978
19405
  return destPath;
18979
19406
  }
18980
19407
  getCanonicalSkillsDir(projectPath, global3 = false) {
18981
- return global3 ? resolve8(homedir5(), ".agents/skills") : resolve8(projectPath, ".agents/skills");
19408
+ return global3 ? resolve9(homedir6(), ".agents/skills") : resolve9(projectPath, ".agents/skills");
18982
19409
  }
18983
19410
  async getInstallPlan(skillName, agent, projectPath, options2 = {}) {
18984
19411
  const normalizedSkillName = this.normalizeSkillName(skillName);
@@ -19021,7 +19448,7 @@ class SkillsManager {
19021
19448
  ...options2.global !== undefined ? { global: options2.global } : {},
19022
19449
  ...options2.copy !== undefined ? { copy: options2.copy } : {}
19023
19450
  });
19024
- return this.compareSkillSnapshot(skill, plan.canonicalPath || plan.path);
19451
+ return this.compareSkillInstallStatus(skill, plan);
19025
19452
  }
19026
19453
  async installSkillForAgent(skillPath, skillName, agent, projectPath, options2 = {}) {
19027
19454
  const plan = await this.getInstallPlan(skillName, agent, projectPath, options2);
@@ -19068,7 +19495,7 @@ class SkillsManager {
19068
19495
  throw new Error(`Missing canonical path for ${skillName}`);
19069
19496
  }
19070
19497
  await this.cleanAndCreateDirectory(canonicalPath);
19071
- await fs24.writeFile(join5(canonicalPath, "SKILL.md"), skillContent, "utf8");
19498
+ await fs26.writeFile(join6(canonicalPath, "SKILL.md"), skillContent, "utf8");
19072
19499
  if (plan.path === canonicalPath) {
19073
19500
  return plan;
19074
19501
  }
@@ -19091,7 +19518,7 @@ class SkillsManager {
19091
19518
  async installSkillFromContentToCanonicalStore(skillName, skillContent, projectPath, options2 = {}) {
19092
19519
  const plan = this.getCanonicalInstallPlan(skillName, projectPath, options2);
19093
19520
  await this.cleanAndCreateDirectory(plan.path);
19094
- await fs24.writeFile(join5(plan.path, "SKILL.md"), skillContent, "utf8");
19521
+ await fs26.writeFile(join6(plan.path, "SKILL.md"), skillContent, "utf8");
19095
19522
  return plan;
19096
19523
  }
19097
19524
  getCanonicalInstallPlan(skillName, projectPath, options2 = {}) {
@@ -19114,8 +19541,8 @@ class SkillsManager {
19114
19541
  return normalized;
19115
19542
  }
19116
19543
  resolveInstallPath(targetDir, skillName) {
19117
- const resolvedTargetDir = resolve8(targetDir);
19118
- const destPath = resolve8(resolvedTargetDir, skillName);
19544
+ const resolvedTargetDir = resolve9(targetDir);
19545
+ const destPath = resolve9(resolvedTargetDir, skillName);
19119
19546
  const relativePath = relative3(resolvedTargetDir, destPath);
19120
19547
  if (relativePath === "" || relativePath.startsWith("..") || relativePath.includes("/../") || relativePath.includes("\\..\\")) {
19121
19548
  throw new Error(`Refusing to install skill outside target directory: ${skillName}`);
@@ -19133,18 +19560,18 @@ class SkillsManager {
19133
19560
  async createDirectorySnapshot(rootPath) {
19134
19561
  if (!await fileExists(rootPath))
19135
19562
  return null;
19136
- const hash = createHash("sha256");
19563
+ const hash = createHash2("sha256");
19137
19564
  const walk = async (currentPath, relativePath) => {
19138
- const stat = await fs24.stat(currentPath);
19565
+ const stat = await fs26.stat(currentPath);
19139
19566
  if (!stat.isDirectory()) {
19140
- const content = await fs24.readFile(currentPath);
19567
+ const content = await fs26.readFile(currentPath);
19141
19568
  this.updateSnapshotWithFile(hash, relativePath, content);
19142
19569
  return;
19143
19570
  }
19144
19571
  hash.update(`dir:${relativePath || "."}\n`);
19145
- const entries = (await fs24.readdir(currentPath)).sort((left, right) => left.localeCompare(right));
19572
+ const entries = (await fs26.readdir(currentPath)).sort((left, right) => left.localeCompare(right));
19146
19573
  for (const entry of entries) {
19147
- await walk(join5(currentPath, entry), relativePath ? join5(relativePath, entry) : entry);
19574
+ await walk(join6(currentPath, entry), relativePath ? join6(relativePath, entry) : entry);
19148
19575
  }
19149
19576
  };
19150
19577
  await walk(rootPath, "");
@@ -19155,7 +19582,7 @@ class SkillsManager {
19155
19582
  }
19156
19583
  async getNewSkillSnapshot(skill) {
19157
19584
  if (skill.generatedContent) {
19158
- const hash = createHash("sha256");
19585
+ const hash = createHash2("sha256");
19159
19586
  hash.update("dir:.\n");
19160
19587
  this.updateSnapshotWithFile(hash, "SKILL.md", skill.generatedContent.trim());
19161
19588
  return hash.digest("hex");
@@ -19171,17 +19598,34 @@ class SkillsManager {
19171
19598
  return "new";
19172
19599
  return existing === incoming ? "unchanged" : "changed";
19173
19600
  }
19601
+ async compareSkillInstallStatus(skill, plan) {
19602
+ const incoming = await this.getNewSkillSnapshot(skill);
19603
+ if (incoming === null)
19604
+ return "new";
19605
+ const existingAtTarget = await this.readExistingSkillSnapshot(plan.path);
19606
+ if (existingAtTarget !== null) {
19607
+ return existingAtTarget === incoming ? "unchanged" : "changed";
19608
+ }
19609
+ if (!plan.canonicalPath || plan.canonicalPath === plan.path) {
19610
+ return "new";
19611
+ }
19612
+ const existingAtCanonical = await this.readExistingSkillSnapshot(plan.canonicalPath);
19613
+ if (existingAtCanonical === null) {
19614
+ return "new";
19615
+ }
19616
+ return existingAtCanonical === incoming ? "new" : "changed";
19617
+ }
19174
19618
  async cleanAndCreateDirectory(path) {
19175
- await fs24.rm(path, { recursive: true, force: true }).catch(() => {
19619
+ await fs26.rm(path, { recursive: true, force: true }).catch(() => {
19176
19620
  });
19177
- await fs24.mkdir(path, { recursive: true });
19621
+ await fs26.mkdir(path, { recursive: true });
19178
19622
  }
19179
19623
  isWithinPath(basePath, targetPath) {
19180
- const relativePath = relative3(resolve8(basePath), resolve8(targetPath));
19624
+ const relativePath = relative3(resolve9(basePath), resolve9(targetPath));
19181
19625
  return relativePath === "" || !relativePath.startsWith("..") && !relativePath.includes("/../") && !relativePath.includes("\\..\\");
19182
19626
  }
19183
19627
  async copyDir(src, dest) {
19184
- await fs24.cp(src, dest, { recursive: true, dereference: true });
19628
+ await fs26.cp(src, dest, { recursive: true, dereference: true });
19185
19629
  }
19186
19630
  async addFromSource(source, projectPath, options2 = {}) {
19187
19631
  const context = this.takePreparedSourceContext(source, projectPath, options2.from) || await this.loadDiscoveredSkillsContext(source, projectPath, {
@@ -19260,10 +19704,10 @@ class SkillsManager {
19260
19704
  ...options2.copy !== undefined ? { copy: options2.copy } : {}
19261
19705
  };
19262
19706
  const plan = await this.getInstallPlan(skill.name, agent, projectPath, installOptions);
19263
- const comparisonPath = plan.canonicalPath || plan.path;
19707
+ const comparisonPath = plan.path;
19264
19708
  let comparison = comparisonCache.get(comparisonPath);
19265
19709
  if (comparison === undefined) {
19266
- comparison = await this.compareSkillSnapshot(skill, comparisonPath);
19710
+ comparison = await this.compareSkillInstallStatus(skill, plan);
19267
19711
  comparisonCache.set(comparisonPath, comparison);
19268
19712
  }
19269
19713
  if (comparison === "unchanged") {
@@ -19310,6 +19754,43 @@ class SkillsManager {
19310
19754
  }
19311
19755
  }
19312
19756
  }
19757
+ try {
19758
+ const lock = new InstallLock;
19759
+ const fromOption = options2.from;
19760
+ const { source: resolvedSource } = this.resolveSourceRequest(source, ...fromOption ? [{ from: fromOption }] : []);
19761
+ const lockSource = {
19762
+ type: resolvedSource.type,
19763
+ ...resolvedSource.marketplace ? { marketplace: resolvedSource.marketplace } : {},
19764
+ ...resolvedSource.pluginName ? { pluginName: resolvedSource.pluginName } : {},
19765
+ ...resolvedSource.url ? { url: resolvedSource.url } : {},
19766
+ ...resolvedSource.path ? { path: resolve9(projectPath, expandTilde(resolvedSource.path)) } : {},
19767
+ ...resolvedSource.owner ? { owner: resolvedSource.owner } : {},
19768
+ ...resolvedSource.repo ? { repo: resolvedSource.repo } : {},
19769
+ ...resolvedSource.subpath ? { subpath: resolvedSource.subpath } : {}
19770
+ };
19771
+ const recordEntries = async (entries, action) => {
19772
+ for (const entry of entries) {
19773
+ const hashPath = entry.canonicalPath || entry.path;
19774
+ const contentHash = await hashDirectory(hashPath);
19775
+ await lock.recordSkill({
19776
+ action,
19777
+ name: entry.skill.name,
19778
+ projectPath: resolve9(projectPath),
19779
+ agents: [entry.agent],
19780
+ scope: options2.global ? "global" : "project",
19781
+ source: lockSource,
19782
+ installPath: entry.path,
19783
+ mode: entry.mode,
19784
+ ...entry.canonicalPath ? { canonicalPath: entry.canonicalPath } : {},
19785
+ ...contentHash ? { contentHash } : {}
19786
+ });
19787
+ }
19788
+ };
19789
+ await recordEntries(result.installed, "install");
19790
+ await recordEntries(result.updated, "update");
19791
+ } catch (error) {
19792
+ logLockWriteWarning("Skills changed successfully", error);
19793
+ }
19313
19794
  return result;
19314
19795
  } finally {
19315
19796
  await context.cleanup();
@@ -19334,11 +19815,11 @@ class SkillsManager {
19334
19815
  continue;
19335
19816
  const entries = await listFiles(dir);
19336
19817
  for (const entry of entries) {
19337
- const entryPath = join5(dir, entry);
19818
+ const entryPath = join6(dir, entry);
19338
19819
  if (!await isDirectory(entryPath))
19339
19820
  continue;
19340
- const skillMdPath = join5(entryPath, "SKILL.md");
19341
- const skillMdPathLower = join5(entryPath, "skill.md");
19821
+ const skillMdPath = join6(entryPath, "SKILL.md");
19822
+ const skillMdPathLower = join6(entryPath, "skill.md");
19342
19823
  const skillFile = await fileExists(skillMdPath) ? skillMdPath : await fileExists(skillMdPathLower) ? skillMdPathLower : null;
19343
19824
  if (!skillFile)
19344
19825
  continue;
@@ -19348,7 +19829,7 @@ class SkillsManager {
19348
19829
  let isSymlink = false;
19349
19830
  let canonicalPath;
19350
19831
  try {
19351
- const stat = await fs24.lstat(entryPath);
19832
+ const stat = await fs26.lstat(entryPath);
19352
19833
  isSymlink = stat.isSymbolicLink();
19353
19834
  const canonicalBase = this.getCanonicalSkillsDir(projectPath, scope === "global");
19354
19835
  const [resolvedEntryPath, resolvedCanonicalBase] = await Promise.all([
@@ -19358,7 +19839,7 @@ class SkillsManager {
19358
19839
  if (this.isWithinPath(resolvedCanonicalBase, resolvedEntryPath)) {
19359
19840
  canonicalPath = resolvedEntryPath;
19360
19841
  } else if (this.isWithinPath(canonicalBase, entryPath)) {
19361
- canonicalPath = resolve8(entryPath);
19842
+ canonicalPath = resolve9(entryPath);
19362
19843
  }
19363
19844
  } catch {
19364
19845
  }
@@ -19378,21 +19859,21 @@ class SkillsManager {
19378
19859
  const includeSharedTarget = !options2.agents || options2.agents.includes(SHARED_SKILLS_TARGET_ID);
19379
19860
  if (includeSharedTarget) {
19380
19861
  const scopes = options2.global ? ["global"] : ["project", "global"];
19381
- const referencedCanonicalPaths = new Set(installed.map((entry) => entry.canonicalPath).filter((value) => !!value).map((value) => resolve8(value)));
19862
+ const referencedCanonicalPaths = new Set(installed.map((entry) => entry.canonicalPath).filter((value) => !!value).map((value) => resolve9(value)));
19382
19863
  for (const scope of scopes) {
19383
19864
  const canonicalDir = this.getCanonicalSkillsDir(projectPath, scope === "global");
19384
19865
  if (!await fileExists(canonicalDir))
19385
19866
  continue;
19386
19867
  const entries = await listFiles(canonicalDir);
19387
19868
  for (const entry of entries) {
19388
- const entryPath = join5(canonicalDir, entry);
19869
+ const entryPath = join6(canonicalDir, entry);
19389
19870
  if (!await isDirectory(entryPath))
19390
19871
  continue;
19391
- const resolvedEntryPath = resolve8(entryPath);
19872
+ const resolvedEntryPath = resolve9(entryPath);
19392
19873
  if (referencedCanonicalPaths.has(resolvedEntryPath))
19393
19874
  continue;
19394
- const skillMdPath = join5(entryPath, "SKILL.md");
19395
- const skillMdPathLower = join5(entryPath, "skill.md");
19875
+ const skillMdPath = join6(entryPath, "SKILL.md");
19876
+ const skillMdPathLower = join6(entryPath, "skill.md");
19396
19877
  const skillFile = await fileExists(skillMdPath) ? skillMdPath : await fileExists(skillMdPathLower) ? skillMdPathLower : null;
19397
19878
  if (!skillFile)
19398
19879
  continue;
@@ -19459,7 +19940,7 @@ class SkillsManager {
19459
19940
  }
19460
19941
  if (!removedPaths.has(entry.path)) {
19461
19942
  try {
19462
- await fs24.rm(entry.path, { recursive: true, force: true });
19943
+ await fs26.rm(entry.path, { recursive: true, force: true });
19463
19944
  removedPaths.add(entry.path);
19464
19945
  } catch {
19465
19946
  skipped.push({
@@ -19472,7 +19953,7 @@ class SkillsManager {
19472
19953
  if (entry.canonicalPath && entry.canonicalPath !== entry.path && !removedCanonicalPaths.has(entry.canonicalPath)) {
19473
19954
  const stillReferenced = remainingEntries.some((other) => other.name.toLowerCase() === entry.name.toLowerCase() && other.canonicalPath === entry.canonicalPath);
19474
19955
  if (!stillReferenced) {
19475
- await fs24.rm(entry.canonicalPath, { recursive: true, force: true }).catch(() => {
19956
+ await fs26.rm(entry.canonicalPath, { recursive: true, force: true }).catch(() => {
19476
19957
  });
19477
19958
  removedCanonicalPaths.add(entry.canonicalPath);
19478
19959
  }
@@ -19485,6 +19966,29 @@ class SkillsManager {
19485
19966
  notFound.push(name);
19486
19967
  }
19487
19968
  }
19969
+ try {
19970
+ if (targetedEntries.length > 0) {
19971
+ const lock = new InstallLock;
19972
+ for (const entry of targetedEntries) {
19973
+ const entryKey = `${entry.agent}:${entry.name}`;
19974
+ if (!removed.includes(entryKey))
19975
+ continue;
19976
+ await lock.recordSkill({
19977
+ action: "remove",
19978
+ name: entry.name,
19979
+ projectPath: resolve9(projectPath),
19980
+ agents: [entry.agent],
19981
+ scope: entry.scope,
19982
+ source: { type: "local", path: entry.path },
19983
+ installPath: entry.path,
19984
+ mode: entry.mode,
19985
+ ...entry.canonicalPath ? { canonicalPath: entry.canonicalPath } : {}
19986
+ });
19987
+ }
19988
+ }
19989
+ } catch (error) {
19990
+ logLockWriteWarning("Skills removed successfully", error);
19991
+ }
19488
19992
  return { removed, notFound, skipped };
19489
19993
  }
19490
19994
  }
@@ -19492,9 +19996,11 @@ var import_gray_matter2, execFileAsync, DEFAULT_SKILLS_CATALOG, SKILL_SEARCH_DIR
19492
19996
  var init_skillsManager = __esm(() => {
19493
19997
  import_gray_matter2 = __toESM(require_gray_matter(), 1);
19494
19998
  init_fs();
19999
+ init_paths();
19495
20000
  init_agentManager();
19496
20001
  init_marketplaceRegistry();
19497
20002
  init_skills();
20003
+ init_installLock();
19498
20004
  execFileAsync = promisify(execFile);
19499
20005
  DEFAULT_SKILLS_CATALOG = {
19500
20006
  owner: "vercel-labs",
@@ -20433,7 +20939,7 @@ var require_uri_all = __commonJS((exports, module) => {
20433
20939
  target.fragment = relative6.fragment;
20434
20940
  return target;
20435
20941
  }
20436
- function resolve12(baseURI, relativeURI, options2) {
20942
+ function resolve13(baseURI, relativeURI, options2) {
20437
20943
  var schemelessOptions = assign({ scheme: "null" }, options2);
20438
20944
  return serialize(resolveComponents(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true), schemelessOptions);
20439
20945
  }
@@ -20701,7 +21207,7 @@ var require_uri_all = __commonJS((exports, module) => {
20701
21207
  exports2.removeDotSegments = removeDotSegments;
20702
21208
  exports2.serialize = serialize;
20703
21209
  exports2.resolveComponents = resolveComponents;
20704
- exports2.resolve = resolve12;
21210
+ exports2.resolve = resolve13;
20705
21211
  exports2.normalize = normalize;
20706
21212
  exports2.equal = equal;
20707
21213
  exports2.escapeComponent = escapeComponent;
@@ -20887,7 +21393,7 @@ var require_util3 = __commonJS((exports, module) => {
20887
21393
  var path = jsonPointers ? toQuotedString("/" + escapeJsonPointer(prop)) : toQuotedString(getProperty(prop));
20888
21394
  return joinPaths(currentPath, path);
20889
21395
  };
20890
- var getData = function($data, lvl, paths5) {
21396
+ var getData = function($data, lvl, paths6) {
20891
21397
  var up, jsonPointer, data, matches;
20892
21398
  if ($data === "")
20893
21399
  return "rootData";
@@ -20905,7 +21411,7 @@ var require_util3 = __commonJS((exports, module) => {
20905
21411
  if (jsonPointer == "#") {
20906
21412
  if (up >= lvl)
20907
21413
  throw new Error("Cannot access property/index " + up + " levels up, current level is " + lvl);
20908
- return paths5[lvl - up];
21414
+ return paths6[lvl - up];
20909
21415
  }
20910
21416
  if (up > lvl)
20911
21417
  throw new Error("Cannot access data " + up + " levels up, current level is " + lvl);
@@ -21064,13 +21570,13 @@ var require_json_schema_traverse = __commonJS((exports, module) => {
21064
21570
 
21065
21571
  // node_modules/ajv/lib/compile/resolve.js
21066
21572
  var require_resolve = __commonJS((exports, module) => {
21067
- var resolve12 = function(compile, root, ref) {
21573
+ var resolve13 = function(compile, root, ref) {
21068
21574
  var refVal = this._refs[ref];
21069
21575
  if (typeof refVal == "string") {
21070
21576
  if (this._refs[refVal])
21071
21577
  refVal = this._refs[refVal];
21072
21578
  else
21073
- return resolve12.call(this, compile, root, refVal);
21579
+ return resolve13.call(this, compile, root, refVal);
21074
21580
  }
21075
21581
  refVal = refVal || this._schemas[ref];
21076
21582
  if (refVal instanceof SchemaObject) {
@@ -21275,13 +21781,13 @@ var require_resolve = __commonJS((exports, module) => {
21275
21781
  var util6 = require_util3();
21276
21782
  var SchemaObject = require_schema_obj();
21277
21783
  var traverse = require_json_schema_traverse();
21278
- module.exports = resolve12;
21279
- resolve12.normalizeId = normalizeId;
21280
- resolve12.fullPath = getFullPath;
21281
- resolve12.url = resolveUrl;
21282
- resolve12.ids = resolveIds;
21283
- resolve12.inlineRef = inlineRef;
21284
- resolve12.schema = resolveSchema;
21784
+ module.exports = resolve13;
21785
+ resolve13.normalizeId = normalizeId;
21786
+ resolve13.fullPath = getFullPath;
21787
+ resolve13.url = resolveUrl;
21788
+ resolve13.ids = resolveIds;
21789
+ resolve13.inlineRef = inlineRef;
21790
+ resolve13.schema = resolveSchema;
21285
21791
  var PREVENT_SCOPE_CHANGE = util6.toHash(["properties", "patternProperties", "enum", "dependencies", "definitions"]);
21286
21792
  var SIMPLE_INLINED = util6.toHash([
21287
21793
  "type",
@@ -21312,15 +21818,15 @@ var require_error_classes = __commonJS((exports, module) => {
21312
21818
  };
21313
21819
  var MissingRefError = function(baseId, ref, message) {
21314
21820
  this.message = message || MissingRefError.message(baseId, ref);
21315
- this.missingRef = resolve12.url(baseId, ref);
21316
- this.missingSchema = resolve12.normalizeId(resolve12.fullPath(this.missingRef));
21821
+ this.missingRef = resolve13.url(baseId, ref);
21822
+ this.missingSchema = resolve13.normalizeId(resolve13.fullPath(this.missingRef));
21317
21823
  };
21318
21824
  var errorSubclass = function(Subclass) {
21319
21825
  Subclass.prototype = Object.create(Error.prototype);
21320
21826
  Subclass.prototype.constructor = Subclass;
21321
21827
  return Subclass;
21322
21828
  };
21323
- var resolve12 = require_resolve();
21829
+ var resolve13 = require_resolve();
21324
21830
  module.exports = {
21325
21831
  Validation: errorSubclass(ValidationError),
21326
21832
  MissingRef: errorSubclass(MissingRefError)
@@ -21914,7 +22420,7 @@ var require_compile = __commonJS((exports, module) => {
21914
22420
  RULES,
21915
22421
  validate: validateGenerator,
21916
22422
  util: util6,
21917
- resolve: resolve12,
22423
+ resolve: resolve13,
21918
22424
  resolveRef,
21919
22425
  usePattern,
21920
22426
  useDefault,
@@ -21953,7 +22459,7 @@ var require_compile = __commonJS((exports, module) => {
21953
22459
  return validate2;
21954
22460
  }
21955
22461
  function resolveRef(baseId2, ref, isRoot) {
21956
- ref = resolve12.url(baseId2, ref);
22462
+ ref = resolve13.url(baseId2, ref);
21957
22463
  var refIndex = refs[ref];
21958
22464
  var _refVal, refCode;
21959
22465
  if (refIndex !== undefined) {
@@ -21970,11 +22476,11 @@ var require_compile = __commonJS((exports, module) => {
21970
22476
  }
21971
22477
  }
21972
22478
  refCode = addLocalRef(ref);
21973
- var v2 = resolve12.call(self, localCompile, root, ref);
22479
+ var v2 = resolve13.call(self, localCompile, root, ref);
21974
22480
  if (v2 === undefined) {
21975
22481
  var localSchema = localRefs && localRefs[ref];
21976
22482
  if (localSchema) {
21977
- v2 = resolve12.inlineRef(localSchema, opts.inlineRefs) ? localSchema : compile.call(self, localSchema, root, localRefs, baseId2);
22483
+ v2 = resolve13.inlineRef(localSchema, opts.inlineRefs) ? localSchema : compile.call(self, localSchema, root, localRefs, baseId2);
21978
22484
  }
21979
22485
  }
21980
22486
  if (v2 === undefined) {
@@ -22116,7 +22622,7 @@ var require_compile = __commonJS((exports, module) => {
22116
22622
  code += statement(i, arr);
22117
22623
  return code;
22118
22624
  };
22119
- var resolve12 = require_resolve();
22625
+ var resolve13 = require_resolve();
22120
22626
  var util6 = require_util3();
22121
22627
  var errorClasses = require_error_classes();
22122
22628
  var stableStringify = require_fast_json_stable_stringify();
@@ -25365,7 +25871,7 @@ var require_ajv = __commonJS((exports, module) => {
25365
25871
  var id = this._getId(schema2);
25366
25872
  if (id !== undefined && typeof id != "string")
25367
25873
  throw new Error("schema id must be string");
25368
- key = resolve12.normalizeId(key || id);
25874
+ key = resolve13.normalizeId(key || id);
25369
25875
  checkUnique(this, key);
25370
25876
  this._schemas[key] = this._addSchema(schema2, _skipValidation, _meta, true);
25371
25877
  return this;
@@ -25411,7 +25917,7 @@ var require_ajv = __commonJS((exports, module) => {
25411
25917
  }
25412
25918
  };
25413
25919
  var _getSchemaFragment = function(self, ref) {
25414
- var res = resolve12.schema.call(self, { schema: {} }, ref);
25920
+ var res = resolve13.schema.call(self, { schema: {} }, ref);
25415
25921
  if (res) {
25416
25922
  var { schema: schema2, root, baseId } = res;
25417
25923
  var v = compileSchema.call(self, schema2, root, undefined, baseId);
@@ -25427,7 +25933,7 @@ var require_ajv = __commonJS((exports, module) => {
25427
25933
  }
25428
25934
  };
25429
25935
  var _getSchemaObj = function(self, keyRef) {
25430
- keyRef = resolve12.normalizeId(keyRef);
25936
+ keyRef = resolve13.normalizeId(keyRef);
25431
25937
  return self._schemas[keyRef] || self._refs[keyRef] || self._fragments[keyRef];
25432
25938
  };
25433
25939
  var removeSchema = function(schemaKeyRef) {
@@ -25455,7 +25961,7 @@ var require_ajv = __commonJS((exports, module) => {
25455
25961
  this._cache.del(cacheKey);
25456
25962
  var id = this._getId(schemaKeyRef);
25457
25963
  if (id) {
25458
- id = resolve12.normalizeId(id);
25964
+ id = resolve13.normalizeId(id);
25459
25965
  delete this._schemas[id];
25460
25966
  delete this._refs[id];
25461
25967
  }
@@ -25480,14 +25986,14 @@ var require_ajv = __commonJS((exports, module) => {
25480
25986
  if (cached)
25481
25987
  return cached;
25482
25988
  shouldAddSchema = shouldAddSchema || this._opts.addUsedSchema !== false;
25483
- var id = resolve12.normalizeId(this._getId(schema2));
25989
+ var id = resolve13.normalizeId(this._getId(schema2));
25484
25990
  if (id && shouldAddSchema)
25485
25991
  checkUnique(this, id);
25486
25992
  var willValidate = this._opts.validateSchema !== false && !skipValidation;
25487
25993
  var recursiveMeta;
25488
- if (willValidate && !(recursiveMeta = id && id == resolve12.normalizeId(schema2.$schema)))
25994
+ if (willValidate && !(recursiveMeta = id && id == resolve13.normalizeId(schema2.$schema)))
25489
25995
  this.validateSchema(schema2, true);
25490
- var localRefs = resolve12.ids.call(this, schema2);
25996
+ var localRefs = resolve13.ids.call(this, schema2);
25491
25997
  var schemaObj = new SchemaObject({
25492
25998
  id,
25493
25999
  schema: schema2,
@@ -25634,21 +26140,21 @@ var require_ajv = __commonJS((exports, module) => {
25634
26140
  return metaOpts;
25635
26141
  };
25636
26142
  var setLogger = function(self) {
25637
- var logger5 = self._opts.logger;
25638
- if (logger5 === false) {
26143
+ var logger6 = self._opts.logger;
26144
+ if (logger6 === false) {
25639
26145
  self.logger = { log: noop, warn: noop, error: noop };
25640
26146
  } else {
25641
- if (logger5 === undefined)
25642
- logger5 = console;
25643
- if (!(typeof logger5 == "object" && logger5.log && logger5.warn && logger5.error))
26147
+ if (logger6 === undefined)
26148
+ logger6 = console;
26149
+ if (!(typeof logger6 == "object" && logger6.log && logger6.warn && logger6.error))
25644
26150
  throw new Error("logger must implement log, warn and error methods");
25645
- self.logger = logger5;
26151
+ self.logger = logger6;
25646
26152
  }
25647
26153
  };
25648
26154
  var noop = function() {
25649
26155
  };
25650
26156
  var compileSchema = require_compile();
25651
- var resolve12 = require_resolve();
26157
+ var resolve13 = require_resolve();
25652
26158
  var Cache = require_cache();
25653
26159
  var SchemaObject = require_schema_obj();
25654
26160
  var stableStringify = require_fast_json_stable_stringify();
@@ -25709,27 +26215,27 @@ var require_windows = __commonJS((exports, module) => {
25709
26215
  return checkPathExt(path, options2);
25710
26216
  };
25711
26217
  var isexe = function(path, options2, cb) {
25712
- fs31.stat(path, function(er, stat) {
26218
+ fs33.stat(path, function(er, stat) {
25713
26219
  cb(er, er ? false : checkStat(stat, path, options2));
25714
26220
  });
25715
26221
  };
25716
26222
  var sync = function(path, options2) {
25717
- return checkStat(fs31.statSync(path), path, options2);
26223
+ return checkStat(fs33.statSync(path), path, options2);
25718
26224
  };
25719
26225
  module.exports = isexe;
25720
26226
  isexe.sync = sync;
25721
- var fs31 = __require("fs");
26227
+ var fs33 = __require("fs");
25722
26228
  });
25723
26229
 
25724
26230
  // node_modules/isexe/mode.js
25725
26231
  var require_mode = __commonJS((exports, module) => {
25726
26232
  var isexe = function(path, options2, cb) {
25727
- fs31.stat(path, function(er, stat) {
26233
+ fs33.stat(path, function(er, stat) {
25728
26234
  cb(er, er ? false : checkStat(stat, options2));
25729
26235
  });
25730
26236
  };
25731
26237
  var sync = function(path, options2) {
25732
- return checkStat(fs31.statSync(path), options2);
26238
+ return checkStat(fs33.statSync(path), options2);
25733
26239
  };
25734
26240
  var checkStat = function(stat, options2) {
25735
26241
  return stat.isFile() && checkMode(stat, options2);
@@ -25749,7 +26255,7 @@ var require_mode = __commonJS((exports, module) => {
25749
26255
  };
25750
26256
  module.exports = isexe;
25751
26257
  isexe.sync = sync;
25752
- var fs31 = __require("fs");
26258
+ var fs33 = __require("fs");
25753
26259
  });
25754
26260
 
25755
26261
  // node_modules/isexe/index.js
@@ -25763,12 +26269,12 @@ var require_isexe = __commonJS((exports, module) => {
25763
26269
  if (typeof Promise !== "function") {
25764
26270
  throw new TypeError("callback not provided");
25765
26271
  }
25766
- return new Promise(function(resolve12, reject) {
26272
+ return new Promise(function(resolve13, reject) {
25767
26273
  isexe(path, options2 || {}, function(er, is) {
25768
26274
  if (er) {
25769
26275
  reject(er);
25770
26276
  } else {
25771
- resolve12(is);
26277
+ resolve13(is);
25772
26278
  }
25773
26279
  });
25774
26280
  });
@@ -25794,7 +26300,7 @@ var require_isexe = __commonJS((exports, module) => {
25794
26300
  }
25795
26301
  }
25796
26302
  };
25797
- var fs31 = __require("fs");
26303
+ var fs33 = __require("fs");
25798
26304
  var core2;
25799
26305
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
25800
26306
  core2 = require_windows();
@@ -25839,27 +26345,27 @@ var require_which = __commonJS((exports, module) => {
25839
26345
  opt = {};
25840
26346
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
25841
26347
  const found = [];
25842
- const step = (i) => new Promise((resolve12, reject) => {
26348
+ const step = (i) => new Promise((resolve13, reject) => {
25843
26349
  if (i === pathEnv.length)
25844
- return opt.all && found.length ? resolve12(found) : reject(getNotFoundError(cmd));
26350
+ return opt.all && found.length ? resolve13(found) : reject(getNotFoundError(cmd));
25845
26351
  const ppRaw = pathEnv[i];
25846
26352
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
25847
26353
  const pCmd = path.join(pathPart, cmd);
25848
26354
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
25849
- resolve12(subStep(p, i, 0));
26355
+ resolve13(subStep(p, i, 0));
25850
26356
  });
25851
- const subStep = (p, i, ii) => new Promise((resolve12, reject) => {
26357
+ const subStep = (p, i, ii) => new Promise((resolve13, reject) => {
25852
26358
  if (ii === pathExt.length)
25853
- return resolve12(step(i + 1));
26359
+ return resolve13(step(i + 1));
25854
26360
  const ext = pathExt[ii];
25855
26361
  isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
25856
26362
  if (!er && is) {
25857
26363
  if (opt.all)
25858
26364
  found.push(p + ext);
25859
26365
  else
25860
- return resolve12(p + ext);
26366
+ return resolve13(p + ext);
25861
26367
  }
25862
- return resolve12(subStep(p, i, ii + 1));
26368
+ return resolve13(subStep(p, i, ii + 1));
25863
26369
  });
25864
26370
  });
25865
26371
  return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
@@ -26001,14 +26507,14 @@ var require_readShebang = __commonJS((exports, module) => {
26001
26507
  const buffer = Buffer.alloc(size);
26002
26508
  let fd;
26003
26509
  try {
26004
- fd = fs31.openSync(command, "r");
26005
- fs31.readSync(fd, buffer, 0, size, 0);
26006
- fs31.closeSync(fd);
26510
+ fd = fs33.openSync(command, "r");
26511
+ fs33.readSync(fd, buffer, 0, size, 0);
26512
+ fs33.closeSync(fd);
26007
26513
  } catch (e) {
26008
26514
  }
26009
26515
  return shebangCommand(buffer.toString());
26010
26516
  };
26011
- var fs31 = __require("fs");
26517
+ var fs33 = __require("fs");
26012
26518
  var shebangCommand = require_shebang_command();
26013
26519
  module.exports = readShebang;
26014
26520
  });
@@ -27461,155 +27967,7 @@ function ora(options2) {
27461
27967
 
27462
27968
  // dist/commands/init.js
27463
27969
  var import_prompts = __toESM(require_prompts3(), 1);
27464
-
27465
- // node_modules/kleur/colors.mjs
27466
- var init = function(x, y) {
27467
- let rgx = new RegExp(`\\x1b\\[${y}m`, "g");
27468
- let open = `\x1B[${x}m`, close = `\x1B[${y}m`;
27469
- return function(txt) {
27470
- if (!$.enabled || txt == null)
27471
- return txt;
27472
- return open + (~("" + txt).indexOf(close) ? txt.replace(rgx, close + open) : txt) + close;
27473
- };
27474
- };
27475
- var FORCE_COLOR;
27476
- var NODE_DISABLE_COLORS;
27477
- var NO_COLOR;
27478
- var TERM;
27479
- var isTTY = true;
27480
- if (typeof process !== "undefined") {
27481
- ({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
27482
- isTTY = process.stdout && process.stdout.isTTY;
27483
- }
27484
- var $ = {
27485
- enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY)
27486
- };
27487
- var reset = init(0, 0);
27488
- var bold = init(1, 22);
27489
- var dim = init(2, 22);
27490
- var italic = init(3, 23);
27491
- var underline = init(4, 24);
27492
- var inverse = init(7, 27);
27493
- var hidden = init(8, 28);
27494
- var strikethrough = init(9, 29);
27495
- var black = init(30, 39);
27496
- var red = init(31, 39);
27497
- var green = init(32, 39);
27498
- var yellow = init(33, 39);
27499
- var blue = init(34, 39);
27500
- var magenta = init(35, 39);
27501
- var cyan = init(36, 39);
27502
- var white = init(37, 39);
27503
- var gray = init(90, 39);
27504
- var grey = init(90, 39);
27505
- var bgBlack = init(40, 49);
27506
- var bgRed = init(41, 49);
27507
- var bgGreen = init(42, 49);
27508
- var bgYellow = init(43, 49);
27509
- var bgBlue = init(44, 49);
27510
- var bgMagenta = init(45, 49);
27511
- var bgCyan = init(46, 49);
27512
- var bgWhite = init(47, 49);
27513
-
27514
- // dist/utils/symbols.js
27515
- var STATUS = {
27516
- success: "\u2713",
27517
- error: "\u2717",
27518
- warning: "\u26A0",
27519
- info: "\u2139",
27520
- debug: "\u2022"
27521
- };
27522
- var TREE = {
27523
- branch: "\u251C\u2500",
27524
- last: "\u2514\u2500"
27525
- };
27526
- var BOX = {
27527
- topLeft: "\u250C",
27528
- topRight: "\u2510",
27529
- bottomLeft: "\u2514",
27530
- bottomRight: "\u2518",
27531
- horizontal: "\u2500",
27532
- vertical: "\u2502"
27533
- };
27534
-
27535
- // dist/utils/logger.js
27536
- var getTerminalWidth = function() {
27537
- const columns = process.stdout.columns;
27538
- return typeof columns === "number" && columns > 0 ? columns : 80;
27539
- };
27540
- var truncateText = function(text, maxLength) {
27541
- if (maxLength <= 0) {
27542
- return "";
27543
- }
27544
- if (text.length <= maxLength) {
27545
- return text;
27546
- }
27547
- if (maxLength <= 3) {
27548
- return ".".repeat(maxLength);
27549
- }
27550
- return `${text.slice(0, maxLength - 3)}...`;
27551
- };
27552
-
27553
- class Logger {
27554
- static instance;
27555
- static getInstance() {
27556
- if (!Logger.instance) {
27557
- Logger.instance = new Logger;
27558
- }
27559
- return Logger.instance;
27560
- }
27561
- info(message) {
27562
- console.log(cyan(STATUS.info), message);
27563
- }
27564
- success(message) {
27565
- console.log(green(STATUS.success), message);
27566
- }
27567
- warning(message) {
27568
- console.log(yellow(STATUS.warning), message);
27569
- }
27570
- warn(message) {
27571
- this.warning(message);
27572
- }
27573
- error(message) {
27574
- console.log(red(STATUS.error), message);
27575
- }
27576
- debug(message) {
27577
- console.log(dim(STATUS.debug), dim(message));
27578
- }
27579
- title(message) {
27580
- console.log(bold(cyan(message)));
27581
- }
27582
- subtitle(message) {
27583
- console.log(bold(message));
27584
- }
27585
- titleBox(message) {
27586
- const w = getTerminalWidth();
27587
- if (w < 8) {
27588
- console.log(bold(cyan(truncateText(message, w))));
27589
- return;
27590
- }
27591
- const maxInner = Math.max(4, w - 2);
27592
- const inner = Math.min(Math.max(message.length + 4, 40), maxInner);
27593
- const visibleMessage = truncateText(message, inner - 2);
27594
- const padR = Math.max(0, inner - visibleMessage.length - 2);
27595
- console.log(dim(BOX.topLeft + BOX.horizontal.repeat(inner) + BOX.topRight));
27596
- console.log(dim(BOX.vertical) + " " + bold(cyan(visibleMessage)) + " ".repeat(padR) + " " + dim(BOX.vertical));
27597
- console.log(dim(BOX.bottomLeft + BOX.horizontal.repeat(inner) + BOX.bottomRight));
27598
- }
27599
- section(title) {
27600
- const w = getTerminalWidth();
27601
- const lineLen = Math.max(0, w - title.length - 5);
27602
- console.log("");
27603
- console.log(bold(`${BOX.horizontal}${BOX.horizontal} ${title} ${BOX.horizontal.repeat(lineLen)}`));
27604
- }
27605
- tree(message, isLast) {
27606
- const connector = isLast ? TREE.last : TREE.branch;
27607
- console.log(`${connector} ${message}`);
27608
- }
27609
- }
27610
- var logger = Logger.getInstance();
27611
-
27612
- // dist/commands/init.js
27970
+ init_logger();
27613
27971
  init_fs();
27614
27972
 
27615
27973
  // dist/core/agentDetector.js
@@ -28270,6 +28628,7 @@ var getProjectName = function(cwd) {
28270
28628
  };
28271
28629
 
28272
28630
  // dist/commands/detect.js
28631
+ init_logger();
28273
28632
  init_skillsManager();
28274
28633
  init_agentManager();
28275
28634
  async function detectCommand(options2) {
@@ -28338,12 +28697,13 @@ async function detectCommand(options2) {
28338
28697
  }
28339
28698
 
28340
28699
  // dist/commands/sync.js
28700
+ init_logger();
28341
28701
  import {relative as relative5} from "path";
28342
28702
 
28343
28703
  // dist/core/propagator.js
28344
28704
  var import_gray_matter3 = __toESM(require_gray_matter(), 1);
28345
- import {promises as fs26} from "fs";
28346
- import {resolve as resolve9} from "path";
28705
+ import {promises as fs28} from "fs";
28706
+ import {resolve as resolve10} from "path";
28347
28707
 
28348
28708
  // node_modules/js-yaml/dist/js-yaml.mjs
28349
28709
  var isNothing = function(subject) {
@@ -30990,7 +31350,7 @@ class Propagator {
30990
31350
  warnings: [],
30991
31351
  resolvedTargets: []
30992
31352
  };
30993
- const agentsPath = resolve9(projectPath, "agents.md");
31353
+ const agentsPath = resolve10(projectPath, "agents.md");
30994
31354
  if (!await fileExists(agentsPath)) {
30995
31355
  result.success = false;
30996
31356
  result.errors.push("agents.md not found. Run `agentinit init` first.");
@@ -31075,7 +31435,7 @@ class Propagator {
31075
31435
  return [...generatedFiles.values()];
31076
31436
  }
31077
31437
  mergeGeneratedFile(projectPath, generatedFiles, output, agentId) {
31078
- const outputPath = resolve9(projectPath, output.path);
31438
+ const outputPath = resolve10(projectPath, output.path);
31079
31439
  const nextKind = output.kind ?? "file";
31080
31440
  const nextContent = nextKind === "file" || output.content !== undefined ? normalizeContent(output.content || "") : undefined;
31081
31441
  const existing = generatedFiles.get(outputPath);
@@ -31110,14 +31470,14 @@ class Propagator {
31110
31470
  resolvedTargets: []
31111
31471
  };
31112
31472
  const exists = await fileExists(generatedFile.path);
31113
- const existingStats = exists ? await fs26.lstat(generatedFile.path).catch(() => null) : null;
31473
+ const existingStats = exists ? await fs28.lstat(generatedFile.path).catch(() => null) : null;
31114
31474
  const existingContent = exists && !existingStats?.isSymbolicLink() ? await readFileIfExists(generatedFile.path) : null;
31115
31475
  const existingTarget = existingStats?.isSymbolicLink() ? await readSymlinkTarget(generatedFile.path) : null;
31116
31476
  if (options2.managedState && !options2.dryRun) {
31117
31477
  await options2.managedState.trackGeneratedPath(generatedFile.path, {
31118
31478
  kind: "file",
31119
31479
  source: "sync",
31120
- ignorePath: resolve9(projectPath, generatedFile.ignorePath)
31480
+ ignorePath: resolve10(projectPath, generatedFile.ignorePath)
31121
31481
  });
31122
31482
  }
31123
31483
  if (generatedFile.kind === "file" && exists && !existingStats?.isSymbolicLink() && existingContent === generatedFile.content) {
@@ -31141,12 +31501,12 @@ class Propagator {
31141
31501
  if (!options2.dryRun) {
31142
31502
  if (generatedFile.kind === "file") {
31143
31503
  if (existingStats?.isSymbolicLink()) {
31144
- await fs26.rm(generatedFile.path, { force: true }).catch(() => {
31504
+ await fs28.rm(generatedFile.path, { force: true }).catch(() => {
31145
31505
  });
31146
31506
  }
31147
31507
  await writeFile(generatedFile.path, generatedFile.content || "");
31148
31508
  } else {
31149
- const symlinkCreated = await createRelativeSymlink(resolve9(projectPath, generatedFile.target || ""), generatedFile.path);
31509
+ const symlinkCreated = await createRelativeSymlink(resolve10(projectPath, generatedFile.target || ""), generatedFile.path);
31150
31510
  if (!symlinkCreated) {
31151
31511
  await writeFile(generatedFile.path, generatedFile.content || "");
31152
31512
  result.warnings.push(`Could not create symlink for ${generatedFile.path}; wrote a copied file instead.`);
@@ -31251,7 +31611,7 @@ class Propagator {
31251
31611
  });
31252
31612
  }
31253
31613
  async buildAiderConfig(projectPath) {
31254
- const configPath = resolve9(projectPath, ".aider.conf.yml");
31614
+ const configPath = resolve10(projectPath, ".aider.conf.yml");
31255
31615
  const existingContent = await readFileIfExists(configPath);
31256
31616
  let document = {};
31257
31617
  if (existingContent) {
@@ -31318,14 +31678,14 @@ ${content}
31318
31678
 
31319
31679
  // dist/core/managedState.js
31320
31680
  init_fs();
31321
- import {promises as fs28} from "fs";
31322
- import {dirname as dirname4, join as join6, relative as relative4, resolve as resolve10} from "path";
31681
+ import {promises as fs30} from "fs";
31682
+ import {dirname as dirname5, join as join7, relative as relative4, resolve as resolve11} from "path";
31323
31683
  var toPosixPath = function(value) {
31324
31684
  return value.replace(/\\/g, "/");
31325
31685
  };
31326
31686
  async function pathType(targetPath) {
31327
31687
  try {
31328
- const stat = await fs28.lstat(targetPath);
31688
+ const stat = await fs30.lstat(targetPath);
31329
31689
  if (stat.isSymbolicLink()) {
31330
31690
  return "symlink";
31331
31691
  }
@@ -31335,20 +31695,20 @@ async function pathType(targetPath) {
31335
31695
  }
31336
31696
  }
31337
31697
  async function copyDirectory(src, dest) {
31338
- await fs28.mkdir(dest, { recursive: true });
31339
- const entries = await fs28.readdir(src, { withFileTypes: true });
31698
+ await fs30.mkdir(dest, { recursive: true });
31699
+ const entries = await fs30.readdir(src, { withFileTypes: true });
31340
31700
  for (const entry of entries) {
31341
- const srcPath = join6(src, entry.name);
31342
- const destPath = join6(dest, entry.name);
31701
+ const srcPath = join7(src, entry.name);
31702
+ const destPath = join7(dest, entry.name);
31343
31703
  if (entry.isDirectory()) {
31344
31704
  await copyDirectory(srcPath, destPath);
31345
31705
  } else if (entry.isSymbolicLink()) {
31346
- const target = await fs28.readlink(srcPath);
31347
- await fs28.mkdir(dirname4(destPath), { recursive: true });
31348
- await fs28.symlink(target, destPath);
31706
+ const target = await fs30.readlink(srcPath);
31707
+ await fs30.mkdir(dirname5(destPath), { recursive: true });
31708
+ await fs30.symlink(target, destPath);
31349
31709
  } else {
31350
- await fs28.mkdir(dirname4(destPath), { recursive: true });
31351
- await fs28.copyFile(srcPath, destPath);
31710
+ await fs30.mkdir(dirname5(destPath), { recursive: true });
31711
+ await fs30.copyFile(srcPath, destPath);
31352
31712
  }
31353
31713
  }
31354
31714
  }
@@ -31357,14 +31717,14 @@ async function copyPath(src, dest) {
31357
31717
  if (!type2) {
31358
31718
  return;
31359
31719
  }
31360
- await fs28.mkdir(dirname4(dest), { recursive: true });
31720
+ await fs30.mkdir(dirname5(dest), { recursive: true });
31361
31721
  if (type2 === "symlink") {
31362
- const target = await fs28.readlink(src);
31363
- await fs28.symlink(target, dest);
31722
+ const target = await fs30.readlink(src);
31723
+ await fs30.symlink(target, dest);
31364
31724
  } else if (type2 === "directory") {
31365
31725
  await copyDirectory(src, dest);
31366
31726
  } else {
31367
- await fs28.copyFile(src, dest);
31727
+ await fs30.copyFile(src, dest);
31368
31728
  }
31369
31729
  }
31370
31730
  var MANAGED_STATE_FILE = "managed-state.json";
@@ -31378,11 +31738,11 @@ class ManagedStateStore {
31378
31738
  this.state = state;
31379
31739
  }
31380
31740
  static async open(projectPath) {
31381
- const agentInitDir = join6(projectPath, ".agentinit");
31382
- const statePath = join6(agentInitDir, MANAGED_STATE_FILE);
31741
+ const agentInitDir = join7(projectPath, ".agentinit");
31742
+ const statePath = join7(agentInitDir, MANAGED_STATE_FILE);
31383
31743
  const emptyState = { version: 1, entries: [] };
31384
31744
  try {
31385
- const raw = await fs28.readFile(statePath, "utf8");
31745
+ const raw = await fs30.readFile(statePath, "utf8");
31386
31746
  const parsed = JSON.parse(raw);
31387
31747
  if (!parsed || parsed.version !== 1 || !Array.isArray(parsed.entries)) {
31388
31748
  return new ManagedStateStore(projectPath, emptyState);
@@ -31393,17 +31753,17 @@ class ManagedStateStore {
31393
31753
  }
31394
31754
  }
31395
31755
  get agentInitDir() {
31396
- return join6(this.projectPath, ".agentinit");
31756
+ return join7(this.projectPath, ".agentinit");
31397
31757
  }
31398
31758
  get stateFilePath() {
31399
- return join6(this.agentInitDir, MANAGED_STATE_FILE);
31759
+ return join7(this.agentInitDir, MANAGED_STATE_FILE);
31400
31760
  }
31401
31761
  get backupsDir() {
31402
- return join6(this.agentInitDir, BACKUPS_DIR);
31762
+ return join7(this.agentInitDir, BACKUPS_DIR);
31403
31763
  }
31404
31764
  normalizeRelativePath(targetPath, preserveTrailingSlash = false) {
31405
31765
  const hasTrailingSlash = preserveTrailingSlash && /[\\/]$/.test(targetPath);
31406
- const relativePath = relative4(this.projectPath, resolve10(targetPath));
31766
+ const relativePath = relative4(this.projectPath, resolve11(targetPath));
31407
31767
  const normalizedPath = toPosixPath(relativePath);
31408
31768
  if (hasTrailingSlash && normalizedPath) {
31409
31769
  return normalizedPath.endsWith("/") ? normalizedPath : `${normalizedPath}/`;
@@ -31421,14 +31781,14 @@ class ManagedStateStore {
31421
31781
  }
31422
31782
  if (type2 === "symlink") {
31423
31783
  try {
31424
- const backupLinkTarget = await fs28.readlink(targetPath);
31784
+ const backupLinkTarget = await fs30.readlink(targetPath);
31425
31785
  return { backupLinkTarget };
31426
31786
  } catch {
31427
31787
  return {};
31428
31788
  }
31429
31789
  }
31430
31790
  const relativeTargetPath = this.normalizeRelativePath(targetPath);
31431
- const backupPath = join6(this.backupsDir, relativeTargetPath);
31791
+ const backupPath = join7(this.backupsDir, relativeTargetPath);
31432
31792
  if (!await fileExists(backupPath)) {
31433
31793
  await copyPath(targetPath, backupPath);
31434
31794
  }
@@ -31463,20 +31823,20 @@ class ManagedStateStore {
31463
31823
  if (this.state.entries.length === 0) {
31464
31824
  return [];
31465
31825
  }
31466
- const paths5 = new Set([
31826
+ const paths6 = new Set([
31467
31827
  ".agentinit/managed-state.json",
31468
31828
  ".agentinit/backups/"
31469
31829
  ]);
31470
31830
  for (const entry of this.state.entries) {
31471
31831
  if (entry.ignorePath) {
31472
- paths5.add(entry.ignorePath);
31832
+ paths6.add(entry.ignorePath);
31473
31833
  }
31474
31834
  }
31475
- return [...paths5];
31835
+ return [...paths6];
31476
31836
  }
31477
31837
  async save() {
31478
- await fs28.mkdir(this.agentInitDir, { recursive: true });
31479
- await fs28.writeFile(this.stateFilePath, JSON.stringify(this.state, null, 2), "utf8");
31838
+ await fs30.mkdir(this.agentInitDir, { recursive: true });
31839
+ await fs30.writeFile(this.stateFilePath, JSON.stringify(this.state, null, 2), "utf8");
31480
31840
  }
31481
31841
  async revertAll(options2 = {}) {
31482
31842
  const summary = {
@@ -31486,34 +31846,34 @@ class ManagedStateStore {
31486
31846
  };
31487
31847
  const entries = [...this.state.entries].sort((a, b) => b.path.length - a.path.length);
31488
31848
  for (const entry of entries) {
31489
- const absolutePath = resolve10(this.projectPath, entry.path);
31490
- const backupPath = entry.backupPath ? resolve10(this.projectPath, entry.backupPath) : null;
31849
+ const absolutePath = resolve11(this.projectPath, entry.path);
31850
+ const backupPath = entry.backupPath ? resolve11(this.projectPath, entry.backupPath) : null;
31491
31851
  const backupLinkTarget = entry.backupLinkTarget;
31492
31852
  if (entry.existedBefore && backupLinkTarget !== undefined) {
31493
31853
  if (!options2.dryRun) {
31494
- await fs28.rm(absolutePath, { recursive: true, force: true }).catch(() => {
31854
+ await fs30.rm(absolutePath, { recursive: true, force: true }).catch(() => {
31495
31855
  });
31496
- await fs28.mkdir(dirname4(absolutePath), { recursive: true });
31497
- await fs28.symlink(backupLinkTarget, absolutePath);
31856
+ await fs30.mkdir(dirname5(absolutePath), { recursive: true });
31857
+ await fs30.symlink(backupLinkTarget, absolutePath);
31498
31858
  }
31499
31859
  summary.restored++;
31500
31860
  } else if (entry.existedBefore && backupPath && await fileExists(backupPath)) {
31501
31861
  if (!options2.dryRun) {
31502
- await fs28.rm(absolutePath, { recursive: true, force: true }).catch(() => {
31862
+ await fs30.rm(absolutePath, { recursive: true, force: true }).catch(() => {
31503
31863
  });
31504
31864
  await copyPath(backupPath, absolutePath);
31505
31865
  }
31506
31866
  summary.restored++;
31507
31867
  } else {
31508
31868
  if (!options2.dryRun) {
31509
- await fs28.rm(absolutePath, { recursive: true, force: true }).catch(() => {
31869
+ await fs30.rm(absolutePath, { recursive: true, force: true }).catch(() => {
31510
31870
  });
31511
31871
  }
31512
31872
  summary.removed++;
31513
31873
  }
31514
31874
  if (!options2.keepBackups && backupPath && await fileExists(backupPath)) {
31515
31875
  if (!options2.dryRun) {
31516
- await fs28.rm(backupPath, { recursive: true, force: true }).catch(() => {
31876
+ await fs30.rm(backupPath, { recursive: true, force: true }).catch(() => {
31517
31877
  });
31518
31878
  }
31519
31879
  summary.backupsRemoved++;
@@ -31521,16 +31881,16 @@ class ManagedStateStore {
31521
31881
  }
31522
31882
  if (!options2.dryRun) {
31523
31883
  this.state.entries.length = 0;
31524
- await fs28.rm(this.stateFilePath, { force: true }).catch(() => {
31884
+ await fs30.rm(this.stateFilePath, { force: true }).catch(() => {
31525
31885
  });
31526
31886
  if (!options2.keepBackups) {
31527
- await fs28.rm(this.backupsDir, { recursive: true, force: true }).catch(() => {
31887
+ await fs30.rm(this.backupsDir, { recursive: true, force: true }).catch(() => {
31528
31888
  });
31529
31889
  }
31530
31890
  try {
31531
- const remainingEntries = await fs28.readdir(this.agentInitDir);
31891
+ const remainingEntries = await fs30.readdir(this.agentInitDir);
31532
31892
  if (remainingEntries.length === 0) {
31533
- await fs28.rm(this.agentInitDir, { recursive: true, force: true });
31893
+ await fs30.rm(this.agentInitDir, { recursive: true, force: true });
31534
31894
  }
31535
31895
  } catch {
31536
31896
  }
@@ -31609,6 +31969,8 @@ async function syncCommand(options2) {
31609
31969
  }
31610
31970
 
31611
31971
  // dist/commands/apply.js
31972
+ init_colors();
31973
+ init_logger();
31612
31974
  import {relative as relative6} from "path";
31613
31975
 
31614
31976
  // dist/types/index.js
@@ -31875,12 +32237,12 @@ class MCPParser {
31875
32237
  // dist/constants/mcp.js
31876
32238
  import {readFileSync as readFileSync2} from "fs";
31877
32239
  import {fileURLToPath} from "url";
31878
- import {dirname as dirname5, join as join7} from "path";
32240
+ import {dirname as dirname6, join as join8} from "path";
31879
32241
  var getPackageVersion = function() {
31880
32242
  try {
31881
32243
  const __filename2 = fileURLToPath(import.meta.url);
31882
- const __dirname2 = dirname5(__filename2);
31883
- const packageJsonPath = join7(__dirname2, "../../package.json");
32244
+ const __dirname2 = dirname6(__filename2);
32245
+ const packageJsonPath = join8(__dirname2, "../../package.json");
31884
32246
  const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
31885
32247
  return packageJson.version || "1.0.0";
31886
32248
  } catch {
@@ -31911,17 +32273,17 @@ import {readFileSync as readFileSync4} from "fs";
31911
32273
 
31912
32274
  // dist/core/rulesTemplateLoader.js
31913
32275
  var toml = __toESM(require_toml(), 1);
31914
- import {resolve as resolve11, dirname as dirname6} from "path";
32276
+ import {resolve as resolve12, dirname as dirname7} from "path";
31915
32277
  import {fileURLToPath as fileURLToPath2} from "url";
31916
32278
  import {readFileSync as readFileSync3, readdirSync, existsSync as existsSync2} from "fs";
31917
32279
  var __filename2 = fileURLToPath2(import.meta.url);
31918
- var __dirname2 = dirname6(__filename2);
32280
+ var __dirname2 = dirname7(__filename2);
31919
32281
 
31920
32282
  class RulesTemplateLoader {
31921
32283
  templatesPath;
31922
32284
  templates = new Map;
31923
32285
  constructor() {
31924
- this.templatesPath = resolve11(__dirname2, "../templates/rules");
32286
+ this.templatesPath = resolve12(__dirname2, "../templates/rules");
31925
32287
  this.loadTemplates();
31926
32288
  }
31927
32289
  loadTemplates() {
@@ -31931,7 +32293,7 @@ class RulesTemplateLoader {
31931
32293
  const files = readdirSync(this.templatesPath).filter((file) => file.endsWith(".toml"));
31932
32294
  for (const file of files) {
31933
32295
  try {
31934
- const filePath = resolve11(this.templatesPath, file);
32296
+ const filePath = resolve12(this.templatesPath, file);
31935
32297
  const content = readFileSync3(filePath, "utf-8");
31936
32298
  const parsed = toml.default.parse(content);
31937
32299
  const template = {
@@ -37503,7 +37865,7 @@ class Protocol {
37503
37865
  }
37504
37866
  request(request, resultSchema, options2) {
37505
37867
  const { relatedRequestId, resumptionToken, onresumptiontoken } = options2 !== null && options2 !== undefined ? options2 : {};
37506
- return new Promise((resolve12, reject) => {
37868
+ return new Promise((resolve13, reject) => {
37507
37869
  var _a, _b, _c, _d, _e, _f;
37508
37870
  if (!this._transport) {
37509
37871
  reject(new Error("Not connected"));
@@ -37554,7 +37916,7 @@ class Protocol {
37554
37916
  }
37555
37917
  try {
37556
37918
  const result = resultSchema.parse(response.result);
37557
- resolve12(result);
37919
+ resolve13(result);
37558
37920
  } catch (error) {
37559
37921
  reject(error);
37560
37922
  }
@@ -37934,7 +38296,7 @@ class StdioClientTransport {
37934
38296
  if (this._process) {
37935
38297
  throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");
37936
38298
  }
37937
- return new Promise((resolve12, reject) => {
38299
+ return new Promise((resolve13, reject) => {
37938
38300
  var _a, _b, _c, _d, _e;
37939
38301
  this._process = import_cross_spawn.default(this._serverParams.command, (_a = this._serverParams.args) !== null && _a !== undefined ? _a : [], {
37940
38302
  env: {
@@ -37957,7 +38319,7 @@ class StdioClientTransport {
37957
38319
  (_b2 = this.onerror) === null || _b2 === undefined || _b2.call(this, error);
37958
38320
  });
37959
38321
  this._process.on("spawn", () => {
37960
- resolve12();
38322
+ resolve13();
37961
38323
  });
37962
38324
  this._process.on("close", (_code) => {
37963
38325
  var _a2;
@@ -38012,16 +38374,16 @@ class StdioClientTransport {
38012
38374
  this._readBuffer.clear();
38013
38375
  }
38014
38376
  send(message) {
38015
- return new Promise((resolve12) => {
38377
+ return new Promise((resolve13) => {
38016
38378
  var _a;
38017
38379
  if (!((_a = this._process) === null || _a === undefined ? undefined : _a.stdin)) {
38018
38380
  throw new Error("Not connected");
38019
38381
  }
38020
38382
  const json2 = serializeMessage(message);
38021
38383
  if (this._process.stdin.write(json2)) {
38022
- resolve12();
38384
+ resolve13();
38023
38385
  } else {
38024
- this._process.stdin.once("drain", resolve12);
38386
+ this._process.stdin.once("drain", resolve13);
38025
38387
  }
38026
38388
  });
38027
38389
  }
@@ -39443,7 +39805,7 @@ class SSEClientTransport {
39443
39805
  _startOrAuth() {
39444
39806
  var _a, _b, _c;
39445
39807
  const fetchImpl = (_c = (_b = (_a = this === null || this === undefined ? undefined : this._eventSourceInit) === null || _a === undefined ? undefined : _a.fetch) !== null && _b !== undefined ? _b : this._fetch) !== null && _c !== undefined ? _c : fetch;
39446
- return new Promise((resolve12, reject) => {
39808
+ return new Promise((resolve13, reject) => {
39447
39809
  this._eventSource = new EventSource(this._url.href, {
39448
39810
  ...this._eventSourceInit,
39449
39811
  fetch: async (url, init2) => {
@@ -39463,7 +39825,7 @@ class SSEClientTransport {
39463
39825
  this._eventSource.onerror = (event) => {
39464
39826
  var _a2;
39465
39827
  if (event.code === 401 && this._authProvider) {
39466
- this._authThenStart().then(resolve12, reject);
39828
+ this._authThenStart().then(resolve13, reject);
39467
39829
  return;
39468
39830
  }
39469
39831
  const error = new SseError(event.code, event.message, event);
@@ -39486,7 +39848,7 @@ class SSEClientTransport {
39486
39848
  this.close();
39487
39849
  return;
39488
39850
  }
39489
- resolve12();
39851
+ resolve13();
39490
39852
  });
39491
39853
  this._eventSource.onmessage = (event) => {
39492
39854
  var _a2, _b2;
@@ -39563,8 +39925,11 @@ class SSEClientTransport {
39563
39925
 
39564
39926
  // dist/core/mcpClient.js
39565
39927
  init_lib();
39928
+ init_colors();
39929
+ init_logger();
39566
39930
 
39567
39931
  // dist/utils/packageVersion.js
39932
+ init_logger();
39568
39933
  function extractExplicitVersion(packageSpec) {
39569
39934
  const versionMatch = packageSpec.match(/@([\d]+\.[\d]+\.[\d]+(?:[-+].+)?$)/);
39570
39935
  if (versionMatch && versionMatch[1]) {
@@ -40150,8 +40515,8 @@ class MCPVerifier {
40150
40515
  }
40151
40516
 
40152
40517
  // dist/core/gitignoreManager.js
40153
- import {promises as fs31} from "fs";
40154
- import {dirname as dirname7, join as join8} from "path";
40518
+ import {promises as fs33} from "fs";
40519
+ import {dirname as dirname8, join as join9} from "path";
40155
40520
  var normalizeIgnorePath = function(projectPath, value) {
40156
40521
  const relative6 = value.startsWith(projectPath) ? value.slice(projectPath.length + 1) : value;
40157
40522
  const normalized = relative6.replace(/\\/g, "/").replace(/^\/+/, "");
@@ -40197,13 +40562,13 @@ var updateManagedBlock = function(existingContent, entries) {
40197
40562
  }
40198
40563
  return content;
40199
40564
  };
40200
- async function updateManagedIgnoreFile(projectPath, paths5, options2 = {}) {
40201
- const ignoreFile = options2.local ? join8(".git", "info", "exclude") : ".gitignore";
40202
- const ignoreFilePath = join8(projectPath, ignoreFile);
40565
+ async function updateManagedIgnoreFile(projectPath, paths6, options2 = {}) {
40566
+ const ignoreFile = options2.local ? join9(".git", "info", "exclude") : ".gitignore";
40567
+ const ignoreFilePath = join9(projectPath, ignoreFile);
40203
40568
  if (options2.local) {
40204
- const gitDir = join8(projectPath, ".git");
40569
+ const gitDir = join9(projectPath, ".git");
40205
40570
  try {
40206
- const stat = await fs31.stat(gitDir);
40571
+ const stat = await fs33.stat(gitDir);
40207
40572
  if (!stat.isDirectory()) {
40208
40573
  throw new Error;
40209
40574
  }
@@ -40211,24 +40576,24 @@ async function updateManagedIgnoreFile(projectPath, paths5, options2 = {}) {
40211
40576
  throw new Error("Cannot update .git/info/exclude because this project is not a Git repository");
40212
40577
  }
40213
40578
  }
40214
- const normalizedPaths = [...new Set(paths5.map((path) => normalizeIgnorePath(projectPath, path)).filter(Boolean))].sort();
40579
+ const normalizedPaths = [...new Set(paths6.map((path) => normalizeIgnorePath(projectPath, path)).filter(Boolean))].sort();
40215
40580
  let existingContent = "";
40216
40581
  try {
40217
- existingContent = await fs31.readFile(ignoreFilePath, "utf8");
40582
+ existingContent = await fs33.readFile(ignoreFilePath, "utf8");
40218
40583
  } catch {
40219
40584
  existingContent = "";
40220
40585
  }
40221
40586
  const updatedContent = updateManagedBlock(existingContent, normalizedPaths);
40222
- await fs31.mkdir(dirname7(ignoreFilePath), { recursive: true });
40223
- await fs31.writeFile(ignoreFilePath, updatedContent, "utf8");
40587
+ await fs33.mkdir(dirname8(ignoreFilePath), { recursive: true });
40588
+ await fs33.writeFile(ignoreFilePath, updatedContent, "utf8");
40224
40589
  return ignoreFilePath;
40225
40590
  }
40226
40591
  async function removeManagedIgnoreBlock(projectPath, options2 = {}) {
40227
- const ignoreFile = options2.local ? join8(".git", "info", "exclude") : ".gitignore";
40228
- const ignoreFilePath = join8(projectPath, ignoreFile);
40592
+ const ignoreFile = options2.local ? join9(".git", "info", "exclude") : ".gitignore";
40593
+ const ignoreFilePath = join9(projectPath, ignoreFile);
40229
40594
  let content;
40230
40595
  try {
40231
- content = await fs31.readFile(ignoreFilePath, "utf8");
40596
+ content = await fs33.readFile(ignoreFilePath, "utf8");
40232
40597
  } catch {
40233
40598
  return false;
40234
40599
  }
@@ -40244,13 +40609,13 @@ async function removeManagedIgnoreBlock(projectPath, options2 = {}) {
40244
40609
  const afterBlock = content.slice(endIndex + END_MARKER.length).replace(/^\n+/, "");
40245
40610
  let nextContent = `${beforeBlock}${afterBlock}`.replace(/\n{3,}/g, "\n\n").replace(/^\n+/, "");
40246
40611
  if (nextContent.trim() === "") {
40247
- await fs31.rm(ignoreFilePath, { force: true }).catch(() => {
40612
+ await fs33.rm(ignoreFilePath, { force: true }).catch(() => {
40248
40613
  });
40249
40614
  } else {
40250
40615
  if (!nextContent.endsWith("\n")) {
40251
40616
  nextContent += "\n";
40252
40617
  }
40253
- await fs31.writeFile(ignoreFilePath, nextContent, "utf8");
40618
+ await fs33.writeFile(ignoreFilePath, nextContent, "utf8");
40254
40619
  }
40255
40620
  return true;
40256
40621
  }
@@ -40261,12 +40626,12 @@ var END_MARKER = "# END AgentInit Generated Files";
40261
40626
  init_agentManager();
40262
40627
  init_skillsManager();
40263
40628
  init_fs();
40264
- import {dirname as dirname8, join as join9} from "path";
40629
+ import {dirname as dirname9, join as join10} from "path";
40265
40630
  async function discoverProjectSkills(projectPath, skillsManager4) {
40266
40631
  const sources = [];
40267
40632
  const skills2 = new Map;
40268
40633
  for (const sourceDir of PROJECT_SKILL_SOURCE_DIRS) {
40269
- const absoluteSourceDir = join9(projectPath, sourceDir);
40634
+ const absoluteSourceDir = join10(projectPath, sourceDir);
40270
40635
  if (!await fileExists(absoluteSourceDir)) {
40271
40636
  continue;
40272
40637
  }
@@ -40339,7 +40704,7 @@ async function applyProjectSkills(projectPath, targetAgentIds, managedState2, op
40339
40704
  await managedState2.trackGeneratedPath(generatedPath, {
40340
40705
  kind: "directory",
40341
40706
  source: "skills",
40342
- ignorePath: `${dirname8(generatedPath)}/`
40707
+ ignorePath: `${dirname9(generatedPath)}/`
40343
40708
  });
40344
40709
  }
40345
40710
  }
@@ -40910,6 +41275,7 @@ var LEGACY_APPLY_FLAGS = new Set([
40910
41275
  ]);
40911
41276
 
40912
41277
  // dist/commands/verifyMcp.js
41278
+ init_logger();
40913
41279
  init_agentManager();
40914
41280
  async function verifyMcpCommand(args) {
40915
41281
  const cwd = process.cwd();
@@ -41115,6 +41481,7 @@ async function verifyMcpCommand(args) {
41115
41481
  }
41116
41482
 
41117
41483
  // dist/commands/revert.js
41484
+ init_logger();
41118
41485
  async function revertCommand(options2) {
41119
41486
  const cwd = process.cwd();
41120
41487
  logger.titleBox("AgentInit Revert");
@@ -41159,6 +41526,7 @@ async function revertCommand(options2) {
41159
41526
  }
41160
41527
 
41161
41528
  // dist/utils/colors.js
41529
+ init_colors();
41162
41530
  var colorsEnabled = function() {
41163
41531
  const env2 = process.env || {};
41164
41532
  const isTTY2 = !!process.stdout?.isTTY;
@@ -41172,6 +41540,7 @@ function orange(text) {
41172
41540
  }
41173
41541
 
41174
41542
  // dist/commands/config.js
41543
+ init_logger();
41175
41544
  init_marketplaceRegistry();
41176
41545
  init_userConfig();
41177
41546
  var sortConfig = function(config) {
@@ -41348,12 +41717,15 @@ var BUILT_IN_VERIFIED_REPOS = new Set(getBuiltInVerifiedGithubRepos());
41348
41717
 
41349
41718
  // dist/commands/skills.js
41350
41719
  var import_prompts3 = __toESM(require_prompts3(), 1);
41351
- import {homedir as homedir6} from "os";
41352
- import {relative as relative7, resolve as resolve12} from "path";
41720
+ init_colors();
41721
+ init_logger();
41722
+ import {homedir as homedir7} from "os";
41723
+ import {relative as relative7, resolve as resolve13} from "path";
41353
41724
 
41354
41725
  // dist/utils/promptUtils.js
41355
41726
  var import_prompts2 = __toESM(require_prompts3(), 1);
41356
41727
  import {createRequire as createRequire2} from "module";
41728
+ init_logger();
41357
41729
  function enableUppercaseToggleAllForMultiselectPrompt() {
41358
41730
  if (uppercaseToggleAllPatched) {
41359
41731
  return;
@@ -41418,6 +41790,8 @@ init_skillsManager();
41418
41790
  init_pluginManager();
41419
41791
  init_marketplaceRegistry();
41420
41792
  init_agentManager();
41793
+ init_installLock();
41794
+ init_fs();
41421
41795
  init_skills();
41422
41796
  function registerSkillsCommand(program2) {
41423
41797
  const marketplaceHelp = getMarketplaceIds().join(", ");
@@ -41500,9 +41874,24 @@ function registerSkillsCommand(program2) {
41500
41874
  }
41501
41875
  let targetAgents = options2.agent;
41502
41876
  let targetGlobal = options2.global;
41877
+ let selectedSkillNames = options2.skill;
41878
+ if (!options2.yes && (!selectedSkillNames || selectedSkillNames.length === 0) && preparedSkills.length > 1) {
41879
+ if (selectedPluginNames && selectedPluginNames.length > 1) {
41880
+ logger.info("Multiple bundled plugins selected; installing all skills from each selected plugin. Use --skill to filter by skill name.");
41881
+ } else {
41882
+ const skillSelection = await resolveInteractiveSkillSelection(preparedSkills);
41883
+ if (skillSelection.aborted) {
41884
+ await skillsManager5.discardPreparedSource(source, process.cwd(), {
41885
+ from: options2.from
41886
+ });
41887
+ return;
41888
+ }
41889
+ selectedSkillNames = skillSelection.skills;
41890
+ }
41891
+ }
41503
41892
  if (!targetAgents && !options2.yes) {
41504
- const selectedSkillNames = options2.skill && options2.skill.length > 0 ? new Set(options2.skill.map((name) => name.toLowerCase())) : undefined;
41505
- const filteredPreviewSkills = selectedSkillNames ? preparedSkills.filter((skill) => selectedSkillNames.has(skill.name.toLowerCase())) : preparedSkills;
41893
+ const selectedSkillNameSet = selectedSkillNames && selectedSkillNames.length > 0 ? new Set(selectedSkillNames.map((name) => name.toLowerCase())) : undefined;
41894
+ const filteredPreviewSkills = selectedSkillNameSet ? preparedSkills.filter((skill) => selectedSkillNameSet.has(skill.name.toLowerCase())) : preparedSkills;
41506
41895
  const selection = await resolveInteractiveSkillTargets(skillsManager5, agentManager9, source, process.cwd(), {
41507
41896
  from: options2.from,
41508
41897
  global: options2.global,
@@ -41534,7 +41923,7 @@ function registerSkillsCommand(program2) {
41534
41923
  ...options2.from !== undefined ? { from: options2.from } : {},
41535
41924
  ...targetGlobal !== undefined ? { global: targetGlobal } : {},
41536
41925
  ...targetAgents !== undefined ? { agents: targetAgents } : {},
41537
- ...options2.skill !== undefined ? { skills: options2.skill } : {},
41926
+ ...selectedSkillNames !== undefined ? { skills: selectedSkillNames } : {},
41538
41927
  ...options2.copy !== undefined ? { copy: options2.copy } : {},
41539
41928
  ...pluginName !== undefined ? { pluginName } : {},
41540
41929
  ...options2.yes !== undefined ? { yes: options2.yes } : {},
@@ -41633,7 +42022,221 @@ function registerSkillsCommand(program2) {
41633
42022
  logger.info("Nothing to remove.");
41634
42023
  }
41635
42024
  });
42025
+ skills3.command("update [name]").description("Update installed skills from their original source").option("--everywhere", "Update across all tracked projects (uses global lockfile)").option("-d, --dry-run", "Show what would be updated without making changes").action(async (name, options2) => {
42026
+ logger.titleBox("AgentInit Skills");
42027
+ const installLock3 = new InstallLock;
42028
+ if (options2.everywhere) {
42029
+ if (!name) {
42030
+ logger.error("Skill name is required with --everywhere.");
42031
+ logger.info("Usage: agentinit skills update <name> --everywhere");
42032
+ return;
42033
+ }
42034
+ const entries = await installLock3.findProjectsWithSkill(name);
42035
+ if (entries.length === 0) {
42036
+ logger.info(`No tracked installations found for skill "${name}".`);
42037
+ logger.info(dim("Install the skill first, then update with --everywhere."));
42038
+ return;
42039
+ }
42040
+ logger.info(`Found ${cyan(String(entries.length))} tracked target(s) with skill "${green(name)}":\n`);
42041
+ const staleProjects = [];
42042
+ const updateTargets = [];
42043
+ for (const entry of entries) {
42044
+ const targetLabel = getLockEntryTargetLabel(entry);
42045
+ if (entry.scope !== "global" && !await fileExists(entry.projectPath)) {
42046
+ staleProjects.push(entry.projectPath);
42047
+ logger.info(` ${red("x")} ${targetLabel} ${dim("(missing)")}`);
42048
+ } else {
42049
+ updateTargets.push(entry);
42050
+ logger.info(` ${green("+")} ${targetLabel} ${dim(`[${entry.agents.join(", ")}]`)}`);
42051
+ }
42052
+ }
42053
+ if (staleProjects.length > 0) {
42054
+ logger.info("");
42055
+ logger.warn(`${staleProjects.length} project(s) no longer exist. Run "agentinit lock prune" to clean up.`);
42056
+ }
42057
+ if (updateTargets.length === 0) {
42058
+ logger.info("\nNo valid projects to update.");
42059
+ return;
42060
+ }
42061
+ if (options2.dryRun) {
42062
+ logger.info(dim(`
42063
+ Dry run \u2014 no changes made.`));
42064
+ return;
42065
+ }
42066
+ logger.info("");
42067
+ const spinner = ora("Updating skills across projects...").start();
42068
+ let updatedCount = 0;
42069
+ let unchangedCount = 0;
42070
+ let failedCount = 0;
42071
+ for (const entry of updateTargets) {
42072
+ spinner.text = `Updating in ${getLockEntryTargetLabel(entry)}...`;
42073
+ try {
42074
+ const sourceString = lockSourceToString(entry.source);
42075
+ if (!sourceString) {
42076
+ failedCount++;
42077
+ logger.info(` ${red("x")} ${getLockEntryTargetLabel(entry)}: cannot reconstruct source`);
42078
+ continue;
42079
+ }
42080
+ const agentManager9 = new AgentManager;
42081
+ const skillsManager5 = new SkillsManager(agentManager9);
42082
+ const result = await skillsManager5.addFromSource(sourceString.source, entry.projectPath, {
42083
+ ...sourceString.from ? { from: sourceString.from } : {},
42084
+ agents: entry.agents,
42085
+ global: entry.scope === "global",
42086
+ skills: [name],
42087
+ yes: true
42088
+ });
42089
+ if (result.updated.length > 0) {
42090
+ updatedCount++;
42091
+ logger.info(` ${green("~")} ${getLockEntryTargetLabel(entry)}: updated`);
42092
+ } else if (result.installed.length > 0) {
42093
+ updatedCount++;
42094
+ logger.info(` ${green("+")} ${getLockEntryTargetLabel(entry)}: installed`);
42095
+ } else {
42096
+ unchangedCount++;
42097
+ logger.info(` ${dim("-")} ${getLockEntryTargetLabel(entry)}: ${dim("unchanged")}`);
42098
+ }
42099
+ } catch (error) {
42100
+ failedCount++;
42101
+ logger.info(` ${red("x")} ${getLockEntryTargetLabel(entry)}: ${error instanceof Error ? error.message : "unknown error"}`);
42102
+ }
42103
+ }
42104
+ if (updatedCount > 0) {
42105
+ spinner.succeed(`Updated "${name}" in ${updatedCount} target(s)`);
42106
+ } else {
42107
+ spinner.info(`"${name}" is already up to date in all tracked targets`);
42108
+ }
42109
+ if (unchangedCount > 0)
42110
+ logger.info(dim(` ${unchangedCount} unchanged`));
42111
+ if (failedCount > 0)
42112
+ logger.info(red(` ${failedCount} failed`));
42113
+ } else {
42114
+ const cwd = process.cwd();
42115
+ const agentManager9 = new AgentManager;
42116
+ const skillsManager5 = new SkillsManager(agentManager9);
42117
+ if (name) {
42118
+ const entries = await installLock3.getCurrentState({
42119
+ kind: "skill",
42120
+ name,
42121
+ projectPath: resolve13(cwd),
42122
+ scope: "project"
42123
+ });
42124
+ if (entries.length === 0) {
42125
+ logger.info(`Skill "${name}" not tracked in the lockfile for this project.`);
42126
+ logger.info(dim("Try: agentinit skills add <source> or use --everywhere for global installs."));
42127
+ return;
42128
+ }
42129
+ if (options2.dryRun) {
42130
+ logger.info(`Would update "${name}" in ${entries.length} tracked target(s):`);
42131
+ for (const entry of entries) {
42132
+ const sourceString = lockSourceToString(entry.source);
42133
+ logger.info(` ${green(entry.name)} ${dim(`[${entry.agents.join(", ")}]`)} ${sourceString ? dim(sourceString.source) : red("unavailable source")}`);
42134
+ }
42135
+ return;
42136
+ }
42137
+ const spinner = ora(`Updating skill "${name}"...`).start();
42138
+ let updatedCount = 0;
42139
+ let unchangedCount = 0;
42140
+ let failedCount = 0;
42141
+ for (const entry of entries) {
42142
+ const sourceString = lockSourceToString(entry.source);
42143
+ if (!sourceString) {
42144
+ failedCount++;
42145
+ continue;
42146
+ }
42147
+ try {
42148
+ const result = await skillsManager5.addFromSource(sourceString.source, cwd, {
42149
+ ...sourceString.from ? { from: sourceString.from } : {},
42150
+ agents: entry.agents,
42151
+ global: entry.scope === "global",
42152
+ skills: [name],
42153
+ yes: true
42154
+ });
42155
+ if (result.updated.length > 0 || result.installed.length > 0) {
42156
+ updatedCount++;
42157
+ } else {
42158
+ unchangedCount++;
42159
+ }
42160
+ } catch {
42161
+ failedCount++;
42162
+ }
42163
+ }
42164
+ if (updatedCount > 0) {
42165
+ spinner.succeed(`Updated "${name}" in ${updatedCount} target(s)`);
42166
+ } else {
42167
+ spinner.info(`"${name}" is already up to date`);
42168
+ }
42169
+ if (unchangedCount > 0)
42170
+ logger.info(dim(` ${unchangedCount} unchanged`));
42171
+ if (failedCount > 0)
42172
+ logger.info(red(` ${failedCount} failed`));
42173
+ } else {
42174
+ const entries = await installLock3.getCurrentState({
42175
+ kind: "skill",
42176
+ projectPath: resolve13(cwd),
42177
+ scope: "project"
42178
+ });
42179
+ if (entries.length === 0) {
42180
+ logger.info("No skills tracked in the lockfile for this project.");
42181
+ return;
42182
+ }
42183
+ if (options2.dryRun) {
42184
+ logger.info(`Would update ${entries.length} skill(s):`);
42185
+ for (const entry of entries) {
42186
+ logger.info(` ${green(entry.name)} ${dim(`[${entry.agents.join(", ")}]`)}`);
42187
+ }
42188
+ return;
42189
+ }
42190
+ const spinner = ora("Updating all skills...").start();
42191
+ let updatedCount = 0;
42192
+ for (const entry of entries) {
42193
+ const sourceString = lockSourceToString(entry.source);
42194
+ if (!sourceString)
42195
+ continue;
42196
+ spinner.text = `Updating "${entry.name}"...`;
42197
+ try {
42198
+ const result = await skillsManager5.addFromSource(sourceString.source, cwd, {
42199
+ ...sourceString.from ? { from: sourceString.from } : {},
42200
+ agents: entry.agents,
42201
+ global: entry.scope === "global",
42202
+ skills: [entry.name],
42203
+ yes: true
42204
+ });
42205
+ if (result.updated.length > 0 || result.installed.length > 0) {
42206
+ updatedCount++;
42207
+ }
42208
+ } catch {
42209
+ }
42210
+ }
42211
+ if (updatedCount > 0) {
42212
+ spinner.succeed(`Updated ${updatedCount} skill(s)`);
42213
+ } else {
42214
+ spinner.info("All skills are up to date");
42215
+ }
42216
+ }
42217
+ }
42218
+ });
41636
42219
  }
42220
+ var lockSourceToString = function(source) {
42221
+ if (source.type === "marketplace" && source.marketplace && source.pluginName) {
42222
+ return { source: source.pluginName, from: source.marketplace };
42223
+ }
42224
+ if (source.type === "github") {
42225
+ if (source.owner && source.repo) {
42226
+ if (source.subpath) {
42227
+ return { source: `${source.owner}/${source.repo}/${source.subpath}` };
42228
+ }
42229
+ return { source: `${source.owner}/${source.repo}` };
42230
+ }
42231
+ if (source.url) {
42232
+ return { source: source.url };
42233
+ }
42234
+ }
42235
+ if (source.type === "local" && source.path) {
42236
+ return { source: source.path };
42237
+ }
42238
+ return null;
42239
+ };
41637
42240
  async function resolveInteractiveSkillTargets(skillsManager5, agentManager9, source, projectPath, options2) {
41638
42241
  let installGlobal = !!options2.global;
41639
42242
  if (!options2.global) {
@@ -41706,6 +42309,24 @@ async function resolveInteractiveSkillTargets(skillsManager5, agentManager9, sou
41706
42309
  }
41707
42310
  return selection;
41708
42311
  }
42312
+ async function resolveInteractiveSkillSelection(skills3) {
42313
+ const response = await promptMultiselect({
42314
+ name: "skills",
42315
+ message: `Select skills to install (${skills3.length} found):`,
42316
+ min: 1,
42317
+ choices: skills3.map((skill) => ({
42318
+ title: skill.name,
42319
+ value: skill.name,
42320
+ description: skill.description,
42321
+ selected: true
42322
+ }))
42323
+ });
42324
+ if (!response.skills || response.skills.length === 0) {
42325
+ logger.info("No skills selected. Aborting.");
42326
+ return { aborted: true };
42327
+ }
42328
+ return { skills: response.skills };
42329
+ }
41709
42330
  async function getDetectedSkillGroups(agentManager9, projectPath, global3) {
41710
42331
  const detectedAgents = (await agentManager9.detectAgents(projectPath)).map((entry) => entry.agent);
41711
42332
  const groups = buildSkillGroups(detectedAgents, projectPath, global3);
@@ -41739,7 +42360,7 @@ var buildSkillGroups = function(agents, projectPath, global3) {
41739
42360
  dirToAgents.set(skillsDir, existing);
41740
42361
  }
41741
42362
  return Array.from(dirToAgents.entries()).map(([dir, groupedAgents]) => {
41742
- const canonicalShared = resolve12(dir) === getCanonicalSkillsDirForScope(projectPath, !!global3) && groupedAgents.every((agent) => agent.getProjectSkillsStandard() === "agents");
42363
+ const canonicalShared = resolve13(dir) === getCanonicalSkillsDirForScope(projectPath, !!global3) && groupedAgents.every((agent) => agent.getProjectSkillsStandard() === "agents");
41743
42364
  return {
41744
42365
  dir,
41745
42366
  displayDir: formatSkillsDir(projectPath, dir),
@@ -41762,7 +42383,7 @@ var prependCanonicalGlobalGroup = function(agentManager9, projectPath, groups) {
41762
42383
  if (sharedAgents.length === 0) {
41763
42384
  return groups;
41764
42385
  }
41765
- const existingCanonicalIndex = groups.findIndex((group) => resolve12(group.dir) === canonicalDir);
42386
+ const existingCanonicalIndex = groups.findIndex((group) => resolve13(group.dir) === canonicalDir);
41766
42387
  if (existingCanonicalIndex >= 0) {
41767
42388
  const existingCanonical = groups[existingCanonicalIndex];
41768
42389
  const remaining = groups.filter((_, index) => index !== existingCanonicalIndex);
@@ -41798,7 +42419,7 @@ var prependCanonicalGlobalGroup = function(agentManager9, projectPath, groups) {
41798
42419
  var formatSkillsDir = function(projectPath, dir) {
41799
42420
  const normalizedDir = dir.replace(/\\/g, "/").replace(/\/?$/, "/");
41800
42421
  const normalizedProjectPath = projectPath.replace(/\\/g, "/");
41801
- const normalizedHome = homedir6().replace(/\\/g, "/");
42422
+ const normalizedHome = homedir7().replace(/\\/g, "/");
41802
42423
  if (normalizedDir.startsWith(`${normalizedProjectPath}/`)) {
41803
42424
  return `${relative7(projectPath, dir).replace(/\\/g, "/").replace(/\/?$/, "/")}`;
41804
42425
  }
@@ -41809,7 +42430,7 @@ var formatSkillsDir = function(projectPath, dir) {
41809
42430
  };
41810
42431
  var formatPromptPath = function(path) {
41811
42432
  const normalizedPath = path.replace(/\\/g, "/").replace(/\/?$/, "/");
41812
- const normalizedHome = homedir6().replace(/\\/g, "/");
42433
+ const normalizedHome = homedir7().replace(/\\/g, "/");
41813
42434
  if (normalizedPath === `${normalizedHome}/`) {
41814
42435
  return "~/";
41815
42436
  }
@@ -41819,10 +42440,10 @@ var formatPromptPath = function(path) {
41819
42440
  return normalizedPath;
41820
42441
  };
41821
42442
  var getCanonicalGlobalSkillsDir = function() {
41822
- return resolve12(homedir6(), ".agents/skills");
42443
+ return resolve13(homedir7(), ".agents/skills");
41823
42444
  };
41824
42445
  var getCanonicalSkillsDirForScope = function(projectPath, global3) {
41825
- return global3 ? getCanonicalGlobalSkillsDir() : resolve12(projectPath, ".agents/skills");
42446
+ return global3 ? getCanonicalGlobalSkillsDir() : resolve13(projectPath, ".agents/skills");
41826
42447
  };
41827
42448
  var getCanonicalGlobalSkillsDisplayPath = function() {
41828
42449
  return formatPromptPath(getCanonicalGlobalSkillsDir());
@@ -41854,7 +42475,11 @@ async function buildSkillGroupPreviewDescription(skillsManager5, group, projectP
41854
42475
  })));
41855
42476
  const unchanged = statuses.filter((entry) => entry.status === "unchanged").map((entry) => entry.skill.name);
41856
42477
  const changed = statuses.filter((entry) => entry.status === "changed").map((entry) => entry.skill.name);
42478
+ const fresh = statuses.filter((entry) => entry.status === "new").map((entry) => entry.skill.name);
41857
42479
  const parts = [];
42480
+ if (fresh.length > 0) {
42481
+ parts.push(`Will install: ${fresh.join(", ")}`);
42482
+ }
41858
42483
  if (unchanged.length > 0) {
41859
42484
  parts.push(`Already up to date: ${unchanged.join(", ")}`);
41860
42485
  }
@@ -42052,8 +42677,11 @@ var displayInstallResult = function(result, spinner, agentManager9, skillsManage
42052
42677
  };
42053
42678
 
42054
42679
  // dist/commands/mcp.js
42680
+ init_colors();
42681
+ init_logger();
42055
42682
  init_mcpFilter();
42056
42683
  init_agentManager();
42684
+ init_installLock();
42057
42685
  var filterMcpArgs = function(args) {
42058
42686
  const filtered = [];
42059
42687
  let i = 0;
@@ -42245,6 +42873,28 @@ var registerAddCommand = function(mcp) {
42245
42873
  logger.info(` ${cyan(server.name)} (${typeLabel}): ${server.url}`);
42246
42874
  }
42247
42875
  });
42876
+ try {
42877
+ const lock = new InstallLock;
42878
+ const lockSource = { type: "local" };
42879
+ for (const plan of plans) {
42880
+ for (const server of plan.servers) {
42881
+ await lock.recordMcp({
42882
+ action: "install",
42883
+ name: server.name,
42884
+ projectPath: cwd,
42885
+ agents: [plan.agent.id],
42886
+ scope: plan.isGlobal ? "global" : "project",
42887
+ source: lockSource,
42888
+ configPath: plan.configPath,
42889
+ serverType: server.type,
42890
+ ...server.command ? { command: server.command } : {},
42891
+ ...server.url ? { url: server.url } : {}
42892
+ });
42893
+ }
42894
+ }
42895
+ } catch (error) {
42896
+ logLockWriteWarning("MCP servers were added successfully", error);
42897
+ }
42248
42898
  }
42249
42899
  } catch (error) {
42250
42900
  spinner.fail("Failed to add MCP servers");
@@ -42338,8 +42988,12 @@ var registerRemoveCommand = function(mcp) {
42338
42988
  }
42339
42989
  let removedCount = 0;
42340
42990
  let failedCount = 0;
42991
+ const removedTargets = [];
42341
42992
  for (const { agent, isGlobal: global3 } of targets) {
42342
42993
  try {
42994
+ const configPath = global3 ? agent.getGlobalMcpPath() : agent.getNativeMcpPath(cwd);
42995
+ const existingServers = global3 ? await agent.getGlobalMCPServers().catch(() => []) : await agent.getMCPServers(cwd).catch(() => []);
42996
+ const existingServer = existingServers.find((server) => server.name.toLowerCase() === name.toLowerCase());
42343
42997
  let removed;
42344
42998
  if (global3) {
42345
42999
  removed = await agent.removeGlobalMCPServer(name);
@@ -42348,6 +43002,14 @@ var registerRemoveCommand = function(mcp) {
42348
43002
  }
42349
43003
  if (removed) {
42350
43004
  removedCount++;
43005
+ if (configPath) {
43006
+ removedTargets.push({
43007
+ agent,
43008
+ isGlobal: global3,
43009
+ configPath,
43010
+ ...existingServer ? { server: existingServer } : {}
43011
+ });
43012
+ }
42351
43013
  logger.info(` ${green("-")} ${agent.name}: removed "${name}"`);
42352
43014
  } else {
42353
43015
  logger.info(` ${yellow("~")} ${agent.name}: "${name}" not found`);
@@ -42359,6 +43021,25 @@ var registerRemoveCommand = function(mcp) {
42359
43021
  }
42360
43022
  if (removedCount > 0) {
42361
43023
  spinner.succeed(`Removed "${name}" from ${removedCount} agent(s)`);
43024
+ try {
43025
+ const lock = new InstallLock;
43026
+ for (const { agent, isGlobal: global3, configPath, server } of removedTargets) {
43027
+ await lock.recordMcp({
43028
+ action: "remove",
43029
+ name,
43030
+ projectPath: cwd,
43031
+ agents: [agent.id],
43032
+ scope: global3 ? "global" : "project",
43033
+ source: { type: "local" },
43034
+ configPath,
43035
+ serverType: server?.type || "stdio",
43036
+ ...server?.command ? { command: server.command } : {},
43037
+ ...server?.url ? { url: server.url } : {}
43038
+ });
43039
+ }
43040
+ } catch (error) {
43041
+ logLockWriteWarning("MCP servers were removed successfully", error);
43042
+ }
42362
43043
  } else if (failedCount > 0) {
42363
43044
  spinner.fail(`Failed to remove "${name}"`);
42364
43045
  } else {
@@ -42547,8 +43228,11 @@ var KNOWN_ADD_OPTIONS = {
42547
43228
  };
42548
43229
 
42549
43230
  // dist/commands/rules.js
43231
+ init_colors();
43232
+ init_logger();
42550
43233
  init_agentManager();
42551
43234
  init_fs();
43235
+ init_installLock();
42552
43236
  var colorizeTokenCount2 = function(tokenCount) {
42553
43237
  if (tokenCount <= TOKEN_COUNT_THRESHOLDS.LOW)
42554
43238
  return green(tokenCount.toString());
@@ -42737,6 +43421,29 @@ function registerRulesCommand(program2) {
42737
43421
  }
42738
43422
  }
42739
43423
  }
43424
+ try {
43425
+ const lock = new InstallLock;
43426
+ for (const { agent, result } of results) {
43427
+ if (!result.success || result.rulesApplied === 0)
43428
+ continue;
43429
+ const sections = result.mergedSections || uniqueSections;
43430
+ for (const section of sections) {
43431
+ await lock.recordRules({
43432
+ action: "install",
43433
+ name: section.templateId,
43434
+ projectPath: cwd,
43435
+ agents: [agent.id],
43436
+ scope: isGlobal ? "global" : "project",
43437
+ source: { type: "local" },
43438
+ configPath: result.configPath || "",
43439
+ templateIds: [section.templateId],
43440
+ ruleCount: section.rules.length
43441
+ });
43442
+ }
43443
+ }
43444
+ } catch (error) {
43445
+ logLockWriteWarning("Rules were applied successfully", error);
43446
+ }
42740
43447
  } catch (error) {
42741
43448
  spinner.fail("Failed to apply rules");
42742
43449
  logger.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
@@ -42799,6 +43506,7 @@ function registerRulesCommand(program2) {
42799
43506
  const agents = await resolveTargetAgents(agentManager11, options2, cwd);
42800
43507
  const spinner = ora("Removing rules...").start();
42801
43508
  let totalRemoved = 0;
43509
+ const removedSections = [];
42802
43510
  try {
42803
43511
  for (const agent of agents) {
42804
43512
  if (!agent.capabilities.rules) {
@@ -42822,6 +43530,9 @@ function registerRulesCommand(program2) {
42822
43530
  const updatedContent = await agent.applyRulesConfig(configPath, buildAppliedRules(remaining), content);
42823
43531
  await writeFile(configPath, updatedContent);
42824
43532
  totalRemoved += removed.length;
43533
+ for (const section of removed) {
43534
+ removedSections.push({ agent, configPath, section });
43535
+ }
42825
43536
  for (const s of removed) {
42826
43537
  logger.info(` ${agent.name}: removed ${green(s.templateName)} (${s.rules.length} rules)`);
42827
43538
  }
@@ -42831,6 +43542,24 @@ function registerRulesCommand(program2) {
42831
43542
  logger.info('Run "agentinit rules list" to see current sections.');
42832
43543
  } else {
42833
43544
  spinner.succeed(`Removed ${totalRemoved} rule section${totalRemoved !== 1 ? "s" : ""}`);
43545
+ try {
43546
+ const lock = new InstallLock;
43547
+ for (const { agent, configPath, section } of removedSections) {
43548
+ await lock.recordRules({
43549
+ action: "remove",
43550
+ name: section.templateId,
43551
+ projectPath: cwd,
43552
+ agents: [agent.id],
43553
+ scope: isGlobal ? "global" : "project",
43554
+ source: { type: "local" },
43555
+ configPath,
43556
+ templateIds: [section.templateId],
43557
+ ruleCount: 0
43558
+ });
43559
+ }
43560
+ } catch (error) {
43561
+ logLockWriteWarning("Rules were removed successfully", error);
43562
+ }
42834
43563
  }
42835
43564
  } catch (error) {
42836
43565
  spinner.fail("Failed to remove rules");
@@ -42842,8 +43571,9 @@ function registerRulesCommand(program2) {
42842
43571
 
42843
43572
  // dist/commands/plugins.js
42844
43573
  var import_prompts4 = __toESM(require_prompts3(), 1);
42845
- import {homedir as homedir7} from "os";
42846
- import {dirname as dirname9, relative as relative8, resolve as resolve13} from "path";
43574
+ import {homedir as homedir8} from "os";
43575
+ import {dirname as dirname10, relative as relative8, resolve as resolve14} from "path";
43576
+ init_logger();
42847
43577
  init_pluginManager();
42848
43578
  init_agentManager();
42849
43579
  init_marketplaceRegistry();
@@ -43385,7 +44115,7 @@ var renderPluginWarnings = function(previewOrResult, projectPath) {
43385
44115
  var renderInstalledComponents = function(result, agentManager12, projectPath) {
43386
44116
  const skillGroups = new Map;
43387
44117
  for (const item of result.skills.installed) {
43388
- const targetDir = dirname9(item.path);
44118
+ const targetDir = dirname10(item.path);
43389
44119
  const existing = skillGroups.get(targetDir) || { agents: new Set, skillNames: new Set };
43390
44120
  existing.agents.add(item.agent);
43391
44121
  existing.skillNames.add(item.name);
@@ -43463,7 +44193,7 @@ var buildGlobalPluginGroups = function(agentManager12, projectPath) {
43463
44193
  compatibleAgentNames: [],
43464
44194
  kind: "native"
43465
44195
  }));
43466
- const canonicalDir = resolve13(homedir7(), ".agents/skills");
44196
+ const canonicalDir = resolve14(homedir8(), ".agents/skills");
43467
44197
  const sharedAgents = agentManager12.getAllAgents().filter((agent) => agent.supportsSkills() && agent.getProjectSkillsStandard() === "agents" && !!agent.getSkillsDir(projectPath, true));
43468
44198
  const claudeGroups = nativeGroups.filter((group) => group.agents.some((agent) => agent.id === "claude"));
43469
44199
  const otherGroups = nativeGroups.filter((group) => !group.agents.some((agent) => agent.id === "claude"));
@@ -43573,7 +44303,161 @@ async function interactiveAgentSelect(pluginManager3, agentManager12, projectPat
43573
44303
  } : undefined;
43574
44304
  }
43575
44305
 
44306
+ // dist/commands/lock.js
44307
+ init_colors();
44308
+ init_logger();
44309
+ init_installLock();
44310
+ import {resolve as resolve15} from "path";
44311
+ var formatTimestamp = function(iso) {
44312
+ const date = new Date(iso);
44313
+ return date.toLocaleDateString("en-US", {
44314
+ month: "short",
44315
+ day: "numeric",
44316
+ year: "numeric"
44317
+ });
44318
+ };
44319
+ var formatKind = function(kind) {
44320
+ switch (kind) {
44321
+ case "skill":
44322
+ return cyan("skill");
44323
+ case "mcp":
44324
+ return yellow("mcp");
44325
+ case "rules":
44326
+ return green("rules");
44327
+ }
44328
+ };
44329
+ var formatSource = function(entry) {
44330
+ const src = entry.source;
44331
+ if (src.type === "marketplace" && src.marketplace) {
44332
+ return `${src.marketplace}/${src.pluginName || ""}`;
44333
+ }
44334
+ if (src.type === "github") {
44335
+ if (src.owner && src.repo) {
44336
+ return src.subpath ? `${src.owner}/${src.repo}/${src.subpath}` : `${src.owner}/${src.repo}`;
44337
+ }
44338
+ return src.url || "github";
44339
+ }
44340
+ if (src.type === "local" && src.path) {
44341
+ return src.path;
44342
+ }
44343
+ return src.type;
44344
+ };
44345
+ function registerLockCommand(program2) {
44346
+ const lock = program2.command("lock").description("View and manage the global install lockfile");
44347
+ lock.command("list").alias("ls").description("List all tracked installations across projects").option("--kind <kind>", "Filter by kind: skill, mcp, rules").option("--project <path>", "Filter by project path").option("--agent <agent>", "Filter by agent ID").option("--scope <scope>", "Filter by scope: project or global").action(async (options2) => {
44348
+ const installLock6 = new InstallLock;
44349
+ const queryOptions = {};
44350
+ if (options2.kind)
44351
+ queryOptions.kind = options2.kind;
44352
+ if (options2.project)
44353
+ queryOptions.projectPath = resolve15(options2.project);
44354
+ if (options2.agent)
44355
+ queryOptions.agent = options2.agent;
44356
+ if (options2.scope)
44357
+ queryOptions.scope = options2.scope;
44358
+ const entries = await installLock6.getCurrentState(queryOptions);
44359
+ if (entries.length === 0) {
44360
+ logger.info("No installations tracked in the lockfile.");
44361
+ logger.info(dim("Install skills, MCPs, or rules to start tracking."));
44362
+ return;
44363
+ }
44364
+ const byProject = new Map;
44365
+ for (const entry of entries) {
44366
+ const key = entry.scope === "global" ? "global" : entry.projectPath;
44367
+ const group = byProject.get(key) || { label: getLockEntryTargetLabel(entry), entries: [] };
44368
+ group.entries.push(entry);
44369
+ byProject.set(key, group);
44370
+ }
44371
+ for (const { label, entries: projectEntries } of byProject.values()) {
44372
+ logger.info(`\n${cyan(label)}`);
44373
+ for (const entry of projectEntries) {
44374
+ const kind = formatKind(entry.kind);
44375
+ const scope = entry.scope === "global" ? dim(" (global)") : "";
44376
+ const agents = dim(`[${entry.agents.join(", ")}]`);
44377
+ const date = dim(formatTimestamp(entry.timestamp));
44378
+ const source = dim(formatSource(entry));
44379
+ logger.info(` ${kind} ${green(entry.name)} ${agents}${scope} ${source} ${date}`);
44380
+ }
44381
+ }
44382
+ logger.info("");
44383
+ logger.info(dim(`${entries.length} installation(s) across ${byProject.size} target(s)`));
44384
+ });
44385
+ lock.command("status").description("Show summary of tracked installations").option("--check-drift", "Check for modified skill files (compares content hashes)").action(async (options2) => {
44386
+ const installLock6 = new InstallLock;
44387
+ const entries = await installLock6.getCurrentState();
44388
+ if (entries.length === 0) {
44389
+ logger.info("No installations tracked in the lockfile.");
44390
+ return;
44391
+ }
44392
+ const projects = new Set(entries.filter((entry) => entry.scope === "project").map((entry) => entry.projectPath));
44393
+ const globalTargets = entries.filter((entry) => entry.scope === "global");
44394
+ const skills3 = entries.filter((e) => e.kind === "skill");
44395
+ const mcps = entries.filter((e) => e.kind === "mcp");
44396
+ const rules = entries.filter((e) => e.kind === "rules");
44397
+ logger.info(`Projects: ${cyan(projects.size.toString())}`);
44398
+ logger.info(`Global targets: ${cyan(globalTargets.length.toString())}`);
44399
+ logger.info(`Skills: ${green(skills3.length.toString())}`);
44400
+ logger.info(`MCPs: ${yellow(mcps.length.toString())}`);
44401
+ logger.info(`Rules: ${green(rules.length.toString())}`);
44402
+ const stale = await installLock6.findStaleProjects();
44403
+ if (stale.length > 0) {
44404
+ logger.info("");
44405
+ logger.info(`${red("Stale projects:")} ${stale.length}`);
44406
+ for (const path of stale) {
44407
+ logger.info(` ${red("x")} ${path}`);
44408
+ }
44409
+ logger.info(dim('Run "agentinit lock prune" to clean up.'));
44410
+ }
44411
+ if (options2.checkDrift) {
44412
+ logger.info("");
44413
+ logger.info("Checking for drift...");
44414
+ let driftCount = 0;
44415
+ let missingCount = 0;
44416
+ for (const entry of skills3) {
44417
+ if (!entry.contentHash)
44418
+ continue;
44419
+ const result = await installLock6.checkDrift(entry);
44420
+ if (result.status === "drift") {
44421
+ driftCount++;
44422
+ logger.info(` ${yellow("~")} ${entry.name} in ${entry.projectPath}`);
44423
+ } else if (result.status === "missing") {
44424
+ missingCount++;
44425
+ logger.info(` ${red("x")} ${entry.name} in ${entry.projectPath} ${dim("(missing)")}`);
44426
+ }
44427
+ }
44428
+ if (driftCount === 0 && missingCount === 0) {
44429
+ logger.info(` ${green("All skills match their installed hashes.")}`);
44430
+ } else {
44431
+ if (driftCount > 0)
44432
+ logger.info(` ${driftCount} skill(s) modified since install`);
44433
+ if (missingCount > 0)
44434
+ logger.info(` ${missingCount} skill(s) missing from disk`);
44435
+ }
44436
+ }
44437
+ });
44438
+ lock.command("prune").description("Remove entries for projects that no longer exist on disk").option("-d, --dry-run", "Show what would be removed without changing the lockfile").action(async (options2) => {
44439
+ const installLock6 = new InstallLock;
44440
+ const stale = await installLock6.findStaleProjects();
44441
+ if (stale.length === 0) {
44442
+ logger.info("No stale projects found. Lockfile is clean.");
44443
+ return;
44444
+ }
44445
+ logger.info(`Found ${stale.length} stale project(s):`);
44446
+ for (const path of stale) {
44447
+ logger.info(` ${red("x")} ${path}`);
44448
+ }
44449
+ if (options2.dryRun) {
44450
+ logger.info(dim(`
44451
+ Dry run \u2014 no changes made.`));
44452
+ return;
44453
+ }
44454
+ const result = await installLock6.pruneStaleEntries();
44455
+ logger.info(`\nRemoved ${result.entriesRemoved} entries for ${result.prunedProjects.length} stale project(s).`);
44456
+ });
44457
+ }
44458
+
43576
44459
  // dist/cli.js
44460
+ init_logger();
43577
44461
  var program2 = new Command;
43578
44462
  program2.name("agentinit").description("A CLI tool for managing and configuring AI coding agents").version("1.0.1");
43579
44463
  registerSkillsCommand(program2);
@@ -43581,6 +44465,7 @@ registerMcpCommand(program2);
43581
44465
  registerRulesCommand(program2);
43582
44466
  registerPluginsCommand(program2);
43583
44467
  registerConfigCommand(program2);
44468
+ registerLockCommand(program2);
43584
44469
  program2.command("init").description("Initialize agents.md configuration for the current project").option("-f, --force", "Overwrite existing configuration").option("-t, --template <template>", "Use specific template (web, cli, library)").action(initCommand);
43585
44470
  program2.command("detect").description("Detect current project stack and existing agent configurations").option("-v, --verbose", "Show detailed detection results").action(detectCommand);
43586
44471
  program2.command("sync").description("Sync agents.md with agent-specific configuration files").option("-a, --agent <agents...>", "Target specific agent(s)").option("-d, --dry-run", "Show what would be changed without making changes").option("-b, --backup", "Create backup before syncing").action(syncCommand);