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/CHANGELOG.md +24 -0
- package/README.md +30 -2
- package/dist/cli.js +1327 -442
- package/dist/cli.js.map +1 -1
- package/dist/commands/lock.d.ts +3 -0
- package/dist/commands/lock.d.ts.map +1 -0
- package/dist/commands/lock.js +172 -0
- package/dist/commands/lock.js.map +1 -0
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +60 -0
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/rules.d.ts.map +1 -1
- package/dist/commands/rules.js +50 -0
- package/dist/commands/rules.js.map +1 -1
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +283 -6
- package/dist/commands/skills.js.map +1 -1
- package/dist/core/installLock.d.ts +54 -0
- package/dist/core/installLock.d.ts.map +1 -0
- package/dist/core/installLock.js +274 -0
- package/dist/core/installLock.js.map +1 -0
- package/dist/core/skillsManager.d.ts +1 -0
- package/dist/core/skillsManager.d.ts.map +1 -1
- package/dist/core/skillsManager.js +87 -4
- package/dist/core/skillsManager.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lockfile.d.ts +67 -0
- package/dist/types/lockfile.d.ts.map +1 -0
- package/dist/types/lockfile.js +2 -0
- package/dist/types/lockfile.js.map +1 -0
- package/package.json +1 -1
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
|
|
17070
|
-
import {promises as
|
|
17071
|
-
import {homedir as
|
|
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
|
|
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 =
|
|
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 =
|
|
17229
|
-
const relativePath = relative2(
|
|
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 =
|
|
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(
|
|
17342
|
-
(async () => !!manifest.hooks || await isDirectory(
|
|
17343
|
-
(async () => !!manifest.agents || await isDirectory(
|
|
17344
|
-
isDirectory(
|
|
17345
|
-
(async () => !!manifest.mcpServers || await fileExists(
|
|
17346
|
-
isDirectory(
|
|
17347
|
-
isDirectory(
|
|
17348
|
-
isDirectory(
|
|
17349
|
-
isDirectory(
|
|
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(
|
|
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:
|
|
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 =
|
|
17878
|
+
let currentDir = resolve8(pluginDir);
|
|
17452
17879
|
while (true) {
|
|
17453
|
-
if (await fileExists(
|
|
17880
|
+
if (await fileExists(join5(currentDir, ".claude-plugin", "marketplace.json"))) {
|
|
17454
17881
|
return currentDir;
|
|
17455
17882
|
}
|
|
17456
|
-
const parentDir =
|
|
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(
|
|
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
|
|
17484
|
-
await writeFile(
|
|
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 =
|
|
17488
|
-
const relativePathFromBase = relative2(
|
|
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(
|
|
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 =
|
|
17512
|
-
await
|
|
17513
|
-
await
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
18046
|
+
await fs24.rm(nativeTarget.installPath, { recursive: true, force: true }).catch(() => {
|
|
17620
18047
|
});
|
|
17621
|
-
await
|
|
17622
|
-
await
|
|
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
|
|
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
|
|
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 =
|
|
17719
|
-
await
|
|
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
|
|
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 =
|
|
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(
|
|
18233
|
+
if (await fileExists(join5(cacheDir, ".git"))) {
|
|
17807
18234
|
const originUrl = await this.getMarketplaceCacheOriginUrl(cacheDir);
|
|
17808
18235
|
if (originUrl !== registry.repoUrl) {
|
|
17809
|
-
await
|
|
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
|
|
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
|
|
17826
|
-
await
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
18332
|
+
const entryPath = join5(fullDir, entry);
|
|
17906
18333
|
if (!await isDirectory(entryPath))
|
|
17907
18334
|
continue;
|
|
17908
|
-
const manifestPath =
|
|
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
|
|
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 =
|
|
18348
|
+
const skillMdPath = join5(entryPath, "SKILL.md");
|
|
17922
18349
|
if (await fileExists(skillMdPath)) {
|
|
17923
18350
|
try {
|
|
17924
|
-
const parsed = import_gray_matter.default(await
|
|
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 =
|
|
18359
|
+
const mcpPath = join5(entryPath, ".mcp.json");
|
|
17933
18360
|
if (await fileExists(mcpPath)) {
|
|
17934
18361
|
try {
|
|
17935
|
-
const mcpConfig = JSON.parse(await
|
|
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(
|
|
18384
|
+
if (await fileExists(join5(pluginDir, ".claude-plugin", "plugin.json"))) {
|
|
17958
18385
|
return "claude";
|
|
17959
18386
|
}
|
|
17960
|
-
if (await fileExists(
|
|
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 =
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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(
|
|
18516
|
+
commandsDirs.push(resolve8(pluginDir, cmd));
|
|
18090
18517
|
}
|
|
18091
18518
|
} else {
|
|
18092
|
-
commandsDirs.push(
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
18957
|
+
return join5(homedir5(), ".agentinit", "marketplace-cache", registryId);
|
|
18531
18958
|
};
|
|
18532
18959
|
getRegistryPath = function(projectPath, global3) {
|
|
18533
18960
|
if (global3) {
|
|
18534
|
-
return
|
|
18961
|
+
return join5(homedir5(), ".agentinit", "plugins.json");
|
|
18535
18962
|
}
|
|
18536
|
-
return
|
|
18963
|
+
return join5(projectPath, ".agentinit", "plugins.json");
|
|
18537
18964
|
};
|
|
18538
18965
|
getClaudeInstalledPluginsPath = function() {
|
|
18539
|
-
return
|
|
18966
|
+
return join5(homedir5(), ".claude", "plugins", "installed_plugins.json");
|
|
18540
18967
|
};
|
|
18541
18968
|
getClaudeKnownMarketplacesPath = function() {
|
|
18542
|
-
return
|
|
18969
|
+
return join5(homedir5(), ".claude", "plugins", "known_marketplaces.json");
|
|
18543
18970
|
};
|
|
18544
18971
|
getClaudeMarketplaceInstallPath = function(namespace) {
|
|
18545
|
-
return
|
|
18972
|
+
return join5(homedir5(), ".claude", "plugins", "marketplaces", namespace);
|
|
18546
18973
|
};
|
|
18547
18974
|
getClaudeSettingsPath = function() {
|
|
18548
|
-
return
|
|
18975
|
+
return join5(homedir5(), ".claude", "settings.json");
|
|
18549
18976
|
};
|
|
18550
18977
|
});
|
|
18551
18978
|
|
|
18552
18979
|
// dist/core/skillsManager.js
|
|
18553
|
-
import {resolve as
|
|
18554
|
-
import {promises as
|
|
18555
|
-
import {homedir as
|
|
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 =
|
|
19135
|
+
const fullDir = resolve9(repoPath, searchDir);
|
|
18709
19136
|
if (!await fileExists(fullDir))
|
|
18710
19137
|
continue;
|
|
18711
|
-
const directSkillMd =
|
|
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:
|
|
19143
|
+
skills2.push({ ...parsed, path: resolve9(fullDir) });
|
|
18717
19144
|
}
|
|
18718
19145
|
}
|
|
18719
|
-
const directSkillMdLower =
|
|
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:
|
|
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 =
|
|
19158
|
+
const entryPath = join6(fullDir, entry);
|
|
18732
19159
|
if (!await isDirectory(entryPath))
|
|
18733
19160
|
continue;
|
|
18734
|
-
const skillMdPath =
|
|
18735
|
-
const skillMdPathLower =
|
|
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
|
|
18750
|
-
await
|
|
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
|
|
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
|
|
19241
|
+
await fs26.rm(tempDir, { recursive: true, force: true }).catch(() => {
|
|
18815
19242
|
});
|
|
18816
19243
|
}
|
|
18817
19244
|
async resolveDiscoveryRoot(repoPath, source, sourceLabel) {
|
|
18818
|
-
const resolvedRepoPath =
|
|
19245
|
+
const resolvedRepoPath = resolve9(repoPath);
|
|
18819
19246
|
if (source.type !== "github" || !source.subpath) {
|
|
18820
19247
|
return resolvedRepoPath;
|
|
18821
19248
|
}
|
|
18822
|
-
const discoveryRoot =
|
|
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
|
|
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 =
|
|
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
|
|
19385
|
+
await fs26.mkdir(resolve9(targetDir), { recursive: true });
|
|
18959
19386
|
if (await fileExists(destPath)) {
|
|
18960
|
-
await
|
|
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
|
|
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
|
|
19399
|
+
await fs26.mkdir(resolve9(targetDir), { recursive: true });
|
|
18973
19400
|
if (await fileExists(destPath)) {
|
|
18974
|
-
await
|
|
19401
|
+
await fs26.rm(destPath, { recursive: true, force: true });
|
|
18975
19402
|
}
|
|
18976
|
-
await
|
|
18977
|
-
await
|
|
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 ?
|
|
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.
|
|
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
|
|
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
|
|
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 =
|
|
19118
|
-
const destPath =
|
|
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 =
|
|
19563
|
+
const hash = createHash2("sha256");
|
|
19137
19564
|
const walk = async (currentPath, relativePath) => {
|
|
19138
|
-
const stat = await
|
|
19565
|
+
const stat = await fs26.stat(currentPath);
|
|
19139
19566
|
if (!stat.isDirectory()) {
|
|
19140
|
-
const content = await
|
|
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
|
|
19572
|
+
const entries = (await fs26.readdir(currentPath)).sort((left, right) => left.localeCompare(right));
|
|
19146
19573
|
for (const entry of entries) {
|
|
19147
|
-
await walk(
|
|
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 =
|
|
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
|
|
19619
|
+
await fs26.rm(path, { recursive: true, force: true }).catch(() => {
|
|
19176
19620
|
});
|
|
19177
|
-
await
|
|
19621
|
+
await fs26.mkdir(path, { recursive: true });
|
|
19178
19622
|
}
|
|
19179
19623
|
isWithinPath(basePath, targetPath) {
|
|
19180
|
-
const relativePath = relative3(
|
|
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
|
|
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.
|
|
19707
|
+
const comparisonPath = plan.path;
|
|
19264
19708
|
let comparison = comparisonCache.get(comparisonPath);
|
|
19265
19709
|
if (comparison === undefined) {
|
|
19266
|
-
comparison = await this.
|
|
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 =
|
|
19818
|
+
const entryPath = join6(dir, entry);
|
|
19338
19819
|
if (!await isDirectory(entryPath))
|
|
19339
19820
|
continue;
|
|
19340
|
-
const skillMdPath =
|
|
19341
|
-
const skillMdPathLower =
|
|
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
|
|
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 =
|
|
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) =>
|
|
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 =
|
|
19869
|
+
const entryPath = join6(canonicalDir, entry);
|
|
19389
19870
|
if (!await isDirectory(entryPath))
|
|
19390
19871
|
continue;
|
|
19391
|
-
const resolvedEntryPath =
|
|
19872
|
+
const resolvedEntryPath = resolve9(entryPath);
|
|
19392
19873
|
if (referencedCanonicalPaths.has(resolvedEntryPath))
|
|
19393
19874
|
continue;
|
|
19394
|
-
const skillMdPath =
|
|
19395
|
-
const skillMdPathLower =
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
21279
|
-
|
|
21280
|
-
|
|
21281
|
-
|
|
21282
|
-
|
|
21283
|
-
|
|
21284
|
-
|
|
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 =
|
|
21316
|
-
this.missingSchema =
|
|
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
|
|
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:
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 ==
|
|
25994
|
+
if (willValidate && !(recursiveMeta = id && id == resolve13.normalizeId(schema2.$schema)))
|
|
25489
25995
|
this.validateSchema(schema2, true);
|
|
25490
|
-
var localRefs =
|
|
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
|
|
25638
|
-
if (
|
|
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 (
|
|
25642
|
-
|
|
25643
|
-
if (!(typeof
|
|
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 =
|
|
26151
|
+
self.logger = logger6;
|
|
25646
26152
|
}
|
|
25647
26153
|
};
|
|
25648
26154
|
var noop = function() {
|
|
25649
26155
|
};
|
|
25650
26156
|
var compileSchema = require_compile();
|
|
25651
|
-
var
|
|
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
|
-
|
|
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(
|
|
26223
|
+
return checkStat(fs33.statSync(path), path, options2);
|
|
25718
26224
|
};
|
|
25719
26225
|
module.exports = isexe;
|
|
25720
26226
|
isexe.sync = sync;
|
|
25721
|
-
var
|
|
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
|
-
|
|
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(
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
|
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((
|
|
26348
|
+
const step = (i) => new Promise((resolve13, reject) => {
|
|
25843
26349
|
if (i === pathEnv.length)
|
|
25844
|
-
return opt.all && found.length ?
|
|
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
|
-
|
|
26355
|
+
resolve13(subStep(p, i, 0));
|
|
25850
26356
|
});
|
|
25851
|
-
const subStep = (p, i, ii) => new Promise((
|
|
26357
|
+
const subStep = (p, i, ii) => new Promise((resolve13, reject) => {
|
|
25852
26358
|
if (ii === pathExt.length)
|
|
25853
|
-
return
|
|
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
|
|
26366
|
+
return resolve13(p + ext);
|
|
25861
26367
|
}
|
|
25862
|
-
return
|
|
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 =
|
|
26005
|
-
|
|
26006
|
-
|
|
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
|
|
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
|
|
28346
|
-
import {resolve as
|
|
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 =
|
|
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 =
|
|
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
|
|
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:
|
|
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
|
|
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(
|
|
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 =
|
|
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
|
|
31322
|
-
import {dirname as
|
|
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
|
|
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
|
|
31339
|
-
const entries = await
|
|
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 =
|
|
31342
|
-
const destPath =
|
|
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
|
|
31347
|
-
await
|
|
31348
|
-
await
|
|
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
|
|
31351
|
-
await
|
|
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
|
|
31720
|
+
await fs30.mkdir(dirname5(dest), { recursive: true });
|
|
31361
31721
|
if (type2 === "symlink") {
|
|
31362
|
-
const target = await
|
|
31363
|
-
await
|
|
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
|
|
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 =
|
|
31382
|
-
const statePath =
|
|
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
|
|
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
|
|
31756
|
+
return join7(this.projectPath, ".agentinit");
|
|
31397
31757
|
}
|
|
31398
31758
|
get stateFilePath() {
|
|
31399
|
-
return
|
|
31759
|
+
return join7(this.agentInitDir, MANAGED_STATE_FILE);
|
|
31400
31760
|
}
|
|
31401
31761
|
get backupsDir() {
|
|
31402
|
-
return
|
|
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,
|
|
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
|
|
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 =
|
|
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
|
|
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
|
-
|
|
31832
|
+
paths6.add(entry.ignorePath);
|
|
31473
31833
|
}
|
|
31474
31834
|
}
|
|
31475
|
-
return [...
|
|
31835
|
+
return [...paths6];
|
|
31476
31836
|
}
|
|
31477
31837
|
async save() {
|
|
31478
|
-
await
|
|
31479
|
-
await
|
|
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 =
|
|
31490
|
-
const backupPath = entry.backupPath ?
|
|
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
|
|
31854
|
+
await fs30.rm(absolutePath, { recursive: true, force: true }).catch(() => {
|
|
31495
31855
|
});
|
|
31496
|
-
await
|
|
31497
|
-
await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
31884
|
+
await fs30.rm(this.stateFilePath, { force: true }).catch(() => {
|
|
31525
31885
|
});
|
|
31526
31886
|
if (!options2.keepBackups) {
|
|
31527
|
-
await
|
|
31887
|
+
await fs30.rm(this.backupsDir, { recursive: true, force: true }).catch(() => {
|
|
31528
31888
|
});
|
|
31529
31889
|
}
|
|
31530
31890
|
try {
|
|
31531
|
-
const remainingEntries = await
|
|
31891
|
+
const remainingEntries = await fs30.readdir(this.agentInitDir);
|
|
31532
31892
|
if (remainingEntries.length === 0) {
|
|
31533
|
-
await
|
|
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
|
|
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 =
|
|
31883
|
-
const packageJsonPath =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
38384
|
+
resolve13();
|
|
38023
38385
|
} else {
|
|
38024
|
-
this._process.stdin.once("drain",
|
|
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((
|
|
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(
|
|
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
|
-
|
|
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
|
|
40154
|
-
import {dirname as
|
|
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,
|
|
40201
|
-
const ignoreFile = options2.local ?
|
|
40202
|
-
const ignoreFilePath =
|
|
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 =
|
|
40569
|
+
const gitDir = join9(projectPath, ".git");
|
|
40205
40570
|
try {
|
|
40206
|
-
const stat = await
|
|
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(
|
|
40579
|
+
const normalizedPaths = [...new Set(paths6.map((path) => normalizeIgnorePath(projectPath, path)).filter(Boolean))].sort();
|
|
40215
40580
|
let existingContent = "";
|
|
40216
40581
|
try {
|
|
40217
|
-
existingContent = await
|
|
40582
|
+
existingContent = await fs33.readFile(ignoreFilePath, "utf8");
|
|
40218
40583
|
} catch {
|
|
40219
40584
|
existingContent = "";
|
|
40220
40585
|
}
|
|
40221
40586
|
const updatedContent = updateManagedBlock(existingContent, normalizedPaths);
|
|
40222
|
-
await
|
|
40223
|
-
await
|
|
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 ?
|
|
40228
|
-
const ignoreFilePath =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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: `${
|
|
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
|
-
|
|
41352
|
-
|
|
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
|
|
41505
|
-
const filteredPreviewSkills =
|
|
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
|
-
...
|
|
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 =
|
|
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) =>
|
|
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 =
|
|
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 =
|
|
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
|
|
42443
|
+
return resolve13(homedir7(), ".agents/skills");
|
|
41823
42444
|
};
|
|
41824
42445
|
var getCanonicalSkillsDirForScope = function(projectPath, global3) {
|
|
41825
|
-
return global3 ? getCanonicalGlobalSkillsDir() :
|
|
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
|
|
42846
|
-
import {dirname as
|
|
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 =
|
|
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 =
|
|
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);
|