@botpress/adk 1.15.3 → 1.15.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
@@ -15,14 +15,23 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
15
15
 
16
16
  // src/agent-project/types.ts
17
17
  import { z } from "@botpress/sdk";
18
- var dependenciesSchema, agentInfoSchema, ValidationErrorCode, ValidationSeverity, ProjectState;
18
+ var pluginDependencyMappingSchema, dependenciesSchema, agentInfoSchema, ValidationErrorCode, ValidationSeverity, ProjectState;
19
19
  var init_types = __esm(() => {
20
+ pluginDependencyMappingSchema = z.object({
21
+ integrationAlias: z.string(),
22
+ integrationInterfaceAlias: z.string().optional()
23
+ });
20
24
  dependenciesSchema = z.object({
21
25
  integrations: z.record(z.object({
22
26
  version: z.string(),
23
27
  enabled: z.boolean(),
24
28
  configurationType: z.string().optional(),
25
29
  config: z.record(z.any()).optional()
30
+ })).optional(),
31
+ plugins: z.record(z.object({
32
+ version: z.string(),
33
+ config: z.record(z.any()).optional(),
34
+ dependencies: z.record(pluginDependencyMappingSchema).optional()
26
35
  })).optional()
27
36
  });
28
37
  agentInfoSchema = z.object({
@@ -44,7 +53,10 @@ var init_types = __esm(() => {
44
53
  ValidationErrorCode2["INVALID_DEPENDENCIES_SCHEMA"] = "INVALID_DEPENDENCIES_SCHEMA";
45
54
  ValidationErrorCode2["INVALID_VERSION_FORMAT"] = "INVALID_VERSION_FORMAT";
46
55
  ValidationErrorCode2["INVALID_INTEGRATION_ALIAS"] = "INVALID_INTEGRATION_ALIAS";
56
+ ValidationErrorCode2["INVALID_PLUGIN_ALIAS"] = "INVALID_PLUGIN_ALIAS";
47
57
  ValidationErrorCode2["UNKNOWN_INTEGRATION"] = "UNKNOWN_INTEGRATION";
58
+ ValidationErrorCode2["UNKNOWN_PLUGIN"] = "UNKNOWN_PLUGIN";
59
+ ValidationErrorCode2["INVALID_PLUGIN_DEPENDENCY"] = "INVALID_PLUGIN_DEPENDENCY";
48
60
  ValidationErrorCode2["INCOMPATIBLE_VERSION"] = "INCOMPATIBLE_VERSION";
49
61
  ValidationErrorCode2["CIRCULAR_DEPENDENCY"] = "CIRCULAR_DEPENDENCY";
50
62
  ValidationErrorCode2["FILE_TOO_LARGE"] = "FILE_TOO_LARGE";
@@ -227,6 +239,61 @@ class ValidationErrors {
227
239
  context: { integration, required, available }
228
240
  };
229
241
  }
242
+ static invalidPluginAlias(alias) {
243
+ return {
244
+ $type: ValidationErrors.$type,
245
+ code: "INVALID_PLUGIN_ALIAS" /* INVALID_PLUGIN_ALIAS */,
246
+ severity: "error" /* ERROR */,
247
+ message: `Invalid plugin alias '${alias}'`,
248
+ file: "agent.config.ts",
249
+ hint: 'Plugin aliases must be 2-100 characters and contain only lowercase letters, numbers, underscores, and hyphens (e.g., "hitl", "my-plugin")',
250
+ context: { alias }
251
+ };
252
+ }
253
+ static invalidPluginVersionFormat(plugin, version) {
254
+ return {
255
+ $type: ValidationErrors.$type,
256
+ code: "INVALID_VERSION_FORMAT" /* INVALID_VERSION_FORMAT */,
257
+ severity: "error" /* ERROR */,
258
+ message: `Invalid version format '${version}' for plugin '${plugin}'`,
259
+ file: "agent.config.ts",
260
+ hint: 'Use exact versioning (e.g., "1.2.3", "2.0.0", "1.5.0")',
261
+ context: { plugin, version }
262
+ };
263
+ }
264
+ static unknownPlugin(plugin, source, detailedMessage) {
265
+ return {
266
+ $type: ValidationErrors.$type,
267
+ code: "UNKNOWN_PLUGIN" /* UNKNOWN_PLUGIN */,
268
+ severity: "error" /* ERROR */,
269
+ message: detailedMessage || `Unknown plugin '${plugin}' from source '${source}'`,
270
+ file: "agent.config.ts",
271
+ hint: detailedMessage ? undefined : `Check if the plugin name is correct or if it exists on the Botpress Hub`,
272
+ context: { plugin, source }
273
+ };
274
+ }
275
+ static invalidPluginDependency(plugin, integrationAlias, availableIntegrations) {
276
+ const available = availableIntegrations.length > 0 ? availableIntegrations.join(", ") : "(none)";
277
+ return {
278
+ $type: ValidationErrors.$type,
279
+ code: "INVALID_PLUGIN_DEPENDENCY" /* INVALID_PLUGIN_DEPENDENCY */,
280
+ severity: "error" /* ERROR */,
281
+ message: `Plugin "${plugin}" references integration "${integrationAlias}" in its dependencies, but "${integrationAlias}" is not declared in dependencies.integrations`,
282
+ file: "agent.config.ts",
283
+ hint: `Add "${integrationAlias}" to dependencies.integrations, or update the plugin dependency to reference one of: ${available}`,
284
+ context: { plugin, integrationAlias, availableIntegrations }
285
+ };
286
+ }
287
+ static pluginVersionError(plugin, errorMessage) {
288
+ return {
289
+ $type: ValidationErrors.$type,
290
+ code: "UNKNOWN_PLUGIN" /* UNKNOWN_PLUGIN */,
291
+ severity: "error" /* ERROR */,
292
+ message: errorMessage,
293
+ file: "agent.config.ts",
294
+ hint: `Update the version for "${plugin}" in agent.config.ts dependencies`
295
+ };
296
+ }
230
297
  static fileTooLarge(file, size, maxSize) {
231
298
  return {
232
299
  $type: ValidationErrors.$type,
@@ -651,7 +718,7 @@ var PRETTIER_CONFIG, formatCode = async (code, filepath) => {
651
718
  `));
652
719
  return code;
653
720
  }
654
- }, ADK_VERSION = "1.15.3", relative2 = (from, to) => {
721
+ }, ADK_VERSION = "1.15.4", relative2 = (from, to) => {
655
722
  const fromDir = path10.dirname(from);
656
723
  const relative3 = path10.relative(fromDir, to);
657
724
  return relative3.startsWith(".") ? relative3 : `./${relative3}`;
@@ -675,7 +742,7 @@ var exports_action_types = {};
675
742
  __export(exports_action_types, {
676
743
  generateActionTypes: () => generateActionTypes
677
744
  });
678
- import path32 from "path";
745
+ import path36 from "path";
679
746
  async function generateActionTypes(project) {
680
747
  const actionDefs = [];
681
748
  for (const action of project.actions) {
@@ -690,7 +757,7 @@ async function generateActionTypes(project) {
690
757
  };`);
691
758
  continue;
692
759
  }
693
- const absolutePath = path32.join(project.path, action.path);
760
+ const absolutePath = path36.join(project.path, action.path);
694
761
  const actionModule = await import(`${absolutePath}?t=${Date.now()}`);
695
762
  const actionInstance = actionModule[action.export] || actionModule.default;
696
763
  if (actionInstance && actionInstance.input && actionInstance.output) {
@@ -735,7 +802,7 @@ ${actionDefs.join(`
735
802
  };
736
803
  }
737
804
  `;
738
- const actionTypesPath = path32.join(project.path, ".adk", "action-types.d.ts");
805
+ const actionTypesPath = path36.join(project.path, ".adk", "action-types.d.ts");
739
806
  await createFile(actionTypesPath, await formatCode(content));
740
807
  }
741
808
  var init_action_types = __esm(() => {
@@ -748,7 +815,7 @@ var exports_integration_action_types = {};
748
815
  __export(exports_integration_action_types, {
749
816
  generateIntegrationActionTypes: () => generateIntegrationActionTypes
750
817
  });
751
- import path33 from "path";
818
+ import path37 from "path";
752
819
  async function generateIntegrationActionTypes(project) {
753
820
  const content = `
754
821
  ////////////////////////////////////////////////////////
@@ -782,7 +849,7 @@ type IntegrationsMap<T> = {
782
849
  export type IntegrationActions = IntegrationsMap<Integrations>;
783
850
  }
784
851
  `;
785
- const integrationActionTypesPath = path33.join(project.path, ".adk", "integration-action-types.d.ts");
852
+ const integrationActionTypesPath = path37.join(project.path, ".adk", "integration-action-types.d.ts");
786
853
  await createFile(integrationActionTypesPath, await formatCode(content));
787
854
  }
788
855
  var init_integration_action_types = __esm(() => {
@@ -794,7 +861,7 @@ var init_integration_action_types = __esm(() => {
794
861
  var require_package = __commonJS((exports, module) => {
795
862
  module.exports = {
796
863
  name: "@botpress/adk",
797
- version: "1.15.3",
864
+ version: "1.15.4",
798
865
  description: "Core ADK library for building AI agents on Botpress",
799
866
  type: "module",
800
867
  main: "dist/index.js",
@@ -841,7 +908,7 @@ var require_package = __commonJS((exports, module) => {
841
908
  "@botpress/cli": "^5.2.0",
842
909
  "@botpress/client": "^1.35.0",
843
910
  "@botpress/cognitive": "^0.3.14",
844
- "@botpress/runtime": "^1.15.3",
911
+ "@botpress/runtime": "^1.15.4",
845
912
  "@botpress/sdk": "^5.4.3",
846
913
  "@bpinternal/jex": "^1.2.4",
847
914
  "@bpinternal/yargs-extra": "^0.0.21",
@@ -2618,6 +2685,118 @@ class IntegrationParser {
2618
2685
  return errors;
2619
2686
  }
2620
2687
  }
2688
+ var PLUGIN_ALIAS_MIN_LENGTH = 2;
2689
+ var PLUGIN_ALIAS_MAX_LENGTH = 100;
2690
+ var PLUGIN_ALIAS_REGEX = /^[a-z][a-z0-9_-]*$/;
2691
+ function isPluginAliasValid(alias) {
2692
+ return alias.length >= PLUGIN_ALIAS_MIN_LENGTH && alias.length <= PLUGIN_ALIAS_MAX_LENGTH && PLUGIN_ALIAS_REGEX.test(alias);
2693
+ }
2694
+ var pluginRefSchema = z2.string().transform((val, ctx) => {
2695
+ const match = val.match(/^([^/@]+)@(.+)$/);
2696
+ if (!match) {
2697
+ ctx.addIssue({
2698
+ code: ZodIssueCode.custom,
2699
+ message: `Invalid plugin version format: ${val}. Expected format: 'name@version' (no workspace prefix)`
2700
+ });
2701
+ return z2.NEVER;
2702
+ }
2703
+ const [, name, version] = match;
2704
+ return {
2705
+ name,
2706
+ version,
2707
+ fullName: name
2708
+ };
2709
+ });
2710
+
2711
+ class PluginParser {
2712
+ static parsePluginRef(versionString) {
2713
+ const result = pluginRefSchema.safeParse(versionString);
2714
+ if (!result.success) {
2715
+ throw new Error(result.error.errors[0]?.message || "Invalid plugin version format");
2716
+ }
2717
+ return result.data;
2718
+ }
2719
+ static parsePlugins(dependencies) {
2720
+ const plugins = [];
2721
+ const errors = [];
2722
+ if (!dependencies.plugins) {
2723
+ return { plugins, errors };
2724
+ }
2725
+ for (const [alias, value] of Object.entries(dependencies.plugins)) {
2726
+ try {
2727
+ if (!isPluginAliasValid(alias)) {
2728
+ errors.push(ValidationErrors.invalidPluginAlias(alias));
2729
+ continue;
2730
+ }
2731
+ const ref = this.parsePluginRef(value.version);
2732
+ const versionResult = versionSchema.safeParse(ref.version);
2733
+ if (!versionResult.success) {
2734
+ errors.push(ValidationErrors.invalidPluginVersionFormat(alias, ref.version));
2735
+ }
2736
+ plugins.push({
2737
+ alias,
2738
+ ref,
2739
+ config: value.config,
2740
+ dependencies: value.dependencies
2741
+ });
2742
+ } catch (error) {
2743
+ errors.push(ValidationErrors.invalidDependenciesSyntax(`Invalid plugin '${alias}': ${error instanceof Error ? error.message : String(error)}`));
2744
+ }
2745
+ }
2746
+ return { plugins, errors };
2747
+ }
2748
+ static validateDependencyReferences(dependencies) {
2749
+ const errors = [];
2750
+ if (!dependencies.plugins) {
2751
+ return errors;
2752
+ }
2753
+ const integrationAliases = Object.keys(dependencies.integrations || {});
2754
+ for (const [alias, pluginConfig] of Object.entries(dependencies.plugins)) {
2755
+ if (!pluginConfig.dependencies) {
2756
+ continue;
2757
+ }
2758
+ for (const [depAlias, depMapping] of Object.entries(pluginConfig.dependencies)) {
2759
+ if (!integrationAliases.includes(depMapping.integrationAlias)) {
2760
+ errors.push(ValidationErrors.invalidPluginDependency(alias, depMapping.integrationAlias, integrationAliases));
2761
+ }
2762
+ }
2763
+ }
2764
+ return errors;
2765
+ }
2766
+ static checkDuplicates(plugins) {
2767
+ const errors = [];
2768
+ const seen = new Map;
2769
+ for (const plugin of plugins) {
2770
+ const key = plugin.ref.fullName;
2771
+ const group = seen.get(key) || [];
2772
+ group.push(plugin);
2773
+ seen.set(key, group);
2774
+ }
2775
+ for (const [pluginName, group] of seen.entries()) {
2776
+ if (group.length > 1) {
2777
+ const duplicateConfigs = [];
2778
+ for (let i = 0;i < group.length; i++) {
2779
+ for (let j = i + 1;j < group.length; j++) {
2780
+ const configA = JSON.stringify(group[i].config ?? {});
2781
+ const configB = JSON.stringify(group[j].config ?? {});
2782
+ if (configA === configB) {
2783
+ if (!duplicateConfigs.includes(group[i].alias)) {
2784
+ duplicateConfigs.push(group[i].alias);
2785
+ }
2786
+ if (!duplicateConfigs.includes(group[j].alias)) {
2787
+ duplicateConfigs.push(group[j].alias);
2788
+ }
2789
+ }
2790
+ }
2791
+ }
2792
+ if (duplicateConfigs.length > 0) {
2793
+ errors.push(ValidationErrors.warning(`Plugin '${pluginName}' has aliases with identical configurations: ${duplicateConfigs.join(", ")}. Consider using different configs or removing duplicates.`, "agent.config.ts"));
2794
+ }
2795
+ }
2796
+ }
2797
+ return errors;
2798
+ }
2799
+ }
2621
2800
 
2622
2801
  // src/integrations/manager.ts
2623
2802
  init_validation_errors();
@@ -6403,7 +6582,7 @@ class AgentProjectGenerator {
6403
6582
  deploy: "adk deploy"
6404
6583
  },
6405
6584
  dependencies: {
6406
- "@botpress/runtime": `^${"1.15.3"}`
6585
+ "@botpress/runtime": `^${"1.15.4"}`
6407
6586
  },
6408
6587
  devDependencies: {
6409
6588
  typescript: "^5.9.3"
@@ -6616,133 +6795,352 @@ export default {};
6616
6795
  `);
6617
6796
  }
6618
6797
  }
6619
- // src/generators/assets.ts
6620
- init_fs();
6798
+ // src/plugins/enhanced-cache.ts
6799
+ import fs12 from "fs/promises";
6621
6800
  import path16 from "path";
6622
- async function generateAssetsTypes(projectPath) {
6623
- const assetsManager = new AssetsManager({ projectPath });
6624
- const typesCode = await assetsManager.generateTypes();
6625
- const typesPath = path16.join(projectPath, defaultAdkFolder, "assets.d.ts");
6626
- await createFile(typesPath, typesCode);
6627
- }
6628
- async function generateAssetsRuntime(projectPath, botId, workspaceId) {
6629
- const assetsManager = new AssetsManager({ projectPath, botId, workspaceId });
6630
- const enrichedAssets = await assetsManager.getEnrichedLocalAssets();
6631
- const assetsMap = {};
6632
- const localHashesMap = {};
6633
- const cacheManager = new AssetsCacheManager(projectPath);
6634
- const cache2 = await cacheManager.load();
6635
- for (const asset of enrichedAssets) {
6636
- assetsMap[asset.path] = asset;
6637
- const cacheEntry = cache2.entries[asset.path];
6638
- if (cacheEntry) {
6639
- localHashesMap[asset.path] = cacheEntry.localHash;
6801
+ import os8 from "os";
6802
+
6803
+ class EnhancedPluginCache {
6804
+ cacheDir;
6805
+ resolutionsDir;
6806
+ definitionsDir;
6807
+ noCache;
6808
+ constructor(noCache = false) {
6809
+ this.noCache = noCache;
6810
+ this.cacheDir = path16.join(os8.homedir(), ".adk", "cache", "plugins");
6811
+ this.resolutionsDir = path16.join(this.cacheDir, "resolutions");
6812
+ this.definitionsDir = path16.join(this.cacheDir, "definitions");
6813
+ }
6814
+ async ensureCacheDirs() {
6815
+ await fs12.mkdir(this.resolutionsDir, { recursive: true });
6816
+ await fs12.mkdir(this.definitionsDir, { recursive: true });
6817
+ }
6818
+ async getResolution(name, version) {
6819
+ if (this.noCache) {
6820
+ return null;
6821
+ }
6822
+ try {
6823
+ const key = this.getResolutionKey(name, version);
6824
+ const cachePath = path16.join(this.resolutionsDir, `${key}.json`);
6825
+ const data = await fs12.readFile(cachePath, "utf-8");
6826
+ const resolution = JSON.parse(data);
6827
+ const cachedAt = new Date(resolution.cachedAt);
6828
+ const now = new Date;
6829
+ const ageMinutes = (now.getTime() - cachedAt.getTime()) / (1000 * 60);
6830
+ if (ageMinutes > 5) {
6831
+ return null;
6832
+ }
6833
+ return resolution;
6834
+ } catch {
6835
+ return null;
6640
6836
  }
6641
6837
  }
6642
- const runtimeCode = `
6643
- // Auto-generated assets metadata
6644
- import { Asset, initAssets } from '@botpress/runtime/runtime';
6645
-
6646
- // Static asset metadata (populated at build time)
6647
- export const assetsMetadata: Record<string, Asset> = ${JSON.stringify(assetsMap, null, 2)};
6648
-
6649
- // Local hashes from cache
6650
- export const localHashes: Record<string, string> = ${JSON.stringify(localHashesMap, null, 2)};
6651
-
6652
- // Initialize the assets runtime with metadata and local hashes
6653
- // The global object should be passed by the agent initialization code
6654
- export function initializeAssets(globalObj: any = globalThis) {
6655
- initAssets(globalObj, assetsMetadata, localHashes);
6656
- }
6657
-
6658
- // Auto-initialize if running in a supported environment
6659
- if (typeof globalThis !== 'undefined') {
6660
- initializeAssets(globalThis);
6661
- } else if (typeof global !== 'undefined') {
6662
- initializeAssets(global);
6663
- }
6664
- `;
6665
- const runtimePath = path16.join(projectPath, defaultAdkFolder, "assets-runtime.ts");
6666
- await createFile(runtimePath, runtimeCode);
6667
- }
6668
- async function initAssets(projectPath, botId, workspaceId) {
6669
- const assetsManager = new AssetsManager({ projectPath, botId, workspaceId });
6670
- if (await assetsManager.hasAssetsDirectory()) {
6671
- await generateAssetsTypes(projectPath);
6672
- await generateAssetsRuntime(projectPath, botId, workspaceId);
6673
- } else {
6674
- const emptyTypesCode = `// No assets directory found
6675
- import { Asset } from '@botpress/runtime';
6676
-
6677
- export type AssetPaths = never;
6678
-
6679
- export interface AssetPathMap {}
6680
-
6681
- // Runtime asset access
6682
- declare global {
6683
- const assets: {
6684
- get<T extends AssetPaths>(path: T): Asset;
6685
- list(): Asset[];
6686
- getSyncStatus(): {
6687
- synced: boolean;
6688
- neverSynced: string[];
6689
- stale: string[];
6690
- upToDate: string[];
6838
+ async setResolution(name, version, pluginId, updatedAt) {
6839
+ await this.ensureCacheDirs();
6840
+ const key = this.getResolutionKey(name, version);
6841
+ const cachePath = path16.join(this.resolutionsDir, `${key}.json`);
6842
+ const resolution = {
6843
+ pluginId,
6844
+ updatedAt,
6845
+ cachedAt: new Date().toISOString()
6691
6846
  };
6692
- };
6693
- }
6694
- `;
6695
- const typesPath = path16.join(projectPath, defaultAdkFolder, "assets.d.ts");
6696
- await createFile(typesPath, emptyTypesCode);
6697
- const emptyRuntimeCode = `
6698
- // No assets available
6699
- import { Asset, initAssets } from '@botpress/runtime';
6700
-
6701
- // Empty asset metadata
6702
- export const assetsMetadata: Record<string, Asset> = {};
6703
-
6704
- // Initialize with empty metadata
6705
- export function initializeAssets(globalObj: any = globalThis) {
6706
- initAssets(globalObj, assetsMetadata);
6707
- }
6708
-
6709
- // Auto-initialize if running in a supported environment
6710
- if (typeof globalThis !== 'undefined') {
6711
- initializeAssets(globalThis);
6712
- } else if (typeof global !== 'undefined') {
6713
- initializeAssets(global);
6714
- }
6715
- `;
6716
- const runtimePath = path16.join(projectPath, defaultAdkFolder, "assets-runtime.ts");
6717
- await createFile(runtimePath, emptyRuntimeCode);
6847
+ await fs12.writeFile(cachePath, JSON.stringify(resolution, null, 2));
6718
6848
  }
6719
- }
6720
- // src/generators/integration-types.ts
6721
- import { transforms } from "@botpress/sdk";
6722
- import crypto2 from "crypto";
6723
- import path17 from "path";
6724
-
6725
- // src/utils/strings.ts
6726
- function pascalCase(str) {
6727
- return str.split(/[-_\s]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
6728
- }
6729
- function camelCase(str) {
6730
- const pascal = pascalCase(str);
6731
- return pascal.charAt(0).toLowerCase() + pascal.slice(1);
6732
- }
6733
- function snakeCase(str) {
6734
- return str.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[\s-]+/g, "_").toLowerCase();
6735
- }
6736
-
6737
- // src/generators/integration-types.ts
6738
- init_utils();
6739
-
6740
- // src/utils/ids.ts
6741
- function getIntegrationAlias(integrationName) {
6742
- return integrationName.replace(/\//g, "__").replace(/-/g, "_").toLowerCase();
6743
- }
6744
-
6745
- // src/generators/integration-types.ts
6849
+ async getDefinition(pluginId, updatedAt) {
6850
+ if (this.noCache) {
6851
+ return null;
6852
+ }
6853
+ try {
6854
+ const key = this.getDefinitionKey(pluginId, updatedAt);
6855
+ const cachePath = path16.join(this.definitionsDir, `${key}.json`);
6856
+ const data = await fs12.readFile(cachePath, "utf-8");
6857
+ const cached = JSON.parse(data);
6858
+ return cached.definition;
6859
+ } catch {
6860
+ return null;
6861
+ }
6862
+ }
6863
+ async setDefinition(pluginId, updatedAt, definition) {
6864
+ await this.ensureCacheDirs();
6865
+ const key = this.getDefinitionKey(pluginId, updatedAt);
6866
+ const cachePath = path16.join(this.definitionsDir, `${key}.json`);
6867
+ const cached = {
6868
+ definition,
6869
+ cachedAt: new Date().toISOString()
6870
+ };
6871
+ await fs12.writeFile(cachePath, JSON.stringify(cached, null, 2));
6872
+ }
6873
+ async clear() {
6874
+ try {
6875
+ const resolutionFiles = await fs12.readdir(this.resolutionsDir);
6876
+ await Promise.all(resolutionFiles.map((file) => fs12.unlink(path16.join(this.resolutionsDir, file))));
6877
+ const definitionFiles = await fs12.readdir(this.definitionsDir);
6878
+ await Promise.all(definitionFiles.map((file) => fs12.unlink(path16.join(this.definitionsDir, file))));
6879
+ } catch {}
6880
+ }
6881
+ async getStats() {
6882
+ const getDirectoryStats = async (dir) => {
6883
+ try {
6884
+ const files = await fs12.readdir(dir);
6885
+ let totalSize = 0;
6886
+ for (const file of files) {
6887
+ const stats = await fs12.stat(path16.join(dir, file));
6888
+ totalSize += stats.size;
6889
+ }
6890
+ return {
6891
+ count: files.length,
6892
+ sizeBytes: totalSize
6893
+ };
6894
+ } catch {
6895
+ return { count: 0, sizeBytes: 0 };
6896
+ }
6897
+ };
6898
+ const [resolutions, definitions] = await Promise.all([
6899
+ getDirectoryStats(this.resolutionsDir),
6900
+ getDirectoryStats(this.definitionsDir)
6901
+ ]);
6902
+ return { resolutions, definitions };
6903
+ }
6904
+ getResolutionKey(name, version) {
6905
+ const key = `${name}_${version}`;
6906
+ return key.replace(/[^a-zA-Z0-9_-]/g, "_");
6907
+ }
6908
+ getDefinitionKey(pluginId, updatedAt) {
6909
+ const key = `${pluginId}_${updatedAt}`;
6910
+ return key.replace(/[^a-zA-Z0-9_-]/g, "_");
6911
+ }
6912
+ }
6913
+ // src/plugins/manager.ts
6914
+ import { Client as Client13 } from "@botpress/client";
6915
+ init_validation_errors();
6916
+
6917
+ class PluginManager {
6918
+ cache;
6919
+ options;
6920
+ client;
6921
+ constructor(options = {}) {
6922
+ this.options = options;
6923
+ this.cache = new EnhancedPluginCache(options.noCache || false);
6924
+ }
6925
+ async getClient() {
6926
+ if (!this.client) {
6927
+ const credentials = this.options.credentials || await auth.getActiveCredentials();
6928
+ if (!this.options.workspaceId && !credentials.workspaceId) {
6929
+ throw new Error('No workspace ID found in current profile. Please login again with "adk login"');
6930
+ }
6931
+ const workspaceId = this.options.workspaceId || credentials.workspaceId;
6932
+ this.client = new Client13({
6933
+ token: credentials.token,
6934
+ apiUrl: credentials.apiUrl,
6935
+ workspaceId,
6936
+ headers: {
6937
+ "x-multiple-integrations": "true"
6938
+ }
6939
+ });
6940
+ }
6941
+ return this.client;
6942
+ }
6943
+ async loadPlugins(dependencies) {
6944
+ const errors = [];
6945
+ const warnings = [];
6946
+ const parseResult = PluginParser.parsePlugins(dependencies);
6947
+ const plugins = parseResult.plugins;
6948
+ errors.push(...parseResult.errors);
6949
+ const duplicateWarnings = PluginParser.checkDuplicates(plugins);
6950
+ warnings.push(...duplicateWarnings);
6951
+ const fetchPromises = plugins.map(async (plugin) => {
6952
+ try {
6953
+ plugin.definition = await this.fetchPlugin(plugin.ref);
6954
+ } catch (error) {
6955
+ if (error instanceof Error && error.message.includes("version")) {
6956
+ errors.push(ValidationErrors.pluginVersionError(plugin.alias, error.message));
6957
+ } else {
6958
+ const errorMessage = error instanceof Error ? error.message : undefined;
6959
+ errors.push(ValidationErrors.unknownPlugin(plugin.alias, plugin.ref.fullName, errorMessage));
6960
+ }
6961
+ }
6962
+ });
6963
+ await Promise.all(fetchPromises);
6964
+ return { plugins, errors, warnings };
6965
+ }
6966
+ async fetchPlugin(ref) {
6967
+ const cachedResolution = await this.cache.getResolution(ref.name, ref.version);
6968
+ if (cachedResolution) {
6969
+ const cachedDefinition = await this.cache.getDefinition(cachedResolution.pluginId, cachedResolution.updatedAt);
6970
+ if (cachedDefinition) {
6971
+ return cachedDefinition;
6972
+ }
6973
+ }
6974
+ const client = await this.getClient();
6975
+ const plugin = await this._findPublicPlugin(client, ref);
6976
+ if (!plugin) {
6977
+ throw new Error(`Plugin "${ref.name}" not found on the Botpress Hub`);
6978
+ }
6979
+ await this.cache.setResolution(ref.name, ref.version, plugin.id, plugin.updatedAt);
6980
+ await this.cache.setDefinition(plugin.id, plugin.updatedAt, plugin);
6981
+ return plugin;
6982
+ }
6983
+ async _findPublicPlugin(client, ref) {
6984
+ try {
6985
+ const response = await client.getPublicPlugin({
6986
+ name: ref.name,
6987
+ version: ref.version
6988
+ });
6989
+ return response.plugin;
6990
+ } catch (error) {
6991
+ if (this._isResourceNotFoundError(error)) {
6992
+ return;
6993
+ }
6994
+ throw error;
6995
+ }
6996
+ }
6997
+ _isResourceNotFoundError(error) {
6998
+ if (error && typeof error === "object" && "type" in error) {
6999
+ return error.type === "ResourceNotFound";
7000
+ }
7001
+ return false;
7002
+ }
7003
+ async getCacheStats() {
7004
+ const stats = await this.cache.getStats();
7005
+ return {
7006
+ count: stats.resolutions.count + stats.definitions.count,
7007
+ sizeBytes: stats.resolutions.sizeBytes + stats.definitions.sizeBytes
7008
+ };
7009
+ }
7010
+ async clearCache() {
7011
+ await this.cache.clear();
7012
+ }
7013
+ }
7014
+ // src/generators/assets.ts
7015
+ init_fs();
7016
+ import path17 from "path";
7017
+ async function generateAssetsTypes(projectPath) {
7018
+ const assetsManager = new AssetsManager({ projectPath });
7019
+ const typesCode = await assetsManager.generateTypes();
7020
+ const typesPath = path17.join(projectPath, defaultAdkFolder, "assets.d.ts");
7021
+ await createFile(typesPath, typesCode);
7022
+ }
7023
+ async function generateAssetsRuntime(projectPath, botId, workspaceId) {
7024
+ const assetsManager = new AssetsManager({ projectPath, botId, workspaceId });
7025
+ const enrichedAssets = await assetsManager.getEnrichedLocalAssets();
7026
+ const assetsMap = {};
7027
+ const localHashesMap = {};
7028
+ const cacheManager = new AssetsCacheManager(projectPath);
7029
+ const cache2 = await cacheManager.load();
7030
+ for (const asset of enrichedAssets) {
7031
+ assetsMap[asset.path] = asset;
7032
+ const cacheEntry = cache2.entries[asset.path];
7033
+ if (cacheEntry) {
7034
+ localHashesMap[asset.path] = cacheEntry.localHash;
7035
+ }
7036
+ }
7037
+ const runtimeCode = `
7038
+ // Auto-generated assets metadata
7039
+ import { Asset, initAssets } from '@botpress/runtime/runtime';
7040
+
7041
+ // Static asset metadata (populated at build time)
7042
+ export const assetsMetadata: Record<string, Asset> = ${JSON.stringify(assetsMap, null, 2)};
7043
+
7044
+ // Local hashes from cache
7045
+ export const localHashes: Record<string, string> = ${JSON.stringify(localHashesMap, null, 2)};
7046
+
7047
+ // Initialize the assets runtime with metadata and local hashes
7048
+ // The global object should be passed by the agent initialization code
7049
+ export function initializeAssets(globalObj: any = globalThis) {
7050
+ initAssets(globalObj, assetsMetadata, localHashes);
7051
+ }
7052
+
7053
+ // Auto-initialize if running in a supported environment
7054
+ if (typeof globalThis !== 'undefined') {
7055
+ initializeAssets(globalThis);
7056
+ } else if (typeof global !== 'undefined') {
7057
+ initializeAssets(global);
7058
+ }
7059
+ `;
7060
+ const runtimePath = path17.join(projectPath, defaultAdkFolder, "assets-runtime.ts");
7061
+ await createFile(runtimePath, runtimeCode);
7062
+ }
7063
+ async function initAssets(projectPath, botId, workspaceId) {
7064
+ const assetsManager = new AssetsManager({ projectPath, botId, workspaceId });
7065
+ if (await assetsManager.hasAssetsDirectory()) {
7066
+ await generateAssetsTypes(projectPath);
7067
+ await generateAssetsRuntime(projectPath, botId, workspaceId);
7068
+ } else {
7069
+ const emptyTypesCode = `// No assets directory found
7070
+ import { Asset } from '@botpress/runtime';
7071
+
7072
+ export type AssetPaths = never;
7073
+
7074
+ export interface AssetPathMap {}
7075
+
7076
+ // Runtime asset access
7077
+ declare global {
7078
+ const assets: {
7079
+ get<T extends AssetPaths>(path: T): Asset;
7080
+ list(): Asset[];
7081
+ getSyncStatus(): {
7082
+ synced: boolean;
7083
+ neverSynced: string[];
7084
+ stale: string[];
7085
+ upToDate: string[];
7086
+ };
7087
+ };
7088
+ }
7089
+ `;
7090
+ const typesPath = path17.join(projectPath, defaultAdkFolder, "assets.d.ts");
7091
+ await createFile(typesPath, emptyTypesCode);
7092
+ const emptyRuntimeCode = `
7093
+ // No assets available
7094
+ import { Asset, initAssets } from '@botpress/runtime';
7095
+
7096
+ // Empty asset metadata
7097
+ export const assetsMetadata: Record<string, Asset> = {};
7098
+
7099
+ // Initialize with empty metadata
7100
+ export function initializeAssets(globalObj: any = globalThis) {
7101
+ initAssets(globalObj, assetsMetadata);
7102
+ }
7103
+
7104
+ // Auto-initialize if running in a supported environment
7105
+ if (typeof globalThis !== 'undefined') {
7106
+ initializeAssets(globalThis);
7107
+ } else if (typeof global !== 'undefined') {
7108
+ initializeAssets(global);
7109
+ }
7110
+ `;
7111
+ const runtimePath = path17.join(projectPath, defaultAdkFolder, "assets-runtime.ts");
7112
+ await createFile(runtimePath, emptyRuntimeCode);
7113
+ }
7114
+ }
7115
+ // src/generators/integration-types.ts
7116
+ import { transforms } from "@botpress/sdk";
7117
+ import crypto2 from "crypto";
7118
+ import path18 from "path";
7119
+
7120
+ // src/utils/strings.ts
7121
+ function pascalCase(str) {
7122
+ return str.split(/[-_\s]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
7123
+ }
7124
+ function camelCase(str) {
7125
+ const pascal = pascalCase(str);
7126
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
7127
+ }
7128
+ function snakeCase(str) {
7129
+ return str.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[\s-]+/g, "_").toLowerCase();
7130
+ }
7131
+
7132
+ // src/generators/integration-types.ts
7133
+ init_utils();
7134
+
7135
+ // src/utils/ids.ts
7136
+ function getIntegrationAlias(integrationName) {
7137
+ return integrationName.replace(/\//g, "__").replace(/-/g, "_").toLowerCase();
7138
+ }
7139
+ function getPluginAlias(pluginName) {
7140
+ return pluginName.replace(/-/g, "_").toLowerCase();
7141
+ }
7142
+
7143
+ // src/generators/integration-types.ts
6746
7144
  var getIntegrationHash = (integration) => {
6747
7145
  return crypto2.createHash("sha256").update(`${integration.alias}|${integration.definition?.id}|${integration.definition?.version}|${integration.definition?.updatedAt}`).digest("hex");
6748
7146
  };
@@ -6757,12 +7155,12 @@ var getIntegrationNames = (integration) => ({
6757
7155
  configurations: `Integration_Configurations_${getPascalAlias(integration)}`
6758
7156
  },
6759
7157
  paths: {
6760
- index: path17.join(snakeCase(getPascalAlias(integration)), `index.ts`),
6761
- actions: path17.join(snakeCase(getPascalAlias(integration)), `actions.ts`),
6762
- channels: path17.join(snakeCase(getPascalAlias(integration)), `channels.ts`),
6763
- events: path17.join(snakeCase(getPascalAlias(integration)), `events.ts`),
6764
- users: path17.join(snakeCase(getPascalAlias(integration)), `users.ts`),
6765
- configurations: path17.join(snakeCase(getPascalAlias(integration)), `configurations.ts`)
7158
+ index: path18.join(snakeCase(getPascalAlias(integration)), `index.ts`),
7159
+ actions: path18.join(snakeCase(getPascalAlias(integration)), `actions.ts`),
7160
+ channels: path18.join(snakeCase(getPascalAlias(integration)), `channels.ts`),
7161
+ events: path18.join(snakeCase(getPascalAlias(integration)), `events.ts`),
7162
+ users: path18.join(snakeCase(getPascalAlias(integration)), `users.ts`),
7163
+ configurations: path18.join(snakeCase(getPascalAlias(integration)), `configurations.ts`)
6766
7164
  }
6767
7165
  });
6768
7166
  async function generateIntegrationTypes(integration) {
@@ -7016,7 +7414,7 @@ Description: ${tag?.description}`);
7016
7414
  // src/generators/client-wrapper.ts
7017
7415
  init_utils();
7018
7416
  init_fs();
7019
- import path18 from "path";
7417
+ import path19 from "path";
7020
7418
  import crypto3 from "crypto";
7021
7419
  import { readFile as readFile3 } from "fs/promises";
7022
7420
  import { BuiltInWorkflows as BuiltInWorkflows2 } from "@botpress/runtime/internal";
@@ -7038,7 +7436,7 @@ async function generateClientWrapper(project) {
7038
7436
  });
7039
7437
  continue;
7040
7438
  }
7041
- const absolutePath = path18.join(project.path, action.path);
7439
+ const absolutePath = path19.join(project.path, action.path);
7042
7440
  const actionModule = await import(`${absolutePath}?t=${Date.now()}`);
7043
7441
  const actionInstance = actionModule[action.export] || actionModule.default;
7044
7442
  if (actionInstance && actionInstance.input && actionInstance.output) {
@@ -7065,7 +7463,7 @@ async function generateClientWrapper(project) {
7065
7463
  if (isBuiltinWorkflow(workflow.definition.name)) {
7066
7464
  continue;
7067
7465
  }
7068
- const workflowPath = path18.join(project.path, workflow.path);
7466
+ const workflowPath = path19.join(project.path, workflow.path);
7069
7467
  const workflowModule = await import(`${workflowPath}?t=${Date.now()}`);
7070
7468
  const workflowInstance = workflowModule[workflow.export] || workflowModule.default;
7071
7469
  if (workflowInstance) {
@@ -7084,7 +7482,7 @@ async function generateClientWrapper(project) {
7084
7482
  const tableTypes = [];
7085
7483
  for (const table of project.tables) {
7086
7484
  try {
7087
- const tablePath = path18.join(project.path, table.path);
7485
+ const tablePath = path19.join(project.path, table.path);
7088
7486
  const tableModule = await import(`${tablePath}?t=${Date.now()}`);
7089
7487
  const tableInstance = tableModule.default || tableModule[table.export];
7090
7488
  if (tableInstance && tableInstance.columns) {
@@ -7347,76 +7745,225 @@ export function createAdkClient(client: Client): AdkClient {
7347
7745
  `)}
7348
7746
  },
7349
7747
 
7350
- tables: {
7351
- ${tableTypes.map((table) => `
7352
- '${table.name}': {
7353
- findTableRows: async (params) => {
7354
- return client.findTableRows({
7355
- table: '${table.name}',
7356
- ...params,
7357
- }) as any
7358
- },
7359
- getTableRow: async (params) => {
7360
- return client.getTableRow({
7361
- table: '${table.name}',
7362
- ...params,
7363
- }) as any
7364
- },
7365
- createTableRows: async (params) => {
7366
- return client.createTableRows({
7367
- table: '${table.name}',
7368
- ...params,
7369
- }) as any
7370
- },
7371
- updateTableRows: async (params) => {
7372
- return client.updateTableRows({
7373
- table: '${table.name}',
7374
- ...params,
7375
- }) as any
7376
- },
7377
- upsertTableRows: async (params) => {
7378
- return client.upsertTableRows({
7379
- table: '${table.name}',
7380
- ...params,
7381
- }) as any
7382
- },
7383
- deleteTableRows: async (params) => {
7384
- return client.deleteTableRows({
7385
- table: '${table.name}',
7386
- ...params,
7387
- }) as any
7388
- },
7748
+ tables: {
7749
+ ${tableTypes.map((table) => `
7750
+ '${table.name}': {
7751
+ findTableRows: async (params) => {
7752
+ return client.findTableRows({
7753
+ table: '${table.name}',
7754
+ ...params,
7755
+ }) as any
7756
+ },
7757
+ getTableRow: async (params) => {
7758
+ return client.getTableRow({
7759
+ table: '${table.name}',
7760
+ ...params,
7761
+ }) as any
7762
+ },
7763
+ createTableRows: async (params) => {
7764
+ return client.createTableRows({
7765
+ table: '${table.name}',
7766
+ ...params,
7767
+ }) as any
7768
+ },
7769
+ updateTableRows: async (params) => {
7770
+ return client.updateTableRows({
7771
+ table: '${table.name}',
7772
+ ...params,
7773
+ }) as any
7774
+ },
7775
+ upsertTableRows: async (params) => {
7776
+ return client.upsertTableRows({
7777
+ table: '${table.name}',
7778
+ ...params,
7779
+ }) as any
7780
+ },
7781
+ deleteTableRows: async (params) => {
7782
+ return client.deleteTableRows({
7783
+ table: '${table.name}',
7784
+ ...params,
7785
+ }) as any
7786
+ },
7787
+ }
7788
+ `).join(`,
7789
+ `)}
7790
+ },
7791
+
7792
+ client,
7793
+ }
7794
+ }
7795
+ `;
7796
+ const clientWrapperPath = path19.join(project.path, ".adk", "client.ts");
7797
+ const formattedContent = await formatCode(content);
7798
+ const contentHash = crypto3.createHash("sha256").update(formattedContent.replace(/\/\/ Generated at: .+\n/, "")).digest("hex");
7799
+ try {
7800
+ const existingContent = await readFile3(clientWrapperPath, "utf-8");
7801
+ const existingHash = crypto3.createHash("sha256").update(existingContent.replace(/\/\/ Generated at: .+\n/, "")).digest("hex");
7802
+ if (contentHash === existingHash) {
7803
+ return;
7804
+ }
7805
+ } catch {}
7806
+ await createFile(clientWrapperPath, formattedContent);
7807
+ }
7808
+ // src/bot-generator/generator.ts
7809
+ import dedent from "dedent";
7810
+ import { existsSync as existsSync8 } from "fs";
7811
+ import fs18 from "fs/promises";
7812
+ import path38 from "path";
7813
+
7814
+ // src/generators/plugin-types.ts
7815
+ import { transforms as transforms2 } from "@botpress/sdk";
7816
+ import crypto4 from "crypto";
7817
+ import path20 from "path";
7818
+ init_utils();
7819
+ function stripRefs(schema) {
7820
+ if (typeof schema !== "object" || schema === null) {
7821
+ return schema;
7822
+ }
7823
+ if (schema.$ref) {
7824
+ return { type: "object", additionalProperties: true, "x-stripped-ref": schema.$ref };
7825
+ }
7826
+ const result = {};
7827
+ for (const [key, value] of Object.entries(schema)) {
7828
+ if (key === "$defs" || key === "definitions") {
7829
+ continue;
7830
+ }
7831
+ if (Array.isArray(value)) {
7832
+ result[key] = value.map((item) => typeof item === "object" && item !== null ? stripRefs(item) : item);
7833
+ } else if (typeof value === "object" && value !== null) {
7834
+ result[key] = stripRefs(value);
7835
+ } else {
7836
+ result[key] = value;
7837
+ }
7838
+ }
7839
+ return result;
7840
+ }
7841
+ function jsonSchemaToTypescript(schema) {
7842
+ const cleaned = stripRefs(schema);
7843
+ return transforms2.fromJSONSchema(cleaned).toTypescriptType();
7844
+ }
7845
+ var getPluginHash = (plugin) => {
7846
+ return crypto4.createHash("sha256").update(`${plugin.alias}|${plugin.definition?.id}|${plugin.definition?.version}|${plugin.definition?.updatedAt}`).digest("hex");
7847
+ };
7848
+ var getPascalAlias2 = (plugin) => pascalCase(getPluginAlias(plugin.alias));
7849
+ var getPluginNames = (plugin) => ({
7850
+ typings: {
7851
+ index: `Plugin_All_${getPascalAlias2(plugin)}`,
7852
+ actions: `Plugin_Actions_${getPascalAlias2(plugin)}`
7853
+ },
7854
+ paths: {
7855
+ index: path20.join(snakeCase(getPascalAlias2(plugin)), `index.ts`),
7856
+ actions: path20.join(snakeCase(getPascalAlias2(plugin)), `actions.ts`)
7857
+ }
7858
+ });
7859
+ async function generatePluginTypes(plugin) {
7860
+ const names = getPluginNames(plugin);
7861
+ const hash = getPluginHash(plugin);
7862
+ const rel = (to) => {
7863
+ const from = names.paths.index;
7864
+ return relative2(from, to).replace(/\.ts$/i, "");
7865
+ };
7866
+ let tIndex = `
7867
+ ////////////////////////////////////////////////////////
7868
+ // DO NOT EDIT THIS FILE DIRECTLY
7869
+ // This file is auto-generated from the Botpress ADK
7870
+ // ADK Version: ${ADK_VERSION}
7871
+ // Plugin: ${plugin.definition?.name}
7872
+ // Version: ${plugin.definition?.version}
7873
+ // File: ${names.paths.index}
7874
+ // Hash: ${hash}
7875
+ // Updated at: ${plugin.definition?.updatedAt}
7876
+ ////////////////////////////////////////////////////////
7877
+
7878
+ import { Plugin_Actions_${getPascalAlias2(plugin)} } from "${rel(names.paths.actions)}";
7879
+
7880
+ export * from "${rel(names.paths.actions)}";
7881
+
7882
+ export type Plugin_All_${getPascalAlias2(plugin)} = {
7883
+ actions: Plugin_Actions_${getPascalAlias2(plugin)};
7884
+ };
7885
+ `;
7886
+ let tActions = `
7887
+ ////////////////////////////////////////////////////////
7888
+ // DO NOT EDIT THIS FILE DIRECTLY
7889
+ // This file is auto-generated from the Botpress ADK
7890
+ // ADK Version: ${ADK_VERSION}
7891
+ // Plugin: ${plugin.definition?.name}
7892
+ // Version: ${plugin.definition?.version}
7893
+ // File: ${names.paths.actions}
7894
+ // Hash: ${hash}
7895
+ // Updated at: ${plugin.definition?.updatedAt}
7896
+ ////////////////////////////////////////////////////////
7897
+
7898
+ export type Plugin_Actions_${getPascalAlias2(plugin)} = {`;
7899
+ for (const [name, action] of Object.entries(plugin.definition.actions)) {
7900
+ const input = jsonSchemaToTypescript(action.input.schema);
7901
+ const output = jsonSchemaToTypescript(action.output.schema);
7902
+ tActions += `
7903
+ ${toMultilineComment(`Title: ${action.title || name}
7904
+ Description: ${action.description || "No description"}`)}
7905
+ "${name}": {
7906
+ input: ${input};
7907
+ output: ${output};
7908
+ },
7909
+ `;
7910
+ }
7911
+ tActions += `};`;
7912
+ return {
7913
+ names,
7914
+ files: {
7915
+ [names.paths.index]: await formatCode(tIndex),
7916
+ [names.paths.actions]: await formatCode(tActions)
7917
+ }
7918
+ };
7919
+ }
7920
+
7921
+ // src/generators/plugin-action-types.ts
7922
+ init_utils();
7923
+ init_fs();
7924
+ import path21 from "path";
7925
+ async function generatePluginActionTypes(project) {
7926
+ const content = `
7927
+ ////////////////////////////////////////////////////////
7928
+ // DO NOT EDIT THIS FILE DIRECTLY
7929
+ // This file is auto-generated from the Botpress ADK
7930
+ // ADK Version: ${ADK_VERSION}
7931
+ // Generated at: ${new Date().toISOString()}
7932
+ ////////////////////////////////////////////////////////
7933
+
7934
+ type Plugins = import("@botpress/runtime/_types/plugins").Plugins;
7935
+
7936
+ declare module "@botpress/runtime/_types/plugin-actions" {
7937
+
7938
+ export interface CallableAction<I, O> {
7939
+ (input: I): Promise<O>;
7940
+ }
7941
+
7942
+ type Callable<T> = T extends { input: infer I; output: infer O }
7943
+ ? CallableAction<I, O>
7944
+ : never;
7945
+
7946
+ type PluginsMap<T> = {
7947
+ [Plugin in keyof T]: T[Plugin] extends { actions: infer Actions }
7948
+ ? {
7949
+ actions: {
7950
+ [Action in keyof Actions]: Callable<Actions[Action]>;
7951
+ };
7389
7952
  }
7390
- `).join(`,
7391
- `)}
7392
- },
7953
+ : never;
7954
+ };
7393
7955
 
7394
- client,
7395
- }
7956
+ export type PluginActions = PluginsMap<Plugins>;
7396
7957
  }
7397
7958
  `;
7398
- const clientWrapperPath = path18.join(project.path, ".adk", "client.ts");
7399
- const formattedContent = await formatCode(content);
7400
- const contentHash = crypto3.createHash("sha256").update(formattedContent.replace(/\/\/ Generated at: .+\n/, "")).digest("hex");
7401
- try {
7402
- const existingContent = await readFile3(clientWrapperPath, "utf-8");
7403
- const existingHash = crypto3.createHash("sha256").update(existingContent.replace(/\/\/ Generated at: .+\n/, "")).digest("hex");
7404
- if (contentHash === existingHash) {
7405
- return;
7406
- }
7407
- } catch {}
7408
- await createFile(clientWrapperPath, formattedContent);
7959
+ const pluginActionTypesPath = path21.join(project.path, ".adk", "plugin-action-types.d.ts");
7960
+ await createFile(pluginActionTypesPath, await formatCode(content));
7409
7961
  }
7410
- // src/bot-generator/generator.ts
7411
- import dedent from "dedent";
7412
- import { existsSync as existsSync7 } from "fs";
7413
- import fs16 from "fs/promises";
7414
- import path34 from "path";
7415
7962
 
7416
7963
  // src/generators/interface-types.ts
7417
- import { transforms as transforms2 } from "@botpress/sdk";
7418
- import crypto4 from "crypto";
7419
- import path19 from "path";
7964
+ import { transforms as transforms3 } from "@botpress/sdk";
7965
+ import crypto5 from "crypto";
7966
+ import path22 from "path";
7420
7967
  init_utils();
7421
7968
  var sameMajorVersion = (a, b) => {
7422
7969
  const majorA = a.split(".")[0];
@@ -7428,7 +7975,7 @@ var getIntegrationInterface = (integration, int) => {
7428
7975
  };
7429
7976
  var getInterfaceHash = (int, integrations) => {
7430
7977
  const versions = integrations.filter((x) => !!getIntegrationInterface(x.definition, int)).map((x) => `${x.definition.id}|${x.definition.version}|${x.definition.updatedAt}|${x.alias}`).sort().join("|");
7431
- return crypto4.createHash("sha256").update(`${int.id}|${int.version}|${int.updatedAt}|${versions}`).digest("hex");
7978
+ return crypto5.createHash("sha256").update(`${int.id}|${int.version}|${int.updatedAt}|${versions}`).digest("hex");
7432
7979
  };
7433
7980
  var getInterfaceNames = (int) => ({
7434
7981
  name: camelCase(int.name),
@@ -7437,8 +7984,8 @@ var getInterfaceNames = (int) => ({
7437
7984
  actions: `Interface_Actions_${pascalCase(int.name)}`
7438
7985
  },
7439
7986
  paths: {
7440
- index: path19.join(snakeCase(int.name), `index.ts`),
7441
- actions: path19.join(snakeCase(int.name), `actions.ts`)
7987
+ index: path22.join(snakeCase(int.name), `index.ts`),
7988
+ actions: path22.join(snakeCase(int.name), `actions.ts`)
7442
7989
  }
7443
7990
  });
7444
7991
  async function generateInterfaceTypes(int, integrations) {
@@ -7490,12 +8037,12 @@ async function generateInterfaceTypes(int, integrations) {
7490
8037
  const entities = Object.entries(integrationInt.entities).reduce((acc, [entityName, value]) => {
7491
8038
  const entity = integration.entities[value.name];
7492
8039
  if (entity) {
7493
- acc[entityName] = transforms2.fromJSONSchema(entity.schema).title(entity.title || entityName).describe(entity.description || "No description");
8040
+ acc[entityName] = transforms3.fromJSONSchema(entity.schema).title(entity.title || entityName).describe(entity.description || "No description");
7494
8041
  }
7495
8042
  return acc;
7496
8043
  }, {});
7497
- const input = transforms2.fromJSONSchema(action.input.schema).dereference(entities).toTypescriptType();
7498
- const output = transforms2.fromJSONSchema(action.output.schema).dereference(entities).toTypescriptType();
8044
+ const input = transforms3.fromJSONSchema(action.input.schema).dereference(entities).toTypescriptType();
8045
+ const output = transforms3.fromJSONSchema(action.output.schema).dereference(entities).toTypescriptType();
7499
8046
  cActions.add(`"${alias}:${name}": "${alias}:${mapping}"`);
7500
8047
  iActions += `
7501
8048
  ${toMultilineComment(`Title: ${action.title || name}
@@ -7543,12 +8090,12 @@ Description: ${action.description || "No description"}`)}
7543
8090
  // src/generators/table-types.ts
7544
8091
  init_utils();
7545
8092
  init_fs();
7546
- import path20 from "path";
8093
+ import path23 from "path";
7547
8094
  async function generateTableTypes(project) {
7548
8095
  const tables = [];
7549
8096
  for (const tableRef of project.tables) {
7550
8097
  try {
7551
- const tablePath = path20.join(project.path, tableRef.path);
8098
+ const tablePath = path23.join(project.path, tableRef.path);
7552
8099
  const tableModule = await import(`${tablePath}?t=${Date.now()}`);
7553
8100
  const tableInstance = tableModule.default || tableModule[tableRef.export];
7554
8101
  if (tableInstance && tableInstance.columns) {
@@ -7634,14 +8181,14 @@ ${outputColumns}
7634
8181
  content += ` };
7635
8182
  }
7636
8183
  `;
7637
- const tableTypesPath = path20.join(project.path, ".adk", "table-types.d.ts");
8184
+ const tableTypesPath = path23.join(project.path, ".adk", "table-types.d.ts");
7638
8185
  await createFile(tableTypesPath, await formatCode(content));
7639
8186
  }
7640
8187
 
7641
8188
  // src/generators/trigger-types.ts
7642
8189
  init_utils();
7643
8190
  init_fs();
7644
- import path21 from "path";
8191
+ import path24 from "path";
7645
8192
  async function generateTriggerTypes(project) {
7646
8193
  const triggerEvents = {};
7647
8194
  for (const trigger of project.triggers) {
@@ -7681,19 +8228,19 @@ ${triggersType}
7681
8228
  };
7682
8229
  }
7683
8230
  `;
7684
- const triggerTypesPath = path21.join(project.path, ".adk", "trigger-types.d.ts");
8231
+ const triggerTypesPath = path24.join(project.path, ".adk", "trigger-types.d.ts");
7685
8232
  await createFile(triggerTypesPath, await formatCode(content));
7686
8233
  }
7687
8234
 
7688
8235
  // src/generators/state-types.ts
7689
8236
  init_utils();
7690
8237
  init_fs();
7691
- import path22 from "path";
8238
+ import path25 from "path";
7692
8239
  async function generateStateTypes(project) {
7693
8240
  let botStateType = "{}";
7694
8241
  let userStateType = "{}";
7695
8242
  try {
7696
- const configPath = path22.join(project.path, "agent.config.ts");
8243
+ const configPath = path25.join(project.path, "agent.config.ts");
7697
8244
  const configModule = await import(`${configPath}?t=${Date.now()}`);
7698
8245
  const config = configModule.default;
7699
8246
  if (config?.bot?.state) {
@@ -7724,14 +8271,14 @@ declare module "@botpress/runtime/_types/state" {
7724
8271
  export type UserState = ${userStateType};
7725
8272
  }
7726
8273
  `;
7727
- const stateTypesPath = path22.join(project.path, ".adk", "state-types.d.ts");
8274
+ const stateTypesPath = path25.join(project.path, ".adk", "state-types.d.ts");
7728
8275
  await createFile(stateTypesPath, await formatCode(content));
7729
8276
  }
7730
8277
 
7731
8278
  // src/generators/tag-types.ts
7732
8279
  init_utils();
7733
8280
  init_fs();
7734
- import path23 from "path";
8281
+ import path26 from "path";
7735
8282
  import { BUILT_IN_TAGS } from "@botpress/runtime/definition";
7736
8283
  function generateTagTypeString(builtInTags, configTags) {
7737
8284
  const builtInTagStrings = Object.entries(builtInTags).map(([key, tag]) => {
@@ -7770,7 +8317,7 @@ async function generateTagTypes(project) {
7770
8317
  let messageTagsType = "Record<string, string | undefined>";
7771
8318
  let workflowTagsType = "Record<string, string | undefined>";
7772
8319
  try {
7773
- const configPath = path23.join(project.path, "agent.config.ts");
8320
+ const configPath = path26.join(project.path, "agent.config.ts");
7774
8321
  const configModule = await import(`${configPath}?t=${Date.now()}`);
7775
8322
  const config = configModule.default;
7776
8323
  botTagsType = generateTagTypeString(BUILT_IN_TAGS.bot, config?.bot?.tags);
@@ -7816,18 +8363,18 @@ declare module "@botpress/runtime/_types/tags" {
7816
8363
  export type WorkflowTags = ${workflowTagsType};
7817
8364
  }
7818
8365
  `;
7819
- const tagTypesPath = path23.join(project.path, ".adk", "tag-types.d.ts");
8366
+ const tagTypesPath = path26.join(project.path, ".adk", "tag-types.d.ts");
7820
8367
  await createFile(tagTypesPath, await formatCode(content));
7821
8368
  }
7822
8369
 
7823
8370
  // src/generators/configuration-types.ts
7824
8371
  init_utils();
7825
8372
  init_fs();
7826
- import path24 from "path";
8373
+ import path27 from "path";
7827
8374
  async function generateConfigurationTypes(project) {
7828
8375
  let configurationType = "{}";
7829
8376
  try {
7830
- const configPath = path24.join(project.path, "agent.config.ts");
8377
+ const configPath = path27.join(project.path, "agent.config.ts");
7831
8378
  const configModule = await import(`${configPath}?t=${Date.now()}`);
7832
8379
  const config = configModule.default;
7833
8380
  if (config?.configuration?.schema) {
@@ -7851,14 +8398,14 @@ declare module "@botpress/runtime/_types/configuration" {
7851
8398
  export type Configuration = ${configurationType};
7852
8399
  }
7853
8400
  `;
7854
- const configTypesPath = path24.join(project.path, ".adk", "configuration-types.d.ts");
8401
+ const configTypesPath = path27.join(project.path, ".adk", "configuration-types.d.ts");
7855
8402
  await createFile(configTypesPath, await formatCode(content));
7856
8403
  }
7857
8404
 
7858
8405
  // src/generators/workflow-types.ts
7859
8406
  init_utils();
7860
8407
  init_fs();
7861
- import * as path25 from "path";
8408
+ import * as path28 from "path";
7862
8409
  import { BuiltInWorkflows as BuiltInWorkflows3 } from "@botpress/runtime/internal";
7863
8410
  function isBuiltinWorkflow2(name) {
7864
8411
  return !!Object.values(BuiltInWorkflows3).find((x) => x.name === name);
@@ -7870,7 +8417,7 @@ async function generateWorkflowTypes(project) {
7870
8417
  if (isBuiltinWorkflow2(workflowRef.definition.name)) {
7871
8418
  continue;
7872
8419
  }
7873
- const workflowPath = path25.join(project.path, workflowRef.path);
8420
+ const workflowPath = path28.join(project.path, workflowRef.path);
7874
8421
  const workflowModule = await import(`${workflowPath}?t=${Date.now()}`);
7875
8422
  const workflowInstance = workflowModule[workflowRef.export] || workflowModule.default;
7876
8423
  if (!workflowInstance) {
@@ -7917,14 +8464,14 @@ declare module "@botpress/runtime/_types/workflows" {
7917
8464
  ${typeDefinitions || " // No workflows defined yet"}
7918
8465
  };
7919
8466
  }`;
7920
- const workflowTypesPath = path25.join(project.path, ".adk", "workflow-types.d.ts");
8467
+ const workflowTypesPath = path28.join(project.path, ".adk", "workflow-types.d.ts");
7921
8468
  await createFile(workflowTypesPath, await formatCode(content));
7922
8469
  }
7923
8470
 
7924
8471
  // src/generators/conversation-types.ts
7925
8472
  init_utils();
7926
8473
  init_fs();
7927
- import path26 from "path";
8474
+ import path29 from "path";
7928
8475
  function hasConversationIdProperty(schema) {
7929
8476
  if (!schema || typeof schema !== "object") {
7930
8477
  return false;
@@ -7947,7 +8494,7 @@ async function generateConversationTypes(project) {
7947
8494
  const conversationTypes = {};
7948
8495
  for (const conversationRef of project.conversations) {
7949
8496
  try {
7950
- const conversationPath = path26.join(project.path, conversationRef.path);
8497
+ const conversationPath = path29.join(project.path, conversationRef.path);
7951
8498
  const conversationModule = await import(`${conversationPath}?t=${Date.now()}`);
7952
8499
  const conversationInstance = conversationModule[conversationRef.export] || conversationModule.default;
7953
8500
  if (!conversationInstance) {
@@ -8033,14 +8580,14 @@ ${routableEventsDefinitions || " // No routable events found"}
8033
8580
  };
8034
8581
  }
8035
8582
  `;
8036
- const conversationTypesPath = path26.join(project.path, ".adk", "conversation-types.d.ts");
8583
+ const conversationTypesPath = path29.join(project.path, ".adk", "conversation-types.d.ts");
8037
8584
  await createFile(conversationTypesPath, await formatCode(content));
8038
8585
  }
8039
8586
 
8040
8587
  // src/generators/event-types.ts
8041
8588
  init_utils();
8042
8589
  init_fs();
8043
- import path27 from "path";
8590
+ import path30 from "path";
8044
8591
  async function generateEventTypes(project) {
8045
8592
  const defaultEvents = ["register: {}"];
8046
8593
  const integrationEvents = [];
@@ -8092,7 +8639,7 @@ ${allEvents.map((e) => ` ${e}`).join(`
8092
8639
  export type EventPayload<T extends EventName> = Events[T];
8093
8640
  }
8094
8641
  `;
8095
- const eventTypesPath = path27.join(project.path, ".adk", "event-types.d.ts");
8642
+ const eventTypesPath = path30.join(project.path, ".adk", "event-types.d.ts");
8096
8643
  await createFile(eventTypesPath, await formatCode(content));
8097
8644
  }
8098
8645
 
@@ -8101,8 +8648,8 @@ init_fs();
8101
8648
 
8102
8649
  // src/utils/link-sdk.ts
8103
8650
  import { existsSync as existsSync3, realpathSync } from "fs";
8104
- import fs12 from "fs/promises";
8105
- import path28 from "path";
8651
+ import fs13 from "fs/promises";
8652
+ import path31 from "path";
8106
8653
  function findPackage(name, startDir) {
8107
8654
  let current;
8108
8655
  try {
@@ -8110,17 +8657,17 @@ function findPackage(name, startDir) {
8110
8657
  } catch {
8111
8658
  current = startDir;
8112
8659
  }
8113
- while (current !== path28.dirname(current)) {
8114
- const pkgPath = path28.join(current, "node_modules", name);
8660
+ while (current !== path31.dirname(current)) {
8661
+ const pkgPath = path31.join(current, "node_modules", name);
8115
8662
  if (existsSync3(pkgPath)) {
8116
8663
  return pkgPath;
8117
8664
  }
8118
- current = path28.dirname(current);
8665
+ current = path31.dirname(current);
8119
8666
  }
8120
8667
  return null;
8121
8668
  }
8122
8669
  async function linkSdk(agentDir, botDir) {
8123
- const targetSdkPath = path28.join(botDir, "node_modules", "@botpress", "sdk");
8670
+ const targetSdkPath = path31.join(botDir, "node_modules", "@botpress", "sdk");
8124
8671
  if (existsSync3(targetSdkPath)) {
8125
8672
  return;
8126
8673
  }
@@ -8134,17 +8681,17 @@ async function linkSdk(agentDir, botDir) {
8134
8681
  console.warn(`Warning: Could not find @botpress/sdk from @botpress/runtime location (${runtimePath})`);
8135
8682
  return;
8136
8683
  }
8137
- const targetBotpressDir = path28.join(botDir, "node_modules", "@botpress");
8138
- await fs12.mkdir(targetBotpressDir, { recursive: true });
8684
+ const targetBotpressDir = path31.join(botDir, "node_modules", "@botpress");
8685
+ await fs13.mkdir(targetBotpressDir, { recursive: true });
8139
8686
  const symlinkType = process.platform === "win32" ? "junction" : undefined;
8140
- await fs12.symlink(sdkPath, targetSdkPath, symlinkType);
8687
+ await fs13.symlink(sdkPath, targetSdkPath, symlinkType);
8141
8688
  }
8142
8689
 
8143
8690
  // src/bot-generator/dev-id-manager.ts
8144
- import path29 from "path";
8145
- import fs13 from "fs/promises";
8691
+ import path32 from "path";
8692
+ import fs14 from "fs/promises";
8146
8693
  import { existsSync as existsSync4 } from "fs";
8147
- import { Client as Client13 } from "@botpress/client";
8694
+ import { Client as Client14 } from "@botpress/client";
8148
8695
  class DevIdManager {
8149
8696
  projectPath;
8150
8697
  botProjectPath;
@@ -8153,7 +8700,7 @@ class DevIdManager {
8153
8700
  constructor(projectPath, botProjectPath) {
8154
8701
  this.projectPath = projectPath;
8155
8702
  this.botProjectPath = botProjectPath;
8156
- this.projectCachePath = path29.join(botProjectPath, ".botpress", "project.cache.json");
8703
+ this.projectCachePath = path32.join(botProjectPath, ".botpress", "project.cache.json");
8157
8704
  }
8158
8705
  async getClient() {
8159
8706
  if (!this.client) {
@@ -8163,7 +8710,7 @@ class DevIdManager {
8163
8710
  if (!workspaceId) {
8164
8711
  throw new Error('No workspace ID found in agent.json or current profile. Please login again with "adk login"');
8165
8712
  }
8166
- this.client = new Client13({
8713
+ this.client = new Client14({
8167
8714
  token: credentials.token,
8168
8715
  apiUrl: credentials.apiUrl,
8169
8716
  workspaceId,
@@ -8180,7 +8727,7 @@ class DevIdManager {
8180
8727
  async readProjectCache() {
8181
8728
  try {
8182
8729
  if (existsSync4(this.projectCachePath)) {
8183
- const content = await fs13.readFile(this.projectCachePath, "utf-8");
8730
+ const content = await fs14.readFile(this.projectCachePath, "utf-8");
8184
8731
  return JSON.parse(content);
8185
8732
  }
8186
8733
  } catch (error) {
@@ -8190,8 +8737,8 @@ class DevIdManager {
8190
8737
  }
8191
8738
  async saveProjectCache(cache2) {
8192
8739
  try {
8193
- await fs13.mkdir(path29.dirname(this.projectCachePath), { recursive: true });
8194
- await fs13.writeFile(this.projectCachePath, JSON.stringify(cache2, null, 2));
8740
+ await fs14.mkdir(path32.dirname(this.projectCachePath), { recursive: true });
8741
+ await fs14.writeFile(this.projectCachePath, JSON.stringify(cache2, null, 2));
8195
8742
  } catch (error) {
8196
8743
  console.error("Error saving project.cache.json:", error);
8197
8744
  }
@@ -8239,8 +8786,8 @@ class DevIdManager {
8239
8786
  }
8240
8787
 
8241
8788
  // src/bot-generator/integration-sync.ts
8242
- import path30 from "path";
8243
- import fs14 from "fs/promises";
8789
+ import path33 from "path";
8790
+ import fs15 from "fs/promises";
8244
8791
  import { existsSync as existsSync5 } from "fs";
8245
8792
  class IntegrationSync {
8246
8793
  projectPath;
@@ -8249,7 +8796,7 @@ class IntegrationSync {
8249
8796
  constructor(projectPath, botProjectPath) {
8250
8797
  this.projectPath = projectPath;
8251
8798
  this.botProjectPath = botProjectPath;
8252
- this.bpModulesPath = path30.join(botProjectPath, "bp_modules");
8799
+ this.bpModulesPath = path33.join(botProjectPath, "bp_modules");
8253
8800
  }
8254
8801
  async parseIntegrations() {
8255
8802
  const project = await AgentProject.load(this.projectPath);
@@ -8280,16 +8827,16 @@ class IntegrationSync {
8280
8827
  return integrations;
8281
8828
  }
8282
8829
  async isIntegrationSynced(integration) {
8283
- const targetFolder = path30.join(this.bpModulesPath, `integration_${integration.alias}`);
8830
+ const targetFolder = path33.join(this.bpModulesPath, `integration_${integration.alias}`);
8284
8831
  if (!existsSync5(targetFolder)) {
8285
8832
  return false;
8286
8833
  }
8287
8834
  try {
8288
- const indexPath = path30.join(targetFolder, "index.ts");
8835
+ const indexPath = path33.join(targetFolder, "index.ts");
8289
8836
  if (!existsSync5(indexPath)) {
8290
8837
  return false;
8291
8838
  }
8292
- const indexContent = await fs14.readFile(indexPath, "utf-8");
8839
+ const indexContent = await fs15.readFile(indexPath, "utf-8");
8293
8840
  const versionMatch = indexContent.match(/version:\s*["']([^"']+)["']/);
8294
8841
  if (!versionMatch) {
8295
8842
  return false;
@@ -8317,20 +8864,20 @@ class IntegrationSync {
8317
8864
  await command.output();
8318
8865
  }
8319
8866
  async renameIntegrationFolder(integration) {
8320
- const sourceFolder = path30.join(this.bpModulesPath, integration.name.replace("/", "-"));
8321
- const targetFolder = path30.join(this.bpModulesPath, `integration_${integration.alias}`);
8867
+ const sourceFolder = path33.join(this.bpModulesPath, integration.name.replace("/", "-"));
8868
+ const targetFolder = path33.join(this.bpModulesPath, `integration_${integration.alias}`);
8322
8869
  if (!existsSync5(sourceFolder)) {
8323
8870
  throw new Error(`Integration folder not found: ${sourceFolder}`);
8324
8871
  }
8325
8872
  if (existsSync5(targetFolder)) {
8326
- await fs14.rm(targetFolder, { recursive: true, force: true });
8873
+ await fs15.rm(targetFolder, { recursive: true, force: true });
8327
8874
  }
8328
- await fs14.rename(sourceFolder, targetFolder);
8875
+ await fs15.rename(sourceFolder, targetFolder);
8329
8876
  }
8330
8877
  async removeIntegrationFolder(alias) {
8331
- const targetFolder = path30.join(this.bpModulesPath, `integration_${alias}`);
8878
+ const targetFolder = path33.join(this.bpModulesPath, `integration_${alias}`);
8332
8879
  if (existsSync5(targetFolder)) {
8333
- await fs14.rm(targetFolder, { recursive: true, force: true });
8880
+ await fs15.rm(targetFolder, { recursive: true, force: true });
8334
8881
  }
8335
8882
  }
8336
8883
  async syncIntegrations() {
@@ -8340,7 +8887,7 @@ class IntegrationSync {
8340
8887
  if (integrations.length === 0) {
8341
8888
  return { synced, errors };
8342
8889
  }
8343
- await fs14.mkdir(this.bpModulesPath, { recursive: true });
8890
+ await fs15.mkdir(this.bpModulesPath, { recursive: true });
8344
8891
  for (const integration of integrations) {
8345
8892
  try {
8346
8893
  const isAlreadySynced = await this.isIntegrationSynced(integration);
@@ -8362,8 +8909,8 @@ class IntegrationSync {
8362
8909
  }
8363
8910
 
8364
8911
  // src/bot-generator/interface-sync.ts
8365
- import path31 from "path";
8366
- import fs15 from "fs/promises";
8912
+ import path34 from "path";
8913
+ import fs16 from "fs/promises";
8367
8914
  import { existsSync as existsSync6 } from "fs";
8368
8915
  init_constants();
8369
8916
  class InterfaceSync {
@@ -8373,7 +8920,7 @@ class InterfaceSync {
8373
8920
  constructor(projectPath, botProjectPath) {
8374
8921
  this.projectPath = projectPath;
8375
8922
  this.botProjectPath = botProjectPath;
8376
- this.bpModulesPath = path31.join(botProjectPath, "bp_modules");
8923
+ this.bpModulesPath = path34.join(botProjectPath, "bp_modules");
8377
8924
  }
8378
8925
  async parseInterfaces() {
8379
8926
  const interfaces = [];
@@ -8391,16 +8938,16 @@ class InterfaceSync {
8391
8938
  return interfaces;
8392
8939
  }
8393
8940
  async isInterfaceSynced(interfaceInfo) {
8394
- const targetFolder = path31.join(this.bpModulesPath, `interface_${pascalCase(interfaceInfo.alias)}`);
8941
+ const targetFolder = path34.join(this.bpModulesPath, `interface_${pascalCase(interfaceInfo.alias)}`);
8395
8942
  if (!existsSync6(targetFolder)) {
8396
8943
  return false;
8397
8944
  }
8398
8945
  try {
8399
- const indexPath = path31.join(targetFolder, "index.ts");
8946
+ const indexPath = path34.join(targetFolder, "index.ts");
8400
8947
  if (!existsSync6(indexPath)) {
8401
8948
  return false;
8402
8949
  }
8403
- const indexContent = await fs15.readFile(indexPath, "utf-8");
8950
+ const indexContent = await fs16.readFile(indexPath, "utf-8");
8404
8951
  const versionMatch = indexContent.match(/version:\s*["']([^"']+)["']/);
8405
8952
  if (!versionMatch) {
8406
8953
  return false;
@@ -8442,20 +8989,20 @@ class InterfaceSync {
8442
8989
  });
8443
8990
  }
8444
8991
  async renameInterfaceFolder(interfaceInfo) {
8445
- const sourceFolder = path31.join(this.bpModulesPath, interfaceInfo.name);
8446
- const targetFolder = path31.join(this.bpModulesPath, `interface_${pascalCase(interfaceInfo.alias)}`);
8992
+ const sourceFolder = path34.join(this.bpModulesPath, interfaceInfo.name);
8993
+ const targetFolder = path34.join(this.bpModulesPath, `interface_${pascalCase(interfaceInfo.alias)}`);
8447
8994
  if (!existsSync6(sourceFolder)) {
8448
8995
  throw new Error(`Interface folder not found: ${sourceFolder}`);
8449
8996
  }
8450
8997
  if (existsSync6(targetFolder)) {
8451
- await fs15.rm(targetFolder, { recursive: true, force: true });
8998
+ await fs16.rm(targetFolder, { recursive: true, force: true });
8452
8999
  }
8453
- await fs15.rename(sourceFolder, targetFolder);
9000
+ await fs16.rename(sourceFolder, targetFolder);
8454
9001
  }
8455
9002
  async removeInterfaceFolder(alias) {
8456
- const targetFolder = path31.join(this.bpModulesPath, `interface_${pascalCase(alias)}`);
9003
+ const targetFolder = path34.join(this.bpModulesPath, `interface_${pascalCase(alias)}`);
8457
9004
  if (existsSync6(targetFolder)) {
8458
- await fs15.rm(targetFolder, { recursive: true, force: true });
9005
+ await fs16.rm(targetFolder, { recursive: true, force: true });
8459
9006
  }
8460
9007
  }
8461
9008
  async syncInterfaces() {
@@ -8465,7 +9012,7 @@ class InterfaceSync {
8465
9012
  if (interfaces.length === 0) {
8466
9013
  return { synced, errors };
8467
9014
  }
8468
- await fs15.mkdir(this.bpModulesPath, { recursive: true });
9015
+ await fs16.mkdir(this.bpModulesPath, { recursive: true });
8469
9016
  for (const interfaceInfo of interfaces) {
8470
9017
  try {
8471
9018
  const isAlreadySynced = await this.isInterfaceSynced(interfaceInfo);
@@ -8486,9 +9033,124 @@ class InterfaceSync {
8486
9033
  }
8487
9034
  }
8488
9035
 
9036
+ // src/bot-generator/plugin-sync.ts
9037
+ import path35 from "path";
9038
+ import fs17 from "fs/promises";
9039
+ import { existsSync as existsSync7 } from "fs";
9040
+ class PluginSync {
9041
+ projectPath;
9042
+ botProjectPath;
9043
+ bpModulesPath;
9044
+ constructor(projectPath, botProjectPath) {
9045
+ this.projectPath = projectPath;
9046
+ this.botProjectPath = botProjectPath;
9047
+ this.bpModulesPath = path35.join(botProjectPath, "bp_modules");
9048
+ }
9049
+ async parsePlugins() {
9050
+ const project = await AgentProject.load(this.projectPath);
9051
+ const dependencies = project.dependencies;
9052
+ if (!dependencies?.plugins) {
9053
+ return [];
9054
+ }
9055
+ const plugins = [];
9056
+ for (const [alias, config] of Object.entries(dependencies.plugins)) {
9057
+ const version = config.version;
9058
+ const parts = version.split("@");
9059
+ const name = parts[0] || "";
9060
+ plugins.push({
9061
+ alias,
9062
+ name,
9063
+ version: parts[1] || "latest",
9064
+ fullVersion: version
9065
+ });
9066
+ }
9067
+ return plugins;
9068
+ }
9069
+ async isPluginSynced(plugin) {
9070
+ const targetFolder = path35.join(this.bpModulesPath, `plugin_${plugin.alias}`);
9071
+ if (!existsSync7(targetFolder)) {
9072
+ return false;
9073
+ }
9074
+ try {
9075
+ const indexPath = path35.join(targetFolder, "index.ts");
9076
+ if (!existsSync7(indexPath)) {
9077
+ return false;
9078
+ }
9079
+ const indexContent = await fs17.readFile(indexPath, "utf-8");
9080
+ const versionMatch = indexContent.match(/version:\s*["']([^"']+)["']/);
9081
+ if (!versionMatch) {
9082
+ return false;
9083
+ }
9084
+ const installedVersion = versionMatch[1];
9085
+ return installedVersion === plugin.version;
9086
+ } catch {
9087
+ return false;
9088
+ }
9089
+ }
9090
+ async installPlugin(plugin) {
9091
+ const credentials = await auth.getActiveCredentials();
9092
+ const project = await AgentProject.load(this.projectPath);
9093
+ const workspaceId = project.agentInfo?.workspaceId || credentials.workspaceId;
9094
+ if (!workspaceId) {
9095
+ throw new Error('No workspace ID found. Please login with "adk login"');
9096
+ }
9097
+ const command = new BpAddCommand({
9098
+ resource: `plugin:${plugin.fullVersion}`,
9099
+ botPath: this.botProjectPath,
9100
+ workspaceId,
9101
+ credentials
9102
+ });
9103
+ await command.run();
9104
+ await command.output();
9105
+ }
9106
+ async renamePluginFolder(plugin) {
9107
+ const sourceFolder = path35.join(this.bpModulesPath, plugin.name.replace("/", "-"));
9108
+ const targetFolder = path35.join(this.bpModulesPath, `plugin_${plugin.alias}`);
9109
+ if (!existsSync7(sourceFolder)) {
9110
+ throw new Error(`Plugin folder not found: ${sourceFolder}`);
9111
+ }
9112
+ if (existsSync7(targetFolder)) {
9113
+ await fs17.rm(targetFolder, { recursive: true, force: true });
9114
+ }
9115
+ await fs17.rename(sourceFolder, targetFolder);
9116
+ }
9117
+ async removePluginFolder(alias) {
9118
+ const targetFolder = path35.join(this.bpModulesPath, `plugin_${alias}`);
9119
+ if (existsSync7(targetFolder)) {
9120
+ await fs17.rm(targetFolder, { recursive: true, force: true });
9121
+ }
9122
+ }
9123
+ async syncPlugins() {
9124
+ const plugins = await this.parsePlugins();
9125
+ const synced = [];
9126
+ const errors = [];
9127
+ if (plugins.length === 0) {
9128
+ return { synced, errors };
9129
+ }
9130
+ await fs17.mkdir(this.bpModulesPath, { recursive: true });
9131
+ for (const plugin of plugins) {
9132
+ try {
9133
+ const isAlreadySynced = await this.isPluginSynced(plugin);
9134
+ if (isAlreadySynced) {
9135
+ synced.push(plugin);
9136
+ continue;
9137
+ }
9138
+ await this.removePluginFolder(plugin.alias);
9139
+ await this.installPlugin(plugin);
9140
+ await this.renamePluginFolder(plugin);
9141
+ synced.push(plugin);
9142
+ } catch (error) {
9143
+ const errorMsg = error instanceof Error ? error.message : String(error);
9144
+ errors.push({ alias: plugin.alias, error: errorMsg });
9145
+ }
9146
+ }
9147
+ return { synced, errors };
9148
+ }
9149
+ }
9150
+
8489
9151
  // src/bot-generator/generator.ts
8490
9152
  init_utils();
8491
- import { transforms as transforms3 } from "@botpress/sdk";
9153
+ import { transforms as transforms4 } from "@botpress/sdk";
8492
9154
  init_constants();
8493
9155
  import { BuiltInActions as BuiltInActions2, BuiltInWorkflows as BuiltInWorkflows4, Primitives as Primitives3 } from "@botpress/runtime/internal";
8494
9156
  import { BUILT_IN_TAGS as BUILT_IN_TAGS2 } from "@botpress/runtime/definition";
@@ -8500,7 +9162,7 @@ function isBuiltinAction(name) {
8500
9162
  return !!Object.values(BuiltInActions2).find((x) => x.name === name);
8501
9163
  }
8502
9164
  function getImportPath(from, to) {
8503
- return path34.relative(path34.dirname(from), to).replace(/\.ts$/, "").replace(/\\/g, "/");
9165
+ return path38.relative(path38.dirname(from), to).replace(/\.ts$/, "").replace(/\\/g, "/");
8504
9166
  }
8505
9167
 
8506
9168
  class BotGenerator {
@@ -8509,21 +9171,21 @@ class BotGenerator {
8509
9171
  adkCommand;
8510
9172
  callbacks;
8511
9173
  constructor(options) {
8512
- this.projectPath = path34.resolve(options.projectPath);
8513
- this.outputPath = path34.resolve(options.outputPath || path34.join(this.projectPath, ".adk"));
9174
+ this.projectPath = path38.resolve(options.projectPath);
9175
+ this.outputPath = path38.resolve(options.outputPath || path38.join(this.projectPath, ".adk"));
8514
9176
  this.adkCommand = options.adkCommand;
8515
9177
  this.callbacks = options.callbacks;
8516
9178
  }
8517
9179
  async listFilesRecursive(rootDir) {
8518
9180
  try {
8519
- if (!existsSync7(rootDir))
9181
+ if (!existsSync8(rootDir))
8520
9182
  return [];
8521
9183
  const result = [];
8522
9184
  const walk = async (dir, relativeBase) => {
8523
- const entries = await fs16.readdir(dir, { withFileTypes: true });
9185
+ const entries = await fs18.readdir(dir, { withFileTypes: true });
8524
9186
  for (const entry of entries) {
8525
- const abs = path34.join(dir, entry.name);
8526
- const rel = path34.join(relativeBase, entry.name);
9187
+ const abs = path38.join(dir, entry.name);
9188
+ const rel = path38.join(relativeBase, entry.name);
8527
9189
  if (entry.isDirectory()) {
8528
9190
  await walk(abs, rel);
8529
9191
  } else {
@@ -8538,20 +9200,20 @@ class BotGenerator {
8538
9200
  }
8539
9201
  }
8540
9202
  async removeEmptyDirectories(rootDir) {
8541
- if (!existsSync7(rootDir))
9203
+ if (!existsSync8(rootDir))
8542
9204
  return;
8543
9205
  const removeIfEmpty = async (dir) => {
8544
- const entries = await fs16.readdir(dir, { withFileTypes: true });
9206
+ const entries = await fs18.readdir(dir, { withFileTypes: true });
8545
9207
  for (const entry of entries) {
8546
9208
  if (entry.isDirectory()) {
8547
- const subdir = path34.join(dir, entry.name);
9209
+ const subdir = path38.join(dir, entry.name);
8548
9210
  await removeIfEmpty(subdir);
8549
9211
  }
8550
9212
  }
8551
- const after = await fs16.readdir(dir);
9213
+ const after = await fs18.readdir(dir);
8552
9214
  if (after.length === 0 && dir !== rootDir) {
8553
9215
  try {
8554
- await fs16.rmdir(dir, { recursive: false });
9216
+ await fs18.rmdir(dir, { recursive: false });
8555
9217
  } catch {}
8556
9218
  }
8557
9219
  };
@@ -8559,11 +9221,13 @@ class BotGenerator {
8559
9221
  }
8560
9222
  async generate() {
8561
9223
  const project = await AgentProject.load(this.projectPath);
8562
- await fs16.mkdir(this.outputPath, { recursive: true });
9224
+ await fs18.mkdir(this.outputPath, { recursive: true });
8563
9225
  await this.generateBotDefinition();
8564
9226
  await this.generateIntegrationsDefinition();
9227
+ await this.generatePluginsDefinition();
8565
9228
  await this.generateInterfacesDefinition();
8566
9229
  await this.generateIntegrationsTypes();
9230
+ await this.generatePluginsTypes();
8567
9231
  await this.generateInterfacesTypes();
8568
9232
  await this.generateTableTypes();
8569
9233
  await this.generateTriggerTypes();
@@ -8575,6 +9239,7 @@ class BotGenerator {
8575
9239
  await this.generateActionTypes();
8576
9240
  await this.generateEventTypes();
8577
9241
  await this.generateIntegrationActionTypes();
9242
+ await this.generatePluginActionTypes();
8578
9243
  await this.generateRuntimeTypes();
8579
9244
  await this.generateClientWrapper();
8580
9245
  await this.generateBotIndex();
@@ -8589,19 +9254,19 @@ class BotGenerator {
8589
9254
  workspaceId: project.agentInfo?.workspaceId
8590
9255
  });
8591
9256
  const integrations = await manager3.loadIntegrations(project.dependencies || {});
8592
- const integrationsDir = path34.join(this.projectPath, ".adk", "integrations");
9257
+ const integrationsDir = path38.join(this.projectPath, ".adk", "integrations");
8593
9258
  const existingIntegrationFiles = await this.listFilesRecursive(integrationsDir);
8594
9259
  let aliases = new Set;
8595
9260
  let files = new Set;
8596
9261
  for (const integration of integrations.integrations) {
8597
9262
  if (integration.definition) {
8598
9263
  const types6 = await generateIntegrationTypes(integration);
8599
- const importPath = `./${path34.join("integrations", types6.names.paths.index).replace(/\\/g, "/")}`;
9264
+ const importPath = `./${path38.join("integrations", types6.names.paths.index).replace(/\\/g, "/")}`;
8600
9265
  aliases.add(`"${integration.alias}": import("${importPath}").${types6.names.typings.index}`);
8601
9266
  for (const [filePath, content] of Object.entries(types6.files)) {
8602
- const fullPath = path34.join(this.projectPath, ".adk", "integrations", filePath);
8603
- const dir = path34.dirname(fullPath);
8604
- await fs16.mkdir(dir, { recursive: true });
9267
+ const fullPath = path38.join(this.projectPath, ".adk", "integrations", filePath);
9268
+ const dir = path38.dirname(fullPath);
9269
+ await fs18.mkdir(dir, { recursive: true });
8605
9270
  await createFile(fullPath, content);
8606
9271
  files.add(filePath);
8607
9272
  }
@@ -8621,18 +9286,68 @@ class BotGenerator {
8621
9286
  };
8622
9287
  }
8623
9288
  `;
8624
- await createFile(path34.join(this.projectPath, ".adk", "integrations-types.d.ts"), await formatCode(types5));
9289
+ await createFile(path38.join(this.projectPath, ".adk", "integrations-types.d.ts"), await formatCode(types5));
8625
9290
  const staleIntegrationFiles = existingIntegrationFiles.filter((f) => !files.has(f));
8626
9291
  if (staleIntegrationFiles.length > 0) {
8627
9292
  for (const rel of staleIntegrationFiles) {
8628
- const abs = path34.join(integrationsDir, rel);
9293
+ const abs = path38.join(integrationsDir, rel);
8629
9294
  try {
8630
- await fs16.rm(abs, { force: true });
9295
+ await fs18.rm(abs, { force: true });
8631
9296
  } catch {}
8632
9297
  }
8633
9298
  }
8634
9299
  await this.removeEmptyDirectories(integrationsDir);
8635
9300
  }
9301
+ async generatePluginsTypes() {
9302
+ const project = await AgentProject.load(this.projectPath);
9303
+ const manager3 = new PluginManager({
9304
+ workspaceId: project.agentInfo?.workspaceId
9305
+ });
9306
+ const result = await manager3.loadPlugins(project.dependencies || {});
9307
+ const pluginsDir = path38.join(this.projectPath, ".adk", "plugins");
9308
+ const existingPluginFiles = await this.listFilesRecursive(pluginsDir);
9309
+ let aliases = new Set;
9310
+ let files = new Set;
9311
+ for (const plugin of result.plugins) {
9312
+ if (plugin.definition) {
9313
+ const types6 = await generatePluginTypes(plugin);
9314
+ const importPath = `./${path38.join("plugins", types6.names.paths.index).replace(/\\/g, "/")}`;
9315
+ aliases.add(`"${plugin.alias}": import("${importPath}").${types6.names.typings.index}`);
9316
+ for (const [filePath, content] of Object.entries(types6.files)) {
9317
+ const fullPath = path38.join(this.projectPath, ".adk", "plugins", filePath);
9318
+ const dir = path38.dirname(fullPath);
9319
+ await fs18.mkdir(dir, { recursive: true });
9320
+ await createFile(fullPath, content);
9321
+ files.add(filePath);
9322
+ }
9323
+ }
9324
+ }
9325
+ const types5 = `
9326
+ ////////////////////////////////////////////////////////
9327
+ // DO NOT EDIT THIS FILE DIRECTLY
9328
+ // This file is auto-generated from the Botpress ADK
9329
+ // ADK Version: ${ADK_VERSION}
9330
+ // Generated at: ${new Date().toISOString()}
9331
+ ////////////////////////////////////////////////////////
9332
+
9333
+ declare module "@botpress/runtime/_types/plugins" {
9334
+ export type Plugins = {
9335
+ ${Array.from(aliases).join(`, `)}
9336
+ };
9337
+ }
9338
+ `;
9339
+ await createFile(path38.join(this.projectPath, ".adk", "plugins-types.d.ts"), await formatCode(types5));
9340
+ const stalePluginFiles = existingPluginFiles.filter((f) => !files.has(f));
9341
+ if (stalePluginFiles.length > 0) {
9342
+ for (const rel of stalePluginFiles) {
9343
+ const abs = path38.join(pluginsDir, rel);
9344
+ try {
9345
+ await fs18.rm(abs, { force: true });
9346
+ } catch {}
9347
+ }
9348
+ }
9349
+ await this.removeEmptyDirectories(pluginsDir);
9350
+ }
8636
9351
  async generateTableTypes() {
8637
9352
  const project = await AgentProject.load(this.projectPath);
8638
9353
  await generateTableTypes(project);
@@ -8675,6 +9390,10 @@ class BotGenerator {
8675
9390
  const { generateIntegrationActionTypes: generateIntegrationActionTypes2 } = await Promise.resolve().then(() => (init_integration_action_types(), exports_integration_action_types));
8676
9391
  await generateIntegrationActionTypes2(project);
8677
9392
  }
9393
+ async generatePluginActionTypes() {
9394
+ const project = await AgentProject.load(this.projectPath);
9395
+ await generatePluginActionTypes(project);
9396
+ }
8678
9397
  async generateClientWrapper() {
8679
9398
  const project = await AgentProject.load(this.projectPath);
8680
9399
  await generateClientWrapper(project);
@@ -8698,7 +9417,7 @@ class BotGenerator {
8698
9417
  let botStateType = "{}";
8699
9418
  let userStateType = "{}";
8700
9419
  try {
8701
- const configPath = path34.join(project.path, "agent.config.ts");
9420
+ const configPath = path38.join(project.path, "agent.config.ts");
8702
9421
  const configModule = await import(`${configPath}?t=${Date.now()}`);
8703
9422
  const config = configModule.default;
8704
9423
  if (config?.bot?.state) {
@@ -8734,7 +9453,7 @@ declare module "@botpress/runtime/_types/state" {
8734
9453
  export type UserState = ${userStateType};
8735
9454
  }
8736
9455
  `;
8737
- await createFile(path34.join(this.projectPath, ".adk", "runtime.d.ts"), await formatCode(types5));
9456
+ await createFile(path38.join(this.projectPath, ".adk", "runtime.d.ts"), await formatCode(types5));
8738
9457
  }
8739
9458
  async generateInterfacesTypes() {
8740
9459
  const project = await AgentProject.load(this.projectPath);
@@ -8742,7 +9461,7 @@ declare module "@botpress/runtime/_types/state" {
8742
9461
  workspaceId: project.agentInfo?.workspaceId
8743
9462
  });
8744
9463
  const manager3 = new InterfaceManager;
8745
- const interfacesDir = path34.join(this.projectPath, ".adk", "interfaces");
9464
+ const interfacesDir = path38.join(this.projectPath, ".adk", "interfaces");
8746
9465
  const existingInterfaceFiles = await this.listFilesRecursive(interfacesDir);
8747
9466
  const interfaces = await manager3.loadInterfaces(project.dependencies || {}).then((result) => result.interfaces.filter((int) => int.definition).map((x) => x.definition));
8748
9467
  const integrationsWithAlias = await integrationManager.loadIntegrations(project.dependencies || {}).then((result) => result.integrations.filter((int) => int.enabled && int.definition).map((x) => ({ alias: x.alias, definition: x.definition })));
@@ -8751,12 +9470,12 @@ declare module "@botpress/runtime/_types/state" {
8751
9470
  let files = new Set;
8752
9471
  for (const int of interfaces) {
8753
9472
  const types6 = await generateInterfaceTypes(int, integrationsWithAlias);
8754
- imports.add(`import { ${types6.names.typings.index} } from "./${path34.join("interfaces", types6.names.paths.index).replace(/\\/g, "/")}";`);
9473
+ imports.add(`import { ${types6.names.typings.index} } from "./${path38.join("interfaces", types6.names.paths.index).replace(/\\/g, "/")}";`);
8755
9474
  aliases.add(`"${types6.names.name}": ${types6.names.typings.index}`);
8756
9475
  for (const [filePath, content] of Object.entries(types6.files)) {
8757
- const fullPath = path34.join(this.projectPath, ".adk", "interfaces", filePath);
8758
- const dir = path34.dirname(fullPath);
8759
- await fs16.mkdir(dir, { recursive: true });
9476
+ const fullPath = path38.join(this.projectPath, ".adk", "interfaces", filePath);
9477
+ const dir = path38.dirname(fullPath);
9478
+ await fs18.mkdir(dir, { recursive: true });
8760
9479
  await createFile(fullPath, content);
8761
9480
  files.add(filePath);
8762
9481
  }
@@ -8792,14 +9511,14 @@ declare module "@botpress/runtime/_types/state" {
8792
9511
  `)}
8793
9512
  };
8794
9513
  `;
8795
- await createFile(path34.join(this.projectPath, ".adk", "interfaces.d.ts"), await formatCode(types5));
8796
- await createFile(path34.join(this.projectPath, ".adk", "interfaces.ts"), await formatCode(consts));
9514
+ await createFile(path38.join(this.projectPath, ".adk", "interfaces.d.ts"), await formatCode(types5));
9515
+ await createFile(path38.join(this.projectPath, ".adk", "interfaces.ts"), await formatCode(consts));
8797
9516
  const staleInterfaceFiles = existingInterfaceFiles.filter((f) => !files.has(f));
8798
9517
  if (staleInterfaceFiles.length > 0) {
8799
9518
  for (const rel of staleInterfaceFiles) {
8800
- const abs = path34.join(interfacesDir, rel);
9519
+ const abs = path38.join(interfacesDir, rel);
8801
9520
  try {
8802
- await fs16.rm(abs, { force: true });
9521
+ await fs18.rm(abs, { force: true });
8803
9522
  } catch {}
8804
9523
  }
8805
9524
  }
@@ -8830,7 +9549,31 @@ declare module "@botpress/runtime/_types/state" {
8830
9549
  `) : ""}
8831
9550
  } as Record<string, IntegrationPackage>;
8832
9551
  `;
8833
- await createFile(path34.join(this.outputPath, "src", "integrations.ts"), content);
9552
+ await createFile(path38.join(this.outputPath, "src", "integrations.ts"), content);
9553
+ }
9554
+ async generatePluginsDefinition() {
9555
+ const project = await AgentProject.load(this.projectPath);
9556
+ const plugins = project.dependencies?.plugins || {};
9557
+ const imports = [];
9558
+ const pluginDefs = [];
9559
+ for (const [alias] of Object.entries(plugins)) {
9560
+ const normalizedAlias = getPluginAlias(alias);
9561
+ imports.push(`import plugin_${normalizedAlias} from "../bp_modules/plugin_${alias}";`);
9562
+ pluginDefs.push(`"${alias}": plugin_${normalizedAlias}`);
9563
+ }
9564
+ const content = dedent`
9565
+ import { PluginPackage } from "@botpress/sdk";
9566
+
9567
+ ${imports.length > 0 ? `
9568
+ ` + imports.join(`
9569
+ `) : ""}
9570
+
9571
+ export const PluginDefinitions = {
9572
+ ${pluginDefs.length > 0 ? pluginDefs.join(`,
9573
+ `) : ""}
9574
+ } as Record<string, PluginPackage>;
9575
+ `;
9576
+ await createFile(path38.join(this.outputPath, "src", "plugins.ts"), content);
8834
9577
  }
8835
9578
  async generateInterfacesDefinition() {
8836
9579
  const interfaces = BUILTIN_INTERFACES;
@@ -8853,7 +9596,7 @@ declare module "@botpress/runtime/_types/state" {
8853
9596
  `) : ""}
8854
9597
  } as Record<string, InterfacePackage>;
8855
9598
  `;
8856
- await createFile(path34.join(this.outputPath, "src", "interfaces.ts"), await formatCode(content));
9599
+ await createFile(path38.join(this.outputPath, "src", "interfaces.ts"), await formatCode(content));
8857
9600
  }
8858
9601
  reportServerConfigSync(serverConfigResult, integrations) {
8859
9602
  if (!this.callbacks) {
@@ -8907,6 +9650,23 @@ declare module "@botpress/runtime/_types/state" {
8907
9650
  const configData = Object.keys(mergedConfig).length > 0 ? `, configuration: ${JSON.stringify(mergedConfig)}` : "";
8908
9651
  addIntegrations.push(`bot.addIntegration(${importName}, { alias: "${alias}", enabled: true${configType}${configData} });`);
8909
9652
  }
9653
+ const depRefErrors = PluginParser.validateDependencyReferences(project.dependencies || {});
9654
+ if (depRefErrors.length > 0) {
9655
+ const messages = depRefErrors.map((e) => e.message).join(`
9656
+ `);
9657
+ throw new Error(`Plugin dependency validation failed:
9658
+ ${messages}`);
9659
+ }
9660
+ const plugins = project.dependencies?.plugins || {};
9661
+ const addPlugins = [];
9662
+ for (const [alias, pluginConfig] of Object.entries(plugins)) {
9663
+ const normalizedAlias = getPluginAlias(alias);
9664
+ const importName = `plugin_${normalizedAlias}`;
9665
+ imports.push(`import ${importName} from "./bp_modules/plugin_${alias}";`);
9666
+ const configData = pluginConfig.config && Object.keys(pluginConfig.config).length > 0 ? `, configuration: ${JSON.stringify(pluginConfig.config)}` : "";
9667
+ const depsData = pluginConfig.dependencies && Object.keys(pluginConfig.dependencies).length > 0 ? `, dependencies: ${JSON.stringify(pluginConfig.dependencies)}` : "";
9668
+ addPlugins.push(`bot.addPlugin(${importName}, { alias: "${alias}"${configData}${depsData} });`);
9669
+ }
8910
9670
  const botTags = {};
8911
9671
  const userTags = {};
8912
9672
  const conversationTags = {};
@@ -8927,9 +9687,9 @@ declare module "@botpress/runtime/_types/state" {
8927
9687
  if (project.config?.workflow?.tags) {
8928
9688
  Object.assign(workflowTags, project.config.workflow.tags);
8929
9689
  }
8930
- const crypto5 = __require("crypto");
9690
+ const crypto6 = __require("crypto");
8931
9691
  const hashString = (str) => {
8932
- return crypto5.createHash("md5").update(str).digest("hex").substring(0, 5).toUpperCase();
9692
+ return crypto6.createHash("md5").update(str).digest("hex").substring(0, 5).toUpperCase();
8933
9693
  };
8934
9694
  for (const trigger of project.triggers) {
8935
9695
  const triggerName = trigger.definition.name;
@@ -8947,7 +9707,7 @@ declare module "@botpress/runtime/_types/state" {
8947
9707
  if (isBuiltinWorkflow3(workflow.definition.name)) {
8948
9708
  continue;
8949
9709
  }
8950
- const workflowPath = path34.join(project.path, workflow.path);
9710
+ const workflowPath = path38.join(project.path, workflow.path);
8951
9711
  const workflowModule = await import(`${workflowPath}?t=${Date.now()}`);
8952
9712
  const workflowInstance = workflowModule.default || workflowModule[workflow.export];
8953
9713
  if (workflowInstance) {
@@ -8971,8 +9731,8 @@ declare module "@botpress/runtime/_types/state" {
8971
9731
  schedule: definition.schedule
8972
9732
  });
8973
9733
  }
8974
- const inputSchema = definition.input ? transforms3.fromJSONSchema(definition.input).naked().toTypescriptSchema() : "z.object({})";
8975
- const outputSchema = definition.output ? transforms3.fromJSONSchema(definition.output).naked().toTypescriptSchema() : "z.object({})";
9734
+ const inputSchema = definition.input ? transforms4.fromJSONSchema(definition.input).naked().toTypescriptSchema() : "z.object({})";
9735
+ const outputSchema = definition.output ? transforms4.fromJSONSchema(definition.output).naked().toTypescriptSchema() : "z.object({})";
8976
9736
  const parts = [];
8977
9737
  if (definition.description) {
8978
9738
  parts.push(`title: ${JSON.stringify(definition.name)}`);
@@ -9012,7 +9772,7 @@ declare module "@botpress/runtime/_types/state" {
9012
9772
  const schema = eventDef.schema;
9013
9773
  let schemaCode = "z.object({})";
9014
9774
  if (schema && typeof schema.toJSONSchema === "function") {
9015
- schemaCode = transforms3.fromJSONSchema(schema.toJSONSchema()).toTypescriptSchema();
9775
+ schemaCode = transforms4.fromJSONSchema(schema.toJSONSchema()).toTypescriptSchema();
9016
9776
  }
9017
9777
  const parts = [`schema: ${schemaCode}`];
9018
9778
  if (eventDef.description) {
@@ -9024,7 +9784,7 @@ declare module "@botpress/runtime/_types/state" {
9024
9784
  }`);
9025
9785
  }
9026
9786
  const configSchema = project.config?.configuration?.schema;
9027
- const configSchemaCode = configSchema ? transforms3.fromJSONSchema(configSchema.toJSONSchema()).toTypescriptSchema() : undefined;
9787
+ const configSchemaCode = configSchema ? transforms4.fromJSONSchema(configSchema.toJSONSchema()).toTypescriptSchema() : undefined;
9028
9788
  const content = dedent`
9029
9789
  import { BotDefinition, z } from "@botpress/sdk";
9030
9790
  import {
@@ -9096,8 +9856,8 @@ configuration: {
9096
9856
  parts.push(`description: ${JSON.stringify(def.description)}`);
9097
9857
  if (def.attributes)
9098
9858
  parts.push(`attributes: ${JSON.stringify(def.attributes)}`);
9099
- parts.push(`input: { schema: ${transforms3.fromJSONSchema(def.input).toTypescriptSchema()} }`);
9100
- parts.push(`output: { schema: ${transforms3.fromJSONSchema(def.output).toTypescriptSchema()} }`);
9859
+ parts.push(`input: { schema: ${transforms4.fromJSONSchema(def.input).toTypescriptSchema()} }`);
9860
+ parts.push(`output: { schema: ${transforms4.fromJSONSchema(def.output).toTypescriptSchema()} }`);
9101
9861
  return `"${name}": {
9102
9862
  ${parts.join(`,
9103
9863
  `)}
@@ -9199,10 +9959,13 @@ configuration: {
9199
9959
  const integrationsSection = addIntegrations.length > 0 ? `
9200
9960
  ` + addIntegrations.join(`
9201
9961
  `) : "";
9202
- const fullContent = content + integrationsSection + `
9962
+ const pluginsSection = addPlugins.length > 0 ? `
9963
+ ` + addPlugins.join(`
9964
+ `) : "";
9965
+ const fullContent = content + integrationsSection + pluginsSection + `
9203
9966
 
9204
9967
  export default bot;`;
9205
- await createFile(path34.join(this.outputPath, "bot.definition.ts"), await formatCode(fullContent));
9968
+ await createFile(path38.join(this.outputPath, "bot.definition.ts"), await formatCode(fullContent));
9206
9969
  }
9207
9970
  async generateBotIndex() {
9208
9971
  const content = dedent`
@@ -9241,7 +10004,7 @@ export default bot;`;
9241
10004
 
9242
10005
  export default bot
9243
10006
  `;
9244
- await createFile(path34.join(this.outputPath, "src", "index.ts"), await formatCode(content));
10007
+ await createFile(path38.join(this.outputPath, "src", "index.ts"), await formatCode(content));
9245
10008
  }
9246
10009
  async generatePackageJson(project) {
9247
10010
  const packageJson = {
@@ -9255,7 +10018,7 @@ export default bot;`;
9255
10018
  typescript: "^5.9.3"
9256
10019
  }
9257
10020
  };
9258
- await createFile(path34.join(this.outputPath, "package.json"), JSON.stringify(packageJson, null, 2));
10021
+ await createFile(path38.join(this.outputPath, "package.json"), JSON.stringify(packageJson, null, 2));
9259
10022
  }
9260
10023
  async generateTsConfig() {
9261
10024
  const tsConfig = {
@@ -9286,7 +10049,7 @@ export default bot;`;
9286
10049
  },
9287
10050
  include: [".botpress/**/*", "src/**/*", "bp_modules/**/*", "./*.ts", "./*.json", "../*.d.ts"]
9288
10051
  };
9289
- await createFile(path34.join(this.outputPath, "tsconfig.json"), JSON.stringify(tsConfig, null, 2));
10052
+ await createFile(path38.join(this.outputPath, "tsconfig.json"), JSON.stringify(tsConfig, null, 2));
9290
10053
  }
9291
10054
  async generateGlobalTypes() {
9292
10055
  const content = dedent`
@@ -9309,42 +10072,42 @@ export default bot;`;
9309
10072
 
9310
10073
  export {};
9311
10074
  `;
9312
- await createFile(path34.join(this.outputPath, "global.d.ts"), await formatCode(content));
10075
+ await createFile(path38.join(this.outputPath, "global.d.ts"), await formatCode(content));
9313
10076
  }
9314
10077
  async copyAssets() {
9315
- const assetsPath = path34.join(this.projectPath, "assets");
9316
- const targetPath = path34.join(this.outputPath, "assets");
9317
- if (existsSync7(assetsPath)) {
9318
- await fs16.mkdir(targetPath, { recursive: true });
10078
+ const assetsPath = path38.join(this.projectPath, "assets");
10079
+ const targetPath = path38.join(this.outputPath, "assets");
10080
+ if (existsSync8(assetsPath)) {
10081
+ await fs18.mkdir(targetPath, { recursive: true });
9319
10082
  await this.copyDirectory(assetsPath, targetPath);
9320
10083
  }
9321
10084
  }
9322
10085
  async copyDirectory(src, dest) {
9323
- const entries = await fs16.readdir(src, { withFileTypes: true });
10086
+ const entries = await fs18.readdir(src, { withFileTypes: true });
9324
10087
  for (const entry of entries) {
9325
- const srcPath = path34.join(src, entry.name);
9326
- const destPath = path34.join(dest, entry.name);
10088
+ const srcPath = path38.join(src, entry.name);
10089
+ const destPath = path38.join(dest, entry.name);
9327
10090
  if (entry.isDirectory()) {
9328
- await fs16.mkdir(destPath, { recursive: true });
10091
+ await fs18.mkdir(destPath, { recursive: true });
9329
10092
  await this.copyDirectory(srcPath, destPath);
9330
10093
  } else {
9331
- await fs16.copyFile(srcPath, destPath);
10094
+ await fs18.copyFile(srcPath, destPath);
9332
10095
  }
9333
10096
  }
9334
10097
  }
9335
10098
  async generateAdkRuntime() {
9336
10099
  const project = new AgentProject(this.projectPath);
9337
10100
  await project.reload();
9338
- const srcDir = path34.join(this.outputPath, "src");
10101
+ const srcDir = path38.join(this.outputPath, "src");
9339
10102
  {
9340
- const dest = path34.join(srcDir, "conversations.ts");
10103
+ const dest = path38.join(srcDir, "conversations.ts");
9341
10104
  const imports = new Map;
9342
10105
  const exports = new Set;
9343
10106
  let index = 1;
9344
10107
  for (const conversation of project.conversations) {
9345
10108
  if (!imports.has(conversation.path)) {
9346
10109
  const name = `conversations_${index++}`;
9347
- const importPath = getImportPath(dest, path34.join(project.path, conversation.path));
10110
+ const importPath = getImportPath(dest, path38.join(project.path, conversation.path));
9348
10111
  imports.set(conversation.path, {
9349
10112
  name,
9350
10113
  statement: `import * as ${name} from "${importPath}";`
@@ -9370,14 +10133,14 @@ export default bot;`;
9370
10133
  await createFile(dest, await formatCode(content2));
9371
10134
  }
9372
10135
  {
9373
- const dest = path34.join(srcDir, "knowledge.ts");
10136
+ const dest = path38.join(srcDir, "knowledge.ts");
9374
10137
  const imports = new Map;
9375
10138
  const exports = new Set;
9376
10139
  let index = 1;
9377
10140
  for (const knowledge of project.knowledge) {
9378
10141
  if (!imports.has(knowledge.path)) {
9379
10142
  const name = `knowledge_${index++}`;
9380
- const importPath = getImportPath(dest, path34.join(project.path, knowledge.path));
10143
+ const importPath = getImportPath(dest, path38.join(project.path, knowledge.path));
9381
10144
  imports.set(knowledge.path, {
9382
10145
  name,
9383
10146
  statement: `import * as ${name} from "${importPath}";`
@@ -9403,8 +10166,8 @@ export default bot;`;
9403
10166
  await createFile(dest, await formatCode(content2));
9404
10167
  }
9405
10168
  {
9406
- const dest = path34.join(srcDir, "triggers.ts");
9407
- const { transforms: transforms4 } = await import("@botpress/sdk");
10169
+ const dest = path38.join(srcDir, "triggers.ts");
10170
+ const { transforms: transforms5 } = await import("@botpress/sdk");
9408
10171
  const imports = new Map;
9409
10172
  const exports = new Set;
9410
10173
  const payloadTypes = {};
@@ -9412,7 +10175,7 @@ export default bot;`;
9412
10175
  for (const trigger of project.triggers) {
9413
10176
  if (!imports.has(trigger.path)) {
9414
10177
  const name = `triggers_${index++}`;
9415
- const importPath = getImportPath(dest, path34.join(project.path, trigger.path));
10178
+ const importPath = getImportPath(dest, path38.join(project.path, trigger.path));
9416
10179
  imports.set(trigger.path, {
9417
10180
  name,
9418
10181
  statement: `import * as ${name} from "${importPath}";`
@@ -9422,12 +10185,12 @@ export default bot;`;
9422
10185
  }
9423
10186
  for (const trigger of project.triggers) {
9424
10187
  try {
9425
- const absolutePath = path34.join(project.path, trigger.path);
10188
+ const absolutePath = path38.join(project.path, trigger.path);
9426
10189
  const triggerModule = await import(`${absolutePath}?t=${Date.now()}`);
9427
10190
  const triggerInstance = triggerModule[trigger.export] || triggerModule.default;
9428
10191
  if (triggerInstance && triggerInstance.payload) {
9429
- const jsonSchema = transforms4.toJSONSchema(triggerInstance.payload);
9430
- const payloadType = transforms4.fromJSONSchema(jsonSchema).toTypescriptType();
10192
+ const jsonSchema = transforms5.toJSONSchema(triggerInstance.payload);
10193
+ const payloadType = transforms5.fromJSONSchema(jsonSchema).toTypescriptType();
9431
10194
  payloadTypes[trigger.definition.name] = payloadType;
9432
10195
  } else {
9433
10196
  payloadTypes[trigger.definition.name] = "{}";
@@ -9465,7 +10228,7 @@ export default bot;`;
9465
10228
  await createFile(dest, await formatCode(content2));
9466
10229
  }
9467
10230
  {
9468
- const dest = path34.join(srcDir, "workflows.ts");
10231
+ const dest = path38.join(srcDir, "workflows.ts");
9469
10232
  const imports = new Map;
9470
10233
  const exports = new Set;
9471
10234
  let index = 1;
@@ -9475,7 +10238,7 @@ export default bot;`;
9475
10238
  }
9476
10239
  if (!imports.has(workflow.path)) {
9477
10240
  const name = `workflows_${index++}`;
9478
- const importPath = getImportPath(dest, path34.join(project.path, workflow.path));
10241
+ const importPath = getImportPath(dest, path38.join(project.path, workflow.path));
9479
10242
  const statement = `import * as ${name} from "${importPath}";`;
9480
10243
  imports.set(workflow.path, {
9481
10244
  name,
@@ -9509,7 +10272,7 @@ export default bot;`;
9509
10272
  await createFile(dest, await formatCode(content2));
9510
10273
  }
9511
10274
  {
9512
- const dest = path34.join(srcDir, "actions.ts");
10275
+ const dest = path38.join(srcDir, "actions.ts");
9513
10276
  const imports = new Map;
9514
10277
  const exports = new Set;
9515
10278
  let index = 1;
@@ -9519,7 +10282,7 @@ export default bot;`;
9519
10282
  }
9520
10283
  if (!imports.has(action.path)) {
9521
10284
  const name = `actions_${index++}`;
9522
- const importPath = getImportPath(dest, path34.join(project.path, action.path));
10285
+ const importPath = getImportPath(dest, path38.join(project.path, action.path));
9523
10286
  imports.set(action.path, {
9524
10287
  name,
9525
10288
  statement: `import * as ${name} from "${importPath}";`
@@ -9545,14 +10308,14 @@ export default bot;`;
9545
10308
  await createFile(dest, await formatCode(content2));
9546
10309
  }
9547
10310
  {
9548
- const dest = path34.join(srcDir, "tables.ts");
10311
+ const dest = path38.join(srcDir, "tables.ts");
9549
10312
  const imports = new Map;
9550
10313
  const exports = new Set;
9551
10314
  let index = 1;
9552
10315
  for (const table of project.tables) {
9553
10316
  if (!imports.has(table.path)) {
9554
10317
  const name = `tables_${index++}`;
9555
- const importPath = getImportPath(dest, path34.join(project.path, table.path));
10318
+ const importPath = getImportPath(dest, path38.join(project.path, table.path));
9556
10319
  imports.set(table.path, {
9557
10320
  name,
9558
10321
  statement: `import * as ${name} from "${importPath}";`
@@ -9578,8 +10341,8 @@ export default bot;`;
9578
10341
  await createFile(dest, await formatCode(content2));
9579
10342
  }
9580
10343
  {
9581
- const dest = path34.join(srcDir, "config.ts");
9582
- const importPath = getImportPath(dest, path34.join(project.path, "agent.config.ts"));
10344
+ const dest = path38.join(srcDir, "config.ts");
10345
+ const importPath = getImportPath(dest, path38.join(project.path, "agent.config.ts"));
9583
10346
  const content2 = `
9584
10347
  ////////////////////////////////////////////////////////
9585
10348
  // DO NOT EDIT THIS FILE DIRECTLY
@@ -9643,15 +10406,16 @@ export default bot;`;
9643
10406
  handlers.trigger.setup(bot);
9644
10407
  handlers.workflow.setup(bot);
9645
10408
  handlers.actions.setup(bot);
10409
+ handlers.plugins.setup(bot);
9646
10410
  }
9647
10411
  `;
9648
- await createFile(path34.join(this.outputPath, "src", "adk-runtime.ts"), await formatCode(content));
10412
+ await createFile(path38.join(this.outputPath, "src", "adk-runtime.ts"), await formatCode(content));
9649
10413
  }
9650
10414
  async copyAssetsRuntime() {
9651
- const assetsRuntimePath = path34.join(this.projectPath, ".adk", "assets-runtime.ts");
9652
- if (existsSync7(assetsRuntimePath)) {
9653
- const content = await fs16.readFile(assetsRuntimePath, "utf-8");
9654
- await createFile(path34.join(this.outputPath, "src", "assets-runtime.ts"), await formatCode(content));
10415
+ const assetsRuntimePath = path38.join(this.projectPath, ".adk", "assets-runtime.ts");
10416
+ if (existsSync8(assetsRuntimePath)) {
10417
+ const content = await fs18.readFile(assetsRuntimePath, "utf-8");
10418
+ await createFile(path38.join(this.outputPath, "src", "assets-runtime.ts"), await formatCode(content));
9655
10419
  }
9656
10420
  }
9657
10421
  }
@@ -9660,11 +10424,11 @@ async function generateBotProject(options) {
9660
10424
  await generator.generate();
9661
10425
  await generator.generateAdkRuntime();
9662
10426
  await generator.copyAssetsRuntime();
9663
- const botPath = options.outputPath || path34.join(options.projectPath, ".adk", "bot");
10427
+ const botPath = options.outputPath || path38.join(options.projectPath, ".adk", "bot");
9664
10428
  await linkSdk(options.projectPath, botPath);
9665
- const devIdManager = new DevIdManager(options.projectPath, options.outputPath || path34.join(options.projectPath, ".adk", "bot"));
10429
+ const devIdManager = new DevIdManager(options.projectPath, options.outputPath || path38.join(options.projectPath, ".adk", "bot"));
9666
10430
  await devIdManager.restoreDevId();
9667
- const integrationSync = new IntegrationSync(options.projectPath, options.outputPath || path34.join(options.projectPath, ".adk", "bot"));
10431
+ const integrationSync = new IntegrationSync(options.projectPath, options.outputPath || path38.join(options.projectPath, ".adk", "bot"));
9668
10432
  const integrationSyncResult = await integrationSync.syncIntegrations();
9669
10433
  if (integrationSyncResult.errors.length > 0) {
9670
10434
  console.warn(`⚠️ Some integrations failed to sync:`);
@@ -9672,7 +10436,7 @@ async function generateBotProject(options) {
9672
10436
  console.warn(` - ${alias}: ${error}`);
9673
10437
  });
9674
10438
  }
9675
- const interfaceSync = new InterfaceSync(options.projectPath, options.outputPath || path34.join(options.projectPath, ".adk", "bot"));
10439
+ const interfaceSync = new InterfaceSync(options.projectPath, options.outputPath || path38.join(options.projectPath, ".adk", "bot"));
9676
10440
  const interfaceSyncResult = await interfaceSync.syncInterfaces();
9677
10441
  if (interfaceSyncResult.errors.length > 0) {
9678
10442
  console.warn(`⚠️ Some interfaces failed to sync:`);
@@ -9680,10 +10444,18 @@ async function generateBotProject(options) {
9680
10444
  console.warn(` - ${alias}: ${error}`);
9681
10445
  });
9682
10446
  }
10447
+ const pluginSync = new PluginSync(options.projectPath, options.outputPath || path38.join(options.projectPath, ".adk", "bot"));
10448
+ const pluginSyncResult = await pluginSync.syncPlugins();
10449
+ if (pluginSyncResult.errors.length > 0) {
10450
+ console.warn(`⚠️ Some plugins failed to sync:`);
10451
+ pluginSyncResult.errors.forEach(({ alias, error }) => {
10452
+ console.warn(` - ${alias}: ${error}`);
10453
+ });
10454
+ }
9683
10455
  }
9684
10456
  // src/tables/table-manager.ts
9685
- import { Client as Client14 } from "@botpress/client";
9686
- import { transforms as transforms4 } from "@botpress/sdk";
10457
+ import { Client as Client15 } from "@botpress/client";
10458
+ import { transforms as transforms5 } from "@botpress/sdk";
9687
10459
  class TableManager {
9688
10460
  client;
9689
10461
  botId;
@@ -9696,7 +10468,7 @@ class TableManager {
9696
10468
  if (!this.client) {
9697
10469
  const credentials = await auth.getActiveCredentials();
9698
10470
  this.assertBotId("initialize client");
9699
- this.client = new Client14({
10471
+ this.client = new Client15({
9700
10472
  token: credentials.token,
9701
10473
  apiUrl: credentials.apiUrl,
9702
10474
  botId: this.botId,
@@ -10006,8 +10778,8 @@ class TableManager {
10006
10778
  const factorMatches = (local.factor || 1) === (remote.factor || 1);
10007
10779
  const keyColumnMatches = (local.keyColumn || "") === (remote.keyColumn || "");
10008
10780
  const tagsMatch = JSON.stringify(local.tags || {}) === JSON.stringify(remote.tags || {});
10009
- const localSchema = transforms4.fromJSONSchema(cleanedLocalSchema);
10010
- const remoteSchema = transforms4.fromJSONSchema(cleanedRemoteSchema);
10781
+ const localSchema = transforms5.fromJSONSchema(cleanedLocalSchema);
10782
+ const remoteSchema = transforms5.fromJSONSchema(cleanedRemoteSchema);
10011
10783
  const schemasEqual = localSchema.isEqual(remoteSchema);
10012
10784
  const hasMetadataChanges = differences.length > 0;
10013
10785
  if (!schemasEqual || !factorMatches || hasMetadataChanges || !keyColumnMatches || !tagsMatch) {
@@ -10180,11 +10952,11 @@ class TableManager {
10180
10952
  }
10181
10953
  }
10182
10954
  // src/knowledge/manager.ts
10183
- import crypto5 from "crypto";
10184
- import path35 from "path";
10185
- import fs17 from "fs/promises";
10955
+ import crypto6 from "crypto";
10956
+ import path39 from "path";
10957
+ import fs19 from "fs/promises";
10186
10958
  import { glob } from "glob";
10187
- import { Client as Client15 } from "@botpress/client";
10959
+ import { Client as Client16 } from "@botpress/client";
10188
10960
  import { DataSource } from "@botpress/runtime";
10189
10961
 
10190
10962
  // src/knowledge/types.ts
@@ -10229,7 +11001,7 @@ class KnowledgeManager {
10229
11001
  if (!this.client) {
10230
11002
  const credentials = await auth.getActiveCredentials();
10231
11003
  this.assertBotId("initialize client");
10232
- this.client = new Client15({
11004
+ this.client = new Client16({
10233
11005
  token: credentials.token,
10234
11006
  apiUrl: credentials.apiUrl,
10235
11007
  botId: this.botId,
@@ -10271,7 +11043,7 @@ class KnowledgeManager {
10271
11043
  const sortedEntries = Object.entries(fileHashes).sort(([a], [b]) => a.localeCompare(b));
10272
11044
  const combined = sortedEntries.map(([filePath, hash]) => `${filePath}:${hash}`).join(`
10273
11045
  `);
10274
- return crypto5.createHash("sha256").update(combined).digest("hex");
11046
+ return crypto6.createHash("sha256").update(combined).digest("hex");
10275
11047
  }
10276
11048
  async listRemoteKnowledgeBases() {
10277
11049
  const client = await this.getClient();
@@ -10386,7 +11158,7 @@ class KnowledgeManager {
10386
11158
  }
10387
11159
  computeConfigHash(config) {
10388
11160
  const sortedConfig = JSON.stringify(config, Object.keys(config).sort());
10389
- return crypto5.createHash("sha256").update(sortedConfig).digest("hex");
11161
+ return crypto6.createHash("sha256").update(sortedConfig).digest("hex");
10390
11162
  }
10391
11163
  async syncWebsiteSource(kbName, kbId, force) {
10392
11164
  const client = await this.getClient();
@@ -10631,16 +11403,16 @@ class KnowledgeManager {
10631
11403
  }
10632
11404
  async scanLocalFileHashes(directoryPath, filterFn) {
10633
11405
  const projectDir = this.project.path;
10634
- const directory = path35.resolve(projectDir, directoryPath);
11406
+ const directory = path39.resolve(projectDir, directoryPath);
10635
11407
  if (this.fileHashCache.has(directory)) {
10636
11408
  return this.fileHashCache.get(directory);
10637
11409
  }
10638
11410
  const files = glob.sync(directory + "/**/*.*", { absolute: true, nodir: true }).filter((file) => !filterFn || filterFn(file));
10639
11411
  const hashes = {};
10640
11412
  for (const file of files) {
10641
- const relPath = path35.relative(directory, file);
10642
- const content = await fs17.readFile(file);
10643
- hashes[relPath] = crypto5.createHash("sha256").update(content).digest("hex");
11413
+ const relPath = path39.relative(directory, file);
11414
+ const content = await fs19.readFile(file);
11415
+ hashes[relPath] = crypto6.createHash("sha256").update(content).digest("hex");
10644
11416
  }
10645
11417
  this.fileHashCache.set(directory, hashes);
10646
11418
  return hashes;
@@ -10746,7 +11518,7 @@ class KnowledgeManager {
10746
11518
  }
10747
11519
  async syncDirectorySource(client, kbName, kbId, dsId, directoryPath, filterFn, force) {
10748
11520
  const projectDir = this.project.path;
10749
- const directory = path35.resolve(projectDir, directoryPath);
11521
+ const directory = path39.resolve(projectDir, directoryPath);
10750
11522
  if (!directory.startsWith(projectDir)) {
10751
11523
  throw new Error("Directory path must be within the agent's directory");
10752
11524
  }
@@ -10768,8 +11540,8 @@ class KnowledgeManager {
10768
11540
  return true;
10769
11541
  }).map((f) => ({
10770
11542
  abs: f,
10771
- rel: path35.relative(directory, f),
10772
- name: path35.basename(f)
11543
+ rel: path39.relative(directory, f),
11544
+ name: path39.basename(f)
10773
11545
  }));
10774
11546
  console.log(` Found ${allFiles.length} files in ${directoryPath}`);
10775
11547
  const cachedHashes = await this.scanLocalFileHashes(directoryPath, filterFn);
@@ -10843,15 +11615,15 @@ class KnowledgeManager {
10843
11615
  }
10844
11616
  async upsertFile(client, local, dsId, tags, force, cachedHash) {
10845
11617
  const key = `data_source://document/${dsId}/${local.rel}`;
10846
- const content = await fs17.readFile(local.abs);
10847
- const hash = cachedHash ?? crypto5.createHash("sha256").update(content).digest("hex");
11618
+ const content = await fs19.readFile(local.abs);
11619
+ const hash = cachedHash ?? crypto6.createHash("sha256").update(content).digest("hex");
10848
11620
  try {
10849
11621
  const { file } = await client.getFile({ id: key });
10850
11622
  if (!force && isFileMetadata(file.metadata) && file.metadata.hash === hash) {
10851
11623
  return null;
10852
11624
  }
10853
11625
  } catch {}
10854
- const title = path35.basename(local.name, path35.extname(local.name));
11626
+ const title = path39.basename(local.name, path39.extname(local.name));
10855
11627
  const metadata = {
10856
11628
  hash,
10857
11629
  dsId,
@@ -10979,7 +11751,7 @@ class KBSyncFormatter {
10979
11751
  import { watch as watch2, readdirSync as readdirSync2 } from "fs";
10980
11752
  import { EventEmitter as EventEmitter3 } from "events";
10981
11753
  import { join as join8, relative as relative3 } from "path";
10982
- import { existsSync as existsSync8 } from "fs";
11754
+ import { existsSync as existsSync9 } from "fs";
10983
11755
 
10984
11756
  class FileWatcher2 extends EventEmitter3 {
10985
11757
  projectPath;
@@ -10997,12 +11769,12 @@ class FileWatcher2 extends EventEmitter3 {
10997
11769
  const rootFiles = ["package.json", "agent.json", "agent.config.ts"];
10998
11770
  for (const file of rootFiles) {
10999
11771
  const filePath = join8(this.projectPath, file);
11000
- if (existsSync8(filePath)) {
11772
+ if (existsSync9(filePath)) {
11001
11773
  this.watchFile(filePath);
11002
11774
  }
11003
11775
  }
11004
11776
  const srcPath = join8(this.projectPath, "src");
11005
- if (existsSync8(srcPath)) {
11777
+ if (existsSync9(srcPath)) {
11006
11778
  this.initializeDirectoryState(srcPath);
11007
11779
  this.watchDirectory(srcPath);
11008
11780
  }
@@ -11051,7 +11823,7 @@ class FileWatcher2 extends EventEmitter3 {
11051
11823
  }
11052
11824
  }
11053
11825
  handleFileChange(filePath) {
11054
- const fileExists = existsSync8(filePath);
11826
+ const fileExists = existsSync9(filePath);
11055
11827
  const previousState = this.fileStates.get(filePath);
11056
11828
  let changeType;
11057
11829
  if (!fileExists && previousState !== undefined) {
@@ -11091,7 +11863,7 @@ class FileWatcher2 extends EventEmitter3 {
11091
11863
  this.emit("change", event);
11092
11864
  }
11093
11865
  updateFileState(filePath) {
11094
- if (existsSync8(filePath)) {
11866
+ if (existsSync9(filePath)) {
11095
11867
  this.fileStates.set(filePath, Date.now());
11096
11868
  }
11097
11869
  }
@@ -11115,8 +11887,8 @@ class FileWatcher2 extends EventEmitter3 {
11115
11887
  }
11116
11888
  }
11117
11889
  // src/preflight/checker.ts
11118
- import { Client as Client16 } from "@botpress/client";
11119
- import path36 from "path";
11890
+ import { Client as Client17 } from "@botpress/client";
11891
+ import path40 from "path";
11120
11892
 
11121
11893
  // src/preflight/types.ts
11122
11894
  function hasIntegrationChanges(integrations) {
@@ -11330,7 +12102,7 @@ class PreflightChecker {
11330
12102
  if (!workspaceId) {
11331
12103
  throw new Error('No workspace ID found. Please login with "adk login"');
11332
12104
  }
11333
- this.client = new Client16({
12105
+ this.client = new Client17({
11334
12106
  token: credentials.token,
11335
12107
  apiUrl: credentials.apiUrl,
11336
12108
  workspaceId,
@@ -11478,7 +12250,7 @@ class PreflightChecker {
11478
12250
  options?.onProgress?.("Regenerating bot project...");
11479
12251
  await generateBotProject({
11480
12252
  projectPath: this.projectPath,
11481
- outputPath: path36.join(this.projectPath, ".adk", "bot"),
12253
+ outputPath: path40.join(this.projectPath, ".adk", "bot"),
11482
12254
  callbacks: options
11483
12255
  });
11484
12256
  options?.onSuccess?.("Bot project regenerated");
@@ -11486,21 +12258,21 @@ class PreflightChecker {
11486
12258
  }
11487
12259
  // src/runner/script-runner.ts
11488
12260
  import dedent2 from "dedent";
11489
- import { existsSync as existsSync9 } from "fs";
11490
- import fs18 from "fs/promises";
11491
- import path37 from "path";
12261
+ import { existsSync as existsSync10 } from "fs";
12262
+ import fs20 from "fs/promises";
12263
+ import path41 from "path";
11492
12264
  import { spawn } from "child_process";
11493
12265
  init_utils();
11494
12266
  init_credentials();
11495
12267
  async function findAgentRoot(startPath) {
11496
- let currentPath = path37.resolve(startPath);
11497
- const root = path37.parse(currentPath).root;
12268
+ let currentPath = path41.resolve(startPath);
12269
+ const root = path41.parse(currentPath).root;
11498
12270
  while (currentPath !== root) {
11499
12271
  try {
11500
- await fs18.access(path37.join(currentPath, "agent.config.ts"));
12272
+ await fs20.access(path41.join(currentPath, "agent.config.ts"));
11501
12273
  return currentPath;
11502
12274
  } catch {
11503
- currentPath = path37.dirname(currentPath);
12275
+ currentPath = path41.dirname(currentPath);
11504
12276
  }
11505
12277
  }
11506
12278
  return null;
@@ -11512,7 +12284,7 @@ class ScriptRunner {
11512
12284
  prod;
11513
12285
  credentials;
11514
12286
  constructor(options) {
11515
- this.projectPath = path37.resolve(options.projectPath);
12287
+ this.projectPath = path41.resolve(options.projectPath);
11516
12288
  this.forceRegenerate = options.forceRegenerate ?? false;
11517
12289
  this.prod = options.prod ?? false;
11518
12290
  this.credentials = options.credentials;
@@ -11521,10 +12293,10 @@ class ScriptRunner {
11521
12293
  const project = await AgentProject.load(this.projectPath, {
11522
12294
  adkCommand: "adk-build"
11523
12295
  });
11524
- const botPath = path37.join(this.projectPath, ".adk", "bot");
11525
- const runnerPath = path37.join(botPath, "src", "script-runner.ts");
11526
- const botpressTypesPath = path37.join(botPath, ".botpress", "implementation", "index.ts");
11527
- const needsRegenerate = this.forceRegenerate || !existsSync9(runnerPath) || !existsSync9(botpressTypesPath);
12296
+ const botPath = path41.join(this.projectPath, ".adk", "bot");
12297
+ const runnerPath = path41.join(botPath, "src", "script-runner.ts");
12298
+ const botpressTypesPath = path41.join(botPath, ".botpress", "implementation", "index.ts");
12299
+ const needsRegenerate = this.forceRegenerate || !existsSync10(runnerPath) || !existsSync10(botpressTypesPath);
11528
12300
  if (needsRegenerate) {
11529
12301
  try {
11530
12302
  await generateAssetsTypes(project.path);
@@ -11640,7 +12412,7 @@ class ScriptRunner {
11640
12412
 
11641
12413
  runScript()
11642
12414
  `;
11643
- await fs18.writeFile(path37.join(botPath, "src", "script-runner.ts"), await formatCode(content), "utf-8");
12415
+ await fs20.writeFile(path41.join(botPath, "src", "script-runner.ts"), await formatCode(content), "utf-8");
11644
12416
  }
11645
12417
  async setupTestRuntime(options = {}) {
11646
12418
  const { botPath, project } = await this.prepare();
@@ -11671,7 +12443,7 @@ class ScriptRunner {
11671
12443
  for (const [key, value] of Object.entries(envVars)) {
11672
12444
  process.env[key] = value;
11673
12445
  }
11674
- const runtimePath = path37.join(botPath, "src", "index.ts");
12446
+ const runtimePath = path41.join(botPath, "src", "index.ts");
11675
12447
  return {
11676
12448
  botPath,
11677
12449
  runtimePath,
@@ -11684,10 +12456,10 @@ class ScriptRunner {
11684
12456
  const runtimeModule = await import("@botpress/runtime/runtime");
11685
12457
  const { Autonomous } = await import("@botpress/runtime");
11686
12458
  const { context, agentRegistry } = runtimeModule;
11687
- const { Client: Client17 } = await import("@botpress/client");
12459
+ const { Client: Client18 } = await import("@botpress/client");
11688
12460
  const { BotSpecificClient, BotLogger } = await import("@botpress/sdk");
11689
12461
  const { Cognitive } = await import("@botpress/cognitive");
11690
- const vanillaClient = new Client17({
12462
+ const vanillaClient = new Client18({
11691
12463
  token: this.credentials.token,
11692
12464
  apiUrl: this.credentials.apiUrl,
11693
12465
  botId
@@ -11719,8 +12491,8 @@ class ScriptRunner {
11719
12491
  }
11720
12492
  async run(scriptPath, options = {}) {
11721
12493
  const { botPath, runnerPath, project } = await this.prepare();
11722
- const absoluteScriptPath = path37.isAbsolute(scriptPath) ? scriptPath : path37.resolve(this.projectPath, scriptPath);
11723
- if (!existsSync9(absoluteScriptPath)) {
12494
+ const absoluteScriptPath = path41.isAbsolute(scriptPath) ? scriptPath : path41.resolve(this.projectPath, scriptPath);
12495
+ if (!existsSync10(absoluteScriptPath)) {
11724
12496
  throw new Error(`Script not found: ${absoluteScriptPath}`);
11725
12497
  }
11726
12498
  const botId = this.prod ? project.agentInfo?.botId : project.agentInfo?.devId || project.agentInfo?.botId;
@@ -11834,6 +12606,7 @@ export {
11834
12606
  ProjectState,
11835
12607
  PreflightFormatter,
11836
12608
  PreflightChecker,
12609
+ PluginParser,
11837
12610
  KnowledgeManager,
11838
12611
  KBSyncOperation,
11839
12612
  KBSyncFormatter,
@@ -11869,4 +12642,4 @@ export {
11869
12642
  AgentProject
11870
12643
  };
11871
12644
 
11872
- //# debugId=AE3B528B2B7EDC6E64756E2164756E21
12645
+ //# debugId=A068F5974643B24F64756E2164756E21