{"version":3,"sources":["../src/diagnostics.ts","../src/marketplace-lock.ts","../src/manifest-loader.ts","../src/integrity.ts","../src/discovery-manager.ts"],"names":["path","fs","randomUUID","path2","fs2","isManifestV3","fs3","crypto","path3","path4","fs4"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @module @kb-labs/core-discovery/diagnostics\n * Structured diagnostic collector for the discovery pipeline.\n */\n\nimport type {\n  DiagnosticEvent,\n  DiagnosticSeverity,\n  DiagnosticCode,\n  EntityKind,\n} from './types.js';\n\n/**\n * Collects diagnostic events during discovery.\n * Passed through the pipeline so every step can report issues.\n */\nexport class DiagnosticCollector {\n  private readonly events: DiagnosticEvent[] = [];\n\n  /** Record a diagnostic event */\n  add(\n    severity: DiagnosticSeverity,\n    code: DiagnosticCode,\n    message: string,\n    opts?: {\n      pluginId?: string;\n      entityKind?: EntityKind;\n      entityId?: string;\n      filePath?: string;\n      stack?: string;\n      remediation?: string;\n    },\n  ): void {\n    this.events.push({\n      severity,\n      code,\n      message,\n      context: opts\n        ? {\n            pluginId: opts.pluginId,\n            entityKind: opts.entityKind,\n            entityId: opts.entityId,\n            filePath: opts.filePath,\n          }\n        : undefined,\n      ts: Date.now(),\n      stack: opts?.stack,\n      remediation: opts?.remediation,\n    });\n  }\n\n  error(code: DiagnosticCode, message: string, opts?: Parameters<DiagnosticCollector['add']>[3]): void {\n    this.add('error', code, message, opts);\n  }\n\n  warning(code: DiagnosticCode, message: string, opts?: Parameters<DiagnosticCollector['add']>[3]): void {\n    this.add('warning', code, message, opts);\n  }\n\n  info(code: DiagnosticCode, message: string, opts?: Parameters<DiagnosticCollector['add']>[3]): void {\n    this.add('info', code, message, opts);\n  }\n\n  debug(code: DiagnosticCode, message: string, opts?: Parameters<DiagnosticCollector['add']>[3]): void {\n    this.add('debug', code, message, opts);\n  }\n\n  /** Return all collected events (immutable copy) */\n  getEvents(): DiagnosticEvent[] {\n    return [...this.events];\n  }\n\n  /** Check if any errors were collected */\n  hasErrors(): boolean {\n    return this.events.some(e => e.severity === 'error');\n  }\n\n  /** Count events by severity */\n  countBySeverity(): Record<DiagnosticSeverity, number> {\n    const counts: Record<DiagnosticSeverity, number> = {\n      error: 0,\n      warning: 0,\n      info: 0,\n      debug: 0,\n    };\n    for (const e of this.events) {\n      counts[e.severity]++;\n    }\n    return counts;\n  }\n}\n","/**\n * @module @kb-labs/core-discovery/marketplace-lock\n * Read / write / validate .kb/marketplace.lock\n */\n\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport type { MarketplaceLock, MarketplaceEntry, EntityKind, EntitySignature } from './types.js';\nimport { DiagnosticCollector } from './diagnostics.js';\n\nconst LOCK_FILE = '.kb/marketplace.lock';\nconst SCHEMA_VERSION = 'kb.marketplace/2' as const;\n\n// ---------------------------------------------------------------------------\n// Read\n// ---------------------------------------------------------------------------\n\n/**\n * Load the marketplace lock file from the given workspace root.\n * Returns null if the file does not exist or is invalid.\n */\nexport async function readMarketplaceLock(\n  root: string,\n  diag: DiagnosticCollector,\n): Promise<MarketplaceLock | null> {\n  const lockPath = path.join(root, LOCK_FILE);\n\n  let raw: string;\n  try {\n    raw = await fs.readFile(lockPath, 'utf-8');\n  } catch (err) {\n    if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n      diag.info('LOCK_NOT_FOUND', `No marketplace lock file found at ${lockPath}`, {\n        filePath: lockPath,\n        remediation: 'Run \"kb marketplace install <package>\" to create one',\n      });\n      return null;\n    }\n    diag.error('LOCK_PARSE_ERROR', `Failed to read ${lockPath}: ${(err as Error).message}`, {\n      filePath: lockPath,\n    });\n    return null;\n  }\n\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(raw);\n  } catch (err) {\n    diag.error('LOCK_PARSE_ERROR', `Invalid JSON in ${lockPath}: ${(err as Error).message}`, {\n      filePath: lockPath,\n      remediation: 'Fix or regenerate the lock file',\n    });\n    return null;\n  }\n\n  if (!isValidLock(parsed)) {\n    diag.error('LOCK_SCHEMA_INVALID', `Lock file schema mismatch — expected ${SCHEMA_VERSION}`, {\n      filePath: lockPath,\n      remediation: 'Delete the lock file and re-install packages via marketplace',\n    });\n    return null;\n  }\n\n  return parsed;\n}\n\n// ---------------------------------------------------------------------------\n// Write\n// ---------------------------------------------------------------------------\n\n/**\n * Write the marketplace lock file atomically (tmp → rename).\n */\nexport async function writeMarketplaceLock(\n  root: string,\n  lock: MarketplaceLock,\n): Promise<void> {\n  const lockPath = path.join(root, LOCK_FILE);\n  const dir = path.dirname(lockPath);\n  await fs.mkdir(dir, { recursive: true });\n\n  const tmpPath = `${lockPath}.tmp.${randomUUID()}`;\n  const content = JSON.stringify(lock, null, 2) + '\\n';\n\n  await fs.writeFile(tmpPath, content, 'utf-8');\n  await fs.rename(tmpPath, lockPath);\n}\n\n// ---------------------------------------------------------------------------\n// Mutate\n// ---------------------------------------------------------------------------\n\n/**\n * Add or update an entry in the marketplace lock.\n * Preserves the existing `enabled` flag when the entry already exists —\n * re-installing a disabled package must not silently re-enable it.\n */\nexport async function addToMarketplaceLock(\n  root: string,\n  packageId: string,\n  entry: MarketplaceEntry,\n): Promise<MarketplaceLock> {\n  const diag = new DiagnosticCollector();\n  const existing = await readMarketplaceLock(root, diag) ?? createEmptyLock();\n  const existingEntry = existing.installed[packageId];\n  existing.installed[packageId] = {\n    ...entry,\n    // Preserve enabled state from prior install — re-install must not override\n    // a user's explicit disable (e.g. parallel test disabling then re-installing).\n    enabled: existingEntry?.enabled ?? entry.enabled,\n  };\n  await writeMarketplaceLock(root, existing);\n  return existing;\n}\n\n/**\n * Remove an entry from the marketplace lock.\n * Returns true if the entry existed and was removed.\n */\nexport async function removeFromMarketplaceLock(\n  root: string,\n  packageId: string,\n): Promise<boolean> {\n  const diag = new DiagnosticCollector();\n  const existing = await readMarketplaceLock(root, diag);\n  if (!existing || !(packageId in existing.installed)) {\n    return false;\n  }\n  delete existing.installed[packageId];\n  await writeMarketplaceLock(root, existing);\n  return true;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/** Create an empty marketplace lock */\nexport function createEmptyLock(): MarketplaceLock {\n  return { schema: SCHEMA_VERSION, installed: {} };\n}\n\n/** Create a marketplace entry */\nexport function createMarketplaceEntry(opts: {\n  version: string;\n  integrity: string;\n  resolvedPath: string;\n  source: 'marketplace' | 'local';\n  primaryKind: EntityKind;\n  provides: EntityKind[];\n  signature?: EntitySignature;\n  trust?: 'trusted' | 'untrusted';\n  spec?: string;\n}): MarketplaceEntry {\n  return {\n    version: opts.version,\n    integrity: opts.integrity,\n    resolvedPath: opts.resolvedPath,\n    installedAt: new Date().toISOString(),\n    source: opts.source,\n    primaryKind: opts.primaryKind,\n    provides: opts.provides,\n    enabled: true,\n    signature: opts.signature,\n    trust: opts.trust ?? 'untrusted',\n    spec: opts.spec,\n  };\n}\n\n// ---------------------------------------------------------------------------\n// Enable / Disable\n// ---------------------------------------------------------------------------\n\n/**\n * Set `enabled` on an entry in the marketplace lock.\n * Returns false if the package is not found in the lock.\n */\nasync function setPluginEnabled(\n  root: string,\n  packageId: string,\n  enabled: boolean,\n): Promise<boolean> {\n  const diag = new DiagnosticCollector();\n  const existing = await readMarketplaceLock(root, diag);\n  if (!existing || !(packageId in existing.installed)) {\n    return false;\n  }\n  existing.installed[packageId]!.enabled = enabled;\n  await writeMarketplaceLock(root, existing);\n  return true;\n}\n\n/**\n * Mark a plugin as enabled in the marketplace lock.\n * Returns false if the package is not installed.\n */\nexport async function enablePlugin(root: string, packageId: string): Promise<boolean> {\n  return setPluginEnabled(root, packageId, true);\n}\n\n/**\n * Mark a plugin as disabled in the marketplace lock.\n * Returns false if the package is not installed.\n */\nexport async function disablePlugin(root: string, packageId: string): Promise<boolean> {\n  return setPluginEnabled(root, packageId, false);\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nfunction isValidLock(value: unknown): value is MarketplaceLock {\n  if (typeof value !== 'object' || value === null) {return false;}\n  const obj = value as Record<string, unknown>;\n  return (\n    obj.schema === SCHEMA_VERSION &&\n    typeof obj.installed === 'object' &&\n    obj.installed !== null &&\n    !Array.isArray(obj.installed)\n  );\n}\n","/**\n * @module @kb-labs/core-discovery/manifest-loader\n * Safe dynamic import of plugin manifests with timeout protection.\n */\n\nimport { isManifestV3, type ManifestV3 } from '@kb-labs/plugin-contracts';\nimport type { DiagnosticCollector } from './diagnostics.js';\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\n\nconst DEFAULT_IMPORT_TIMEOUT_MS = 5_000;\n\n/**\n * Validate that a resolved path stays within the allowed root directory.\n * Prevents path traversal attacks via manifest fields like `\"../../etc/passwd\"`.\n */\nfunction isWithinRoot(filePath: string, root: string): boolean {\n  const resolved = path.resolve(filePath);\n  const resolvedRoot = path.resolve(root);\n  return resolved.startsWith(resolvedRoot + path.sep) || resolved === resolvedRoot;\n}\n\n/**\n * Safely import a module with a timeout guard.\n * Cleans up the timer on success to avoid resource leaks.\n */\nasync function safeImport<T = unknown>(\n  modulePath: string,\n  timeoutMs: number = DEFAULT_IMPORT_TIMEOUT_MS,\n): Promise<T> {\n  let timer: ReturnType<typeof setTimeout>;\n  const timeoutPromise = new Promise<never>((_, reject) => {\n    timer = setTimeout(\n      () => reject(new Error(`Import timeout after ${timeoutMs}ms: ${modulePath}`)),\n      timeoutMs,\n    );\n  });\n\n  try {\n    return await Promise.race([\n      import(modulePath) as Promise<T>,\n      timeoutPromise,\n    ]);\n  } finally {\n    clearTimeout(timer!);\n  }\n}\n\n/**\n * Attempt to locate and load a ManifestV3 from a package root directory.\n *\n * Resolution order:\n *   1. package.json `kbLabs.manifest` or `kb.manifest` field (relative path)\n *   2. `kb.plugin.json` in package root\n *   3. Manifest exported from package entry point (`dist/index.js`)\n */\nexport async function loadManifest(\n  packageRoot: string,\n  diag: DiagnosticCollector,\n  timeoutMs: number = DEFAULT_IMPORT_TIMEOUT_MS,\n): Promise<ManifestV3 | null> {\n  const pluginId = path.basename(packageRoot);\n  const resolvedRoot = path.resolve(packageRoot);\n\n  // --- 1. Check package.json for manifest field ---\n  const pkgJsonPath = path.join(resolvedRoot, 'package.json');\n  try {\n    const raw = await fs.readFile(pkgJsonPath, 'utf-8');\n    const pkg = JSON.parse(raw) as Record<string, unknown>;\n    const manifestField =\n      (pkg.kbLabs as Record<string, unknown> | undefined)?.manifest ??\n      (pkg.kb as Record<string, unknown> | undefined)?.manifest;\n\n    if (typeof manifestField === 'string') {\n      const manifestPath = path.resolve(resolvedRoot, manifestField);\n\n      // Path traversal guard\n      if (!isWithinRoot(manifestPath, resolvedRoot)) {\n        diag.error('MANIFEST_VALIDATION_ERROR',\n          `Manifest path \"${manifestField}\" escapes package root — possible path traversal`, {\n          pluginId,\n          filePath: manifestPath,\n          remediation: 'Use a relative path within the package directory',\n        });\n        return null;\n      }\n\n      return await importManifestFile(manifestPath, pluginId, diag, timeoutMs);\n    }\n  } catch {\n    // package.json missing or unreadable — continue\n  }\n\n  // --- 2. Try kb.plugin.json ---\n  const kbPluginJsonPath = path.join(resolvedRoot, 'kb.plugin.json');\n  try {\n    await fs.access(kbPluginJsonPath);\n    const raw = await fs.readFile(kbPluginJsonPath, 'utf-8');\n    const parsed = JSON.parse(raw);\n    if (isManifestV3(parsed)) {\n      return parsed;\n    }\n    diag.warning('MANIFEST_VALIDATION_ERROR', `kb.plugin.json exists but is not a valid ManifestV3`, {\n      pluginId,\n      filePath: kbPluginJsonPath,\n      remediation: 'Ensure the file has schema: \"kb.plugin/3\" and required fields (id, version)',\n    });\n    return null;\n  } catch {\n    // No kb.plugin.json — continue\n  }\n\n  // --- 3. Try dist/index.js (always within package root, no traversal risk) ---\n  try {\n    const entryPoint = path.join(resolvedRoot, 'dist', 'index.js');\n    await fs.access(entryPoint);\n    return await importManifestFile(entryPoint, pluginId, diag, timeoutMs);\n  } catch {\n    // No dist/index.js or import failed\n  }\n\n  diag.error('MANIFEST_NOT_FOUND', `No manifest found in ${resolvedRoot}`, {\n    pluginId,\n    filePath: resolvedRoot,\n    remediation: 'Add a kb.plugin.json file or set kbLabs.manifest in package.json',\n  });\n  return null;\n}\n\n/**\n * Import a manifest from a specific file path.\n */\nasync function importManifestFile(\n  filePath: string,\n  pluginId: string,\n  diag: DiagnosticCollector,\n  timeoutMs: number,\n): Promise<ManifestV3 | null> {\n  try {\n    const mod = await safeImport<Record<string, unknown>>(filePath, timeoutMs);\n    const candidate = mod.manifest ?? mod.default ?? mod;\n\n    if (isManifestV3(candidate)) {\n      return candidate;\n    }\n\n    diag.warning('MANIFEST_VALIDATION_ERROR', `Imported module is not a valid ManifestV3`, {\n      pluginId,\n      filePath,\n      remediation: 'Ensure the module exports a ManifestV3 object with schema: \"kb.plugin/3\"',\n    });\n    return null;\n  } catch (err) {\n    const message = err instanceof Error ? err.message : String(err);\n    const isTimeout = message.includes('Import timeout');\n\n    diag.error(\n      isTimeout ? 'MANIFEST_LOAD_TIMEOUT' : 'MANIFEST_PARSE_ERROR',\n      `Failed to load manifest from ${filePath}: ${message}`,\n      {\n        pluginId,\n        filePath,\n        stack: err instanceof Error ? err.stack : undefined,\n        remediation: isTimeout\n          ? 'Check for circular dependencies or blocking top-level await in the module'\n          : 'Ensure the manifest file is valid JavaScript/JSON',\n      },\n    );\n    return null;\n  }\n}\n","/**\n * @module @kb-labs/core-discovery/integrity\n * SRI integrity computation and parsing for marketplace packages.\n *\n * Packages are identified by a hash of their package.json (not the full tarball).\n * This keeps verification fast and stable across tarball recompression.\n */\n\nimport * as crypto from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Compute the SRI integrity string for an arbitrary file.\n *\n * Format: `sha256-<base64>` (SubResource Integrity convention).\n * Throws if the file cannot be read.\n */\nexport async function computeFileIntegrity(filePath: string): Promise<string> {\n  const content = await fs.readFile(filePath);\n  const hash = crypto.createHash('sha256').update(content).digest('base64');\n  return `sha256-${hash}`;\n}\n\n/**\n * Compute the SRI integrity string for a package by hashing its package.json.\n * Kept for backwards compatibility — delegates to computeFileIntegrity.\n */\nexport async function computePackageIntegrity(pkgRoot: string): Promise<string> {\n  return computeFileIntegrity(path.join(pkgRoot, 'package.json'));\n}\n\n/**\n * Compute the SRI integrity string for a manifest file (e.g. dist/index.js).\n * Used by CLI discovery to detect when a plugin was rebuilt.\n */\nexport async function computeManifestIntegrity(manifestPath: string): Promise<string> {\n  return computeFileIntegrity(manifestPath);\n}\n\n/**\n * Parse an SRI integrity string (e.g. `sha256-<base64>`) into its components.\n * Returns `null` when the value is malformed.\n */\nexport function parseIntegrity(value: string): { algorithm: string; hash: string } | null {\n  const dash = value.indexOf('-');\n  if (dash <= 0 || dash === value.length - 1) {\n    return null;\n  }\n  return {\n    algorithm: value.slice(0, dash),\n    hash: value.slice(dash + 1),\n  };\n}\n","/**\n * @module @kb-labs/core-discovery/discovery-manager\n * Marketplace-based discovery: reads .kb/marketplace.lock, loads & validates manifests.\n */\n\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { type ManifestV3 } from '@kb-labs/plugin-contracts';\nimport type {\n  DiscoveryResult,\n  DiscoveredPlugin,\n  MarketplaceEntry,\n  EntityKind,\n} from './types.js';\nimport { DiagnosticCollector } from './diagnostics.js';\nimport { readMarketplaceLock } from './marketplace-lock.js';\nimport { loadManifest } from './manifest-loader.js';\nimport { computePackageIntegrity } from './integrity.js';\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface DiscoveryOptions {\n  /** Workspace root directory (default: process.cwd()) */\n  root?: string;\n  /**\n   * Platform installation root (e.g. ~/kb-platform).\n   * When set and different from root, both lock files are read:\n   * project lock wins, platform lock fills gaps.\n   */\n  platformRoot?: string;\n  /** Timeout for each manifest import in milliseconds (default: 5000) */\n  importTimeoutMs?: number;\n  /** Whether to verify integrity hashes (default: true) */\n  verifyIntegrity?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Discovery Manager\n// ---------------------------------------------------------------------------\n\n/**\n * Discovers installed entities by reading the marketplace lock file\n * and loading manifests from the resolved paths.\n *\n * There is no filesystem scanning — every entity must be registered\n * in .kb/marketplace.lock via `kb marketplace install` or `kb marketplace link`.\n */\nexport class DiscoveryManager {\n  private readonly root: string;\n  private readonly platformRoot: string | undefined;\n  private readonly importTimeoutMs: number;\n  private readonly verifyIntegrity: boolean;\n\n  constructor(opts: DiscoveryOptions = {}) {\n    this.root = opts.root ?? process.cwd();\n    this.platformRoot = opts.platformRoot !== this.root ? opts.platformRoot : undefined;\n    this.importTimeoutMs = opts.importTimeoutMs ?? 5_000;\n    this.verifyIntegrity = opts.verifyIntegrity ?? true;\n  }\n\n  /**\n   * Run full discovery pipeline.\n   *\n   * When platformRoot is set, both lock files are merged:\n   * project lock (this.root) is read first and wins on conflicts.\n   * Platform lock fills in any entries not present in the project.\n   *\n   *   1. Read .kb/marketplace.lock (project first, then platform)\n   *   2. For each entry → resolve path → load manifest → validate → verify integrity\n   *   3. Return aggregated result with diagnostics\n   */\n  async discover(): Promise<DiscoveryResult> {\n    const diag = new DiagnosticCollector();\n    const plugins: DiscoveredPlugin[] = [];\n    const manifests = new Map<string, ManifestV3>();\n\n    // 1. Build merged entry map: project wins, platform fills gaps\n    const mergedEntries = await this.readMergedLock(diag);\n    if (!mergedEntries) {\n      return { plugins, manifests, diagnostics: diag.getEvents() };\n    }\n\n    // 2. Process each entry\n    for (const [packageId, { entry, root }] of mergedEntries) {\n      await this.processEntry(packageId, entry, root, plugins, manifests, diag);\n    }\n\n    return { plugins, manifests, diagnostics: diag.getEvents() };\n  }\n\n  /**\n   * Read and merge marketplace.lock from project root and (optionally) platform root.\n   * Returns a map of packageId → { entry, root } where root is the directory\n   * the entry's resolvedPath should be resolved against.\n   * Project entries win over platform entries on conflict.\n   */\n  private async readMergedLock(\n    diag: DiagnosticCollector,\n  ): Promise<Map<string, { entry: MarketplaceEntry; root: string }> | null> {\n    const merged = new Map<string, { entry: MarketplaceEntry; root: string }>();\n\n    // Platform lock first (lower priority — fills gaps)\n    if (this.platformRoot) {\n      const platformLock = await readMarketplaceLock(this.platformRoot, diag);\n      if (platformLock) {\n        for (const [packageId, entry] of Object.entries(platformLock.installed)) {\n          merged.set(packageId, { entry, root: this.platformRoot });\n        }\n      }\n    }\n\n    // Project lock second (higher priority — overwrites platform entries)\n    const projectLock = await readMarketplaceLock(this.root, diag);\n    if (projectLock) {\n      for (const [packageId, entry] of Object.entries(projectLock.installed)) {\n        merged.set(packageId, { entry, root: this.root });\n      }\n    } else if (!this.platformRoot) {\n      // No project lock and no platform lock — nothing to discover\n      return null;\n    }\n\n    return merged.size > 0 ? merged : null;\n  }\n\n  // -------------------------------------------------------------------------\n  // Private\n  // -------------------------------------------------------------------------\n\n  private async processEntry(\n    packageId: string,\n    entry: MarketplaceEntry,\n    root: string,\n    plugins: DiscoveredPlugin[],\n    manifests: Map<string, ManifestV3>,\n    diag: DiagnosticCollector,\n  ): Promise<void> {\n    // Skip disabled entries\n    if (entry.enabled === false) {\n      diag.info('PLUGIN_DISABLED', `Plugin \"${packageId}\" is disabled — skipping`, {\n        pluginId: packageId,\n      });\n      return;\n    }\n\n    // Resolve the package root relative to the lock file's root directory\n    const packageRoot = path.resolve(root, entry.resolvedPath);\n\n    // Check the package directory exists\n    try {\n      await fs.access(packageRoot);\n    } catch {\n      diag.error('PACKAGE_NOT_FOUND', `Package directory not found: ${packageRoot}`, {\n        pluginId: packageId,\n        filePath: packageRoot,\n        remediation: `Run \"pnpm install\" or \"kb marketplace install ${packageId}\" to restore`,\n      });\n      return;\n    }\n\n    // Verify integrity for non-local packages. Local packages change frequently\n    // (rebuilds, version bumps) — integrity is updated at install/sync time, not here.\n    if (this.verifyIntegrity && entry.integrity && entry.source !== 'local') {\n      const ok = await this.checkIntegrity(packageRoot, entry.integrity, packageId, diag);\n      if (!ok) {return;}\n    }\n\n    // Load manifest\n    const manifest = await loadManifest(packageRoot, diag, this.importTimeoutMs);\n    if (!manifest) {return;}\n\n    // Validate manifest ID matches expected package ID\n    if (manifest.id !== packageId) {\n      diag.warning('MANIFEST_VALIDATION_ERROR',\n        `Manifest ID \"${manifest.id}\" does not match lock entry \"${packageId}\"`, {\n        pluginId: packageId,\n        filePath: packageRoot,\n      });\n      // Continue anyway — use the manifest's own ID\n    }\n\n    const pluginId = manifest.id;\n\n    // Check for duplicate\n    if (manifests.has(pluginId)) {\n      diag.warning('ENTITY_CONFLICT', `Duplicate plugin ID \"${pluginId}\" — skipping later entry`, {\n        pluginId,\n        filePath: packageRoot,\n      });\n      return;\n    }\n\n    // Extract entity kinds this plugin provides\n    const provides = extractEntityKinds(manifest);\n\n    // Signature check (info-level, not blocking)\n    if (!entry.signature) {\n      diag.info('SIGNATURE_MISSING', `Plugin \"${pluginId}\" is not signed`, {\n        pluginId,\n        remediation: 'Publish through the official marketplace to get a platform signature',\n      });\n    }\n\n    manifests.set(pluginId, manifest);\n    plugins.push({\n      id: pluginId,\n      version: manifest.version,\n      packageRoot,\n      source: { kind: entry.source, path: entry.resolvedPath },\n      display: manifest.display\n        ? { name: manifest.display.name, description: manifest.display.description }\n        : undefined,\n      integrity: entry.integrity,\n      signature: entry.signature,\n      provides,\n    });\n  }\n\n  /**\n   * Verify the SRI integrity hash of a package by hashing its package.json.\n   */\n  private async checkIntegrity(\n    packageRoot: string,\n    expected: string,\n    pluginId: string,\n    diag: DiagnosticCollector,\n  ): Promise<boolean> {\n    try {\n      const computed = await computePackageIntegrity(packageRoot);\n\n      if (computed !== expected) {\n        diag.error('INTEGRITY_MISMATCH',\n          `Integrity mismatch for \"${pluginId}\": expected ${expected}, got ${computed}`, {\n          pluginId,\n          filePath: path.join(packageRoot, 'package.json'),\n          remediation: `Re-install: kb marketplace install ${pluginId}`,\n        });\n        return false;\n      }\n      return true;\n    } catch (err) {\n      diag.warning('INTEGRITY_MISMATCH',\n        `Could not verify integrity for \"${pluginId}\": ${(err as Error).message}`, {\n        pluginId,\n        filePath: packageRoot,\n      });\n      // Non-blocking — proceed without integrity verification\n      return true;\n    }\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extract which entity kinds a manifest provides by inspecting its sections.\n */\nexport function extractEntityKinds(manifest: ManifestV3): EntityKind[] {\n  const kinds: EntityKind[] = ['plugin']; // Every manifest is at least a plugin\n\n  if (manifest.cli?.commands?.length)               {kinds.push('cli-command');}\n  if (manifest.rest?.routes?.length)                 {kinds.push('rest-route');}\n  if (manifest.ws?.channels?.length)                 {kinds.push('ws-channel');}\n  if (manifest.workflows?.handlers?.length)          {kinds.push('workflow');}\n  if (manifest.webhooks?.handlers?.length)           {kinds.push('webhook');}\n  if (manifest.jobs?.handlers?.length)               {kinds.push('job');}\n  if (manifest.cron?.schedules?.length)              {kinds.push('cron');}\n  if (manifest.studio?.pages?.length)                {kinds.push('studio-widget');}\n  if (manifest.studio?.menus?.length)                {kinds.push('studio-menu');}\n\n  return kinds;\n}\n"]}