@apollo/client-ai-apps 0.5.4 → 0.6.0

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/config/defineConfig.d.ts +1 -0
  3. package/dist/config/defineConfig.d.ts.map +1 -1
  4. package/dist/config/schema.d.ts +1 -0
  5. package/dist/config/schema.d.ts.map +1 -1
  6. package/dist/config/schema.js +1 -0
  7. package/dist/config/schema.js.map +1 -1
  8. package/dist/mcp/core/McpAppManager.d.ts +2 -1
  9. package/dist/mcp/core/McpAppManager.d.ts.map +1 -1
  10. package/dist/mcp/core/McpAppManager.js +11 -1
  11. package/dist/mcp/core/McpAppManager.js.map +1 -1
  12. package/dist/mcp/react/hooks/useHostContext.d.ts +2 -0
  13. package/dist/mcp/react/hooks/useHostContext.d.ts.map +1 -0
  14. package/dist/mcp/react/hooks/useHostContext.js +7 -0
  15. package/dist/mcp/react/hooks/useHostContext.js.map +1 -0
  16. package/dist/mcp/react/index.d.ts +1 -0
  17. package/dist/mcp/react/index.d.ts.map +1 -1
  18. package/dist/mcp/react/index.js +1 -0
  19. package/dist/mcp/react/index.js.map +1 -1
  20. package/dist/openai/core/McpAppManager.d.ts +2 -1
  21. package/dist/openai/core/McpAppManager.d.ts.map +1 -1
  22. package/dist/openai/core/McpAppManager.js +11 -1
  23. package/dist/openai/core/McpAppManager.js.map +1 -1
  24. package/dist/openai/react/hooks/useHostContext.d.ts +2 -0
  25. package/dist/openai/react/hooks/useHostContext.d.ts.map +1 -0
  26. package/dist/openai/react/hooks/useHostContext.js +7 -0
  27. package/dist/openai/react/hooks/useHostContext.js.map +1 -0
  28. package/dist/openai/react/index.d.ts +1 -0
  29. package/dist/openai/react/index.d.ts.map +1 -1
  30. package/dist/openai/react/index.js +1 -0
  31. package/dist/openai/react/index.js.map +1 -1
  32. package/dist/react/index.d.ts +1 -0
  33. package/dist/react/index.d.ts.map +1 -1
  34. package/dist/react/index.js +1 -0
  35. package/dist/react/index.js.map +1 -1
  36. package/dist/react/index.mcp.d.ts +1 -1
  37. package/dist/react/index.mcp.d.ts.map +1 -1
  38. package/dist/react/index.mcp.js +1 -1
  39. package/dist/react/index.mcp.js.map +1 -1
  40. package/dist/react/index.openai.d.ts +1 -1
  41. package/dist/react/index.openai.d.ts.map +1 -1
  42. package/dist/react/index.openai.js +1 -1
  43. package/dist/react/index.openai.js.map +1 -1
  44. package/dist/types/application-manifest.d.ts +1 -0
  45. package/dist/types/application-manifest.d.ts.map +1 -1
  46. package/dist/types/application-manifest.js.map +1 -1
  47. package/dist/vite/__tests__/utilities/build.d.ts.map +1 -1
  48. package/dist/vite/__tests__/utilities/build.js +0 -1
  49. package/dist/vite/__tests__/utilities/build.js.map +1 -1
  50. package/dist/vite/apolloClientAiApps.d.ts +1 -0
  51. package/dist/vite/apolloClientAiApps.d.ts.map +1 -1
  52. package/dist/vite/apolloClientAiApps.js +28 -15
  53. package/dist/vite/apolloClientAiApps.js.map +1 -1
  54. package/package.json +1 -4
  55. package/src/config/schema.ts +1 -0
  56. package/src/mcp/core/McpAppManager.ts +23 -1
  57. package/src/mcp/react/hooks/__tests__/useHostContext.test.tsx +95 -0
  58. package/src/mcp/react/hooks/useHostContext.ts +14 -0
  59. package/src/mcp/react/index.ts +1 -0
  60. package/src/openai/core/McpAppManager.ts +22 -1
  61. package/src/openai/react/hooks/useHostContext.ts +14 -0
  62. package/src/openai/react/index.ts +1 -0
  63. package/src/react/index.mcp.ts +1 -0
  64. package/src/react/index.openai.ts +1 -0
  65. package/src/react/index.ts +3 -0
  66. package/src/testing/internal/mcp/mockMcpHost.ts +12 -0
  67. package/src/testing/internal/utilities/mockApplicationManifest.ts +1 -0
  68. package/src/types/application-manifest.ts +1 -0
  69. package/src/vite/__tests__/apolloClientAiApps.test.ts +279 -61
  70. package/src/vite/__tests__/utilities/build.ts +0 -1
  71. package/src/vite/apolloClientAiApps.ts +54 -17
@@ -33,7 +33,6 @@ export async function buildApp(
33
33
  ...config,
34
34
  build: {
35
35
  emptyOutDir: false,
36
- outDir: "dist",
37
36
  ...config.build,
38
37
  rollupOptions: {
39
38
  input: config.build?.rollupOptions?.input ?? "virtual:entry",
@@ -38,6 +38,7 @@ export declare namespace apolloClientAiApps {
38
38
  export interface Options {
39
39
  targets: Target[];
40
40
  devTarget?: Target | undefined;
41
+ appsOutDir: string;
41
42
  }
42
43
  }
43
44
 
@@ -74,10 +75,12 @@ export function apolloClientAiApps(
74
75
  options: apolloClientAiApps.Options
75
76
  ): Plugin {
76
77
  const targets = Array.from(new Set(options.targets));
77
- const { devTarget = targets.length === 1 ? targets[0] : undefined } = options;
78
+ const {
79
+ devTarget = targets.length === 1 ? targets[0] : undefined,
80
+ appsOutDir,
81
+ } = options;
78
82
  const cache = new Map<string, FileCache>();
79
83
 
80
- let packageJson!: Record<string, any>;
81
84
  let config!: ResolvedConfig;
82
85
 
83
86
  const fragments = createFragmentRegistry();
@@ -92,6 +95,11 @@ export function apolloClientAiApps(
92
95
  `All targets must be one of: ${VALID_TARGETS.join(", ")}`
93
96
  );
94
97
 
98
+ invariant(
99
+ path.basename(path.normalize(appsOutDir)) === "apps",
100
+ "`appsOutDir` must end with `apps` as the final path segment (e.g. `path/to/apps`)."
101
+ );
102
+
95
103
  const client = new ApolloClient({
96
104
  cache: new InMemoryCache({ fragments }),
97
105
  link: processQueryLink,
@@ -193,6 +201,14 @@ export function apolloClientAiApps(
193
201
  ) as { mcp?: string; openai?: string };
194
202
  }
195
203
 
204
+ const packageJson = readPackageJson();
205
+ const appName = appsConfig.name ?? packageJson.name;
206
+
207
+ invariant(
208
+ appName,
209
+ "Error generating application manifest. Could not determine app name. Set `name` in your apollo-client-ai-apps config or `package.json`."
210
+ );
211
+
196
212
  const manifest: ApplicationManifest = {
197
213
  format: "apollo-ai-app-manifest",
198
214
  version: "1",
@@ -203,6 +219,7 @@ export function apolloClientAiApps(
203
219
  operations,
204
220
  resource,
205
221
  csp: {
222
+ baseUriDomains: appsConfig.csp?.baseUriDomains ?? [],
206
223
  connectDomains: appsConfig.csp?.connectDomains ?? [],
207
224
  frameDomains: appsConfig.csp?.frameDomains ?? [],
208
225
  redirectDomains: appsConfig.csp?.redirectDomains ?? [],
@@ -218,14 +235,7 @@ export function apolloClientAiApps(
218
235
  manifest.labels = appsConfig.labels;
219
236
  }
220
237
 
221
- // We create mcp and openai environments in order to write to
222
- // subdirectories, but we want the manifest to be in the root outDir. If we
223
- // are running in a different environment, we'll put it in the configured
224
- // outDir directly instead.
225
- const outDir =
226
- environment?.name === "mcp" || environment?.name === "openai" ?
227
- path.resolve(config.build.outDir, "../")
228
- : config.build.outDir;
238
+ const outDir = path.join(appsOutDir, appName);
229
239
 
230
240
  // Always write to build directory so the MCP server picks it up
231
241
  const dest = path.resolve(root, outDir, ".application-manifest.json");
@@ -239,9 +249,6 @@ export function apolloClientAiApps(
239
249
  return {
240
250
  name: "@apollo/client-ai-apps/vite",
241
251
  async buildStart() {
242
- // Read package.json on start
243
- packageJson = JSON.parse(fs.readFileSync("package.json", "utf-8"));
244
-
245
252
  // Scan all files on startup
246
253
  const files = await glob("./src/**/*.{ts,tsx,js,jsx}", { fs });
247
254
 
@@ -258,19 +265,27 @@ export function apolloClientAiApps(
258
265
  configResolved(resolvedConfig) {
259
266
  config = resolvedConfig;
260
267
  },
261
- configEnvironment(name, { build }) {
268
+ async configEnvironment(name, { build }) {
262
269
  if (!targets.includes(name as any)) return;
263
270
 
271
+ const appsConfig = await getAppsConfig();
272
+ const appName = appsConfig.name ?? readPackageJson().name;
273
+
274
+ invariant(
275
+ appName,
276
+ "Could not determine app name. Set `name` in your apollo-client-ai-apps config or `package.json`."
277
+ );
278
+
264
279
  return {
265
280
  build: {
266
- outDir: path.join(build?.outDir ?? "dist", name),
281
+ outDir: path.join(appsOutDir, appName, name),
267
282
  },
268
283
  };
269
284
  },
270
285
  configureServer(server) {
271
286
  server.watcher.on("change", async (file) => {
272
287
  if (file.endsWith("package.json")) {
273
- packageJson = JSON.parse(fs.readFileSync("package.json", "utf-8"));
288
+ readPackageJson.resetCache();
274
289
  await generateManifest();
275
290
  } else if (file.match(/\.?apollo-client-ai-apps\.config\.\w+$/)) {
276
291
  explorer.clearCaches();
@@ -282,7 +297,14 @@ export function apolloClientAiApps(
282
297
  });
283
298
  },
284
299
 
285
- config(_, { command }) {
300
+ config(userConfig, { command }) {
301
+ if (userConfig.build?.outDir) {
302
+ console.warn(
303
+ "[@apollo/client-ai-apps/vite] `build.outDir` is set in your Vite config but will be " +
304
+ "ignored. Use `appsOutDir` in the plugin options to control the output location."
305
+ );
306
+ }
307
+
286
308
  if (command === "serve") {
287
309
  invariant(
288
310
  isValidTarget(devTarget) || targets.length === 1,
@@ -503,6 +525,21 @@ function getResourceFromConfig(
503
525
  return typeof config === "string" ? config : config[target];
504
526
  }
505
527
 
528
+ function readPackageJson(): Record<string, any> {
529
+ if (readPackageJson.cache) {
530
+ return readPackageJson.cache;
531
+ }
532
+
533
+ return (readPackageJson.cache = JSON.parse(
534
+ fs.readFileSync("package.json", "utf-8")
535
+ ));
536
+ }
537
+
538
+ readPackageJson.cache = undefined as Record<string, any> | undefined;
539
+ readPackageJson.resetCache = () => {
540
+ readPackageJson.cache = undefined;
541
+ };
542
+
506
543
  const ToolDirectiveSchema = z.strictObject({
507
544
  name: z.stringFormat("toolName", (value) => value.indexOf(" ") === -1, {
508
545
  error: (iss) => `Tool with name "${iss.input}" must not contain spaces`,