@decantr/registry 1.0.0-beta.8 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,64 @@
1
+ // src/types.ts
2
+ var CONTENT_TYPES = [
3
+ "pattern",
4
+ "theme",
5
+ "blueprint",
6
+ "archetype",
7
+ "shell"
8
+ ];
9
+ var API_CONTENT_TYPES = [
10
+ "patterns",
11
+ "themes",
12
+ "blueprints",
13
+ "archetypes",
14
+ "shells"
15
+ ];
16
+ var CONTENT_TYPE_TO_API_CONTENT_TYPE = {
17
+ pattern: "patterns",
18
+ theme: "themes",
19
+ blueprint: "blueprints",
20
+ archetype: "archetypes",
21
+ shell: "shells"
22
+ };
23
+ var API_CONTENT_TYPE_TO_CONTENT_TYPE = {
24
+ patterns: "pattern",
25
+ themes: "theme",
26
+ blueprints: "blueprint",
27
+ archetypes: "archetype",
28
+ shells: "shell"
29
+ };
30
+ function isContentType(value) {
31
+ return CONTENT_TYPES.includes(value);
32
+ }
33
+ function isApiContentType(value) {
34
+ return API_CONTENT_TYPES.includes(value);
35
+ }
36
+ var PUBLIC_CONTENT_SOURCES = [
37
+ "official",
38
+ "community",
39
+ "organization"
40
+ ];
41
+ function isPublicContentSource(value) {
42
+ return PUBLIC_CONTENT_SOURCES.includes(value);
43
+ }
44
+ var CONTENT_INTELLIGENCE_SOURCES = [
45
+ "authored",
46
+ "benchmark",
47
+ "hybrid"
48
+ ];
49
+ function isContentIntelligenceSource(value) {
50
+ return CONTENT_INTELLIGENCE_SOURCES.includes(value);
51
+ }
52
+
1
53
  // src/resolver.ts
2
54
  import { readFile } from "fs/promises";
3
55
  import { join } from "path";
4
56
  var TYPE_DIRS = {
5
57
  pattern: "patterns",
6
58
  archetype: "archetypes",
7
- recipe: "recipes",
8
59
  theme: "themes",
9
- blueprint: "blueprints"
60
+ blueprint: "blueprints",
61
+ shell: "shells"
10
62
  };
11
63
  async function tryLoadJson(filePath) {
12
64
  try {
@@ -39,7 +91,7 @@ function createResolver(options) {
39
91
  }
40
92
 
41
93
  // src/pattern.ts
42
- function resolvePatternPreset(pattern, explicitPreset, recipeDefaultPresets) {
94
+ function resolvePatternPreset(pattern, explicitPreset, themeDefaultPresets) {
43
95
  const presets = pattern.presets;
44
96
  const hasPresets = Object.keys(presets).length > 0;
45
97
  if (!hasPresets) {
@@ -51,9 +103,9 @@ function resolvePatternPreset(pattern, explicitPreset, recipeDefaultPresets) {
51
103
  }
52
104
  let presetName = explicitPreset;
53
105
  if (presetName && !presets[presetName]) presetName = void 0;
54
- if (!presetName && recipeDefaultPresets?.[pattern.id]) {
55
- const recipeName = recipeDefaultPresets[pattern.id];
56
- if (presets[recipeName]) presetName = recipeName;
106
+ if (!presetName && themeDefaultPresets?.[pattern.id]) {
107
+ const themeName = themeDefaultPresets[pattern.id];
108
+ if (presets[themeName]) presetName = themeName;
57
109
  }
58
110
  if (!presetName) presetName = pattern.default_preset;
59
111
  if (!presetName || !presets[presetName]) presetName = Object.keys(presets)[0];
@@ -209,15 +261,36 @@ function classifySignal(signal) {
209
261
  var DEFAULT_BASE_URL = "https://api.decantr.ai/v1";
210
262
  var DEFAULT_TIMEOUT_MS = 3e4;
211
263
  var DEFAULT_CACHE_TTL_MS = 5 * 60 * 1e3;
264
+ function unwrapDataEnvelope(value) {
265
+ if (typeof value === "object" && value !== null && "data" in value) {
266
+ return value.data;
267
+ }
268
+ return value;
269
+ }
270
+ var RegistryAPIError = class extends Error {
271
+ status;
272
+ details;
273
+ constructor(status, message, details) {
274
+ super(message);
275
+ this.name = "RegistryAPIError";
276
+ this.status = status;
277
+ this.details = details;
278
+ }
279
+ };
280
+ function isRecord(value) {
281
+ return typeof value === "object" && value !== null && !Array.isArray(value);
282
+ }
212
283
  var RegistryAPIClient = class {
213
284
  baseUrl;
214
285
  apiKey;
286
+ accessToken;
215
287
  timeoutMs;
216
288
  cacheTtlMs;
217
289
  cache = /* @__PURE__ */ new Map();
218
290
  constructor(options = {}) {
219
291
  this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
220
292
  this.apiKey = options.apiKey;
293
+ this.accessToken = options.accessToken;
221
294
  this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
222
295
  this.cacheTtlMs = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
223
296
  }
@@ -229,6 +302,9 @@ var RegistryAPIClient = class {
229
302
  if (this.apiKey) {
230
303
  headers["X-API-Key"] = this.apiKey;
231
304
  }
305
+ if (this.accessToken) {
306
+ headers["Authorization"] = `Bearer ${this.accessToken}`;
307
+ }
232
308
  return headers;
233
309
  }
234
310
  async fetchWithTimeout(url, init) {
@@ -247,8 +323,22 @@ var RegistryAPIClient = class {
247
323
  headers: { ...this.buildHeaders(), ...init?.headers }
248
324
  });
249
325
  if (!response.ok) {
250
- const body = await response.text().catch(() => "");
251
- throw new Error(`API ${response.status}: ${body || response.statusText}`);
326
+ const bodyText = await response.text().catch(() => "");
327
+ let details;
328
+ let message = response.statusText;
329
+ if (bodyText) {
330
+ try {
331
+ details = JSON.parse(bodyText);
332
+ if (isRecord(details) && typeof details.error === "string") {
333
+ message = details.error;
334
+ } else {
335
+ message = bodyText;
336
+ }
337
+ } catch {
338
+ message = bodyText;
339
+ }
340
+ }
341
+ throw new RegistryAPIError(response.status, `API ${response.status}: ${message}`, details);
252
342
  }
253
343
  return response.json();
254
344
  }
@@ -285,6 +375,10 @@ var RegistryAPIClient = class {
285
375
  if (cached) return cached;
286
376
  const searchParams = new URLSearchParams();
287
377
  if (params?.namespace) searchParams.set("namespace", params.namespace);
378
+ if (params?.source) searchParams.set("source", params.source);
379
+ if (params?.sort) searchParams.set("sort", params.sort);
380
+ if (params?.recommended) searchParams.set("recommended", "true");
381
+ if (params?.intelligenceSource) searchParams.set("intelligence_source", params.intelligenceSource);
288
382
  if (params?.limit) searchParams.set("limit", String(params.limit));
289
383
  if (params?.offset) searchParams.set("offset", String(params.offset));
290
384
  const query = searchParams.toString();
@@ -297,6 +391,23 @@ var RegistryAPIClient = class {
297
391
  const cacheKey = `get:${type}:${namespace}:${slug}`;
298
392
  const cached = this.getCached(cacheKey);
299
393
  if (cached) return cached;
394
+ const raw = await this.request(`/${type}/${namespace}/${slug}`);
395
+ const unwrapped = unwrapDataEnvelope(raw);
396
+ this.setCache(cacheKey, unwrapped);
397
+ return unwrapped;
398
+ }
399
+ async getPublicContentRecord(type, namespace, slug) {
400
+ const cacheKey = `public-record:${type}:${namespace}:${slug}`;
401
+ const cached = this.getCached(cacheKey);
402
+ if (cached) return cached;
403
+ const result = await this.request(`/${type}/${namespace}/${slug}`);
404
+ this.setCache(cacheKey, result);
405
+ return result;
406
+ }
407
+ async getContentRecord(type, namespace, slug) {
408
+ const cacheKey = `content-record:${type}:${namespace}:${slug}:${this.apiKey ?? ""}:${this.accessToken ?? ""}`;
409
+ const cached = this.getCached(cacheKey);
410
+ if (cached) return cached;
300
411
  const result = await this.request(`/${type}/${namespace}/${slug}`);
301
412
  this.setCache(cacheKey, result);
302
413
  return result;
@@ -308,9 +419,6 @@ var RegistryAPIClient = class {
308
419
  async getArchetype(namespace, slug) {
309
420
  return this.getContent("archetypes", namespace, slug);
310
421
  }
311
- async getRecipe(namespace, slug) {
312
- return this.getContent("recipes", namespace, slug);
313
- }
314
422
  async getTheme(namespace, slug) {
315
423
  return this.getContent("themes", namespace, slug);
316
424
  }
@@ -325,10 +433,41 @@ var RegistryAPIClient = class {
325
433
  const searchParams = new URLSearchParams({ q: params.q });
326
434
  if (params.type) searchParams.set("type", params.type);
327
435
  if (params.namespace) searchParams.set("namespace", params.namespace);
436
+ if (params.source) searchParams.set("source", params.source);
437
+ if (params.sort) searchParams.set("sort", params.sort);
438
+ if (params.recommended) searchParams.set("recommended", "true");
439
+ if (params.intelligenceSource) searchParams.set("intelligence_source", params.intelligenceSource);
328
440
  if (params.limit) searchParams.set("limit", String(params.limit));
329
441
  if (params.offset) searchParams.set("offset", String(params.offset));
330
442
  return this.request(`/search?${searchParams}`);
331
443
  }
444
+ async getPublicUserProfile(username) {
445
+ const cacheKey = `public-user:${username}`;
446
+ const cached = this.getCached(cacheKey);
447
+ if (cached) return cached;
448
+ const result = await this.request(`/users/${encodeURIComponent(username)}`);
449
+ this.setCache(cacheKey, result);
450
+ return result;
451
+ }
452
+ async getPublicUserContent(username, params) {
453
+ const cacheKey = `public-user-content:${username}:${JSON.stringify(params ?? {})}`;
454
+ const cached = this.getCached(cacheKey);
455
+ if (cached) return cached;
456
+ const searchParams = new URLSearchParams();
457
+ if (params?.type) searchParams.set("type", params.type);
458
+ if (params?.source) searchParams.set("source", params.source);
459
+ if (params?.sort) searchParams.set("sort", params.sort);
460
+ if (params?.recommended) searchParams.set("recommended", "true");
461
+ if (params?.intelligenceSource) searchParams.set("intelligence_source", params.intelligenceSource);
462
+ if (params?.limit != null) searchParams.set("limit", String(params.limit));
463
+ if (params?.offset != null) searchParams.set("offset", String(params.offset));
464
+ const query = searchParams.toString();
465
+ const result = await this.request(
466
+ `/users/${encodeURIComponent(username)}/content${query ? `?${query}` : ""}`
467
+ );
468
+ this.setCache(cacheKey, result);
469
+ return result;
470
+ }
332
471
  // ── Authenticated endpoints ──
333
472
  async getProfile() {
334
473
  return this.request("/me");
@@ -343,10 +482,122 @@ var RegistryAPIClient = class {
343
482
  async getMyContent() {
344
483
  return this.request("/my/content");
345
484
  }
485
+ async getAccessiblePrivateContent(params) {
486
+ const searchParams = new URLSearchParams();
487
+ if (params?.type) searchParams.set("type", params.type);
488
+ if (params?.scope) searchParams.set("scope", params.scope);
489
+ if (params?.q) searchParams.set("q", params.q);
490
+ if (params?.limit != null) searchParams.set("limit", String(params.limit));
491
+ if (params?.offset != null) searchParams.set("offset", String(params.offset));
492
+ const query = searchParams.toString();
493
+ return this.request(
494
+ `/private/content${query ? `?${query}` : ""}`
495
+ );
496
+ }
346
497
  // ── Schema ──
347
498
  async getSchema(name = "essence.v3.json") {
348
499
  return this.request(`/schema/${name}`);
349
500
  }
501
+ // ── Showcase benchmarks ──
502
+ async getShowcaseManifest() {
503
+ const cacheKey = "showcase:manifest";
504
+ const cached = this.getCached(cacheKey);
505
+ if (cached) return cached;
506
+ const result = await this.request("/showcase/manifest");
507
+ this.setCache(cacheKey, result);
508
+ return result;
509
+ }
510
+ async getShowcaseShortlist() {
511
+ const cacheKey = "showcase:shortlist";
512
+ const cached = this.getCached(cacheKey);
513
+ if (cached) return cached;
514
+ const result = await this.request("/showcase/shortlist");
515
+ this.setCache(cacheKey, result);
516
+ return result;
517
+ }
518
+ async getShowcaseShortlistVerification() {
519
+ const cacheKey = "showcase:shortlist-verification";
520
+ const cached = this.getCached(cacheKey);
521
+ if (cached) return cached;
522
+ const result = await this.request("/showcase/shortlist-verification");
523
+ this.setCache(cacheKey, result);
524
+ return result;
525
+ }
526
+ async getRegistryIntelligenceSummary(params) {
527
+ const cacheKey = `registry-intelligence-summary:${JSON.stringify(params ?? {})}`;
528
+ const cached = this.getCached(cacheKey);
529
+ if (cached) return cached;
530
+ const searchParams = new URLSearchParams();
531
+ if (params?.namespace) searchParams.set("namespace", params.namespace);
532
+ const query = searchParams.toString();
533
+ const result = await this.request(
534
+ `/intelligence/summary${query ? `?${query}` : ""}`
535
+ );
536
+ this.setCache(cacheKey, result);
537
+ return result;
538
+ }
539
+ async compileExecutionPacks(essence, params) {
540
+ const searchParams = new URLSearchParams();
541
+ if (params?.namespace) searchParams.set("namespace", params.namespace);
542
+ const query = searchParams.toString();
543
+ return this.request(
544
+ `/packs/compile${query ? `?${query}` : ""}`,
545
+ {
546
+ method: "POST",
547
+ headers: { "Content-Type": "application/json" },
548
+ body: JSON.stringify(essence)
549
+ }
550
+ );
551
+ }
552
+ async selectExecutionPack(input, params) {
553
+ const searchParams = new URLSearchParams();
554
+ if (params?.namespace) searchParams.set("namespace", params.namespace);
555
+ const query = searchParams.toString();
556
+ return this.request(
557
+ `/packs/select${query ? `?${query}` : ""}`,
558
+ {
559
+ method: "POST",
560
+ headers: { "Content-Type": "application/json" },
561
+ body: JSON.stringify(input)
562
+ }
563
+ );
564
+ }
565
+ async getExecutionPackManifest(essence, params) {
566
+ const selected = await this.selectExecutionPack(
567
+ {
568
+ essence,
569
+ pack_type: "scaffold"
570
+ },
571
+ params
572
+ );
573
+ return selected.manifest;
574
+ }
575
+ async critiqueFile(input, params) {
576
+ const searchParams = new URLSearchParams();
577
+ if (params?.namespace) searchParams.set("namespace", params.namespace);
578
+ const query = searchParams.toString();
579
+ return this.request(
580
+ `/critique/file${query ? `?${query}` : ""}`,
581
+ {
582
+ method: "POST",
583
+ headers: { "Content-Type": "application/json" },
584
+ body: JSON.stringify(input)
585
+ }
586
+ );
587
+ }
588
+ async auditProject(input, params) {
589
+ const searchParams = new URLSearchParams();
590
+ if (params?.namespace) searchParams.set("namespace", params.namespace);
591
+ const query = searchParams.toString();
592
+ return this.request(
593
+ `/audit/project${query ? `?${query}` : ""}`,
594
+ {
595
+ method: "POST",
596
+ headers: { "Content-Type": "application/json" },
597
+ body: JSON.stringify(input)
598
+ }
599
+ );
600
+ }
350
601
  };
351
602
  function createRegistryClient(options = {}) {
352
603
  const baseUrl = options.baseUrl ?? "https://api.decantr.ai/v1";
@@ -368,14 +619,135 @@ function createRegistryClient(options = {}) {
368
619
  }
369
620
  };
370
621
  }
622
+
623
+ // src/ranking.ts
624
+ function verificationScore(status) {
625
+ switch (status) {
626
+ case "smoke-green":
627
+ return 200;
628
+ case "build-green":
629
+ return 120;
630
+ case "pending":
631
+ return 20;
632
+ case "smoke-red":
633
+ case "build-red":
634
+ return -40;
635
+ default:
636
+ return 0;
637
+ }
638
+ }
639
+ function confidenceScore(level) {
640
+ switch (level) {
641
+ case "high":
642
+ return 120;
643
+ case "medium":
644
+ return 70;
645
+ case "low":
646
+ return 30;
647
+ default:
648
+ return 0;
649
+ }
650
+ }
651
+ function confidenceTierScore(tier) {
652
+ switch (tier) {
653
+ case "verified":
654
+ return 180;
655
+ case "high":
656
+ return 120;
657
+ case "medium":
658
+ return 60;
659
+ case "low":
660
+ return 10;
661
+ default:
662
+ return 0;
663
+ }
664
+ }
665
+ function getRecommendedPriority(item) {
666
+ const intelligence = item.intelligence;
667
+ let score = 0;
668
+ if (!intelligence) {
669
+ return score;
670
+ }
671
+ if (intelligence.recommended) {
672
+ score += 500;
673
+ }
674
+ if (intelligence.golden_usage === "shortlisted") {
675
+ score += 160;
676
+ } else if (intelligence.golden_usage === "showcase") {
677
+ score += 80;
678
+ }
679
+ score += verificationScore(intelligence.verification_status);
680
+ score += confidenceScore(intelligence.benchmark_confidence);
681
+ score += confidenceTierScore(intelligence.confidence_tier);
682
+ score += Math.round((intelligence.confidence_score ?? 0) / 2);
683
+ score += intelligence.quality_score ?? 0;
684
+ return score;
685
+ }
686
+ function normalizePublicContentSort(value) {
687
+ switch (value) {
688
+ case "popular":
689
+ case "recommended":
690
+ return "recommended";
691
+ case "newest":
692
+ case "recent":
693
+ case "published":
694
+ return "recent";
695
+ case "name":
696
+ return "name";
697
+ default:
698
+ return "recommended";
699
+ }
700
+ }
701
+ function comparePublicContent(a, b, sort = "recommended") {
702
+ if (sort === "name") {
703
+ return (a.name ?? a.slug).localeCompare(b.name ?? b.slug);
704
+ }
705
+ if (sort === "recent") {
706
+ const publishedDelta2 = new Date(b.published_at ?? 0).getTime() - new Date(a.published_at ?? 0).getTime();
707
+ if (publishedDelta2 !== 0) {
708
+ return publishedDelta2;
709
+ }
710
+ return a.slug.localeCompare(b.slug);
711
+ }
712
+ const priorityDelta = getRecommendedPriority(b) - getRecommendedPriority(a);
713
+ if (priorityDelta !== 0) {
714
+ return priorityDelta;
715
+ }
716
+ if (a.namespace !== b.namespace) {
717
+ if (a.namespace === "@official") return -1;
718
+ if (b.namespace === "@official") return 1;
719
+ }
720
+ const publishedDelta = new Date(b.published_at ?? 0).getTime() - new Date(a.published_at ?? 0).getTime();
721
+ if (publishedDelta !== 0) {
722
+ return publishedDelta;
723
+ }
724
+ return (a.name ?? a.slug).localeCompare(b.name ?? b.slug);
725
+ }
726
+ function sortPublicContent(items, sort = "recommended") {
727
+ return [...items].sort((left, right) => comparePublicContent(left, right, sort));
728
+ }
371
729
  export {
730
+ API_CONTENT_TYPES,
731
+ API_CONTENT_TYPE_TO_CONTENT_TYPE,
732
+ CONTENT_INTELLIGENCE_SOURCES,
733
+ CONTENT_TYPES,
734
+ CONTENT_TYPE_TO_API_CONTENT_TYPE,
735
+ PUBLIC_CONTENT_SOURCES,
372
736
  RegistryAPIClient,
737
+ RegistryAPIError,
373
738
  WIRING_RULES,
374
739
  buildIOMap,
740
+ comparePublicContent,
375
741
  createRegistryClient,
376
742
  createResolver,
377
743
  deriveIOWirings,
378
744
  detectWirings,
379
- resolvePatternPreset
745
+ isApiContentType,
746
+ isContentIntelligenceSource,
747
+ isContentType,
748
+ isPublicContentSource,
749
+ normalizePublicContentSort,
750
+ resolvePatternPreset,
751
+ sortPublicContent
380
752
  };
381
753
  //# sourceMappingURL=index.js.map