@nextclaw/kernel 0.8.0 → 0.8.1

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.js CHANGED
@@ -2876,17 +2876,16 @@ var AppPackageManager = class {
2876
2876
  installRuntimeHooks = (hooks) => {
2877
2877
  this.runtimeHooks = hooks;
2878
2878
  };
2879
- listPackages = async () => {
2880
- await this.ensureBuiltInPackages();
2879
+ start = async () => await this.ensureBuiltInPackages();
2880
+ listPackages = async (options = {}) => {
2881
2881
  const records = await this.registryService.listApps();
2882
- return { entries: await Promise.all(records.map(async (record) => await this.toPackageView(await this.installationService.info(record.appId)))) };
2882
+ return { entries: await Promise.all(records.map(async (record) => await this.toPackageView(await this.installationService.info(record.appId, { measureStorageUsage: options.includeStorageUsage !== false })))) };
2883
2883
  };
2884
2884
  listInstalledDataOwners = async () => (await this.registryService.listApps()).map((record) => ({
2885
2885
  id: record.appId,
2886
2886
  name: record.name
2887
2887
  }));
2888
2888
  getPackage = async (appId) => {
2889
- await this.ensureBuiltInPackages();
2890
2889
  try {
2891
2890
  return await this.toPackageView(await this.installationService.info(appId));
2892
2891
  } catch (error) {
@@ -2895,7 +2894,6 @@ var AppPackageManager = class {
2895
2894
  }
2896
2895
  };
2897
2896
  listActiveComponentSources = async () => {
2898
- await this.ensureBuiltInPackages();
2899
2897
  const records = await this.registryService.listApps();
2900
2898
  return (await Promise.all(records.filter((record) => record.enabled).map(async (record) => {
2901
2899
  await this.installationService.assertVersionIntegrity(record.appId, record.activeVersion);
@@ -3212,10 +3210,22 @@ var AppDataManager = class {
3212
3210
  appHomeService;
3213
3211
  fileLockService = new FileLockService();
3214
3212
  inventoryService = new AppInstanceInventoryService();
3213
+ reconciliationDiagnostics = [];
3215
3214
  constructor(params) {
3216
3215
  this.params = params;
3217
3216
  this.appHomeService = new AppHomeService(params.appHomeDirectory);
3218
3217
  }
3218
+ start = async () => {
3219
+ const workspacePath = path.resolve(this.params.getWorkspacePath());
3220
+ const [packageDiagnostics, workspaceDiagnostics] = await Promise.all([this.inventoryService.reconcileDeletions(this.appHomeService.getInstancesDirectory()), this.inventoryService.reconcileDeletions(this.getWorkspaceInstancesRoot(workspacePath))]);
3221
+ this.reconciliationDiagnostics = [...packageDiagnostics.map((entry) => ({
3222
+ ...entry,
3223
+ source: "package"
3224
+ })), ...workspaceDiagnostics.map((entry) => ({
3225
+ ...entry,
3226
+ source: "workspace-service"
3227
+ }))];
3228
+ };
3219
3229
  list = async () => {
3220
3230
  const workspacePath = path.resolve(this.params.getWorkspacePath());
3221
3231
  const workspaceInstancesRoot = this.getWorkspaceInstancesRoot(workspacePath);
@@ -3228,26 +3238,31 @@ var AppDataManager = class {
3228
3238
  const packageOwners = new Map(packageList.map((entry) => [entry.id, entry]));
3229
3239
  const workspaceOwnerMap = new Map(workspaceOwners.map((entry) => [entry.id, entry]));
3230
3240
  const workspaceScope = this.workspaceScope(workspacePath);
3241
+ const entries = [...packageInventory.entries.map((entry) => this.toEntry({
3242
+ entry,
3243
+ source: "package",
3244
+ displayName: packageOwners.get(entry.appId)?.name ?? entry.appId,
3245
+ active: packageOwners.has(entry.appId)
3246
+ })), ...workspaceInventory.entries.map((entry) => this.toEntry({
3247
+ entry,
3248
+ source: "workspace-service",
3249
+ displayName: workspaceOwnerMap.get(entry.appId)?.title ?? entry.appId,
3250
+ active: workspaceOwnerMap.has(entry.appId),
3251
+ scope: workspaceScope
3252
+ }))].sort((left, right) => left.displayName.localeCompare(right.displayName) || left.id.localeCompare(right.id));
3253
+ const currentDiagnostics = [...packageInventory.diagnostics.map((diagnostic) => ({
3254
+ ...diagnostic,
3255
+ source: "package"
3256
+ })), ...workspaceInventory.diagnostics.map((diagnostic) => ({
3257
+ ...diagnostic,
3258
+ source: "workspace-service"
3259
+ }))];
3260
+ const currentDiagnosticKeys = new Set(currentDiagnostics.map((entry) => `${entry.source}:${entry.instanceDirectory}`));
3261
+ const diagnostics = /* @__PURE__ */ new Map();
3262
+ for (const entry of [...currentDiagnostics, ...this.reconciliationDiagnostics.filter((diagnostic) => currentDiagnosticKeys.has(`${diagnostic.source}:${diagnostic.instanceDirectory}`))]) diagnostics.set(`${entry.source}:${entry.instanceDirectory}`, entry);
3231
3263
  return {
3232
- entries: [...packageInventory.entries.map((entry) => this.toEntry({
3233
- entry,
3234
- source: "package",
3235
- displayName: packageOwners.get(entry.appId)?.name ?? entry.appId,
3236
- active: packageOwners.has(entry.appId)
3237
- })), ...workspaceInventory.entries.map((entry) => this.toEntry({
3238
- entry,
3239
- source: "workspace-service",
3240
- displayName: workspaceOwnerMap.get(entry.appId)?.title ?? entry.appId,
3241
- active: workspaceOwnerMap.has(entry.appId),
3242
- scope: workspaceScope
3243
- }))].sort((left, right) => left.displayName.localeCompare(right.displayName) || left.id.localeCompare(right.id)),
3244
- diagnostics: [...packageInventory.diagnostics.map((entry) => ({
3245
- ...entry,
3246
- source: "package"
3247
- })), ...workspaceInventory.diagnostics.map((entry) => ({
3248
- ...entry,
3249
- source: "workspace-service"
3250
- }))]
3264
+ entries,
3265
+ diagnostics: Array.from(diagnostics.values())
3251
3266
  };
3252
3267
  };
3253
3268
  deleteRetained = async (dataId, confirmAppId) => {
@@ -10115,7 +10130,8 @@ var ServiceAppRecordService = class {
10115
10130
  const dirPath = join(serviceAppsPath, dirName);
10116
10131
  try {
10117
10132
  const manifest = await readServiceAppManifest(dirPath);
10118
- return this.fromManifest(dirPath, manifest, void 0, await this.materializeWorkspaceStorage(manifest.id));
10133
+ if (manifest.id !== dirName) throw new Error(`service app manifest id must match directory name: ${dirName}`);
10134
+ return this.fromManifest(dirPath, manifest, void 0, await this.inspectWorkspaceStorage(manifest.id));
10119
10135
  } catch (error) {
10120
10136
  if (this.isMissingFileError(error)) return null;
10121
10137
  return this.failedWorkspaceRecord(dirName, dirPath, error);
@@ -10144,13 +10160,22 @@ var ServiceAppRecordService = class {
10144
10160
  }))).filter((entry) => Boolean(entry));
10145
10161
  };
10146
10162
  materializeWorkspaceStorage = async (serviceId) => {
10147
- const instanceDirectory = join(this.params.getWorkspacePath(), ".nextclaw", "app-instances", serviceId, "default");
10163
+ const instanceDirectory = this.getWorkspaceInstanceDirectory(serviceId);
10148
10164
  return (await this.instanceStorageService.materialize({
10149
10165
  appId: serviceId,
10150
10166
  instanceId: "default",
10151
10167
  instanceDirectory
10152
10168
  })).storage;
10153
10169
  };
10170
+ inspectWorkspaceStorage = async (serviceId) => {
10171
+ const instanceDirectory = this.getWorkspaceInstanceDirectory(serviceId);
10172
+ if (!await this.pathExists(instanceDirectory)) return;
10173
+ return (await this.instanceStorageService.inspect({
10174
+ appId: serviceId,
10175
+ instanceId: "default",
10176
+ instanceDirectory
10177
+ })).storage;
10178
+ };
10154
10179
  fromManifest = (dirPath, manifest, packageSource, storage) => {
10155
10180
  const runtimeStatus = this.params.runtimeService.getStatus(manifest.id);
10156
10181
  return {
@@ -10210,10 +10235,26 @@ var ServiceAppRecordService = class {
10210
10235
  isolation: source.isolation
10211
10236
  });
10212
10237
  toTitle = (value) => basename(value).replace(/[-_]+/g, " ").trim() || value;
10238
+ getWorkspaceInstanceDirectory = (serviceId) => join(this.params.getWorkspacePath(), ".nextclaw", "app-instances", serviceId, "default");
10239
+ pathExists = async (targetPath) => {
10240
+ try {
10241
+ await access(targetPath);
10242
+ return true;
10243
+ } catch (error) {
10244
+ if (this.isMissingFileError(error)) return false;
10245
+ throw error;
10246
+ }
10247
+ };
10213
10248
  isMissingFileError = (error) => typeof error === "object" && error !== null && error.code === "ENOENT";
10214
10249
  };
10215
10250
  //#endregion
10216
10251
  //#region src/services/service-app-removal.service.ts
10252
+ const TRANSACTION_ID = "[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}";
10253
+ const CURRENT_DELETION_PATTERN = new RegExp(`^\\.deleting-(?<appId>[a-z0-9]+(?:-[a-z0-9]+)*)-(?<transactionId>${TRANSACTION_ID})$`);
10254
+ const LEGACY_DELETION_PATTERN = new RegExp(`^(?<appId>[a-z0-9]+(?:-[a-z0-9]+)*)\\.deleting-(?<transactionId>${TRANSACTION_ID})$`);
10255
+ function isServiceAppDeletionTombstone(directoryName) {
10256
+ return Boolean(parseServiceAppDeletionTombstone(directoryName));
10257
+ }
10217
10258
  var ServiceAppRemovalCleanupError = class extends Error {
10218
10259
  constructor(cause) {
10219
10260
  super(`临时目录清理失败:${cause instanceof Error ? cause.message : String(cause)}`);
@@ -10223,6 +10264,7 @@ var ServiceAppRemovalCleanupError = class extends Error {
10223
10264
  };
10224
10265
  var ServiceAppRemovalService = class {
10225
10266
  fileLockService = new FileLockService();
10267
+ listCanonicalDirectoryNames = async (serviceAppsPath) => (await this.listDirectories(serviceAppsPath)).filter((directoryName) => !directoryName.startsWith(".") && !isServiceAppDeletionTombstone(directoryName));
10226
10268
  remove = async (params) => await this.fileLockService.withLock(params.lockPath, async () => {
10227
10269
  const record = await params.loadRecord();
10228
10270
  await this.removeLocked({
@@ -10231,14 +10273,39 @@ var ServiceAppRemovalService = class {
10231
10273
  });
10232
10274
  return record;
10233
10275
  });
10276
+ reconcile = async (params) => {
10277
+ const { grantStore, lockPathForAppId, serviceAppsPath } = params;
10278
+ const diagnostics = [];
10279
+ for (const directoryName of await this.listDirectories(serviceAppsPath)) {
10280
+ const appId = parseServiceAppDeletionTombstone(directoryName);
10281
+ if (!appId) continue;
10282
+ const stagedPath = join(serviceAppsPath, directoryName);
10283
+ const canonicalPath = join(serviceAppsPath, appId);
10284
+ try {
10285
+ await this.fileLockService.withLock(lockPathForAppId(appId), async () => {
10286
+ const manifest = await readServiceAppManifest(stagedPath);
10287
+ if (manifest.id !== appId) throw new Error(`Service App 删除墓碑 identity 不匹配:${manifest.id}`);
10288
+ if (!await this.pathExists(canonicalPath)) await grantStore.revokeActionsByPrefix(`${appId}.`);
10289
+ await rm(stagedPath, { recursive: true });
10290
+ });
10291
+ } catch (error) {
10292
+ diagnostics.push({
10293
+ appId,
10294
+ stagedPath,
10295
+ message: error instanceof Error ? error.message : String(error)
10296
+ });
10297
+ }
10298
+ }
10299
+ return diagnostics.sort((left, right) => left.stagedPath.localeCompare(right.stagedPath));
10300
+ };
10234
10301
  removeLocked = async (params) => {
10235
10302
  const { grantStore, purgeData, record, stopRuntime } = params;
10236
10303
  const grants = (await grantStore.list()).filter((grant) => grant.actionId.startsWith(`${record.id}.`));
10237
10304
  const stagedPaths = [];
10238
10305
  try {
10239
10306
  await stopRuntime(record);
10240
- await this.stagePath(record.dirPath, stagedPaths);
10241
- if (purgeData && record.storage) await this.stagePath(record.storage.instanceDirectory, stagedPaths);
10307
+ await this.stageSourcePath(record.dirPath, stagedPaths);
10308
+ if (purgeData && record.storage) await this.stageInstancePath(record.storage.instanceDirectory, stagedPaths);
10242
10309
  await grantStore.revokeActionsByPrefix(`${record.id}.`);
10243
10310
  } catch (error) {
10244
10311
  const recoveryErrors = [...await this.restoreStagedPaths(stagedPaths), ...await this.restoreGrants(grantStore, grants)];
@@ -10251,7 +10318,15 @@ var ServiceAppRemovalService = class {
10251
10318
  throw new ServiceAppRemovalCleanupError(error);
10252
10319
  }
10253
10320
  };
10254
- stagePath = async (originalPath, stagedPaths) => {
10321
+ stageSourcePath = async (originalPath, stagedPaths) => {
10322
+ const stagedPath = join(dirname(originalPath), `.deleting-${basename(originalPath)}-${randomUUID()}`);
10323
+ await rename(originalPath, stagedPath);
10324
+ stagedPaths.push({
10325
+ originalPath,
10326
+ stagedPath
10327
+ });
10328
+ };
10329
+ stageInstancePath = async (originalPath, stagedPaths) => {
10255
10330
  const stagedPath = `${originalPath}.deleting-${randomUUID()}`;
10256
10331
  await rename(originalPath, stagedPath);
10257
10332
  stagedPaths.push({
@@ -10259,6 +10334,24 @@ var ServiceAppRemovalService = class {
10259
10334
  stagedPath
10260
10335
  });
10261
10336
  };
10337
+ listDirectories = async (directory) => {
10338
+ try {
10339
+ return (await readdir(directory, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
10340
+ } catch (error) {
10341
+ if (this.isMissingFileError(error)) return [];
10342
+ throw error;
10343
+ }
10344
+ };
10345
+ pathExists = async (targetPath) => {
10346
+ try {
10347
+ await access(targetPath);
10348
+ return true;
10349
+ } catch (error) {
10350
+ if (this.isMissingFileError(error)) return false;
10351
+ throw error;
10352
+ }
10353
+ };
10354
+ isMissingFileError = (error) => typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
10262
10355
  restoreStagedPaths = async (stagedPaths) => {
10263
10356
  const errors = [];
10264
10357
  for (const entry of [...stagedPaths].reverse()) try {
@@ -10278,6 +10371,9 @@ var ServiceAppRemovalService = class {
10278
10371
  return errors;
10279
10372
  };
10280
10373
  };
10374
+ function parseServiceAppDeletionTombstone(directoryName) {
10375
+ return CURRENT_DELETION_PATTERN.exec(directoryName)?.groups?.appId ?? LEGACY_DELETION_PATTERN.exec(directoryName)?.groups?.appId;
10376
+ }
10281
10377
  //#endregion
10282
10378
  //#region src/stores/service-action-grant.store.ts
10283
10379
  const EMPTY_GRANTS = {
@@ -10425,13 +10521,12 @@ var ServiceAppError = class extends Error {
10425
10521
  this.name = "ServiceAppError";
10426
10522
  }
10427
10523
  };
10428
- function isServiceAppError(error) {
10429
- return error instanceof ServiceAppError;
10430
- }
10524
+ const isServiceAppError = (error) => error instanceof ServiceAppError;
10431
10525
  var ServiceAppManager = class {
10432
10526
  removalService = new ServiceAppRemovalService();
10433
10527
  runtimeService;
10434
10528
  recordService;
10529
+ reconciliationDiagnostics = [];
10435
10530
  constructor(params) {
10436
10531
  this.params = params;
10437
10532
  this.runtimeService = params.runtimeService ?? new McpServiceAppRuntimeService({ getConfig: () => params.configManager.config });
@@ -10440,6 +10535,13 @@ var ServiceAppManager = class {
10440
10535
  runtimeService: this.runtimeService
10441
10536
  });
10442
10537
  }
10538
+ start = async () => {
10539
+ this.reconciliationDiagnostics = await this.removalService.reconcile({
10540
+ grantStore: this.createGrantStore(),
10541
+ lockPathForAppId: (appId) => this.getServiceAppLockPath(this.getWorkspacePath(), appId),
10542
+ serviceAppsPath: this.getServiceAppsPath(this.getWorkspacePath())
10543
+ });
10544
+ };
10443
10545
  listServiceApps = async () => {
10444
10546
  const workspacePath = this.getWorkspacePath();
10445
10547
  const serviceAppsPath = this.getServiceAppsPath(workspacePath);
@@ -10450,6 +10552,7 @@ var ServiceAppManager = class {
10450
10552
  return {
10451
10553
  workspacePath,
10452
10554
  serviceAppsPath,
10555
+ diagnostics: this.reconciliationDiagnostics,
10453
10556
  entries: [...workspaceEntries, ...packageEntries].filter((entry) => Boolean(entry)).sort((left, right) => left.title.localeCompare(right.title))
10454
10557
  };
10455
10558
  };
@@ -10462,7 +10565,7 @@ var ServiceAppManager = class {
10462
10565
  return await Promise.all(actions.map(async (action) => await this.withGrantState(action, params)));
10463
10566
  };
10464
10567
  discoverServiceAppActions = async (appId) => {
10465
- const { manifest, record } = await this.requireServiceApp(appId);
10568
+ const { manifest, record } = await this.requireServiceApp(appId, true);
10466
10569
  return mergeServiceAppRuntimeActions({
10467
10570
  record,
10468
10571
  manifest,
@@ -10475,7 +10578,7 @@ var ServiceAppManager = class {
10475
10578
  invokeServiceAction = async (actionId, request) => {
10476
10579
  this.assertCaller(request.caller);
10477
10580
  this.assertDeclaredAction(actionId, request.declaredActions);
10478
- const { manifest, record } = await this.requireServiceAppForAction(actionId);
10581
+ const { manifest, record } = await this.requireServiceAppForAction(actionId, true);
10479
10582
  const actionName = getServiceActionName(actionId, record.id);
10480
10583
  if (!Object.hasOwn(manifest.actions, actionName)) throw new ServiceAppError("SERVICE_APP_ACTION_NOT_FOUND", "service action not found");
10481
10584
  const declaredRisk = manifest.actions[actionName]?.risk ?? "dangerous";
@@ -10535,12 +10638,11 @@ var ServiceAppManager = class {
10535
10638
  try {
10536
10639
  record = await this.removalService.remove({
10537
10640
  grantStore: this.createGrantStore(),
10538
- lockPath: join(workspacePath, ".nextclaw", "locks", "service-apps", `${appId}.lock`),
10641
+ lockPath: this.getServiceAppLockPath(workspacePath, appId),
10539
10642
  purgeData,
10540
10643
  loadRecord: async () => {
10541
10644
  const { record } = await this.requireServiceApp(appId);
10542
10645
  if (record.sourceKind === "package") throw new ServiceAppError("SERVICE_APP_MANAGED_SOURCE", `package service must be managed through Apps: ${record.packageId}`);
10543
- if (purgeData && !record.storage) throw new ServiceAppError("SERVICE_APP_READ_FAILED", `Service App ${appId} 缺少受管数据目录,已停止删除。`);
10544
10646
  return record;
10545
10647
  },
10546
10648
  stopRuntime: async (loaded) => await this.runtimeService.restart(loaded.id)
@@ -10624,12 +10726,12 @@ var ServiceAppManager = class {
10624
10726
  if (!action) throw new ServiceAppError("SERVICE_APP_ACTION_NOT_FOUND", "service action not found");
10625
10727
  return action;
10626
10728
  };
10627
- requireServiceAppForAction = async (actionId) => {
10729
+ requireServiceAppForAction = async (actionId, materializeStorage = false) => {
10628
10730
  const appId = actionId.split(".")[0]?.trim();
10629
10731
  if (!appId) throw new ServiceAppError("SERVICE_APP_INVALID_ACTION", "service action id is invalid");
10630
- return await this.requireServiceApp(appId);
10732
+ return await this.requireServiceApp(appId, materializeStorage);
10631
10733
  };
10632
- requireServiceApp = async (appId) => {
10734
+ requireServiceApp = async (appId, materializeStorage = false) => {
10633
10735
  let dirPath = join(this.getServiceAppsPath(this.getWorkspacePath()), appId);
10634
10736
  let packageSource;
10635
10737
  try {
@@ -10644,9 +10746,10 @@ var ServiceAppManager = class {
10644
10746
  if (!(await stat(dirPath)).isDirectory()) throw new ServiceAppError("SERVICE_APP_NOT_FOUND", "service app not found");
10645
10747
  const manifest = await readServiceAppManifest(dirPath);
10646
10748
  if (manifest.id !== appId) throw new ServiceAppError("SERVICE_APP_INVALID_MANIFEST", "service app manifest id must match directory name");
10749
+ const storage = packageSource?.storage ?? (materializeStorage ? await this.recordService.materializeWorkspaceStorage(manifest.id) : await this.recordService.inspectWorkspaceStorage(manifest.id));
10647
10750
  return {
10648
10751
  manifest,
10649
- record: this.recordService.fromManifest(dirPath, manifest, packageSource, packageSource?.storage ?? await this.recordService.materializeWorkspaceStorage(manifest.id))
10752
+ record: this.recordService.fromManifest(dirPath, manifest, packageSource, storage)
10650
10753
  };
10651
10754
  } catch (error) {
10652
10755
  if (isServiceAppError(error)) throw error;
@@ -10664,7 +10767,7 @@ var ServiceAppManager = class {
10664
10767
  const manifest = await readServiceAppManifest(dirPath);
10665
10768
  return {
10666
10769
  manifest,
10667
- record: this.recordService.fromManifest(dirPath, manifest, void 0, await this.recordService.materializeWorkspaceStorage(manifest.id))
10770
+ record: this.recordService.fromManifest(dirPath, manifest, void 0, await this.recordService.inspectWorkspaceStorage(manifest.id))
10668
10771
  };
10669
10772
  } catch {
10670
10773
  return null;
@@ -10692,13 +10795,13 @@ var ServiceAppManager = class {
10692
10795
  normalizeActionIds = (actionIds) => Array.from(new Set(actionIds.map((actionId) => actionId.trim()).filter((actionId) => actionId.length > 0)));
10693
10796
  getWorkspacePath = () => getWorkspacePathFromConfig(this.params.configManager.config);
10694
10797
  getServiceAppsPath = (workspacePath) => join(workspacePath, DEFAULT_SERVICE_APPS_DIR);
10798
+ getServiceAppLockPath = (workspacePath, appId) => join(workspacePath, ".nextclaw", "locks", "service-apps", `${appId}.lock`);
10695
10799
  createGrantStore = () => new ServiceActionGrantStore(join(this.getServiceAppsPath(this.getWorkspacePath()), SERVICE_ACTION_GRANTS_FILE_NAME));
10696
10800
  listPackageComponentSources = async () => await this.params.listPackageComponentSources?.() ?? [];
10697
10801
  listServiceAppDirNames = async (serviceAppsPath) => {
10698
10802
  try {
10699
- return (await readdir(serviceAppsPath, { withFileTypes: true })).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
10803
+ return await this.removalService.listCanonicalDirectoryNames(serviceAppsPath);
10700
10804
  } catch (error) {
10701
- if (this.isMissingFileError(error)) return [];
10702
10805
  throw new ServiceAppError("SERVICE_APP_READ_FAILED", error instanceof Error ? error.message : String(error));
10703
10806
  }
10704
10807
  };
@@ -15970,6 +16073,9 @@ var NextclawKernel = class {
15970
16073
  };
15971
16074
  getGatewayController = () => this.gatewayController;
15972
16075
  start = async () => {
16076
+ await this.appPackageManager.start();
16077
+ await this.appDataManager.start();
16078
+ await this.serviceAppManager.start();
15973
16079
  this.sessionSearch.start();
15974
16080
  this.mcpManager.start();
15975
16081
  this.providerModelCatalog.start();