@nextclaw/server 0.20.5 → 0.22.0-beta.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
@@ -1,7 +1,7 @@
1
1
  import { Hono } from "hono";
2
2
  import { compress } from "hono/compress";
3
3
  import { serve } from "@hono/node-server";
4
- import { AccessManager, PanelAppError, injectUiContentParamsBootstrap, isAppDataError, isAppPackageError, isInboxDeliveryError, isPanelAppError, isPreferenceError, isProjectError, isServiceAppError, isSessionContextCompactionError, isSessionMessageCursorError, isSessionSettingsError, isSystemObjectReferenceError } from "@nextclaw/kernel";
4
+ import { AccessManager, PanelAppError, injectUiContentParamsBootstrap, isAppDataError, isAppPackageError, isInboxDeliveryError, isPanelAppError, isPreferenceError, isProjectError, isProjectObservationError, isServiceAppError, isSessionContextCompactionError, isSessionMessageCursorError, isSessionSettingsError, isSystemObjectReferenceError } from "@nextclaw/kernel";
5
5
  import { WebSocket, WebSocketServer } from "ws";
6
6
  import { existsSync, mkdirSync, readFileSync, watch, writeFileSync } from "node:fs";
7
7
  import { lstat, mkdir, open, readFile, readdir, realpath, rename, rm, stat, writeFile } from "node:fs/promises";
@@ -2197,6 +2197,40 @@ var AppPackagesRoutesController = class {
2197
2197
  return this.handleError(c, error);
2198
2198
  }
2199
2199
  };
2200
+ inspectSecrets = async (c) => {
2201
+ try {
2202
+ return c.json(ok(await this.manager.inspectSecrets(c.req.param("appId"))));
2203
+ } catch (error) {
2204
+ return this.handleError(c, error);
2205
+ }
2206
+ };
2207
+ verifySecrets = async (c) => {
2208
+ try {
2209
+ return c.json(ok(await this.manager.verifySecrets(c.req.param("appId"))));
2210
+ } catch (error) {
2211
+ return this.handleError(c, error);
2212
+ }
2213
+ };
2214
+ bindSecret = async (c) => {
2215
+ const body = await readJson(c.req.raw);
2216
+ const input = body.ok ? readSecretBinding(body.data) : void 0;
2217
+ if (!input) return c.json(err("INVALID_APP_SECRET_BINDING", "slotId, source, and id are required"), 400);
2218
+ try {
2219
+ return c.json(ok(await this.manager.bindSecret(c.req.param("appId"), input)));
2220
+ } catch (error) {
2221
+ return this.handleError(c, error);
2222
+ }
2223
+ };
2224
+ unbindSecret = async (c) => {
2225
+ const body = await readJson(c.req.raw);
2226
+ const slotId = body.ok && isRecord$3(body.data) && typeof body.data.slotId === "string" ? body.data.slotId.trim() : "";
2227
+ if (!slotId) return c.json(err("INVALID_APP_SECRET_BINDING", "slotId is required"), 400);
2228
+ try {
2229
+ return c.json(ok(await this.manager.unbindSecret(c.req.param("appId"), slotId)));
2230
+ } catch (error) {
2231
+ return this.handleError(c, error);
2232
+ }
2233
+ };
2200
2234
  install = async (c) => {
2201
2235
  const body = await readJson(c.req.raw);
2202
2236
  if (!body.ok || !isRecord$3(body.data) || typeof body.data.source !== "string") return c.json(err("INVALID_APP_PACKAGE_INSTALL", "source is required"), 400);
@@ -2252,7 +2286,7 @@ var AppPackagesRoutesController = class {
2252
2286
  };
2253
2287
  handleError = (c, error) => {
2254
2288
  if (isAppPackageError(error)) {
2255
- const status = error.code === "APP_PACKAGE_NOT_FOUND" ? 404 : error.code === "APP_PACKAGE_CONFLICT" || error.code === "APP_PACKAGE_NOT_READY" ? 409 : 400;
2289
+ const status = error.code === "APP_PACKAGE_NOT_FOUND" ? 404 : error.code === "APP_PACKAGE_CONFLICT" || error.code === "APP_PACKAGE_NOT_READY" || error.code === "SECRET_BINDING_MISSING" || error.code === "SECRET_RESOLUTION_FAILED" ? 409 : 400;
2256
2290
  return c.json(err(error.code, error.message), status);
2257
2291
  }
2258
2292
  return c.json(err("APP_PACKAGE_OPERATION_FAILED", error instanceof Error ? error.message : String(error)), 400);
@@ -2267,6 +2301,21 @@ function readDependencyBinding(value, requireProvider) {
2267
2301
  ...requireProvider ? { providerId: value.providerId } : {}
2268
2302
  };
2269
2303
  }
2304
+ function readSecretBinding(value) {
2305
+ if (!isRecord$3(value) || typeof value.slotId !== "string" || !value.slotId.trim() || ![
2306
+ "env",
2307
+ "file",
2308
+ "exec"
2309
+ ].includes(String(value.source)) || typeof value.id !== "string" || !value.id.trim() || value.provider !== void 0 && (typeof value.provider !== "string" || !value.provider.trim())) return;
2310
+ return {
2311
+ slotId: value.slotId.trim(),
2312
+ binding: {
2313
+ source: value.source,
2314
+ provider: typeof value.provider === "string" ? value.provider.trim() : void 0,
2315
+ id: value.id.trim()
2316
+ }
2317
+ };
2318
+ }
2270
2319
  //#endregion
2271
2320
  //#region src/features/app-data/controllers/app-data.controller.ts
2272
2321
  var AppDataRoutesController = class {
@@ -6784,6 +6833,26 @@ var ProjectsRoutesController = class {
6784
6833
  };
6785
6834
  };
6786
6835
  //#endregion
6836
+ //#region src/features/projects/controllers/project-observation.controller.ts
6837
+ var ProjectObservationRoutesController = class {
6838
+ constructor(projectManager, projectObservation) {
6839
+ this.projectManager = projectManager;
6840
+ this.projectObservation = projectObservation;
6841
+ }
6842
+ get = async (c) => {
6843
+ const projectId = c.req.param("projectId")?.trim();
6844
+ if (!projectId) return c.json(err("INVALID_PROJECT", "registered project id is required"), 400);
6845
+ try {
6846
+ const project = await this.projectManager.getProjectById(projectId);
6847
+ if (!project) return c.json(err("PROJECT_NOT_FOUND", "registered project was not found"), 404);
6848
+ return c.json(ok(await this.projectObservation.observe(project.rootPath)));
6849
+ } catch (error) {
6850
+ if (isProjectObservationError(error)) return c.json(err(error.code, error.message), error.code === "PROJECT_NOT_REGISTERED" ? 404 : 400);
6851
+ throw error;
6852
+ }
6853
+ };
6854
+ };
6855
+ //#endregion
6787
6856
  //#region src/features/service-apps/controllers/service-apps.controller.ts
6788
6857
  const PANEL_BRIDGE_SESSION_HEADER = "x-nextclaw-panel-bridge-session";
6789
6858
  function statusForServiceAppError(code) {
@@ -6791,7 +6860,9 @@ function statusForServiceAppError(code) {
6791
6860
  case "AUTHORIZATION_REQUIRED": return 401;
6792
6861
  case "SERVICE_APP_ACTION_NOT_DECLARED": return 403;
6793
6862
  case "SERVICE_APP_ACTION_NOT_FOUND":
6794
- case "SERVICE_APP_NOT_FOUND": return 404;
6863
+ case "SERVICE_APP_NOT_FOUND":
6864
+ case "SERVICE_APP_JOB_NOT_FOUND":
6865
+ case "SERVICE_APP_RESIDENT_EVENT_NOT_FOUND": return 404;
6795
6866
  case "SERVICE_APP_RUNTIME_FAILED":
6796
6867
  case "WASI_ABI_VERSION_MISMATCH":
6797
6868
  case "WASI_COMPONENT_FAILED":
@@ -6799,6 +6870,7 @@ function statusForServiceAppError(code) {
6799
6870
  case "WASI_GUEST_EXPORT_MISSING": return 502;
6800
6871
  case "WASI_CAPABILITY_DENIED": return 403;
6801
6872
  case "WASI_INPUT_SCHEMA_MISMATCH": return 422;
6873
+ case "STREAM_CURSOR_EXPIRED": return 422;
6802
6874
  default: return 400;
6803
6875
  }
6804
6876
  }
@@ -6816,6 +6888,39 @@ var ServiceAppsRoutesController = class {
6816
6888
  return this.handleServiceAppError(c, error);
6817
6889
  }
6818
6890
  };
6891
+ inspectServiceAppAiCapabilities = async (c) => {
6892
+ try {
6893
+ return c.json(ok(await this.params.serviceAppManager.inspectServiceAppAiCapabilities(c.req.param("appId"))));
6894
+ } catch (error) {
6895
+ return this.handleServiceAppError(c, error);
6896
+ }
6897
+ };
6898
+ verifyServiceAppAiCapabilities = async (c) => {
6899
+ try {
6900
+ return c.json(ok(await this.params.serviceAppManager.verifyServiceAppAiCapabilities(c.req.param("appId"))));
6901
+ } catch (error) {
6902
+ return this.handleServiceAppError(c, error);
6903
+ }
6904
+ };
6905
+ bindServiceAppAiCapability = async (c) => {
6906
+ const body = await readJson(c.req.raw);
6907
+ if (!body.ok || body.data?.kind !== "model" && body.data?.kind !== "agent" || typeof body.data.slotId !== "string" || typeof body.data.targetId !== "string") return c.json(err("INVALID_SERVICE_APP_AI_BINDING", "kind, slotId, and targetId are required."), 400);
6908
+ try {
6909
+ const result = body.data.kind === "model" ? await this.params.serviceAppManager.bindServiceAppModelSlot(c.req.param("appId"), body.data.slotId, body.data.targetId) : await this.params.serviceAppManager.bindServiceAppAgentSlot(c.req.param("appId"), body.data.slotId, body.data.targetId);
6910
+ return c.json(ok(result));
6911
+ } catch (error) {
6912
+ return this.handleServiceAppError(c, error);
6913
+ }
6914
+ };
6915
+ unbindServiceAppAiCapability = async (c) => {
6916
+ const body = await readJson(c.req.raw);
6917
+ if (!body.ok || body.data?.kind !== "model" && body.data?.kind !== "agent" || typeof body.data.slotId !== "string") return c.json(err("INVALID_SERVICE_APP_AI_BINDING", "kind and slotId are required."), 400);
6918
+ try {
6919
+ return c.json(ok(await this.params.serviceAppManager.unbindServiceAppAiSlot(c.req.param("appId"), body.data.kind, body.data.slotId)));
6920
+ } catch (error) {
6921
+ return this.handleServiceAppError(c, error);
6922
+ }
6923
+ };
6819
6924
  listServiceActions = async (c) => {
6820
6925
  try {
6821
6926
  const bridgeSession = this.readOptionalBridgeSession(c);
@@ -6853,6 +6958,121 @@ var ServiceAppsRoutesController = class {
6853
6958
  return this.handleServiceAppError(c, error);
6854
6959
  }
6855
6960
  };
6961
+ invokeInstalledServiceAction = async (c) => {
6962
+ const body = await readJson(c.req.raw);
6963
+ if (!body.ok || body.data?.input !== void 0 && !isRecord$3(body.data.input)) return c.json(err("INVALID_SERVICE_ACTION_REQUEST", "invalid service action request"), 400);
6964
+ try {
6965
+ return c.json(ok(await this.params.serviceAppManager.invokeInstalledServiceAction(c.req.param("appId"), c.req.param("actionName"), isRecord$3(body.data?.input) ? body.data.input : {})));
6966
+ } catch (error) {
6967
+ return this.handleServiceAppError(c, error);
6968
+ }
6969
+ };
6970
+ /**
6971
+ * Agent tool providers call the same manager method. This explicit endpoint
6972
+ * is the non-LLM integration/diagnostic surface: it still requires a real
6973
+ * configured Agent and its explicit Service Action grant, so it cannot
6974
+ * impersonate either a Panel bridge or an arbitrary Agent.
6975
+ */
6976
+ invokeAgentServiceAction = async (c) => {
6977
+ const body = await readJson(c.req.raw);
6978
+ if (!body.ok || body.data?.input !== void 0 && !isRecord$3(body.data.input)) return c.json(err("INVALID_SERVICE_ACTION_REQUEST", "invalid service action request"), 400);
6979
+ try {
6980
+ return c.json(ok(await this.params.serviceAppManager.invokeServiceAction(c.req.param("actionId"), {
6981
+ caller: {
6982
+ surface: "agent",
6983
+ agentId: c.req.param("agentId")
6984
+ },
6985
+ input: isRecord$3(body.data?.input) ? body.data.input : {}
6986
+ })));
6987
+ } catch (error) {
6988
+ return this.handleServiceAppError(c, error);
6989
+ }
6990
+ };
6991
+ listVerificationRecords = async (c) => {
6992
+ try {
6993
+ return c.json(ok(await this.params.serviceAppManager.listVerificationRecords({
6994
+ acceptanceId: this.readOptionalQuery(c, "acceptanceId"),
6995
+ appId: this.readOptionalQuery(c, "appId"),
6996
+ limit: this.readLimit(c)
6997
+ })));
6998
+ } catch (error) {
6999
+ return this.handleServiceAppError(c, error);
7000
+ }
7001
+ };
7002
+ /** Stable read-only projection of the single portable-runtime acceptance registry. */
7003
+ getPortableRuntimeAcceptanceContract = async (c) => {
7004
+ try {
7005
+ return c.json(ok(this.params.portableRuntimeAcceptance.contract(this.readLocale(c))));
7006
+ } catch (error) {
7007
+ return this.handleServiceAppError(c, error);
7008
+ }
7009
+ };
7010
+ getPortableRuntimeAcceptanceStatus = async (c) => {
7011
+ try {
7012
+ return c.json(ok(await this.params.portableRuntimeAcceptance.status({
7013
+ appId: this.readOptionalQuery(c, "appId"),
7014
+ locale: this.readLocale(c)
7015
+ })));
7016
+ } catch (error) {
7017
+ return this.handleServiceAppError(c, error);
7018
+ }
7019
+ };
7020
+ exportPortableRuntimeAcceptance = async (c) => {
7021
+ try {
7022
+ return c.json(ok(await this.params.portableRuntimeAcceptance.export({
7023
+ appId: this.readOptionalQuery(c, "appId"),
7024
+ locale: this.readLocale(c)
7025
+ })));
7026
+ } catch (error) {
7027
+ return this.handleServiceAppError(c, error);
7028
+ }
7029
+ };
7030
+ listServiceAppJobs = async (c) => {
7031
+ try {
7032
+ return c.json(ok(await this.params.serviceAppManager.listServiceAppJobs(c.req.param("appId"))));
7033
+ } catch (error) {
7034
+ return this.handleServiceAppError(c, error);
7035
+ }
7036
+ };
7037
+ getServiceAppJob = async (c) => {
7038
+ try {
7039
+ return c.json(ok(await this.params.serviceAppManager.getServiceAppJob(c.req.param("appId"), c.req.param("jobId"))));
7040
+ } catch (error) {
7041
+ return this.handleServiceAppError(c, error);
7042
+ }
7043
+ };
7044
+ /** Cursor replay only; a disconnected client never changes Job execution. */
7045
+ watchServiceAppJob = async (c) => {
7046
+ const afterSequence = this.readAfterSequence(c);
7047
+ if (afterSequence === null) return c.json(err("INVALID_JOB_CURSOR", "afterSequence must be a non-negative integer"), 400);
7048
+ try {
7049
+ return c.json(ok(await this.params.serviceAppManager.watchServiceAppJob(c.req.param("appId"), c.req.param("jobId"), afterSequence)));
7050
+ } catch (error) {
7051
+ return this.handleServiceAppError(c, error);
7052
+ }
7053
+ };
7054
+ cancelServiceAppJob = async (c) => {
7055
+ try {
7056
+ return c.json(ok(await this.params.serviceAppManager.cancelServiceAppJob(c.req.param("appId"), c.req.param("jobId"))));
7057
+ } catch (error) {
7058
+ return this.handleServiceAppError(c, error);
7059
+ }
7060
+ };
7061
+ /** Inspect durable Resident delivery facts; payload stays private to the instance journal. */
7062
+ listResidentInbox = async (c) => {
7063
+ try {
7064
+ return c.json(ok(await this.params.serviceAppManager.listResidentInbox(c.req.param("appId"), { deadLettersOnly: c.req.query("deadLetters") === "true" })));
7065
+ } catch (error) {
7066
+ return this.handleServiceAppError(c, error);
7067
+ }
7068
+ };
7069
+ replayResidentDeadLetter = async (c) => {
7070
+ try {
7071
+ return c.json(ok(await this.params.serviceAppManager.replayResidentDeadLetter(c.req.param("appId"), c.req.param("eventId"))));
7072
+ } catch (error) {
7073
+ return this.handleServiceAppError(c, error);
7074
+ }
7075
+ };
6856
7076
  grantServiceAction = async (c) => {
6857
7077
  try {
6858
7078
  const bridgeSession = this.requireBridgeSession(c);
@@ -6954,6 +7174,22 @@ var ServiceAppsRoutesController = class {
6954
7174
  };
6955
7175
  return null;
6956
7176
  };
7177
+ readOptionalQuery = (c, key) => {
7178
+ return c.req.query(key)?.trim() || void 0;
7179
+ };
7180
+ readLocale = (c) => c.req.query("locale") === "en" ? "en" : "zh-CN";
7181
+ readLimit = (c) => {
7182
+ const raw = c.req.query("limit");
7183
+ if (!raw) return void 0;
7184
+ const value = Number(raw);
7185
+ return Number.isInteger(value) && value > 0 ? value : void 0;
7186
+ };
7187
+ readAfterSequence = (c) => {
7188
+ const raw = c.req.query("afterSequence");
7189
+ if (raw === void 0 || raw === "") return void 0;
7190
+ const value = Number(raw);
7191
+ return Number.isInteger(value) && value >= 0 ? value : null;
7192
+ };
6957
7193
  handleServiceAppError = (c, error) => {
6958
7194
  if (isServiceAppError(error)) return c.json(err(error.code, error.message, error.details), statusForServiceAppError(error.code));
6959
7195
  if (isPanelAppError(error)) return c.json(err(error.code, error.message), 404);
@@ -7048,9 +7284,11 @@ function createUiRouteControllers(options, authService, marketplaceBaseUrls, ser
7048
7284
  panelApps: new PanelAppsRoutesController(kernel.panelAppManager, { panelAppClientSdkScript }),
7049
7285
  preferences: new PreferencesRoutesController(kernel.preferenceManager),
7050
7286
  projects: new ProjectsRoutesController(kernel.projectManager),
7287
+ projectObservation: new ProjectObservationRoutesController(kernel.projectManager, kernel.projectObservation),
7051
7288
  serviceApps: new ServiceAppsRoutesController({
7052
7289
  panelAppManager: kernel.panelAppManager,
7053
- serviceAppManager: kernel.serviceAppManager
7290
+ serviceAppManager: kernel.serviceAppManager,
7291
+ portableRuntimeAcceptance: kernel.portableRuntimeAcceptance
7054
7292
  }),
7055
7293
  serverPath: new ServerPathRoutesController(serverPathWatchService),
7056
7294
  remote: remoteAccess ? new RemoteRoutesController(remoteAccess) : null,
@@ -7162,7 +7400,7 @@ var UiRouteRegistry = class {
7162
7400
  ]]);
7163
7401
  };
7164
7402
  mountResourceRoutes = () => {
7165
- const { appData, appPackages, capabilityAccess, featureControls, ncpSession, inboxDeliveries, panelApps, preferences, projects, serviceApps, serverPath, systemObjectReferences } = this.controllers;
7403
+ const { appData, appPackages, capabilityAccess, featureControls, ncpSession, inboxDeliveries, panelApps, preferences, projects, projectObservation, serviceApps, serverPath, systemObjectReferences } = this.controllers;
7166
7404
  this.mountRoutes([
7167
7405
  [
7168
7406
  "get",
@@ -7384,6 +7622,26 @@ var UiRouteRegistry = class {
7384
7622
  "/api/app-packages/:appId/dependencies/unbind",
7385
7623
  appPackages.unbindDependency
7386
7624
  ],
7625
+ [
7626
+ "get",
7627
+ "/api/app-packages/:appId/secrets",
7628
+ appPackages.inspectSecrets
7629
+ ],
7630
+ [
7631
+ "post",
7632
+ "/api/app-packages/:appId/secrets/verify",
7633
+ appPackages.verifySecrets
7634
+ ],
7635
+ [
7636
+ "post",
7637
+ "/api/app-packages/:appId/secrets/bind",
7638
+ appPackages.bindSecret
7639
+ ],
7640
+ [
7641
+ "post",
7642
+ "/api/app-packages/:appId/secrets/unbind",
7643
+ appPackages.unbindSecret
7644
+ ],
7387
7645
  [
7388
7646
  "post",
7389
7647
  "/api/app-packages/:appId/enable",
@@ -7484,6 +7742,11 @@ var UiRouteRegistry = class {
7484
7742
  "/api/projects",
7485
7743
  projects.list
7486
7744
  ],
7745
+ [
7746
+ "get",
7747
+ "/api/projects/:projectId/observation",
7748
+ projectObservation.get
7749
+ ],
7487
7750
  [
7488
7751
  "post",
7489
7752
  "/api/projects",
@@ -7524,6 +7787,26 @@ var UiRouteRegistry = class {
7524
7787
  "/api/service-apps",
7525
7788
  serviceApps.listServiceApps
7526
7789
  ],
7790
+ [
7791
+ "get",
7792
+ "/api/service-apps/:appId/ai-capabilities",
7793
+ serviceApps.inspectServiceAppAiCapabilities
7794
+ ],
7795
+ [
7796
+ "post",
7797
+ "/api/service-apps/:appId/ai-capabilities/verify",
7798
+ serviceApps.verifyServiceAppAiCapabilities
7799
+ ],
7800
+ [
7801
+ "post",
7802
+ "/api/service-apps/:appId/ai-capabilities/bind",
7803
+ serviceApps.bindServiceAppAiCapability
7804
+ ],
7805
+ [
7806
+ "post",
7807
+ "/api/service-apps/:appId/ai-capabilities/unbind",
7808
+ serviceApps.unbindServiceAppAiCapability
7809
+ ],
7527
7810
  [
7528
7811
  "post",
7529
7812
  "/api/service-apps/:appId/restart",
@@ -7534,6 +7817,36 @@ var UiRouteRegistry = class {
7534
7817
  "/api/service-apps/:appId/actions/discover",
7535
7818
  serviceApps.discoverServiceAppActions
7536
7819
  ],
7820
+ [
7821
+ "get",
7822
+ "/api/service-apps/:appId/jobs",
7823
+ serviceApps.listServiceAppJobs
7824
+ ],
7825
+ [
7826
+ "get",
7827
+ "/api/service-apps/:appId/jobs/:jobId",
7828
+ serviceApps.getServiceAppJob
7829
+ ],
7830
+ [
7831
+ "get",
7832
+ "/api/service-apps/:appId/jobs/:jobId/watch",
7833
+ serviceApps.watchServiceAppJob
7834
+ ],
7835
+ [
7836
+ "post",
7837
+ "/api/service-apps/:appId/jobs/:jobId/cancel",
7838
+ serviceApps.cancelServiceAppJob
7839
+ ],
7840
+ [
7841
+ "get",
7842
+ "/api/service-apps/:appId/resident-inbox",
7843
+ serviceApps.listResidentInbox
7844
+ ],
7845
+ [
7846
+ "post",
7847
+ "/api/service-apps/:appId/resident-inbox/:eventId/replay",
7848
+ serviceApps.replayResidentDeadLetter
7849
+ ],
7537
7850
  [
7538
7851
  "get",
7539
7852
  "/api/service-apps/:appId",
@@ -7554,6 +7867,31 @@ var UiRouteRegistry = class {
7554
7867
  "/api/service-actions/:actionId/invoke",
7555
7868
  serviceApps.invokeServiceAction
7556
7869
  ],
7870
+ [
7871
+ "post",
7872
+ "/api/service-apps/:appId/actions/:actionName/invoke",
7873
+ serviceApps.invokeInstalledServiceAction
7874
+ ],
7875
+ [
7876
+ "get",
7877
+ "/api/runtime-verification-records",
7878
+ serviceApps.listVerificationRecords
7879
+ ],
7880
+ [
7881
+ "get",
7882
+ "/api/portable-runtime/acceptance/contract",
7883
+ serviceApps.getPortableRuntimeAcceptanceContract
7884
+ ],
7885
+ [
7886
+ "get",
7887
+ "/api/portable-runtime/acceptance/status",
7888
+ serviceApps.getPortableRuntimeAcceptanceStatus
7889
+ ],
7890
+ [
7891
+ "get",
7892
+ "/api/portable-runtime/acceptance/export",
7893
+ serviceApps.exportPortableRuntimeAcceptance
7894
+ ],
7557
7895
  [
7558
7896
  "post",
7559
7897
  "/api/service-actions/:actionId/grant",
@@ -7579,6 +7917,11 @@ var UiRouteRegistry = class {
7579
7917
  "/api/agents/:agentId/service-action-grants",
7580
7918
  serviceApps.grantAgentServiceActions
7581
7919
  ],
7920
+ [
7921
+ "post",
7922
+ "/api/agents/:agentId/service-actions/:actionId/invoke",
7923
+ serviceApps.invokeAgentServiceAction
7924
+ ],
7582
7925
  [
7583
7926
  "delete",
7584
7927
  "/api/service-action-grants/:actionId",