@cursor/july 0.1.37 → 0.1.39

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 (122) hide show
  1. package/README.md +3 -1
  2. package/dist/bin/agent-serve.js +0 -0
  3. package/dist/channels/slack/api.d.ts +5 -0
  4. package/dist/channels/slack/api.d.ts.map +1 -1
  5. package/dist/channels/slack/api.js +57 -18
  6. package/dist/channels/slack/constants.d.ts +2 -0
  7. package/dist/channels/slack/constants.d.ts.map +1 -1
  8. package/dist/channels/slack/constants.js +2 -0
  9. package/dist/channels/slack/post-update-delivery.d.ts +85 -0
  10. package/dist/channels/slack/post-update-delivery.d.ts.map +1 -0
  11. package/dist/connections.d.ts +14 -2
  12. package/dist/connections.d.ts.map +1 -1
  13. package/dist/connections.js +13 -1
  14. package/dist/docs/404.html +3 -3
  15. package/dist/docs/ab.html +6 -6
  16. package/dist/docs/assets/{app.Bu9SRvZ9.js → app.BQ8Hihdf.js} +1 -1
  17. package/dist/docs/assets/chunks/@localSearchIndexroot.B-VTH4As.js +1 -0
  18. package/dist/docs/assets/chunks/{VPLocalSearchBox.D9u9czHO.js → VPLocalSearchBox.BBCr8Yuy.js} +2 -2
  19. package/dist/docs/assets/chunks/theme.CK_NiGC-.js +2 -0
  20. package/dist/docs/assets/{example-agents_weather-agent.md.CrGZ0SqR.js → example-agents_weather-agent.md.DC3lINjo.js} +5 -6
  21. package/dist/docs/assets/{reference_connections.md.DGqAsFXb.js → reference_connections.md.CSQiNzre.js} +11 -2
  22. package/dist/docs/assets/{reference_connections.md.DGqAsFXb.lean.js → reference_connections.md.CSQiNzre.lean.js} +1 -1
  23. package/dist/docs/assets/{style.Bj-IXa5W.css → style.CK3hwt6q.css} +1 -1
  24. package/dist/docs/building-with-agents.html +6 -6
  25. package/dist/docs/concepts.html +6 -6
  26. package/dist/docs/deployment.html +6 -6
  27. package/dist/docs/evals.html +6 -6
  28. package/dist/docs/example-agents/approval-buddy.html +6 -6
  29. package/dist/docs/example-agents/benny.html +6 -6
  30. package/dist/docs/example-agents/bugbot.html +6 -6
  31. package/dist/docs/example-agents/codebase-wiki.html +6 -6
  32. package/dist/docs/example-agents/codeowners-review.html +6 -6
  33. package/dist/docs/example-agents/concierge.html +6 -6
  34. package/dist/docs/example-agents/fsd.html +6 -6
  35. package/dist/docs/example-agents/index.html +6 -6
  36. package/dist/docs/example-agents/knowledge-base.html +6 -6
  37. package/dist/docs/example-agents/oncall.html +6 -6
  38. package/dist/docs/example-agents/security-reviewer.html +6 -6
  39. package/dist/docs/example-agents/slack-agent.html +6 -6
  40. package/dist/docs/example-agents/weather-agent.html +10 -11
  41. package/dist/docs/guides/agent-to-agent.html +6 -6
  42. package/dist/docs/guides/cloud-runtime.html +6 -6
  43. package/dist/docs/guides/github.html +6 -6
  44. package/dist/docs/guides/human-in-the-loop.html +6 -6
  45. package/dist/docs/guides/mcp-oauth.html +6 -6
  46. package/dist/docs/guides/slack.html +6 -6
  47. package/dist/docs/guides/webhooks.html +6 -6
  48. package/dist/docs/hashmap.json +1 -1
  49. package/dist/docs/hillclimbing.html +6 -6
  50. package/dist/docs/index.html +6 -6
  51. package/dist/docs/quickstart.html +6 -6
  52. package/dist/docs/reference/agent-config.html +6 -6
  53. package/dist/docs/reference/artifacts.html +6 -6
  54. package/dist/docs/reference/channels.html +6 -6
  55. package/dist/docs/reference/cli.html +6 -6
  56. package/dist/docs/reference/connections.html +17 -8
  57. package/dist/docs/reference/hooks.html +6 -6
  58. package/dist/docs/reference/http-api.html +6 -6
  59. package/dist/docs/reference/instructions.html +6 -6
  60. package/dist/docs/reference/playground.html +5 -5
  61. package/dist/docs/reference/project-layout.html +6 -6
  62. package/dist/docs/reference/prompt.html +6 -6
  63. package/dist/docs/reference/schedules.html +6 -6
  64. package/dist/docs/reference/sessions.html +6 -6
  65. package/dist/docs/reference/skills.html +6 -6
  66. package/dist/docs/reference/subagents.html +6 -6
  67. package/dist/docs/reference/tools.html +6 -6
  68. package/dist/docs/scaffolding-agents.html +5 -5
  69. package/dist/docs/storage.html +6 -6
  70. package/dist/docs/troubleshooting.html +5 -5
  71. package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
  72. package/dist/files-backends/cursor-hosted.js +13 -2
  73. package/dist/internal/discovery.d.ts.map +1 -1
  74. package/dist/internal/discovery.js +95 -2
  75. package/dist/internal/framework-storage-selection.d.ts +37 -0
  76. package/dist/internal/framework-storage-selection.d.ts.map +1 -0
  77. package/dist/internal/framework-storage-selection.js +35 -0
  78. package/dist/internal/inline-stdio-define-stub.d.ts +3 -0
  79. package/dist/internal/inline-stdio-define-stub.d.ts.map +1 -0
  80. package/dist/internal/inline-stdio-define-stub.js +4 -0
  81. package/dist/internal/inline-stdio-mcp.d.ts +32 -0
  82. package/dist/internal/inline-stdio-mcp.d.ts.map +1 -0
  83. package/dist/internal/inline-stdio-mcp.js +180 -0
  84. package/dist/internal/json-dir-store.d.ts +32 -0
  85. package/dist/internal/json-dir-store.d.ts.map +1 -0
  86. package/dist/internal/package-inline-stdio.d.ts +12 -0
  87. package/dist/internal/package-inline-stdio.d.ts.map +1 -0
  88. package/dist/internal/package-inline-stdio.js +109 -0
  89. package/dist/internal/persistence-coordinator.d.ts +127 -0
  90. package/dist/internal/persistence-coordinator.d.ts.map +1 -0
  91. package/dist/internal/session-engine.d.ts.map +1 -1
  92. package/dist/internal/session-engine.js +9 -2
  93. package/dist/multi-tenant.d.ts +80 -0
  94. package/dist/multi-tenant.d.ts.map +1 -0
  95. package/dist/multi-tenant.js +69 -0
  96. package/dist/persistence.d.ts +184 -0
  97. package/dist/persistence.d.ts.map +1 -0
  98. package/dist/playground/assets/index-BRhBbnd4.css +1 -0
  99. package/dist/playground/assets/{index-DRtusTV1.js → index-_2WKw9a-.js} +43 -43
  100. package/dist/playground/index.html +2 -2
  101. package/dist/types.d.ts +20 -1
  102. package/dist/types.d.ts.map +1 -1
  103. package/dist/types.js +4 -0
  104. package/docs/example-agents/weather-agent.md +25 -22
  105. package/docs/reference/connections.md +17 -0
  106. package/package.json +3 -1
  107. package/skills/framework-map/SKILL.md +1 -1
  108. package/src/channels/slack/api.ts +72 -20
  109. package/src/channels/slack/constants.ts +2 -0
  110. package/src/connections.ts +18 -1
  111. package/src/files-backends/cursor-hosted.ts +13 -2
  112. package/src/internal/discovery.ts +111 -1
  113. package/src/internal/framework-storage-selection.ts +45 -0
  114. package/src/internal/inline-stdio-define-stub.ts +4 -0
  115. package/src/internal/inline-stdio-mcp.ts +229 -0
  116. package/src/internal/package-inline-stdio.ts +121 -0
  117. package/src/internal/session-engine.ts +9 -2
  118. package/src/types.ts +27 -0
  119. package/dist/docs/assets/chunks/@localSearchIndexroot.pVFW7oJd.js +0 -1
  120. package/dist/docs/assets/chunks/theme.Bc61GzOf.js +0 -2
  121. package/dist/playground/assets/index-DZp6n4bv.css +0 -1
  122. /package/dist/docs/assets/{example-agents_weather-agent.md.CrGZ0SqR.lean.js → example-agents_weather-agent.md.DC3lINjo.lean.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-hosted.d.ts","sourceRoot":"","sources":["../../src/files-backends/cursor-hosted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,YAAY,EAGlB,MAAM,aAAa,CAAC;AAWrB;;;;;;GAMG;AACH,eAAO,MAAM,mCAAmC,gCACjB,CAAC;AAgBhC;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAGT;AAED,MAAM,WAAW,wBAAwB;IACvC,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAuCD,KAAK,kBAAkB,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG;IAChD,gFAAgF;IAChF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,wBAA6B,GACrC,kBAAkB,CAyWpB"}
1
+ {"version":3,"file":"cursor-hosted.d.ts","sourceRoot":"","sources":["../../src/files-backends/cursor-hosted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,YAAY,EAGlB,MAAM,aAAa,CAAC;AAWrB;;;;;;GAMG;AACH,eAAO,MAAM,mCAAmC,gCACjB,CAAC;AAgBhC;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAGT;AAED,MAAM,WAAW,wBAAwB;IACvC,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAuCD,KAAK,kBAAkB,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG;IAChD,gFAAgF;IAChF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,wBAA6B,GACrC,kBAAkB,CAoXpB"}
@@ -368,10 +368,21 @@ export function cursorHostedFiles(options = {}) {
368
368
  method: "GET",
369
369
  redirect: "manual",
370
370
  });
371
- if (response.status === 404 || response.status === 403) {
372
- // A presigned GET for a missing object surfaces as 403 on S3.
371
+ if (response.status === 404) {
373
372
  return undefined;
374
373
  }
374
+ // A 403 here is deliberately *not* absence. Absence was already
375
+ // settled above: the store refuses to presign a path with no live
376
+ // object, so reaching this point means the object existed moments
377
+ // ago. What produces a 403 after a good presign is an expired or
378
+ // clock-skewed signature, a policy change, or a delete that raced the
379
+ // GET — all transient or retryable, none of them "definitively gone".
380
+ //
381
+ // Reporting them as absence is how a store blip becomes data loss:
382
+ // `undefined` on a continuation read is taken as "unknown token", and
383
+ // the engine mints a fresh session under it, forking the thread. The
384
+ // delete race resolves itself on retry, where the presign returns 404
385
+ // and this correctly reads as a miss.
375
386
  if (!response.ok) {
376
387
  throw new Error(`cursorHostedFiles: download of "${key}" failed (HTTP ${response.status})`);
377
388
  }
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/internal/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiBH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EASrB,KAAK,UAAU,EAqBhB,MAAM,aAAa,CAAC;AA0BrB,MAAM,WAAW,uBAAuB;IACtC,sDAAsD;IACtD,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC3E;AAmBD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASrE;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,EAAE,CAAC,CA2B1B;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC,CAoBzD;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,uBAAuB,GAAG;IACjC,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CACtB,GACL,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC,CAgBzD;AAWD,iFAAiF;AACjF,eAAO,MAAM,cAAc,EAAE,GAAG,CAAC,MAAM,CAIrC,CAAC;AAEH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,YAAY,CAAC,CAiEvB;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAElE;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAOnE;AA8oBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAiB3E;AAkrBD,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,CA6InE"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/internal/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiBH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EASrB,KAAK,UAAU,EAuBhB,MAAM,aAAa,CAAC;AA2BrB,MAAM,WAAW,uBAAuB;IACtC,sDAAsD;IACtD,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC3E;AAmBD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASrE;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,EAAE,CAAC,CA2B1B;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC,CAoBzD;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,uBAAuB,GAAG;IACjC,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CACtB,GACL,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC,CAgBzD;AAWD,iFAAiF;AACjF,eAAO,MAAM,cAAc,EAAE,GAAG,CAAC,MAAM,CAIrC,CAAC;AAEH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,YAAY,CAAC,CAiEvB;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAElE;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAOnE;AA2pBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAiB3E;AAgxBD,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,CA6InE"}
@@ -31,7 +31,7 @@ import { pathToFileURL } from "node:url";
31
31
  import { resolveABMaxPlaygroundSessions } from "../ab.js";
32
32
  import { resolveArtifactsMax } from "../artifacts.js";
33
33
  import { httpChannel } from "../channels.js";
34
- import { cursorAccountServersHasMixedWildcard, DEFAULT_MODEL, MAX_RUNNING_TURNS_LIMIT, normalizeCursorAccountServers, toPublicCloudInfo, } from "../types.js";
34
+ import { cursorAccountServersHasMixedWildcard, DEFAULT_MODEL, isInlineStdioConnection, MAX_RUNNING_TURNS_LIMIT, normalizeCursorAccountServers, toPublicCloudInfo, } from "../types.js";
35
35
  import { registerAuthoredModuleLoaders } from "./authored-loaders.js";
36
36
  import { normalizePositiveInt } from "./bounded-int.js";
37
37
  import { getDefinitionKind } from "./brand.js";
@@ -41,6 +41,7 @@ import { parseFrontmatter } from "./frontmatter.js";
41
41
  import { isReservedSecretName, MAX_EGRESS_DOMAINS, validateEgressDomain, validateSecretName, } from "./hosting.js";
42
42
  import { toolInputJsonSchema } from "./json-schema.js";
43
43
  import { MCP_ENDPOINT_PATH, mcpEndpointToolNames } from "./mcp-endpoint.js";
44
+ import { packageInlineStdioConnection } from "./package-inline-stdio.js";
44
45
  import { withIdentityPreamble } from "./workspace.js";
45
46
  const MODULE_EXTENSIONS = new Set([".ts", ".mts", ".js", ".mjs"]);
46
47
  const NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
@@ -739,6 +740,18 @@ function hasAuthorizationHeader(headers) {
739
740
  }
740
741
  return Object.keys(headers).some((key) => key.toLowerCase() === "authorization");
741
742
  }
743
+ function connectionHasSpawnOrRemote(connection) {
744
+ if ("cursorAccount" in connection && connection.cursorAccount === true) {
745
+ return true;
746
+ }
747
+ if ("agent" in connection && !isBlank(connection.agent)) {
748
+ return true;
749
+ }
750
+ if ("url" in connection && !isBlank(connection.url)) {
751
+ return true;
752
+ }
753
+ return "command" in connection && !isBlank(connection.command);
754
+ }
742
755
  function connectionTransport(connection) {
743
756
  if ("cursorAccount" in connection && connection.cursorAccount === true) {
744
757
  const servers = normalizeCursorAccountServers(connection.servers);
@@ -850,6 +863,23 @@ function loadConnections(ctx, connectionsDir) {
850
863
  continue;
851
864
  }
852
865
  const connection = definition;
866
+ if (isInlineStdioConnection(connection) &&
867
+ connectionHasSpawnOrRemote(connection)) {
868
+ ctx.diagnostics.push({
869
+ severity: "error",
870
+ path: displayPath(ctx, entryPath),
871
+ message: "MCP connection `tools` cannot be combined with `command`, `url`, `agent`, or `cursorAccount`. Author TypeScript tools, or point at an existing server, not both.",
872
+ });
873
+ continue;
874
+ }
875
+ if (isInlineStdioConnection(connection)) {
876
+ const packed = yield loadInlineStdioConnection(ctx, name, entryPath, connection);
877
+ if (packed === undefined) {
878
+ continue;
879
+ }
880
+ connections.push(packed);
881
+ continue;
882
+ }
853
883
  if ("url" in connection &&
854
884
  connection.oauth === true &&
855
885
  hasAuthorizationHeader(connection.headers)) {
@@ -875,7 +905,7 @@ function loadConnections(ctx, connectionsDir) {
875
905
  ctx.diagnostics.push({
876
906
  severity: "error",
877
907
  path: displayPath(ctx, entryPath),
878
- message: "MCP connections require a `url` (http/sse), a `command` (stdio), an `agent` (peer agent slug on the same serve host), or `cursorAccount: true` (the Cursor account's MCP connectors).",
908
+ message: "MCP connections require a `url` (http/sse), a `command` (stdio), `tools` (TypeScript packaged as stdio), an `agent` (peer agent slug on the same serve host), or `cursorAccount: true` (the Cursor account's MCP connectors).",
879
909
  });
880
910
  continue;
881
911
  }
@@ -908,6 +938,69 @@ function loadConnections(ctx, connectionsDir) {
908
938
  return connections;
909
939
  });
910
940
  }
941
+ function loadInlineStdioConnection(ctx, name, entryPath, connection) {
942
+ return __awaiter(this, void 0, void 0, function* () {
943
+ const tools = connection.tools;
944
+ const names = Object.keys(tools);
945
+ if (names.length === 0) {
946
+ ctx.diagnostics.push({
947
+ severity: "error",
948
+ path: displayPath(ctx, entryPath),
949
+ message: "MCP connection `tools` must declare at least one tool.",
950
+ });
951
+ return undefined;
952
+ }
953
+ for (const toolName of names) {
954
+ if (!NAME_PATTERN.test(toolName)) {
955
+ ctx.diagnostics.push({
956
+ severity: "error",
957
+ path: displayPath(ctx, entryPath),
958
+ message: `MCP tool name "${toolName}" must match ${NAME_PATTERN}.`,
959
+ });
960
+ return undefined;
961
+ }
962
+ const tool = tools[toolName];
963
+ if (tool === undefined || isBlank(tool.description)) {
964
+ ctx.diagnostics.push({
965
+ severity: "error",
966
+ path: displayPath(ctx, entryPath),
967
+ message: `MCP tool "${toolName}" requires a non-empty description.`,
968
+ });
969
+ return undefined;
970
+ }
971
+ if (typeof tool.execute !== "function") {
972
+ ctx.diagnostics.push({
973
+ severity: "error",
974
+ path: displayPath(ctx, entryPath),
975
+ message: `MCP tool "${toolName}" requires an execute(input) function.`,
976
+ });
977
+ return undefined;
978
+ }
979
+ }
980
+ try {
981
+ const transport = yield packageInlineStdioConnection({
982
+ name,
983
+ entryPath,
984
+ tools,
985
+ absWorkingDir: ctx.rootDir,
986
+ });
987
+ return {
988
+ name,
989
+ transport,
990
+ description: connection.description,
991
+ hostOnly: connection.hostOnly,
992
+ };
993
+ }
994
+ catch (error) {
995
+ ctx.diagnostics.push({
996
+ severity: "error",
997
+ path: displayPath(ctx, entryPath),
998
+ message: `Failed to package inline stdio MCP connection: ${errorMessage(error)}`,
999
+ });
1000
+ return undefined;
1001
+ }
1002
+ });
1003
+ }
911
1004
  // ============================================================================
912
1005
  // Subagents
913
1006
  // ============================================================================
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Which backend framework session state is mirrored to.
3
+ *
4
+ * Framework state — session records, event chunks, the continuation index —
5
+ * is how a session outlives the process that served it. Today that mirror
6
+ * exists only when the agent author wrote `agent/storage.ts`, which makes
7
+ * platform durability an agent-level decision: of the first-party agents,
8
+ * some choose `cursorHostedStorage()` and some choose `fileKv()` (pod-local
9
+ * disk, lost on pod replacement), and one selects between them at runtime by
10
+ * reading the deployment-id environment variable itself.
11
+ *
12
+ * That selection is a hosting-mode question, not an authoring question, and
13
+ * this module is where it will move. It deliberately reproduces today's
14
+ * behavior exactly for now — authored definition or nothing — so the change
15
+ * that makes framework durability automatic is a change to
16
+ * {@link selectFrameworkStorageDefinition} alone, reviewable on its own and
17
+ * revertable without touching the engine.
18
+ *
19
+ * Local disk is not part of this decision. `<stateRoot>/sessions/<id>/`
20
+ * already holds `session.json` and `events.ndjson` unconditionally, through
21
+ * the session store; what this selects is the durable mirror *beyond* the
22
+ * pod's filesystem.
23
+ */
24
+ import type { StorageDefinition } from "../storage.js";
25
+ export interface FrameworkStorageSelectionInput {
26
+ /** `agent/storage.ts`, when the author wrote one. */
27
+ readonly authored: StorageDefinition | undefined;
28
+ }
29
+ /**
30
+ * Pick the backend for framework session state.
31
+ *
32
+ * Returns `undefined` when there is no mirror, in which case the pod's local
33
+ * disk is the only copy — the condition F0 exists to remove for hosted
34
+ * deployments.
35
+ */
36
+ export declare function selectFrameworkStorageDefinition(input: FrameworkStorageSelectionInput): StorageDefinition | undefined;
37
+ //# sourceMappingURL=framework-storage-selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-storage-selection.d.ts","sourceRoot":"","sources":["../../src/internal/framework-storage-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,WAAW,8BAA8B;IAC7C,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAClD;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,8BAA8B,GACpC,iBAAiB,GAAG,SAAS,CAI/B"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Which backend framework session state is mirrored to.
3
+ *
4
+ * Framework state — session records, event chunks, the continuation index —
5
+ * is how a session outlives the process that served it. Today that mirror
6
+ * exists only when the agent author wrote `agent/storage.ts`, which makes
7
+ * platform durability an agent-level decision: of the first-party agents,
8
+ * some choose `cursorHostedStorage()` and some choose `fileKv()` (pod-local
9
+ * disk, lost on pod replacement), and one selects between them at runtime by
10
+ * reading the deployment-id environment variable itself.
11
+ *
12
+ * That selection is a hosting-mode question, not an authoring question, and
13
+ * this module is where it will move. It deliberately reproduces today's
14
+ * behavior exactly for now — authored definition or nothing — so the change
15
+ * that makes framework durability automatic is a change to
16
+ * {@link selectFrameworkStorageDefinition} alone, reviewable on its own and
17
+ * revertable without touching the engine.
18
+ *
19
+ * Local disk is not part of this decision. `<stateRoot>/sessions/<id>/`
20
+ * already holds `session.json` and `events.ndjson` unconditionally, through
21
+ * the session store; what this selects is the durable mirror *beyond* the
22
+ * pod's filesystem.
23
+ */
24
+ /**
25
+ * Pick the backend for framework session state.
26
+ *
27
+ * Returns `undefined` when there is no mirror, in which case the pod's local
28
+ * disk is the only copy — the condition F0 exists to remove for hosted
29
+ * deployments.
30
+ */
31
+ export function selectFrameworkStorageDefinition(input) {
32
+ // Today: the author decides, or there is no mirror. Hosting-mode selection
33
+ // replaces this body; every caller already routes through here.
34
+ return input.authored;
35
+ }
@@ -0,0 +1,3 @@
1
+ /** Bundled stand-in for `@anysphere/agent-serve/connections` / `@cursor/july/connections`. */
2
+ export declare function defineConnection<T>(config: T): T;
3
+ //# sourceMappingURL=inline-stdio-define-stub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-stdio-define-stub.d.ts","sourceRoot":"","sources":["../../src/internal/inline-stdio-define-stub.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAEhD"}
@@ -0,0 +1,4 @@
1
+ /** Bundled stand-in for `@anysphere/agent-serve/connections` / `@cursor/july/connections`. */
2
+ export function defineConnection(config) {
3
+ return config;
4
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Generic newline-delimited JSON-RPC stdio MCP server for packaged
3
+ * `defineConnection({ tools })` modules. Bundled into `node -e` so a
4
+ * repo-less cloud VM can spawn it. Keep this file free of framework
5
+ * barrels and the official MCP SDK.
6
+ */
7
+ type InlineTool = {
8
+ description: string;
9
+ inputSchema?: {
10
+ safeParse?: (value: unknown) => {
11
+ success: boolean;
12
+ data?: unknown;
13
+ error?: {
14
+ issues?: Array<{
15
+ path: unknown[];
16
+ message: string;
17
+ }>;
18
+ };
19
+ };
20
+ };
21
+ execute: (input: Record<string, unknown>) => unknown | Promise<unknown>;
22
+ };
23
+ export type InlineStdioCatalogEntry = {
24
+ description: string;
25
+ inputSchema: Record<string, unknown>;
26
+ };
27
+ export type InlineStdioDefinition = {
28
+ tools?: Record<string, InlineTool>;
29
+ };
30
+ export declare function serveInlineStdioMcp(serverName: string, definition: InlineStdioDefinition, catalog: Record<string, InlineStdioCatalogEntry>): void;
31
+ export {};
32
+ //# sourceMappingURL=inline-stdio-mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-stdio-mcp.d.ts","sourceRoot":"","sources":["../../src/internal/inline-stdio-mcp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,KAAK,UAAU,GAAG;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QACZ,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK;YAC9B,OAAO,EAAE,OAAO,CAAC;YACjB,IAAI,CAAC,EAAE,OAAO,CAAC;YACf,KAAK,CAAC,EAAE;gBAAE,MAAM,CAAC,EAAE,KAAK,CAAC;oBAAE,IAAI,EAAE,OAAO,EAAE,CAAC;oBAAC,OAAO,EAAE,MAAM,CAAA;iBAAE,CAAC,CAAA;aAAE,CAAC;SAClE,CAAC;KACH,CAAC;IACF,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACzE,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACpC,CAAC;AAmKF,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,qBAAqB,EACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,GAC/C,IAAI,CAwBN"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Generic newline-delimited JSON-RPC stdio MCP server for packaged
3
+ * `defineConnection({ tools })` modules. Bundled into `node -e` so a
4
+ * repo-less cloud VM can spawn it. Keep this file free of framework
5
+ * barrels and the official MCP SDK.
6
+ */
7
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
9
+ return new (P || (P = Promise))(function (resolve, reject) {
10
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
11
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
12
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
13
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
14
+ });
15
+ };
16
+ const PROTOCOL_VERSION = "2025-03-26";
17
+ function write(message) {
18
+ process.stdout.write(`${JSON.stringify(message)}\n`);
19
+ }
20
+ function stringifyResult(result) {
21
+ if (typeof result === "string") {
22
+ return result;
23
+ }
24
+ return JSON.stringify(result);
25
+ }
26
+ function isMcpEnvelope(result) {
27
+ return (typeof result === "object" &&
28
+ result !== null &&
29
+ "content" in result &&
30
+ Array.isArray(result.content));
31
+ }
32
+ function validateInput(tool, args) {
33
+ var _a;
34
+ var _b;
35
+ const record = typeof args === "object" && args !== null
36
+ ? args
37
+ : {};
38
+ const schema = tool.inputSchema;
39
+ if (schema === undefined || typeof schema.safeParse !== "function") {
40
+ return { ok: true, value: record };
41
+ }
42
+ const parsed = schema.safeParse(args !== null && args !== void 0 ? args : {});
43
+ if (parsed.success) {
44
+ const value = typeof parsed.data === "object" && parsed.data !== null
45
+ ? parsed.data
46
+ : record;
47
+ return { ok: true, value };
48
+ }
49
+ const issues = (_b = (_a = parsed.error) === null || _a === void 0 ? void 0 : _a.issues) !== null && _b !== void 0 ? _b : [];
50
+ const message = issues
51
+ .map((issue) => {
52
+ const path = issue.path.join(".");
53
+ return path === "" ? issue.message : `${path}: ${issue.message}`;
54
+ })
55
+ .join("; ") || "invalid input";
56
+ return { ok: false, message };
57
+ }
58
+ function handle(message, serverName, tools, catalog) {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ const method = message.method;
61
+ if (typeof method !== "string" || !("id" in message)) {
62
+ return;
63
+ }
64
+ const id = message.id;
65
+ const params = typeof message.params === "object" && message.params !== null
66
+ ? message.params
67
+ : {};
68
+ try {
69
+ if (method === "initialize") {
70
+ const requested = params.protocolVersion;
71
+ write({
72
+ jsonrpc: "2.0",
73
+ id,
74
+ result: {
75
+ protocolVersion: typeof requested === "string" ? requested : PROTOCOL_VERSION,
76
+ capabilities: { tools: {} },
77
+ serverInfo: { name: serverName, version: "0.1.0" },
78
+ },
79
+ });
80
+ return;
81
+ }
82
+ if (method === "ping") {
83
+ write({ jsonrpc: "2.0", id, result: {} });
84
+ return;
85
+ }
86
+ if (method === "tools/list") {
87
+ write({
88
+ jsonrpc: "2.0",
89
+ id,
90
+ result: {
91
+ tools: Object.entries(catalog).map(([name, entry]) => ({
92
+ name,
93
+ description: entry.description,
94
+ inputSchema: entry.inputSchema,
95
+ })),
96
+ },
97
+ });
98
+ return;
99
+ }
100
+ if (method === "tools/call") {
101
+ const name = params.name;
102
+ const tool = typeof name === "string" ? tools[name] : undefined;
103
+ if (tool === undefined) {
104
+ write({
105
+ jsonrpc: "2.0",
106
+ id,
107
+ result: {
108
+ content: [{ type: "text", text: `Unknown tool: ${String(name)}` }],
109
+ isError: true,
110
+ },
111
+ });
112
+ return;
113
+ }
114
+ const checked = validateInput(tool, params.arguments);
115
+ if (!checked.ok) {
116
+ write({
117
+ jsonrpc: "2.0",
118
+ id,
119
+ result: {
120
+ content: [{ type: "text", text: checked.message }],
121
+ isError: true,
122
+ },
123
+ });
124
+ return;
125
+ }
126
+ const result = yield tool.execute(checked.value);
127
+ if (isMcpEnvelope(result)) {
128
+ write({ jsonrpc: "2.0", id, result });
129
+ return;
130
+ }
131
+ write({
132
+ jsonrpc: "2.0",
133
+ id,
134
+ result: {
135
+ content: [{ type: "text", text: stringifyResult(result) }],
136
+ },
137
+ });
138
+ return;
139
+ }
140
+ write({
141
+ jsonrpc: "2.0",
142
+ id,
143
+ error: { code: -32601, message: `Method not found: ${method}` },
144
+ });
145
+ }
146
+ catch (error) {
147
+ write({
148
+ jsonrpc: "2.0",
149
+ id,
150
+ error: {
151
+ code: -32603,
152
+ message: error instanceof Error ? error.message : String(error),
153
+ },
154
+ });
155
+ }
156
+ });
157
+ }
158
+ export function serveInlineStdioMcp(serverName, definition, catalog) {
159
+ var _a;
160
+ const tools = (_a = definition.tools) !== null && _a !== void 0 ? _a : {};
161
+ let buffer = "";
162
+ process.stdin.setEncoding("utf8");
163
+ process.stdin.on("data", (chunk) => {
164
+ buffer += chunk;
165
+ let newline = buffer.indexOf("\n");
166
+ while (newline !== -1) {
167
+ const line = buffer.slice(0, newline).replace(/\r$/, "");
168
+ buffer = buffer.slice(newline + 1);
169
+ if (line.length > 0) {
170
+ try {
171
+ void handle(JSON.parse(line), serverName, tools, catalog);
172
+ }
173
+ catch (error) {
174
+ process.stderr.write(`${serverName}: failed to parse MCP message: ${error instanceof Error ? error.message : String(error)}\n`);
175
+ }
176
+ }
177
+ newline = buffer.indexOf("\n");
178
+ }
179
+ });
180
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Small filesystem helpers for one-JSON-file-per-id persistence under a
3
+ * project-relative directory (eval run snapshots, A/B aggregate snapshots).
4
+ */
5
+ export declare function assertNonEmptyDir(dir: string, fnName: string): string;
6
+ /** Resolve `dir` against `projectRoot` when relative. */
7
+ export declare function resolveProjectRelativeDir(args: {
8
+ dir: string;
9
+ projectRoot: string;
10
+ }): string;
11
+ /** List `*.json` basenames in `root` (any order). Missing dir → []. */
12
+ export declare function listJsonBasenames(root: string): Promise<string[]>;
13
+ /**
14
+ * Read and JSON.parse every `*.json` file under `root`. Missing dir → [].
15
+ * Unreadable or corrupt files are skipped so one bad snapshot cannot wipe
16
+ * the rest of the history.
17
+ */
18
+ export declare function readJsonDir<T>(root: string, options?: {
19
+ sortBasenames?: "asc" | "desc";
20
+ }): Promise<T[]>;
21
+ /** Atomically write JSON under `root`/`fileName` (temp file + rename). */
22
+ export declare function writeJsonFile(args: {
23
+ root: string;
24
+ fileName: string;
25
+ value: unknown;
26
+ }): Promise<void>;
27
+ /** Best-effort delete; ignores missing files. */
28
+ export declare function deleteFileInDir(args: {
29
+ root: string;
30
+ fileName: string;
31
+ }): Promise<void>;
32
+ //# sourceMappingURL=json-dir-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-dir-store.d.ts","sourceRoot":"","sources":["../../src/internal/json-dir-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED,yDAAyD;AACzD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAET;AAWD,uEAAuE;AACvE,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAWvE;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;CAAE,GAC3C,OAAO,CAAC,CAAC,EAAE,CAAC,CAiBd;AAED,0EAA0E;AAC1E,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhB;AAED,iDAAiD;AACjD,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhB"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Package `defineConnection({ tools })` into a `node -e` stdio transport a
3
+ * repo-less cloud VM can spawn.
4
+ */
5
+ import type { ConnectionTransport, InlineStdioConnectionConfig } from "../types.js";
6
+ export declare function packageInlineStdioConnection(options: {
7
+ name: string;
8
+ entryPath: string;
9
+ tools: InlineStdioConnectionConfig["tools"];
10
+ absWorkingDir: string;
11
+ }): Promise<ConnectionTransport>;
12
+ //# sourceMappingURL=package-inline-stdio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-inline-stdio.d.ts","sourceRoot":"","sources":["../../src/internal/package-inline-stdio.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EACV,mBAAmB,EACnB,2BAA2B,EAE5B,MAAM,aAAa,CAAC;AA+BrB,wBAAsB,4BAA4B,CAAC,OAAO,EAAE;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,2BAA2B,CAAC,OAAO,CAAC,CAAC;IAC5C,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAsE/B"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Package `defineConnection({ tools })` into a `node -e` stdio transport a
3
+ * repo-less cloud VM can spawn.
4
+ */
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ import { existsSync } from "node:fs";
15
+ import { createRequire } from "node:module";
16
+ import { dirname, join } from "node:path";
17
+ import { fileURLToPath } from "node:url";
18
+ import * as esbuild from "esbuild";
19
+ import { toolInputJsonSchema } from "./json-schema.js";
20
+ const require = createRequire(import.meta.url);
21
+ const CONNECTION_SPECIFIERS = new Set([
22
+ "@anysphere/agent-serve/connections",
23
+ "@cursor/july/connections",
24
+ "@cursor/agentkit/connections",
25
+ ]);
26
+ function sibling(basename) {
27
+ const dir = fileURLToPath(new URL(".", import.meta.url));
28
+ const ts = join(dir, `${basename}.ts`);
29
+ return existsSync(ts) ? ts : join(dir, `${basename}.js`);
30
+ }
31
+ function jsonSchemaCatalog(tools) {
32
+ const catalog = {};
33
+ for (const [name, tool] of Object.entries(tools)) {
34
+ catalog[name] = {
35
+ description: tool.description,
36
+ inputSchema: toolInputJsonSchema(tool.inputSchema),
37
+ };
38
+ }
39
+ return catalog;
40
+ }
41
+ export function packageInlineStdioConnection(options) {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ var _a;
44
+ const runtimePath = sibling("inline-stdio-mcp");
45
+ const stubPath = sibling("inline-stdio-define-stub");
46
+ const catalog = jsonSchemaCatalog(options.tools);
47
+ const result = yield esbuild.build({
48
+ entryPoints: ["inline-stdio-entry"],
49
+ bundle: true,
50
+ write: false,
51
+ platform: "node",
52
+ format: "esm",
53
+ target: "node22",
54
+ minify: true,
55
+ legalComments: "none",
56
+ absWorkingDir: options.absWorkingDir,
57
+ alias: {
58
+ zod: require.resolve("zod"),
59
+ },
60
+ plugins: [
61
+ {
62
+ name: "inline-stdio-entry",
63
+ setup(build) {
64
+ build.onResolve({ filter: /^inline-stdio-entry$/ }, () => ({
65
+ path: "inline-stdio-entry",
66
+ namespace: "inline-stdio",
67
+ }));
68
+ build.onLoad({ filter: /.*/, namespace: "inline-stdio" }, () => ({
69
+ contents: `import definition from ${JSON.stringify(options.entryPath)};
70
+ import { serveInlineStdioMcp } from ${JSON.stringify(runtimePath)};
71
+ serveInlineStdioMcp(
72
+ ${JSON.stringify(options.name)},
73
+ definition,
74
+ ${JSON.stringify(catalog)}
75
+ );
76
+ `,
77
+ resolveDir: dirname(options.entryPath),
78
+ loader: "ts",
79
+ }));
80
+ },
81
+ },
82
+ {
83
+ name: "inline-stdio-connection-stub",
84
+ setup(build) {
85
+ build.onResolve({ filter: /.*/ }, (args) => {
86
+ if (CONNECTION_SPECIFIERS.has(args.path)) {
87
+ return { path: stubPath };
88
+ }
89
+ return undefined;
90
+ });
91
+ },
92
+ },
93
+ ],
94
+ });
95
+ const file = (_a = result.outputFiles) === null || _a === void 0 ? void 0 : _a[0];
96
+ if (file === undefined) {
97
+ throw new Error(`Failed to package inline stdio MCP connection "${options.name}": esbuild produced no output.`);
98
+ }
99
+ const source = file.text.replace(/^#!.*\r?\n/, "");
100
+ if (source.trim() === "") {
101
+ throw new Error(`Failed to package inline stdio MCP connection "${options.name}": empty bundle.`);
102
+ }
103
+ return {
104
+ type: "stdio",
105
+ command: "node",
106
+ args: ["--input-type=module", "-e", source],
107
+ };
108
+ });
109
+ }