@sidecar-ai/compiler 0.1.0-alpha.4 → 0.1.0-alpha.5
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 +11 -5
- package/dist/index.js +92 -28
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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 =
|
|
29
|
+
type SidecarTarget = BuildTarget;
|
|
30
30
|
/** Host runtime artifact emitted for a build output. */
|
|
31
|
-
type SidecarHost =
|
|
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
|
|
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
|
|
2809
|
-
|
|
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
|
-
|
|
2840
|
-
await
|
|
2841
|
-
await
|
|
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 "
|
|
3075
|
+
return `export { default } from "./server/index.js";
|
|
3043
3076
|
`;
|
|
3044
3077
|
}
|
|
3045
|
-
function
|
|
3078
|
+
function renderVercelFunctionConfig() {
|
|
3046
3079
|
return `${JSON.stringify({
|
|
3047
|
-
|
|
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
|
-
|
|
3050
|
-
|
|
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 ??
|
|
3126
|
-
|
|
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(
|
|
3181
|
+
await mkdir9(runtimeOutDir, { recursive: true });
|
|
3141
3182
|
await writeFile9(
|
|
3142
|
-
path18.join(
|
|
3183
|
+
path18.join(runtimeOutDir, "manifest.sidecar.json"),
|
|
3143
3184
|
`${JSON.stringify(manifest, null, 2)}
|
|
3144
3185
|
`
|
|
3145
3186
|
);
|
|
3146
|
-
await writeFile9(path18.join(
|
|
3187
|
+
await writeFile9(path18.join(runtimeOutDir, "README.md"), renderMcpReadme(manifest));
|
|
3147
3188
|
await writeGeneratedTypes(rootDir, tools);
|
|
3148
|
-
await buildServerOutput(rootDir,
|
|
3149
|
-
|
|
3150
|
-
|
|
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
|
|
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 {
|