@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.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
- getSkillsDir
2106
+ getDefaultModeConfig,
2107
+ getSkillsDir,
2108
+ isAllowed,
2109
+ isDenied,
2110
+ matchPattern,
2111
+ needsConfirmation,
2112
+ parseGlobsFromMDC
1189
2113
  };
1190
2114
  //# sourceMappingURL=index.js.map