@kb-labs/marketplace-core 2.111.0 → 2.112.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 +1 -1
- package/dist/index.js +20 -8
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ declare class MarketplaceService implements MarketplaceServiceAPI {
|
|
|
40
40
|
shareToken?: string;
|
|
41
41
|
}): Promise<InstallResult>;
|
|
42
42
|
uninstall(ctx: ScopeContext, packageIds: string[]): Promise<void>;
|
|
43
|
-
link(ctx: ScopeContext, packagePath: string): Promise<InstallResultEntry>;
|
|
43
|
+
link(ctx: ScopeContext, packagePath: string, sourceManifest?: unknown): Promise<InstallResultEntry>;
|
|
44
44
|
unlink(ctx: ScopeContext, packageId: string): Promise<void>;
|
|
45
45
|
update(ctx: ScopeContext, packageIds?: string[]): Promise<InstallResult>;
|
|
46
46
|
enable(ctx: ScopeContext, packageId: string): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { randomUUID } from 'crypto';
|
|
|
5
5
|
import { pathToFileURL } from 'url';
|
|
6
6
|
import { glob } from 'glob';
|
|
7
7
|
import { DiagnosticCollector, loadManifest, extractEntityKinds, createMarketplaceEntry, addToMarketplaceLock, removeFromMarketplaceLock, readMarketplaceLock, enablePlugin, disablePlugin, createEmptyLock, writeMarketplaceLock } from '@kb-labs/core-discovery';
|
|
8
|
+
import { isManifestV3 } from '@kb-labs/plugin-contracts';
|
|
8
9
|
import { accessSync, constants } from 'fs';
|
|
9
10
|
|
|
10
11
|
// src/marketplace-service.ts
|
|
@@ -304,7 +305,7 @@ var MarketplaceService = class {
|
|
|
304
305
|
// -------------------------------------------------------------------------
|
|
305
306
|
// Link / Unlink
|
|
306
307
|
// -------------------------------------------------------------------------
|
|
307
|
-
async link(ctx, packagePath) {
|
|
308
|
+
async link(ctx, packagePath, sourceManifest) {
|
|
308
309
|
const scopeRoot = resolveScopeRoot(this.roots, ctx);
|
|
309
310
|
const absPath = path4.resolve(scopeRoot, packagePath);
|
|
310
311
|
if (!isPathInside(scopeRoot, absPath)) {
|
|
@@ -317,7 +318,8 @@ var MarketplaceService = class {
|
|
|
317
318
|
);
|
|
318
319
|
const id = pkgJson.name;
|
|
319
320
|
const version = pkgJson.version ?? "0.0.0";
|
|
320
|
-
const
|
|
321
|
+
const manifest = sourceManifest && isManifestV3(sourceManifest) ? sourceManifest : void 0;
|
|
322
|
+
const primaryKind = manifest ? "plugin" : await this.detectKind(absPath);
|
|
321
323
|
if (primaryKind === null) {
|
|
322
324
|
throw new InvalidEntityError(
|
|
323
325
|
`Cannot link "${id}" (${absPath}) \u2014 not a valid KB Labs entity (no plugin/adapter/workflow manifest found).`
|
|
@@ -325,7 +327,7 @@ var MarketplaceService = class {
|
|
|
325
327
|
}
|
|
326
328
|
this.assertScopeAllowsKind(ctx.scope, primaryKind);
|
|
327
329
|
const strategy = this.strategies.get(primaryKind);
|
|
328
|
-
const provides = strategy ? await strategy.extractProvides(absPath) : [primaryKind];
|
|
330
|
+
const provides = manifest ? extractEntityKinds(manifest) : strategy ? await strategy.extractProvides(absPath) : [primaryKind];
|
|
329
331
|
const integrity = await computeIntegrity(absPath);
|
|
330
332
|
const entry = createMarketplaceEntry({
|
|
331
333
|
version,
|
|
@@ -335,12 +337,13 @@ var MarketplaceService = class {
|
|
|
335
337
|
primaryKind,
|
|
336
338
|
provides
|
|
337
339
|
});
|
|
338
|
-
|
|
339
|
-
await
|
|
340
|
+
const canonicalId = manifest?.id ?? id;
|
|
341
|
+
await addToMarketplaceLock(scopeRoot, canonicalId, entry);
|
|
342
|
+
await this.cacheManifest(scopeRoot, canonicalId, absPath, primaryKind, integrity, manifest);
|
|
340
343
|
if (strategy?.afterInstall) {
|
|
341
|
-
await strategy.afterInstall(
|
|
344
|
+
await strategy.afterInstall(canonicalId, absPath, this, ctx);
|
|
342
345
|
}
|
|
343
|
-
return { id, version, primaryKind, provides, packageRoot: absPath, scope: ctx.scope };
|
|
346
|
+
return { id: canonicalId, version, primaryKind, provides, packageRoot: absPath, scope: ctx.scope };
|
|
344
347
|
}
|
|
345
348
|
async unlink(ctx, packageId) {
|
|
346
349
|
const scopeRoot = resolveScopeRoot(this.roots, ctx);
|
|
@@ -566,9 +569,18 @@ var MarketplaceService = class {
|
|
|
566
569
|
);
|
|
567
570
|
}
|
|
568
571
|
}
|
|
569
|
-
async cacheManifest(scopeRoot, packageId, packageRoot, primaryKind, integrity) {
|
|
572
|
+
async cacheManifest(scopeRoot, packageId, packageRoot, primaryKind, integrity, sourceManifest) {
|
|
570
573
|
try {
|
|
571
574
|
if (primaryKind === "plugin") {
|
|
575
|
+
if (sourceManifest) {
|
|
576
|
+
await setCacheEntry(scopeRoot, packageId, {
|
|
577
|
+
manifestType: "plugin",
|
|
578
|
+
manifest: sourceManifest,
|
|
579
|
+
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
580
|
+
integrity
|
|
581
|
+
});
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
572
584
|
const diag = new DiagnosticCollector();
|
|
573
585
|
const manifest = await loadManifest(packageRoot, diag);
|
|
574
586
|
if (manifest) {
|
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","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"]}
|
|
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","extractEntityKinds","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 extractEntityKinds,\n} from '@kb-labs/core-discovery';\nimport { isManifestV3, type ManifestV3 } from '@kb-labs/plugin-contracts';\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, sourceManifest?: unknown): 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 // Scaffold can link a package before its TypeScript entry has been built.\n // In that case the caller supplies the generated manifest; it is still\n // validated here and becomes the canonical source for lock/cache metadata.\n const manifest = sourceManifest && isManifestV3(sourceManifest)\n ? sourceManifest as ManifestV3\n : undefined;\n const primaryKind = manifest ? 'plugin' : 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 = manifest\n ? extractEntityKinds(manifest)\n : 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 const canonicalId = manifest?.id ?? id;\n await addToMarketplaceLock(scopeRoot, canonicalId, entry);\n await this.cacheManifest(scopeRoot, canonicalId, absPath, primaryKind, integrity, manifest);\n\n if (strategy?.afterInstall) {\n await strategy.afterInstall(canonicalId, absPath, this, ctx);\n }\n\n return { id: canonicalId, 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 sourceManifest?: ManifestV3,\n ): Promise<void> {\n try {\n if (primaryKind === 'plugin') {\n if (sourceManifest) {\n await setCacheEntry(scopeRoot, packageId, {\n manifestType: 'plugin',\n manifest: sourceManifest,\n cachedAt: new Date().toISOString(),\n integrity,\n });\n return;\n }\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.112.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"type-check": "tsc --noEmit"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@kb-labs/core-discovery": "^2.
|
|
31
|
-
"@kb-labs/core-platform": "^2.
|
|
32
|
-
"@kb-labs/marketplace-contracts": "^2.
|
|
33
|
-
"@kb-labs/plugin-contracts": "^2.
|
|
30
|
+
"@kb-labs/core-discovery": "^2.112.0",
|
|
31
|
+
"@kb-labs/core-platform": "^2.112.0",
|
|
32
|
+
"@kb-labs/marketplace-contracts": "^2.112.0",
|
|
33
|
+
"@kb-labs/plugin-contracts": "^2.112.0",
|
|
34
34
|
"glob": "^11.0.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|