@sidecar-ai/compiler 0.1.0-alpha.4 → 0.1.0-alpha.6

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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { SourceFile } from 'ts-morph';
2
- import { JsonSchema, ToolAnnotations, ToolVisibility, ToolWidgetOptions, McpToolDescriptor, ResourceAnnotations, McpResourceDescriptor, McpResourceTemplateDescriptor, PromptArgsDefinition, McpPromptDescriptor } from '@sidecar-ai/core';
2
+ import { BuildHost, BuildTarget, JsonSchema, ToolAnnotations, ToolVisibility, ToolWidgetOptions, McpToolDescriptor, ResourceAnnotations, McpResourceDescriptor, McpResourceTemplateDescriptor, PromptArgsDefinition, McpPromptDescriptor } from '@sidecar-ai/core';
3
3
 
4
4
  /** Diagnostic severity surfaced by the CLI and future editor integrations. */
5
5
  type DiagnosticSeverity = "warning" | "error";
@@ -26,9 +26,9 @@ declare function formatDiagnostic(diagnostic: SidecarDiagnostic): string;
26
26
  /** Manifest and option types shared across the Sidecar compiler modules. */
27
27
 
28
28
  /** Build target profile selected by reserved platform file suffixes. */
29
- type SidecarTarget = "mcp" | "chatgpt" | "claude";
29
+ type SidecarTarget = BuildTarget;
30
30
  /** Host runtime artifact emitted for a build output. */
31
- type SidecarHost = "node" | "vercel";
31
+ type SidecarHost = BuildHost;
32
32
  /** Platform suffix chosen for a reserved tool or widget file. */
33
33
  type SidecarSourceVariant = "shared" | "openai" | "anthropic";
34
34
  /** Tool entry emitted into `manifest.sidecar.json`. */
@@ -92,6 +92,12 @@ type SidecarPromptManifestEntry = {
92
92
  };
93
93
  /** Serializable project config subset recorded in build manifests. */
94
94
  type SidecarCompilerConfig = {
95
+ build: {
96
+ target?: SidecarTarget;
97
+ host?: SidecarHost;
98
+ outDir?: string;
99
+ plugins?: boolean;
100
+ };
95
101
  resources: {
96
102
  subscribe: boolean;
97
103
  listChanged: boolean;
@@ -178,7 +184,7 @@ declare function analyzeResourceFile(sourceFile: SourceFile, rootDir: string): S
178
184
 
179
185
  /** Relative location of the generated server entrypoint inside a build output. */
180
186
  declare const SERVER_ENTRYPOINT = "server/index.js";
181
- /** Relative location of the optional Vercel request-handler shim. */
182
- declare const VERCEL_ENTRYPOINT = "api/sidecar.js";
187
+ /** Relative location of the Vercel Build Output API function entrypoint. */
188
+ declare const VERCEL_ENTRYPOINT = "functions/api/sidecar.func/index.js";
183
189
 
184
190
  export { type BuildProjectOptions, CompilerError, type ProjectIdentity, SERVER_ENTRYPOINT, type SidecarCompilerConfig, type SidecarDiagnostic, type SidecarHost, type SidecarManifest, type SidecarPromptManifestEntry, type SidecarResourceManifestEntry, type SidecarResourceTemplateManifestEntry, type SidecarSourceVariant, type SidecarTarget, type SidecarToolManifestEntry, type SidecarWidgetManifestEntry, VERCEL_ENTRYPOINT, analyzeProjectConfig, analyzeProjectPrompts, analyzeProjectResources, analyzeProjectTools, analyzePromptFile, analyzeResourceFile, analyzeToolFile, buildProject, collectProjectDiagnostics, formatDiagnostic };
package/dist/index.js CHANGED
@@ -1504,6 +1504,12 @@ function analyzeProjectConfig(rootDir) {
1504
1504
  return defaultCompilerConfig();
1505
1505
  }
1506
1506
  return {
1507
+ build: {
1508
+ target: readTargetNested(definition, "build", "target"),
1509
+ host: readHostNested(definition, "build", "host"),
1510
+ outDir: readStringNested(definition, "build", "outDir"),
1511
+ plugins: readBooleanNested(definition, "build", "plugins")
1512
+ },
1507
1513
  resources: {
1508
1514
  subscribe: readBooleanNested(definition, "resources", "subscribe") ?? false,
1509
1515
  listChanged: readBooleanNested(definition, "resources", "listChanged") ?? false
@@ -1522,6 +1528,7 @@ function analyzeProjectConfig(rootDir) {
1522
1528
  }
1523
1529
  function defaultCompilerConfig() {
1524
1530
  return {
1531
+ build: {},
1525
1532
  resources: {
1526
1533
  subscribe: false,
1527
1534
  listChanged: false
@@ -1538,6 +1545,26 @@ function defaultCompilerConfig() {
1538
1545
  }
1539
1546
  };
1540
1547
  }
1548
+ function readTargetNested(definition, section, propertyName) {
1549
+ const value = readStringNested(definition, section, propertyName);
1550
+ return value === "mcp" || value === "chatgpt" || value === "claude" ? value : void 0;
1551
+ }
1552
+ function readHostNested(definition, section, propertyName) {
1553
+ const value = readStringNested(definition, section, propertyName);
1554
+ return value === "node" || value === "vercel" ? value : void 0;
1555
+ }
1556
+ function readStringNested(definition, section, propertyName) {
1557
+ const object = readObjectProperty3(definition, section);
1558
+ if (!object) {
1559
+ return void 0;
1560
+ }
1561
+ const property = object.getProperty(propertyName);
1562
+ if (!property || !Node5.isPropertyAssignment(property)) {
1563
+ return void 0;
1564
+ }
1565
+ const initializer = unwrapExpression(property.getInitializer());
1566
+ return initializer && Node5.isStringLiteral(initializer) ? initializer.getLiteralText() : void 0;
1567
+ }
1541
1568
  function readBooleanNested(definition, section, propertyName) {
1542
1569
  const object = readObjectProperty3(definition, section);
1543
1570
  if (!object) {
@@ -2805,8 +2832,10 @@ import { mkdir as mkdir8, rm, writeFile as writeFile8 } from "fs/promises";
2805
2832
  import path17 from "path";
2806
2833
  import { build as esbuild2 } from "esbuild";
2807
2834
  var SERVER_ENTRYPOINT = "server/index.js";
2808
- var VERCEL_ENTRYPOINT = "api/sidecar.js";
2809
- async function buildServerOutput(rootDir, outDir, manifest, identity, host = "node") {
2835
+ var VERCEL_FUNCTION_DIR = "functions/api/sidecar.func";
2836
+ var VERCEL_ENTRYPOINT = `${VERCEL_FUNCTION_DIR}/index.js`;
2837
+ var VERCEL_HANDLER_FILE = "index.js";
2838
+ async function buildServerOutput(rootDir, outDir, manifest, identity, host = "node", options = {}) {
2810
2839
  const cacheDir = path17.join(rootDir, ".sidecar", "cache", "server");
2811
2840
  await mkdir8(cacheDir, { recursive: true });
2812
2841
  const entryFile = path17.join(cacheDir, "index.ts");
@@ -2836,9 +2865,13 @@ const require = __sidecarCreateRequire(import.meta.url);`
2836
2865
  });
2837
2866
  await writeFile8(path17.join(outDir, "package.json"), renderServerPackage(identity));
2838
2867
  if (host === "vercel") {
2839
- await mkdir8(path17.join(outDir, "api"), { recursive: true });
2840
- await writeFile8(path17.join(outDir, VERCEL_ENTRYPOINT), renderVercelEntrypoint());
2841
- await writeFile8(path17.join(outDir, "vercel.json"), renderVercelConfig());
2868
+ const vercelOutputDir = options.vercelOutputDir ?? outDir;
2869
+ await rm(path17.join(vercelOutputDir, "api"), { recursive: true, force: true });
2870
+ await rm(path17.join(vercelOutputDir, "vercel.json"), { force: true });
2871
+ await writeFile8(path17.join(outDir, VERCEL_HANDLER_FILE), renderVercelEntrypoint());
2872
+ await writeFile8(path17.join(outDir, ".vc-config.json"), renderVercelFunctionConfig());
2873
+ await mkdir8(vercelOutputDir, { recursive: true });
2874
+ await writeFile8(path17.join(vercelOutputDir, "config.json"), renderVercelOutputConfig());
2842
2875
  } else {
2843
2876
  await rm(path17.join(outDir, "api"), { recursive: true, force: true });
2844
2877
  await rm(path17.join(outDir, "vercel.json"), { force: true });
@@ -3039,23 +3072,29 @@ function renderServerPackage(identity) {
3039
3072
  `;
3040
3073
  }
3041
3074
  function renderVercelEntrypoint() {
3042
- return `export { default } from "../server/index.js";
3075
+ return `export { default } from "./server/index.js";
3043
3076
  `;
3044
3077
  }
3045
- function renderVercelConfig() {
3078
+ function renderVercelFunctionConfig() {
3046
3079
  return `${JSON.stringify({
3047
- rewrites: [
3080
+ runtime: "nodejs22.x",
3081
+ handler: VERCEL_HANDLER_FILE,
3082
+ launcherType: "Nodejs",
3083
+ shouldAddHelpers: true,
3084
+ supportsResponseStreaming: true,
3085
+ maxDuration: 300
3086
+ }, null, 2)}
3087
+ `;
3088
+ }
3089
+ function renderVercelOutputConfig() {
3090
+ return `${JSON.stringify({
3091
+ version: 3,
3092
+ routes: [
3048
3093
  {
3049
- source: "/(.*)",
3050
- destination: "/api/sidecar"
3051
- }
3052
- ],
3053
- functions: {
3054
- "api/sidecar.js": {
3055
- includeFiles: "public/**",
3056
- maxDuration: 300
3094
+ src: "/(.*)",
3095
+ dest: "/api/sidecar"
3057
3096
  }
3058
- }
3097
+ ]
3059
3098
  }, null, 2)}
3060
3099
  `;
3061
3100
  }
@@ -3104,9 +3143,10 @@ function findSidecarRepoRoot2(startDir) {
3104
3143
  // packages/compiler/src/build.ts
3105
3144
  async function buildProject(options) {
3106
3145
  const rootDir = path18.resolve(options.rootDir);
3107
- const target = options.target ?? "mcp";
3108
- const host = options.host ?? "node";
3109
3146
  const config = analyzeProjectConfig(rootDir);
3147
+ const target = options.target ?? config.build.target ?? "mcp";
3148
+ const host = options.host ?? config.build.host ?? "node";
3149
+ const plugins = options.plugins ?? config.build.plugins ?? false;
3110
3150
  const tools = await analyzeProjectTools(rootDir, { target });
3111
3151
  const resources = await analyzeProjectResources(rootDir);
3112
3152
  const resourceTemplates = [];
@@ -3122,8 +3162,9 @@ async function buildProject(options) {
3122
3162
  if (errors.length) {
3123
3163
  throw new Error(errors.map(formatDiagnostic).join("\n"));
3124
3164
  }
3125
- const outDir = resolveInsideRoot(rootDir, options.outDir ?? "out/mcp");
3126
- await buildWidgets(rootDir, outDir, tools);
3165
+ const outDir = resolveInsideRoot(rootDir, options.outDir ?? config.build.outDir ?? defaultBuildOutDir(host, target));
3166
+ const runtimeOutDir = resolveRuntimeOutputDir(outDir, host);
3167
+ await buildWidgets(rootDir, runtimeOutDir, tools);
3127
3168
  const manifest = {
3128
3169
  version: 1,
3129
3170
  target,
@@ -3137,20 +3178,43 @@ async function buildProject(options) {
3137
3178
  prompts,
3138
3179
  diagnostics
3139
3180
  };
3140
- await mkdir9(outDir, { recursive: true });
3181
+ await mkdir9(runtimeOutDir, { recursive: true });
3141
3182
  await writeFile9(
3142
- path18.join(outDir, "manifest.sidecar.json"),
3183
+ path18.join(runtimeOutDir, "manifest.sidecar.json"),
3143
3184
  `${JSON.stringify(manifest, null, 2)}
3144
3185
  `
3145
3186
  );
3146
- await writeFile9(path18.join(outDir, "README.md"), renderMcpReadme(manifest));
3187
+ await writeFile9(path18.join(runtimeOutDir, "README.md"), renderMcpReadme(manifest));
3147
3188
  await writeGeneratedTypes(rootDir, tools);
3148
- await buildServerOutput(rootDir, outDir, manifest, identity, host);
3149
- if (options.plugins) {
3150
- await buildPluginPackages(rootDir, path18.dirname(outDir), manifest);
3189
+ await buildServerOutput(rootDir, runtimeOutDir, manifest, identity, host, {
3190
+ vercelOutputDir: outDir
3191
+ });
3192
+ if (plugins) {
3193
+ await buildPluginPackages(rootDir, resolvePluginOutputBase(rootDir, outDir, host), manifest);
3151
3194
  }
3152
3195
  return manifest;
3153
3196
  }
3197
+ function defaultBuildOutDir(host, target) {
3198
+ if (host === "vercel") {
3199
+ return ".vercel/output";
3200
+ }
3201
+ return `out/${target}`;
3202
+ }
3203
+ function resolveRuntimeOutputDir(outDir, host) {
3204
+ if (host === "vercel") {
3205
+ return path18.join(outDir, VERCEL_FUNCTION_DIR);
3206
+ }
3207
+ return outDir;
3208
+ }
3209
+ function resolvePluginOutputBase(rootDir, outDir, host) {
3210
+ if (host === "vercel" && isVercelBuildOutputDir(outDir)) {
3211
+ return path18.join(rootDir, "out");
3212
+ }
3213
+ return path18.dirname(outDir);
3214
+ }
3215
+ function isVercelBuildOutputDir(outDir) {
3216
+ return path18.basename(outDir) === "output" && path18.basename(path18.dirname(outDir)) === ".vercel";
3217
+ }
3154
3218
  function resolveInsideRoot(rootDir, output) {
3155
3219
  const resolved = path18.resolve(rootDir, output);
3156
3220
  const relative = path18.relative(rootDir, resolved);
@@ -3207,7 +3271,7 @@ Set \`PORT\` or \`SIDECAR_PORT\` to choose the listen port. Hosted/authenticated
3207
3271
  function renderVercelReadmeSection() {
3208
3272
  return `## Deploy To Vercel
3209
3273
 
3210
- This output includes a Vercel Function shim at \`api/sidecar.js\` and a \`vercel.json\` rewrite that sends Streamable HTTP traffic to \`/mcp\`. Deploy this output directory with Vercel and set \`SIDECAR_MCP_URL\` to the public \`https://.../mcp\` URL.
3274
+ This output uses Vercel's Build Output API. The MCP function is emitted at \`${VERCEL_FUNCTION_DIR}\`, and \`config.json\` routes Streamable HTTP traffic to it. Set \`SIDECAR_MCP_URL\` to the public \`https://.../mcp\` URL in Vercel.
3211
3275
  `;
3212
3276
  }
3213
3277
  export {