@kb-labs/marketplace-core 2.93.0 → 2.96.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.d.ts +26 -6
- package/dist/index.js +56 -22
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -21,19 +21,23 @@ interface MarketplaceServiceOptions {
|
|
|
21
21
|
* provided, per-call `ctx.projectRoot` wins.
|
|
22
22
|
*/
|
|
23
23
|
projectRoot?: string;
|
|
24
|
-
/**
|
|
24
|
+
/** Default package source (npm/pnpm) */
|
|
25
25
|
source: PackageSource;
|
|
26
|
+
/** KB Registry package source — used for specs starting with 'kb:' */
|
|
27
|
+
registrySource?: PackageSource;
|
|
26
28
|
/** Additional strategies beyond built-in plugin/adapter */
|
|
27
29
|
strategies?: EntityKindStrategy[];
|
|
28
30
|
}
|
|
29
31
|
declare class MarketplaceService implements MarketplaceServiceAPI {
|
|
30
32
|
private readonly roots;
|
|
31
33
|
private readonly source;
|
|
34
|
+
private readonly registrySource?;
|
|
32
35
|
private readonly strategies;
|
|
33
36
|
constructor(opts: MarketplaceServiceOptions);
|
|
34
37
|
registerStrategy(strategy: EntityKindStrategy): void;
|
|
35
38
|
install(ctx: ScopeContext, specs: string[], opts?: {
|
|
36
39
|
dev?: boolean;
|
|
40
|
+
shareToken?: string;
|
|
37
41
|
}): Promise<InstallResult>;
|
|
38
42
|
uninstall(ctx: ScopeContext, packageIds: string[]): Promise<void>;
|
|
39
43
|
link(ctx: ScopeContext, packagePath: string): Promise<InstallResultEntry>;
|
|
@@ -61,6 +65,13 @@ declare class MarketplaceService implements MarketplaceServiceAPI {
|
|
|
61
65
|
}): Promise<SyncResult>;
|
|
62
66
|
private _syncPackage;
|
|
63
67
|
doctor(ctx: ScopeContext): Promise<DoctorReport>;
|
|
68
|
+
/**
|
|
69
|
+
* Detect the primary entity kind of a package via registered strategies.
|
|
70
|
+
* Returns null when no strategy recognizes the package — i.e. it is not a
|
|
71
|
+
* valid KB Labs entity (no plugin/adapter/... manifest). Callers MUST treat
|
|
72
|
+
* null as a hard failure rather than defaulting to 'plugin' (B-021): a plain
|
|
73
|
+
* npm package with no kb manifest must never be recorded as a plugin.
|
|
74
|
+
*/
|
|
64
75
|
private detectKind;
|
|
65
76
|
/**
|
|
66
77
|
* Hard guard: adapters may only be installed/linked in platform scope.
|
|
@@ -75,11 +86,20 @@ declare class AdapterScopeError extends Error {
|
|
|
75
86
|
constructor(message: string);
|
|
76
87
|
}
|
|
77
88
|
/**
|
|
78
|
-
*
|
|
89
|
+
* Thrown when a package was resolved/installed but is not a recognizable KB Labs
|
|
90
|
+
* entity (no plugin/adapter/workflow manifest). Maps to HTTP 422. Prevents
|
|
91
|
+
* recording bogus lock entries for unrelated npm packages (B-021).
|
|
92
|
+
*/
|
|
93
|
+
declare class InvalidEntityError extends Error {
|
|
94
|
+
readonly code = "MARKETPLACE_NOT_AN_ENTITY";
|
|
95
|
+
constructor(message: string);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Merge per-scope entries with project-wins precedence.
|
|
79
99
|
*
|
|
80
|
-
* For a given package id present in both platform and project, the
|
|
100
|
+
* For a given package id present in both platform and project, the project
|
|
81
101
|
* entry is kept and a diagnostic is emitted so the caller can surface the
|
|
82
|
-
*
|
|
102
|
+
* override.
|
|
83
103
|
*/
|
|
84
104
|
declare function mergeScopedEntries(perScope: Array<{
|
|
85
105
|
scope: MarketplaceScope;
|
|
@@ -123,7 +143,7 @@ declare function resolveScopeRoot(roots: ServiceRoots, ctx: ScopeContext): strin
|
|
|
123
143
|
/**
|
|
124
144
|
* Resolve the set of roots to read from for a query context (`list`,
|
|
125
145
|
* `getEntry`). `'all'` returns both; the caller is responsible for merging
|
|
126
|
-
* with a
|
|
146
|
+
* with a project-wins precedence.
|
|
127
147
|
*/
|
|
128
148
|
declare function resolveQueryRoots(roots: ServiceRoots, ctx: QueryScopeContext): Array<{
|
|
129
149
|
scope: MarketplaceScope;
|
|
@@ -189,4 +209,4 @@ declare class AdapterStrategy implements EntityKindStrategy {
|
|
|
189
209
|
beforeUninstall(packageId: string, service: MarketplaceServiceAPI, ctx: ScopeContext): Promise<void>;
|
|
190
210
|
}
|
|
191
211
|
|
|
192
|
-
export { AdapterScopeError, AdapterStrategy, MarketplaceService, type MarketplaceServiceOptions, PluginStrategy, ScopeResolutionError, type ServiceRoots, createEmptyManifestCache, mergeScopedEntries, readManifestCache, removeCacheEntry, resolveQueryRoots, resolveScopeRoot, setCacheEntry, writeManifestCache };
|
|
212
|
+
export { AdapterScopeError, AdapterStrategy, InvalidEntityError, MarketplaceService, type MarketplaceServiceOptions, PluginStrategy, ScopeResolutionError, type ServiceRoots, createEmptyManifestCache, mergeScopedEntries, readManifestCache, removeCacheEntry, resolveQueryRoots, resolveScopeRoot, setCacheEntry, writeManifestCache };
|
package/dist/index.js
CHANGED
|
@@ -202,10 +202,12 @@ var ScopeResolutionError = class extends Error {
|
|
|
202
202
|
var MarketplaceService = class {
|
|
203
203
|
roots;
|
|
204
204
|
source;
|
|
205
|
+
registrySource;
|
|
205
206
|
strategies = /* @__PURE__ */ new Map();
|
|
206
207
|
constructor(opts) {
|
|
207
208
|
this.roots = { platformRoot: opts.platformRoot, projectRoot: opts.projectRoot };
|
|
208
209
|
this.source = opts.source;
|
|
210
|
+
this.registrySource = opts.registrySource;
|
|
209
211
|
this.registerStrategy(new PluginStrategy());
|
|
210
212
|
this.registerStrategy(new AdapterStrategy());
|
|
211
213
|
if (opts.strategies) {
|
|
@@ -226,19 +228,38 @@ var MarketplaceService = class {
|
|
|
226
228
|
const warnings = [];
|
|
227
229
|
const diagnostics = [];
|
|
228
230
|
for (const spec of specs) {
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
+
const isKbSpec = spec.startsWith("kb:");
|
|
232
|
+
if (isKbSpec && !this.registrySource) {
|
|
233
|
+
warnings.push(`Registry source not configured \u2014 cannot install '${spec}'. Set marketplace.registry.url in kb.config.json.`);
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
let source = isKbSpec ? this.registrySource : this.source;
|
|
237
|
+
if (isKbSpec && opts?.shareToken && source.withShareToken) {
|
|
238
|
+
source = source.withShareToken(opts.shareToken);
|
|
239
|
+
}
|
|
240
|
+
const resolved = await source.resolve(spec);
|
|
241
|
+
const result = await source.install(resolved, scopeRoot, opts);
|
|
231
242
|
const primaryKind = await this.detectKind(result.packageRoot);
|
|
243
|
+
if (primaryKind === null) {
|
|
244
|
+
await source.remove(result.id, scopeRoot).catch(() => void 0);
|
|
245
|
+
throw new InvalidEntityError(
|
|
246
|
+
`Package "${result.id}" (resolved from "${spec}") is not a valid KB Labs entity \u2014 no plugin/adapter/workflow manifest found. Nothing was installed. Did you mean a scoped package such as "@kb-labs/${spec}-entry"?`
|
|
247
|
+
);
|
|
248
|
+
}
|
|
232
249
|
this.assertScopeAllowsKind(ctx.scope, primaryKind);
|
|
233
250
|
const strategy = this.strategies.get(primaryKind);
|
|
234
251
|
const provides = strategy ? await strategy.extractProvides(result.packageRoot) : [primaryKind];
|
|
252
|
+
const trust = resolved.signature ? "trusted" : "untrusted";
|
|
235
253
|
const entry = createMarketplaceEntry({
|
|
236
254
|
version: result.version,
|
|
237
255
|
integrity: result.integrity,
|
|
238
256
|
resolvedPath: relativeToRoot(scopeRoot, result.packageRoot),
|
|
239
257
|
source: resolved.source,
|
|
240
258
|
primaryKind,
|
|
241
|
-
provides
|
|
259
|
+
provides,
|
|
260
|
+
trust,
|
|
261
|
+
signature: resolved.signature,
|
|
262
|
+
spec
|
|
242
263
|
});
|
|
243
264
|
await addToMarketplaceLock(scopeRoot, result.id, entry);
|
|
244
265
|
await this.cacheManifest(scopeRoot, result.id, result.packageRoot, primaryKind, result.integrity);
|
|
@@ -267,11 +288,13 @@ var MarketplaceService = class {
|
|
|
267
288
|
const scopeRoot = resolveScopeRoot(this.roots, ctx);
|
|
268
289
|
for (const id of packageIds) {
|
|
269
290
|
const entry = await this.getEntry(ctx, id);
|
|
270
|
-
if (entry) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
291
|
+
if (!entry) {
|
|
292
|
+
await removeCacheEntry(scopeRoot, id);
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
const strategy = this.strategies.get(entry.primaryKind);
|
|
296
|
+
if (strategy?.beforeUninstall) {
|
|
297
|
+
await strategy.beforeUninstall(id, this, ctx);
|
|
275
298
|
}
|
|
276
299
|
await removeFromMarketplaceLock(scopeRoot, id);
|
|
277
300
|
await removeCacheEntry(scopeRoot, id);
|
|
@@ -295,6 +318,11 @@ var MarketplaceService = class {
|
|
|
295
318
|
const id = pkgJson.name;
|
|
296
319
|
const version = pkgJson.version ?? "0.0.0";
|
|
297
320
|
const primaryKind = await this.detectKind(absPath);
|
|
321
|
+
if (primaryKind === null) {
|
|
322
|
+
throw new InvalidEntityError(
|
|
323
|
+
`Cannot link "${id}" (${absPath}) \u2014 not a valid KB Labs entity (no plugin/adapter/workflow manifest found).`
|
|
324
|
+
);
|
|
325
|
+
}
|
|
298
326
|
this.assertScopeAllowsKind(ctx.scope, primaryKind);
|
|
299
327
|
const strategy = this.strategies.get(primaryKind);
|
|
300
328
|
const provides = strategy ? await strategy.extractProvides(absPath) : [primaryKind];
|
|
@@ -426,18 +454,10 @@ var MarketplaceService = class {
|
|
|
426
454
|
skipped.push({ id: pkgName, reason: "already in lock" });
|
|
427
455
|
return;
|
|
428
456
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const kind = await strategy2.detectKind(pkgDir);
|
|
432
|
-
if (kind) {
|
|
433
|
-
detected = true;
|
|
434
|
-
break;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
if (!detected) {
|
|
457
|
+
const primaryKind = await this.detectKind(pkgDir);
|
|
458
|
+
if (primaryKind === null) {
|
|
438
459
|
return;
|
|
439
460
|
}
|
|
440
|
-
const primaryKind = await this.detectKind(pkgDir);
|
|
441
461
|
if (scope === "project" && primaryKind === "adapter") {
|
|
442
462
|
skipped.push({ id: pkgName, reason: "adapter not allowed in project scope" });
|
|
443
463
|
return;
|
|
@@ -518,6 +538,13 @@ var MarketplaceService = class {
|
|
|
518
538
|
// -------------------------------------------------------------------------
|
|
519
539
|
// Private
|
|
520
540
|
// -------------------------------------------------------------------------
|
|
541
|
+
/**
|
|
542
|
+
* Detect the primary entity kind of a package via registered strategies.
|
|
543
|
+
* Returns null when no strategy recognizes the package — i.e. it is not a
|
|
544
|
+
* valid KB Labs entity (no plugin/adapter/... manifest). Callers MUST treat
|
|
545
|
+
* null as a hard failure rather than defaulting to 'plugin' (B-021): a plain
|
|
546
|
+
* npm package with no kb manifest must never be recorded as a plugin.
|
|
547
|
+
*/
|
|
521
548
|
async detectKind(packageRoot) {
|
|
522
549
|
for (const strategy of this.strategies.values()) {
|
|
523
550
|
const kind = await strategy.detectKind(packageRoot);
|
|
@@ -525,7 +552,7 @@ var MarketplaceService = class {
|
|
|
525
552
|
return kind;
|
|
526
553
|
}
|
|
527
554
|
}
|
|
528
|
-
return
|
|
555
|
+
return null;
|
|
529
556
|
}
|
|
530
557
|
/**
|
|
531
558
|
* Hard guard: adapters may only be installed/linked in platform scope.
|
|
@@ -576,6 +603,13 @@ var AdapterScopeError = class extends Error {
|
|
|
576
603
|
this.name = "AdapterScopeError";
|
|
577
604
|
}
|
|
578
605
|
};
|
|
606
|
+
var InvalidEntityError = class extends Error {
|
|
607
|
+
code = "MARKETPLACE_NOT_AN_ENTITY";
|
|
608
|
+
constructor(message) {
|
|
609
|
+
super(message);
|
|
610
|
+
this.name = "InvalidEntityError";
|
|
611
|
+
}
|
|
612
|
+
};
|
|
579
613
|
function relativeToRoot(root, absPath) {
|
|
580
614
|
const rel = path4.relative(root, absPath);
|
|
581
615
|
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
@@ -599,7 +633,7 @@ function mergeScopedEntries(perScope) {
|
|
|
599
633
|
if (a.scope === b.scope) {
|
|
600
634
|
return 0;
|
|
601
635
|
}
|
|
602
|
-
return a.scope === "
|
|
636
|
+
return a.scope === "project" ? -1 : 1;
|
|
603
637
|
});
|
|
604
638
|
for (const { scope, entries } of ordered) {
|
|
605
639
|
for (const e of entries) {
|
|
@@ -607,7 +641,7 @@ function mergeScopedEntries(perScope) {
|
|
|
607
641
|
if (existing) {
|
|
608
642
|
diagnostics.push({
|
|
609
643
|
code: "MARKETPLACE_SCOPE_COLLISION",
|
|
610
|
-
message: `Package "${e.id}" exists in both platform and
|
|
644
|
+
message: `Package "${e.id}" exists in both platform and project scopes \u2014 project wins.`,
|
|
611
645
|
packageId: e.id,
|
|
612
646
|
scope
|
|
613
647
|
});
|
|
@@ -619,6 +653,6 @@ function mergeScopedEntries(perScope) {
|
|
|
619
653
|
return { entries: Array.from(out.values()), diagnostics };
|
|
620
654
|
}
|
|
621
655
|
|
|
622
|
-
export { AdapterScopeError, AdapterStrategy, MarketplaceService, PluginStrategy, ScopeResolutionError, createEmptyManifestCache, mergeScopedEntries, readManifestCache, removeCacheEntry, resolveQueryRoots, resolveScopeRoot, setCacheEntry, writeManifestCache };
|
|
656
|
+
export { AdapterScopeError, AdapterStrategy, InvalidEntityError, MarketplaceService, PluginStrategy, ScopeResolutionError, createEmptyManifestCache, mergeScopedEntries, readManifestCache, removeCacheEntry, resolveQueryRoots, resolveScopeRoot, setCacheEntry, writeManifestCache };
|
|
623
657
|
//# sourceMappingURL=index.js.map
|
|
624
658
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/manifest-cache.ts","../src/strategies/plugin-strategy.ts","../src/strategies/adapter-strategy.ts","../src/scope.ts","../src/marketplace-service.ts"],"names":["path","path2","fs2","path3","fs3","DiagnosticCollector","strategy","loadManifest","pathToFileURL"],"mappings":";;;;;;;;;;AAUA,IAAM,UAAA,GAAa,gCAAA;AACnB,IAAM,cAAA,GAAiB,4BAAA;AAKvB,eAAsB,kBAAkB,IAAA,EAA6C;AACnF,EAAA,MAAM,SAAA,GAAiBA,KAAA,CAAA,IAAA,CAAK,IAAA,EAAM,UAAU,CAAA;AAC5C,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAS,EAAA,CAAA,QAAA,CAAS,SAAA,EAAW,OAAO,CAAA;AAChD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAA,EAAQ,WAAW,cAAA,EAAgB;AAAC,MAAA,OAAO,IAAA;AAAA,IAAK;AACpD,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAKA,eAAsB,kBAAA,CAAmB,MAAc,KAAA,EAAqC;AAC1F,EAAA,MAAM,SAAA,GAAiBA,KAAA,CAAA,IAAA,CAAK,IAAA,EAAM,UAAU,CAAA;AAC5C,EAAA,MAAM,GAAA,GAAWA,cAAQ,SAAS,CAAA;AAClC,EAAA,MAAS,EAAA,CAAA,KAAA,CAAM,GAAA,EAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AAEvC,EAAA,MAAM,OAAA,GAAU,CAAA,EAAG,SAAS,CAAA,KAAA,EAAQ,YAAY,CAAA,CAAA;AAChD,EAAA,MAAS,EAAA,CAAA,SAAA,CAAU,SAAS,IAAA,CAAK,SAAA,CAAU,OAAO,IAAA,EAAM,CAAC,CAAA,GAAI,IAAA,EAAM,OAAO,CAAA;AAC1E,EAAA,MAAS,EAAA,CAAA,MAAA,CAAO,SAAS,SAAS,CAAA;AACpC;AAKO,SAAS,wBAAA,GAA0C;AACxD,EAAA,OAAO,EAAE,MAAA,EAAQ,cAAA,EAAgB,OAAA,EAAS,EAAC,EAAE;AAC/C;AAKA,eAAsB,aAAA,CACpB,IAAA,EACA,SAAA,EACA,KAAA,EACe;AACf,EAAA,MAAM,QAAA,GAAW,MAAM,iBAAA,CAAkB,IAAI,KAAK,wBAAA,EAAyB;AAC3E,EAAA,QAAA,CAAS,OAAA,CAAQ,SAAS,CAAA,GAAI,KAAA;AAC9B,EAAA,MAAM,kBAAA,CAAmB,MAAM,QAAQ,CAAA;AACzC;AAKA,eAAsB,gBAAA,CACpB,MACA,SAAA,EACe;AACf,EAAA,MAAM,QAAA,GAAW,MAAM,iBAAA,CAAkB,IAAI,CAAA;AAC7C,EAAA,IAAI,CAAC,QAAA,IAAY,EAAE,SAAA,IAAa,SAAS,OAAA,CAAA,EAAU;AAAC,IAAA;AAAA,EAAO;AAC3D,EAAA,OAAO,QAAA,CAAS,QAAQ,SAAS,CAAA;AACjC,EAAA,MAAM,kBAAA,CAAmB,MAAM,QAAQ,CAAA;AACzC;AC/DO,IAAM,iBAAN,MAAmD;AAAA,EACxD,IAAA,GAAmB,QAAA;AAAA,EAEnB,MAAM,WAAW,WAAA,EAAiD;AAChE,IAAA,MAAM,IAAA,GAAO,IAAI,mBAAA,EAAoB;AACrC,IAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,WAAA,EAAa,IAAI,CAAA;AACrD,IAAA,OAAO,WAAW,QAAA,GAAW,IAAA;AAAA,EAC/B;AAAA,EAEA,MAAM,gBAAgB,WAAA,EAA4C;AAChE,IAAA,MAAM,IAAA,GAAO,IAAI,mBAAA,EAAoB;AACrC,IAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,WAAA,EAAa,IAAI,CAAA;AACrD,IAAA,IAAI,CAAC,QAAA,EAAU;AAAC,MAAA,OAAO,CAAC,QAAQ,CAAA;AAAA,IAAE;AAClC,IAAA,OAAO,mBAAmB,QAAQ,CAAA;AAAA,EACpC;AAAA,EAEA,MAAM,UAAU,WAAA,EAA6C;AAC3D,IAAA,MAAM,IAAA,GAAO,IAAI,mBAAA,EAAoB;AACrC,IAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,WAAA,EAAa,IAAI,CAAA;AACrD,IAAA,OAAO,UAAU,EAAA,IAAM,IAAA;AAAA,EACzB;AACF;ACfO,IAAM,kBAAN,MAAoD;AAAA,EACzD,IAAA,GAAmB,SAAA;AAAA,EAEnB,MAAM,WAAW,WAAA,EAAiD;AAChE,IAAA,MAAM,QAAA,GAAW,MAAM,mBAAA,CAAoB,WAAW,CAAA;AACtD,IAAA,OAAO,WAAW,SAAA,GAAY,IAAA;AAAA,EAChC;AAAA,EAEA,MAAM,gBAAgB,YAAA,EAA6C;AACjE,IAAA,OAAO,CAAC,SAAS,CAAA;AAAA,EACnB;AAAA,EAEA,MAAM,YAAA,CACJ,SAAA,EACA,WAAA,EACA,SACA,GAAA,EACe;AACf,IAAA,MAAM,QAAA,GAAW,MAAM,mBAAA,CAAoB,WAAW,CAAA;AACtD,IAAA,IAAI,CAAC,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU;AAAC,MAAA;AAAA,IAAO;AAI3C,IAAA,MAAM,SAAA,GAAY,MAAM,OAAA,CAAQ,IAAA,CAAK,KAAK,EAAE,IAAA,EAAM,WAAW,CAAA;AAC7D,IAAA,MAAM,YAAA,GAAe,IAAI,GAAA,CAAI,SAAA,CAAU,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,EAAE,CAAC,CAAA;AAErD,IAAA,KAAA,MAAW,GAAA,IAAO,QAAA,CAAS,QAAA,CAAS,QAAA,EAAU;AAC5C,MAAA,MAAM,KAAA,GAAQ,OAAO,GAAA,KAAQ,QAAA,GAAW,MAAM,GAAA,CAAI,EAAA;AAClD,MAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,GAAA,CAAI,KAAK,KAClC,SAAA,CAAU,IAAA,CAAK,CAAA,CAAA,KAAK,CAAA,CAAE,EAAA,CAAG,QAAA,CAAS,CAAA,SAAA,EAAY,KAAK,EAAE,CAAC,CAAA;AAExD,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,CAAA,uBAAA,EAA0B,SAAS,CAAA,oBAAA,EAAuB,KAAK,qFACJ,KAAK,CAAA,CAAA;AAAA,SAClE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eAAA,CACJ,SAAA,EACA,OAAA,EACA,GAAA,EACe;AACf,IAAA,MAAM,SAAA,GAAY,MAAM,OAAA,CAAQ,IAAA,CAAK,KAAK,EAAE,IAAA,EAAM,WAAW,CAAA;AAC7D,IAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG;AACxB,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,mCAAmC,SAAS,CAAA,8CAAA;AAAA,OAC9C;AAAA,IACF;AAAA,EACF;AACF;AAeA,eAAe,oBAAoB,WAAA,EAA0D;AAC3F,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAgBC,KAAA,CAAA,IAAA,CAAK,WAAA,EAAa,MAAA,EAAQ,UAAU,CAAA;AAC1D,IAAA,MAASC,UAAO,QAAQ,CAAA;AACxB,IAAA,MAAM,GAAA,GAAM,MAAM,OAAO,aAAA,CAAc,QAAQ,CAAA,CAAE,IAAA,CAAA;AACjD,IAAA,IAAI,GAAA,CAAI,YAAY,OAAO,GAAA,CAAI,aAAa,QAAA,IAAY,GAAA,CAAI,SAAS,UAAA,EAAY;AAC/E,MAAA,OAAO,GAAA,CAAI,QAAA;AAAA,IACb;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AC5EA,IAAM,sBAAA,GAAyB,CAAC,iBAAA,EAAmB,gBAAgB,CAAA;AAuB5D,SAAS,gBAAA,CAAiB,OAAqB,GAAA,EAA2B;AAC/E,EAAA,IAAI,GAAA,CAAI,UAAU,UAAA,EAAY;AAC5B,IAAA,OAAO,KAAA,CAAM,YAAA;AAAA,EACf;AAEA,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,WAAA,IAAe,KAAA,CAAM,WAAA;AAC3C,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,oBAAA;AAAA,MACR,4BAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,CAAMC,KAAA,CAAA,UAAA,CAAW,SAAS,CAAA,EAAG;AAC/B,IAAA,MAAM,IAAI,oBAAA;AAAA,MACR,iCAAA;AAAA,MACA,sCAAsC,SAAS,CAAA,EAAA;AAAA,KACjD;AAAA,EACF;AAEA,EAAA,IAAI;AACF,IAAA,UAAA,CAAW,SAAA,EAAW,UAAU,IAAI,CAAA;AAAA,EACtC,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,oBAAA;AAAA,MACR,8BAAA;AAAA,MACA,gCAAgC,SAAS,CAAA,EAAA;AAAA,KAC3C;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,GAAY,sBAAA,CAAuB,IAAA,CAAK,CAAC,IAAA,KAAS;AACtD,IAAA,IAAI;AACF,MAAA,UAAA,CAAgBA,WAAK,SAAA,EAAW,KAAA,EAAO,IAAI,CAAA,EAAG,UAAU,IAAI,CAAA;AAC5D,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF,CAAC,CAAA;AACD,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,oBAAA;AAAA,MACR,8BAAA;AAAA,MACA,gBAAgB,SAAS,CAAA,uFAAA;AAAA,KAC3B;AAAA,EACF;AAEA,EAAA,IAASA,cAAQ,SAAS,CAAA,KAAWA,KAAA,CAAA,OAAA,CAAQ,KAAA,CAAM,YAAY,CAAA,EAAG;AAChE,IAAA,MAAM,IAAI,oBAAA;AAAA,MACR,+BAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAYA,cAAQ,SAAS,CAAA;AAC/B;AAOO,SAAS,iBAAA,CACd,OACA,GAAA,EACkD;AAClD,EAAA,IAAI,GAAA,CAAI,UAAU,UAAA,EAAY;AAC5B,IAAA,OAAO,CAAC,EAAE,KAAA,EAAO,YAAY,IAAA,EAAM,KAAA,CAAM,cAAc,CAAA;AAAA,EACzD;AACA,EAAA,IAAI,GAAA,CAAI,UAAU,SAAA,EAAW;AAC3B,IAAA,OAAO;AAAA,MACL;AAAA,QACE,KAAA,EAAO,SAAA;AAAA,QACP,IAAA,EAAM,iBAAiB,KAAA,EAAO,EAAE,OAAO,SAAA,EAAW,WAAA,EAAa,GAAA,CAAI,WAAA,EAAa;AAAA;AAClF,KACF;AAAA,EACF;AAIA,EAAA,MAAM,GAAA,GAAwD;AAAA,IAC5D,EAAE,KAAA,EAAO,UAAA,EAAY,IAAA,EAAM,MAAM,YAAA;AAAa,GAChD;AACA,EAAA,MAAM,gBAAA,GAAmB,GAAA,CAAI,WAAA,IAAe,KAAA,CAAM,WAAA;AAClD,EAAA,IAAI,gBAAA,EAAkB;AACpB,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,iBAAiB,KAAA,EAAO,EAAE,OAAO,SAAA,EAAW,WAAA,EAAa,kBAAkB,CAAA;AAC/F,MAAA,GAAA,CAAI,KAAK,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,aAAa,CAAA;AAAA,IAClD,CAAA,CAAA,MAAQ;AAAA,IAGR;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAMO,IAAM,oBAAA,GAAN,cAAmC,KAAA,CAAM;AAAA,EACrC,IAAA;AAAA,EACT,WAAA,CAAY,MAAc,OAAA,EAAiB;AACzC,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AAAA,EACd;AACF;;;ACxEO,IAAM,qBAAN,MAA0D;AAAA,EAC9C,KAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA,uBAAiB,GAAA,EAAoC;AAAA,EAEtE,YAAY,IAAA,EAAiC;AAC3C,IAAA,IAAA,CAAK,QAAQ,EAAE,YAAA,EAAc,KAAK,YAAA,EAAc,WAAA,EAAa,KAAK,WAAA,EAAY;AAC9E,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AAGnB,IAAA,IAAA,CAAK,gBAAA,CAAiB,IAAI,cAAA,EAAgB,CAAA;AAC1C,IAAA,IAAA,CAAK,gBAAA,CAAiB,IAAI,eAAA,EAAiB,CAAA;AAG3C,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,KAAA,MAAW,CAAA,IAAK,KAAK,UAAA,EAAY;AAC/B,QAAA,IAAA,CAAK,iBAAiB,CAAC,CAAA;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,iBAAiB,QAAA,EAAoC;AACnD,IAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,QAAA,CAAS,IAAA,EAAM,QAAQ,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACA,IAAA,EACwB;AACxB,IAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAClD,IAAA,MAAM,YAAkC,EAAC;AACzC,IAAA,MAAM,WAAqB,EAAC;AAC5B,IAAA,MAAM,cAAuC,EAAC;AAE9C,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,MAAA,CAAO,QAAQ,IAAI,CAAA;AAC/C,MAAA,MAAM,SAAS,MAAM,IAAA,CAAK,OAAO,OAAA,CAAQ,QAAA,EAAU,WAAW,IAAI,CAAA;AAGlE,MAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,UAAA,CAAW,OAAO,WAAW,CAAA;AAC5D,MAAA,IAAA,CAAK,qBAAA,CAAsB,GAAA,CAAI,KAAA,EAAO,WAAW,CAAA;AAEjD,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,WAAW,CAAA;AAChD,MAAA,MAAM,QAAA,GAAW,WACb,MAAM,QAAA,CAAS,gBAAgB,MAAA,CAAO,WAAW,CAAA,GACjD,CAAC,WAAW,CAAA;AAGhB,MAAA,MAAM,QAAQ,sBAAA,CAAuB;AAAA,QACnC,SAAS,MAAA,CAAO,OAAA;AAAA,QAChB,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,YAAA,EAAc,cAAA,CAAe,SAAA,EAAW,MAAA,CAAO,WAAW,CAAA;AAAA,QAC1D,QAAQ,QAAA,CAAS,MAAA;AAAA,QACjB,WAAA;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,MAAM,oBAAA,CAAqB,SAAA,EAAW,MAAA,CAAO,EAAA,EAAI,KAAK,CAAA;AAGtD,MAAA,MAAM,IAAA,CAAK,cAAc,SAAA,EAAW,MAAA,CAAO,IAAI,MAAA,CAAO,WAAA,EAAa,WAAA,EAAa,MAAA,CAAO,SAAS,CAAA;AAGhG,MAAA,IAAI,UAAU,YAAA,EAAc;AAC1B,QAAA,IAAI;AACF,UAAA,MAAM,SAAS,YAAA,CAAa,MAAA,CAAO,IAAI,MAAA,CAAO,WAAA,EAAa,MAAM,GAAG,CAAA;AAAA,QACtE,SAAS,GAAA,EAAK;AACZ,UAAA,QAAA,CAAS,KAAK,CAAA,iBAAA,EAAoB,MAAA,CAAO,EAAE,CAAA,EAAA,EAAM,GAAA,CAAc,OAAO,CAAA,CAAE,CAAA;AAAA,QAC1E;AAAA,MACF;AAEA,MAAA,SAAA,CAAU,IAAA,CAAK;AAAA,QACb,IAAI,MAAA,CAAO,EAAA;AAAA,QACX,SAAS,MAAA,CAAO,OAAA;AAAA,QAChB,WAAA;AAAA,QACA,QAAA;AAAA,QACA,aAAa,MAAA,CAAO,WAAA;AAAA,QACpB,OAAO,GAAA,CAAI;AAAA,OACZ,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,EAAE,SAAA,EAAW,QAAA,EAAU,KAAA,EAAO,GAAA,CAAI,OAAO,WAAA,EAAa,WAAA,CAAY,MAAA,GAAS,WAAA,GAAc,MAAA,EAAU;AAAA,EAC5G;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAAA,CAAU,GAAA,EAAmB,UAAA,EAAqC;AACtE,IAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAClD,IAAA,KAAA,MAAW,MAAM,UAAA,EAAY;AAE3B,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,QAAA,CAAS,KAAK,EAAE,CAAA;AACzC,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,MAAM,WAAW,CAAA;AACtD,QAAA,IAAI,UAAU,eAAA,EAAiB;AAC7B,UAAA,MAAM,QAAA,CAAS,eAAA,CAAgB,EAAA,EAAI,IAAA,EAAM,GAAG,CAAA;AAAA,QAC9C;AAAA,MACF;AAEA,MAAA,MAAM,yBAAA,CAA0B,WAAW,EAAE,CAAA;AAC7C,MAAA,MAAM,gBAAA,CAAiB,WAAW,EAAE,CAAA;AACpC,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,EAAA,EAAI,SAAS,CAAA;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAA,CAAK,GAAA,EAAmB,WAAA,EAAkD;AAC9E,IAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAClD,IAAA,MAAM,OAAA,GAAe,KAAA,CAAA,OAAA,CAAQ,SAAA,EAAW,WAAW,CAAA;AAGnD,IAAA,IAAI,CAAC,YAAA,CAAa,SAAA,EAAW,OAAO,CAAA,EAAG;AACrC,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,SAAS,WAAW,CAAA,aAAA,EAAgB,GAAA,CAAI,KAAK,UAAU,SAAS,CAAA,yBAAA;AAAA,OAClE;AAAA,IACF;AAEA,IAAA,MAAM,UAAU,IAAA,CAAK,KAAA;AAAA,MACnB,MAASC,EAAA,CAAA,QAAA,CAAc,KAAA,CAAA,IAAA,CAAK,OAAA,EAAS,cAAc,GAAG,OAAO;AAAA,KAC/D;AACA,IAAA,MAAM,KAAa,OAAA,CAAQ,IAAA;AAC3B,IAAA,MAAM,OAAA,GAAkB,QAAQ,OAAA,IAAW,OAAA;AAE3C,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,UAAA,CAAW,OAAO,CAAA;AACjD,IAAA,IAAA,CAAK,qBAAA,CAAsB,GAAA,CAAI,KAAA,EAAO,WAAW,CAAA;AAEjD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,WAAW,CAAA;AAChD,IAAA,MAAM,QAAA,GAAW,WACb,MAAM,QAAA,CAAS,gBAAgB,OAAO,CAAA,GACtC,CAAC,WAAW,CAAA;AAEhB,IAAA,MAAM,SAAA,GAAY,MAAM,gBAAA,CAAiB,OAAO,CAAA;AAEhD,IAAA,MAAM,QAAQ,sBAAA,CAAuB;AAAA,MACnC,OAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAA,EAAc,cAAA,CAAe,SAAA,EAAW,OAAO,CAAA;AAAA,MAC/C,MAAA,EAAQ,OAAA;AAAA,MACR,WAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,MAAM,oBAAA,CAAqB,SAAA,EAAW,EAAA,EAAI,KAAK,CAAA;AAC/C,IAAA,MAAM,KAAK,aAAA,CAAc,SAAA,EAAW,EAAA,EAAI,OAAA,EAAS,aAAa,SAAS,CAAA;AAEvE,IAAA,IAAI,UAAU,YAAA,EAAc;AAC1B,MAAA,MAAM,QAAA,CAAS,YAAA,CAAa,EAAA,EAAI,OAAA,EAAS,MAAM,GAAG,CAAA;AAAA,IACpD;AAEA,IAAA,OAAO,EAAE,IAAI,OAAA,EAAS,WAAA,EAAa,UAAU,WAAA,EAAa,OAAA,EAAS,KAAA,EAAO,GAAA,CAAI,KAAA,EAAM;AAAA,EACtF;AAAA,EAEA,MAAM,MAAA,CAAO,GAAA,EAAmB,SAAA,EAAkC;AAChE,IAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAClD,IAAA,MAAM,yBAAA,CAA0B,WAAW,SAAS,CAAA;AACpD,IAAA,MAAM,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,CAAO,GAAA,EAAmB,UAAA,EAA+C;AAC7E,IAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAClD,IAAA,MAAM,IAAA,GAAO,IAAIC,mBAAAA,EAAoB;AACrC,IAAA,MAAM,IAAA,GAAO,MAAM,mBAAA,CAAoB,SAAA,EAAW,IAAI,CAAA;AACtD,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,OAAO,EAAE,SAAA,EAAW,EAAC,EAAG,QAAA,EAAU,CAAC,2BAA2B,CAAA,EAAG,KAAA,EAAO,GAAA,CAAI,KAAA,EAAM;AAAA,IACpF;AAEA,IAAA,MAAM,GAAA,GAAM,UAAA,IAAc,MAAA,CAAO,IAAA,CAAK,KAAK,SAAS,CAAA;AACpD,IAAA,MAAM,QAAQ,GAAA,CAAI,MAAA,CAAO,CAAA,EAAA,KAAM,EAAA,IAAM,KAAK,SAAS,CAAA;AAEnD,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,KAAK,CAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,CAAO,GAAA,EAAmB,SAAA,EAAkC;AAChE,IAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAClD,IAAA,MAAM,EAAA,GAAK,MAAM,YAAA,CAAa,SAAA,EAAW,SAAS,CAAA;AAClD,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,SAAA,EAAY,SAAS,CAAA,eAAA,EAAkB,GAAA,CAAI,KAAK,CAAA,iBAAA,CAAmB,CAAA;AAAA,IACrF;AAAA,EACF;AAAA,EAEA,MAAM,OAAA,CAAQ,GAAA,EAAmB,SAAA,EAAkC;AACjE,IAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAClD,IAAA,MAAM,EAAA,GAAK,MAAM,aAAA,CAAc,SAAA,EAAW,SAAS,CAAA;AACnD,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,SAAA,EAAY,SAAS,CAAA,eAAA,EAAkB,GAAA,CAAI,KAAK,CAAA,iBAAA,CAAmB,CAAA;AAAA,IACrF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAA,CACJ,GAAA,EACA,MAAA,EACmC;AACnC,IAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAGjD,IAAA,MAAM,WAAkF,EAAC;AACzF,IAAA,KAAA,MAAW,EAAE,KAAA,EAAO,IAAA,EAAK,IAAK,OAAA,EAAS;AACrC,MAAA,MAAM,IAAA,GAAO,IAAIA,mBAAAA,EAAoB;AACrC,MAAA,MAAM,IAAA,GAAO,MAAM,mBAAA,CAAoB,IAAA,EAAM,IAAI,CAAA;AACjD,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,QAAA,CAAS,KAAK,EAAE,KAAA,EAAO,OAAA,EAAS,IAAI,CAAA;AACpC,QAAA;AAAA,MACF;AACA,MAAA,MAAM,UAAU,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK,SAAS,EAAE,GAAA,CAAI,CAAC,CAAC,EAAA,EAAI,KAAK,CAAA,MAAO,EAAE,GAAG,KAAA,EAAO,IAAG,CAAE,CAAA;AACtF,MAAA,QAAA,CAAS,IAAA,CAAK,EAAE,KAAA,EAAO,OAAA,EAAS,CAAA;AAAA,IAClC;AAEA,IAAA,MAAM,MAAA,GAAS,mBAAmB,QAAQ,CAAA;AAC1C,IAAA,OAAO,MAAA,EAAQ,IAAA,GACX,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,WAAA,KAAgB,MAAA,CAAO,IAAI,CAAA,GACxD,MAAA,CAAO,OAAA;AAAA,EACb;AAAA,EAEA,MAAM,QAAA,CAAS,GAAA,EAAmB,SAAA,EAAqD;AACrF,IAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAClD,IAAA,MAAM,IAAA,GAAO,IAAIA,mBAAAA,EAAoB;AACrC,IAAA,MAAM,IAAA,GAAO,MAAM,mBAAA,CAAoB,SAAA,EAAW,IAAI,CAAA;AACtD,IAAA,OAAO,IAAA,EAAM,SAAA,CAAU,SAAS,CAAA,IAAK,IAAA;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,IAAA,CACJ,GAAA,EACA,IAAA,EAKqB;AACrB,IAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAClD,IAAA,MAAM,UAAA,GAAa,KAAK,UAAA,IAAc,KAAA;AACtC,IAAA,MAAM,IAAA,GAAO,IAAIA,mBAAAA,EAAoB;AACrC,IAAA,MAAM,OAAO,MAAM,mBAAA,CAAoB,SAAA,EAAW,IAAI,KAAK,eAAA,EAAgB;AAC3E,IAAA,MAAM,cAAc,IAAI,GAAA,CAAI,OAAO,IAAA,CAAK,IAAA,CAAK,SAAS,CAAC,CAAA;AAEvD,IAAA,MAAM,QAA6B,EAAC;AACpC,IAAA,MAAM,UAAiC,EAAC;AAExC,IAAA,MAAM,eAAA,GAAkB,KAAK,OAAA,CAAQ,GAAA,CAAI,OAAU,KAAA,CAAA,IAAA,CAAK,CAAA,EAAG,cAAc,CAAC,CAAA;AAC1E,IAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,OAAA,IAAW,EAAC;AAEzC,IAAA,MAAM,gBAAA,GAAmB,MAAM,IAAA,CAAK,eAAA,EAAiB;AAAA,MACnD,GAAA,EAAK,SAAA;AAAA,MACL,MAAA,EAAQ,eAAA;AAAA,MACR,QAAA,EAAU;AAAA,KACX,CAAA;AAED,IAAA,KAAA,MAAW,cAAc,gBAAA,EAAkB;AACzC,MAAA,MAAM,MAAA,GAAc,KAAA,CAAA,OAAA,CAAQ,SAAA,EAAgB,KAAA,CAAA,OAAA,CAAQ,UAAU,CAAC,CAAA;AAC/D,MAAA,MAAM,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,UAAA,EAAY,WAAA,EAAa,UAAA,EAAY,IAAA,EAAM,KAAA,EAAO,OAAO,CAAA;AAAA,IACjH;AAEA,IAAA,MAAM,oBAAA,CAAqB,WAAW,IAAI,CAAA;AAE1C,IAAA,OAAO,EAAE,OAAO,OAAA,EAAS,KAAA,EAAO,OAAO,IAAA,CAAK,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,EAAO;AAAA,EACrE;AAAA,EAEA,MAAc,YAAA,CACZ,KAAA,EACA,SAAA,EACA,MAAA,EACA,aACA,WAAA,EACA,UAAA,EACA,IAAA,EACA,KAAA,EACA,OAAA,EACe;AACf,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,MAASD,EAAA,CAAA,QAAA,CAAc,WAAK,MAAA,EAAQ,cAAc,CAAA,EAAG,OAAO,CAAC,CAAA;AACxF,MAAA,OAAA,GAAU,OAAA,CAAQ,IAAA;AAClB,MAAA,UAAA,GAAa,QAAQ,OAAA,IAAW,OAAA;AAChC,MAAA,IAAI,CAAC,OAAA,EAAS;AAAE,QAAA;AAAA,MAAQ;AAAA,IAC1B,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,WAAA,CAAY,GAAA,CAAI,OAAO,CAAA,EAAG;AAC5B,MAAA,OAAA,CAAQ,KAAK,EAAE,EAAA,EAAI,OAAA,EAAS,MAAA,EAAQ,mBAAmB,CAAA;AACvD,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,QAAA,GAAW,KAAA;AACf,IAAA,KAAA,MAAWE,SAAAA,IAAY,IAAA,CAAK,UAAA,CAAW,MAAA,EAAO,EAAG;AAC/C,MAAA,MAAM,IAAA,GAAO,MAAMA,SAAAA,CAAS,UAAA,CAAW,MAAM,CAAA;AAC7C,MAAA,IAAI,IAAA,EAAM;AAAE,QAAA,QAAA,GAAW,IAAA;AAAM,QAAA;AAAA,MAAO;AAAA,IACtC;AACA,IAAA,IAAI,CAAC,QAAA,EAAU;AAAE,MAAA;AAAA,IAAQ;AAEzB,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,UAAA,CAAW,MAAM,CAAA;AAGhD,IAAA,IAAI,KAAA,KAAU,SAAA,IAAa,WAAA,KAAgB,SAAA,EAAW;AACpD,MAAA,OAAA,CAAQ,KAAK,EAAE,EAAA,EAAI,OAAA,EAAS,MAAA,EAAQ,wCAAwC,CAAA;AAC5E,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,WAAW,CAAA;AAChD,IAAA,MAAM,QAAA,GAAW,WAAW,MAAM,QAAA,CAAS,gBAAgB,MAAM,CAAA,GAAI,CAAC,WAAW,CAAA;AACjF,IAAA,MAAM,SAAA,GAAY,MAAM,gBAAA,CAAiB,MAAM,CAAA;AAK/C,IAAA,MAAM,UAAA,GAAA,CAAc,UAAU,SAAA,GAAY,MAAM,SAAS,SAAA,CAAU,MAAM,IAAI,IAAA,KAAS,OAAA;AAEtF,IAAA,IAAI,WAAA,CAAY,GAAA,CAAI,UAAU,CAAA,IAAK,eAAe,OAAA,EAAS;AACzD,MAAA,OAAA,CAAQ,KAAK,EAAE,EAAA,EAAI,UAAA,EAAY,MAAA,EAAQ,mBAAmB,CAAA;AAC1D,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAQ,sBAAA,CAAuB;AAAA,MACnC,OAAA,EAAS,UAAA;AAAA,MACT,SAAA;AAAA,MACA,YAAA,EAAc,cAAA,CAAe,SAAA,EAAW,MAAM,CAAA;AAAA,MAC9C,MAAA,EAAQ,OAAA;AAAA,MACR,WAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,IAAI,CAAC,UAAA,EAAY;AAAE,MAAA,KAAA,CAAM,OAAA,GAAU,KAAA;AAAA,IAAO;AAE1C,IAAA,IAAA,CAAK,SAAA,CAAU,UAAU,CAAA,GAAI,KAAA;AAC7B,IAAA,KAAA,CAAM,KAAK,EAAE,EAAA,EAAI,YAAY,WAAA,EAAa,OAAA,EAAS,YAAY,CAAA;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,GAAA,EAA0C;AACrD,IAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAClD,IAAA,MAAM,IAAA,GAAO,IAAID,mBAAAA,EAAoB;AACrC,IAAA,MAAM,IAAA,GAAO,MAAM,mBAAA,CAAoB,SAAA,EAAW,IAAI,CAAA;AACtD,IAAA,MAAM,SAAwB,EAAC;AAE/B,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAO,GAAG,MAAA,EAAQ,CAAC,EAAE,QAAA,EAAU,QAAQ,SAAA,EAAW,EAAA,EAAI,OAAA,EAAS,2BAAA,EAA6B,CAAA,EAAE;AAAA,IACnH;AAEA,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK,SAAS,CAAA;AAE7C,IAAA,KAAA,MAAW,CAAC,EAAA,EAAI,KAAK,CAAA,IAAK,OAAA,EAAS;AACjC,MAAA,MAAM,OAAA,GAAe,KAAA,CAAA,OAAA,CAAQ,SAAA,EAAW,KAAA,CAAM,YAAY,CAAA;AAE1D,MAAA,IAAI;AACF,QAAA,MAASD,UAAO,OAAO,CAAA;AAAA,MACzB,CAAA,CAAA,MAAQ;AACN,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,QAAA,EAAU,OAAA;AAAA,UACV,SAAA,EAAW,EAAA;AAAA,UACX,OAAA,EAAS,gCAAgC,OAAO,CAAA,CAAA;AAAA,UAChD,WAAA,EAAa,+BAA+B,EAAE,CAAA,YAAA;AAAA,SAC/C,CAAA;AACD,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,MAAM,SAAA,EAAW;AACnB,QAAA,MAAM,QAAA,GAAW,MAAM,gBAAA,CAAiB,OAAO,CAAA;AAC/C,QAAA,IAAI,QAAA,IAAY,QAAA,KAAa,KAAA,CAAM,SAAA,EAAW;AAC5C,UAAA,MAAA,CAAO,IAAA,CAAK;AAAA,YACV,QAAA,EAAU,SAAA;AAAA,YACV,SAAA,EAAW,EAAA;AAAA,YACX,OAAA,EAAS,CAAA,6BAAA,EAAgC,KAAA,CAAM,SAAS,SAAS,QAAQ,CAAA,CAAA;AAAA,YACzE,WAAA,EAAa,sCAAsC,EAAE,CAAA;AAAA,WACtD,CAAA;AAAA,QACH;AAAA,MACF;AAEA,MAAA,IAAI,CAAC,MAAM,SAAA,EAAW;AACpB,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,QAAA,EAAU,MAAA;AAAA,UACV,SAAA,EAAW,EAAA;AAAA,UACX,OAAA,EAAS,uBAAA;AAAA,UACT,WAAA,EAAa;AAAA,SACd,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,OAAO,MAAA,CAAO,CAAA,CAAA,KAAK,EAAE,QAAA,KAAa,OAAO,EAAE,MAAA,KAAW,CAAA;AAAA,MAC1D,OAAO,OAAA,CAAQ,MAAA;AAAA,MACf;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,WAAW,WAAA,EAA0C;AACjE,IAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,UAAA,CAAW,MAAA,EAAO,EAAG;AAC/C,MAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,UAAA,CAAW,WAAW,CAAA;AAClD,MAAA,IAAI,IAAA,EAAM;AAAE,QAAA,OAAO,IAAA;AAAA,MAAM;AAAA,IAC3B;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,qBAAA,CAAsB,OAAyB,IAAA,EAAwB;AAC7E,IAAA,IAAI,KAAA,KAAU,SAAA,IAAa,IAAA,KAAS,SAAA,EAAW;AAC7C,MAAA,MAAM,IAAI,iBAAA;AAAA,QACR;AAAA,OAEF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,aAAA,CACZ,SAAA,EACA,SAAA,EACA,WAAA,EACA,aACA,SAAA,EACe;AACf,IAAA,IAAI;AACF,MAAA,IAAI,gBAAgB,QAAA,EAAU;AAC5B,QAAA,MAAM,IAAA,GAAO,IAAIC,mBAAAA,EAAoB;AACrC,QAAA,MAAM,QAAA,GAAW,MAAME,YAAAA,CAAa,WAAA,EAAa,IAAI,CAAA;AACrD,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,MAAM,aAAA,CAAc,WAAW,SAAA,EAAW;AAAA,YACxC,YAAA,EAAc,QAAA;AAAA,YACd,QAAA;AAAA,YACA,QAAA,EAAA,iBAAU,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,YACjC;AAAA,WACD,CAAA;AAAA,QACH;AAAA,MACF,CAAA,MAAA,IAAW,gBAAgB,SAAA,EAAW;AACpC,QAAA,MAAM,QAAA,GAAgB,KAAA,CAAA,IAAA,CAAK,WAAA,EAAa,MAAA,EAAQ,UAAU,CAAA;AAC1D,QAAA,MAAM,GAAA,GAAM,MAAM,OAAOC,aAAAA,CAAc,QAAQ,CAAA,CAAE,IAAA,CAAA;AACjD,QAAA,IAAI,IAAI,QAAA,EAAU;AAChB,UAAA,MAAM,aAAA,CAAc,WAAW,SAAA,EAAW;AAAA,YACxC,YAAA,EAAc,SAAA;AAAA,YACd,UAAU,GAAA,CAAI,QAAA;AAAA,YACd,QAAA,EAAA,iBAAU,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,YACjC;AAAA,WACD,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,KAAK,CAAA,4CAAA,EAA+C,SAAS,CAAA,GAAA,EAAO,GAAA,CAAc,OAAO,CAAA,CAAE,CAAA;AAAA,IACrG;AAAA,EACF;AACF;AAMO,IAAM,iBAAA,GAAN,cAAgC,KAAA,CAAM;AAAA,EAClC,IAAA,GAAO,mCAAA;AAAA,EAChB,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AAAA,EACd;AACF;AAMA,SAAS,cAAA,CAAe,MAAc,OAAA,EAAyB;AAC7D,EAAA,MAAM,GAAA,GAAW,KAAA,CAAA,QAAA,CAAS,IAAA,EAAM,OAAO,CAAA;AACvC,EAAA,OAAO,IAAI,UAAA,CAAW,GAAG,CAAA,GAAI,GAAA,GAAM,KAAK,GAAG,CAAA,CAAA;AAC7C;AAEA,SAAS,YAAA,CAAa,QAAgB,KAAA,EAAwB;AAC5D,EAAA,MAAM,MAAW,KAAA,CAAA,QAAA,CAAc,KAAA,CAAA,OAAA,CAAQ,MAAM,CAAA,EAAQ,KAAA,CAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AACnE,EAAA,OAAO,CAAC,GAAA,CAAI,UAAA,CAAW,IAAI,CAAA,IAAK,CAAM,iBAAW,GAAG,CAAA;AACtD;AAEA,eAAe,iBAAiB,WAAA,EAAsC;AACpE,EAAA,IAAI;AACF,IAAA,MAAM,UAAU,MAASJ,EAAA,CAAA,QAAA,CAAc,KAAA,CAAA,IAAA,CAAK,WAAA,EAAa,cAAc,CAAC,CAAA;AACxE,IAAA,OAAO,CAAA,OAAA,EAAiB,kBAAW,QAAQ,CAAA,CAAE,OAAO,OAAO,CAAA,CAAE,MAAA,CAAO,QAAQ,CAAC,CAAA,CAAA;AAAA,EAC/E,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAA;AAAA,EACT;AACF;AASO,SAAS,mBACd,QAAA,EAC6E;AAC7E,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAoC;AACpD,EAAA,MAAM,cAAuC,EAAC;AAI9C,EAAA,MAAM,OAAA,GAAU,CAAC,GAAG,QAAQ,EAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AAC3C,IAAA,IAAI,CAAA,CAAE,KAAA,KAAU,CAAA,CAAE,KAAA,EAAO;AAAE,MAAA,OAAO,CAAA;AAAA,IAAG;AACrC,IAAA,OAAO,CAAA,CAAE,KAAA,KAAU,UAAA,GAAa,EAAA,GAAK,CAAA;AAAA,EACvC,CAAC,CAAA;AAED,EAAA,KAAA,MAAW,EAAE,KAAA,EAAO,OAAA,EAAQ,IAAK,OAAA,EAAS;AACxC,IAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA;AAC7B,MAAA,IAAI,QAAA,EAAU;AAEZ,QAAA,WAAA,CAAY,IAAA,CAAK;AAAA,UACf,IAAA,EAAM,6BAAA;AAAA,UACN,OAAA,EAAS,CAAA,SAAA,EAAY,CAAA,CAAE,EAAE,iCAAiC,KAAK,CAAA,6BAAA,CAAA;AAAA,UAC/D,WAAW,CAAA,CAAE,EAAA;AAAA,UACb;AAAA,SACD,CAAA;AACD,QAAA;AAAA,MACF;AACA,MAAA,GAAA,CAAI,IAAI,CAAA,CAAE,EAAA,EAAI,EAAE,GAAG,CAAA,EAAG,OAAO,CAAA;AAAA,IAC/B;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,SAAS,KAAA,CAAM,IAAA,CAAK,IAAI,MAAA,EAAQ,GAAG,WAAA,EAAY;AAC1D","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/marketplace-core/manifest-cache\n * Read/write .kb/marketplace.manifests.json — cached manifests for fast discovery.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport type { ManifestCache, ManifestCacheEntry } from '@kb-labs/marketplace-contracts';\n\nconst CACHE_FILE = '.kb/marketplace.manifests.json';\nconst SCHEMA_VERSION = 'kb.marketplace.manifests/1' as const;\n\n/**\n * Read the manifest cache from disk. Returns null if missing or invalid.\n */\nexport async function readManifestCache(root: string): Promise<ManifestCache | null> {\n const cachePath = path.join(root, CACHE_FILE);\n try {\n const raw = await fs.readFile(cachePath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (parsed?.schema !== SCHEMA_VERSION) {return null;}\n return parsed as ManifestCache;\n } catch {\n return null;\n }\n}\n\n/**\n * Write the manifest cache atomically (tmp → rename).\n */\nexport async function writeManifestCache(root: string, cache: ManifestCache): Promise<void> {\n const cachePath = path.join(root, CACHE_FILE);\n const dir = path.dirname(cachePath);\n await fs.mkdir(dir, { recursive: true });\n\n const tmpPath = `${cachePath}.tmp.${randomUUID()}`;\n await fs.writeFile(tmpPath, JSON.stringify(cache, null, 2) + '\\n', 'utf-8');\n await fs.rename(tmpPath, cachePath);\n}\n\n/**\n * Create an empty manifest cache.\n */\nexport function createEmptyManifestCache(): ManifestCache {\n return { schema: SCHEMA_VERSION, entries: {} };\n}\n\n/**\n * Set a single entry in the manifest cache and persist.\n */\nexport async function setCacheEntry(\n root: string,\n packageId: string,\n entry: ManifestCacheEntry,\n): Promise<void> {\n const existing = await readManifestCache(root) ?? createEmptyManifestCache();\n existing.entries[packageId] = entry;\n await writeManifestCache(root, existing);\n}\n\n/**\n * Remove a single entry from the manifest cache and persist.\n */\nexport async function removeCacheEntry(\n root: string,\n packageId: string,\n): Promise<void> {\n const existing = await readManifestCache(root);\n if (!existing || !(packageId in existing.entries)) {return;}\n delete existing.entries[packageId];\n await writeManifestCache(root, existing);\n}\n","/**\n * @module @kb-labs/marketplace-core/strategies/plugin-strategy\n * Strategy for plugins — detects ManifestV3 and extracts entity kinds.\n */\n\nimport type { EntityKind } from '@kb-labs/core-discovery';\nimport type { EntityKindStrategy } from '@kb-labs/marketplace-contracts';\nimport { loadManifest, DiagnosticCollector, extractEntityKinds } from '@kb-labs/core-discovery';\n\nexport class PluginStrategy implements EntityKindStrategy {\n kind: EntityKind = 'plugin';\n\n async detectKind(packageRoot: string): Promise<EntityKind | null> {\n const diag = new DiagnosticCollector();\n const manifest = await loadManifest(packageRoot, diag);\n return manifest ? 'plugin' : null;\n }\n\n async extractProvides(packageRoot: string): Promise<EntityKind[]> {\n const diag = new DiagnosticCollector();\n const manifest = await loadManifest(packageRoot, diag);\n if (!manifest) {return ['plugin'];}\n return extractEntityKinds(manifest);\n }\n\n async resolveId(packageRoot: string): Promise<string | null> {\n const diag = new DiagnosticCollector();\n const manifest = await loadManifest(packageRoot, diag);\n return manifest?.id ?? null;\n }\n}\n","/**\n * @module @kb-labs/marketplace-core/strategies/adapter-strategy\n * Strategy for adapters — detects AdapterManifest, validates dependencies.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { EntityKind } from '@kb-labs/core-discovery';\nimport type {\n EntityKindStrategy,\n MarketplaceServiceAPI,\n ScopeContext,\n} from '@kb-labs/marketplace-contracts';\n\nexport class AdapterStrategy implements EntityKindStrategy {\n kind: EntityKind = 'adapter';\n\n async detectKind(packageRoot: string): Promise<EntityKind | null> {\n const manifest = await loadAdapterManifest(packageRoot);\n return manifest ? 'adapter' : null;\n }\n\n async extractProvides(_packageRoot: string): Promise<EntityKind[]> {\n return ['adapter'];\n }\n\n async afterInstall(\n packageId: string,\n packageRoot: string,\n service: MarketplaceServiceAPI,\n ctx: ScopeContext,\n ): Promise<void> {\n const manifest = await loadAdapterManifest(packageRoot);\n if (!manifest?.requires?.adapters) {return;}\n\n // Adapters only live in platform scope (guarded in MarketplaceService),\n // so we query the same scope we were invoked with.\n const installed = await service.list(ctx, { kind: 'adapter' });\n const installedIds = new Set(installed.map(e => e.id));\n\n for (const dep of manifest.requires.adapters) {\n const depId = typeof dep === 'string' ? dep : dep.id;\n const found = installedIds.has(depId) ||\n installed.some(e => e.id.includes(`adapters-${depId}`));\n\n if (!found) {\n console.warn(\n `[marketplace] Adapter \"${packageId}\" requires adapter \"${depId}\" which is not installed. ` +\n `Run: kb marketplace link <adapter-package-that-provides-${depId}>`,\n );\n }\n }\n }\n\n async beforeUninstall(\n packageId: string,\n service: MarketplaceServiceAPI,\n ctx: ScopeContext,\n ): Promise<void> {\n const installed = await service.list(ctx, { kind: 'adapter' });\n if (installed.length > 1) {\n console.warn(\n `[marketplace] Removing adapter \"${packageId}\" — verify no other adapters depend on it`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ninterface AdapterManifestLike {\n id?: string;\n type?: 'core' | 'extension' | 'proxy';\n implements?: string;\n requires?: {\n adapters?: Array<string | { id: string; alias?: string }>;\n };\n}\n\nasync function loadAdapterManifest(packageRoot: string): Promise<AdapterManifestLike | null> {\n try {\n const distPath = path.join(packageRoot, 'dist', 'index.js');\n await fs.access(distPath);\n const mod = await import(pathToFileURL(distPath).href);\n if (mod.manifest && typeof mod.manifest === 'object' && mod.manifest.implements) {\n return mod.manifest as AdapterManifestLike;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * @module @kb-labs/marketplace-core/scope\n * Scope resolution helpers for the platform/project marketplace split.\n *\n * Every mutating service method is explicitly scope-bound — there is no\n * implicit default. The helpers below compute the absolute root directory\n * for a given ScopeContext and enforce the invariants that the rest of the\n * service relies on (distinct platform/project roots, project has a `.kb/`).\n */\n\nimport * as path from 'node:path';\nimport { accessSync, constants } from 'node:fs';\nimport type {\n MarketplaceScope,\n ScopeContext,\n QueryScopeContext,\n} from '@kb-labs/marketplace-contracts';\n\nconst CONFIG_FILE_CANDIDATES = ['kb.config.jsonc', 'kb.config.json'] as const;\n\n/**\n * Roots known to the MarketplaceService at construction time.\n * `platformRoot` is always known. `projectRoot` is optional at construction\n * (daemon may serve multiple projects); per-call `ctx.projectRoot` can\n * override it.\n */\nexport interface ServiceRoots {\n platformRoot: string;\n projectRoot?: string;\n}\n\n/**\n * Resolve the absolute scope root for a single mutating call.\n *\n * - `scope: 'platform'` — returns `roots.platformRoot`. `projectRoot` in\n * the context is ignored.\n * - `scope: 'project'` — prefers `ctx.projectRoot`, falls back to\n * `roots.projectRoot` from construction. Throws if neither is set,\n * if the path isn't absolute, doesn't exist, lacks a `.kb/kb.config.*`,\n * or equals `roots.platformRoot`.\n */\nexport function resolveScopeRoot(roots: ServiceRoots, ctx: ScopeContext): string {\n if (ctx.scope === 'platform') {\n return roots.platformRoot;\n }\n\n const candidate = ctx.projectRoot ?? roots.projectRoot;\n if (!candidate) {\n throw new ScopeResolutionError(\n 'SCOPE_PROJECT_ROOT_MISSING',\n 'scope=\"project\" requires a projectRoot (pass ctx.projectRoot or configure the service with projectRoot).',\n );\n }\n\n if (!path.isAbsolute(candidate)) {\n throw new ScopeResolutionError(\n 'SCOPE_PROJECT_ROOT_NOT_ABSOLUTE',\n `projectRoot must be absolute, got \"${candidate}\".`,\n );\n }\n\n try {\n accessSync(candidate, constants.F_OK);\n } catch {\n throw new ScopeResolutionError(\n 'SCOPE_PROJECT_ROOT_NOT_FOUND',\n `projectRoot does not exist: \"${candidate}\".`,\n );\n }\n\n const hasConfig = CONFIG_FILE_CANDIDATES.some((name) => {\n try {\n accessSync(path.join(candidate, '.kb', name), constants.F_OK);\n return true;\n } catch {\n return false;\n }\n });\n if (!hasConfig) {\n throw new ScopeResolutionError(\n 'SCOPE_PROJECT_ROOT_NO_KB_DIR',\n `projectRoot \"${candidate}\" does not contain .kb/kb.config.{json,jsonc} — refusing to treat it as a project.`,\n );\n }\n\n if (path.resolve(candidate) === path.resolve(roots.platformRoot)) {\n throw new ScopeResolutionError(\n 'SCOPE_PROJECT_EQUALS_PLATFORM',\n 'projectRoot must not equal platformRoot; use scope=\"platform\" for platform-level operations.',\n );\n }\n\n return path.resolve(candidate);\n}\n\n/**\n * Resolve the set of roots to read from for a query context (`list`,\n * `getEntry`). `'all'` returns both; the caller is responsible for merging\n * with a platform-wins precedence.\n */\nexport function resolveQueryRoots(\n roots: ServiceRoots,\n ctx: QueryScopeContext,\n): Array<{ scope: MarketplaceScope; root: string }> {\n if (ctx.scope === 'platform') {\n return [{ scope: 'platform', root: roots.platformRoot }];\n }\n if (ctx.scope === 'project') {\n return [\n {\n scope: 'project',\n root: resolveScopeRoot(roots, { scope: 'project', projectRoot: ctx.projectRoot }),\n },\n ];\n }\n // 'all' — platform is always included. Project is included only when a\n // project root is available (explicitly via ctx or implicitly from the\n // service). If no project context is known, 'all' degrades to platform-only.\n const out: Array<{ scope: MarketplaceScope; root: string }> = [\n { scope: 'platform', root: roots.platformRoot },\n ];\n const projectCandidate = ctx.projectRoot ?? roots.projectRoot;\n if (projectCandidate) {\n try {\n const projectRoot = resolveScopeRoot(roots, { scope: 'project', projectRoot: projectCandidate });\n out.push({ scope: 'project', root: projectRoot });\n } catch {\n // For 'all' we swallow resolution errors — a missing or invalid project\n // context should not block a platform-only listing.\n }\n }\n return out;\n}\n\n/**\n * Thrown when a scope context cannot be resolved to a concrete root.\n * Uses a stable `code` so API/CLI can surface actionable errors.\n */\nexport class ScopeResolutionError extends Error {\n readonly code: string;\n constructor(code: string, message: string) {\n super(message);\n this.code = code;\n this.name = 'ScopeResolutionError';\n }\n}\n","/**\n * @module @kb-labs/marketplace-core/marketplace-service\n * Unified marketplace service — install/uninstall/enable/disable for all entity types.\n *\n * Every mutating method is explicitly scope-bound (`platform` or `project`).\n * There is no implicit default: callers pass a `ScopeContext` per call so\n * the service can target the right `.kb/marketplace.lock`.\n *\n * Works through PackageSource abstraction — never calls pnpm directly.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as crypto from 'node:crypto';\nimport { pathToFileURL } from 'node:url';\nimport { glob } from 'glob';\nimport type { EntityKind, MarketplaceEntry, MarketplaceLock } from '@kb-labs/core-discovery';\nimport {\n readMarketplaceLock,\n writeMarketplaceLock,\n createEmptyLock,\n createMarketplaceEntry,\n addToMarketplaceLock,\n removeFromMarketplaceLock,\n enablePlugin,\n disablePlugin,\n DiagnosticCollector,\n loadManifest,\n} from '@kb-labs/core-discovery';\nimport type {\n PackageSource,\n EntityKindStrategy,\n MarketplaceServiceAPI,\n MarketplaceEntryWithId,\n ScopedMarketplaceEntry,\n ScopeContext,\n QueryScopeContext,\n MarketplaceScope,\n MarketplaceDiagnostic,\n InstallResult,\n InstallResultEntry,\n SyncResult,\n DoctorReport,\n DoctorIssue,\n} from '@kb-labs/marketplace-contracts';\nimport { setCacheEntry, removeCacheEntry } from './manifest-cache.js';\nimport { PluginStrategy } from './strategies/plugin-strategy.js';\nimport { AdapterStrategy } from './strategies/adapter-strategy.js';\nimport { resolveScopeRoot, resolveQueryRoots, type ServiceRoots } from './scope.js';\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface MarketplaceServiceOptions {\n /** Platform workspace root — always required. Used for `scope: 'platform'`. */\n platformRoot: string;\n /**\n * Default project root. Optional — a daemon serving multiple projects can\n * leave this unset and pass `ctx.projectRoot` per call. When both are\n * provided, per-call `ctx.projectRoot` wins.\n */\n projectRoot?: string;\n /** Package source (npm, registry, etc.) */\n source: PackageSource;\n /** Additional strategies beyond built-in plugin/adapter */\n strategies?: EntityKindStrategy[];\n}\n\n// ---------------------------------------------------------------------------\n// Service\n// ---------------------------------------------------------------------------\n\nexport class MarketplaceService implements MarketplaceServiceAPI {\n private readonly roots: ServiceRoots;\n private readonly source: PackageSource;\n private readonly strategies = new Map<EntityKind, EntityKindStrategy>();\n\n constructor(opts: MarketplaceServiceOptions) {\n this.roots = { platformRoot: opts.platformRoot, projectRoot: opts.projectRoot };\n this.source = opts.source;\n\n // Built-in strategies\n this.registerStrategy(new PluginStrategy());\n this.registerStrategy(new AdapterStrategy());\n\n // User-supplied strategies\n if (opts.strategies) {\n for (const s of opts.strategies) {\n this.registerStrategy(s);\n }\n }\n }\n\n registerStrategy(strategy: EntityKindStrategy): void {\n this.strategies.set(strategy.kind, strategy);\n }\n\n // -------------------------------------------------------------------------\n // Install\n // -------------------------------------------------------------------------\n\n async install(\n ctx: ScopeContext,\n specs: string[],\n opts?: { dev?: boolean },\n ): Promise<InstallResult> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const installed: InstallResultEntry[] = [];\n const warnings: string[] = [];\n const diagnostics: MarketplaceDiagnostic[] = [];\n\n for (const spec of specs) {\n const resolved = await this.source.resolve(spec);\n const result = await this.source.install(resolved, scopeRoot, opts);\n\n // Detect primary kind via strategies\n const primaryKind = await this.detectKind(result.packageRoot);\n this.assertScopeAllowsKind(ctx.scope, primaryKind);\n\n const strategy = this.strategies.get(primaryKind);\n const provides = strategy\n ? await strategy.extractProvides(result.packageRoot)\n : [primaryKind];\n\n // Write to marketplace.lock\n const entry = createMarketplaceEntry({\n version: result.version,\n integrity: result.integrity,\n resolvedPath: relativeToRoot(scopeRoot, result.packageRoot),\n source: resolved.source,\n primaryKind,\n provides,\n });\n\n await addToMarketplaceLock(scopeRoot, result.id, entry);\n\n // Cache manifest\n await this.cacheManifest(scopeRoot, result.id, result.packageRoot, primaryKind, result.integrity);\n\n // Run post-install hook\n if (strategy?.afterInstall) {\n try {\n await strategy.afterInstall(result.id, result.packageRoot, this, ctx);\n } catch (err) {\n warnings.push(`afterInstall for ${result.id}: ${(err as Error).message}`);\n }\n }\n\n installed.push({\n id: result.id,\n version: result.version,\n primaryKind,\n provides,\n packageRoot: result.packageRoot,\n scope: ctx.scope,\n });\n }\n\n return { installed, warnings, scope: ctx.scope, diagnostics: diagnostics.length ? diagnostics : undefined };\n }\n\n // -------------------------------------------------------------------------\n // Uninstall\n // -------------------------------------------------------------------------\n\n async uninstall(ctx: ScopeContext, packageIds: string[]): Promise<void> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n for (const id of packageIds) {\n // Run pre-uninstall hook\n const entry = await this.getEntry(ctx, id);\n if (entry) {\n const strategy = this.strategies.get(entry.primaryKind);\n if (strategy?.beforeUninstall) {\n await strategy.beforeUninstall(id, this, ctx);\n }\n }\n\n await removeFromMarketplaceLock(scopeRoot, id);\n await removeCacheEntry(scopeRoot, id);\n await this.source.remove(id, scopeRoot);\n }\n }\n\n // -------------------------------------------------------------------------\n // Link / Unlink\n // -------------------------------------------------------------------------\n\n async link(ctx: ScopeContext, packagePath: string): Promise<InstallResultEntry> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const absPath = path.resolve(scopeRoot, packagePath);\n\n // Path traversal guard — linked path must be within the scope root.\n if (!isPathInside(scopeRoot, absPath)) {\n throw new Error(\n `Path \"${packagePath}\" is outside ${ctx.scope} root \"${scopeRoot}\" — refusing to link`,\n );\n }\n\n const pkgJson = JSON.parse(\n await fs.readFile(path.join(absPath, 'package.json'), 'utf-8'),\n );\n const id: string = pkgJson.name;\n const version: string = pkgJson.version ?? '0.0.0';\n\n const primaryKind = await this.detectKind(absPath);\n this.assertScopeAllowsKind(ctx.scope, primaryKind);\n\n const strategy = this.strategies.get(primaryKind);\n const provides = strategy\n ? await strategy.extractProvides(absPath)\n : [primaryKind];\n\n const integrity = await computeIntegrity(absPath);\n\n const entry = createMarketplaceEntry({\n version,\n integrity,\n resolvedPath: relativeToRoot(scopeRoot, absPath),\n source: 'local',\n primaryKind,\n provides,\n });\n\n await addToMarketplaceLock(scopeRoot, id, entry);\n await this.cacheManifest(scopeRoot, id, absPath, primaryKind, integrity);\n\n if (strategy?.afterInstall) {\n await strategy.afterInstall(id, absPath, this, ctx);\n }\n\n return { id, version, primaryKind, provides, packageRoot: absPath, scope: ctx.scope };\n }\n\n async unlink(ctx: ScopeContext, packageId: string): Promise<void> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n await removeFromMarketplaceLock(scopeRoot, packageId);\n await removeCacheEntry(scopeRoot, packageId);\n }\n\n // -------------------------------------------------------------------------\n // Update\n // -------------------------------------------------------------------------\n\n async update(ctx: ScopeContext, packageIds?: string[]): Promise<InstallResult> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const diag = new DiagnosticCollector();\n const lock = await readMarketplaceLock(scopeRoot, diag);\n if (!lock) {\n return { installed: [], warnings: ['No marketplace.lock found'], scope: ctx.scope };\n }\n\n const ids = packageIds ?? Object.keys(lock.installed);\n const specs = ids.filter(id => id in lock.installed);\n\n return this.install(ctx, specs);\n }\n\n // -------------------------------------------------------------------------\n // Enable / Disable\n // -------------------------------------------------------------------------\n\n async enable(ctx: ScopeContext, packageId: string): Promise<void> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const ok = await enablePlugin(scopeRoot, packageId);\n if (!ok) {\n throw new Error(`Package \"${packageId}\" not found in ${ctx.scope} marketplace.lock`);\n }\n }\n\n async disable(ctx: ScopeContext, packageId: string): Promise<void> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const ok = await disablePlugin(scopeRoot, packageId);\n if (!ok) {\n throw new Error(`Package \"${packageId}\" not found in ${ctx.scope} marketplace.lock`);\n }\n }\n\n // -------------------------------------------------------------------------\n // List / GetEntry (MarketplaceServiceAPI)\n // -------------------------------------------------------------------------\n\n async list(\n ctx: QueryScopeContext,\n filter?: { kind?: EntityKind },\n ): Promise<ScopedMarketplaceEntry[]> {\n const targets = resolveQueryRoots(this.roots, ctx);\n\n // Collect per-scope entries. For 'all' we later apply platform-wins.\n const perScope: Array<{ scope: MarketplaceScope; entries: MarketplaceEntryWithId[] }> = [];\n for (const { scope, root } of targets) {\n const diag = new DiagnosticCollector();\n const lock = await readMarketplaceLock(root, diag);\n if (!lock) {\n perScope.push({ scope, entries: [] });\n continue;\n }\n const entries = Object.entries(lock.installed).map(([id, entry]) => ({ ...entry, id }));\n perScope.push({ scope, entries });\n }\n\n const merged = mergeScopedEntries(perScope);\n return filter?.kind\n ? merged.entries.filter(e => e.primaryKind === filter.kind)\n : merged.entries;\n }\n\n async getEntry(ctx: ScopeContext, packageId: string): Promise<MarketplaceEntry | null> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const diag = new DiagnosticCollector();\n const lock = await readMarketplaceLock(scopeRoot, diag);\n return lock?.installed[packageId] ?? null;\n }\n\n // -------------------------------------------------------------------------\n // Sync (scan workspace → populate lock from config-driven globs)\n // -------------------------------------------------------------------------\n\n /**\n * Scan workspace for plugins and adapters using glob patterns.\n * Existing entries are preserved (not overwritten).\n * Patterns come from kb.config.json marketplace.sync.include.\n *\n * Sync is scope-bound: globs resolve against the scope root and results go\n * into that scope's lock. Adapter discovery in `project` scope is refused\n * with a clear error to preserve the adapters-are-platform-only invariant.\n */\n async sync(\n ctx: ScopeContext,\n opts: {\n include: string[];\n exclude?: string[];\n autoEnable?: boolean;\n },\n ): Promise<SyncResult> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const autoEnable = opts.autoEnable ?? false;\n const diag = new DiagnosticCollector();\n const lock = await readMarketplaceLock(scopeRoot, diag) ?? createEmptyLock();\n const existingIds = new Set(Object.keys(lock.installed));\n\n const added: SyncResult['added'] = [];\n const skipped: SyncResult['skipped'] = [];\n\n const includePatterns = opts.include.map(p => path.join(p, 'package.json'));\n const excludePatterns = opts.exclude ?? [];\n\n const packageJsonPaths = await glob(includePatterns, {\n cwd: scopeRoot,\n ignore: excludePatterns,\n absolute: false,\n });\n\n for (const relPkgJson of packageJsonPaths) {\n const pkgDir = path.resolve(scopeRoot, path.dirname(relPkgJson));\n await this._syncPackage(ctx.scope, scopeRoot, pkgDir, relPkgJson, existingIds, autoEnable, lock, added, skipped);\n }\n\n await writeMarketplaceLock(scopeRoot, lock);\n\n return { added, skipped, total: Object.keys(lock.installed).length };\n }\n\n private async _syncPackage(\n scope: MarketplaceScope,\n scopeRoot: string,\n pkgDir: string,\n _relPkgJson: string,\n existingIds: Set<string>,\n autoEnable: boolean,\n lock: MarketplaceLock,\n added: SyncResult['added'],\n skipped: SyncResult['skipped'],\n ): Promise<void> {\n let pkgName: string;\n let pkgVersion: string;\n try {\n const pkgJson = JSON.parse(await fs.readFile(path.join(pkgDir, 'package.json'), 'utf-8'));\n pkgName = pkgJson.name;\n pkgVersion = pkgJson.version ?? '0.0.0';\n if (!pkgName) { return; }\n } catch {\n return;\n }\n\n if (existingIds.has(pkgName)) {\n skipped.push({ id: pkgName, reason: 'already in lock' });\n return;\n }\n\n let detected = false;\n for (const strategy of this.strategies.values()) {\n const kind = await strategy.detectKind(pkgDir);\n if (kind) { detected = true; break; }\n }\n if (!detected) { return; }\n\n const primaryKind = await this.detectKind(pkgDir);\n\n // Adapters can only live in platform scope.\n if (scope === 'project' && primaryKind === 'adapter') {\n skipped.push({ id: pkgName, reason: 'adapter not allowed in project scope' });\n return;\n }\n\n const strategy = this.strategies.get(primaryKind);\n const provides = strategy ? await strategy.extractProvides(pkgDir) : [primaryKind];\n const integrity = await computeIntegrity(pkgDir);\n\n // Use manifest ID as lock key if the strategy can resolve it.\n // This keeps discovery working even when package.json name differs from manifest.id\n // (e.g. after folder renames like cli/ → entry/).\n const resolvedId = (strategy?.resolveId ? await strategy.resolveId(pkgDir) : null) ?? pkgName;\n\n if (existingIds.has(resolvedId) && resolvedId !== pkgName) {\n skipped.push({ id: resolvedId, reason: 'already in lock' });\n return;\n }\n\n const entry = createMarketplaceEntry({\n version: pkgVersion,\n integrity,\n resolvedPath: relativeToRoot(scopeRoot, pkgDir),\n source: 'local',\n primaryKind,\n provides,\n });\n\n if (!autoEnable) { entry.enabled = false; }\n\n lock.installed[resolvedId] = entry;\n added.push({ id: resolvedId, primaryKind, version: pkgVersion });\n }\n\n // -------------------------------------------------------------------------\n // Doctor\n // -------------------------------------------------------------------------\n\n async doctor(ctx: ScopeContext): Promise<DoctorReport> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const diag = new DiagnosticCollector();\n const lock = await readMarketplaceLock(scopeRoot, diag);\n const issues: DoctorIssue[] = [];\n\n if (!lock) {\n return { ok: true, total: 0, issues: [{ severity: 'info', packageId: '', message: 'No marketplace.lock found' }] };\n }\n\n const entries = Object.entries(lock.installed);\n\n for (const [id, entry] of entries) {\n const pkgRoot = path.resolve(scopeRoot, entry.resolvedPath);\n\n try {\n await fs.access(pkgRoot);\n } catch {\n issues.push({\n severity: 'error',\n packageId: id,\n message: `Package directory not found: ${pkgRoot}`,\n remediation: `Run \"kb marketplace install ${id}\" to restore`,\n });\n continue;\n }\n\n if (entry.integrity) {\n const computed = await computeIntegrity(pkgRoot);\n if (computed && computed !== entry.integrity) {\n issues.push({\n severity: 'warning',\n packageId: id,\n message: `Integrity mismatch: expected ${entry.integrity}, got ${computed}`,\n remediation: `Re-install: kb marketplace install ${id}`,\n });\n }\n }\n\n if (!entry.signature) {\n issues.push({\n severity: 'info',\n packageId: id,\n message: 'Package is not signed',\n remediation: 'Publish through the official marketplace to get a platform signature',\n });\n }\n }\n\n return {\n ok: issues.filter(i => i.severity === 'error').length === 0,\n total: entries.length,\n issues,\n };\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n private async detectKind(packageRoot: string): Promise<EntityKind> {\n for (const strategy of this.strategies.values()) {\n const kind = await strategy.detectKind(packageRoot);\n if (kind) { return kind; }\n }\n return 'plugin';\n }\n\n /**\n * Hard guard: adapters may only be installed/linked in platform scope.\n * Lives in one place so adapter-scope policy is not duplicated across\n * `link`, `install`, and `sync`.\n */\n private assertScopeAllowsKind(scope: MarketplaceScope, kind: EntityKind): void {\n if (scope === 'project' && kind === 'adapter') {\n throw new AdapterScopeError(\n 'Adapters can only be installed in platform scope. ' +\n 'Use --scope platform or install globally via the platform marketplace.',\n );\n }\n }\n\n private async cacheManifest(\n scopeRoot: string,\n packageId: string,\n packageRoot: string,\n primaryKind: EntityKind,\n integrity: string,\n ): Promise<void> {\n try {\n if (primaryKind === 'plugin') {\n const diag = new DiagnosticCollector();\n const manifest = await loadManifest(packageRoot, diag);\n if (manifest) {\n await setCacheEntry(scopeRoot, packageId, {\n manifestType: 'plugin',\n manifest,\n cachedAt: new Date().toISOString(),\n integrity,\n });\n }\n } else if (primaryKind === 'adapter') {\n const distPath = path.join(packageRoot, 'dist', 'index.js');\n const mod = await import(pathToFileURL(distPath).href);\n if (mod.manifest) {\n await setCacheEntry(scopeRoot, packageId, {\n manifestType: 'adapter',\n manifest: mod.manifest,\n cachedAt: new Date().toISOString(),\n integrity,\n });\n }\n }\n } catch (err) {\n console.warn(`[marketplace] Failed to cache manifest for \"${packageId}\": ${(err as Error).message}`);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\nexport class AdapterScopeError extends Error {\n readonly code = 'MARKETPLACE_ADAPTER_PROJECT_SCOPE';\n constructor(message: string) {\n super(message);\n this.name = 'AdapterScopeError';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction relativeToRoot(root: string, absPath: string): string {\n const rel = path.relative(root, absPath);\n return rel.startsWith('.') ? rel : `./${rel}`;\n}\n\nfunction isPathInside(parent: string, child: string): boolean {\n const rel = path.relative(path.resolve(parent), path.resolve(child));\n return !rel.startsWith('..') && !path.isAbsolute(rel);\n}\n\nasync function computeIntegrity(packageRoot: string): Promise<string> {\n try {\n const content = await fs.readFile(path.join(packageRoot, 'package.json'));\n return `sha256-${crypto.createHash('sha256').update(content).digest('base64')}`;\n } catch {\n return '';\n }\n}\n\n/**\n * Merge per-scope entries with platform-wins precedence.\n *\n * For a given package id present in both platform and project, the platform\n * entry is kept and a diagnostic is emitted so the caller can surface the\n * conflict.\n */\nexport function mergeScopedEntries(\n perScope: Array<{ scope: MarketplaceScope; entries: MarketplaceEntryWithId[] }>,\n): { entries: ScopedMarketplaceEntry[]; diagnostics: MarketplaceDiagnostic[] } {\n const out = new Map<string, ScopedMarketplaceEntry>();\n const diagnostics: MarketplaceDiagnostic[] = [];\n\n // Process platform first so platform entries land first and project\n // duplicates are rejected with a diagnostic.\n const ordered = [...perScope].sort((a, b) => {\n if (a.scope === b.scope) { return 0; }\n return a.scope === 'platform' ? -1 : 1;\n });\n\n for (const { scope, entries } of ordered) {\n for (const e of entries) {\n const existing = out.get(e.id);\n if (existing) {\n // platform-wins: ignore subsequent duplicates, emit a diagnostic.\n diagnostics.push({\n code: 'MARKETPLACE_SCOPE_COLLISION',\n message: `Package \"${e.id}\" exists in both platform and ${scope} scopes — platform wins.`,\n packageId: e.id,\n scope,\n });\n continue;\n }\n out.set(e.id, { ...e, scope });\n }\n }\n\n return { entries: Array.from(out.values()), diagnostics };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/manifest-cache.ts","../src/strategies/plugin-strategy.ts","../src/strategies/adapter-strategy.ts","../src/scope.ts","../src/marketplace-service.ts"],"names":["path","path2","fs2","path3","fs3","DiagnosticCollector","loadManifest","pathToFileURL"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/marketplace-core/manifest-cache\n * Read/write .kb/marketplace.manifests.json — cached manifests for fast discovery.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport type { ManifestCache, ManifestCacheEntry } from '@kb-labs/marketplace-contracts';\n\nconst CACHE_FILE = '.kb/marketplace.manifests.json';\nconst SCHEMA_VERSION = 'kb.marketplace.manifests/1' as const;\n\n/**\n * Read the manifest cache from disk. Returns null if missing or invalid.\n */\nexport async function readManifestCache(root: string): Promise<ManifestCache | null> {\n const cachePath = path.join(root, CACHE_FILE);\n try {\n const raw = await fs.readFile(cachePath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (parsed?.schema !== SCHEMA_VERSION) {return null;}\n return parsed as ManifestCache;\n } catch {\n return null;\n }\n}\n\n/**\n * Write the manifest cache atomically (tmp → rename).\n */\nexport async function writeManifestCache(root: string, cache: ManifestCache): Promise<void> {\n const cachePath = path.join(root, CACHE_FILE);\n const dir = path.dirname(cachePath);\n await fs.mkdir(dir, { recursive: true });\n\n const tmpPath = `${cachePath}.tmp.${randomUUID()}`;\n await fs.writeFile(tmpPath, JSON.stringify(cache, null, 2) + '\\n', 'utf-8');\n await fs.rename(tmpPath, cachePath);\n}\n\n/**\n * Create an empty manifest cache.\n */\nexport function createEmptyManifestCache(): ManifestCache {\n return { schema: SCHEMA_VERSION, entries: {} };\n}\n\n/**\n * Set a single entry in the manifest cache and persist.\n */\nexport async function setCacheEntry(\n root: string,\n packageId: string,\n entry: ManifestCacheEntry,\n): Promise<void> {\n const existing = await readManifestCache(root) ?? createEmptyManifestCache();\n existing.entries[packageId] = entry;\n await writeManifestCache(root, existing);\n}\n\n/**\n * Remove a single entry from the manifest cache and persist.\n */\nexport async function removeCacheEntry(\n root: string,\n packageId: string,\n): Promise<void> {\n const existing = await readManifestCache(root);\n if (!existing || !(packageId in existing.entries)) {return;}\n delete existing.entries[packageId];\n await writeManifestCache(root, existing);\n}\n","/**\n * @module @kb-labs/marketplace-core/strategies/plugin-strategy\n * Strategy for plugins — detects ManifestV3 and extracts entity kinds.\n */\n\nimport type { EntityKind } from '@kb-labs/core-discovery';\nimport type { EntityKindStrategy } from '@kb-labs/marketplace-contracts';\nimport { loadManifest, DiagnosticCollector, extractEntityKinds } from '@kb-labs/core-discovery';\n\nexport class PluginStrategy implements EntityKindStrategy {\n kind: EntityKind = 'plugin';\n\n async detectKind(packageRoot: string): Promise<EntityKind | null> {\n const diag = new DiagnosticCollector();\n const manifest = await loadManifest(packageRoot, diag);\n return manifest ? 'plugin' : null;\n }\n\n async extractProvides(packageRoot: string): Promise<EntityKind[]> {\n const diag = new DiagnosticCollector();\n const manifest = await loadManifest(packageRoot, diag);\n if (!manifest) {return ['plugin'];}\n return extractEntityKinds(manifest);\n }\n\n async resolveId(packageRoot: string): Promise<string | null> {\n const diag = new DiagnosticCollector();\n const manifest = await loadManifest(packageRoot, diag);\n return manifest?.id ?? null;\n }\n}\n","/**\n * @module @kb-labs/marketplace-core/strategies/adapter-strategy\n * Strategy for adapters — detects AdapterManifest, validates dependencies.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { EntityKind } from '@kb-labs/core-discovery';\nimport type {\n EntityKindStrategy,\n MarketplaceServiceAPI,\n ScopeContext,\n} from '@kb-labs/marketplace-contracts';\n\nexport class AdapterStrategy implements EntityKindStrategy {\n kind: EntityKind = 'adapter';\n\n async detectKind(packageRoot: string): Promise<EntityKind | null> {\n const manifest = await loadAdapterManifest(packageRoot);\n return manifest ? 'adapter' : null;\n }\n\n async extractProvides(_packageRoot: string): Promise<EntityKind[]> {\n return ['adapter'];\n }\n\n async afterInstall(\n packageId: string,\n packageRoot: string,\n service: MarketplaceServiceAPI,\n ctx: ScopeContext,\n ): Promise<void> {\n const manifest = await loadAdapterManifest(packageRoot);\n if (!manifest?.requires?.adapters) {return;}\n\n // Adapters only live in platform scope (guarded in MarketplaceService),\n // so we query the same scope we were invoked with.\n const installed = await service.list(ctx, { kind: 'adapter' });\n const installedIds = new Set(installed.map(e => e.id));\n\n for (const dep of manifest.requires.adapters) {\n const depId = typeof dep === 'string' ? dep : dep.id;\n const found = installedIds.has(depId) ||\n installed.some(e => e.id.includes(`adapters-${depId}`));\n\n if (!found) {\n console.warn(\n `[marketplace] Adapter \"${packageId}\" requires adapter \"${depId}\" which is not installed. ` +\n `Run: kb marketplace link <adapter-package-that-provides-${depId}>`,\n );\n }\n }\n }\n\n async beforeUninstall(\n packageId: string,\n service: MarketplaceServiceAPI,\n ctx: ScopeContext,\n ): Promise<void> {\n const installed = await service.list(ctx, { kind: 'adapter' });\n if (installed.length > 1) {\n console.warn(\n `[marketplace] Removing adapter \"${packageId}\" — verify no other adapters depend on it`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ninterface AdapterManifestLike {\n id?: string;\n type?: 'core' | 'extension' | 'proxy';\n implements?: string;\n requires?: {\n adapters?: Array<string | { id: string; alias?: string }>;\n };\n}\n\nasync function loadAdapterManifest(packageRoot: string): Promise<AdapterManifestLike | null> {\n try {\n const distPath = path.join(packageRoot, 'dist', 'index.js');\n await fs.access(distPath);\n const mod = await import(pathToFileURL(distPath).href);\n if (mod.manifest && typeof mod.manifest === 'object' && mod.manifest.implements) {\n return mod.manifest as AdapterManifestLike;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * @module @kb-labs/marketplace-core/scope\n * Scope resolution helpers for the platform/project marketplace split.\n *\n * Every mutating service method is explicitly scope-bound — there is no\n * implicit default. The helpers below compute the absolute root directory\n * for a given ScopeContext and enforce the invariants that the rest of the\n * service relies on (distinct platform/project roots, project has a `.kb/`).\n */\n\nimport * as path from 'node:path';\nimport { accessSync, constants } from 'node:fs';\nimport type {\n MarketplaceScope,\n ScopeContext,\n QueryScopeContext,\n} from '@kb-labs/marketplace-contracts';\n\nconst CONFIG_FILE_CANDIDATES = ['kb.config.jsonc', 'kb.config.json'] as const;\n\n/**\n * Roots known to the MarketplaceService at construction time.\n * `platformRoot` is always known. `projectRoot` is optional at construction\n * (daemon may serve multiple projects); per-call `ctx.projectRoot` can\n * override it.\n */\nexport interface ServiceRoots {\n platformRoot: string;\n projectRoot?: string;\n}\n\n/**\n * Resolve the absolute scope root for a single mutating call.\n *\n * - `scope: 'platform'` — returns `roots.platformRoot`. `projectRoot` in\n * the context is ignored.\n * - `scope: 'project'` — prefers `ctx.projectRoot`, falls back to\n * `roots.projectRoot` from construction. Throws if neither is set,\n * if the path isn't absolute, doesn't exist, lacks a `.kb/kb.config.*`,\n * or equals `roots.platformRoot`.\n */\nexport function resolveScopeRoot(roots: ServiceRoots, ctx: ScopeContext): string {\n if (ctx.scope === 'platform') {\n return roots.platformRoot;\n }\n\n const candidate = ctx.projectRoot ?? roots.projectRoot;\n if (!candidate) {\n throw new ScopeResolutionError(\n 'SCOPE_PROJECT_ROOT_MISSING',\n 'scope=\"project\" requires a projectRoot (pass ctx.projectRoot or configure the service with projectRoot).',\n );\n }\n\n if (!path.isAbsolute(candidate)) {\n throw new ScopeResolutionError(\n 'SCOPE_PROJECT_ROOT_NOT_ABSOLUTE',\n `projectRoot must be absolute, got \"${candidate}\".`,\n );\n }\n\n try {\n accessSync(candidate, constants.F_OK);\n } catch {\n throw new ScopeResolutionError(\n 'SCOPE_PROJECT_ROOT_NOT_FOUND',\n `projectRoot does not exist: \"${candidate}\".`,\n );\n }\n\n const hasConfig = CONFIG_FILE_CANDIDATES.some((name) => {\n try {\n accessSync(path.join(candidate, '.kb', name), constants.F_OK);\n return true;\n } catch {\n return false;\n }\n });\n if (!hasConfig) {\n throw new ScopeResolutionError(\n 'SCOPE_PROJECT_ROOT_NO_KB_DIR',\n `projectRoot \"${candidate}\" does not contain .kb/kb.config.{json,jsonc} — refusing to treat it as a project.`,\n );\n }\n\n if (path.resolve(candidate) === path.resolve(roots.platformRoot)) {\n throw new ScopeResolutionError(\n 'SCOPE_PROJECT_EQUALS_PLATFORM',\n 'projectRoot must not equal platformRoot; use scope=\"platform\" for platform-level operations.',\n );\n }\n\n return path.resolve(candidate);\n}\n\n/**\n * Resolve the set of roots to read from for a query context (`list`,\n * `getEntry`). `'all'` returns both; the caller is responsible for merging\n * with a project-wins precedence.\n */\nexport function resolveQueryRoots(\n roots: ServiceRoots,\n ctx: QueryScopeContext,\n): Array<{ scope: MarketplaceScope; root: string }> {\n if (ctx.scope === 'platform') {\n return [{ scope: 'platform', root: roots.platformRoot }];\n }\n if (ctx.scope === 'project') {\n return [\n {\n scope: 'project',\n root: resolveScopeRoot(roots, { scope: 'project', projectRoot: ctx.projectRoot }),\n },\n ];\n }\n // 'all' — platform is always included. Project is included only when a\n // project root is available (explicitly via ctx or implicitly from the\n // service). If no project context is known, 'all' degrades to platform-only.\n const out: Array<{ scope: MarketplaceScope; root: string }> = [\n { scope: 'platform', root: roots.platformRoot },\n ];\n const projectCandidate = ctx.projectRoot ?? roots.projectRoot;\n if (projectCandidate) {\n try {\n const projectRoot = resolveScopeRoot(roots, { scope: 'project', projectRoot: projectCandidate });\n out.push({ scope: 'project', root: projectRoot });\n } catch {\n // For 'all' we swallow resolution errors — a missing or invalid project\n // context should not block a platform-only listing.\n }\n }\n return out;\n}\n\n/**\n * Thrown when a scope context cannot be resolved to a concrete root.\n * Uses a stable `code` so API/CLI can surface actionable errors.\n */\nexport class ScopeResolutionError extends Error {\n readonly code: string;\n constructor(code: string, message: string) {\n super(message);\n this.code = code;\n this.name = 'ScopeResolutionError';\n }\n}\n","/**\n * @module @kb-labs/marketplace-core/marketplace-service\n * Unified marketplace service — install/uninstall/enable/disable for all entity types.\n *\n * Every mutating method is explicitly scope-bound (`platform` or `project`).\n * There is no implicit default: callers pass a `ScopeContext` per call so\n * the service can target the right `.kb/marketplace.lock`.\n *\n * Works through PackageSource abstraction — never calls pnpm directly.\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as crypto from 'node:crypto';\nimport { pathToFileURL } from 'node:url';\nimport { glob } from 'glob';\nimport type { EntityKind, MarketplaceEntry, MarketplaceLock } from '@kb-labs/core-discovery';\nimport {\n readMarketplaceLock,\n writeMarketplaceLock,\n createEmptyLock,\n createMarketplaceEntry,\n addToMarketplaceLock,\n removeFromMarketplaceLock,\n enablePlugin,\n disablePlugin,\n DiagnosticCollector,\n loadManifest,\n} from '@kb-labs/core-discovery';\nimport type {\n PackageSource,\n EntityKindStrategy,\n MarketplaceServiceAPI,\n MarketplaceEntryWithId,\n ScopedMarketplaceEntry,\n ScopeContext,\n QueryScopeContext,\n MarketplaceScope,\n MarketplaceDiagnostic,\n InstallResult,\n InstallResultEntry,\n SyncResult,\n DoctorReport,\n DoctorIssue,\n} from '@kb-labs/marketplace-contracts';\nimport { setCacheEntry, removeCacheEntry } from './manifest-cache.js';\nimport { PluginStrategy } from './strategies/plugin-strategy.js';\nimport { AdapterStrategy } from './strategies/adapter-strategy.js';\nimport { resolveScopeRoot, resolveQueryRoots, type ServiceRoots } from './scope.js';\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface MarketplaceServiceOptions {\n /** Platform workspace root — always required. Used for `scope: 'platform'`. */\n platformRoot: string;\n /**\n * Default project root. Optional — a daemon serving multiple projects can\n * leave this unset and pass `ctx.projectRoot` per call. When both are\n * provided, per-call `ctx.projectRoot` wins.\n */\n projectRoot?: string;\n /** Default package source (npm/pnpm) */\n source: PackageSource;\n /** KB Registry package source — used for specs starting with 'kb:' */\n registrySource?: PackageSource;\n /** Additional strategies beyond built-in plugin/adapter */\n strategies?: EntityKindStrategy[];\n}\n\n// ---------------------------------------------------------------------------\n// Service\n// ---------------------------------------------------------------------------\n\nexport class MarketplaceService implements MarketplaceServiceAPI {\n private readonly roots: ServiceRoots;\n private readonly source: PackageSource;\n private readonly registrySource?: PackageSource;\n private readonly strategies = new Map<EntityKind, EntityKindStrategy>();\n\n constructor(opts: MarketplaceServiceOptions) {\n this.roots = { platformRoot: opts.platformRoot, projectRoot: opts.projectRoot };\n this.source = opts.source;\n this.registrySource = opts.registrySource;\n\n // Built-in strategies\n this.registerStrategy(new PluginStrategy());\n this.registerStrategy(new AdapterStrategy());\n\n // User-supplied strategies\n if (opts.strategies) {\n for (const s of opts.strategies) {\n this.registerStrategy(s);\n }\n }\n }\n\n registerStrategy(strategy: EntityKindStrategy): void {\n this.strategies.set(strategy.kind, strategy);\n }\n\n // -------------------------------------------------------------------------\n // Install\n // -------------------------------------------------------------------------\n\n async install(\n ctx: ScopeContext,\n specs: string[],\n opts?: { dev?: boolean; shareToken?: string },\n ): Promise<InstallResult> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const installed: InstallResultEntry[] = [];\n const warnings: string[] = [];\n const diagnostics: MarketplaceDiagnostic[] = [];\n\n for (const spec of specs) {\n // Route kb: specs to registry source; fall back to npm source\n const isKbSpec = spec.startsWith('kb:');\n if (isKbSpec && !this.registrySource) {\n warnings.push(`Registry source not configured — cannot install '${spec}'. Set marketplace.registry.url in kb.config.json.`);\n continue;\n }\n let source = isKbSpec ? this.registrySource! : this.source;\n if (isKbSpec && opts?.shareToken && source.withShareToken) {\n source = source.withShareToken(opts.shareToken);\n }\n\n const resolved = await source.resolve(spec);\n const result = await source.install(resolved, scopeRoot, opts);\n\n // Detect primary kind via strategies. A null result means the installed\n // package is not a KB Labs entity (no plugin/adapter/... manifest) —\n // fail loudly and roll back the npm install instead of recording a bogus\n // lock entry (B-021).\n const primaryKind = await this.detectKind(result.packageRoot);\n if (primaryKind === null) {\n await source.remove(result.id, scopeRoot).catch(() => undefined);\n throw new InvalidEntityError(\n `Package \"${result.id}\" (resolved from \"${spec}\") is not a valid KB Labs entity — ` +\n `no plugin/adapter/workflow manifest found. Nothing was installed. ` +\n `Did you mean a scoped package such as \"@kb-labs/${spec}-entry\"?`,\n );\n }\n this.assertScopeAllowsKind(ctx.scope, primaryKind);\n\n const strategy = this.strategies.get(primaryKind);\n const provides = strategy\n ? await strategy.extractProvides(result.packageRoot)\n : [primaryKind];\n\n // Packages from registry with a platform signature are trusted and sealed\n const trust: 'trusted' | 'untrusted' = resolved.signature ? 'trusted' : 'untrusted';\n\n // Write to marketplace.lock\n const entry = createMarketplaceEntry({\n version: result.version,\n integrity: result.integrity,\n resolvedPath: relativeToRoot(scopeRoot, result.packageRoot),\n source: resolved.source,\n primaryKind,\n provides,\n trust,\n signature: resolved.signature,\n spec,\n });\n\n await addToMarketplaceLock(scopeRoot, result.id, entry);\n\n // Cache manifest\n await this.cacheManifest(scopeRoot, result.id, result.packageRoot, primaryKind, result.integrity);\n\n // Run post-install hook\n if (strategy?.afterInstall) {\n try {\n await strategy.afterInstall(result.id, result.packageRoot, this, ctx);\n } catch (err) {\n warnings.push(`afterInstall for ${result.id}: ${(err as Error).message}`);\n }\n }\n\n installed.push({\n id: result.id,\n version: result.version,\n primaryKind,\n provides,\n packageRoot: result.packageRoot,\n scope: ctx.scope,\n });\n }\n\n return { installed, warnings, scope: ctx.scope, diagnostics: diagnostics.length ? diagnostics : undefined };\n }\n\n // -------------------------------------------------------------------------\n // Uninstall\n // -------------------------------------------------------------------------\n\n async uninstall(ctx: ScopeContext, packageIds: string[]): Promise<void> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n for (const id of packageIds) {\n // Look up the entry first — if not tracked we skip source removal (idempotent).\n const entry = await this.getEntry(ctx, id);\n\n if (!entry) {\n // Package not in lock — nothing to uninstall. Remove any stale cache entries\n // but do not call source.remove (pnpm would fail on an unknown package).\n await removeCacheEntry(scopeRoot, id);\n continue;\n }\n\n // Run pre-uninstall hook\n const strategy = this.strategies.get(entry.primaryKind);\n if (strategy?.beforeUninstall) {\n await strategy.beforeUninstall(id, this, ctx);\n }\n\n await removeFromMarketplaceLock(scopeRoot, id);\n await removeCacheEntry(scopeRoot, id);\n await this.source.remove(id, scopeRoot);\n }\n }\n\n // -------------------------------------------------------------------------\n // Link / Unlink\n // -------------------------------------------------------------------------\n\n async link(ctx: ScopeContext, packagePath: string): Promise<InstallResultEntry> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const absPath = path.resolve(scopeRoot, packagePath);\n\n // Path traversal guard — linked path must be within the scope root.\n if (!isPathInside(scopeRoot, absPath)) {\n throw new Error(\n `Path \"${packagePath}\" is outside ${ctx.scope} root \"${scopeRoot}\" — refusing to link`,\n );\n }\n\n const pkgJson = JSON.parse(\n await fs.readFile(path.join(absPath, 'package.json'), 'utf-8'),\n );\n const id: string = pkgJson.name;\n const version: string = pkgJson.version ?? '0.0.0';\n\n const primaryKind = await this.detectKind(absPath);\n if (primaryKind === null) {\n throw new InvalidEntityError(\n `Cannot link \"${id}\" (${absPath}) — not a valid KB Labs entity ` +\n `(no plugin/adapter/workflow manifest found).`,\n );\n }\n this.assertScopeAllowsKind(ctx.scope, primaryKind);\n\n const strategy = this.strategies.get(primaryKind);\n const provides = strategy\n ? await strategy.extractProvides(absPath)\n : [primaryKind];\n\n const integrity = await computeIntegrity(absPath);\n\n const entry = createMarketplaceEntry({\n version,\n integrity,\n resolvedPath: relativeToRoot(scopeRoot, absPath),\n source: 'local',\n primaryKind,\n provides,\n });\n\n await addToMarketplaceLock(scopeRoot, id, entry);\n await this.cacheManifest(scopeRoot, id, absPath, primaryKind, integrity);\n\n if (strategy?.afterInstall) {\n await strategy.afterInstall(id, absPath, this, ctx);\n }\n\n return { id, version, primaryKind, provides, packageRoot: absPath, scope: ctx.scope };\n }\n\n async unlink(ctx: ScopeContext, packageId: string): Promise<void> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n await removeFromMarketplaceLock(scopeRoot, packageId);\n await removeCacheEntry(scopeRoot, packageId);\n }\n\n // -------------------------------------------------------------------------\n // Update\n // -------------------------------------------------------------------------\n\n async update(ctx: ScopeContext, packageIds?: string[]): Promise<InstallResult> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const diag = new DiagnosticCollector();\n const lock = await readMarketplaceLock(scopeRoot, diag);\n if (!lock) {\n return { installed: [], warnings: ['No marketplace.lock found'], scope: ctx.scope };\n }\n\n const ids = packageIds ?? Object.keys(lock.installed);\n const specs = ids.filter(id => id in lock.installed);\n\n return this.install(ctx, specs);\n }\n\n // -------------------------------------------------------------------------\n // Enable / Disable\n // -------------------------------------------------------------------------\n\n async enable(ctx: ScopeContext, packageId: string): Promise<void> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const ok = await enablePlugin(scopeRoot, packageId);\n if (!ok) {\n throw new Error(`Package \"${packageId}\" not found in ${ctx.scope} marketplace.lock`);\n }\n }\n\n async disable(ctx: ScopeContext, packageId: string): Promise<void> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const ok = await disablePlugin(scopeRoot, packageId);\n if (!ok) {\n throw new Error(`Package \"${packageId}\" not found in ${ctx.scope} marketplace.lock`);\n }\n }\n\n // -------------------------------------------------------------------------\n // List / GetEntry (MarketplaceServiceAPI)\n // -------------------------------------------------------------------------\n\n async list(\n ctx: QueryScopeContext,\n filter?: { kind?: EntityKind },\n ): Promise<ScopedMarketplaceEntry[]> {\n const targets = resolveQueryRoots(this.roots, ctx);\n\n // Collect per-scope entries. For 'all' we later apply project-wins.\n const perScope: Array<{ scope: MarketplaceScope; entries: MarketplaceEntryWithId[] }> = [];\n for (const { scope, root } of targets) {\n const diag = new DiagnosticCollector();\n const lock = await readMarketplaceLock(root, diag);\n if (!lock) {\n perScope.push({ scope, entries: [] });\n continue;\n }\n const entries = Object.entries(lock.installed).map(([id, entry]) => ({ ...entry, id }));\n perScope.push({ scope, entries });\n }\n\n const merged = mergeScopedEntries(perScope);\n return filter?.kind\n ? merged.entries.filter(e => e.primaryKind === filter.kind)\n : merged.entries;\n }\n\n async getEntry(ctx: ScopeContext, packageId: string): Promise<MarketplaceEntry | null> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const diag = new DiagnosticCollector();\n const lock = await readMarketplaceLock(scopeRoot, diag);\n return lock?.installed[packageId] ?? null;\n }\n\n // -------------------------------------------------------------------------\n // Sync (scan workspace → populate lock from config-driven globs)\n // -------------------------------------------------------------------------\n\n /**\n * Scan workspace for plugins and adapters using glob patterns.\n * Existing entries are preserved (not overwritten).\n * Patterns come from kb.config.json marketplace.sync.include.\n *\n * Sync is scope-bound: globs resolve against the scope root and results go\n * into that scope's lock. Adapter discovery in `project` scope is refused\n * with a clear error to preserve the adapters-are-platform-only invariant.\n */\n async sync(\n ctx: ScopeContext,\n opts: {\n include: string[];\n exclude?: string[];\n autoEnable?: boolean;\n },\n ): Promise<SyncResult> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const autoEnable = opts.autoEnable ?? false;\n const diag = new DiagnosticCollector();\n const lock = await readMarketplaceLock(scopeRoot, diag) ?? createEmptyLock();\n const existingIds = new Set(Object.keys(lock.installed));\n\n const added: SyncResult['added'] = [];\n const skipped: SyncResult['skipped'] = [];\n\n const includePatterns = opts.include.map(p => path.join(p, 'package.json'));\n const excludePatterns = opts.exclude ?? [];\n\n const packageJsonPaths = await glob(includePatterns, {\n cwd: scopeRoot,\n ignore: excludePatterns,\n absolute: false,\n });\n\n for (const relPkgJson of packageJsonPaths) {\n const pkgDir = path.resolve(scopeRoot, path.dirname(relPkgJson));\n await this._syncPackage(ctx.scope, scopeRoot, pkgDir, relPkgJson, existingIds, autoEnable, lock, added, skipped);\n }\n\n await writeMarketplaceLock(scopeRoot, lock);\n\n return { added, skipped, total: Object.keys(lock.installed).length };\n }\n\n private async _syncPackage(\n scope: MarketplaceScope,\n scopeRoot: string,\n pkgDir: string,\n _relPkgJson: string,\n existingIds: Set<string>,\n autoEnable: boolean,\n lock: MarketplaceLock,\n added: SyncResult['added'],\n skipped: SyncResult['skipped'],\n ): Promise<void> {\n let pkgName: string;\n let pkgVersion: string;\n try {\n const pkgJson = JSON.parse(await fs.readFile(path.join(pkgDir, 'package.json'), 'utf-8'));\n pkgName = pkgJson.name;\n pkgVersion = pkgJson.version ?? '0.0.0';\n if (!pkgName) { return; }\n } catch {\n return;\n }\n\n if (existingIds.has(pkgName)) {\n skipped.push({ id: pkgName, reason: 'already in lock' });\n return;\n }\n\n const primaryKind = await this.detectKind(pkgDir);\n // Not a KB Labs entity — skip silently during scan (unlike install/link,\n // scanning node_modules legitimately encounters many non-entity packages).\n if (primaryKind === null) { return; }\n\n // Adapters can only live in platform scope.\n if (scope === 'project' && primaryKind === 'adapter') {\n skipped.push({ id: pkgName, reason: 'adapter not allowed in project scope' });\n return;\n }\n\n const strategy = this.strategies.get(primaryKind);\n const provides = strategy ? await strategy.extractProvides(pkgDir) : [primaryKind];\n const integrity = await computeIntegrity(pkgDir);\n\n // Use manifest ID as lock key if the strategy can resolve it.\n // This keeps discovery working even when package.json name differs from manifest.id\n // (e.g. after folder renames like cli/ → entry/).\n const resolvedId = (strategy?.resolveId ? await strategy.resolveId(pkgDir) : null) ?? pkgName;\n\n if (existingIds.has(resolvedId) && resolvedId !== pkgName) {\n skipped.push({ id: resolvedId, reason: 'already in lock' });\n return;\n }\n\n const entry = createMarketplaceEntry({\n version: pkgVersion,\n integrity,\n resolvedPath: relativeToRoot(scopeRoot, pkgDir),\n source: 'local',\n primaryKind,\n provides,\n });\n\n if (!autoEnable) { entry.enabled = false; }\n\n lock.installed[resolvedId] = entry;\n added.push({ id: resolvedId, primaryKind, version: pkgVersion });\n }\n\n // -------------------------------------------------------------------------\n // Doctor\n // -------------------------------------------------------------------------\n\n async doctor(ctx: ScopeContext): Promise<DoctorReport> {\n const scopeRoot = resolveScopeRoot(this.roots, ctx);\n const diag = new DiagnosticCollector();\n const lock = await readMarketplaceLock(scopeRoot, diag);\n const issues: DoctorIssue[] = [];\n\n if (!lock) {\n return { ok: true, total: 0, issues: [{ severity: 'info', packageId: '', message: 'No marketplace.lock found' }] };\n }\n\n const entries = Object.entries(lock.installed);\n\n for (const [id, entry] of entries) {\n const pkgRoot = path.resolve(scopeRoot, entry.resolvedPath);\n\n try {\n await fs.access(pkgRoot);\n } catch {\n issues.push({\n severity: 'error',\n packageId: id,\n message: `Package directory not found: ${pkgRoot}`,\n remediation: `Run \"kb marketplace install ${id}\" to restore`,\n });\n continue;\n }\n\n if (entry.integrity) {\n const computed = await computeIntegrity(pkgRoot);\n if (computed && computed !== entry.integrity) {\n issues.push({\n severity: 'warning',\n packageId: id,\n message: `Integrity mismatch: expected ${entry.integrity}, got ${computed}`,\n remediation: `Re-install: kb marketplace install ${id}`,\n });\n }\n }\n\n if (!entry.signature) {\n issues.push({\n severity: 'info',\n packageId: id,\n message: 'Package is not signed',\n remediation: 'Publish through the official marketplace to get a platform signature',\n });\n }\n }\n\n return {\n ok: issues.filter(i => i.severity === 'error').length === 0,\n total: entries.length,\n issues,\n };\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n /**\n * Detect the primary entity kind of a package via registered strategies.\n * Returns null when no strategy recognizes the package — i.e. it is not a\n * valid KB Labs entity (no plugin/adapter/... manifest). Callers MUST treat\n * null as a hard failure rather than defaulting to 'plugin' (B-021): a plain\n * npm package with no kb manifest must never be recorded as a plugin.\n */\n private async detectKind(packageRoot: string): Promise<EntityKind | null> {\n for (const strategy of this.strategies.values()) {\n const kind = await strategy.detectKind(packageRoot);\n if (kind) { return kind; }\n }\n return null;\n }\n\n /**\n * Hard guard: adapters may only be installed/linked in platform scope.\n * Lives in one place so adapter-scope policy is not duplicated across\n * `link`, `install`, and `sync`.\n */\n private assertScopeAllowsKind(scope: MarketplaceScope, kind: EntityKind): void {\n if (scope === 'project' && kind === 'adapter') {\n throw new AdapterScopeError(\n 'Adapters can only be installed in platform scope. ' +\n 'Use --scope platform or install globally via the platform marketplace.',\n );\n }\n }\n\n private async cacheManifest(\n scopeRoot: string,\n packageId: string,\n packageRoot: string,\n primaryKind: EntityKind,\n integrity: string,\n ): Promise<void> {\n try {\n if (primaryKind === 'plugin') {\n const diag = new DiagnosticCollector();\n const manifest = await loadManifest(packageRoot, diag);\n if (manifest) {\n await setCacheEntry(scopeRoot, packageId, {\n manifestType: 'plugin',\n manifest,\n cachedAt: new Date().toISOString(),\n integrity,\n });\n }\n } else if (primaryKind === 'adapter') {\n const distPath = path.join(packageRoot, 'dist', 'index.js');\n const mod = await import(pathToFileURL(distPath).href);\n if (mod.manifest) {\n await setCacheEntry(scopeRoot, packageId, {\n manifestType: 'adapter',\n manifest: mod.manifest,\n cachedAt: new Date().toISOString(),\n integrity,\n });\n }\n }\n } catch (err) {\n console.warn(`[marketplace] Failed to cache manifest for \"${packageId}\": ${(err as Error).message}`);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\nexport class AdapterScopeError extends Error {\n readonly code = 'MARKETPLACE_ADAPTER_PROJECT_SCOPE';\n constructor(message: string) {\n super(message);\n this.name = 'AdapterScopeError';\n }\n}\n\n/**\n * Thrown when a package was resolved/installed but is not a recognizable KB Labs\n * entity (no plugin/adapter/workflow manifest). Maps to HTTP 422. Prevents\n * recording bogus lock entries for unrelated npm packages (B-021).\n */\nexport class InvalidEntityError extends Error {\n readonly code = 'MARKETPLACE_NOT_AN_ENTITY';\n constructor(message: string) {\n super(message);\n this.name = 'InvalidEntityError';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction relativeToRoot(root: string, absPath: string): string {\n const rel = path.relative(root, absPath);\n return rel.startsWith('.') ? rel : `./${rel}`;\n}\n\nfunction isPathInside(parent: string, child: string): boolean {\n const rel = path.relative(path.resolve(parent), path.resolve(child));\n return !rel.startsWith('..') && !path.isAbsolute(rel);\n}\n\nasync function computeIntegrity(packageRoot: string): Promise<string> {\n try {\n const content = await fs.readFile(path.join(packageRoot, 'package.json'));\n return `sha256-${crypto.createHash('sha256').update(content).digest('base64')}`;\n } catch {\n return '';\n }\n}\n\n/**\n * Merge per-scope entries with project-wins precedence.\n *\n * For a given package id present in both platform and project, the project\n * entry is kept and a diagnostic is emitted so the caller can surface the\n * override.\n */\nexport function mergeScopedEntries(\n perScope: Array<{ scope: MarketplaceScope; entries: MarketplaceEntryWithId[] }>,\n): { entries: ScopedMarketplaceEntry[]; diagnostics: MarketplaceDiagnostic[] } {\n const out = new Map<string, ScopedMarketplaceEntry>();\n const diagnostics: MarketplaceDiagnostic[] = [];\n\n // Process project first so project entries land first and platform\n // duplicates are skipped with a diagnostic.\n const ordered = [...perScope].sort((a, b) => {\n if (a.scope === b.scope) { return 0; }\n return a.scope === 'project' ? -1 : 1;\n });\n\n for (const { scope, entries } of ordered) {\n for (const e of entries) {\n const existing = out.get(e.id);\n if (existing) {\n // project-wins: ignore subsequent duplicates, emit a diagnostic.\n diagnostics.push({\n code: 'MARKETPLACE_SCOPE_COLLISION',\n message: `Package \"${e.id}\" exists in both platform and project scopes — project wins.`,\n packageId: e.id,\n scope,\n });\n continue;\n }\n out.set(e.id, { ...e, scope });\n }\n }\n\n return { entries: Array.from(out.values()), diagnostics };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kb-labs/marketplace-core",
|
|
3
3
|
"description": "Marketplace service — unified install/uninstall/enable/disable for all entity types",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.96.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -18,16 +18,16 @@
|
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"glob": "^11.0.0",
|
|
21
|
-
"@kb-labs/core-
|
|
22
|
-
"@kb-labs/
|
|
23
|
-
"@kb-labs/
|
|
24
|
-
"@kb-labs/marketplace-contracts": "2.
|
|
21
|
+
"@kb-labs/core-platform": "2.96.0",
|
|
22
|
+
"@kb-labs/plugin-contracts": "2.96.0",
|
|
23
|
+
"@kb-labs/core-discovery": "2.96.0",
|
|
24
|
+
"@kb-labs/marketplace-contracts": "2.96.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"tsup": "^8.5.0",
|
|
28
28
|
"typescript": "^5",
|
|
29
|
-
"vitest": "^3.2.
|
|
30
|
-
"@kb-labs/devkit": "2.
|
|
29
|
+
"vitest": "^3.2.6",
|
|
30
|
+
"@kb-labs/devkit": "2.96.0"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
33
33
|
"node": ">=20.0.0",
|