skill-tree 0.1.7 → 0.2.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.
@@ -9,11 +9,25 @@ var __export = (target, all) => {
9
9
  __defProp(target, name, { get: all[name], enumerable: true });
10
10
  };
11
11
 
12
+ // node_modules/tsup/assets/esm_shims.js
13
+ import path from "path";
14
+ import { fileURLToPath } from "url";
15
+ var getFilename, getDirname, __dirname;
16
+ var init_esm_shims = __esm({
17
+ "node_modules/tsup/assets/esm_shims.js"() {
18
+ "use strict";
19
+ getFilename = () => fileURLToPath(import.meta.url);
20
+ getDirname = () => path.dirname(getFilename());
21
+ __dirname = /* @__PURE__ */ getDirname();
22
+ }
23
+ });
24
+
12
25
  // src/storage/base.ts
13
26
  var BaseStorageAdapter, MemoryStorageAdapter;
14
27
  var init_base = __esm({
15
28
  "src/storage/base.ts"() {
16
29
  "use strict";
30
+ init_esm_shims();
17
31
  BaseStorageAdapter = class {
18
32
  constructor() {
19
33
  this.initialized = false;
@@ -42,9 +56,6 @@ var init_base = __esm({
42
56
  if (filter.author && skill.author !== filter.author) {
43
57
  return false;
44
58
  }
45
- if (filter.minSuccessRate !== void 0 && skill.metrics.successRate < filter.minSuccessRate) {
46
- return false;
47
- }
48
59
  if (filter.createdAfter && skill.createdAt < filter.createdAfter) {
49
60
  return false;
50
61
  }
@@ -283,12 +294,13 @@ __export(sqlite_exports, {
283
294
  SQLiteStorageAdapter: () => SQLiteStorageAdapter
284
295
  });
285
296
  import Database from "better-sqlite3";
286
- import * as path7 from "path";
297
+ import * as path8 from "path";
287
298
  import * as fs7 from "fs";
288
299
  var SCHEMA_VERSION, SQLiteStorageAdapter;
289
300
  var init_sqlite = __esm({
290
301
  "src/storage/sqlite.ts"() {
291
302
  "use strict";
303
+ init_esm_shims();
292
304
  init_base();
293
305
  SCHEMA_VERSION = 3;
294
306
  SQLiteStorageAdapter = class extends BaseStorageAdapter {
@@ -302,7 +314,7 @@ var init_sqlite = __esm({
302
314
  };
303
315
  }
304
316
  async initialize() {
305
- const dir = path7.dirname(this.config.dbPath);
317
+ const dir = path8.dirname(this.config.dbPath);
306
318
  if (dir && !fs7.existsSync(dir)) {
307
319
  fs7.mkdirSync(dir, { recursive: true });
308
320
  }
@@ -337,12 +349,19 @@ var init_sqlite = __esm({
337
349
  status TEXT NOT NULL,
338
350
  parent_version TEXT,
339
351
  derived_from TEXT,
340
- metrics TEXT NOT NULL,
341
352
  source TEXT,
342
353
  taxonomy TEXT,
343
354
  external_source TEXT
344
355
  )
345
356
  `);
357
+ try {
358
+ db.exec("ALTER TABLE skills DROP COLUMN metrics");
359
+ } catch {
360
+ const cols = db.prepare("PRAGMA table_info(skills)").all();
361
+ if (cols.some((c) => c.name === "metrics")) {
362
+ this.rebuildSkillsTableWithoutMetrics(db, cols);
363
+ }
364
+ }
346
365
  db.exec(`
347
366
  CREATE TABLE IF NOT EXISTS skill_versions (
348
367
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -506,6 +525,75 @@ var init_sqlite = __esm({
506
525
  db.prepare("UPDATE schema_version SET version = ?").run(SCHEMA_VERSION);
507
526
  }
508
527
  }
528
+ /**
529
+ * Rebuild the `skills` table without the legacy `metrics` column.
530
+ *
531
+ * Used as the fallback path on SQLite < 3.35 where ALTER TABLE DROP
532
+ * COLUMN isn't supported. Uses the standard "table dance" pattern:
533
+ * CREATE NEW → INSERT FROM OLD → DROP OLD → RENAME, inside a single
534
+ * transaction so a partial state can't outlive a crash.
535
+ *
536
+ * The `existingCols` arg is the full PRAGMA table_info output for the
537
+ * legacy table — we use it to figure out which columns to copy. Some
538
+ * legacy installs may have a subset of the current schema's columns
539
+ * (e.g., taxonomy/external_source were added in v2, related in v3),
540
+ * so we only copy columns that exist on both sides.
541
+ */
542
+ rebuildSkillsTableWithoutMetrics(db, existingCols) {
543
+ const NEW_SCHEMA_COLUMNS = [
544
+ "id",
545
+ "version",
546
+ "name",
547
+ "description",
548
+ "instructions",
549
+ "related",
550
+ "author",
551
+ "tags",
552
+ "created_at",
553
+ "updated_at",
554
+ "status",
555
+ "parent_version",
556
+ "derived_from",
557
+ "source",
558
+ "taxonomy",
559
+ "external_source"
560
+ ];
561
+ const sourceNames = new Set(existingCols.map((c) => c.name));
562
+ const copyable = NEW_SCHEMA_COLUMNS.filter((c) => sourceNames.has(c));
563
+ const copyList = copyable.join(", ");
564
+ db.exec("BEGIN");
565
+ try {
566
+ db.exec(`
567
+ CREATE TABLE skills_new (
568
+ id TEXT PRIMARY KEY,
569
+ version TEXT NOT NULL,
570
+ name TEXT NOT NULL,
571
+ description TEXT,
572
+ instructions TEXT NOT NULL DEFAULT '',
573
+ related TEXT,
574
+ author TEXT NOT NULL,
575
+ tags TEXT NOT NULL,
576
+ created_at TEXT NOT NULL,
577
+ updated_at TEXT NOT NULL,
578
+ status TEXT NOT NULL,
579
+ parent_version TEXT,
580
+ derived_from TEXT,
581
+ source TEXT,
582
+ taxonomy TEXT,
583
+ external_source TEXT
584
+ )
585
+ `);
586
+ db.exec(
587
+ `INSERT INTO skills_new (${copyList}) SELECT ${copyList} FROM skills`
588
+ );
589
+ db.exec("DROP TABLE skills");
590
+ db.exec("ALTER TABLE skills_new RENAME TO skills");
591
+ db.exec("COMMIT");
592
+ } catch (err) {
593
+ db.exec("ROLLBACK");
594
+ throw err;
595
+ }
596
+ }
509
597
  getDb() {
510
598
  if (!this.db) {
511
599
  throw new Error("Database not initialized. Call initialize() first.");
@@ -518,10 +606,10 @@ var init_sqlite = __esm({
518
606
  const stmt = db.prepare(`
519
607
  INSERT OR REPLACE INTO skills (
520
608
  id, version, name, description, instructions, related, author, tags,
521
- created_at, updated_at, status, parent_version, derived_from, metrics,
609
+ created_at, updated_at, status, parent_version, derived_from,
522
610
  source, taxonomy, external_source
523
611
  ) VALUES (
524
- ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
612
+ ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
525
613
  )
526
614
  `);
527
615
  stmt.run(
@@ -538,7 +626,6 @@ var init_sqlite = __esm({
538
626
  skill.status,
539
627
  skill.parentVersion || null,
540
628
  skill.derivedFrom ? JSON.stringify(skill.derivedFrom) : null,
541
- JSON.stringify(skill.metrics),
542
629
  skill.source ? JSON.stringify(skill.source) : null,
543
630
  skill.taxonomy ? JSON.stringify(skill.taxonomy) : null,
544
631
  skill.externalSource ? JSON.stringify({
@@ -633,10 +720,6 @@ var init_sqlite = __esm({
633
720
  sql += " AND author = ?";
634
721
  params.push(filter.author);
635
722
  }
636
- if (filter?.minSuccessRate !== void 0) {
637
- sql += " AND json_extract(metrics, '$.successRate') >= ?";
638
- params.push(filter.minSuccessRate);
639
- }
640
723
  if (filter?.createdAfter) {
641
724
  sql += " AND created_at >= ?";
642
725
  params.push(filter.createdAfter.toISOString());
@@ -832,15 +915,15 @@ var init_sqlite = __esm({
832
915
  /**
833
916
  * Get or create a taxonomy node
834
917
  */
835
- async ensureTaxonomyNode(path18) {
918
+ async ensureTaxonomyNode(path19) {
836
919
  this.ensureInitialized();
837
920
  const db = this.getDb();
838
- const pathStr = path18.join("/");
921
+ const pathStr = path19.join("/");
839
922
  const existing = db.prepare("SELECT id FROM taxonomy_nodes WHERE path = ?").get(pathStr);
840
923
  if (existing) return existing.id;
841
924
  const id = `node-${pathStr.replace(/\//g, "-").toLowerCase()}`;
842
- const name = path18[path18.length - 1] || "Root";
843
- const parentPath = path18.slice(0, -1);
925
+ const name = path19[path19.length - 1] || "Root";
926
+ const parentPath = path19.slice(0, -1);
844
927
  let parentId = null;
845
928
  if (parentPath.length > 0) {
846
929
  parentId = await this.ensureTaxonomyNode(parentPath);
@@ -1031,7 +1114,6 @@ var init_sqlite = __esm({
1031
1114
  status: row.status,
1032
1115
  parentVersion: row.parent_version || void 0,
1033
1116
  derivedFrom: row.derived_from ? JSON.parse(row.derived_from) : void 0,
1034
- metrics: JSON.parse(row.metrics),
1035
1117
  source: row.source ? JSON.parse(row.source) : void 0,
1036
1118
  taxonomy: row.taxonomy ? JSON.parse(row.taxonomy) : void 0,
1037
1119
  externalSource: externalSource ? {
@@ -1048,11 +1130,7 @@ var init_sqlite = __esm({
1048
1130
  source: skill.source ? {
1049
1131
  ...skill.source,
1050
1132
  importedAt: skill.source.importedAt.toISOString()
1051
- } : void 0,
1052
- metrics: {
1053
- ...skill.metrics,
1054
- lastUsed: skill.metrics.lastUsed?.toISOString()
1055
- }
1133
+ } : void 0
1056
1134
  };
1057
1135
  }
1058
1136
  deserializeSkill(data) {
@@ -1063,11 +1141,7 @@ var init_sqlite = __esm({
1063
1141
  source: data.source ? {
1064
1142
  ...data.source,
1065
1143
  importedAt: new Date(data.source.importedAt)
1066
- } : void 0,
1067
- metrics: {
1068
- ...data.metrics,
1069
- lastUsed: data.metrics.lastUsed ? new Date(data.metrics.lastUsed) : void 0
1070
- }
1144
+ } : void 0
1071
1145
  };
1072
1146
  }
1073
1147
  hashSkill(skill) {
@@ -1091,6 +1165,7 @@ var DEFAULT_AGENTS_CONFIG;
1091
1165
  var init_types = __esm({
1092
1166
  "src/agents/types.ts"() {
1093
1167
  "use strict";
1168
+ init_esm_shims();
1094
1169
  DEFAULT_AGENTS_CONFIG = {
1095
1170
  format: "xml",
1096
1171
  includeIds: true,
@@ -1105,6 +1180,7 @@ var AgentsGenerator;
1105
1180
  var init_generator = __esm({
1106
1181
  "src/agents/generator.ts"() {
1107
1182
  "use strict";
1183
+ init_esm_shims();
1108
1184
  init_types();
1109
1185
  AgentsGenerator = class {
1110
1186
  constructor(config2) {
@@ -1273,9 +1349,6 @@ ${this.indentContent(skill.instructions, 4)}
1273
1349
  if (filter.tags && filter.tags.length > 0) {
1274
1350
  result = result.filter((s) => s.tags.some((t) => filter.tags.includes(t)));
1275
1351
  }
1276
- if (filter.minSuccessRate !== void 0) {
1277
- result = result.filter((s) => s.metrics.successRate >= filter.minSuccessRate);
1278
- }
1279
1352
  if (filter.limit) {
1280
1353
  result = result.slice(0, filter.limit);
1281
1354
  }
@@ -1319,6 +1392,7 @@ var AgentsParser;
1319
1392
  var init_parser = __esm({
1320
1393
  "src/agents/parser.ts"() {
1321
1394
  "use strict";
1395
+ init_esm_shims();
1322
1396
  AgentsParser = class {
1323
1397
  /**
1324
1398
  * Parse AGENTS.md content
@@ -1372,11 +1446,6 @@ var init_parser = __esm({
1372
1446
  createdAt: defaults?.createdAt || now,
1373
1447
  updatedAt: now,
1374
1448
  status: "active",
1375
- metrics: defaults?.metrics || {
1376
- usageCount: 0,
1377
- successRate: 0,
1378
- feedbackScores: []
1379
- },
1380
1449
  source: {
1381
1450
  type: "imported",
1382
1451
  location: "AGENTS.md",
@@ -1559,7 +1628,7 @@ __export(sync_exports, {
1559
1628
  writeAgentsMd: () => writeAgentsMd
1560
1629
  });
1561
1630
  import * as fs9 from "fs";
1562
- import * as path9 from "path";
1631
+ import * as path10 from "path";
1563
1632
  function createAgentsSync() {
1564
1633
  return new AgentsSync();
1565
1634
  }
@@ -1569,7 +1638,7 @@ async function generateAgentsMd(storage, config2) {
1569
1638
  }
1570
1639
  async function writeAgentsMd(storage, filePath, config2) {
1571
1640
  const content = await generateAgentsMd(storage, config2);
1572
- const dir = path9.dirname(filePath);
1641
+ const dir = path10.dirname(filePath);
1573
1642
  if (dir && !fs9.existsSync(dir)) {
1574
1643
  fs9.mkdirSync(dir, { recursive: true });
1575
1644
  }
@@ -1587,6 +1656,7 @@ var AgentsSync;
1587
1656
  var init_sync = __esm({
1588
1657
  "src/agents/sync.ts"() {
1589
1658
  "use strict";
1659
+ init_esm_shims();
1590
1660
  init_generator();
1591
1661
  init_parser();
1592
1662
  AgentsSync = class {
@@ -1692,7 +1762,7 @@ var init_sync = __esm({
1692
1762
  }
1693
1763
  }
1694
1764
  if (!options.dryRun) {
1695
- const dir = path9.dirname(agentsPath);
1765
+ const dir = path10.dirname(agentsPath);
1696
1766
  if (!fs9.existsSync(dir)) {
1697
1767
  fs9.mkdirSync(dir, { recursive: true });
1698
1768
  }
@@ -1744,8 +1814,6 @@ var init_sync = __esm({
1744
1814
  // Keep existing ID
1745
1815
  createdAt: existing.createdAt,
1746
1816
  // Preserve creation date
1747
- metrics: existing.metrics,
1748
- // Preserve usage metrics
1749
1817
  source: incoming.source || existing.source,
1750
1818
  parentVersion: existing.version
1751
1819
  // Track update lineage
@@ -1756,9 +1824,17 @@ var init_sync = __esm({
1756
1824
  });
1757
1825
 
1758
1826
  // src/cli/index.ts
1759
- import { Command as Command39 } from "commander";
1827
+ init_esm_shims();
1828
+ import { Command as Command38 } from "commander";
1829
+
1830
+ // src/index.ts
1831
+ init_esm_shims();
1832
+
1833
+ // src/skill-bank.ts
1834
+ init_esm_shims();
1760
1835
 
1761
1836
  // src/types.ts
1837
+ init_esm_shims();
1762
1838
  function hasTaxonomySupport(storage) {
1763
1839
  return typeof storage.placeInTaxonomy === "function";
1764
1840
  }
@@ -1766,18 +1842,23 @@ function hasForkSupport(storage) {
1766
1842
  return typeof storage.recordFork === "function";
1767
1843
  }
1768
1844
 
1845
+ // src/sync/sync-manager.ts
1846
+ init_esm_shims();
1847
+
1769
1848
  // src/sync/git-sync-adapter.ts
1849
+ init_esm_shims();
1770
1850
  import * as fs2 from "fs";
1771
- import * as path2 from "path";
1851
+ import * as path3 from "path";
1772
1852
 
1773
1853
  // src/sync/conflict-store.ts
1854
+ init_esm_shims();
1774
1855
  import * as fs from "fs";
1775
- import * as path from "path";
1856
+ import * as path2 from "path";
1776
1857
  var ConflictStore = class {
1777
1858
  constructor(basePath) {
1778
- const skillbankDir = path.join(basePath, ".skillbank");
1779
- this.conflictsDir = path.join(skillbankDir, "conflicts");
1780
- this.stateFile = path.join(skillbankDir, "sync-state.json");
1859
+ const skillbankDir = path2.join(basePath, ".skillbank");
1860
+ this.conflictsDir = path2.join(skillbankDir, "conflicts");
1861
+ this.stateFile = path2.join(skillbankDir, "sync-state.json");
1781
1862
  }
1782
1863
  /**
1783
1864
  * Initialize the store (create directories if needed)
@@ -1794,7 +1875,7 @@ var ConflictStore = class {
1794
1875
  async saveConflict(conflict) {
1795
1876
  await this.initialize();
1796
1877
  const filename = this.getConflictFilename(conflict.skillId);
1797
- const filepath = path.join(this.conflictsDir, filename);
1878
+ const filepath = path2.join(this.conflictsDir, filename);
1798
1879
  const data = JSON.stringify(this.serializeConflict(conflict), null, 2);
1799
1880
  await fs.promises.writeFile(filepath, data, "utf-8");
1800
1881
  }
@@ -1803,7 +1884,7 @@ var ConflictStore = class {
1803
1884
  */
1804
1885
  async getConflict(skillId) {
1805
1886
  const filename = this.getConflictFilename(skillId);
1806
- const filepath = path.join(this.conflictsDir, filename);
1887
+ const filepath = path2.join(this.conflictsDir, filename);
1807
1888
  try {
1808
1889
  const data = await fs.promises.readFile(filepath, "utf-8");
1809
1890
  return this.deserializeConflict(JSON.parse(data));
@@ -1824,7 +1905,7 @@ var ConflictStore = class {
1824
1905
  const conflicts = [];
1825
1906
  for (const file of files) {
1826
1907
  if (file.endsWith(".json")) {
1827
- const filepath = path.join(this.conflictsDir, file);
1908
+ const filepath = path2.join(this.conflictsDir, file);
1828
1909
  try {
1829
1910
  const data = await fs.promises.readFile(filepath, "utf-8");
1830
1911
  conflicts.push(this.deserializeConflict(JSON.parse(data)));
@@ -1847,7 +1928,7 @@ var ConflictStore = class {
1847
1928
  */
1848
1929
  async removeConflict(skillId) {
1849
1930
  const filename = this.getConflictFilename(skillId);
1850
- const filepath = path.join(this.conflictsDir, filename);
1931
+ const filepath = path2.join(this.conflictsDir, filename);
1851
1932
  try {
1852
1933
  await fs.promises.unlink(filepath);
1853
1934
  return true;
@@ -1986,10 +2067,6 @@ var ConflictStore = class {
1986
2067
  ...skill,
1987
2068
  createdAt: skill.createdAt instanceof Date ? skill.createdAt.toISOString() : skill.createdAt,
1988
2069
  updatedAt: skill.updatedAt instanceof Date ? skill.updatedAt.toISOString() : skill.updatedAt,
1989
- metrics: {
1990
- ...skill.metrics,
1991
- lastUsed: skill.metrics?.lastUsed instanceof Date ? skill.metrics.lastUsed.toISOString() : skill.metrics?.lastUsed
1992
- },
1993
2070
  source: skill.source ? {
1994
2071
  ...skill.source,
1995
2072
  importedAt: skill.source.importedAt instanceof Date ? skill.source.importedAt.toISOString() : skill.source.importedAt
@@ -2001,10 +2078,6 @@ var ConflictStore = class {
2001
2078
  ...data,
2002
2079
  createdAt: new Date(data.createdAt),
2003
2080
  updatedAt: new Date(data.updatedAt),
2004
- metrics: {
2005
- ...data.metrics,
2006
- lastUsed: data.metrics?.lastUsed ? new Date(data.metrics.lastUsed) : void 0
2007
- },
2008
2081
  source: data.source ? {
2009
2082
  ...data.source,
2010
2083
  importedAt: new Date(data.source.importedAt)
@@ -2072,7 +2145,7 @@ var GitSyncAdapter = class {
2072
2145
  for (const file of changedFiles) {
2073
2146
  const skillId = this.extractSkillIdFromPath(file);
2074
2147
  if (!skillId) continue;
2075
- const localPath = path2.join(this.repoPath, file);
2148
+ const localPath = path3.join(this.repoPath, file);
2076
2149
  const existsLocally = fs2.existsSync(localPath);
2077
2150
  let existsRemotely = true;
2078
2151
  try {
@@ -2359,7 +2432,7 @@ var GitSyncAdapter = class {
2359
2432
  return this.config.remote.skillsPath || "skills/";
2360
2433
  }
2361
2434
  getSkillFilePath(skillId) {
2362
- return path2.join(this.getSkillsPath(), skillId, "SKILL.md");
2435
+ return path3.join(this.getSkillsPath(), skillId, "SKILL.md");
2363
2436
  }
2364
2437
  extractSkillIdFromPath(filePath) {
2365
2438
  const skillsPath = this.getSkillsPath();
@@ -2373,7 +2446,7 @@ var GitSyncAdapter = class {
2373
2446
  }
2374
2447
  async pullSkill(skillId, branch, syncState, options) {
2375
2448
  const skillPath = this.getSkillFilePath(skillId);
2376
- const fullPath = path2.join(this.repoPath, skillPath);
2449
+ const fullPath = path3.join(this.repoPath, skillPath);
2377
2450
  let remoteContent;
2378
2451
  try {
2379
2452
  remoteContent = await this.git.show([`origin/${branch}:${skillPath}`]);
@@ -2571,18 +2644,13 @@ ${remoteValue}`;
2571
2644
  tags: metadata.tags ? metadata.tags.split(",").map((t) => t.trim()) : [],
2572
2645
  createdAt: metadata.created ? new Date(metadata.created) : /* @__PURE__ */ new Date(),
2573
2646
  updatedAt: metadata.updated ? new Date(metadata.updated) : /* @__PURE__ */ new Date(),
2574
- status: isValidStatus(metadata.status) ? metadata.status : "active",
2575
- metrics: {
2576
- usageCount: 0,
2577
- successRate: 0,
2578
- feedbackScores: []
2579
- }
2647
+ status: isValidStatus(metadata.status) ? metadata.status : "active"
2580
2648
  };
2581
2649
  }
2582
2650
  async writeSkill(skill) {
2583
2651
  const skillPath = this.getSkillFilePath(skill.id);
2584
- const fullPath = path2.join(this.repoPath, skillPath);
2585
- await fs2.promises.mkdir(path2.dirname(fullPath), { recursive: true });
2652
+ const fullPath = path3.join(this.repoPath, skillPath);
2653
+ await fs2.promises.mkdir(path3.dirname(fullPath), { recursive: true });
2586
2654
  const content = this.buildSkillContent(skill);
2587
2655
  await fs2.promises.writeFile(fullPath, content, "utf-8");
2588
2656
  }
@@ -2633,11 +2701,11 @@ ${body.join("\n")}
2633
2701
  agent: this.config.agent,
2634
2702
  skills: {}
2635
2703
  };
2636
- const skillsPath = path2.join(this.repoPath, this.getSkillsPath());
2704
+ const skillsPath = path3.join(this.repoPath, this.getSkillsPath());
2637
2705
  if (fs2.existsSync(skillsPath)) {
2638
2706
  const dirs = await fs2.promises.readdir(skillsPath);
2639
2707
  for (const dir of dirs) {
2640
- const skillPath = path2.join(skillsPath, dir, "SKILL.md");
2708
+ const skillPath = path3.join(skillsPath, dir, "SKILL.md");
2641
2709
  if (fs2.existsSync(skillPath)) {
2642
2710
  try {
2643
2711
  const content = await fs2.promises.readFile(skillPath, "utf-8");
@@ -2831,7 +2899,14 @@ var SyncManager = class {
2831
2899
  }
2832
2900
  };
2833
2901
 
2902
+ // src/serving/graph-server.ts
2903
+ init_esm_shims();
2904
+
2905
+ // src/serving/catalog-renderer.ts
2906
+ init_esm_shims();
2907
+
2834
2908
  // src/serving/xml-utils.ts
2909
+ init_esm_shims();
2835
2910
  function escapeXml(text) {
2836
2911
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
2837
2912
  }
@@ -2899,11 +2974,11 @@ var CatalogRenderer = class _CatalogRenderer {
2899
2974
  * Render a specific category path for browse drill-down.
2900
2975
  * Shows subcategories at intermediate nodes, or skill summaries at leaf nodes.
2901
2976
  */
2902
- async renderCategory(path18) {
2977
+ async renderCategory(path19) {
2903
2978
  if (hasCatalogSupport(this.storage)) {
2904
- return this.renderCategoryFromTaxonomy(this.storage, path18);
2979
+ return this.renderCategoryFromTaxonomy(this.storage, path19);
2905
2980
  }
2906
- return this.renderCategoryFromTags(path18);
2981
+ return this.renderCategoryFromTags(path19);
2907
2982
  }
2908
2983
  /**
2909
2984
  * Invalidate the overview cache (e.g., after skill changes).
@@ -2941,9 +3016,9 @@ var CatalogRenderer = class _CatalogRenderer {
2941
3016
  const categories = counted.sort((a, b) => b.count - a.count).slice(0, this.config.maxCategoriesPerLevel).map((c) => ({ name: c.node.name, count: c.count }));
2942
3017
  return this.renderOverviewXml(totalSkills, categories);
2943
3018
  }
2944
- async renderCategoryFromTaxonomy(storage, path18) {
2945
- const tree = await storage.getTaxonomyTree(path18);
2946
- const pathStr = path18.join("/");
3019
+ async renderCategoryFromTaxonomy(storage, path19) {
3020
+ const tree = await storage.getTaxonomyTree(path19);
3021
+ const pathStr = path19.join("/");
2947
3022
  if (tree.length > 0 && tree.some((n) => n.children.length > 0)) {
2948
3023
  const root = tree[0];
2949
3024
  const rootCount = this.countNodeSkills(root);
@@ -2953,7 +3028,7 @@ var CatalogRenderer = class _CatalogRenderer {
2953
3028
  lines.push(`<catalog_browse path="${escapeXml(pathStr)}" count="${rootCount}">`);
2954
3029
  lines.push(" <subcategories>");
2955
3030
  for (const { node: child, count } of children) {
2956
- const childPath = [...path18, child.name].join("/");
3031
+ const childPath = [...path19, child.name].join("/");
2957
3032
  lines.push(` <category path="${escapeXml(childPath)}" count="${count}" />`);
2958
3033
  }
2959
3034
  lines.push(" </subcategories>");
@@ -2977,13 +3052,13 @@ var CatalogRenderer = class _CatalogRenderer {
2977
3052
  const categories = Array.from(tagCounts.entries()).sort((a, b) => b[1] - a[1]).slice(0, this.config.maxCategoriesPerLevel).map(([name, count]) => ({ name, count }));
2978
3053
  return this.renderOverviewXml(skills.length, categories);
2979
3054
  }
2980
- async renderCategoryFromTags(path18) {
2981
- if (path18.length === 0) {
3055
+ async renderCategoryFromTags(path19) {
3056
+ if (path19.length === 0) {
2982
3057
  return this.renderOverviewFromTags();
2983
3058
  }
2984
- const tag = path18[0];
3059
+ const tag = path19[0];
2985
3060
  const matching = await this.storage.listSkills({ status: ["active"], tags: [tag] });
2986
- const pathStr = path18.join("/");
3061
+ const pathStr = path19.join("/");
2987
3062
  return this.renderLeafSkills(matching, pathStr, matching.length);
2988
3063
  }
2989
3064
  // ===========================================================================
@@ -3038,6 +3113,7 @@ var CatalogRenderer = class _CatalogRenderer {
3038
3113
  };
3039
3114
 
3040
3115
  // src/serving/loadout-compiler.ts
3116
+ init_esm_shims();
3041
3117
  var DEFAULT_CONFIG2 = {
3042
3118
  defaultMaxSkills: 15,
3043
3119
  defaultStatus: ["active"],
@@ -3052,7 +3128,24 @@ var LoadoutCompiler = class {
3052
3128
  };
3053
3129
  }
3054
3130
  /**
3055
- * Main entry point - compile skills from criteria
3131
+ * Main entry point - compile skills from criteria.
3132
+ *
3133
+ * Filter pipeline order:
3134
+ * 1. status (initial query)
3135
+ * 2. exclude (drop matching IDs)
3136
+ * 3. tags / tagsAll
3137
+ * 4. author
3138
+ * 5. semantic (currently no-op)
3139
+ * 6. relationships (rootSkills traversal)
3140
+ * 7. **include** — presence guarantee: ensures every ID in the
3141
+ * include list is in the result regardless of the filters above,
3142
+ * fetching missing ones from storage as needed. `exclude` still
3143
+ * wins (excluded IDs are removed from the include list before
3144
+ * this step).
3145
+ * 8. limits (maxSkills, maxTokens)
3146
+ *
3147
+ * For "restrict to exactly these skills" semantics, combine
3148
+ * `include: [...]` with `maxSkills: include.length`.
3056
3149
  */
3057
3150
  async compile(criteria) {
3058
3151
  const status = criteria.status ?? this.config.defaultStatus;
@@ -3062,6 +3155,7 @@ var LoadoutCompiler = class {
3062
3155
  candidates = this.applyQualityFilters(candidates, criteria);
3063
3156
  candidates = await this.applySemanticFilters(candidates, criteria);
3064
3157
  candidates = await this.applyRelationshipFilters(candidates, criteria);
3158
+ candidates = await this.ensureIncludedPresent(candidates, criteria);
3065
3159
  candidates = this.applyLimits(candidates, criteria);
3066
3160
  return candidates;
3067
3161
  }
@@ -3107,7 +3201,9 @@ var LoadoutCompiler = class {
3107
3201
  // Filter Methods
3108
3202
  // ===========================================================================
3109
3203
  /**
3110
- * Apply explicit include/exclude filters
3204
+ * Apply explicit exclude filter. Include is handled separately at the
3205
+ * compile level (see `ensureIncludedPresent`) so it can guarantee
3206
+ * presence regardless of the other filters in this method or below.
3111
3207
  */
3112
3208
  applyExplicitFilters(skills, criteria) {
3113
3209
  let result = skills;
@@ -3115,15 +3211,6 @@ var LoadoutCompiler = class {
3115
3211
  const excludeSet = new Set(criteria.exclude);
3116
3212
  result = result.filter((s) => !excludeSet.has(s.id));
3117
3213
  }
3118
- if (criteria.include && criteria.include.length > 0) {
3119
- const includeSet = new Set(criteria.include);
3120
- const currentIds = new Set(result.map((s) => s.id));
3121
- const includedSkills = result.filter((s) => includeSet.has(s.id));
3122
- const otherSkills = result.filter((s) => !includeSet.has(s.id));
3123
- if (includedSkills.length > 0) {
3124
- result = [...includedSkills, ...otherSkills];
3125
- }
3126
- }
3127
3214
  return result;
3128
3215
  }
3129
3216
  /**
@@ -3147,11 +3234,6 @@ var LoadoutCompiler = class {
3147
3234
  */
3148
3235
  applyQualityFilters(skills, criteria) {
3149
3236
  let result = skills;
3150
- if (criteria.minSuccessRate !== void 0) {
3151
- result = result.filter(
3152
- (s) => s.metrics.successRate >= criteria.minSuccessRate
3153
- );
3154
- }
3155
3237
  if (criteria.author) {
3156
3238
  result = result.filter((s) => s.author === criteria.author);
3157
3239
  }
@@ -3209,27 +3291,48 @@ var LoadoutCompiler = class {
3209
3291
  }
3210
3292
  return skills.filter((s) => result.has(s.id));
3211
3293
  }
3294
+ /**
3295
+ * Ensure every ID in `criteria.include` is present in the result,
3296
+ * regardless of which earlier filter would have dropped it. Missing
3297
+ * skills are fetched directly from storage.
3298
+ *
3299
+ * `criteria.exclude` still wins: an ID listed in both `include` and
3300
+ * `exclude` is treated as excluded (consistent with openteams' "deny
3301
+ * wins" inheritance rule on permissions).
3302
+ *
3303
+ * Included skills are placed at the front of the result, preserving
3304
+ * the order of `criteria.include`. Other skills retain their relative
3305
+ * order behind them.
3306
+ */
3307
+ async ensureIncludedPresent(current, criteria) {
3308
+ if (!criteria.include?.length) return current;
3309
+ const excludeSet = new Set(criteria.exclude ?? []);
3310
+ const effectiveInclude = criteria.include.filter(
3311
+ (id) => !excludeSet.has(id)
3312
+ );
3313
+ if (effectiveInclude.length === 0) return current;
3314
+ const currentById = new Map(current.map((s) => [s.id, s]));
3315
+ const ordered = [];
3316
+ for (const id of effectiveInclude) {
3317
+ const existing = currentById.get(id);
3318
+ if (existing) {
3319
+ ordered.push(existing);
3320
+ currentById.delete(id);
3321
+ continue;
3322
+ }
3323
+ const fetched = await this.storage.getSkill(id);
3324
+ if (fetched) {
3325
+ ordered.push(fetched);
3326
+ }
3327
+ }
3328
+ return [...ordered, ...currentById.values()];
3329
+ }
3212
3330
  /**
3213
3331
  * Apply limits and sorting
3214
3332
  */
3215
3333
  applyLimits(skills, criteria) {
3216
3334
  let result = skills;
3217
- if (criteria.priorityOrder) {
3218
- result = [...result].sort((a, b) => {
3219
- switch (criteria.priorityOrder) {
3220
- case "usage":
3221
- return b.metrics.usageCount - a.metrics.usageCount;
3222
- case "successRate":
3223
- return b.metrics.successRate - a.metrics.successRate;
3224
- case "recent":
3225
- const aDate = a.metrics.lastUsed?.getTime() ?? 0;
3226
- const bDate = b.metrics.lastUsed?.getTime() ?? 0;
3227
- return bDate - aDate;
3228
- case "relevance":
3229
- default:
3230
- return 0;
3231
- }
3232
- });
3335
+ if (criteria.priorityOrder === "relevance") {
3233
3336
  }
3234
3337
  const maxSkills = criteria.maxSkills ?? this.config.defaultMaxSkills;
3235
3338
  if (result.length > maxSkills) {
@@ -3266,6 +3369,7 @@ var LoadoutCompiler = class {
3266
3369
  };
3267
3370
 
3268
3371
  // src/serving/project-detector.ts
3372
+ init_esm_shims();
3269
3373
  import { existsSync as existsSync2, readFileSync } from "fs";
3270
3374
  import { join as join3 } from "path";
3271
3375
  var ProjectDetector = class _ProjectDetector {
@@ -3501,6 +3605,7 @@ var ProjectDetector = class _ProjectDetector {
3501
3605
  };
3502
3606
 
3503
3607
  // src/serving/view-renderer.ts
3608
+ init_esm_shims();
3504
3609
  var DEFAULT_CONFIG3 = {
3505
3610
  includeTokenEstimates: false,
3506
3611
  maxSummaryLength: 150
@@ -3696,6 +3801,7 @@ var ViewRenderer = class {
3696
3801
  };
3697
3802
 
3698
3803
  // src/serving/profiles/index.ts
3804
+ init_esm_shims();
3699
3805
  var codeReviewProfile = {
3700
3806
  tags: ["review", "quality", "security", "best-practices"],
3701
3807
  taskDescription: "review code for quality, security, and best practices",
@@ -3720,7 +3826,6 @@ var securityProfile = {
3720
3826
  tagsAll: ["security"],
3721
3827
  taskDescription: "security review, vulnerability detection, secure coding",
3722
3828
  maxSkills: 8,
3723
- minSuccessRate: 0.7,
3724
3829
  priorityOrder: "relevance"
3725
3830
  };
3726
3831
  var testingProfile = {
@@ -3968,16 +4073,6 @@ var SkillGraphServer = class {
3968
4073
  this.emit({ type: "skill:collapsed", skillId });
3969
4074
  return true;
3970
4075
  }
3971
- /**
3972
- * Record skill usage (for LRU tracking and auto-expansion)
3973
- */
3974
- recordUsage(skillId) {
3975
- if (!this.state.available.has(skillId)) return;
3976
- this.touchLru(skillId);
3977
- if (this.config.autoExpandOnUse && !this.state.expanded.has(skillId)) {
3978
- this.expandSkill(skillId);
3979
- }
3980
- }
3981
4076
  // ===========================================================================
3982
4077
  // AGENT API - Methods for agent-side modifications
3983
4078
  // ===========================================================================
@@ -4087,19 +4182,19 @@ var SkillGraphServer = class {
4087
4182
  * Returns rendered category view (subcategories or skill summaries at leaf).
4088
4183
  * Pass no path for the top-level overview.
4089
4184
  */
4090
- async agentBrowseCatalog(path18) {
4185
+ async agentBrowseCatalog(path19) {
4091
4186
  if (!this.catalogRenderer) {
4092
4187
  return "<error>Catalog browsing is not enabled</error>";
4093
4188
  }
4094
- if (!path18 || path18.length === 0) {
4189
+ if (!path19 || path19.length === 0) {
4095
4190
  const result2 = await this.catalogRenderer.renderOverview();
4096
4191
  if (result2) {
4097
4192
  this.emit({ type: "catalog:browsed", path: [] });
4098
4193
  }
4099
4194
  return result2;
4100
4195
  }
4101
- const result = await this.catalogRenderer.renderCategory(path18);
4102
- this.emit({ type: "catalog:browsed", path: path18 });
4196
+ const result = await this.catalogRenderer.renderCategory(path19);
4197
+ this.emit({ type: "catalog:browsed", path: path19 });
4103
4198
  return result;
4104
4199
  }
4105
4200
  /**
@@ -4266,6 +4361,7 @@ var SkillGraphServer = class {
4266
4361
  };
4267
4362
 
4268
4363
  // src/serving/interfaces.ts
4364
+ init_esm_shims();
4269
4365
  function createStorageView(storage) {
4270
4366
  return {
4271
4367
  getSkill: storage.getSkill.bind(storage),
@@ -4305,17 +4401,21 @@ function createServingEventBridge() {
4305
4401
  };
4306
4402
  }
4307
4403
 
4404
+ // src/federation/index.ts
4405
+ init_esm_shims();
4406
+
4308
4407
  // src/federation/remote-store.ts
4408
+ init_esm_shims();
4309
4409
  import * as fs3 from "fs";
4310
- import * as path3 from "path";
4410
+ import * as path4 from "path";
4311
4411
  var REMOTES_FILE = "remotes.json";
4312
4412
  var RemoteStore = class {
4313
4413
  constructor(options) {
4314
4414
  this.remotes = /* @__PURE__ */ new Map();
4315
4415
  this.initialized = false;
4316
4416
  this.basePath = options.basePath;
4317
- this.configDir = path3.join(this.basePath, ".skillbank");
4318
- this.configPath = path3.join(this.configDir, REMOTES_FILE);
4417
+ this.configDir = path4.join(this.basePath, ".skillbank");
4418
+ this.configPath = path4.join(this.configDir, REMOTES_FILE);
4319
4419
  }
4320
4420
  /**
4321
4421
  * Initialize the store, loading existing configuration
@@ -4387,7 +4487,7 @@ var RemoteStore = class {
4387
4487
  ...config2,
4388
4488
  branch: config2.branch || "main",
4389
4489
  skillsPath: config2.skillsPath || "skills/",
4390
- localCache: config2.localCache || path3.join(this.basePath, ".remotes", name)
4490
+ localCache: config2.localCache || path4.join(this.basePath, ".remotes", name)
4391
4491
  };
4392
4492
  this.remotes.set(name, normalizedConfig);
4393
4493
  await this.save();
@@ -4461,7 +4561,7 @@ var RemoteStore = class {
4461
4561
  if (!config2) {
4462
4562
  throw new Error(`Remote not found: ${name}`);
4463
4563
  }
4464
- return config2.localCache || path3.join(this.basePath, ".remotes", name);
4564
+ return config2.localCache || path4.join(this.basePath, ".remotes", name);
4465
4565
  }
4466
4566
  /**
4467
4567
  * Validate a remote name
@@ -4501,20 +4601,22 @@ var RemoteStore = class {
4501
4601
  };
4502
4602
 
4503
4603
  // src/federation/remote-manager.ts
4604
+ init_esm_shims();
4504
4605
  import * as fs5 from "fs";
4505
- import * as path5 from "path";
4606
+ import * as path6 from "path";
4506
4607
  import { exec } from "child_process";
4507
4608
  import { promisify } from "util";
4508
4609
 
4509
4610
  // src/federation/skilltree-config.ts
4611
+ init_esm_shims();
4510
4612
  import * as fs4 from "fs";
4511
- import * as path4 from "path";
4613
+ import * as path5 from "path";
4512
4614
  function resolveSkilltreeDir(repoRoot) {
4513
4615
  const envDir = process.env.SKILL_TREE_PROJECT_DIR;
4514
- if (envDir) return path4.join(repoRoot, envDir);
4515
- const swarmDir = path4.join(repoRoot, ".swarm", "skilltree");
4616
+ if (envDir) return path5.join(repoRoot, envDir);
4617
+ const swarmDir = path5.join(repoRoot, ".swarm", "skilltree");
4516
4618
  if (fs4.existsSync(swarmDir)) return swarmDir;
4517
- return path4.join(repoRoot, ".skilltree");
4619
+ return path5.join(repoRoot, ".skilltree");
4518
4620
  }
4519
4621
  var DEFAULT_CONFIG5 = {
4520
4622
  version: 1,
@@ -4545,7 +4647,7 @@ function getSkilltreeDir(repoRoot) {
4545
4647
  function getSkillsDir(repoRoot, config2) {
4546
4648
  const skilltreeDir = getSkilltreeDir(repoRoot);
4547
4649
  const paths = config2?.paths || DEFAULT_CONFIG5.paths;
4548
- return path4.join(skilltreeDir, paths[0]);
4650
+ return path5.join(skilltreeDir, paths[0]);
4549
4651
  }
4550
4652
  function parseSkilltreeConfig(content) {
4551
4653
  const parsed = JSON.parse(content);
@@ -4565,7 +4667,7 @@ function validateConfig(config2) {
4565
4667
  };
4566
4668
  }
4567
4669
  async function loadSkilltreeConfig(repoRoot) {
4568
- const configPath = path4.join(getSkilltreeDir(repoRoot), "config.json");
4670
+ const configPath = path5.join(getSkilltreeDir(repoRoot), "config.json");
4569
4671
  try {
4570
4672
  const content = await fs4.promises.readFile(configPath, "utf-8");
4571
4673
  return parseSkilltreeConfig(content);
@@ -4582,9 +4684,9 @@ async function initSkilltreeDir(repoRoot, config2) {
4582
4684
  await fs4.promises.mkdir(skilltreeDir, { recursive: true });
4583
4685
  const skillsDir = getSkillsDir(repoRoot, fullConfig);
4584
4686
  await fs4.promises.mkdir(skillsDir, { recursive: true });
4585
- const cacheDir = path4.join(skilltreeDir, ".cache");
4687
+ const cacheDir = path5.join(skilltreeDir, ".cache");
4586
4688
  await fs4.promises.mkdir(cacheDir, { recursive: true });
4587
- const gitignorePath = path4.join(skilltreeDir, ".gitignore");
4689
+ const gitignorePath = path5.join(skilltreeDir, ".gitignore");
4588
4690
  try {
4589
4691
  const existing = await fs4.promises.readFile(gitignorePath, "utf-8");
4590
4692
  if (!existing.includes(".cache")) {
@@ -4598,7 +4700,7 @@ async function initSkilltreeDir(repoRoot, config2) {
4598
4700
  await fs4.promises.writeFile(gitignorePath, ".cache/\n", "utf-8");
4599
4701
  }
4600
4702
  if (config2 && Object.keys(config2).length > 0) {
4601
- const configPath = path4.join(skilltreeDir, "config.json");
4703
+ const configPath = path5.join(skilltreeDir, "config.json");
4602
4704
  await fs4.promises.writeFile(
4603
4705
  configPath,
4604
4706
  JSON.stringify(fullConfig, null, 2),
@@ -4621,7 +4723,7 @@ function isSkillFile(filename, patterns = DEFAULT_CONFIG5.skillFilePatterns) {
4621
4723
  return false;
4622
4724
  }
4623
4725
  function shouldExclude(relativePath, excludePatterns) {
4624
- const parts = relativePath.split(path4.sep);
4726
+ const parts = relativePath.split(path5.sep);
4625
4727
  for (const part of parts) {
4626
4728
  if (excludePatterns.includes(part)) {
4627
4729
  return true;
@@ -4641,14 +4743,14 @@ async function discoverSkills(repoRoot) {
4641
4743
  } else {
4642
4744
  const paths = config2.paths || DEFAULT_CONFIG5.paths;
4643
4745
  for (const searchPath of paths) {
4644
- const fullPath = path4.join(skilltreeDir, searchPath);
4746
+ const fullPath = path5.join(skilltreeDir, searchPath);
4645
4747
  await scanForSkills(skilltreeDir, fullPath, config2, discovered);
4646
4748
  }
4647
4749
  }
4648
4750
  return discovered;
4649
4751
  }
4650
4752
  async function scanForSkills(skilltreeDir, dir, config2, discovered) {
4651
- const relativePath = path4.relative(skilltreeDir, dir);
4753
+ const relativePath = path5.relative(skilltreeDir, dir);
4652
4754
  if (relativePath && shouldExclude(relativePath, config2.exclude || [])) {
4653
4755
  return;
4654
4756
  }
@@ -4656,7 +4758,7 @@ async function scanForSkills(skilltreeDir, dir, config2, discovered) {
4656
4758
  const entries = await fs4.promises.readdir(dir, { withFileTypes: true });
4657
4759
  for (const entry of entries) {
4658
4760
  if (entry.isFile() && isSkillFile(entry.name, config2.skillFilePatterns)) {
4659
- const filePath = path4.join(dir, entry.name);
4761
+ const filePath = path5.join(dir, entry.name);
4660
4762
  const id = deriveSkillId(skilltreeDir, filePath);
4661
4763
  if (!discovered.some((d) => d.id === id)) {
4662
4764
  discovered.push({
@@ -4671,7 +4773,7 @@ async function scanForSkills(skilltreeDir, dir, config2, discovered) {
4671
4773
  if (entry.isDirectory() && !entry.name.startsWith(".")) {
4672
4774
  await scanForSkills(
4673
4775
  skilltreeDir,
4674
- path4.join(dir, entry.name),
4776
+ path5.join(dir, entry.name),
4675
4777
  config2,
4676
4778
  discovered
4677
4779
  );
@@ -4684,11 +4786,11 @@ async function scanForSkills(skilltreeDir, dir, config2, discovered) {
4684
4786
  }
4685
4787
  }
4686
4788
  function deriveSkillId(skilltreeDir, filePath) {
4687
- const dir = path4.dirname(filePath);
4688
- const filename = path4.basename(filePath);
4689
- const dirName = path4.basename(dir);
4690
- const parentDir = path4.dirname(dir);
4691
- const parentDirName = path4.basename(parentDir);
4789
+ const dir = path5.dirname(filePath);
4790
+ const filename = path5.basename(filePath);
4791
+ const dirName = path5.basename(dir);
4792
+ const parentDir = path5.dirname(dir);
4793
+ const parentDirName = path5.basename(parentDir);
4692
4794
  if (dir !== skilltreeDir) {
4693
4795
  const skillMatch = filename.match(/^(.+)\.skill\.md$/i);
4694
4796
  if (skillMatch) {
@@ -4705,7 +4807,7 @@ function deriveSkillId(skilltreeDir, filePath) {
4705
4807
  return dirName;
4706
4808
  }
4707
4809
  }
4708
- const relativePath = path4.relative(skilltreeDir, filePath);
4810
+ const relativePath = path5.relative(skilltreeDir, filePath);
4709
4811
  const withoutExt = relativePath.replace(/\.(skill\.)?md$/i, "");
4710
4812
  return withoutExt.replace(/[\/\\]/g, "-");
4711
4813
  }
@@ -4722,7 +4824,7 @@ var RemoteManager = class {
4722
4824
  /** Cache of discovered skill locations per remote */
4723
4825
  this.discoveryCache = /* @__PURE__ */ new Map();
4724
4826
  this.basePath = options.basePath;
4725
- this.remotesDir = path5.join(this.basePath, ".remotes");
4827
+ this.remotesDir = path6.join(this.basePath, ".remotes");
4726
4828
  this.remoteStore = options.remoteStore;
4727
4829
  this.gitTimeout = options.gitTimeout || 6e4;
4728
4830
  }
@@ -4893,10 +4995,10 @@ var RemoteManager = class {
4893
4995
  throw new Error(`Remote ${remoteName} is read-only`);
4894
4996
  }
4895
4997
  const skillsPath = await this.getWritePath(remoteName);
4896
- const skillDir = path5.join(skillsPath, skill.id);
4998
+ const skillDir = path6.join(skillsPath, skill.id);
4897
4999
  await fs5.promises.mkdir(skillDir, { recursive: true });
4898
5000
  const content = this.serializeSkill(skill);
4899
- const skillPath = path5.join(skillDir, "SKILL.md");
5001
+ const skillPath = path6.join(skillDir, "SKILL.md");
4900
5002
  await fs5.promises.writeFile(skillPath, content, "utf-8");
4901
5003
  this.discoveryCache.delete(remoteName);
4902
5004
  return skillPath;
@@ -5015,7 +5117,7 @@ ${err.stderr || err.message}`
5015
5117
  * Get the cache path for a remote
5016
5118
  */
5017
5119
  getCachePath(name) {
5018
- return path5.join(this.remotesDir, name);
5120
+ return path6.join(this.remotesDir, name);
5019
5121
  }
5020
5122
  /**
5021
5123
  * Load and cache the .skilltree config for a remote
@@ -5095,12 +5197,7 @@ ${err.stderr || err.message}`
5095
5197
  tags: this.parseTags(metadata.tags),
5096
5198
  createdAt: metadata.created ? new Date(metadata.created) : /* @__PURE__ */ new Date(),
5097
5199
  updatedAt: metadata.updated ? new Date(metadata.updated) : /* @__PURE__ */ new Date(),
5098
- status: metadata.status || "active",
5099
- metrics: {
5100
- usageCount: parseInt(metadata.usageCount) || 0,
5101
- successRate: parseFloat(metadata.successRate) || 0,
5102
- feedbackScores: []
5103
- }
5200
+ status: metadata.status || "active"
5104
5201
  };
5105
5202
  }
5106
5203
  /**
@@ -5169,9 +5266,6 @@ ${body.join("\n")}
5169
5266
  if (filter.author && skill.author !== filter.author) {
5170
5267
  return false;
5171
5268
  }
5172
- if (filter.minSuccessRate !== void 0 && skill.metrics.successRate < filter.minSuccessRate) {
5173
- return false;
5174
- }
5175
5269
  if (filter.createdAfter && skill.createdAt < filter.createdAfter) {
5176
5270
  return false;
5177
5271
  }
@@ -5183,7 +5277,11 @@ ${body.join("\n")}
5183
5277
  }
5184
5278
  };
5185
5279
 
5280
+ // src/federation/federation-manager.ts
5281
+ init_esm_shims();
5282
+
5186
5283
  // src/versioning/semver.ts
5284
+ init_esm_shims();
5187
5285
  function parseVersion(version) {
5188
5286
  const match = version.match(
5189
5287
  /^(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9.-]+))?(?:\+([a-zA-Z0-9.-]+))?$/
@@ -5733,14 +5831,16 @@ ${remote.instructions}` : remote.instructions,
5733
5831
  init_base();
5734
5832
 
5735
5833
  // src/storage/cached.ts
5834
+ init_esm_shims();
5736
5835
  init_base();
5737
5836
  import * as fs8 from "fs";
5738
- import * as path8 from "path";
5837
+ import * as path9 from "path";
5739
5838
 
5740
5839
  // src/storage/filesystem.ts
5840
+ init_esm_shims();
5741
5841
  init_base();
5742
5842
  import * as fs6 from "fs/promises";
5743
- import * as path6 from "path";
5843
+ import * as path7 from "path";
5744
5844
  var FilesystemStorageAdapter = class extends BaseStorageAdapter {
5745
5845
  constructor(config2) {
5746
5846
  super();
@@ -5751,7 +5851,7 @@ var FilesystemStorageAdapter = class extends BaseStorageAdapter {
5751
5851
  };
5752
5852
  this.skilltreeDir = getSkilltreeDir(this.config.basePath);
5753
5853
  this.skillsDir = getSkillsDir(this.config.basePath);
5754
- this.versionsDir = path6.join(this.skilltreeDir, ".versions");
5854
+ this.versionsDir = path7.join(this.skilltreeDir, ".versions");
5755
5855
  }
5756
5856
  async initialize() {
5757
5857
  await initSkilltreeDir(this.config.basePath);
@@ -5768,14 +5868,14 @@ var FilesystemStorageAdapter = class extends BaseStorageAdapter {
5768
5868
  }
5769
5869
  async saveSkill(skill) {
5770
5870
  this.ensureInitialized();
5771
- const skillDir = path6.join(this.skillsDir, skill.id);
5871
+ const skillDir = path7.join(this.skillsDir, skill.id);
5772
5872
  await fs6.mkdir(skillDir, { recursive: true });
5773
5873
  const skillContent = this.serializeSkill(skill);
5774
5874
  const skillFileName = this.config.openSkillsCompatible ? "SKILL.md" : "skill.md";
5775
- await fs6.writeFile(path6.join(skillDir, skillFileName), skillContent, "utf-8");
5875
+ await fs6.writeFile(path7.join(skillDir, skillFileName), skillContent, "utf-8");
5776
5876
  const metadata = this.createMetadata(skill);
5777
5877
  await fs6.writeFile(
5778
- path6.join(skillDir, ".skilltree.json"),
5878
+ path7.join(skillDir, ".skilltree.json"),
5779
5879
  JSON.stringify(metadata, null, 2),
5780
5880
  "utf-8"
5781
5881
  );
@@ -5833,7 +5933,7 @@ var FilesystemStorageAdapter = class extends BaseStorageAdapter {
5833
5933
  try {
5834
5934
  await fs6.rm(location.directory, { recursive: true });
5835
5935
  if (this.config.trackVersions) {
5836
- const versionDir = path6.join(this.versionsDir, id);
5936
+ const versionDir = path7.join(this.versionsDir, id);
5837
5937
  await fs6.rm(versionDir, { recursive: true }).catch(() => {
5838
5938
  });
5839
5939
  }
@@ -5861,13 +5961,13 @@ var FilesystemStorageAdapter = class extends BaseStorageAdapter {
5861
5961
  }
5862
5962
  ];
5863
5963
  }
5864
- const versionDir = path6.join(this.versionsDir, skillId);
5964
+ const versionDir = path7.join(this.versionsDir, skillId);
5865
5965
  const versions = [];
5866
5966
  try {
5867
5967
  const entries = await fs6.readdir(versionDir);
5868
5968
  for (const entry of entries) {
5869
5969
  if (!entry.endsWith(".json")) continue;
5870
- const versionPath = path6.join(versionDir, entry);
5970
+ const versionPath = path7.join(versionDir, entry);
5871
5971
  const content = await fs6.readFile(versionPath, "utf-8");
5872
5972
  const versionData = JSON.parse(content);
5873
5973
  versionData.createdAt = new Date(versionData.createdAt);
@@ -5990,11 +6090,6 @@ ${skill.instructions}
5990
6090
  status,
5991
6091
  parentVersion: parentVersion || void 0,
5992
6092
  derivedFrom: derivedFrom.length > 0 ? derivedFrom : void 0,
5993
- metrics: {
5994
- usageCount: 0,
5995
- successRate: 0,
5996
- feedbackScores: []
5997
- },
5998
6093
  source: metadata?.source,
5999
6094
  upstream,
6000
6095
  namespace: metadata?.namespace
@@ -6044,9 +6139,9 @@ ${skill.instructions}
6044
6139
  * Save a version snapshot
6045
6140
  */
6046
6141
  async saveVersionSnapshot(skill) {
6047
- const versionDir = path6.join(this.versionsDir, skill.id);
6142
+ const versionDir = path7.join(this.versionsDir, skill.id);
6048
6143
  await fs6.mkdir(versionDir, { recursive: true });
6049
- const versionFile = path6.join(versionDir, `${skill.version}.json`);
6144
+ const versionFile = path7.join(versionDir, `${skill.version}.json`);
6050
6145
  const versionData = {
6051
6146
  skillId: skill.id,
6052
6147
  version: skill.version,
@@ -6062,7 +6157,7 @@ ${skill.instructions}
6062
6157
  * Get a specific version of a skill
6063
6158
  */
6064
6159
  async getVersionedSkill(id, version) {
6065
- const versionFile = path6.join(this.versionsDir, id, `${version}.json`);
6160
+ const versionFile = path7.join(this.versionsDir, id, `${version}.json`);
6066
6161
  try {
6067
6162
  const content = await fs6.readFile(versionFile, "utf-8");
6068
6163
  const versionData = JSON.parse(content);
@@ -6081,7 +6176,7 @@ ${skill.instructions}
6081
6176
  * Delete a specific version
6082
6177
  */
6083
6178
  async deleteVersion(id, version) {
6084
- const versionFile = path6.join(this.versionsDir, id, `${version}.json`);
6179
+ const versionFile = path7.join(this.versionsDir, id, `${version}.json`);
6085
6180
  try {
6086
6181
  await fs6.unlink(versionFile);
6087
6182
  return true;
@@ -6115,7 +6210,7 @@ ${skill.instructions}
6115
6210
  * Load metadata for a skill directory
6116
6211
  */
6117
6212
  async loadMetadata(skillDir) {
6118
- const metadataPath = path6.join(skillDir, ".skilltree.json");
6213
+ const metadataPath = path7.join(skillDir, ".skilltree.json");
6119
6214
  try {
6120
6215
  const content = await fs6.readFile(metadataPath, "utf-8");
6121
6216
  return JSON.parse(content);
@@ -6127,7 +6222,7 @@ ${skill.instructions}
6127
6222
  * Save metadata for a skill directory
6128
6223
  */
6129
6224
  async saveMetadata(skillDir, metadata) {
6130
- const metadataPath = path6.join(skillDir, ".skilltree.json");
6225
+ const metadataPath = path7.join(skillDir, ".skilltree.json");
6131
6226
  await fs6.writeFile(metadataPath, JSON.stringify(metadata, null, 2), "utf-8");
6132
6227
  }
6133
6228
  // ==========================================================================
@@ -6193,9 +6288,9 @@ var CachedStorageAdapter = class extends BaseStorageAdapter {
6193
6288
  super();
6194
6289
  this.cache = null;
6195
6290
  this.basePath = config2.basePath;
6196
- this.cacheDir = path8.join(config2.basePath, ".skilltree", ".cache");
6197
- this.dbPath = path8.join(this.cacheDir, "index.db");
6198
- this.manifestPath = path8.join(this.cacheDir, "manifest.json");
6291
+ this.cacheDir = path9.join(config2.basePath, ".skilltree", ".cache");
6292
+ this.dbPath = path9.join(this.cacheDir, "index.db");
6293
+ this.manifestPath = path9.join(this.cacheDir, "manifest.json");
6199
6294
  this.source = new FilesystemStorageAdapter({
6200
6295
  basePath: config2.basePath,
6201
6296
  openSkillsCompatible: config2.openSkillsCompatible ?? true,
@@ -6397,7 +6492,11 @@ var CachedStorageAdapter = class extends BaseStorageAdapter {
6397
6492
  }
6398
6493
  };
6399
6494
 
6495
+ // src/versioning/index.ts
6496
+ init_esm_shims();
6497
+
6400
6498
  // src/versioning/lineage.ts
6499
+ init_esm_shims();
6401
6500
  var LineageTracker = class {
6402
6501
  constructor(storage) {
6403
6502
  this.storage = storage;
@@ -6441,11 +6540,6 @@ var LineageTracker = class {
6441
6540
  createdAt: /* @__PURE__ */ new Date(),
6442
6541
  updatedAt: /* @__PURE__ */ new Date(),
6443
6542
  status: "draft",
6444
- metrics: {
6445
- usageCount: 0,
6446
- successRate: 0,
6447
- feedbackScores: []
6448
- },
6449
6543
  source: {
6450
6544
  type: "composed",
6451
6545
  importedAt: /* @__PURE__ */ new Date()
@@ -6645,7 +6739,11 @@ ${source}`;
6645
6739
  }
6646
6740
  };
6647
6741
 
6742
+ // src/versioning/merge.ts
6743
+ init_esm_shims();
6744
+
6648
6745
  // src/hooks/registry.ts
6746
+ init_esm_shims();
6649
6747
  import { randomUUID } from "crypto";
6650
6748
  var PRIORITY_ORDER = {
6651
6749
  high: 0,
@@ -6830,8 +6928,9 @@ var HookRegistry = class {
6830
6928
  var hookRegistry = new HookRegistry();
6831
6929
 
6832
6930
  // src/materialization/materializer.ts
6931
+ init_esm_shims();
6833
6932
  import * as fs10 from "fs";
6834
- import * as path10 from "path";
6933
+ import * as path11 from "path";
6835
6934
  var SKILLTREE_MARKER_START = "<!-- SKILLTREE_START -->";
6836
6935
  var SKILLTREE_MARKER_END = "<!-- SKILLTREE_END -->";
6837
6936
  var Materializer = class {
@@ -6849,7 +6948,7 @@ var Materializer = class {
6849
6948
  return this.config.mode ?? "symlink";
6850
6949
  }
6851
6950
  get skillsSourceDir() {
6852
- return path10.join(this.basePath, ".skilltree", "skills");
6951
+ return path11.join(this.basePath, ".skilltree", "skills");
6853
6952
  }
6854
6953
  /**
6855
6954
  * Initial materialization: create all symlinks/copies + generate AGENTS.md
@@ -6892,11 +6991,11 @@ var Materializer = class {
6892
6991
  * Materialize a skill to all configured paths (symlink or copy)
6893
6992
  */
6894
6993
  async ensureMaterialized(skillId) {
6895
- const sourcePath = path10.join(this.skillsSourceDir, skillId);
6994
+ const sourcePath = path11.join(this.skillsSourceDir, skillId);
6896
6995
  if (!fs10.existsSync(sourcePath)) return;
6897
6996
  for (const targetBase of this.config.symlinkPaths ?? []) {
6898
6997
  const targetDir = this.resolvePath(targetBase);
6899
- const targetPath = path10.join(targetDir, skillId);
6998
+ const targetPath = path11.join(targetDir, skillId);
6900
6999
  if (this.mode === "copy") {
6901
7000
  this.copyDir(sourcePath, targetPath);
6902
7001
  } else {
@@ -6908,19 +7007,19 @@ var Materializer = class {
6908
7007
  * Remove a materialized skill from all configured paths
6909
7008
  */
6910
7009
  async removeMaterialized(skillId) {
6911
- const sourcePath = path10.resolve(path10.join(this.skillsSourceDir, skillId));
7010
+ const sourcePath = path11.resolve(path11.join(this.skillsSourceDir, skillId));
6912
7011
  for (const targetBase of this.config.symlinkPaths ?? []) {
6913
- const targetPath = path10.join(this.resolvePath(targetBase), skillId);
7012
+ const targetPath = path11.join(this.resolvePath(targetBase), skillId);
6914
7013
  if (!fs10.existsSync(targetPath)) continue;
6915
7014
  if (this.mode === "copy") {
6916
- const markerPath = path10.join(targetPath, ".skilltree-managed");
7015
+ const markerPath = path11.join(targetPath, ".skilltree-managed");
6917
7016
  if (fs10.existsSync(markerPath)) {
6918
7017
  fs10.rmSync(targetPath, { recursive: true, force: true });
6919
7018
  }
6920
7019
  } else {
6921
7020
  try {
6922
7021
  const linkTarget = fs10.readlinkSync(targetPath);
6923
- if (path10.resolve(linkTarget) === sourcePath) {
7022
+ if (path11.resolve(linkTarget) === sourcePath) {
6924
7023
  fs10.unlinkSync(targetPath);
6925
7024
  }
6926
7025
  } catch {
@@ -6935,7 +7034,7 @@ var Materializer = class {
6935
7034
  if (fs10.existsSync(targetPath)) {
6936
7035
  try {
6937
7036
  const existing = fs10.readlinkSync(targetPath);
6938
- if (path10.resolve(existing) === path10.resolve(sourcePath)) return;
7037
+ if (path11.resolve(existing) === path11.resolve(sourcePath)) return;
6939
7038
  fs10.unlinkSync(targetPath);
6940
7039
  } catch {
6941
7040
  return;
@@ -6957,7 +7056,7 @@ var Materializer = class {
6957
7056
  */
6958
7057
  copyDir(sourcePath, targetPath) {
6959
7058
  if (fs10.existsSync(targetPath)) {
6960
- const markerPath = path10.join(targetPath, ".skilltree-managed");
7059
+ const markerPath = path11.join(targetPath, ".skilltree-managed");
6961
7060
  if (fs10.existsSync(markerPath)) {
6962
7061
  fs10.rmSync(targetPath, { recursive: true, force: true });
6963
7062
  } else {
@@ -6966,7 +7065,7 @@ var Materializer = class {
6966
7065
  }
6967
7066
  fs10.cpSync(sourcePath, targetPath, { recursive: true });
6968
7067
  fs10.writeFileSync(
6969
- path10.join(targetPath, ".skilltree-managed"),
7068
+ path11.join(targetPath, ".skilltree-managed"),
6970
7069
  JSON.stringify({ source: sourcePath, copiedAt: (/* @__PURE__ */ new Date()).toISOString() })
6971
7070
  );
6972
7071
  }
@@ -7035,7 +7134,7 @@ ${SKILLTREE_MARKER_END}`;
7035
7134
  fs10.writeFileSync(resolvedPath, existing + "\n\n" + markedContent + "\n");
7036
7135
  return;
7037
7136
  }
7038
- const dir = path10.dirname(resolvedPath);
7137
+ const dir = path11.dirname(resolvedPath);
7039
7138
  if (!fs10.existsSync(dir)) {
7040
7139
  fs10.mkdirSync(dir, { recursive: true });
7041
7140
  }
@@ -7055,18 +7154,18 @@ ${SKILLTREE_MARKER_END}`;
7055
7154
  if (!fs10.existsSync(resolved)) continue;
7056
7155
  const entries = fs10.readdirSync(resolved);
7057
7156
  for (const entry of entries) {
7058
- const entryPath = path10.join(resolved, entry);
7157
+ const entryPath = path11.join(resolved, entry);
7059
7158
  if (skillIds.has(entry)) continue;
7060
7159
  if (this.mode === "copy") {
7061
- const markerPath = path10.join(entryPath, ".skilltree-managed");
7160
+ const markerPath = path11.join(entryPath, ".skilltree-managed");
7062
7161
  if (fs10.existsSync(markerPath)) {
7063
7162
  fs10.rmSync(entryPath, { recursive: true, force: true });
7064
7163
  }
7065
7164
  } else {
7066
7165
  try {
7067
7166
  const linkTarget = fs10.readlinkSync(entryPath);
7068
- const resolvedTarget = path10.resolve(linkTarget);
7069
- if (resolvedTarget.startsWith(this.skillsSourceDir + path10.sep) || resolvedTarget === this.skillsSourceDir) {
7167
+ const resolvedTarget = path11.resolve(linkTarget);
7168
+ if (resolvedTarget.startsWith(this.skillsSourceDir + path11.sep) || resolvedTarget === this.skillsSourceDir) {
7070
7169
  fs10.unlinkSync(entryPath);
7071
7170
  }
7072
7171
  } catch {
@@ -7153,10 +7252,10 @@ ${SKILLTREE_MARKER_END}`;
7153
7252
  */
7154
7253
  resolvePath(p) {
7155
7254
  if (p.startsWith("~")) {
7156
- return path10.join(process.env.HOME || process.env.USERPROFILE || "", p.slice(1));
7255
+ return path11.join(process.env.HOME || process.env.USERPROFILE || "", p.slice(1));
7157
7256
  }
7158
- if (path10.isAbsolute(p)) return p;
7159
- return path10.resolve(this.basePath, p);
7257
+ if (path11.isAbsolute(p)) return p;
7258
+ return path11.resolve(this.basePath, p);
7160
7259
  }
7161
7260
  };
7162
7261
 
@@ -7572,41 +7671,16 @@ var SkillBank = class {
7572
7671
  }
7573
7672
  }
7574
7673
  /**
7575
- * Handle events from serving layer
7674
+ * Handle events from serving layer.
7675
+ *
7676
+ * The `loadout:changed` event is currently the only one we react to.
7677
+ * Earlier versions also handled `skill:used` / `skill:feedback` to mutate
7678
+ * `Skill.metrics`, but skill-tree no longer tracks per-skill usage —
7679
+ * cognitive-core owns that signal via `playbook.evolution.*`. See
7680
+ * docs/SKILL_TREE_METRICS_DEPRECATION.md.
7576
7681
  */
7577
7682
  async handleServingEvent(event) {
7578
7683
  switch (event.type) {
7579
- case "skill:used":
7580
- const skill = await this.storage.getSkill(event.skillId);
7581
- if (skill) {
7582
- skill.metrics.usageCount++;
7583
- skill.metrics.lastUsed = /* @__PURE__ */ new Date();
7584
- if (event.success) {
7585
- const total = skill.metrics.usageCount;
7586
- const currentSuccesses = skill.metrics.successRate * (total - 1);
7587
- skill.metrics.successRate = (currentSuccesses + 1) / total;
7588
- } else {
7589
- const total = skill.metrics.usageCount;
7590
- const currentSuccesses = skill.metrics.successRate * (total - 1);
7591
- skill.metrics.successRate = currentSuccesses / total;
7592
- }
7593
- skill.updatedAt = /* @__PURE__ */ new Date();
7594
- await this.storage.saveSkill(skill);
7595
- }
7596
- break;
7597
- case "skill:feedback":
7598
- const feedbackSkill = await this.storage.getSkill(event.skillId);
7599
- if (feedbackSkill) {
7600
- feedbackSkill.metrics.feedbackScores.push(event.score);
7601
- if (feedbackSkill.metrics.feedbackScores.length > 50) {
7602
- feedbackSkill.metrics.feedbackScores = feedbackSkill.metrics.feedbackScores.slice(-50);
7603
- }
7604
- feedbackSkill.updatedAt = /* @__PURE__ */ new Date();
7605
- await this.storage.saveSkill(feedbackSkill);
7606
- }
7607
- break;
7608
- case "skill:requested":
7609
- break;
7610
7684
  case "loadout:changed":
7611
7685
  break;
7612
7686
  }
@@ -7628,26 +7702,17 @@ var SkillBank = class {
7628
7702
  deprecated: 0,
7629
7703
  experimental: 0
7630
7704
  },
7631
- byTag: {},
7632
- avgSuccessRate: 0,
7633
- totalUsage: 0
7705
+ byTag: {}
7634
7706
  };
7635
7707
  if (this.namespaceConfig) {
7636
7708
  stats.byScope = { personal: 0, team: 0, global: 0 };
7637
7709
  stats.byVisibility = { private: 0, "team-only": 0, public: 0 };
7638
7710
  }
7639
- let successRateSum = 0;
7640
- let successRateCount = 0;
7641
7711
  for (const skill of skills) {
7642
7712
  stats.byStatus[skill.status]++;
7643
7713
  for (const tag of skill.tags) {
7644
7714
  stats.byTag[tag] = (stats.byTag[tag] || 0) + 1;
7645
7715
  }
7646
- stats.totalUsage += skill.metrics.usageCount;
7647
- if (skill.metrics.successRate > 0) {
7648
- successRateSum += skill.metrics.successRate;
7649
- successRateCount++;
7650
- }
7651
7716
  if (stats.byScope && stats.byVisibility) {
7652
7717
  const scope = skill.namespace?.scope || "personal";
7653
7718
  const visibility = skill.namespace?.visibility || "private";
@@ -7655,7 +7720,6 @@ var SkillBank = class {
7655
7720
  stats.byVisibility[visibility]++;
7656
7721
  }
7657
7722
  }
7658
- stats.avgSuccessRate = successRateCount > 0 ? successRateSum / successRateCount : 0;
7659
7723
  return stats;
7660
7724
  }
7661
7725
  /**
@@ -7718,15 +7782,38 @@ var SkillBank = class {
7718
7782
  };
7719
7783
 
7720
7784
  // src/storage/index.ts
7785
+ init_esm_shims();
7721
7786
  init_base();
7722
7787
  init_sqlite();
7723
7788
 
7789
+ // src/storage/migration.ts
7790
+ init_esm_shims();
7791
+
7724
7792
  // src/agents/index.ts
7793
+ init_esm_shims();
7725
7794
  init_types();
7726
7795
  init_generator();
7727
7796
  init_parser();
7728
7797
  init_sync();
7729
7798
 
7799
+ // src/hooks/index.ts
7800
+ init_esm_shims();
7801
+
7802
+ // src/hooks/builtin.ts
7803
+ init_esm_shims();
7804
+
7805
+ // src/serving/index.ts
7806
+ init_esm_shims();
7807
+
7808
+ // src/materialization/index.ts
7809
+ init_esm_shims();
7810
+
7811
+ // src/sync/index.ts
7812
+ init_esm_shims();
7813
+
7814
+ // src/sync/hierarchical-sync-adapter.ts
7815
+ init_esm_shims();
7816
+
7730
7817
  // src/sync/index.ts
7731
7818
  function createDefaultSyncConfig(remoteUrl, agentId, options) {
7732
7819
  return {
@@ -7756,10 +7843,15 @@ function createDefaultSyncConfig(remoteUrl, agentId, options) {
7756
7843
  }
7757
7844
 
7758
7845
  // src/services/indexer.ts
7759
- import * as path12 from "path";
7846
+ init_esm_shims();
7847
+ import * as path13 from "path";
7760
7848
  import * as fs12 from "fs";
7761
7849
 
7850
+ // src/config/index.ts
7851
+ init_esm_shims();
7852
+
7762
7853
  // src/config/types.ts
7854
+ init_esm_shims();
7763
7855
  var DEFAULT_CONFIG6 = {
7764
7856
  storage: {
7765
7857
  path: "~/.skill-tree"
@@ -7794,8 +7886,9 @@ var DEFAULT_CONFIG6 = {
7794
7886
  };
7795
7887
 
7796
7888
  // src/config/loader.ts
7889
+ init_esm_shims();
7797
7890
  import * as fs11 from "fs";
7798
- import * as path11 from "path";
7891
+ import * as path12 from "path";
7799
7892
  import * as os from "os";
7800
7893
  var ENV_MAPPINGS = {
7801
7894
  GITHUB_TOKEN: "indexer.github_token",
@@ -7806,17 +7899,17 @@ var ENV_MAPPINGS = {
7806
7899
  SKILL_TREE_NO_COLOR: "cli.color"
7807
7900
  };
7808
7901
  function getConfigDir() {
7809
- return path11.join(os.homedir(), ".skill-tree");
7902
+ return path12.join(os.homedir(), ".skill-tree");
7810
7903
  }
7811
7904
  function getConfigPath() {
7812
- return path11.join(getConfigDir(), "config.yaml");
7905
+ return path12.join(getConfigDir(), "config.yaml");
7813
7906
  }
7814
7907
  function expandPath(filePath) {
7815
7908
  if (filePath.startsWith("~/")) {
7816
- return path11.join(os.homedir(), filePath.slice(2));
7909
+ return path12.join(os.homedir(), filePath.slice(2));
7817
7910
  }
7818
7911
  if (filePath.startsWith("~")) {
7819
- return path11.join(os.homedir(), filePath.slice(1));
7912
+ return path12.join(os.homedir(), filePath.slice(1));
7820
7913
  }
7821
7914
  return filePath;
7822
7915
  }
@@ -7845,8 +7938,8 @@ function substituteEnvVarsInObject(obj) {
7845
7938
  }
7846
7939
  return obj;
7847
7940
  }
7848
- function setNestedProperty(obj, path18, value) {
7849
- const parts = path18.split(".");
7941
+ function setNestedProperty(obj, path19, value) {
7942
+ const parts = path19.split(".");
7850
7943
  let current = obj;
7851
7944
  for (let i = 0; i < parts.length - 1; i++) {
7852
7945
  const part = parts[i];
@@ -8005,8 +8098,8 @@ var ConfigLoader = class {
8005
8098
  /**
8006
8099
  * Get a specific config value by path
8007
8100
  */
8008
- get(path18) {
8009
- const parts = path18.split(".");
8101
+ get(path19) {
8102
+ const parts = path19.split(".");
8010
8103
  let current = this.getConfig();
8011
8104
  for (const part of parts) {
8012
8105
  if (current === null || typeof current !== "object") {
@@ -8026,7 +8119,7 @@ var ConfigLoader = class {
8026
8119
  * Create default config file
8027
8120
  */
8028
8121
  createDefaultConfigFile() {
8029
- const configDir = path11.dirname(expandPath(this.configPath));
8122
+ const configDir = path12.dirname(expandPath(this.configPath));
8030
8123
  if (!fs11.existsSync(configDir)) {
8031
8124
  fs11.mkdirSync(configDir, { recursive: true });
8032
8125
  }
@@ -8089,6 +8182,7 @@ function loadConfig(configPath) {
8089
8182
  }
8090
8183
 
8091
8184
  // src/import/converter.ts
8185
+ init_esm_shims();
8092
8186
  function convertIndexerSkill(indexerSkill) {
8093
8187
  const warnings = [];
8094
8188
  const instructions = indexerSkill.content || "";
@@ -8115,11 +8209,6 @@ function convertIndexerSkill(indexerSkill) {
8115
8209
  createdAt: new Date(indexerSkill.scrapedAt),
8116
8210
  updatedAt: new Date(indexerSkill.updatedAt),
8117
8211
  status,
8118
- metrics: {
8119
- usageCount: 0,
8120
- successRate: 0,
8121
- feedbackScores: []
8122
- },
8123
8212
  source: {
8124
8213
  type: "imported",
8125
8214
  location: indexerSkill.sourceUrl,
@@ -8215,8 +8304,8 @@ var IndexerService = class {
8215
8304
  const mod = this.serviceConfig.scraperModules;
8216
8305
  this.databaseModule = mod;
8217
8306
  if (mod.createDatabase) {
8218
- const dbPath = this.serviceConfig.databasePath || path12.join(process.cwd(), "scraper/data/skills.db");
8219
- const dbDir = path12.dirname(dbPath);
8307
+ const dbPath = this.serviceConfig.databasePath || path13.join(process.cwd(), "scraper/data/skills.db");
8308
+ const dbDir = path13.dirname(dbPath);
8220
8309
  if (!fs12.existsSync(dbDir)) fs12.mkdirSync(dbDir, { recursive: true });
8221
8310
  this.db = mod.createDatabase({ type: "sqlite", path: dbPath });
8222
8311
  if (this.db.connect) await this.db.connect();
@@ -8229,7 +8318,7 @@ var IndexerService = class {
8229
8318
  const scraperConfig = {
8230
8319
  githubToken: config2.githubToken || "",
8231
8320
  cacheEnabled: true,
8232
- cacheDir: config2.cacheDir || path12.join(process.cwd(), ".cache/scraper"),
8321
+ cacheDir: config2.cacheDir || path13.join(process.cwd(), ".cache/scraper"),
8233
8322
  cacheTtlSeconds: config2.cacheTtlSeconds || 3600,
8234
8323
  requestDelayMs: 100,
8235
8324
  maxRetries: 3
@@ -8282,15 +8371,15 @@ var IndexerService = class {
8282
8371
  }
8283
8372
  const possiblePaths = [
8284
8373
  // Relative to this file in dist
8285
- path12.resolve(__dirname, "../../scraper/dist"),
8374
+ path13.resolve(__dirname, "../../scraper/dist"),
8286
8375
  // Relative to project root
8287
- path12.resolve(process.cwd(), "scraper/dist"),
8376
+ path13.resolve(process.cwd(), "scraper/dist"),
8288
8377
  // Absolute paths from config
8289
- this.serviceConfig.cacheDir ? path12.resolve(this.serviceConfig.cacheDir, "../scraper/dist") : null
8378
+ this.serviceConfig.cacheDir ? path13.resolve(this.serviceConfig.cacheDir, "../scraper/dist") : null
8290
8379
  ].filter(Boolean);
8291
8380
  let scraperBasePath = null;
8292
8381
  for (const basePath of possiblePaths) {
8293
- const scraperIndex = path12.join(basePath, "scraper/index.js");
8382
+ const scraperIndex = path13.join(basePath, "scraper/index.js");
8294
8383
  if (fs12.existsSync(scraperIndex)) {
8295
8384
  scraperBasePath = basePath;
8296
8385
  break;
@@ -8301,9 +8390,9 @@ var IndexerService = class {
8301
8390
  "Scraper modules not found. Run `cd scraper && npm run build` first."
8302
8391
  );
8303
8392
  }
8304
- const scraperPath = path12.join(scraperBasePath, "scraper/index.js");
8305
- const indexerPath = path12.join(scraperBasePath, "indexer/index.js");
8306
- const databasePath = path12.join(scraperBasePath, "database/index.js");
8393
+ const scraperPath = path13.join(scraperBasePath, "scraper/index.js");
8394
+ const indexerPath = path13.join(scraperBasePath, "indexer/index.js");
8395
+ const databasePath = path13.join(scraperBasePath, "database/index.js");
8307
8396
  this.scraperModule = await import(
8308
8397
  /* webpackIgnore: true */
8309
8398
  scraperPath
@@ -8317,7 +8406,7 @@ var IndexerService = class {
8317
8406
  databasePath
8318
8407
  );
8319
8408
  if (this.databaseModule.createDatabase) {
8320
- const dbPath = this.serviceConfig.databasePath || path12.join(process.cwd(), "scraper/data/skills.db");
8409
+ const dbPath = this.serviceConfig.databasePath || path13.join(process.cwd(), "scraper/data/skills.db");
8321
8410
  this.db = this.databaseModule.createDatabase(dbPath);
8322
8411
  }
8323
8412
  this.initialized = true;
@@ -8957,14 +9046,19 @@ function createIntegratedIndexer(skillBank, config2 = {}) {
8957
9046
  }
8958
9047
 
8959
9048
  // src/index.ts
8960
- var VERSION = "0.1.0";
9049
+ var VERSION = "0.2.0";
8961
9050
 
8962
9051
  // src/cli/commands/list.ts
9052
+ init_esm_shims();
8963
9053
  import { Command } from "commander";
8964
9054
 
9055
+ // src/cli/utils/skillbank.ts
9056
+ init_esm_shims();
9057
+
8965
9058
  // src/cli/utils/paths.ts
9059
+ init_esm_shims();
8966
9060
  import * as fs13 from "fs";
8967
- import * as path13 from "path";
9061
+ import * as path14 from "path";
8968
9062
  import * as os2 from "os";
8969
9063
  var DEFAULT_PATHS = [
8970
9064
  ".claude/skills",
@@ -8978,7 +9072,7 @@ var DEFAULT_PATHS = [
8978
9072
  ];
8979
9073
  function expandHome(p) {
8980
9074
  if (p.startsWith("~/")) {
8981
- return path13.join(os2.homedir(), p.slice(2));
9075
+ return path14.join(os2.homedir(), p.slice(2));
8982
9076
  }
8983
9077
  return p;
8984
9078
  }
@@ -8992,19 +9086,19 @@ function dirExists(p) {
8992
9086
  function resolveSkillPath(explicitPath) {
8993
9087
  if (explicitPath) {
8994
9088
  const resolved = expandHome(explicitPath);
8995
- return path13.resolve(resolved);
9089
+ return path14.resolve(resolved);
8996
9090
  }
8997
9091
  const envPath = process.env.SKILL_TREE_PATH;
8998
9092
  if (envPath) {
8999
- return path13.resolve(expandHome(envPath));
9093
+ return path14.resolve(expandHome(envPath));
9000
9094
  }
9001
9095
  for (const defaultPath of DEFAULT_PATHS) {
9002
- const resolved = path13.resolve(expandHome(defaultPath));
9096
+ const resolved = path14.resolve(expandHome(defaultPath));
9003
9097
  if (dirExists(resolved)) {
9004
9098
  return resolved;
9005
9099
  }
9006
9100
  }
9007
- return path13.resolve(".claude/skills");
9101
+ return path14.resolve(".claude/skills");
9008
9102
  }
9009
9103
  function ensureDir(dir) {
9010
9104
  if (!dirExists(dir)) {
@@ -9045,6 +9139,7 @@ function getSkillPath(options) {
9045
9139
  var getSkillBank = createSkillBankFromOptions;
9046
9140
 
9047
9141
  // src/cli/utils/output.ts
9142
+ init_esm_shims();
9048
9143
  import chalk from "chalk";
9049
9144
  function formatSkillLine(skill) {
9050
9145
  const status = formatStatus(skill.status);
@@ -9083,10 +9178,6 @@ function formatSkillDetail(skill) {
9083
9178
  if (skill.derivedFrom && skill.derivedFrom.length > 0) {
9084
9179
  lines.push(`${chalk.dim("Derived:")} ${skill.derivedFrom.join(", ")}`);
9085
9180
  }
9086
- const { usageCount, successRate } = skill.metrics;
9087
- if (usageCount > 0) {
9088
- lines.push(`${chalk.dim("Usage:")} ${usageCount} times, ${Math.round(successRate * 100)}% success`);
9089
- }
9090
9181
  lines.push("");
9091
9182
  lines.push(chalk.dim("Description"));
9092
9183
  lines.push(chalk.dim("\u2500".repeat(50)));
@@ -9166,11 +9257,6 @@ function formatStats(stats) {
9166
9257
  }
9167
9258
  lines.push("");
9168
9259
  }
9169
- if (stats.totalUsage > 0) {
9170
- lines.push(chalk.dim("Usage:"));
9171
- lines.push(` Total uses: ${stats.totalUsage}`);
9172
- lines.push(` Avg success: ${Math.round(stats.avgSuccessRate * 100)}%`);
9173
- }
9174
9260
  return lines.join("\n");
9175
9261
  }
9176
9262
  function printError(message) {
@@ -9235,6 +9321,7 @@ var listCommand = new Command("list").description("List all skills").option("-s,
9235
9321
  });
9236
9322
 
9237
9323
  // src/cli/commands/show.ts
9324
+ init_esm_shims();
9238
9325
  import { Command as Command2 } from "commander";
9239
9326
  var showCommand = new Command2("show").description("Show skill details").argument("<id>", "Skill ID").option("-v, --version <version>", "Show specific version").action(async (id, options, command) => {
9240
9327
  const globalOpts = command.optsWithGlobals();
@@ -9257,6 +9344,7 @@ var showCommand = new Command2("show").description("Show skill details").argumen
9257
9344
  });
9258
9345
 
9259
9346
  // src/cli/commands/search.ts
9347
+ init_esm_shims();
9260
9348
  import { Command as Command3 } from "commander";
9261
9349
  var searchCommand = new Command3("search").description("Search skills by text").argument("<query>", "Search query").action(async (query, options, command) => {
9262
9350
  const globalOpts = command.optsWithGlobals();
@@ -9289,6 +9377,7 @@ var searchCommand = new Command3("search").description("Search skills by text").
9289
9377
  });
9290
9378
 
9291
9379
  // src/cli/commands/stats.ts
9380
+ init_esm_shims();
9292
9381
  import { Command as Command4 } from "commander";
9293
9382
  var statsCommand = new Command4("stats").description("Show skill bank statistics").action(async (options, command) => {
9294
9383
  const globalOpts = command.optsWithGlobals();
@@ -9307,6 +9396,7 @@ var statsCommand = new Command4("stats").description("Show skill bank statistics
9307
9396
  });
9308
9397
 
9309
9398
  // src/cli/commands/versions.ts
9399
+ init_esm_shims();
9310
9400
  import { Command as Command5 } from "commander";
9311
9401
  var versionsCommand = new Command5("versions").description("Show version history for a skill").argument("<id>", "Skill ID").action(async (id, options, command) => {
9312
9402
  const globalOpts = command.optsWithGlobals();
@@ -9329,6 +9419,7 @@ var versionsCommand = new Command5("versions").description("Show version history
9329
9419
  });
9330
9420
 
9331
9421
  // src/cli/commands/diff.ts
9422
+ init_esm_shims();
9332
9423
  import { Command as Command6 } from "commander";
9333
9424
  var diffCommand = new Command6("diff").description("Compare two versions of a skill").argument("<id>", "Skill ID").argument("<version-a>", "First version").argument("<version-b>", "Second version").action(async (id, versionA, versionB, options, command) => {
9334
9425
  const globalOpts = command.optsWithGlobals();
@@ -9347,6 +9438,7 @@ var diffCommand = new Command6("diff").description("Compare two versions of a sk
9347
9438
  });
9348
9439
 
9349
9440
  // src/cli/commands/rollback.ts
9441
+ init_esm_shims();
9350
9442
  import { Command as Command7 } from "commander";
9351
9443
  var rollbackCommand = new Command7("rollback").description("Rollback a skill to a previous version").argument("<id>", "Skill ID").requiredOption("--to <version>", "Version to rollback to").action(async (id, options, command) => {
9352
9444
  const globalOpts = command.optsWithGlobals();
@@ -9365,6 +9457,7 @@ var rollbackCommand = new Command7("rollback").description("Rollback a skill to
9365
9457
  });
9366
9458
 
9367
9459
  // src/cli/commands/fork.ts
9460
+ init_esm_shims();
9368
9461
  import { Command as Command8 } from "commander";
9369
9462
  var forkCommand = new Command8("fork").description("Fork a skill to create a variant").argument("<id>", "Skill ID to fork from").requiredOption("--new-id <id>", "ID for the new forked skill").requiredOption("--reason <reason>", "Reason for forking").option("--name <name>", "Name for the forked skill").option("--from-version <version>", "Version to fork from (defaults to latest)").action(async (id, options, command) => {
9370
9463
  const globalOpts = command.optsWithGlobals();
@@ -9388,6 +9481,7 @@ var forkCommand = new Command8("fork").description("Fork a skill to create a var
9388
9481
  });
9389
9482
 
9390
9483
  // src/cli/commands/deprecate.ts
9484
+ init_esm_shims();
9391
9485
  import { Command as Command9 } from "commander";
9392
9486
  var deprecateCommand = new Command9("deprecate").description("Mark a skill as deprecated").argument("<id>", "Skill ID").action(async (id, options, command) => {
9393
9487
  const globalOpts = command.optsWithGlobals();
@@ -9406,6 +9500,7 @@ var deprecateCommand = new Command9("deprecate").description("Mark a skill as de
9406
9500
  });
9407
9501
 
9408
9502
  // src/cli/commands/activate.ts
9503
+ init_esm_shims();
9409
9504
  import { Command as Command10 } from "commander";
9410
9505
  var activateCommand = new Command10("activate").description("Mark a skill as active").argument("<id>", "Skill ID").action(async (id, options, command) => {
9411
9506
  const globalOpts = command.optsWithGlobals();
@@ -9431,6 +9526,7 @@ var activateCommand = new Command10("activate").description("Mark a skill as act
9431
9526
  });
9432
9527
 
9433
9528
  // src/cli/commands/delete.ts
9529
+ init_esm_shims();
9434
9530
  import { Command as Command11 } from "commander";
9435
9531
  var deleteCommand = new Command11("delete").description("Delete a skill").argument("<id>", "Skill ID").option("-f, --force", "Skip confirmation").option("-v, --version <version>", "Delete specific version only").action(async (id, options, command) => {
9436
9532
  const globalOpts = command.optsWithGlobals();
@@ -9463,6 +9559,7 @@ var deleteCommand = new Command11("delete").description("Delete a skill").argume
9463
9559
  });
9464
9560
 
9465
9561
  // src/cli/commands/export.ts
9562
+ init_esm_shims();
9466
9563
  import { Command as Command12 } from "commander";
9467
9564
  import * as fs14 from "fs";
9468
9565
  var exportCommand = new Command12("export").description("Export all skills to JSON").option("-o, --output <file>", "Output file path (defaults to stdout)").action(async (options, command) => {
@@ -9486,14 +9583,19 @@ var exportCommand = new Command12("export").description("Export all skills to JS
9486
9583
  });
9487
9584
 
9488
9585
  // src/cli/commands/import.ts
9586
+ init_esm_shims();
9489
9587
  import { Command as Command13 } from "commander";
9490
9588
  import * as fs15 from "fs";
9491
9589
 
9590
+ // src/import/index.ts
9591
+ init_esm_shims();
9592
+
9492
9593
  // src/import/detect.ts
9594
+ init_esm_shims();
9493
9595
  function isSkillTreeSkill(obj) {
9494
9596
  if (typeof obj !== "object" || obj === null) return false;
9495
9597
  const skill = obj;
9496
- return typeof skill.id === "string" && typeof skill.name === "string" && typeof skill.version === "string" && typeof skill.instructions === "string" && typeof skill.metrics === "object";
9598
+ return typeof skill.id === "string" && typeof skill.name === "string" && typeof skill.version === "string" && typeof skill.instructions === "string";
9497
9599
  }
9498
9600
  function isIndexerSkill(obj) {
9499
9601
  if (typeof obj !== "object" || obj === null) return false;
@@ -9584,9 +9686,6 @@ var importCommand = new Command13("import").description("Import skills from JSON
9584
9686
  for (const skill of skills) {
9585
9687
  skill.createdAt = new Date(skill.createdAt);
9586
9688
  skill.updatedAt = new Date(skill.updatedAt);
9587
- if (skill.metrics.lastUsed) {
9588
- skill.metrics.lastUsed = new Date(skill.metrics.lastUsed);
9589
- }
9590
9689
  if (skill.source?.importedAt) {
9591
9690
  skill.source.importedAt = new Date(skill.source.importedAt);
9592
9691
  }
@@ -9615,9 +9714,11 @@ var importCommand = new Command13("import").description("Import skills from JSON
9615
9714
  });
9616
9715
 
9617
9716
  // src/cli/commands/indexer/index.ts
9717
+ init_esm_shims();
9618
9718
  import { Command as Command20 } from "commander";
9619
9719
 
9620
9720
  // src/cli/commands/indexer/scrape.ts
9721
+ init_esm_shims();
9621
9722
  import { Command as Command14 } from "commander";
9622
9723
  import { spawn } from "child_process";
9623
9724
  var scrapeCommand = new Command14("scrape").description("Scrape skills from GitHub sources").argument("[url]", "Repository or awesome-list URL").option("-d, --discover", "Discover from default sources").option("-f, --force", "Force scrape even if no changes detected").option("--standalone", "Use standalone skillindexer CLI (fallback)").option("--import", "Auto-import scraped skills into skill-tree", true).action(async (url, options, command) => {
@@ -9742,6 +9843,7 @@ async function runSkillIndexer(args, quiet) {
9742
9843
  }
9743
9844
 
9744
9845
  // src/cli/commands/indexer/classify.ts
9846
+ init_esm_shims();
9745
9847
  import { Command as Command15 } from "commander";
9746
9848
  import { spawn as spawn2 } from "child_process";
9747
9849
  var classifyCommand = new Command15("classify").description("Classify unindexed skills using AI").option("-s, --skill <id>", "Classify specific skill by ID").option("--all", "Re-classify all skills (including already indexed)").option("--standalone", "Use standalone skillindexer CLI (fallback)").action(async (options, command) => {
@@ -9836,6 +9938,7 @@ async function runSkillIndexer2(args, quiet) {
9836
9938
  }
9837
9939
 
9838
9940
  // src/cli/commands/indexer/taxonomy.ts
9941
+ init_esm_shims();
9839
9942
  import { Command as Command16 } from "commander";
9840
9943
  import { spawn as spawn3 } from "child_process";
9841
9944
  var taxonomyCommand = new Command16("taxonomy").description("Browse the taxonomy tree").argument("[path]", 'Subtree path (e.g., "Development/Python")').option("-i, --interactive", "Interactive browsing mode").option("--standalone", "Use standalone skillindexer CLI (fallback)").action(async (pathArg, options, command) => {
@@ -9916,6 +10019,7 @@ async function runSkillIndexer3(args, quiet) {
9916
10019
  }
9917
10020
 
9918
10021
  // src/cli/commands/indexer/relationships.ts
10022
+ init_esm_shims();
9919
10023
  import { Command as Command17 } from "commander";
9920
10024
  import { spawn as spawn4 } from "child_process";
9921
10025
  var relationshipsCommand = new Command17("relationships").description("Detect relationships between indexed skills").option("-s, --skill <id>", "Detect relationships for specific skill").option("--use-ai", "Use AI for relationship reasoning (slower, more accurate)").option("--clear", "Clear existing relationships before detection").option("--standalone", "Use standalone skillindexer CLI (fallback)").action(async (options, command) => {
@@ -10002,6 +10106,7 @@ async function runSkillIndexer4(args, quiet) {
10002
10106
  }
10003
10107
 
10004
10108
  // src/cli/commands/indexer/stats.ts
10109
+ init_esm_shims();
10005
10110
  import { Command as Command18 } from "commander";
10006
10111
  import { spawn as spawn5 } from "child_process";
10007
10112
  var indexerStatsCommand = new Command18("stats").description("Show indexer database statistics").option("--standalone", "Use standalone skillindexer CLI (fallback)").action(async (options, command) => {
@@ -10081,13 +10186,15 @@ async function runSkillIndexer5(args, quiet) {
10081
10186
  }
10082
10187
 
10083
10188
  // src/cli/commands/indexer/sync.ts
10189
+ init_esm_shims();
10084
10190
  import { Command as Command19 } from "commander";
10085
10191
  import * as fs16 from "fs";
10086
- import * as path14 from "path";
10192
+ import * as path15 from "path";
10087
10193
  import * as os3 from "os";
10088
10194
  import { spawn as spawn6 } from "child_process";
10089
10195
 
10090
10196
  // src/services/sync.ts
10197
+ init_esm_shims();
10091
10198
  var SyncService = class {
10092
10199
  constructor(skillBank, config2 = {}) {
10093
10200
  this.syncStates = /* @__PURE__ */ new Map();
@@ -10544,7 +10651,7 @@ async function runLegacyImport(options, globalOpts) {
10544
10651
  if (!globalOpts.quiet) {
10545
10652
  printInfo("Exporting skills from indexer...");
10546
10653
  }
10547
- exportPath = path14.join(os3.tmpdir(), `skill-tree-sync-${Date.now()}.json`);
10654
+ exportPath = path15.join(os3.tmpdir(), `skill-tree-sync-${Date.now()}.json`);
10548
10655
  const args = ["export-skilltree", "-o", exportPath, "-f", "json"];
10549
10656
  if (options.indexedOnly) args.push("--indexed-only");
10550
10657
  await runSkillIndexer6(args, true);
@@ -10612,6 +10719,7 @@ async function runSkillIndexer6(args, quiet) {
10612
10719
  var indexerCommand = new Command20("index").description("Skill indexer - discover and classify skills from GitHub").addCommand(scrapeCommand).addCommand(classifyCommand).addCommand(taxonomyCommand).addCommand(relationshipsCommand).addCommand(indexerStatsCommand).addCommand(syncCommand);
10613
10720
 
10614
10721
  // src/cli/commands/config.ts
10722
+ init_esm_shims();
10615
10723
  import { Command as Command21 } from "commander";
10616
10724
  import * as fs17 from "fs";
10617
10725
  var configCommand = new Command21("config").description("View and manage configuration");
@@ -10762,11 +10870,12 @@ function printConfig(obj, indent) {
10762
10870
  }
10763
10871
 
10764
10872
  // src/cli/commands/sync.ts
10873
+ init_esm_shims();
10765
10874
  import { Command as Command22 } from "commander";
10766
- import * as path15 from "path";
10875
+ import * as path16 from "path";
10767
10876
  import * as fs18 from "fs";
10768
10877
  function getSyncConfigPath(basePath) {
10769
- return path15.join(basePath, ".skillbank", "sync-config.json");
10878
+ return path16.join(basePath, ".skillbank", "sync-config.json");
10770
10879
  }
10771
10880
  async function loadSyncConfig(basePath) {
10772
10881
  const configPath = getSyncConfigPath(basePath);
@@ -10779,7 +10888,7 @@ async function loadSyncConfig(basePath) {
10779
10888
  }
10780
10889
  async function saveSyncConfig(basePath, config2) {
10781
10890
  const configPath = getSyncConfigPath(basePath);
10782
- await fs18.promises.mkdir(path15.dirname(configPath), { recursive: true });
10891
+ await fs18.promises.mkdir(path16.dirname(configPath), { recursive: true });
10783
10892
  await fs18.promises.writeFile(configPath, JSON.stringify(config2, null, 2), "utf-8");
10784
10893
  }
10785
10894
  async function createSyncAdapter(basePath, globalOpts) {
@@ -10810,7 +10919,7 @@ function initCommand() {
10810
10919
  agentName: options.name,
10811
10920
  environment: options.env
10812
10921
  });
10813
- const gitDir = path15.join(basePath, ".git");
10922
+ const gitDir = path16.join(basePath, ".git");
10814
10923
  if (!fs18.existsSync(gitDir)) {
10815
10924
  printError(`Not a git repository: ${basePath}`);
10816
10925
  printInfo("Initialize a git repository first with: git init");
@@ -11086,8 +11195,9 @@ function resolveCommand() {
11086
11195
  }
11087
11196
 
11088
11197
  // src/cli/commands/read.ts
11198
+ init_esm_shims();
11089
11199
  import { Command as Command23 } from "commander";
11090
- import * as path16 from "path";
11200
+ import * as path17 from "path";
11091
11201
  function serializeSkillMd(skill) {
11092
11202
  const lines = [];
11093
11203
  lines.push("---");
@@ -11133,7 +11243,7 @@ var readCommand = new Command23("read").description("Read skill(s) to stdout (fo
11133
11243
  } else {
11134
11244
  console.log(`Reading: ${skill.name}`);
11135
11245
  }
11136
- const skillDir = path16.join(basePath, ".skilltree", "skills", skill.id);
11246
+ const skillDir = path17.join(basePath, ".skilltree", "skills", skill.id);
11137
11247
  console.log(`Base directory: ${skillDir}`);
11138
11248
  console.log("");
11139
11249
  console.log(serializeSkillMd(skill));
@@ -11150,6 +11260,7 @@ var readCommand = new Command23("read").description("Read skill(s) to stdout (fo
11150
11260
  });
11151
11261
 
11152
11262
  // src/cli/commands/materialize.ts
11263
+ init_esm_shims();
11153
11264
  import { Command as Command24 } from "commander";
11154
11265
  var materializeCommand = new Command24("materialize").description("Materialize skills to agent-discoverable paths").option("--paths <dirs>", "Comma-separated target directories (e.g. .claude/skills,.agent/skills)").option("--agents-md <path>", "Path to write AGENTS.md").option("--format <format>", "AGENTS.md format: xml, markdown, json", "xml").option("--mode <mode>", "Materialization mode: symlink or copy", "symlink").option("-w, --watch", "Watch for changes and re-materialize").action(async (options, command) => {
11155
11266
  const globalOpts = command.optsWithGlobals();
@@ -11210,17 +11321,23 @@ var materializeCommand = new Command24("materialize").description("Materialize s
11210
11321
  });
11211
11322
 
11212
11323
  // src/cli/commands/loadout/index.ts
11213
- import { Command as Command38 } from "commander";
11324
+ init_esm_shims();
11325
+ import { Command as Command37 } from "commander";
11214
11326
 
11215
11327
  // src/cli/commands/loadout/list.ts
11328
+ init_esm_shims();
11216
11329
  import { Command as Command25 } from "commander";
11217
11330
 
11331
+ // src/cli/utils/loadout-server.ts
11332
+ init_esm_shims();
11333
+
11218
11334
  // src/serving/state-persistence.ts
11335
+ init_esm_shims();
11219
11336
  import * as fs19 from "fs";
11220
- import * as path17 from "path";
11337
+ import * as path18 from "path";
11221
11338
  var STATE_FILENAME = ".loadout-state.json";
11222
11339
  function loadState(skillPath) {
11223
- const filePath = path17.join(skillPath, STATE_FILENAME);
11340
+ const filePath = path18.join(skillPath, STATE_FILENAME);
11224
11341
  try {
11225
11342
  const raw = fs19.readFileSync(filePath, "utf-8");
11226
11343
  const data = JSON.parse(raw);
@@ -11236,7 +11353,7 @@ function loadState(skillPath) {
11236
11353
  }
11237
11354
  }
11238
11355
  function saveState(skillPath, state) {
11239
- const filePath = path17.join(skillPath, STATE_FILENAME);
11356
+ const filePath = path18.join(skillPath, STATE_FILENAME);
11240
11357
  const data = {
11241
11358
  available: Array.from(state.available.entries()),
11242
11359
  expanded: Array.from(state.expanded),
@@ -11247,7 +11364,7 @@ function saveState(skillPath, state) {
11247
11364
  fs19.writeFileSync(filePath, JSON.stringify(data, null, 2));
11248
11365
  }
11249
11366
  function clearState(skillPath) {
11250
- const filePath = path17.join(skillPath, STATE_FILENAME);
11367
+ const filePath = path18.join(skillPath, STATE_FILENAME);
11251
11368
  try {
11252
11369
  fs19.unlinkSync(filePath);
11253
11370
  return true;
@@ -11323,6 +11440,7 @@ var listSubcommand = new Command25("list").description("List skills in the curre
11323
11440
  });
11324
11441
 
11325
11442
  // src/cli/commands/loadout/search.ts
11443
+ init_esm_shims();
11326
11444
  import { Command as Command26 } from "commander";
11327
11445
  var searchSubcommand = new Command26("search").description("Search for skills to add to the loadout").argument("<query>", "Search query").option("-l, --limit <n>", "Maximum results", "10").action(async (query, options, command) => {
11328
11446
  const globalOpts = command.optsWithGlobals();
@@ -11354,6 +11472,7 @@ var searchSubcommand = new Command26("search").description("Search for skills to
11354
11472
  });
11355
11473
 
11356
11474
  // src/cli/commands/loadout/add.ts
11475
+ init_esm_shims();
11357
11476
  import { Command as Command27 } from "commander";
11358
11477
  var addSubcommand = new Command27("add").description("Add skills to the loadout").argument("<ids...>", "Skill IDs to add").action(async (ids, _options, command) => {
11359
11478
  const globalOpts = command.optsWithGlobals();
@@ -11373,6 +11492,7 @@ var addSubcommand = new Command27("add").description("Add skills to the loadout"
11373
11492
  });
11374
11493
 
11375
11494
  // src/cli/commands/loadout/remove.ts
11495
+ init_esm_shims();
11376
11496
  import { Command as Command28 } from "commander";
11377
11497
  var removeSubcommand = new Command28("remove").description("Remove skills from the loadout").argument("<ids...>", "Skill IDs to remove").action(async (ids, _options, command) => {
11378
11498
  const globalOpts = command.optsWithGlobals();
@@ -11392,6 +11512,7 @@ var removeSubcommand = new Command28("remove").description("Remove skills from t
11392
11512
  });
11393
11513
 
11394
11514
  // src/cli/commands/loadout/profile.ts
11515
+ init_esm_shims();
11395
11516
  import { Command as Command29 } from "commander";
11396
11517
  var profileSubcommand = new Command29("profile").description("Switch to a named skill profile").argument("[name]", "Profile name (e.g. debugging, security, code-review)").option("--list", "List available profiles").action(async (name, options, command) => {
11397
11518
  const globalOpts = command.optsWithGlobals();
@@ -11424,6 +11545,7 @@ var profileSubcommand = new Command29("profile").description("Switch to a named
11424
11545
  });
11425
11546
 
11426
11547
  // src/cli/commands/loadout/set.ts
11548
+ init_esm_shims();
11427
11549
  import { Command as Command30 } from "commander";
11428
11550
  var setSubcommand = new Command30("set").description("Set loadout from criteria (tags, task description, etc.)").option("--tags <tags>", "Comma-separated tags to match").option("--task <description>", "Task description for semantic matching").option("--max-skills <n>", "Maximum number of skills").action(async (options, command) => {
11429
11551
  const globalOpts = command.optsWithGlobals();
@@ -11454,6 +11576,7 @@ var setSubcommand = new Command30("set").description("Set loadout from criteria
11454
11576
  });
11455
11577
 
11456
11578
  // src/cli/commands/loadout/expand.ts
11579
+ init_esm_shims();
11457
11580
  import { Command as Command31 } from "commander";
11458
11581
  var expandSubcommand = new Command31("expand").description("Expand a skill to see its full content").argument("<id>", "Skill ID to expand").action(async (id, _options, command) => {
11459
11582
  const globalOpts = command.optsWithGlobals();
@@ -11480,6 +11603,7 @@ var expandSubcommand = new Command31("expand").description("Expand a skill to se
11480
11603
  });
11481
11604
 
11482
11605
  // src/cli/commands/loadout/collapse.ts
11606
+ init_esm_shims();
11483
11607
  import { Command as Command32 } from "commander";
11484
11608
  var collapseSubcommand = new Command32("collapse").description("Collapse an expanded skill back to summary").argument("<id>", "Skill ID to collapse").action(async (id, _options, command) => {
11485
11609
  const globalOpts = command.optsWithGlobals();
@@ -11502,36 +11626,10 @@ var collapseSubcommand = new Command32("collapse").description("Collapse an expa
11502
11626
  }
11503
11627
  });
11504
11628
 
11505
- // src/cli/commands/loadout/use.ts
11506
- import { Command as Command33 } from "commander";
11507
- var useSubcommand = new Command33("use").description("Mark a skill as being used (auto-expands and records usage)").argument("<id>", "Skill ID to use").action(async (id, _options, command) => {
11508
- const globalOpts = command.optsWithGlobals();
11509
- try {
11510
- const { server, save } = await createLoadoutServer(globalOpts);
11511
- server.recordUsage(id);
11512
- const expanded = server.expandSkill(id);
11513
- if (!expanded) {
11514
- printError(`Skill "${id}" not found in loadout`);
11515
- process.exit(1);
11516
- }
11517
- save();
11518
- const skill = server.getState().available.get(id);
11519
- if (globalOpts.json) {
11520
- console.log(JSON.stringify(skill, null, 2));
11521
- return;
11522
- }
11523
- printSuccess(`Using "${id}"`);
11524
- console.log();
11525
- console.log(formatSkillDetail(skill));
11526
- } catch (error) {
11527
- printError(error.message);
11528
- process.exit(1);
11529
- }
11530
- });
11531
-
11532
11629
  // src/cli/commands/loadout/get.ts
11533
- import { Command as Command34 } from "commander";
11534
- var getSubcommand = new Command34("get").description("Get details about a skill in the loadout").argument("<id>", "Skill ID").action(async (id, _options, command) => {
11630
+ init_esm_shims();
11631
+ import { Command as Command33 } from "commander";
11632
+ var getSubcommand = new Command33("get").description("Get details about a skill in the loadout").argument("<id>", "Skill ID").action(async (id, _options, command) => {
11535
11633
  const globalOpts = command.optsWithGlobals();
11536
11634
  try {
11537
11635
  const { server } = await createLoadoutServer(globalOpts);
@@ -11553,8 +11651,9 @@ var getSubcommand = new Command34("get").description("Get details about a skill
11553
11651
  });
11554
11652
 
11555
11653
  // src/cli/commands/loadout/render.ts
11556
- import { Command as Command35 } from "commander";
11557
- var renderSubcommand = new Command35("render").description("Render the current loadout as a system prompt (XML or Markdown)").option("--format <format>", "Output format: xml or markdown", "xml").action(async (options, command) => {
11654
+ init_esm_shims();
11655
+ import { Command as Command34 } from "commander";
11656
+ var renderSubcommand = new Command34("render").description("Render the current loadout as a system prompt (XML or Markdown)").option("--format <format>", "Output format: xml or markdown", "xml").action(async (options, command) => {
11558
11657
  const globalOpts = command.optsWithGlobals();
11559
11658
  try {
11560
11659
  const { server } = await createLoadoutServer(globalOpts);
@@ -11572,8 +11671,9 @@ var renderSubcommand = new Command35("render").description("Render the current l
11572
11671
  });
11573
11672
 
11574
11673
  // src/cli/commands/loadout/clear.ts
11575
- import { Command as Command36 } from "commander";
11576
- var clearSubcommand = new Command36("clear").description("Clear the current loadout state").action(async (_options, command) => {
11674
+ init_esm_shims();
11675
+ import { Command as Command35 } from "commander";
11676
+ var clearSubcommand = new Command35("clear").description("Clear the current loadout state").action(async (_options, command) => {
11577
11677
  const globalOpts = command.optsWithGlobals();
11578
11678
  try {
11579
11679
  const skillPath = resolveSkillPath(globalOpts.path);
@@ -11594,15 +11694,16 @@ var clearSubcommand = new Command36("clear").description("Clear the current load
11594
11694
  });
11595
11695
 
11596
11696
  // src/cli/commands/loadout/browse.ts
11597
- import { Command as Command37 } from "commander";
11598
- var browseSubcommand = new Command37("browse").description("Browse the skill catalog by category").argument("[path]", "Category path to browse (e.g., Development/Python)").action(async (pathArg, _options, command) => {
11697
+ init_esm_shims();
11698
+ import { Command as Command36 } from "commander";
11699
+ var browseSubcommand = new Command36("browse").description("Browse the skill catalog by category").argument("[path]", "Category path to browse (e.g., Development/Python)").action(async (pathArg, _options, command) => {
11599
11700
  const globalOpts = command.optsWithGlobals();
11600
11701
  try {
11601
11702
  const { server } = await createLoadoutServer(globalOpts);
11602
- const path18 = pathArg ? pathArg.split("/").filter(Boolean) : void 0;
11603
- const output = await server.agentBrowseCatalog(path18);
11703
+ const path19 = pathArg ? pathArg.split("/").filter(Boolean) : void 0;
11704
+ const output = await server.agentBrowseCatalog(path19);
11604
11705
  if (globalOpts.json) {
11605
- console.log(JSON.stringify({ path: path18 ?? [], output }, null, 2));
11706
+ console.log(JSON.stringify({ path: path19 ?? [], output }, null, 2));
11606
11707
  return;
11607
11708
  }
11608
11709
  if (!output) {
@@ -11617,10 +11718,10 @@ var browseSubcommand = new Command37("browse").description("Browse the skill cat
11617
11718
  });
11618
11719
 
11619
11720
  // src/cli/commands/loadout/index.ts
11620
- var loadoutCommand = new Command38("loadout").description("Manage skill loadouts for agent sessions").addCommand(listSubcommand).addCommand(searchSubcommand).addCommand(addSubcommand).addCommand(removeSubcommand).addCommand(profileSubcommand).addCommand(setSubcommand).addCommand(expandSubcommand).addCommand(collapseSubcommand).addCommand(useSubcommand).addCommand(getSubcommand).addCommand(renderSubcommand).addCommand(clearSubcommand).addCommand(browseSubcommand);
11721
+ var loadoutCommand = new Command37("loadout").description("Manage skill loadouts for agent sessions").addCommand(listSubcommand).addCommand(searchSubcommand).addCommand(addSubcommand).addCommand(removeSubcommand).addCommand(profileSubcommand).addCommand(setSubcommand).addCommand(expandSubcommand).addCommand(collapseSubcommand).addCommand(getSubcommand).addCommand(renderSubcommand).addCommand(clearSubcommand).addCommand(browseSubcommand);
11621
11722
 
11622
11723
  // src/cli/index.ts
11623
- var program = new Command39();
11724
+ var program = new Command38();
11624
11725
  var config = loadConfig();
11625
11726
  program.name("skill-tree").description("Management CLI for agent skills").version(VERSION).option("-p, --path <dir>", "Skills directory path", config.storage.path).option("-c, --config <file>", "Config file path", getConfigPath()).option("--json", "Output as JSON", config.cli.output_format === "json").option("-q, --quiet", "Suppress non-essential output", config.cli.quiet).option("--no-color", "Disable colored output", !config.cli.color);
11626
11727
  program.addCommand(listCommand);
@@ -11643,4 +11744,3 @@ program.addCommand(readCommand);
11643
11744
  program.addCommand(materializeCommand);
11644
11745
  program.addCommand(loadoutCommand);
11645
11746
  program.parse();
11646
- //# sourceMappingURL=index.mjs.map