@sidecar-ai/cli 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.js +221 -50
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1686,6 +1686,12 @@ function analyzeProjectConfig(rootDir) {
|
|
|
1686
1686
|
return defaultCompilerConfig();
|
|
1687
1687
|
}
|
|
1688
1688
|
return {
|
|
1689
|
+
build: {
|
|
1690
|
+
target: readTargetNested(definition, "build", "target"),
|
|
1691
|
+
host: readHostNested(definition, "build", "host"),
|
|
1692
|
+
outDir: readStringNested(definition, "build", "outDir"),
|
|
1693
|
+
plugins: readBooleanNested(definition, "build", "plugins")
|
|
1694
|
+
},
|
|
1689
1695
|
resources: {
|
|
1690
1696
|
subscribe: readBooleanNested(definition, "resources", "subscribe") ?? false,
|
|
1691
1697
|
listChanged: readBooleanNested(definition, "resources", "listChanged") ?? false
|
|
@@ -1704,6 +1710,7 @@ function analyzeProjectConfig(rootDir) {
|
|
|
1704
1710
|
}
|
|
1705
1711
|
function defaultCompilerConfig() {
|
|
1706
1712
|
return {
|
|
1713
|
+
build: {},
|
|
1707
1714
|
resources: {
|
|
1708
1715
|
subscribe: false,
|
|
1709
1716
|
listChanged: false
|
|
@@ -1720,6 +1727,26 @@ function defaultCompilerConfig() {
|
|
|
1720
1727
|
}
|
|
1721
1728
|
};
|
|
1722
1729
|
}
|
|
1730
|
+
function readTargetNested(definition, section, propertyName) {
|
|
1731
|
+
const value = readStringNested(definition, section, propertyName);
|
|
1732
|
+
return value === "mcp" || value === "chatgpt" || value === "claude" ? value : void 0;
|
|
1733
|
+
}
|
|
1734
|
+
function readHostNested(definition, section, propertyName) {
|
|
1735
|
+
const value = readStringNested(definition, section, propertyName);
|
|
1736
|
+
return value === "node" || value === "vercel" ? value : void 0;
|
|
1737
|
+
}
|
|
1738
|
+
function readStringNested(definition, section, propertyName) {
|
|
1739
|
+
const object = readObjectProperty3(definition, section);
|
|
1740
|
+
if (!object) {
|
|
1741
|
+
return void 0;
|
|
1742
|
+
}
|
|
1743
|
+
const property = object.getProperty(propertyName);
|
|
1744
|
+
if (!property || !Node5.isPropertyAssignment(property)) {
|
|
1745
|
+
return void 0;
|
|
1746
|
+
}
|
|
1747
|
+
const initializer = unwrapExpression(property.getInitializer());
|
|
1748
|
+
return initializer && Node5.isStringLiteral(initializer) ? initializer.getLiteralText() : void 0;
|
|
1749
|
+
}
|
|
1723
1750
|
function readBooleanNested(definition, section, propertyName) {
|
|
1724
1751
|
const object = readObjectProperty3(definition, section);
|
|
1725
1752
|
if (!object) {
|
|
@@ -2987,8 +3014,10 @@ import { mkdir as mkdir8, rm, writeFile as writeFile8 } from "fs/promises";
|
|
|
2987
3014
|
import path17 from "path";
|
|
2988
3015
|
import { build as esbuild2 } from "esbuild";
|
|
2989
3016
|
var SERVER_ENTRYPOINT = "server/index.js";
|
|
2990
|
-
var
|
|
2991
|
-
|
|
3017
|
+
var VERCEL_FUNCTION_DIR = "functions/api/sidecar.func";
|
|
3018
|
+
var VERCEL_ENTRYPOINT = `${VERCEL_FUNCTION_DIR}/index.js`;
|
|
3019
|
+
var VERCEL_HANDLER_FILE = "index.js";
|
|
3020
|
+
async function buildServerOutput(rootDir, outDir, manifest, identity, host = "node", options = {}) {
|
|
2992
3021
|
const cacheDir = path17.join(rootDir, ".sidecar", "cache", "server");
|
|
2993
3022
|
await mkdir8(cacheDir, { recursive: true });
|
|
2994
3023
|
const entryFile = path17.join(cacheDir, "index.ts");
|
|
@@ -3018,9 +3047,13 @@ const require = __sidecarCreateRequire(import.meta.url);`
|
|
|
3018
3047
|
});
|
|
3019
3048
|
await writeFile8(path17.join(outDir, "package.json"), renderServerPackage(identity));
|
|
3020
3049
|
if (host === "vercel") {
|
|
3021
|
-
|
|
3022
|
-
await
|
|
3023
|
-
await
|
|
3050
|
+
const vercelOutputDir = options.vercelOutputDir ?? outDir;
|
|
3051
|
+
await rm(path17.join(vercelOutputDir, "api"), { recursive: true, force: true });
|
|
3052
|
+
await rm(path17.join(vercelOutputDir, "vercel.json"), { force: true });
|
|
3053
|
+
await writeFile8(path17.join(outDir, VERCEL_HANDLER_FILE), renderVercelEntrypoint());
|
|
3054
|
+
await writeFile8(path17.join(outDir, ".vc-config.json"), renderVercelFunctionConfig());
|
|
3055
|
+
await mkdir8(vercelOutputDir, { recursive: true });
|
|
3056
|
+
await writeFile8(path17.join(vercelOutputDir, "config.json"), renderVercelOutputConfig());
|
|
3024
3057
|
} else {
|
|
3025
3058
|
await rm(path17.join(outDir, "api"), { recursive: true, force: true });
|
|
3026
3059
|
await rm(path17.join(outDir, "vercel.json"), { force: true });
|
|
@@ -3221,23 +3254,29 @@ function renderServerPackage(identity) {
|
|
|
3221
3254
|
`;
|
|
3222
3255
|
}
|
|
3223
3256
|
function renderVercelEntrypoint() {
|
|
3224
|
-
return `export { default } from "
|
|
3257
|
+
return `export { default } from "./server/index.js";
|
|
3258
|
+
`;
|
|
3259
|
+
}
|
|
3260
|
+
function renderVercelFunctionConfig() {
|
|
3261
|
+
return `${JSON.stringify({
|
|
3262
|
+
runtime: "nodejs22.x",
|
|
3263
|
+
handler: VERCEL_HANDLER_FILE,
|
|
3264
|
+
launcherType: "Nodejs",
|
|
3265
|
+
shouldAddHelpers: true,
|
|
3266
|
+
supportsResponseStreaming: true,
|
|
3267
|
+
maxDuration: 300
|
|
3268
|
+
}, null, 2)}
|
|
3225
3269
|
`;
|
|
3226
3270
|
}
|
|
3227
|
-
function
|
|
3271
|
+
function renderVercelOutputConfig() {
|
|
3228
3272
|
return `${JSON.stringify({
|
|
3229
|
-
|
|
3273
|
+
version: 3,
|
|
3274
|
+
routes: [
|
|
3230
3275
|
{
|
|
3231
|
-
|
|
3232
|
-
|
|
3276
|
+
src: "/(.*)",
|
|
3277
|
+
dest: "/api/sidecar"
|
|
3233
3278
|
}
|
|
3234
|
-
]
|
|
3235
|
-
functions: {
|
|
3236
|
-
"api/sidecar.js": {
|
|
3237
|
-
includeFiles: "public/**",
|
|
3238
|
-
maxDuration: 300
|
|
3239
|
-
}
|
|
3240
|
-
}
|
|
3279
|
+
]
|
|
3241
3280
|
}, null, 2)}
|
|
3242
3281
|
`;
|
|
3243
3282
|
}
|
|
@@ -3286,9 +3325,10 @@ function findSidecarRepoRoot2(startDir) {
|
|
|
3286
3325
|
// packages/compiler/src/build.ts
|
|
3287
3326
|
async function buildProject(options) {
|
|
3288
3327
|
const rootDir = path18.resolve(options.rootDir);
|
|
3289
|
-
const target = options.target ?? "mcp";
|
|
3290
|
-
const host = options.host ?? "node";
|
|
3291
3328
|
const config = analyzeProjectConfig(rootDir);
|
|
3329
|
+
const target = options.target ?? config.build.target ?? "mcp";
|
|
3330
|
+
const host = options.host ?? config.build.host ?? "node";
|
|
3331
|
+
const plugins = options.plugins ?? config.build.plugins ?? false;
|
|
3292
3332
|
const tools = await analyzeProjectTools(rootDir, { target });
|
|
3293
3333
|
const resources = await analyzeProjectResources(rootDir);
|
|
3294
3334
|
const resourceTemplates = [];
|
|
@@ -3304,8 +3344,9 @@ async function buildProject(options) {
|
|
|
3304
3344
|
if (errors.length) {
|
|
3305
3345
|
throw new Error(errors.map(formatDiagnostic).join("\n"));
|
|
3306
3346
|
}
|
|
3307
|
-
const outDir = resolveInsideRoot(rootDir, options.outDir ??
|
|
3308
|
-
|
|
3347
|
+
const outDir = resolveInsideRoot(rootDir, options.outDir ?? config.build.outDir ?? defaultBuildOutDir(host, target));
|
|
3348
|
+
const runtimeOutDir = resolveRuntimeOutputDir(outDir, host);
|
|
3349
|
+
await buildWidgets(rootDir, runtimeOutDir, tools);
|
|
3309
3350
|
const manifest = {
|
|
3310
3351
|
version: 1,
|
|
3311
3352
|
target,
|
|
@@ -3319,20 +3360,43 @@ async function buildProject(options) {
|
|
|
3319
3360
|
prompts,
|
|
3320
3361
|
diagnostics
|
|
3321
3362
|
};
|
|
3322
|
-
await mkdir9(
|
|
3363
|
+
await mkdir9(runtimeOutDir, { recursive: true });
|
|
3323
3364
|
await writeFile9(
|
|
3324
|
-
path18.join(
|
|
3365
|
+
path18.join(runtimeOutDir, "manifest.sidecar.json"),
|
|
3325
3366
|
`${JSON.stringify(manifest, null, 2)}
|
|
3326
3367
|
`
|
|
3327
3368
|
);
|
|
3328
|
-
await writeFile9(path18.join(
|
|
3369
|
+
await writeFile9(path18.join(runtimeOutDir, "README.md"), renderMcpReadme(manifest));
|
|
3329
3370
|
await writeGeneratedTypes(rootDir, tools);
|
|
3330
|
-
await buildServerOutput(rootDir,
|
|
3331
|
-
|
|
3332
|
-
|
|
3371
|
+
await buildServerOutput(rootDir, runtimeOutDir, manifest, identity, host, {
|
|
3372
|
+
vercelOutputDir: outDir
|
|
3373
|
+
});
|
|
3374
|
+
if (plugins) {
|
|
3375
|
+
await buildPluginPackages(rootDir, resolvePluginOutputBase(rootDir, outDir, host), manifest);
|
|
3333
3376
|
}
|
|
3334
3377
|
return manifest;
|
|
3335
3378
|
}
|
|
3379
|
+
function defaultBuildOutDir(host, target) {
|
|
3380
|
+
if (host === "vercel") {
|
|
3381
|
+
return ".vercel/output";
|
|
3382
|
+
}
|
|
3383
|
+
return `out/${target}`;
|
|
3384
|
+
}
|
|
3385
|
+
function resolveRuntimeOutputDir(outDir, host) {
|
|
3386
|
+
if (host === "vercel") {
|
|
3387
|
+
return path18.join(outDir, VERCEL_FUNCTION_DIR);
|
|
3388
|
+
}
|
|
3389
|
+
return outDir;
|
|
3390
|
+
}
|
|
3391
|
+
function resolvePluginOutputBase(rootDir, outDir, host) {
|
|
3392
|
+
if (host === "vercel" && isVercelBuildOutputDir(outDir)) {
|
|
3393
|
+
return path18.join(rootDir, "out");
|
|
3394
|
+
}
|
|
3395
|
+
return path18.dirname(outDir);
|
|
3396
|
+
}
|
|
3397
|
+
function isVercelBuildOutputDir(outDir) {
|
|
3398
|
+
return path18.basename(outDir) === "output" && path18.basename(path18.dirname(outDir)) === ".vercel";
|
|
3399
|
+
}
|
|
3336
3400
|
function resolveInsideRoot(rootDir, output) {
|
|
3337
3401
|
const resolved = path18.resolve(rootDir, output);
|
|
3338
3402
|
const relative = path18.relative(rootDir, resolved);
|
|
@@ -3389,7 +3453,7 @@ Set \`PORT\` or \`SIDECAR_PORT\` to choose the listen port. Hosted/authenticated
|
|
|
3389
3453
|
function renderVercelReadmeSection() {
|
|
3390
3454
|
return `## Deploy To Vercel
|
|
3391
3455
|
|
|
3392
|
-
This output
|
|
3456
|
+
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.
|
|
3393
3457
|
`;
|
|
3394
3458
|
}
|
|
3395
3459
|
|
|
@@ -3899,6 +3963,11 @@ function createSidecarHttpHandler(options) {
|
|
|
3899
3963
|
const streamHub = createSseHub();
|
|
3900
3964
|
const mcp = createSidecarMcpServer(options);
|
|
3901
3965
|
return async (request, response) => {
|
|
3966
|
+
const pathname = request.url?.split("?")[0];
|
|
3967
|
+
const requestLog = createHttpRequestLog(request, pathname);
|
|
3968
|
+
response.once("finish", () => {
|
|
3969
|
+
logHttpRequest(requestLog, response.statusCode);
|
|
3970
|
+
});
|
|
3902
3971
|
if (isRejectedOrigin(request, options.allowedOrigins)) {
|
|
3903
3972
|
response.writeHead(403, { "content-type": "application/json" });
|
|
3904
3973
|
response.end(JSON.stringify({ error: "forbidden_origin" }));
|
|
@@ -3910,16 +3979,17 @@ function createSidecarHttpHandler(options) {
|
|
|
3910
3979
|
response.end(proxyResult.body ?? "");
|
|
3911
3980
|
return;
|
|
3912
3981
|
}
|
|
3913
|
-
const pathname = request.url?.split("?")[0];
|
|
3914
3982
|
if (options.auth && request.method === "GET" && isProtectedResourceMetadataPath(pathname, endpoint)) {
|
|
3915
3983
|
response.writeHead(200, { "content-type": "application/json" });
|
|
3916
3984
|
response.end(JSON.stringify(options.auth.metadata()));
|
|
3917
3985
|
return;
|
|
3918
3986
|
}
|
|
3987
|
+
if (options.auth && request.method === "GET" && pathname === "/.well-known/oauth-authorization-server") {
|
|
3988
|
+
await proxyAuthorizationServerMetadata(options.auth, response);
|
|
3989
|
+
return;
|
|
3990
|
+
}
|
|
3919
3991
|
if (request.method === "GET" && pathname === endpoint) {
|
|
3920
3992
|
try {
|
|
3921
|
-
validateProtocolVersion(request);
|
|
3922
|
-
validateGetHeaders(request);
|
|
3923
3993
|
const fetchRequest = toFetchRequest(request, options.publicUrl ?? options.auth?.resource);
|
|
3924
3994
|
if (options.auth) {
|
|
3925
3995
|
const authSession = await authorizeHttpRequest(options.auth, fetchRequest, response);
|
|
@@ -3927,6 +3997,8 @@ function createSidecarHttpHandler(options) {
|
|
|
3927
3997
|
return;
|
|
3928
3998
|
}
|
|
3929
3999
|
}
|
|
4000
|
+
validateProtocolVersion(request);
|
|
4001
|
+
validateGetHeaders(request);
|
|
3930
4002
|
streamHub.open(response);
|
|
3931
4003
|
} catch (error) {
|
|
3932
4004
|
const status = error instanceof JsonRpcHttpError ? error.status : 400;
|
|
@@ -3955,6 +4027,11 @@ function createSidecarHttpHandler(options) {
|
|
|
3955
4027
|
return;
|
|
3956
4028
|
}
|
|
3957
4029
|
try {
|
|
4030
|
+
const fetchRequest = toFetchRequest(request, options.publicUrl ?? options.auth?.resource);
|
|
4031
|
+
const authSession = options.auth ? await authorizeHttpRequest(options.auth, fetchRequest, response) : void 0;
|
|
4032
|
+
if (options.auth && authSession === AUTH_RESPONSE_SENT) {
|
|
4033
|
+
return;
|
|
4034
|
+
}
|
|
3958
4035
|
validateProtocolVersion(request);
|
|
3959
4036
|
validatePostHeaders(request);
|
|
3960
4037
|
const body = await readJson(request, maxBodyBytes);
|
|
@@ -3967,11 +4044,6 @@ function createSidecarHttpHandler(options) {
|
|
|
3967
4044
|
return;
|
|
3968
4045
|
}
|
|
3969
4046
|
const rpcRequest = assertJsonRpcRequest(body);
|
|
3970
|
-
const fetchRequest = toFetchRequest(request, options.publicUrl ?? options.auth?.resource);
|
|
3971
|
-
const authSession = options.auth ? await authorizeHttpRequest(options.auth, fetchRequest, response) : void 0;
|
|
3972
|
-
if (options.auth && authSession === AUTH_RESPONSE_SENT) {
|
|
3973
|
-
return;
|
|
3974
|
-
}
|
|
3975
4047
|
if (rpcRequest.id !== void 0 && hasProgressToken(rpcRequest)) {
|
|
3976
4048
|
const stream = createSseStream(response, { supportsRequestProgress: true });
|
|
3977
4049
|
const payload2 = await mcp.handle(rpcRequest, {
|
|
@@ -4063,6 +4135,73 @@ function escapeRegExp(value) {
|
|
|
4063
4135
|
function isProtectedResourceMetadataPath(pathname, endpoint) {
|
|
4064
4136
|
return pathname === "/.well-known/oauth-protected-resource" || pathname === `/.well-known/oauth-protected-resource${endpoint}`;
|
|
4065
4137
|
}
|
|
4138
|
+
function createHttpRequestLog(request, pathname) {
|
|
4139
|
+
return {
|
|
4140
|
+
method: request.method,
|
|
4141
|
+
path: pathname,
|
|
4142
|
+
host: truncateHeader(singleHeader(request.headers.host)),
|
|
4143
|
+
accept: truncateHeader(singleHeader(request.headers.accept)),
|
|
4144
|
+
contentType: truncateHeader(singleHeader(request.headers["content-type"])),
|
|
4145
|
+
contentLength: truncateHeader(singleHeader(request.headers["content-length"])),
|
|
4146
|
+
mcpProtocolVersion: truncateHeader(singleHeader(request.headers["mcp-protocol-version"])),
|
|
4147
|
+
origin: truncateHeader(singleHeader(request.headers.origin)),
|
|
4148
|
+
userAgent: truncateHeader(singleHeader(request.headers["user-agent"])),
|
|
4149
|
+
authorization: request.headers.authorization ? "present" : "absent",
|
|
4150
|
+
cookie: request.headers.cookie ? "present" : "absent"
|
|
4151
|
+
};
|
|
4152
|
+
}
|
|
4153
|
+
function logHttpRequest(metadata, status) {
|
|
4154
|
+
const debug = process.env.SIDECAR_DEBUG === "1" || process.env.SIDECAR_LOG_LEVEL === "debug";
|
|
4155
|
+
if (!debug && status < 400) {
|
|
4156
|
+
return;
|
|
4157
|
+
}
|
|
4158
|
+
const message = JSON.stringify({
|
|
4159
|
+
event: "sidecar.mcp.http",
|
|
4160
|
+
status,
|
|
4161
|
+
...stripUndefined4(metadata)
|
|
4162
|
+
});
|
|
4163
|
+
if (status >= 500) {
|
|
4164
|
+
console.error(message);
|
|
4165
|
+
} else if (status >= 400) {
|
|
4166
|
+
console.warn(message);
|
|
4167
|
+
} else {
|
|
4168
|
+
console.info(message);
|
|
4169
|
+
}
|
|
4170
|
+
}
|
|
4171
|
+
function singleHeader(value) {
|
|
4172
|
+
return Array.isArray(value) ? value.join(", ") : value;
|
|
4173
|
+
}
|
|
4174
|
+
function truncateHeader(value) {
|
|
4175
|
+
if (!value) {
|
|
4176
|
+
return void 0;
|
|
4177
|
+
}
|
|
4178
|
+
return value.length > 240 ? `${value.slice(0, 237)}...` : value;
|
|
4179
|
+
}
|
|
4180
|
+
async function proxyAuthorizationServerMetadata(auth, response) {
|
|
4181
|
+
const [authorizationServer] = auth.authorizationServers;
|
|
4182
|
+
if (!authorizationServer) {
|
|
4183
|
+
response.writeHead(404, { "content-type": "application/json" });
|
|
4184
|
+
response.end(JSON.stringify({ error: "authorization_server_not_configured" }));
|
|
4185
|
+
return;
|
|
4186
|
+
}
|
|
4187
|
+
try {
|
|
4188
|
+
const url = new URL("/.well-known/oauth-authorization-server", authorizationServer);
|
|
4189
|
+
const upstream = await fetch(url, { headers: { accept: "application/json" } });
|
|
4190
|
+
const body = await upstream.text();
|
|
4191
|
+
response.writeHead(upstream.ok ? 200 : 502, {
|
|
4192
|
+
"content-type": upstream.headers.get("content-type") ?? "application/json"
|
|
4193
|
+
});
|
|
4194
|
+
response.end(body);
|
|
4195
|
+
} catch (error) {
|
|
4196
|
+
console.warn(JSON.stringify({
|
|
4197
|
+
event: "sidecar.mcp.authorization_metadata_proxy_failed",
|
|
4198
|
+
authorizationServer,
|
|
4199
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
4200
|
+
}));
|
|
4201
|
+
response.writeHead(502, { "content-type": "application/json" });
|
|
4202
|
+
response.end(JSON.stringify({ error: "authorization_metadata_unavailable" }));
|
|
4203
|
+
}
|
|
4204
|
+
}
|
|
4066
4205
|
var JsonRpcError = class extends Error {
|
|
4067
4206
|
constructor(code, message, data) {
|
|
4068
4207
|
super(message);
|
|
@@ -5094,26 +5233,27 @@ async function main(argv) {
|
|
|
5094
5233
|
const rootDir = readOption(argv, "--cwd") ?? cwd();
|
|
5095
5234
|
switch (command) {
|
|
5096
5235
|
case "build": {
|
|
5097
|
-
const target =
|
|
5098
|
-
const host =
|
|
5099
|
-
const outDir = readOption(argv, "--out")
|
|
5100
|
-
const plugins = argv
|
|
5236
|
+
const target = readOptionalTarget(argv);
|
|
5237
|
+
const host = readOptionalHost(argv) ?? detectHostFromEnvironment();
|
|
5238
|
+
const outDir = readOption(argv, "--out");
|
|
5239
|
+
const plugins = readOptionalPlugins(argv);
|
|
5101
5240
|
const strict = argv.includes("--strict");
|
|
5102
5241
|
const manifest = await buildProject({ rootDir, host, outDir, plugins, strict, target });
|
|
5242
|
+
const resolvedOutDir = outDir ?? manifest.config.build.outDir ?? defaultBuildOutDir2(manifest.host, manifest.target);
|
|
5103
5243
|
printDiagnostics(manifest.diagnostics ?? []);
|
|
5104
5244
|
if (strict && manifest.diagnostics?.length) {
|
|
5105
5245
|
exit(1);
|
|
5106
5246
|
}
|
|
5107
5247
|
console.log(
|
|
5108
|
-
`Built ${manifest.tools.length} ${target} tool${manifest.tools.length === 1 ? "" : "s"}, ${manifest.resources.length} resource${manifest.resources.length === 1 ? "" : "s"}, and ${manifest.prompts.length} prompt${manifest.prompts.length === 1 ? "" : "s"} to ${
|
|
5248
|
+
`Built ${manifest.tools.length} ${manifest.target} tool${manifest.tools.length === 1 ? "" : "s"}, ${manifest.resources.length} resource${manifest.resources.length === 1 ? "" : "s"}, and ${manifest.prompts.length} prompt${manifest.prompts.length === 1 ? "" : "s"} to ${resolvedOutDir}.`
|
|
5109
5249
|
);
|
|
5110
|
-
console.log(`Host runtime: ${host}`);
|
|
5111
|
-
if (host === "vercel") {
|
|
5112
|
-
console.log(`Vercel MCP function: ${path19.join(
|
|
5250
|
+
console.log(`Host runtime: ${manifest.host}`);
|
|
5251
|
+
if (manifest.host === "vercel") {
|
|
5252
|
+
console.log(`Vercel MCP function: ${path19.join(resolvedOutDir, VERCEL_ENTRYPOINT)}`);
|
|
5113
5253
|
} else {
|
|
5114
|
-
console.log(`Hostable MCP server: ${path19.join(
|
|
5254
|
+
console.log(`Hostable MCP server: ${path19.join(resolvedOutDir, SERVER_ENTRYPOINT)}`);
|
|
5115
5255
|
}
|
|
5116
|
-
if (plugins) {
|
|
5256
|
+
if (plugins ?? manifest.config.build.plugins) {
|
|
5117
5257
|
console.log("Built claude-plugin package.");
|
|
5118
5258
|
}
|
|
5119
5259
|
return;
|
|
@@ -5243,7 +5383,7 @@ async function main(argv) {
|
|
|
5243
5383
|
console.log(`Sidecar
|
|
5244
5384
|
|
|
5245
5385
|
Usage:
|
|
5246
|
-
sidecar build [--cwd <dir>] [--target mcp|chatgpt|claude] [--host node|vercel] [--out <dir>] [--plugins] [--strict]
|
|
5386
|
+
sidecar build [--cwd <dir>] [--target mcp|chatgpt|claude] [--host node|vercel] [--out <dir>] [--plugins|--no-plugins] [--strict]
|
|
5247
5387
|
sidecar check [--cwd <dir>] [--target mcp|chatgpt|claude] [--strict]
|
|
5248
5388
|
sidecar dev [--cwd <dir>] [--target mcp|chatgpt|claude] [--port <port>] [--tunnel [cloudflared|wrangler]]
|
|
5249
5389
|
sidecar inspect [--cwd <dir>] [--target mcp|chatgpt|claude]
|
|
@@ -5251,20 +5391,51 @@ Usage:
|
|
|
5251
5391
|
`);
|
|
5252
5392
|
}
|
|
5253
5393
|
}
|
|
5394
|
+
function defaultBuildOutDir2(host, target) {
|
|
5395
|
+
if (host === "vercel") {
|
|
5396
|
+
return ".vercel/output";
|
|
5397
|
+
}
|
|
5398
|
+
return `out/${target}`;
|
|
5399
|
+
}
|
|
5254
5400
|
function readTarget(argv) {
|
|
5255
|
-
const target =
|
|
5401
|
+
const target = readOptionalTarget(argv) ?? "mcp";
|
|
5402
|
+
return target;
|
|
5403
|
+
}
|
|
5404
|
+
function readOptionalTarget(argv) {
|
|
5405
|
+
const target = readOption(argv, "--target");
|
|
5406
|
+
if (!target) {
|
|
5407
|
+
return void 0;
|
|
5408
|
+
}
|
|
5256
5409
|
if (target === "mcp" || target === "chatgpt" || target === "claude") {
|
|
5257
5410
|
return target;
|
|
5258
5411
|
}
|
|
5259
5412
|
throw new Error(`Unsupported Sidecar target "${target}". Expected mcp, chatgpt, or claude.`);
|
|
5260
5413
|
}
|
|
5261
|
-
function
|
|
5262
|
-
const host = readOption(argv, "--host")
|
|
5414
|
+
function readOptionalHost(argv) {
|
|
5415
|
+
const host = readOption(argv, "--host");
|
|
5416
|
+
if (!host) {
|
|
5417
|
+
return void 0;
|
|
5418
|
+
}
|
|
5263
5419
|
if (host === "node" || host === "vercel") {
|
|
5264
5420
|
return host;
|
|
5265
5421
|
}
|
|
5266
5422
|
throw new Error(`Unsupported Sidecar host "${host}". Expected node or vercel.`);
|
|
5267
5423
|
}
|
|
5424
|
+
function detectHostFromEnvironment() {
|
|
5425
|
+
if (process.env.VERCEL === "1") {
|
|
5426
|
+
return "vercel";
|
|
5427
|
+
}
|
|
5428
|
+
return void 0;
|
|
5429
|
+
}
|
|
5430
|
+
function readOptionalPlugins(argv) {
|
|
5431
|
+
if (argv.includes("--plugins")) {
|
|
5432
|
+
return true;
|
|
5433
|
+
}
|
|
5434
|
+
if (argv.includes("--no-plugins")) {
|
|
5435
|
+
return false;
|
|
5436
|
+
}
|
|
5437
|
+
return void 0;
|
|
5438
|
+
}
|
|
5268
5439
|
async function previewComponents(options) {
|
|
5269
5440
|
const cliDir = path19.dirname(fileURLToPath(import.meta.url));
|
|
5270
5441
|
const css = await readFile8(path19.join(cliDir, "../../native/src/styles.css"), "utf8").catch(() => readFile8(path19.join(process.cwd(), "packages/native/src/styles.css"), "utf8")).catch(() => "");
|