@nextclaw/kernel 0.6.19 → 0.6.20

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
@@ -5,7 +5,7 @@ import { APP_NAME, AgentRouteResolver, BUILTIN_MAIN_AGENT_ID, CLEAR_THINKING_TOK
5
5
  import { NCP_AI_EXECUTION_METADATA_KEY, NcpEventType, createUnavailableNcpAiExecutionMetadata, normalizeAssistantText, readNcpAiExecutionMetadata, sanitizeAssistantReplyTags } from "@nextclaw/ncp";
6
6
  import { LocalAssetStore, buildAssetContentPath, buildNcpUserContent, buildOpenAiFunctionTool, ncpMessageToOpenAiMessages, validateToolArgs } from "@nextclaw/ncp-agent-runtime";
7
7
  import { createHash, createHmac, randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
8
- import { CHAT_INLINE_TOKENS_METADATA_KEY, CHAT_INLINE_TOKENS_SCHEMA_VERSION, CHAT_PROJECT_TOKEN_KIND, CHAT_SESSION_MATERIALIZATION_METADATA_KEY, CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND, CHAT_WORKSPACE_FILE_TOKEN_KIND, EventBus, Ingress, PANEL_APP_INLINE_HOST_CONTRACT, UI_CONTENT_PARAMS_HOST_CONTRACT, eventKeys, ingressKeys, isRuntimeDefaultModelValue, normalizeRuntimeModelSelectionMode, readInlineContentHeight, readUiContentParams } from "@nextclaw/shared";
8
+ import { CHAT_INLINE_TOKENS_METADATA_KEY, CHAT_INLINE_TOKENS_SCHEMA_VERSION, CHAT_PROJECT_TOKEN_KIND, CHAT_SESSION_MATERIALIZATION_METADATA_KEY, CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND, CHAT_WORKSPACE_FILE_TOKEN_KIND, EventBus, INBOX_DELIVERY_SESSION_METADATA_KEY, Ingress, PANEL_APP_INLINE_HOST_CONTRACT, UI_CONTENT_PARAMS_HOST_CONTRACT, eventKeys, ingressKeys, isRuntimeDefaultModelValue, normalizeRuntimeModelSelectionMode, readInlineContentHeight, readUiContentParams } from "@nextclaw/shared";
9
9
  import { catchError, filter, from, lastValueFrom, tap } from "rxjs";
10
10
  import { appendFileSync, chmodSync, constants, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
11
11
  import { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
@@ -693,13 +693,13 @@ function createUnavailableAiExecutionMetadataEvent(params) {
693
693
  }
694
694
  //#endregion
695
695
  //#region src/utils/agent-run-request.utils.ts
696
- function readOptionalString$11(value) {
696
+ function readOptionalString$12(value) {
697
697
  if (typeof value !== "string") return;
698
698
  return value.trim() || void 0;
699
699
  }
700
700
  function toAgentRunRequest(envelope) {
701
701
  const metadata = envelope.metadata ?? {};
702
- const peerId = readOptionalString$11(envelope.peerId);
702
+ const peerId = readOptionalString$12(envelope.peerId);
703
703
  const requestMetadata = {
704
704
  agentRuntimeId: metadata.agentRuntimeId,
705
705
  agentId: metadata.agentId,
@@ -712,7 +712,7 @@ function toAgentRunRequest(envelope) {
712
712
  thinkingEffort: metadata.thinkingEffort
713
713
  };
714
714
  if (Array.isArray(envelope.content)) {
715
- const sessionId = readOptionalString$11(envelope.sessionId);
715
+ const sessionId = readOptionalString$12(envelope.sessionId);
716
716
  if (sessionId && peerId) throw new Error("agent-run.send cannot accept both sessionId and peerId.");
717
717
  return {
718
718
  ...requestMetadata,
@@ -730,8 +730,8 @@ function toAgentRunRequest(envelope) {
730
730
  }
731
731
  const sourceMessage = envelope.message;
732
732
  if (!sourceMessage) throw new Error("Invalid agent run send request.");
733
- const envelopeSessionId = readOptionalString$11(envelope.sessionId);
734
- const messageSessionId = readOptionalString$11(sourceMessage.sessionId);
733
+ const envelopeSessionId = readOptionalString$12(envelope.sessionId);
734
+ const messageSessionId = readOptionalString$12(sourceMessage.sessionId);
735
735
  const sessionId = envelopeSessionId ?? messageSessionId;
736
736
  if (sessionId && peerId) throw new Error("agent-run.send cannot accept both sessionId and peerId.");
737
737
  return {
@@ -792,7 +792,7 @@ function readSessionMaterialization(metadata) {
792
792
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
793
793
  const materialization = value;
794
794
  if (materialization.kind !== "child") throw new Error("session_materialization.kind must be \"child\".");
795
- const parentSessionId = readOptionalString$11(materialization.parentSessionId);
795
+ const parentSessionId = readOptionalString$12(materialization.parentSessionId);
796
796
  if (!parentSessionId) throw new Error("session_materialization.parentSessionId is required.");
797
797
  if (materialization.inheritContext !== true) throw new Error("session_materialization.inheritContext must be true.");
798
798
  return {
@@ -2737,7 +2737,7 @@ function readString$5(value) {
2737
2737
  function readRecord$1(value) {
2738
2738
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
2739
2739
  }
2740
- function readRequiredString$7(value, name) {
2740
+ function readRequiredString$8(value, name) {
2741
2741
  const trimmed = readString$5(value);
2742
2742
  if (!trimmed) throw new Error(`${name} is required`);
2743
2743
  return trimmed;
@@ -2768,9 +2768,9 @@ function readInboundAttachments(value) {
2768
2768
  function toInboundMessage(value) {
2769
2769
  const payload = readRecord$1(value);
2770
2770
  return {
2771
- channel: readRequiredString$7(payload.channelId, "channelId"),
2772
- chatId: readRequiredString$7(payload.conversationId, "conversationId"),
2773
- senderId: readRequiredString$7(payload.senderId, "senderId"),
2771
+ channel: readRequiredString$8(payload.channelId, "channelId"),
2772
+ chatId: readRequiredString$8(payload.conversationId, "conversationId"),
2773
+ senderId: readRequiredString$8(payload.senderId, "senderId"),
2774
2774
  content: readTextContent(payload.content),
2775
2775
  timestamp: /* @__PURE__ */ new Date(),
2776
2776
  attachments: readInboundAttachments(payload.attachments),
@@ -2792,7 +2792,7 @@ function normalizeAuthPollResult(value) {
2792
2792
  if (!value) return null;
2793
2793
  const record = readRecord$1(value);
2794
2794
  return {
2795
- channel: readRequiredString$7(record.channel, "channel"),
2795
+ channel: readRequiredString$8(record.channel, "channel"),
2796
2796
  status: record.status,
2797
2797
  message: readString$5(record.message),
2798
2798
  nextPollMs: readOptionalNumber(record.nextPollMs),
@@ -2890,7 +2890,7 @@ var ExtensionRuntimeService = class {
2890
2890
  if (running.length > 0) console.log(`✓ Extensions started: ${running.map((entry) => entry.manifest.id).join(", ")}`);
2891
2891
  };
2892
2892
  getExtensionProcessToken = (extensionId) => {
2893
- const id = readRequiredString$7(extensionId, "extensionId");
2893
+ const id = readRequiredString$8(extensionId, "extensionId");
2894
2894
  const current = this.extensionTokens.get(id);
2895
2895
  if (current) return current;
2896
2896
  const token = randomUUID();
@@ -2953,7 +2953,7 @@ var ExtensionRuntimeService = class {
2953
2953
  };
2954
2954
  handleChannelConfigGet = (envelope, context) => {
2955
2955
  this.assertAuthorized(envelope, context);
2956
- const channelId = readRequiredString$7(readRecord$1(envelope.payload).channelId, "channelId");
2956
+ const channelId = readRequiredString$8(readRecord$1(envelope.payload).channelId, "channelId");
2957
2957
  return { config: this.options.getConfig().channels[channelId] ?? {} };
2958
2958
  };
2959
2959
  handleChannelMessageSubmit = async (envelope, context) => {
@@ -2968,9 +2968,9 @@ var ExtensionRuntimeService = class {
2968
2968
  handleChannelCommandExecute = async (envelope, context) => {
2969
2969
  this.assertAuthorized(envelope, context);
2970
2970
  const payload = readRecord$1(envelope.payload);
2971
- const channel = readRequiredString$7(payload.channelId, "channelId");
2972
- const chatId = readRequiredString$7(payload.conversationId, "conversationId");
2973
- const senderId = readRequiredString$7(payload.senderId, "senderId");
2971
+ const channel = readRequiredString$8(payload.channelId, "channelId");
2972
+ const chatId = readRequiredString$8(payload.conversationId, "conversationId");
2973
+ const senderId = readRequiredString$8(payload.senderId, "senderId");
2974
2974
  const metadata = readRecord$1(payload.metadata);
2975
2975
  const config = this.options.getConfig();
2976
2976
  const registry = new CommandRegistry(config, this.options.sessionManager);
@@ -2997,7 +2997,7 @@ var ExtensionRuntimeService = class {
2997
2997
  content: "",
2998
2998
  ephemeral: true
2999
2999
  };
3000
- return await registry.execute(readRequiredString$7(payload.commandName, "commandName"), readRecord$1(payload.args), {
3000
+ return await registry.execute(readRequiredString$8(payload.commandName, "commandName"), readRecord$1(payload.args), {
3001
3001
  channel,
3002
3002
  chatId,
3003
3003
  senderId,
@@ -3007,7 +3007,7 @@ var ExtensionRuntimeService = class {
3007
3007
  handleExtensionResponse = (envelope, context) => {
3008
3008
  this.assertAuthorized(envelope, context);
3009
3009
  const payload = readRecord$1(envelope.payload);
3010
- const requestId = readRequiredString$7(payload.requestId, "requestId");
3010
+ const requestId = readRequiredString$8(payload.requestId, "requestId");
3011
3011
  const pending = this.pendingRequests.get(requestId);
3012
3012
  if (!pending) return { accepted: false };
3013
3013
  this.pendingRequests.delete(requestId);
@@ -3689,6 +3689,228 @@ var LlmUsageManager = class {
3689
3689
  };
3690
3690
  };
3691
3691
  //#endregion
3692
+ //#region src/stores/inbox-delivery.store.ts
3693
+ const INBOX_DELIVERY_STORE_VERSION = 1;
3694
+ var InboxDeliveryStoreError = class extends Error {
3695
+ constructor(message) {
3696
+ super(message);
3697
+ this.name = "InboxDeliveryStoreError";
3698
+ }
3699
+ };
3700
+ var InboxDeliveryStore = class {
3701
+ constructor(storePath) {
3702
+ this.storePath = storePath;
3703
+ }
3704
+ list = async () => {
3705
+ try {
3706
+ return this.parseStoreFile(await readFile(this.storePath, "utf8")).deliveries;
3707
+ } catch (error) {
3708
+ if (this.isMissingFileError(error)) return [];
3709
+ if (error instanceof SyntaxError) throw new InboxDeliveryStoreError("inbox delivery store contains invalid JSON");
3710
+ throw error;
3711
+ }
3712
+ };
3713
+ save = async (deliveries) => {
3714
+ const tempPath = `${this.storePath}.${randomUUID()}.tmp`;
3715
+ const storeFile = {
3716
+ version: INBOX_DELIVERY_STORE_VERSION,
3717
+ deliveries: deliveries.map((delivery) => structuredClone(delivery))
3718
+ };
3719
+ await mkdir(dirname(this.storePath), { recursive: true });
3720
+ try {
3721
+ await writeFile(tempPath, `${JSON.stringify(storeFile, null, 2)}\n`, "utf8");
3722
+ await rename(tempPath, this.storePath);
3723
+ } catch (error) {
3724
+ await rm(tempPath, { force: true }).catch(() => void 0);
3725
+ throw error;
3726
+ }
3727
+ };
3728
+ parseStoreFile = (source) => {
3729
+ const value = JSON.parse(source);
3730
+ if (!this.isRecord(value) || value.version !== INBOX_DELIVERY_STORE_VERSION || !Array.isArray(value.deliveries) || !value.deliveries.every(this.isDelivery)) throw new InboxDeliveryStoreError("inbox delivery store has an unsupported structure");
3731
+ return {
3732
+ version: INBOX_DELIVERY_STORE_VERSION,
3733
+ deliveries: value.deliveries.map((delivery) => structuredClone(delivery))
3734
+ };
3735
+ };
3736
+ isDelivery = (value) => {
3737
+ if (!this.isRecord(value) || !this.isSource(value.source)) return false;
3738
+ return typeof value.id === "string" && typeof value.title === "string" && (value.summary === null || typeof value.summary === "string") && typeof value.content === "string" && (value.contentType === "markdown" || value.contentType === "html") && typeof value.createdAt === "string" && typeof value.updatedAt === "string" && this.isOptionalTimestamp(value.presentedAt) && this.isOptionalTimestamp(value.readAt) && this.isOptionalTimestamp(value.archivedAt) && (value.conversationSessionId === null || typeof value.conversationSessionId === "string");
3739
+ };
3740
+ isSource = (value) => this.isRecord(value) && value.kind === "agent" && this.isOptionalString(value.agentId) && this.isOptionalString(value.sessionId) && this.isOptionalString(value.toolCallId) && this.isOptionalString(value.filePath);
3741
+ isOptionalString = (value) => value === null || typeof value === "string";
3742
+ isOptionalTimestamp = (value) => this.isOptionalString(value);
3743
+ isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
3744
+ isMissingFileError = (error) => typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
3745
+ };
3746
+ //#endregion
3747
+ //#region src/managers/inbox-delivery.manager.ts
3748
+ const MAX_TITLE_LENGTH = 160;
3749
+ const MAX_SUMMARY_LENGTH = 500;
3750
+ const MAX_INBOX_DELIVERY_CONTENT_LENGTH = 512 * 1024;
3751
+ var InboxDeliveryError = class extends Error {
3752
+ constructor(code, message) {
3753
+ super(message);
3754
+ this.code = code;
3755
+ this.name = "InboxDeliveryError";
3756
+ }
3757
+ };
3758
+ function isInboxDeliveryError(error) {
3759
+ return error instanceof InboxDeliveryError;
3760
+ }
3761
+ var InboxDeliveryManager = class {
3762
+ store;
3763
+ writeQueue = Promise.resolve();
3764
+ constructor(options) {
3765
+ this.options = options;
3766
+ this.store = new InboxDeliveryStore(options.storePath);
3767
+ }
3768
+ listDeliveries = async () => {
3769
+ await this.writeQueue;
3770
+ const deliveries = (await this.store.list()).sort((left, right) => right.createdAt.localeCompare(left.createdAt));
3771
+ return {
3772
+ deliveries,
3773
+ total: deliveries.length,
3774
+ unreadCount: deliveries.filter((delivery) => !delivery.readAt && !delivery.archivedAt).length,
3775
+ unpresentedCount: deliveries.filter((delivery) => !delivery.presentedAt && !delivery.readAt && !delivery.archivedAt).length
3776
+ };
3777
+ };
3778
+ getDelivery = async (deliveryId) => {
3779
+ await this.writeQueue;
3780
+ const delivery = (await this.store.list()).find(({ id }) => id === deliveryId);
3781
+ return delivery ? structuredClone(delivery) : null;
3782
+ };
3783
+ createDelivery = async (input) => await this.mutate(async () => {
3784
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3785
+ const delivery = {
3786
+ id: randomUUID(),
3787
+ title: this.normalizeRequiredText(input.title, "title", MAX_TITLE_LENGTH),
3788
+ summary: this.normalizeOptionalText(input.summary, "summary", MAX_SUMMARY_LENGTH),
3789
+ content: this.normalizeRequiredText(input.content, "content", MAX_INBOX_DELIVERY_CONTENT_LENGTH),
3790
+ contentType: input.contentType,
3791
+ source: structuredClone(input.source),
3792
+ createdAt: now,
3793
+ updatedAt: now,
3794
+ presentedAt: null,
3795
+ readAt: null,
3796
+ archivedAt: null,
3797
+ conversationSessionId: null
3798
+ };
3799
+ const deliveries = await this.store.list();
3800
+ await this.store.save([delivery, ...deliveries]);
3801
+ this.publishChange(delivery.id, "upsert");
3802
+ return structuredClone(delivery);
3803
+ });
3804
+ updateDeliveryState = async (deliveryId, action) => await this.mutate(async () => {
3805
+ const deliveries = await this.store.list();
3806
+ const index = deliveries.findIndex(({ id }) => id === deliveryId);
3807
+ if (index < 0) throw this.notFound(deliveryId);
3808
+ const current = deliveries[index];
3809
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3810
+ const next = this.applyStateAction(current, action, now);
3811
+ deliveries[index] = next;
3812
+ await this.store.save(deliveries);
3813
+ this.publishChange(deliveryId, "upsert");
3814
+ return structuredClone(next);
3815
+ });
3816
+ deleteDelivery = async (deliveryId) => await this.mutate(async () => {
3817
+ const deliveries = await this.store.list();
3818
+ const remaining = deliveries.filter(({ id }) => id !== deliveryId);
3819
+ if (remaining.length === deliveries.length) return false;
3820
+ await this.store.save(remaining);
3821
+ this.publishChange(deliveryId, "delete");
3822
+ return true;
3823
+ });
3824
+ continueInChat = async (deliveryId) => await this.mutate(async () => {
3825
+ const deliveries = await this.store.list();
3826
+ const index = deliveries.findIndex(({ id }) => id === deliveryId);
3827
+ if (index < 0) throw this.notFound(deliveryId);
3828
+ const current = deliveries[index];
3829
+ const existingSession = current.conversationSessionId ? await this.options.sessionManager.getSessionRecord(current.conversationSessionId) : null;
3830
+ let sessionId = current.conversationSessionId;
3831
+ let created = false;
3832
+ if (!sessionId || !existingSession) {
3833
+ sessionId = (await this.options.sessionManager.createSession({
3834
+ sourceSessionMetadata: {},
3835
+ metadataOverrides: { [INBOX_DELIVERY_SESSION_METADATA_KEY]: current.id },
3836
+ task: `Continue discussing inbox delivery: ${current.title}`,
3837
+ title: current.title,
3838
+ agentId: current.source.agentId ?? void 0
3839
+ })).sessionId;
3840
+ created = true;
3841
+ }
3842
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3843
+ const delivery = {
3844
+ ...current,
3845
+ updatedAt: now,
3846
+ presentedAt: current.presentedAt ?? now,
3847
+ readAt: current.readAt ?? now,
3848
+ conversationSessionId: sessionId
3849
+ };
3850
+ deliveries[index] = delivery;
3851
+ await this.store.save(deliveries);
3852
+ this.publishChange(deliveryId, "upsert");
3853
+ return {
3854
+ delivery: structuredClone(delivery),
3855
+ sessionId,
3856
+ created
3857
+ };
3858
+ });
3859
+ applyStateAction = (delivery, action, now) => {
3860
+ switch (action) {
3861
+ case "present": return {
3862
+ ...delivery,
3863
+ updatedAt: now,
3864
+ presentedAt: delivery.presentedAt ?? now
3865
+ };
3866
+ case "read": return {
3867
+ ...delivery,
3868
+ updatedAt: now,
3869
+ presentedAt: delivery.presentedAt ?? now,
3870
+ readAt: delivery.readAt ?? now
3871
+ };
3872
+ case "mark_unread": return {
3873
+ ...delivery,
3874
+ updatedAt: now,
3875
+ readAt: null
3876
+ };
3877
+ case "archive": return {
3878
+ ...delivery,
3879
+ updatedAt: now,
3880
+ presentedAt: delivery.presentedAt ?? now,
3881
+ archivedAt: delivery.archivedAt ?? now
3882
+ };
3883
+ case "restore": return {
3884
+ ...delivery,
3885
+ updatedAt: now,
3886
+ archivedAt: null
3887
+ };
3888
+ }
3889
+ };
3890
+ normalizeRequiredText = (value, field, maxLength) => {
3891
+ const normalized = value.trim();
3892
+ if (!normalized || normalized.length > maxLength) throw new InboxDeliveryError(field === "title" ? "INBOX_DELIVERY_INVALID_TITLE" : "INBOX_DELIVERY_INVALID_CONTENT", `${field} must contain between 1 and ${maxLength} characters`);
3893
+ return normalized;
3894
+ };
3895
+ normalizeOptionalText = (value, field, maxLength) => {
3896
+ const normalized = value?.trim() ?? "";
3897
+ if (normalized.length > maxLength) throw new InboxDeliveryError("INBOX_DELIVERY_INVALID_SUMMARY", `${field} must contain at most ${maxLength} characters`);
3898
+ return normalized || null;
3899
+ };
3900
+ notFound = (deliveryId) => new InboxDeliveryError("INBOX_DELIVERY_NOT_FOUND", `inbox delivery not found: ${deliveryId}`);
3901
+ publishChange = (deliveryId, operation) => {
3902
+ this.options.eventBus.emit(eventKeys.inboxDeliveryChanged, {
3903
+ deliveryId,
3904
+ operation
3905
+ }, { source: "inbox-delivery" });
3906
+ };
3907
+ mutate = (operation) => {
3908
+ const result = this.writeQueue.then(operation, operation);
3909
+ this.writeQueue = result.then(() => void 0, () => void 0);
3910
+ return result;
3911
+ };
3912
+ };
3913
+ //#endregion
3692
3914
  //#region src/managers/mcp.manager.ts
3693
3915
  var McpManager = class {
3694
3916
  currentMcpConfig;
@@ -3743,11 +3965,11 @@ function createAgentPeerSessionIdentity(params) {
3743
3965
  }
3744
3966
  function resolveAgentPeerScope(params) {
3745
3967
  const metadata = params.metadata ?? {};
3746
- const explicitScope = readOptionalString$10(metadata["agent_peer_scope"]) ?? readOptionalString$10(metadata.agentPeerScope);
3968
+ const explicitScope = readOptionalString$11(metadata["agent_peer_scope"]) ?? readOptionalString$11(metadata.agentPeerScope);
3747
3969
  if (explicitScope) return explicitScope;
3748
- return `agent:${readOptionalString$10(params.agentId) ?? BUILTIN_MAIN_AGENT_ID}:${readOptionalString$10(params.channel) ?? readOptionalString$10(metadata.channel) ?? "agent-run"}:${readOptionalString$10(metadata.accountId) ?? readOptionalString$10(metadata.account_id) ?? "default"}`;
3970
+ return `agent:${readOptionalString$11(params.agentId) ?? BUILTIN_MAIN_AGENT_ID}:${readOptionalString$11(params.channel) ?? readOptionalString$11(metadata.channel) ?? "agent-run"}:${readOptionalString$11(metadata.accountId) ?? readOptionalString$11(metadata.account_id) ?? "default"}`;
3749
3971
  }
3750
- function readOptionalString$10(value) {
3972
+ function readOptionalString$11(value) {
3751
3973
  if (typeof value !== "string") return;
3752
3974
  return value.trim() || void 0;
3753
3975
  }
@@ -4054,7 +4276,7 @@ function applyLimit(items, limit) {
4054
4276
  if (!Number.isFinite(limit) || typeof limit !== "number" || limit <= 0) return items;
4055
4277
  return items.slice(0, Math.trunc(limit));
4056
4278
  }
4057
- function readOptionalString$9(value) {
4279
+ function readOptionalString$10(value) {
4058
4280
  if (typeof value !== "string") return null;
4059
4281
  const trimmed = value.trim();
4060
4282
  return trimmed.length > 0 ? trimmed : null;
@@ -4107,7 +4329,7 @@ function mergeMetadataOverrides(metadata, overrides) {
4107
4329
  }
4108
4330
  function resolveSessionType(params) {
4109
4331
  const { metadata, runtime, sessionType } = params;
4110
- return readOptionalString$9(runtime) ?? readOptionalString$9(metadata.runtime) ?? readOptionalString$9(sessionType) ?? readOptionalString$9(metadata.session_type) ?? "native";
4332
+ return readOptionalString$10(runtime) ?? readOptionalString$10(metadata.runtime) ?? readOptionalString$10(sessionType) ?? readOptionalString$10(metadata.session_type) ?? "native";
4111
4333
  }
4112
4334
  function applySessionOverrides(params) {
4113
4335
  const { lifecycle, metadata, model, parentSessionId, projectRoot, requestId, sessionType, thinkingLevel, title } = params;
@@ -4117,15 +4339,15 @@ function applySessionOverrides(params) {
4117
4339
  metadata[CHILD_SESSION_LIFECYCLE_METADATA_KEY] = lifecycle;
4118
4340
  if (parentSessionId) metadata[CHILD_SESSION_PARENT_METADATA_KEY] = parentSessionId;
4119
4341
  if (requestId) metadata[CHILD_SESSION_REQUEST_METADATA_KEY] = requestId;
4120
- if (readOptionalString$9(model)) {
4342
+ if (readOptionalString$10(model)) {
4121
4343
  metadata.model = model?.trim();
4122
4344
  metadata.preferred_model = model?.trim();
4123
4345
  }
4124
- if (readOptionalString$9(thinkingLevel)) {
4346
+ if (readOptionalString$10(thinkingLevel)) {
4125
4347
  metadata.thinking = thinkingLevel?.trim();
4126
4348
  metadata.preferred_thinking = thinkingLevel?.trim();
4127
4349
  }
4128
- if (readOptionalString$9(projectRoot)) metadata.project_root = projectRoot?.trim();
4350
+ if (readOptionalString$10(projectRoot)) metadata.project_root = projectRoot?.trim();
4129
4351
  }
4130
4352
  //#endregion
4131
4353
  //#region src/utils/session-context-inheritance.utils.ts
@@ -4136,7 +4358,7 @@ function hasToolCall(message, toolCallId) {
4136
4358
  return message.parts.some((part) => part.type === "tool-invocation" && part.toolCallId === toolCallId);
4137
4359
  }
4138
4360
  function findContextInheritanceAnchor(params) {
4139
- const anchorToolCallId = readOptionalString$9(params.anchorToolCallId);
4361
+ const anchorToolCallId = readOptionalString$10(params.anchorToolCallId);
4140
4362
  if (!anchorToolCallId) return null;
4141
4363
  const index = params.messages.findIndex((message) => hasToolCall(message, anchorToolCallId));
4142
4364
  const message = index >= 0 ? params.messages[index] : void 0;
@@ -4176,7 +4398,7 @@ function createInheritedContextSnapshot(params) {
4176
4398
  enabled: true,
4177
4399
  sourceSessionId: sourceRecord.sessionId,
4178
4400
  anchorKind: anchor ? "tool_call" : "latest_persisted",
4179
- anchorToolCallId: readOptionalString$9(anchorToolCallId),
4401
+ anchorToolCallId: readOptionalString$10(anchorToolCallId),
4180
4402
  anchorMessageId: anchor?.message.id,
4181
4403
  inheritedMessageCount: messages.length
4182
4404
  }
@@ -4322,7 +4544,7 @@ const SESSION_ACTIVITY_PREVIEW_STATES = new Set([
4322
4544
  function isRecord$10(value) {
4323
4545
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4324
4546
  }
4325
- function readOptionalString$8(value) {
4547
+ function readOptionalString$9(value) {
4326
4548
  if (typeof value !== "string") return;
4327
4549
  const trimmed = value.trim();
4328
4550
  return trimmed.length > 0 ? trimmed : void 0;
@@ -4330,13 +4552,13 @@ function readOptionalString$8(value) {
4330
4552
  function readSessionActivityPreviewMetadata(value) {
4331
4553
  if (!isRecord$10(value)) return null;
4332
4554
  const state = value.state;
4333
- const timestamp = readOptionalString$8(value.timestamp);
4555
+ const timestamp = readOptionalString$9(value.timestamp);
4334
4556
  if (!SESSION_ACTIVITY_PREVIEW_STATES.has(state) || !timestamp) return null;
4335
4557
  return {
4336
4558
  state,
4337
4559
  timestamp,
4338
- ...readOptionalString$8(value.statusText) ? { statusText: readOptionalString$8(value.statusText) } : {},
4339
- ...readOptionalString$8(value.replyText) ? { replyText: readOptionalString$8(value.replyText) } : {}
4560
+ ...readOptionalString$9(value.statusText) ? { statusText: readOptionalString$9(value.statusText) } : {},
4561
+ ...readOptionalString$9(value.replyText) ? { replyText: readOptionalString$9(value.replyText) } : {}
4340
4562
  };
4341
4563
  }
4342
4564
  function compareIsoTimestamp(left, right) {
@@ -4490,7 +4712,7 @@ var SessionWorkingDirResolver = class {
4490
4712
  return this.resolveContext(params).effectiveWorkspace;
4491
4713
  };
4492
4714
  resolveContext = (params) => {
4493
- const profile = this.agentManager.resolveAgentProfile(readOptionalString$9(params.agentId));
4715
+ const profile = this.agentManager.resolveAgentProfile(readOptionalString$10(params.agentId));
4494
4716
  return resolveSessionProjectContext({
4495
4717
  sessionMetadata: params.metadata,
4496
4718
  workspace: profile.workspace
@@ -4546,9 +4768,9 @@ var SessionManager = class {
4546
4768
  const { agentId: requestedAgentId, contextInheritance, metadataOverrides, model, parentSessionId: rawParentSessionId, projectRoot, requestId: rawRequestId, runtime, sessionId: requestedSessionId, sessionType: requestedSessionType, sourceSessionId, sourceSessionMetadata, task, thinkingLevel, title: requestedTitle } = params;
4547
4769
  const sourceRecord = sourceSessionId ? await this.getSessionRecord(sourceSessionId) : null;
4548
4770
  const metadata = cloneInheritedMetadata(sourceSessionMetadata);
4549
- const title = readOptionalString$9(requestedTitle) ?? summarizeTask(task);
4550
- const parentSessionId = readOptionalString$9(rawParentSessionId);
4551
- const requestId = readOptionalString$9(rawRequestId);
4771
+ const title = readOptionalString$10(requestedTitle) ?? summarizeTask(task);
4772
+ const parentSessionId = readOptionalString$10(rawParentSessionId);
4773
+ const requestId = readOptionalString$10(rawRequestId);
4552
4774
  const sessionType = resolveSessionType({
4553
4775
  runtime,
4554
4776
  sessionType: requestedSessionType,
@@ -4574,8 +4796,8 @@ var SessionManager = class {
4574
4796
  if (normalizedProjectRoot) nextMetadata.project_root = normalizedProjectRoot;
4575
4797
  else delete nextMetadata.project_root;
4576
4798
  }
4577
- const agentId = readOptionalString$9(requestedAgentId) ?? readOptionalString$9(sourceRecord?.agentId) ?? BUILTIN_MAIN_AGENT_ID;
4578
- const sessionId = readOptionalString$9(requestedSessionId) ?? buildSessionId();
4799
+ const agentId = readOptionalString$10(requestedAgentId) ?? readOptionalString$10(sourceRecord?.agentId) ?? BUILTIN_MAIN_AGENT_ID;
4800
+ const sessionId = readOptionalString$10(requestedSessionId) ?? buildSessionId();
4579
4801
  const inheritedContext = createSessionContextInheritance({
4580
4802
  childSessionId: sessionId,
4581
4803
  contextInheritance,
@@ -4670,7 +4892,7 @@ var SessionManager = class {
4670
4892
  return await this.options.journalStore.getSession(normalizedSessionId);
4671
4893
  };
4672
4894
  listSessions = async (options) => {
4673
- const peerId = readOptionalString$9(options?.peerId);
4895
+ const peerId = readOptionalString$10(options?.peerId);
4674
4896
  return applyLimit((await this.options.journalStore.listSessionSummaries()).filter((summary) => !peerId || summary.peerId === peerId).map(this.workingDirResolver.withWorkingDir), options?.limit);
4675
4897
  };
4676
4898
  listSessionMessages = async (sessionId, options) => {
@@ -4733,9 +4955,9 @@ var SessionManager = class {
4733
4955
  };
4734
4956
  createAgentRunSession = async (params) => {
4735
4957
  const { agentId, agentRuntimeId: requestedAgentRuntimeId, channel, contextInheritance, metadata, model, parentSessionId: rawParentSessionId, peerId: rawPeerId, projectRoot, sessionId, sourceSessionId: rawSourceSessionId, sourceSessionMetadata: requestedSourceSessionMetadata, task, thinkingEffort } = params;
4736
- const peerId = readOptionalString$9(rawPeerId);
4737
- const parentSessionId = readOptionalString$9(rawParentSessionId);
4738
- const sourceSessionId = readOptionalString$9(rawSourceSessionId);
4958
+ const peerId = readOptionalString$10(rawPeerId);
4959
+ const parentSessionId = readOptionalString$10(rawParentSessionId);
4960
+ const sourceSessionId = readOptionalString$10(rawSourceSessionId);
4739
4961
  const sourceRecord = sourceSessionId ? await this.getSessionRecord(sourceSessionId) : null;
4740
4962
  const sourceSessionMetadata = requestedSourceSessionMetadata ?? sourceRecord?.metadata ?? {};
4741
4963
  const agentRuntimeId = requestedAgentRuntimeId ?? readAgentRuntimeId(sourceSessionMetadata) ?? "native";
@@ -4745,7 +4967,7 @@ var SessionManager = class {
4745
4967
  metadata,
4746
4968
  peerId
4747
4969
  }) : void 0;
4748
- const requestedSessionId = readOptionalString$9(sessionId);
4970
+ const requestedSessionId = readOptionalString$10(sessionId);
4749
4971
  const created = await this.createSession({
4750
4972
  contextInheritance,
4751
4973
  parentSessionId: parentSessionId ?? void 0,
@@ -5928,14 +6150,14 @@ function parsePanelAppFolderManifest(raw) {
5928
6150
  throw new Error(`panel-app.json is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
5929
6151
  }
5930
6152
  if (!isRecord$6(parsed)) throw new Error("panel-app.json must contain an object.");
5931
- const id = readOptionalString$7(parsed, "id");
6153
+ const id = readOptionalString$8(parsed, "id");
5932
6154
  if (id && !PANEL_APP_ID_PATTERN.test(id)) throw new Error("panel app id must be kebab-case.");
5933
6155
  return {
5934
6156
  id,
5935
- title: readRequiredString$6(parsed, "title"),
5936
- description: readOptionalString$7(parsed, "description"),
5937
- icon: readOptionalString$7(parsed, "icon"),
5938
- entry: readRequiredString$6(parsed, "entry"),
6157
+ title: readRequiredString$7(parsed, "title"),
6158
+ description: readOptionalString$8(parsed, "description"),
6159
+ icon: readOptionalString$8(parsed, "icon"),
6160
+ entry: readRequiredString$7(parsed, "entry"),
5939
6161
  capabilities: readStringArray$1(parsed.capabilities, "capabilities"),
5940
6162
  client: readOptionalBoolean$2(parsed, "client"),
5941
6163
  serviceActions: readStringArray$1(parsed.actions, "actions")
@@ -5995,12 +6217,12 @@ function parseTokenList(content) {
5995
6217
  if (!content) return [];
5996
6218
  return [...new Set(content.split(/[,\s]+/).map((entry) => entry.trim()).filter(Boolean))];
5997
6219
  }
5998
- function readRequiredString$6(record, key) {
5999
- const value = readOptionalString$7(record, key);
6220
+ function readRequiredString$7(record, key) {
6221
+ const value = readOptionalString$8(record, key);
6000
6222
  if (!value) throw new Error(`panel app ${key} is required.`);
6001
6223
  return value;
6002
6224
  }
6003
- function readOptionalString$7(record, key) {
6225
+ function readOptionalString$8(record, key) {
6004
6226
  return typeof record[key] === "string" && record[key].trim() ? record[key].trim() : void 0;
6005
6227
  }
6006
6228
  function readOptionalBoolean$2(record, key) {
@@ -7147,17 +7369,17 @@ function parseServiceAppManifest(raw) {
7147
7369
  throw new Error(`service-app.json is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
7148
7370
  }
7149
7371
  if (!isRecord$4(parsed)) throw new Error("service-app.json must contain an object.");
7150
- const id = readRequiredString$5(parsed, "id");
7372
+ const id = readRequiredString$6(parsed, "id");
7151
7373
  if (!SERVICE_APP_ID_PATTERN.test(id)) throw new Error("service app id must be kebab-case.");
7152
- const protocol = readOptionalString$6(parsed, "protocol") ?? "mcp";
7374
+ const protocol = readOptionalString$7(parsed, "protocol") ?? "mcp";
7153
7375
  if (protocol !== "mcp") throw new Error("service app protocol must be mcp.");
7154
7376
  return {
7155
7377
  id,
7156
- title: readRequiredString$5(parsed, "title"),
7157
- description: readOptionalString$6(parsed, "description"),
7378
+ title: readRequiredString$6(parsed, "title"),
7379
+ description: readOptionalString$7(parsed, "description"),
7158
7380
  enabled: readOptionalBoolean$1(parsed, "enabled") ?? true,
7159
7381
  protocol,
7160
- command: readRequiredString$5(parsed, "command"),
7382
+ command: readRequiredString$6(parsed, "command"),
7161
7383
  args: readStringArray(parsed.args, "args"),
7162
7384
  actions: readManifestActions(parsed.actions)
7163
7385
  };
@@ -7170,25 +7392,25 @@ function readManifestActions(value) {
7170
7392
  for (const [name, action] of Object.entries(value)) {
7171
7393
  if (!name.trim()) throw new Error("service app action name cannot be empty.");
7172
7394
  if (!isRecord$4(action)) throw new Error(`service app action ${name} must be an object.`);
7173
- const risk = readOptionalString$6(action, "risk");
7395
+ const risk = readOptionalString$7(action, "risk");
7174
7396
  if (risk !== void 0 && !SERVICE_ACTION_RISKS.has(risk)) throw new Error(`service app action ${name} has invalid risk.`);
7175
7397
  const inputSchema = action.inputSchema;
7176
7398
  if (inputSchema !== void 0 && !isRecord$4(inputSchema)) throw new Error(`service app action ${name} inputSchema must be an object.`);
7177
7399
  actions[name] = {
7178
7400
  risk,
7179
- title: readOptionalString$6(action, "title"),
7180
- description: readOptionalString$6(action, "description"),
7401
+ title: readOptionalString$7(action, "title"),
7402
+ description: readOptionalString$7(action, "description"),
7181
7403
  inputSchema
7182
7404
  };
7183
7405
  }
7184
7406
  return actions;
7185
7407
  }
7186
- function readRequiredString$5(record, key) {
7187
- const value = readOptionalString$6(record, key);
7408
+ function readRequiredString$6(record, key) {
7409
+ const value = readOptionalString$7(record, key);
7188
7410
  if (!value) throw new Error(`service app ${key} is required.`);
7189
7411
  return value;
7190
7412
  }
7191
- function readOptionalString$6(record, key) {
7413
+ function readOptionalString$7(record, key) {
7192
7414
  return typeof record[key] === "string" && record[key].trim() ? record[key].trim() : void 0;
7193
7415
  }
7194
7416
  function readOptionalBoolean$1(record, key) {
@@ -9206,13 +9428,13 @@ var ProviderManagerNcpLLMApi = class {
9206
9428
  };
9207
9429
  //#endregion
9208
9430
  //#region src/features/native-runtime/tools/ncp-asset.tools.ts
9209
- function readOptionalString$5(value) {
9431
+ function readOptionalString$6(value) {
9210
9432
  if (typeof value !== "string") return null;
9211
9433
  const trimmed = value.trim();
9212
9434
  return trimmed.length > 0 ? trimmed : null;
9213
9435
  }
9214
9436
  function readOptionalBase64Bytes(value) {
9215
- const base64 = readOptionalString$5(value);
9437
+ const base64 = readOptionalString$6(value);
9216
9438
  if (!base64) return null;
9217
9439
  try {
9218
9440
  return Buffer.from(base64, "base64");
@@ -9263,18 +9485,18 @@ var AssetPutTool = class {
9263
9485
  this.contentBasePath = contentBasePath;
9264
9486
  }
9265
9487
  validateArgs = (args) => {
9266
- const path = readOptionalString$5(args.path);
9267
- const bytesBase64 = readOptionalString$5(args.bytesBase64);
9268
- const fileName = readOptionalString$5(args.fileName);
9488
+ const path = readOptionalString$6(args.path);
9489
+ const bytesBase64 = readOptionalString$6(args.bytesBase64);
9490
+ const fileName = readOptionalString$6(args.fileName);
9269
9491
  if (path && bytesBase64) return ["Provide either path, or bytesBase64 + fileName, not both."];
9270
9492
  if (path) return [];
9271
9493
  if (bytesBase64) return fileName ? [] : ["fileName is required when using bytesBase64."];
9272
9494
  return ["Provide either path, or bytesBase64 + fileName."];
9273
9495
  };
9274
9496
  execute = async (args) => {
9275
- const path = readOptionalString$5(args?.path);
9276
- const fileName = readOptionalString$5(args?.fileName);
9277
- const mimeType = readOptionalString$5(args?.mimeType);
9497
+ const path = readOptionalString$6(args?.path);
9498
+ const fileName = readOptionalString$6(args?.fileName);
9499
+ const mimeType = readOptionalString$6(args?.mimeType);
9278
9500
  const bytes = readOptionalBase64Bytes(args?.bytesBase64);
9279
9501
  if (path) return {
9280
9502
  ok: true,
@@ -9317,8 +9539,8 @@ var AssetExportTool = class {
9317
9539
  this.assetStore = assetStore;
9318
9540
  }
9319
9541
  execute = async (args) => {
9320
- const assetUri = readOptionalString$5(args?.assetUri);
9321
- const targetPath = readOptionalString$5(args?.targetPath);
9542
+ const assetUri = readOptionalString$6(args?.assetUri);
9543
+ const targetPath = readOptionalString$6(args?.targetPath);
9322
9544
  if (!assetUri || !targetPath) throw new Error("asset_export requires assetUri and targetPath.");
9323
9545
  return {
9324
9546
  ok: true,
@@ -9344,7 +9566,7 @@ var AssetStatTool = class {
9344
9566
  this.contentBasePath = contentBasePath;
9345
9567
  }
9346
9568
  execute = async (args) => {
9347
- const assetUri = readOptionalString$5(args?.assetUri);
9569
+ const assetUri = readOptionalString$6(args?.assetUri);
9348
9570
  if (!assetUri) throw new Error("asset_stat requires assetUri.");
9349
9571
  const record = await this.assetStore.statRecord(assetUri);
9350
9572
  if (!record) return {
@@ -9967,6 +10189,30 @@ var CurrentSessionContextProvider = class {
9967
10189
  };
9968
10190
  };
9969
10191
  //#endregion
10192
+ //#region src/contributions/context-provider/providers/inbox-delivery-context.provider.ts
10193
+ var InboxDeliveryContextProvider = class {
10194
+ constructor(deliveryManager, sessionManager) {
10195
+ this.deliveryManager = deliveryManager;
10196
+ this.sessionManager = sessionManager;
10197
+ }
10198
+ provide = async (request) => {
10199
+ if (!request.sessionId) return [];
10200
+ const rawDeliveryId = (await this.sessionManager.getSessionRecord(request.sessionId))?.metadata?.[INBOX_DELIVERY_SESSION_METADATA_KEY];
10201
+ if (typeof rawDeliveryId !== "string" || !rawDeliveryId.trim()) return [];
10202
+ const delivery = await this.deliveryManager.getDelivery(rawDeliveryId);
10203
+ if (!delivery) return [];
10204
+ const lines = [
10205
+ "## Inbox Delivery Context",
10206
+ "This chat was opened from a durable inbox delivery. Treat the following content as the shared subject for this conversation.",
10207
+ `Delivery ID: ${delivery.id}`,
10208
+ `Title: ${delivery.title}`
10209
+ ];
10210
+ if (delivery.summary) lines.push(`Summary: ${delivery.summary}`);
10211
+ lines.push("", "### Delivered content", delivery.content);
10212
+ return [lines.join("\n")];
10213
+ };
10214
+ };
10215
+ //#endregion
9970
10216
  //#region src/contributions/context-provider/providers/execution-policy-context.provider.ts
9971
10217
  function normalizeModel(model) {
9972
10218
  return model?.trim().toLowerCase() ?? "";
@@ -10783,6 +11029,7 @@ var ContextProviderContribution = class {
10783
11029
  new SkillsContextProvider(context),
10784
11030
  createSessionOrchestrationContextProvider(),
10785
11031
  new ExecutionPolicyContextProvider(context),
11032
+ new InboxDeliveryContextProvider(this.kernel.inboxDeliveryManager, this.kernel.sessionManager),
10786
11033
  new CurrentSessionContextProvider(context),
10787
11034
  new ReplyFormatContextProvider()
10788
11035
  ]) this.cleanups.push(this.kernel.contextProviderManager.register(provider));
@@ -11127,11 +11374,11 @@ var MessagingToolProvider = class {
11127
11374
  };
11128
11375
  //#endregion
11129
11376
  //#region src/tools/project.tools.ts
11130
- function readRequiredString$4(value, key) {
11377
+ function readRequiredString$5(value, key) {
11131
11378
  if (typeof value !== "string" || !value.trim()) throw new Error(`${key} must be a non-empty string.`);
11132
11379
  return value.trim();
11133
11380
  }
11134
- function readOptionalString$4(value) {
11381
+ function readOptionalString$5(value) {
11135
11382
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
11136
11383
  }
11137
11384
  var ProjectsListTool = class {
@@ -11182,9 +11429,9 @@ var ProjectsCreateTool = class {
11182
11429
  }
11183
11430
  execute = async (args) => {
11184
11431
  const params = normalizeToolParams(args);
11185
- const name = readRequiredString$4(params.name, "name");
11186
- const rootPath = readOptionalString$4(params.rootPath);
11187
- const template = readOptionalString$4(params.template);
11432
+ const name = readRequiredString$5(params.name, "name");
11433
+ const rootPath = readOptionalString$5(params.rootPath);
11434
+ const template = readOptionalString$5(params.template);
11188
11435
  return JSON.stringify(await this.projects.createProject({
11189
11436
  name,
11190
11437
  ...rootPath ? { rootPath } : {},
@@ -11335,12 +11582,12 @@ var SessionsHistoryTool = class {
11335
11582
  };
11336
11583
  //#endregion
11337
11584
  //#region src/tools/session-request.tools.ts
11338
- function readRequiredString$3(params, key) {
11585
+ function readRequiredString$4(params, key) {
11339
11586
  const value = params[key];
11340
11587
  if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${key} must be a non-empty string.`);
11341
11588
  return value.trim();
11342
11589
  }
11343
- function readOptionalString$3(params, key) {
11590
+ function readOptionalString$4(params, key) {
11344
11591
  const value = params[key];
11345
11592
  if (typeof value !== "string") return;
11346
11593
  const trimmed = value.trim();
@@ -11394,16 +11641,16 @@ var SessionRequestTool = class {
11394
11641
  const params = normalizeToolParams(args);
11395
11642
  const target = params.target;
11396
11643
  if (!target || typeof target !== "object" || Array.isArray(target)) throw new Error("target must be an object.");
11397
- const task = readRequiredString$3(params, "task");
11398
- const notifyMode = readOptionalString$3(params, "notify")?.toLowerCase();
11644
+ const task = readRequiredString$4(params, "task");
11645
+ const notifyMode = readOptionalString$4(params, "notify")?.toLowerCase();
11399
11646
  if (notifyMode !== "none" && notifyMode !== "final_reply") throw new Error("notify must be \"none\" or \"final_reply\".");
11400
11647
  return this.manager.requestSession({
11401
11648
  sourceSessionId: this.sourceSessionId,
11402
11649
  sourceToolCallId: context?.toolCallId,
11403
11650
  updateToolCallResult: context?.updateToolCallResult,
11404
- targetSessionId: readRequiredString$3(target, "session_id"),
11651
+ targetSessionId: readRequiredString$4(target, "session_id"),
11405
11652
  task,
11406
- title: readOptionalString$3(params, "title"),
11653
+ title: readOptionalString$4(params, "title"),
11407
11654
  notify: notifyMode,
11408
11655
  handoffDepth: this.handoffDepth
11409
11656
  });
@@ -11474,23 +11721,23 @@ var SessionSearchTool = class {
11474
11721
  };
11475
11722
  //#endregion
11476
11723
  //#region src/tools/session-spawn.tools.ts
11477
- function readRequiredString$2(value, key) {
11724
+ function readRequiredString$3(value, key) {
11478
11725
  if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${key} must be a non-empty string.`);
11479
11726
  return value.trim();
11480
11727
  }
11481
- function readOptionalString$2(value) {
11728
+ function readOptionalString$3(value) {
11482
11729
  if (typeof value !== "string") return;
11483
11730
  const trimmed = value.trim();
11484
11731
  return trimmed.length > 0 ? trimmed : void 0;
11485
11732
  }
11486
11733
  function readSpawnScope(value) {
11487
- const normalized = readOptionalString$2(value)?.toLowerCase();
11734
+ const normalized = readOptionalString$3(value)?.toLowerCase();
11488
11735
  if (!normalized || normalized === "standalone") return "standalone";
11489
11736
  if (normalized === "child") return "child";
11490
11737
  throw new Error("scope must be \"standalone\" or \"child\".");
11491
11738
  }
11492
11739
  function readSpawnNotify(value) {
11493
- const notifyMode = readOptionalString$2(value)?.toLowerCase();
11740
+ const notifyMode = readOptionalString$3(value)?.toLowerCase();
11494
11741
  if (!notifyMode && typeof value === "undefined") return;
11495
11742
  if (notifyMode === "none" || notifyMode === "final_reply") return notifyMode;
11496
11743
  throw new Error("notify must be \"none\" or \"final_reply\".");
@@ -11558,7 +11805,7 @@ var SessionSpawnTool = class {
11558
11805
  };
11559
11806
  execute = async (args, context) => {
11560
11807
  const { agentId: rawAgentId, model: rawModel, notify: rawNotify, runtime: rawRuntime, scope: rawScope, task: rawTask, title: rawTitle, inheritContext: rawInheritContext } = normalizeToolParams(args);
11561
- const task = readRequiredString$2(rawTask, "task");
11808
+ const task = readRequiredString$3(rawTask, "task");
11562
11809
  const scope = readSpawnScope(rawScope);
11563
11810
  const notify = readSpawnNotify(rawNotify);
11564
11811
  const inheritContext = readInheritContext(rawInheritContext);
@@ -11571,10 +11818,10 @@ var SessionSpawnTool = class {
11571
11818
  updateToolCallResult: context?.updateToolCallResult,
11572
11819
  sourceSessionMetadata: this.sourceSessionMetadata,
11573
11820
  task,
11574
- title: readOptionalString$2(rawTitle),
11575
- agentId: readOptionalString$2(rawAgentId),
11576
- model: readOptionalString$2(rawModel),
11577
- runtime: readOptionalString$2(rawRuntime),
11821
+ title: readOptionalString$3(rawTitle),
11822
+ agentId: readOptionalString$3(rawAgentId),
11823
+ model: readOptionalString$3(rawModel),
11824
+ runtime: readOptionalString$3(rawRuntime),
11578
11825
  contextInheritance,
11579
11826
  handoffDepth: this.handoffDepth,
11580
11827
  parentSessionId,
@@ -11583,11 +11830,11 @@ var SessionSpawnTool = class {
11583
11830
  const session = await this.sessionManager.createSession({
11584
11831
  sourceSessionId: this.sourceSessionId,
11585
11832
  task,
11586
- title: readOptionalString$2(rawTitle),
11833
+ title: readOptionalString$3(rawTitle),
11587
11834
  sourceSessionMetadata: this.sourceSessionMetadata,
11588
- agentId: readOptionalString$2(rawAgentId),
11589
- model: readOptionalString$2(rawModel),
11590
- runtime: readOptionalString$2(rawRuntime),
11835
+ agentId: readOptionalString$3(rawAgentId),
11836
+ model: readOptionalString$3(rawModel),
11837
+ runtime: readOptionalString$3(rawRuntime),
11591
11838
  contextInheritance,
11592
11839
  parentSessionId
11593
11840
  });
@@ -11611,7 +11858,7 @@ var SessionSpawnTool = class {
11611
11858
  };
11612
11859
  //#endregion
11613
11860
  //#region src/tools/session-update.tools.ts
11614
- function readRequiredString$1(value, key) {
11861
+ function readRequiredString$2(value, key) {
11615
11862
  if (typeof value !== "string" || !value.trim()) throw new Error(`${key} must be a non-empty string.`);
11616
11863
  return value.trim();
11617
11864
  }
@@ -11642,10 +11889,10 @@ var SessionsUpdateTool = class {
11642
11889
  }
11643
11890
  execute = async (args) => {
11644
11891
  const params = normalizeToolParams(args);
11645
- const sessionKey = readRequiredString$1(params.sessionKey, "sessionKey");
11892
+ const sessionKey = readRequiredString$2(params.sessionKey, "sessionKey");
11646
11893
  const patch = {};
11647
- if (Object.prototype.hasOwnProperty.call(params, "label")) patch.label = readRequiredString$1(params.label, "label");
11648
- if (Object.prototype.hasOwnProperty.call(params, "projectRoot")) patch.projectRoot = readRequiredString$1(params.projectRoot, "projectRoot");
11894
+ if (Object.prototype.hasOwnProperty.call(params, "label")) patch.label = readRequiredString$2(params.label, "label");
11895
+ if (Object.prototype.hasOwnProperty.call(params, "projectRoot")) patch.projectRoot = readRequiredString$2(params.projectRoot, "projectRoot");
11649
11896
  if (patch.label === void 0 && patch.projectRoot === void 0) throw new Error("label or projectRoot is required.");
11650
11897
  const session = await this.sessions.patchSessionSettings(sessionKey, patch);
11651
11898
  if (!session) throw new Error(`Session not found: ${sessionKey}`);
@@ -11701,11 +11948,11 @@ const FILE_VIEWERS = [
11701
11948
  "source",
11702
11949
  "rendered"
11703
11950
  ];
11704
- function readRequiredString(value, key) {
11951
+ function readRequiredString$1(value, key) {
11705
11952
  if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${key} must be a non-empty string.`);
11706
11953
  return value.trim();
11707
11954
  }
11708
- function readOptionalString$1(value) {
11955
+ function readOptionalString$2(value) {
11709
11956
  if (typeof value !== "string") return;
11710
11957
  return value.trim() || void 0;
11711
11958
  }
@@ -11715,14 +11962,14 @@ function readOptionalPositiveInteger(value, key) {
11715
11962
  return value;
11716
11963
  }
11717
11964
  function readOptionalEnum(value, key, allowed) {
11718
- const normalized = readOptionalString$1(value);
11965
+ const normalized = readOptionalString$2(value);
11719
11966
  if (!normalized) return;
11720
11967
  if (allowed.includes(normalized)) return normalized;
11721
11968
  const expected = allowed.map((item) => `"${item}"`).join(", ");
11722
11969
  throw new Error(`${key} must be ${expected}.`);
11723
11970
  }
11724
11971
  function readUrl(value) {
11725
- const url = readRequiredString(value, "url");
11972
+ const url = readRequiredString$1(value, "url");
11726
11973
  let parsed;
11727
11974
  try {
11728
11975
  parsed = new URL(url);
@@ -11734,13 +11981,13 @@ function readUrl(value) {
11734
11981
  }
11735
11982
  function readCommonRequestFields(params, allowedPurposes) {
11736
11983
  return {
11737
- title: readOptionalString$1(params.title),
11984
+ title: readOptionalString$2(params.title),
11738
11985
  purpose: readOptionalEnum(params.purpose, "purpose", allowedPurposes)
11739
11986
  };
11740
11987
  }
11741
11988
  function normalizeShowFileArgs(args) {
11742
11989
  const params = normalizeToolParams(args);
11743
- const path = readRequiredString(params.path, "path");
11990
+ const path = readRequiredString$1(params.path, "path");
11744
11991
  const viewer = readOptionalEnum(params.viewer, "viewer", FILE_VIEWERS) ?? "auto";
11745
11992
  const contentParams = readUiContentParams(params.params);
11746
11993
  if (contentParams && (viewer === "source" || !/\.html?$/i.test(path))) throw new Error("params are supported only for rendered HTML file previews.");
@@ -11770,14 +12017,14 @@ function normalizeShowUrlArgs(args) {
11770
12017
  }
11771
12018
  function normalizeShowPanelAppArgs(args) {
11772
12019
  const params = normalizeToolParams(args);
11773
- const path = readOptionalString$1(params.path);
12020
+ const path = readOptionalString$2(params.path);
11774
12021
  const contentParams = readUiContentParams(params.params);
11775
12022
  if (path && !isAbsolute(path)) throw new Error("path must be an absolute path.");
11776
12023
  return {
11777
12024
  target: {
11778
12025
  type: "panel_app",
11779
12026
  payload: {
11780
- appId: readRequiredString(params.appId, "appId"),
12027
+ appId: readRequiredString$1(params.appId, "appId"),
11781
12028
  path,
11782
12029
  params: contentParams
11783
12030
  }
@@ -11791,7 +12038,7 @@ function summarizeTarget(target) {
11791
12038
  return target.payload.appId;
11792
12039
  }
11793
12040
  function createShowContentEventPayload(request, context) {
11794
- const toolCallId = readOptionalString$1(context?.toolCallId);
12041
+ const toolCallId = readOptionalString$2(context?.toolCallId);
11795
12042
  return {
11796
12043
  id: toolCallId ? `tool:${toolCallId}:show-content` : `show-content:${request.target.type}:${summarizeTarget(request.target)}`,
11797
12044
  toolCallId,
@@ -11941,6 +12188,119 @@ var ShowContentToolProvider = class {
11941
12188
  provide = () => createShowContentTools(this.eventBus);
11942
12189
  };
11943
12190
  //#endregion
12191
+ //#region src/tools/inbox-delivery.tools.ts
12192
+ function readRequiredString(value, key) {
12193
+ if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${key} must be a non-empty string.`);
12194
+ return value.trim();
12195
+ }
12196
+ function readOptionalString$1(value) {
12197
+ if (typeof value !== "string") return null;
12198
+ return value.trim() || null;
12199
+ }
12200
+ function readContentType(value) {
12201
+ if (value === void 0 || value === null) return null;
12202
+ if (value !== "markdown" && value !== "html") throw new Error("contentType must be markdown or html.");
12203
+ return value;
12204
+ }
12205
+ function normalizeRequest(args) {
12206
+ const params = normalizeToolParams(args);
12207
+ const content = readOptionalString$1(params.content);
12208
+ const filePath = readOptionalString$1(params.filePath);
12209
+ if (Boolean(content) === Boolean(filePath)) throw new Error("exactly one of content or filePath must be provided.");
12210
+ if (filePath && !isAbsolute(filePath)) throw new Error("filePath must be an absolute path.");
12211
+ const requestedContentType = readContentType(params.contentType);
12212
+ return {
12213
+ title: readRequiredString(params.title, "title"),
12214
+ summary: readOptionalString$1(params.summary),
12215
+ content,
12216
+ contentType: requestedContentType ?? (filePath && [".htm", ".html"].includes(extname(filePath).toLowerCase()) ? "html" : "markdown"),
12217
+ filePath
12218
+ };
12219
+ }
12220
+ var DeliverToInboxTool = class {
12221
+ name = "deliver_to_inbox";
12222
+ description = "Deliver a durable Markdown or static HTML report, recommendation, or article to the user's NextClaw inbox. Use content for direct text or filePath to snapshot a local UTF-8 text file. Set contentType for direct HTML; .html and .htm files are detected automatically. The user can read it later and continue in a new chat.";
12223
+ parameters = {
12224
+ type: "object",
12225
+ properties: {
12226
+ title: {
12227
+ type: "string",
12228
+ description: "Concise user-facing title, at most 160 characters."
12229
+ },
12230
+ summary: {
12231
+ type: "string",
12232
+ description: "Optional one-paragraph summary, at most 500 characters."
12233
+ },
12234
+ content: {
12235
+ type: "string",
12236
+ description: "Markdown or static HTML content. Provide exactly one of content or filePath."
12237
+ },
12238
+ contentType: {
12239
+ type: "string",
12240
+ enum: ["markdown", "html"],
12241
+ description: "Content format. Defaults to HTML for .html/.htm files and Markdown otherwise."
12242
+ },
12243
+ filePath: {
12244
+ type: "string",
12245
+ description: "Absolute path to a UTF-8 Markdown, HTML, or text file to snapshot."
12246
+ }
12247
+ },
12248
+ required: ["title"],
12249
+ additionalProperties: false
12250
+ };
12251
+ constructor(manager, source) {
12252
+ this.manager = manager;
12253
+ this.source = source;
12254
+ }
12255
+ execute = async (args, context) => {
12256
+ const request = normalizeRequest(args);
12257
+ const content = request.content ?? await this.readFileContent(request.filePath);
12258
+ const delivery = await this.manager.createDelivery({
12259
+ title: request.title,
12260
+ summary: request.summary,
12261
+ content,
12262
+ contentType: request.contentType,
12263
+ source: {
12264
+ kind: "agent",
12265
+ agentId: this.source.agentId,
12266
+ sessionId: this.source.sessionId,
12267
+ toolCallId: readOptionalString$1(context?.toolCallId),
12268
+ filePath: request.filePath
12269
+ }
12270
+ });
12271
+ return {
12272
+ ok: true,
12273
+ deliveryId: delivery.id,
12274
+ title: delivery.title
12275
+ };
12276
+ };
12277
+ readFileContent = async (filePath) => {
12278
+ const file = await stat(filePath);
12279
+ if (!file.isFile()) throw new Error("filePath must point to a regular file.");
12280
+ if (file.size > 524288) throw new Error(`filePath must be at most ${MAX_INBOX_DELIVERY_CONTENT_LENGTH} bytes.`);
12281
+ try {
12282
+ return new TextDecoder("utf-8", { fatal: true }).decode(await readFile(filePath));
12283
+ } catch (error) {
12284
+ if (error instanceof TypeError) throw new Error("filePath must contain valid UTF-8 text.");
12285
+ throw error;
12286
+ }
12287
+ };
12288
+ };
12289
+ function createInboxDeliveryTools(manager, source) {
12290
+ return [new DeliverToInboxTool(manager, source)];
12291
+ }
12292
+ //#endregion
12293
+ //#region src/contributions/tool-provider/providers/inbox-delivery-tool.provider.ts
12294
+ var InboxDeliveryToolProvider = class {
12295
+ constructor(manager) {
12296
+ this.manager = manager;
12297
+ }
12298
+ provide = (request) => createInboxDeliveryTools(this.manager, {
12299
+ agentId: request.agentId ?? null,
12300
+ sessionId: request.sessionId ?? null
12301
+ });
12302
+ };
12303
+ //#endregion
11944
12304
  //#region src/contributions/tool-provider/providers/structured-result-tool.provider.ts
11945
12305
  var StructuredResultToolProvider = class {
11946
12306
  provide = (request) => {
@@ -12015,6 +12375,7 @@ var ToolProviderContribution = class {
12015
12375
  return [
12016
12376
  new StructuredResultToolProvider(),
12017
12377
  new ShowContentToolProvider(this.kernel.eventBus),
12378
+ new InboxDeliveryToolProvider(this.kernel.inboxDeliveryManager),
12018
12379
  new CoreToolProvider(runContextService, this.kernel.getGatewayController),
12019
12380
  new MessagingToolProvider(runContextService, this.kernel.channels, this.kernel.automation, this.kernel.extensions),
12020
12381
  new ProjectToolProvider(this.kernel.projectManager),
@@ -12046,6 +12407,11 @@ function resolveKernelProjectStorePath(options) {
12046
12407
  if (homeDir) return resolve(expandHome(homeDir), "projects", "projects.json");
12047
12408
  return resolve(getDataDir(), "projects", "projects.json");
12048
12409
  }
12410
+ function resolveKernelInboxDeliveryStorePath(options) {
12411
+ const homeDir = options.homeDir?.trim();
12412
+ if (homeDir) return resolve(expandHome(homeDir), "inbox", "deliveries.json");
12413
+ return resolve(getDataDir(), "inbox", "deliveries.json");
12414
+ }
12049
12415
  var NextclawKernelControlManager = class {
12050
12416
  runtimeControl = null;
12051
12417
  installRuntimeControl = (runtimeControl) => {
@@ -12074,6 +12440,7 @@ var NextclawKernel = class {
12074
12440
  assetStore;
12075
12441
  mcpManager;
12076
12442
  sessionManager;
12443
+ inboxDeliveryManager;
12077
12444
  panelAppManager;
12078
12445
  preferenceManager;
12079
12446
  projectManager;
@@ -12122,6 +12489,11 @@ var NextclawKernel = class {
12122
12489
  projectManager: this.projectManager,
12123
12490
  sessionSearch: this.sessionSearch
12124
12491
  });
12492
+ this.inboxDeliveryManager = new InboxDeliveryManager({
12493
+ eventBus: this.eventBus,
12494
+ sessionManager: this.sessionManager,
12495
+ storePath: resolveKernelInboxDeliveryStorePath(options)
12496
+ });
12125
12497
  this.panelAppManager = new PanelAppManager({
12126
12498
  configManager: this.configManager,
12127
12499
  eventBus: this.eventBus,
@@ -12760,6 +13132,6 @@ function resolveLegacyEventType(message) {
12760
13132
  return `message.${role || "other"}`;
12761
13133
  }
12762
13134
  //#endregion
12763
- export { AUTOMATIC_UPDATE_CHECK_INTERVAL_MS, AccessManager, AgentManager, AgentRunClient, AutomationManager, BuiltinNarpRuntimeProviderService, CONTEXT_COMPACTION_PROJECTION_KIND, CONTEXT_COMPACTION_PROJECTION_METADATA_KEY, CONTEXT_COMPACTION_TIMELINE_KIND, ChannelManager, CommandRegistry, ConfigManager, ContextCompactionPreflightService, ContextWindowPreviewManager, DEFAULT_AGENT_RUNTIME_ENTRY_ID, DEFAULT_SERVICE_ACTION_RISK, ExtensionManager, GatewayInboundProcessor, LlmProviderManager, LlmUsageManager, LlmUsageStore, McpManager, McpServiceAppRuntimeService, NARP_HTTP_RUNTIME_KIND, NARP_STDIO_RUNTIME_KIND, NEXTCLAW_TIMELINE_KIND_METADATA_KEY, NcpAgentSessionJournalStore, NextclawKernel, PANEL_APP_AGENT_CAPABILITIES, PROJECT_TEMPLATE_IDS, PanelAppAssetTokenService, PanelAppError, PanelAppManager, PreferenceError, PreferenceManager, ProjectError, ProjectManager, ProviderManagerNcpLLMApi, SERVICE_APP_MANIFEST_FILE_NAME, ServiceAppError, ServiceAppManager, SessionContextCompactionError, SessionContextCompactionManager, SessionManager, SessionMessageCursorError, SessionRequestManager, SessionSettingsError, SkillManager, UpdateManifestReader, buildAgentRunSendPayload, buildContextCompactionModelInput, buildContextCompactionTimelineNcpMessage, buildLlmUsageSummary, buildLocalizedTextMap, buildNextclawNcpRunContext, buildServiceActionId, createAgentRuntimeSessionRequestDispatcher, createAssetTools, createContextCompactionMessageId, createContextWindowSignature, createLlmUsageRecord, describeAgentRuntimeSessionTypes, dispatchAgentRuntimeSessionRequest, dispatchChannelReplyRoute, dispatchPromptOverNcp, getAutomaticUpdateCheckDelay, getServiceActionName, getServiceAppManifestPath, getUiContentParamsBootstrapScript, getUnsignedUpdateManifest, hasLlmUsageTelemetry, injectUiContentParamsBootstrap, isContextCompactionProjectionMessage, isContextCompactionTimelineMessage, isContextWindowSnapshot, isPanelAppAgentCapability, isPanelAppError, isPreferenceError, isProjectError, isReplyCapableChannel, isServiceAppError, isSessionContextCompactionError, isSessionMessageCursorError, isSessionSettingsError, listExtensionChannelIds, listServiceAppManifestActions, mergeServiceAppRuntimeActions, normalizeAgentRuntimeSessionTypeIcon, normalizeLlmUsageModel, normalizeOptionalString, parseServiceAppManifest, parseSkillFrontmatter, readContextWindowEventSessionId, readLatestContextCompactionCheckpoint, readLearningLoopRuntimeConfig, readMetadataModel, readMetadataThinking, readServiceAppManifest, resolveAgentRuntimeEntries, resolveAutomaticUpdateCheckIntervalMs, resolveChannelReplyRoute, resolveEffectiveModel, resolveLegacyEventType, resolveSessionChannelContext, runGatewayInboundLoop, sanitizeLlmUsage, serializeUnsignedUpdateManifest, shouldRefreshContextWindowDuringStream, shouldRefreshContextWindowImmediately, stripSkillFrontmatter, syncSessionThinkingPreference, toNcpMessages, waitForAgentRuntimeSessionReply };
13135
+ export { AUTOMATIC_UPDATE_CHECK_INTERVAL_MS, AccessManager, AgentManager, AgentRunClient, AutomationManager, BuiltinNarpRuntimeProviderService, CONTEXT_COMPACTION_PROJECTION_KIND, CONTEXT_COMPACTION_PROJECTION_METADATA_KEY, CONTEXT_COMPACTION_TIMELINE_KIND, ChannelManager, CommandRegistry, ConfigManager, ContextCompactionPreflightService, ContextWindowPreviewManager, 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, PanelAppAssetTokenService, PanelAppError, PanelAppManager, PreferenceError, PreferenceManager, ProjectError, ProjectManager, ProviderManagerNcpLLMApi, SERVICE_APP_MANIFEST_FILE_NAME, ServiceAppError, ServiceAppManager, SessionContextCompactionError, SessionContextCompactionManager, SessionManager, SessionMessageCursorError, SessionRequestManager, SessionSettingsError, SkillManager, UpdateManifestReader, buildAgentRunSendPayload, buildContextCompactionModelInput, buildContextCompactionTimelineNcpMessage, buildLlmUsageSummary, buildLocalizedTextMap, buildNextclawNcpRunContext, buildServiceActionId, createAgentRuntimeSessionRequestDispatcher, createAssetTools, createContextCompactionMessageId, createContextWindowSignature, createLlmUsageRecord, describeAgentRuntimeSessionTypes, dispatchAgentRuntimeSessionRequest, dispatchChannelReplyRoute, dispatchPromptOverNcp, getAutomaticUpdateCheckDelay, getServiceActionName, getServiceAppManifestPath, getUiContentParamsBootstrapScript, getUnsignedUpdateManifest, hasLlmUsageTelemetry, injectUiContentParamsBootstrap, isContextCompactionProjectionMessage, isContextCompactionTimelineMessage, isContextWindowSnapshot, isInboxDeliveryError, isPanelAppAgentCapability, isPanelAppError, isPreferenceError, isProjectError, isReplyCapableChannel, isServiceAppError, isSessionContextCompactionError, isSessionMessageCursorError, isSessionSettingsError, listExtensionChannelIds, listServiceAppManifestActions, mergeServiceAppRuntimeActions, normalizeAgentRuntimeSessionTypeIcon, normalizeLlmUsageModel, normalizeOptionalString, parseServiceAppManifest, parseSkillFrontmatter, readContextWindowEventSessionId, readLatestContextCompactionCheckpoint, readLearningLoopRuntimeConfig, readMetadataModel, readMetadataThinking, readServiceAppManifest, resolveAgentRuntimeEntries, resolveAutomaticUpdateCheckIntervalMs, resolveChannelReplyRoute, resolveEffectiveModel, resolveLegacyEventType, resolveSessionChannelContext, runGatewayInboundLoop, sanitizeLlmUsage, serializeUnsignedUpdateManifest, shouldRefreshContextWindowDuringStream, shouldRefreshContextWindowImmediately, stripSkillFrontmatter, syncSessionThinkingPreference, toNcpMessages, waitForAgentRuntimeSessionReply };
12764
13136
 
12765
13137
  //# sourceMappingURL=index.js.map