@botpress/adk 1.15.2 → 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.
Files changed (33) hide show
  1. package/dist/agent-project/config-writer.d.ts +7 -1
  2. package/dist/agent-project/config-writer.d.ts.map +1 -1
  3. package/dist/agent-project/dependencies-parser.d.ts +26 -0
  4. package/dist/agent-project/dependencies-parser.d.ts.map +1 -1
  5. package/dist/agent-project/types.d.ts +47 -0
  6. package/dist/agent-project/types.d.ts.map +1 -1
  7. package/dist/agent-project/validation-errors.d.ts +5 -0
  8. package/dist/agent-project/validation-errors.d.ts.map +1 -1
  9. package/dist/bot-generator/generator.d.ts +3 -0
  10. package/dist/bot-generator/generator.d.ts.map +1 -1
  11. package/dist/bot-generator/index.d.ts +1 -0
  12. package/dist/bot-generator/index.d.ts.map +1 -1
  13. package/dist/bot-generator/plugin-sync.d.ts +44 -0
  14. package/dist/bot-generator/plugin-sync.d.ts.map +1 -0
  15. package/dist/generators/plugin-action-types.d.ts +3 -0
  16. package/dist/generators/plugin-action-types.d.ts.map +1 -0
  17. package/dist/generators/plugin-types.d.ts +17 -0
  18. package/dist/generators/plugin-types.d.ts.map +1 -0
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +1191 -408
  22. package/dist/index.js.map +14 -9
  23. package/dist/plugins/enhanced-cache.d.ts +53 -0
  24. package/dist/plugins/enhanced-cache.d.ts.map +1 -0
  25. package/dist/plugins/index.d.ts +6 -0
  26. package/dist/plugins/index.d.ts.map +1 -0
  27. package/dist/plugins/manager.d.ts +44 -0
  28. package/dist/plugins/manager.d.ts.map +1 -0
  29. package/dist/plugins/types.d.ts +19 -0
  30. package/dist/plugins/types.d.ts.map +1 -0
  31. package/dist/utils/ids.d.ts +1 -0
  32. package/dist/utils/ids.d.ts.map +1 -1
  33. package/package.json +2 -2
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.2", 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.2",
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.2",
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();
@@ -3058,12 +3237,11 @@ class ConfigWriter {
3058
3237
  constructor(projectPath) {
3059
3238
  this.configPath = path11.join(projectPath, "agent.config.ts");
3060
3239
  }
3061
- async updateDependencies(dependencies) {
3240
+ loadConfig() {
3062
3241
  const project = new Project;
3063
3242
  const sourceFile = project.addSourceFileAtPath(this.configPath);
3064
3243
  const defineConfigCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((call) => {
3065
- const expression = call.getExpression();
3066
- return expression.getText() === "defineConfig";
3244
+ return call.getExpression().getText() === "defineConfig";
3067
3245
  });
3068
3246
  if (!defineConfigCall) {
3069
3247
  throw new Error("Could not find defineConfig() call in agent.config.ts");
@@ -3072,10 +3250,17 @@ class ConfigWriter {
3072
3250
  if (!configArg || !configArg.isKind(SyntaxKind.ObjectLiteralExpression)) {
3073
3251
  throw new Error("defineConfig() must have an object literal as its first argument");
3074
3252
  }
3075
- const configObject = configArg.asKind(SyntaxKind.ObjectLiteralExpression);
3076
- if (!configObject) {
3077
- throw new Error("Could not find dependencies property in agent.config.ts");
3078
- }
3253
+ return { sourceFile, configObject: configArg };
3254
+ }
3255
+ async saveConfig(sourceFile) {
3256
+ sourceFile.formatText();
3257
+ const content = sourceFile.getFullText();
3258
+ const formatted = await formatCode(content, this.configPath);
3259
+ sourceFile.replaceWithText(formatted);
3260
+ await sourceFile.save();
3261
+ }
3262
+ async updateDependencies(dependencies) {
3263
+ const { sourceFile, configObject } = this.loadConfig();
3079
3264
  let dependenciesProperty = configObject.getProperty("dependencies");
3080
3265
  if (dependenciesProperty) {
3081
3266
  dependenciesProperty.setInitializer(JSON.stringify(dependencies));
@@ -3085,11 +3270,15 @@ class ConfigWriter {
3085
3270
  initializer: JSON.stringify(dependencies)
3086
3271
  });
3087
3272
  }
3088
- sourceFile.formatText();
3089
- const content = sourceFile.getFullText();
3090
- const formatted = await formatCode(content, this.configPath);
3091
- sourceFile.replaceWithText(formatted);
3092
- await sourceFile.save();
3273
+ await this.saveConfig(sourceFile);
3274
+ }
3275
+ async updateName(name) {
3276
+ const { sourceFile, configObject } = this.loadConfig();
3277
+ const nameProperty = configObject.getProperty("name");
3278
+ if (nameProperty) {
3279
+ nameProperty.setInitializer(`'${name.replace(/'/g, "\\'")}'`);
3280
+ }
3281
+ await this.saveConfig(sourceFile);
3093
3282
  }
3094
3283
  }
3095
3284
 
@@ -6393,7 +6582,7 @@ class AgentProjectGenerator {
6393
6582
  deploy: "adk deploy"
6394
6583
  },
6395
6584
  dependencies: {
6396
- "@botpress/runtime": `^${"1.15.2"}`
6585
+ "@botpress/runtime": `^${"1.15.4"}`
6397
6586
  },
6398
6587
  devDependencies: {
6399
6588
  typescript: "^5.9.3"
@@ -6606,116 +6795,332 @@ export default {};
6606
6795
  `);
6607
6796
  }
6608
6797
  }
6609
- // src/generators/assets.ts
6610
- init_fs();
6798
+ // src/plugins/enhanced-cache.ts
6799
+ import fs12 from "fs/promises";
6611
6800
  import path16 from "path";
6612
- async function generateAssetsTypes(projectPath) {
6613
- const assetsManager = new AssetsManager({ projectPath });
6614
- const typesCode = await assetsManager.generateTypes();
6615
- const typesPath = path16.join(projectPath, defaultAdkFolder, "assets.d.ts");
6616
- await createFile(typesPath, typesCode);
6617
- }
6618
- async function generateAssetsRuntime(projectPath, botId, workspaceId) {
6619
- const assetsManager = new AssetsManager({ projectPath, botId, workspaceId });
6620
- const enrichedAssets = await assetsManager.getEnrichedLocalAssets();
6621
- const assetsMap = {};
6622
- const localHashesMap = {};
6623
- const cacheManager = new AssetsCacheManager(projectPath);
6624
- const cache2 = await cacheManager.load();
6625
- for (const asset of enrichedAssets) {
6626
- assetsMap[asset.path] = asset;
6627
- const cacheEntry = cache2.entries[asset.path];
6628
- if (cacheEntry) {
6629
- 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;
6630
6836
  }
6631
6837
  }
6632
- const runtimeCode = `
6633
- // Auto-generated assets metadata
6634
- import { Asset, initAssets } from '@botpress/runtime/runtime';
6635
-
6636
- // Static asset metadata (populated at build time)
6637
- export const assetsMetadata: Record<string, Asset> = ${JSON.stringify(assetsMap, null, 2)};
6638
-
6639
- // Local hashes from cache
6640
- export const localHashes: Record<string, string> = ${JSON.stringify(localHashesMap, null, 2)};
6641
-
6642
- // Initialize the assets runtime with metadata and local hashes
6643
- // The global object should be passed by the agent initialization code
6644
- export function initializeAssets(globalObj: any = globalThis) {
6645
- initAssets(globalObj, assetsMetadata, localHashes);
6646
- }
6647
-
6648
- // Auto-initialize if running in a supported environment
6649
- if (typeof globalThis !== 'undefined') {
6650
- initializeAssets(globalThis);
6651
- } else if (typeof global !== 'undefined') {
6652
- initializeAssets(global);
6653
- }
6654
- `;
6655
- const runtimePath = path16.join(projectPath, defaultAdkFolder, "assets-runtime.ts");
6656
- await createFile(runtimePath, runtimeCode);
6657
- }
6658
- async function initAssets(projectPath, botId, workspaceId) {
6659
- const assetsManager = new AssetsManager({ projectPath, botId, workspaceId });
6660
- if (await assetsManager.hasAssetsDirectory()) {
6661
- await generateAssetsTypes(projectPath);
6662
- await generateAssetsRuntime(projectPath, botId, workspaceId);
6663
- } else {
6664
- const emptyTypesCode = `// No assets directory found
6665
- import { Asset } from '@botpress/runtime';
6666
-
6667
- export type AssetPaths = never;
6668
-
6669
- export interface AssetPathMap {}
6670
-
6671
- // Runtime asset access
6672
- declare global {
6673
- const assets: {
6674
- get<T extends AssetPaths>(path: T): Asset;
6675
- list(): Asset[];
6676
- getSyncStatus(): {
6677
- synced: boolean;
6678
- neverSynced: string[];
6679
- stale: string[];
6680
- 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()
6681
6846
  };
6682
- };
6683
- }
6684
- `;
6685
- const typesPath = path16.join(projectPath, defaultAdkFolder, "assets.d.ts");
6686
- await createFile(typesPath, emptyTypesCode);
6687
- const emptyRuntimeCode = `
6688
- // No assets available
6689
- import { Asset, initAssets } from '@botpress/runtime';
6690
-
6691
- // Empty asset metadata
6692
- export const assetsMetadata: Record<string, Asset> = {};
6693
-
6694
- // Initialize with empty metadata
6695
- export function initializeAssets(globalObj: any = globalThis) {
6696
- initAssets(globalObj, assetsMetadata);
6697
- }
6698
-
6699
- // Auto-initialize if running in a supported environment
6700
- if (typeof globalThis !== 'undefined') {
6701
- initializeAssets(globalThis);
6702
- } else if (typeof global !== 'undefined') {
6703
- initializeAssets(global);
6704
- }
6705
- `;
6706
- const runtimePath = path16.join(projectPath, defaultAdkFolder, "assets-runtime.ts");
6707
- await createFile(runtimePath, emptyRuntimeCode);
6847
+ await fs12.writeFile(cachePath, JSON.stringify(resolution, null, 2));
6708
6848
  }
6709
- }
6710
- // src/generators/integration-types.ts
6711
- import { transforms } from "@botpress/sdk";
6712
- import crypto2 from "crypto";
6713
- import path17 from "path";
6714
-
6715
- // src/utils/strings.ts
6716
- function pascalCase(str) {
6717
- return str.split(/[-_\s]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
6718
- }
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
+ }
6719
7124
  function camelCase(str) {
6720
7125
  const pascal = pascalCase(str);
6721
7126
  return pascal.charAt(0).toLowerCase() + pascal.slice(1);
@@ -6731,6 +7136,9 @@ init_utils();
6731
7136
  function getIntegrationAlias(integrationName) {
6732
7137
  return integrationName.replace(/\//g, "__").replace(/-/g, "_").toLowerCase();
6733
7138
  }
7139
+ function getPluginAlias(pluginName) {
7140
+ return pluginName.replace(/-/g, "_").toLowerCase();
7141
+ }
6734
7142
 
6735
7143
  // src/generators/integration-types.ts
6736
7144
  var getIntegrationHash = (integration) => {
@@ -6747,12 +7155,12 @@ var getIntegrationNames = (integration) => ({
6747
7155
  configurations: `Integration_Configurations_${getPascalAlias(integration)}`
6748
7156
  },
6749
7157
  paths: {
6750
- index: path17.join(snakeCase(getPascalAlias(integration)), `index.ts`),
6751
- actions: path17.join(snakeCase(getPascalAlias(integration)), `actions.ts`),
6752
- channels: path17.join(snakeCase(getPascalAlias(integration)), `channels.ts`),
6753
- events: path17.join(snakeCase(getPascalAlias(integration)), `events.ts`),
6754
- users: path17.join(snakeCase(getPascalAlias(integration)), `users.ts`),
6755
- 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`)
6756
7164
  }
6757
7165
  });
6758
7166
  async function generateIntegrationTypes(integration) {
@@ -7006,7 +7414,7 @@ Description: ${tag?.description}`);
7006
7414
  // src/generators/client-wrapper.ts
7007
7415
  init_utils();
7008
7416
  init_fs();
7009
- import path18 from "path";
7417
+ import path19 from "path";
7010
7418
  import crypto3 from "crypto";
7011
7419
  import { readFile as readFile3 } from "fs/promises";
7012
7420
  import { BuiltInWorkflows as BuiltInWorkflows2 } from "@botpress/runtime/internal";
@@ -7028,7 +7436,7 @@ async function generateClientWrapper(project) {
7028
7436
  });
7029
7437
  continue;
7030
7438
  }
7031
- const absolutePath = path18.join(project.path, action.path);
7439
+ const absolutePath = path19.join(project.path, action.path);
7032
7440
  const actionModule = await import(`${absolutePath}?t=${Date.now()}`);
7033
7441
  const actionInstance = actionModule[action.export] || actionModule.default;
7034
7442
  if (actionInstance && actionInstance.input && actionInstance.output) {
@@ -7055,7 +7463,7 @@ async function generateClientWrapper(project) {
7055
7463
  if (isBuiltinWorkflow(workflow.definition.name)) {
7056
7464
  continue;
7057
7465
  }
7058
- const workflowPath = path18.join(project.path, workflow.path);
7466
+ const workflowPath = path19.join(project.path, workflow.path);
7059
7467
  const workflowModule = await import(`${workflowPath}?t=${Date.now()}`);
7060
7468
  const workflowInstance = workflowModule[workflow.export] || workflowModule.default;
7061
7469
  if (workflowInstance) {
@@ -7074,7 +7482,7 @@ async function generateClientWrapper(project) {
7074
7482
  const tableTypes = [];
7075
7483
  for (const table of project.tables) {
7076
7484
  try {
7077
- const tablePath = path18.join(project.path, table.path);
7485
+ const tablePath = path19.join(project.path, table.path);
7078
7486
  const tableModule = await import(`${tablePath}?t=${Date.now()}`);
7079
7487
  const tableInstance = tableModule.default || tableModule[table.export];
7080
7488
  if (tableInstance && tableInstance.columns) {
@@ -7337,76 +7745,225 @@ export function createAdkClient(client: Client): AdkClient {
7337
7745
  `)}
7338
7746
  },
7339
7747
 
7340
- tables: {
7341
- ${tableTypes.map((table) => `
7342
- '${table.name}': {
7343
- findTableRows: async (params) => {
7344
- return client.findTableRows({
7345
- table: '${table.name}',
7346
- ...params,
7347
- }) as any
7348
- },
7349
- getTableRow: async (params) => {
7350
- return client.getTableRow({
7351
- table: '${table.name}',
7352
- ...params,
7353
- }) as any
7354
- },
7355
- createTableRows: async (params) => {
7356
- return client.createTableRows({
7357
- table: '${table.name}',
7358
- ...params,
7359
- }) as any
7360
- },
7361
- updateTableRows: async (params) => {
7362
- return client.updateTableRows({
7363
- table: '${table.name}',
7364
- ...params,
7365
- }) as any
7366
- },
7367
- upsertTableRows: async (params) => {
7368
- return client.upsertTableRows({
7369
- table: '${table.name}',
7370
- ...params,
7371
- }) as any
7372
- },
7373
- deleteTableRows: async (params) => {
7374
- return client.deleteTableRows({
7375
- table: '${table.name}',
7376
- ...params,
7377
- }) as any
7378
- },
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
+ };
7379
7952
  }
7380
- `).join(`,
7381
- `)}
7382
- },
7953
+ : never;
7954
+ };
7383
7955
 
7384
- client,
7385
- }
7956
+ export type PluginActions = PluginsMap<Plugins>;
7386
7957
  }
7387
7958
  `;
7388
- const clientWrapperPath = path18.join(project.path, ".adk", "client.ts");
7389
- const formattedContent = await formatCode(content);
7390
- const contentHash = crypto3.createHash("sha256").update(formattedContent.replace(/\/\/ Generated at: .+\n/, "")).digest("hex");
7391
- try {
7392
- const existingContent = await readFile3(clientWrapperPath, "utf-8");
7393
- const existingHash = crypto3.createHash("sha256").update(existingContent.replace(/\/\/ Generated at: .+\n/, "")).digest("hex");
7394
- if (contentHash === existingHash) {
7395
- return;
7396
- }
7397
- } catch {}
7398
- await createFile(clientWrapperPath, formattedContent);
7959
+ const pluginActionTypesPath = path21.join(project.path, ".adk", "plugin-action-types.d.ts");
7960
+ await createFile(pluginActionTypesPath, await formatCode(content));
7399
7961
  }
7400
- // src/bot-generator/generator.ts
7401
- import dedent from "dedent";
7402
- import { existsSync as existsSync7 } from "fs";
7403
- import fs16 from "fs/promises";
7404
- import path34 from "path";
7405
7962
 
7406
7963
  // src/generators/interface-types.ts
7407
- import { transforms as transforms2 } from "@botpress/sdk";
7408
- import crypto4 from "crypto";
7409
- import path19 from "path";
7964
+ import { transforms as transforms3 } from "@botpress/sdk";
7965
+ import crypto5 from "crypto";
7966
+ import path22 from "path";
7410
7967
  init_utils();
7411
7968
  var sameMajorVersion = (a, b) => {
7412
7969
  const majorA = a.split(".")[0];
@@ -7418,7 +7975,7 @@ var getIntegrationInterface = (integration, int) => {
7418
7975
  };
7419
7976
  var getInterfaceHash = (int, integrations) => {
7420
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("|");
7421
- 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");
7422
7979
  };
7423
7980
  var getInterfaceNames = (int) => ({
7424
7981
  name: camelCase(int.name),
@@ -7427,8 +7984,8 @@ var getInterfaceNames = (int) => ({
7427
7984
  actions: `Interface_Actions_${pascalCase(int.name)}`
7428
7985
  },
7429
7986
  paths: {
7430
- index: path19.join(snakeCase(int.name), `index.ts`),
7431
- 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`)
7432
7989
  }
7433
7990
  });
7434
7991
  async function generateInterfaceTypes(int, integrations) {
@@ -7480,12 +8037,12 @@ async function generateInterfaceTypes(int, integrations) {
7480
8037
  const entities = Object.entries(integrationInt.entities).reduce((acc, [entityName, value]) => {
7481
8038
  const entity = integration.entities[value.name];
7482
8039
  if (entity) {
7483
- 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");
7484
8041
  }
7485
8042
  return acc;
7486
8043
  }, {});
7487
- const input = transforms2.fromJSONSchema(action.input.schema).dereference(entities).toTypescriptType();
7488
- 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();
7489
8046
  cActions.add(`"${alias}:${name}": "${alias}:${mapping}"`);
7490
8047
  iActions += `
7491
8048
  ${toMultilineComment(`Title: ${action.title || name}
@@ -7533,12 +8090,12 @@ Description: ${action.description || "No description"}`)}
7533
8090
  // src/generators/table-types.ts
7534
8091
  init_utils();
7535
8092
  init_fs();
7536
- import path20 from "path";
8093
+ import path23 from "path";
7537
8094
  async function generateTableTypes(project) {
7538
8095
  const tables = [];
7539
8096
  for (const tableRef of project.tables) {
7540
8097
  try {
7541
- const tablePath = path20.join(project.path, tableRef.path);
8098
+ const tablePath = path23.join(project.path, tableRef.path);
7542
8099
  const tableModule = await import(`${tablePath}?t=${Date.now()}`);
7543
8100
  const tableInstance = tableModule.default || tableModule[tableRef.export];
7544
8101
  if (tableInstance && tableInstance.columns) {
@@ -7624,14 +8181,14 @@ ${outputColumns}
7624
8181
  content += ` };
7625
8182
  }
7626
8183
  `;
7627
- const tableTypesPath = path20.join(project.path, ".adk", "table-types.d.ts");
8184
+ const tableTypesPath = path23.join(project.path, ".adk", "table-types.d.ts");
7628
8185
  await createFile(tableTypesPath, await formatCode(content));
7629
8186
  }
7630
8187
 
7631
8188
  // src/generators/trigger-types.ts
7632
8189
  init_utils();
7633
8190
  init_fs();
7634
- import path21 from "path";
8191
+ import path24 from "path";
7635
8192
  async function generateTriggerTypes(project) {
7636
8193
  const triggerEvents = {};
7637
8194
  for (const trigger of project.triggers) {
@@ -7671,19 +8228,19 @@ ${triggersType}
7671
8228
  };
7672
8229
  }
7673
8230
  `;
7674
- const triggerTypesPath = path21.join(project.path, ".adk", "trigger-types.d.ts");
8231
+ const triggerTypesPath = path24.join(project.path, ".adk", "trigger-types.d.ts");
7675
8232
  await createFile(triggerTypesPath, await formatCode(content));
7676
8233
  }
7677
8234
 
7678
8235
  // src/generators/state-types.ts
7679
8236
  init_utils();
7680
8237
  init_fs();
7681
- import path22 from "path";
8238
+ import path25 from "path";
7682
8239
  async function generateStateTypes(project) {
7683
8240
  let botStateType = "{}";
7684
8241
  let userStateType = "{}";
7685
8242
  try {
7686
- const configPath = path22.join(project.path, "agent.config.ts");
8243
+ const configPath = path25.join(project.path, "agent.config.ts");
7687
8244
  const configModule = await import(`${configPath}?t=${Date.now()}`);
7688
8245
  const config = configModule.default;
7689
8246
  if (config?.bot?.state) {
@@ -7714,14 +8271,14 @@ declare module "@botpress/runtime/_types/state" {
7714
8271
  export type UserState = ${userStateType};
7715
8272
  }
7716
8273
  `;
7717
- const stateTypesPath = path22.join(project.path, ".adk", "state-types.d.ts");
8274
+ const stateTypesPath = path25.join(project.path, ".adk", "state-types.d.ts");
7718
8275
  await createFile(stateTypesPath, await formatCode(content));
7719
8276
  }
7720
8277
 
7721
8278
  // src/generators/tag-types.ts
7722
8279
  init_utils();
7723
8280
  init_fs();
7724
- import path23 from "path";
8281
+ import path26 from "path";
7725
8282
  import { BUILT_IN_TAGS } from "@botpress/runtime/definition";
7726
8283
  function generateTagTypeString(builtInTags, configTags) {
7727
8284
  const builtInTagStrings = Object.entries(builtInTags).map(([key, tag]) => {
@@ -7760,7 +8317,7 @@ async function generateTagTypes(project) {
7760
8317
  let messageTagsType = "Record<string, string | undefined>";
7761
8318
  let workflowTagsType = "Record<string, string | undefined>";
7762
8319
  try {
7763
- const configPath = path23.join(project.path, "agent.config.ts");
8320
+ const configPath = path26.join(project.path, "agent.config.ts");
7764
8321
  const configModule = await import(`${configPath}?t=${Date.now()}`);
7765
8322
  const config = configModule.default;
7766
8323
  botTagsType = generateTagTypeString(BUILT_IN_TAGS.bot, config?.bot?.tags);
@@ -7806,18 +8363,18 @@ declare module "@botpress/runtime/_types/tags" {
7806
8363
  export type WorkflowTags = ${workflowTagsType};
7807
8364
  }
7808
8365
  `;
7809
- const tagTypesPath = path23.join(project.path, ".adk", "tag-types.d.ts");
8366
+ const tagTypesPath = path26.join(project.path, ".adk", "tag-types.d.ts");
7810
8367
  await createFile(tagTypesPath, await formatCode(content));
7811
8368
  }
7812
8369
 
7813
8370
  // src/generators/configuration-types.ts
7814
8371
  init_utils();
7815
8372
  init_fs();
7816
- import path24 from "path";
8373
+ import path27 from "path";
7817
8374
  async function generateConfigurationTypes(project) {
7818
8375
  let configurationType = "{}";
7819
8376
  try {
7820
- const configPath = path24.join(project.path, "agent.config.ts");
8377
+ const configPath = path27.join(project.path, "agent.config.ts");
7821
8378
  const configModule = await import(`${configPath}?t=${Date.now()}`);
7822
8379
  const config = configModule.default;
7823
8380
  if (config?.configuration?.schema) {
@@ -7841,14 +8398,14 @@ declare module "@botpress/runtime/_types/configuration" {
7841
8398
  export type Configuration = ${configurationType};
7842
8399
  }
7843
8400
  `;
7844
- const configTypesPath = path24.join(project.path, ".adk", "configuration-types.d.ts");
8401
+ const configTypesPath = path27.join(project.path, ".adk", "configuration-types.d.ts");
7845
8402
  await createFile(configTypesPath, await formatCode(content));
7846
8403
  }
7847
8404
 
7848
8405
  // src/generators/workflow-types.ts
7849
8406
  init_utils();
7850
8407
  init_fs();
7851
- import * as path25 from "path";
8408
+ import * as path28 from "path";
7852
8409
  import { BuiltInWorkflows as BuiltInWorkflows3 } from "@botpress/runtime/internal";
7853
8410
  function isBuiltinWorkflow2(name) {
7854
8411
  return !!Object.values(BuiltInWorkflows3).find((x) => x.name === name);
@@ -7860,7 +8417,7 @@ async function generateWorkflowTypes(project) {
7860
8417
  if (isBuiltinWorkflow2(workflowRef.definition.name)) {
7861
8418
  continue;
7862
8419
  }
7863
- const workflowPath = path25.join(project.path, workflowRef.path);
8420
+ const workflowPath = path28.join(project.path, workflowRef.path);
7864
8421
  const workflowModule = await import(`${workflowPath}?t=${Date.now()}`);
7865
8422
  const workflowInstance = workflowModule[workflowRef.export] || workflowModule.default;
7866
8423
  if (!workflowInstance) {
@@ -7907,14 +8464,14 @@ declare module "@botpress/runtime/_types/workflows" {
7907
8464
  ${typeDefinitions || " // No workflows defined yet"}
7908
8465
  };
7909
8466
  }`;
7910
- const workflowTypesPath = path25.join(project.path, ".adk", "workflow-types.d.ts");
8467
+ const workflowTypesPath = path28.join(project.path, ".adk", "workflow-types.d.ts");
7911
8468
  await createFile(workflowTypesPath, await formatCode(content));
7912
8469
  }
7913
8470
 
7914
8471
  // src/generators/conversation-types.ts
7915
8472
  init_utils();
7916
8473
  init_fs();
7917
- import path26 from "path";
8474
+ import path29 from "path";
7918
8475
  function hasConversationIdProperty(schema) {
7919
8476
  if (!schema || typeof schema !== "object") {
7920
8477
  return false;
@@ -7937,7 +8494,7 @@ async function generateConversationTypes(project) {
7937
8494
  const conversationTypes = {};
7938
8495
  for (const conversationRef of project.conversations) {
7939
8496
  try {
7940
- const conversationPath = path26.join(project.path, conversationRef.path);
8497
+ const conversationPath = path29.join(project.path, conversationRef.path);
7941
8498
  const conversationModule = await import(`${conversationPath}?t=${Date.now()}`);
7942
8499
  const conversationInstance = conversationModule[conversationRef.export] || conversationModule.default;
7943
8500
  if (!conversationInstance) {
@@ -8023,14 +8580,14 @@ ${routableEventsDefinitions || " // No routable events found"}
8023
8580
  };
8024
8581
  }
8025
8582
  `;
8026
- const conversationTypesPath = path26.join(project.path, ".adk", "conversation-types.d.ts");
8583
+ const conversationTypesPath = path29.join(project.path, ".adk", "conversation-types.d.ts");
8027
8584
  await createFile(conversationTypesPath, await formatCode(content));
8028
8585
  }
8029
8586
 
8030
8587
  // src/generators/event-types.ts
8031
8588
  init_utils();
8032
8589
  init_fs();
8033
- import path27 from "path";
8590
+ import path30 from "path";
8034
8591
  async function generateEventTypes(project) {
8035
8592
  const defaultEvents = ["register: {}"];
8036
8593
  const integrationEvents = [];
@@ -8082,7 +8639,7 @@ ${allEvents.map((e) => ` ${e}`).join(`
8082
8639
  export type EventPayload<T extends EventName> = Events[T];
8083
8640
  }
8084
8641
  `;
8085
- const eventTypesPath = path27.join(project.path, ".adk", "event-types.d.ts");
8642
+ const eventTypesPath = path30.join(project.path, ".adk", "event-types.d.ts");
8086
8643
  await createFile(eventTypesPath, await formatCode(content));
8087
8644
  }
8088
8645
 
@@ -8091,8 +8648,8 @@ init_fs();
8091
8648
 
8092
8649
  // src/utils/link-sdk.ts
8093
8650
  import { existsSync as existsSync3, realpathSync } from "fs";
8094
- import fs12 from "fs/promises";
8095
- import path28 from "path";
8651
+ import fs13 from "fs/promises";
8652
+ import path31 from "path";
8096
8653
  function findPackage(name, startDir) {
8097
8654
  let current;
8098
8655
  try {
@@ -8100,17 +8657,17 @@ function findPackage(name, startDir) {
8100
8657
  } catch {
8101
8658
  current = startDir;
8102
8659
  }
8103
- while (current !== path28.dirname(current)) {
8104
- const pkgPath = path28.join(current, "node_modules", name);
8660
+ while (current !== path31.dirname(current)) {
8661
+ const pkgPath = path31.join(current, "node_modules", name);
8105
8662
  if (existsSync3(pkgPath)) {
8106
8663
  return pkgPath;
8107
8664
  }
8108
- current = path28.dirname(current);
8665
+ current = path31.dirname(current);
8109
8666
  }
8110
8667
  return null;
8111
8668
  }
8112
8669
  async function linkSdk(agentDir, botDir) {
8113
- const targetSdkPath = path28.join(botDir, "node_modules", "@botpress", "sdk");
8670
+ const targetSdkPath = path31.join(botDir, "node_modules", "@botpress", "sdk");
8114
8671
  if (existsSync3(targetSdkPath)) {
8115
8672
  return;
8116
8673
  }
@@ -8124,17 +8681,17 @@ async function linkSdk(agentDir, botDir) {
8124
8681
  console.warn(`Warning: Could not find @botpress/sdk from @botpress/runtime location (${runtimePath})`);
8125
8682
  return;
8126
8683
  }
8127
- const targetBotpressDir = path28.join(botDir, "node_modules", "@botpress");
8128
- await fs12.mkdir(targetBotpressDir, { recursive: true });
8684
+ const targetBotpressDir = path31.join(botDir, "node_modules", "@botpress");
8685
+ await fs13.mkdir(targetBotpressDir, { recursive: true });
8129
8686
  const symlinkType = process.platform === "win32" ? "junction" : undefined;
8130
- await fs12.symlink(sdkPath, targetSdkPath, symlinkType);
8687
+ await fs13.symlink(sdkPath, targetSdkPath, symlinkType);
8131
8688
  }
8132
8689
 
8133
8690
  // src/bot-generator/dev-id-manager.ts
8134
- import path29 from "path";
8135
- import fs13 from "fs/promises";
8691
+ import path32 from "path";
8692
+ import fs14 from "fs/promises";
8136
8693
  import { existsSync as existsSync4 } from "fs";
8137
- import { Client as Client13 } from "@botpress/client";
8694
+ import { Client as Client14 } from "@botpress/client";
8138
8695
  class DevIdManager {
8139
8696
  projectPath;
8140
8697
  botProjectPath;
@@ -8143,7 +8700,7 @@ class DevIdManager {
8143
8700
  constructor(projectPath, botProjectPath) {
8144
8701
  this.projectPath = projectPath;
8145
8702
  this.botProjectPath = botProjectPath;
8146
- this.projectCachePath = path29.join(botProjectPath, ".botpress", "project.cache.json");
8703
+ this.projectCachePath = path32.join(botProjectPath, ".botpress", "project.cache.json");
8147
8704
  }
8148
8705
  async getClient() {
8149
8706
  if (!this.client) {
@@ -8153,7 +8710,7 @@ class DevIdManager {
8153
8710
  if (!workspaceId) {
8154
8711
  throw new Error('No workspace ID found in agent.json or current profile. Please login again with "adk login"');
8155
8712
  }
8156
- this.client = new Client13({
8713
+ this.client = new Client14({
8157
8714
  token: credentials.token,
8158
8715
  apiUrl: credentials.apiUrl,
8159
8716
  workspaceId,
@@ -8170,7 +8727,7 @@ class DevIdManager {
8170
8727
  async readProjectCache() {
8171
8728
  try {
8172
8729
  if (existsSync4(this.projectCachePath)) {
8173
- const content = await fs13.readFile(this.projectCachePath, "utf-8");
8730
+ const content = await fs14.readFile(this.projectCachePath, "utf-8");
8174
8731
  return JSON.parse(content);
8175
8732
  }
8176
8733
  } catch (error) {
@@ -8180,8 +8737,8 @@ class DevIdManager {
8180
8737
  }
8181
8738
  async saveProjectCache(cache2) {
8182
8739
  try {
8183
- await fs13.mkdir(path29.dirname(this.projectCachePath), { recursive: true });
8184
- 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));
8185
8742
  } catch (error) {
8186
8743
  console.error("Error saving project.cache.json:", error);
8187
8744
  }
@@ -8229,8 +8786,8 @@ class DevIdManager {
8229
8786
  }
8230
8787
 
8231
8788
  // src/bot-generator/integration-sync.ts
8232
- import path30 from "path";
8233
- import fs14 from "fs/promises";
8789
+ import path33 from "path";
8790
+ import fs15 from "fs/promises";
8234
8791
  import { existsSync as existsSync5 } from "fs";
8235
8792
  class IntegrationSync {
8236
8793
  projectPath;
@@ -8239,7 +8796,7 @@ class IntegrationSync {
8239
8796
  constructor(projectPath, botProjectPath) {
8240
8797
  this.projectPath = projectPath;
8241
8798
  this.botProjectPath = botProjectPath;
8242
- this.bpModulesPath = path30.join(botProjectPath, "bp_modules");
8799
+ this.bpModulesPath = path33.join(botProjectPath, "bp_modules");
8243
8800
  }
8244
8801
  async parseIntegrations() {
8245
8802
  const project = await AgentProject.load(this.projectPath);
@@ -8270,16 +8827,16 @@ class IntegrationSync {
8270
8827
  return integrations;
8271
8828
  }
8272
8829
  async isIntegrationSynced(integration) {
8273
- const targetFolder = path30.join(this.bpModulesPath, `integration_${integration.alias}`);
8830
+ const targetFolder = path33.join(this.bpModulesPath, `integration_${integration.alias}`);
8274
8831
  if (!existsSync5(targetFolder)) {
8275
8832
  return false;
8276
8833
  }
8277
8834
  try {
8278
- const indexPath = path30.join(targetFolder, "index.ts");
8835
+ const indexPath = path33.join(targetFolder, "index.ts");
8279
8836
  if (!existsSync5(indexPath)) {
8280
8837
  return false;
8281
8838
  }
8282
- const indexContent = await fs14.readFile(indexPath, "utf-8");
8839
+ const indexContent = await fs15.readFile(indexPath, "utf-8");
8283
8840
  const versionMatch = indexContent.match(/version:\s*["']([^"']+)["']/);
8284
8841
  if (!versionMatch) {
8285
8842
  return false;
@@ -8307,20 +8864,20 @@ class IntegrationSync {
8307
8864
  await command.output();
8308
8865
  }
8309
8866
  async renameIntegrationFolder(integration) {
8310
- const sourceFolder = path30.join(this.bpModulesPath, integration.name.replace("/", "-"));
8311
- 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}`);
8312
8869
  if (!existsSync5(sourceFolder)) {
8313
8870
  throw new Error(`Integration folder not found: ${sourceFolder}`);
8314
8871
  }
8315
8872
  if (existsSync5(targetFolder)) {
8316
- await fs14.rm(targetFolder, { recursive: true, force: true });
8873
+ await fs15.rm(targetFolder, { recursive: true, force: true });
8317
8874
  }
8318
- await fs14.rename(sourceFolder, targetFolder);
8875
+ await fs15.rename(sourceFolder, targetFolder);
8319
8876
  }
8320
8877
  async removeIntegrationFolder(alias) {
8321
- const targetFolder = path30.join(this.bpModulesPath, `integration_${alias}`);
8878
+ const targetFolder = path33.join(this.bpModulesPath, `integration_${alias}`);
8322
8879
  if (existsSync5(targetFolder)) {
8323
- await fs14.rm(targetFolder, { recursive: true, force: true });
8880
+ await fs15.rm(targetFolder, { recursive: true, force: true });
8324
8881
  }
8325
8882
  }
8326
8883
  async syncIntegrations() {
@@ -8330,7 +8887,7 @@ class IntegrationSync {
8330
8887
  if (integrations.length === 0) {
8331
8888
  return { synced, errors };
8332
8889
  }
8333
- await fs14.mkdir(this.bpModulesPath, { recursive: true });
8890
+ await fs15.mkdir(this.bpModulesPath, { recursive: true });
8334
8891
  for (const integration of integrations) {
8335
8892
  try {
8336
8893
  const isAlreadySynced = await this.isIntegrationSynced(integration);
@@ -8352,8 +8909,8 @@ class IntegrationSync {
8352
8909
  }
8353
8910
 
8354
8911
  // src/bot-generator/interface-sync.ts
8355
- import path31 from "path";
8356
- import fs15 from "fs/promises";
8912
+ import path34 from "path";
8913
+ import fs16 from "fs/promises";
8357
8914
  import { existsSync as existsSync6 } from "fs";
8358
8915
  init_constants();
8359
8916
  class InterfaceSync {
@@ -8363,7 +8920,7 @@ class InterfaceSync {
8363
8920
  constructor(projectPath, botProjectPath) {
8364
8921
  this.projectPath = projectPath;
8365
8922
  this.botProjectPath = botProjectPath;
8366
- this.bpModulesPath = path31.join(botProjectPath, "bp_modules");
8923
+ this.bpModulesPath = path34.join(botProjectPath, "bp_modules");
8367
8924
  }
8368
8925
  async parseInterfaces() {
8369
8926
  const interfaces = [];
@@ -8381,16 +8938,16 @@ class InterfaceSync {
8381
8938
  return interfaces;
8382
8939
  }
8383
8940
  async isInterfaceSynced(interfaceInfo) {
8384
- const targetFolder = path31.join(this.bpModulesPath, `interface_${pascalCase(interfaceInfo.alias)}`);
8941
+ const targetFolder = path34.join(this.bpModulesPath, `interface_${pascalCase(interfaceInfo.alias)}`);
8385
8942
  if (!existsSync6(targetFolder)) {
8386
8943
  return false;
8387
8944
  }
8388
8945
  try {
8389
- const indexPath = path31.join(targetFolder, "index.ts");
8946
+ const indexPath = path34.join(targetFolder, "index.ts");
8390
8947
  if (!existsSync6(indexPath)) {
8391
8948
  return false;
8392
8949
  }
8393
- const indexContent = await fs15.readFile(indexPath, "utf-8");
8950
+ const indexContent = await fs16.readFile(indexPath, "utf-8");
8394
8951
  const versionMatch = indexContent.match(/version:\s*["']([^"']+)["']/);
8395
8952
  if (!versionMatch) {
8396
8953
  return false;
@@ -8432,20 +8989,20 @@ class InterfaceSync {
8432
8989
  });
8433
8990
  }
8434
8991
  async renameInterfaceFolder(interfaceInfo) {
8435
- const sourceFolder = path31.join(this.bpModulesPath, interfaceInfo.name);
8436
- 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)}`);
8437
8994
  if (!existsSync6(sourceFolder)) {
8438
8995
  throw new Error(`Interface folder not found: ${sourceFolder}`);
8439
8996
  }
8440
8997
  if (existsSync6(targetFolder)) {
8441
- await fs15.rm(targetFolder, { recursive: true, force: true });
8998
+ await fs16.rm(targetFolder, { recursive: true, force: true });
8442
8999
  }
8443
- await fs15.rename(sourceFolder, targetFolder);
9000
+ await fs16.rename(sourceFolder, targetFolder);
8444
9001
  }
8445
9002
  async removeInterfaceFolder(alias) {
8446
- const targetFolder = path31.join(this.bpModulesPath, `interface_${pascalCase(alias)}`);
9003
+ const targetFolder = path34.join(this.bpModulesPath, `interface_${pascalCase(alias)}`);
8447
9004
  if (existsSync6(targetFolder)) {
8448
- await fs15.rm(targetFolder, { recursive: true, force: true });
9005
+ await fs16.rm(targetFolder, { recursive: true, force: true });
8449
9006
  }
8450
9007
  }
8451
9008
  async syncInterfaces() {
@@ -8455,7 +9012,7 @@ class InterfaceSync {
8455
9012
  if (interfaces.length === 0) {
8456
9013
  return { synced, errors };
8457
9014
  }
8458
- await fs15.mkdir(this.bpModulesPath, { recursive: true });
9015
+ await fs16.mkdir(this.bpModulesPath, { recursive: true });
8459
9016
  for (const interfaceInfo of interfaces) {
8460
9017
  try {
8461
9018
  const isAlreadySynced = await this.isInterfaceSynced(interfaceInfo);
@@ -8476,9 +9033,124 @@ class InterfaceSync {
8476
9033
  }
8477
9034
  }
8478
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
+
8479
9151
  // src/bot-generator/generator.ts
8480
9152
  init_utils();
8481
- import { transforms as transforms3 } from "@botpress/sdk";
9153
+ import { transforms as transforms4 } from "@botpress/sdk";
8482
9154
  init_constants();
8483
9155
  import { BuiltInActions as BuiltInActions2, BuiltInWorkflows as BuiltInWorkflows4, Primitives as Primitives3 } from "@botpress/runtime/internal";
8484
9156
  import { BUILT_IN_TAGS as BUILT_IN_TAGS2 } from "@botpress/runtime/definition";
@@ -8490,7 +9162,7 @@ function isBuiltinAction(name) {
8490
9162
  return !!Object.values(BuiltInActions2).find((x) => x.name === name);
8491
9163
  }
8492
9164
  function getImportPath(from, to) {
8493
- return path34.relative(path34.dirname(from), to).replace(/\.ts$/, "").replace(/\\/g, "/");
9165
+ return path38.relative(path38.dirname(from), to).replace(/\.ts$/, "").replace(/\\/g, "/");
8494
9166
  }
8495
9167
 
8496
9168
  class BotGenerator {
@@ -8499,21 +9171,21 @@ class BotGenerator {
8499
9171
  adkCommand;
8500
9172
  callbacks;
8501
9173
  constructor(options) {
8502
- this.projectPath = path34.resolve(options.projectPath);
8503
- 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"));
8504
9176
  this.adkCommand = options.adkCommand;
8505
9177
  this.callbacks = options.callbacks;
8506
9178
  }
8507
9179
  async listFilesRecursive(rootDir) {
8508
9180
  try {
8509
- if (!existsSync7(rootDir))
9181
+ if (!existsSync8(rootDir))
8510
9182
  return [];
8511
9183
  const result = [];
8512
9184
  const walk = async (dir, relativeBase) => {
8513
- const entries = await fs16.readdir(dir, { withFileTypes: true });
9185
+ const entries = await fs18.readdir(dir, { withFileTypes: true });
8514
9186
  for (const entry of entries) {
8515
- const abs = path34.join(dir, entry.name);
8516
- const rel = path34.join(relativeBase, entry.name);
9187
+ const abs = path38.join(dir, entry.name);
9188
+ const rel = path38.join(relativeBase, entry.name);
8517
9189
  if (entry.isDirectory()) {
8518
9190
  await walk(abs, rel);
8519
9191
  } else {
@@ -8528,20 +9200,20 @@ class BotGenerator {
8528
9200
  }
8529
9201
  }
8530
9202
  async removeEmptyDirectories(rootDir) {
8531
- if (!existsSync7(rootDir))
9203
+ if (!existsSync8(rootDir))
8532
9204
  return;
8533
9205
  const removeIfEmpty = async (dir) => {
8534
- const entries = await fs16.readdir(dir, { withFileTypes: true });
9206
+ const entries = await fs18.readdir(dir, { withFileTypes: true });
8535
9207
  for (const entry of entries) {
8536
9208
  if (entry.isDirectory()) {
8537
- const subdir = path34.join(dir, entry.name);
9209
+ const subdir = path38.join(dir, entry.name);
8538
9210
  await removeIfEmpty(subdir);
8539
9211
  }
8540
9212
  }
8541
- const after = await fs16.readdir(dir);
9213
+ const after = await fs18.readdir(dir);
8542
9214
  if (after.length === 0 && dir !== rootDir) {
8543
9215
  try {
8544
- await fs16.rmdir(dir, { recursive: false });
9216
+ await fs18.rmdir(dir, { recursive: false });
8545
9217
  } catch {}
8546
9218
  }
8547
9219
  };
@@ -8549,11 +9221,13 @@ class BotGenerator {
8549
9221
  }
8550
9222
  async generate() {
8551
9223
  const project = await AgentProject.load(this.projectPath);
8552
- await fs16.mkdir(this.outputPath, { recursive: true });
9224
+ await fs18.mkdir(this.outputPath, { recursive: true });
8553
9225
  await this.generateBotDefinition();
8554
9226
  await this.generateIntegrationsDefinition();
9227
+ await this.generatePluginsDefinition();
8555
9228
  await this.generateInterfacesDefinition();
8556
9229
  await this.generateIntegrationsTypes();
9230
+ await this.generatePluginsTypes();
8557
9231
  await this.generateInterfacesTypes();
8558
9232
  await this.generateTableTypes();
8559
9233
  await this.generateTriggerTypes();
@@ -8565,6 +9239,7 @@ class BotGenerator {
8565
9239
  await this.generateActionTypes();
8566
9240
  await this.generateEventTypes();
8567
9241
  await this.generateIntegrationActionTypes();
9242
+ await this.generatePluginActionTypes();
8568
9243
  await this.generateRuntimeTypes();
8569
9244
  await this.generateClientWrapper();
8570
9245
  await this.generateBotIndex();
@@ -8579,19 +9254,19 @@ class BotGenerator {
8579
9254
  workspaceId: project.agentInfo?.workspaceId
8580
9255
  });
8581
9256
  const integrations = await manager3.loadIntegrations(project.dependencies || {});
8582
- const integrationsDir = path34.join(this.projectPath, ".adk", "integrations");
9257
+ const integrationsDir = path38.join(this.projectPath, ".adk", "integrations");
8583
9258
  const existingIntegrationFiles = await this.listFilesRecursive(integrationsDir);
8584
9259
  let aliases = new Set;
8585
9260
  let files = new Set;
8586
9261
  for (const integration of integrations.integrations) {
8587
9262
  if (integration.definition) {
8588
9263
  const types6 = await generateIntegrationTypes(integration);
8589
- const importPath = `./${path34.join("integrations", types6.names.paths.index).replace(/\\/g, "/")}`;
9264
+ const importPath = `./${path38.join("integrations", types6.names.paths.index).replace(/\\/g, "/")}`;
8590
9265
  aliases.add(`"${integration.alias}": import("${importPath}").${types6.names.typings.index}`);
8591
9266
  for (const [filePath, content] of Object.entries(types6.files)) {
8592
- const fullPath = path34.join(this.projectPath, ".adk", "integrations", filePath);
8593
- const dir = path34.dirname(fullPath);
8594
- 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 });
8595
9270
  await createFile(fullPath, content);
8596
9271
  files.add(filePath);
8597
9272
  }
@@ -8611,18 +9286,68 @@ class BotGenerator {
8611
9286
  };
8612
9287
  }
8613
9288
  `;
8614
- 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));
8615
9290
  const staleIntegrationFiles = existingIntegrationFiles.filter((f) => !files.has(f));
8616
9291
  if (staleIntegrationFiles.length > 0) {
8617
9292
  for (const rel of staleIntegrationFiles) {
8618
- const abs = path34.join(integrationsDir, rel);
9293
+ const abs = path38.join(integrationsDir, rel);
8619
9294
  try {
8620
- await fs16.rm(abs, { force: true });
9295
+ await fs18.rm(abs, { force: true });
8621
9296
  } catch {}
8622
9297
  }
8623
9298
  }
8624
9299
  await this.removeEmptyDirectories(integrationsDir);
8625
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
+ }
8626
9351
  async generateTableTypes() {
8627
9352
  const project = await AgentProject.load(this.projectPath);
8628
9353
  await generateTableTypes(project);
@@ -8665,6 +9390,10 @@ class BotGenerator {
8665
9390
  const { generateIntegrationActionTypes: generateIntegrationActionTypes2 } = await Promise.resolve().then(() => (init_integration_action_types(), exports_integration_action_types));
8666
9391
  await generateIntegrationActionTypes2(project);
8667
9392
  }
9393
+ async generatePluginActionTypes() {
9394
+ const project = await AgentProject.load(this.projectPath);
9395
+ await generatePluginActionTypes(project);
9396
+ }
8668
9397
  async generateClientWrapper() {
8669
9398
  const project = await AgentProject.load(this.projectPath);
8670
9399
  await generateClientWrapper(project);
@@ -8688,7 +9417,7 @@ class BotGenerator {
8688
9417
  let botStateType = "{}";
8689
9418
  let userStateType = "{}";
8690
9419
  try {
8691
- const configPath = path34.join(project.path, "agent.config.ts");
9420
+ const configPath = path38.join(project.path, "agent.config.ts");
8692
9421
  const configModule = await import(`${configPath}?t=${Date.now()}`);
8693
9422
  const config = configModule.default;
8694
9423
  if (config?.bot?.state) {
@@ -8724,7 +9453,7 @@ declare module "@botpress/runtime/_types/state" {
8724
9453
  export type UserState = ${userStateType};
8725
9454
  }
8726
9455
  `;
8727
- 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));
8728
9457
  }
8729
9458
  async generateInterfacesTypes() {
8730
9459
  const project = await AgentProject.load(this.projectPath);
@@ -8732,7 +9461,7 @@ declare module "@botpress/runtime/_types/state" {
8732
9461
  workspaceId: project.agentInfo?.workspaceId
8733
9462
  });
8734
9463
  const manager3 = new InterfaceManager;
8735
- const interfacesDir = path34.join(this.projectPath, ".adk", "interfaces");
9464
+ const interfacesDir = path38.join(this.projectPath, ".adk", "interfaces");
8736
9465
  const existingInterfaceFiles = await this.listFilesRecursive(interfacesDir);
8737
9466
  const interfaces = await manager3.loadInterfaces(project.dependencies || {}).then((result) => result.interfaces.filter((int) => int.definition).map((x) => x.definition));
8738
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 })));
@@ -8741,12 +9470,12 @@ declare module "@botpress/runtime/_types/state" {
8741
9470
  let files = new Set;
8742
9471
  for (const int of interfaces) {
8743
9472
  const types6 = await generateInterfaceTypes(int, integrationsWithAlias);
8744
- 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, "/")}";`);
8745
9474
  aliases.add(`"${types6.names.name}": ${types6.names.typings.index}`);
8746
9475
  for (const [filePath, content] of Object.entries(types6.files)) {
8747
- const fullPath = path34.join(this.projectPath, ".adk", "interfaces", filePath);
8748
- const dir = path34.dirname(fullPath);
8749
- 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 });
8750
9479
  await createFile(fullPath, content);
8751
9480
  files.add(filePath);
8752
9481
  }
@@ -8782,14 +9511,14 @@ declare module "@botpress/runtime/_types/state" {
8782
9511
  `)}
8783
9512
  };
8784
9513
  `;
8785
- await createFile(path34.join(this.projectPath, ".adk", "interfaces.d.ts"), await formatCode(types5));
8786
- 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));
8787
9516
  const staleInterfaceFiles = existingInterfaceFiles.filter((f) => !files.has(f));
8788
9517
  if (staleInterfaceFiles.length > 0) {
8789
9518
  for (const rel of staleInterfaceFiles) {
8790
- const abs = path34.join(interfacesDir, rel);
9519
+ const abs = path38.join(interfacesDir, rel);
8791
9520
  try {
8792
- await fs16.rm(abs, { force: true });
9521
+ await fs18.rm(abs, { force: true });
8793
9522
  } catch {}
8794
9523
  }
8795
9524
  }
@@ -8820,7 +9549,31 @@ declare module "@botpress/runtime/_types/state" {
8820
9549
  `) : ""}
8821
9550
  } as Record<string, IntegrationPackage>;
8822
9551
  `;
8823
- 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);
8824
9577
  }
8825
9578
  async generateInterfacesDefinition() {
8826
9579
  const interfaces = BUILTIN_INTERFACES;
@@ -8843,7 +9596,7 @@ declare module "@botpress/runtime/_types/state" {
8843
9596
  `) : ""}
8844
9597
  } as Record<string, InterfacePackage>;
8845
9598
  `;
8846
- 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));
8847
9600
  }
8848
9601
  reportServerConfigSync(serverConfigResult, integrations) {
8849
9602
  if (!this.callbacks) {
@@ -8897,6 +9650,23 @@ declare module "@botpress/runtime/_types/state" {
8897
9650
  const configData = Object.keys(mergedConfig).length > 0 ? `, configuration: ${JSON.stringify(mergedConfig)}` : "";
8898
9651
  addIntegrations.push(`bot.addIntegration(${importName}, { alias: "${alias}", enabled: true${configType}${configData} });`);
8899
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
+ }
8900
9670
  const botTags = {};
8901
9671
  const userTags = {};
8902
9672
  const conversationTags = {};
@@ -8917,9 +9687,9 @@ declare module "@botpress/runtime/_types/state" {
8917
9687
  if (project.config?.workflow?.tags) {
8918
9688
  Object.assign(workflowTags, project.config.workflow.tags);
8919
9689
  }
8920
- const crypto5 = __require("crypto");
9690
+ const crypto6 = __require("crypto");
8921
9691
  const hashString = (str) => {
8922
- 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();
8923
9693
  };
8924
9694
  for (const trigger of project.triggers) {
8925
9695
  const triggerName = trigger.definition.name;
@@ -8937,7 +9707,7 @@ declare module "@botpress/runtime/_types/state" {
8937
9707
  if (isBuiltinWorkflow3(workflow.definition.name)) {
8938
9708
  continue;
8939
9709
  }
8940
- const workflowPath = path34.join(project.path, workflow.path);
9710
+ const workflowPath = path38.join(project.path, workflow.path);
8941
9711
  const workflowModule = await import(`${workflowPath}?t=${Date.now()}`);
8942
9712
  const workflowInstance = workflowModule.default || workflowModule[workflow.export];
8943
9713
  if (workflowInstance) {
@@ -8961,8 +9731,8 @@ declare module "@botpress/runtime/_types/state" {
8961
9731
  schedule: definition.schedule
8962
9732
  });
8963
9733
  }
8964
- const inputSchema = definition.input ? transforms3.fromJSONSchema(definition.input).naked().toTypescriptSchema() : "z.object({})";
8965
- 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({})";
8966
9736
  const parts = [];
8967
9737
  if (definition.description) {
8968
9738
  parts.push(`title: ${JSON.stringify(definition.name)}`);
@@ -9002,7 +9772,7 @@ declare module "@botpress/runtime/_types/state" {
9002
9772
  const schema = eventDef.schema;
9003
9773
  let schemaCode = "z.object({})";
9004
9774
  if (schema && typeof schema.toJSONSchema === "function") {
9005
- schemaCode = transforms3.fromJSONSchema(schema.toJSONSchema()).toTypescriptSchema();
9775
+ schemaCode = transforms4.fromJSONSchema(schema.toJSONSchema()).toTypescriptSchema();
9006
9776
  }
9007
9777
  const parts = [`schema: ${schemaCode}`];
9008
9778
  if (eventDef.description) {
@@ -9014,7 +9784,7 @@ declare module "@botpress/runtime/_types/state" {
9014
9784
  }`);
9015
9785
  }
9016
9786
  const configSchema = project.config?.configuration?.schema;
9017
- const configSchemaCode = configSchema ? transforms3.fromJSONSchema(configSchema.toJSONSchema()).toTypescriptSchema() : undefined;
9787
+ const configSchemaCode = configSchema ? transforms4.fromJSONSchema(configSchema.toJSONSchema()).toTypescriptSchema() : undefined;
9018
9788
  const content = dedent`
9019
9789
  import { BotDefinition, z } from "@botpress/sdk";
9020
9790
  import {
@@ -9086,8 +9856,8 @@ configuration: {
9086
9856
  parts.push(`description: ${JSON.stringify(def.description)}`);
9087
9857
  if (def.attributes)
9088
9858
  parts.push(`attributes: ${JSON.stringify(def.attributes)}`);
9089
- parts.push(`input: { schema: ${transforms3.fromJSONSchema(def.input).toTypescriptSchema()} }`);
9090
- 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()} }`);
9091
9861
  return `"${name}": {
9092
9862
  ${parts.join(`,
9093
9863
  `)}
@@ -9189,10 +9959,13 @@ configuration: {
9189
9959
  const integrationsSection = addIntegrations.length > 0 ? `
9190
9960
  ` + addIntegrations.join(`
9191
9961
  `) : "";
9192
- const fullContent = content + integrationsSection + `
9962
+ const pluginsSection = addPlugins.length > 0 ? `
9963
+ ` + addPlugins.join(`
9964
+ `) : "";
9965
+ const fullContent = content + integrationsSection + pluginsSection + `
9193
9966
 
9194
9967
  export default bot;`;
9195
- 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));
9196
9969
  }
9197
9970
  async generateBotIndex() {
9198
9971
  const content = dedent`
@@ -9231,7 +10004,7 @@ export default bot;`;
9231
10004
 
9232
10005
  export default bot
9233
10006
  `;
9234
- 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));
9235
10008
  }
9236
10009
  async generatePackageJson(project) {
9237
10010
  const packageJson = {
@@ -9245,7 +10018,7 @@ export default bot;`;
9245
10018
  typescript: "^5.9.3"
9246
10019
  }
9247
10020
  };
9248
- 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));
9249
10022
  }
9250
10023
  async generateTsConfig() {
9251
10024
  const tsConfig = {
@@ -9276,7 +10049,7 @@ export default bot;`;
9276
10049
  },
9277
10050
  include: [".botpress/**/*", "src/**/*", "bp_modules/**/*", "./*.ts", "./*.json", "../*.d.ts"]
9278
10051
  };
9279
- 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));
9280
10053
  }
9281
10054
  async generateGlobalTypes() {
9282
10055
  const content = dedent`
@@ -9299,42 +10072,42 @@ export default bot;`;
9299
10072
 
9300
10073
  export {};
9301
10074
  `;
9302
- 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));
9303
10076
  }
9304
10077
  async copyAssets() {
9305
- const assetsPath = path34.join(this.projectPath, "assets");
9306
- const targetPath = path34.join(this.outputPath, "assets");
9307
- if (existsSync7(assetsPath)) {
9308
- 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 });
9309
10082
  await this.copyDirectory(assetsPath, targetPath);
9310
10083
  }
9311
10084
  }
9312
10085
  async copyDirectory(src, dest) {
9313
- const entries = await fs16.readdir(src, { withFileTypes: true });
10086
+ const entries = await fs18.readdir(src, { withFileTypes: true });
9314
10087
  for (const entry of entries) {
9315
- const srcPath = path34.join(src, entry.name);
9316
- const destPath = path34.join(dest, entry.name);
10088
+ const srcPath = path38.join(src, entry.name);
10089
+ const destPath = path38.join(dest, entry.name);
9317
10090
  if (entry.isDirectory()) {
9318
- await fs16.mkdir(destPath, { recursive: true });
10091
+ await fs18.mkdir(destPath, { recursive: true });
9319
10092
  await this.copyDirectory(srcPath, destPath);
9320
10093
  } else {
9321
- await fs16.copyFile(srcPath, destPath);
10094
+ await fs18.copyFile(srcPath, destPath);
9322
10095
  }
9323
10096
  }
9324
10097
  }
9325
10098
  async generateAdkRuntime() {
9326
10099
  const project = new AgentProject(this.projectPath);
9327
10100
  await project.reload();
9328
- const srcDir = path34.join(this.outputPath, "src");
10101
+ const srcDir = path38.join(this.outputPath, "src");
9329
10102
  {
9330
- const dest = path34.join(srcDir, "conversations.ts");
10103
+ const dest = path38.join(srcDir, "conversations.ts");
9331
10104
  const imports = new Map;
9332
10105
  const exports = new Set;
9333
10106
  let index = 1;
9334
10107
  for (const conversation of project.conversations) {
9335
10108
  if (!imports.has(conversation.path)) {
9336
10109
  const name = `conversations_${index++}`;
9337
- const importPath = getImportPath(dest, path34.join(project.path, conversation.path));
10110
+ const importPath = getImportPath(dest, path38.join(project.path, conversation.path));
9338
10111
  imports.set(conversation.path, {
9339
10112
  name,
9340
10113
  statement: `import * as ${name} from "${importPath}";`
@@ -9360,14 +10133,14 @@ export default bot;`;
9360
10133
  await createFile(dest, await formatCode(content2));
9361
10134
  }
9362
10135
  {
9363
- const dest = path34.join(srcDir, "knowledge.ts");
10136
+ const dest = path38.join(srcDir, "knowledge.ts");
9364
10137
  const imports = new Map;
9365
10138
  const exports = new Set;
9366
10139
  let index = 1;
9367
10140
  for (const knowledge of project.knowledge) {
9368
10141
  if (!imports.has(knowledge.path)) {
9369
10142
  const name = `knowledge_${index++}`;
9370
- const importPath = getImportPath(dest, path34.join(project.path, knowledge.path));
10143
+ const importPath = getImportPath(dest, path38.join(project.path, knowledge.path));
9371
10144
  imports.set(knowledge.path, {
9372
10145
  name,
9373
10146
  statement: `import * as ${name} from "${importPath}";`
@@ -9393,8 +10166,8 @@ export default bot;`;
9393
10166
  await createFile(dest, await formatCode(content2));
9394
10167
  }
9395
10168
  {
9396
- const dest = path34.join(srcDir, "triggers.ts");
9397
- const { transforms: transforms4 } = await import("@botpress/sdk");
10169
+ const dest = path38.join(srcDir, "triggers.ts");
10170
+ const { transforms: transforms5 } = await import("@botpress/sdk");
9398
10171
  const imports = new Map;
9399
10172
  const exports = new Set;
9400
10173
  const payloadTypes = {};
@@ -9402,7 +10175,7 @@ export default bot;`;
9402
10175
  for (const trigger of project.triggers) {
9403
10176
  if (!imports.has(trigger.path)) {
9404
10177
  const name = `triggers_${index++}`;
9405
- const importPath = getImportPath(dest, path34.join(project.path, trigger.path));
10178
+ const importPath = getImportPath(dest, path38.join(project.path, trigger.path));
9406
10179
  imports.set(trigger.path, {
9407
10180
  name,
9408
10181
  statement: `import * as ${name} from "${importPath}";`
@@ -9412,12 +10185,12 @@ export default bot;`;
9412
10185
  }
9413
10186
  for (const trigger of project.triggers) {
9414
10187
  try {
9415
- const absolutePath = path34.join(project.path, trigger.path);
10188
+ const absolutePath = path38.join(project.path, trigger.path);
9416
10189
  const triggerModule = await import(`${absolutePath}?t=${Date.now()}`);
9417
10190
  const triggerInstance = triggerModule[trigger.export] || triggerModule.default;
9418
10191
  if (triggerInstance && triggerInstance.payload) {
9419
- const jsonSchema = transforms4.toJSONSchema(triggerInstance.payload);
9420
- const payloadType = transforms4.fromJSONSchema(jsonSchema).toTypescriptType();
10192
+ const jsonSchema = transforms5.toJSONSchema(triggerInstance.payload);
10193
+ const payloadType = transforms5.fromJSONSchema(jsonSchema).toTypescriptType();
9421
10194
  payloadTypes[trigger.definition.name] = payloadType;
9422
10195
  } else {
9423
10196
  payloadTypes[trigger.definition.name] = "{}";
@@ -9455,7 +10228,7 @@ export default bot;`;
9455
10228
  await createFile(dest, await formatCode(content2));
9456
10229
  }
9457
10230
  {
9458
- const dest = path34.join(srcDir, "workflows.ts");
10231
+ const dest = path38.join(srcDir, "workflows.ts");
9459
10232
  const imports = new Map;
9460
10233
  const exports = new Set;
9461
10234
  let index = 1;
@@ -9465,7 +10238,7 @@ export default bot;`;
9465
10238
  }
9466
10239
  if (!imports.has(workflow.path)) {
9467
10240
  const name = `workflows_${index++}`;
9468
- const importPath = getImportPath(dest, path34.join(project.path, workflow.path));
10241
+ const importPath = getImportPath(dest, path38.join(project.path, workflow.path));
9469
10242
  const statement = `import * as ${name} from "${importPath}";`;
9470
10243
  imports.set(workflow.path, {
9471
10244
  name,
@@ -9499,7 +10272,7 @@ export default bot;`;
9499
10272
  await createFile(dest, await formatCode(content2));
9500
10273
  }
9501
10274
  {
9502
- const dest = path34.join(srcDir, "actions.ts");
10275
+ const dest = path38.join(srcDir, "actions.ts");
9503
10276
  const imports = new Map;
9504
10277
  const exports = new Set;
9505
10278
  let index = 1;
@@ -9509,7 +10282,7 @@ export default bot;`;
9509
10282
  }
9510
10283
  if (!imports.has(action.path)) {
9511
10284
  const name = `actions_${index++}`;
9512
- const importPath = getImportPath(dest, path34.join(project.path, action.path));
10285
+ const importPath = getImportPath(dest, path38.join(project.path, action.path));
9513
10286
  imports.set(action.path, {
9514
10287
  name,
9515
10288
  statement: `import * as ${name} from "${importPath}";`
@@ -9535,14 +10308,14 @@ export default bot;`;
9535
10308
  await createFile(dest, await formatCode(content2));
9536
10309
  }
9537
10310
  {
9538
- const dest = path34.join(srcDir, "tables.ts");
10311
+ const dest = path38.join(srcDir, "tables.ts");
9539
10312
  const imports = new Map;
9540
10313
  const exports = new Set;
9541
10314
  let index = 1;
9542
10315
  for (const table of project.tables) {
9543
10316
  if (!imports.has(table.path)) {
9544
10317
  const name = `tables_${index++}`;
9545
- const importPath = getImportPath(dest, path34.join(project.path, table.path));
10318
+ const importPath = getImportPath(dest, path38.join(project.path, table.path));
9546
10319
  imports.set(table.path, {
9547
10320
  name,
9548
10321
  statement: `import * as ${name} from "${importPath}";`
@@ -9568,8 +10341,8 @@ export default bot;`;
9568
10341
  await createFile(dest, await formatCode(content2));
9569
10342
  }
9570
10343
  {
9571
- const dest = path34.join(srcDir, "config.ts");
9572
- 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"));
9573
10346
  const content2 = `
9574
10347
  ////////////////////////////////////////////////////////
9575
10348
  // DO NOT EDIT THIS FILE DIRECTLY
@@ -9633,15 +10406,16 @@ export default bot;`;
9633
10406
  handlers.trigger.setup(bot);
9634
10407
  handlers.workflow.setup(bot);
9635
10408
  handlers.actions.setup(bot);
10409
+ handlers.plugins.setup(bot);
9636
10410
  }
9637
10411
  `;
9638
- 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));
9639
10413
  }
9640
10414
  async copyAssetsRuntime() {
9641
- const assetsRuntimePath = path34.join(this.projectPath, ".adk", "assets-runtime.ts");
9642
- if (existsSync7(assetsRuntimePath)) {
9643
- const content = await fs16.readFile(assetsRuntimePath, "utf-8");
9644
- 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));
9645
10419
  }
9646
10420
  }
9647
10421
  }
@@ -9650,11 +10424,11 @@ async function generateBotProject(options) {
9650
10424
  await generator.generate();
9651
10425
  await generator.generateAdkRuntime();
9652
10426
  await generator.copyAssetsRuntime();
9653
- const botPath = options.outputPath || path34.join(options.projectPath, ".adk", "bot");
10427
+ const botPath = options.outputPath || path38.join(options.projectPath, ".adk", "bot");
9654
10428
  await linkSdk(options.projectPath, botPath);
9655
- 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"));
9656
10430
  await devIdManager.restoreDevId();
9657
- 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"));
9658
10432
  const integrationSyncResult = await integrationSync.syncIntegrations();
9659
10433
  if (integrationSyncResult.errors.length > 0) {
9660
10434
  console.warn(`⚠️ Some integrations failed to sync:`);
@@ -9662,7 +10436,7 @@ async function generateBotProject(options) {
9662
10436
  console.warn(` - ${alias}: ${error}`);
9663
10437
  });
9664
10438
  }
9665
- 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"));
9666
10440
  const interfaceSyncResult = await interfaceSync.syncInterfaces();
9667
10441
  if (interfaceSyncResult.errors.length > 0) {
9668
10442
  console.warn(`⚠️ Some interfaces failed to sync:`);
@@ -9670,10 +10444,18 @@ async function generateBotProject(options) {
9670
10444
  console.warn(` - ${alias}: ${error}`);
9671
10445
  });
9672
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
+ }
9673
10455
  }
9674
10456
  // src/tables/table-manager.ts
9675
- import { Client as Client14 } from "@botpress/client";
9676
- import { transforms as transforms4 } from "@botpress/sdk";
10457
+ import { Client as Client15 } from "@botpress/client";
10458
+ import { transforms as transforms5 } from "@botpress/sdk";
9677
10459
  class TableManager {
9678
10460
  client;
9679
10461
  botId;
@@ -9686,7 +10468,7 @@ class TableManager {
9686
10468
  if (!this.client) {
9687
10469
  const credentials = await auth.getActiveCredentials();
9688
10470
  this.assertBotId("initialize client");
9689
- this.client = new Client14({
10471
+ this.client = new Client15({
9690
10472
  token: credentials.token,
9691
10473
  apiUrl: credentials.apiUrl,
9692
10474
  botId: this.botId,
@@ -9996,8 +10778,8 @@ class TableManager {
9996
10778
  const factorMatches = (local.factor || 1) === (remote.factor || 1);
9997
10779
  const keyColumnMatches = (local.keyColumn || "") === (remote.keyColumn || "");
9998
10780
  const tagsMatch = JSON.stringify(local.tags || {}) === JSON.stringify(remote.tags || {});
9999
- const localSchema = transforms4.fromJSONSchema(cleanedLocalSchema);
10000
- const remoteSchema = transforms4.fromJSONSchema(cleanedRemoteSchema);
10781
+ const localSchema = transforms5.fromJSONSchema(cleanedLocalSchema);
10782
+ const remoteSchema = transforms5.fromJSONSchema(cleanedRemoteSchema);
10001
10783
  const schemasEqual = localSchema.isEqual(remoteSchema);
10002
10784
  const hasMetadataChanges = differences.length > 0;
10003
10785
  if (!schemasEqual || !factorMatches || hasMetadataChanges || !keyColumnMatches || !tagsMatch) {
@@ -10170,11 +10952,11 @@ class TableManager {
10170
10952
  }
10171
10953
  }
10172
10954
  // src/knowledge/manager.ts
10173
- import crypto5 from "crypto";
10174
- import path35 from "path";
10175
- import fs17 from "fs/promises";
10955
+ import crypto6 from "crypto";
10956
+ import path39 from "path";
10957
+ import fs19 from "fs/promises";
10176
10958
  import { glob } from "glob";
10177
- import { Client as Client15 } from "@botpress/client";
10959
+ import { Client as Client16 } from "@botpress/client";
10178
10960
  import { DataSource } from "@botpress/runtime";
10179
10961
 
10180
10962
  // src/knowledge/types.ts
@@ -10219,7 +11001,7 @@ class KnowledgeManager {
10219
11001
  if (!this.client) {
10220
11002
  const credentials = await auth.getActiveCredentials();
10221
11003
  this.assertBotId("initialize client");
10222
- this.client = new Client15({
11004
+ this.client = new Client16({
10223
11005
  token: credentials.token,
10224
11006
  apiUrl: credentials.apiUrl,
10225
11007
  botId: this.botId,
@@ -10261,7 +11043,7 @@ class KnowledgeManager {
10261
11043
  const sortedEntries = Object.entries(fileHashes).sort(([a], [b]) => a.localeCompare(b));
10262
11044
  const combined = sortedEntries.map(([filePath, hash]) => `${filePath}:${hash}`).join(`
10263
11045
  `);
10264
- return crypto5.createHash("sha256").update(combined).digest("hex");
11046
+ return crypto6.createHash("sha256").update(combined).digest("hex");
10265
11047
  }
10266
11048
  async listRemoteKnowledgeBases() {
10267
11049
  const client = await this.getClient();
@@ -10376,7 +11158,7 @@ class KnowledgeManager {
10376
11158
  }
10377
11159
  computeConfigHash(config) {
10378
11160
  const sortedConfig = JSON.stringify(config, Object.keys(config).sort());
10379
- return crypto5.createHash("sha256").update(sortedConfig).digest("hex");
11161
+ return crypto6.createHash("sha256").update(sortedConfig).digest("hex");
10380
11162
  }
10381
11163
  async syncWebsiteSource(kbName, kbId, force) {
10382
11164
  const client = await this.getClient();
@@ -10621,16 +11403,16 @@ class KnowledgeManager {
10621
11403
  }
10622
11404
  async scanLocalFileHashes(directoryPath, filterFn) {
10623
11405
  const projectDir = this.project.path;
10624
- const directory = path35.resolve(projectDir, directoryPath);
11406
+ const directory = path39.resolve(projectDir, directoryPath);
10625
11407
  if (this.fileHashCache.has(directory)) {
10626
11408
  return this.fileHashCache.get(directory);
10627
11409
  }
10628
11410
  const files = glob.sync(directory + "/**/*.*", { absolute: true, nodir: true }).filter((file) => !filterFn || filterFn(file));
10629
11411
  const hashes = {};
10630
11412
  for (const file of files) {
10631
- const relPath = path35.relative(directory, file);
10632
- const content = await fs17.readFile(file);
10633
- 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");
10634
11416
  }
10635
11417
  this.fileHashCache.set(directory, hashes);
10636
11418
  return hashes;
@@ -10736,7 +11518,7 @@ class KnowledgeManager {
10736
11518
  }
10737
11519
  async syncDirectorySource(client, kbName, kbId, dsId, directoryPath, filterFn, force) {
10738
11520
  const projectDir = this.project.path;
10739
- const directory = path35.resolve(projectDir, directoryPath);
11521
+ const directory = path39.resolve(projectDir, directoryPath);
10740
11522
  if (!directory.startsWith(projectDir)) {
10741
11523
  throw new Error("Directory path must be within the agent's directory");
10742
11524
  }
@@ -10758,8 +11540,8 @@ class KnowledgeManager {
10758
11540
  return true;
10759
11541
  }).map((f) => ({
10760
11542
  abs: f,
10761
- rel: path35.relative(directory, f),
10762
- name: path35.basename(f)
11543
+ rel: path39.relative(directory, f),
11544
+ name: path39.basename(f)
10763
11545
  }));
10764
11546
  console.log(` Found ${allFiles.length} files in ${directoryPath}`);
10765
11547
  const cachedHashes = await this.scanLocalFileHashes(directoryPath, filterFn);
@@ -10833,15 +11615,15 @@ class KnowledgeManager {
10833
11615
  }
10834
11616
  async upsertFile(client, local, dsId, tags, force, cachedHash) {
10835
11617
  const key = `data_source://document/${dsId}/${local.rel}`;
10836
- const content = await fs17.readFile(local.abs);
10837
- 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");
10838
11620
  try {
10839
11621
  const { file } = await client.getFile({ id: key });
10840
11622
  if (!force && isFileMetadata(file.metadata) && file.metadata.hash === hash) {
10841
11623
  return null;
10842
11624
  }
10843
11625
  } catch {}
10844
- const title = path35.basename(local.name, path35.extname(local.name));
11626
+ const title = path39.basename(local.name, path39.extname(local.name));
10845
11627
  const metadata = {
10846
11628
  hash,
10847
11629
  dsId,
@@ -10969,7 +11751,7 @@ class KBSyncFormatter {
10969
11751
  import { watch as watch2, readdirSync as readdirSync2 } from "fs";
10970
11752
  import { EventEmitter as EventEmitter3 } from "events";
10971
11753
  import { join as join8, relative as relative3 } from "path";
10972
- import { existsSync as existsSync8 } from "fs";
11754
+ import { existsSync as existsSync9 } from "fs";
10973
11755
 
10974
11756
  class FileWatcher2 extends EventEmitter3 {
10975
11757
  projectPath;
@@ -10987,12 +11769,12 @@ class FileWatcher2 extends EventEmitter3 {
10987
11769
  const rootFiles = ["package.json", "agent.json", "agent.config.ts"];
10988
11770
  for (const file of rootFiles) {
10989
11771
  const filePath = join8(this.projectPath, file);
10990
- if (existsSync8(filePath)) {
11772
+ if (existsSync9(filePath)) {
10991
11773
  this.watchFile(filePath);
10992
11774
  }
10993
11775
  }
10994
11776
  const srcPath = join8(this.projectPath, "src");
10995
- if (existsSync8(srcPath)) {
11777
+ if (existsSync9(srcPath)) {
10996
11778
  this.initializeDirectoryState(srcPath);
10997
11779
  this.watchDirectory(srcPath);
10998
11780
  }
@@ -11041,7 +11823,7 @@ class FileWatcher2 extends EventEmitter3 {
11041
11823
  }
11042
11824
  }
11043
11825
  handleFileChange(filePath) {
11044
- const fileExists = existsSync8(filePath);
11826
+ const fileExists = existsSync9(filePath);
11045
11827
  const previousState = this.fileStates.get(filePath);
11046
11828
  let changeType;
11047
11829
  if (!fileExists && previousState !== undefined) {
@@ -11081,7 +11863,7 @@ class FileWatcher2 extends EventEmitter3 {
11081
11863
  this.emit("change", event);
11082
11864
  }
11083
11865
  updateFileState(filePath) {
11084
- if (existsSync8(filePath)) {
11866
+ if (existsSync9(filePath)) {
11085
11867
  this.fileStates.set(filePath, Date.now());
11086
11868
  }
11087
11869
  }
@@ -11105,8 +11887,8 @@ class FileWatcher2 extends EventEmitter3 {
11105
11887
  }
11106
11888
  }
11107
11889
  // src/preflight/checker.ts
11108
- import { Client as Client16 } from "@botpress/client";
11109
- import path36 from "path";
11890
+ import { Client as Client17 } from "@botpress/client";
11891
+ import path40 from "path";
11110
11892
 
11111
11893
  // src/preflight/types.ts
11112
11894
  function hasIntegrationChanges(integrations) {
@@ -11320,7 +12102,7 @@ class PreflightChecker {
11320
12102
  if (!workspaceId) {
11321
12103
  throw new Error('No workspace ID found. Please login with "adk login"');
11322
12104
  }
11323
- this.client = new Client16({
12105
+ this.client = new Client17({
11324
12106
  token: credentials.token,
11325
12107
  apiUrl: credentials.apiUrl,
11326
12108
  workspaceId,
@@ -11468,7 +12250,7 @@ class PreflightChecker {
11468
12250
  options?.onProgress?.("Regenerating bot project...");
11469
12251
  await generateBotProject({
11470
12252
  projectPath: this.projectPath,
11471
- outputPath: path36.join(this.projectPath, ".adk", "bot"),
12253
+ outputPath: path40.join(this.projectPath, ".adk", "bot"),
11472
12254
  callbacks: options
11473
12255
  });
11474
12256
  options?.onSuccess?.("Bot project regenerated");
@@ -11476,21 +12258,21 @@ class PreflightChecker {
11476
12258
  }
11477
12259
  // src/runner/script-runner.ts
11478
12260
  import dedent2 from "dedent";
11479
- import { existsSync as existsSync9 } from "fs";
11480
- import fs18 from "fs/promises";
11481
- import path37 from "path";
12261
+ import { existsSync as existsSync10 } from "fs";
12262
+ import fs20 from "fs/promises";
12263
+ import path41 from "path";
11482
12264
  import { spawn } from "child_process";
11483
12265
  init_utils();
11484
12266
  init_credentials();
11485
12267
  async function findAgentRoot(startPath) {
11486
- let currentPath = path37.resolve(startPath);
11487
- const root = path37.parse(currentPath).root;
12268
+ let currentPath = path41.resolve(startPath);
12269
+ const root = path41.parse(currentPath).root;
11488
12270
  while (currentPath !== root) {
11489
12271
  try {
11490
- await fs18.access(path37.join(currentPath, "agent.config.ts"));
12272
+ await fs20.access(path41.join(currentPath, "agent.config.ts"));
11491
12273
  return currentPath;
11492
12274
  } catch {
11493
- currentPath = path37.dirname(currentPath);
12275
+ currentPath = path41.dirname(currentPath);
11494
12276
  }
11495
12277
  }
11496
12278
  return null;
@@ -11502,7 +12284,7 @@ class ScriptRunner {
11502
12284
  prod;
11503
12285
  credentials;
11504
12286
  constructor(options) {
11505
- this.projectPath = path37.resolve(options.projectPath);
12287
+ this.projectPath = path41.resolve(options.projectPath);
11506
12288
  this.forceRegenerate = options.forceRegenerate ?? false;
11507
12289
  this.prod = options.prod ?? false;
11508
12290
  this.credentials = options.credentials;
@@ -11511,10 +12293,10 @@ class ScriptRunner {
11511
12293
  const project = await AgentProject.load(this.projectPath, {
11512
12294
  adkCommand: "adk-build"
11513
12295
  });
11514
- const botPath = path37.join(this.projectPath, ".adk", "bot");
11515
- const runnerPath = path37.join(botPath, "src", "script-runner.ts");
11516
- const botpressTypesPath = path37.join(botPath, ".botpress", "implementation", "index.ts");
11517
- 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);
11518
12300
  if (needsRegenerate) {
11519
12301
  try {
11520
12302
  await generateAssetsTypes(project.path);
@@ -11630,7 +12412,7 @@ class ScriptRunner {
11630
12412
 
11631
12413
  runScript()
11632
12414
  `;
11633
- 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");
11634
12416
  }
11635
12417
  async setupTestRuntime(options = {}) {
11636
12418
  const { botPath, project } = await this.prepare();
@@ -11661,7 +12443,7 @@ class ScriptRunner {
11661
12443
  for (const [key, value] of Object.entries(envVars)) {
11662
12444
  process.env[key] = value;
11663
12445
  }
11664
- const runtimePath = path37.join(botPath, "src", "index.ts");
12446
+ const runtimePath = path41.join(botPath, "src", "index.ts");
11665
12447
  return {
11666
12448
  botPath,
11667
12449
  runtimePath,
@@ -11674,10 +12456,10 @@ class ScriptRunner {
11674
12456
  const runtimeModule = await import("@botpress/runtime/runtime");
11675
12457
  const { Autonomous } = await import("@botpress/runtime");
11676
12458
  const { context, agentRegistry } = runtimeModule;
11677
- const { Client: Client17 } = await import("@botpress/client");
12459
+ const { Client: Client18 } = await import("@botpress/client");
11678
12460
  const { BotSpecificClient, BotLogger } = await import("@botpress/sdk");
11679
12461
  const { Cognitive } = await import("@botpress/cognitive");
11680
- const vanillaClient = new Client17({
12462
+ const vanillaClient = new Client18({
11681
12463
  token: this.credentials.token,
11682
12464
  apiUrl: this.credentials.apiUrl,
11683
12465
  botId
@@ -11709,8 +12491,8 @@ class ScriptRunner {
11709
12491
  }
11710
12492
  async run(scriptPath, options = {}) {
11711
12493
  const { botPath, runnerPath, project } = await this.prepare();
11712
- const absoluteScriptPath = path37.isAbsolute(scriptPath) ? scriptPath : path37.resolve(this.projectPath, scriptPath);
11713
- if (!existsSync9(absoluteScriptPath)) {
12494
+ const absoluteScriptPath = path41.isAbsolute(scriptPath) ? scriptPath : path41.resolve(this.projectPath, scriptPath);
12495
+ if (!existsSync10(absoluteScriptPath)) {
11714
12496
  throw new Error(`Script not found: ${absoluteScriptPath}`);
11715
12497
  }
11716
12498
  const botId = this.prod ? project.agentInfo?.botId : project.agentInfo?.devId || project.agentInfo?.botId;
@@ -11824,6 +12606,7 @@ export {
11824
12606
  ProjectState,
11825
12607
  PreflightFormatter,
11826
12608
  PreflightChecker,
12609
+ PluginParser,
11827
12610
  KnowledgeManager,
11828
12611
  KBSyncOperation,
11829
12612
  KBSyncFormatter,
@@ -11859,4 +12642,4 @@ export {
11859
12642
  AgentProject
11860
12643
  };
11861
12644
 
11862
- //# debugId=00C8C8308374DF0664756E2164756E21
12645
+ //# debugId=A068F5974643B24F64756E2164756E21