@standardagents/builder 0.40.5-next.3b25e2a → 0.40.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/plugin.d.ts CHANGED
@@ -30,6 +30,13 @@ interface AgentPluginOptions {
30
30
  providers?: string[];
31
31
  /** Presentation used by the built-in device sign-in confirmation page. */
32
32
  deviceApproval?: DeviceApprovalBrand;
33
+ /**
34
+ * Exact additional hostnames trusted for local authoring APIs.
35
+ * Anyone who can reach the dev server through one of these names can attempt
36
+ * to authenticate to the authoring surface; same-origin and credential
37
+ * checks still apply.
38
+ */
39
+ trustedDevHosts?: string[];
33
40
  }
34
41
  declare function agentbuilder(options?: AgentPluginOptions): PluginOption[];
35
42
  declare const builder: typeof agentbuilder;
package/dist/plugin.js CHANGED
@@ -1226,7 +1226,7 @@ function createHmrReloader() {
1226
1226
  const isConfigFile = isModelFile || isProviderFile || isPromptFile || isAgentFile || isEffectFile;
1227
1227
  if (!isToolFile && !isThreadApiFile && !isHookFile && !isConfigFile && !isUserEndpointFile) return;
1228
1228
  reloader.invalidateSourceFileModule(server, file);
1229
- if (isConfigFile || isToolFile) regenerateTypes();
1229
+ if (isConfigFile || isToolFile || isHookFile) regenerateTypes();
1230
1230
  if (isToolFile) await reloader.reloadToolsModule(server);
1231
1231
  if (isModelFile) await reloader.reloadModelsModule(server);
1232
1232
  if (isProviderFile) await reloader.reloadProvidersModule(server);
@@ -3269,6 +3269,29 @@ async function scanPromptsDirectory(dir) {
3269
3269
  async function scanAgentsDirectory(dir) {
3270
3270
  return scanConfigDirectory(dir, /export\s+default\s+defineAgent/);
3271
3271
  }
3272
+ function findLegacyRootAgentFiles(agentsDir) {
3273
+ const agentsRoot = path9__default.dirname(agentsDir);
3274
+ if (path9__default.basename(agentsDir) !== "agents" || path9__default.basename(agentsRoot) !== "agents") {
3275
+ return [];
3276
+ }
3277
+ if (!fs9__default.existsSync(agentsRoot)) return [];
3278
+ return fs9__default.readdirSync(agentsRoot, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => path9__default.join(agentsRoot, entry.name)).filter((filePath) => {
3279
+ try {
3280
+ return /export\s+default\s+defineAgent/.test(fs9__default.readFileSync(filePath, "utf8"));
3281
+ } catch {
3282
+ return false;
3283
+ }
3284
+ }).sort();
3285
+ }
3286
+ function warnLegacyRootAgentFiles(agentsDir) {
3287
+ const expectedDir = path9__default.relative(process.cwd(), agentsDir).replace(/\\/g, "/");
3288
+ for (const filePath of findLegacyRootAgentFiles(agentsDir)) {
3289
+ const source = path9__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
3290
+ console.warn(
3291
+ `[agentbuilder] Agent definition "${source}" is outside the scanned agent directory. Move it to "${expectedDir}/" so it is registered.`
3292
+ );
3293
+ }
3294
+ }
3272
3295
  async function scanEffectsDirectory(dir) {
3273
3296
  const effects = [];
3274
3297
  if (!fs9__default.existsSync(dir)) {
@@ -6960,7 +6983,32 @@ function isHostedInstance(env) {
6960
6983
  }
6961
6984
  return Boolean(value);
6962
6985
  }
6963
- function isTrustedLocalDevelopmentRequest(request, env) {
6986
+ function normalizeTrustedDevHosts(hosts) {
6987
+ const normalized = /* @__PURE__ */ new Set();
6988
+ for (const rawHost of hosts ?? []) {
6989
+ const candidate = rawHost.trim().toLowerCase().replace(/\.$/, "");
6990
+ try {
6991
+ const parsed = new URL(`http://${candidate}`);
6992
+ if (!candidate || candidate.includes("*") || parsed.hostname.toLowerCase().replace(/\.$/, "") !== candidate || parsed.port || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
6993
+ throw new Error("invalid hostname");
6994
+ }
6995
+ } catch {
6996
+ throw new Error(
6997
+ `Invalid trusted development hostname "${rawHost}". Use an exact hostname without a scheme, port, path, or wildcard.`
6998
+ );
6999
+ }
7000
+ normalized.add(candidate);
7001
+ }
7002
+ return [...normalized];
7003
+ }
7004
+ function compiledTrustedDevHosts() {
7005
+ try {
7006
+ return typeof __STANDARD_AGENTS_TRUSTED_DEV_HOSTS__ !== "undefined" && Array.isArray(__STANDARD_AGENTS_TRUSTED_DEV_HOSTS__) ? __STANDARD_AGENTS_TRUSTED_DEV_HOSTS__ : [];
7007
+ } catch {
7008
+ return [];
7009
+ }
7010
+ }
7011
+ function isTrustedLocalDevelopmentRequest(request, env, trustedDevHosts = compiledTrustedDevHosts()) {
6964
7012
  if (isHostedInstance(env)) return false;
6965
7013
  let hostname;
6966
7014
  try {
@@ -6968,7 +7016,7 @@ function isTrustedLocalDevelopmentRequest(request, env) {
6968
7016
  } catch {
6969
7017
  return false;
6970
7018
  }
6971
- return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname.endsWith(".localhost") || hostname.endsWith(".orb.local");
7019
+ return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname.endsWith(".localhost") || hostname.endsWith(".orb.local") || trustedDevHosts.some((trusted) => trusted.trim().toLowerCase() === hostname);
6972
7020
  }
6973
7021
  function isAdminOnlyApiRoute(routePath, method = "GET") {
6974
7022
  if (routePath === "/api/hooks") return true;
@@ -7063,7 +7111,8 @@ function createDevMiddleware(server, context) {
7063
7111
  installedProviderPackageMap,
7064
7112
  hmr,
7065
7113
  sourceDirs,
7066
- regenerateTypes
7114
+ regenerateTypes,
7115
+ trustedDevHosts
7067
7116
  } = context;
7068
7117
  server.watcher.on("add", async (file) => {
7069
7118
  await hmr.handleFileChange(file, server, sourceDirs, regenerateTypes);
@@ -7097,7 +7146,8 @@ function createDevMiddleware(server, context) {
7097
7146
  try {
7098
7147
  trustedLocalHost = isTrustedLocalDevelopmentRequest(
7099
7148
  new Request(`http://${req.headers.host || "invalid.remote"}${routePath}`),
7100
- {}
7149
+ {},
7150
+ trustedDevHosts
7101
7151
  );
7102
7152
  } catch {
7103
7153
  }
@@ -8331,7 +8381,7 @@ var firstPartyProviderPackages = [
8331
8381
  "@standardagents/openrouter",
8332
8382
  "@standardagents/xai"
8333
8383
  ];
8334
- var depsToInclude = [
8384
+ var baseDepsToInclude = [
8335
8385
  "zod",
8336
8386
  "zod/v3",
8337
8387
  "zod/v4",
@@ -8342,17 +8392,24 @@ var depsToInclude = [
8342
8392
  // a root dep). The `parent > child` form pre-bundles it at startup so Vite
8343
8393
  // doesn't discover it mid-request and reload the worker (which would destroy
8344
8394
  // an in-flight Durable Object execution and drop the client bridge).
8345
- "@standardagents/openrouter > @openrouter/sdk",
8346
8395
  "magic-string",
8347
8396
  "@standardagents/spec",
8348
8397
  // Incremental JSON reader used by the runtime to surface a tool's progress
8349
8398
  // argument from partial streamed tool-call arguments (tool_call_started).
8350
- "@formkit/jsonreader",
8351
- // Pre-bundle the provider packages themselves so their whole subtree (SDKs,
8352
- // pricing tables) lands in the initial optimized bundle and nothing is
8353
- // discovered lazily by workerd.
8354
- ...firstPartyProviderPackages
8399
+ "@formkit/jsonreader"
8355
8400
  ];
8401
+ function depsToInclude(options = {}) {
8402
+ const installedProviders = options.isPackageInstalled ? firstPartyProviderPackages.filter(options.isPackageInstalled) : firstPartyProviderPackages;
8403
+ const openRouterTransitive = installedProviders.includes("@standardagents/openrouter") ? ["@standardagents/openrouter > @openrouter/sdk"] : [];
8404
+ return [...baseDepsToInclude, ...openRouterTransitive, ...installedProviders];
8405
+ }
8406
+ function trustedDevHostDefines(options) {
8407
+ return {
8408
+ __STANDARD_AGENTS_TRUSTED_DEV_HOSTS__: JSON.stringify(
8409
+ normalizeTrustedDevHosts(options.trustedDevHosts)
8410
+ )
8411
+ };
8412
+ }
8356
8413
  var packingDeps = [
8357
8414
  "rollup",
8358
8415
  "@rollup/plugin-commonjs",
@@ -8361,7 +8418,7 @@ var packingDeps = [
8361
8418
  "fsevents",
8362
8419
  "typescript"
8363
8420
  ];
8364
- function createPluginViteConfig(pluginModuleUrl) {
8421
+ function createPluginViteConfig(pluginModuleUrl, options = {}) {
8365
8422
  const currentDir = path9__default.dirname(fileURLToPath(pluginModuleUrl));
8366
8423
  const isInDist = currentDir.endsWith("dist");
8367
8424
  const builderClientDir = path9__default.resolve(
@@ -8369,6 +8426,7 @@ function createPluginViteConfig(pluginModuleUrl) {
8369
8426
  isInDist ? "./client" : "../dist/client"
8370
8427
  );
8371
8428
  return {
8429
+ define: trustedDevHostDefines(options),
8372
8430
  publicDir: fs9__default.existsSync(builderClientDir) ? builderClientDir : void 0,
8373
8431
  build: {
8374
8432
  rollupOptions: {
@@ -8384,7 +8442,7 @@ function createPluginViteConfig(pluginModuleUrl) {
8384
8442
  // `npm run dev` ("There is a new version of the pre-bundle for X").
8385
8443
  holdUntilCrawlEnd: true,
8386
8444
  exclude: depsToExclude,
8387
- include: depsToInclude.filter((dep) => dep !== "zod/v3" && dep !== "zod/v4" && dep !== "zod/v4/core")
8445
+ include: depsToInclude(options).filter((dep) => dep !== "zod/v3" && dep !== "zod/v4" && dep !== "zod/v4/core")
8388
8446
  },
8389
8447
  ssr: {
8390
8448
  noExternal: [
@@ -8489,7 +8547,11 @@ function createAgentBuilderCloudflarePlugins(options) {
8489
8547
  }
8490
8548
  });
8491
8549
  }
8492
- function applyPluginEnvironmentConfig(config) {
8550
+ function applyPluginEnvironmentConfig(config, options = {}) {
8551
+ config.define = {
8552
+ ...config.define || {},
8553
+ ...trustedDevHostDefines(options)
8554
+ };
8493
8555
  config.optimizeDeps = config.optimizeDeps || {};
8494
8556
  config.optimizeDeps.holdUntilCrawlEnd = true;
8495
8557
  config.optimizeDeps.exclude = [
@@ -8498,7 +8560,7 @@ function applyPluginEnvironmentConfig(config) {
8498
8560
  ];
8499
8561
  config.optimizeDeps.include = [
8500
8562
  ...config.optimizeDeps.include || [],
8501
- ...depsToInclude.filter((dep) => !config.optimizeDeps?.include?.includes(dep))
8563
+ ...depsToInclude(options).filter((dep) => !config.optimizeDeps?.include?.includes(dep))
8502
8564
  ];
8503
8565
  config.build = config.build || {};
8504
8566
  config.build.rollupOptions = config.build.rollupOptions || {};
@@ -8558,6 +8620,7 @@ function normalizeDeviceApprovalBrand(value) {
8558
8620
  // src/plugin.ts
8559
8621
  function agentbuilder(options = {}) {
8560
8622
  const deviceApproval = normalizeDeviceApprovalBrand(options.deviceApproval);
8623
+ const trustedDevHosts = normalizeTrustedDevHosts(options.trustedDevHosts);
8561
8624
  const toolsDir = options.toolsDir ? path9__default.resolve(process.cwd(), options.toolsDir) : path9__default.resolve(process.cwd(), "agents/tools");
8562
8625
  const hooksDir = options.hooksDir ? path9__default.resolve(process.cwd(), options.hooksDir) : path9__default.resolve(process.cwd(), "agents/hooks");
8563
8626
  const threadApiDir = options.apiDir ? path9__default.resolve(process.cwd(), options.apiDir) : path9__default.resolve(process.cwd(), "agents/api");
@@ -8662,7 +8725,8 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog
8662
8725
  installedProviderPackageMap,
8663
8726
  hmr,
8664
8727
  sourceDirs,
8665
- regenerateTypes
8728
+ regenerateTypes,
8729
+ trustedDevHosts
8666
8730
  };
8667
8731
  const workerEntry = path9__default.relative(process.cwd(), generatedWorkerEntry).split(path9__default.sep).join("/");
8668
8732
  const corePlugin = {
@@ -8670,12 +8734,18 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog
8670
8734
  enforce: "pre",
8671
8735
  config() {
8672
8736
  writeGeneratedWorkerEntry();
8673
- const viteConfig = createPluginViteConfig(import.meta.url);
8737
+ const viteConfig = createPluginViteConfig(import.meta.url, {
8738
+ isPackageInstalled: isProviderPackageInstalled,
8739
+ trustedDevHosts
8740
+ });
8674
8741
  return viteConfig;
8675
8742
  },
8676
8743
  // Apply exclusions and inclusions to ALL environments including Cloudflare worker
8677
8744
  configEnvironment(_name, config) {
8678
- applyPluginEnvironmentConfig(config);
8745
+ applyPluginEnvironmentConfig(config, {
8746
+ isPackageInstalled: isProviderPackageInstalled,
8747
+ trustedDevHosts
8748
+ });
8679
8749
  },
8680
8750
  resolveId(id) {
8681
8751
  if (id === VIRTUAL_TOOLS_ID) {
@@ -8720,6 +8790,7 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog
8720
8790
  },
8721
8791
  buildStart() {
8722
8792
  writeGeneratedWorkerEntry();
8793
+ warnLegacyRootAgentFiles(agentsDir);
8723
8794
  regenerateTypes();
8724
8795
  this.addWatchFile(toolsDir);
8725
8796
  this.addWatchFile(threadApiDir);