adapt method

Future<ApplicationDefinition> adapt(
  1. McpBundle bundle,
  2. BundleEntryPoint entry, {
  3. required BundleUriResolver uriResolver,
})

FR-APP-LOCAL-004~008

Implementation

Future<ApplicationDefinition> adapt(
  McpBundle bundle,
  BundleEntryPoint entry, {
  required BundleUriResolver uriResolver,
}) async {
  _assertRuntimeCompatibility(bundle.manifest);

  final bundleId = bundle.manifest.id;
  if (bundle.directory == null) {
    throw BundleAdaptException(
      bundleId: bundleId,
      reason: BundleAdaptReason.unsupportedEntryPoint,
      message:
          'Bundle has no filesystem root — inline / remote refs must '
          'be materialised to a directory before adapting',
    );
  }

  final ui = bundle.uiResources;
  if (!await ui.exists('app.json')) {
    throw BundleAdaptException(
      bundleId: bundleId,
      reason: BundleAdaptReason.unsupportedEntryPoint,
      message:
          'ui/app.json not found in installed bundle ${bundle.directory} '
          '— the bundle likely predates the filesystem-snapshot layout. '
          'Delete the app entry in the launcher and reinstall from '
          'the .mcpb. Available ui/* files: '
          '${await ui.list(extension: '.json')}',
    );
  }

  final Map<String, dynamic> definitionJson;
  try {
    final raw = await ui.readJson('app.json');
    if (raw is! Map<String, dynamic>) {
      throw const FormatException('ui/app.json must be a JSON object');
    }
    definitionJson = raw;
  } catch (e, st) {
    _logger.logError('bundle.adapter.app_json_parse', e, st,
        {'bundleId': bundleId});
    throw BundleAdaptException(
      bundleId: bundleId,
      reason: BundleAdaptReason.unsupportedEntryPoint,
      message: 'ui/app.json parse failed: $e',
    );
  }

  final Map<String, dynamic> rewritten;
  try {
    rewritten =
        uriResolver.rewriteDefinition(definitionJson) as Map<String, dynamic>;
  } on BundleUriResolutionException catch (e, st) {
    _logger.logError('bundle.adapter.uri_resolution', e, st,
        {'bundleId': bundleId});
    throw BundleAdaptException(
      bundleId: bundleId,
      reason: BundleAdaptReason.uriResolution,
      cause: e,
    );
  }

  final pageLoader = _pageLoaderFor(bundle, uriResolver);

  _logger.debug('bundle.adapter.result', {
    'bundleId': bundleId,
    'entry': entry.toString(),
    'routes':
        (rewritten['routes'] as Map?)?.length ?? 0,
  });

  return ApplicationDefinition(
    json: rewritten,
    pageLoader: pageLoader,
    sourceKind: ApplicationSourceKind.localBundle,
    appId: bundleId,
  );
}