@skillkit/agents 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +599 -1
- package/dist/index.js +925 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1101,6 +1101,911 @@ ${skillsXml}
|
|
|
1101
1101
|
}
|
|
1102
1102
|
};
|
|
1103
1103
|
|
|
1104
|
+
// src/features/permissions.ts
|
|
1105
|
+
import { minimatch } from "minimatch";
|
|
1106
|
+
var PermissionManager = class {
|
|
1107
|
+
config;
|
|
1108
|
+
constructor(config) {
|
|
1109
|
+
this.config = config || { default: "ask" };
|
|
1110
|
+
}
|
|
1111
|
+
/**
|
|
1112
|
+
* Set permission configuration
|
|
1113
|
+
*/
|
|
1114
|
+
setConfig(config) {
|
|
1115
|
+
this.config = config;
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Get permission configuration
|
|
1119
|
+
*/
|
|
1120
|
+
getConfig() {
|
|
1121
|
+
return this.config;
|
|
1122
|
+
}
|
|
1123
|
+
/**
|
|
1124
|
+
* Check file access permission
|
|
1125
|
+
*/
|
|
1126
|
+
checkFileAccess(path) {
|
|
1127
|
+
return this.checkPattern(path, this.config.files);
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Check command execution permission
|
|
1131
|
+
*/
|
|
1132
|
+
checkCommandAccess(command) {
|
|
1133
|
+
return this.checkPattern(command, this.config.commands);
|
|
1134
|
+
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Check network access permission
|
|
1137
|
+
*/
|
|
1138
|
+
checkNetworkAccess(url) {
|
|
1139
|
+
return this.checkPattern(url, this.config.network);
|
|
1140
|
+
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Check environment variable access
|
|
1143
|
+
*/
|
|
1144
|
+
checkEnvAccess(varName) {
|
|
1145
|
+
return this.checkPattern(varName, this.config.env);
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Add file permission pattern
|
|
1149
|
+
*/
|
|
1150
|
+
addFilePattern(pattern) {
|
|
1151
|
+
if (!this.config.files) {
|
|
1152
|
+
this.config.files = [];
|
|
1153
|
+
}
|
|
1154
|
+
this.config.files.push(pattern);
|
|
1155
|
+
}
|
|
1156
|
+
/**
|
|
1157
|
+
* Add command permission pattern
|
|
1158
|
+
*/
|
|
1159
|
+
addCommandPattern(pattern) {
|
|
1160
|
+
if (!this.config.commands) {
|
|
1161
|
+
this.config.commands = [];
|
|
1162
|
+
}
|
|
1163
|
+
this.config.commands.push(pattern);
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Check pattern against permission list
|
|
1167
|
+
*/
|
|
1168
|
+
checkPattern(value, patterns) {
|
|
1169
|
+
if (!patterns || patterns.length === 0) {
|
|
1170
|
+
return this.config.default || "ask";
|
|
1171
|
+
}
|
|
1172
|
+
for (const pattern of patterns) {
|
|
1173
|
+
if (this.matchPattern(value, pattern.pattern)) {
|
|
1174
|
+
return pattern.level;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
return this.config.default || "ask";
|
|
1178
|
+
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Match value against pattern (glob-style)
|
|
1181
|
+
*
|
|
1182
|
+
* Uses minimatch for safe glob matching, avoiding ReDoS vulnerabilities.
|
|
1183
|
+
*/
|
|
1184
|
+
matchPattern(value, pattern) {
|
|
1185
|
+
return minimatch(value, pattern, { nocase: true });
|
|
1186
|
+
}
|
|
1187
|
+
/**
|
|
1188
|
+
* Generate OpenCode-compatible permission config
|
|
1189
|
+
*/
|
|
1190
|
+
generateOpenCodeConfig() {
|
|
1191
|
+
const lines = [];
|
|
1192
|
+
lines.push("# Permission Configuration");
|
|
1193
|
+
lines.push("");
|
|
1194
|
+
if (this.config.files && this.config.files.length > 0) {
|
|
1195
|
+
lines.push("## File Access");
|
|
1196
|
+
lines.push("");
|
|
1197
|
+
for (const pattern of this.config.files) {
|
|
1198
|
+
lines.push(`- ${pattern.level}: \`${pattern.pattern}\``);
|
|
1199
|
+
if (pattern.reason) {
|
|
1200
|
+
lines.push(` - Reason: ${pattern.reason}`);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
lines.push("");
|
|
1204
|
+
}
|
|
1205
|
+
if (this.config.commands && this.config.commands.length > 0) {
|
|
1206
|
+
lines.push("## Command Execution");
|
|
1207
|
+
lines.push("");
|
|
1208
|
+
for (const pattern of this.config.commands) {
|
|
1209
|
+
lines.push(`- ${pattern.level}: \`${pattern.pattern}\``);
|
|
1210
|
+
if (pattern.reason) {
|
|
1211
|
+
lines.push(` - Reason: ${pattern.reason}`);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
lines.push("");
|
|
1215
|
+
}
|
|
1216
|
+
if (this.config.network && this.config.network.length > 0) {
|
|
1217
|
+
lines.push("## Network Access");
|
|
1218
|
+
lines.push("");
|
|
1219
|
+
for (const pattern of this.config.network) {
|
|
1220
|
+
lines.push(`- ${pattern.level}: \`${pattern.pattern}\``);
|
|
1221
|
+
if (pattern.reason) {
|
|
1222
|
+
lines.push(` - Reason: ${pattern.reason}`);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
lines.push("");
|
|
1226
|
+
}
|
|
1227
|
+
lines.push(`Default: ${this.config.default || "ask"}`);
|
|
1228
|
+
lines.push("");
|
|
1229
|
+
return lines.join("\n");
|
|
1230
|
+
}
|
|
1231
|
+
/**
|
|
1232
|
+
* Generate SKILL.md metadata for permissions
|
|
1233
|
+
*/
|
|
1234
|
+
generateSkillMetadata() {
|
|
1235
|
+
const metadata = {};
|
|
1236
|
+
if (this.config.files) {
|
|
1237
|
+
metadata.filePermissions = this.config.files.map((p) => ({
|
|
1238
|
+
pattern: p.pattern,
|
|
1239
|
+
level: p.level
|
|
1240
|
+
}));
|
|
1241
|
+
}
|
|
1242
|
+
if (this.config.commands) {
|
|
1243
|
+
metadata.commandPermissions = this.config.commands.map((p) => ({
|
|
1244
|
+
pattern: p.pattern,
|
|
1245
|
+
level: p.level
|
|
1246
|
+
}));
|
|
1247
|
+
}
|
|
1248
|
+
if (this.config.network) {
|
|
1249
|
+
metadata.networkPermissions = this.config.network.map((p) => ({
|
|
1250
|
+
pattern: p.pattern,
|
|
1251
|
+
level: p.level
|
|
1252
|
+
}));
|
|
1253
|
+
}
|
|
1254
|
+
if (this.config.default) {
|
|
1255
|
+
metadata.defaultPermission = this.config.default;
|
|
1256
|
+
}
|
|
1257
|
+
return metadata;
|
|
1258
|
+
}
|
|
1259
|
+
/**
|
|
1260
|
+
* Parse permissions from SKILL.md metadata
|
|
1261
|
+
*/
|
|
1262
|
+
static fromMetadata(metadata) {
|
|
1263
|
+
const config = {};
|
|
1264
|
+
if (metadata.filePermissions && Array.isArray(metadata.filePermissions)) {
|
|
1265
|
+
config.files = metadata.filePermissions;
|
|
1266
|
+
}
|
|
1267
|
+
if (metadata.commandPermissions && Array.isArray(metadata.commandPermissions)) {
|
|
1268
|
+
config.commands = metadata.commandPermissions;
|
|
1269
|
+
}
|
|
1270
|
+
if (metadata.networkPermissions && Array.isArray(metadata.networkPermissions)) {
|
|
1271
|
+
config.network = metadata.networkPermissions;
|
|
1272
|
+
}
|
|
1273
|
+
if (metadata.defaultPermission) {
|
|
1274
|
+
config.default = metadata.defaultPermission;
|
|
1275
|
+
}
|
|
1276
|
+
return config;
|
|
1277
|
+
}
|
|
1278
|
+
/**
|
|
1279
|
+
* Merge two permission configs
|
|
1280
|
+
*/
|
|
1281
|
+
static merge(base, override) {
|
|
1282
|
+
return {
|
|
1283
|
+
files: [...base.files || [], ...override.files || []],
|
|
1284
|
+
commands: [...base.commands || [], ...override.commands || []],
|
|
1285
|
+
network: [...base.network || [], ...override.network || []],
|
|
1286
|
+
env: [...base.env || [], ...override.env || []],
|
|
1287
|
+
default: override.default || base.default
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
};
|
|
1291
|
+
function createPermissionManager(config) {
|
|
1292
|
+
return new PermissionManager(config);
|
|
1293
|
+
}
|
|
1294
|
+
function isAllowed(level) {
|
|
1295
|
+
return level === "allow";
|
|
1296
|
+
}
|
|
1297
|
+
function isDenied(level) {
|
|
1298
|
+
return level === "deny";
|
|
1299
|
+
}
|
|
1300
|
+
function needsConfirmation(level) {
|
|
1301
|
+
return level === "ask";
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
// src/features/globs.ts
|
|
1305
|
+
import { minimatch as minimatch2 } from "minimatch";
|
|
1306
|
+
var GlobMatcher = class {
|
|
1307
|
+
config;
|
|
1308
|
+
includePatterns;
|
|
1309
|
+
excludePatterns;
|
|
1310
|
+
constructor(config) {
|
|
1311
|
+
this.config = config;
|
|
1312
|
+
this.includePatterns = config.include.map((p) => this.patternToRegex(p));
|
|
1313
|
+
this.excludePatterns = (config.exclude || []).map((p) => this.patternToRegex(p));
|
|
1314
|
+
}
|
|
1315
|
+
/**
|
|
1316
|
+
* Check if a file matches the glob patterns
|
|
1317
|
+
*/
|
|
1318
|
+
matches(filePath) {
|
|
1319
|
+
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
1320
|
+
if (!this.config.matchHidden && this.isHiddenFile(normalizedPath)) {
|
|
1321
|
+
return false;
|
|
1322
|
+
}
|
|
1323
|
+
for (const pattern of this.excludePatterns) {
|
|
1324
|
+
if (pattern.test(normalizedPath)) {
|
|
1325
|
+
return false;
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
for (const pattern of this.includePatterns) {
|
|
1329
|
+
if (pattern.test(normalizedPath)) {
|
|
1330
|
+
return true;
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
return false;
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
1336
|
+
* Filter a list of files
|
|
1337
|
+
*/
|
|
1338
|
+
filter(filePaths) {
|
|
1339
|
+
return filePaths.filter((p) => this.matches(p));
|
|
1340
|
+
}
|
|
1341
|
+
/**
|
|
1342
|
+
* Get all include patterns
|
|
1343
|
+
*/
|
|
1344
|
+
getIncludePatterns() {
|
|
1345
|
+
return [...this.config.include];
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Get all exclude patterns
|
|
1349
|
+
*/
|
|
1350
|
+
getExcludePatterns() {
|
|
1351
|
+
return [...this.config.exclude || []];
|
|
1352
|
+
}
|
|
1353
|
+
/**
|
|
1354
|
+
* Add an include pattern
|
|
1355
|
+
*/
|
|
1356
|
+
addInclude(pattern) {
|
|
1357
|
+
this.config.include.push(pattern);
|
|
1358
|
+
this.includePatterns.push(this.patternToRegex(pattern));
|
|
1359
|
+
}
|
|
1360
|
+
/**
|
|
1361
|
+
* Add an exclude pattern
|
|
1362
|
+
*/
|
|
1363
|
+
addExclude(pattern) {
|
|
1364
|
+
if (!this.config.exclude) {
|
|
1365
|
+
this.config.exclude = [];
|
|
1366
|
+
}
|
|
1367
|
+
this.config.exclude.push(pattern);
|
|
1368
|
+
this.excludePatterns.push(this.patternToRegex(pattern));
|
|
1369
|
+
}
|
|
1370
|
+
/**
|
|
1371
|
+
* Convert glob pattern to regex using minimatch
|
|
1372
|
+
*
|
|
1373
|
+
* Uses the battle-tested minimatch library to avoid ReDoS vulnerabilities
|
|
1374
|
+
* and ensure consistent glob matching behavior.
|
|
1375
|
+
*/
|
|
1376
|
+
patternToRegex(pattern) {
|
|
1377
|
+
const isNegated = pattern.startsWith("!");
|
|
1378
|
+
const cleanPattern = isNegated ? pattern.slice(1) : pattern;
|
|
1379
|
+
let adjustedPattern = cleanPattern;
|
|
1380
|
+
if (this.config.matchDirectories && !cleanPattern.endsWith("/**")) {
|
|
1381
|
+
adjustedPattern = cleanPattern.endsWith("/") ? `${cleanPattern}**` : `${cleanPattern}/**`;
|
|
1382
|
+
}
|
|
1383
|
+
const regex = minimatch2.makeRe(adjustedPattern, { dot: this.config.matchHidden });
|
|
1384
|
+
return regex || /(?!)/;
|
|
1385
|
+
}
|
|
1386
|
+
/**
|
|
1387
|
+
* Check if file is hidden (starts with .)
|
|
1388
|
+
*/
|
|
1389
|
+
isHiddenFile(path) {
|
|
1390
|
+
const parts = path.split("/");
|
|
1391
|
+
return parts.some((part) => part.startsWith(".") && part !== "." && part !== "..");
|
|
1392
|
+
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Generate Cursor-compatible globs field
|
|
1395
|
+
*/
|
|
1396
|
+
generateCursorGlobs() {
|
|
1397
|
+
const globs = [...this.config.include];
|
|
1398
|
+
if (this.config.exclude) {
|
|
1399
|
+
for (const pattern of this.config.exclude) {
|
|
1400
|
+
globs.push(`!${pattern}`);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
return globs;
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* Generate MDC frontmatter
|
|
1407
|
+
*/
|
|
1408
|
+
generateMDCFrontmatter() {
|
|
1409
|
+
const globs = this.generateCursorGlobs();
|
|
1410
|
+
return `globs: ${JSON.stringify(globs)}`;
|
|
1411
|
+
}
|
|
1412
|
+
};
|
|
1413
|
+
function createGlobMatcher(config) {
|
|
1414
|
+
return new GlobMatcher(config);
|
|
1415
|
+
}
|
|
1416
|
+
function matchPattern(pattern) {
|
|
1417
|
+
return new GlobMatcher({ include: [pattern] });
|
|
1418
|
+
}
|
|
1419
|
+
function parseGlobsFromMDC(content) {
|
|
1420
|
+
const match = content.match(/globs:\s*(\[.*?\])/s);
|
|
1421
|
+
if (!match) {
|
|
1422
|
+
return null;
|
|
1423
|
+
}
|
|
1424
|
+
try {
|
|
1425
|
+
const patterns = JSON.parse(match[1]);
|
|
1426
|
+
const include = [];
|
|
1427
|
+
const exclude = [];
|
|
1428
|
+
for (const pattern of patterns) {
|
|
1429
|
+
if (pattern.startsWith("!")) {
|
|
1430
|
+
exclude.push(pattern.slice(1));
|
|
1431
|
+
} else {
|
|
1432
|
+
include.push(pattern);
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
return { include, exclude };
|
|
1436
|
+
} catch {
|
|
1437
|
+
return null;
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
var COMMON_PATTERNS = {
|
|
1441
|
+
/** All TypeScript files */
|
|
1442
|
+
typescript: ["**/*.ts", "**/*.tsx"],
|
|
1443
|
+
/** All JavaScript files */
|
|
1444
|
+
javascript: ["**/*.js", "**/*.jsx", "**/*.mjs", "**/*.cjs"],
|
|
1445
|
+
/** All test files */
|
|
1446
|
+
tests: ["**/*.test.*", "**/*.spec.*", "**/__tests__/**"],
|
|
1447
|
+
/** All config files */
|
|
1448
|
+
configs: ["*.config.*", "*rc", "*rc.*", "*.json", "*.yaml", "*.yml"],
|
|
1449
|
+
/** All source files */
|
|
1450
|
+
source: ["src/**/*"],
|
|
1451
|
+
/** All documentation */
|
|
1452
|
+
docs: ["**/*.md", "docs/**/*", "README*"],
|
|
1453
|
+
/** Node modules (usually excluded) */
|
|
1454
|
+
nodeModules: ["**/node_modules/**"],
|
|
1455
|
+
/** Build outputs (usually excluded) */
|
|
1456
|
+
buildOutputs: ["**/dist/**", "**/build/**", "**/.next/**"],
|
|
1457
|
+
/** All files */
|
|
1458
|
+
all: ["**/*"]
|
|
1459
|
+
};
|
|
1460
|
+
function fromCommonPatterns(includeNames, excludeNames) {
|
|
1461
|
+
const include = [];
|
|
1462
|
+
const exclude = [];
|
|
1463
|
+
for (const name of includeNames) {
|
|
1464
|
+
include.push(...COMMON_PATTERNS[name]);
|
|
1465
|
+
}
|
|
1466
|
+
if (excludeNames) {
|
|
1467
|
+
for (const name of excludeNames) {
|
|
1468
|
+
exclude.push(...COMMON_PATTERNS[name]);
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
return { include, exclude };
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
// src/features/bootstrap.ts
|
|
1475
|
+
var DEFAULT_FILE_NAMES = {
|
|
1476
|
+
agents: "AGENTS.md",
|
|
1477
|
+
soul: "SOUL.md",
|
|
1478
|
+
tools: "TOOLS.md",
|
|
1479
|
+
identity: "IDENTITY.md",
|
|
1480
|
+
context: "CONTEXT.md",
|
|
1481
|
+
brief: "BRIEF.md",
|
|
1482
|
+
history: "HISTORY.md"
|
|
1483
|
+
};
|
|
1484
|
+
var BootstrapManager = class {
|
|
1485
|
+
files = /* @__PURE__ */ new Map();
|
|
1486
|
+
/**
|
|
1487
|
+
* Add a bootstrap file
|
|
1488
|
+
*/
|
|
1489
|
+
addFile(file) {
|
|
1490
|
+
this.files.set(file.type, file);
|
|
1491
|
+
}
|
|
1492
|
+
/**
|
|
1493
|
+
* Get a bootstrap file by type
|
|
1494
|
+
*/
|
|
1495
|
+
getFile(type) {
|
|
1496
|
+
return this.files.get(type);
|
|
1497
|
+
}
|
|
1498
|
+
/**
|
|
1499
|
+
* Get all bootstrap files
|
|
1500
|
+
*/
|
|
1501
|
+
getAllFiles() {
|
|
1502
|
+
return Array.from(this.files.values());
|
|
1503
|
+
}
|
|
1504
|
+
/**
|
|
1505
|
+
* Get files sorted by priority
|
|
1506
|
+
*/
|
|
1507
|
+
getFilesByPriority() {
|
|
1508
|
+
return this.getAllFiles().sort((a, b) => (b.priority || 0) - (a.priority || 0));
|
|
1509
|
+
}
|
|
1510
|
+
/**
|
|
1511
|
+
* Remove a bootstrap file
|
|
1512
|
+
*/
|
|
1513
|
+
removeFile(type) {
|
|
1514
|
+
return this.files.delete(type);
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Check if a file type exists
|
|
1518
|
+
*/
|
|
1519
|
+
hasFile(type) {
|
|
1520
|
+
return this.files.has(type);
|
|
1521
|
+
}
|
|
1522
|
+
/**
|
|
1523
|
+
* Create AGENTS.md file
|
|
1524
|
+
*/
|
|
1525
|
+
createAgentsFile(agents) {
|
|
1526
|
+
const lines = [];
|
|
1527
|
+
lines.push("# Agents");
|
|
1528
|
+
lines.push("");
|
|
1529
|
+
lines.push("This file defines the available agents and their capabilities.");
|
|
1530
|
+
lines.push("");
|
|
1531
|
+
for (const agent of agents) {
|
|
1532
|
+
lines.push(`## ${agent.name}`);
|
|
1533
|
+
lines.push("");
|
|
1534
|
+
if (agent.description) {
|
|
1535
|
+
lines.push(agent.description);
|
|
1536
|
+
lines.push("");
|
|
1537
|
+
}
|
|
1538
|
+
if (agent.capabilities && agent.capabilities.length > 0) {
|
|
1539
|
+
lines.push("### Capabilities");
|
|
1540
|
+
lines.push("");
|
|
1541
|
+
for (const cap of agent.capabilities) {
|
|
1542
|
+
lines.push(`- ${cap}`);
|
|
1543
|
+
}
|
|
1544
|
+
lines.push("");
|
|
1545
|
+
}
|
|
1546
|
+
if (agent.constraints && agent.constraints.length > 0) {
|
|
1547
|
+
lines.push("### Constraints");
|
|
1548
|
+
lines.push("");
|
|
1549
|
+
for (const constraint of agent.constraints) {
|
|
1550
|
+
lines.push(`- ${constraint}`);
|
|
1551
|
+
}
|
|
1552
|
+
lines.push("");
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
this.addFile({
|
|
1556
|
+
type: "agents",
|
|
1557
|
+
name: "AGENTS.md",
|
|
1558
|
+
content: lines.join("\n"),
|
|
1559
|
+
priority: 100,
|
|
1560
|
+
required: true
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
/**
|
|
1564
|
+
* Create SOUL.md file
|
|
1565
|
+
*/
|
|
1566
|
+
createSoulFile(soul) {
|
|
1567
|
+
const lines = [];
|
|
1568
|
+
lines.push("# Soul");
|
|
1569
|
+
lines.push("");
|
|
1570
|
+
lines.push("This file defines the personality and behavior of the agent.");
|
|
1571
|
+
lines.push("");
|
|
1572
|
+
if (soul.personality) {
|
|
1573
|
+
lines.push("## Personality");
|
|
1574
|
+
lines.push("");
|
|
1575
|
+
lines.push(soul.personality);
|
|
1576
|
+
lines.push("");
|
|
1577
|
+
}
|
|
1578
|
+
if (soul.values && soul.values.length > 0) {
|
|
1579
|
+
lines.push("## Values");
|
|
1580
|
+
lines.push("");
|
|
1581
|
+
for (const value of soul.values) {
|
|
1582
|
+
lines.push(`- ${value}`);
|
|
1583
|
+
}
|
|
1584
|
+
lines.push("");
|
|
1585
|
+
}
|
|
1586
|
+
if (soul.communication) {
|
|
1587
|
+
lines.push("## Communication Style");
|
|
1588
|
+
lines.push("");
|
|
1589
|
+
lines.push(soul.communication);
|
|
1590
|
+
lines.push("");
|
|
1591
|
+
}
|
|
1592
|
+
if (soul.rules && soul.rules.length > 0) {
|
|
1593
|
+
lines.push("## Rules");
|
|
1594
|
+
lines.push("");
|
|
1595
|
+
for (const rule of soul.rules) {
|
|
1596
|
+
lines.push(`- ${rule}`);
|
|
1597
|
+
}
|
|
1598
|
+
lines.push("");
|
|
1599
|
+
}
|
|
1600
|
+
this.addFile({
|
|
1601
|
+
type: "soul",
|
|
1602
|
+
name: "SOUL.md",
|
|
1603
|
+
content: lines.join("\n"),
|
|
1604
|
+
priority: 90
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1607
|
+
/**
|
|
1608
|
+
* Create TOOLS.md file
|
|
1609
|
+
*/
|
|
1610
|
+
createToolsFile(tools) {
|
|
1611
|
+
const lines = [];
|
|
1612
|
+
lines.push("# Tools");
|
|
1613
|
+
lines.push("");
|
|
1614
|
+
lines.push("This file defines the available tools and their usage.");
|
|
1615
|
+
lines.push("");
|
|
1616
|
+
for (const tool of tools) {
|
|
1617
|
+
lines.push(`## ${tool.name}`);
|
|
1618
|
+
lines.push("");
|
|
1619
|
+
if (tool.description) {
|
|
1620
|
+
lines.push(tool.description);
|
|
1621
|
+
lines.push("");
|
|
1622
|
+
}
|
|
1623
|
+
if (tool.usage) {
|
|
1624
|
+
lines.push("### Usage");
|
|
1625
|
+
lines.push("");
|
|
1626
|
+
lines.push("```");
|
|
1627
|
+
lines.push(tool.usage);
|
|
1628
|
+
lines.push("```");
|
|
1629
|
+
lines.push("");
|
|
1630
|
+
}
|
|
1631
|
+
if (tool.examples && tool.examples.length > 0) {
|
|
1632
|
+
lines.push("### Examples");
|
|
1633
|
+
lines.push("");
|
|
1634
|
+
for (const example of tool.examples) {
|
|
1635
|
+
lines.push(`- ${example}`);
|
|
1636
|
+
}
|
|
1637
|
+
lines.push("");
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
this.addFile({
|
|
1641
|
+
type: "tools",
|
|
1642
|
+
name: "TOOLS.md",
|
|
1643
|
+
content: lines.join("\n"),
|
|
1644
|
+
priority: 80
|
|
1645
|
+
});
|
|
1646
|
+
}
|
|
1647
|
+
/**
|
|
1648
|
+
* Create IDENTITY.md file
|
|
1649
|
+
*/
|
|
1650
|
+
createIdentityFile(identity) {
|
|
1651
|
+
const lines = [];
|
|
1652
|
+
lines.push("# Identity");
|
|
1653
|
+
lines.push("");
|
|
1654
|
+
if (identity.name) {
|
|
1655
|
+
lines.push(`**Name:** ${identity.name}`);
|
|
1656
|
+
lines.push("");
|
|
1657
|
+
}
|
|
1658
|
+
if (identity.role) {
|
|
1659
|
+
lines.push(`**Role:** ${identity.role}`);
|
|
1660
|
+
lines.push("");
|
|
1661
|
+
}
|
|
1662
|
+
if (identity.description) {
|
|
1663
|
+
lines.push("## Description");
|
|
1664
|
+
lines.push("");
|
|
1665
|
+
lines.push(identity.description);
|
|
1666
|
+
lines.push("");
|
|
1667
|
+
}
|
|
1668
|
+
if (identity.expertise && identity.expertise.length > 0) {
|
|
1669
|
+
lines.push("## Expertise");
|
|
1670
|
+
lines.push("");
|
|
1671
|
+
for (const exp of identity.expertise) {
|
|
1672
|
+
lines.push(`- ${exp}`);
|
|
1673
|
+
}
|
|
1674
|
+
lines.push("");
|
|
1675
|
+
}
|
|
1676
|
+
this.addFile({
|
|
1677
|
+
type: "identity",
|
|
1678
|
+
name: "IDENTITY.md",
|
|
1679
|
+
content: lines.join("\n"),
|
|
1680
|
+
priority: 95
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
/**
|
|
1684
|
+
* Create CONTEXT.md file
|
|
1685
|
+
*/
|
|
1686
|
+
createContextFile(context) {
|
|
1687
|
+
const lines = [];
|
|
1688
|
+
lines.push("# Context");
|
|
1689
|
+
lines.push("");
|
|
1690
|
+
if (context.project) {
|
|
1691
|
+
lines.push("## Project");
|
|
1692
|
+
lines.push("");
|
|
1693
|
+
lines.push(context.project);
|
|
1694
|
+
lines.push("");
|
|
1695
|
+
}
|
|
1696
|
+
if (context.techStack && context.techStack.length > 0) {
|
|
1697
|
+
lines.push("## Tech Stack");
|
|
1698
|
+
lines.push("");
|
|
1699
|
+
for (const tech of context.techStack) {
|
|
1700
|
+
lines.push(`- ${tech}`);
|
|
1701
|
+
}
|
|
1702
|
+
lines.push("");
|
|
1703
|
+
}
|
|
1704
|
+
if (context.conventions && context.conventions.length > 0) {
|
|
1705
|
+
lines.push("## Conventions");
|
|
1706
|
+
lines.push("");
|
|
1707
|
+
for (const conv of context.conventions) {
|
|
1708
|
+
lines.push(`- ${conv}`);
|
|
1709
|
+
}
|
|
1710
|
+
lines.push("");
|
|
1711
|
+
}
|
|
1712
|
+
if (context.currentTask) {
|
|
1713
|
+
lines.push("## Current Task");
|
|
1714
|
+
lines.push("");
|
|
1715
|
+
lines.push(context.currentTask);
|
|
1716
|
+
lines.push("");
|
|
1717
|
+
}
|
|
1718
|
+
this.addFile({
|
|
1719
|
+
type: "context",
|
|
1720
|
+
name: "CONTEXT.md",
|
|
1721
|
+
content: lines.join("\n"),
|
|
1722
|
+
priority: 70
|
|
1723
|
+
});
|
|
1724
|
+
}
|
|
1725
|
+
/**
|
|
1726
|
+
* Generate all files as a map
|
|
1727
|
+
*/
|
|
1728
|
+
generateFiles() {
|
|
1729
|
+
const files = /* @__PURE__ */ new Map();
|
|
1730
|
+
for (const file of this.getFilesByPriority()) {
|
|
1731
|
+
files.set(file.name, file.content);
|
|
1732
|
+
}
|
|
1733
|
+
return files;
|
|
1734
|
+
}
|
|
1735
|
+
/**
|
|
1736
|
+
* Generate combined content for agents without file support
|
|
1737
|
+
*/
|
|
1738
|
+
generateCombinedContent() {
|
|
1739
|
+
const lines = [];
|
|
1740
|
+
for (const file of this.getFilesByPriority()) {
|
|
1741
|
+
lines.push(`<!-- ${file.name} -->`);
|
|
1742
|
+
lines.push("");
|
|
1743
|
+
lines.push(file.content);
|
|
1744
|
+
lines.push("");
|
|
1745
|
+
lines.push("---");
|
|
1746
|
+
lines.push("");
|
|
1747
|
+
}
|
|
1748
|
+
return lines.join("\n");
|
|
1749
|
+
}
|
|
1750
|
+
/**
|
|
1751
|
+
* Get default file name for a type
|
|
1752
|
+
*/
|
|
1753
|
+
static getDefaultFileName(type) {
|
|
1754
|
+
return DEFAULT_FILE_NAMES[type];
|
|
1755
|
+
}
|
|
1756
|
+
};
|
|
1757
|
+
function createBootstrapManager() {
|
|
1758
|
+
return new BootstrapManager();
|
|
1759
|
+
}
|
|
1760
|
+
function createBootstrapSet(options) {
|
|
1761
|
+
const manager = new BootstrapManager();
|
|
1762
|
+
if (options.agents) {
|
|
1763
|
+
manager.createAgentsFile(options.agents);
|
|
1764
|
+
}
|
|
1765
|
+
if (options.soul) {
|
|
1766
|
+
manager.createSoulFile(options.soul);
|
|
1767
|
+
}
|
|
1768
|
+
if (options.tools) {
|
|
1769
|
+
manager.createToolsFile(options.tools);
|
|
1770
|
+
}
|
|
1771
|
+
if (options.identity) {
|
|
1772
|
+
manager.createIdentityFile(options.identity);
|
|
1773
|
+
}
|
|
1774
|
+
if (options.context) {
|
|
1775
|
+
manager.createContextFile(options.context);
|
|
1776
|
+
}
|
|
1777
|
+
return manager;
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
// src/features/modes.ts
|
|
1781
|
+
var DEFAULT_MODES = {
|
|
1782
|
+
code: {
|
|
1783
|
+
mode: "code",
|
|
1784
|
+
description: "Code editing and implementation mode",
|
|
1785
|
+
promptPrefix: "You are in code mode. Focus on writing and editing code."
|
|
1786
|
+
},
|
|
1787
|
+
architect: {
|
|
1788
|
+
mode: "architect",
|
|
1789
|
+
description: "Architecture and planning mode",
|
|
1790
|
+
promptPrefix: "You are in architect mode. Focus on system design and planning."
|
|
1791
|
+
},
|
|
1792
|
+
ask: {
|
|
1793
|
+
mode: "ask",
|
|
1794
|
+
description: "Question and answer mode",
|
|
1795
|
+
promptPrefix: "You are in ask mode. Focus on answering questions clearly."
|
|
1796
|
+
},
|
|
1797
|
+
debug: {
|
|
1798
|
+
mode: "debug",
|
|
1799
|
+
description: "Debugging and troubleshooting mode",
|
|
1800
|
+
promptPrefix: "You are in debug mode. Focus on finding and fixing issues."
|
|
1801
|
+
},
|
|
1802
|
+
review: {
|
|
1803
|
+
mode: "review",
|
|
1804
|
+
description: "Code review mode",
|
|
1805
|
+
promptPrefix: "You are in review mode. Focus on reviewing code quality."
|
|
1806
|
+
},
|
|
1807
|
+
test: {
|
|
1808
|
+
mode: "test",
|
|
1809
|
+
description: "Testing mode",
|
|
1810
|
+
promptPrefix: "You are in test mode. Focus on writing and running tests."
|
|
1811
|
+
},
|
|
1812
|
+
docs: {
|
|
1813
|
+
mode: "docs",
|
|
1814
|
+
description: "Documentation mode",
|
|
1815
|
+
promptPrefix: "You are in docs mode. Focus on writing documentation."
|
|
1816
|
+
}
|
|
1817
|
+
};
|
|
1818
|
+
var ModeManager = class {
|
|
1819
|
+
modes = /* @__PURE__ */ new Map();
|
|
1820
|
+
currentMode = "code";
|
|
1821
|
+
modeListeners = /* @__PURE__ */ new Set();
|
|
1822
|
+
constructor(modes) {
|
|
1823
|
+
if (modes) {
|
|
1824
|
+
for (const mode of modes) {
|
|
1825
|
+
this.addMode(mode);
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
/**
|
|
1830
|
+
* Add a mode configuration
|
|
1831
|
+
*/
|
|
1832
|
+
addMode(config) {
|
|
1833
|
+
this.modes.set(config.mode, config);
|
|
1834
|
+
}
|
|
1835
|
+
/**
|
|
1836
|
+
* Get a mode configuration
|
|
1837
|
+
*/
|
|
1838
|
+
getMode(mode) {
|
|
1839
|
+
return this.modes.get(mode);
|
|
1840
|
+
}
|
|
1841
|
+
/**
|
|
1842
|
+
* Get all mode configurations
|
|
1843
|
+
*/
|
|
1844
|
+
getAllModes() {
|
|
1845
|
+
return Array.from(this.modes.values());
|
|
1846
|
+
}
|
|
1847
|
+
/**
|
|
1848
|
+
* Get available mode names
|
|
1849
|
+
*/
|
|
1850
|
+
getAvailableModes() {
|
|
1851
|
+
return Array.from(this.modes.keys());
|
|
1852
|
+
}
|
|
1853
|
+
/**
|
|
1854
|
+
* Set the current mode
|
|
1855
|
+
*/
|
|
1856
|
+
setMode(mode) {
|
|
1857
|
+
const config = this.modes.get(mode);
|
|
1858
|
+
if (!config) {
|
|
1859
|
+
throw new Error(`Mode not configured: ${mode}`);
|
|
1860
|
+
}
|
|
1861
|
+
const previousMode = this.currentMode;
|
|
1862
|
+
this.currentMode = mode;
|
|
1863
|
+
for (const listener of this.modeListeners) {
|
|
1864
|
+
listener(mode, previousMode, config);
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
/**
|
|
1868
|
+
* Get the current mode
|
|
1869
|
+
*/
|
|
1870
|
+
getCurrentMode() {
|
|
1871
|
+
return this.currentMode;
|
|
1872
|
+
}
|
|
1873
|
+
/**
|
|
1874
|
+
* Get current mode configuration
|
|
1875
|
+
*/
|
|
1876
|
+
getCurrentModeConfig() {
|
|
1877
|
+
return this.modes.get(this.currentMode);
|
|
1878
|
+
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Get skills for current mode
|
|
1881
|
+
*/
|
|
1882
|
+
getCurrentSkills() {
|
|
1883
|
+
const config = this.getCurrentModeConfig();
|
|
1884
|
+
return config?.skills || [];
|
|
1885
|
+
}
|
|
1886
|
+
/**
|
|
1887
|
+
* Get tools for current mode
|
|
1888
|
+
*/
|
|
1889
|
+
getCurrentTools() {
|
|
1890
|
+
const config = this.getCurrentModeConfig();
|
|
1891
|
+
return config?.tools || [];
|
|
1892
|
+
}
|
|
1893
|
+
/**
|
|
1894
|
+
* Check if a skill is available in current mode
|
|
1895
|
+
*/
|
|
1896
|
+
isSkillAvailable(skillName) {
|
|
1897
|
+
const skills = this.getCurrentSkills();
|
|
1898
|
+
return skills.length === 0 || skills.includes(skillName);
|
|
1899
|
+
}
|
|
1900
|
+
/**
|
|
1901
|
+
* Check if a file is allowed in current mode
|
|
1902
|
+
*/
|
|
1903
|
+
isFileAllowed(filePath) {
|
|
1904
|
+
const config = this.getCurrentModeConfig();
|
|
1905
|
+
if (!config?.allowedFiles || config.allowedFiles.length === 0) {
|
|
1906
|
+
return true;
|
|
1907
|
+
}
|
|
1908
|
+
const matcher = new GlobMatcher({ include: config.allowedFiles });
|
|
1909
|
+
return matcher.matches(filePath);
|
|
1910
|
+
}
|
|
1911
|
+
/**
|
|
1912
|
+
* Add mode change listener
|
|
1913
|
+
*/
|
|
1914
|
+
addModeListener(listener) {
|
|
1915
|
+
this.modeListeners.add(listener);
|
|
1916
|
+
}
|
|
1917
|
+
/**
|
|
1918
|
+
* Remove mode change listener
|
|
1919
|
+
*/
|
|
1920
|
+
removeModeListener(listener) {
|
|
1921
|
+
this.modeListeners.delete(listener);
|
|
1922
|
+
}
|
|
1923
|
+
/**
|
|
1924
|
+
* Create a mode from default configuration
|
|
1925
|
+
*/
|
|
1926
|
+
addDefaultMode(mode, skills) {
|
|
1927
|
+
const defaultConfig = DEFAULT_MODES[mode];
|
|
1928
|
+
this.addMode({
|
|
1929
|
+
...defaultConfig,
|
|
1930
|
+
skills
|
|
1931
|
+
});
|
|
1932
|
+
}
|
|
1933
|
+
/**
|
|
1934
|
+
* Generate mode-specific prompt prefix
|
|
1935
|
+
*/
|
|
1936
|
+
getPromptPrefix() {
|
|
1937
|
+
const config = this.getCurrentModeConfig();
|
|
1938
|
+
return config?.promptPrefix || "";
|
|
1939
|
+
}
|
|
1940
|
+
/**
|
|
1941
|
+
* Generate Roo-compatible mode configuration
|
|
1942
|
+
*/
|
|
1943
|
+
generateRooConfig() {
|
|
1944
|
+
const modes = {};
|
|
1945
|
+
for (const config of this.modes.values()) {
|
|
1946
|
+
modes[config.mode] = {
|
|
1947
|
+
description: config.description,
|
|
1948
|
+
skills: config.skills,
|
|
1949
|
+
tools: config.tools,
|
|
1950
|
+
promptPrefix: config.promptPrefix
|
|
1951
|
+
};
|
|
1952
|
+
}
|
|
1953
|
+
return {
|
|
1954
|
+
defaultMode: this.currentMode,
|
|
1955
|
+
modes
|
|
1956
|
+
};
|
|
1957
|
+
}
|
|
1958
|
+
/**
|
|
1959
|
+
* Generate mode documentation
|
|
1960
|
+
*/
|
|
1961
|
+
generateModeDocumentation() {
|
|
1962
|
+
const lines = [];
|
|
1963
|
+
lines.push("# Available Modes");
|
|
1964
|
+
lines.push("");
|
|
1965
|
+
for (const config of this.modes.values()) {
|
|
1966
|
+
lines.push(`## ${config.mode}`);
|
|
1967
|
+
lines.push("");
|
|
1968
|
+
lines.push(config.description);
|
|
1969
|
+
lines.push("");
|
|
1970
|
+
if (config.skills.length > 0) {
|
|
1971
|
+
lines.push("### Skills");
|
|
1972
|
+
lines.push("");
|
|
1973
|
+
for (const skill of config.skills) {
|
|
1974
|
+
lines.push(`- ${skill}`);
|
|
1975
|
+
}
|
|
1976
|
+
lines.push("");
|
|
1977
|
+
}
|
|
1978
|
+
if (config.tools && config.tools.length > 0) {
|
|
1979
|
+
lines.push("### Tools");
|
|
1980
|
+
lines.push("");
|
|
1981
|
+
for (const tool of config.tools) {
|
|
1982
|
+
lines.push(`- ${tool}`);
|
|
1983
|
+
}
|
|
1984
|
+
lines.push("");
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
return lines.join("\n");
|
|
1988
|
+
}
|
|
1989
|
+
};
|
|
1990
|
+
function createModeManager(modes) {
|
|
1991
|
+
return new ModeManager(modes);
|
|
1992
|
+
}
|
|
1993
|
+
function createDefaultModeManager(skillsPerMode) {
|
|
1994
|
+
const manager = new ModeManager();
|
|
1995
|
+
for (const [mode, config] of Object.entries(DEFAULT_MODES)) {
|
|
1996
|
+
const skills = skillsPerMode[mode] || [];
|
|
1997
|
+
manager.addMode({
|
|
1998
|
+
...config,
|
|
1999
|
+
skills
|
|
2000
|
+
});
|
|
2001
|
+
}
|
|
2002
|
+
return manager;
|
|
2003
|
+
}
|
|
2004
|
+
function getDefaultModeConfig(mode) {
|
|
2005
|
+
return DEFAULT_MODES[mode];
|
|
2006
|
+
}
|
|
2007
|
+
var ALL_MODES = ["code", "architect", "ask", "debug", "review", "test", "docs"];
|
|
2008
|
+
|
|
1104
2009
|
// src/index.ts
|
|
1105
2010
|
var adapters = {
|
|
1106
2011
|
"claude-code": new ClaudeCodeAdapter(),
|
|
@@ -1162,8 +2067,11 @@ function getConfigFile(type) {
|
|
|
1162
2067
|
return adapters[type].configFile;
|
|
1163
2068
|
}
|
|
1164
2069
|
export {
|
|
2070
|
+
ALL_MODES,
|
|
1165
2071
|
AmpAdapter,
|
|
1166
2072
|
AntigravityAdapter,
|
|
2073
|
+
BootstrapManager,
|
|
2074
|
+
COMMON_PATTERNS,
|
|
1167
2075
|
ClaudeCodeAdapter,
|
|
1168
2076
|
ClawdbotAdapter,
|
|
1169
2077
|
CodexAdapter,
|
|
@@ -1171,20 +2079,36 @@ export {
|
|
|
1171
2079
|
DroidAdapter,
|
|
1172
2080
|
GeminiCliAdapter,
|
|
1173
2081
|
GitHubCopilotAdapter,
|
|
2082
|
+
GlobMatcher,
|
|
1174
2083
|
GooseAdapter,
|
|
1175
2084
|
KiloAdapter,
|
|
1176
2085
|
KiroCliAdapter,
|
|
2086
|
+
ModeManager,
|
|
1177
2087
|
OpenCodeAdapter,
|
|
2088
|
+
PermissionManager,
|
|
1178
2089
|
RooAdapter,
|
|
1179
2090
|
TraeAdapter,
|
|
1180
2091
|
UniversalAdapter,
|
|
1181
2092
|
WindsurfAdapter,
|
|
2093
|
+
createBootstrapManager,
|
|
2094
|
+
createBootstrapSet,
|
|
2095
|
+
createDefaultModeManager,
|
|
2096
|
+
createGlobMatcher,
|
|
2097
|
+
createModeManager,
|
|
2098
|
+
createPermissionManager,
|
|
1182
2099
|
createSkillXml,
|
|
1183
2100
|
detectAgent,
|
|
1184
2101
|
escapeXml,
|
|
2102
|
+
fromCommonPatterns,
|
|
1185
2103
|
getAdapter,
|
|
1186
2104
|
getAllAdapters,
|
|
1187
2105
|
getConfigFile,
|
|
1188
|
-
|
|
2106
|
+
getDefaultModeConfig,
|
|
2107
|
+
getSkillsDir,
|
|
2108
|
+
isAllowed,
|
|
2109
|
+
isDenied,
|
|
2110
|
+
matchPattern,
|
|
2111
|
+
needsConfirmation,
|
|
2112
|
+
parseGlobsFromMDC
|
|
1189
2113
|
};
|
|
1190
2114
|
//# sourceMappingURL=index.js.map
|