@nextclaw/kernel 0.7.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.d.ts +111 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +414 -51
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
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";
|
|
@@ -2876,13 +2876,16 @@ var AppPackageManager = class {
|
|
|
2876
2876
|
installRuntimeHooks = (hooks) => {
|
|
2877
2877
|
this.runtimeHooks = hooks;
|
|
2878
2878
|
};
|
|
2879
|
-
|
|
2880
|
-
|
|
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
|
+
listInstalledDataOwners = async () => (await this.registryService.listApps()).map((record) => ({
|
|
2885
|
+
id: record.appId,
|
|
2886
|
+
name: record.name
|
|
2887
|
+
}));
|
|
2884
2888
|
getPackage = async (appId) => {
|
|
2885
|
-
await this.ensureBuiltInPackages();
|
|
2886
2889
|
try {
|
|
2887
2890
|
return await this.toPackageView(await this.installationService.info(appId));
|
|
2888
2891
|
} catch (error) {
|
|
@@ -2891,7 +2894,6 @@ var AppPackageManager = class {
|
|
|
2891
2894
|
}
|
|
2892
2895
|
};
|
|
2893
2896
|
listActiveComponentSources = async () => {
|
|
2894
|
-
await this.ensureBuiltInPackages();
|
|
2895
2897
|
const records = await this.registryService.listApps();
|
|
2896
2898
|
return (await Promise.all(records.filter((record) => record.enabled).map(async (record) => {
|
|
2897
2899
|
await this.installationService.assertVersionIntegrity(record.appId, record.activeVersion);
|
|
@@ -3188,6 +3190,165 @@ var AppPackageManager = class {
|
|
|
3188
3190
|
isMissingFileError = (error) => typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
3189
3191
|
};
|
|
3190
3192
|
//#endregion
|
|
3193
|
+
//#region src/types/app-data.types.ts
|
|
3194
|
+
var AppDataError = class extends Error {
|
|
3195
|
+
constructor(code, message) {
|
|
3196
|
+
super(message);
|
|
3197
|
+
this.code = code;
|
|
3198
|
+
this.name = "AppDataError";
|
|
3199
|
+
}
|
|
3200
|
+
};
|
|
3201
|
+
function isAppDataError(error) {
|
|
3202
|
+
return error instanceof AppDataError;
|
|
3203
|
+
}
|
|
3204
|
+
//#endregion
|
|
3205
|
+
//#region src/managers/app-data.manager.ts
|
|
3206
|
+
const DATA_ID_PREFIX = "ad1.";
|
|
3207
|
+
const SAFE_ID_PATTERN = /^[a-z0-9]+(?:[.-][a-z0-9]+)*$/;
|
|
3208
|
+
const WORKSPACE_SCOPE_PATTERN = /^[a-f0-9]{16}$/;
|
|
3209
|
+
var AppDataManager = class {
|
|
3210
|
+
appHomeService;
|
|
3211
|
+
fileLockService = new FileLockService();
|
|
3212
|
+
inventoryService = new AppInstanceInventoryService();
|
|
3213
|
+
reconciliationDiagnostics = [];
|
|
3214
|
+
constructor(params) {
|
|
3215
|
+
this.params = params;
|
|
3216
|
+
this.appHomeService = new AppHomeService(params.appHomeDirectory);
|
|
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
|
+
};
|
|
3229
|
+
list = async () => {
|
|
3230
|
+
const workspacePath = path.resolve(this.params.getWorkspacePath());
|
|
3231
|
+
const workspaceInstancesRoot = this.getWorkspaceInstancesRoot(workspacePath);
|
|
3232
|
+
const [packageInventory, workspaceInventory, packageList, workspaceOwners] = await Promise.all([
|
|
3233
|
+
this.inventoryService.list(this.appHomeService.getInstancesDirectory()),
|
|
3234
|
+
this.inventoryService.list(workspaceInstancesRoot),
|
|
3235
|
+
this.params.listInstalledPackageOwners(),
|
|
3236
|
+
this.params.listWorkspaceDataOwners()
|
|
3237
|
+
]);
|
|
3238
|
+
const packageOwners = new Map(packageList.map((entry) => [entry.id, entry]));
|
|
3239
|
+
const workspaceOwnerMap = new Map(workspaceOwners.map((entry) => [entry.id, entry]));
|
|
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);
|
|
3263
|
+
return {
|
|
3264
|
+
entries,
|
|
3265
|
+
diagnostics: Array.from(diagnostics.values())
|
|
3266
|
+
};
|
|
3267
|
+
};
|
|
3268
|
+
deleteRetained = async (dataId, confirmAppId) => {
|
|
3269
|
+
const payload = this.parseDataId(dataId);
|
|
3270
|
+
if (confirmAppId !== payload.appId) throw new AppDataError("APP_DATA_CONFIRMATION_MISMATCH", `确认的 App id 与目标不一致:${confirmAppId || "(empty)"}`);
|
|
3271
|
+
if (payload.source === "package") await this.deletePackageData(payload);
|
|
3272
|
+
else await this.deleteWorkspaceData(payload);
|
|
3273
|
+
return {
|
|
3274
|
+
deleted: true,
|
|
3275
|
+
id: dataId,
|
|
3276
|
+
appId: payload.appId,
|
|
3277
|
+
instanceId: payload.instanceId
|
|
3278
|
+
};
|
|
3279
|
+
};
|
|
3280
|
+
deletePackageData = async (payload) => {
|
|
3281
|
+
await this.fileLockService.withLock(this.appHomeService.getAppOperationLockPath(payload.appId), async () => {
|
|
3282
|
+
await this.inventoryService.purge({
|
|
3283
|
+
instancesRoot: this.appHomeService.getInstancesDirectory(),
|
|
3284
|
+
appId: payload.appId,
|
|
3285
|
+
instanceId: payload.instanceId,
|
|
3286
|
+
assertCanPurge: async () => {
|
|
3287
|
+
if (await this.isPackageActive(payload.appId)) throw new AppDataError("APP_DATA_ACTIVE", `应用 ${payload.appId} 仍已安装,请通过卸载入口处理其数据。`);
|
|
3288
|
+
}
|
|
3289
|
+
});
|
|
3290
|
+
}).catch((error) => this.rethrowMissing(error, payload));
|
|
3291
|
+
};
|
|
3292
|
+
deleteWorkspaceData = async (payload) => {
|
|
3293
|
+
const workspacePath = path.resolve(this.params.getWorkspacePath());
|
|
3294
|
+
if (payload.scope !== this.workspaceScope(workspacePath)) throw new AppDataError("APP_DATA_INVALID_ID", "App data id 不属于当前 workspace。");
|
|
3295
|
+
const lockPath = path.join(workspacePath, ".nextclaw", "locks", "service-apps", `${payload.appId}.lock`);
|
|
3296
|
+
await this.fileLockService.withLock(lockPath, async () => {
|
|
3297
|
+
await this.inventoryService.purge({
|
|
3298
|
+
instancesRoot: this.getWorkspaceInstancesRoot(workspacePath),
|
|
3299
|
+
appId: payload.appId,
|
|
3300
|
+
instanceId: payload.instanceId,
|
|
3301
|
+
assertCanPurge: async () => {
|
|
3302
|
+
if (await this.isWorkspaceServiceActive(payload.appId)) throw new AppDataError("APP_DATA_ACTIVE", `Service App ${payload.appId} 仍在 workspace 中,请通过 Service Apps 删除入口处理其数据。`);
|
|
3303
|
+
}
|
|
3304
|
+
});
|
|
3305
|
+
}).catch((error) => this.rethrowMissing(error, payload));
|
|
3306
|
+
};
|
|
3307
|
+
toEntry = (params) => {
|
|
3308
|
+
const { active, displayName, entry, scope, source } = params;
|
|
3309
|
+
return {
|
|
3310
|
+
id: this.createDataId({
|
|
3311
|
+
version: 1,
|
|
3312
|
+
source,
|
|
3313
|
+
appId: entry.appId,
|
|
3314
|
+
instanceId: entry.instanceId,
|
|
3315
|
+
scope
|
|
3316
|
+
}),
|
|
3317
|
+
appId: entry.appId,
|
|
3318
|
+
instanceId: entry.instanceId,
|
|
3319
|
+
publisherId: entry.publisherId,
|
|
3320
|
+
displayName,
|
|
3321
|
+
source,
|
|
3322
|
+
lifecycle: active ? "active" : "retained",
|
|
3323
|
+
storage: entry.storage,
|
|
3324
|
+
usage: entry.usage,
|
|
3325
|
+
createdAt: entry.createdAt,
|
|
3326
|
+
migratedAt: entry.migratedAt,
|
|
3327
|
+
actions: { deleteRetainedData: !active }
|
|
3328
|
+
};
|
|
3329
|
+
};
|
|
3330
|
+
createDataId = (payload) => `${DATA_ID_PREFIX}${Buffer.from(JSON.stringify(payload), "utf8").toString("base64url")}`;
|
|
3331
|
+
parseDataId = (dataId) => {
|
|
3332
|
+
try {
|
|
3333
|
+
if (!dataId.startsWith(DATA_ID_PREFIX)) throw new Error("prefix");
|
|
3334
|
+
const raw = JSON.parse(Buffer.from(dataId.slice(4), "base64url").toString("utf8"));
|
|
3335
|
+
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");
|
|
3336
|
+
return raw;
|
|
3337
|
+
} catch {
|
|
3338
|
+
throw new AppDataError("APP_DATA_INVALID_ID", "App data id 无效。");
|
|
3339
|
+
}
|
|
3340
|
+
};
|
|
3341
|
+
isPackageActive = async (appId) => (await this.params.listInstalledPackageOwners()).some((entry) => entry.id === appId);
|
|
3342
|
+
isWorkspaceServiceActive = async (appId) => (await this.params.listWorkspaceDataOwners()).some((entry) => entry.id === appId);
|
|
3343
|
+
getWorkspaceInstancesRoot = (workspacePath) => path.join(workspacePath, ".nextclaw", "app-instances");
|
|
3344
|
+
workspaceScope = (workspacePath) => createHash("sha256").update(workspacePath).digest("hex").slice(0, 16);
|
|
3345
|
+
rethrowMissing = (error, payload) => {
|
|
3346
|
+
if (error instanceof Error && (error.message.includes("metadata 不存在") || this.isMissingFileError(error))) throw new AppDataError("APP_DATA_NOT_FOUND", `未找到 App 数据:${payload.appId}/${payload.instanceId}`);
|
|
3347
|
+
throw error;
|
|
3348
|
+
};
|
|
3349
|
+
isMissingFileError = (error) => typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
3350
|
+
};
|
|
3351
|
+
//#endregion
|
|
3191
3352
|
//#region src/managers/channel.manager.ts
|
|
3192
3353
|
var ChannelManager = class {
|
|
3193
3354
|
channels = {};
|
|
@@ -9879,7 +10040,7 @@ var McpServiceAppRuntimeService = class {
|
|
|
9879
10040
|
};
|
|
9880
10041
|
//#endregion
|
|
9881
10042
|
//#region src/utils/service-app-manifest.utils.ts
|
|
9882
|
-
const SERVICE_APP_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
10043
|
+
const SERVICE_APP_ID_PATTERN$1 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
9883
10044
|
const SERVICE_ACTION_RISKS = new Set([
|
|
9884
10045
|
"read",
|
|
9885
10046
|
"write",
|
|
@@ -9902,7 +10063,7 @@ function parseServiceAppManifest(raw) {
|
|
|
9902
10063
|
}
|
|
9903
10064
|
if (!isRecord$9(parsed)) throw new Error("service-app.json must contain an object.");
|
|
9904
10065
|
const id = readRequiredString$6(parsed, "id");
|
|
9905
|
-
if (!SERVICE_APP_ID_PATTERN.test(id)) throw new Error("service app id must be kebab-case.");
|
|
10066
|
+
if (!SERVICE_APP_ID_PATTERN$1.test(id)) throw new Error("service app id must be kebab-case.");
|
|
9906
10067
|
const protocol = readOptionalString$7(parsed, "protocol") ?? "mcp";
|
|
9907
10068
|
if (protocol !== "mcp") throw new Error("service app protocol must be mcp.");
|
|
9908
10069
|
return {
|
|
@@ -9969,7 +10130,8 @@ var ServiceAppRecordService = class {
|
|
|
9969
10130
|
const dirPath = join(serviceAppsPath, dirName);
|
|
9970
10131
|
try {
|
|
9971
10132
|
const manifest = await readServiceAppManifest(dirPath);
|
|
9972
|
-
|
|
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));
|
|
9973
10135
|
} catch (error) {
|
|
9974
10136
|
if (this.isMissingFileError(error)) return null;
|
|
9975
10137
|
return this.failedWorkspaceRecord(dirName, dirPath, error);
|
|
@@ -9984,14 +10146,36 @@ var ServiceAppRecordService = class {
|
|
|
9984
10146
|
return this.failedPackageRecord(source, error);
|
|
9985
10147
|
}
|
|
9986
10148
|
};
|
|
10149
|
+
listWorkspaceDataOwners = async (serviceAppsPath, dirNames) => {
|
|
10150
|
+
return (await Promise.all(dirNames.map(async (dirName) => {
|
|
10151
|
+
try {
|
|
10152
|
+
const manifest = await readServiceAppManifest(join(serviceAppsPath, dirName));
|
|
10153
|
+
return manifest.id === dirName ? {
|
|
10154
|
+
id: manifest.id,
|
|
10155
|
+
title: manifest.title
|
|
10156
|
+
} : null;
|
|
10157
|
+
} catch {
|
|
10158
|
+
return null;
|
|
10159
|
+
}
|
|
10160
|
+
}))).filter((entry) => Boolean(entry));
|
|
10161
|
+
};
|
|
9987
10162
|
materializeWorkspaceStorage = async (serviceId) => {
|
|
9988
|
-
const instanceDirectory =
|
|
10163
|
+
const instanceDirectory = this.getWorkspaceInstanceDirectory(serviceId);
|
|
9989
10164
|
return (await this.instanceStorageService.materialize({
|
|
9990
10165
|
appId: serviceId,
|
|
9991
10166
|
instanceId: "default",
|
|
9992
10167
|
instanceDirectory
|
|
9993
10168
|
})).storage;
|
|
9994
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
|
+
};
|
|
9995
10179
|
fromManifest = (dirPath, manifest, packageSource, storage) => {
|
|
9996
10180
|
const runtimeStatus = this.params.runtimeService.getStatus(manifest.id);
|
|
9997
10181
|
return {
|
|
@@ -10051,9 +10235,146 @@ var ServiceAppRecordService = class {
|
|
|
10051
10235
|
isolation: source.isolation
|
|
10052
10236
|
});
|
|
10053
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
|
+
};
|
|
10054
10248
|
isMissingFileError = (error) => typeof error === "object" && error !== null && error.code === "ENOENT";
|
|
10055
10249
|
};
|
|
10056
10250
|
//#endregion
|
|
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
|
+
}
|
|
10258
|
+
var ServiceAppRemovalCleanupError = class extends Error {
|
|
10259
|
+
constructor(cause) {
|
|
10260
|
+
super(`临时目录清理失败:${cause instanceof Error ? cause.message : String(cause)}`);
|
|
10261
|
+
this.cause = cause;
|
|
10262
|
+
this.name = "ServiceAppRemovalCleanupError";
|
|
10263
|
+
}
|
|
10264
|
+
};
|
|
10265
|
+
var ServiceAppRemovalService = class {
|
|
10266
|
+
fileLockService = new FileLockService();
|
|
10267
|
+
listCanonicalDirectoryNames = async (serviceAppsPath) => (await this.listDirectories(serviceAppsPath)).filter((directoryName) => !directoryName.startsWith(".") && !isServiceAppDeletionTombstone(directoryName));
|
|
10268
|
+
remove = async (params) => await this.fileLockService.withLock(params.lockPath, async () => {
|
|
10269
|
+
const record = await params.loadRecord();
|
|
10270
|
+
await this.removeLocked({
|
|
10271
|
+
...params,
|
|
10272
|
+
record
|
|
10273
|
+
});
|
|
10274
|
+
return record;
|
|
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
|
+
};
|
|
10301
|
+
removeLocked = async (params) => {
|
|
10302
|
+
const { grantStore, purgeData, record, stopRuntime } = params;
|
|
10303
|
+
const grants = (await grantStore.list()).filter((grant) => grant.actionId.startsWith(`${record.id}.`));
|
|
10304
|
+
const stagedPaths = [];
|
|
10305
|
+
try {
|
|
10306
|
+
await stopRuntime(record);
|
|
10307
|
+
await this.stageSourcePath(record.dirPath, stagedPaths);
|
|
10308
|
+
if (purgeData && record.storage) await this.stageInstancePath(record.storage.instanceDirectory, stagedPaths);
|
|
10309
|
+
await grantStore.revokeActionsByPrefix(`${record.id}.`);
|
|
10310
|
+
} catch (error) {
|
|
10311
|
+
const recoveryErrors = [...await this.restoreStagedPaths(stagedPaths), ...await this.restoreGrants(grantStore, grants)];
|
|
10312
|
+
if (recoveryErrors.length > 0) throw new AggregateError([error, ...recoveryErrors], `Service App ${record.id} 删除失败,且恢复未完整完成。`);
|
|
10313
|
+
throw error;
|
|
10314
|
+
}
|
|
10315
|
+
try {
|
|
10316
|
+
await Promise.all(stagedPaths.map(async ({ stagedPath }) => await rm(stagedPath, { recursive: true })));
|
|
10317
|
+
} catch (error) {
|
|
10318
|
+
throw new ServiceAppRemovalCleanupError(error);
|
|
10319
|
+
}
|
|
10320
|
+
};
|
|
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) => {
|
|
10330
|
+
const stagedPath = `${originalPath}.deleting-${randomUUID()}`;
|
|
10331
|
+
await rename(originalPath, stagedPath);
|
|
10332
|
+
stagedPaths.push({
|
|
10333
|
+
originalPath,
|
|
10334
|
+
stagedPath
|
|
10335
|
+
});
|
|
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";
|
|
10355
|
+
restoreStagedPaths = async (stagedPaths) => {
|
|
10356
|
+
const errors = [];
|
|
10357
|
+
for (const entry of [...stagedPaths].reverse()) try {
|
|
10358
|
+
await rename(entry.stagedPath, entry.originalPath);
|
|
10359
|
+
} catch (error) {
|
|
10360
|
+
errors.push(error);
|
|
10361
|
+
}
|
|
10362
|
+
return errors;
|
|
10363
|
+
};
|
|
10364
|
+
restoreGrants = async (grantStore, grants) => {
|
|
10365
|
+
const errors = [];
|
|
10366
|
+
for (const grant of grants) try {
|
|
10367
|
+
await grantStore.grant(grant);
|
|
10368
|
+
} catch (error) {
|
|
10369
|
+
errors.push(error);
|
|
10370
|
+
}
|
|
10371
|
+
return errors;
|
|
10372
|
+
};
|
|
10373
|
+
};
|
|
10374
|
+
function parseServiceAppDeletionTombstone(directoryName) {
|
|
10375
|
+
return CURRENT_DELETION_PATTERN.exec(directoryName)?.groups?.appId ?? LEGACY_DELETION_PATTERN.exec(directoryName)?.groups?.appId;
|
|
10376
|
+
}
|
|
10377
|
+
//#endregion
|
|
10057
10378
|
//#region src/stores/service-action-grant.store.ts
|
|
10058
10379
|
const EMPTY_GRANTS = {
|
|
10059
10380
|
version: 1,
|
|
@@ -10192,6 +10513,7 @@ function mergeServiceAppRuntimeActions({ record, manifest, runtimeActions }) {
|
|
|
10192
10513
|
//#endregion
|
|
10193
10514
|
//#region src/managers/service-app.manager.ts
|
|
10194
10515
|
const SERVICE_ACTION_GRANTS_FILE_NAME = ".service-action-grants.json";
|
|
10516
|
+
const SERVICE_APP_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
10195
10517
|
var ServiceAppError = class extends Error {
|
|
10196
10518
|
constructor(code, message) {
|
|
10197
10519
|
super(message);
|
|
@@ -10199,12 +10521,12 @@ var ServiceAppError = class extends Error {
|
|
|
10199
10521
|
this.name = "ServiceAppError";
|
|
10200
10522
|
}
|
|
10201
10523
|
};
|
|
10202
|
-
|
|
10203
|
-
return error instanceof ServiceAppError;
|
|
10204
|
-
}
|
|
10524
|
+
const isServiceAppError = (error) => error instanceof ServiceAppError;
|
|
10205
10525
|
var ServiceAppManager = class {
|
|
10526
|
+
removalService = new ServiceAppRemovalService();
|
|
10206
10527
|
runtimeService;
|
|
10207
10528
|
recordService;
|
|
10529
|
+
reconciliationDiagnostics = [];
|
|
10208
10530
|
constructor(params) {
|
|
10209
10531
|
this.params = params;
|
|
10210
10532
|
this.runtimeService = params.runtimeService ?? new McpServiceAppRuntimeService({ getConfig: () => params.configManager.config });
|
|
@@ -10213,6 +10535,13 @@ var ServiceAppManager = class {
|
|
|
10213
10535
|
runtimeService: this.runtimeService
|
|
10214
10536
|
});
|
|
10215
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
|
+
};
|
|
10216
10545
|
listServiceApps = async () => {
|
|
10217
10546
|
const workspacePath = this.getWorkspacePath();
|
|
10218
10547
|
const serviceAppsPath = this.getServiceAppsPath(workspacePath);
|
|
@@ -10223,6 +10552,7 @@ var ServiceAppManager = class {
|
|
|
10223
10552
|
return {
|
|
10224
10553
|
workspacePath,
|
|
10225
10554
|
serviceAppsPath,
|
|
10555
|
+
diagnostics: this.reconciliationDiagnostics,
|
|
10226
10556
|
entries: [...workspaceEntries, ...packageEntries].filter((entry) => Boolean(entry)).sort((left, right) => left.title.localeCompare(right.title))
|
|
10227
10557
|
};
|
|
10228
10558
|
};
|
|
@@ -10235,7 +10565,7 @@ var ServiceAppManager = class {
|
|
|
10235
10565
|
return await Promise.all(actions.map(async (action) => await this.withGrantState(action, params)));
|
|
10236
10566
|
};
|
|
10237
10567
|
discoverServiceAppActions = async (appId) => {
|
|
10238
|
-
const { manifest, record } = await this.requireServiceApp(appId);
|
|
10568
|
+
const { manifest, record } = await this.requireServiceApp(appId, true);
|
|
10239
10569
|
return mergeServiceAppRuntimeActions({
|
|
10240
10570
|
record,
|
|
10241
10571
|
manifest,
|
|
@@ -10248,7 +10578,7 @@ var ServiceAppManager = class {
|
|
|
10248
10578
|
invokeServiceAction = async (actionId, request) => {
|
|
10249
10579
|
this.assertCaller(request.caller);
|
|
10250
10580
|
this.assertDeclaredAction(actionId, request.declaredActions);
|
|
10251
|
-
const { manifest, record } = await this.requireServiceAppForAction(actionId);
|
|
10581
|
+
const { manifest, record } = await this.requireServiceAppForAction(actionId, true);
|
|
10252
10582
|
const actionName = getServiceActionName(actionId, record.id);
|
|
10253
10583
|
if (!Object.hasOwn(manifest.actions, actionName)) throw new ServiceAppError("SERVICE_APP_ACTION_NOT_FOUND", "service action not found");
|
|
10254
10584
|
const declaredRisk = manifest.actions[actionName]?.risk ?? "dangerous";
|
|
@@ -10300,20 +10630,34 @@ var ServiceAppManager = class {
|
|
|
10300
10630
|
await this.runtimeService.restart(record.id);
|
|
10301
10631
|
return await this.getServiceApp(appId);
|
|
10302
10632
|
};
|
|
10303
|
-
|
|
10304
|
-
|
|
10305
|
-
if (
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
|
|
10633
|
+
listWorkspaceDataOwners = async () => await this.recordService.listWorkspaceDataOwners(this.getServiceAppsPath(this.getWorkspacePath()), await this.listServiceAppDirNames(this.getServiceAppsPath(this.getWorkspacePath())));
|
|
10634
|
+
deleteServiceApp = async (appId, purgeData = false) => {
|
|
10635
|
+
if (!SERVICE_APP_ID_PATTERN.test(appId)) throw new ServiceAppError("SERVICE_APP_INVALID_MANIFEST", "service app id must use kebab-case");
|
|
10636
|
+
const workspacePath = this.getWorkspacePath();
|
|
10637
|
+
let record;
|
|
10638
|
+
try {
|
|
10639
|
+
record = await this.removalService.remove({
|
|
10640
|
+
grantStore: this.createGrantStore(),
|
|
10641
|
+
lockPath: this.getServiceAppLockPath(workspacePath, appId),
|
|
10642
|
+
purgeData,
|
|
10643
|
+
loadRecord: async () => {
|
|
10644
|
+
const { record } = await this.requireServiceApp(appId);
|
|
10645
|
+
if (record.sourceKind === "package") throw new ServiceAppError("SERVICE_APP_MANAGED_SOURCE", `package service must be managed through Apps: ${record.packageId}`);
|
|
10646
|
+
return record;
|
|
10647
|
+
},
|
|
10648
|
+
stopRuntime: async (loaded) => await this.runtimeService.restart(loaded.id)
|
|
10649
|
+
});
|
|
10650
|
+
} catch (error) {
|
|
10651
|
+
if (error instanceof ServiceAppRemovalCleanupError) throw new ServiceAppError("SERVICE_APP_RUNTIME_FAILED", `Service App ${appId} 已从 workspace 移除,但${error.message}`);
|
|
10652
|
+
throw error;
|
|
10653
|
+
}
|
|
10309
10654
|
return {
|
|
10310
10655
|
deleted: true,
|
|
10311
|
-
id: record.id
|
|
10656
|
+
id: record.id,
|
|
10657
|
+
dataRemoved: purgeData
|
|
10312
10658
|
};
|
|
10313
10659
|
};
|
|
10314
|
-
dispose = async () =>
|
|
10315
|
-
await this.runtimeService.dispose();
|
|
10316
|
-
};
|
|
10660
|
+
dispose = async () => await this.runtimeService.dispose();
|
|
10317
10661
|
assertCanActivatePackageComponents = async (components) => {
|
|
10318
10662
|
const serviceComponents = components.filter((component) => component.kind === "service");
|
|
10319
10663
|
if (serviceComponents.length === 0) return;
|
|
@@ -10382,12 +10726,12 @@ var ServiceAppManager = class {
|
|
|
10382
10726
|
if (!action) throw new ServiceAppError("SERVICE_APP_ACTION_NOT_FOUND", "service action not found");
|
|
10383
10727
|
return action;
|
|
10384
10728
|
};
|
|
10385
|
-
requireServiceAppForAction = async (actionId) => {
|
|
10729
|
+
requireServiceAppForAction = async (actionId, materializeStorage = false) => {
|
|
10386
10730
|
const appId = actionId.split(".")[0]?.trim();
|
|
10387
10731
|
if (!appId) throw new ServiceAppError("SERVICE_APP_INVALID_ACTION", "service action id is invalid");
|
|
10388
|
-
return await this.requireServiceApp(appId);
|
|
10732
|
+
return await this.requireServiceApp(appId, materializeStorage);
|
|
10389
10733
|
};
|
|
10390
|
-
requireServiceApp = async (appId) => {
|
|
10734
|
+
requireServiceApp = async (appId, materializeStorage = false) => {
|
|
10391
10735
|
let dirPath = join(this.getServiceAppsPath(this.getWorkspacePath()), appId);
|
|
10392
10736
|
let packageSource;
|
|
10393
10737
|
try {
|
|
@@ -10402,9 +10746,10 @@ var ServiceAppManager = class {
|
|
|
10402
10746
|
if (!(await stat(dirPath)).isDirectory()) throw new ServiceAppError("SERVICE_APP_NOT_FOUND", "service app not found");
|
|
10403
10747
|
const manifest = await readServiceAppManifest(dirPath);
|
|
10404
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));
|
|
10405
10750
|
return {
|
|
10406
10751
|
manifest,
|
|
10407
|
-
record: this.recordService.fromManifest(dirPath, manifest, packageSource,
|
|
10752
|
+
record: this.recordService.fromManifest(dirPath, manifest, packageSource, storage)
|
|
10408
10753
|
};
|
|
10409
10754
|
} catch (error) {
|
|
10410
10755
|
if (isServiceAppError(error)) throw error;
|
|
@@ -10422,7 +10767,7 @@ var ServiceAppManager = class {
|
|
|
10422
10767
|
const manifest = await readServiceAppManifest(dirPath);
|
|
10423
10768
|
return {
|
|
10424
10769
|
manifest,
|
|
10425
|
-
record: this.recordService.fromManifest(dirPath, manifest, void 0, await this.recordService.
|
|
10770
|
+
record: this.recordService.fromManifest(dirPath, manifest, void 0, await this.recordService.inspectWorkspaceStorage(manifest.id))
|
|
10426
10771
|
};
|
|
10427
10772
|
} catch {
|
|
10428
10773
|
return null;
|
|
@@ -10450,13 +10795,13 @@ var ServiceAppManager = class {
|
|
|
10450
10795
|
normalizeActionIds = (actionIds) => Array.from(new Set(actionIds.map((actionId) => actionId.trim()).filter((actionId) => actionId.length > 0)));
|
|
10451
10796
|
getWorkspacePath = () => getWorkspacePathFromConfig(this.params.configManager.config);
|
|
10452
10797
|
getServiceAppsPath = (workspacePath) => join(workspacePath, DEFAULT_SERVICE_APPS_DIR);
|
|
10798
|
+
getServiceAppLockPath = (workspacePath, appId) => join(workspacePath, ".nextclaw", "locks", "service-apps", `${appId}.lock`);
|
|
10453
10799
|
createGrantStore = () => new ServiceActionGrantStore(join(this.getServiceAppsPath(this.getWorkspacePath()), SERVICE_ACTION_GRANTS_FILE_NAME));
|
|
10454
10800
|
listPackageComponentSources = async () => await this.params.listPackageComponentSources?.() ?? [];
|
|
10455
10801
|
listServiceAppDirNames = async (serviceAppsPath) => {
|
|
10456
10802
|
try {
|
|
10457
|
-
return
|
|
10803
|
+
return await this.removalService.listCanonicalDirectoryNames(serviceAppsPath);
|
|
10458
10804
|
} catch (error) {
|
|
10459
|
-
if (this.isMissingFileError(error)) return [];
|
|
10460
10805
|
throw new ServiceAppError("SERVICE_APP_READ_FAILED", error instanceof Error ? error.message : String(error));
|
|
10461
10806
|
}
|
|
10462
10807
|
};
|
|
@@ -15515,35 +15860,48 @@ var ToolProviderContribution = class {
|
|
|
15515
15860
|
};
|
|
15516
15861
|
};
|
|
15517
15862
|
//#endregion
|
|
15518
|
-
//#region src/app/
|
|
15863
|
+
//#region src/app/kernel-storage-paths.ts
|
|
15519
15864
|
function resolveKernelAppHomeDirectory(options) {
|
|
15520
15865
|
const homeDir = options.homeDir?.trim();
|
|
15521
15866
|
return resolve(homeDir ? expandHome(homeDir) : getDataDir(), "apps");
|
|
15522
15867
|
}
|
|
15523
15868
|
function resolveKernelSessionsDir(options) {
|
|
15524
15869
|
const homeDir = options.homeDir?.trim();
|
|
15525
|
-
|
|
15526
|
-
return getSessionsPath();
|
|
15870
|
+
return homeDir ? ensureDir(resolve(expandHome(homeDir), "sessions")) : getSessionsPath();
|
|
15527
15871
|
}
|
|
15528
15872
|
function resolveKernelAutomationStorePath(options) {
|
|
15529
|
-
|
|
15530
|
-
if (homeDir) return resolve(expandHome(homeDir), "cron", "jobs.json");
|
|
15531
|
-
return resolve(getDataDir(), "cron", "jobs.json");
|
|
15873
|
+
return resolveKernelDataPath(options, "cron", "jobs.json");
|
|
15532
15874
|
}
|
|
15533
15875
|
function resolveKernelPreferenceStorePath(options) {
|
|
15534
|
-
|
|
15535
|
-
if (homeDir) return resolve(expandHome(homeDir), "preferences", "preferences.json");
|
|
15536
|
-
return resolve(getDataDir(), "preferences", "preferences.json");
|
|
15876
|
+
return resolveKernelDataPath(options, "preferences", "preferences.json");
|
|
15537
15877
|
}
|
|
15538
15878
|
function resolveKernelProjectStorePath(options) {
|
|
15539
|
-
|
|
15540
|
-
if (homeDir) return resolve(expandHome(homeDir), "projects", "projects.json");
|
|
15541
|
-
return resolve(getDataDir(), "projects", "projects.json");
|
|
15879
|
+
return resolveKernelDataPath(options, "projects", "projects.json");
|
|
15542
15880
|
}
|
|
15543
15881
|
function resolveKernelInboxDeliveryStorePath(options) {
|
|
15882
|
+
return resolveKernelDataPath(options, "inbox", "deliveries.json");
|
|
15883
|
+
}
|
|
15884
|
+
function resolveKernelDataPath(options, ...segments) {
|
|
15544
15885
|
const homeDir = options.homeDir?.trim();
|
|
15545
|
-
|
|
15546
|
-
|
|
15886
|
+
return resolve(homeDir ? expandHome(homeDir) : getDataDir(), ...segments);
|
|
15887
|
+
}
|
|
15888
|
+
//#endregion
|
|
15889
|
+
//#region src/app/nextclaw-kernel.ts
|
|
15890
|
+
function createKernelServiceAppManagers(params) {
|
|
15891
|
+
const { appHomeDirectory, appPackageManager, configManager } = params;
|
|
15892
|
+
const serviceAppManager = new ServiceAppManager({
|
|
15893
|
+
configManager,
|
|
15894
|
+
listPackageComponentSources: appPackageManager.listActiveComponentSources
|
|
15895
|
+
});
|
|
15896
|
+
return {
|
|
15897
|
+
serviceAppManager,
|
|
15898
|
+
appDataManager: new AppDataManager({
|
|
15899
|
+
appHomeDirectory,
|
|
15900
|
+
getWorkspacePath: () => getWorkspacePathFromConfig(configManager.config),
|
|
15901
|
+
listInstalledPackageOwners: appPackageManager.listInstalledDataOwners,
|
|
15902
|
+
listWorkspaceDataOwners: serviceAppManager.listWorkspaceDataOwners
|
|
15903
|
+
})
|
|
15904
|
+
};
|
|
15547
15905
|
}
|
|
15548
15906
|
var NextclawKernelControlManager = class {
|
|
15549
15907
|
runtimeControl = null;
|
|
@@ -15569,6 +15927,7 @@ var NextclawKernel = class {
|
|
|
15569
15927
|
skills;
|
|
15570
15928
|
automation;
|
|
15571
15929
|
appPackageManager;
|
|
15930
|
+
appDataManager;
|
|
15572
15931
|
channels;
|
|
15573
15932
|
sessionRequests;
|
|
15574
15933
|
sessionSearch;
|
|
@@ -15646,10 +16005,11 @@ var NextclawKernel = class {
|
|
|
15646
16005
|
listPackageComponentSources: this.appPackageManager.listActiveComponentSources
|
|
15647
16006
|
});
|
|
15648
16007
|
this.preferenceManager = new PreferenceManager({ storePath: resolveKernelPreferenceStorePath(options) });
|
|
15649
|
-
this.serviceAppManager =
|
|
15650
|
-
|
|
15651
|
-
|
|
15652
|
-
|
|
16008
|
+
({appDataManager: this.appDataManager, serviceAppManager: this.serviceAppManager} = createKernelServiceAppManagers({
|
|
16009
|
+
appHomeDirectory: resolveKernelAppHomeDirectory(options),
|
|
16010
|
+
appPackageManager: this.appPackageManager,
|
|
16011
|
+
configManager: this.configManager
|
|
16012
|
+
}));
|
|
15653
16013
|
this.installAppPackageRuntimeHooks();
|
|
15654
16014
|
this.extensions = new ExtensionManager({
|
|
15655
16015
|
configManager: this.configManager,
|
|
@@ -15713,6 +16073,9 @@ var NextclawKernel = class {
|
|
|
15713
16073
|
};
|
|
15714
16074
|
getGatewayController = () => this.gatewayController;
|
|
15715
16075
|
start = async () => {
|
|
16076
|
+
await this.appPackageManager.start();
|
|
16077
|
+
await this.appDataManager.start();
|
|
16078
|
+
await this.serviceAppManager.start();
|
|
15716
16079
|
this.sessionSearch.start();
|
|
15717
16080
|
this.mcpManager.start();
|
|
15718
16081
|
this.providerModelCatalog.start();
|
|
@@ -16306,6 +16669,6 @@ function resolveLegacyEventType(message) {
|
|
|
16306
16669
|
return `message.${role || "other"}`;
|
|
16307
16670
|
}
|
|
16308
16671
|
//#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 };
|
|
16672
|
+
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
16673
|
|
|
16311
16674
|
//# sourceMappingURL=index.js.map
|