eve 0.79.2 → 0.80.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.
Files changed (119) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/src/compiled/.vendor-stamp.json +6 -6
  3. package/dist/src/compiled/@chat-adapter/slack/api.d.ts +6 -0
  4. package/dist/src/compiled/@chat-adapter/slack/api.js +1 -1
  5. package/dist/src/compiled/@chat-adapter/slack/blocks.js +1 -1
  6. package/dist/src/compiled/@chat-adapter/slack/format.js +1 -1
  7. package/dist/src/compiled/@chat-adapter/slack/index.d.ts +14 -8
  8. package/dist/src/compiled/@chat-adapter/slack/index.js +33 -32
  9. package/dist/src/compiled/@chat-adapter/twilio/index.d.ts +37 -1
  10. package/dist/src/compiled/@chat-adapter/twilio/index.js +2 -2
  11. package/dist/src/compiled/@linqapp/chat-sdk-adapter/index.js +1 -1
  12. package/dist/src/compiled/@photon-ai/chat-adapter-imessage/index.js +1 -1
  13. package/dist/src/compiled/@vercel/connect/index.js +5 -5
  14. package/dist/src/compiled/@vercel/connect/token.d.ts +11 -1
  15. package/dist/src/compiled/_chunks/node/chunk-NBSLXVG3-Bt7pDfyn.js +12 -0
  16. package/dist/src/compiled/_chunks/node/dist-BKsV21Vu.js +6 -0
  17. package/dist/src/compiled/_chunks/node/dist-CO_n_hUa.js +98 -0
  18. package/dist/src/compiled/chat/index.js +1 -1
  19. package/dist/src/compiler/extension-compatibility.d.ts +6 -6
  20. package/dist/src/compiler/extension-compatibility.js +1 -1
  21. package/dist/src/compiler/manifest.d.ts +8 -4
  22. package/dist/src/compiler/manifest.js +1 -1
  23. package/dist/src/compiler/normalize-connection.js +1 -1
  24. package/dist/src/compiler/normalize-manifest.js +1 -1
  25. package/dist/src/context/schedule-collection-tools.js +1 -1
  26. package/dist/src/execution/catalog/connection-auth.d.ts +4 -2
  27. package/dist/src/execution/catalog/connection-auth.js +1 -1
  28. package/dist/src/execution/catalog/connection-entry.js +1 -1
  29. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  30. package/dist/src/execution/session/entry.js +1 -1
  31. package/dist/src/execution/session-event-stream.js +1 -1
  32. package/dist/src/execution/stable-workflow-names.d.ts +2 -0
  33. package/dist/src/execution/stable-workflow-names.js +1 -1
  34. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  35. package/dist/src/execution/web-fetch/execute.js +1 -1
  36. package/dist/src/execution/workflow-runtime.d.ts +6 -0
  37. package/dist/src/execution/workflow-runtime.js +1 -1
  38. package/dist/src/extensions/git/extension/extension.d.ts +3 -1
  39. package/dist/src/extensions/git/extension/extension.js +1 -1
  40. package/dist/src/extensions/git/extension/lib/gh-tool.js +1 -1
  41. package/dist/src/extensions/git/extension/lib/github-shell.d.ts +14 -0
  42. package/dist/src/extensions/git/extension/lib/github-shell.js +1 -1
  43. package/dist/src/harness/model-call/call.js +1 -1
  44. package/dist/src/harness/model-call/errors.d.ts +2 -2
  45. package/dist/src/harness/model-call/recovery.d.ts +2 -3
  46. package/dist/src/instrumentation/session-init.d.ts +2 -1
  47. package/dist/src/instrumentation/session-init.js +1 -1
  48. package/dist/src/internal/application/stamped-package-version.js +1 -1
  49. package/dist/src/internal/authored-definition/connection.js +1 -1
  50. package/dist/src/internal/authored-definition/schedule-collection.js +1 -1
  51. package/dist/src/internal/nitro/host/application-route-registry.d.ts +7 -2
  52. package/dist/src/internal/nitro/host/application-route-registry.js +1 -1
  53. package/dist/src/internal/nitro/host/configure-nitro-routes.js +1 -1
  54. package/dist/src/internal/nitro/routes/channel-request-instrumentation.d.ts +3 -1
  55. package/dist/src/internal/nitro/routes/channel-request-instrumentation.js +1 -1
  56. package/dist/src/internal/nitro/routes/connection-events.d.ts +5 -0
  57. package/dist/src/internal/nitro/routes/connection-events.js +1 -0
  58. package/dist/src/internal/workflow-bundle/builder.js +1 -1
  59. package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.js +1 -1
  60. package/dist/src/public/channels/slack/blocks.js +2 -2
  61. package/dist/src/public/connections/index.d.ts +1 -0
  62. package/dist/src/public/definitions/connections/events.d.ts +43 -0
  63. package/dist/src/public/definitions/connections/events.js +1 -0
  64. package/dist/src/public/definitions/connections/mcp.d.ts +3 -0
  65. package/dist/src/public/schedules/subscription.d.ts +4 -3
  66. package/dist/src/runtime/connections/events/actions.d.ts +17 -0
  67. package/dist/src/runtime/connections/events/actions.js +1 -0
  68. package/dist/src/runtime/connections/events/delivery.d.ts +10 -0
  69. package/dist/src/runtime/connections/events/delivery.js +1 -0
  70. package/dist/src/runtime/connections/events/dispatch-step.d.ts +20 -0
  71. package/dist/src/runtime/connections/events/dispatch-step.js +1 -0
  72. package/dist/src/runtime/connections/events/lifecycle-step.d.ts +42 -0
  73. package/dist/src/runtime/connections/events/lifecycle-step.js +1 -0
  74. package/dist/src/runtime/connections/events/owner.d.ts +38 -0
  75. package/dist/src/runtime/connections/events/owner.js +1 -0
  76. package/dist/src/runtime/connections/events/path.d.ts +4 -0
  77. package/dist/src/runtime/connections/events/path.js +1 -0
  78. package/dist/src/runtime/connections/events/state.d.ts +37 -0
  79. package/dist/src/runtime/connections/events/state.js +1 -0
  80. package/dist/src/runtime/connections/events/workflow.d.ts +28 -0
  81. package/dist/src/runtime/connections/events/workflow.js +1 -0
  82. package/dist/src/runtime/connections/mcp-client.d.ts +4 -2
  83. package/dist/src/runtime/connections/mcp-client.js +1 -1
  84. package/dist/src/runtime/connections/openapi-client.js +1 -1
  85. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  86. package/dist/src/runtime/resolve-connection.js +1 -1
  87. package/dist/src/runtime/schedules/collection-client.d.ts +0 -2
  88. package/dist/src/runtime/schedules/collection-client.js +1 -1
  89. package/dist/src/runtime/types.d.ts +11 -0
  90. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  91. package/dist/src/setup/scaffold/create/project.js +2 -2
  92. package/dist/src/setup/scaffold/update/channels.js +1 -1
  93. package/dist/src/setup/scaffold/update/connections.js +2 -2
  94. package/dist/src/setup/scaffold/version-tokens.d.ts +1 -1
  95. package/dist/src/setup/scaffold/version-tokens.js +1 -1
  96. package/dist/src/shared/agent-definition.d.ts +12 -4
  97. package/dist/src/shared/connection-events.d.ts +84 -0
  98. package/dist/src/shared/connection-events.js +1 -0
  99. package/dist/src/shared/connection-types.d.ts +10 -0
  100. package/dist/src/shared/validate-authorization.js +1 -1
  101. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  102. package/dist/src/tools/provided/no-reply.d.ts +5 -0
  103. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  104. package/dist/src/tracing/eve/connection-events.d.ts +25 -0
  105. package/dist/src/tracing/eve/connection-events.js +1 -0
  106. package/dist/src/tracing/eve/install-instrumentation-runtime.js +1 -1
  107. package/dist/src/tracing/eve/mcp.d.ts +1 -0
  108. package/dist/src/tracing/eve/mcp.js +1 -1
  109. package/dist/src/tracing/eve/otel-declaration.d.ts +5 -0
  110. package/docs/agent-config.md +38 -13
  111. package/docs/code-extension.mdx +28 -0
  112. package/docs/concepts/built-in-tools.md +2 -0
  113. package/docs/connections/mcp.mdx +105 -0
  114. package/docs/guides/instrumentation/otel.mdx +10 -0
  115. package/docs/sandbox/vercel.mdx +46 -0
  116. package/package.json +7 -7
  117. package/dist/src/compiled/_chunks/node/chunk-6QHBXN7B-gl4n6nmi.js +0 -12
  118. package/dist/src/compiled/_chunks/node/dist-DYDVZ-FS.js +0 -98
  119. package/dist/src/compiled/_chunks/node/dist-iEFkK9qw.js +0 -6
@@ -205,6 +205,111 @@ An MCP tool call returns the tool's `structuredContent` when the server sends it
205
205
 
206
206
  When a remote tool returns more data than the model needs, narrow the result at the MCP server. Prefer a purpose-built search or summary tool, or return a stable handle that another call can use to fetch a smaller slice. If you do not control the server and an equivalent upstream API is available, replace only that operation with an authored tool that stores the full payload outside model context and projects the needed fields through `toModelOutput`. Block the original MCP operation through [`tools.block`](#tool-filters) so the model does not see duplicate tools.
207
207
 
208
+ ## Events (experimental)
209
+
210
+ An MCP connection can watch the server's events and run your code when one arrives. Vercel Connect holds the upstream subscription and forwards each event to your agent; eve runs your callback.
211
+
212
+ Requirements:
213
+
214
+ - A statically authored MCP connection with a static `connect()` auth provider. Dynamic connections and auth resolvers are not supported.
215
+ - `@vercel/connect@2.5.2` or later.
216
+ - An MCP server that supports events over Streamable HTTP.
217
+
218
+ ### Handle events
219
+
220
+ Add `experimental_events` to the connection. In this example, a user asks the agent to "watch the support inbox and draft replies to new bug reports". The model subscribes to Bird's `email_mailbox.message_received` event for that mailbox. Each new email then starts a turn in the same conversation, with instructions to triage it:
221
+
222
+ ```ts title="agent/connections/bird.ts"
223
+ import { connect } from "@vercel/connect/eve";
224
+ import { defineMcpClientConnection } from "eve/connections";
225
+
226
+ export default defineMcpClientConnection({
227
+ url: "https://mcp.bird.com/",
228
+ description: "Bird: email, SMS, and contacts. Can watch a mailbox for new mail.",
229
+ auth: connect("bird/bird"),
230
+ experimental_events: {
231
+ async onEvent({ event, origin, auth, attachSession }) {
232
+ if (event.name !== "email_mailbox.message_received") return;
233
+ await attachSession(origin.sessionId).send(
234
+ [
235
+ "A new email arrived in the mailbox you are watching:",
236
+ JSON.stringify(event.data),
237
+ "If it is a bug report, look up the sender's earlier threads, draft a reply " +
238
+ "that says what we know and what happens next, and ask me before sending it. " +
239
+ "Otherwise, summarize it in one line.",
240
+ ].join("\n\n"),
241
+ { auth, turnPolicy: "queue" },
242
+ );
243
+ },
244
+ },
245
+ });
246
+ ```
247
+
248
+ The model does the work with the connection's own tools: it reads the thread, drafts the reply, and waits for the user's approval in the conversation. `turnPolicy: "queue"` lets a burst of emails run one turn after another instead of interrupting the user.
249
+
250
+ `onEvent` is required. Defining it does not subscribe to anything: the model subscribes at runtime.
251
+
252
+ Callbacks run outside any conversation, as the user who subscribed (`auth`). Nothing enters a session unless you call `attachSession(sessionId).send(...)`, and `attachSession` never creates a session.
253
+
254
+ Each delivery runs in its own durable workflow, so callbacks can run concurrently, out of order, and more than once. Use `deliveryId` to deduplicate side effects:
255
+
256
+ ```ts
257
+ async onEvent({ event, deliveryId }) {
258
+ await fetch("https://crm.example/notes", {
259
+ method: "POST",
260
+ headers: { "Idempotency-Key": deliveryId },
261
+ body: JSON.stringify(event.data),
262
+ });
263
+ },
264
+ ```
265
+
266
+ ### Handle missed events and ended subscriptions
267
+
268
+ ```ts
269
+ experimental_events: {
270
+ async onEvent({ event }) {
271
+ // ...
272
+ },
273
+ async onGap({ origin, auth, attachSession }) {
274
+ // The server could not deliver every event. Re-read the source.
275
+ await attachSession(origin.sessionId).send(
276
+ "Some Bird events were missed. Re-check the mailbox.",
277
+ { auth },
278
+ );
279
+ },
280
+ async onTerminated({ origin, auth, error, attachSession }) {
281
+ // The upstream subscription ended. The watch ends when this returns.
282
+ await attachSession(origin.sessionId).send(
283
+ `The Bird watch ended: ${error.message}`,
284
+ { auth },
285
+ );
286
+ },
287
+ },
288
+ ```
289
+
290
+ ### What the model can call
291
+
292
+ `eve__search` lists three kinds of actions for the connection:
293
+
294
+ | Action | Input | Result |
295
+ | ------------------------- | ---------------------- | --------------------------------------- |
296
+ | `events_subscribe_<hash>` | `{ arguments, ttlMs }` | `{ id, status, expiresAt, ... }` |
297
+ | `events_get_subscription` | `{ id }` | The subscription, or unknown once ended |
298
+ | `events_unsubscribe` | `{ id }` | `{ id, status: "stopping" }` |
299
+
300
+ There is one subscribe action per event the server offers; its description names the event. `ttlMs` is required: an integer from `120000` (2 minutes) to `31536000000` (365 days), or `null` to watch until stopped. `expiresAt` is the resulting deadline, or `null`.
301
+
302
+ - **Pending.** If Connect has not confirmed in time, subscribe returns the `id` with `status: "pending"`. Call get with that `id` later.
303
+ - **Repeats.** Subscribing again to the same event with the same arguments from the same session returns the existing watch. Another session gets its own watch.
304
+ - **Stopping.** Get and stop accept the `id` from any of the creator's sessions. After stop, eve keeps retrying Connect's unsubscribe until cleanup completes; until then get still reports the watch and stop can be called again.
305
+ - **Lifetime.** A watch outlives the session that created it. It ends on stop, at `expiresAt`, or when the upstream subscription terminates.
306
+
307
+ `tools.allow` and `tools.block` apply to these actions. An allow list hides any event action it does not name, so copy the exact `events_subscribe_<hash>` names from `eve__search`. `toolCall.providedArguments` does not apply to event actions.
308
+
309
+ ### Receiver
310
+
311
+ eve mounts `POST /eve/v1/hooks/:connectionName`, under any configured agent or public prefix. It accepts only Connect's delivery token and only deliveries for a live watch's subscription; it answers `410` once the watch has ended. The callback's identity always comes from the saved watch, never from the event payload.
312
+
208
313
  ## Troubleshooting
209
314
 
210
315
  | Symptom | Check |
@@ -38,6 +38,16 @@ does not affect lifecycle instrumentation created with `defineInstrumentation()`
38
38
  See [Audience](../channels/overview#audience) for how channels classify the
39
39
  conversation passed to this policy.
40
40
 
41
+ The session's resolved capture decision also selects its default
42
+ [Workflow run-data retention](/docs/agent-config#run-data-retention). Allowing
43
+ both inputs and outputs uses the World's default; dropping the trace or excluding
44
+ either direction requests deletion of durable payloads and streams when the run
45
+ ends. This makes completed private and unknown-audience transcripts unreadable
46
+ under the default policy outside development. Set
47
+ `experimental.workflow.retention: "default"` on the agent to retain completed
48
+ sessions independently of tracing. Destination `exportPolicy` filters do not
49
+ change Workflow retention, and Workflow deletion does not delete exported traces.
50
+
41
51
  ## Instrument Node.js dependencies
42
52
 
43
53
  Pass OpenTelemetry instrumentation instances to `otel({ instrumentations })`.
@@ -104,6 +104,52 @@ const sandbox = await ctx.getSandbox(environment);
104
104
  const sandboxName = sandbox.name;
105
105
  ```
106
106
 
107
+ ## Mount a Drive
108
+
109
+ A [Vercel Sandbox Drive](https://vercel.com/docs/sandbox/concepts/drives) stores files independently of a sandbox. Create or retrieve the Drive before calling `open()`, then pass it in `mounts` under an absolute path:
110
+
111
+ ```ts
112
+ import { defineSandbox } from "eve/sandbox";
113
+ import { Drive, VercelSandbox } from "eve/sandbox/vercel";
114
+
115
+ const REGION = "iad1";
116
+
117
+ export const environment = VercelSandbox.environment({ region: REGION });
118
+
119
+ export default defineSandbox(async () => {
120
+ const drive = await Drive.getOrCreate({
121
+ name: "agent-workspace",
122
+ region: REGION,
123
+ });
124
+
125
+ return environment.open({
126
+ mounts: {
127
+ "/data": drive,
128
+ },
129
+ });
130
+ });
131
+ ```
132
+
133
+ This example mounts the Drive read-write at `/data`. Files written there remain on the Drive after the sandbox stops. Keep Drive mounts separate from eve's managed `/workspace` directory.
134
+
135
+ Set the same region on the environment and the Drive. The environment region places the prepared snapshot and each session sandbox together with the Drive.
136
+
137
+ A Drive supports one active read-write mount. Because each eve session gets its own sandbox, the fixed `agent-workspace` name works only when one eve session uses the Drive at a time. If sessions can overlap, derive an opaque, stable Drive name per owner or tenant. The [Vercel guide to using Drives with eve](https://vercel.com/kb/guide/vercel-drives-eve-agent) shows how to derive a Drive name from the session initiator.
138
+
139
+ To share a point-in-time view across concurrent sandboxes, mount a read-only snapshot instead:
140
+
141
+ ```ts
142
+ return environment.open({
143
+ mounts: {
144
+ "/data": drive.snapshot(),
145
+ },
146
+ });
147
+ ```
148
+
149
+ Before mounting `drive.snapshot()`, seed a new Drive by mounting it read-write and writing at least one file. An uninitialized Drive cannot be mounted as a snapshot.
150
+
151
+ Vercel allows up to four non-overlapping, absolute Drive mount paths per sandbox. See the Vercel documentation for [Drive lifecycle, limits, and pricing](https://vercel.com/docs/sandbox/concepts/drives).
152
+
107
153
  ## Live sandbox options
108
154
 
109
155
  `open()` also accepts Vercel compute resources, timeout, and Drive mounts. Configure project credentials and custom fetch behavior on the environment, not in `open()`, because resume does not reconstruct start-only options.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.79.2",
3
+ "version": "0.80.0",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [
@@ -569,9 +569,9 @@
569
569
  "@ai-sdk/provider": "^4.0.26",
570
570
  "@ai-sdk/provider-utils": "^5.0.58",
571
571
  "@cfworker/json-schema": "4.1.1",
572
- "@chat-adapter/slack": "4.41.0",
573
- "@chat-adapter/state-memory": "4.41.0",
574
- "@chat-adapter/twilio": "4.41.0",
572
+ "@chat-adapter/slack": "4.42.0",
573
+ "@chat-adapter/state-memory": "4.42.0",
574
+ "@chat-adapter/twilio": "4.42.0",
575
575
  "@clack/core": "1.3.1",
576
576
  "@eve/catalog": "0.0.1",
577
577
  "@eve/tracing": "0.0.0",
@@ -592,7 +592,7 @@
592
592
  "@types/react": "19.2.15",
593
593
  "@types/react-test-renderer": "19.1.0",
594
594
  "@vercel/blob": "2.8.0",
595
- "@vercel/connect": "2.3.3",
595
+ "@vercel/connect": "2.5.2",
596
596
  "@vercel/detect-agent": "1.2.3",
597
597
  "@vercel/oidc": "3.8.0",
598
598
  "@vercel/otel": "2.1.3",
@@ -607,7 +607,7 @@
607
607
  "@workflow/world-local": "5.1.0",
608
608
  "@workflow/world-vercel": "5.2.0",
609
609
  "ai": "^7.0.137",
610
- "chat": "4.41.0",
610
+ "chat": "4.42.0",
611
611
  "chokidar": "5.0.0",
612
612
  "commander": "14.0.3",
613
613
  "dd-trace": "6.13.0",
@@ -640,7 +640,7 @@
640
640
  "@opentelemetry/api": "^1.0.0",
641
641
  "ai": "^7.0.137",
642
642
  "braintrust": "^3.0.0",
643
- "chat": "^4.41.0",
643
+ "chat": "^4.42.0",
644
644
  "dd-trace": "^6.13.0",
645
645
  "just-bash": "^3.1.0",
646
646
  "microsandbox": "^0.5.0"
@@ -1,12 +0,0 @@
1
- var e=/[<>|]/,t=/[\^|>]/,n=/^[A-Z0-9_]+$/,r=/(?<![<\w])@([A-Z][A-Z0-9_]+)/g,i=3e3,a=/^[ \t]+/,o=/^(?:&gt;|&lt;|#{1,6}(?=[ \t\n]|$)|[-+*](?=[ \t\n]|$)|`{3,}|~{3,}|(?:[-*_][ \t]*){3,}(?=\n|$))/,s=/^(\d{1,9})([.)])(?=[ \t\n]|$)/;function c(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`)}function l(e){return e.replace(/&lt;/g,`<`).replace(/&gt;/g,`>`).replace(/&amp;/g,`&`)}function u(e,t={}){return O(e),{...t.emoji===void 0?{}:{emoji:t.emoji},text:e,type:`plain_text`}}function d(e,t={}){return O(e),{text:e,type:`mrkdwn`,...t.verbatim===void 0?{}:{verbatim:t.verbatim}}}function f(e){return k(e,`userId`),`<@${e}>`}function p(e){return k(e,`channelId`),`<#${e}>`}function m(e){return k(e,`userGroupId`),`<!subteam^${e}>`}function h(e){return`<!${e}>`}function g(e,t){return A(e,`url`),t?`<${e}|${c(t)}>`:`<${e}>`}function _(e,t,n,r={}){j(t,`token`);let i=e instanceof Date?Math.floor(e.getTime()/1e3):e;if(!Number.isInteger(i))throw TypeError(`timestamp must be an integer unix timestamp or Date`);return`<!date^${i}^${t}${r.link?`^${M(r.link)}`:``}|${c(n)}>`}function v(e){return l(e.includes("```")?x(e):b(e))}function y(e){let t=e.replace(/<@([A-Z0-9_]+)\|([^<>]+)>/g,`@$2`);return t=t.replace(/<@([A-Z0-9_]+)>/g,`@$1`),t=t.replace(/<#([A-Z0-9_]+)\|([^<>]+)>/g,`#$2 ($1)`),t=t.replace(/<#([A-Z0-9_]+)>/g,`#$1`),t=t.replace(/<(?!https?:\/\/)([^<>|]+)\|(https?:\/\/[^|<>]+)>/g,`<$2|$1>`),t=t.replace(/<(https?:\/\/[^|<>]+)\|([^<>]+)>/g,`[$2]($1)`),t=t.replace(/<(https?:\/\/[^<>]+)>/g,`$1`),t}function b(e){let t=y(e);return t=t.replace(/(?<![_*\\])\*([^*\n]+)\*(?![_*])/g,`**$1**`),t=t.replace(/(?<!~)~([^~\n]+)~(?!~)/g,`~~$1~~`),t}function x(e){let t=``,n=0,r=0,i=!1,a=r=>{let a=e.slice(n,r);i&&=(a=T(a),!1),t+=b(a)};for(;r<e.length;){let o=e[r];if(o===`<`){let t=S(e,r);r=t===-1?r+1:t;continue}if(o!=="`"){r+=1;continue}if(!e.startsWith("```",r)){let t=C(e,r);r=t===-1?r+1:t;continue}let s=r+3,c=e.indexOf("```",s);if(c===-1||w(e,r)){r=s;continue}a(r),t.length>0&&!t.endsWith(`
2
- `)&&(t+=`
3
- `);let l=e.slice(s,c);t+="```",l.startsWith(`
4
- `)||(t+=`
5
- `),t+=y(l),l.endsWith(`
6
- `)||(t+=`
7
- `),t+="```",r=c+3,n=r,r<e.length&&e[r]!==`
8
- `&&(t+=`
9
- `,i=!0)}return a(e.length),t}function S(e,t){let n=t+1;for(;n<e.length&&e[n]!==`>`&&e[n]!==`
10
- `&&e[n]!==`\r`;)n+=1;return e[n]===`>`?n+1:-1}function C(e,t){let n=e.indexOf("`",t+1);if(n===-1)return-1;let r=e.indexOf(`
11
- `,t+1);return r!==-1&&r<n?-1:n+1}function w(e,t){let n=e.lastIndexOf(`
12
- `,t-1)+1;return e.slice(n,t).trimStart().startsWith(`&gt;`)}function T(e){let t=a.exec(e)?.[0]??``,n=t.length>0?` `:``,r=e.slice(t.length);return o.test(r)?`${n}\\${r}`:n+r.replace(s,`$1\\$2`)}function E(e){return e.replace(/\*\*(.+?)\*\*/g,`*$1*`)}function D(e){return e.replace(r,`<@$1>`)}function O(e){if(e.length<1||e.length>i)throw TypeError(`text must be between 1 and ${i} characters`)}function k(e,t){if(!n.test(e))throw TypeError(`${t} must be a Slack ID`)}function A(t,n){if(e.test(t))throw TypeError(`${n} cannot contain Slack control characters`)}function j(e,n){if(t.test(e))throw TypeError(`${n} cannot contain Slack date control characters`)}function M(e){return j(e,`link`),e}export{_ as a,f as c,E as d,v as f,p as i,m as l,u as n,g as o,l as p,c as r,h as s,d as t,D as u};