eve 0.15.5 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/src/channel/compiled-channel.d.ts +2 -0
  3. package/dist/src/channel/cors.d.ts +43 -0
  4. package/dist/src/channel/cors.js +1 -0
  5. package/dist/src/cli/commands/init.js +1 -1
  6. package/dist/src/cli/dev/tui/agent-header.js +1 -1
  7. package/dist/src/cli/dev/tui/agent-info-probe.d.ts +16 -0
  8. package/dist/src/cli/dev/tui/agent-info-probe.js +1 -0
  9. package/dist/src/cli/dev/tui/blocks.js +8 -8
  10. package/dist/src/cli/dev/tui/mcp-connection-status.d.ts +19 -0
  11. package/dist/src/cli/dev/tui/mcp-connection-status.js +1 -0
  12. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  13. package/dist/src/cli/dev/tui/prompt-commands.d.ts +1 -1
  14. package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
  15. package/dist/src/cli/dev/tui/remote-connection-probe.js +1 -1
  16. package/dist/src/cli/dev/tui/runner.d.ts +14 -3
  17. package/dist/src/cli/dev/tui/runner.js +1 -1
  18. package/dist/src/cli/dev/tui/setup-commands.d.ts +10 -1
  19. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  20. package/dist/src/cli/dev/tui/setup-flow.d.ts +8 -1
  21. package/dist/src/cli/dev/tui/setup-issues.d.ts +2 -14
  22. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  23. package/dist/src/cli/dev/tui/setup-panel.d.ts +14 -8
  24. package/dist/src/cli/dev/tui/setup-panel.js +3 -3
  25. package/dist/src/cli/dev/tui/terminal-renderer.js +6 -6
  26. package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
  27. package/dist/src/cli/dev/tui/tui.d.ts +2 -3
  28. package/dist/src/cli/dev/tui/tui.js +1 -1
  29. package/dist/src/cli/dev/ui-options.d.ts +21 -0
  30. package/dist/src/cli/dev/ui-options.js +1 -0
  31. package/dist/src/cli/run.d.ts +6 -42
  32. package/dist/src/cli/run.js +2 -2
  33. package/dist/src/compiled/.vendor-stamp.json +1 -1
  34. package/dist/src/compiled/@ai-sdk/mcp/index.d.ts +71 -1
  35. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  36. package/dist/src/compiler/manifest.d.ts +8 -2
  37. package/dist/src/compiler/manifest.js +1 -1
  38. package/dist/src/compiler/normalize-channel.js +1 -1
  39. package/dist/src/context/providers/connection-key.d.ts +9 -0
  40. package/dist/src/context/providers/connection-key.js +1 -0
  41. package/dist/src/context/providers/connection.d.ts +1 -9
  42. package/dist/src/context/providers/connection.js +1 -1
  43. package/dist/src/harness/emission.d.ts +3 -3
  44. package/dist/src/harness/emission.js +1 -1
  45. package/dist/src/harness/input-requests.d.ts +1 -0
  46. package/dist/src/harness/input-requests.js +1 -1
  47. package/dist/src/harness/stream-actions.d.ts +17 -0
  48. package/dist/src/harness/stream-actions.js +1 -0
  49. package/dist/src/harness/tool-loop.js +1 -1
  50. package/dist/src/internal/application/package.js +1 -1
  51. package/dist/src/internal/nitro/host/channel-routes.d.ts +2 -0
  52. package/dist/src/internal/nitro/host/channel-routes.js +5 -3
  53. package/dist/src/internal/nitro/host/configure-nitro-routes.js +2 -2
  54. package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +1 -0
  55. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  56. package/dist/src/internal/nitro/host/start-development-server.d.ts +8 -0
  57. package/dist/src/internal/nitro/host/start-development-server.js +2 -2
  58. package/dist/src/internal/nitro/host.d.ts +1 -1
  59. package/dist/src/internal/nitro/host.js +1 -1
  60. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  61. package/dist/src/internal/nitro/routes/dev-runtime-artifacts.d.ts +0 -3
  62. package/dist/src/internal/nitro/routes/dev-runtime-artifacts.js +1 -1
  63. package/dist/src/internal/nitro/routes/info.js +1 -1
  64. package/dist/src/internal/vercel/project-link.d.ts +10 -0
  65. package/dist/src/internal/vercel/project-link.js +1 -0
  66. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  67. package/dist/src/public/channels/auth.d.ts +26 -13
  68. package/dist/src/public/channels/auth.js +1 -1
  69. package/dist/src/public/channels/eve.d.ts +31 -0
  70. package/dist/src/public/channels/eve.js +1 -1
  71. package/dist/src/public/channels/github/githubChannel.js +1 -1
  72. package/dist/src/public/channels/github/inbound-types.d.ts +189 -0
  73. package/dist/src/public/channels/github/inbound-types.js +1 -0
  74. package/dist/src/public/channels/github/inbound.d.ts +2 -190
  75. package/dist/src/public/channels/github/inbound.js +2 -2
  76. package/dist/src/public/channels/index.d.ts +1 -1
  77. package/dist/src/public/definitions/defineChannel.d.ts +10 -0
  78. package/dist/src/public/definitions/defineChannel.js +1 -1
  79. package/dist/src/runtime/agent/mock-model-adapter.d.ts +3 -2
  80. package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
  81. package/dist/src/runtime/connections/principal.d.ts +2 -0
  82. package/dist/src/runtime/connections/principal.js +1 -1
  83. package/dist/src/runtime/connections/scoped-authorization.d.ts +9 -0
  84. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  85. package/dist/src/runtime/connections/types.d.ts +8 -5
  86. package/dist/src/runtime/framework-channels/index.d.ts +1 -6
  87. package/dist/src/runtime/framework-channels/index.js +1 -1
  88. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -1
  89. package/dist/src/runtime/framework-tools/index.d.ts +1 -1
  90. package/dist/src/runtime/framework-tools/index.js +1 -1
  91. package/dist/src/runtime/framework-tools/skill.js +1 -1
  92. package/dist/src/runtime/governance/auth/oidc.js +1 -1
  93. package/dist/src/runtime/governance/auth/types.d.ts +14 -10
  94. package/dist/src/runtime/governance/auth/vercel-oidc-project.d.ts +12 -0
  95. package/dist/src/runtime/governance/auth/vercel-oidc-project.js +1 -0
  96. package/dist/src/runtime/resolve-channel.js +1 -1
  97. package/dist/src/runtime/types.d.ts +2 -0
  98. package/dist/src/services/dev-client/client-options.d.ts +5 -0
  99. package/dist/src/services/dev-client/client-options.js +1 -1
  100. package/dist/src/services/dev-client/request-headers.d.ts +8 -0
  101. package/dist/src/services/dev-client/request-headers.js +1 -1
  102. package/dist/src/services/dev-client/runtime-artifacts.d.ts +1 -0
  103. package/dist/src/services/dev-client/runtime-artifacts.js +1 -1
  104. package/dist/src/services/dev-client.d.ts +8 -0
  105. package/dist/src/services/dev-client.js +1 -1
  106. package/dist/src/setup/boxes/add-connections.d.ts +10 -8
  107. package/dist/src/setup/boxes/add-connections.js +1 -1
  108. package/dist/src/setup/boxes/resolve-provisioning.d.ts +1 -0
  109. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  110. package/dist/src/setup/boxes/select-connections.js +1 -1
  111. package/dist/src/setup/cli/channel-setup-prompter.d.ts +9 -2
  112. package/dist/src/setup/cli/channel-setup-prompter.js +1 -1
  113. package/dist/src/setup/cli/index.d.ts +1 -1
  114. package/dist/src/setup/cli/option-row.d.ts +2 -0
  115. package/dist/src/setup/cli/option-row.js +1 -1
  116. package/dist/src/setup/cli/prompt-ui.d.ts +2 -0
  117. package/dist/src/setup/cli/select-state.js +1 -1
  118. package/dist/src/setup/connection-connector.d.ts +26 -52
  119. package/dist/src/setup/connection-connector.js +2 -1
  120. package/dist/src/setup/flows/channels.js +1 -1
  121. package/dist/src/setup/flows/connections.d.ts +37 -0
  122. package/dist/src/setup/flows/connections.js +3 -0
  123. package/dist/src/setup/flows/link.d.ts +1 -0
  124. package/dist/src/setup/flows/link.js +1 -1
  125. package/dist/src/setup/project-resolution.d.ts +2 -8
  126. package/dist/src/setup/project-resolution.js +1 -1
  127. package/dist/src/setup/prompter.d.ts +2 -0
  128. package/dist/src/setup/scaffold/connections/catalog.d.ts +10 -5
  129. package/dist/src/setup/scaffold/connections/catalog.js +1 -1
  130. package/dist/src/setup/scaffold/create/project.js +11 -11
  131. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  132. package/dist/src/setup/scaffold/create/web-template.js +2 -2
  133. package/dist/src/setup/scaffold/index.d.ts +1 -1
  134. package/dist/src/setup/scaffold/index.js +1 -1
  135. package/dist/src/setup/scaffold/update/connections.d.ts +6 -0
  136. package/dist/src/setup/scaffold/update/connections.js +3 -3
  137. package/docs/channels/custom.mdx +19 -0
  138. package/docs/channels/eve.mdx +26 -3
  139. package/docs/concepts/sessions-runs-and-streaming.md +3 -1
  140. package/docs/connections/mcp.mdx +161 -19
  141. package/docs/connections/openapi.mdx +133 -36
  142. package/docs/connections/overview.mdx +4 -4
  143. package/docs/guides/auth-and-route-protection.md +5 -5
  144. package/docs/guides/dev-tui.md +11 -4
  145. package/docs/guides/frontend/nextjs.mdx +2 -2
  146. package/docs/guides/frontend/nuxt.mdx +2 -2
  147. package/docs/guides/frontend/sveltekit.mdx +2 -2
  148. package/docs/patterns/multi-tenant-approvals.md +4 -0
  149. package/docs/patterns/multi-tenant-auth.md +156 -37
  150. package/docs/reference/cli.md +3 -1
  151. package/docs/tools/human-in-the-loop.md +3 -1
  152. package/docs/tutorial/ship-it.mdx +1 -1
  153. package/docs/tutorial/team-playbooks.mdx +1 -1
  154. package/package.json +2 -2
  155. package/dist/src/internal/nitro/host/dev-rebuild-registry.d.ts +0 -5
  156. package/dist/src/internal/nitro/host/dev-rebuild-registry.js +0 -1
@@ -3,6 +3,7 @@ import type { SessionAuthContext } from "#channel/types.js";
3
3
  import { type AuthFn } from "#public/channels/auth.js";
4
4
  import { type UploadPolicyInput } from "#public/channels/upload-policy.js";
5
5
  import { type Channel, type ChannelEvents, type ChannelSessionOps } from "#public/definitions/defineChannel.js";
6
+ import type { ChannelMethod } from "#public/definitions/channel.js";
6
7
  /**
7
8
  * Event-handler channel context exposed by `eveChannel({ events })`. The default eve HTTP channel
8
9
  * has no platform-specific state, so handlers receive session continuation operations plus the `SessionContext` third arg from {@link ChannelEvents}.
@@ -10,6 +11,30 @@ import { type Channel, type ChannelEvents, type ChannelSessionOps } from "#publi
10
11
  export type EveEventContext = ChannelSessionOps;
11
12
  /** Runtime stream-event handlers supported by `eveChannel({ events })`. */
12
13
  export type EveChannelEvents = ChannelEvents<EveEventContext>;
14
+ export interface EveChannelCorsOptions {
15
+ /**
16
+ * Allowed request origin. Pass a single origin string, an exact-origin list,
17
+ * `"null"`, or `"*"`. Omit for `"*"`.
18
+ */
19
+ readonly origin?: "*" | "null" | string | readonly string[];
20
+ /** Methods emitted on preflight responses. Omit for `"*"`. */
21
+ readonly methods?: "*" | readonly ChannelMethod[];
22
+ /** Request headers emitted on preflight responses. Omit for `"*"`. */
23
+ readonly allowedHeaders?: "*" | readonly string[];
24
+ /** Response headers exposed to browser callers. Omit for `"*"`. */
25
+ readonly exposedHeaders?: "*" | readonly string[];
26
+ /** Whether to emit `access-control-allow-credentials: true`. */
27
+ readonly credentials?: boolean;
28
+ /** Max age, in seconds, emitted on preflight responses. */
29
+ readonly maxAge?: number | false;
30
+ /** Preflight response status code. Defaults to 204. */
31
+ readonly preflightStatus?: number;
32
+ }
33
+ /**
34
+ * Higher-level CORS policy for the default eve HTTP channel. Pass `true` for
35
+ * fully permissive browser access, or pass an options object to narrow it.
36
+ */
37
+ export type EveChannelCors = boolean | EveChannelCorsOptions;
13
38
  /** Low-level eve HTTP handle exposed to `eveChannel({ onMessage })`. */
14
39
  export interface EveHandle {
15
40
  /** Route-auth result for the request; `onMessage` chooses session auth by returning `{ auth }`. */
@@ -53,6 +78,12 @@ export interface EveChannelInput {
53
78
  * types); `"disabled"` rejects every attachment; a partial config is merged onto the default. Violations reject with 413 (too large) or 415 (bad type).
54
79
  */
55
80
  readonly uploadPolicy?: UploadPolicyInput;
81
+ /**
82
+ * Browser CORS policy for the eve HTTP routes. Omit or pass `false` to leave
83
+ * CORS untouched, pass `true` for fully permissive CORS, or pass an options
84
+ * object to narrow the policy.
85
+ */
86
+ readonly cors?: EveChannelCors;
56
87
  /**
57
88
  * Pre-dispatch hook for inbound eve HTTP messages. Runs after route auth and body
58
89
  * parsing, before runtime dispatch.
@@ -1,2 +1,2 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{hasInternalRefScheme}from"#internal/attachments/url-refs.js";import{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{isInputResponse}from"#runtime/input/types.js";import{parseJsonObject}from"#shared/json.js";import"ai";import{parseSessionCallback}from"#channel/session-callback.js";import{routeAuth}from"#public/channels/auth.js";import{GET,POST,defineChannel}from"#public/definitions/defineChannel.js";import{collectUploadPolicyViolations,formatUploadPolicyViolation,mergeUploadPolicy}from"#public/channels/upload-policy.js";const log=createLogger(`eve.channel`);function defaultEveAuth(e){return e.eve.caller}function eveChannel(e){let t=mergeUploadPolicy(e.uploadPolicy);return defineChannel({routes:[POST(`/eve/v1/session`,async(n,{send:r})=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=i,o;try{o=await n.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof o!=`object`||!o)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let s=parseCreateBody(o);if(s instanceof Response)return s;let c=checkUploadPolicy(s,t);if(c!==null)return c;let l=await resolveOnMessage({auth:a,config:e,message:s.message,request:n});if(l instanceof Response)return l;if(!l.dispatch)return droppedMessageResponse();let u=`eve:${crypto.randomUUID()}`,d=await r(createSendPayload(s,mergeContext(s.context,l.context)),{auth:l.auth,callback:s.callback,continuationToken:u,mode:s.mode});return Response.json({continuationToken:d.continuationToken,ok:!0,sessionId:d.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:d.id},status:202})}),POST(`/eve/v1/session/:sessionId`,async(n,{send:r,getSession:i,params:a})=>{let o=await routeAuth(n,e.auth);if(o instanceof Response)return o;let s=o,c=a.sessionId;if(!c)return Response.json({error:`Missing session id.`,ok:!1},{status:400});try{i(c)}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}let l;try{l=await n.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof l!=`object`||!l)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let u=parseContinueBody(l);if(u instanceof Response)return u;let d=checkUploadPolicy(u,t);if(d!==null)return d;let f=u.context,p=s;if(u.message!==void 0){let t=await resolveOnMessage({auth:s,config:e,message:u.message,request:n,sessionId:c});if(t instanceof Response)return t;if(!t.dispatch)return droppedMessageResponse();f=mergeContext(u.context,t.context),p=t.auth}let m=await r({inputResponses:u.inputResponses,message:u.message,context:f,outputSchema:u.outputSchema},{auth:p,continuationToken:u.continuationToken});return Response.json({ok:!0,sessionId:m.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:m.id},status:200})}),GET(`/eve/v1/session/:sessionId/stream`,async(t,{getSession:n,params:c})=>{let l=await routeAuth(t,e.auth);if(l instanceof Response)return l;let u=c.sessionId;if(!u)return Response.json({error:`Missing session id.`,ok:!1},{status:400});let d=parseStartIndex(t);if(d instanceof Response)return d;try{let e=serializeAsNdjson(await n(u).getEventStream({startIndex:d}));return new Response(e,{headers:{"cache-control":`no-store, no-transform`,"content-type":EVE_MESSAGE_STREAM_CONTENT_TYPE,"x-accel-buffering":`no`,[EVE_SESSION_ID_HEADER]:u,[EVE_STREAM_FORMAT_HEADER]:EVE_MESSAGE_STREAM_FORMAT,[EVE_STREAM_VERSION_HEADER]:EVE_MESSAGE_STREAM_VERSION}})}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}})],events:e.events})}async function resolveOnMessage(e){let n=e.config.onMessage??defaultOnMessage,r;try{r=await n({eve:e.sessionId===void 0?{caller:e.auth,request:e.request}:{caller:e.auth,request:e.request,sessionId:e.sessionId}},e.message)}catch(n){let r=logError(log,`onMessage handler failed`,n,{sessionId:e.sessionId});return Response.json({error:`onMessage handler failed.`,errorId:r,ok:!1},{status:500})}return r==null?{dispatch:!1}:r.context===void 0?{auth:r.auth,dispatch:!0}:{auth:r.auth,context:r.context,dispatch:!0}}function defaultOnMessage(e){return{auth:defaultEveAuth(e)}}function droppedMessageResponse(){return new Response(null,{headers:{"cache-control":`no-store`},status:204})}function parseCreateBody(e){let t=parseMessageField(e.message);if(t instanceof Response)return t;let n=parseClientContextField(e.clientContext);if(n instanceof Response)return n;let r=parseCallbackField(e.callback);if(r instanceof Response)return r;let i=parseModeField(e.mode);if(i instanceof Response)return i;let a=parseOutputSchemaField(e.outputSchema);return a instanceof Response?a:t===void 0?Response.json({error:`Missing or empty 'message' field.`,ok:!1},{status:400}):{callback:r,message:t,mode:i,context:n,outputSchema:a}}function parseContinueBody(e){let t=typeof e.continuationToken==`string`&&e.continuationToken.length>0?e.continuationToken:void 0;if(t===void 0)return Response.json({error:`Missing or empty 'continuationToken' field.`,ok:!1},{status:400});let n=parseMessageField(e.message);if(n instanceof Response)return n;let r=parseInputResponses(e.inputResponses);if(r instanceof Response)return r;let i=parseClientContextField(e.clientContext);if(i instanceof Response)return i;let a=parseOutputSchemaField(e.outputSchema);return a instanceof Response?a:n===void 0&&r===void 0?Response.json({error:`Expected a non-empty 'message', a non-empty 'inputResponses' array, or both.`,ok:!1},{status:400}):{message:n,continuationToken:t,inputResponses:r,context:i,outputSchema:a}}function createSendPayload(e,t=e.context){if(t===void 0&&e.outputSchema===void 0)return e.message;let n={message:e.message};return t!==void 0&&(n.context=t),e.outputSchema!==void 0&&(n.outputSchema=e.outputSchema),n}function parseOutputSchemaField(e){if(e!==void 0)try{return parseJsonObject(e)}catch{return Response.json({error:`Expected 'outputSchema' to be a JSON-serializable object.`,ok:!1},{status:400})}}function parseCallbackField(e){if(e===void 0)return;let t=parseSessionCallback(e);return t.ok?t.callback:Response.json({error:t.message,ok:!1},{status:400})}function parseModeField(e){if(e!==void 0)return e===`conversation`||e===`task`?e:Response.json({error:`Expected 'mode' to be either 'conversation' or 'task'.`,ok:!1},{status:400})}function parseMessageField(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=parseMessagePart(n);if(e instanceof Response)return e;t.push(e)}return t}function parseMessagePart(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});if(hasInternalRefScheme(t.data))return Response.json({error:`File part 'data' must not use a framework-internal ref scheme.`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function checkUploadPolicy(e,t){if(!e.message)return null;let n=collectUploadPolicyViolations(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:formatUploadPolicyViolation(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function parseInputResponses(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(isInputResponse);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function mergeContext(e,t){return e===void 0?t:t===void 0?e:[...e,...t]}function parseClientContextField(e){if(e!==void 0){if(typeof e==`string`)return e.length>0?[toClientContextMessage(e)]:void 0;if(Array.isArray(e))return e.length===0?void 0:e.every(e=>typeof e==`string`&&e.length>0)?e.map(e=>toClientContextMessage(e)):Response.json({error:`Expected 'clientContext' array entries to be non-empty strings.`,ok:!1},{status:400});if(typeof e!=`object`||!e)return Response.json({error:`Expected 'clientContext' to be a string, string array, or JSON object.`,ok:!1},{status:400});try{let t=parseJsonObject(e);return[toClientContextMessage(JSON.stringify(t))]}catch{return Response.json({error:`Expected 'clientContext' to be a JSON-serializable object.`,ok:!1},{status:400})}}}function toClientContextMessage(e){return`Client context:
1
+ import{createLogger,logError}from"#internal/logging.js";import{hasInternalRefScheme}from"#internal/attachments/url-refs.js";import{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_VERSION_HEADER}from"#protocol/message.js";import{isInputResponse}from"#runtime/input/types.js";import{parseJsonObject}from"#shared/json.js";import"ai";import{parseSessionCallback}from"#channel/session-callback.js";import{routeAuth}from"#public/channels/auth.js";import{GET,POST,defineChannel}from"#public/definitions/defineChannel.js";import{collectUploadPolicyViolations,formatUploadPolicyViolation,mergeUploadPolicy}from"#public/channels/upload-policy.js";const log=createLogger(`eve.channel`);function defaultEveAuth(e){return e.eve.caller}function eveChannel(e){let t=mergeUploadPolicy(e.uploadPolicy);return defineChannel({cors:normalizeEveCors(e.cors),routes:[POST(`/eve/v1/session`,async(n,{send:r})=>{let i=await routeAuth(n,e.auth);if(i instanceof Response)return i;let a=i,o;try{o=await n.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof o!=`object`||!o)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let s=parseCreateBody(o);if(s instanceof Response)return s;let c=checkUploadPolicy(s,t);if(c!==null)return c;let l=await resolveOnMessage({auth:a,config:e,message:s.message,request:n});if(l instanceof Response)return l;if(!l.dispatch)return droppedMessageResponse();let u=`eve:${crypto.randomUUID()}`,d=await r(createSendPayload(s,mergeContext(s.context,l.context)),{auth:l.auth,callback:s.callback,continuationToken:u,mode:s.mode});return Response.json({continuationToken:d.continuationToken,ok:!0,sessionId:d.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:d.id},status:202})}),POST(`/eve/v1/session/:sessionId`,async(n,{send:r,getSession:i,params:a})=>{let o=await routeAuth(n,e.auth);if(o instanceof Response)return o;let s=o,c=a.sessionId;if(!c)return Response.json({error:`Missing session id.`,ok:!1},{status:400});try{i(c)}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}let l;try{l=await n.json()}catch{return Response.json({error:`Invalid JSON body.`,ok:!1},{status:400})}if(typeof l!=`object`||!l)return Response.json({error:`Expected a JSON object.`,ok:!1},{status:400});let u=parseContinueBody(l);if(u instanceof Response)return u;let d=checkUploadPolicy(u,t);if(d!==null)return d;let f=u.context,p=s;if(u.message!==void 0){let t=await resolveOnMessage({auth:s,config:e,message:u.message,request:n,sessionId:c});if(t instanceof Response)return t;if(!t.dispatch)return droppedMessageResponse();f=mergeContext(u.context,t.context),p=t.auth}let m=await r({inputResponses:u.inputResponses,message:u.message,context:f,outputSchema:u.outputSchema},{auth:p,continuationToken:u.continuationToken});return Response.json({ok:!0,sessionId:m.id},{headers:{"cache-control":`no-store`,[EVE_SESSION_ID_HEADER]:m.id},status:200})}),GET(`/eve/v1/session/:sessionId/stream`,async(t,{getSession:n,params:c})=>{let l=await routeAuth(t,e.auth);if(l instanceof Response)return l;let u=c.sessionId;if(!u)return Response.json({error:`Missing session id.`,ok:!1},{status:400});let d=parseStartIndex(t);if(d instanceof Response)return d;try{let e=serializeAsNdjson(await n(u).getEventStream({startIndex:d}));return new Response(e,{headers:{"cache-control":`no-store, no-transform`,"content-type":EVE_MESSAGE_STREAM_CONTENT_TYPE,"x-accel-buffering":`no`,[EVE_SESSION_ID_HEADER]:u,[EVE_STREAM_FORMAT_HEADER]:EVE_MESSAGE_STREAM_FORMAT,[EVE_STREAM_VERSION_HEADER]:EVE_MESSAGE_STREAM_VERSION}})}catch{return Response.json({error:`Session not found.`,ok:!1},{status:404})}})],events:e.events})}function normalizeEveCors(e){if(e===void 0||e===!1)return!1;if(e===!0)return!0;let t={};return e.origin!==void 0&&(t.origin=normalizeEveCorsOrigin(e.origin)),e.methods!==void 0&&(t.methods=e.methods),e.allowedHeaders!==void 0&&(t.allowHeaders=e.allowedHeaders),e.exposedHeaders!==void 0&&(t.exposeHeaders=e.exposedHeaders),e.credentials!==void 0&&(t.credentials=e.credentials),e.maxAge!==void 0&&(t.maxAge=e.maxAge),e.preflightStatus!==void 0&&(t.preflight={statusCode:e.preflightStatus}),t}function normalizeEveCorsOrigin(e){return e===`*`||e===`null`?e:typeof e==`string`?[e]:e}async function resolveOnMessage(e){let n=e.config.onMessage??defaultOnMessage,r;try{r=await n({eve:e.sessionId===void 0?{caller:e.auth,request:e.request}:{caller:e.auth,request:e.request,sessionId:e.sessionId}},e.message)}catch(n){let r=logError(log,`onMessage handler failed`,n,{sessionId:e.sessionId});return Response.json({error:`onMessage handler failed.`,errorId:r,ok:!1},{status:500})}return r==null?{dispatch:!1}:r.context===void 0?{auth:r.auth,dispatch:!0}:{auth:r.auth,context:r.context,dispatch:!0}}function defaultOnMessage(e){return{auth:defaultEveAuth(e)}}function droppedMessageResponse(){return new Response(null,{headers:{"cache-control":`no-store`},status:204})}function parseCreateBody(e){let t=parseMessageField(e.message);if(t instanceof Response)return t;let n=parseClientContextField(e.clientContext);if(n instanceof Response)return n;let r=parseCallbackField(e.callback);if(r instanceof Response)return r;let i=parseModeField(e.mode);if(i instanceof Response)return i;let a=parseOutputSchemaField(e.outputSchema);return a instanceof Response?a:t===void 0?Response.json({error:`Missing or empty 'message' field.`,ok:!1},{status:400}):{callback:r,message:t,mode:i,context:n,outputSchema:a}}function parseContinueBody(e){let t=typeof e.continuationToken==`string`&&e.continuationToken.length>0?e.continuationToken:void 0;if(t===void 0)return Response.json({error:`Missing or empty 'continuationToken' field.`,ok:!1},{status:400});let n=parseMessageField(e.message);if(n instanceof Response)return n;let r=parseInputResponses(e.inputResponses);if(r instanceof Response)return r;let i=parseClientContextField(e.clientContext);if(i instanceof Response)return i;let a=parseOutputSchemaField(e.outputSchema);return a instanceof Response?a:n===void 0&&r===void 0?Response.json({error:`Expected a non-empty 'message', a non-empty 'inputResponses' array, or both.`,ok:!1},{status:400}):{message:n,continuationToken:t,inputResponses:r,context:i,outputSchema:a}}function createSendPayload(e,t=e.context){if(t===void 0&&e.outputSchema===void 0)return e.message;let n={message:e.message};return t!==void 0&&(n.context=t),e.outputSchema!==void 0&&(n.outputSchema=e.outputSchema),n}function parseOutputSchemaField(e){if(e!==void 0)try{return parseJsonObject(e)}catch{return Response.json({error:`Expected 'outputSchema' to be a JSON-serializable object.`,ok:!1},{status:400})}}function parseCallbackField(e){if(e===void 0)return;let t=parseSessionCallback(e);return t.ok?t.callback:Response.json({error:t.message,ok:!1},{status:400})}function parseModeField(e){if(e!==void 0)return e===`conversation`||e===`task`?e:Response.json({error:`Expected 'mode' to be either 'conversation' or 'task'.`,ok:!1},{status:400})}function parseMessageField(e){if(e===void 0)return;if(typeof e==`string`)return e.length>0?e:void 0;if(!Array.isArray(e))return Response.json({error:`Expected 'message' to be a string or an array of text/file parts.`,ok:!1},{status:400});if(e.length===0)return;let t=[];for(let n of e){let e=parseMessagePart(n);if(e instanceof Response)return e;t.push(e)}return t}function parseMessagePart(e){if(typeof e!=`object`||!e)return Response.json({error:`Expected each message part to be an object.`,ok:!1},{status:400});let t=e;if(t.type===`text`)return typeof t.text!=`string`||t.text.length===0?Response.json({error:`Text parts require a non-empty 'text' string.`,ok:!1},{status:400}):{type:`text`,text:t.text};if(t.type===`file`){if(typeof t.mediaType!=`string`||t.mediaType.length===0)return Response.json({error:`File parts require a non-empty 'mediaType' string.`,ok:!1},{status:400});if(typeof t.data!=`string`)return Response.json({error:`File parts require a 'data' string (base64, data URL, or URL).`,ok:!1},{status:400});if(hasInternalRefScheme(t.data))return Response.json({error:`File part 'data' must not use a framework-internal ref scheme.`,ok:!1},{status:400});let e={type:`file`,mediaType:t.mediaType,data:t.data};return typeof t.filename==`string`&&t.filename.length>0&&(e.filename=t.filename),e}return Response.json({error:`Unsupported message part type "${String(t.type)}". Use 'text' or 'file'.`,ok:!1},{status:400})}function checkUploadPolicy(e,t){if(!e.message)return null;let n=collectUploadPolicyViolations(e.message,t);if(n.length===0)return null;let[r]=n;if(!r)return null;let i=r.kind===`too-large`?413:415;return Response.json({error:formatUploadPolicyViolation(r),ok:!1,violations:n.map(e=>e.kind===`too-large`?{byteLength:e.byteLength,filename:e.filename,kind:e.kind,limit:e.limit,mediaType:e.mediaType}:{allowedMediaTypes:e.allowedMediaTypes,filename:e.filename,kind:e.kind,mediaType:e.mediaType})},{status:i})}function parseInputResponses(e){if(e===void 0)return;if(!Array.isArray(e)||e.length===0)return Response.json({error:`Expected 'inputResponses' to be a non-empty array.`,ok:!1},{status:400});let t=e.filter(isInputResponse);return t.length===e.length?t:Response.json({error:`Expected every 'inputResponses' entry to match the HITL response schema.`,ok:!1},{status:400})}function mergeContext(e,t){return e===void 0?t:t===void 0?e:[...e,...t]}function parseClientContextField(e){if(e!==void 0){if(typeof e==`string`)return e.length>0?[toClientContextMessage(e)]:void 0;if(Array.isArray(e))return e.length===0?void 0:e.every(e=>typeof e==`string`&&e.length>0)?e.map(e=>toClientContextMessage(e)):Response.json({error:`Expected 'clientContext' array entries to be non-empty strings.`,ok:!1},{status:400});if(typeof e!=`object`||!e)return Response.json({error:`Expected 'clientContext' to be a string, string array, or JSON object.`,ok:!1},{status:400});try{let t=parseJsonObject(e);return[toClientContextMessage(JSON.stringify(t))]}catch{return Response.json({error:`Expected 'clientContext' to be a JSON-serializable object.`,ok:!1},{status:400})}}}function toClientContextMessage(e){return`Client context:
2
2
  ${e}`}function parseStartIndex(e){let t=new URL(e.url).searchParams.get(`startIndex`);if(t===null)return;let n=Number.parseInt(t,10);return!Number.isSafeInteger(n)||n<0?Response.json({error:`Expected startIndex to be a non-negative integer.`,ok:!1},{status:400}):n}function serializeAsNdjson(e){let t=new TextEncoder;return e.pipeThrough(new TransformStream({transform(e,n){n.enqueue(t.encode(`${JSON.stringify(e)}\n`))}}))}export{defaultEveAuth,eveChannel};
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{POST,defineChannel}from"#public/definitions/defineChannel.js";import{getGitHubRepository}from"#public/channels/github/api.js";import{parseGitHubWebhookEvent}from"#public/channels/github/inbound.js";import{buildGitHubBinding}from"#public/channels/github/binding.js";import{continuationTokenFromState,conversationFromState,initialGitHubState,stateFromReceiveTarget}from"#public/channels/github/state.js";import{GITHUB_CHANNEL_DEFAULT_ROUTE}from"#public/channels/github/constants.js";import{createDefaultEvents,defaultOnComment}from"#public/channels/github/defaults.js";import{dispatchCheckRun,dispatchCheckSuite,dispatchIssue,dispatchIssueComment,dispatchPullRequest,dispatchPullRequestReviewComment,dispatchWorkflowRun}from"#public/channels/github/dispatch.js";import{verifyGitHubRequest}from"#public/channels/github/verify.js";const log=createLogger(`github.channel`);function githubChannel(e={}){let s=e.botName??process.env.GITHUB_APP_SLUG,u={botName:s},d={...createDefaultEvents({api:e.api,credentials:e.credentials,progress:e.progress}),...e.events};return defineChannel({kindHint:`github`,state:initialGitHubState(),context(t,n){return rebuildGitHubContext(t,n,e)},routes:[POST(e.route??GITHUB_CHANNEL_DEFAULT_ROUTE,async(t,{send:n,waitUntil:r})=>{let a=await verifyInbound(t,e.credentials);if(a===null)return new Response(`unauthorized`,{status:401});let o;try{o=parseGitHubWebhookEvent({body:a,contentType:t.headers.get(`content-type`)??void 0,headers:t.headers})}catch(e){return log.warn(`inbound GitHub body is not valid JSON`,{error:e}),jsonOk({ignored:!0,ok:!0})}return o===null?jsonOk({ignored:!0,ok:!0}):o.kind===`ping`?jsonOk({ok:!0}):o.kind===`issue_comment`&&o.action===`created`?(r(dispatchIssueComment({botName:s,config:e,event:o,handler:e.onComment??((e,t)=>defaultOnComment(e,t,u)),send:n})),jsonOk({ok:!0})):o.kind===`pull_request_review_comment`&&o.action===`created`?(r(dispatchPullRequestReviewComment({botName:s,config:e,event:o,handler:e.onComment??((e,t)=>defaultOnComment(e,t,u)),send:n})),jsonOk({ok:!0})):o.kind===`issues`&&e.onIssue!==void 0?(r(dispatchIssue({config:e,event:o,handler:e.onIssue,send:n})),jsonOk({ok:!0})):o.kind===`pull_request`&&e.onPullRequest!==void 0?(r(dispatchPullRequest({config:e,event:o,handler:e.onPullRequest,send:n})),jsonOk({ok:!0})):o.kind===`check_suite`&&e.onCheckSuite!==void 0?(r(dispatchCheckSuite({config:e,event:o,handler:e.onCheckSuite,send:n})),jsonOk({ok:!0})):o.kind===`check_run`&&e.onCheckRun!==void 0?(r(dispatchCheckRun({config:e,event:o,handler:e.onCheckRun,send:n})),jsonOk({ok:!0})):o.kind===`workflow_run`&&e.onWorkflowRun!==void 0?(r(dispatchWorkflowRun({config:e,event:o,handler:e.onWorkflowRun,send:n})),jsonOk({ok:!0})):jsonOk({ignored:!0,ok:!0})})],async receive(t,{send:n}){let i=t.target,s=readNonEmptyString(i.owner),c=readNonEmptyString(i.repo);if(s===void 0||c===void 0)throw Error(`githubChannel().receive requires target.owner and target.repo.`);if([i.issueNumber!==void 0,i.pullRequestNumber!==void 0].filter(Boolean).length!==1)throw Error(`githubChannel().receive requires exactly one of issueNumber or pullRequestNumber.`);let l=stateFromReceiveTarget({target:i,owner:s,repo:c,repositoryId:i.repositoryId??(await getGitHubRepository({api:e.api,credentials:e.credentials,installationId:i.installationId,owner:s,repo:c})).id});if(i.initialMessage!==void 0){let{thread:t}=buildGitHubBinding({config:e,state:l});await t.post(i.initialMessage)}return n(t.message,{auth:t.auth,continuationToken:continuationTokenFromState(l),state:l})},events:d})}function rebuildGitHubContext(e,t,n){let r=buildGitHubBinding({config:n,state:e});return{conversation:conversationFromState(e),github:r.github,repository:r.github.repository,state:e,thread:r.thread}}async function verifyInbound(e,t){try{return await verifyGitHubRequest(e,{webhookSecret:t?.webhookSecret,webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`github inbound verification failed`,{error:e}),null}}function readNonEmptyString(e){return typeof e==`string`&&e.length>0?e:void 0}function jsonOk(e){return new Response(JSON.stringify(e),{headers:{"content-type":`application/json; charset=utf-8`},status:200})}export{githubChannel};
1
+ import{createLogger}from"#internal/logging.js";import{POST,defineChannel}from"#public/definitions/defineChannel.js";import{getGitHubRepository}from"#public/channels/github/api.js";import{parseGitHubWebhookEvent}from"#public/channels/github/inbound.js";import{buildGitHubBinding}from"#public/channels/github/binding.js";import{continuationTokenFromState,conversationFromState,initialGitHubState,stateFromReceiveTarget}from"#public/channels/github/state.js";import{GITHUB_CHANNEL_DEFAULT_ROUTE}from"#public/channels/github/constants.js";import{createDefaultEvents,defaultOnComment}from"#public/channels/github/defaults.js";import{dispatchCheckRun,dispatchCheckSuite,dispatchIssue,dispatchIssueComment,dispatchPullRequest,dispatchPullRequestReviewComment,dispatchWorkflowRun}from"#public/channels/github/dispatch.js";import{verifyGitHubRequest}from"#public/channels/github/verify.js";const log=createLogger(`github.channel`);function githubChannel(e={}){let s=e.botName??process.env.GITHUB_APP_SLUG,u={botName:s},d={...createDefaultEvents({api:e.api,credentials:e.credentials,progress:e.progress}),...e.events};return defineChannel({kindHint:`github`,state:initialGitHubState(),context(t,n){return rebuildGitHubContext(t,n,e)},routes:[POST(e.route??GITHUB_CHANNEL_DEFAULT_ROUTE,async(t,{send:n,waitUntil:r})=>{let a=await verifyInbound(t,e.credentials);if(a===null)return new Response(`unauthorized`,{status:401});let o=missingGitHubWebhookHeaders(t.headers),c;try{c=parseGitHubWebhookEvent({body:a,contentType:t.headers.get(`content-type`)??void 0,headers:t.headers})}catch(e){return log.warn(`inbound GitHub body is not valid JSON`,{error:e}),jsonOk({ignored:!0,ok:!0})}return c===null?(o.length>0&&log.warn(`GitHub webhook ignored because standard headers were missing`,{missingHeaders:o}),jsonOk({ignored:!0,ok:!0})):(o.length>0&&log.warn(`GitHub webhook missing standard headers; inferred metadata from payload`,{deliveryId:c.delivery.id,event:c.delivery.event,missingHeaders:o,repository:c.repository.fullName}),c.kind===`ping`?jsonOk({ok:!0}):c.kind===`issue_comment`&&c.action===`created`?(r(dispatchIssueComment({botName:s,config:e,event:c,handler:e.onComment??((e,t)=>defaultOnComment(e,t,u)),send:n})),jsonOk({ok:!0})):c.kind===`pull_request_review_comment`&&c.action===`created`?(r(dispatchPullRequestReviewComment({botName:s,config:e,event:c,handler:e.onComment??((e,t)=>defaultOnComment(e,t,u)),send:n})),jsonOk({ok:!0})):c.kind===`issues`&&e.onIssue!==void 0?(r(dispatchIssue({config:e,event:c,handler:e.onIssue,send:n})),jsonOk({ok:!0})):c.kind===`pull_request`&&e.onPullRequest!==void 0?(r(dispatchPullRequest({config:e,event:c,handler:e.onPullRequest,send:n})),jsonOk({ok:!0})):c.kind===`check_suite`&&e.onCheckSuite!==void 0?(r(dispatchCheckSuite({config:e,event:c,handler:e.onCheckSuite,send:n})),jsonOk({ok:!0})):c.kind===`check_run`&&e.onCheckRun!==void 0?(r(dispatchCheckRun({config:e,event:c,handler:e.onCheckRun,send:n})),jsonOk({ok:!0})):c.kind===`workflow_run`&&e.onWorkflowRun!==void 0?(r(dispatchWorkflowRun({config:e,event:c,handler:e.onWorkflowRun,send:n})),jsonOk({ok:!0})):jsonOk({ignored:!0,ok:!0}))})],async receive(t,{send:n}){let i=t.target,s=readNonEmptyString(i.owner),c=readNonEmptyString(i.repo);if(s===void 0||c===void 0)throw Error(`githubChannel().receive requires target.owner and target.repo.`);if([i.issueNumber!==void 0,i.pullRequestNumber!==void 0].filter(Boolean).length!==1)throw Error(`githubChannel().receive requires exactly one of issueNumber or pullRequestNumber.`);let l=stateFromReceiveTarget({target:i,owner:s,repo:c,repositoryId:i.repositoryId??(await getGitHubRepository({api:e.api,credentials:e.credentials,installationId:i.installationId,owner:s,repo:c})).id});if(i.initialMessage!==void 0){let{thread:t}=buildGitHubBinding({config:e,state:l});await t.post(i.initialMessage)}return n(t.message,{auth:t.auth,continuationToken:continuationTokenFromState(l),state:l})},events:d})}function rebuildGitHubContext(e,t,n){let r=buildGitHubBinding({config:n,state:e});return{conversation:conversationFromState(e),github:r.github,repository:r.github.repository,state:e,thread:r.thread}}async function verifyInbound(e,t){try{return await verifyGitHubRequest(e,{webhookSecret:t?.webhookSecret,webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`github inbound verification failed`,{error:e}),null}}function readNonEmptyString(e){return typeof e==`string`&&e.length>0?e:void 0}function missingGitHubWebhookHeaders(e){return[`x-github-event`,`x-github-delivery`].filter(t=>{let n=e.get(t);return n===null||n.trim().length===0})}function jsonOk(e){return new Response(JSON.stringify(e),{headers:{"content-type":`application/json; charset=utf-8`},status:200})}export{githubChannel};
@@ -0,0 +1,189 @@
1
+ import type { JsonObject } from "#shared/json.js";
2
+ /** GitHub conversation kinds represented by the channel state. */
3
+ export type GitHubConversationKind = "issue" | "pull_request" | "review_thread";
4
+ /** Stable repository identity normalized from webhook payloads. */
5
+ export interface GitHubRepositoryRef {
6
+ readonly fullName: string;
7
+ readonly id: number;
8
+ readonly name: string;
9
+ readonly owner: string;
10
+ readonly private: boolean;
11
+ }
12
+ /** GitHub actor metadata normalized from webhook payloads. */
13
+ export interface GitHubUser {
14
+ readonly htmlUrl: string | undefined;
15
+ readonly id: number;
16
+ readonly login: string;
17
+ readonly type: string;
18
+ readonly url: string | undefined;
19
+ }
20
+ /** GitHub webhook delivery metadata. */
21
+ export interface GitHubDelivery {
22
+ readonly event: string;
23
+ readonly hookId: string | undefined;
24
+ readonly id: string;
25
+ }
26
+ /** Channel-local conversation reference. */
27
+ export interface GitHubConversationRef {
28
+ readonly issueNumber: number | null;
29
+ readonly kind: GitHubConversationKind;
30
+ readonly pullRequestNumber: number | null;
31
+ }
32
+ /**
33
+ * Normalized GitHub comment handed to the `onComment` hook. Covers issue and PR
34
+ * timeline comments and inline review comments alike; `ctx.conversation.kind`
35
+ * distinguishes them.
36
+ */
37
+ export interface GitHubComment {
38
+ readonly author: GitHubUser | undefined;
39
+ readonly body: string;
40
+ readonly htmlUrl: string | undefined;
41
+ readonly id: number;
42
+ readonly raw: JsonObject;
43
+ readonly url: string | undefined;
44
+ }
45
+ /** Normalized issue/PR timeline comment. */
46
+ export interface GitHubIssueComment {
47
+ readonly author: GitHubUser | undefined;
48
+ readonly body: string;
49
+ readonly htmlUrl: string | undefined;
50
+ readonly id: number;
51
+ readonly issueNumber: number;
52
+ readonly pullRequestNumber: number | null;
53
+ readonly raw: JsonObject;
54
+ readonly url: string | undefined;
55
+ }
56
+ /** Normalized inline pull-request review comment. */
57
+ export interface GitHubPullRequestReviewComment {
58
+ readonly author: GitHubUser | undefined;
59
+ readonly body: string;
60
+ readonly htmlUrl: string | undefined;
61
+ readonly id: number;
62
+ readonly inReplyToId: number | null;
63
+ readonly pullRequestNumber: number;
64
+ readonly raw: JsonObject;
65
+ readonly reviewThreadRootCommentId: number;
66
+ readonly url: string | undefined;
67
+ }
68
+ /**
69
+ * Common `issues` webhook actions, kept open to any action GitHub sends so
70
+ * authors get autocomplete without losing forward compatibility.
71
+ */
72
+ export type GitHubIssueAction = "assigned" | "closed" | "edited" | "labeled" | "opened" | "reopened" | "unassigned" | "unlabeled" | (string & {});
73
+ /** Common `pull_request` webhook actions, kept open to any action GitHub sends. */
74
+ export type GitHubPullRequestAction = "closed" | "edited" | "labeled" | "opened" | "ready_for_review" | "reopened" | "synchronize" | "unlabeled" | (string & {});
75
+ /** Normalized issue event payload. */
76
+ export interface GitHubIssueEvent {
77
+ readonly action: GitHubIssueAction;
78
+ readonly issueNumber: number;
79
+ readonly raw: JsonObject;
80
+ }
81
+ /** Normalized pull-request event payload. */
82
+ export interface GitHubPullRequestEvent {
83
+ readonly action: GitHubPullRequestAction;
84
+ readonly headSha: string | null;
85
+ readonly pullRequestNumber: number;
86
+ readonly raw: JsonObject;
87
+ }
88
+ /** GitHub App identity attached to CI webhook payloads. */
89
+ export interface GitHubAppRef {
90
+ readonly slug: string | null;
91
+ }
92
+ /** Common fields normalized from GitHub CI webhook payloads. */
93
+ export interface GitHubCiEvent {
94
+ readonly action: string;
95
+ readonly app: GitHubAppRef;
96
+ readonly conclusion: string | null;
97
+ readonly headSha: string | null;
98
+ readonly pullRequests: readonly number[];
99
+ readonly raw: JsonObject;
100
+ readonly status: string | null;
101
+ }
102
+ /** Normalized `check_suite` webhook payload. */
103
+ export interface GitHubCheckSuiteEvent extends GitHubCiEvent {
104
+ readonly checkSuiteId: number;
105
+ }
106
+ /** Normalized `check_run` webhook payload. */
107
+ export interface GitHubCheckRunEvent extends GitHubCiEvent {
108
+ readonly checkRunId: number;
109
+ }
110
+ /** Normalized `workflow_run` webhook payload. */
111
+ export interface GitHubWorkflowRunEvent extends GitHubCiEvent {
112
+ readonly workflowRunId: number;
113
+ }
114
+ /** Normalized payload accepted by one of the GitHub CI event hooks. */
115
+ export type GitHubCiPayload = GitHubCheckRunEvent | GitHubCheckSuiteEvent | GitHubWorkflowRunEvent;
116
+ export interface GitHubInboundEventBase {
117
+ readonly delivery: GitHubDelivery;
118
+ readonly installationId: number | undefined;
119
+ readonly raw: JsonObject;
120
+ readonly repository: GitHubRepositoryRef;
121
+ readonly sender: GitHubUser;
122
+ }
123
+ export interface GitHubPingEvent extends GitHubInboundEventBase {
124
+ readonly kind: "ping";
125
+ }
126
+ export interface GitHubIssueCommentEvent extends GitHubInboundEventBase {
127
+ readonly action: string;
128
+ readonly baseRef: string | null;
129
+ readonly baseSha: string | null;
130
+ readonly comment: GitHubIssueComment;
131
+ readonly conversation: GitHubConversationRef;
132
+ readonly defaultBranch: string | null;
133
+ readonly headRef: string | null;
134
+ readonly headSha: string | null;
135
+ readonly kind: "issue_comment";
136
+ }
137
+ export interface GitHubPullRequestReviewCommentEvent extends GitHubInboundEventBase {
138
+ readonly action: string;
139
+ readonly baseRef: string | null;
140
+ readonly baseSha: string | null;
141
+ readonly comment: GitHubPullRequestReviewComment;
142
+ readonly conversation: GitHubConversationRef;
143
+ readonly defaultBranch: string | null;
144
+ readonly headRef: string | null;
145
+ readonly headSha: string | null;
146
+ readonly kind: "pull_request_review_comment";
147
+ }
148
+ export interface GitHubIssueWebhookEvent extends GitHubInboundEventBase {
149
+ readonly action: string;
150
+ readonly conversation: GitHubConversationRef;
151
+ readonly issue: GitHubIssueEvent;
152
+ readonly kind: "issues";
153
+ }
154
+ export interface GitHubPullRequestWebhookEvent extends GitHubInboundEventBase {
155
+ readonly action: string;
156
+ readonly baseRef: string | null;
157
+ readonly baseSha: string | null;
158
+ readonly conversation: GitHubConversationRef;
159
+ readonly defaultBranch: string | null;
160
+ readonly headRef: string | null;
161
+ readonly headSha: string | null;
162
+ readonly kind: "pull_request";
163
+ readonly pullRequest: GitHubPullRequestEvent;
164
+ }
165
+ export interface GitHubCheckSuiteWebhookEvent extends GitHubInboundEventBase {
166
+ readonly checkSuite: GitHubCheckSuiteEvent;
167
+ readonly conversation: GitHubConversationRef;
168
+ readonly kind: "check_suite";
169
+ }
170
+ export interface GitHubCheckRunWebhookEvent extends GitHubInboundEventBase {
171
+ readonly checkRun: GitHubCheckRunEvent;
172
+ readonly conversation: GitHubConversationRef;
173
+ readonly kind: "check_run";
174
+ }
175
+ export interface GitHubWorkflowRunWebhookEvent extends GitHubInboundEventBase {
176
+ readonly conversation: GitHubConversationRef;
177
+ readonly kind: "workflow_run";
178
+ readonly workflowRun: GitHubWorkflowRunEvent;
179
+ }
180
+ /** Parsed CI webhook envelopes consumed by the GitHub channel. */
181
+ export type GitHubCiWebhookEvent = GitHubCheckRunWebhookEvent | GitHubCheckSuiteWebhookEvent | GitHubWorkflowRunWebhookEvent;
182
+ /** Parsed GitHub webhook event shape consumed by the channel. */
183
+ export type GitHubInboundEvent = GitHubCheckRunWebhookEvent | GitHubCheckSuiteWebhookEvent | GitHubIssueCommentEvent | GitHubIssueWebhookEvent | GitHubPingEvent | GitHubPullRequestReviewCommentEvent | GitHubPullRequestWebhookEvent | GitHubWorkflowRunWebhookEvent;
184
+ /** Parsed mention trigger for a bot-directed GitHub comment. */
185
+ export interface GitHubCommentTrigger {
186
+ readonly kind: "mention";
187
+ readonly message: string;
188
+ readonly token: string;
189
+ }
@@ -0,0 +1 @@
1
+ export{};
@@ -1,193 +1,6 @@
1
1
  import type { UserContent } from "ai";
2
- import { type JsonObject } from "#shared/json.js";
3
- /** GitHub conversation kinds represented by the channel state. */
4
- export type GitHubConversationKind = "issue" | "pull_request" | "review_thread";
5
- /** Stable repository identity normalized from webhook payloads. */
6
- export interface GitHubRepositoryRef {
7
- readonly fullName: string;
8
- readonly id: number;
9
- readonly name: string;
10
- readonly owner: string;
11
- readonly private: boolean;
12
- }
13
- /** GitHub actor metadata normalized from webhook payloads. */
14
- export interface GitHubUser {
15
- readonly htmlUrl: string | undefined;
16
- readonly id: number;
17
- readonly login: string;
18
- readonly type: string;
19
- readonly url: string | undefined;
20
- }
21
- /** Verified GitHub webhook delivery headers. */
22
- export interface GitHubDelivery {
23
- readonly event: string;
24
- readonly hookId: string | undefined;
25
- readonly id: string;
26
- }
27
- /** Channel-local conversation reference. */
28
- export interface GitHubConversationRef {
29
- readonly issueNumber: number | null;
30
- readonly kind: GitHubConversationKind;
31
- readonly pullRequestNumber: number | null;
32
- }
33
- /**
34
- * Normalized GitHub comment handed to the `onComment` hook. Covers issue and PR
35
- * timeline comments and inline review comments alike; `ctx.conversation.kind`
36
- * distinguishes them.
37
- */
38
- export interface GitHubComment {
39
- readonly author: GitHubUser | undefined;
40
- readonly body: string;
41
- readonly htmlUrl: string | undefined;
42
- readonly id: number;
43
- readonly raw: JsonObject;
44
- readonly url: string | undefined;
45
- }
46
- /** Normalized issue/PR timeline comment. */
47
- export interface GitHubIssueComment {
48
- readonly author: GitHubUser | undefined;
49
- readonly body: string;
50
- readonly htmlUrl: string | undefined;
51
- readonly id: number;
52
- readonly issueNumber: number;
53
- readonly pullRequestNumber: number | null;
54
- readonly raw: JsonObject;
55
- readonly url: string | undefined;
56
- }
57
- /** Normalized inline pull-request review comment. */
58
- export interface GitHubPullRequestReviewComment {
59
- readonly author: GitHubUser | undefined;
60
- readonly body: string;
61
- readonly htmlUrl: string | undefined;
62
- readonly id: number;
63
- readonly inReplyToId: number | null;
64
- readonly pullRequestNumber: number;
65
- readonly raw: JsonObject;
66
- readonly reviewThreadRootCommentId: number;
67
- readonly url: string | undefined;
68
- }
69
- /**
70
- * Common `issues` webhook actions, kept open to any action GitHub sends so
71
- * authors get autocomplete without losing forward compatibility.
72
- */
73
- export type GitHubIssueAction = "assigned" | "closed" | "edited" | "labeled" | "opened" | "reopened" | "unassigned" | "unlabeled" | (string & {});
74
- /** Common `pull_request` webhook actions, kept open to any action GitHub sends. */
75
- export type GitHubPullRequestAction = "closed" | "edited" | "labeled" | "opened" | "ready_for_review" | "reopened" | "synchronize" | "unlabeled" | (string & {});
76
- /** Normalized issue event payload. */
77
- export interface GitHubIssueEvent {
78
- readonly action: GitHubIssueAction;
79
- readonly issueNumber: number;
80
- readonly raw: JsonObject;
81
- }
82
- /** Normalized pull-request event payload. */
83
- export interface GitHubPullRequestEvent {
84
- readonly action: GitHubPullRequestAction;
85
- readonly headSha: string | null;
86
- readonly pullRequestNumber: number;
87
- readonly raw: JsonObject;
88
- }
89
- /** GitHub App identity attached to CI webhook payloads. */
90
- export interface GitHubAppRef {
91
- readonly slug: string | null;
92
- }
93
- /** Common fields normalized from GitHub CI webhook payloads. */
94
- export interface GitHubCiEvent {
95
- readonly action: string;
96
- readonly app: GitHubAppRef;
97
- readonly conclusion: string | null;
98
- readonly headSha: string | null;
99
- readonly pullRequests: readonly number[];
100
- readonly raw: JsonObject;
101
- readonly status: string | null;
102
- }
103
- /** Normalized `check_suite` webhook payload. */
104
- export interface GitHubCheckSuiteEvent extends GitHubCiEvent {
105
- readonly checkSuiteId: number;
106
- }
107
- /** Normalized `check_run` webhook payload. */
108
- export interface GitHubCheckRunEvent extends GitHubCiEvent {
109
- readonly checkRunId: number;
110
- }
111
- /** Normalized `workflow_run` webhook payload. */
112
- export interface GitHubWorkflowRunEvent extends GitHubCiEvent {
113
- readonly workflowRunId: number;
114
- }
115
- /** Normalized payload accepted by one of the GitHub CI event hooks. */
116
- export type GitHubCiPayload = GitHubCheckRunEvent | GitHubCheckSuiteEvent | GitHubWorkflowRunEvent;
117
- export interface GitHubPingEvent extends GitHubInboundEventBase {
118
- readonly kind: "ping";
119
- }
120
- export interface GitHubIssueCommentEvent extends GitHubInboundEventBase {
121
- readonly action: string;
122
- readonly baseRef: string | null;
123
- readonly baseSha: string | null;
124
- readonly comment: GitHubIssueComment;
125
- readonly conversation: GitHubConversationRef;
126
- readonly defaultBranch: string | null;
127
- readonly headRef: string | null;
128
- readonly headSha: string | null;
129
- readonly kind: "issue_comment";
130
- }
131
- export interface GitHubPullRequestReviewCommentEvent extends GitHubInboundEventBase {
132
- readonly action: string;
133
- readonly baseRef: string | null;
134
- readonly baseSha: string | null;
135
- readonly comment: GitHubPullRequestReviewComment;
136
- readonly conversation: GitHubConversationRef;
137
- readonly defaultBranch: string | null;
138
- readonly headRef: string | null;
139
- readonly headSha: string | null;
140
- readonly kind: "pull_request_review_comment";
141
- }
142
- export interface GitHubIssueWebhookEvent extends GitHubInboundEventBase {
143
- readonly action: string;
144
- readonly conversation: GitHubConversationRef;
145
- readonly issue: GitHubIssueEvent;
146
- readonly kind: "issues";
147
- }
148
- export interface GitHubPullRequestWebhookEvent extends GitHubInboundEventBase {
149
- readonly action: string;
150
- readonly baseRef: string | null;
151
- readonly baseSha: string | null;
152
- readonly conversation: GitHubConversationRef;
153
- readonly defaultBranch: string | null;
154
- readonly headRef: string | null;
155
- readonly headSha: string | null;
156
- readonly kind: "pull_request";
157
- readonly pullRequest: GitHubPullRequestEvent;
158
- }
159
- export interface GitHubCheckSuiteWebhookEvent extends GitHubInboundEventBase {
160
- readonly checkSuite: GitHubCheckSuiteEvent;
161
- readonly conversation: GitHubConversationRef;
162
- readonly kind: "check_suite";
163
- }
164
- export interface GitHubCheckRunWebhookEvent extends GitHubInboundEventBase {
165
- readonly checkRun: GitHubCheckRunEvent;
166
- readonly conversation: GitHubConversationRef;
167
- readonly kind: "check_run";
168
- }
169
- export interface GitHubWorkflowRunWebhookEvent extends GitHubInboundEventBase {
170
- readonly conversation: GitHubConversationRef;
171
- readonly kind: "workflow_run";
172
- readonly workflowRun: GitHubWorkflowRunEvent;
173
- }
174
- /** Parsed CI webhook envelopes consumed by the GitHub channel. */
175
- export type GitHubCiWebhookEvent = GitHubCheckRunWebhookEvent | GitHubCheckSuiteWebhookEvent | GitHubWorkflowRunWebhookEvent;
176
- interface GitHubInboundEventBase {
177
- readonly delivery: GitHubDelivery;
178
- readonly installationId: number | undefined;
179
- readonly raw: JsonObject;
180
- readonly repository: GitHubRepositoryRef;
181
- readonly sender: GitHubUser;
182
- }
183
- /** Parsed GitHub webhook event shape consumed by the channel. */
184
- export type GitHubInboundEvent = GitHubCheckRunWebhookEvent | GitHubCheckSuiteWebhookEvent | GitHubIssueCommentEvent | GitHubIssueWebhookEvent | GitHubPingEvent | GitHubPullRequestReviewCommentEvent | GitHubPullRequestWebhookEvent | GitHubWorkflowRunWebhookEvent;
185
- /** Parsed mention trigger for a bot-directed GitHub comment. */
186
- export interface GitHubCommentTrigger {
187
- readonly kind: "mention";
188
- readonly message: string;
189
- readonly token: string;
190
- }
2
+ import type { GitHubCommentTrigger, GitHubConversationKind, GitHubInboundEvent, GitHubRepositoryRef, GitHubUser } from "#public/channels/github/inbound-types.js";
3
+ export type { GitHubAppRef, GitHubCheckRunEvent, GitHubCheckRunWebhookEvent, GitHubCheckSuiteEvent, GitHubCheckSuiteWebhookEvent, GitHubCiEvent, GitHubCiPayload, GitHubCiWebhookEvent, GitHubComment, GitHubCommentTrigger, GitHubConversationKind, GitHubConversationRef, GitHubDelivery, GitHubInboundEvent, GitHubIssueAction, GitHubIssueComment, GitHubIssueCommentEvent, GitHubIssueEvent, GitHubIssueWebhookEvent, GitHubPullRequestAction, GitHubPullRequestEvent, GitHubPullRequestReviewComment, GitHubPullRequestReviewCommentEvent, GitHubPullRequestWebhookEvent, GitHubRepositoryRef, GitHubUser, GitHubWorkflowRunEvent, GitHubWorkflowRunWebhookEvent, } from "#public/channels/github/inbound-types.js";
191
4
  /** Builds the channel-local continuation token for a GitHub conversation. */
192
5
  export declare function githubContinuationToken(input: {
193
6
  readonly conversationKind: GitHubConversationKind;
@@ -225,4 +38,3 @@ export declare function formatGitHubContextBlock(input: {
225
38
  }): string;
226
39
  /** Prepends a `<github_context>` block to the inbound turn message. */
227
40
  export declare function prependGitHubContext(message: string | UserContent, block: string): string | UserContent;
228
- export {};
@@ -1,2 +1,2 @@
1
- import{isObject}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";function githubContinuationToken(e){return e.conversationKind===`issue`?`repo:${e.repositoryId}:issue:${requiredNumber(e.issueNumber,`issueNumber`)}`:e.conversationKind===`pull_request`?`repo:${e.repositoryId}:pull:${requiredNumber(e.pullRequestNumber,`pullRequestNumber`)}`:`repo:${e.repositoryId}:pull:${requiredNumber(e.pullRequestNumber,`pullRequestNumber`)}:review-comment:${requiredNumber(e.reviewThreadRootCommentId,`reviewThreadRootCommentId`)}`}function shouldDispatchGitHubComment(e){return isIgnoredGitHubComment(e.body,e.author,e.botName)?!1:extractGitHubCommentTrigger(e)!==null}function extractGitHubCommentTrigger(e){let t=e.botName?.trim();if(!t)return null;let n=RegExp(`@${escapeRegExp(t)}(?=$|[^A-Za-z0-9_-])`,`iu`).exec(e.body);if(n===null)return null;let r=n.index,i=r+n[0].length;return{kind:`mention`,message:`${e.body.slice(0,r)}${e.body.slice(i)}`.trim(),token:n[0]}}function parseGitHubWebhookEvent(e){let t=e.headers.get(`x-github-event`)??``,n=e.headers.get(`x-github-delivery`)??``;if(!t||!n)return null;let r=decodePayload(e.body,e.contentType),i=normalizeRepository(r.repository),a=normalizeUser(r.sender);if(i===null||a===void 0)return null;let o={delivery:{event:t,hookId:e.headers.get(`x-github-hook-id`)??void 0,id:n},installationId:readInstallationId(r.installation),raw:r,repository:i,sender:a};return t===`ping`?{...o,kind:`ping`}:t===`issue_comment`?parseIssueCommentEvent(o):t===`pull_request_review_comment`?parsePullRequestReviewCommentEvent(o):t===`issues`?parseIssueEvent(o):t===`pull_request`?parsePullRequestEvent(o):t===`check_suite`?parseCheckSuiteEvent(o):t===`check_run`?parseCheckRunEvent(o):t===`workflow_run`?parseWorkflowRunEvent(o):null}function formatGitHubContextBlock(e){return[`<github_context>`,`repository: ${e.repository.fullName}`,`repository_id: ${e.repository.id}`,...e.issueNumber!==void 0&&e.issueNumber!==null?[`issue_number: ${e.issueNumber}`]:[],...e.pullRequestNumber!==void 0&&e.pullRequestNumber!==null?[`pull_request_number: ${e.pullRequestNumber}`]:[],`sender: ${e.sender.login}`,`sender_type: ${e.sender.type}`,...e.commentUrl?[`comment_url: ${e.commentUrl}`]:[],...e.headSha?[`head_sha: ${e.headSha}`]:[],`delivery_id: ${e.deliveryId}`,`</github_context>`].join(`
2
- `)}function prependGitHubContext(e,t){return typeof e==`string`?e.length>0?`${t}\n\n${e}`:t:[{text:t,type:`text`},...e]}function parseIssueCommentEvent(n){let r=isObject(n.raw.issue)?n.raw.issue:null,i=isObject(n.raw.comment)?parseJsonObject(n.raw.comment):null,a=typeof r?.number==`number`?r.number:void 0;if(i===null||r===null||a===void 0)return null;let o=isObject(r.pull_request)?a:null,s=readAction(n.raw),c={author:normalizeUser(i.user),body:typeof i.body==`string`?i.body:``,htmlUrl:typeof i.html_url==`string`?i.html_url:void 0,id:typeof i.id==`number`?i.id:0,issueNumber:a,pullRequestNumber:o,raw:i,url:typeof i.url==`string`?i.url:void 0};return{...n,action:s,baseRef:null,baseSha:null,comment:c,conversation:{issueNumber:a,kind:o===null?`issue`:`pull_request`,pullRequestNumber:o},defaultBranch:null,headRef:null,headSha:null,kind:`issue_comment`}}function parsePullRequestReviewCommentEvent(n){let r=isObject(n.raw.comment)?parseJsonObject(n.raw.comment):null,i=isObject(n.raw.pull_request)?n.raw.pull_request:null,a=typeof i?.number==`number`?i.number:void 0;if(r===null||a===void 0)return null;let o=typeof r.id==`number`?r.id:0,s=typeof r.in_reply_to_id==`number`?r.in_reply_to_id:null,c={author:normalizeUser(r.user),body:typeof r.body==`string`?r.body:``,htmlUrl:typeof r.html_url==`string`?r.html_url:void 0,id:o,inReplyToId:s,pullRequestNumber:a,raw:r,reviewThreadRootCommentId:s??o,url:typeof r.url==`string`?r.url:void 0};return{...n,action:readAction(n.raw),baseRef:readPullRequestBaseRef(i),baseSha:readPullRequestBaseSha(i),comment:c,conversation:{issueNumber:null,kind:`review_thread`,pullRequestNumber:a},defaultBranch:readPullRequestDefaultBranch(i),headRef:readPullRequestHeadRef(i),headSha:readPullRequestHeadSha(i),kind:`pull_request_review_comment`}}function parseIssueEvent(n){let r=isObject(n.raw.issue)?n.raw.issue:null,i=typeof r?.number==`number`?r.number:void 0;return i===void 0?null:{...n,action:readAction(n.raw),conversation:{issueNumber:i,kind:`issue`,pullRequestNumber:null},issue:{action:readAction(n.raw),issueNumber:i,raw:parseJsonObject(r)},kind:`issues`}}function parsePullRequestEvent(n){let r=isObject(n.raw.pull_request)?n.raw.pull_request:null,i=typeof r?.number==`number`?r.number:void 0;return i===void 0?null:{...n,action:readAction(n.raw),baseRef:readPullRequestBaseRef(r),baseSha:readPullRequestBaseSha(r),conversation:{issueNumber:null,kind:`pull_request`,pullRequestNumber:i},defaultBranch:readPullRequestDefaultBranch(r),headRef:readPullRequestHeadRef(r),headSha:readPullRequestHeadSha(r),kind:`pull_request`,pullRequest:{action:readAction(n.raw),headSha:readPullRequestHeadSha(r),pullRequestNumber:i,raw:parseJsonObject(r)}}}function parseCheckSuiteEvent(e){let t=readEventObject(e.raw.check_suite);if(t===null)return null;let n=readId(t);if(n===null)return null;let r=normalizeCiEvent(e.raw,t,normalizeApp(t.app));return{...e,checkSuite:{...r,checkSuiteId:n},conversation:ciConversation(r.pullRequests),kind:`check_suite`}}function parseCheckRunEvent(e){let t=readEventObject(e.raw.check_run);if(t===null)return null;let n=readId(t);if(n===null)return null;let r=normalizeCiEvent(e.raw,t,normalizeApp(t.app));return{...e,checkRun:{...r,checkRunId:n},conversation:ciConversation(r.pullRequests),kind:`check_run`}}function parseWorkflowRunEvent(e){let t=readEventObject(e.raw.workflow_run);if(t===null)return null;let n=readId(t);if(n===null)return null;let r=normalizeCiEvent(e.raw,t,{slug:`github-actions`});return{...e,conversation:ciConversation(r.pullRequests),kind:`workflow_run`,workflowRun:{...r,workflowRunId:n}}}function normalizeCiEvent(e,t,n){return{action:readAction(e),app:n,conclusion:readNullableString(t.conclusion),headSha:readNullableString(t.head_sha),pullRequests:readPullRequestNumbers(t.pull_requests),raw:t,status:readNullableString(t.status)}}function readEventObject(n){return isObject(n)?parseJsonObject(n):null}function readId(e){return typeof e.id==`number`?e.id:null}function normalizeApp(t){return{slug:isObject(t)&&typeof t.slug==`string`?t.slug:null}}function readNullableString(e){return typeof e==`string`?e:null}function readPullRequestNumbers(t){return Array.isArray(t)?t.flatMap(t=>isObject(t)&&typeof t.number==`number`?[t.number]:[]):[]}function ciConversation(e){return{issueNumber:null,kind:`pull_request`,pullRequestNumber:e[0]??null}}function decodePayload(e,n){if(n?.includes(`application/x-www-form-urlencoded`)===!0){let n=new URLSearchParams(e).get(`payload`)??``;return parseJsonObject(JSON.parse(n))}return parseJsonObject(JSON.parse(e))}function normalizeRepository(t){if(!isObject(t))return null;let n=typeof t.full_name==`string`?t.full_name:``,[r=``,i=``]=n.split(`/`),a=isObject(t.owner)?t.owner:{},o=typeof a.login==`string`?a.login:r,s=typeof t.name==`string`?t.name:i,c=typeof t.id==`number`?t.id:0;return!o||!s?null:{fullName:n||`${o}/${s}`,id:c,name:s,owner:o,private:t.private===!0}}function normalizeUser(t){if(!isObject(t))return;let n=typeof t.login==`string`?t.login:``;if(n)return{htmlUrl:typeof t.html_url==`string`?t.html_url:void 0,id:typeof t.id==`number`?t.id:0,login:n,type:typeof t.type==`string`?t.type:`User`,url:typeof t.url==`string`?t.url:void 0}}function readInstallationId(t){if(isObject(t))return typeof t.id==`number`?t.id:void 0}function readAction(e){return typeof e.action==`string`?e.action:``}function readPullRequestHeadSha(t){let n=isObject(t?.head)?t.head:null;return typeof n?.sha==`string`?n.sha:null}function readPullRequestHeadRef(t){let n=isObject(t?.head)?t.head:null;return typeof n?.ref==`string`?n.ref:null}function readPullRequestBaseRef(t){let n=isObject(t?.base)?t.base:null;return typeof n?.ref==`string`?n.ref:null}function readPullRequestBaseSha(t){let n=isObject(t?.base)?t.base:null;return typeof n?.sha==`string`?n.sha:null}function readPullRequestDefaultBranch(t){let n=isObject(t?.base)?t.base:null,r=isObject(n?.repo)?n.repo:null;return typeof r?.default_branch==`string`?r.default_branch:null}function isIgnoredGitHubComment(e,t,n){if(e.includes(`<!-- eve:github:`))return!0;if(t===void 0)return!1;if(t.type===`Bot`)return!0;let r=n?`${n}[bot]`.toLowerCase():``;return r.length>0&&t.login.toLowerCase()===r}function requiredNumber(e,t){if(typeof e==`number`&&Number.isFinite(e))return e;throw Error(`githubContinuationToken requires ${t}.`)}function escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,`\\$&`)}export{extractGitHubCommentTrigger,formatGitHubContextBlock,githubContinuationToken,parseGitHubWebhookEvent,prependGitHubContext,shouldDispatchGitHubComment};
1
+ import{isObject}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";function githubContinuationToken(e){return e.conversationKind===`issue`?`repo:${e.repositoryId}:issue:${requiredNumber(e.issueNumber,`issueNumber`)}`:e.conversationKind===`pull_request`?`repo:${e.repositoryId}:pull:${requiredNumber(e.pullRequestNumber,`pullRequestNumber`)}`:`repo:${e.repositoryId}:pull:${requiredNumber(e.pullRequestNumber,`pullRequestNumber`)}:review-comment:${requiredNumber(e.reviewThreadRootCommentId,`reviewThreadRootCommentId`)}`}function shouldDispatchGitHubComment(e){return isIgnoredGitHubComment(e.body,e.author,e.botName)?!1:extractGitHubCommentTrigger(e)!==null}function extractGitHubCommentTrigger(e){let t=e.botName?.trim();if(!t)return null;let n=RegExp(`@${escapeRegExp(t)}(?=$|[^A-Za-z0-9_-])`,`iu`).exec(e.body);if(n===null)return null;let r=n.index,i=r+n[0].length;return{kind:`mention`,message:`${e.body.slice(0,r)}${e.body.slice(i)}`.trim(),token:n[0]}}function parseGitHubWebhookEvent(e){let t=decodePayload(e.body,e.contentType),n=readHeader(e.headers,`x-github-event`)??inferGitHubWebhookEventName(t);if(n===null)return null;let r=normalizeRepository(t.repository),i=normalizeUser(t.sender);if(r===null||i===void 0)return null;let a={delivery:{event:n,hookId:readHeader(e.headers,`x-github-hook-id`)??readGitHubHookId(t),id:readHeader(e.headers,`x-github-delivery`)??inferGitHubDeliveryId(n,t)},installationId:readInstallationId(t.installation),raw:t,repository:r,sender:i};return n===`ping`?{...a,kind:`ping`}:n===`issue_comment`?parseIssueCommentEvent(a):n===`pull_request_review_comment`?parsePullRequestReviewCommentEvent(a):n===`issues`?parseIssueEvent(a):n===`pull_request`?parsePullRequestEvent(a):n===`check_suite`?parseCheckSuiteEvent(a):n===`check_run`?parseCheckRunEvent(a):n===`workflow_run`?parseWorkflowRunEvent(a):null}function inferGitHubWebhookEventName(t){return isObject(t.hook)&&typeof t.zen==`string`?`ping`:isObject(t.comment)&&isObject(t.issue)?`issue_comment`:isObject(t.comment)&&isObject(t.pull_request)?`pull_request_review_comment`:isObject(t.check_suite)?`check_suite`:isObject(t.check_run)?`check_run`:isObject(t.workflow_run)?`workflow_run`:isObject(t.issue)?`issues`:isObject(t.pull_request)&&!isObject(t.review)?`pull_request`:null}function inferGitHubDeliveryId(e,t){return`inferred:${e}:${readObjectNumber(t.comment,`id`)??readObjectNumber(t.issue,`id`)??readObjectNumber(t.issue,`number`)??readObjectNumber(t.pull_request,`id`)??readObjectNumber(t.pull_request,`number`)??readObjectNumber(t.check_suite,`id`)??readObjectNumber(t.check_run,`id`)??readObjectNumber(t.workflow_run,`id`)??readObjectNumber(t.hook,`id`)??`unknown`}:${readAction(t)||`unknown`}`}function readHeader(e,t){let n=e.get(t)?.trim();return n&&n.length>0?n:void 0}function formatGitHubContextBlock(e){return[`<github_context>`,`repository: ${e.repository.fullName}`,`repository_id: ${e.repository.id}`,...e.issueNumber!==void 0&&e.issueNumber!==null?[`issue_number: ${e.issueNumber}`]:[],...e.pullRequestNumber!==void 0&&e.pullRequestNumber!==null?[`pull_request_number: ${e.pullRequestNumber}`]:[],`sender: ${e.sender.login}`,`sender_type: ${e.sender.type}`,...e.commentUrl?[`comment_url: ${e.commentUrl}`]:[],...e.headSha?[`head_sha: ${e.headSha}`]:[],`delivery_id: ${e.deliveryId}`,`</github_context>`].join(`
2
+ `)}function prependGitHubContext(e,t){return typeof e==`string`?e.length>0?`${t}\n\n${e}`:t:[{text:t,type:`text`},...e]}function parseIssueCommentEvent(n){let r=isObject(n.raw.issue)?n.raw.issue:null,i=isObject(n.raw.comment)?parseJsonObject(n.raw.comment):null,a=typeof r?.number==`number`?r.number:void 0;if(i===null||r===null||a===void 0)return null;let o=isObject(r.pull_request)?a:null,s=readAction(n.raw),c={author:normalizeUser(i.user),body:typeof i.body==`string`?i.body:``,htmlUrl:typeof i.html_url==`string`?i.html_url:void 0,id:typeof i.id==`number`?i.id:0,issueNumber:a,pullRequestNumber:o,raw:i,url:typeof i.url==`string`?i.url:void 0};return{...n,action:s,baseRef:null,baseSha:null,comment:c,conversation:{issueNumber:a,kind:o===null?`issue`:`pull_request`,pullRequestNumber:o},defaultBranch:null,headRef:null,headSha:null,kind:`issue_comment`}}function parsePullRequestReviewCommentEvent(n){let r=isObject(n.raw.comment)?parseJsonObject(n.raw.comment):null,i=isObject(n.raw.pull_request)?n.raw.pull_request:null,a=typeof i?.number==`number`?i.number:void 0;if(r===null||a===void 0)return null;let o=typeof r.id==`number`?r.id:0,s=typeof r.in_reply_to_id==`number`?r.in_reply_to_id:null,c={author:normalizeUser(r.user),body:typeof r.body==`string`?r.body:``,htmlUrl:typeof r.html_url==`string`?r.html_url:void 0,id:o,inReplyToId:s,pullRequestNumber:a,raw:r,reviewThreadRootCommentId:s??o,url:typeof r.url==`string`?r.url:void 0};return{...n,action:readAction(n.raw),baseRef:readPullRequestBaseRef(i),baseSha:readPullRequestBaseSha(i),comment:c,conversation:{issueNumber:null,kind:`review_thread`,pullRequestNumber:a},defaultBranch:readPullRequestDefaultBranch(i),headRef:readPullRequestHeadRef(i),headSha:readPullRequestHeadSha(i),kind:`pull_request_review_comment`}}function parseIssueEvent(n){let r=isObject(n.raw.issue)?n.raw.issue:null,i=typeof r?.number==`number`?r.number:void 0;return i===void 0?null:{...n,action:readAction(n.raw),conversation:{issueNumber:i,kind:`issue`,pullRequestNumber:null},issue:{action:readAction(n.raw),issueNumber:i,raw:parseJsonObject(r)},kind:`issues`}}function parsePullRequestEvent(n){let r=isObject(n.raw.pull_request)?n.raw.pull_request:null,i=typeof r?.number==`number`?r.number:void 0;return i===void 0?null:{...n,action:readAction(n.raw),baseRef:readPullRequestBaseRef(r),baseSha:readPullRequestBaseSha(r),conversation:{issueNumber:null,kind:`pull_request`,pullRequestNumber:i},defaultBranch:readPullRequestDefaultBranch(r),headRef:readPullRequestHeadRef(r),headSha:readPullRequestHeadSha(r),kind:`pull_request`,pullRequest:{action:readAction(n.raw),headSha:readPullRequestHeadSha(r),pullRequestNumber:i,raw:parseJsonObject(r)}}}function parseCheckSuiteEvent(e){let t=readEventObject(e.raw.check_suite);if(t===null)return null;let n=readId(t);if(n===null)return null;let r=normalizeCiEvent(e.raw,t,normalizeApp(t.app));return{...e,checkSuite:{...r,checkSuiteId:n},conversation:ciConversation(r.pullRequests),kind:`check_suite`}}function parseCheckRunEvent(e){let t=readEventObject(e.raw.check_run);if(t===null)return null;let n=readId(t);if(n===null)return null;let r=normalizeCiEvent(e.raw,t,normalizeApp(t.app));return{...e,checkRun:{...r,checkRunId:n},conversation:ciConversation(r.pullRequests),kind:`check_run`}}function parseWorkflowRunEvent(e){let t=readEventObject(e.raw.workflow_run);if(t===null)return null;let n=readId(t);if(n===null)return null;let r=normalizeCiEvent(e.raw,t,{slug:`github-actions`});return{...e,conversation:ciConversation(r.pullRequests),kind:`workflow_run`,workflowRun:{...r,workflowRunId:n}}}function normalizeCiEvent(e,t,n){return{action:readAction(e),app:n,conclusion:readNullableString(t.conclusion),headSha:readNullableString(t.head_sha),pullRequests:readPullRequestNumbers(t.pull_requests),raw:t,status:readNullableString(t.status)}}function readEventObject(n){return isObject(n)?parseJsonObject(n):null}function readId(e){return typeof e.id==`number`?e.id:null}function readObjectNumber(t,n){return isObject(t)&&typeof t[n]==`number`?t[n]:null}function normalizeApp(t){return{slug:isObject(t)&&typeof t.slug==`string`?t.slug:null}}function readNullableString(e){return typeof e==`string`?e:null}function readPullRequestNumbers(t){return Array.isArray(t)?t.flatMap(t=>isObject(t)&&typeof t.number==`number`?[t.number]:[]):[]}function ciConversation(e){return{issueNumber:null,kind:`pull_request`,pullRequestNumber:e[0]??null}}function decodePayload(e,n){if(n?.includes(`application/x-www-form-urlencoded`)===!0){let n=new URLSearchParams(e).get(`payload`)??``;return parseJsonObject(JSON.parse(n))}return parseJsonObject(JSON.parse(e))}function normalizeRepository(t){if(!isObject(t))return null;let n=typeof t.full_name==`string`?t.full_name:``,[r=``,i=``]=n.split(`/`),a=isObject(t.owner)?t.owner:{},o=typeof a.login==`string`?a.login:r,s=typeof t.name==`string`?t.name:i,c=typeof t.id==`number`?t.id:0;return!o||!s?null:{fullName:n||`${o}/${s}`,id:c,name:s,owner:o,private:t.private===!0}}function normalizeUser(t){if(!isObject(t))return;let n=typeof t.login==`string`?t.login:``;if(n)return{htmlUrl:typeof t.html_url==`string`?t.html_url:void 0,id:typeof t.id==`number`?t.id:0,login:n,type:typeof t.type==`string`?t.type:`User`,url:typeof t.url==`string`?t.url:void 0}}function readInstallationId(t){if(isObject(t))return typeof t.id==`number`?t.id:void 0}function readGitHubHookId(e){if(typeof e.hook_id==`number`)return String(e.hook_id);if(typeof e.hook_id==`string`&&e.hook_id.length>0)return e.hook_id;let t=readObjectNumber(e.hook,`id`);return t===null?void 0:String(t)}function readAction(e){return typeof e.action==`string`?e.action:``}function readPullRequestHeadSha(t){let n=isObject(t?.head)?t.head:null;return typeof n?.sha==`string`?n.sha:null}function readPullRequestHeadRef(t){let n=isObject(t?.head)?t.head:null;return typeof n?.ref==`string`?n.ref:null}function readPullRequestBaseRef(t){let n=isObject(t?.base)?t.base:null;return typeof n?.ref==`string`?n.ref:null}function readPullRequestBaseSha(t){let n=isObject(t?.base)?t.base:null;return typeof n?.sha==`string`?n.sha:null}function readPullRequestDefaultBranch(t){let n=isObject(t?.base)?t.base:null,r=isObject(n?.repo)?n.repo:null;return typeof r?.default_branch==`string`?r.default_branch:null}function isIgnoredGitHubComment(e,t,n){if(e.includes(`<!-- eve:github:`))return!0;if(t===void 0)return!1;if(t.type===`Bot`)return!0;let r=n?`${n}[bot]`.toLowerCase():``;return r.length>0&&t.login.toLowerCase()===r}function requiredNumber(e,t){if(typeof e==`number`&&Number.isFinite(e))return e;throw Error(`githubContinuationToken requires ${t}.`)}function escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,`\\$&`)}export{extractGitHubCommentTrigger,formatGitHubContextBlock,githubContinuationToken,parseGitHubWebhookEvent,prependGitHubContext,shouldDispatchGitHubComment};
@@ -1,4 +1,4 @@
1
- export { defineChannel, GET, POST, PUT, PATCH, DELETE, WS, type Channel, type ChannelDefinition, type ChannelSessionOps, type ChannelEvents, type InferChannelMetadata, type Session, type SessionHandle, type RouteDefinition, type RouteHandlerArgs, type SendFn, type SendOptions, type SendPayload, type GetSessionFn, type HttpRouteDefinition, type WebSocketMessage, type WebSocketPeer, type WebSocketRouteDefinition, type WebSocketRouteHandler, type WebSocketRouteHooks, type WebSocketUpgradeRequest, type WebSocketUpgradeResult, } from "#public/definitions/defineChannel.js";
1
+ export { defineChannel, GET, POST, PUT, PATCH, DELETE, WS, type Channel, type ChannelCors, type ChannelCorsOptions, type ChannelDefinition, type ChannelSessionOps, type ChannelEvents, type InferChannelMetadata, type Session, type SessionHandle, type RouteDefinition, type RouteHandlerArgs, type SendFn, type SendOptions, type SendPayload, type GetSessionFn, type HttpRouteDefinition, type WebSocketMessage, type WebSocketPeer, type WebSocketRouteDefinition, type WebSocketRouteHandler, type WebSocketRouteHooks, type WebSocketUpgradeRequest, type WebSocketUpgradeResult, } from "#public/definitions/defineChannel.js";
2
2
  export { createWebSocketUpgradeServer, type WebSocketUpgradeServerBridge, } from "#channel/websocket-upgrade-server.js";
3
3
  import type { Channel } from "#public/definitions/defineChannel.js";
4
4
  /**
@@ -1,5 +1,6 @@
1
1
  import type { FetchFileResult } from "#channel/adapter.js";
2
2
  import { CHANNEL_SENTINEL } from "#channel/compiled-channel.js";
3
+ import { type ChannelCors, type ChannelCorsOptions } from "#channel/cors.js";
3
4
  import type { TypedReceiveTarget } from "#channel/receive-target.js";
4
5
  import type { SessionAuthContext } from "#channel/types.js";
5
6
  import type { HandleMessageStreamEvent } from "#protocol/message.js";
@@ -8,6 +9,7 @@ import type { RouteDefinition, SendFn } from "#channel/routes.js";
8
9
  import type { Session, SessionHandle } from "#channel/session.js";
9
10
  declare const CHANNEL_METADATA_TYPE: unique symbol;
10
11
  export type { Session, SessionHandle } from "#channel/session.js";
12
+ export type { ChannelCors, ChannelCorsOptions } from "#channel/cors.js";
11
13
  export { GET, POST, PUT, PATCH, DELETE, WS } from "#channel/routes.js";
12
14
  export type { HttpRouteDefinition, RouteDefinition, RouteHandlerArgs, SendFn, SendOptions, SendPayload, GetSessionFn, WebSocketMessage, WebSocketPeer, WebSocketRouteDefinition, WebSocketRouteHandler, WebSocketRouteHooks, WebSocketUpgradeRequest, WebSocketUpgradeResult, } from "#channel/routes.js";
13
15
  type EventData<T extends HandleMessageStreamEvent["type"]> = Extract<HandleMessageStreamEvent, {
@@ -74,6 +76,13 @@ export interface ReceiveInput<TReceiveTarget = Record<string, unknown>> {
74
76
  */
75
77
  export interface ChannelDefinition<TState = undefined, TCtx = void, TReceiveTarget = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>> {
76
78
  readonly state?: TState;
79
+ /**
80
+ * CORS policy for this channel's HTTP routes. `true` enables H3/Nitro's
81
+ * permissive defaults (`origin`, methods, request headers, and exposed
82
+ * headers all `"*"`); `false` or omission leaves CORS untouched. Pass an
83
+ * object for a serializable subset of H3/Nitro CORS options.
84
+ */
85
+ readonly cors?: ChannelCors;
77
86
  /**
78
87
  * Builds the per-step channel context handed to `events` and `deliver`.
79
88
  * Receives the live {@link SessionHandle}, so a factory can close over it to
@@ -129,6 +138,7 @@ export interface Channel<TState = undefined, TReceiveTarget = Record<string, unk
129
138
  readonly __kind: typeof CHANNEL_SENTINEL;
130
139
  readonly [CHANNEL_METADATA_TYPE]?: TMetadata;
131
140
  readonly routes: readonly RouteDefinition<TState>[];
141
+ readonly cors?: ChannelCorsOptions;
132
142
  readonly receive?: (input: ReceiveInput<TReceiveTarget>, args: {
133
143
  send: SendFn<TState>;
134
144
  }) => Promise<Session>;
@@ -1 +1 @@
1
- import{CHANNEL_SENTINEL}from"#channel/compiled-channel.js";import{defaultDeliverResult}from"#channel/adapter.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";import{DELETE,GET,PATCH,POST,PUT,WS}from"#channel/routes.js";function defineChannel(t){let n=buildAdapter(t);return{__kind:CHANNEL_SENTINEL,routes:t.routes,adapter:n,receive:t.receive}}function buildAdapter(e){let i=e.state!=null,a=e.context!=null,o=e.fetchFile!==void 0,s=e.metadata,c=i||a||s!==void 0,l={},u=!1,d=[`turn.started`,`actions.requested`,`action.result`,`message.completed`,`message.appended`,`reasoning.appended`,`reasoning.completed`,`input.requested`,`turn.failed`,`turn.completed`,`session.failed`,`session.completed`,`session.waiting`,`authorization.required`,`authorization.completed`],f=e.events;for(let e of d){let t=f?.[e];t&&(u=!0,l[e]=(r,i)=>{let a={...i,continuationToken:i.session?.continuationToken??``,setContinuationToken:e=>i.session?.setContinuationToken(e)};return e===`session.failed`?t(r,a):t(r,a,buildCallbackContext())})}return!c&&!u&&!o?{kind:e.kindHint??HTTP_ADAPTER_KIND}:{kind:e.kindHint??`defineChannel`,state:i?{...e.state}:{},fetchFile:e.fetchFile,instrumentation:s===void 0?void 0:{metadata(e){return s(e)}},createAdapterContext(t){let n=t.state,r=t.session;return{...a?e.context(n,r):{},state:n,ctx:t.ctx,session:r}},deliver(e){return defaultDeliverResult(e)},...l}}export{DELETE,GET,PATCH,POST,PUT,WS,defineChannel};
1
+ import{CHANNEL_SENTINEL}from"#channel/compiled-channel.js";import{defaultDeliverResult}from"#channel/adapter.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{normalizeChannelCors}from"#channel/cors.js";import{HTTP_ADAPTER_KIND}from"#channel/http.js";import{DELETE,GET,PATCH,POST,PUT,WS}from"#channel/routes.js";function defineChannel(t){let n=buildAdapter(t),i=normalizeChannelCors(t.cors);return{__kind:CHANNEL_SENTINEL,routes:t.routes,adapter:n,cors:i,receive:t.receive}}function buildAdapter(e){let r=e.state!=null,a=e.context!=null,o=e.fetchFile!==void 0,s=e.metadata,c=r||a||s!==void 0,l={},u=!1,d=[`turn.started`,`actions.requested`,`action.result`,`message.completed`,`message.appended`,`reasoning.appended`,`reasoning.completed`,`input.requested`,`turn.failed`,`turn.completed`,`session.failed`,`session.completed`,`session.waiting`,`authorization.required`,`authorization.completed`],f=e.events;for(let e of d){let t=f?.[e];t&&(u=!0,l[e]=(r,i)=>{let a={...i,continuationToken:i.session?.continuationToken??``,setContinuationToken:e=>i.session?.setContinuationToken(e)};return e===`session.failed`?t(r,a):t(r,a,buildCallbackContext())})}return!c&&!u&&!o?{kind:e.kindHint??HTTP_ADAPTER_KIND}:{kind:e.kindHint??`defineChannel`,state:r?{...e.state}:{},fetchFile:e.fetchFile,instrumentation:s===void 0?void 0:{metadata(e){return s(e)}},createAdapterContext(t){let n=t.state,r=t.session;return{...a?e.context(n,r):{},state:n,ctx:t.ctx,session:r}},deliver(e){return defaultDeliverResult(e)},...l}}export{DELETE,GET,PATCH,POST,PUT,WS,defineChannel};
@@ -3,8 +3,9 @@ import { type RuntimeModelReference } from "#runtime/agent/bootstrap.js";
3
3
  /**
4
4
  * Returns true when authored runtime models should resolve through the
5
5
  * dedicated deterministic mock adapter. The adapter is internal to the test
6
- * tiers: it activates only under `NODE_ENV=test`, keeping the unit,
7
- * integration, and scenario suites deterministic and credential-free.
6
+ * tiers: unit, integration, and scenario tests activate it through
7
+ * `NODE_ENV=test`; spawned smoke servers use the explicit opt-in environment
8
+ * variable so their package-manager build keeps its normal environment.
8
9
  */
9
10
  export declare function shouldMockAuthoredRuntimeModels(): boolean;
10
11
  /**