@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.
- package/README.md +3 -1
- package/dist/bin/agent-serve.js +0 -0
- package/dist/channels/slack/api.d.ts +5 -0
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +57 -18
- package/dist/channels/slack/constants.d.ts +2 -0
- package/dist/channels/slack/constants.d.ts.map +1 -1
- package/dist/channels/slack/constants.js +2 -0
- package/dist/channels/slack/post-update-delivery.d.ts +85 -0
- package/dist/channels/slack/post-update-delivery.d.ts.map +1 -0
- package/dist/connections.d.ts +14 -2
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +13 -1
- package/dist/docs/404.html +3 -3
- package/dist/docs/ab.html +6 -6
- package/dist/docs/assets/{app.Bu9SRvZ9.js → app.BQ8Hihdf.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.B-VTH4As.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.D9u9czHO.js → VPLocalSearchBox.BBCr8Yuy.js} +2 -2
- package/dist/docs/assets/chunks/theme.CK_NiGC-.js +2 -0
- package/dist/docs/assets/{example-agents_weather-agent.md.CrGZ0SqR.js → example-agents_weather-agent.md.DC3lINjo.js} +5 -6
- package/dist/docs/assets/{reference_connections.md.DGqAsFXb.js → reference_connections.md.CSQiNzre.js} +11 -2
- package/dist/docs/assets/{reference_connections.md.DGqAsFXb.lean.js → reference_connections.md.CSQiNzre.lean.js} +1 -1
- package/dist/docs/assets/{style.Bj-IXa5W.css → style.CK3hwt6q.css} +1 -1
- package/dist/docs/building-with-agents.html +6 -6
- package/dist/docs/concepts.html +6 -6
- package/dist/docs/deployment.html +6 -6
- package/dist/docs/evals.html +6 -6
- package/dist/docs/example-agents/approval-buddy.html +6 -6
- package/dist/docs/example-agents/benny.html +6 -6
- package/dist/docs/example-agents/bugbot.html +6 -6
- package/dist/docs/example-agents/codebase-wiki.html +6 -6
- package/dist/docs/example-agents/codeowners-review.html +6 -6
- package/dist/docs/example-agents/concierge.html +6 -6
- package/dist/docs/example-agents/fsd.html +6 -6
- package/dist/docs/example-agents/index.html +6 -6
- package/dist/docs/example-agents/knowledge-base.html +6 -6
- package/dist/docs/example-agents/oncall.html +6 -6
- package/dist/docs/example-agents/security-reviewer.html +6 -6
- package/dist/docs/example-agents/slack-agent.html +6 -6
- package/dist/docs/example-agents/weather-agent.html +10 -11
- package/dist/docs/guides/agent-to-agent.html +6 -6
- package/dist/docs/guides/cloud-runtime.html +6 -6
- package/dist/docs/guides/github.html +6 -6
- package/dist/docs/guides/human-in-the-loop.html +6 -6
- package/dist/docs/guides/mcp-oauth.html +6 -6
- package/dist/docs/guides/slack.html +6 -6
- package/dist/docs/guides/webhooks.html +6 -6
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +6 -6
- package/dist/docs/index.html +6 -6
- package/dist/docs/quickstart.html +6 -6
- package/dist/docs/reference/agent-config.html +6 -6
- package/dist/docs/reference/artifacts.html +6 -6
- package/dist/docs/reference/channels.html +6 -6
- package/dist/docs/reference/cli.html +6 -6
- package/dist/docs/reference/connections.html +17 -8
- package/dist/docs/reference/hooks.html +6 -6
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/instructions.html +6 -6
- package/dist/docs/reference/playground.html +5 -5
- package/dist/docs/reference/project-layout.html +6 -6
- package/dist/docs/reference/prompt.html +6 -6
- package/dist/docs/reference/schedules.html +6 -6
- package/dist/docs/reference/sessions.html +6 -6
- package/dist/docs/reference/skills.html +6 -6
- package/dist/docs/reference/subagents.html +6 -6
- package/dist/docs/reference/tools.html +6 -6
- package/dist/docs/scaffolding-agents.html +5 -5
- package/dist/docs/storage.html +6 -6
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +13 -2
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +95 -2
- package/dist/internal/framework-storage-selection.d.ts +37 -0
- package/dist/internal/framework-storage-selection.d.ts.map +1 -0
- package/dist/internal/framework-storage-selection.js +35 -0
- package/dist/internal/inline-stdio-define-stub.d.ts +3 -0
- package/dist/internal/inline-stdio-define-stub.d.ts.map +1 -0
- package/dist/internal/inline-stdio-define-stub.js +4 -0
- package/dist/internal/inline-stdio-mcp.d.ts +32 -0
- package/dist/internal/inline-stdio-mcp.d.ts.map +1 -0
- package/dist/internal/inline-stdio-mcp.js +180 -0
- package/dist/internal/json-dir-store.d.ts +32 -0
- package/dist/internal/json-dir-store.d.ts.map +1 -0
- package/dist/internal/package-inline-stdio.d.ts +12 -0
- package/dist/internal/package-inline-stdio.d.ts.map +1 -0
- package/dist/internal/package-inline-stdio.js +109 -0
- package/dist/internal/persistence-coordinator.d.ts +127 -0
- package/dist/internal/persistence-coordinator.d.ts.map +1 -0
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +9 -2
- package/dist/multi-tenant.d.ts +80 -0
- package/dist/multi-tenant.d.ts.map +1 -0
- package/dist/multi-tenant.js +69 -0
- package/dist/persistence.d.ts +184 -0
- package/dist/persistence.d.ts.map +1 -0
- package/dist/playground/assets/index-BRhBbnd4.css +1 -0
- package/dist/playground/assets/{index-DRtusTV1.js → index-_2WKw9a-.js} +43 -43
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +20 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -0
- package/docs/example-agents/weather-agent.md +25 -22
- package/docs/reference/connections.md +17 -0
- package/package.json +3 -1
- package/skills/framework-map/SKILL.md +1 -1
- package/src/channels/slack/api.ts +72 -20
- package/src/channels/slack/constants.ts +2 -0
- package/src/connections.ts +18 -1
- package/src/files-backends/cursor-hosted.ts +13 -2
- package/src/internal/discovery.ts +111 -1
- package/src/internal/framework-storage-selection.ts +45 -0
- package/src/internal/inline-stdio-define-stub.ts +4 -0
- package/src/internal/inline-stdio-mcp.ts +229 -0
- package/src/internal/package-inline-stdio.ts +121 -0
- package/src/internal/session-engine.ts +9 -2
- package/src/types.ts +27 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.pVFW7oJd.js +0 -1
- package/dist/docs/assets/chunks/theme.Bc61GzOf.js +0 -2
- package/dist/playground/assets/index-DZp6n4bv.css +0 -1
- /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,
|
|
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
|
|
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,
|
|
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 @@
|
|
|
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,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
|
+
}
|