@skillkit/agents 1.5.0 → 1.6.1

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