@musher-dev/musher-sdk 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -641,46 +641,10 @@ var Selection = class {
641
641
  result.push(fh);
642
642
  }
643
643
  };
644
- if (this._filter.skills) {
645
- for (const name of this._filter.skills) {
646
- const skill = this._bundle.skills().find((s) => s.name === name);
647
- if (skill) {
648
- for (const f of skill.files()) {
649
- addFile(f);
650
- }
651
- }
652
- }
653
- }
654
- if (this._filter.prompts) {
655
- for (const name of this._filter.prompts) {
656
- const prompt = this._bundle.prompts().find((p) => p.name === name);
657
- if (prompt) {
658
- for (const f of prompt.files()) {
659
- addFile(f);
660
- }
661
- }
662
- }
663
- }
664
- if (this._filter.toolsets) {
665
- for (const name of this._filter.toolsets) {
666
- const toolset = this._bundle.toolsets().find((t) => t.name === name);
667
- if (toolset) {
668
- for (const f of toolset.files()) {
669
- addFile(f);
670
- }
671
- }
672
- }
673
- }
674
- if (this._filter.agentSpecs) {
675
- for (const name of this._filter.agentSpecs) {
676
- const spec = this._bundle.agentSpecs().find((a) => a.name === name);
677
- if (spec) {
678
- for (const f of spec.files()) {
679
- addFile(f);
680
- }
681
- }
682
- }
683
- }
644
+ this.collectFromCategory(this._bundle.skills(), this._filter.skills, addFile);
645
+ this.collectFromCategory(this._bundle.prompts(), this._filter.prompts, addFile);
646
+ this.collectFromCategory(this._bundle.toolsets(), this._filter.toolsets, addFile);
647
+ this.collectFromCategory(this._bundle.agentSpecs(), this._filter.agentSpecs, addFile);
684
648
  if (this._filter.paths) {
685
649
  for (const path of this._filter.paths) {
686
650
  const fh = this._bundle.file(path);
@@ -691,6 +655,19 @@ var Selection = class {
691
655
  }
692
656
  return result;
693
657
  }
658
+ collectFromCategory(items, names, addFile) {
659
+ if (!names) {
660
+ return;
661
+ }
662
+ for (const name of names) {
663
+ const item = items.find((i) => i.name === name);
664
+ if (item) {
665
+ for (const f of item.files()) {
666
+ addFile(f);
667
+ }
668
+ }
669
+ }
670
+ }
694
671
  skills() {
695
672
  const names = this._filter.skills;
696
673
  if (!names) {
@@ -1191,41 +1168,19 @@ var BundleCache = class {
1191
1168
  }
1192
1169
  /** Walk manifests, remove expired, collect digests from surviving ones. */
1193
1170
  async cleanManifests(referencedDigests) {
1194
- const manifestsRoot = (0, import_node_path5.join)(this.cacheDir, "manifests");
1195
- if (!(0, import_node_fs.existsSync)(manifestsRoot)) {
1196
- return;
1197
- }
1198
- for (const hostId of await safeReaddir(manifestsRoot)) {
1199
- const hostDir = (0, import_node_path5.join)(manifestsRoot, hostId);
1200
- if (!await isDir(hostDir)) {
1201
- continue;
1171
+ await walkCacheTree((0, import_node_path5.join)(this.cacheDir, "manifests"), async (ns, slug, slugDir, file) => {
1172
+ if (!file.endsWith(".json") || file.endsWith(".meta.json")) {
1173
+ return;
1202
1174
  }
1203
- for (const ns of await safeReaddir(hostDir)) {
1204
- const nsDir = (0, import_node_path5.join)(hostDir, ns);
1205
- if (!await isDir(nsDir)) {
1206
- continue;
1207
- }
1208
- for (const slug of await safeReaddir(nsDir)) {
1209
- const slugDir = (0, import_node_path5.join)(nsDir, slug);
1210
- if (!await isDir(slugDir)) {
1211
- continue;
1212
- }
1213
- for (const file of await safeReaddir(slugDir)) {
1214
- if (!file.endsWith(".json") || file.endsWith(".meta.json")) {
1215
- continue;
1216
- }
1217
- const version = file.replace(JSON_EXT_RE, "");
1218
- const fresh = await this.isFresh(ns, slug, version);
1219
- if (fresh) {
1220
- await this.collectDigests((0, import_node_path5.join)(slugDir, file), referencedDigests);
1221
- } else {
1222
- await safeRm((0, import_node_path5.join)(slugDir, file));
1223
- await safeRm((0, import_node_path5.join)(slugDir, `${version}.meta.json`));
1224
- }
1225
- }
1226
- }
1175
+ const version = file.replace(JSON_EXT_RE, "");
1176
+ const fresh = await this.isFresh(ns, slug, version);
1177
+ if (fresh) {
1178
+ await this.collectDigests((0, import_node_path5.join)(slugDir, file), referencedDigests);
1179
+ } else {
1180
+ await safeRm((0, import_node_path5.join)(slugDir, file));
1181
+ await safeRm((0, import_node_path5.join)(slugDir, `${version}.meta.json`));
1227
1182
  }
1228
- }
1183
+ });
1229
1184
  }
1230
1185
  /** Collect blob digests referenced by a manifest file. */
1231
1186
  async collectDigests(manifestFile, digests) {
@@ -1242,38 +1197,16 @@ var BundleCache = class {
1242
1197
  }
1243
1198
  /** Walk refs and remove expired entries. */
1244
1199
  async cleanRefs() {
1245
- const refsRoot = (0, import_node_path5.join)(this.cacheDir, "refs");
1246
- if (!(0, import_node_fs.existsSync)(refsRoot)) {
1247
- return;
1248
- }
1249
- for (const hostId of await safeReaddir(refsRoot)) {
1250
- const hostDir = (0, import_node_path5.join)(refsRoot, hostId);
1251
- if (!await isDir(hostDir)) {
1252
- continue;
1200
+ await walkCacheTree((0, import_node_path5.join)(this.cacheDir, "refs"), async (ns, slug, slugDir, file) => {
1201
+ if (!file.endsWith(".json")) {
1202
+ return;
1253
1203
  }
1254
- for (const ns of await safeReaddir(hostDir)) {
1255
- const nsDir = (0, import_node_path5.join)(hostDir, ns);
1256
- if (!await isDir(nsDir)) {
1257
- continue;
1258
- }
1259
- for (const slug of await safeReaddir(nsDir)) {
1260
- const slugDir = (0, import_node_path5.join)(nsDir, slug);
1261
- if (!await isDir(slugDir)) {
1262
- continue;
1263
- }
1264
- for (const file of await safeReaddir(slugDir)) {
1265
- if (!file.endsWith(".json")) {
1266
- continue;
1267
- }
1268
- const ref = file.replace(JSON_EXT_RE, "");
1269
- const version = await this.resolveRef(ns, slug, ref);
1270
- if (version === null) {
1271
- await safeRm((0, import_node_path5.join)(slugDir, file));
1272
- }
1273
- }
1274
- }
1204
+ const ref = file.replace(JSON_EXT_RE, "");
1205
+ const version = await this.resolveRef(ns, slug, ref);
1206
+ if (version === null) {
1207
+ await safeRm((0, import_node_path5.join)(slugDir, file));
1275
1208
  }
1276
- }
1209
+ });
1277
1210
  }
1278
1211
  /** Remove blobs not referenced by any surviving manifest. */
1279
1212
  async gcBlobs(referencedDigests) {
@@ -1309,6 +1242,30 @@ function computeHostId(registryUrl) {
1309
1242
  return registryUrl.replace(/[:/]/g, "_");
1310
1243
  }
1311
1244
  }
1245
+ async function listSubdirs(parent) {
1246
+ const result = [];
1247
+ for (const name of await safeReaddir(parent)) {
1248
+ const p = (0, import_node_path5.join)(parent, name);
1249
+ if (await isDir(p)) {
1250
+ result.push({ name, path: p });
1251
+ }
1252
+ }
1253
+ return result;
1254
+ }
1255
+ async function walkCacheTree(root, visitor) {
1256
+ if (!(0, import_node_fs.existsSync)(root)) {
1257
+ return;
1258
+ }
1259
+ for (const host of await listSubdirs(root)) {
1260
+ for (const ns of await listSubdirs(host.path)) {
1261
+ for (const slug of await listSubdirs(ns.path)) {
1262
+ for (const file of await safeReaddir(slug.path)) {
1263
+ await visitor(ns.name, slug.name, slug.path, file);
1264
+ }
1265
+ }
1266
+ }
1267
+ }
1268
+ }
1312
1269
  async function isDir(path) {
1313
1270
  try {
1314
1271
  return (await (0, import_promises5.stat)(path)).isDirectory();
@@ -1556,40 +1513,43 @@ var HttpTransport = class {
1556
1513
  const headers = this.buildHeaders();
1557
1514
  let lastError;
1558
1515
  for (let attempt = 0; attempt <= this.config.retries; attempt++) {
1559
- try {
1560
- const init = { method, headers };
1561
- if (options?.body) {
1562
- init.body = JSON.stringify(options.body);
1563
- }
1564
- const response = await this.fetchWithTimeout(url, init);
1565
- if (!response.ok) {
1566
- const error = await this.mapError(response);
1567
- if (response.status === 429 || response.status >= 500) {
1568
- lastError = error;
1569
- if (attempt < this.config.retries) {
1570
- await this.backoff(attempt, error);
1571
- continue;
1572
- }
1573
- }
1574
- throw error;
1575
- }
1576
- const json = await response.json();
1577
- return this.parse(schema, json);
1578
- } catch (error) {
1579
- if (error instanceof ApiError) {
1580
- throw error;
1581
- }
1582
- if (error instanceof SchemaError) {
1583
- throw error;
1584
- }
1585
- lastError = error instanceof Error ? error : new Error(String(error));
1586
- if (attempt < this.config.retries) {
1587
- await this.backoff(attempt);
1588
- }
1516
+ const result = await this.attemptRequest(method, url, headers, schema, options?.body);
1517
+ if (result.ok) {
1518
+ return result.value;
1519
+ }
1520
+ lastError = result.error;
1521
+ if (!result.retryable || attempt >= this.config.retries) {
1522
+ throw lastError;
1589
1523
  }
1524
+ await this.backoff(attempt, lastError);
1590
1525
  }
1591
1526
  throw lastError ?? new NetworkError("Request failed after retries");
1592
1527
  }
1528
+ async attemptRequest(method, url, headers, schema, body) {
1529
+ try {
1530
+ const init = { method, headers };
1531
+ if (body) {
1532
+ init.body = JSON.stringify(body);
1533
+ }
1534
+ const response = await this.fetchWithTimeout(url, init);
1535
+ if (!response.ok) {
1536
+ const error = await this.mapError(response);
1537
+ const retryable = response.status === 429 || response.status >= 500;
1538
+ return { ok: false, error, retryable };
1539
+ }
1540
+ const json = await response.json();
1541
+ return { ok: true, value: this.parse(schema, json) };
1542
+ } catch (error) {
1543
+ if (error instanceof ApiError || error instanceof SchemaError) {
1544
+ return { ok: false, error, retryable: false };
1545
+ }
1546
+ return {
1547
+ ok: false,
1548
+ error: error instanceof Error ? error : new Error(String(error)),
1549
+ retryable: true
1550
+ };
1551
+ }
1552
+ }
1593
1553
  buildUrl(path, params) {
1594
1554
  const base = this.config.baseUrl.replace(TRAILING_SLASH_RE, "");
1595
1555
  const url = new URL(`${base}${path}`);