Member Junction
    Preparing search index...
    • Loads every dynamic package that applies to options.processId and returns a report of what happened to each entry. This is the one call a host makes; everything else in the package is a primitive it composes.

      Parameters

      Returns Promise<DynamicPackagesReport>

      The DynamicPackagesReport: Loaded, Skipped (with a reason), NotFound, Failed, plus the resolved mode and where it came from.

      Order of operations. Mode is resolved first (MJ_DYNAMIC_PACKAGES env var → options.modedynamicPackages.policy'load'). Candidates are then discovered generic-to-specific — the host's codeGeneration.packages, then dynamicPackages.<tier>[], then the mj-app.json beside the config — and merged by package name (mergeCandidates). Under mode 'none' every candidate is reported as skipped and nothing is imported. Otherwise each candidate is filtered (Enabled === false, then Processes / ExcludeProcesses via MatchesProcess), served from the per-process cache when an earlier call already loaded it (module returned, startup export not re-run), or imported through importFromHost with an on-disk workspace fallback for manifest entries.

      Why order matters. @RegisterClass resolves by load-order priority — the last registration for a key wins — so importing generic-to-specific is what makes an Open App's server subclass beat its generated one, and the app you are standing in beat an installed copy.

      When to call it. After the host's class-registration manifest has been imported (so app registrations land last) and before any database provider exists (a StartupExport may rely on nothing but the ClassFactory).

      Failure model. Throws only when processId is missing. A package that no anchor can resolve is NotFound (expected before npm install, or for an unbuilt workspace member); one that resolves but throws while loading is Failed with its own error, logged on the warn path and never masked by a resolution message. Boot never crashes because of an app package.

      const { config, configFilePath } = DiscoverMJConfig();
      const report = await LoadDynamicPackages({ processId: 'mcp', config, configFilePath });
      for (const failed of report.Failed) {
      console.error(`app package ${failed.Entry.PackageName} failed to load`, failed.Error);
      }
      const resolverPaths = report.Loaded.flatMap((l) => {
      const paths = l.Module.RESOLVER_PATHS;
      return Array.isArray(paths) ? (paths as string[]) : [];
      });
      await LoadDynamicPackages({
      processId: EffectiveProcessId('ai-cli'), // 'cli:ai:agents:run' when run under `mj ai …`
      config, configFilePath,
      log: StderrDynamicPackagesLogger, // stdout may be a JSON envelope
      });