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

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 CHANGED
@@ -1,12 +1,6 @@
1
1
  // packages/core/src/index.ts
2
- var toolBrand = /* @__PURE__ */ Symbol.for("sidecar.tool");
3
2
  var toolResultBrand = /* @__PURE__ */ Symbol.for("sidecar.toolResult");
4
3
  var resourceResultBrand = /* @__PURE__ */ Symbol.for("sidecar.resourceResult");
5
- function isSidecarTool(value) {
6
- return Boolean(
7
- value && typeof value === "object" && (value[toolBrand] || value.kind === "sidecar.tool")
8
- );
9
- }
10
4
  var toolResult = Object.assign(
11
5
  createToolResult,
12
6
  {
@@ -33,9 +27,9 @@ var resourceResult = Object.assign(
33
27
  );
34
28
  function createToolResult(input) {
35
29
  const resultEnvelope = stripUndefined({
36
- structuredContent: stripJsonUndefined(input.structuredContent),
30
+ structuredContent: input.structuredContent,
37
31
  content: normalizeRequiredContent(input.content),
38
- _meta: stripJsonUndefined(input.meta),
32
+ _meta: input.meta,
39
33
  isError: input.isError
40
34
  });
41
35
  Object.defineProperty(resultEnvelope, toolResultBrand, {
@@ -277,24 +271,10 @@ function isReadonlyArray(value) {
277
271
  function stripUndefined(value) {
278
272
  return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
279
273
  }
280
- function stripJsonUndefined(value) {
281
- if (value === void 0) {
282
- return void 0;
283
- }
284
- if (Array.isArray(value)) {
285
- return value.map((entry) => stripJsonUndefined(entry)).filter((entry) => entry !== void 0);
286
- }
287
- if (!value || typeof value !== "object") {
288
- return value;
289
- }
290
- return Object.fromEntries(
291
- Object.entries(value).map(([key, entry]) => [key, stripJsonUndefined(entry)]).filter(([, entry]) => entry !== void 0)
292
- );
293
- }
294
274
 
295
275
  // packages/compiler/src/analyze.ts
296
276
  import { readdir } from "fs/promises";
297
- import path5 from "path";
277
+ import path4 from "path";
298
278
  import {
299
279
  Node as Node4,
300
280
  SyntaxKind as SyntaxKind2
@@ -461,7 +441,14 @@ function devSidecarTypePaths() {
461
441
  import {
462
442
  Node as Node2
463
443
  } from "ts-morph";
464
- function getParamsSchema(_definition, execute) {
444
+ function getParamsSchema(definition, execute) {
445
+ const explicitParams = definition.getProperty("params");
446
+ if (explicitParams && Node2.isPropertyAssignment(explicitParams)) {
447
+ const inferred = getSchemaFromZodProperty(explicitParams);
448
+ if (inferred) {
449
+ return inferred;
450
+ }
451
+ }
465
452
  const [params] = execute.getParameters();
466
453
  if (!params) {
467
454
  return emptyObjectSchema();
@@ -482,6 +469,74 @@ function getOutputSchema(definition, execute) {
482
469
  }
483
470
  return typeToJsonSchema(returnType);
484
471
  }
472
+ function getSchemaFromZodProperty(property) {
473
+ const initializer = property.getInitializer();
474
+ if (!initializer) {
475
+ return void 0;
476
+ }
477
+ if (Node2.isCallExpression(initializer) && initializer.getExpression().getText().endsWith(".object")) {
478
+ const [shape] = initializer.getArguments();
479
+ if (shape && Node2.isObjectLiteralExpression(shape)) {
480
+ return zodObjectLiteralToSchema(shape);
481
+ }
482
+ }
483
+ return void 0;
484
+ }
485
+ function zodObjectLiteralToSchema(shape) {
486
+ const properties = {};
487
+ const required = [];
488
+ for (const property of shape.getProperties()) {
489
+ if (!Node2.isPropertyAssignment(property)) {
490
+ continue;
491
+ }
492
+ const name = property.getName().replace(/^["']|["']$/g, "");
493
+ const initializer = property.getInitializer();
494
+ if (!initializer) {
495
+ continue;
496
+ }
497
+ const propertySchema = zodExpressionToSchema(initializer);
498
+ properties[name] = propertySchema.schema;
499
+ if (!propertySchema.optional) {
500
+ required.push(name);
501
+ }
502
+ }
503
+ return {
504
+ type: "object",
505
+ properties,
506
+ required,
507
+ additionalProperties: false
508
+ };
509
+ }
510
+ function zodExpressionToSchema(expression) {
511
+ const text = expression.getText();
512
+ const optional = /\.optional\(\)/.test(text) || /\.default\(/.test(text);
513
+ const schema = {};
514
+ if (/z\.string\(\)/.test(text)) {
515
+ schema.type = "string";
516
+ } else if (/z\.number\(\)/.test(text)) {
517
+ schema.type = "number";
518
+ } else if (/z\.boolean\(\)/.test(text)) {
519
+ schema.type = "boolean";
520
+ } else if (/z\.array\(/.test(text)) {
521
+ schema.type = "array";
522
+ schema.items = {};
523
+ } else {
524
+ schema.type = "object";
525
+ }
526
+ const min = text.match(/\.min\((\d+)/);
527
+ const max = text.match(/\.max\((\d+)/);
528
+ if (schema.type === "string") {
529
+ if (min) schema.minLength = Number(min[1]);
530
+ if (max) schema.maxLength = Number(max[1]);
531
+ } else {
532
+ if (min) schema.minimum = Number(min[1]);
533
+ if (max) schema.maximum = Number(max[1]);
534
+ }
535
+ if (/\.int\(\)/.test(text)) {
536
+ schema.type = "integer";
537
+ }
538
+ return { schema, optional };
539
+ }
485
540
  function typeToJsonSchema(type, description) {
486
541
  const withoutUndefined = removeUndefined(type);
487
542
  const schema = typeToJsonSchemaInner(withoutUndefined);
@@ -627,103 +682,11 @@ function schemaDescription(symbol) {
627
682
  }).find((comment) => comment.trim().length > 0);
628
683
  }
629
684
 
630
- // packages/compiler/src/runtime-schema.ts
631
- import { existsSync as existsSync2 } from "fs";
632
- import path3 from "path";
633
- import { pathToFileURL } from "url";
634
- import { tsImport } from "tsx/esm/api";
635
- async function readRuntimeToolInputSchema(rootDir, sourcePath) {
636
- let sidecarTool;
637
- try {
638
- sidecarTool = await importRuntimeTool(rootDir, sourcePath);
639
- } catch (error) {
640
- warnRuntimeSchemaFallback(sourcePath, error);
641
- return void 0;
642
- }
643
- if (!sidecarTool.params) {
644
- return void 0;
645
- }
646
- try {
647
- return await paramsToJsonSchema(sidecarTool.params);
648
- } catch (error) {
649
- warnRuntimeSchemaFallback(sourcePath, error);
650
- return void 0;
651
- }
652
- }
653
- async function importRuntimeTool(rootDir, sourcePath) {
654
- const module = await tsImport(pathToFileURL(sourcePath).href, {
655
- parentURL: runtimeParentUrl(rootDir),
656
- tsconfig: runtimeTsconfig(rootDir)
657
- });
658
- const defaultExport = unwrapRuntimeDefault(module.default);
659
- if (!isSidecarTool(defaultExport)) {
660
- throw new Error(`${path3.relative(rootDir, sourcePath)} must default-export tool({ ... }).`);
661
- }
662
- return defaultExport;
663
- }
664
- async function paramsToJsonSchema(params) {
665
- const instanceConverter = readInstanceConverter(params);
666
- if (instanceConverter) {
667
- return ensureJsonSchema(instanceConverter({ io: "input" }));
668
- }
669
- if (isZodMiniSchema(params)) {
670
- const zod = await import("zod/v4-mini");
671
- if (typeof zod.toJSONSchema === "function") {
672
- return ensureJsonSchema(zod.toJSONSchema(params, { io: "input" }));
673
- }
674
- }
675
- return void 0;
676
- }
677
- function readInstanceConverter(params) {
678
- if (!params || typeof params !== "object") {
679
- return void 0;
680
- }
681
- const record = params;
682
- const converter = record.toJSONSchema ?? record.toJsonSchema;
683
- return typeof converter === "function" ? converter.bind(params) : void 0;
684
- }
685
- function isZodMiniSchema(params) {
686
- return Boolean(params && typeof params === "object" && "_zod" in params);
687
- }
688
- function ensureJsonSchema(value) {
689
- if (!value || typeof value !== "object" || Array.isArray(value)) {
690
- return void 0;
691
- }
692
- return value;
693
- }
694
- function runtimeParentUrl(rootDir) {
695
- const configPath = path3.join(rootDir, "sidecar.config.ts");
696
- return pathToFileURL(existsSync2(configPath) ? configPath : rootDir).href;
697
- }
698
- function runtimeTsconfig(rootDir) {
699
- const projectTsconfig = path3.join(rootDir, "tsconfig.json");
700
- if (existsSync2(projectTsconfig)) {
701
- return projectTsconfig;
702
- }
703
- const repoTsconfig = path3.join(process.cwd(), "tsconfig.json");
704
- const repoCore = path3.join(process.cwd(), "packages", "core", "src", "index.ts");
705
- return existsSyncSafe(repoTsconfig) && existsSyncSafe(repoCore) ? repoTsconfig : false;
706
- }
707
- function unwrapRuntimeDefault(value) {
708
- if (value && typeof value === "object" && "default" in value && Object.keys(value).every((key) => key === "default" || key === "__esModule")) {
709
- return unwrapRuntimeDefault(value.default);
710
- }
711
- return value;
712
- }
713
- function warnRuntimeSchemaFallback(sourcePath, error) {
714
- const message = error instanceof Error ? error.message : String(error);
715
- console.warn(
716
- `[sidecar] Could not convert runtime params schema for ${sourcePath}; falling back to TypeScript parameter inference. ${message}`
717
- );
718
- }
719
-
720
685
  // packages/compiler/src/widgets.ts
721
686
  import { createHash } from "crypto";
722
- import { existsSync as existsSync3 } from "fs";
687
+ import { existsSync as existsSync2 } from "fs";
723
688
  import { mkdir, readFile, writeFile } from "fs/promises";
724
- import { createRequire } from "module";
725
- import path4 from "path";
726
- import { pathToFileURL as pathToFileURL2 } from "url";
689
+ import path3 from "path";
727
690
  import { build as esbuild } from "esbuild";
728
691
  import postcss from "postcss";
729
692
  import {
@@ -731,30 +694,28 @@ import {
731
694
  SyntaxKind
732
695
  } from "ts-morph";
733
696
  var CLAUDE_FONT_RESOURCE_DOMAIN = "https://assets.claude.ai";
734
- var requireFromCompiler = createRequire(import.meta.url);
735
- async function buildWidgets(rootDir, outDir, tools, config = void 0) {
697
+ async function buildWidgets(rootDir, outDir, tools) {
736
698
  const widgets = tools.filter(
737
699
  (entry) => Boolean(entry.widget)
738
700
  );
739
701
  if (!widgets.length) {
740
702
  return;
741
703
  }
742
- const cacheDir = path4.join(rootDir, ".sidecar", "cache", "widgets");
704
+ const cacheDir = path3.join(rootDir, ".sidecar", "cache", "widgets");
743
705
  await mkdir(cacheDir, { recursive: true });
744
706
  const appStyle = await prepareAppStyle(rootDir, cacheDir);
745
- const configure = await loadWidgetBundlerHook(rootDir, cacheDir, config?.configure);
746
707
  for (const entry of widgets) {
747
- const sourceFile = path4.join(rootDir, entry.widget.sourceFile);
708
+ const sourceFile = path3.join(rootDir, entry.widget.sourceFile);
748
709
  const safeId = safePathSegment(entry.id);
749
- const entryFile = path4.join(cacheDir, `${safeId}.entry.tsx`);
750
- const importPath = toImportSpecifier(path4.dirname(entryFile), sourceFile);
710
+ const entryFile = path3.join(cacheDir, `${safeId}.entry.tsx`);
711
+ const importPath = toImportSpecifier(path3.dirname(entryFile), sourceFile);
751
712
  await writeFile(
752
713
  entryFile,
753
714
  `import React from "react";
754
715
  import { createRoot } from "react-dom/client";
755
716
  import { SidecarWidgetRoot } from "@sidecar-ai/react";
756
717
  import "@sidecar-ai/native/styles.css";
757
- ${appStyle ? `import ${JSON.stringify(toImportSpecifier(path4.dirname(entryFile), appStyle))};` : ""}
718
+ ${appStyle ? `import ${JSON.stringify(toImportSpecifier(path3.dirname(entryFile), appStyle))};` : ""}
758
719
  import Component from ${JSON.stringify(importPath)};
759
720
 
760
721
  createRoot(document.getElementById("root")!).render(
@@ -762,219 +723,64 @@ createRoot(document.getElementById("root")!).render(
762
723
  );
763
724
  `
764
725
  );
765
- const baseOptions = enforceWidgetBuildInvariants({
726
+ const bundled = await esbuild({
766
727
  absWorkingDir: rootDir,
767
- alias: sidecarWidgetAliases(rootDir),
728
+ alias: devSidecarBundleAliases(rootDir),
768
729
  bundle: true,
769
- define: {
770
- "process.env.NODE_ENV": JSON.stringify("production")
771
- },
772
730
  entryPoints: [entryFile],
773
731
  format: "iife",
774
732
  jsx: "automatic",
775
- minify: true,
733
+ minify: false,
776
734
  nodePaths: [
777
- path4.join(rootDir, "node_modules"),
778
- path4.join(process.cwd(), "node_modules")
735
+ path3.join(rootDir, "node_modules"),
736
+ path3.join(process.cwd(), "node_modules")
779
737
  ],
780
738
  outfile: "widget.js",
781
739
  platform: "browser",
782
740
  sourcemap: false,
783
741
  write: false
784
742
  });
785
- const staticOptions = widgetBuildOptionsFromConfig(rootDir, config);
786
- const configuredOptions = configure ? await configureWidgetBuild(configure, {
787
- rootDir,
788
- outDir,
789
- entryFile,
790
- widget: {
791
- toolId: entry.id,
792
- toolName: entry.name,
793
- target: entry.target,
794
- sourceFile: entry.widget.sourceFile
795
- },
796
- esbuildOptions: mergeWidgetBuildOptions(baseOptions, staticOptions)
797
- }) : void 0;
798
- const bundled = await esbuild(enforceWidgetBuildInvariants(
799
- mergeWidgetBuildOptions(baseOptions, staticOptions, configuredOptions),
800
- { rootDir, entryFile }
801
- ));
802
- const outputFiles = bundled.outputFiles ?? [];
803
- const javascript = outputFiles.find((file) => file.path.endsWith(".js"))?.text ?? "";
804
- const css = outputFiles.filter((file) => file.path.endsWith(".css")).map((file) => file.text).join("\n");
743
+ const javascript = bundled.outputFiles.find((file) => file.path.endsWith(".js"))?.text ?? "";
744
+ const css = bundled.outputFiles.filter((file) => file.path.endsWith(".css")).map((file) => file.text).join("\n");
805
745
  const html = renderWidgetHtml(entry.name, javascript, css);
806
746
  const hash = createHash("sha256").update(html).digest("hex").slice(0, 12);
807
- const outputDir = path4.join(outDir, "public", "widgets", safeId);
808
- const outputFile = path4.join(outputDir, `widget.${hash}.html`);
747
+ const outputDir = path3.join(outDir, "public", "widgets", safeId);
748
+ const outputFile = path3.join(outputDir, `widget.${hash}.html`);
809
749
  const resourceUri = `ui://${safeId}/widget.${hash}.html`;
810
750
  await mkdir(outputDir, { recursive: true });
811
751
  await writeFile(outputFile, html);
812
752
  entry.widget.resourceUri = resourceUri;
813
753
  entry.widget.resourceMeta = widgetResourceMeta(entry.widget.options, entry.target);
814
- entry.widget.outputFile = path4.relative(outDir, outputFile);
754
+ entry.widget.outputFile = path3.relative(outDir, outputFile);
815
755
  entry.descriptor._meta = mergeWidgetMeta(entry.descriptor._meta, widgetMeta(resourceUri, entry.widget.options, entry.target));
816
756
  }
817
757
  }
818
- function widgetBuildOptionsFromConfig(rootDir, config) {
819
- const esbuildConfig = config?.esbuild;
820
- if (!esbuildConfig) {
821
- return void 0;
822
- }
823
- return {
824
- alias: normalizeAliases(rootDir, esbuildConfig.alias),
825
- conditions: esbuildConfig.conditions,
826
- define: esbuildConfig.define,
827
- external: esbuildConfig.external,
828
- jsx: esbuildConfig.jsx,
829
- jsxImportSource: esbuildConfig.jsxImportSource,
830
- loader: esbuildConfig.loader,
831
- mainFields: esbuildConfig.mainFields
832
- };
833
- }
834
- async function loadWidgetBundlerHook(rootDir, cacheDir, hookPath) {
835
- if (!hookPath) {
836
- return void 0;
837
- }
838
- const sourcePath = path4.resolve(rootDir, hookPath);
839
- const relative = path4.relative(rootDir, sourcePath);
840
- if (relative.startsWith("..") || path4.isAbsolute(relative)) {
841
- throw new Error(`Widget bundler hook must stay inside the project root: ${hookPath}`);
842
- }
843
- if (!existsSync3(sourcePath)) {
844
- throw new Error(`Widget bundler hook not found: ${hookPath}`);
845
- }
846
- const outputFile = path4.join(cacheDir, `widget-bundler.${contentHash(hookPath)}.mjs`);
847
- await esbuild({
848
- absWorkingDir: rootDir,
849
- alias: devSidecarBundleAliases(rootDir),
850
- bundle: true,
851
- entryPoints: [sourcePath],
852
- format: "esm",
853
- nodePaths: [
854
- path4.join(rootDir, "node_modules"),
855
- path4.join(process.cwd(), "node_modules")
856
- ],
857
- outfile: outputFile,
858
- packages: "external",
859
- platform: "node",
860
- target: "node20"
861
- });
862
- const module = await import(`${pathToFileURL2(outputFile).href}?t=${Date.now()}`);
863
- if (typeof module.default !== "function") {
864
- throw new Error(`Widget bundler hook must default-export a function: ${hookPath}`);
865
- }
866
- return module.default;
867
- }
868
- async function configureWidgetBuild(hook, input) {
869
- const result = await hook(input);
870
- if (!result) {
871
- return void 0;
872
- }
873
- if (typeof result === "object" && "esbuildOptions" in result) {
874
- return result.esbuildOptions;
875
- }
876
- return result;
877
- }
878
- function mergeWidgetBuildOptions(...options) {
879
- const merged = {};
880
- for (const option of options) {
881
- if (!option) {
882
- continue;
883
- }
884
- const previousAlias = merged.alias;
885
- const previousDefine = merged.define;
886
- const previousLoader = merged.loader;
887
- const previousExternal = merged.external;
888
- const previousNodePaths = merged.nodePaths;
889
- const previousPlugins = merged.plugins;
890
- Object.assign(merged, option);
891
- merged.alias = { ...previousAlias ?? {}, ...option.alias ?? {} };
892
- merged.define = { ...previousDefine ?? {}, ...option.define ?? {} };
893
- merged.loader = { ...previousLoader ?? {}, ...option.loader ?? {} };
894
- merged.external = uniqueStrings([...previousExternal ?? [], ...option.external ?? []]);
895
- merged.nodePaths = uniqueStrings([...previousNodePaths ?? [], ...option.nodePaths ?? []]);
896
- merged.plugins = [...previousPlugins ?? [], ...option.plugins ?? []];
897
- }
898
- return merged;
899
- }
900
- function enforceWidgetBuildInvariants(options, required) {
901
- const aliases = required ? { ...options.alias ?? {}, ...reactSingletonAliases(required.rootDir) } : options.alias;
902
- return {
903
- ...options,
904
- absWorkingDir: required?.rootDir ?? options.absWorkingDir,
905
- alias: aliases,
906
- bundle: true,
907
- entryPoints: required ? [required.entryFile] : options.entryPoints,
908
- format: "iife",
909
- outfile: "widget.js",
910
- platform: "browser",
911
- write: false
912
- };
913
- }
914
- function sidecarWidgetAliases(rootDir) {
915
- return {
916
- ...devSidecarBundleAliases(rootDir) ?? {},
917
- ...reactSingletonAliases(rootDir)
918
- };
919
- }
920
- function reactSingletonAliases(rootDir) {
921
- return {
922
- react: resolveProjectModule(rootDir, "react"),
923
- "react/jsx-runtime": resolveProjectModule(rootDir, "react/jsx-runtime"),
924
- "react/jsx-dev-runtime": resolveProjectModule(rootDir, "react/jsx-dev-runtime"),
925
- "react-dom": resolveProjectModule(rootDir, "react-dom"),
926
- "react-dom/client": resolveProjectModule(rootDir, "react-dom/client"),
927
- "react-dom/server": resolveProjectModule(rootDir, "react-dom/server")
928
- };
929
- }
930
- function resolveProjectModule(rootDir, specifier) {
931
- return requireFromCompiler.resolve(specifier, {
932
- paths: [rootDir, process.cwd()]
933
- });
934
- }
935
- function normalizeAliases(rootDir, aliases) {
936
- if (!aliases) {
937
- return void 0;
938
- }
939
- return Object.fromEntries(
940
- Object.entries(aliases).map(([key, value]) => [
941
- key,
942
- value.startsWith(".") ? path4.resolve(rootDir, value) : value
943
- ])
944
- );
945
- }
946
- function uniqueStrings(values) {
947
- return [...new Set(values)];
948
- }
949
- function contentHash(value) {
950
- return createHash("sha256").update(value).digest("hex").slice(0, 12);
951
- }
952
758
  function devSidecarBundleAliases(rootDir) {
953
759
  const repoRoot = findSidecarRepoRoot(rootDir) ?? findSidecarRepoRoot(process.cwd());
954
760
  if (!repoRoot) {
955
761
  return void 0;
956
762
  }
957
- const reactEntry = path4.join(repoRoot, "packages", "react", "src", "index.ts");
958
- if (!existsSync3(reactEntry)) {
763
+ const reactEntry = path3.join(repoRoot, "packages", "react", "src", "index.ts");
764
+ if (!existsSync2(reactEntry)) {
959
765
  return void 0;
960
766
  }
961
767
  return {
962
- "sidecar-ai": path4.join(repoRoot, "packages", "sidecar-ai", "src", "index.ts"),
963
- "@sidecar-ai/client": path4.join(repoRoot, "packages", "client", "src", "index.ts"),
964
- "@sidecar-ai/core": path4.join(repoRoot, "packages", "core", "src", "index.ts"),
768
+ "sidecar-ai": path3.join(repoRoot, "packages", "sidecar-ai", "src", "index.ts"),
769
+ "@sidecar-ai/client": path3.join(repoRoot, "packages", "client", "src", "index.ts"),
770
+ "@sidecar-ai/core": path3.join(repoRoot, "packages", "core", "src", "index.ts"),
965
771
  "@sidecar-ai/react": reactEntry,
966
- "@sidecar-ai/native": path4.join(repoRoot, "packages", "native", "src", "index.ts"),
967
- "@sidecar-ai/native/components": path4.join(repoRoot, "packages", "native", "src", "components", "index.tsx"),
968
- "@sidecar-ai/native/styles.css": path4.join(repoRoot, "packages", "native", "src", "styles.css")
772
+ "@sidecar-ai/native": path3.join(repoRoot, "packages", "native", "src", "index.ts"),
773
+ "@sidecar-ai/native/components": path3.join(repoRoot, "packages", "native", "src", "components", "index.tsx"),
774
+ "@sidecar-ai/native/styles.css": path3.join(repoRoot, "packages", "native", "src", "styles.css")
969
775
  };
970
776
  }
971
777
  function findSidecarRepoRoot(startDir) {
972
- let current = path4.resolve(startDir);
778
+ let current = path3.resolve(startDir);
973
779
  while (true) {
974
- if (existsSync3(path4.join(current, "packages", "core", "src", "index.ts"))) {
780
+ if (existsSync2(path3.join(current, "packages", "core", "src", "index.ts"))) {
975
781
  return current;
976
782
  }
977
- const parent = path4.dirname(current);
783
+ const parent = path3.dirname(current);
978
784
  if (parent === current) {
979
785
  return void 0;
980
786
  }
@@ -982,13 +788,13 @@ function findSidecarRepoRoot(startDir) {
982
788
  }
983
789
  }
984
790
  async function prepareAppStyle(rootDir, cacheDir) {
985
- const sourceFile = path4.join(rootDir, "style.css");
986
- if (!existsSync3(sourceFile)) {
791
+ const sourceFile = path3.join(rootDir, "style.css");
792
+ if (!existsSync2(sourceFile)) {
987
793
  return void 0;
988
794
  }
989
795
  const source = await readFile(sourceFile, "utf8");
990
796
  const css = await processAppStyle(source, sourceFile);
991
- const outputFile = path4.join(cacheDir, "style.css");
797
+ const outputFile = path3.join(cacheDir, "style.css");
992
798
  await writeFile(outputFile, css);
993
799
  return outputFile;
994
800
  }
@@ -1000,7 +806,7 @@ async function processAppStyle(source, from) {
1000
806
  const plugins = [];
1001
807
  if (cssSource.includes("@tailwind")) {
1002
808
  const tailwind = await import("@tailwindcss/postcss");
1003
- plugins.push(tailwind.default({ base: path4.dirname(from) }));
809
+ plugins.push(tailwind.default({ base: path3.dirname(from) }));
1004
810
  }
1005
811
  const autoprefixer = await import("autoprefixer");
1006
812
  plugins.push(autoprefixer.default());
@@ -1014,13 +820,13 @@ function needsPostcss(source) {
1014
820
  return /@import\s+["']tailwindcss["']|@tailwind|@source|@theme|@plugin/.test(source);
1015
821
  }
1016
822
  function findWidget(rootDir, toolFile, id, target = "mcp", toolVariant = "shared") {
1017
- const selected = selectWidgetFile(path4.dirname(toolFile), target, toolVariant);
823
+ const selected = selectWidgetFile(path3.dirname(toolFile), target, toolVariant);
1018
824
  if (!selected) {
1019
825
  return void 0;
1020
826
  }
1021
827
  const safeId = safePathSegment(id);
1022
828
  return {
1023
- sourceFile: path4.relative(rootDir, selected.filePath),
829
+ sourceFile: path3.relative(rootDir, selected.filePath),
1024
830
  variant: selected.variant,
1025
831
  resourceUri: `ui://${safeId}/widget.html`
1026
832
  };
@@ -1055,8 +861,7 @@ function widgetMeta(resourceUri, options = {}, target = "mcp") {
1055
861
  const standard = {
1056
862
  ui: {
1057
863
  resourceUri
1058
- },
1059
- "ui/resourceUri": resourceUri
864
+ }
1060
865
  };
1061
866
  if (target !== "chatgpt") {
1062
867
  return standard;
@@ -1203,17 +1008,17 @@ function readStringArrayProperty(definition, propertyName) {
1203
1008
  }
1204
1009
  function selectWidgetFile(directory, target, toolVariant) {
1205
1010
  if (toolVariant === "openai") {
1206
- const filePath = path4.join(directory, "widget.openai.tsx");
1207
- return existsSync3(filePath) ? { filePath, variant: "openai" } : void 0;
1011
+ const filePath = path3.join(directory, "widget.openai.tsx");
1012
+ return existsSync2(filePath) ? { filePath, variant: "openai" } : void 0;
1208
1013
  }
1209
1014
  if (toolVariant === "anthropic") {
1210
- const filePath = path4.join(directory, "widget.anthropic.tsx");
1211
- return existsSync3(filePath) ? { filePath, variant: "anthropic" } : void 0;
1015
+ const filePath = path3.join(directory, "widget.anthropic.tsx");
1016
+ return existsSync2(filePath) ? { filePath, variant: "anthropic" } : void 0;
1212
1017
  }
1213
1018
  const candidates = target === "chatgpt" || target === "claude" || target === "mcp" ? [{ name: "widget.tsx", variant: "shared" }] : [];
1214
1019
  for (const candidate of candidates) {
1215
- const filePath = path4.join(directory, candidate.name);
1216
- if (existsSync3(filePath)) {
1020
+ const filePath = path3.join(directory, candidate.name);
1021
+ if (existsSync2(filePath)) {
1217
1022
  return { filePath, variant: candidate.variant };
1218
1023
  }
1219
1024
  }
@@ -1264,23 +1069,17 @@ function stripUndefined3(value) {
1264
1069
  // packages/compiler/src/analyze.ts
1265
1070
  async function analyzeProjectTools(rootDir, options = {}) {
1266
1071
  const target = options.target ?? "mcp";
1267
- const toolFiles = await findToolFiles(path5.join(rootDir, "server"), target);
1072
+ const toolFiles = await findToolFiles(path4.join(rootDir, "server"), target);
1268
1073
  if (toolFiles.length === 0) {
1269
1074
  return [];
1270
1075
  }
1271
1076
  const project = createProject(rootDir);
1272
1077
  const authScopes = readAuthScopeCatalog(project, rootDir);
1273
- const sources = toolFiles.map((candidate) => ({
1274
- candidate,
1275
- sourceFile: project.addSourceFileAtPath(candidate.filePath)
1276
- }));
1277
- const runtimeInputSchemas = await readRuntimeInputSchemas(rootDir, sources);
1278
- return sources.map(
1279
- ({ candidate, sourceFile }) => analyzeToolFile(sourceFile, rootDir, {
1078
+ return toolFiles.map(
1079
+ (candidate) => analyzeToolFile(project.addSourceFileAtPath(candidate.filePath), rootDir, {
1280
1080
  target,
1281
1081
  variant: candidate.variant,
1282
- authScopes,
1283
- inputSchema: runtimeInputSchemas.get(candidate.filePath)
1082
+ authScopes
1284
1083
  })
1285
1084
  );
1286
1085
  }
@@ -1289,7 +1088,7 @@ function analyzeToolFile(sourceFile, rootDir, options = {}) {
1289
1088
  const variant = options.variant ?? "shared";
1290
1089
  const definition = findToolDefinition(sourceFile);
1291
1090
  const absoluteFile = sourceFile.getFilePath();
1292
- const directory = path5.basename(path5.dirname(absoluteFile));
1091
+ const directory = path4.basename(path4.dirname(absoluteFile));
1293
1092
  const name = getRequiredStringProperty(definition, "name", sourceFile);
1294
1093
  const id = getOptionalStringProperty(definition, "id") ?? toMachineName(directory);
1295
1094
  const description = getRequiredStringProperty(
@@ -1302,7 +1101,7 @@ function analyzeToolFile(sourceFile, rootDir, options = {}) {
1302
1101
  const hosts = readHosts(definition);
1303
1102
  const auth = readAuthPolicy(definition, options.authScopes ?? {});
1304
1103
  const execute = getExecuteFunction(definition, sourceFile);
1305
- const inputSchema = options.inputSchema ?? getParamsSchema(definition, execute);
1104
+ const inputSchema = getParamsSchema(definition, execute);
1306
1105
  const outputSchema = getOutputSchema(definition, execute);
1307
1106
  const descriptor = createToolDescriptor({
1308
1107
  name,
@@ -1320,7 +1119,7 @@ function analyzeToolFile(sourceFile, rootDir, options = {}) {
1320
1119
  validateWidgetHierarchy(sourceFile, absoluteFile, target, variant);
1321
1120
  const widget = findWidget(rootDir, absoluteFile, id, target, variant);
1322
1121
  if (widget) {
1323
- const widgetFile = path5.join(rootDir, widget.sourceFile);
1122
+ const widgetFile = path4.join(rootDir, widget.sourceFile);
1324
1123
  const project = sourceFile.getProject();
1325
1124
  const widgetSourceFile = project.getSourceFile(widgetFile) ?? project.addSourceFileAtPath(widgetFile);
1326
1125
  widget.options = {
@@ -1331,7 +1130,7 @@ function analyzeToolFile(sourceFile, rootDir, options = {}) {
1331
1130
  descriptor._meta = mergeWidgetMeta(descriptor._meta, widgetMeta(widget.resourceUri, widget.options, target));
1332
1131
  }
1333
1132
  return {
1334
- sourceFile: path5.relative(rootDir, absoluteFile),
1133
+ sourceFile: path4.relative(rootDir, absoluteFile),
1335
1134
  variant,
1336
1135
  target,
1337
1136
  directory,
@@ -1346,26 +1145,6 @@ function analyzeToolFile(sourceFile, rootDir, options = {}) {
1346
1145
  descriptor
1347
1146
  };
1348
1147
  }
1349
- async function readRuntimeInputSchemas(rootDir, sources) {
1350
- const schemas = /* @__PURE__ */ new Map();
1351
- await Promise.all(sources.map(async ({ candidate, sourceFile }) => {
1352
- const definition = findToolDefinition(sourceFile);
1353
- if (!definitionHasRuntimeParams(definition)) {
1354
- return;
1355
- }
1356
- const schema = await readRuntimeToolInputSchema(rootDir, candidate.filePath);
1357
- if (schema) {
1358
- schemas.set(candidate.filePath, schema);
1359
- }
1360
- }));
1361
- return schemas;
1362
- }
1363
- function definitionHasRuntimeParams(definition) {
1364
- if (definition.getProperty("params")) {
1365
- return true;
1366
- }
1367
- return Boolean(getWithParamsCall(definition));
1368
- }
1369
1148
  function readAuthPolicy(definition, authScopes) {
1370
1149
  const initializer = readObjectProperty2(definition, "auth");
1371
1150
  if (!initializer) {
@@ -1382,7 +1161,7 @@ function readAuthPolicy(definition, authScopes) {
1382
1161
  return { authenticated: true };
1383
1162
  }
1384
1163
  function readAuthScopeCatalog(project, rootDir) {
1385
- const authPath = path5.join(rootDir, "auth.ts");
1164
+ const authPath = path4.join(rootDir, "auth.ts");
1386
1165
  if (!existsSyncSafe(authPath)) {
1387
1166
  return {};
1388
1167
  }
@@ -1464,12 +1243,12 @@ function isNamedCall(call, name) {
1464
1243
  return callee === name || callee.endsWith(`.${name}`);
1465
1244
  }
1466
1245
  function validateWidgetHierarchy(sourceFile, toolFile, target, variant) {
1467
- const directory = path5.dirname(toolFile);
1246
+ const directory = path4.dirname(toolFile);
1468
1247
  const platformWidget = target === "chatgpt" ? "widget.openai.tsx" : target === "claude" ? "widget.anthropic.tsx" : void 0;
1469
1248
  if (!platformWidget || variant !== "shared") {
1470
1249
  return;
1471
1250
  }
1472
- if (existsSyncSafe(path5.join(directory, platformWidget))) {
1251
+ if (existsSyncSafe(path4.join(directory, platformWidget))) {
1473
1252
  const expectedTool = target === "chatgpt" ? "tool.openai.ts" : "tool.anthropic.ts";
1474
1253
  throw new CompilerError(
1475
1254
  sourceFile,
@@ -1484,7 +1263,7 @@ async function findToolFiles(serverDir, target) {
1484
1263
  const entries = await readdir(serverDir, { withFileTypes: true });
1485
1264
  const files = [];
1486
1265
  for (const entry of entries) {
1487
- const entryPath = path5.join(serverDir, entry.name);
1266
+ const entryPath = path4.join(serverDir, entry.name);
1488
1267
  if (entry.isDirectory()) {
1489
1268
  const candidate = selectToolFile(entryPath, target);
1490
1269
  if (candidate) {
@@ -1503,7 +1282,7 @@ function selectToolFile(directory, target) {
1503
1282
  { name: "tool.ts", variant: "shared" }
1504
1283
  ] : [{ name: "tool.ts", variant: "shared" }];
1505
1284
  for (const candidate of candidates) {
1506
- const filePath = path5.join(directory, candidate.name);
1285
+ const filePath = path4.join(directory, candidate.name);
1507
1286
  if (existsSyncSafe(filePath)) {
1508
1287
  return { filePath, variant: candidate.variant };
1509
1288
  }
@@ -1539,32 +1318,16 @@ function getExecuteFunction(definition, sourceFile) {
1539
1318
  return property;
1540
1319
  }
1541
1320
  if (Node4.isPropertyAssignment(property)) {
1542
- const initializer = unwrapExpression(property.getInitializer());
1321
+ const initializer = property.getInitializer();
1543
1322
  if (initializer && (Node4.isArrowFunction(initializer) || Node4.isFunctionExpression(initializer))) {
1544
1323
  return initializer;
1545
1324
  }
1546
- const withParamsCall = getWithParamsCall(definition);
1547
- const wrappedExecute = unwrapExpression(withParamsCall?.getArguments()[1]);
1548
- if (wrappedExecute && (Node4.isArrowFunction(wrappedExecute) || Node4.isFunctionExpression(wrappedExecute))) {
1549
- return wrappedExecute;
1550
- }
1551
1325
  }
1552
1326
  throw new CompilerError(
1553
1327
  sourceFile,
1554
1328
  "execute must be a method, function expression, or arrow function."
1555
1329
  );
1556
1330
  }
1557
- function getWithParamsCall(definition) {
1558
- const property = definition.getProperty("execute");
1559
- if (!property || !Node4.isPropertyAssignment(property)) {
1560
- return void 0;
1561
- }
1562
- const initializer = unwrapExpression(property.getInitializer());
1563
- if (!initializer || !Node4.isCallExpression(initializer)) {
1564
- return void 0;
1565
- }
1566
- return isNamedCall(initializer, "withParams") ? initializer : void 0;
1567
- }
1568
1331
  function getRequiredStringProperty(definition, propertyName, sourceFile) {
1569
1332
  const value = getOptionalStringProperty(definition, propertyName);
1570
1333
  if (value === void 0 || !value.trim()) {
@@ -1720,16 +1483,16 @@ function readStringArrayProperty2(definition, propertyName) {
1720
1483
 
1721
1484
  // packages/compiler/src/build.ts
1722
1485
  import { mkdir as mkdir9, writeFile as writeFile9 } from "fs/promises";
1723
- import path19 from "path";
1486
+ import path18 from "path";
1724
1487
 
1725
1488
  // packages/compiler/src/config.ts
1726
- import path6 from "path";
1489
+ import path5 from "path";
1727
1490
  import {
1728
1491
  Node as Node5,
1729
1492
  SyntaxKind as SyntaxKind3
1730
1493
  } from "ts-morph";
1731
1494
  function analyzeProjectConfig(rootDir) {
1732
- const configPath = path6.join(rootDir, "sidecar.config.ts");
1495
+ const configPath = path5.join(rootDir, "sidecar.config.ts");
1733
1496
  if (!existsSyncSafe(configPath)) {
1734
1497
  return defaultCompilerConfig();
1735
1498
  }
@@ -1741,13 +1504,6 @@ function analyzeProjectConfig(rootDir) {
1741
1504
  return defaultCompilerConfig();
1742
1505
  }
1743
1506
  return {
1744
- build: {
1745
- target: readTargetNested(definition, "build", "target"),
1746
- host: readHostNested(definition, "build", "host"),
1747
- outDir: readStringNested(definition, "build", "outDir"),
1748
- plugins: readBooleanNested(definition, "build", "plugins"),
1749
- widgets: readWidgetBuildConfig(definition)
1750
- },
1751
1507
  resources: {
1752
1508
  subscribe: readBooleanNested(definition, "resources", "subscribe") ?? false,
1753
1509
  listChanged: readBooleanNested(definition, "resources", "listChanged") ?? false
@@ -1759,52 +1515,13 @@ function analyzeProjectConfig(rootDir) {
1759
1515
  listChanged: readBooleanNested(definition, "tools", "listChanged") ?? false
1760
1516
  },
1761
1517
  pagination: {
1762
- pageSize: readNumberNested(definition, "pagination", "pageSize") ?? 50,
1518
+ pageSize: readNumberNested(definition, "pagination", "pageSize") ?? 10,
1763
1519
  hasOverride: hasProperty(readObjectProperty3(definition, "pagination"), "override")
1764
1520
  }
1765
1521
  };
1766
1522
  }
1767
- function readWidgetBuildConfig(definition) {
1768
- const widgets = readObjectProperty3(readObjectProperty3(definition, "build"), "widgets");
1769
- if (!widgets) {
1770
- return void 0;
1771
- }
1772
- const config = {};
1773
- const configure = readStringProperty3(widgets, "configure");
1774
- const esbuild3 = readWidgetEsbuildConfig(widgets);
1775
- if (configure) config.configure = configure;
1776
- if (esbuild3) config.esbuild = esbuild3;
1777
- return Object.keys(config).length ? config : void 0;
1778
- }
1779
- function readWidgetEsbuildConfig(widgets) {
1780
- const esbuild3 = readObjectProperty3(widgets, "esbuild");
1781
- if (!esbuild3) {
1782
- return void 0;
1783
- }
1784
- const config = {};
1785
- const alias = readStringRecordProperty(esbuild3, "alias");
1786
- const define = readStringRecordProperty(esbuild3, "define");
1787
- const external = readStringArrayProperty3(esbuild3, "external");
1788
- const loader = readStringRecordProperty(esbuild3, "loader");
1789
- const conditions = readStringArrayProperty3(esbuild3, "conditions");
1790
- const mainFields = readStringArrayProperty3(esbuild3, "mainFields");
1791
- const jsx = readStringProperty3(esbuild3, "jsx");
1792
- const jsxImportSource = readStringProperty3(esbuild3, "jsxImportSource");
1793
- if (alias) config.alias = alias;
1794
- if (define) config.define = define;
1795
- if (external) config.external = external;
1796
- if (loader) config.loader = loader;
1797
- if (conditions) config.conditions = conditions;
1798
- if (mainFields) config.mainFields = mainFields;
1799
- if (jsx === "automatic" || jsx === "transform" || jsx === "preserve") {
1800
- config.jsx = jsx;
1801
- }
1802
- if (jsxImportSource) config.jsxImportSource = jsxImportSource;
1803
- return Object.keys(config).length ? config : void 0;
1804
- }
1805
1523
  function defaultCompilerConfig() {
1806
1524
  return {
1807
- build: {},
1808
1525
  resources: {
1809
1526
  subscribe: false,
1810
1527
  listChanged: false
@@ -1816,26 +1533,11 @@ function defaultCompilerConfig() {
1816
1533
  listChanged: false
1817
1534
  },
1818
1535
  pagination: {
1819
- pageSize: 50,
1536
+ pageSize: 10,
1820
1537
  hasOverride: false
1821
1538
  }
1822
1539
  };
1823
1540
  }
1824
- function readTargetNested(definition, section, propertyName) {
1825
- const value = readStringNested(definition, section, propertyName);
1826
- return value === "mcp" || value === "chatgpt" || value === "claude" ? value : void 0;
1827
- }
1828
- function readHostNested(definition, section, propertyName) {
1829
- const value = readStringNested(definition, section, propertyName);
1830
- return value === "node" || value === "vercel" ? value : void 0;
1831
- }
1832
- function readStringNested(definition, section, propertyName) {
1833
- const object = readObjectProperty3(definition, section);
1834
- if (!object) {
1835
- return void 0;
1836
- }
1837
- return readStringProperty3(object, propertyName);
1838
- }
1839
1541
  function readBooleanNested(definition, section, propertyName) {
1840
1542
  const object = readObjectProperty3(definition, section);
1841
1543
  if (!object) {
@@ -1866,9 +1568,6 @@ function readNumberNested(definition, section, propertyName) {
1866
1568
  return initializer && Node5.isNumericLiteral(initializer) ? Number(initializer.getLiteralText()) : void 0;
1867
1569
  }
1868
1570
  function readObjectProperty3(definition, propertyName) {
1869
- if (!definition) {
1870
- return void 0;
1871
- }
1872
1571
  const property = definition.getProperty(propertyName);
1873
1572
  if (!property || !Node5.isPropertyAssignment(property)) {
1874
1573
  return void 0;
@@ -1876,79 +1575,38 @@ function readObjectProperty3(definition, propertyName) {
1876
1575
  const initializer = unwrapExpression(property.getInitializer());
1877
1576
  return initializer && Node5.isObjectLiteralExpression(initializer) ? initializer : void 0;
1878
1577
  }
1879
- function readStringProperty3(definition, propertyName) {
1880
- const property = definition.getProperty(propertyName);
1881
- if (!property || !Node5.isPropertyAssignment(property)) {
1882
- return void 0;
1883
- }
1884
- const initializer = unwrapExpression(property.getInitializer());
1885
- return initializer && Node5.isStringLiteral(initializer) ? initializer.getLiteralText() : void 0;
1886
- }
1887
- function readStringArrayProperty3(definition, propertyName) {
1888
- const property = definition.getProperty(propertyName);
1889
- if (!property || !Node5.isPropertyAssignment(property)) {
1890
- return void 0;
1891
- }
1892
- const initializer = unwrapExpression(property.getInitializer());
1893
- if (!initializer || !Node5.isArrayLiteralExpression(initializer)) {
1894
- return void 0;
1895
- }
1896
- const values = initializer.getElements().map((element) => {
1897
- const unwrapped = unwrapExpression(element);
1898
- return unwrapped && Node5.isStringLiteral(unwrapped) ? unwrapped.getLiteralText() : void 0;
1899
- });
1900
- return values.every((value) => value !== void 0) ? values : void 0;
1901
- }
1902
- function readStringRecordProperty(definition, propertyName) {
1903
- const object = readObjectProperty3(definition, propertyName);
1904
- if (!object) {
1905
- return void 0;
1906
- }
1907
- const record = {};
1908
- for (const property of object.getProperties()) {
1909
- if (!Node5.isPropertyAssignment(property)) {
1910
- return void 0;
1911
- }
1912
- const initializer = unwrapExpression(property.getInitializer());
1913
- if (!initializer || !Node5.isStringLiteral(initializer)) {
1914
- return void 0;
1915
- }
1916
- record[property.getName().replace(/^["']|["']$/g, "")] = initializer.getLiteralText();
1917
- }
1918
- return record;
1919
- }
1920
1578
  function hasProperty(definition, propertyName) {
1921
1579
  return Boolean(definition?.getProperty(propertyName));
1922
1580
  }
1923
1581
 
1924
1582
  // packages/compiler/src/diagnostics.ts
1925
- import { existsSync as existsSync4 } from "fs";
1583
+ import { existsSync as existsSync3 } from "fs";
1926
1584
  import { readFile as readFile2 } from "fs/promises";
1927
- import path7 from "path";
1585
+ import path6 from "path";
1928
1586
  async function collectProjectDiagnostics(rootDir, input) {
1929
1587
  const diagnostics = [];
1930
1588
  const tools = Array.isArray(input) ? input : input.tools;
1931
1589
  const resources = Array.isArray(input) ? [] : input.resources ?? [];
1932
1590
  const prompts = Array.isArray(input) ? [] : input.prompts ?? [];
1933
1591
  const config = Array.isArray(input) ? void 0 : input.config;
1934
- const hasAuthConfig = existsSync4(path7.join(rootDir, "auth.ts"));
1592
+ const hasAuthConfig = existsSync3(path6.join(rootDir, "auth.ts"));
1935
1593
  for (const entry of tools) {
1936
- const toolPath = path7.join(rootDir, entry.sourceFile);
1594
+ const toolPath = path6.join(rootDir, entry.sourceFile);
1937
1595
  const toolSource = await readFile2(toolPath, "utf8");
1938
- diagnostics.push(...diagnoseToolSource(entry, toolSource, hasAuthConfig));
1596
+ diagnostics.push(...diagnoseToolSource(rootDir, entry, toolSource, hasAuthConfig));
1939
1597
  if (entry.widget) {
1940
- const widgetPath = path7.join(rootDir, entry.widget.sourceFile);
1598
+ const widgetPath = path6.join(rootDir, entry.widget.sourceFile);
1941
1599
  const widgetSource = await readFile2(widgetPath, "utf8");
1942
1600
  diagnostics.push(...diagnoseWidgetSource(rootDir, entry, widgetSource));
1943
1601
  }
1944
1602
  }
1945
1603
  for (const entry of resources) {
1946
- const resourcePath = path7.join(rootDir, entry.sourceFile);
1604
+ const resourcePath = path6.join(rootDir, entry.sourceFile);
1947
1605
  const resourceSource = await readFile2(resourcePath, "utf8");
1948
1606
  diagnostics.push(...diagnoseResourceSource(entry, resourceSource));
1949
1607
  }
1950
1608
  for (const entry of prompts) {
1951
- const promptPath = path7.join(rootDir, entry.sourceFile);
1609
+ const promptPath = path6.join(rootDir, entry.sourceFile);
1952
1610
  const promptSource = await readFile2(promptPath, "utf8");
1953
1611
  diagnostics.push(...diagnosePromptSource(entry, promptSource));
1954
1612
  }
@@ -1963,7 +1621,7 @@ function formatDiagnostic(diagnostic) {
1963
1621
  hint: ${diagnostic.hint}` : "";
1964
1622
  return `${location} - ${diagnostic.severity} ${diagnostic.code}: ${diagnostic.message}${hint}`;
1965
1623
  }
1966
- function diagnoseToolSource(entry, source, hasAuthConfig) {
1624
+ function diagnoseToolSource(rootDir, entry, source, hasAuthConfig) {
1967
1625
  const diagnostics = [];
1968
1626
  const toolLocation = locate(source, "tool({");
1969
1627
  if (!entry.description.trim().startsWith("Use this when")) {
@@ -2180,21 +1838,21 @@ function isIgnored(source, code) {
2180
1838
 
2181
1839
  // packages/compiler/src/generated.ts
2182
1840
  import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
2183
- import path8 from "path";
1841
+ import path7 from "path";
2184
1842
  async function writeGeneratedTypes(rootDir, tools) {
2185
- const generatedDir = path8.join(rootDir, ".sidecar", "generated");
1843
+ const generatedDir = path7.join(rootDir, ".sidecar", "generated");
2186
1844
  await mkdir2(generatedDir, { recursive: true });
2187
1845
  const appCallableTools = tools.filter(isAppCallable);
2188
1846
  const methodNames = uniqueMethodNames(appCallableTools.map((entry) => toIdentifier(entry.id)));
2189
1847
  const imports = appCallableTools.map(
2190
- (entry, index) => `import type tool${index} from ${JSON.stringify(toImportSpecifier(generatedDir, path8.join(rootDir, entry.sourceFile), { extension: "js" }))};`
1848
+ (entry, index) => `import type tool${index} from ${JSON.stringify(toImportSpecifier(generatedDir, path7.join(rootDir, entry.sourceFile), { extension: "js" }))};`
2191
1849
  ).join("\n");
2192
1850
  const ids = appCallableTools.map((entry, index) => ` ${methodNames[index]}: ${JSON.stringify(entry.id)}`).join(",\n");
2193
1851
  const toolTypes = appCallableTools.map(
2194
- (_entry, index) => ` ${methodNames[index]}(params: ToolParams<typeof tool${index}>): Promise<ToolOutput<typeof tool${index}>>;`
1852
+ (entry, index) => ` ${methodNames[index]}(params: ToolParams<typeof tool${index}>): Promise<ToolOutput<typeof tool${index}>>;`
2195
1853
  ).join("\n");
2196
1854
  await writeFile2(
2197
- path8.join(generatedDir, "tools.ts"),
1855
+ path7.join(generatedDir, "tools.ts"),
2198
1856
  `/**
2199
1857
  * Generated Sidecar widget tool client.
2200
1858
  *
@@ -2244,13 +1902,13 @@ function uniqueMethodNames(names) {
2244
1902
 
2245
1903
  // packages/compiler/src/identity.ts
2246
1904
  import { readFile as readFile3 } from "fs/promises";
2247
- import path9 from "path";
1905
+ import path8 from "path";
2248
1906
  async function loadProjectIdentity(rootDir) {
2249
- const packageJson = await readOptionalJson(path9.join(rootDir, "package.json"));
1907
+ const packageJson = await readOptionalJson(path8.join(rootDir, "package.json"));
2250
1908
  const configText = await readOptionalText(
2251
- path9.join(rootDir, "sidecar.config.ts")
1909
+ path8.join(rootDir, "sidecar.config.ts")
2252
1910
  );
2253
- const name = readConfigString(configText, "name") ?? packageJson?.name ?? path9.basename(rootDir);
1911
+ const name = readConfigString(configText, "name") ?? packageJson?.name ?? path8.basename(rootDir);
2254
1912
  const version = readConfigString(configText, "version") ?? packageJson?.version ?? "0.0.0-dev";
2255
1913
  const description = readConfigString(configText, "description") ?? packageJson?.description ?? `${name} Sidecar app.`;
2256
1914
  return {
@@ -2284,32 +1942,32 @@ function readConfigString(configText, key) {
2284
1942
 
2285
1943
  // packages/compiler/src/plugins.ts
2286
1944
  import { mkdir as mkdir7, writeFile as writeFile7 } from "fs/promises";
2287
- import path15 from "path";
1945
+ import path14 from "path";
2288
1946
 
2289
1947
  // packages/compiler/src/plugin-components/agents.ts
2290
1948
  import { mkdir as mkdir3, readdir as readdir2, readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
2291
- import path10 from "path";
1949
+ import path9 from "path";
2292
1950
  async function emitClaudeAgents(rootDir, destination) {
2293
- const source = path10.join(rootDir, "agents");
1951
+ const source = path9.join(rootDir, "agents");
2294
1952
  if (!existsSyncSafe(source)) {
2295
1953
  return;
2296
1954
  }
2297
1955
  const entries = await readdir2(source, { withFileTypes: true });
2298
1956
  const agentDirs = entries.filter(
2299
- (entry) => entry.isDirectory() && existsSyncSafe(path10.join(source, entry.name, "agent.ts"))
1957
+ (entry) => entry.isDirectory() && existsSyncSafe(path9.join(source, entry.name, "agent.ts"))
2300
1958
  );
2301
1959
  if (!agentDirs.length) {
2302
1960
  return;
2303
1961
  }
2304
1962
  await mkdir3(destination, { recursive: true });
2305
1963
  for (const entry of agentDirs) {
2306
- const sourceText = await readFile4(path10.join(source, entry.name, "agent.ts"), "utf8");
1964
+ const sourceText = await readFile4(path9.join(source, entry.name, "agent.ts"), "utf8");
2307
1965
  const markdown = parseClaudeAgent(
2308
1966
  sourceText,
2309
1967
  entry.name
2310
1968
  );
2311
1969
  const agentName = readObjectString(sourceText, "name") ?? entry.name;
2312
- await writeFile3(path10.join(destination, `${safeFileStem(agentName)}.md`), markdown);
1970
+ await writeFile3(path9.join(destination, `${safeFileStem(agentName)}.md`), markdown);
2313
1971
  }
2314
1972
  }
2315
1973
  function parseClaudeAgent(source, fallbackName) {
@@ -2338,41 +1996,41 @@ ${prompt.trim()}
2338
1996
 
2339
1997
  // packages/compiler/src/plugin-components/commands.ts
2340
1998
  import { cp, lstat, mkdir as mkdir4, readdir as readdir3, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
2341
- import path11 from "path";
1999
+ import path10 from "path";
2342
2000
  async function copyCommands(rootDir, destination) {
2343
- const source = path11.join(rootDir, "commands");
2001
+ const source = path10.join(rootDir, "commands");
2344
2002
  if (!existsSyncSafe(source)) {
2345
2003
  return;
2346
2004
  }
2347
2005
  await mkdir4(destination, { recursive: true });
2348
2006
  const entries = await readdir3(source, { withFileTypes: true });
2349
2007
  for (const entry of entries) {
2350
- const sourcePath = path11.join(source, entry.name);
2008
+ const sourcePath = path10.join(source, entry.name);
2351
2009
  if (entry.isFile() && entry.name.endsWith(".md")) {
2352
2010
  if (await safeCommandCopyFilter(sourcePath)) {
2353
- await cp(sourcePath, path11.join(destination, safeFileStem(entry.name.replace(/\.md$/, "")) + ".md"));
2011
+ await cp(sourcePath, path10.join(destination, safeFileStem(entry.name.replace(/\.md$/, "")) + ".md"));
2354
2012
  }
2355
2013
  continue;
2356
2014
  }
2357
2015
  if (!entry.isDirectory()) {
2358
2016
  continue;
2359
2017
  }
2360
- const dynamicCommand = path11.join(sourcePath, "command.ts");
2018
+ const dynamicCommand = path10.join(sourcePath, "command.ts");
2361
2019
  if (existsSyncSafe(dynamicCommand)) {
2362
2020
  const sourceText = await readFile5(dynamicCommand, "utf8");
2363
2021
  const markdown = parseDynamicCommand(sourceText, entry.name);
2364
2022
  const commandName = readObjectString(sourceText, "name") ?? entry.name;
2365
- await writeFile4(path11.join(destination, `${safeFileStem(commandName)}.md`), markdown);
2023
+ await writeFile4(path10.join(destination, `${safeFileStem(commandName)}.md`), markdown);
2366
2024
  continue;
2367
2025
  }
2368
- await cp(sourcePath, path11.join(destination, entry.name), {
2026
+ await cp(sourcePath, path10.join(destination, entry.name), {
2369
2027
  recursive: true,
2370
2028
  filter: safeCommandCopyFilter
2371
2029
  });
2372
2030
  }
2373
2031
  }
2374
2032
  async function safeCommandCopyFilter(sourcePath) {
2375
- const basename = path11.basename(sourcePath);
2033
+ const basename = path10.basename(sourcePath);
2376
2034
  if (basename === ".env" || basename.startsWith(".env.") || basename === "node_modules" || basename === ".git") {
2377
2035
  return false;
2378
2036
  }
@@ -2401,32 +2059,32 @@ ${Object.entries(frontmatter).map(([key, value]) => `${key}: ${yamlScalar(value)
2401
2059
 
2402
2060
  // packages/compiler/src/plugin-components/hooks.ts
2403
2061
  import { mkdir as mkdir5, readdir as readdir4, readFile as readFile6, writeFile as writeFile5 } from "fs/promises";
2404
- import path12 from "path";
2062
+ import path11 from "path";
2405
2063
  import {
2406
2064
  Node as Node6,
2407
2065
  Project as Project2,
2408
2066
  SyntaxKind as SyntaxKind4
2409
2067
  } from "ts-morph";
2410
2068
  async function copyHooks(rootDir, destination) {
2411
- const source = path12.join(rootDir, "hooks");
2069
+ const source = path11.join(rootDir, "hooks");
2412
2070
  if (!existsSyncSafe(source)) {
2413
2071
  return;
2414
2072
  }
2415
2073
  const entries = await readdir4(source, { withFileTypes: true });
2416
2074
  const hookDirs = entries.filter(
2417
- (entry) => entry.isDirectory() && existsSyncSafe(path12.join(source, entry.name, "hook.ts"))
2075
+ (entry) => entry.isDirectory() && existsSyncSafe(path11.join(source, entry.name, "hook.ts"))
2418
2076
  );
2419
2077
  if (!hookDirs.length) {
2420
2078
  return;
2421
2079
  }
2422
2080
  const config = {};
2423
2081
  for (const entry of hookDirs) {
2424
- const filePath = path12.join(source, entry.name, "hook.ts");
2082
+ const filePath = path11.join(source, entry.name, "hook.ts");
2425
2083
  mergeHooks(config, parseHookFile(await readFile6(filePath, "utf8"), entry.name));
2426
2084
  }
2427
2085
  await mkdir5(destination, { recursive: true });
2428
2086
  await writeFile5(
2429
- path12.join(destination, "hooks.json"),
2087
+ path11.join(destination, "hooks.json"),
2430
2088
  `${JSON.stringify(config, null, 2)}
2431
2089
  `
2432
2090
  );
@@ -2453,7 +2111,7 @@ function parseHookFile(source, fallbackName) {
2453
2111
  throw new Error(`hooks/${fallbackName}/hook.ts must default-export hook({ ... }) or hooks({ ... }).`);
2454
2112
  }
2455
2113
  function parseHookDefinition(definition, fallbackName) {
2456
- const event = readStringProperty4(definition, "event");
2114
+ const event = readStringProperty3(definition, "event");
2457
2115
  if (!event) {
2458
2116
  throw new Error(`hooks/${fallbackName}/hook.ts must declare an event string.`);
2459
2117
  }
@@ -2463,7 +2121,7 @@ function parseHookDefinition(definition, fallbackName) {
2463
2121
  }
2464
2122
  return {
2465
2123
  event,
2466
- matcher: readStringProperty4(definition, "matcher"),
2124
+ matcher: readStringProperty3(definition, "matcher"),
2467
2125
  run: hooks
2468
2126
  };
2469
2127
  }
@@ -2483,7 +2141,7 @@ function parseHooksDefinition(definition, fallbackName) {
2483
2141
  throw new Error(`hooks/${fallbackName}/hook.ts event "${event}" entries must be objects.`);
2484
2142
  }
2485
2143
  return stripUndefined2({
2486
- matcher: readStringProperty4(entry, "matcher"),
2144
+ matcher: readStringProperty3(entry, "matcher"),
2487
2145
  hooks: readHookArray(entry, "run", fallbackName)
2488
2146
  });
2489
2147
  });
@@ -2506,7 +2164,7 @@ function parseHookHandlers(handlers, fallbackName) {
2506
2164
  }
2507
2165
  function parseHookHandler(handler, fallbackName) {
2508
2166
  if (Node6.isObjectLiteralExpression(handler)) {
2509
- const type = readStringProperty4(handler, "type");
2167
+ const type = readStringProperty3(handler, "type");
2510
2168
  if (type !== "command" && type !== "http") {
2511
2169
  throw new Error(`hooks/${fallbackName}/hook.ts hook handlers need type "command" or "http".`);
2512
2170
  }
@@ -2556,7 +2214,7 @@ function objectLiteralToRecord(object) {
2556
2214
  }
2557
2215
  return stripUndefined2(record);
2558
2216
  }
2559
- function readStringProperty4(object, propertyName) {
2217
+ function readStringProperty3(object, propertyName) {
2560
2218
  const property = object.getProperty(propertyName);
2561
2219
  if (!property || !Node6.isPropertyAssignment(property)) {
2562
2220
  return void 0;
@@ -2600,7 +2258,7 @@ function mergeHooks(target, source) {
2600
2258
 
2601
2259
  // packages/compiler/src/plugin-components/passthrough.ts
2602
2260
  import { cp as cp2, lstat as lstat2 } from "fs/promises";
2603
- import path13 from "path";
2261
+ import path12 from "path";
2604
2262
  async function copyClaudePassthroughDirectories(rootDir, pluginDir) {
2605
2263
  for (const directory of [
2606
2264
  "assets",
@@ -2609,18 +2267,18 @@ async function copyClaudePassthroughDirectories(rootDir, pluginDir) {
2609
2267
  "output-styles",
2610
2268
  "themes"
2611
2269
  ]) {
2612
- const source = path13.join(rootDir, directory);
2270
+ const source = path12.join(rootDir, directory);
2613
2271
  if (!existsSyncSafe(source)) {
2614
2272
  continue;
2615
2273
  }
2616
- await cp2(source, path13.join(pluginDir, directory), {
2274
+ await cp2(source, path12.join(pluginDir, directory), {
2617
2275
  recursive: true,
2618
2276
  filter: safePluginCopyFilter
2619
2277
  });
2620
2278
  }
2621
2279
  }
2622
2280
  async function safePluginCopyFilter(sourcePath) {
2623
- const basename = path13.basename(sourcePath);
2281
+ const basename = path12.basename(sourcePath);
2624
2282
  if (basename === "node_modules" || basename === ".git" || basename === ".env" || basename.startsWith(".env.")) {
2625
2283
  return false;
2626
2284
  }
@@ -2629,11 +2287,11 @@ async function safePluginCopyFilter(sourcePath) {
2629
2287
  }
2630
2288
 
2631
2289
  // packages/compiler/src/plugin-components/skills.ts
2632
- import { existsSync as existsSync5 } from "fs";
2290
+ import { existsSync as existsSync4 } from "fs";
2633
2291
  import { cp as cp3, lstat as lstat3, mkdir as mkdir6, readdir as readdir5, readFile as readFile7, writeFile as writeFile6 } from "fs/promises";
2634
- import path14 from "path";
2292
+ import path13 from "path";
2635
2293
  async function copySkills(rootDir, destination) {
2636
- const source = path14.join(rootDir, "skills");
2294
+ const source = path13.join(rootDir, "skills");
2637
2295
  if (!existsSyncSafe(source)) {
2638
2296
  return;
2639
2297
  }
@@ -2643,27 +2301,27 @@ async function copySkills(rootDir, destination) {
2643
2301
  if (!entry.isDirectory()) {
2644
2302
  continue;
2645
2303
  }
2646
- const sourceDir = path14.join(source, entry.name);
2647
- const destinationDir = path14.join(destination, entry.name);
2648
- const staticSkill = path14.join(sourceDir, "SKILL.md");
2649
- const dynamicSkill = path14.join(sourceDir, "skill.ts");
2304
+ const sourceDir = path13.join(source, entry.name);
2305
+ const destinationDir = path13.join(destination, entry.name);
2306
+ const staticSkill = path13.join(sourceDir, "SKILL.md");
2307
+ const dynamicSkill = path13.join(sourceDir, "skill.ts");
2650
2308
  await mkdir6(destinationDir, { recursive: true });
2651
- if (existsSync5(staticSkill)) {
2309
+ if (existsSync4(staticSkill)) {
2652
2310
  await cp3(sourceDir, destinationDir, {
2653
2311
  recursive: true,
2654
- filter: async (sourcePath) => !sourcePath.endsWith(`${path14.sep}skill.ts`) && await safeSkillCopyFilter(sourcePath)
2312
+ filter: async (sourcePath) => !sourcePath.endsWith(`${path13.sep}skill.ts`) && await safeSkillCopyFilter(sourcePath)
2655
2313
  });
2656
- } else if (existsSync5(dynamicSkill)) {
2314
+ } else if (existsSync4(dynamicSkill)) {
2657
2315
  const generated = parseDynamicSkill(
2658
2316
  await readFile7(dynamicSkill, "utf8"),
2659
2317
  entry.name
2660
2318
  );
2661
- await writeFile6(path14.join(destinationDir, "SKILL.md"), generated);
2319
+ await writeFile6(path13.join(destinationDir, "SKILL.md"), generated);
2662
2320
  }
2663
2321
  }
2664
2322
  }
2665
2323
  async function safeSkillCopyFilter(sourcePath) {
2666
- const basename = path14.basename(sourcePath);
2324
+ const basename = path13.basename(sourcePath);
2667
2325
  if (basename === ".env" || basename.startsWith(".env.") || basename === "node_modules" || basename === ".git") {
2668
2326
  return false;
2669
2327
  }
@@ -2689,25 +2347,25 @@ async function buildPluginPackages(rootDir, outRoot, manifest) {
2689
2347
  await buildClaudePlugin(rootDir, outRoot, identity, manifest);
2690
2348
  }
2691
2349
  async function buildClaudePlugin(rootDir, outRoot, identity, manifest) {
2692
- const pluginDir = path15.join(outRoot, "claude-plugin");
2693
- await mkdir7(path15.join(pluginDir, ".claude-plugin"), { recursive: true });
2694
- await copySkills(rootDir, path15.join(pluginDir, "skills"));
2695
- await copyCommands(rootDir, path15.join(pluginDir, "commands"));
2696
- await copyHooks(rootDir, path15.join(pluginDir, "hooks"));
2697
- await emitClaudeAgents(rootDir, path15.join(pluginDir, "agents"));
2350
+ const pluginDir = path14.join(outRoot, "claude-plugin");
2351
+ await mkdir7(path14.join(pluginDir, ".claude-plugin"), { recursive: true });
2352
+ await copySkills(rootDir, path14.join(pluginDir, "skills"));
2353
+ await copyCommands(rootDir, path14.join(pluginDir, "commands"));
2354
+ await copyHooks(rootDir, path14.join(pluginDir, "hooks"));
2355
+ await emitClaudeAgents(rootDir, path14.join(pluginDir, "agents"));
2698
2356
  await copyClaudePassthroughDirectories(rootDir, pluginDir);
2699
- await writeJson(path15.join(pluginDir, ".claude-plugin", "plugin.json"), {
2357
+ await writeJson(path14.join(pluginDir, ".claude-plugin", "plugin.json"), {
2700
2358
  name: identity.slug,
2701
2359
  version: identity.version,
2702
2360
  description: identity.description,
2703
2361
  displayName: identity.name,
2704
2362
  installationPreference: "available"
2705
2363
  });
2706
- await writeJson(path15.join(pluginDir, "version.json"), {
2364
+ await writeJson(path14.join(pluginDir, "version.json"), {
2707
2365
  version: identity.version,
2708
2366
  generatedBy: "sidecar"
2709
2367
  });
2710
- await writeJson(path15.join(pluginDir, ".mcp.json"), {
2368
+ await writeJson(path14.join(pluginDir, ".mcp.json"), {
2711
2369
  mcpServers: {
2712
2370
  [identity.slug]: {
2713
2371
  type: "http",
@@ -2715,7 +2373,7 @@ async function buildClaudePlugin(rootDir, outRoot, identity, manifest) {
2715
2373
  }
2716
2374
  }
2717
2375
  });
2718
- await writeJson(path15.join(pluginDir, "settings.json"), {
2376
+ await writeJson(path14.join(pluginDir, "settings.json"), {
2719
2377
  sidecar: {
2720
2378
  tools: manifest.tools.map((entry) => entry.id),
2721
2379
  resources: manifest.resources.map((entry) => entry.uri),
@@ -2723,7 +2381,7 @@ async function buildClaudePlugin(rootDir, outRoot, identity, manifest) {
2723
2381
  }
2724
2382
  });
2725
2383
  await writeFile7(
2726
- path15.join(pluginDir, "README.md"),
2384
+ path14.join(pluginDir, "README.md"),
2727
2385
  `# ${identity.name} Claude Plugin
2728
2386
 
2729
2387
  This package was generated by Sidecar.
@@ -2737,7 +2395,7 @@ Claude/Cowork plugin-specific components such as skills, slash commands, agents,
2737
2395
  );
2738
2396
  }
2739
2397
  async function writeJson(filePath, value) {
2740
- await mkdir7(path15.dirname(filePath), { recursive: true });
2398
+ await mkdir7(path14.dirname(filePath), { recursive: true });
2741
2399
  await writeFile7(
2742
2400
  filePath,
2743
2401
  `${JSON.stringify(stripUndefined2(value), null, 2)}
@@ -2747,13 +2405,13 @@ async function writeJson(filePath, value) {
2747
2405
 
2748
2406
  // packages/compiler/src/prompts.ts
2749
2407
  import { readdir as readdir6 } from "fs/promises";
2750
- import path16 from "path";
2408
+ import path15 from "path";
2751
2409
  import {
2752
2410
  Node as Node7,
2753
2411
  SyntaxKind as SyntaxKind5
2754
2412
  } from "ts-morph";
2755
2413
  async function analyzeProjectPrompts(rootDir) {
2756
- const promptFiles = await findPromptFiles(path16.join(rootDir, "prompts"));
2414
+ const promptFiles = await findPromptFiles(path15.join(rootDir, "prompts"));
2757
2415
  if (promptFiles.length === 0) {
2758
2416
  return [];
2759
2417
  }
@@ -2765,7 +2423,7 @@ async function analyzeProjectPrompts(rootDir) {
2765
2423
  function analyzePromptFile(sourceFile, rootDir) {
2766
2424
  const definition = findPromptDefinition(sourceFile);
2767
2425
  const absoluteFile = sourceFile.getFilePath();
2768
- const directory = path16.basename(path16.dirname(absoluteFile));
2426
+ const directory = path15.basename(path15.dirname(absoluteFile));
2769
2427
  const name = getOptionalStringProperty2(definition, "name") ?? safePathSegment(directory);
2770
2428
  const title = getRequiredStringProperty2(definition, "title", sourceFile);
2771
2429
  const description = getOptionalStringProperty2(definition, "description");
@@ -2781,7 +2439,7 @@ function analyzePromptFile(sourceFile, rootDir) {
2781
2439
  throw new CompilerError(sourceFile, "prompt({ ... }) must include a run method.");
2782
2440
  }
2783
2441
  return {
2784
- sourceFile: path16.relative(rootDir, absoluteFile),
2442
+ sourceFile: path15.relative(rootDir, absoluteFile),
2785
2443
  directory,
2786
2444
  name,
2787
2445
  title,
@@ -2800,7 +2458,7 @@ async function findPromptFiles(promptsDir) {
2800
2458
  if (!entry.isDirectory()) {
2801
2459
  continue;
2802
2460
  }
2803
- const filePath = path16.join(promptsDir, entry.name, "prompt.ts");
2461
+ const filePath = path15.join(promptsDir, entry.name, "prompt.ts");
2804
2462
  if (existsSyncSafe(filePath)) {
2805
2463
  files.push(filePath);
2806
2464
  }
@@ -2922,7 +2580,7 @@ function readIcons(definition) {
2922
2580
  return [{
2923
2581
  src,
2924
2582
  mimeType: getOptionalStringProperty2(object, "mimeType"),
2925
- sizes: readStringArrayProperty4(object, "sizes")
2583
+ sizes: readStringArrayProperty3(object, "sizes")
2926
2584
  }];
2927
2585
  });
2928
2586
  return icons.length ? icons : void 0;
@@ -2935,7 +2593,7 @@ function readObjectProperty4(definition, propertyName) {
2935
2593
  const initializer = unwrapExpression(property.getInitializer());
2936
2594
  return initializer && Node7.isObjectLiteralExpression(initializer) ? initializer : void 0;
2937
2595
  }
2938
- function readStringArrayProperty4(definition, propertyName) {
2596
+ function readStringArrayProperty3(definition, propertyName) {
2939
2597
  const property = definition.getProperty(propertyName);
2940
2598
  if (!property || !Node7.isPropertyAssignment(property)) {
2941
2599
  return void 0;
@@ -2949,13 +2607,13 @@ function readStringArrayProperty4(definition, propertyName) {
2949
2607
 
2950
2608
  // packages/compiler/src/resources.ts
2951
2609
  import { readdir as readdir7 } from "fs/promises";
2952
- import path17 from "path";
2610
+ import path16 from "path";
2953
2611
  import {
2954
2612
  Node as Node8,
2955
2613
  SyntaxKind as SyntaxKind6
2956
2614
  } from "ts-morph";
2957
2615
  async function analyzeProjectResources(rootDir) {
2958
- const resourceFiles = await findResourceFiles(path17.join(rootDir, "resources"));
2616
+ const resourceFiles = await findResourceFiles(path16.join(rootDir, "resources"));
2959
2617
  if (resourceFiles.length === 0) {
2960
2618
  return [];
2961
2619
  }
@@ -2967,7 +2625,7 @@ async function analyzeProjectResources(rootDir) {
2967
2625
  function analyzeResourceFile(sourceFile, rootDir) {
2968
2626
  const definition = findResourceDefinition(sourceFile);
2969
2627
  const absoluteFile = sourceFile.getFilePath();
2970
- const directory = path17.basename(path17.dirname(absoluteFile));
2628
+ const directory = path16.basename(path16.dirname(absoluteFile));
2971
2629
  const defaultUri = `sidecar://resources/${safePathSegment(directory)}`;
2972
2630
  const name = getRequiredStringProperty3(definition, "name", sourceFile);
2973
2631
  const uri = getOptionalStringProperty3(definition, "uri") ?? defaultUri;
@@ -2985,7 +2643,7 @@ function analyzeResourceFile(sourceFile, rootDir) {
2985
2643
  throw new CompilerError(sourceFile, "resource({ ... }) must include a read method.");
2986
2644
  }
2987
2645
  return {
2988
- sourceFile: path17.relative(rootDir, absoluteFile),
2646
+ sourceFile: path16.relative(rootDir, absoluteFile),
2989
2647
  directory,
2990
2648
  uri,
2991
2649
  name,
@@ -3008,7 +2666,7 @@ async function findResourceFiles(resourcesDir) {
3008
2666
  if (!entry.isDirectory()) {
3009
2667
  continue;
3010
2668
  }
3011
- const filePath = path17.join(resourcesDir, entry.name, "resource.ts");
2669
+ const filePath = path16.join(resourcesDir, entry.name, "resource.ts");
3012
2670
  if (existsSyncSafe(filePath)) {
3013
2671
  files.push(filePath);
3014
2672
  }
@@ -3087,7 +2745,7 @@ function readAnnotations2(definition) {
3087
2745
  return void 0;
3088
2746
  }
3089
2747
  const annotations = {};
3090
- const audience = readStringArrayProperty5(initializer, "audience")?.filter((value) => value === "user" || value === "assistant");
2748
+ const audience = readStringArrayProperty4(initializer, "audience")?.filter((value) => value === "user" || value === "assistant");
3091
2749
  const priority = getOptionalNumberProperty(initializer, "priority");
3092
2750
  const lastModified = getOptionalStringProperty3(initializer, "lastModified");
3093
2751
  if (audience?.length) annotations.audience = audience;
@@ -3116,7 +2774,7 @@ function readIcons2(definition) {
3116
2774
  return [{
3117
2775
  src,
3118
2776
  mimeType: getOptionalStringProperty3(object, "mimeType"),
3119
- sizes: readStringArrayProperty5(object, "sizes")
2777
+ sizes: readStringArrayProperty4(object, "sizes")
3120
2778
  }];
3121
2779
  });
3122
2780
  return icons.length ? icons : void 0;
@@ -3129,7 +2787,7 @@ function readObjectProperty5(definition, propertyName) {
3129
2787
  const initializer = unwrapExpression(property.getInitializer());
3130
2788
  return initializer && Node8.isObjectLiteralExpression(initializer) ? initializer : void 0;
3131
2789
  }
3132
- function readStringArrayProperty5(definition, propertyName) {
2790
+ function readStringArrayProperty4(definition, propertyName) {
3133
2791
  const property = definition.getProperty(propertyName);
3134
2792
  if (!property || !Node8.isPropertyAssignment(property)) {
3135
2793
  return void 0;
@@ -3142,21 +2800,19 @@ function readStringArrayProperty5(definition, propertyName) {
3142
2800
  }
3143
2801
 
3144
2802
  // packages/compiler/src/server-output.ts
3145
- import { existsSync as existsSync6 } from "fs";
2803
+ import { existsSync as existsSync5 } from "fs";
3146
2804
  import { mkdir as mkdir8, rm, writeFile as writeFile8 } from "fs/promises";
3147
- import path18 from "path";
2805
+ import path17 from "path";
3148
2806
  import { build as esbuild2 } from "esbuild";
3149
2807
  var SERVER_ENTRYPOINT = "server/index.js";
3150
- var VERCEL_FUNCTION_DIR = "functions/api/sidecar.func";
3151
- var VERCEL_ENTRYPOINT = `${VERCEL_FUNCTION_DIR}/index.js`;
3152
- var VERCEL_HANDLER_FILE = "index.js";
3153
- async function buildServerOutput(rootDir, outDir, manifest, identity, host = "node", options = {}) {
3154
- const cacheDir = path18.join(rootDir, ".sidecar", "cache", "server");
2808
+ var VERCEL_ENTRYPOINT = "api/sidecar.js";
2809
+ async function buildServerOutput(rootDir, outDir, manifest, identity, host = "node") {
2810
+ const cacheDir = path17.join(rootDir, ".sidecar", "cache", "server");
3155
2811
  await mkdir8(cacheDir, { recursive: true });
3156
- const entryFile = path18.join(cacheDir, "index.ts");
2812
+ const entryFile = path17.join(cacheDir, "index.ts");
3157
2813
  await writeFile8(entryFile, renderServerEntry(rootDir, entryFile, manifest, identity));
3158
- const serverFile = path18.join(outDir, SERVER_ENTRYPOINT);
3159
- await mkdir8(path18.dirname(serverFile), { recursive: true });
2814
+ const serverFile = path17.join(outDir, SERVER_ENTRYPOINT);
2815
+ await mkdir8(path17.dirname(serverFile), { recursive: true });
3160
2816
  await esbuild2({
3161
2817
  absWorkingDir: rootDir,
3162
2818
  alias: sidecarBundleAliases(rootDir),
@@ -3170,30 +2826,26 @@ const require = __sidecarCreateRequire(import.meta.url);`
3170
2826
  legalComments: "none",
3171
2827
  minify: false,
3172
2828
  nodePaths: [
3173
- path18.join(rootDir, "node_modules"),
3174
- path18.join(process.cwd(), "node_modules")
2829
+ path17.join(rootDir, "node_modules"),
2830
+ path17.join(process.cwd(), "node_modules")
3175
2831
  ],
3176
2832
  outfile: serverFile,
3177
2833
  platform: "node",
3178
2834
  sourcemap: false,
3179
2835
  target: "node20"
3180
2836
  });
3181
- await writeFile8(path18.join(outDir, "package.json"), renderServerPackage(identity));
2837
+ await writeFile8(path17.join(outDir, "package.json"), renderServerPackage(identity));
3182
2838
  if (host === "vercel") {
3183
- const vercelOutputDir = options.vercelOutputDir ?? outDir;
3184
- await rm(path18.join(vercelOutputDir, "api"), { recursive: true, force: true });
3185
- await rm(path18.join(vercelOutputDir, "vercel.json"), { force: true });
3186
- await writeFile8(path18.join(outDir, VERCEL_HANDLER_FILE), renderVercelEntrypoint());
3187
- await writeFile8(path18.join(outDir, ".vc-config.json"), renderVercelFunctionConfig());
3188
- await mkdir8(vercelOutputDir, { recursive: true });
3189
- await writeFile8(path18.join(vercelOutputDir, "config.json"), renderVercelOutputConfig());
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());
3190
2842
  } else {
3191
- await rm(path18.join(outDir, "api"), { recursive: true, force: true });
3192
- await rm(path18.join(outDir, "vercel.json"), { force: true });
2843
+ await rm(path17.join(outDir, "api"), { recursive: true, force: true });
2844
+ await rm(path17.join(outDir, "vercel.json"), { force: true });
3193
2845
  }
3194
2846
  }
3195
2847
  function renderServerEntry(rootDir, entryFile, manifest, identity) {
3196
- const entryDir = path18.dirname(entryFile);
2848
+ const entryDir = path17.dirname(entryFile);
3197
2849
  const tools = manifest.tools;
3198
2850
  const resources = manifest.resources;
3199
2851
  const prompts = manifest.prompts;
@@ -3206,17 +2858,17 @@ function renderServerEntry(rootDir, entryFile, manifest, identity) {
3206
2858
  `import { isSidecarPrompt, isSidecarResource, isSidecarTool } from "@sidecar-ai/core";`,
3207
2859
  `import { isSidecarProxy } from "@sidecar-ai/server/proxy";`,
3208
2860
  ...tools.map(
3209
- (entry, index) => `import tool${index} from ${JSON.stringify(toImportSpecifier(entryDir, path18.join(rootDir, entry.sourceFile)))};`
2861
+ (entry, index) => `import tool${index} from ${JSON.stringify(toImportSpecifier(entryDir, path17.join(rootDir, entry.sourceFile)))};`
3210
2862
  ),
3211
2863
  ...resources.map(
3212
- (entry, index) => `import resource${index} from ${JSON.stringify(toImportSpecifier(entryDir, path18.join(rootDir, entry.sourceFile)))};`
2864
+ (entry, index) => `import resource${index} from ${JSON.stringify(toImportSpecifier(entryDir, path17.join(rootDir, entry.sourceFile)))};`
3213
2865
  ),
3214
2866
  ...prompts.map(
3215
- (entry, index) => `import prompt${index} from ${JSON.stringify(toImportSpecifier(entryDir, path18.join(rootDir, entry.sourceFile)))};`
2867
+ (entry, index) => `import prompt${index} from ${JSON.stringify(toImportSpecifier(entryDir, path17.join(rootDir, entry.sourceFile)))};`
3216
2868
  ),
3217
- existsSync6(path18.join(rootDir, "auth.ts")) ? `import authExport from ${JSON.stringify(toImportSpecifier(entryDir, path18.join(rootDir, "auth.ts")))};` : `const authExport = undefined;`,
3218
- existsSync6(path18.join(rootDir, "proxy.ts")) ? `import proxyExport from ${JSON.stringify(toImportSpecifier(entryDir, path18.join(rootDir, "proxy.ts")))};` : `const proxyExport = undefined;`,
3219
- existsSync6(path18.join(rootDir, "sidecar.config.ts")) ? `import configExport from ${JSON.stringify(toImportSpecifier(entryDir, path18.join(rootDir, "sidecar.config.ts")))};` : `const configExport = undefined;`
2869
+ existsSync5(path17.join(rootDir, "auth.ts")) ? `import authExport from ${JSON.stringify(toImportSpecifier(entryDir, path17.join(rootDir, "auth.ts")))};` : `const authExport = undefined;`,
2870
+ existsSync5(path17.join(rootDir, "proxy.ts")) ? `import proxyExport from ${JSON.stringify(toImportSpecifier(entryDir, path17.join(rootDir, "proxy.ts")))};` : `const proxyExport = undefined;`,
2871
+ existsSync5(path17.join(rootDir, "sidecar.config.ts")) ? `import configExport from ${JSON.stringify(toImportSpecifier(entryDir, path17.join(rootDir, "sidecar.config.ts")))};` : `const configExport = undefined;`
3220
2872
  ].join("\n");
3221
2873
  return `${imports}
3222
2874
 
@@ -3327,7 +2979,7 @@ function unwrapRuntimeDefault(value) {
3327
2979
  value &&
3328
2980
  typeof value === "object" &&
3329
2981
  "default" in value &&
3330
- Object.keys(value).every((key) => key === "default" || key === "__esModule")
2982
+ Object.keys(value).length === 1
3331
2983
  ) {
3332
2984
  return unwrapRuntimeDefault(value.default);
3333
2985
  }
@@ -3387,29 +3039,23 @@ function renderServerPackage(identity) {
3387
3039
  `;
3388
3040
  }
3389
3041
  function renderVercelEntrypoint() {
3390
- return `export { default } from "./server/index.js";
3391
- `;
3392
- }
3393
- function renderVercelFunctionConfig() {
3394
- return `${JSON.stringify({
3395
- runtime: "nodejs22.x",
3396
- handler: VERCEL_HANDLER_FILE,
3397
- launcherType: "Nodejs",
3398
- shouldAddHelpers: true,
3399
- supportsResponseStreaming: true,
3400
- maxDuration: 300
3401
- }, null, 2)}
3042
+ return `export { default } from "../server/index.js";
3402
3043
  `;
3403
3044
  }
3404
- function renderVercelOutputConfig() {
3045
+ function renderVercelConfig() {
3405
3046
  return `${JSON.stringify({
3406
- version: 3,
3407
- routes: [
3047
+ rewrites: [
3408
3048
  {
3409
- src: "/(.*)",
3410
- dest: "/api/sidecar"
3049
+ source: "/(.*)",
3050
+ destination: "/api/sidecar"
3051
+ }
3052
+ ],
3053
+ functions: {
3054
+ "api/sidecar.js": {
3055
+ includeFiles: "public/**",
3056
+ maxDuration: 300
3411
3057
  }
3412
- ]
3058
+ }
3413
3059
  }, null, 2)}
3414
3060
  `;
3415
3061
  }
@@ -3419,35 +3065,35 @@ function sidecarBundleAliases(rootDir) {
3419
3065
  return void 0;
3420
3066
  }
3421
3067
  return {
3422
- "sidecar-ai": path18.join(repoRoot, "packages", "sidecar-ai", "src", "index.ts"),
3423
- "@sidecar-ai/auth": path18.join(repoRoot, "packages", "auth", "src", "index.ts"),
3424
- "@sidecar-ai/core": path18.join(repoRoot, "packages", "core", "src", "index.ts"),
3425
- "@sidecar-ai/server": path18.join(repoRoot, "packages", "server", "src", "index.ts"),
3426
- "@sidecar-ai/server/proxy": path18.join(repoRoot, "packages", "server", "src", "proxy.ts"),
3427
- "@sidecar-ai/client": path18.join(repoRoot, "packages", "client", "src", "index.ts"),
3428
- "@sidecar-ai/react": path18.join(repoRoot, "packages", "react", "src", "index.ts"),
3429
- "@sidecar-ai/native": path18.join(repoRoot, "packages", "native", "src", "index.ts"),
3430
- "@sidecar-ai/native/components": path18.join(repoRoot, "packages", "native", "src", "components", "index.tsx"),
3431
- "@sidecar-ai/openai": path18.join(repoRoot, "packages", "openai", "src", "index.ts"),
3432
- "@sidecar-ai/openai/components": path18.join(repoRoot, "packages", "openai", "src", "components.tsx"),
3433
- "@sidecar-ai/openai/official": path18.join(repoRoot, "packages", "openai", "src", "official.ts"),
3434
- "@sidecar-ai/anthropic": path18.join(repoRoot, "packages", "anthropic", "src", "index.ts"),
3435
- "@sidecar-ai/anthropic/agent": path18.join(repoRoot, "packages", "anthropic", "src", "agent.ts"),
3436
- "@sidecar-ai/anthropic/command": path18.join(repoRoot, "packages", "anthropic", "src", "command.ts"),
3437
- "@sidecar-ai/anthropic/components": path18.join(repoRoot, "packages", "anthropic", "src", "components.tsx"),
3438
- "@sidecar-ai/anthropic/hooks": path18.join(repoRoot, "packages", "anthropic", "src", "hooks.ts"),
3439
- "@sidecar-ai/anthropic/mcp": path18.join(repoRoot, "packages", "anthropic", "src", "mcp.ts"),
3440
- "@sidecar-ai/anthropic/plugin": path18.join(repoRoot, "packages", "anthropic", "src", "plugin.ts"),
3441
- "@sidecar-ai/anthropic/skill": path18.join(repoRoot, "packages", "anthropic", "src", "skill.ts")
3068
+ "sidecar-ai": path17.join(repoRoot, "packages", "sidecar-ai", "src", "index.ts"),
3069
+ "@sidecar-ai/auth": path17.join(repoRoot, "packages", "auth", "src", "index.ts"),
3070
+ "@sidecar-ai/core": path17.join(repoRoot, "packages", "core", "src", "index.ts"),
3071
+ "@sidecar-ai/server": path17.join(repoRoot, "packages", "server", "src", "index.ts"),
3072
+ "@sidecar-ai/server/proxy": path17.join(repoRoot, "packages", "server", "src", "proxy.ts"),
3073
+ "@sidecar-ai/client": path17.join(repoRoot, "packages", "client", "src", "index.ts"),
3074
+ "@sidecar-ai/react": path17.join(repoRoot, "packages", "react", "src", "index.ts"),
3075
+ "@sidecar-ai/native": path17.join(repoRoot, "packages", "native", "src", "index.ts"),
3076
+ "@sidecar-ai/native/components": path17.join(repoRoot, "packages", "native", "src", "components", "index.tsx"),
3077
+ "@sidecar-ai/openai": path17.join(repoRoot, "packages", "openai", "src", "index.ts"),
3078
+ "@sidecar-ai/openai/components": path17.join(repoRoot, "packages", "openai", "src", "components.tsx"),
3079
+ "@sidecar-ai/openai/official": path17.join(repoRoot, "packages", "openai", "src", "official.ts"),
3080
+ "@sidecar-ai/anthropic": path17.join(repoRoot, "packages", "anthropic", "src", "index.ts"),
3081
+ "@sidecar-ai/anthropic/agent": path17.join(repoRoot, "packages", "anthropic", "src", "agent.ts"),
3082
+ "@sidecar-ai/anthropic/command": path17.join(repoRoot, "packages", "anthropic", "src", "command.ts"),
3083
+ "@sidecar-ai/anthropic/components": path17.join(repoRoot, "packages", "anthropic", "src", "components.tsx"),
3084
+ "@sidecar-ai/anthropic/hooks": path17.join(repoRoot, "packages", "anthropic", "src", "hooks.ts"),
3085
+ "@sidecar-ai/anthropic/mcp": path17.join(repoRoot, "packages", "anthropic", "src", "mcp.ts"),
3086
+ "@sidecar-ai/anthropic/plugin": path17.join(repoRoot, "packages", "anthropic", "src", "plugin.ts"),
3087
+ "@sidecar-ai/anthropic/skill": path17.join(repoRoot, "packages", "anthropic", "src", "skill.ts")
3442
3088
  };
3443
3089
  }
3444
3090
  function findSidecarRepoRoot2(startDir) {
3445
- let current = path18.resolve(startDir);
3091
+ let current = path17.resolve(startDir);
3446
3092
  while (true) {
3447
- if (existsSync6(path18.join(current, "packages", "core", "src", "index.ts"))) {
3093
+ if (existsSync5(path17.join(current, "packages", "core", "src", "index.ts"))) {
3448
3094
  return current;
3449
3095
  }
3450
- const parent = path18.dirname(current);
3096
+ const parent = path17.dirname(current);
3451
3097
  if (parent === current) {
3452
3098
  return void 0;
3453
3099
  }
@@ -3457,11 +3103,10 @@ function findSidecarRepoRoot2(startDir) {
3457
3103
 
3458
3104
  // packages/compiler/src/build.ts
3459
3105
  async function buildProject(options) {
3460
- const rootDir = path19.resolve(options.rootDir);
3106
+ const rootDir = path18.resolve(options.rootDir);
3107
+ const target = options.target ?? "mcp";
3108
+ const host = options.host ?? "node";
3461
3109
  const config = analyzeProjectConfig(rootDir);
3462
- const target = options.target ?? config.build.target ?? "mcp";
3463
- const host = options.host ?? config.build.host ?? "node";
3464
- const plugins = options.plugins ?? config.build.plugins ?? false;
3465
3110
  const tools = await analyzeProjectTools(rootDir, { target });
3466
3111
  const resources = await analyzeProjectResources(rootDir);
3467
3112
  const resourceTemplates = [];
@@ -3477,9 +3122,8 @@ async function buildProject(options) {
3477
3122
  if (errors.length) {
3478
3123
  throw new Error(errors.map(formatDiagnostic).join("\n"));
3479
3124
  }
3480
- const outDir = resolveInsideRoot(rootDir, options.outDir ?? config.build.outDir ?? defaultBuildOutDir(host, target));
3481
- const runtimeOutDir = resolveRuntimeOutputDir(outDir, host);
3482
- await buildWidgets(rootDir, runtimeOutDir, tools, config.build.widgets);
3125
+ const outDir = resolveInsideRoot(rootDir, options.outDir ?? "out/mcp");
3126
+ await buildWidgets(rootDir, outDir, tools);
3483
3127
  const manifest = {
3484
3128
  version: 1,
3485
3129
  target,
@@ -3493,47 +3137,24 @@ async function buildProject(options) {
3493
3137
  prompts,
3494
3138
  diagnostics
3495
3139
  };
3496
- await mkdir9(runtimeOutDir, { recursive: true });
3140
+ await mkdir9(outDir, { recursive: true });
3497
3141
  await writeFile9(
3498
- path19.join(runtimeOutDir, "manifest.sidecar.json"),
3142
+ path18.join(outDir, "manifest.sidecar.json"),
3499
3143
  `${JSON.stringify(manifest, null, 2)}
3500
3144
  `
3501
3145
  );
3502
- await writeFile9(path19.join(runtimeOutDir, "README.md"), renderMcpReadme(manifest));
3146
+ await writeFile9(path18.join(outDir, "README.md"), renderMcpReadme(manifest));
3503
3147
  await writeGeneratedTypes(rootDir, tools);
3504
- await buildServerOutput(rootDir, runtimeOutDir, manifest, identity, host, {
3505
- vercelOutputDir: outDir
3506
- });
3507
- if (plugins) {
3508
- await buildPluginPackages(rootDir, resolvePluginOutputBase(rootDir, outDir, host), manifest);
3148
+ await buildServerOutput(rootDir, outDir, manifest, identity, host);
3149
+ if (options.plugins) {
3150
+ await buildPluginPackages(rootDir, path18.dirname(outDir), manifest);
3509
3151
  }
3510
3152
  return manifest;
3511
3153
  }
3512
- function defaultBuildOutDir(host, target) {
3513
- if (host === "vercel") {
3514
- return ".vercel/output";
3515
- }
3516
- return `out/${target}`;
3517
- }
3518
- function resolveRuntimeOutputDir(outDir, host) {
3519
- if (host === "vercel") {
3520
- return path19.join(outDir, VERCEL_FUNCTION_DIR);
3521
- }
3522
- return outDir;
3523
- }
3524
- function resolvePluginOutputBase(rootDir, outDir, host) {
3525
- if (host === "vercel" && isVercelBuildOutputDir(outDir)) {
3526
- return path19.join(rootDir, "out");
3527
- }
3528
- return path19.dirname(outDir);
3529
- }
3530
- function isVercelBuildOutputDir(outDir) {
3531
- return path19.basename(outDir) === "output" && path19.basename(path19.dirname(outDir)) === ".vercel";
3532
- }
3533
3154
  function resolveInsideRoot(rootDir, output) {
3534
- const resolved = path19.resolve(rootDir, output);
3535
- const relative = path19.relative(rootDir, resolved);
3536
- if (relative.startsWith("..") || path19.isAbsolute(relative)) {
3155
+ const resolved = path18.resolve(rootDir, output);
3156
+ const relative = path18.relative(rootDir, resolved);
3157
+ if (relative.startsWith("..") || path18.isAbsolute(relative)) {
3537
3158
  throw new Error(`Build output must stay inside the project root: ${output}`);
3538
3159
  }
3539
3160
  return resolved;
@@ -3586,7 +3207,7 @@ Set \`PORT\` or \`SIDECAR_PORT\` to choose the listen port. Hosted/authenticated
3586
3207
  function renderVercelReadmeSection() {
3587
3208
  return `## Deploy To Vercel
3588
3209
 
3589
- 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.
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.
3590
3211
  `;
3591
3212
  }
3592
3213
  export {