@nextclaw/kernel 0.7.0 → 0.8.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.js CHANGED
@@ -10,7 +10,7 @@ import { catchError, filter, from, lastValueFrom, tap } from "rxjs";
10
10
  import { appendFileSync, chmodSync, constants, createReadStream, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
11
11
  import path, { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
12
12
  import { access, appendFile, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
13
- import { AppHomeService, AppInstallationService, AppInstanceStorageService, AppManifestService, AppRegistryService, isAppComponentManifestBundle } from "@nextclaw/app-runtime";
13
+ import { AppHomeService, AppInstallationService, AppInstanceInventoryService, AppInstanceStorageService, AppManifestService, AppRegistryService, FileLockService, isAppComponentManifestBundle } from "@nextclaw/app-runtime";
14
14
  import { execFileSync, spawn } from "node:child_process";
15
15
  import { fileURLToPath } from "node:url";
16
16
  import { BUILTIN_PROVIDER_PLUGINS } from "@nextclaw/runtime";
@@ -2881,6 +2881,10 @@ var AppPackageManager = class {
2881
2881
  const records = await this.registryService.listApps();
2882
2882
  return { entries: await Promise.all(records.map(async (record) => await this.toPackageView(await this.installationService.info(record.appId)))) };
2883
2883
  };
2884
+ listInstalledDataOwners = async () => (await this.registryService.listApps()).map((record) => ({
2885
+ id: record.appId,
2886
+ name: record.name
2887
+ }));
2884
2888
  getPackage = async (appId) => {
2885
2889
  await this.ensureBuiltInPackages();
2886
2890
  try {
@@ -3188,6 +3192,148 @@ var AppPackageManager = class {
3188
3192
  isMissingFileError = (error) => typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
3189
3193
  };
3190
3194
  //#endregion
3195
+ //#region src/types/app-data.types.ts
3196
+ var AppDataError = class extends Error {
3197
+ constructor(code, message) {
3198
+ super(message);
3199
+ this.code = code;
3200
+ this.name = "AppDataError";
3201
+ }
3202
+ };
3203
+ function isAppDataError(error) {
3204
+ return error instanceof AppDataError;
3205
+ }
3206
+ //#endregion
3207
+ //#region src/managers/app-data.manager.ts
3208
+ const DATA_ID_PREFIX = "ad1.";
3209
+ const SAFE_ID_PATTERN = /^[a-z0-9]+(?:[.-][a-z0-9]+)*$/;
3210
+ const WORKSPACE_SCOPE_PATTERN = /^[a-f0-9]{16}$/;
3211
+ var AppDataManager = class {
3212
+ appHomeService;
3213
+ fileLockService = new FileLockService();
3214
+ inventoryService = new AppInstanceInventoryService();
3215
+ constructor(params) {
3216
+ this.params = params;
3217
+ this.appHomeService = new AppHomeService(params.appHomeDirectory);
3218
+ }
3219
+ list = async () => {
3220
+ const workspacePath = path.resolve(this.params.getWorkspacePath());
3221
+ const workspaceInstancesRoot = this.getWorkspaceInstancesRoot(workspacePath);
3222
+ const [packageInventory, workspaceInventory, packageList, workspaceOwners] = await Promise.all([
3223
+ this.inventoryService.list(this.appHomeService.getInstancesDirectory()),
3224
+ this.inventoryService.list(workspaceInstancesRoot),
3225
+ this.params.listInstalledPackageOwners(),
3226
+ this.params.listWorkspaceDataOwners()
3227
+ ]);
3228
+ const packageOwners = new Map(packageList.map((entry) => [entry.id, entry]));
3229
+ const workspaceOwnerMap = new Map(workspaceOwners.map((entry) => [entry.id, entry]));
3230
+ const workspaceScope = this.workspaceScope(workspacePath);
3231
+ 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
+ }))]
3251
+ };
3252
+ };
3253
+ deleteRetained = async (dataId, confirmAppId) => {
3254
+ const payload = this.parseDataId(dataId);
3255
+ if (confirmAppId !== payload.appId) throw new AppDataError("APP_DATA_CONFIRMATION_MISMATCH", `确认的 App id 与目标不一致:${confirmAppId || "(empty)"}`);
3256
+ if (payload.source === "package") await this.deletePackageData(payload);
3257
+ else await this.deleteWorkspaceData(payload);
3258
+ return {
3259
+ deleted: true,
3260
+ id: dataId,
3261
+ appId: payload.appId,
3262
+ instanceId: payload.instanceId
3263
+ };
3264
+ };
3265
+ deletePackageData = async (payload) => {
3266
+ await this.fileLockService.withLock(this.appHomeService.getAppOperationLockPath(payload.appId), async () => {
3267
+ await this.inventoryService.purge({
3268
+ instancesRoot: this.appHomeService.getInstancesDirectory(),
3269
+ appId: payload.appId,
3270
+ instanceId: payload.instanceId,
3271
+ assertCanPurge: async () => {
3272
+ if (await this.isPackageActive(payload.appId)) throw new AppDataError("APP_DATA_ACTIVE", `应用 ${payload.appId} 仍已安装,请通过卸载入口处理其数据。`);
3273
+ }
3274
+ });
3275
+ }).catch((error) => this.rethrowMissing(error, payload));
3276
+ };
3277
+ deleteWorkspaceData = async (payload) => {
3278
+ const workspacePath = path.resolve(this.params.getWorkspacePath());
3279
+ if (payload.scope !== this.workspaceScope(workspacePath)) throw new AppDataError("APP_DATA_INVALID_ID", "App data id 不属于当前 workspace。");
3280
+ const lockPath = path.join(workspacePath, ".nextclaw", "locks", "service-apps", `${payload.appId}.lock`);
3281
+ await this.fileLockService.withLock(lockPath, async () => {
3282
+ await this.inventoryService.purge({
3283
+ instancesRoot: this.getWorkspaceInstancesRoot(workspacePath),
3284
+ appId: payload.appId,
3285
+ instanceId: payload.instanceId,
3286
+ assertCanPurge: async () => {
3287
+ if (await this.isWorkspaceServiceActive(payload.appId)) throw new AppDataError("APP_DATA_ACTIVE", `Service App ${payload.appId} 仍在 workspace 中,请通过 Service Apps 删除入口处理其数据。`);
3288
+ }
3289
+ });
3290
+ }).catch((error) => this.rethrowMissing(error, payload));
3291
+ };
3292
+ toEntry = (params) => {
3293
+ const { active, displayName, entry, scope, source } = params;
3294
+ return {
3295
+ id: this.createDataId({
3296
+ version: 1,
3297
+ source,
3298
+ appId: entry.appId,
3299
+ instanceId: entry.instanceId,
3300
+ scope
3301
+ }),
3302
+ appId: entry.appId,
3303
+ instanceId: entry.instanceId,
3304
+ publisherId: entry.publisherId,
3305
+ displayName,
3306
+ source,
3307
+ lifecycle: active ? "active" : "retained",
3308
+ storage: entry.storage,
3309
+ usage: entry.usage,
3310
+ createdAt: entry.createdAt,
3311
+ migratedAt: entry.migratedAt,
3312
+ actions: { deleteRetainedData: !active }
3313
+ };
3314
+ };
3315
+ createDataId = (payload) => `${DATA_ID_PREFIX}${Buffer.from(JSON.stringify(payload), "utf8").toString("base64url")}`;
3316
+ parseDataId = (dataId) => {
3317
+ try {
3318
+ if (!dataId.startsWith(DATA_ID_PREFIX)) throw new Error("prefix");
3319
+ const raw = JSON.parse(Buffer.from(dataId.slice(4), "base64url").toString("utf8"));
3320
+ if (raw.version !== 1 || raw.source !== "package" && raw.source !== "workspace-service" || typeof raw.appId !== "string" || !SAFE_ID_PATTERN.test(raw.appId) || typeof raw.instanceId !== "string" || !SAFE_ID_PATTERN.test(raw.instanceId) || raw.source === "package" && raw.scope !== void 0 || raw.source === "workspace-service" && (typeof raw.scope !== "string" || !WORKSPACE_SCOPE_PATTERN.test(raw.scope))) throw new Error("shape");
3321
+ return raw;
3322
+ } catch {
3323
+ throw new AppDataError("APP_DATA_INVALID_ID", "App data id 无效。");
3324
+ }
3325
+ };
3326
+ isPackageActive = async (appId) => (await this.params.listInstalledPackageOwners()).some((entry) => entry.id === appId);
3327
+ isWorkspaceServiceActive = async (appId) => (await this.params.listWorkspaceDataOwners()).some((entry) => entry.id === appId);
3328
+ getWorkspaceInstancesRoot = (workspacePath) => path.join(workspacePath, ".nextclaw", "app-instances");
3329
+ workspaceScope = (workspacePath) => createHash("sha256").update(workspacePath).digest("hex").slice(0, 16);
3330
+ rethrowMissing = (error, payload) => {
3331
+ if (error instanceof Error && (error.message.includes("metadata 不存在") || this.isMissingFileError(error))) throw new AppDataError("APP_DATA_NOT_FOUND", `未找到 App 数据:${payload.appId}/${payload.instanceId}`);
3332
+ throw error;
3333
+ };
3334
+ isMissingFileError = (error) => typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
3335
+ };
3336
+ //#endregion
3191
3337
  //#region src/managers/channel.manager.ts
3192
3338
  var ChannelManager = class {
3193
3339
  channels = {};
@@ -9879,7 +10025,7 @@ var McpServiceAppRuntimeService = class {
9879
10025
  };
9880
10026
  //#endregion
9881
10027
  //#region src/utils/service-app-manifest.utils.ts
9882
- const SERVICE_APP_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
10028
+ const SERVICE_APP_ID_PATTERN$1 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
9883
10029
  const SERVICE_ACTION_RISKS = new Set([
9884
10030
  "read",
9885
10031
  "write",
@@ -9902,7 +10048,7 @@ function parseServiceAppManifest(raw) {
9902
10048
  }
9903
10049
  if (!isRecord$9(parsed)) throw new Error("service-app.json must contain an object.");
9904
10050
  const id = readRequiredString$6(parsed, "id");
9905
- if (!SERVICE_APP_ID_PATTERN.test(id)) throw new Error("service app id must be kebab-case.");
10051
+ if (!SERVICE_APP_ID_PATTERN$1.test(id)) throw new Error("service app id must be kebab-case.");
9906
10052
  const protocol = readOptionalString$7(parsed, "protocol") ?? "mcp";
9907
10053
  if (protocol !== "mcp") throw new Error("service app protocol must be mcp.");
9908
10054
  return {
@@ -9984,6 +10130,19 @@ var ServiceAppRecordService = class {
9984
10130
  return this.failedPackageRecord(source, error);
9985
10131
  }
9986
10132
  };
10133
+ listWorkspaceDataOwners = async (serviceAppsPath, dirNames) => {
10134
+ return (await Promise.all(dirNames.map(async (dirName) => {
10135
+ try {
10136
+ const manifest = await readServiceAppManifest(join(serviceAppsPath, dirName));
10137
+ return manifest.id === dirName ? {
10138
+ id: manifest.id,
10139
+ title: manifest.title
10140
+ } : null;
10141
+ } catch {
10142
+ return null;
10143
+ }
10144
+ }))).filter((entry) => Boolean(entry));
10145
+ };
9987
10146
  materializeWorkspaceStorage = async (serviceId) => {
9988
10147
  const instanceDirectory = join(this.params.getWorkspacePath(), ".nextclaw", "app-instances", serviceId, "default");
9989
10148
  return (await this.instanceStorageService.materialize({
@@ -10054,6 +10213,72 @@ var ServiceAppRecordService = class {
10054
10213
  isMissingFileError = (error) => typeof error === "object" && error !== null && error.code === "ENOENT";
10055
10214
  };
10056
10215
  //#endregion
10216
+ //#region src/services/service-app-removal.service.ts
10217
+ var ServiceAppRemovalCleanupError = class extends Error {
10218
+ constructor(cause) {
10219
+ super(`临时目录清理失败:${cause instanceof Error ? cause.message : String(cause)}`);
10220
+ this.cause = cause;
10221
+ this.name = "ServiceAppRemovalCleanupError";
10222
+ }
10223
+ };
10224
+ var ServiceAppRemovalService = class {
10225
+ fileLockService = new FileLockService();
10226
+ remove = async (params) => await this.fileLockService.withLock(params.lockPath, async () => {
10227
+ const record = await params.loadRecord();
10228
+ await this.removeLocked({
10229
+ ...params,
10230
+ record
10231
+ });
10232
+ return record;
10233
+ });
10234
+ removeLocked = async (params) => {
10235
+ const { grantStore, purgeData, record, stopRuntime } = params;
10236
+ const grants = (await grantStore.list()).filter((grant) => grant.actionId.startsWith(`${record.id}.`));
10237
+ const stagedPaths = [];
10238
+ try {
10239
+ await stopRuntime(record);
10240
+ await this.stagePath(record.dirPath, stagedPaths);
10241
+ if (purgeData && record.storage) await this.stagePath(record.storage.instanceDirectory, stagedPaths);
10242
+ await grantStore.revokeActionsByPrefix(`${record.id}.`);
10243
+ } catch (error) {
10244
+ const recoveryErrors = [...await this.restoreStagedPaths(stagedPaths), ...await this.restoreGrants(grantStore, grants)];
10245
+ if (recoveryErrors.length > 0) throw new AggregateError([error, ...recoveryErrors], `Service App ${record.id} 删除失败,且恢复未完整完成。`);
10246
+ throw error;
10247
+ }
10248
+ try {
10249
+ await Promise.all(stagedPaths.map(async ({ stagedPath }) => await rm(stagedPath, { recursive: true })));
10250
+ } catch (error) {
10251
+ throw new ServiceAppRemovalCleanupError(error);
10252
+ }
10253
+ };
10254
+ stagePath = async (originalPath, stagedPaths) => {
10255
+ const stagedPath = `${originalPath}.deleting-${randomUUID()}`;
10256
+ await rename(originalPath, stagedPath);
10257
+ stagedPaths.push({
10258
+ originalPath,
10259
+ stagedPath
10260
+ });
10261
+ };
10262
+ restoreStagedPaths = async (stagedPaths) => {
10263
+ const errors = [];
10264
+ for (const entry of [...stagedPaths].reverse()) try {
10265
+ await rename(entry.stagedPath, entry.originalPath);
10266
+ } catch (error) {
10267
+ errors.push(error);
10268
+ }
10269
+ return errors;
10270
+ };
10271
+ restoreGrants = async (grantStore, grants) => {
10272
+ const errors = [];
10273
+ for (const grant of grants) try {
10274
+ await grantStore.grant(grant);
10275
+ } catch (error) {
10276
+ errors.push(error);
10277
+ }
10278
+ return errors;
10279
+ };
10280
+ };
10281
+ //#endregion
10057
10282
  //#region src/stores/service-action-grant.store.ts
10058
10283
  const EMPTY_GRANTS = {
10059
10284
  version: 1,
@@ -10192,6 +10417,7 @@ function mergeServiceAppRuntimeActions({ record, manifest, runtimeActions }) {
10192
10417
  //#endregion
10193
10418
  //#region src/managers/service-app.manager.ts
10194
10419
  const SERVICE_ACTION_GRANTS_FILE_NAME = ".service-action-grants.json";
10420
+ const SERVICE_APP_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
10195
10421
  var ServiceAppError = class extends Error {
10196
10422
  constructor(code, message) {
10197
10423
  super(message);
@@ -10203,6 +10429,7 @@ function isServiceAppError(error) {
10203
10429
  return error instanceof ServiceAppError;
10204
10430
  }
10205
10431
  var ServiceAppManager = class {
10432
+ removalService = new ServiceAppRemovalService();
10206
10433
  runtimeService;
10207
10434
  recordService;
10208
10435
  constructor(params) {
@@ -10300,20 +10527,35 @@ var ServiceAppManager = class {
10300
10527
  await this.runtimeService.restart(record.id);
10301
10528
  return await this.getServiceApp(appId);
10302
10529
  };
10303
- deleteServiceApp = async (appId) => {
10304
- const { record } = await this.requireServiceApp(appId);
10305
- if (record.sourceKind === "package") throw new ServiceAppError("SERVICE_APP_MANAGED_SOURCE", `package service must be managed through Apps: ${record.packageId}`);
10306
- await this.runtimeService.restart(record.id);
10307
- await rm(record.dirPath, { recursive: true });
10308
- await this.createGrantStore().revokeActionsByPrefix(`${record.id}.`);
10530
+ listWorkspaceDataOwners = async () => await this.recordService.listWorkspaceDataOwners(this.getServiceAppsPath(this.getWorkspacePath()), await this.listServiceAppDirNames(this.getServiceAppsPath(this.getWorkspacePath())));
10531
+ deleteServiceApp = async (appId, purgeData = false) => {
10532
+ if (!SERVICE_APP_ID_PATTERN.test(appId)) throw new ServiceAppError("SERVICE_APP_INVALID_MANIFEST", "service app id must use kebab-case");
10533
+ const workspacePath = this.getWorkspacePath();
10534
+ let record;
10535
+ try {
10536
+ record = await this.removalService.remove({
10537
+ grantStore: this.createGrantStore(),
10538
+ lockPath: join(workspacePath, ".nextclaw", "locks", "service-apps", `${appId}.lock`),
10539
+ purgeData,
10540
+ loadRecord: async () => {
10541
+ const { record } = await this.requireServiceApp(appId);
10542
+ 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
+ return record;
10545
+ },
10546
+ stopRuntime: async (loaded) => await this.runtimeService.restart(loaded.id)
10547
+ });
10548
+ } catch (error) {
10549
+ if (error instanceof ServiceAppRemovalCleanupError) throw new ServiceAppError("SERVICE_APP_RUNTIME_FAILED", `Service App ${appId} 已从 workspace 移除,但${error.message}`);
10550
+ throw error;
10551
+ }
10309
10552
  return {
10310
10553
  deleted: true,
10311
- id: record.id
10554
+ id: record.id,
10555
+ dataRemoved: purgeData
10312
10556
  };
10313
10557
  };
10314
- dispose = async () => {
10315
- await this.runtimeService.dispose();
10316
- };
10558
+ dispose = async () => await this.runtimeService.dispose();
10317
10559
  assertCanActivatePackageComponents = async (components) => {
10318
10560
  const serviceComponents = components.filter((component) => component.kind === "service");
10319
10561
  if (serviceComponents.length === 0) return;
@@ -15515,35 +15757,48 @@ var ToolProviderContribution = class {
15515
15757
  };
15516
15758
  };
15517
15759
  //#endregion
15518
- //#region src/app/nextclaw-kernel.ts
15760
+ //#region src/app/kernel-storage-paths.ts
15519
15761
  function resolveKernelAppHomeDirectory(options) {
15520
15762
  const homeDir = options.homeDir?.trim();
15521
15763
  return resolve(homeDir ? expandHome(homeDir) : getDataDir(), "apps");
15522
15764
  }
15523
15765
  function resolveKernelSessionsDir(options) {
15524
15766
  const homeDir = options.homeDir?.trim();
15525
- if (homeDir) return ensureDir(resolve(expandHome(homeDir), "sessions"));
15526
- return getSessionsPath();
15767
+ return homeDir ? ensureDir(resolve(expandHome(homeDir), "sessions")) : getSessionsPath();
15527
15768
  }
15528
15769
  function resolveKernelAutomationStorePath(options) {
15529
- const homeDir = options.homeDir?.trim();
15530
- if (homeDir) return resolve(expandHome(homeDir), "cron", "jobs.json");
15531
- return resolve(getDataDir(), "cron", "jobs.json");
15770
+ return resolveKernelDataPath(options, "cron", "jobs.json");
15532
15771
  }
15533
15772
  function resolveKernelPreferenceStorePath(options) {
15534
- const homeDir = options.homeDir?.trim();
15535
- if (homeDir) return resolve(expandHome(homeDir), "preferences", "preferences.json");
15536
- return resolve(getDataDir(), "preferences", "preferences.json");
15773
+ return resolveKernelDataPath(options, "preferences", "preferences.json");
15537
15774
  }
15538
15775
  function resolveKernelProjectStorePath(options) {
15539
- const homeDir = options.homeDir?.trim();
15540
- if (homeDir) return resolve(expandHome(homeDir), "projects", "projects.json");
15541
- return resolve(getDataDir(), "projects", "projects.json");
15776
+ return resolveKernelDataPath(options, "projects", "projects.json");
15542
15777
  }
15543
15778
  function resolveKernelInboxDeliveryStorePath(options) {
15779
+ return resolveKernelDataPath(options, "inbox", "deliveries.json");
15780
+ }
15781
+ function resolveKernelDataPath(options, ...segments) {
15544
15782
  const homeDir = options.homeDir?.trim();
15545
- if (homeDir) return resolve(expandHome(homeDir), "inbox", "deliveries.json");
15546
- return resolve(getDataDir(), "inbox", "deliveries.json");
15783
+ return resolve(homeDir ? expandHome(homeDir) : getDataDir(), ...segments);
15784
+ }
15785
+ //#endregion
15786
+ //#region src/app/nextclaw-kernel.ts
15787
+ function createKernelServiceAppManagers(params) {
15788
+ const { appHomeDirectory, appPackageManager, configManager } = params;
15789
+ const serviceAppManager = new ServiceAppManager({
15790
+ configManager,
15791
+ listPackageComponentSources: appPackageManager.listActiveComponentSources
15792
+ });
15793
+ return {
15794
+ serviceAppManager,
15795
+ appDataManager: new AppDataManager({
15796
+ appHomeDirectory,
15797
+ getWorkspacePath: () => getWorkspacePathFromConfig(configManager.config),
15798
+ listInstalledPackageOwners: appPackageManager.listInstalledDataOwners,
15799
+ listWorkspaceDataOwners: serviceAppManager.listWorkspaceDataOwners
15800
+ })
15801
+ };
15547
15802
  }
15548
15803
  var NextclawKernelControlManager = class {
15549
15804
  runtimeControl = null;
@@ -15569,6 +15824,7 @@ var NextclawKernel = class {
15569
15824
  skills;
15570
15825
  automation;
15571
15826
  appPackageManager;
15827
+ appDataManager;
15572
15828
  channels;
15573
15829
  sessionRequests;
15574
15830
  sessionSearch;
@@ -15646,10 +15902,11 @@ var NextclawKernel = class {
15646
15902
  listPackageComponentSources: this.appPackageManager.listActiveComponentSources
15647
15903
  });
15648
15904
  this.preferenceManager = new PreferenceManager({ storePath: resolveKernelPreferenceStorePath(options) });
15649
- this.serviceAppManager = new ServiceAppManager({
15650
- configManager: this.configManager,
15651
- listPackageComponentSources: this.appPackageManager.listActiveComponentSources
15652
- });
15905
+ ({appDataManager: this.appDataManager, serviceAppManager: this.serviceAppManager} = createKernelServiceAppManagers({
15906
+ appHomeDirectory: resolveKernelAppHomeDirectory(options),
15907
+ appPackageManager: this.appPackageManager,
15908
+ configManager: this.configManager
15909
+ }));
15653
15910
  this.installAppPackageRuntimeHooks();
15654
15911
  this.extensions = new ExtensionManager({
15655
15912
  configManager: this.configManager,
@@ -16306,6 +16563,6 @@ function resolveLegacyEventType(message) {
16306
16563
  return `message.${role || "other"}`;
16307
16564
  }
16308
16565
  //#endregion
16309
- export { AUTOMATIC_UPDATE_CHECK_INTERVAL_MS, AccessManager, AgentManager, AgentRunClient, AppPackageError, AppPackageManager, AutomationManager, BuiltinNarpRuntimeProviderService, CONTEXT_COMPACTION_CONTINUATION_TEXT, CONTEXT_COMPACTION_PROJECTION_KIND, CONTEXT_COMPACTION_PROJECTION_METADATA_KEY, CONTEXT_COMPACTION_SYSTEM_PREAMBLE, CONTEXT_COMPACTION_TIMELINE_KIND, ChannelManager, CommandRegistry, ConfigManager, ContextCompactionJournalRecoveryService, ContextCompactionPreflightService, DEFAULT_AGENT_RUNTIME_ENTRY_ID, DEFAULT_SERVICE_ACTION_RISK, ExtensionManager, GatewayInboundProcessor, InboxDeliveryError, InboxDeliveryManager, LlmProviderManager, LlmUsageManager, LlmUsageStore, MAX_INBOX_DELIVERY_CONTENT_LENGTH, McpManager, McpServiceAppRuntimeService, NARP_HTTP_RUNTIME_KIND, NARP_STDIO_RUNTIME_KIND, NEXTCLAW_TIMELINE_KIND_METADATA_KEY, NcpAgentSessionJournalStore, NextclawKernel, PANEL_APP_AGENT_CAPABILITIES, PROJECT_TEMPLATE_IDS, PROVIDER_MODEL_CATALOG_REFRESH_INTERVAL_MS, PanelAppAssetTokenService, PanelAppError, PanelAppManager, PreferenceError, PreferenceManager, ProjectError, ProjectManager, ProviderManagerNcpLLMApi, ProviderModelCatalogManager, SERVICE_APP_MANIFEST_FILE_NAME, ServiceAppError, ServiceAppManager, SessionContextCompactionError, SessionContextCompactionManager, SessionManager, SessionMessageCursorError, SessionRequestManager, SessionSettingsError, SkillManager, SystemObjectReferenceError, SystemObjectReferenceManager, UpdateManifestReader, buildAgentRunSendPayload, buildContextCompactionModelProjection, buildContextCompactionTimelineNcpMessage, buildLlmUsageSummary, buildLocalizedTextMap, buildNextclawNcpRunContext, buildServiceActionId, createAgentRuntimeSessionRequestDispatcher, createAssetTools, createContextCompactionMessageId, createContextWindowSignature, createCronJobSystemObjectProvider, createInboxDeliverySystemObjectProvider, createLlmUsageRecord, describeAgentRuntimeSessionTypes, dispatchAgentRuntimeSessionRequest, dispatchChannelReplyRoute, dispatchPromptOverNcp, getAutomaticUpdateCheckDelay, getServiceActionName, getServiceAppManifestPath, getUiContentParamsBootstrapScript, getUnsignedUpdateManifest, hasLlmUsageTelemetry, injectUiContentParamsBootstrap, isAppPackageError, isContextCompactionProjectionMessage, isContextCompactionTimelineMessage, isContextWindowSnapshot, isInboxDeliveryError, isPanelAppAgentCapability, isPanelAppError, isPreferenceError, isProjectError, isReplyCapableChannel, isServiceAppError, isSessionContextCompactionError, isSessionMessageCursorError, isSessionSettingsError, isSystemObjectReferenceError, listExtensionChannelIds, listServiceAppManifestActions, mergeServiceAppRuntimeActions, normalizeAgentRuntimeSessionTypeIcon, normalizeLlmUsageModel, normalizeOptionalString, parseServiceAppManifest, parseSkillFrontmatter, readContextCompactionCheckpoint, readContextWindowEventSessionId, readLatestContextCompactionCheckpoint, readLearningLoopRuntimeConfig, readMetadataModel, readMetadataThinking, readServiceAppManifest, resolveAgentRuntimeEntries, resolveAutomaticUpdateCheckIntervalMs, resolveChannelReplyRoute, resolveEffectiveModel, resolveLegacyEventType, resolveSessionChannelContext, runGatewayInboundLoop, sanitizeLlmUsage, serializeUnsignedUpdateManifest, shouldRefreshContextWindowDuringStream, shouldRefreshContextWindowImmediately, stripSkillFrontmatter, syncSessionThinkingPreference, toNcpMessages, waitForAgentRuntimeSessionReply };
16566
+ export { AUTOMATIC_UPDATE_CHECK_INTERVAL_MS, AccessManager, AgentManager, AgentRunClient, AppDataError, AppDataManager, AppPackageError, AppPackageManager, AutomationManager, BuiltinNarpRuntimeProviderService, CONTEXT_COMPACTION_CONTINUATION_TEXT, CONTEXT_COMPACTION_PROJECTION_KIND, CONTEXT_COMPACTION_PROJECTION_METADATA_KEY, CONTEXT_COMPACTION_SYSTEM_PREAMBLE, CONTEXT_COMPACTION_TIMELINE_KIND, ChannelManager, CommandRegistry, ConfigManager, ContextCompactionJournalRecoveryService, ContextCompactionPreflightService, DEFAULT_AGENT_RUNTIME_ENTRY_ID, DEFAULT_SERVICE_ACTION_RISK, ExtensionManager, GatewayInboundProcessor, InboxDeliveryError, InboxDeliveryManager, LlmProviderManager, LlmUsageManager, LlmUsageStore, MAX_INBOX_DELIVERY_CONTENT_LENGTH, McpManager, McpServiceAppRuntimeService, NARP_HTTP_RUNTIME_KIND, NARP_STDIO_RUNTIME_KIND, NEXTCLAW_TIMELINE_KIND_METADATA_KEY, NcpAgentSessionJournalStore, NextclawKernel, PANEL_APP_AGENT_CAPABILITIES, PROJECT_TEMPLATE_IDS, PROVIDER_MODEL_CATALOG_REFRESH_INTERVAL_MS, PanelAppAssetTokenService, PanelAppError, PanelAppManager, PreferenceError, PreferenceManager, ProjectError, ProjectManager, ProviderManagerNcpLLMApi, ProviderModelCatalogManager, SERVICE_APP_MANIFEST_FILE_NAME, ServiceAppError, ServiceAppManager, SessionContextCompactionError, SessionContextCompactionManager, SessionManager, SessionMessageCursorError, SessionRequestManager, SessionSettingsError, SkillManager, SystemObjectReferenceError, SystemObjectReferenceManager, UpdateManifestReader, buildAgentRunSendPayload, buildContextCompactionModelProjection, buildContextCompactionTimelineNcpMessage, buildLlmUsageSummary, buildLocalizedTextMap, buildNextclawNcpRunContext, buildServiceActionId, createAgentRuntimeSessionRequestDispatcher, createAssetTools, createContextCompactionMessageId, createContextWindowSignature, createCronJobSystemObjectProvider, createInboxDeliverySystemObjectProvider, createLlmUsageRecord, describeAgentRuntimeSessionTypes, dispatchAgentRuntimeSessionRequest, dispatchChannelReplyRoute, dispatchPromptOverNcp, getAutomaticUpdateCheckDelay, getServiceActionName, getServiceAppManifestPath, getUiContentParamsBootstrapScript, getUnsignedUpdateManifest, hasLlmUsageTelemetry, injectUiContentParamsBootstrap, isAppDataError, isAppPackageError, isContextCompactionProjectionMessage, isContextCompactionTimelineMessage, isContextWindowSnapshot, isInboxDeliveryError, isPanelAppAgentCapability, isPanelAppError, isPreferenceError, isProjectError, isReplyCapableChannel, isServiceAppError, isSessionContextCompactionError, isSessionMessageCursorError, isSessionSettingsError, isSystemObjectReferenceError, listExtensionChannelIds, listServiceAppManifestActions, mergeServiceAppRuntimeActions, normalizeAgentRuntimeSessionTypeIcon, normalizeLlmUsageModel, normalizeOptionalString, parseServiceAppManifest, parseSkillFrontmatter, readContextCompactionCheckpoint, readContextWindowEventSessionId, readLatestContextCompactionCheckpoint, readLearningLoopRuntimeConfig, readMetadataModel, readMetadataThinking, readServiceAppManifest, resolveAgentRuntimeEntries, resolveAutomaticUpdateCheckIntervalMs, resolveChannelReplyRoute, resolveEffectiveModel, resolveLegacyEventType, resolveSessionChannelContext, runGatewayInboundLoop, sanitizeLlmUsage, serializeUnsignedUpdateManifest, shouldRefreshContextWindowDuringStream, shouldRefreshContextWindowImmediately, stripSkillFrontmatter, syncSessionThinkingPreference, toNcpMessages, waitForAgentRuntimeSessionReply };
16310
16567
 
16311
16568
  //# sourceMappingURL=index.js.map