@zackbart/connecta 0.28.0 → 0.29.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 (320) hide show
  1. package/CHANGELOG.md +961 -5
  2. package/README.md +62 -39
  3. package/bin/connecta.mjs +110 -139
  4. package/bin/meta-tool-names.d.mts +2 -0
  5. package/bin/meta-tool-names.mjs +9 -0
  6. package/bin/version.mjs +3 -0
  7. package/dist/access-tokens.js +53 -63
  8. package/dist/activity-request.js +8 -0
  9. package/dist/activity.d.ts +76 -42
  10. package/dist/activity.js +110 -42
  11. package/dist/auth/clerk-sdk/client.d.ts +65 -0
  12. package/dist/auth/clerk-sdk/client.js +5 -0
  13. package/dist/auth/clerk-sdk/generated.js +1845 -0
  14. package/dist/auth/clerk-transport.js +19 -0
  15. package/dist/auth/clerk.d.ts +17 -7
  16. package/dist/auth/clerk.js +189 -107
  17. package/dist/auth/cloudflare-access.js +25 -26
  18. package/dist/auth/downstream-client-metadata.d.ts +29 -0
  19. package/dist/auth/downstream-client-metadata.js +133 -0
  20. package/dist/auth/downstream-oauth.js +1632 -1509
  21. package/dist/auth/downstream-revocation.js +106 -0
  22. package/dist/auth/oauth-token-response.js +231 -0
  23. package/dist/auth/oauth-v2-migration.js +116 -0
  24. package/dist/auth/static-oauth.js +526 -0
  25. package/dist/auth-elicitation.js +283 -0
  26. package/dist/branding.d.ts +8 -16
  27. package/dist/branding.js +26 -59
  28. package/dist/byte-read-response.js +39 -0
  29. package/dist/call-admission.js +12 -16
  30. package/dist/catalog-cache.js +739 -0
  31. package/dist/catalog-drift.d.ts +50 -15
  32. package/dist/catalog-drift.js +365 -128
  33. package/dist/catalog-fingerprint.js +2 -4
  34. package/dist/catalog-freshness.js +13 -0
  35. package/dist/catalog-limits.js +2 -2
  36. package/dist/catalog-service.js +368 -224
  37. package/dist/catalog.js +43 -84
  38. package/dist/concurrency.js +3 -4
  39. package/dist/config-defaults.d.ts +39 -0
  40. package/dist/config-defaults.js +46 -0
  41. package/dist/config-schema.d.ts +181 -0
  42. package/dist/config-schema.js +435 -0
  43. package/dist/config-value-sources.js +102 -0
  44. package/dist/config.d.ts +631 -0
  45. package/dist/config.js +503 -0
  46. package/dist/connector-access.d.ts +1 -0
  47. package/dist/connector-access.js +13 -15
  48. package/dist/connector-caller.d.ts +8 -0
  49. package/dist/connector-caller.js +15 -6
  50. package/dist/connector-scope.js +1 -1
  51. package/dist/connectors/api-connector.d.ts +220 -0
  52. package/dist/connectors/api-connector.js +214 -0
  53. package/dist/connectors/api.d.ts +8 -71
  54. package/dist/connectors/api.js +13 -99
  55. package/dist/connectors/guarded-fetch.d.ts +144 -0
  56. package/dist/connectors/guarded-fetch.js +108 -25
  57. package/dist/connectors/negotiation-cache.js +46 -0
  58. package/dist/connectors/option-shapes.js +27 -0
  59. package/dist/connectors/remote-mcp.d.ts +30 -4
  60. package/dist/connectors/remote-mcp.js +1780 -351
  61. package/dist/connectors/resource-uri.js +335 -0
  62. package/dist/credential-contract.d.ts +10 -0
  63. package/dist/credential-rules.js +1 -3
  64. package/dist/credential-url.js +108 -0
  65. package/dist/credentials.d.ts +6 -1
  66. package/dist/credentials.js +27 -18
  67. package/dist/d1.d.ts +130 -0
  68. package/dist/d1.js +290 -0
  69. package/dist/describe-config.d.ts +165 -0
  70. package/dist/describe-config.js +315 -0
  71. package/dist/described.js +106 -0
  72. package/dist/downstream-input-context.js +119 -0
  73. package/dist/downstream-input.js +323 -0
  74. package/dist/errors.d.ts +97 -20
  75. package/dist/errors.js +158 -80
  76. package/dist/execute.js +453 -305
  77. package/dist/executor-admission.d.ts +1 -0
  78. package/dist/executor-admission.js +11 -15
  79. package/dist/executor-contract.d.ts +20 -0
  80. package/dist/executor-contract.js +48 -0
  81. package/dist/executor-result.js +24 -9
  82. package/dist/executors/quickjs-child.js +3 -4
  83. package/dist/executors/quickjs-runtime.js +147 -59
  84. package/dist/executors/quickjs.js +29 -35
  85. package/dist/favicon.js +1 -2
  86. package/dist/fix-prompt.js +1 -3
  87. package/dist/guest-runtime.js +188 -0
  88. package/dist/guest-types.d.ts +176 -0
  89. package/dist/guest-types.js +1 -0
  90. package/dist/html-security.js +24 -0
  91. package/dist/identity.js +1 -3
  92. package/dist/inbound-credential.js +52 -0
  93. package/dist/index.d.ts +25 -257
  94. package/dist/index.js +65 -478
  95. package/dist/invocation-auth.js +69 -0
  96. package/dist/invocation.js +230 -73
  97. package/dist/json-schema.d.ts +1 -1
  98. package/dist/mcp-client-context.js +35 -0
  99. package/dist/mcp-result.js +11 -7
  100. package/dist/meta-output.js +76 -0
  101. package/dist/meta-tool-names.d.ts +2 -0
  102. package/dist/meta-tool-names.js +3 -0
  103. package/dist/meta-tools.js +285 -209
  104. package/dist/module-contracts.d.ts +8 -23
  105. package/dist/node.d.ts +0 -2
  106. package/dist/node.js +2 -2
  107. package/dist/oauth-callback-outcome.js +1 -3
  108. package/dist/oauth-handoff.js +117 -0
  109. package/dist/oauth-partition.js +17 -0
  110. package/dist/oauth-sealing.js +20 -0
  111. package/dist/operator-record.d.ts +137 -0
  112. package/dist/operator-record.js +420 -0
  113. package/dist/operator-ui/assets.js +31 -0
  114. package/dist/operator-ui/contract.d.ts +72 -0
  115. package/dist/operator-ui/contract.js +1 -0
  116. package/dist/operator-ui/fix-prompts.d.ts +18 -0
  117. package/dist/operator-ui/generated.js +5 -4
  118. package/dist/operator-ui/model.d.ts +12 -87
  119. package/dist/operator-ui/model.js +2 -9
  120. package/dist/operator-ui/setup-commands.js +1 -3
  121. package/dist/operator-ui/view.d.ts +323 -0
  122. package/dist/operator-ui/view.js +62 -189
  123. package/dist/page-styles.js +2 -3
  124. package/dist/program-source.js +14 -2
  125. package/dist/{exempt-writes.js → program-writes.js} +55 -18
  126. package/dist/provider.d.ts +142 -0
  127. package/dist/provider.js +187 -0
  128. package/dist/providers/_shared/google/result-size.js +57 -0
  129. package/dist/providers/_shared/google/service-account.d.ts +58 -0
  130. package/dist/providers/_shared/google/service-account.js +500 -0
  131. package/dist/providers/_shared/google/workspace.d.ts +276 -0
  132. package/dist/providers/_shared/google/workspace.js +518 -0
  133. package/dist/providers/basecamp/index.d.ts +43 -0
  134. package/dist/providers/basecamp/index.js +997 -0
  135. package/dist/providers/basecamp/skill.generated.js +9 -0
  136. package/dist/providers/breeze/index.d.ts +34 -0
  137. package/dist/providers/breeze/index.js +1446 -0
  138. package/dist/providers/breeze/skill.generated.js +9 -0
  139. package/dist/providers/ccb/index.d.ts +103 -0
  140. package/dist/providers/ccb/index.js +1725 -0
  141. package/dist/providers/ccb/skill.generated.js +9 -0
  142. package/dist/providers/{cloudflare.d.ts → cloudflare/index.d.ts} +8 -7
  143. package/dist/providers/{cloudflare.js → cloudflare/index.js} +171 -738
  144. package/dist/providers/cloudflare/skill.generated.js +10 -0
  145. package/dist/providers/docs/index.d.ts +54 -0
  146. package/dist/providers/docs/index.js +1237 -0
  147. package/dist/providers/docs/skill.generated.js +9 -0
  148. package/dist/providers/drive/index.d.ts +53 -0
  149. package/dist/providers/drive/index.js +1523 -0
  150. package/dist/providers/drive/skill.generated.js +9 -0
  151. package/dist/providers/forms/index.d.ts +54 -0
  152. package/dist/providers/forms/index.js +1217 -0
  153. package/dist/providers/forms/skill.generated.js +11 -0
  154. package/dist/providers/github/auth.d.ts +32 -0
  155. package/dist/providers/github/auth.js +361 -0
  156. package/dist/providers/github/hosted.js +218 -0
  157. package/dist/providers/github/index.d.ts +13 -0
  158. package/dist/providers/github/index.js +140 -0
  159. package/dist/providers/github/key.js +100 -0
  160. package/dist/providers/github/rest.js +321 -0
  161. package/dist/providers/github/scope.d.ts +29 -0
  162. package/dist/providers/github/scope.js +124 -0
  163. package/dist/providers/github/skill.generated.js +8 -0
  164. package/dist/providers/gmail/index.d.ts +51 -0
  165. package/dist/providers/gmail/index.js +1436 -0
  166. package/dist/providers/gmail/skill.generated.js +9 -0
  167. package/dist/providers/{linear.d.ts → linear/index.d.ts} +11 -14
  168. package/dist/providers/linear/index.js +352 -0
  169. package/dist/providers/linear/skill.generated.js +8 -0
  170. package/dist/providers/{mixpanel.d.ts → mixpanel/index.d.ts} +5 -10
  171. package/dist/providers/mixpanel/index.js +416 -0
  172. package/dist/providers/mixpanel/skill.generated.js +9 -0
  173. package/dist/providers/{notion.d.ts → notion/index.d.ts} +8 -8
  174. package/dist/providers/{notion.js → notion/index.js} +226 -239
  175. package/dist/providers/notion/skill.generated.js +10 -0
  176. package/dist/providers/overflow/index.d.ts +60 -0
  177. package/dist/providers/overflow/index.js +1535 -0
  178. package/dist/providers/overflow/skill.generated.js +8 -0
  179. package/dist/providers/planning-center/index.d.ts +59 -0
  180. package/dist/providers/planning-center/index.js +2199 -0
  181. package/dist/providers/planning-center/skill.generated.js +10 -0
  182. package/dist/providers/{revenuecat.d.ts → revenuecat/index.d.ts} +5 -10
  183. package/dist/providers/revenuecat/index.js +557 -0
  184. package/dist/providers/revenuecat/skill.generated.js +11 -0
  185. package/dist/providers/sheets/index.d.ts +54 -0
  186. package/dist/providers/sheets/index.js +1237 -0
  187. package/dist/providers/sheets/skill.generated.js +10 -0
  188. package/dist/providers/slides/index.d.ts +53 -0
  189. package/dist/providers/slides/index.js +2645 -0
  190. package/dist/providers/slides/skill.generated.js +9 -0
  191. package/dist/providers/{stripe.d.ts → stripe/index.d.ts} +5 -12
  192. package/dist/providers/stripe/index.js +266 -0
  193. package/dist/providers/stripe/skill.generated.js +11 -0
  194. package/dist/providers/tithely/index.d.ts +49 -0
  195. package/dist/providers/tithely/index.js +1003 -0
  196. package/dist/providers/tithely/skill.generated.js +8 -0
  197. package/dist/providers/{vercel.d.ts → vercel/index.d.ts} +8 -8
  198. package/dist/providers/vercel/index.js +1038 -0
  199. package/dist/providers/vercel/mcp-ownership.js +212 -0
  200. package/dist/providers/vercel/skill.generated.js +11 -0
  201. package/dist/registry.d.ts +108 -171
  202. package/dist/registry.js +513 -925
  203. package/dist/request-state.js +21 -0
  204. package/dist/resource-read.js +100 -0
  205. package/dist/result-shapes.js +17 -49
  206. package/dist/retired-toolkits.js +1 -1
  207. package/dist/routes/access-tokens.js +3 -6
  208. package/dist/routes/activity-context.js +21 -0
  209. package/dist/routes/activity-disclosure.js +40 -0
  210. package/dist/routes/activity.js +59 -21
  211. package/dist/routes/actor-labels.js +3 -50
  212. package/dist/routes/connect.js +221 -0
  213. package/dist/routes/credentials.js +15 -27
  214. package/dist/routes/mcp.js +356 -130
  215. package/dist/routes/oauth-client-metadata.js +15 -0
  216. package/dist/routes/oauth-management.js +45 -107
  217. package/dist/routes/oauth.js +136 -57
  218. package/dist/routes/operator.js +3 -3
  219. package/dist/routes/shared.d.ts +25 -64
  220. package/dist/routes/shared.js +160 -80
  221. package/dist/routes/skills.js +30 -0
  222. package/dist/routes/ui-config.js +225 -0
  223. package/dist/routes/ui-data.js +40 -35
  224. package/dist/routes/ui.js +66 -56
  225. package/dist/runtime/admission.js +4 -2
  226. package/dist/runtime/call-admission.js +3 -1
  227. package/dist/runtime/connector-scope.js +1 -4
  228. package/dist/runtime/run.js +10 -39
  229. package/dist/runtime/services.js +12 -117
  230. package/dist/runtime/shared-read.js +1 -3
  231. package/dist/runtime/storage.js +8 -1
  232. package/dist/sent-secrets.d.ts +52 -0
  233. package/dist/sent-secrets.js +474 -0
  234. package/dist/server.js +28 -71
  235. package/dist/skills.js +406 -174
  236. package/dist/sqlite.d.ts +48 -0
  237. package/dist/sqlite.js +166 -0
  238. package/dist/storage/keys.js +428 -0
  239. package/dist/storage/memory.js +7 -0
  240. package/dist/storage/sql.d.ts +66 -0
  241. package/dist/storage/sql.js +534 -0
  242. package/dist/timeout.js +4 -2
  243. package/dist/tool-name.js +17 -0
  244. package/dist/tool-safety.d.ts +9 -35
  245. package/dist/tool-safety.js +20 -40
  246. package/dist/types.d.ts +320 -54
  247. package/dist/types.js +0 -1
  248. package/dist/ui.d.ts +7 -19
  249. package/dist/ui.js +76 -90
  250. package/dist/url-safety.js +3 -6
  251. package/dist/usage-guide.js +137 -0
  252. package/dist/validate.d.ts +7 -0
  253. package/dist/validate.js +309 -47
  254. package/dist/version.d.ts +1 -7
  255. package/dist/version.js +3 -7
  256. package/dist/worker.d.ts +11 -0
  257. package/dist/worker.js +434 -0
  258. package/documentation/architecture.md +665 -230
  259. package/documentation/auth.md +962 -458
  260. package/documentation/code-mode.md +501 -312
  261. package/documentation/meta-tools.md +449 -200
  262. package/documentation/operator-tests.md +93 -0
  263. package/documentation/provider-migration-0.29.md +60 -0
  264. package/examples/worker/AGENTS.md +34 -12
  265. package/examples/worker/README.md +286 -255
  266. package/examples/worker/kv-to-d1.wrangler.jsonc +26 -0
  267. package/examples/worker/scripts/copy-kv-to-d1.mjs +162 -0
  268. package/examples/worker/src/connecta.config.ts +151 -0
  269. package/examples/worker/src/index.ts +14 -197
  270. package/examples/worker/wrangler.jsonc +15 -35
  271. package/package.json +125 -35
  272. package/templates/node/.dockerignore +1 -2
  273. package/templates/node/.env.example +20 -21
  274. package/templates/node/AGENTS.md +21 -17
  275. package/templates/node/Dockerfile +3 -5
  276. package/templates/node/README.md +133 -58
  277. package/templates/node/docker-compose.yml +11 -12
  278. package/templates/node/package.json +4 -2
  279. package/templates/node/src/connecta.config.ts +119 -0
  280. package/templates/node/src/index.ts +9 -154
  281. package/templates/node/src/provision-token.ts +17 -0
  282. package/AGENTS.md +0 -170
  283. package/dist/artifacts/connector.d.ts +0 -58
  284. package/dist/artifacts/connector.js +0 -730
  285. package/dist/artifacts/document.js +0 -86
  286. package/dist/artifacts/guide.js +0 -140
  287. package/dist/artifacts/html-scan.js +0 -329
  288. package/dist/artifacts/json.js +0 -78
  289. package/dist/artifacts/kv-store.d.ts +0 -20
  290. package/dist/artifacts/kv-store.js +0 -140
  291. package/dist/artifacts/markdown.js +0 -478
  292. package/dist/artifacts/module.d.ts +0 -37
  293. package/dist/artifacts/module.js +0 -66
  294. package/dist/artifacts/operations.d.ts +0 -197
  295. package/dist/artifacts/operations.js +0 -1002
  296. package/dist/artifacts/refresh.d.ts +0 -55
  297. package/dist/artifacts/refresh.js +0 -236
  298. package/dist/artifacts/routes.js +0 -206
  299. package/dist/artifacts/types.d.ts +0 -214
  300. package/dist/artifacts/types.js +0 -22
  301. package/dist/artifacts/validate.d.ts +0 -62
  302. package/dist/artifacts/validate.js +0 -651
  303. package/dist/artifacts.d.ts +0 -6
  304. package/dist/artifacts.js +0 -9
  305. package/dist/auth/bearer.d.ts +0 -11
  306. package/dist/auth/bearer.js +0 -50
  307. package/dist/providers/linear.js +0 -217
  308. package/dist/providers/mixpanel.js +0 -247
  309. package/dist/providers/revenuecat.js +0 -317
  310. package/dist/providers/stripe.js +0 -253
  311. package/dist/providers/vercel.js +0 -1253
  312. package/dist/storage/file.d.ts +0 -15
  313. package/dist/storage/file.js +0 -455
  314. package/ethos.md +0 -93
  315. package/examples/worker/src/cloudflare-kv.ts +0 -43
  316. package/examples/worker/src/d1-activity-row.ts +0 -155
  317. package/examples/worker/src/d1-activity.ts +0 -147
  318. package/examples/worker/src/d1-storage.ts +0 -138
  319. package/examples/worker/src/r2-artifact-blobs.ts +0 -29
  320. package/templates/node/src/file-activity.ts +0 -182
package/dist/server.js CHANGED
@@ -3,10 +3,11 @@ import { notFoundResponse } from "./branding.js";
3
3
  import { aggregateCallAdmissionSnapshots } from "./call-admission.js";
4
4
  import { isAdmittingExecutor } from "./executor-admission.js";
5
5
  import { createMcpRoute, MCP_CORS_HEADERS } from "./routes/mcp.js";
6
- import { routeOAuthCallback, } from "./routes/oauth.js";
6
+ import { routeOAuthCallback } from "./routes/oauth.js";
7
+ import { routeOAuthClientMetadata } from "./routes/oauth-client-metadata.js";
8
+ import { routeConnect } from "./routes/connect.js";
7
9
  import { runEdge } from "./runtime/run.js";
8
- import { withSecurityHeaders, } from "./routes/shared.js";
9
- const isArtifactPath = (path) => path === "/artifacts" || path.startsWith("/artifacts/");
10
+ import { authMetadata, withSecurityHeaders, } from "./routes/shared.js";
10
11
  /**
11
12
  * Build the Web-standard fetch handler.
12
13
  *
@@ -20,47 +21,24 @@ const isArtifactPath = (path) => path === "/artifacts" || path.startsWith("/arti
20
21
  * `close()` has disposed that runtime.
21
22
  */
22
23
  export function createFetchHandler(opts) {
23
- const { auth, publicUrl, registry } = opts;
24
+ const { registry } = opts;
25
+ const { auth, publicUrl } = opts.config;
24
26
  const routeMcp = createMcpRoute(opts);
25
- // The first provider's metadata answer for this request, if any has one.
26
- const metadata = (request, baseUrl) => Effect.gen(function* () {
27
- for (const provider of auth) {
28
- const handleMetadata = provider.handleMetadata?.bind(provider);
29
- if (handleMetadata) {
30
- const response = yield* Effect.promise(async () => handleMetadata(request, baseUrl));
31
- if (response)
32
- return response;
33
- }
34
- }
35
- return null;
36
- });
27
+ const metadata = (request, baseUrl) => Effect.promise(async () => (await authMetadata(request, baseUrl, auth))?.response ?? null);
37
28
  const health = async () => {
38
29
  // The executor is required, so code admission always has a shape to
39
30
  // report: either the executor's own pool or the fallback controller
40
31
  // wrapped around it at construction.
41
- const codeAdmission = isAdmittingExecutor(opts.executor)
42
- ? opts.executor.admissionSnapshot?.()
43
- : undefined;
32
+ const codeAdmission = isAdmittingExecutor(opts.executor) ? opts.executor.admissionSnapshot?.() : undefined;
44
33
  return Response.json({
45
34
  status: "ok",
46
35
  connectors: registry.listConnectors().length,
47
- server: opts.serverInfo,
36
+ server: opts.config.serverInfo,
48
37
  // Which sandbox, not how it is tuned: `connecta doctor` reports the
49
38
  // executor it just exercised rather than assuming one, and a
50
39
  // deployment whose executor identifies as nothing omits the key
51
40
  // instead of inviting a guess (#368).
52
- ...(opts.executorName !== undefined
53
- ? { executor: { name: opts.executorName } }
54
- : {}),
55
- // Counts only, from refreshes that already happened — the endpoint
56
- // asks no downstream anything, and `connecta doctor` reads it to
57
- // report a stale allowlist without a probe of its own (#343).
58
- // Stable 64-bit hashes preserve that shape without publishing ids.
59
- catalogDrift: Object.fromEntries(await Promise.all(Object.entries(registry.catalogDriftSnapshot()).map(async ([id, report]) => {
60
- const hash = new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(id)));
61
- const key = Array.from(hash.subarray(0, 8), byte => byte.toString(16).padStart(2, "0")).join("");
62
- return [key, report];
63
- }))),
41
+ ...(opts.executorName !== undefined ? { executor: { name: opts.executorName } } : {}),
64
42
  admission: {
65
43
  policy: "global-fifo",
66
44
  requests: opts.requestAdmission.snapshot(),
@@ -71,24 +49,32 @@ export function createFetchHandler(opts) {
71
49
  },
72
50
  reservedRoutes: [
73
51
  "/health",
74
- ...(opts.ui?.reservedPaths ?? []),
75
- ...(opts.ui && opts.activity?.list ? ["/activity"] : []),
76
- ...(opts.ui && opts.accessTokens ? ["/tokens"] : []),
77
- ...(opts.ui && opts.artifactsModule ? ["/artifacts", "/artifacts/*"] : []),
52
+ ...(opts.config.ui?.reservedPaths ?? []),
53
+ ...(opts.config.ui && opts.config.activity?.store.list ? ["/activity"] : []),
54
+ ...(opts.config.ui && opts.config.accessTokens ? ["/tokens"] : []),
78
55
  ],
79
56
  },
80
- ...(opts.deploymentInfo ? { deployment: opts.deploymentInfo } : {}),
57
+ ...(opts.config.deploymentInfo ? { deployment: opts.config.deploymentInfo } : {}),
81
58
  });
82
59
  };
83
60
  const route = (context) => Effect.gen(function* () {
84
61
  const { request, path, baseUrl } = context;
62
+ const clientMetadata = routeOAuthClientMetadata(context);
63
+ if (clientMetadata)
64
+ return clientMetadata;
85
65
  // Private mutations own OPTIONS so they never inherit wildcard CORS.
86
- const ui = opts.ui;
66
+ const ui = opts.config.ui;
87
67
  if (ui) {
88
68
  const uiResponse = yield* Effect.promise(() => ui.handle(context));
89
69
  if (uiResponse)
90
70
  return uiResponse;
91
71
  }
72
+ const connect = yield* routeConnect(context);
73
+ if (connect)
74
+ return connect;
75
+ const oauthCallback = yield* routeOAuthCallback(context);
76
+ if (oauthCallback)
77
+ return oauthCallback;
92
78
  if (request.method === "OPTIONS") {
93
79
  const preflight = yield* routeMcp.handle(context);
94
80
  if (preflight)
@@ -105,46 +91,20 @@ export function createFetchHandler(opts) {
105
91
  const response = yield* metadata(request, baseUrl);
106
92
  if (response)
107
93
  return response;
108
- return notFoundResponse(request, opts);
94
+ return notFoundResponse(request, opts.config);
109
95
  }
110
96
  if (path === "/health")
111
97
  return yield* Effect.promise(health);
112
- const oauthCallback = yield* routeOAuthCallback(context);
113
- if (oauthCallback)
114
- return oauthCallback;
115
98
  const mcp = yield* routeMcp.handle(context);
116
99
  if (mcp)
117
100
  return mcp;
118
- return notFoundResponse(request, opts);
101
+ return notFoundResponse(request, opts.config);
119
102
  });
120
103
  const serve = (request, runtimeContext) => Effect.suspend(() => {
121
104
  const url = new URL(request.url);
122
105
  const baseUrl = publicUrl ?? url.origin;
123
106
  const path = url.pathname;
124
- const defer = runtimeContext
125
- ? runtimeContext.waitUntil.bind(runtimeContext)
126
- : undefined;
127
- // The artifact hostname has no MCP, health, OAuth, or operator routes.
128
- // Dispatch before MCP origin checks so even a hostile /mcp gets the same
129
- // 404 as any other unserved path.
130
- if (opts.artifactOrigin && url.origin === new URL(opts.artifactOrigin).origin) {
131
- if (!isArtifactPath(path) || !opts.ui || !opts.artifactsModule) {
132
- return Effect.succeed(withSecurityHeaders(notFoundResponse(request, opts), url, path));
133
- }
134
- const context = {
135
- request, url, path, baseUrl: opts.artifactOrigin, opts, defer, runtimeContext,
136
- };
137
- return Effect.map(Effect.promise(() => opts.ui.handle(context)), response => withSecurityHeaders(response ?? notFoundResponse(request, opts), url, path));
138
- }
139
- if (opts.artifactOrigin && isArtifactPath(path) && opts.ui && opts.artifactsModule) {
140
- const target = new URL(opts.artifactOrigin);
141
- target.pathname = path;
142
- target.search = url.search;
143
- return Effect.succeed(withSecurityHeaders(new Response(null, {
144
- status: 308,
145
- headers: { Location: target.toString() },
146
- }), url, path));
147
- }
107
+ const defer = runtimeContext ? runtimeContext.waitUntil.bind(runtimeContext) : undefined;
148
108
  const originRefusal = routeMcp.rejectOrigin(request);
149
109
  if (originRefusal) {
150
110
  return Effect.succeed(withSecurityHeaders(originRefusal, url, path));
@@ -155,10 +115,7 @@ export function createFetchHandler(opts) {
155
115
  // external DNS, TLS, and the tunnel in front of connecta — so /health is
156
116
  // exempt. It is unauthenticated, returns no user data, and sets no
157
117
  // cookies, so forcing HTTPS on it protects nothing.
158
- if (publicUrl &&
159
- path !== "/health" &&
160
- new URL(publicUrl).protocol === "https:" &&
161
- url.protocol === "http:") {
118
+ if (publicUrl && path !== "/health" && new URL(publicUrl).protocol === "https:" && url.protocol === "http:") {
162
119
  // Assign the path and query onto the configured URL instead of resolving
163
120
  // attacker-controlled text against it. A pathname beginning with `//`
164
121
  // (including a backslash form normalized by URL parsing) is an authority