UNPKG

@botpress/adk-cli

Version:

Command-line interface for the Botpress Agent Development Kit (ADK)

6,284 lines 222 kB
// @bun
import {
  require_ts_morph
} from "./chunk-np5wcwfv.js";
import {
  BuiltInActions,
  BuiltInWorkflows,
  Errors,
  Primitives,
  setAdkCommand
} from "./chunk-dq2xpa24.js";
import {
  ne
} from "./chunk-6w0knnta.js";
import {
  Autonomous,
  extractMissingRequiredFields
} from "./chunk-40x04ckt.js";
import {
  require_semver
} from "./chunk-2a5b6azq.js";
import {
  Uk
} from "./chunk-3xrpxgq4.js";
import {
  require_src
} from "./chunk-g8mm42v1.js";
import {
  __require,
  __toESM
} from "./chunk-dhs2bg35.js";

// ../adk/dist/dependencies/index.js
import fs from "fs/promises";
import path from "path";
import fs2 from "fs/promises";
import path2 from "path";
import os from "os";
import fs3 from "fs/promises";
import path3 from "path";
import os2 from "os";
var semver = __toESM(require_semver(), 1);
import fs4 from "fs/promises";
import path4 from "path";
import os3 from "os";
import fs5 from "fs/promises";
import path5 from "path";
import fs6 from "fs/promises";
import path6 from "path";
import crypto from "crypto";
var import_ts_morph = __toESM(require_ts_morph(), 1);
import { readFileSync } from "fs";
import * as path8 from "path";
import * as fs8 from "fs/promises";
import * as path9 from "path";
var import_debug = __toESM(require_src(), 1);
import { createRequire as createRequire2 } from "module";
import fs9 from "fs/promises";
import path10 from "path";
var semver2 = __toESM(require_semver(), 1);
var import_ts_morph2 = __toESM(require_ts_morph(), 1);
var import_ts_morph3 = __toESM(require_ts_morph(), 1);
import { existsSync } from "fs";
import * as path11 from "path";
import * as fs11 from "fs/promises";
import * as path15 from "path";
import * as fs10 from "fs/promises";
import * as path12 from "path";
import { readFileSync as readFileSync2 } from "fs";
import * as path14 from "path";
var __defProp = Object.defineProperty;
var __returnValue = (v) => v;
function __exportSetter(name, newValue) {
  this[name] = __returnValue.bind(null, newValue);
}
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, {
      get: all[name],
      enumerable: true,
      configurable: true,
      set: __exportSetter.bind(all, name)
    });
};
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
function sortKeysDeep(value) {
  if (Array.isArray(value))
    return value.map(sortKeysDeep);
  if (value && typeof value === "object") {
    const obj = value;
    const sorted = {};
    for (const key of Object.keys(obj).sort()) {
      sorted[key] = sortKeysDeep(obj[key]);
    }
    return sorted;
  }
  return value;
}
function jsonEqual(a, b) {
  return JSON.stringify(sortKeysDeep(a)) === JSON.stringify(sortKeysDeep(b));
}
var integrationDependencyEntrySchema;
var pluginDependencyMappingSchema;
var pluginDependencyEntrySchema;
var integrationSnapshotEntrySchema;
var pluginSnapshotEntrySchema;
var dependencyStateSchema;
var dependencySnapshotSchema;
var dependencyMigrationMarkerSchema;
var init_types = __esm(() => {
  integrationDependencyEntrySchema = ne.object({
    name: ne.string(),
    version: ne.string(),
    enabled: ne.boolean(),
    config: ne.record(ne.any()).default({}),
    configurationType: ne.string().optional(),
    missingFields: ne.array(ne.string()).optional(),
    authorizationPending: ne.boolean().optional()
  });
  pluginDependencyMappingSchema = ne.object({
    integrationAlias: ne.string()
  });
  pluginDependencyEntrySchema = ne.object({
    name: ne.string(),
    version: ne.string(),
    enabled: ne.boolean().default(true),
    config: ne.record(ne.any()).default({}),
    dependencies: ne.record(pluginDependencyMappingSchema).default({}),
    missingFields: ne.array(ne.string()).optional()
  });
  integrationSnapshotEntrySchema = integrationDependencyEntrySchema.extend({
    cloudAlias: ne.string().optional(),
    cloudId: ne.string().optional(),
    updatedAt: ne.string().optional()
  });
  pluginSnapshotEntrySchema = pluginDependencyEntrySchema.extend({
    cloudAlias: ne.string().optional(),
    cloudId: ne.string().optional(),
    updatedAt: ne.string().optional()
  });
  dependencyStateSchema = ne.object({
    $schema: ne.string().optional(),
    version: ne.literal(1),
    env: ne.enum(["dev", "prod"]),
    integrations: ne.record(integrationDependencyEntrySchema).default({}),
    plugins: ne.record(pluginDependencyEntrySchema).default({})
  });
  dependencySnapshotSchema = ne.object({
    $schema: ne.string().optional(),
    version: ne.literal(1),
    env: ne.enum(["dev", "prod"]),
    botId: ne.string(),
    fetchedAt: ne.string(),
    botUpdatedAt: ne.string().optional(),
    stale: ne.boolean().optional(),
    integrations: ne.record(integrationSnapshotEntrySchema).default({}),
    plugins: ne.record(pluginSnapshotEntrySchema).default({})
  });
  dependencyMigrationMarkerSchema = ne.object({
    version: ne.literal(1),
    migratedAt: ne.string(),
    sources: ne.array(ne.enum(["lock", "agentConfig", "cloud"]))
  });
});
var AdkError;
var init_errors = __esm(() => {
  AdkError = class AdkError2 extends Error {
    static __IS_ADK_BASE_ERROR = true;
    code;
    expected;
    details;
    suggestion;
    constructor(opts) {
      super(opts.message, opts.cause !== undefined ? { cause: opts.cause } : undefined);
      this.name = this.constructor.name;
      this.code = opts.code;
      this.expected = opts.expected ?? false;
      if (opts.details !== undefined) {
        this.details = opts.details;
      }
      if (opts.suggestion !== undefined) {
        this.suggestion = opts.suggestion;
      }
    }
  };
});
var init_src = __esm(() => {
  init_errors();
});
var DEPENDENCY_ERROR_CODES;
var DependencyError;
var DEPENDENCY_WARNING_CODES;
var init_errors2 = __esm(() => {
  init_src();
  DEPENDENCY_ERROR_CODES = [
    "AUTH_REQUIRED",
    "INTEGRATION_NOT_FOUND",
    "PLUGIN_NOT_FOUND",
    "INTERFACE_NOT_FOUND",
    "VERSION_NOT_FOUND",
    "MISSING_INPUT",
    "MISSING_DEPENDENCY",
    "AMBIGUOUS_DEPENDENCY",
    "INTERFACE_NOT_IMPLEMENTED",
    "SNAPSHOT_DRIFT",
    "UNINSTALL_REQUIRES_CONFIRMATION",
    "SAME_SOURCE_TARGET",
    "SOURCE_SNAPSHOT_MISSING",
    "MIGRATION_CONFLICT",
    "INVALID_CONFIG",
    "BOT_NOT_FOUND",
    "BUILTIN_INTERFACE_IMMUTABLE",
    "PROD_CONFIRMATION_REQUIRED",
    "UNCONFIGURED_DEPENDENCIES"
  ];
  DependencyError = class DependencyError2 extends AdkError {
    constructor(opts) {
      super({ ...opts, expected: true });
    }
  };
  DEPENDENCY_WARNING_CODES = ["MIGRATED_DEPENDENCIES", "CLOUD_FETCH_PARTIAL", "NO_PROD_BOT"];
});
function schemaRequiredFields(config) {
  const required = config?.schema?.required;
  if (!Array.isArray(required))
    return [];
  return required.filter((field) => typeof field === "string");
}
function configurationRequiresInput(config) {
  if (!config)
    return false;
  if (configGatesOnAuthorization(config))
    return true;
  return schemaRequiredFields(config).length > 0;
}
function configGatesOnAuthorization(config) {
  return !!(config?.identifier?.required || config?.identifier?.linkTemplateScript);
}
function missingRequiredFields(config, values) {
  return schemaRequiredFields(config).filter((field) => values[field] === undefined);
}
function unconfigured(missingFields) {
  if (missingFields.length > 0)
    return { state: "unconfigured", missingFields };
  return {
    state: "unconfigured",
    missingFields: [],
    reason: "requires authorization or credentials (configure it in the Control Panel)"
  };
}
function authorizationPendingVerdict() {
  return {
    state: "unconfigured",
    missingFields: [],
    reason: "requires authorization \u2014 connect it in the Control Panel, then re-deploy"
  };
}
function snapshotOnlyVerdict(enabled, persistedMissingFields) {
  if (persistedMissingFields.length > 0)
    return unconfigured(persistedMissingFields);
  if (!enabled)
    return { state: "disabled" };
  return { state: "available" };
}
function integrationRequiresConfiguration(definition) {
  const config = definition.configuration;
  if (!config)
    return true;
  return configurationRequiresInput(config);
}
function pluginRequiresConfiguration(definition) {
  return schemaRequiredFields(definition.configuration).length > 0;
}
function integrationRequiresAuthorization(definition, configurationType) {
  const { config } = resolveActiveConfiguration(definition, configurationType);
  return configGatesOnAuthorization(config);
}
function resolveActiveConfiguration(spec, configurationType) {
  if (configurationType && configurationType !== "default") {
    const variant = spec.configurations?.[configurationType];
    if (variant)
      return { config: variant, isDefault: false, variantMissing: false };
    return { config: undefined, isDefault: false, variantMissing: true };
  }
  return { config: spec.configuration, isDefault: true, variantMissing: false };
}
function computeIntegrationStatus(input) {
  if (!input.installed)
    return { state: "not_installed" };
  if (!input.spec)
    return { state: "unresolved", reason: "integration definition could not be resolved" };
  const {
    config: activeConfig,
    isDefault,
    variantMissing
  } = resolveActiveConfiguration(input.spec, input.configurationType);
  if (variantMissing) {
    return { state: "unresolved", reason: `configuration variant '${input.configurationType}' not found in spec` };
  }
  const requiresConfig = isDefault ? integrationRequiresConfiguration(input.spec) : configurationRequiresInput(activeConfig);
  const values = input.config ?? {};
  const schemaMissing = requiresConfig ? missingRequiredFields(activeConfig, values) : [];
  let configIncomplete = false;
  if (input.persistedMissingFields !== undefined) {
    configIncomplete = input.persistedMissingFields.length > 0;
  } else if (requiresConfig) {
    if (schemaMissing.length > 0) {
      configIncomplete = true;
    } else if (input.cloudEnabled === false && configGatesOnAuthorization(activeConfig)) {
      configIncomplete = true;
    }
  }
  if (configIncomplete) {
    const missingFields = input.persistedMissingFields && input.persistedMissingFields.length > 0 ? input.persistedMissingFields : schemaMissing;
    return unconfigured(missingFields);
  }
  if (input.authorizationPending)
    return authorizationPendingVerdict();
  if (!input.enabled || input.cloudEnabled === false)
    return { state: "disabled" };
  return { state: "available" };
}
function transitiveDependencyVerdict(dependencyStatuses) {
  const broken = (dependencyStatuses ?? []).find((dep) => dep.verdict.state !== "available");
  if (!broken)
    return null;
  const state = broken.verdict.state === "disabled" ? "disabled" : "unresolved";
  return { state, reason: `dependency '${broken.alias}' is ${broken.verdict.state}` };
}
function mapPluginDependencyStatuses(dependencies, verdictFor) {
  return Object.values(dependencies ?? {}).map((dep) => dep.integrationAlias).filter((alias) => !!alias).map((alias) => ({
    alias,
    verdict: verdictFor(alias) ?? {
      state: "unresolved",
      reason: `backing integration '${alias}' is not declared in the project`
    }
  }));
}
function computePluginStatus(input) {
  if (!input.installed)
    return { state: "not_installed" };
  if (!input.spec)
    return { state: "unresolved", reason: "plugin definition could not be resolved" };
  const transitive = transitiveDependencyVerdict(input.dependencyStatuses);
  if (transitive)
    return transitive;
  const requiresConfig = pluginRequiresConfiguration(input.spec);
  const values = input.config ?? {};
  const schemaMissing = requiresConfig ? missingRequiredFields(input.spec.configuration, values) : [];
  let configIncomplete = false;
  if (input.persistedMissingFields !== undefined) {
    configIncomplete = input.persistedMissingFields.length > 0;
  } else if (requiresConfig) {
    configIncomplete = schemaMissing.length > 0;
  }
  if (configIncomplete) {
    const missingFields = input.persistedMissingFields && input.persistedMissingFields.length > 0 ? input.persistedMissingFields : schemaMissing;
    return unconfigured(missingFields);
  }
  if (!input.enabled)
    return { state: "disabled" };
  return { state: "available" };
}
function computeSnapshotOnlyStatus(input) {
  if (!input.installed)
    return { state: "not_installed" };
  const verdict = snapshotOnlyVerdict(input.enabled, input.missingFields ?? []);
  if (verdict.state === "available" || verdict.state === "disabled") {
    if (input.authorizationPending)
      return authorizationPendingVerdict();
  }
  return verdict;
}
function isCallable(state) {
  return state === "available";
}
var pluginDependencyMappingSchema2;
var dependenciesSchema;
var agentInfoSchema;
var agentLocalInfoSchema;
var ValidationErrorCode;
var ValidationSeverity;
var ProjectState;
var init_types2 = __esm(() => {
  pluginDependencyMappingSchema2 = ne.object({
    integrationAlias: ne.string(),
    integrationInterfaceAlias: ne.string().optional()
  });
  dependenciesSchema = ne.object({
    integrations: ne.record(ne.union([
      ne.string(),
      ne.object({
        version: ne.string(),
        enabled: ne.boolean(),
        configurationType: ne.string().optional(),
        config: ne.record(ne.any()).optional()
      })
    ])).optional(),
    plugins: ne.record(ne.object({
      version: ne.string(),
      config: ne.record(ne.any()).optional(),
      dependencies: ne.record(pluginDependencyMappingSchema2).optional(),
      missingFields: ne.array(ne.string()).optional()
    })).optional()
  });
  agentInfoSchema = ne.object({
    botId: ne.string().describe("The bot ID from Botpress deployment"),
    workspaceId: ne.string().describe("The workspace ID where the bot is deployed"),
    apiUrl: ne.string().optional().describe("The Botpress API URL (e.g., https://api.botpress.cloud)")
  });
  agentLocalInfoSchema = ne.object({
    botId: ne.string().optional().describe("The bot ID (overrides agent.json for local development)"),
    workspaceId: ne.string().optional().describe("The workspace ID (overrides agent.json for local development)"),
    apiUrl: ne.string().optional().describe("The Botpress API URL (overrides agent.json for local development)"),
    devId: ne.string().optional().describe("The development bot ID used during local development")
  });
  ((ValidationErrorCode2) => {
    ValidationErrorCode2["DIRECTORY_NOT_FOUND"] = "DIRECTORY_NOT_FOUND";
    ValidationErrorCode2["DIRECTORY_ACCESS_ERROR"] = "DIRECTORY_ACCESS_ERROR";
    ValidationErrorCode2["REQUIRED_FILE_MISSING"] = "REQUIRED_FILE_MISSING";
    ValidationErrorCode2["INVALID_STRUCTURE"] = "INVALID_STRUCTURE";
    ValidationErrorCode2["INVALID_CONFIG_SYNTAX"] = "INVALID_CONFIG_SYNTAX";
    ValidationErrorCode2["INVALID_CONFIG_SCHEMA"] = "INVALID_CONFIG_SCHEMA";
    ValidationErrorCode2["MISSING_REQUIRED_FIELD"] = "MISSING_REQUIRED_FIELD";
    ValidationErrorCode2["AGENT_NOT_LINKED"] = "AGENT_NOT_LINKED";
    ValidationErrorCode2["INVALID_DEPENDENCIES_SYNTAX"] = "INVALID_DEPENDENCIES_SYNTAX";
    ValidationErrorCode2["INVALID_DEPENDENCIES_SCHEMA"] = "INVALID_DEPENDENCIES_SCHEMA";
    ValidationErrorCode2["INVALID_VERSION_FORMAT"] = "INVALID_VERSION_FORMAT";
    ValidationErrorCode2["INVALID_INTEGRATION_ALIAS"] = "INVALID_INTEGRATION_ALIAS";
    ValidationErrorCode2["INVALID_PLUGIN_ALIAS"] = "INVALID_PLUGIN_ALIAS";
    ValidationErrorCode2["UNKNOWN_INTEGRATION"] = "UNKNOWN_INTEGRATION";
    ValidationErrorCode2["UNKNOWN_PLUGIN"] = "UNKNOWN_PLUGIN";
    ValidationErrorCode2["INVALID_PLUGIN_DEPENDENCY"] = "INVALID_PLUGIN_DEPENDENCY";
    ValidationErrorCode2["INCOMPATIBLE_VERSION"] = "INCOMPATIBLE_VERSION";
    ValidationErrorCode2["CIRCULAR_DEPENDENCY"] = "CIRCULAR_DEPENDENCY";
    ValidationErrorCode2["FILE_TOO_LARGE"] = "FILE_TOO_LARGE";
    ValidationErrorCode2["INVALID_FILE_TYPE"] = "INVALID_FILE_TYPE";
    ValidationErrorCode2["INVALID_FILE_NAME"] = "INVALID_FILE_NAME";
    ValidationErrorCode2["DUPLICATE_FILE_NAME"] = "DUPLICATE_FILE_NAME";
    ValidationErrorCode2["DUPLICATE_PRIMITIVE"] = "DUPLICATE_PRIMITIVE";
    ValidationErrorCode2["INVALID_PRIMITIVE_DEFINITION"] = "INVALID_PRIMITIVE_DEFINITION";
    ValidationErrorCode2["TABLE_TOO_MANY_COLUMNS"] = "TABLE_TOO_MANY_COLUMNS";
    ValidationErrorCode2["BUILD_FAILED"] = "BUILD_FAILED";
    ValidationErrorCode2["SYNTAX_ERROR"] = "SYNTAX_ERROR";
    ValidationErrorCode2["TYPE_ERROR"] = "TYPE_ERROR";
    ValidationErrorCode2["IMPORT_ERROR"] = "IMPORT_ERROR";
  })(ValidationErrorCode ||= {});
  ((ValidationSeverity2) => {
    ValidationSeverity2["ERROR"] = "error";
    ValidationSeverity2["WARNING"] = "warning";
    ValidationSeverity2["INFO"] = "info";
  })(ValidationSeverity ||= {});
  ((ProjectState2) => {
    ProjectState2["Unloaded"] = "unloaded";
    ProjectState2["Loading"] = "loading";
    ProjectState2["Ready"] = "ready";
    ProjectState2["Building"] = "building";
    ProjectState2["Error"] = "error";
  })(ProjectState ||= {});
});

class ValidationErrors {
  static $type = "ValidationError";
  static isValidationError(error) {
    return error !== null && typeof error === "object" && "$type" in error && error.$type === "ValidationError";
  }
  static directoryNotFound(path7) {
    return {
      $type: ValidationErrors.$type,
      code: "DIRECTORY_NOT_FOUND",
      severity: "error",
      message: `Project directory not found: ${path7}`,
      hint: "Ensure the directory exists and you have permission to access it",
      context: { path: path7 }
    };
  }
  static directoryAccessError(path7, error) {
    return {
      $type: ValidationErrors.$type,
      code: "DIRECTORY_ACCESS_ERROR",
      severity: "error",
      message: `Cannot access project directory: ${error}`,
      hint: "Check file system permissions",
      context: { path: path7, error }
    };
  }
  static requiredFileMissing(file) {
    return {
      $type: ValidationErrors.$type,
      code: "REQUIRED_FILE_MISSING",
      severity: "error",
      message: `Required file '${file}' not found`,
      file,
      hint: `Create a ${file} file in your project root`,
      documentation: "https://docs.botpress.com/adk/project-structure"
    };
  }
  static invalidStructure(directory, expected) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_STRUCTURE",
      severity: "warning",
      message: `Expected '${directory}' to be a ${expected}`,
      file: directory,
      hint: `Ensure ${directory} is a ${expected}, not a ${expected === "directory" ? "file" : "directory"}`
    };
  }
  static invalidConfigSyntax(file, error, line, column) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_CONFIG_SYNTAX",
      severity: "error",
      message: `Invalid syntax in ${file}: ${error}`,
      file,
      line,
      column,
      hint: "Check for syntax errors like missing commas, brackets, or quotes"
    };
  }
  static invalidConfigSchema(file, field, error) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_CONFIG_SCHEMA",
      severity: "error",
      message: `Invalid configuration in ${file}: ${error}`,
      file,
      hint: `Check the '${field}' field matches the expected schema`,
      context: { field, error }
    };
  }
  static missingRequiredField(file, field) {
    return {
      $type: ValidationErrors.$type,
      code: "MISSING_REQUIRED_FIELD",
      severity: "error",
      message: `Missing required field '${field}' in ${file}`,
      file,
      hint: `Add the '${field}' field to your configuration`,
      documentation: "https://docs.botpress.com/adk/configuration"
    };
  }
  static tableTooManyColumns(tableName, filePath, columnCount, max) {
    return {
      $type: ValidationErrors.$type,
      code: "TABLE_TOO_MANY_COLUMNS",
      severity: "error",
      message: `Table '${tableName}' has ${columnCount} columns (max ${max})`,
      file: filePath,
      hint: `Reduce columns or split into multiple tables. The limit is ${max} columns per table.`,
      context: { tableName, columnCount, max }
    };
  }
  static invalidDependenciesSyntax(error, line) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_DEPENDENCIES_SYNTAX",
      severity: "error",
      message: `Invalid syntax in agent.config.ts dependencies: ${error}`,
      file: "agent.config.ts",
      line,
      hint: "Ensure agent.config.ts exports a valid dependencies object"
    };
  }
  static invalidVersionFormat(integration, version) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_VERSION_FORMAT",
      severity: "error",
      message: `Invalid version format '${version}' for integration '${integration}'`,
      file: "agent.config.ts",
      hint: 'Use exact versioning (e.g., "1.2.3", "2.0.0", "1.5.0")',
      context: { integration, version }
    };
  }
  static invalidIntegrationAlias(alias) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_INTEGRATION_ALIAS",
      severity: "error",
      message: `Invalid integration alias '${alias}'`,
      file: "agent.config.ts",
      hint: 'Integration aliases must be 2-100 characters and contain only lowercase letters, numbers, underscores, and hyphens (e.g., "slack", "my-slack", "slack_prod")',
      context: { alias }
    };
  }
  static unknownIntegration(integration, source, detailedMessage) {
    return {
      $type: ValidationErrors.$type,
      code: "UNKNOWN_INTEGRATION",
      severity: "error",
      message: detailedMessage || `Unknown integration '${integration}' from source '${source}'`,
      file: "agent.config.ts",
      hint: detailedMessage ? undefined : `Check if the integration name is correct or if it exists in ${source}`,
      context: { integration, source }
    };
  }
  static integrationVersionError(integration, errorMessage) {
    return {
      $type: ValidationErrors.$type,
      code: "UNKNOWN_INTEGRATION",
      severity: "error",
      message: errorMessage,
      file: "agent.config.ts",
      hint: `Update the version for "${integration}" in agent.config.ts dependencies`
    };
  }
  static unknownInterface(errorMessage) {
    return {
      $type: ValidationErrors.$type,
      code: "UNKNOWN_INTEGRATION",
      severity: "error",
      message: errorMessage,
      file: "agent.config.ts"
    };
  }
  static incompatibleVersion(integration, required, available) {
    return {
      $type: ValidationErrors.$type,
      code: "INCOMPATIBLE_VERSION",
      severity: "error",
      message: `Integration '${integration}' requires version ${required}, but only ${available} is available`,
      file: "agent.config.ts",
      hint: "Update the version requirement or check for compatible versions",
      context: { integration, required, available }
    };
  }
  static invalidPluginAlias(alias) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_PLUGIN_ALIAS",
      severity: "error",
      message: `Invalid plugin alias '${alias}'`,
      file: "agent.config.ts",
      hint: 'Plugin aliases must be 2-100 characters and contain only lowercase letters, numbers, underscores, and hyphens (e.g., "hitl", "my-plugin")',
      context: { alias }
    };
  }
  static invalidPluginVersionFormat(plugin, version) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_VERSION_FORMAT",
      severity: "error",
      message: `Invalid version format '${version}' for plugin '${plugin}'`,
      file: "agent.config.ts",
      hint: 'Use exact versioning (e.g., "1.2.3", "2.0.0", "1.5.0")',
      context: { plugin, version }
    };
  }
  static unknownPlugin(plugin, source, detailedMessage) {
    return {
      $type: ValidationErrors.$type,
      code: "UNKNOWN_PLUGIN",
      severity: "error",
      message: detailedMessage || `Unknown plugin '${plugin}' from source '${source}'`,
      file: "agent.config.ts",
      hint: detailedMessage ? undefined : `Check if the plugin name is correct or if it exists on the Botpress Hub`,
      context: { plugin, source }
    };
  }
  static invalidPluginDependency(plugin, integrationAlias, availableIntegrations) {
    const available = availableIntegrations.length > 0 ? availableIntegrations.join(", ") : "(none)";
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_PLUGIN_DEPENDENCY",
      severity: "error",
      message: `Plugin "${plugin}" references integration "${integrationAlias}" in its dependencies, but "${integrationAlias}" is not declared in dependencies.integrations`,
      file: "agent.config.ts",
      hint: `Add "${integrationAlias}" to dependencies.integrations, or update the plugin dependency to reference one of: ${available}`,
      context: { plugin, integrationAlias, availableIntegrations }
    };
  }
  static pluginVersionError(plugin, errorMessage) {
    return {
      $type: ValidationErrors.$type,
      code: "UNKNOWN_PLUGIN",
      severity: "error",
      message: errorMessage,
      file: "agent.config.ts",
      hint: `Update the version for "${plugin}" in agent.config.ts dependencies`
    };
  }
  static fileTooLarge(file, size, maxSize) {
    return {
      $type: ValidationErrors.$type,
      code: "FILE_TOO_LARGE",
      severity: "error",
      message: `File '${file}' is too large (${formatBytes(size)} > ${formatBytes(maxSize)})`,
      file,
      hint: "Reduce file size or split into smaller files",
      context: { size, maxSize }
    };
  }
  static invalidFileType(file, type, allowedTypes) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_FILE_TYPE",
      severity: "error",
      message: `Invalid file type '${type}' for file '${file}'`,
      file,
      hint: `Allowed file types: ${allowedTypes.join(", ")}`,
      context: { type, allowedTypes }
    };
  }
  static invalidFileName(file, reason) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_FILE_NAME",
      severity: "error",
      message: `Invalid file name '${file}': ${reason}`,
      file,
      hint: "Use lowercase letters, numbers, and hyphens only"
    };
  }
  static duplicateFileName(file, existingFile) {
    return {
      $type: ValidationErrors.$type,
      code: "DUPLICATE_FILE_NAME",
      severity: "error",
      message: `Duplicate file name '${file}' conflicts with '${existingFile}'`,
      file,
      hint: "Rename one of the files to avoid conflicts",
      context: { existingFile }
    };
  }
  static buildFailed(error, file) {
    return {
      $type: ValidationErrors.$type,
      code: "BUILD_FAILED",
      severity: "error",
      message: `Build failed: ${error}`,
      file,
      hint: "Check the error message and fix any issues in your code"
    };
  }
  static syntaxError(file, error, line, column) {
    return {
      $type: ValidationErrors.$type,
      code: "SYNTAX_ERROR",
      severity: "error",
      message: `Syntax error: ${error}`,
      file,
      line,
      column,
      hint: "Check for missing semicolons, brackets, or other syntax issues"
    };
  }
  static typeError(file, error, line) {
    return {
      $type: ValidationErrors.$type,
      code: "TYPE_ERROR",
      severity: "error",
      message: `Type error: ${error}`,
      file,
      line,
      hint: "Ensure types match expected values and imports are correct"
    };
  }
  static importError(file, module, error) {
    return {
      $type: ValidationErrors.$type,
      code: "IMPORT_ERROR",
      severity: "error",
      message: `Cannot import '${module}': ${error}`,
      file,
      hint: "Check if the module exists and is properly installed",
      context: { module }
    };
  }
  static unsafeKnowledgePath(knowledgeBase, pattern) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_FILE_NAME",
      severity: "error",
      message: `Knowledge base '${knowledgeBase}' contains unsafe path pattern '${pattern}'`,
      file: `src/knowledge/${knowledgeBase}.ts`,
      hint: "Knowledge patterns must not reference files outside the agent directory (remove ../ or absolute paths)",
      context: { knowledgeBase, pattern }
    };
  }
  static agentNotLinked() {
    return {
      $type: ValidationErrors.$type,
      code: "AGENT_NOT_LINKED",
      severity: "error",
      message: "Agent is not linked to a workspace",
      file: "agent.json",
      hint: 'Please run "adk link" to link your agent to a workspace'
    };
  }
  static workspaceIdMissing() {
    return {
      $type: ValidationErrors.$type,
      code: "AGENT_NOT_LINKED",
      severity: "error",
      message: "No workspaceId found in agent.json",
      file: "agent.json",
      hint: 'Please run "adk link" to link your agent to a workspace'
    };
  }
  static botIdMissing() {
    return {
      $type: ValidationErrors.$type,
      code: "AGENT_NOT_LINKED",
      severity: "error",
      message: "No botId found in agent.json",
      file: "agent.json",
      hint: 'Please run "adk link" to link your agent to a bot'
    };
  }
  static info(message, file) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_STRUCTURE",
      severity: "info",
      message,
      file
    };
  }
  static warning(message, file, hint) {
    return {
      $type: ValidationErrors.$type,
      code: "INVALID_STRUCTURE",
      severity: "warning",
      message,
      file,
      hint
    };
  }
}
function formatBytes(bytes) {
  if (bytes === 0)
    return "0 Bytes";
  const k = 1024;
  const sizes = ["Bytes", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
}
var init_validation_errors = __esm(() => {
  init_types2();
});
function isIntegrationAliasValid(alias) {
  return alias.length >= INTEGRATION_ALIAS_MIN_LENGTH && alias.length <= INTEGRATION_ALIAS_MAX_LENGTH && INTEGRATION_ALIAS_REGEX.test(alias);
}

class IntegrationParser {
  static parseIntegrationRef(versionString) {
    const result = integrationRefSchema.safeParse(versionString);
    if (!result.success) {
      throw new AdkError({
        code: "INVALID_VERSION_FORMAT",
        expected: true,
        message: result.error.errors[0]?.message || "Invalid integration version format"
      });
    }
    return result.data;
  }
  static parseIntegrations(dependencies) {
    const integrations = [];
    const errors = [];
    if (!dependencies.integrations) {
      return { integrations, errors };
    }
    for (const [alias, value] of Object.entries(dependencies.integrations)) {
      try {
        if (!isIntegrationAliasValid(alias)) {
          errors.push(ValidationErrors.invalidIntegrationAlias(alias));
          continue;
        }
        const normalized = typeof value === "string" ? { version: value } : value;
        const ref = this.parseIntegrationRef(normalized.version);
        const versionResult = versionSchema.safeParse(ref.version);
        if (!versionResult.success) {
          errors.push(ValidationErrors.invalidVersionFormat(alias, ref.version));
        }
        integrations.push({
          alias,
          ref,
          enabled: "enabled" in normalized ? normalized.enabled : undefined,
          configurationType: "configurationType" in normalized ? normalized.configurationType : undefined,
          config: "config" in normalized ? normalized.config : undefined
        });
      } catch (error) {
        errors.push(ValidationErrors.invalidDependenciesSyntax(`Invalid integration '${alias}': ${error instanceof Error ? error.message : String(error)}`));
      }
    }
    return { integrations, errors };
  }
  static checkDuplicates(integrations) {
    const errors = [];
    const seen = new Map;
    for (const integration of integrations) {
      const key = integration.ref.fullName;
      const group = seen.get(key) || [];
      group.push(integration);
      seen.set(key, group);
    }
    for (const [integrationName, group] of seen.entries()) {
      if (group.length > 1) {
        const duplicateConfigs = [];
        for (let i = 0;i < group.length; i++) {
          for (let j = i + 1;j < group.length; j++) {
            const configA = JSON.stringify(group[i].config ?? {});
            const configB = JSON.stringify(group[j].config ?? {});
            if (configA === configB) {
              if (!duplicateConfigs.includes(group[i].alias)) {
                duplicateConfigs.push(group[i].alias);
              }
              if (!duplicateConfigs.includes(group[j].alias)) {
                duplicateConfigs.push(group[j].alias);
              }
            }
          }
        }
        if (duplicateConfigs.length > 0) {
          errors.push(ValidationErrors.warning(`Integration '${integrationName}' has aliases with identical configurations: ${duplicateConfigs.join(", ")}. Consider using different configs or removing duplicates.`, "agent.config.ts"));
        }
      }
    }
    return errors;
  }
}
function isPluginAliasValid(alias) {
  return alias.length >= PLUGIN_ALIAS_MIN_LENGTH && alias.length <= PLUGIN_ALIAS_MAX_LENGTH && PLUGIN_ALIAS_REGEX.test(alias);
}

class PluginParser {
  static parsePluginRef(versionString) {
    const result = pluginRefSchema.safeParse(versionString);
    if (!result.success) {
      throw new AdkError({
        code: "INVALID_VERSION_FORMAT",
        expected: true,
        message: result.error.errors[0]?.message || "Invalid plugin version format"
      });
    }
    return result.data;
  }
  static parsePlugins(dependencies) {
    const plugins = [];
    const errors = [];
    if (!dependencies.plugins) {
      return { plugins, errors };
    }
    for (const [alias, value] of Object.entries(dependencies.plugins)) {
      try {
        if (!isPluginAliasValid(alias)) {
          errors.push(ValidationErrors.invalidPluginAlias(alias));
          continue;
        }
        const ref = this.parsePluginRef(value.version);
        const versionResult = versionSchema.safeParse(ref.version);
        if (!versionResult.success) {
          errors.push(ValidationErrors.invalidPluginVersionFormat(alias, ref.version));
        }
        plugins.push({
          alias,
          ref,
          config: value.config,
          dependencies: value.dependencies
        });
      } catch (error) {
        errors.push(ValidationErrors.invalidDependenciesSyntax(`Invalid plugin '${alias}': ${error instanceof Error ? error.message : String(error)}`));
      }
    }
    return { plugins, errors };
  }
  static validateDependencyReferences(dependencies) {
    const errors = [];
    if (!dependencies.plugins) {
      return errors;
    }
    const integrationAliases = Object.keys(dependencies.integrations || {});
    for (const [alias, pluginConfig] of Object.entries(dependencies.plugins)) {
      if (!pluginConfig.dependencies) {
        continue;
      }
      for (const [_depAlias, depMapping] of Object.entries(pluginConfig.dependencies)) {
        if (!integrationAliases.includes(depMapping.integrationAlias)) {
          errors.push(ValidationErrors.invalidPluginDependency(alias, depMapping.integrationAlias, integrationAliases));
        }
      }
    }
    return errors;
  }
  static checkDuplicates(plugins) {
    const errors = [];
    const seen = new Map;
    for (const plugin of plugins) {
      const key = plugin.ref.fullName;
      const group = seen.get(key) || [];
      group.push(plugin);
      seen.set(key, group);
    }
    for (const [pluginName, group] of seen.entries()) {
      if (group.length > 1) {
        const duplicateConfigs = [];
        for (let i = 0;i < group.length; i++) {
          for (let j = i + 1;j < group.length; j++) {
            const configA = JSON.stringify(group[i].config ?? {});
            const configB = JSON.stringify(group[j].config ?? {});
            if (configA === configB) {
              if (!duplicateConfigs.includes(group[i].alias)) {
                duplicateConfigs.push(group[i].alias);
              }
              if (!duplicateConfigs.includes(group[j].alias)) {
                duplicateConfigs.push(group[j].alias);
              }
            }
          }
        }
        if (duplicateConfigs.length > 0) {
          errors.push(ValidationErrors.warning(`Plugin '${pluginName}' has aliases with identical configurations: ${duplicateConfigs.join(", ")}. Consider using different configs or removing duplicates.`, "agent.config.ts"));
        }
      }
    }
    return errors;
  }
}
var INTEGRATION_ALIAS_MIN_LENGTH = 2;
var INTEGRATION_ALIAS_MAX_LENGTH = 100;
var INTEGRATION_ALIAS_REGEX;
var integrationRefSchema;
var versionSchema;
var PLUGIN_ALIAS_MIN_LENGTH = 2;
var PLUGIN_ALIAS_MAX_LENGTH = 100;
var PLUGIN_ALIAS_REGEX;
var pluginRefSchema;
var init_dependencies_parser = __esm(() => {
  init_src();
  init_validation_errors();
  INTEGRATION_ALIAS_REGEX = /^(?:[a-z][a-z0-9_-]*\/)?[a-z][a-z0-9_-]*$/;
  integrationRefSchema = ne.string().transform((val, ctx) => {
    const match = val.match(/^(?:([^/]+)\/)?([^@]+)@(.+)$/);
    if (!match) {
      ctx.addIssue({
        code: "custom",
        message: `Invalid integration version format: ${val}. Expected format: 'name@version' or 'workspace/name@version'`
      });
      return;
    }
    const [, workspace, name, version] = match;
    return {
      workspace: workspace || undefined,
      name,
      version,
      fullName: workspace ? `${workspace}/${name}` : name
    };
  });
  versionSchema = ne.string().refine((version) => {
    if (version === "latest")
      return true;
    const semverPattern = /^(\d+)\.(\d+)\.(\d+)(-[\w.]+)?(\+[\w.]+)?$/;
    return semverPattern.test(version);
  }, { message: "Version must be exact semver (e.g., 1.2.3) or 'latest'" });
  PLUGIN_ALIAS_REGEX = /^[a-z][a-z0-9_-]*$/;
  pluginRefSchema = ne.string().transform((val, ctx) => {
    const match = val.match(/^([^/@]+)@(.+)$/);
    if (!match) {
      ctx.addIssue({
        code: "custom",
        message: `Invalid plugin version format: ${val}. Expected format: 'name@version' (no workspace prefix)`
      });
      return;
    }
    const [, name, version] = match;
    return {
      name,
      version,
      fullName: name
    };
  });
});
var DEFAULT_API_URL = "https://api.botpress.cloud";
var BUILTIN_INTERFACES;
var MAX_TABLE_COLUMNS = 20;
var init_constants = __esm(() => {
  BUILTIN_INTERFACES = {
    "typing-indicator": "typing-indicator@0.0.3",
    llm: "llm@9.0.0",
    listable: "listable@0.0.2"
  };
});
async function readLocalInfo(agentPath) {
  const localPath = path.join(agentPath, "agent.local.json");
  try {
    const localContent = await fs.readFile(localPath, "utf-8");
    const localData = JSON.parse(localContent);
    const localResult = agentLocalInfoSchema.safeParse(localData);
    if (!localResult.success) {
      const issue = localResult.error.errors[0];
      throw ValidationErrors.warning(`agent.local.json has an invalid field: ${issue?.path.join(".")} \u2014 ${issue?.message}`, "agent.local.json");
    }
    return localResult.data;
  } catch (error) {
    if (error.code === "ENOENT") {
      return null;
    }
    if (ValidationErrors.isValidationError(error)) {
      throw error;
    }
    throw ValidationErrors.warning(`Failed to read agent.local.json: ${error.message}`, "agent.local.json");
  }
}
function applyLocalOverrides(agentInfo, localInfo) {
  if (localInfo.botId) {
    agentInfo.botId = localInfo.botId;
  }
  if (localInfo.workspaceId) {
    agentInfo.workspaceId = localInfo.workspaceId;
  }
  if (localInfo.apiUrl) {
    agentInfo.apiUrl = localInfo.apiUrl;
  }
  if (localInfo.devId) {
    agentInfo.devId = localInfo.devId;
  }
}
async function resolveAgent(agentPath, options = {}) {
  const { required = false, requireWorkspace = false, requireBot = false } = options;
  const agentJsonPath = path.join(agentPath, "agent.json");
  const localInfo = await readLocalInfo(agentPath);
  let agentInfo = null;
  try {
    const agentJsonContent = await fs.readFile(agentJsonPath, "utf-8");
    let agentData;
    try {
      agentData = JSON.parse(agentJsonContent);
    } catch (parseError) {
      throw ValidationErrors.invalidConfigSyntax("agent.json", parseError.message);
    }
    const validationResult = agentInfoSchema.safeParse(agentData);
    if (!validationResult.success) {
      const zodError = validationResult.error.errors[0];
      throw ValidationErrors.invalidConfigSchema("agent.json", zodError?.path.join(".") || "unknown", zodError?.message || "Invalid schema");
    }
    const parsed = validationResult.data;
    agentInfo = {
      botId: parsed.botId,
      workspaceId: parsed.workspaceId,
      apiUrl: parsed.apiUrl
    };
  } catch (error) {
    if (error.code === "ENOENT") {} else if (ValidationErrors.isValidationError(error)) {
      throw error;
    } else {
      throw ValidationErrors.warning(`Failed to read agent.json: ${error.message}`, "agent.json");
    }
  }
  if (!agentInfo) {
    if (localInfo?.botId && localInfo?.workspaceId) {
      agentInfo = {
        botId: localInfo.botId,
        workspaceId: localInfo.workspaceId,
        apiUrl: localInfo.apiUrl,
        devId: localInfo.devId
      };
    } else if (required || requireWorkspace || requireBot) {
      throw ValidationErrors.requiredFileMissing("agent.json or agent.local.json");
    } else {
      return null;
    }
  } else {
    if (localInfo) {
      applyLocalOverrides(agentInfo, localInfo);
    }
  }
  if (!agentInfo.apiUrl) {
    agentInfo.apiUrl = DEFAULT_API_URL;
  }
  if (requireWorkspace && !agentInfo.workspaceId) {
    throw ValidationErrors.workspaceIdMissing();
  }
  if (requireBot && !agentInfo.botId) {
    throw ValidationErrors.botIdMissing();
  }
  return agentInfo;
}
var init_agent_resolver = __esm(() => {
  init_types2();
  init_validation_errors();
  init_constants();
});
var exports_credentials = {};
__export(exports_credentials, {
  CredentialsManager: () => CredentialsManager
});

class CredentialsManager {
  credentialsPath;
  configDir;
  profileOverride;
  constructor() {
    this.configDir = path2.join(os.homedir(), ".adk");
    this.credentialsPath = path2.join(this.configDir, "credentials");
  }
  setProfileOverride(profile) {
    this.profileOverride = profile;
  }
  async ensureConfigDir() {
    try {
      await fs2.mkdir(this.configDir, { recursive: true });
    } catch {}
  }
  async readCredentials() {
    try {
      const data = await fs2.readFile(this.credentialsPath, "utf-8");
      return JSON.parse(data);
    } catch {
      return {
        profiles: {},
        profileMetadata: {},
        currentProfile: "default"
      };
    }
  }
  async writeCredentials(store) {
    await this.ensureConfigDir();
    await fs2.writeFile(this.credentialsPath, JSON.stringify(store, null, 2));
    await fs2.chmod(this.credentialsPath, 384);
  }
  async saveCredentials(profileName, credentials, userInfo) {
    const store = await this.readCredentials();
    store.profiles[profileName] = credentials;
    if (!store.profileMetadata) {
      store.profileMetadata = {};
    }
    store.profileMetadata[profileName] = {
      lastUsed: new Date().toISOString(),
      ...userInfo
    };
    if (Object.keys(store.profiles).length === 1) {
      store.currentProfile = profileName;
    }
    await this.writeCredentials(store);
  }
  async getCredentials(profileName) {
    const store = await this.readCredentials();
    const profile = profileName || store.currentProfile;
    if (!store.profiles[profile]) {
      return null;
    }
    return store.profiles[profile];
  }
  async listProfiles() {
    const store = await this.readCredentials();
    if (!store.profileMetadata) {
      store.profileMetadata = {};
    }
    return Object.entries(store.profiles).map(([name, credentials]) => {
      const metadata = store.profileMetadata[name] || {};
      return {
        name,
        credentials,
        apiUrl: credentials.apiUrl,
        lastUsed: metadata.lastUsed || new Date().toISOString(),
        email: metadata.email,
        displayName: metadata.displayName,
        accountId: metadata.accountId,
        createdAt: metadata.createdAt
      };
    });
  }
  async getCurrentProfile() {
    const store = await this.readCredentials();
    return store.currentProfile || "default";
  }
  async getCurrentProfileDetails() {
    const store = await this.readCredentials();
    const currentProfileName = store.currentProfile || "default";
    if (!store.profiles[currentProfileName]) {
      return null;
    }
    const credentials = store.profiles[currentProfileName];
    const metadata = store.profileMetadata?.[currentProfileName] || {};
    return {
      name: currentProfileName,
      credentials,
      apiUrl: credentials.apiUrl,
      lastUsed: metadata.lastUsed || new Date().toISOString(),
      email: metadata.email,
      displayName: metadata.displayName,
      accountId: metadata.accountId,
      createdAt: metadata.createdAt
    };
  }
  async setCurrentProfile(profileName) {
    const store = await this.readCredentials();
    if (!store.profiles[profileName]) {
      throw new AdkError({
        code: "PROFILE_NOT_FOUND",
        message: `Profile '${profileName}' not found`,
        expected: true
      });
    }
    if (!store.profileMetadata) {
      store.profileMetadata = {};
    }
    store.profileMetadata[profileName] = {
      ...store.profileMetadata[profileName],
      lastUsed: new Date().toISOString()
    };
    store.currentProfile = profileName;
    await this.writeCredentials(store);
  }
  async deleteProfile(profileName) {
    const store = await this.readCredentials();
    if (!store.profiles[profileName]) {
      throw new AdkError({
        code: "PROFILE_NOT_FOUND",
        message: `Profile '${profileName}' not found`,
        expected: true
      });
    }
    delete store.profiles[profileName];
    delete store.profileMetadata?.[profileName];
    if (store.currentProfile === profileName) {
      const remainingProfiles = Object.keys(store.profiles);
      store.currentProfile = remainingProfiles.length > 0 ? remainingProfiles[0] : "default";
    }
    await this.writeCredentials(store);
  }
  async getActiveCredentials() {
    const profileName = this.profileOverride;
    const credentials = await this.getCredentials(profileName);
    if (!credentials) {
      const displayName = profileName || "default";
      throw new AdkError({
        code: "NOT_AUTHENTICATED",
        message: `No credentials found for profile '${displayName}'. ` + `Please run 'adk login' to authenticate.`,
        expected: true,
        suggestion: "Run 'adk login' to authenticate."
      });
    }
    return credentials;
  }
  findProfileByApiUrl(store, apiUrl) {
    const normalizedUrl = apiUrl.replace(/\/+$/, "");
    for (const [, credentials] of Object.entries(store.profiles)) {
      if (!credentials.apiUrl)
        continue;
      const profileUrl = credentials.apiUrl.replace(/\/+$/, "");
      if (profileUrl === normalizedUrl) {
        return credentials;
      }
    }
    return null;
  }
  async getAgentCredentials(agentPath) {
    const agentInfo = await resolveAgent(agentPath, {
      required: true,
      requireWorkspace: true
    });
    const agentApiUrl = agentInfo.apiUrl;
    let baseCredentials;
    const hasExplicitProfile = !!this.profileOverride;
    if (hasExplicitProfile) {
      baseCredentials = await this.getActiveCredentials();
    } else {
      const store = await this.readCredentials();
      const matchingCredentials = this.findProfileByApiUrl(store, agentApiUrl);
      if (matchingCredentials) {
        baseCredentials = matchingCredentials;
      } else {
        const profileName = store.currentProfile || "default";
        const activeCredentials = store.profiles[profileName];
        if (!activeCredentials) {
          throw new AdkError({
            code: "NOT_AUTHENTICATED",
            message: `No credentials found for profile '${profileName}'. ` + `Please run 'adk login' to authenticate.`,
            expected: true,
            suggestion: "Run 'adk login' to authenticate."
          });
        }
        baseCredentials = activeCredentials;
      }
    }
    return {
      ...baseCredentials,
      apiUrl: agentApiUrl,
      workspaceId: agentInfo.workspaceId,
      botId: agentInfo.botId
    };
  }
}
var init_credentials = __esm(() => {
  init_src();
  init_agent_resolver();
});

class AuthService {
  apiUrl;
  constructor(apiUrl) {
    this.apiUrl = apiUrl || "https://api.botpress.cloud";
  }
  async validateToken(token) {
    if (!token || !token.startsWith("bp_")) {
      throw new AdkError({
        code: "INVALID_TOKEN_FORMAT",
        message: 'Invalid token format. Token should start with "bp_"',
        expected: true
      });
    }
    try {
      const client = new Uk({
        apiUrl: this.apiUrl,
        token,
        headers: {
          "x-multiple-integrations": "true"
        }
      });
      const accountResponse = await client.getAccount({});
      const { account } = accountResponse;
      const workspaces = await client.list.workspaces({}).collect();
      return {
        workspaceId: workspaces[0]?.id,
        workspaceName: workspaces[0]?.name,
        accountId: account.id,
        email: account.email,
        displayName: account.displayName,
        createdAt: account.createdAt
      };
    } catch (error) {
      if (error instanceof Error) {
        if (error.message.includes("401") || error.message.includes("Unauthorized")) {
          throw new AdkError({
            code: "AUTH_FAILED",
            message: "Invalid token. Please check your API token and try again.",
            expected: true,
            cause: error
          });
        }
        if (error.message.includes("Network") || error.message.includes("ENOTFOUND")) {
          throw new AdkError({
            code: "NETWORK_ERROR",
            message: `Unable to connect to ${this.apiUrl}. Please check your internet connection and API URL.`,
            expected: true,
            cause: error
          });
        }
      }
      throw error;
    }
  }
  async testConnection(token) {
    try {
      await this.validateToken(token);
      return true;
    } catch {
      return false;
    }
  }
}
var init_service = __esm(() => {
  init_src();
});

class BpCliImporter {
  bpCachePath;
  constructor() {
    this.bpCachePath = path3.join(os2.homedir(), ".botpress", "global.cache.json");
  }
  async hasBpCliCredentials() {
    try {
      await fs3.access(this.bpCachePath);
      return true;
    } catch {
      return false;
    }
  }
  async getBpCliCredentials() {
    try {
      const data = await fs3.readFile(this.bpCachePath, "utf-8");
      const credentials = JSON.parse(data);
      if (!credentials.token || !credentials.workspaceId || !credentials.apiUrl) {
        return null;
      }
      return credentials;
    } catch {
      return null;
    }
  }
  async importFromBpCli(profileName = "default") {
    const bpCredentials = await this.getBpCliCredentials();
    if (!bpCredentials) {
      return false;
    }
    try {
      await auth.login(bpCredentials.token, {
        profile: profileName,
        apiUrl: bpCredentials.apiUrl
      });
      const credentialsManager = new (await Promise.resolve().then(() => (init_credentials(), exports_credentials))).CredentialsManager;
      const store = await credentialsManager["readCredentials"]();
      if (store.profiles[profileName]) {
        store.profiles[profileName].workspaceId = bpCredentials.workspaceId;
        if (bpCredentials.botId) {
          store.profiles[profileName].botId = bpCredentials.botId;
        }
        await credentialsManager["writeCredentials"](store);
      }
      return true;
    } catch {
      return false;
    }
  }
}
var bpCliImporter;
var init_bp_cli_import = __esm(() => {
  init_auth();
  bpCliImporter = new BpCliImporter;
});

class Auth {
  credentialsManager;
  constructor() {
    this.credentialsManager = new CredentialsManager;
  }
  async login(token, options = {}) {
    const apiUrl = options.apiUrl ?? "https://api.botpress.cloud";
    const authService = new AuthService(apiUrl);
    const authResult = await authService.validateToken(token);
    const autoResolved = options.profile == null;
    const profile = options.profile ?? await this.resolveProfileName(authResult);
    try {
      const client = new Uk({ apiUrl, token });
      await client.setAccountPreference({ key: "adkCliConnected", value: true });
    } catch {}
    await this.credentialsManager.saveCredentials(profile, {
      token,
      apiUrl,
      workspaceId: authResult.workspaceId,
      workspaceName: authResult.workspaceName,
      botId: authResult.botId
    }, {
      email: authResult.email,
      displayName: authResult.displayName,
      accountId: authResult.accountId,
      createdAt: authResult.createdAt
    });
    if (autoResolved) {
      await this.credentialsManager.setCurrentProfile(profile);
    }
    clearProjectClientCache();
  }
  async resolveProfileName(authResult) {
    const profiles = await this.credentialsManager.listProfiles();
    if (profiles.length === 0) {
      return "default";
    }
    if (authResult.accountId) {
      const existing = profiles.find((p) => p.accountId === authResult.accountId);
      if (existing) {
        return existing.name;
      }
    }
    if (authResult.email) {
      const baseName = authResult.email.split("@")[0] || "profile";
      const existingNames2 = new Set(profiles.map((p) => p.name));
      if (!existingNames2.has(baseName)) {
        return baseName;
      }
      let i2 = 2;
      while (existingNames2.has(`${baseName}-${i2}`)) {
        i2++;
      }
      return `${baseName}-${i2}`;
    }
    const existingNames = new Set(profiles.map((p) => p.name));
    let i = profiles.length + 1;
    while (existingNames.has(`profile-${i}`)) {
      i++;
    }
    return `profile-${i}`;
  }
  async logout(profile) {
    if (profile) {
      await this.credentialsManager.deleteProfile(profile);
    } else {
      const currentProfile = await this.credentialsManager.getCurrentProfile();
      await this.credentialsManager.deleteProfile(currentProfile);
    }
    clearProjectClientCache();
  }
  async listProfiles() {
    return this.credentialsManager.listProfiles();
  }
  async getCurrentProfile() {
    return this.credentialsManager.getCurrentProfile();
  }
  async getCurrentProfileDetails() {
    return this.credentialsManager.getCurrentProfileDetails();
  }
  async setCurrentProfile(profileName) {
    await this.credentialsManager.setCurrentProfile(profileName);
    clearProjectClientCache();
  }
  setProfileOverride(profile) {
    this.credentialsManager.setProfileOverride(profile);
    clearProjectClientCache();
  }
  async getActiveCredentials() {
    return this.credentialsManager.getActiveCredentials();
  }
  async getAgentCredentials(agentPath) {
    return this.credentialsManager.getAgentCredentials(agentPath);
  }
  async validateToken(token, apiUrl) {
    const authService = new AuthService(apiUrl);
    return authService.testConnection(token);
  }
}
async function resolveProjectCredentials(options = {}) {
  const { project, credentials: providedCredentials } = options;
  const agentInfo = project?.agentInfo ?? (project?.path ? await resolveAgent(project.path) : undefined);
  const baseCredentials = providedCredentials || (project?.path && agentInfo?.workspaceId ? await auth.getAgentCredentials(project.path) : await auth.getActiveCredentials());
  const workspaceId = options.workspaceId || agentInfo?.workspaceId || baseCredentials.workspaceId;
  const botId = options.botId || agentInfo?.botId || baseCredentials.botId;
  return {
    ...baseCredentials,
    apiUrl: options.apiUrl || agentInfo?.apiUrl || baseCredentials.apiUrl,
    ...workspaceId ? { workspaceId } : {},
    ...botId ? { botId } : {}
  };
}
async function resolveWorkspaceCredentials(options = {}) {
  const credentials = await resolveProjectCredentials(options);
  if (!credentials.workspaceId) {
    throw new AdkError({
      code: "WORKSPACE_ID_MISSING",
      message: 'No workspace ID found. Please login again with "adk login" or link your agent first.',
      expected: true,
      suggestion: 'Login again with "adk login" or link your agent first.'
    });
  }
  return {
    ...credentials,
    workspaceId: credentials.workspaceId
  };
}
async function getProjectClient(options = {}) {
  const credentials = await resolveWorkspaceCredentials(options);
  const botId = options.botId;
  const headers = {
    "x-multiple-integrations": "true",
    ...options.headers ?? {}
  };
  const cacheKey = stableStringify({
    token: credentials.token,
    apiUrl: credentials.apiUrl,
    workspaceId: credentials.workspaceId,
    botId,
    integrationId: options.integrationId,
    integrationAlias: options.integrationAlias,
    headers
  });
  const cached = projectClientCache.get(cacheKey);
  if (cached) {
    projectClientCache.delete(cacheKey);
    projectClientCache.set(cacheKey, cached);
    return cached;
  }
  const client = new Uk({
    token: credentials.token,
    apiUrl: credentials.apiUrl,
    workspaceId: credentials.workspaceId,
    ...botId ? { botId } : {},
    ...options.integrationId ? { integrationId: options.integrationId } : {},
    ...options.integrationAlias ? { integrationAlias: options.integrationAlias } : {},
    headers
  });
  if (projectClientCache.size >= MAX_PROJECT_CLIENT_CACHE_ENTRIES) {
    const oldestKey = projectClientCache.keys().next().value;
    if (oldestKey) {
      projectClientCache.delete(oldestKey);
    }
  }
  projectClientCache.set(cacheKey, client);
  return client;
}
function clearProjectClientCache() {
  projectClientCache.clear();
}
var auth;
var projectClientCache;
var MAX_PROJECT_CLIENT_CACHE_ENTRIES = 32;
var stableStringify = (value) => {
  if (value === undefined) {
    return "undefined";
  }
  if (!value || typeof value !== "object") {
    return JSON.stringify(value);
  }
  if (Array.isArray(value)) {
    return `[${value.map((item) => stableStringify(item)).join(",")}]`;
  }
  const record = value;
  return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`).join(",")}}`;
};
var init_auth = __esm(() => {
  init_src();
  init_credentials();
  init_service();
  init_agent_resolver();
  init_credentials();
  init_bp_cli_import();
  auth = new Auth;
  projectClientCache = new Map;
});

class CatalogClientFactory {
  options;
  client;
  constructor(options = {}) {
    this.options = options;
  }
  async getClient() {
    if (this.client)
      return this.client;
    const { project, workspaceId, credentials, apiUrl } = this.options;
    const hasProjectScope = !!(project || workspaceId);
    if (hasProjectScope) {
      this.client = await getProjectClient({
        project,
        credentials,
        apiUrl,
        workspaceId,
        headers: { ...CATALOG_HEADERS }
      });
    } else if (credentials) {
      this.client = new Uk({
        token: credentials.token,
        apiUrl: apiUrl || credentials.apiUrl,
        ...credentials.workspaceId ? { workspaceId: credentials.workspaceId } : {},
        headers: { ...CATALOG_HEADERS }
      });
    } else {
      this.client = await getProjectClient({ headers: { ...CATALOG_HEADERS } });
    }
    return this.client;
  }
}
var CATALOG_HEADERS;
var init_client_factory = __esm(() => {
  init_auth();
  CATALOG_HEADERS = { "x-multiple-integrations": "true" };
});

class ResolutionCache {
  cacheDir;
  resolutionsDir;
  definitionsDir;
  idField;
  noCache;
  constructor(config, noCache = false) {
    this.idField = config.idField;
    this.noCache = noCache;
    const cacheRoot = config.cacheRoot ?? path4.join(os3.homedir(), ".adk", "cache");
    this.cacheDir = path4.join(cacheRoot, config.cacheType);
    this.resolutionsDir = path4.join(this.cacheDir, "resolutions");
    this.definitionsDir = path4.join(this.cacheDir, "definitions");
  }
  async ensureCacheDirs() {
    await fs4.mkdir(this.resolutionsDir, { recursive: true });
    await fs4.mkdir(this.definitionsDir, { recursive: true });
  }
  async getResolution(name, version, workspace, options) {
    if (this.noCache) {
      return null;
    }
    try {
      const key = this.getResolutionKey(name, version, workspace);
      const cachePath = path4.join(this.resolutionsDir, `${key}.json`);
      const data = await fs4.readFile(cachePath, "utf-8");
      const raw = JSON.parse(data);
      if (!options?.allowStale) {
        const cachedAt = new Date(raw.cachedAt);
        const ageMinutes = (Date.now() - cachedAt.getTime()) / (1000 * 60);
        if (ageMinutes > RESOLUTION_TTL_MINUTES) {
          return null;
        }
      }
      const id = raw[this.idField];
      if (!id) {
        return null;
      }
      return { id, updatedAt: raw.updatedAt, cachedAt: raw.cachedAt };
    } catch {
      return null;
    }
  }
  async setResolution(name, version, workspace, id, updatedAt) {
    await this.ensureCacheDirs();
    const key = this.getResolutionKey(name, version, workspace);
    const cachePath = path4.join(this.resolutionsDir, `${key}.json`);
    const resolution = {
      [this.idField]: id,
      updatedAt,
      cachedAt: new Date().toISOString()
    };
    await fs4.writeFile(cachePath, JSON.stringify(resolution));
  }
  async getDefinition(id, updatedAt) {
    if (this.noCache) {
      return null;
    }
    try {
      const key = this.getDefinitionKey(id, updatedAt);
      const cachePath = path4.join(this.definitionsDir, `${key}.json`);
      const data = await fs4.readFile(cachePath, "utf-8");
      const cached = JSON.parse(data);
      return cached.definition;
    } catch {
      return null;
    }
  }
  async setDefinition(id, updatedAt, definition) {
    await this.ensureCacheDirs();
    const key = this.getDefinitionKey(id, updatedAt);
    const cachePath = path4.join(this.definitionsDir, `${key}.json`);
    const cached = {
      definition,
      cachedAt: new Date().toISOString()
    };
    await fs4.writeFile(cachePath, JSON.stringify(cached));
  }
  async clear() {
    try {
      const resolutionFiles = await fs4.readdir(this.resolutionsDir);
      await Promise.all(resolutionFiles.map((file) => fs4.unlink(path4.join(this.resolutionsDir, file))));
      const definitionFiles = await fs4.readdir(this.definitionsDir);
      await Promise.all(definitionFiles.map((file) => fs4.unlink(path4.join(this.definitionsDir, file))));
    } catch {}
  }
  async getStats() {
    const getDirectoryStats = async (dir) => {
      try {
        const files = await fs4.readdir(dir);
        let totalSize = 0;
        for (const file of files) {
          const stats = await fs4.stat(path4.join(dir, file));
          totalSize += stats.size;
        }
        return { count: files.length, sizeBytes: totalSize };
      } catch {
        return { count: 0, sizeBytes: 0 };
      }
    };
    const [resolutions, definitions] = await Promise.all([
      getDirectoryStats(this.resolutionsDir),
      getDirectoryStats(this.definitionsDir)
    ]);
    return { resolutions, definitions };
  }
  getResolutionKey(name, version, workspace) {
    const prefix = workspace ? `${workspace}_` : "";
    const key = `${prefix}${name}_${version}`;
    return key.replace(/[^a-zA-Z0-9_-]/g, "_");
  }
  getDefinitionKey(id, updatedAt) {
    const key = `${id}_${updatedAt}`;
    return key.replace(/[^a-zA-Z0-9_-]/g, "_");
  }
}
var RESOLUTION_TTL_MINUTES = 5;
var init_resolution_cache = () => {};

class CatalogService {
  source;
  cache;
  constructor(source, noCache = false) {
    this.source = source;
    this.cache = new ResolutionCache(source.cacheConfig, noCache);
  }
  async getDefinition(ref) {
    const cachedResolution = await this.cache.getResolution(ref.name, ref.version, ref.workspace);
    if (cachedResolution) {
      const cachedDefinition = await this.cache.getDefinition(cachedResolution.id, cachedResolution.updatedAt);
      if (cachedDefinition) {
        return cachedDefinition;
      }
    }
    try {
      const { id, updatedAt, definition } = await this.source.fetchByRef(ref);
      await this.cache.setResolution(ref.name, ref.version, ref.workspace, id, updatedAt);
      await this.cache.setDefinition(id, updatedAt, definition);
      return definition;
    } catch (err) {
      if (!(err instanceof AdkError && err.expected)) {
        const stale = await this.getStaleDefinition(ref);
        if (stale !== null) {
          return stale;
        }
      }
      throw err;
    }
  }
  async getStaleDefinition(ref) {
    const stale = await this.cache.getResolution(ref.name, ref.version, ref.workspace, { allowStale: true });
    if (!stale)
      return null;
    return this.cache.getDefinition(stale.id, stale.updatedAt);
  }
  async getCacheStats() {
    const stats = await this.cache.getStats();
    return {
      count: stats.resolutions.count + stats.definitions.count,
      sizeBytes: stats.resolutions.sizeBytes + stats.definitions.sizeBytes
    };
  }
  async clearCache() {
    await this.cache.clear();
  }
}
var init_catalog_service = __esm(() => {
  init_src();
  init_resolution_cache();
});
function collectCatalogSearchResult(results, entry, query) {
  const rank = getCatalogSearchRank(entry, query);
  if (rank === undefined) {
    return;
  }
  const key = entry.name.toLowerCase();
  const existing = results.get(key);
  if (!existing || isBetterCatalogResult({ entry, rank }, existing)) {
    results.set(key, { entry, rank });
  }
}
function getSortedCatalogSearchResults(results, limit) {
  return [...results.values()].sort((a, b) => a.rank - b.rank || a.entry.name.localeCompare(b.entry.name) || compareVersions(b.entry.version, a.entry.version)).slice(0, limit).map(({ entry }) => entry);
}
function getSortedVersions(versions) {
  return [...versions].sort((a, b) => compareVersions(b, a));
}
function getCatalogSearchRank(entry, query) {
  const q = normalize(query);
  if (!q) {
    return 0;
  }
  const name = normalize(entry.name);
  const title = normalize(entry.title);
  const description = normalize(entry.description);
  if (name === q)
    return 0;
  if (title === q)
    return 1;
  if (name.startsWith(q))
    return 2;
  if (title.startsWith(q))
    return 3;
  if (name.includes(q))
    return 4;
  if (title.includes(q))
    return 5;
  if (description.includes(q))
    return 6;
  return;
}
function isBetterCatalogResult(candidate, existing) {
  if (candidate.rank !== existing.rank) {
    return candidate.rank < existing.rank;
  }
  const versionComparison = compareVersions(candidate.entry.version, existing.entry.version);
  if (versionComparison !== 0) {
    return versionComparison > 0;
  }
  return (candidate.entry.updatedAt ?? "").localeCompare(existing.entry.updatedAt ?? "") > 0;
}
function compareVersions(a, b) {
  const validA = semver.valid(a);
  const validB = semver.valid(b);
  if (validA && validB) {
    return semver.compare(validA, validB);
  }
  return a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" });
}
function normalize(value) {
  return (value ?? "").trim().toLowerCase();
}
var init_search_ranking = () => {};

class IntegrationCatalogSource {
  clientFactory;
  cacheConfig = { cacheType: "integrations", idField: "integrationId" };
  constructor(clientFactory) {
    this.clientFactory = clientFactory;
  }
  async fetchByRef(ref) {
    const client = await this.clientFactory.getClient();
    const integration = await this._findPrivateOrPublicIntegration(client, ref);
    if (!integration) {
      throw await this._buildIntegrationNotFoundError(client, ref);
    }
    return { id: integration.id, updatedAt: integration.updatedAt, definition: integration };
  }
  async search(query, limit = 20) {
    const client = await this.clientFactory.getClient();
    const results = new Map;
    const scanLimit = Math.max(limit * 5, 50);
    for await (const integration of client.list.publicIntegrations({
      name: query,
      sortBy: "updatedAt",
      direction: "desc"
    })) {
      collectCatalogSearchResult(results, toHubCacheEntry(integration), query);
    }
    let scanned = 0;
    for await (const integration of client.list.publicIntegrations({
      search: query,
      sortBy: "popularity",
      direction: "desc",
      limit: scanLimit
    })) {
      collectCatalogSearchResult(results, toHubCacheEntry(integration), query);
      scanned += 1;
      if (scanned >= scanLimit)
        break;
    }
    return getSortedCatalogSearchResults(results, limit);
  }
  async findImplementersOfInterface(interfaceName, limit = 10) {
    const client = await this.clientFactory.getClient();
    const seen = new Map;
    for await (const integration of client.list.publicIntegrations({
      interfaceName,
      sortBy: "popularity",
      direction: "desc",
      limit
    })) {
      const entry = toHubCacheEntry(integration);
      if (!seen.has(entry.name))
        seen.set(entry.name, entry);
      if (seen.size >= limit)
        break;
    }
    return [...seen.values()];
  }
  async listVersions(name) {
    const client = await this.clientFactory.getClient();
    const versions = new Set;
    for await (const integration of client.list.publicIntegrations({
      name,
      sortBy: "updatedAt",
      direction: "desc"
    })) {
      versions.add(integration.version);
    }
    return getSortedVersions(versions);
  }
  async _findPrivateOrPublicIntegration(client, ref) {
    const privateIntegration = await this._findPrivateIntegration(client, ref);
    if (privateIntegration) {
      return privateIntegration;
    }
    const publicIntegration = await this._findPublicIntegration(client, ref);
    if (publicIntegration) {
      return publicIntegration;
    }
    return;
  }
  async _findPrivateIntegration(client, ref) {
    try {
      const version = ref.workspace && ref.version !== "latest" ? "latest" : ref.version;
      const response = await client.getIntegrationByName({
        name: ref.fullName,
        version
      });
      return response.integration;
    } catch (error) {
      if (this._isResourceNotFoundError(error)) {
        return;
      }
      throw error;
    }
  }
  async _findPublicIntegration(client, ref) {
    try {
      const response = await client.getPublicIntegration({
        name: ref.fullName,
        version: ref.version
      });
      return response.integration;
    } catch (error) {
      if (this._isResourceNotFoundError(error)) {
        return;
      }
      throw error;
    }
  }
  _isResourceNotFoundError(error) {
    if (error && typeof error === "object" && "type" in error) {
      return error.type === "ResourceNotFound";
    }
    return false;
  }
  async _buildIntegrationNotFoundError(client, ref) {
    if (ref.version !== "latest") {
      const latestExists = await this._findPrivateOrPublicIntegration(client, { ...ref, version: "latest" });
      if (latestExists) {
        const scope = ref.workspace ? `workspace "${ref.workspace}"` : "the official Botpress hub";
        return new AdkError({
          code: "INTEGRATION_NOT_FOUND",
          message: `Integration "${ref.name}" version "${ref.version}" not found in ${scope} ` + `(latest is ${latestExists.version}). Run 'adk integrations info ${ref.fullName}' to see available versions.`,
          expected: true
        });
      }
    }
    if (!ref.workspace) {
      return new AdkError({
        code: "INTEGRATION_NOT_FOUND",
        message: `Integration "${ref.name}" not found in the official Botpress hub`,
        expected: true
      });
    }
    let currentWorkspaceHandle;
    let workspaceId;
    try {
      const credentials = await resolveWorkspaceCredentials({
        project: this.clientFactory.options.project,
        credentials: this.clientFactory.options.credentials,
        apiUrl: this.clientFactory.options.apiUrl,
        workspaceId: this.clientFactory.options.workspaceId
      });
      workspaceId = credentials.workspaceId;
      if (workspaceId) {
        const currentWorkspace = await client.getWorkspace({ id: workspaceId });
        currentWorkspaceHandle = currentWorkspace?.handle;
      }
    } catch {
      return new AdkError({
        code: "INTEGRATION_NOT_FOUND",
        message: `Integration "${ref.name}" not found in workspace "${ref.workspace}"`,
        expected: true
      });
    }
    if (currentWorkspaceHandle === ref.workspace) {
      return new AdkError({
        code: "INTEGRATION_NOT_FOUND",
        message: `Integration "${ref.name}" not found in workspace "${ref.workspace}" (workspaceId: ${workspaceId}). ` + `Are you sure you published the integration? ` + `Run 'adk deploy' to publish it to your workspace.`,
        expected: true,
        suggestion: "Are you sure you published the integration? Run 'adk deploy' to publish it to your workspace."
      });
    }
    return new AdkError({
      code: "INTEGRATION_NOT_FOUND",
      message: `Integration "${ref.name}" not found in workspace "${ref.workspace}" (current workspaceId: ${workspaceId}). ` + `This integration may be private. Private integrations can only be installed in the same workspace. ` + `If you want to share this integration with other workspaces, deploy it with --visibility="unlisted" or --visibility="public".`,
      expected: true
    });
  }
}
function toHubCacheEntry(integration) {
  return {
    id: integration.id,
    name: integration.name,
    version: integration.version,
    updatedAt: integration.updatedAt,
    createdAt: integration.createdAt,
    title: integration.title,
    description: integration.description,
    iconUrl: integration.iconUrl,
    public: integration.public,
    visibility: integration.visibility,
    ownerWorkspace: integration.ownerWorkspace ? { id: integration.ownerWorkspace.id, name: integration.ownerWorkspace.name } : undefined,
    verificationStatus: integration.verificationStatus
  };
}
var init_integration_source = __esm(() => {
  init_src();
  init_auth();
  init_search_ranking();
});

class IntegrationManager {
  source;
  service;
  constructor(options = {}) {
    const { noCache, ...clientOptions } = options;
    this.source = new IntegrationCatalogSource(new CatalogClientFactory(clientOptions));
    this.service = new CatalogService(this.source, noCache || false);
  }
  async loadIntegrations(dependencies) {
    const errors = [];
    const warnings = [];
    const parseResult = IntegrationParser.parseIntegrations(dependencies);
    const integrations = parseResult.integrations;
    errors.push(...parseResult.errors);
    const duplicateWarnings = IntegrationParser.checkDuplicates(integrations);
    warnings.push(...duplicateWarnings);
    const fetchPromises = integrations.map(async (integration) => {
      try {
        const definition = await this.fetchIntegration(integration.ref);
        integration.definition = definition;
        const validation = this.validateIntegration(integration);
        integration.validationResult = validation;
        if (!validation.valid) {
          validation.errors.forEach(() => {
            errors.push(ValidationErrors.unknownIntegration(integration.alias, integration.ref.fullName));
          });
        }
        if (validation.warnings.length > 0) {
          validation.warnings.forEach((warn) => {
            warnings.push(ValidationErrors.warning(warn, "agent.config.ts"));
          });
        }
      } catch (error) {
        if (error instanceof Error && error.message.includes("version")) {
          errors.push(ValidationErrors.integrationVersionError(integration.alias, error.message));
        } else {
          const errorMessage = error instanceof Error ? error.message : undefined;
          errors.push(ValidationErrors.unknownIntegration(integration.alias, integration.ref.fullName, errorMessage));
        }
      }
    });
    await Promise.all(fetchPromises);
    const hasChannels = integrations.some((i) => i.definition?.channels && Object.keys(i.definition.channels).length > 0);
    if (!hasChannels && integrations.length > 0) {
      warnings.push(ValidationErrors.warning("No integrations with channels found. Your agent may not be able to receive messages.", "agent.config.ts", "Add an integration with channels (e.g., slack, webchat) to enable conversations"));
    }
    return { integrations, errors, warnings };
  }
  async fetchIntegration(ref) {
    return this.service.getDefinition(ref);
  }
  async searchIntegrations(query, limit = 20) {
    return this.source.search(query, limit);
  }
  async findImplementersOfInterface(interfaceName, limit = 10) {
    return this.source.findImplementersOfInterface(interfaceName, limit);
  }
  async listIntegrationVersions(name) {
    return this.source.listVersions(name);
  }
  async getCacheStats() {
    return this.service.getCacheStats();
  }
  async clearCache() {
    await this.service.clearCache();
  }
  validateIntegration(integration) {
    const errors = [];
    const warnings = [];
    if (!integration.definition) {
      errors.push(`Integration definition not found for ${integration.alias}`);
      return { valid: false, errors, warnings };
    }
    const hasChannels = integration.definition.channels && Object.keys(integration.definition.channels).length > 0;
    if (!integration.config && integration.enabled !== undefined) {
      let requiresConfig = false;
      if (integration.definition.configurations) {
        requiresConfig = Object.values(integration.definition.configurations).some((config) => config.identifier?.required === true);
      }
      if (!requiresConfig && integration.definition.configuration) {
        const config = integration.definition.configuration;
        const schema = config.schema;
        requiresConfig = schema?.required && schema.required.length > 0;
      }
      if (requiresConfig) {
        warnings.push(`Integration '${integration.alias}' requires configuration. Add a config object in agent.config.ts dependencies`);
      }
    }
    return {
      valid: errors.length === 0,
      errors,
      warnings,
      missingChannels: !hasChannels
    };
  }
}
var init_manager = __esm(() => {
  init_dependencies_parser();
  init_validation_errors();
  init_client_factory();
  init_catalog_service();
  init_integration_source();
});
var init_types3 = () => {};
var defaultAdkFolder = ".adk";

class AssetsCacheManager {
  projectPath;
  cachePath;
  cache = null;
  constructor(projectPath) {
    this.projectPath = projectPath;
    this.cachePath = path5.join(projectPath, defaultAdkFolder, "assets-cache.json");
  }
  async load() {
    if (this.cache) {
      return this.cache;
    }
    try {
      const content = await fs5.readFile(this.cachePath, "utf-8");
      this.cache = JSON.parse(content);
      return this.cache;
    } catch {
      this.cache = {
        version: "1.0",
        entries: {}
      };
      return this.cache;
    }
  }
  async save() {
    if (!this.cache) {
      return;
    }
    const cacheDir = path5.dirname(this.cachePath);
    await fs5.mkdir(cacheDir, { recursive: true });
    await fs5.writeFile(this.cachePath, JSON.stringify(this.cache, null, 2), "utf-8");
  }
  async getEntry(assetPath) {
    const cache = await this.load();
    return cache.entries[assetPath] || null;
  }
  async setEntry(assetPath, localHash, remoteHash, metadata) {
    const cache = await this.load();
    cache.entries[assetPath] = {
      path: assetPath,
      localHash,
      remoteHash,
      metadata,
      lastUpdated: new Date().toISOString()
    };
    await this.save();
  }
  async isStale(assetPath) {
    const entry = await this.getEntry(assetPath);
    if (!entry)
      return false;
    return entry.localHash !== entry.remoteHash;
  }
  async removeEntry(assetPath) {
    const cache = await this.load();
    delete cache.entries[assetPath];
    await this.save();
  }
  async clear() {
    this.cache = {
      version: "1.0",
      entries: {}
    };
    await this.save();
  }
  async getAllEntries() {
    const cache = await this.load();
    return Object.values(cache.entries);
  }
}
var init_cache = () => {};

class AssetsManager {
  projectPath;
  assetsPath;
  client;
  botId;
  credentials;
  cacheManager;
  constructor(options) {
    this.projectPath = options.projectPath;
    this.assetsPath = path6.join(this.projectPath, "assets");
    this.botId = options.botId;
    this.credentials = options.credentials;
    this.cacheManager = new AssetsCacheManager(this.projectPath);
  }
  async getClient() {
    if (!this.client) {
      if (!this.botId) {
        throw new AdkError({
          code: "BOT_ID_REQUIRED",
          message: "Bot ID is required for asset operations. Please deploy your agent first or create agent.json with botId and workspaceId.",
          expected: true,
          suggestion: "Deploy your agent first or create agent.json with botId and workspaceId."
        });
      }
      this.client = await getProjectClient({
        project: { path: this.projectPath },
        credentials: this.credentials,
        botId: this.botId,
        headers: {
          "x-multiple-integrations": "true"
        }
      });
    }
    return this.client;
  }
  assertBotId(operation) {
    if (!this.botId) {
      throw new AdkError({
        code: "BOT_ID_REQUIRED",
        message: `Operation "${operation}" requires a bot ID. ` + "Please deploy your agent first or create agent.json with botId and workspaceId.",
        expected: true,
        suggestion: "Deploy your agent first or create agent.json with botId and workspaceId."
      });
    }
  }
  async hasAssetsDirectory() {
    try {
      const stats = await fs6.stat(this.assetsPath);
      return stats.isDirectory();
    } catch {
      return false;
    }
  }
  async getLocalAssets() {
    if (!await this.hasAssetsDirectory()) {
      return [];
    }
    const files = await this.scanDirectory(this.assetsPath);
    const assets = [];
    for (const filePath of files) {
      try {
        const stats = await fs6.stat(filePath);
        if (stats.isFile()) {
          const relativePath = path6.relative(this.assetsPath, filePath);
          const content = await fs6.readFile(filePath);
          const hash = this.calculateHash(content);
          const mime = this.getMimeType(filePath);
          assets.push({
            relativePath,
            absolutePath: filePath,
            name: path6.basename(filePath),
            size: stats.size,
            mime,
            hash,
            stats: {
              mtime: stats.mtime,
              size: stats.size
            }
          });
        }
      } catch (error) {
        console.warn(`Warning: Could not read asset file ${filePath}:`, error);
      }
    }
    return assets;
  }
  async getRemoteAssets() {
    this.assertBotId("get remote assets");
    const client = await this.getClient();
    try {
      const response = await client.listFiles({
        tags: {
          type: "asset",
          adk: "true"
        }
      });
      return response.files.map((file) => ({
        path: file.tags?.path || file.key,
        name: path6.basename(file.tags?.path || file.key),
        size: file.size || 0,
        mime: file.contentType,
        hash: file.tags?.hash || "",
        createdAt: file.createdAt,
        updatedAt: file.updatedAt,
        fileId: file.id,
        url: file.url || ""
      }));
    } catch (error) {
      throw new AdkError({
        code: "ASSET_FETCH_FAILED",
        message: `Failed to fetch remote assets: ${error}`,
        expected: true,
        cause: error
      });
    }
  }
  async createSyncPlan() {
    const [localAssets, remoteAssets] = await Promise.all([this.getLocalAssets(), this.getRemoteAssets()]);
    const items = [];
    const remoteMap = new Map;
    for (const remote of remoteAssets) {
      remoteMap.set(remote.path, remote);
    }
    for (const local of localAssets) {
      const remote = remoteMap.get(local.relativePath);
      if (!remote) {
        items.push({
          operation: "create",
          localFile: local,
          reason: "New local file"
        });
      } else if (local.hash !== remote.hash) {
        items.push({
          operation: "update",
          localFile: local,
          remoteFile: remote,
          reason: "Content changed"
        });
      } else {
        items.push({
          operation: "none",
          localFile: local,
          remoteFile: remote,
          reason: "Up to date"
        });
      }
      remoteMap.delete(local.relativePath);
    }
    for (const [, remote] of remoteMap) {
      items.push({
        operation: "delete",
        remoteFile: remote,
        reason: "Local file deleted"
      });
    }
    const totalCreate = items.filter((i) => i.operation === "create").length;
    const totalUpdate = items.filter((i) => i.operation === "update").length;
    const totalDelete = items.filter((i) => i.operation === "delete").length;
    const hasChanges = totalCreate > 0 || totalUpdate > 0 || totalDelete > 0;
    return {
      items,
      totalCreate,
      totalUpdate,
      totalDelete,
      hasChanges
    };
  }
  async executeSync(plan, options = {}) {
    this.assertBotId("sync assets");
    if (options.dryRun) {
      return {
        applied: false,
        success: [],
        skipped: [],
        failed: [],
        summary: {
          created: 0,
          updated: 0,
          deleted: 0,
          skipped: 0,
          failed: 0
        }
      };
    }
    const client = await this.getClient();
    const success = [];
    const skipped = [];
    const failed = [];
    for (const item of plan.items) {
      if (item.operation === "none") {
        success.push(item);
        continue;
      }
      try {
        switch (item.operation) {
          case "create":
          case "update":
            if (item.localFile) {
              await this.uploadAsset(client, item.localFile);
              success.push(item);
            }
            break;
          case "delete":
            if (item.remoteFile?.fileId) {
              if (!options.confirmDestructive) {
                skipped.push(item);
                continue;
              }
              await client.deleteFile({ id: item.remoteFile.fileId });
              success.push(item);
            }
            break;
        }
      } catch (error) {
        const err = error instanceof Error ? error : new Error(String(error));
        failed.push({ item, error: err });
        if (options.bailOnFailure) {
          break;
        }
      }
    }
    return {
      applied: true,
      success,
      skipped,
      failed,
      summary: {
        created: success.filter((i) => i.operation === "create").length,
        updated: success.filter((i) => i.operation === "update").length,
        deleted: success.filter((i) => i.operation === "delete").length,
        skipped: skipped.length,
        failed: failed.length
      }
    };
  }
  async uploadAsset(client, localFile) {
    const content = await fs6.readFile(localFile.absolutePath);
    await client.uploadFile({
      key: localFile.relativePath,
      content,
      contentType: localFile.mime,
      tags: {
        type: "asset",
        adk: "true",
        path: localFile.relativePath,
        hash: localFile.hash,
        name: localFile.name,
        size: localFile.size.toString()
      },
      index: false
    });
  }
  async generateTypes() {
    const localAssets = await this.getLocalAssets();
    const pathUnion = localAssets.map((asset) => `"${asset.relativePath}"`).join(" | ");
    const paths = localAssets.map((asset) => `  "${asset.relativePath}": "${asset.relativePath}";`).join(`
`);
    return `// Auto-generated asset types
import { Asset } from '@botpress/runtime';

export type AssetPaths = ${pathUnion || "never"};

export interface AssetPathMap {
${paths}
}

// Runtime asset access
declare global {
  const assets: {
    get<T extends AssetPaths>(path: T): Promise<Asset>;
    list(): Asset[];
    getSyncStatus(): {
      synced: boolean;
      neverSynced: string[];
      stale: string[];
      upToDate: string[];
    };
  };
}
`;
  }
  async createAssetsIndex() {
    const remoteAssets = await this.getRemoteAssets();
    return {
      files: remoteAssets,
      generatedAt: new Date().toISOString(),
      totalFiles: remoteAssets.length,
      totalSize: remoteAssets.reduce((sum, asset) => sum + asset.size, 0)
    };
  }
  async getEnrichedLocalAssets() {
    const localAssets = await this.getLocalAssets();
    const enrichedAssets = [];
    let remoteAssetsMap = new Map;
    try {
      if (this.botId) {
        const remoteAssets = await this.getRemoteAssets();
        remoteAssetsMap = new Map(remoteAssets.map((asset) => [asset.path, asset]));
      }
    } catch (error) {
      console.debug("Could not fetch remote assets:", error);
    }
    for (const localAsset of localAssets) {
      const cachedEntry = await this.cacheManager.getEntry(localAsset.relativePath);
      const remoteAsset = remoteAssetsMap.get(localAsset.relativePath);
      if (cachedEntry) {
        enrichedAssets.push(cachedEntry.metadata);
        await this.cacheManager.setEntry(localAsset.relativePath, localAsset.hash, cachedEntry.remoteHash, cachedEntry.metadata);
      } else if (remoteAsset) {
        enrichedAssets.push(remoteAsset);
        await this.cacheManager.setEntry(localAsset.relativePath, localAsset.hash, remoteAsset.hash, remoteAsset);
      } else {
        const placeholderAsset = {
          url: `__PLACEHOLDER_URL_${localAsset.relativePath}__`,
          path: localAsset.relativePath,
          size: localAsset.size,
          name: localAsset.name,
          mime: localAsset.mime,
          createdAt: new Date().toISOString(),
          updatedAt: new Date().toISOString(),
          fileId: `__PLACEHOLDER_ID_${localAsset.relativePath}__`,
          hash: localAsset.hash
        };
        enrichedAssets.push(placeholderAsset);
      }
    }
    return enrichedAssets;
  }
  async scanDirectory(dir, files = []) {
    const items = await fs6.readdir(dir);
    for (const item of items) {
      const fullPath = path6.join(dir, item);
      const stats = await fs6.stat(fullPath);
      if (stats.isDirectory()) {
        await this.scanDirectory(fullPath, files);
      } else {
        files.push(fullPath);
      }
    }
    return files;
  }
  calculateHash(content) {
    return crypto.createHash("sha256").update(content).digest("hex");
  }
  getMimeType(filePath) {
    const ext = path6.extname(filePath).toLowerCase();
    const mimeTypes = {
      ".png": "image/png",
      ".jpg": "image/jpeg",
      ".jpeg": "image/jpeg",
      ".gif": "image/gif",
      ".svg": "image/svg+xml",
      ".webp": "image/webp",
      ".pdf": "application/pdf",
      ".txt": "text/plain",
      ".md": "text/markdown",
      ".html": "text/html",
      ".css": "text/css",
      ".js": "application/javascript",
      ".json": "application/json",
      ".xml": "application/xml",
      ".zip": "application/zip",
      ".mp4": "video/mp4",
      ".webm": "video/webm",
      ".mp3": "audio/mpeg",
      ".wav": "audio/wav",
      ".ogg": "audio/ogg"
    };
    return mimeTypes[ext] || "application/octet-stream";
  }
}
var init_manager2 = __esm(() => {
  init_src();
  init_auth();
  init_types3();
  init_cache();
});
var init_fs = () => {};
var init_updater = __esm(() => {
  init_fs();
});
var init_assets = __esm(() => {
  init_types3();
  init_manager2();
  init_updater();
  init_cache();
});
var init_cache2 = () => {};
var init_config_utils = __esm(() => {
  init_auth();
});
var init_integrations = __esm(() => {
  init_manager();
  init_dependencies_parser();
  init_cache2();
  init_config_utils();
});

class InterfaceParser {
  static parseInterfaceRef(versionString) {
    const match = versionString.match(/^(?:([^/]+)\/)?([^@]+)@(.+)$/);
    if (!match) {
      throw new AdkError({
        code: "INVALID_VERSION_FORMAT",
        message: `Invalid interface version format: ${versionString}. Expected format: 'name@version' or 'workspace/name@version'`,
        expected: true
      });
    }
    const [, workspace, name, version] = match;
    return {
      workspace: workspace || undefined,
      name,
      version,
      fullName: workspace ? `${workspace}/${name}` : name
    };
  }
  static parseInterfaces(_dependencies) {
    const interfaces = [];
    const errors = [];
    for (const [alias, versionString] of Object.entries(BUILTIN_INTERFACES)) {
      try {
        const ref = this.parseInterfaceRef(versionString);
        if (!this.isValidVersion(ref.version)) {
          errors.push(ValidationErrors.invalidVersionFormat(alias, ref.version));
        }
        interfaces.push({ alias, ref, config: undefined });
      } catch (error) {
        errors.push(ValidationErrors.invalidDependenciesSyntax(`Invalid interface '${alias}': ${error instanceof Error ? error.message : String(error)}`));
      }
    }
    return { interfaces, errors };
  }
  static isValidVersion(version) {
    if (version === "latest")
      return true;
    const semverPattern = /^(\d+)\.(\d+)\.(\d+)(-[\w.]+)?(\+[\w.]+)?$/;
    return semverPattern.test(version);
  }
}
var init_parser = __esm(() => {
  init_src();
  init_validation_errors();
  init_constants();
});

class InterfaceCatalogSource {
  clientFactory;
  cacheConfig = { cacheType: "interfaces", idField: "interfaceId" };
  constructor(clientFactory) {
    this.clientFactory = clientFactory;
  }
  async fetchByRef(ref) {
    const client = await this.clientFactory.getClient();
    let interfaceResponse;
    let versionError = null;
    try {
      interfaceResponse = await client.getInterfaceByName({
        name: ref.name,
        version: ref.version
      });
    } catch {
      try {
        interfaceResponse = await client.getPublicInterface({
          name: ref.name,
          version: ref.version
        });
      } catch (publicError) {
        versionError = publicError;
      }
    }
    if (!interfaceResponse && versionError) {
      let latestVersion = null;
      try {
        const latestPrivate = await client.getInterfaceByName({
          name: ref.name,
          version: "latest"
        });
        latestVersion = latestPrivate.interface.version;
      } catch {
        try {
          const latestPublic = await client.getPublicInterface({
            name: ref.name,
            version: "latest"
          });
          latestVersion = latestPublic.interface.version;
        } catch {
          const location2 = ref.workspace ? `workspace "${ref.workspace}"` : "the official Botpress hub";
          throw new AdkError({
            code: "INTERFACE_NOT_FOUND",
            message: `Interface "${ref.name}" does not exist in ${location2}`,
            expected: true
          });
        }
      }
      const location = ref.workspace ? `workspace "${ref.workspace}"` : "Botpress";
      throw new AdkError({
        code: "VERSION_NOT_FOUND",
        message: `Interface "${ref.name}" version "${ref.version}" not found in ${location}. Latest available version is "${latestVersion}"`,
        expected: true
      });
    }
    const intf = interfaceResponse.interface;
    return { id: intf.id, updatedAt: intf.updatedAt, definition: intf };
  }
}
var init_interface_source = __esm(() => {
  init_src();
});

class InterfaceManager {
  service;
  constructor(options = {}) {
    const { noCache, ...clientOptions } = options;
    this.service = new CatalogService(new InterfaceCatalogSource(new CatalogClientFactory(clientOptions)), noCache || false);
  }
  async loadInterfaces(dependencies) {
    const errors = [];
    const warnings = [];
    const parseResult = InterfaceParser.parseInterfaces(dependencies);
    const interfaces = parseResult.interfaces;
    errors.push(...parseResult.errors);
    const fetchPromises = interfaces.map(async (intf) => {
      try {
        const definition = await this.fetchInterface(intf.ref);
        intf.definition = definition;
        const validation = this.validateInterface(intf);
        intf.validationResult = validation;
        if (!validation.valid) {
          validation.errors.forEach((msg) => {
            errors.push(ValidationErrors.warning(msg, "agent.config.ts"));
          });
        }
      } catch (error) {
        if (error instanceof Error && error.message.includes("version")) {
          errors.push(ValidationErrors.unknownInterface(error.message));
        } else {
          errors.push(ValidationErrors.invalidDependenciesSyntax(`Unknown interface '${intf.alias}' (${intf.ref.fullName})`));
        }
      }
    });
    await Promise.all(fetchPromises);
    return { interfaces, errors, warnings };
  }
  async fetchInterface(ref) {
    return this.service.getDefinition(ref);
  }
  validateInterface(intf) {
    const errors = [];
    const warnings = [];
    if (!intf.definition) {
      errors.push(`Interface definition not found for ${intf.alias}`);
      return { valid: false, errors, warnings };
    }
    return { valid: errors.length === 0, errors, warnings };
  }
  async getCacheStats() {
    return this.service.getCacheStats();
  }
  async clearCache() {
    await this.service.clearCache();
  }
}
var init_manager3 = __esm(() => {
  init_parser();
  init_validation_errors();
  init_client_factory();
  init_catalog_service();
  init_interface_source();
});
var init_enhanced_cache = __esm(() => {
  init_resolution_cache();
});
var init_interfaces = __esm(() => {
  init_manager3();
  init_parser();
  init_enhanced_cache();
});
function orderKeys(obj, keyOrder) {
  const objKeys = Object.keys(obj);
  const orderedKeys = [];
  const remainingKeys = [];
  if (keyOrder) {
    for (const key of keyOrder) {
      const keyStr = String(key);
      if (objKeys.includes(keyStr)) {
        orderedKeys.push(keyStr);
      }
    }
  }
  for (const key of objKeys) {
    if (!orderedKeys.includes(key)) {
      remainingKeys.push(key);
    }
  }
  remainingKeys.sort();
  const finalKeys = [...orderedKeys, ...remainingKeys];
  const result = {};
  for (const key of finalKeys) {
    result[key] = obj[key];
  }
  return result;
}
function orderIntegrationKeys(integrations) {
  const result = {};
  for (const [name, config] of Object.entries(integrations)) {
    if (typeof config === "object" && config !== null && !Array.isArray(config)) {
      result[name] = orderKeys(config, integrationKeyOrder);
    } else {
      result[name] = config;
    }
  }
  return result;
}
function stringifyWithOrder(obj, keyOrder, space = 2) {
  const orderedObj = orderKeys(obj, keyOrder);
  if ("integrations" in orderedObj) {
    const integrations = orderedObj.integrations;
    if (integrations && typeof integrations === "object") {
      orderedObj.integrations = orderIntegrationKeys(integrations);
    }
  }
  return JSON.stringify(orderedObj, null, space);
}
var agentInfoKeyOrder;
var agentLocalInfoKeyOrder;
var dependenciesKeyOrder;
var integrationKeyOrder;
var init_json_ordering = __esm(() => {
  agentInfoKeyOrder = ["botId", "workspaceId", "apiUrl"];
  agentLocalInfoKeyOrder = ["botId", "workspaceId", "apiUrl", "devId"];
  dependenciesKeyOrder = ["integrations"];
  integrationKeyOrder = ["version", "enabled", "configurationType", "config"];
});
async function expandExports(options) {
  const { absolutePath, relPath, filename, onWarning } = options;
  let result = {};
  try {
    const importPath = `${absolutePath}?t=${Date.now()}`;
    const exports = await import(importPath);
    if (typeof exports === "object" && exports !== null) {
      for (const key of Object.keys(exports)) {
        try {
          result[key] = exports[key];
        } catch (error) {
          if (Errors.isAdkError(error)) {
            onWarning({
              $type: "ValidationError",
              code: "INVALID_PRIMITIVE_DEFINITION",
              severity: "warning",
              message: error.message,
              file: relPath,
              hint: `Invalid primitive instantiation in ${filename} -> ${key}`
            });
          }
        }
      }
      if (typeof exports.default === "object" && exports.default !== null) {
        try {
          const definition = Primitives.Definitions.getDefinition(exports.default);
          if (!definition) {
            for (const key of Object.keys(exports.default)) {
              try {
                result[`default.${key}`] = exports.default[key];
              } catch (error) {
                if (Errors.isAdkError(error)) {
                  onWarning({
                    $type: "ValidationError",
                    code: "INVALID_PRIMITIVE_DEFINITION",
                    severity: "warning",
                    message: error.message,
                    file: relPath,
                    hint: `Invalid primitive instantiation in ${filename} -> default.${key}`
                  });
                }
              }
            }
          }
        } catch (error) {
          if (Errors.isAdkError(error)) {
            onWarning({
              $type: "ValidationError",
              code: "INVALID_PRIMITIVE_DEFINITION",
              severity: "warning",
              message: error.message,
              file: relPath,
              hint: `Invalid primitive instantiation in ${filename} -> default`
            });
          }
        }
      }
    }
    return result;
  } catch (importError) {
    if (Errors.isAdkError(importError)) {
      onWarning({
        $type: "ValidationError",
        code: "INVALID_PRIMITIVE_DEFINITION",
        severity: "warning",
        message: importError.message,
        file: relPath,
        hint: `Invalid primitive instantiation in ${filename}`
      });
      return {};
    }
    let currentError = importError;
    while (currentError) {
      if (Errors.isAdkError(currentError)) {
        onWarning({
          $type: "ValidationError",
          code: "INVALID_PRIMITIVE_DEFINITION",
          severity: "warning",
          message: currentError.message,
          file: relPath,
          hint: `Invalid primitive instantiation in ${filename}`
        });
        return {};
      }
      currentError = currentError instanceof Error ? currentError.cause : undefined;
    }
    throw importError;
  }
}
var init_expand_exports = __esm(() => {
  init_types2();
});
var BP_TSX_SUFFIX = ".bp.tsx";
var BP_CSS_SUFFIX = ".bp.css";
var BP_TYPES_SUFFIX = ".bp.types.ts";
var BP_BUNDLE_SUFFIXES;
var COMPONENTS_DIR = "src/components";
var init_component_files = __esm(() => {
  BP_BUNDLE_SUFFIXES = [BP_TSX_SUFFIX, BP_CSS_SUFFIX, BP_TYPES_SUFFIX];
});
function resolveComponentSources(absolutePath) {
  const project = new import_ts_morph.Project({ useInMemoryFileSystem: false, skipAddingFilesFromTsConfig: true });
  const sourceFile = project.createSourceFile(absolutePath, readFileSync(absolutePath, "utf-8"), { overwrite: true });
  const importBindings = collectBpTsxImports(sourceFile, absolutePath);
  if (importBindings.size === 0) {
    return new Map;
  }
  const localToSource = resolveLocalBindings(sourceFile, importBindings);
  return resolveExports(sourceFile, localToSource, importBindings);
}
function collectBpTsxImports(sourceFile, absolutePath) {
  const imports = new Map;
  const dir = path8.dirname(absolutePath);
  for (const decl of sourceFile.getImportDeclarations()) {
    const specifier = decl.getModuleSpecifierValue();
    if (!specifier.endsWith(BP_TSX_SUFFIX))
      continue;
    const resolved = path8.resolve(dir, specifier);
    const defaultImport = decl.getDefaultImport();
    if (defaultImport) {
      imports.set(defaultImport.getText(), resolved);
    }
    const namespaceImport = decl.getNamespaceImport();
    if (namespaceImport) {
      imports.set(namespaceImport.getText(), resolved);
    }
  }
  return imports;
}
function resolveLocalBindings(sourceFile, importBindings) {
  const result = new Map;
  for (const stmt of sourceFile.getVariableStatements()) {
    for (const decl of stmt.getDeclarations()) {
      const initializer = decl.getInitializer();
      if (!initializer)
        continue;
      const source = sourceFromCustomComponentExpr(initializer, importBindings);
      if (source) {
        result.set(decl.getName(), source);
      }
    }
  }
  return result;
}
function resolveExports(sourceFile, localToSource, importBindings) {
  const exportMap = new Map;
  for (const stmt of sourceFile.getVariableStatements()) {
    if (!stmt.isExported())
      continue;
    for (const decl of stmt.getDeclarations()) {
      const source = localToSource.get(decl.getName());
      if (source)
        exportMap.set(decl.getName(), source);
    }
  }
  for (const assignment of sourceFile.getExportAssignments()) {
    if (assignment.isExportEquals())
      continue;
    const expr = assignment.getExpression();
    const direct = sourceFromCustomComponentExpr(expr, importBindings);
    if (direct) {
      exportMap.set("default", direct);
      continue;
    }
    if (expr.getKind() === import_ts_morph.SyntaxKind.Identifier) {
      const fromLocal = localToSource.get(expr.getText());
      if (fromLocal)
        exportMap.set("default", fromLocal);
    }
  }
  for (const decl of sourceFile.getExportDeclarations()) {
    if (decl.getModuleSpecifier())
      continue;
    for (const named of decl.getNamedExports()) {
      const localName = named.getNameNode().getText();
      const aliasNode = named.getAliasNode();
      const exportName = aliasNode ? aliasNode.getText() : localName;
      const source = localToSource.get(localName);
      if (source)
        exportMap.set(exportName, source);
    }
  }
  return exportMap;
}
function sourceFromCustomComponentExpr(expr, importBindings) {
  if (expr.getKind() !== import_ts_morph.SyntaxKind.NewExpression)
    return;
  const newExpr = expr.asKindOrThrow(import_ts_morph.SyntaxKind.NewExpression);
  if (newExpr.getExpression().getText() !== CUSTOM_COMPONENT_CLASS)
    return;
  const args = newExpr.getArguments();
  const firstArg = args[0];
  if (!firstArg || firstArg.getKind() !== import_ts_morph.SyntaxKind.Identifier)
    return;
  return importBindings.get(firstArg.getText());
}
var CUSTOM_COMPONENT_CLASS = "CustomComponent";
var init_component_source_resolver = __esm(() => {
  init_component_files();
});
function getColumnCount(table) {
  const properties = table.definition.schema?.properties;
  return properties ? Object.keys(properties).length : 0;
}
function findTableColumnViolations(tables, max = MAX_TABLE_COLUMNS) {
  return tables.map((table) => ({
    name: table.definition.name,
    path: table.path,
    columnCount: getColumnCount(table)
  })).filter((t) => t.columnCount > max);
}
var init_table_validation = __esm(() => {
  init_constants();
});
function isBotpressInternalId(alias) {
  return BP_INTERNAL_ID_PREFIXES.some((prefix) => alias.startsWith(prefix));
}
function isFriendlyAlias(alias) {
  return FRIENDLY_ALIAS_RE.test(alias) && !isBotpressInternalId(alias);
}
function generateFriendlyAlias(cloudName, cloudAlias, used) {
  if (isFriendlyAlias(cloudAlias) && !used.has(cloudAlias))
    return cloudAlias;
  const base = cloudName?.split("/").at(-1) ?? cloudAlias;
  const sanitized = base.toLowerCase().replace(/[^a-z0-9_-]/g, "-");
  let candidate = sanitized;
  let n = 2;
  while (used.has(candidate)) {
    candidate = `${sanitized}-${n}`;
    n++;
  }
  return candidate;
}
var FRIENDLY_ALIAS_RE;
var BP_INTERNAL_ID_PREFIXES;
var init_alias_utils = __esm(() => {
  FRIENDLY_ALIAS_RE = /^[a-z0-9_-]{2,100}$/;
  BP_INTERNAL_ID_PREFIXES = ["intver_", "plgver_", "int_", "plg_"];
});

class DependencySnapshotStore {
  projectPath;
  dirPath;
  constructor(opts) {
    this.projectPath = opts.projectPath;
    this.dirPath = path9.join(opts.projectPath, ".adk", "dependencies");
  }
  getSnapshotPath(env) {
    return path9.join(this.dirPath, `${env}.json`);
  }
  getMigrationMarkerPath() {
    return path9.join(this.dirPath, "migration.json");
  }
  async exists(env) {
    try {
      await fs8.access(this.getSnapshotPath(env));
      return true;
    } catch {
      return false;
    }
  }
  async read(env, options) {
    const filePath = this.getSnapshotPath(env);
    let raw;
    try {
      raw = await fs8.readFile(filePath, "utf8");
    } catch (err) {
      if (err.code === "ENOENT")
        return null;
      throw err;
    }
    try {
      return dependencySnapshotSchema.parse(JSON.parse(raw));
    } catch (err) {
      if (options?.tolerant)
        return null;
      throw new DependencyError({
        code: "INVALID_CONFIG",
        message: `Dependency snapshot at ${filePath} failed schema validation`,
        details: { issues: err.issues ?? String(err) }
      });
    }
  }
  async readOrEmpty(env, options) {
    const snapshot = await this.read(env, options);
    return snapshot ?? emptyDependencySnapshot(env, options?.botId, options?.fetchedAt);
  }
  async write(snapshot) {
    const validated = dependencySnapshotSchema.parse(snapshot);
    await fs8.mkdir(this.dirPath, { recursive: true });
    const filePath = this.getSnapshotPath(validated.env);
    const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
    await fs8.writeFile(tmp, JSON.stringify(sortKeysDeep(validated), null, 2) + `
`, "utf8");
    await fs8.rename(tmp, filePath);
  }
  async delete(env) {
    try {
      await fs8.unlink(this.getSnapshotPath(env));
    } catch (err) {
      if (err.code !== "ENOENT")
        throw err;
    }
  }
  async hasMigrationMarker() {
    try {
      await fs8.access(this.getMigrationMarkerPath());
      return true;
    } catch {
      return false;
    }
  }
  async writeMigrationMarker(marker) {
    const validated = dependencyMigrationMarkerSchema.parse(marker);
    await fs8.mkdir(this.dirPath, { recursive: true });
    const filePath = this.getMigrationMarkerPath();
    const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
    await fs8.writeFile(tmp, JSON.stringify(sortKeysDeep(validated), null, 2) + `
`, "utf8");
    await fs8.rename(tmp, filePath);
  }
  async refreshFromCloud(opts) {
    const previous = await this.readForRefresh(opts.env, opts.onWarning);
    const { bot } = await opts.client.getBot({ id: opts.botId });
    const snapshot = dependencySnapshotFromBot({
      bot,
      botId: opts.botId,
      env: opts.env,
      fetchedAt: opts.fetchedAt ?? new Date,
      previous
    });
    await annotateAuthorizationPending({
      snapshot,
      bot,
      integrationRegistry: opts.integrationRegistry
    });
    if (previous && cloudSnapshotUnchanged(previous, snapshot)) {
      return previous;
    }
    await this.write(snapshot);
    return snapshot;
  }
  async readForRefresh(env, onWarning) {
    try {
      return await this.read(env);
    } catch (err) {
      if (!(err instanceof DependencyError) || err.code !== "INVALID_CONFIG")
        throw err;
      const filePath = this.getSnapshotPath(env);
      await this.delete(env);
      onWarning?.({
        code: "SNAPSHOT_CORRUPT",
        message: `Removed corrupt dependency snapshot at ${filePath}; refreshing from Cloud.`,
        env,
        path: filePath
      });
      return null;
    }
  }
}
function emptyDependencySnapshot(env, botId = "local", fetchedAt = new Date(0)) {
  return {
    version: 1,
    env,
    botId,
    fetchedAt: fetchedAt.toISOString(),
    integrations: {},
    plugins: {}
  };
}
function cloudSnapshotUnchanged(previous, next) {
  if (previous.botId !== next.botId || previous.env !== next.env)
    return false;
  if (previous.botUpdatedAt !== next.botUpdatedAt)
    return false;
  return jsonEqual({ integrations: previous.integrations, plugins: previous.plugins }, { integrations: next.integrations, plugins: next.plugins });
}
async function annotateAuthorizationPending(opts) {
  const registry = opts.integrationRegistry;
  if (!registry)
    return;
  const cloudIntegrations = opts.bot.integrations ?? {};
  const specCache = new Map;
  const getSpec = (name, version) => {
    const key = `${name}@${version}`;
    const cached = specCache.get(key);
    if (cached)
      return cached;
    const promise = registry.getSpec(name, version).catch(() => null);
    specCache.set(key, promise);
    return promise;
  };
  await Promise.all(Object.entries(opts.snapshot.integrations).map(async ([alias, entry]) => {
    const cloudAlias = entry.cloudAlias ?? alias;
    const cloud = cloudIntegrations[cloudAlias];
    if (!cloud)
      return;
    if (cloud.identifier) {
      delete entry.authorizationPending;
      return;
    }
    const spec = await getSpec(entry.name, entry.version);
    if (!spec)
      return;
    const requiresAuthorization = integrationRequiresAuthorization(spec, entry.configurationType);
    if (requiresAuthorization) {
      entry.authorizationPending = true;
    } else {
      delete entry.authorizationPending;
    }
  }));
}
function dependencySnapshotFromBot(opts) {
  const integrations = {};
  const usedIntegrationAliases = new Set;
  for (const [cloudAlias, cloud] of Object.entries(opts.bot.integrations ?? {})) {
    const cloudName = typeof cloud.name === "string" ? cloud.name : undefined;
    const config = cloud.configuration ?? {};
    const version = cloud.version ?? "0.0.0";
    const configurationType = typeof cloud.configurationType === "string" && cloud.configurationType && cloud.configurationType !== "default" ? cloud.configurationType : undefined;
    const alias = chooseCloudAlias({
      cloudAlias,
      cloudName,
      previous: opts.previous?.integrations ?? {},
      used: usedIntegrationAliases,
      matches: (entry) => entry.version === version && entry.configurationType === configurationType && jsonEqual(entry.config, config)
    });
    usedIntegrationAliases.add(alias);
    const previousEntry = opts.previous?.integrations[alias];
    const previousMissingFields = previousEntry?.missingFields?.length && !cloud.enabled && previousEntry.version === version && previousEntry.configurationType === configurationType && jsonEqual(previousEntry.config, config) ? previousEntry.missingFields : undefined;
    integrations[alias] = {
      name: cloud.name ?? "",
      version,
      enabled: Boolean(cloud.enabled),
      config,
      ...configurationType ? { configurationType } : {},
      ...previousMissingFields ? { missingFields: previousMissingFields } : {},
      ...!cloud.identifier && previousEntry?.authorizationPending ? { authorizationPending: true } : {},
      ...typeof cloud.id === "string" ? { cloudId: cloud.id } : {},
      cloudAlias,
      ...typeof cloud.updatedAt === "string" ? { updatedAt: cloud.updatedAt } : {}
    };
  }
  const plugins = {};
  const usedPluginAliases = new Set;
  for (const [cloudAlias, cloud] of Object.entries(opts.bot.plugins ?? {})) {
    const cloudName = typeof cloud.name === "string" ? cloud.name : undefined;
    const config = cloud.configuration ?? {};
    const version = cloud.version ?? "0.0.0";
    const dependencies = {};
    for (const [ifaceAlias, dep] of Object.entries(cloud.interfaces ?? {})) {
      if (typeof dep.integrationAlias === "string") {
        dependencies[ifaceAlias] = { integrationAlias: dep.integrationAlias };
      }
    }
    const alias = chooseCloudAlias({
      cloudAlias,
      cloudName,
      previous: opts.previous?.plugins ?? {},
      used: usedPluginAliases,
      matches: (entry) => entry.version === version && jsonEqual(entry.config, config)
    });
    usedPluginAliases.add(alias);
    const previousEntry = opts.previous?.plugins[alias];
    const previousMissingFields = previousEntry?.missingFields?.length && !(cloud.enabled ?? true) && previousEntry.version === version && jsonEqual(previousEntry.config, config) ? previousEntry.missingFields : undefined;
    plugins[alias] = {
      name: cloud.name ?? "",
      version,
      enabled: cloud.enabled ?? true,
      config,
      dependencies,
      ...previousMissingFields ? { missingFields: previousMissingFields } : {},
      ...typeof cloud.id === "string" ? { cloudId: cloud.id } : {},
      cloudAlias,
      ...typeof cloud.updatedAt === "string" ? { updatedAt: cloud.updatedAt } : {}
    };
  }
  return {
    version: 1,
    env: opts.env,
    botId: opts.botId,
    fetchedAt: opts.fetchedAt.toISOString(),
    ...typeof opts.bot.updatedAt === "string" ? { botUpdatedAt: opts.bot.updatedAt } : {},
    integrations,
    plugins
  };
}
function chooseCloudAlias(opts) {
  if (isFriendlyAlias(opts.cloudAlias) && opts.previous[opts.cloudAlias] && !opts.used.has(opts.cloudAlias)) {
    return opts.cloudAlias;
  }
  if (opts.cloudName) {
    if (opts.matches) {
      const exactMatch = Object.entries(opts.previous).find(([alias, entry]) => !opts.used.has(alias) && entry.name === opts.cloudName && opts.matches(entry));
      if (exactMatch)
        return exactMatch[0];
    }
    const match = Object.entries(opts.previous).find(([alias, entry]) => !opts.used.has(alias) && entry.name === opts.cloudName);
    if (match)
      return match[0];
  }
  return generateFriendlyAlias(opts.cloudName, opts.cloudAlias, opts.used);
}
var init_snapshot_store = __esm(() => {
  init_alias_utils();
  init_errors2();
  init_types();
});
function dependencyStateToDependencies(state) {
  const integrations = {};
  for (const [alias, entry] of Object.entries(state.integrations)) {
    integrations[alias] = {
      version: `${entry.name}@${entry.version}`,
      enabled: entry.enabled,
      config: entry.config,
      ...entry.configurationType ? { configurationType: entry.configurationType } : {}
    };
  }
  const plugins = {};
  for (const [alias, entry] of Object.entries(state.plugins)) {
    plugins[alias] = {
      version: `${entry.name}@${entry.version}`,
      config: entry.config,
      dependencies: entry.dependencies,
      ...entry.missingFields !== undefined ? { missingFields: entry.missingFields } : {}
    };
  }
  return { integrations, plugins };
}
function getToolDefinition(value) {
  if (typeof value !== "object" || value === null) {
    return;
  }
  const maybeTool = value;
  const isAutonomousToolInstance = value instanceof Autonomous.Tool;
  const looksLikeAutonomousTool = typeof maybeTool.name === "string" && typeof maybeTool.execute === "function" && typeof maybeTool.toJSON === "function";
  if (!isAutonomousToolInstance && !looksLikeAutonomousTool) {
    return;
  }
  return {
    name: maybeTool.name,
    description: maybeTool.description
  };
}
var debug;
var AgentProject;
var init_agent_project = __esm(() => {
  init_src();
  init_assets();
  init_integrations();
  init_interfaces();
  init_json_ordering();
  init_expand_exports();
  init_component_source_resolver();
  init_component_files();
  init_agent_resolver();
  init_types2();
  init_validation_errors();
  init_table_validation();
  init_constants();
  init_snapshot_store();
  debug = import_debug.default("adk:agent-project");
  AgentProject = class AgentProject2 {
    static _projectCache = new Map;
    _options;
    _path;
    _config;
    _dependencies;
    _agentInfo;
    _state = "unloaded";
    _errors = [];
    _warnings = [];
    _lastBuildTime;
    _integrations;
    _interfaces;
    _integrationManager;
    _interfaceManager;
    _assetsManager;
    _conversations = [];
    _knowledge = [];
    _triggers = [];
    _workflows = [];
    _actions = [];
    _tables = [];
    _customComponents = [];
    _tools = [];
    constructor(projectPath, options = {}) {
      this._options = options;
      this._path = path10.resolve(projectPath);
      this._integrationManager = new IntegrationManager({
        noCache: options.noCache
      });
      this._interfaceManager = new InterfaceManager({
        noCache: options.noCache
      });
      this._assetsManager = new AssetsManager({
        projectPath: this._path
      });
    }
    static async load(projectPath, options = {}) {
      const resolvedPath = path10.resolve(projectPath);
      const cacheKey = AgentProject2._getCacheKey(resolvedPath, options);
      if (!options.noCache) {
        const cached = AgentProject2._projectCache.get(cacheKey);
        if (cached) {
          return cached;
        }
      }
      const project = new AgentProject2(resolvedPath, options);
      await project.reload();
      if (!options.noCache) {
        AgentProject2._projectCache.set(cacheKey, project);
      }
      return project;
    }
    static _getCacheKey(resolvedPath, options) {
      const adkCommand = options.adkCommand ?? "default";
      const offline = options.offline ? "offline" : "online";
      return `${resolvedPath}\x00${adkCommand}\x00${offline}`;
    }
    static clearCache() {
      AgentProject2._projectCache.clear();
    }
    static clearCacheForPath(projectPath) {
      const resolvedPath = path10.resolve(projectPath);
      const prefix = `${resolvedPath}\x00`;
      for (const key of AgentProject2._projectCache.keys()) {
        if (key.startsWith(prefix)) {
          AgentProject2._projectCache.delete(key);
        }
      }
    }
    get path() {
      return this._path;
    }
    get conversations() {
      return this._conversations;
    }
    get knowledge() {
      return this._knowledge;
    }
    get triggers() {
      return this._triggers;
    }
    get workflows() {
      return this._workflows;
    }
    get actions() {
      return this._actions;
    }
    get tables() {
      return this._tables;
    }
    get customComponents() {
      return this._customComponents;
    }
    get tools() {
      return this._tools;
    }
    get config() {
      return this._config;
    }
    get dependencies() {
      return this._dependencies;
    }
    get agentInfo() {
      return this._agentInfo;
    }
    get state() {
      return this._state;
    }
    get info() {
      return {
        path: this._path,
        config: this._config,
        dependencies: this._dependencies || {
          integrations: {}
        },
        agentInfo: this._agentInfo,
        state: this._state,
        lastBuildTime: this._lastBuildTime,
        errors: [...this._errors],
        warnings: [...this._warnings],
        errorCount: this._errors.filter((e) => e.severity === "error").length,
        warningCount: this._warnings.filter((e) => e.severity === "warning").length,
        infoCount: [...this._errors, ...this._warnings].filter((e) => e.severity === "info").length
      };
    }
    async reload() {
      this._state = "loading";
      try {
        this._conversations = [];
        this._knowledge = [];
        this._triggers = [];
        this._workflows = [];
        this._actions = [];
        this._tables = [];
        this._tools = [];
        this._errors = [];
        this._warnings = [];
        this._customComponents = [];
        const validation = await this.validate();
        this._errors = validation.errors;
        this._warnings = validation.warnings;
        if (!validation.valid) {
          this._state = "error";
          throw new AdkError({
            code: "PROJECT_VALIDATION_FAILED",
            expected: true,
            message: `Project validation failed: ${validation.errors[0]?.message}`,
            details: { errors: validation.errors }
          });
        }
        await this.loadAgentInfo();
        this._integrationManager = new IntegrationManager({
          noCache: this._options.noCache,
          project: this
        });
        this._interfaceManager = new InterfaceManager({
          noCache: this._options.noCache,
          project: this
        });
        this._assetsManager = new AssetsManager({
          projectPath: this._path,
          botId: this._agentInfo?.botId
        });
        await this.loadConfig();
        await this.loadBuiltInWorkflows();
        await this.loadBuiltInActions();
        await this.loadAgentPrimitives();
        if (this._errors.length > 0) {
          this._state = "error";
        } else {
          this._state = "ready";
        }
      } catch (error) {
        this._state = "error";
        throw error;
      }
    }
    async validate() {
      const errors = [];
      const warnings = [];
      const info = [];
      try {
        await fs9.access(this._path);
        const requiredFiles = ["agent.config.ts"];
        for (const file of requiredFiles) {
          try {
            await fs9.access(path10.join(this._path, file));
          } catch {
            errors.push(ValidationErrors.requiredFileMissing(file));
          }
        }
        try {
          await fs9.access(path10.join(this._path, "agent.json"));
        } catch {
          info.push({
            $type: "ValidationError",
            code: "MISSING_REQUIRED_FIELD",
            severity: "info",
            message: "agent.json not found - this file will be required for deployment and remote operations",
            file: "agent.json",
            hint: "Create agent.json with botId and workspaceId after deploying your agent"
          });
        }
        const expectedDirs = ["actions", "workflows", "conversations", "assets"];
        for (const dir of expectedDirs) {
          try {
            const stats = await fs9.stat(path10.join(this._path, dir));
            if (!stats.isDirectory()) {
              warnings.push(ValidationErrors.invalidStructure(dir, "directory"));
            }
          } catch {}
        }
      } catch (error) {
        errors.push(ValidationErrors.directoryAccessError(this._path, String(error)));
      }
      for (const violation of findTableColumnViolations(this._tables)) {
        errors.push(ValidationErrors.tableTooManyColumns(violation.name, violation.path, violation.columnCount, MAX_TABLE_COLUMNS));
      }
      const errorsBySeverity = {
        errors: errors.filter((e) => e.severity === "error"),
        warnings: [...warnings, ...errors.filter((e) => e.severity === "warning")],
        info: [...info, ...errors.filter((e) => e.severity === "info")]
      };
      return {
        valid: errorsBySeverity.errors.length === 0,
        errors: errorsBySeverity.errors,
        warnings: errorsBySeverity.warnings,
        info: errorsBySeverity.info,
        errorCount: errorsBySeverity.errors.length,
        warningCount: errorsBySeverity.warnings.length,
        infoCount: errorsBySeverity.info.length
      };
    }
    get integrations() {
      if (!this._integrations) {
        throw new AdkError({ code: "PROJECT_NOT_LOADED", expected: false, message: "Integrations not loaded" });
      }
      return this._integrations;
    }
    get interfaces() {
      if (!this._interfaces) {
        throw new AdkError({ code: "PROJECT_NOT_LOADED", expected: false, message: "Interfaces not loaded" });
      }
      return this._interfaces;
    }
    async getIntegrations() {
      if (!this._dependencies || !this._integrations) {
        throw new AdkError({ code: "PROJECT_NOT_LOADED", expected: false, message: "Project not loaded" });
      }
      return this._integrations.map((parsed) => ({
        name: parsed.alias,
        version: parsed.ref.version,
        workspace: parsed.ref.workspace,
        config: parsed.config,
        installed: false,
        installedVersion: undefined,
        hasChannels: parsed.definition?.channels && Object.keys(parsed.definition.channels).length > 0
      }));
    }
    async createAssetSyncPlan() {
      if (this._state !== "ready") {
        throw new AdkError({
          code: "PROJECT_NOT_READY",
          expected: false,
          message: "Project must be in Ready state to create asset sync plan"
        });
      }
      this.requiresAgentInfo("create asset sync plan");
      return await this._assetsManager.createSyncPlan();
    }
    async syncAssets(options) {
      if (this._state !== "ready") {
        throw new AdkError({
          code: "PROJECT_NOT_READY",
          expected: false,
          message: "Project must be in Ready state to sync assets"
        });
      }
      this.requiresAgentInfo("sync assets");
      const plan = await this._assetsManager.createSyncPlan();
      return await this._assetsManager.executeSync(plan, options);
    }
    async hasAssetsDirectory() {
      return await this._assetsManager.hasAssetsDirectory();
    }
    get assetsManager() {
      return this._assetsManager;
    }
    async createAgentInfo(info) {
      const agentJsonData = {
        botId: info.botId,
        workspaceId: info.workspaceId,
        apiUrl: info.apiUrl
      };
      const agentPath = path10.join(this._path, "agent.json");
      const agentContent = stringifyWithOrder(agentJsonData, agentInfoKeyOrder);
      await fs9.writeFile(agentPath, agentContent);
      this._agentInfo = agentJsonData;
    }
    async updateAgentInfo(updates) {
      if (!this._agentInfo) {
        throw new AdkError({
          code: "AGENT_INFO_MISSING",
          expected: false,
          message: "No agent.json found. Use createAgentInfo() first."
        });
      }
      const updatedInfo = {
        botId: updates.botId ?? this._agentInfo.botId,
        workspaceId: updates.workspaceId ?? this._agentInfo.workspaceId,
        apiUrl: "apiUrl" in updates ? updates.apiUrl : this._agentInfo.apiUrl,
        ...this._agentInfo.devId ? { devId: this._agentInfo.devId } : {}
      };
      const agentJsonData = {
        botId: updatedInfo.botId,
        workspaceId: updatedInfo.workspaceId,
        apiUrl: updatedInfo.apiUrl
      };
      const agentPath = path10.join(this._path, "agent.json");
      const agentContent = stringifyWithOrder(agentJsonData, agentInfoKeyOrder);
      await fs9.writeFile(agentPath, agentContent);
      this._agentInfo = updatedInfo;
    }
    async createAgentLocalInfo(info) {
      const localPath = path10.join(this._path, "agent.local.json");
      let existing = {};
      try {
        const content2 = await fs9.readFile(localPath, "utf-8");
        existing = JSON.parse(content2);
      } catch {}
      const merged = { ...existing, ...info };
      const content = stringifyWithOrder(merged, agentLocalInfoKeyOrder);
      await fs9.writeFile(localPath, content);
      if (this._agentInfo) {
        if (merged.botId)
          this._agentInfo.botId = merged.botId;
        if (merged.workspaceId)
          this._agentInfo.workspaceId = merged.workspaceId;
        if (merged.apiUrl)
          this._agentInfo.apiUrl = merged.apiUrl;
        if (merged.devId)
          this._agentInfo.devId = merged.devId;
      } else if (merged.botId && merged.workspaceId) {
        this._agentInfo = {
          botId: merged.botId,
          workspaceId: merged.workspaceId,
          apiUrl: merged.apiUrl,
          devId: merged.devId
        };
      }
    }
    async updateAgentLocalInfo(updates) {
      const localPath = path10.join(this._path, "agent.local.json");
      let existing = {};
      try {
        const content = await fs9.readFile(localPath, "utf-8");
        existing = JSON.parse(content);
      } catch {}
      const updated = { ...existing, ...updates };
      for (const key of Object.keys(updated)) {
        if (updated[key] === undefined) {
          delete updated[key];
        }
      }
      if (Object.keys(updated).length === 0) {
        try {
          await fs9.unlink(localPath);
        } catch {}
      } else {
        const content = stringifyWithOrder(updated, agentLocalInfoKeyOrder);
        await fs9.writeFile(localPath, content);
      }
      if (this._agentInfo) {
        const agentJsonPath = path10.join(this._path, "agent.json");
        let base = {
          botId: this._agentInfo.botId,
          workspaceId: this._agentInfo.workspaceId,
          apiUrl: this._agentInfo.apiUrl
        };
        try {
          const agentJsonContent = await fs9.readFile(agentJsonPath, "utf-8");
          const parsed = agentInfoSchema.parse(JSON.parse(agentJsonContent));
          base = {
            botId: parsed.botId,
            workspaceId: parsed.workspaceId,
            apiUrl: parsed.apiUrl
          };
        } catch {}
        const local = updated;
        this._agentInfo = {
          botId: local.botId ?? base.botId,
          workspaceId: local.workspaceId ?? base.workspaceId,
          apiUrl: local.apiUrl ?? base.apiUrl,
          devId: local.devId
        };
      }
    }
    requiresAgentInfo(operation) {
      if (!this._agentInfo?.botId) {
        throw new AdkError({
          code: "BOT_ID_REQUIRED",
          expected: true,
          message: `Operation "${operation}" requires a bot ID. Please create agent.json with botId and workspaceId after deploying your agent.`,
          suggestion: "Create agent.json with botId and workspaceId after deploying your agent."
        });
      }
    }
    async loadConfig() {
      this._dependencies = { integrations: {} };
      this._integrations = [];
      this._interfaces = [];
      try {
        const configPath = path10.join(this._path, "agent.config.ts");
        debug("loading agent.config.ts from %s", configPath);
        const projectRequire = createRequire2(path10.join(this._path, "package.json"));
        debug("created projectRequire from %s", path10.join(this._path, "package.json"));
        try {
          const resolvedPath = projectRequire.resolve(configPath);
          debug("resolved config path: %s", resolvedPath);
          if (projectRequire.cache[resolvedPath]) {
            debug("clearing require.cache for %s", resolvedPath);
            delete projectRequire.cache[resolvedPath];
          }
        } catch {
          debug("config not in require.cache (first load)");
        }
        let configModule;
        try {
          const configUrl = `${configPath}?t=${Date.now()}`;
          debug("importing from: %s", configUrl);
          configModule = await import(configUrl);
          debug("successfully loaded agent.config.ts");
        } catch (importError) {
          debug("failed to load agent.config.ts: %O", importError);
          throw importError;
        }
        if (!configModule || !configModule.default) {
          this._errors.push({
            $type: "ValidationError",
            code: "INVALID_CONFIG_SCHEMA",
            severity: "error",
            message: "agent.config.ts does not export a default configuration object",
            file: "agent.config.ts"
          });
          return;
        }
        const { isAgentConfig } = await import("./chunk-qk5pnkf4.js");
        if (!isAgentConfig(configModule.default)) {
          this._errors.push({
            $type: "ValidationError",
            code: "INVALID_CONFIG_SCHEMA",
            severity: "error",
            message: "agent.config.ts must export the result of defineConfig(). Example: export default defineConfig({ name: 'my-agent', ... })",
            file: "agent.config.ts",
            hint: "Wrap your config object with defineConfig() from @botpress/runtime"
          });
          return;
        }
        this._config = configModule.default;
        const dependencyEnv = this._options.adkCommand === "adk-deploy" ? "prod" : "dev";
        const snapshotStore = new DependencySnapshotStore({ projectPath: this._path });
        let snapshotBasedDependencies;
        let dependencySnapshotReadFailed = false;
        try {
          const snapshot = await snapshotStore.read(dependencyEnv);
          const state = snapshot ?? { version: 1, env: dependencyEnv, integrations: {}, plugins: {} };
          const hasDependencies = Object.keys(state.integrations).length > 0 || Object.keys(state.plugins).length > 0;
          if (hasDependencies) {
            snapshotBasedDependencies = dependencyStateToDependencies(state);
          }
        } catch (err) {
          this._warnings.push({
            $type: "ValidationError",
            code: "INVALID_DEPENDENCIES_SCHEMA",
            severity: "warning",
            message: `Could not read .adk/dependencies/${dependencyEnv}.json: ${err.message}. Refresh dependencies from Cloud; agent.config.ts dependencies is not used when a snapshot exists but is invalid.`,
            file: `.adk/dependencies/${dependencyEnv}.json`
          });
          dependencySnapshotReadFailed = true;
        }
        if (snapshotBasedDependencies) {
          this._dependencies = snapshotBasedDependencies;
          if (!this._options.offline) {
            const [intRes, ifRes] = await Promise.all([
              this._integrationManager.loadIntegrations(this._dependencies),
              this._interfaceManager.loadInterfaces(this._dependencies)
            ]);
            this._integrations = intRes.integrations;
            this._interfaces = ifRes.interfaces;
            this._errors.push(...intRes.errors, ...ifRes.errors);
            this._warnings.push(...intRes.warnings, ...ifRes.warnings);
          } else {
            this._integrations = [];
            this._interfaces = [];
          }
        } else {
          this._dependencies = { integrations: {} };
          this._integrations = [];
          this._interfaces = [];
        }
      } catch (error) {
        const err = error;
        debug("loadConfig error: %O", err);
        let detailedMessage = `Failed to load agent.config.ts: ${err.message}`;
        if (err.stack) {
          debug(`stack trace:
%s`, err.stack);
        }
        let hint;
        if (err.message.includes("Cannot find module")) {
          const moduleMatch = err.message.match(/Cannot find module '([^']+)'/);
          const moduleName = moduleMatch?.[1] || "unknown";
          hint = `Module "${moduleName}" is not installed. Run "bun install" to install dependencies.`;
          detailedMessage += `

  Stack trace:
${err.stack?.split(`
`).slice(0, 5).join(`
`)}`;
        }
        this._errors.push({
          $type: "ValidationError",
          code: "INVALID_CONFIG_SYNTAX",
          severity: "error",
          message: detailedMessage,
          file: "agent.config.ts",
          hint
        });
      }
    }
    async loadAgentInfo() {
      try {
        const agentInfo = await resolveAgent(this._path, { required: false });
        this._agentInfo = agentInfo ?? undefined;
      } catch (error) {
        if (ValidationErrors.isValidationError(error)) {
          this._errors.push(error);
        } else if (error instanceof Error) {
          this._errors.push(ValidationErrors.warning(`Failed to load agent.json: ${error.message}`, "agent.json"));
        }
        this._agentInfo = undefined;
      }
    }
    async loadBuiltInWorkflows() {
      for (const wf of Object.values(BuiltInWorkflows)) {
        const definition = Primitives.Definitions.getDefinition(wf);
        if (Primitives.Definitions.isWorkflowDefinition(definition)) {
          this._workflows.push({
            definition,
            export: "default",
            path: "<adk:builtin>"
          });
        }
      }
    }
    async loadBuiltInActions() {
      for (const action of Object.values(BuiltInActions)) {
        const definition = Primitives.Definitions.getDefinition(action);
        if (Primitives.Definitions.isActionDefinition(definition)) {
          this._actions.push({
            definition,
            export: "default",
            path: "<adk:builtin>"
          });
        }
      }
    }
    async registerDataSourceWorkflows(knowledgeBase, kbPath, kbExport) {
      try {
        if (!knowledgeBase.sources || !Array.isArray(knowledgeBase.sources)) {
          return;
        }
        for (const source of knowledgeBase.sources) {
          if (!source.syncWorkflow) {
            continue;
          }
          const workflowDefinition = source.syncWorkflow.getDefinition();
          const existing = this._workflows.find((p) => p.definition.name === workflowDefinition.name);
          if (existing) {
            continue;
          }
          this._workflows.push({
            definition: workflowDefinition,
            export: `${kbExport}.sources[${knowledgeBase.sources.indexOf(source)}].syncWorkflow`,
            path: kbPath
          });
        }
      } catch (error) {
        console.warn(`Failed to register data source workflows for ${kbPath}:`, error);
      }
    }
    isBarrelReexport(existing, newPath, newExport, newDefinition) {
      const isNewBarrel = /^index\.[tj]s$/i.test(path10.basename(newPath));
      const isExistingBarrel = /^index\.[tj]s$/i.test(path10.basename(existing.path));
      if (!isNewBarrel && !isExistingBarrel) {
        return false;
      }
      if (isExistingBarrel && !isNewBarrel) {
        existing.path = newPath;
        existing.export = newExport;
        existing.definition = newDefinition;
      }
      return true;
    }
    isToolBarrelReexport(existingPath, newPath) {
      const isNewBarrel = /^index\.[tj]s$/i.test(path10.basename(newPath));
      const isExistingBarrel = /^index\.[tj]s$/i.test(path10.basename(existingPath));
      if (!isNewBarrel && !isExistingBarrel) {
        return false;
      }
      return true;
    }
    shouldPreferToolDefinition(existingPath, newPath) {
      const isNewBarrel = /^index\.[tj]s$/i.test(path10.basename(newPath));
      const isExistingBarrel = /^index\.[tj]s$/i.test(path10.basename(existingPath));
      return isExistingBarrel && !isNewBarrel;
    }
    getChannelsList(channelSpec) {
      if (channelSpec === "*") {
        return ["*"];
      } else if (Array.isArray(channelSpec)) {
        return channelSpec;
      } else {
        return [channelSpec];
      }
    }
    async loadAgentPrimitives() {
      if (this._options.adkCommand) {
        setAdkCommand(this._options.adkCommand);
      }
      const src = path10.join(this._path, "src");
      if (!await fs9.stat(src).catch(() => false)) {
        this._errors.push({
          $type: "ValidationError",
          code: "INVALID_STRUCTURE",
          severity: "error",
          message: `\`src\` directory not found at expected path: ${src}`
        });
        return;
      }
      const allFiles = await fs9.readdir(src, {
        withFileTypes: true,
        recursive: true
      });
      for (const file of allFiles.filter((x) => x.isFile())) {
        const filename = file.name;
        const absolutePath = path10.join(file.parentPath, file.name);
        const relPath = path10.relative(this.path, absolutePath);
        if (filename.toLowerCase().endsWith(".d.ts")) {
          continue;
        }
        if (filename.toLowerCase().endsWith(".test.ts") || filename.toLowerCase().endsWith(".test.js")) {
          continue;
        }
        if (!filename.toLowerCase().endsWith(".js") && !filename.toLowerCase().endsWith(".ts")) {
          continue;
        }
        if (file.isSymbolicLink()) {
          this._errors.push({
            $type: "ValidationError",
            code: "INVALID_FILE_TYPE",
            severity: "warning",
            message: `Skipping symbolic link in conversations directory: ${relPath}`,
            file: relPath
          });
          continue;
        }
        try {
          const expandedExports = await expandExports({
            absolutePath,
            relPath,
            filename,
            onWarning: (warning) => this._warnings.push(warning)
          });
          let componentSources;
          for (const key of Object.keys(expandedExports)) {
            let definition;
            try {
              definition = Primitives.Definitions.getDefinition(expandedExports[key]);
            } catch (error) {
              if (Errors.isAdkError(error)) {
                this._warnings.push({
                  $type: "ValidationError",
                  code: "INVALID_PRIMITIVE_DEFINITION",
                  severity: "warning",
                  message: error.message,
                  file: relPath,
                  hint: `Check the primitive definition in ${filename} -> ${key}`
                });
                continue;
              }
              throw error;
            }
            if (Primitives.Definitions.isConversationDefinition(definition)) {
              const overlapping = this._conversations.find((p) => {
                const existingChannels = this.getChannelsList(p.definition.channel);
                const newChannels = this.getChannelsList(definition.channel);
                return existingChannels.some((ch) => newChannels.includes(ch));
              });
              if (overlapping) {
                if (this.isBarrelReexport(overlapping, relPath, key, definition)) {
                  continue;
                }
                this._warnings.push({
                  $type: "ValidationError",
                  code: "DUPLICATE_PRIMITIVE",
                  severity: "warning",
                  message: `Overlapping conversation channels found: ${filename} -> ${key} overlaps with ${overlapping.path} -> ${overlapping.export}`,
                  file: relPath
                });
                continue;
              }
              this._conversations.push({
                definition,
                export: key,
                path: relPath
              });
            } else if (Primitives.Definitions.isKnowledgeDefinition(definition)) {
              const existing = this._knowledge.find((p) => p.definition.name === definition.name);
              if (existing) {
                if (this.isBarrelReexport(existing, relPath, key, definition)) {
                  continue;
                }
                this._warnings.push({
                  $type: "ValidationError",
                  code: "DUPLICATE_PRIMITIVE",
                  severity: "warning",
                  message: `Duplicate knowledge definition found: ${filename} -> ${key} (already defined in ${existing.path} -> ${existing.export})`,
                  file: relPath
                });
                continue;
              }
              this._knowledge.push({
                definition,
                export: key,
                path: relPath
              });
              await this.registerDataSourceWorkflows(expandedExports[key], relPath, key);
            } else if (Primitives.Definitions.isTriggerDefinition(definition)) {
              const existing = this._triggers.find((p) => p.definition.name === definition.name);
              if (existing) {
                if (this.isBarrelReexport(existing, relPath, key, definition)) {
                  continue;
                }
                this._warnings.push({
                  $type: "ValidationError",
                  code: "DUPLICATE_PRIMITIVE",
                  severity: "warning",
                  message: `Duplicate trigger definition found: ${filename} -> ${key} (already defined in ${existing.path} -> ${existing.export})`,
                  file: relPath
                });
                continue;
              }
              this._triggers.push({
                definition,
                export: key,
                path: relPath
              });
            } else if (Primitives.Definitions.isWorkflowDefinition(definition)) {
              const existing = this._workflows.find((p) => p.definition.name === definition.name);
              if (existing) {
                if (this.isBarrelReexport(existing, relPath, key, definition)) {
                  continue;
                }
                this._warnings.push({
                  $type: "ValidationError",
                  code: "DUPLICATE_PRIMITIVE",
                  severity: "warning",
                  message: `Duplicate workflow definition found: ${filename} -> ${key} (already defined in ${existing.path} -> ${existing.export})`,
                  file: relPath
                });
                continue;
              }
              this._workflows.push({
                definition,
                export: key,
                path: relPath
              });
            } else if (Primitives.Definitions.isActionDefinition(definition)) {
              const existing = this._actions.find((p) => p.definition.name === definition.name);
              if (existing) {
                if (this.isBarrelReexport(existing, relPath, key, definition)) {
                  continue;
                }
                this._warnings.push({
                  $type: "ValidationError",
                  code: "DUPLICATE_PRIMITIVE",
                  severity: "warning",
                  message: `Duplicate action definition found: ${filename} -> ${key} (already defined in ${existing.path} -> ${existing.export})`,
                  file: relPath
                });
                continue;
              }
              this._actions.push({
                definition,
                export: key,
                path: relPath
              });
            } else if (Primitives.Definitions.isCustomComponentDefinition(definition)) {
              const posixRelPath = relPath.split(/[\\/]+/).join("/");
              if (!posixRelPath.startsWith(`${COMPONENTS_DIR}/`)) {
                this._warnings.push({
                  $type: "ValidationError",
                  code: "INVALID_PRIMITIVE_DEFINITION",
                  severity: "warning",
                  message: `Custom components must be defined under \`${COMPONENTS_DIR}/\`. Found "${definition.name}" in ${relPath}.`,
                  file: relPath
                });
                continue;
              }
              if (componentSources === undefined) {
                try {
                  componentSources = resolveComponentSources(absolutePath);
                } catch (error) {
                  componentSources = new Map;
                  this._warnings.push({
                    $type: "ValidationError",
                    code: "INVALID_PRIMITIVE_DEFINITION",
                    severity: "warning",
                    message: `Failed to parse component sources from ${relPath}: ${error instanceof Error ? error.message : String(error)}`,
                    file: relPath
                  });
                }
              }
              const source = componentSources.get(key);
              const existing = this._customComponents.find((p) => p.definition.name === definition.name);
              if (existing) {
                if (this.isBarrelReexport(existing, relPath, key, definition)) {
                  if (existing.path === relPath && source) {
                    existing.source = source;
                  }
                  existing.instance = expandedExports[key];
                  continue;
                }
                this._warnings.push({
                  $type: "ValidationError",
                  code: "DUPLICATE_PRIMITIVE",
                  severity: "warning",
                  message: `Duplicate custom component definition found: ${filename} -> ${key} (already defined in ${existing.path} -> ${existing.export})`,
                  file: relPath
                });
                continue;
              }
              this._customComponents.push({
                definition,
                export: key,
                path: relPath,
                source: source ?? "",
                instance: expandedExports[key]
              });
            } else if (Primitives.Definitions.isTableDefinition(definition)) {
              const existing = this._tables.find((p) => p.definition.name === definition.name);
              if (existing) {
                if (this.isBarrelReexport(existing, relPath, key, definition)) {
                  continue;
                }
                this._warnings.push({
                  $type: "ValidationError",
                  code: "DUPLICATE_PRIMITIVE",
                  severity: "warning",
                  message: `Duplicate table definition found: ${filename} -> ${key} (already defined in ${existing.path} -> ${existing.export})`,
                  file: relPath
                });
                continue;
              }
              this._tables.push({
                definition,
                export: key,
                path: relPath
              });
            } else {
              const toolDefinition = getToolDefinition(expandedExports[key]);
              if (!toolDefinition) {
                continue;
              }
              const existing = this._tools.find((tool) => tool.definition.name === toolDefinition.name);
              if (existing) {
                if (this.isToolBarrelReexport(existing.path, relPath)) {
                  if (this.shouldPreferToolDefinition(existing.path, relPath)) {
                    existing.path = relPath;
                    existing.export = key;
                    existing.definition = toolDefinition;
                  }
                  continue;
                }
                this._warnings.push({
                  $type: "ValidationError",
                  code: "DUPLICATE_PRIMITIVE",
                  severity: "warning",
                  message: `Duplicate tool definition found: ${filename} -> ${key} (already defined in ${existing.path} -> ${existing.export})`,
                  file: relPath
                });
                continue;
              }
              this._tools.push({
                definition: toolDefinition,
                export: key,
                path: relPath
              });
            }
          }
        } catch (error) {
          if (Errors.isAdkError(error)) {
            continue;
          }
          this._warnings.push({
            $type: "ValidationError",
            code: "IMPORT_ERROR",
            severity: "warning",
            message: `Failed to import primitive from ${relPath}: ${error instanceof Error ? error.message : String(error)}`,
            file: relPath,
            hint: "Ensure the file exports valid primitives and has no syntax errors"
          });
        }
      }
      const unresolved = this._customComponents.filter((c) => !c.source);
      if (unresolved.length > 0) {
        this._customComponents = this._customComponents.filter((c) => c.source);
        for (const comp of unresolved) {
          this._errors.push({
            $type: "ValidationError",
            code: "INVALID_PRIMITIVE_DEFINITION",
            severity: "error",
            message: `Cannot resolve .bp.tsx source for custom component "${comp.definition.name}" exported from ${comp.path} as "${comp.export}".`,
            file: comp.path,
            hint: "Each CustomComponent must be constructed from a default-imported .bp.tsx component, e.g. `import Foo from './Foo.bp.tsx'; export const FooComponent = new CustomComponent(Foo, ...)`."
          });
        }
      }
    }
  };
});
async function getFormat() {
  if (!_formatLoaded) {
    _formatLoaded = true;
    try {
      const oxfmt = await import("oxfmt");
      _format = oxfmt.format;
    } catch {}
  }
  return _format;
}
var _format = null;
var _formatLoaded = false;
var formatCode = async (code, filepath) => {
  try {
    if (!code || code.length > 1e6) {
      return code;
    }
    const format = await getFormat();
    if (!format)
      return code;
    const fileName = filepath || "file.ts";
    const result = await format(fileName, code);
    return result.code;
  } catch (err) {
    console.warn("Failed to format code with oxfmt:", err);
    console.warn(code.slice(0, 1000).split(`
`).map((l, i) => `	${i.toString().padStart(2, "0")} | ${l}`).join(`
`));
    return code;
  }
};
var init_utils = () => {};
var exports_dependencies = {};
__export(exports_dependencies, {
  sortKeysDeep: () => sortKeysDeep,
  resolveDependencyStatuses: () => resolveDependencyStatuses,
  migrateFromConfig: () => migrateFromConfig,
  jsonEqual: () => jsonEqual,
  isCallable: () => isCallable,
  emptyDependencySnapshot: () => emptyDependencySnapshot,
  dependencyStateSchema: () => dependencyStateSchema,
  dependencySnapshotFromBot: () => dependencySnapshotFromBot,
  computePluginStatus: () => computePluginStatus,
  computeIntegrationStatus: () => computeIntegrationStatus,
  PluginResolver: () => PluginResolver,
  PluginRegistry: () => PluginRegistry,
  InterfaceRegistry: () => InterfaceRegistry,
  IntegrationResolver: () => IntegrationResolver,
  IntegrationRegistry: () => IntegrationRegistry,
  DependencySnapshotStore: () => DependencySnapshotStore,
  DependencyMigrationManager: () => DependencyMigrationManager,
  DependencyManager: () => DependencyManager,
  DependencyError: () => DependencyError,
  DEPENDENCY_WARNING_CODES: () => DEPENDENCY_WARNING_CODES,
  DEPENDENCY_ERROR_CODES: () => DEPENDENCY_ERROR_CODES
});
init_types();
init_errors2();
init_errors2();

class IntegrationResolver {
  registry;
  client;
  constructor(opts) {
    this.registry = opts.registry;
    this.client = opts.client;
  }
  toDependencyEntry(cloud) {
    const entry = {
      name: cloud.name ?? "",
      version: cloud.version ?? "0.0.0",
      enabled: Boolean(cloud.enabled),
      config: cloud.configuration ?? {}
    };
    if (typeof cloud.configurationType === "string" && cloud.configurationType && cloud.configurationType !== "default") {
      entry.configurationType = cloud.configurationType;
    }
    return entry;
  }
  async applyToCloud(opts) {
    const spec = await this.registry.getSpec(opts.entry.name, opts.entry.version);
    const integrationId = spec.id;
    if (!integrationId) {
      throw new DependencyError({
        code: "INTEGRATION_NOT_FOUND",
        message: `Could not resolve integrationId for ${opts.entry.name}@${opts.entry.version}`
      });
    }
    await this.client.updateBot({
      id: opts.botId,
      integrations: {
        [opts.alias]: {
          integrationId,
          enabled: opts.entry.enabled,
          configuration: opts.entry.config
        }
      }
    });
  }
  async removeFromCloud(opts) {
    await this.client.updateBot({
      id: opts.botId,
      integrations: { [opts.alias]: null }
    });
  }
}
init_errors2();

class PluginResolver {
  registry;
  integrationRegistry;
  client;
  constructor(opts) {
    this.registry = opts.registry;
    this.integrationRegistry = opts.integrationRegistry;
    this.client = opts.client;
  }
  toDependencyEntry(cloud) {
    const dependencies = {};
    for (const [ifaceAlias, dep] of Object.entries(cloud.interfaces ?? {})) {
      if (dep.integrationAlias) {
        dependencies[ifaceAlias] = { integrationAlias: dep.integrationAlias };
      }
    }
    return {
      name: cloud.name ?? "",
      version: cloud.version ?? "0.0.0",
      enabled: cloud.enabled ?? true,
      config: cloud.configuration ?? {},
      dependencies
    };
  }
  async applyToCloud(opts) {
    const pluginSpec = await this.registry.getSpec(opts.entry.name, opts.entry.version);
    const requiredInterfaces = pluginSpec.dependencies?.interfaces ?? {};
    const resolvedInterfaces = {};
    for (const [pluginIfaceAlias, requirement] of Object.entries(requiredInterfaces)) {
      const dep = opts.entry.dependencies[pluginIfaceAlias];
      if (!dep) {
        throw new DependencyError({
          code: "MISSING_DEPENDENCY",
          message: `Plugin '${opts.alias}' is missing dependency '${pluginIfaceAlias}' (needs an integration implementing '${requirement.name}')`,
          details: { plugin: opts.alias, pluginInterfaceAlias: pluginIfaceAlias, interfaceName: requirement.name }
        });
      }
      const integration = opts.state.integrations[dep.integrationAlias];
      if (!integration) {
        throw new DependencyError({
          code: "MISSING_DEPENDENCY",
          message: `Plugin '${opts.alias}' references integration alias '${dep.integrationAlias}' which is not installed`,
          details: { plugin: opts.alias, integrationAlias: dep.integrationAlias },
          suggestion: `Run: adk integrations add ${dep.integrationAlias}`
        });
      }
      const integrationSpec = await this.integrationRegistry.getSpec(integration.name, integration.version);
      const integrationIfaceAlias = Object.entries(integrationSpec.interfaces ?? {}).find(([, def]) => def.name === requirement.name)?.[0];
      if (!integrationIfaceAlias) {
        throw new DependencyError({
          code: "INTERFACE_NOT_IMPLEMENTED",
          message: `Integration '${integration.name}' does not implement interface '${requirement.name}' required by plugin '${opts.alias}'`,
          details: { integration: integration.name, interfaceName: requirement.name }
        });
      }
      resolvedInterfaces[pluginIfaceAlias] = {
        integrationId: integrationSpec.id,
        integrationAlias: dep.integrationAlias,
        integrationInterfaceAlias: integrationIfaceAlias
      };
    }
    const pluginId = pluginSpec.id;
    if (!pluginId) {
      throw new DependencyError({
        code: "PLUGIN_NOT_FOUND",
        message: `Could not resolve plugin id for ${opts.entry.name}@${opts.entry.version}`
      });
    }
    await this.client.updateBot({
      id: opts.botId,
      plugins: {
        [opts.alias]: {
          id: pluginId,
          enabled: opts.entry.enabled,
          configuration: opts.entry.config,
          interfaces: resolvedInterfaces
        }
      }
    });
  }
  async removeFromCloud(opts) {
    await this.client.updateBot({ id: opts.botId, plugins: { [opts.alias]: null } });
  }
}
init_manager();

class IntegrationRegistry {
  manager;
  constructor(opts = {}) {
    this.manager = opts.manager ?? new IntegrationManager(opts.managerOptions);
  }
  async getSpec(name, version) {
    const ref = {
      name,
      version: version ?? "latest",
      fullName: name
    };
    return this.manager.fetchIntegration(ref);
  }
  async search(_query) {
    return this.manager.searchIntegrations(_query);
  }
  async findImplementersOfInterface(interfaceName, limit) {
    return this.manager.findImplementersOfInterface(interfaceName, limit);
  }
  async listVersions(name) {
    return this.manager.listIntegrationVersions(name);
  }
}
init_dependencies_parser();
init_validation_errors();
init_client_factory();
init_catalog_service();
init_src();
init_search_ranking();

class PluginCatalogSource {
  clientFactory;
  cacheConfig = { cacheType: "plugins", idField: "pluginId" };
  constructor(clientFactory) {
    this.clientFactory = clientFactory;
  }
  async fetchByRef(ref) {
    const client = await this.clientFactory.getClient();
    const plugin = await this._findPublicPlugin(client, ref);
    if (!plugin) {
      throw new AdkError({
        code: "PLUGIN_NOT_FOUND",
        expected: true,
        message: await this._buildPluginNotFoundMessage(client, ref)
      });
    }
    return { id: plugin.id, updatedAt: plugin.updatedAt, definition: plugin };
  }
  async search(query, limit = 20) {
    const client = await this.clientFactory.getClient();
    const results = new Map;
    for await (const plugin of client.list.publicPlugins({})) {
      collectCatalogSearchResult(results, plugin, query);
    }
    return getSortedCatalogSearchResults(results, limit);
  }
  async listVersions(name) {
    const client = await this.clientFactory.getClient();
    const versions = new Set;
    for await (const plugin of client.list.publicPlugins({ name })) {
      versions.add(plugin.version);
    }
    return getSortedVersions(versions);
  }
  async _buildPluginNotFoundMessage(client, ref) {
    if (ref.version !== "latest") {
      const latest = await this._findPublicPlugin(client, { ...ref, version: "latest" });
      if (latest) {
        return `Plugin "${ref.name}" version "${ref.version}" not found on the Botpress Hub (latest is ${latest.version}).`;
      }
    }
    return `Plugin "${ref.name}" not found on the Botpress Hub`;
  }
  async _findPublicPlugin(client, ref) {
    try {
      const response = await client.getPublicPlugin({
        name: ref.name,
        version: ref.version
      });
      return response.plugin;
    } catch (error) {
      if (this._isResourceNotFoundError(error)) {
        return;
      }
      throw error;
    }
  }
  _isResourceNotFoundError(error) {
    if (error && typeof error === "object" && "type" in error) {
      return error.type === "ResourceNotFound";
    }
    return false;
  }
}

class PluginManager {
  source;
  service;
  constructor(options = {}) {
    const { noCache, ...clientOptions } = options;
    this.source = new PluginCatalogSource(new CatalogClientFactory(clientOptions));
    this.service = new CatalogService(this.source, noCache || false);
  }
  async loadPlugins(dependencies) {
    const errors = [];
    const warnings = [];
    const parseResult = PluginParser.parsePlugins(dependencies);
    const plugins = parseResult.plugins;
    errors.push(...parseResult.errors);
    const duplicateWarnings = PluginParser.checkDuplicates(plugins);
    warnings.push(...duplicateWarnings);
    const fetchPromises = plugins.map(async (plugin) => {
      try {
        plugin.definition = await this.fetchPlugin(plugin.ref);
      } catch {
        errors.push(ValidationErrors.unknownPlugin(plugin.alias, plugin.ref.fullName));
      }
    });
    await Promise.all(fetchPromises);
    return { plugins, errors, warnings };
  }
  async fetchPlugin(ref) {
    return this.service.getDefinition(ref);
  }
  async searchPlugins(query, limit = 20) {
    return this.source.search(query, limit);
  }
  async listPluginVersions(name) {
    return this.source.listVersions(name);
  }
  async getCacheStats() {
    return this.service.getCacheStats();
  }
  async clearCache() {
    await this.service.clearCache();
  }
}

class PluginRegistry {
  manager;
  constructor(opts = {}) {
    this.manager = opts.manager ?? new PluginManager(opts.managerOptions);
  }
  async getSpec(name, version) {
    const ref = {
      name,
      version: version ?? "latest",
      fullName: name
    };
    return this.manager.fetchPlugin(ref);
  }
  async search(_query) {
    return this.manager.searchPlugins(_query);
  }
  async listVersions(name) {
    return this.manager.listPluginVersions(name);
  }
}
init_agent_project();
init_snapshot_store();

class DependencyManager {
  snapshotStore;
  env;
  client;
  projectPath;
  botId;
  integrationRegistry;
  pluginRegistry;
  integrationResolver;
  pluginResolver;
  constructor(opts) {
    this.projectPath = opts.projectPath;
    this.env = opts.env;
    this.client = opts.client;
    this.botId = opts.botId;
    this.snapshotStore = new DependencySnapshotStore({ projectPath: opts.projectPath });
    this.integrationRegistry = opts.integrationRegistry ?? new IntegrationRegistry;
    this.pluginRegistry = opts.pluginRegistry ?? new PluginRegistry;
    this.integrationResolver = opts.integrationResolver ?? new IntegrationResolver({ registry: this.integrationRegistry, client: this.client });
    this.pluginResolver = opts.pluginResolver ?? new PluginResolver({
      registry: this.pluginRegistry,
      integrationRegistry: this.integrationRegistry,
      client: this.client
    });
  }
  static async fromProject(opts) {
    const project = await AgentProject.load(opts.projectPath);
    const botId = opts.botId ?? DependencyManager.getProjectBotId(project, opts.env);
    if (!botId) {
      throw new DependencyError({
        code: "BOT_NOT_FOUND",
        message: `No ${opts.env} bot ID found in ${opts.projectPath}. Run 'adk link' to link the project to a bot.`
      });
    }
    return new DependencyManager({
      projectPath: project.path,
      env: opts.env,
      client: opts.client,
      botId,
      integrationRegistry: opts.integrationRegistry,
      pluginRegistry: opts.pluginRegistry,
      integrationResolver: opts.integrationResolver,
      pluginResolver: opts.pluginResolver
    });
  }
  static getProjectBotId(project, env) {
    const info = project.agentInfo;
    if (!info)
      return;
    return env === "dev" ? info.devId ?? info.botId : info.botId;
  }
  async getProjectBotId(env) {
    const project = await AgentProject.load(this.projectPath);
    const botId = DependencyManager.getProjectBotId(project, env);
    if (!botId) {
      throw new DependencyError({
        code: "BOT_NOT_FOUND",
        message: `No ${env} bot ID found in ${this.projectPath}. Run 'adk link' to link the project to a bot.`
      });
    }
    return botId;
  }
  async readSnapshot(options) {
    return this.snapshotStore.readOrEmpty(this.env, {
      tolerant: options?.tolerant,
      botId: this.botId
    });
  }
  async writeSnapshot(snapshot) {
    await this.snapshotStore.write({
      ...snapshot,
      botId: snapshot.botId || this.botId,
      fetchedAt: new Date().toISOString()
    });
  }
  async readCloudSnapshot(previous) {
    const { bot } = await this.client.getBot({ id: this.botId });
    return dependencySnapshotFromBot({
      bot,
      botId: this.botId,
      env: this.env,
      fetchedAt: new Date,
      previous
    });
  }
  async snapshotStateFromCloud() {
    const previous = await this.readSnapshot({ tolerant: true });
    const cloud = await this.readCloudSnapshot(previous);
    return dependencySnapshotToState(cloud);
  }
  async applyState(state, opts) {
    const parsed = dependencyStateSchema.parse({
      ...state,
      env: this.env
    });
    await this.writeSnapshot({
      version: 1,
      env: this.env,
      botId: this.botId,
      fetchedAt: new Date().toISOString(),
      integrations: parsed.integrations,
      plugins: parsed.plugins
    });
    const result = await this.apply(opts);
    if (!result.dryRun && result.applied.length === 0 && result.skipped.length === 0 && result.errors.length === 0) {
      await this.refreshSnapshotFromCloud();
    }
    return result;
  }
  async list(type) {
    const data = await this.readSnapshot({ tolerant: true });
    const out = [];
    if (!type || type === "integration") {
      for (const [alias, e] of Object.entries(data.integrations)) {
        out.push({ type: "integration", alias, name: e.name, version: e.version, enabled: e.enabled });
      }
    }
    if (!type || type === "plugin") {
      for (const [alias, e] of Object.entries(data.plugins)) {
        out.push({ type: "plugin", alias, name: e.name, version: e.version, enabled: e.enabled });
      }
    }
    return out;
  }
  async get(type, alias) {
    const all = await this.list(type);
    return all.find((e) => e.alias === alias);
  }
  async waitForIntegrationWebhook(name, opts) {
    const deadline = Date.now() + opts.timeoutMs;
    for (;; ) {
      try {
        const { bot } = await this.client.getBot({ id: this.botId });
        const integrations = Object.values(bot.integrations ?? {});
        if (integrations.some((i) => i?.name === name && !!i?.webhookId)) {
          return true;
        }
      } catch {}
      if (Date.now() >= deadline) {
        return false;
      }
      await new Promise((resolve2) => setTimeout(resolve2, opts.intervalMs));
    }
  }
  async add(type, spec) {
    if (type === "interface") {
      throw new DependencyError({
        code: "BUILTIN_INTERFACE_IMMUTABLE",
        message: "Interfaces are built-in platform constants and cannot be added."
      });
    }
    const alias = spec.alias ?? spec.name;
    const version = spec.version ?? "latest";
    const snapshot = await this.readSnapshot();
    if (type === "integration" && snapshot.integrations[alias]) {
      const existing = snapshot.integrations[alias];
      const versionMatch = version === "latest" || existing.version === version;
      if (existing.enabled && versionMatch && jsonEqual(existing.config, spec.config ?? {})) {
        return {
          ok: true,
          noop: true,
          resource: { type, alias, name: spec.name, version: existing.version }
        };
      }
    }
    if (type === "plugin" && snapshot.plugins[alias]) {
      const existing = snapshot.plugins[alias];
      const versionMatch = version === "latest" || existing.version === version;
      if (existing.enabled && versionMatch && jsonEqual(existing.config, spec.config ?? {})) {
        return {
          ok: true,
          noop: true,
          resource: { type, alias, name: spec.name, version: existing.version }
        };
      }
    }
    if (type === "integration") {
      const desired = {
        name: spec.name,
        version,
        enabled: true,
        config: spec.config ?? {}
      };
      let installedDisabled;
      let authorizationPending = false;
      try {
        await this.integrationResolver.applyToCloud({ botId: this.botId, alias, entry: desired });
      } catch (err) {
        const missingFields = extractMissingRequiredFields(err);
        if (missingFields) {
          await this.integrationResolver.applyToCloud({
            botId: this.botId,
            alias,
            entry: { ...desired, enabled: false }
          });
          installedDisabled = { missingFields };
        } else if (await this.specRequiresAuthorization(spec.name, spec.version)) {
          await this.integrationResolver.applyToCloud({
            botId: this.botId,
            alias,
            entry: { ...desired, enabled: false }
          });
          authorizationPending = true;
        } else {
          throw err;
        }
      }
      const refreshed = await this.refreshSnapshotFromCloud();
      if (installedDisabled || authorizationPending) {
        const snapshotAlias = refreshed.integrations[alias] ? alias : Object.keys(refreshed.integrations).find((k) => !snapshot.integrations[k] && !refreshed.integrations[k].enabled && refreshed.integrations[k].name === spec.name);
        if (snapshotAlias && refreshed.integrations[snapshotAlias]) {
          refreshed.integrations[snapshotAlias] = {
            ...refreshed.integrations[snapshotAlias],
            ...installedDisabled ? { missingFields: installedDisabled.missingFields } : {},
            ...authorizationPending ? { authorizationPending: true } : {}
          };
          await this.writeSnapshot(refreshed);
        }
      }
      const resolvedVersion = refreshed.integrations[alias]?.version ?? version;
      return {
        ok: true,
        resource: { type, alias, name: spec.name, version: resolvedVersion },
        installedDisabled,
        ...authorizationPending ? { installedAwaitingAuthorization: true } : {}
      };
    } else {
      const { dependencies: resolvedDeps, autoResolved } = await this.resolvePluginDependencies({
        pluginName: spec.name,
        pluginVersion: version,
        userDeps: spec.dependencies ?? {},
        state: snapshot
      });
      const desired = {
        name: spec.name,
        version,
        enabled: true,
        config: spec.config ?? {},
        dependencies: resolvedDeps
      };
      let installedDisabled;
      try {
        await this.pluginResolver.applyToCloud({ botId: this.botId, alias, entry: desired, state: snapshot });
      } catch (err) {
        const missingFields = extractMissingRequiredFields(err);
        if (!missingFields)
          throw err;
        await this.pluginResolver.applyToCloud({
          botId: this.botId,
          alias,
          entry: { ...desired, enabled: false },
          state: snapshot
        });
        installedDisabled = { missingFields };
      }
      const refreshed = await this.refreshSnapshotFromCloud();
      if (installedDisabled) {
        const snapshotAlias = refreshed.plugins[alias] ? alias : Object.keys(refreshed.plugins).find((k) => !snapshot.plugins[k] && !refreshed.plugins[k].enabled && refreshed.plugins[k].name === spec.name);
        if (snapshotAlias && refreshed.plugins[snapshotAlias]) {
          refreshed.plugins[snapshotAlias] = {
            ...refreshed.plugins[snapshotAlias],
            missingFields: installedDisabled.missingFields
          };
          await this.writeSnapshot(refreshed);
        }
      }
      const resolvedVersion = refreshed.plugins[alias]?.version ?? version;
      return {
        ok: true,
        resource: { type, alias, name: spec.name, version: resolvedVersion },
        autoResolved,
        installedDisabled
      };
    }
  }
  async remove(type, alias) {
    if (type === "interface") {
      throw new DependencyError({ code: "BUILTIN_INTERFACE_IMMUTABLE", message: "Interfaces cannot be removed." });
    }
    const snapshot = await this.readSnapshot();
    const exists = type === "integration" ? !!snapshot.integrations[alias] : !!snapshot.plugins[alias];
    if (!exists)
      return { ok: true, noop: true };
    if (type === "integration") {
      await this.integrationResolver.removeFromCloud({ botId: this.botId, alias });
    } else {
      await this.pluginResolver.removeFromCloud({ botId: this.botId, alias });
    }
    await this.refreshSnapshotFromCloud();
    return { ok: true };
  }
  async upgrade(type, alias, version) {
    if (type === "interface") {
      throw new DependencyError({ code: "BUILTIN_INTERFACE_IMMUTABLE", message: "Interfaces cannot be upgraded." });
    }
    const snapshot = await this.readSnapshot();
    const existing = type === "integration" ? snapshot.integrations[alias] : snapshot.plugins[alias];
    if (!existing) {
      throw new DependencyError({
        code: type === "integration" ? "INTEGRATION_NOT_FOUND" : "PLUGIN_NOT_FOUND",
        message: `'${alias}' is not installed in ${this.env}`
      });
    }
    const targetVersion = version ?? "latest";
    if (existing.version === targetVersion) {
      return { ok: true, noop: true, resource: { type, alias, name: existing.name, version: existing.version } };
    }
    const next = { ...existing, version: targetVersion };
    await this.applyEntry(type, alias, next, snapshot);
    await this.refreshSnapshotFromCloud();
    return { ok: true, resource: { type, alias, name: existing.name, version: next.version } };
  }
  async enable(type, alias) {
    return this.toggleEnabled(type, alias, true);
  }
  async disable(type, alias) {
    return this.toggleEnabled(type, alias, false);
  }
  async toggleEnabled(type, alias, enabled) {
    if (type === "interface") {
      throw new DependencyError({
        code: "BUILTIN_INTERFACE_IMMUTABLE",
        message: "Interfaces cannot be enabled/disabled."
      });
    }
    const snapshot = await this.readSnapshot();
    const existing = type === "integration" ? snapshot.integrations[alias] : snapshot.plugins[alias];
    if (!existing) {
      throw new DependencyError({
        code: type === "integration" ? "INTEGRATION_NOT_FOUND" : "PLUGIN_NOT_FOUND",
        message: `'${alias}' is not installed in ${this.env}`
      });
    }
    if (existing.enabled === enabled)
      return { ok: true, noop: true };
    await this.applyEntry(type, alias, { ...existing, enabled }, snapshot);
    const refreshedSnapshot = await this.refreshSnapshotFromCloud();
    const refreshedEntry = type === "integration" ? refreshedSnapshot.integrations[alias] : refreshedSnapshot.plugins[alias];
    if (!refreshedEntry || refreshedEntry.enabled !== enabled) {
      throw new DependencyError({
        code: "SNAPSHOT_DRIFT",
        message: `Cloud did not persist ${type} '${alias}' as ${enabled ? "enabled" : "disabled"}.`,
        details: {
          type,
          alias,
          expected: { enabled },
          actual: refreshedEntry ? { enabled: refreshedEntry.enabled } : null
        }
      });
    }
    return { ok: true, resource: { type, alias, name: existing.name, version: existing.version } };
  }
  async configure(type, alias, patch) {
    if (type === "interface") {
      throw new DependencyError({ code: "BUILTIN_INTERFACE_IMMUTABLE", message: "Interfaces cannot be configured." });
    }
    const snapshot = await this.readSnapshot();
    const existing = type === "integration" ? snapshot.integrations[alias] : snapshot.plugins[alias];
    if (!existing) {
      throw new DependencyError({
        code: type === "integration" ? "INTEGRATION_NOT_FOUND" : "PLUGIN_NOT_FOUND",
        message: `'${alias}' is not installed in ${this.env}`
      });
    }
    const nextConfig = { ...existing.config, ...patch.set ?? {} };
    for (const key of patch.unset ?? [])
      delete nextConfig[key];
    const next = { ...existing, config: nextConfig };
    if (type === "plugin" && patch.map && "dependencies" in next) {
      next.dependencies = { ...next.dependencies, ...patch.map };
    }
    if (jsonEqual(next, existing)) {
      return { ok: true, noop: true, resource: { type, alias, name: existing.name, version: existing.version } };
    }
    await this.applyEntry(type, alias, next, snapshot);
    await this.refreshSnapshotFromCloud();
    return { ok: true, resource: { type, alias, name: existing.name, version: existing.version } };
  }
  async applyEntry(type, alias, entry, state) {
    if (type === "integration") {
      await this.integrationResolver.applyToCloud({
        botId: this.botId,
        alias,
        entry
      });
    } else {
      await this.pluginResolver.applyToCloud({
        botId: this.botId,
        alias,
        entry,
        state
      });
    }
  }
  async resolvePluginDependencies(opts) {
    const pluginSpec = await this.pluginRegistry.getSpec(opts.pluginName, opts.pluginVersion);
    const requiredInterfaces = pluginSpec.dependencies?.interfaces ?? {};
    const resolved = { ...opts.userDeps };
    const autoResolved = [];
    for (const [pluginIfaceAlias, requirement] of Object.entries(requiredInterfaces)) {
      if (resolved[pluginIfaceAlias]) {
        continue;
      }
      const candidates = [];
      for (const [integrationAlias, integrationEntry] of Object.entries(opts.state.integrations)) {
        let integrationSpec;
        try {
          integrationSpec = await this.integrationRegistry.getSpec(integrationEntry.name, integrationEntry.version);
        } catch {
          continue;
        }
        const implements_ = Object.values(integrationSpec.interfaces ?? {}).some((iface) => iface.name === requirement.name);
        if (implements_) {
          candidates.push({ alias: integrationAlias, integrationName: integrationEntry.name });
        }
      }
      if (candidates.length === 1) {
        const match = candidates[0];
        resolved[pluginIfaceAlias] = { integrationAlias: match.alias };
        autoResolved.push({ pluginInterfaceAlias: pluginIfaceAlias, integrationAlias: match.alias });
      } else if (candidates.length > 1) {
        throw new DependencyError({
          code: "AMBIGUOUS_DEPENDENCY",
          message: `Multiple installed integrations implement interface '${requirement.name}' required by plugin '${opts.pluginName}': ${candidates.map((c) => c.alias).join(", ")}. Pass --dep ${pluginIfaceAlias}=<alias> to disambiguate.`,
          details: {
            plugin: opts.pluginName,
            pluginInterfaceAlias: pluginIfaceAlias,
            interfaceName: requirement.name,
            candidates: candidates.map((c) => ({ alias: c.alias, name: c.integrationName }))
          },
          suggestion: `Pass --dep ${pluginIfaceAlias}=<alias> where <alias> is one of: ${candidates.map((c) => c.alias).join(", ")}`
        });
      } else {
        const implementers = await this.findHubImplementersSafely(requirement.name);
        const suggestion = formatMissingDependencySuggestion({
          interfaceName: requirement.name,
          pluginInterfaceAlias: pluginIfaceAlias,
          implementers
        });
        throw new DependencyError({
          code: "MISSING_DEPENDENCY",
          message: `Plugin '${opts.pluginName}' requires interface '${requirement.name}', but no installed integration implements it.
` + suggestion,
          details: {
            plugin: opts.pluginName,
            pluginInterfaceAlias: pluginIfaceAlias,
            interfaceName: requirement.name,
            implementers: implementers.map((i) => ({ name: i.name, version: i.version, title: i.title }))
          },
          suggestion
        });
      }
    }
    return { dependencies: resolved, autoResolved };
  }
  async findHubImplementersSafely(interfaceName) {
    try {
      const results = await this.integrationRegistry.findImplementersOfInterface(interfaceName, 5);
      return results;
    } catch {
      return [];
    }
  }
  async specRequiresAuthorization(name, version) {
    try {
      const spec = await this.integrationRegistry.getSpec(name, version);
      return integrationRequiresAuthorization(spec);
    } catch {
      return false;
    }
  }
  async refreshSnapshotFromCloud() {
    return this.snapshotStore.refreshFromCloud({
      client: this.client,
      botId: this.botId,
      env: this.env,
      integrationRegistry: this.integrationRegistry
    });
  }
  integrationEntriesMatch(a, b) {
    return jsonEqual(stripSnapshotMetadata(a), stripSnapshotMetadata(b));
  }
  pluginEntriesMatch(a, b) {
    return jsonEqual(stripSnapshotMetadata(a), stripSnapshotMetadata(b));
  }
  async diff() {
    const snapshot = await this.readSnapshot();
    const cloud = await this.readCloudSnapshot(snapshot);
    const delta = { addedInSnapshot: [], removedInSnapshot: [], changedInSnapshot: [] };
    for (const [alias, entry] of Object.entries(snapshot.integrations)) {
      const cloudEntry = cloud.integrations[alias];
      if (!cloudEntry) {
        delta.addedInSnapshot.push({ type: "integration", alias, name: entry.name, version: entry.version });
      } else if (!this.integrationEntriesMatch(entry, cloudEntry)) {
        delta.changedInSnapshot.push({ type: "integration", alias, field: "unspecified" });
      }
    }
    for (const [alias, entry] of Object.entries(cloud.integrations)) {
      if (!snapshot.integrations[alias]) {
        delta.removedInSnapshot.push({ type: "integration", alias, name: entry.name, version: entry.version });
      }
    }
    for (const [alias, entry] of Object.entries(snapshot.plugins)) {
      const cloudEntry = cloud.plugins[alias];
      if (!cloudEntry) {
        delta.addedInSnapshot.push({ type: "plugin", alias, name: entry.name, version: entry.version });
      } else if (!this.pluginEntriesMatch(entry, cloudEntry)) {
        delta.changedInSnapshot.push({ type: "plugin", alias, field: "unspecified" });
      }
    }
    for (const [alias, entry] of Object.entries(cloud.plugins)) {
      if (!snapshot.plugins[alias]) {
        delta.removedInSnapshot.push({ type: "plugin", alias, name: entry.name, version: entry.version });
      }
    }
    const snapshotReflectsCloud = delta.addedInSnapshot.length === 0 && delta.removedInSnapshot.length === 0 && delta.changedInSnapshot.length === 0;
    return { target: this.env, snapshotReflectsCloud, delta };
  }
  async apply(opts) {
    const snapshot = await this.readSnapshot();
    const cloud = await this.readCloudSnapshot(snapshot);
    const actions = [];
    const errors = [];
    for (const [alias, entry] of Object.entries(snapshot.integrations)) {
      const c = cloud.integrations[alias];
      if (!c) {
        actions.push({
          type: "integration",
          alias,
          action: "install",
          details: { name: entry.name, version: entry.version }
        });
      } else if (c.version !== entry.version) {
        const isDowngrade = semver2.valid(c.version) && semver2.valid(entry.version) && semver2.gt(c.version, entry.version);
        actions.push({
          type: "integration",
          alias,
          action: isDowngrade ? "downgrade" : "upgrade",
          details: { name: entry.name, fromVersion: c.version, toVersion: entry.version }
        });
      } else {
        if (c.enabled !== entry.enabled)
          actions.push({
            type: "integration",
            alias,
            action: entry.enabled ? "enable" : "disable",
            details: { name: entry.name, version: entry.version, previous: c.enabled }
          });
        if (!jsonEqual(c.config, entry.config))
          actions.push({
            type: "integration",
            alias,
            action: "reconfigure",
            details: { name: entry.name, version: entry.version, changedFields: ["config"] }
          });
      }
    }
    for (const alias of Object.keys(cloud.integrations)) {
      if (!snapshot.integrations[alias]) {
        const c = cloud.integrations[alias];
        actions.push({
          type: "integration",
          alias,
          action: "uninstall",
          details: { name: c.name, version: c.version }
        });
      }
    }
    for (const [alias, entry] of Object.entries(snapshot.plugins)) {
      const c = cloud.plugins[alias];
      if (!c) {
        actions.push({
          type: "plugin",
          alias,
          action: "install",
          details: { name: entry.name, version: entry.version }
        });
      } else if (c.version !== entry.version) {
        const isDowngrade = semver2.valid(c.version) && semver2.valid(entry.version) && semver2.gt(c.version, entry.version);
        actions.push({
          type: "plugin",
          alias,
          action: isDowngrade ? "downgrade" : "upgrade",
          details: { name: entry.name, fromVersion: c.version, toVersion: entry.version }
        });
      } else {
        if (c.enabled !== entry.enabled)
          actions.push({
            type: "plugin",
            alias,
            action: entry.enabled ? "enable" : "disable",
            details: { name: entry.name, version: entry.version, previous: c.enabled }
          });
        const configChanged = !jsonEqual(c.config, entry.config);
        const depsChanged = !jsonEqual(c.dependencies, entry.dependencies);
        if (configChanged || depsChanged) {
          const changedFields = [];
          if (configChanged)
            changedFields.push("config");
          if (depsChanged)
            changedFields.push("dependencies");
          actions.push({
            type: "plugin",
            alias,
            action: "reconfigure",
            details: { name: entry.name, version: entry.version, changedFields }
          });
        }
      }
    }
    for (const alias of Object.keys(cloud.plugins)) {
      if (!snapshot.plugins[alias]) {
        const c = cloud.plugins[alias];
        actions.push({
          type: "plugin",
          alias,
          action: "uninstall",
          details: { name: c.name, version: c.version }
        });
      }
    }
    if (opts?.dryRun) {
      return { target: this.env, applied: [], errors: [], skipped: actions, dryRun: true };
    }
    if (actions.length === 0) {
      return { target: this.env, applied: [], skipped: [], errors, dryRun: false };
    }
    if (!opts?.yes && this.env === "prod") {
      throw new DependencyError({
        code: "PROD_CONFIRMATION_REQUIRED",
        message: "Apply targets production. Pass yes: true to confirm.",
        details: { planned: actions }
      });
    }
    if (!opts?.yes && actions.some((a) => a.action === "uninstall")) {
      throw new DependencyError({
        code: "UNINSTALL_REQUIRES_CONFIRMATION",
        message: "Apply would uninstall resources from cloud. Pass yes: true to confirm.",
        details: { destructive: actions.filter((a) => a.action === "uninstall") }
      });
    }
    const order = ["uninstall", "upgrade", "install", "reconfigure", "enable", "disable"];
    function typeWeight(action, type) {
      if (action === "uninstall")
        return type === "plugin" ? 0 : 1;
      return type === "integration" ? 0 : 1;
    }
    const sorted = [...actions].sort((a, b) => {
      const verbDiff = order.indexOf(a.action) - order.indexOf(b.action);
      if (verbDiff !== 0)
        return verbDiff;
      return typeWeight(a.action, a.type) - typeWeight(b.action, b.type);
    });
    const applied = [];
    const appliedKeys = new Set;
    for (const a of sorted) {
      try {
        const key = `${a.type}:${a.alias}`;
        if (a.action === "uninstall") {
          if (a.type === "integration")
            await this.integrationResolver.removeFromCloud({ botId: this.botId, alias: a.alias });
          else
            await this.pluginResolver.removeFromCloud({ botId: this.botId, alias: a.alias });
        } else if (!appliedKeys.has(key)) {
          const entry = a.type === "integration" ? snapshot.integrations[a.alias] : snapshot.plugins[a.alias];
          await this.applyEntry(a.type, a.alias, entry, snapshot);
          appliedKeys.add(key);
        }
        applied.push(a);
      } catch (err) {
        errors.push({
          action: a,
          code: err.code ?? "INVALID_CONFIG",
          message: err.message,
          suggestion: err.suggestion
        });
      }
    }
    await this.refreshSnapshotFromCloud();
    return { target: this.env, applied, skipped: [], errors, dryRun: false };
  }
  async copy(opts) {
    if (opts.from === opts.to) {
      throw new DependencyError({ code: "SAME_SOURCE_TARGET", message: "--from and --to must be different" });
    }
    if (this.env !== opts.to) {
      throw new DependencyError({
        code: "INVALID_CONFIG",
        message: `DependencyManager constructed with env='${this.env}' but copy targets '${opts.to}'`
      });
    }
    const sourceBotId = opts.sourceBotId?.trim() || await this.getProjectBotId(opts.from);
    if (sourceBotId === this.botId) {
      throw new DependencyError({
        code: "SAME_SOURCE_TARGET",
        message: `${opts.from} and ${opts.to} resolve to the same Cloud bot (${sourceBotId}).`
      });
    }
    const sourceStore = new DependencySnapshotStore({ projectPath: this.projectPath });
    const sourceData = await sourceStore.refreshFromCloud({
      client: this.client,
      botId: sourceBotId,
      env: opts.from,
      integrationRegistry: this.integrationRegistry
    });
    const targetSnapshotExists = await this.snapshotStore.exists(this.env);
    const targetSnapshot = await this.readSnapshot();
    const originalSnapshot = JSON.stringify(targetSnapshot);
    const merged = { ...targetSnapshot, integrations: sourceData.integrations, plugins: sourceData.plugins };
    await this.writeSnapshot(merged);
    try {
      const result = await this.apply({ dryRun: opts.dryRun, yes: opts.yes });
      if (opts.dryRun) {
        if (targetSnapshotExists) {
          await this.writeSnapshot(JSON.parse(originalSnapshot));
        } else {
          await this.snapshotStore.delete(this.env);
        }
      }
      return result;
    } catch (err) {
      if (targetSnapshotExists) {
        await this.writeSnapshot(JSON.parse(originalSnapshot)).catch(() => {});
      } else {
        await this.snapshotStore.delete(this.env).catch(() => {});
      }
      throw err;
    }
  }
}
function formatMissingDependencySuggestion(opts) {
  if (opts.implementers.length === 0) {
    return `Install an integration that implements '${opts.interfaceName}' first, ` + `then retry \u2014 or pass --dep ${opts.pluginInterfaceAlias}=<alias> if you already have one.`;
  }
  const lines = [`Hub integrations that implement '${opts.interfaceName}':`];
  for (const i of opts.implementers) {
    const title = i.title && i.title !== i.name ? ` \u2014 ${i.title}` : "";
    lines.push(`  \u2022 ${i.name}@${i.version}${title}`);
  }
  lines.push("");
  lines.push(`Install one and retry:  adk integrations add ${opts.implementers[0].name}`);
  lines.push(`Or, if you have an installed integration that implements this:  --dep ${opts.pluginInterfaceAlias}=<alias>`);
  return lines.join(`
`);
}
function stripSnapshotMetadata(entry) {
  const {
    cloudAlias: _cloudAlias,
    cloudId: _cloudId,
    updatedAt: _updatedAt,
    ...semantic
  } = entry;
  return semantic;
}
function dependencySnapshotToState(snapshot) {
  const integrations = {};
  for (const [alias, entry] of Object.entries(snapshot.integrations)) {
    integrations[alias] = stripSnapshotMetadata(entry);
  }
  const plugins = {};
  for (const [alias, entry] of Object.entries(snapshot.plugins)) {
    plugins[alias] = stripSnapshotMetadata(entry);
  }
  return dependencyStateSchema.parse({
    version: 1,
    env: snapshot.env,
    integrations,
    plugins
  });
}
init_types();
function getIntegrationAlias(integrationName) {
  return integrationName.replace(/\//g, "__").replace(/-/g, "_").toLowerCase();
}
function bpModuleDirName(kind, alias) {
  return kind === "integration" ? `integration_${getIntegrationAlias(alias)}` : `plugin_${alias}`;
}
async function resolveDependencyStatuses(input) {
  const out = [];
  const integrationVerdicts = new Map;
  for (const [alias, entry] of Object.entries(input.snapshot.integrations)) {
    const installed = input.bpModulesDir ? existsSync(path11.join(input.bpModulesDir, bpModuleDirName("integration", alias))) : true;
    const spec = await tryGetSpec(input.integrationRegistry, entry.name, entry.version);
    const verdict = spec ? computeIntegrationStatus({
      installed,
      spec,
      enabled: entry.enabled,
      config: entry.config,
      ...entry.configurationType ? { configurationType: entry.configurationType } : {},
      ...entry.missingFields !== undefined ? { persistedMissingFields: entry.missingFields } : {},
      ...entry.authorizationPending !== undefined ? { authorizationPending: entry.authorizationPending } : {}
    }) : computeSnapshotOnlyStatus({
      installed,
      enabled: entry.enabled,
      ...entry.missingFields !== undefined ? { missingFields: entry.missingFields } : {},
      ...entry.authorizationPending !== undefined ? { authorizationPending: entry.authorizationPending } : {}
    });
    integrationVerdicts.set(alias, verdict);
    out.push({
      type: "integration",
      alias,
      name: entry.name,
      version: entry.version,
      enabled: entry.enabled,
      ...verdict
    });
  }
  for (const [alias, entry] of Object.entries(input.snapshot.plugins)) {
    const installed = input.bpModulesDir ? existsSync(path11.join(input.bpModulesDir, bpModuleDirName("plugin", alias))) : true;
    const spec = await tryGetSpec(input.pluginRegistry, entry.name, entry.version);
    const dependencyStatuses = mapPluginDependencyStatuses(entry.dependencies, (intAlias) => integrationVerdicts.get(intAlias));
    let verdict;
    if (spec) {
      verdict = computePluginStatus({
        installed,
        spec,
        enabled: entry.enabled,
        config: entry.config,
        dependencyStatuses,
        ...entry.missingFields !== undefined ? { persistedMissingFields: entry.missingFields } : {}
      });
    } else if (!installed) {
      verdict = { state: "not_installed" };
    } else {
      verdict = transitiveDependencyVerdict(dependencyStatuses) ?? computeSnapshotOnlyStatus({
        installed: true,
        enabled: entry.enabled,
        ...entry.missingFields !== undefined ? { missingFields: entry.missingFields } : {}
      });
    }
    out.push({ type: "plugin", alias, name: entry.name, version: entry.version, enabled: entry.enabled, ...verdict });
  }
  return out;
}
async function tryGetSpec(source, name, version) {
  if (!source)
    return null;
  try {
    return await source.getSpec(name, version);
  } catch {
    return null;
  }
}
init_errors2();
init_constants();

class InterfaceRegistry {
  async list() {
    return Object.entries(BUILTIN_INTERFACES).map(([alias, versionString]) => {
      const [name, version] = versionString.split("@");
      return { alias, name: name || alias, version: version || "latest", builtin: true };
    });
  }
  async getInfo(alias) {
    const all = await this.list();
    return all.find((i) => i.alias === alias);
  }
}
init_snapshot_store();
init_types();
init_errors2();

class LegacyDependencyLockFile {
  filePath;
  env;
  constructor(opts) {
    this.env = opts.env;
    this.filePath = path12.join(opts.projectPath, `dependencies.${opts.env}.lock.json`);
  }
  async exists() {
    try {
      await fs10.access(this.filePath);
      return true;
    } catch {
      return false;
    }
  }
  async read(options) {
    let raw;
    try {
      raw = await fs10.readFile(this.filePath, "utf8");
    } catch (err) {
      if (err.code === "ENOENT") {
        return dependencyStateSchema.parse({ version: 1, env: this.env });
      }
      throw err;
    }
    try {
      return dependencyStateSchema.parse(JSON.parse(raw));
    } catch (err) {
      if (options?.tolerant) {
        return dependencyStateSchema.parse({ version: 1, env: this.env });
      }
      throw new DependencyError({
        code: "INVALID_CONFIG",
        message: `Legacy dependency lock at ${this.filePath} failed schema validation`,
        details: { issues: err.issues ?? String(err) }
      });
    }
  }
  async delete() {
    try {
      await fs10.unlink(this.filePath);
    } catch (err) {
      if (err.code !== "ENOENT")
        throw err;
    }
  }
}
init_utils();
init_src();

class ConfigWriter {
  configPath;
  constructor(projectPath) {
    this.configPath = path14.join(projectPath, "agent.config.ts");
  }
  loadConfig() {
    const project = new import_ts_morph3.Project;
    const sourceFile = project.createSourceFile(this.configPath, readFileSync2(this.configPath, "utf-8"), {
      overwrite: true
    });
    const defineConfigCall = sourceFile.getDescendantsOfKind(import_ts_morph3.SyntaxKind.CallExpression).find((call) => {
      return call.getExpression().getText() === "defineConfig";
    });
    if (!defineConfigCall) {
      throw new AdkError({
        code: "CONFIG_AST_INVALID",
        expected: true,
        message: "Could not find defineConfig() call in agent.config.ts"
      });
    }
    const configArg = defineConfigCall.getArguments()[0];
    if (!configArg || !configArg.isKind(import_ts_morph3.SyntaxKind.ObjectLiteralExpression)) {
      throw new AdkError({
        code: "CONFIG_AST_INVALID",
        expected: true,
        message: "defineConfig() must have an object literal as its first argument"
      });
    }
    return { sourceFile, configObject: configArg };
  }
  async saveConfig(sourceFile) {
    sourceFile.formatText();
    const content = sourceFile.getFullText();
    const formatted = await formatCode(content, this.configPath);
    sourceFile.replaceWithText(formatted);
    await sourceFile.save();
  }
  serializeDefaultModelSelection(value) {
    if (Array.isArray(value)) {
      return `[${value.map((entry) => `'${entry.replace(/'/g, "\\'")}'`).join(", ")}]`;
    }
    return `'${value.replace(/'/g, "\\'")}'`;
  }
  getIntegrationConfigMigrationCandidates() {
    const { sourceFile, configObject } = this.loadConfig();
    const dependenciesProp = configObject.getProperty("dependencies");
    if (!dependenciesProp) {
      return { sourceFile, candidates: [] };
    }
    const depsInit = dependenciesProp.getInitializerIfKind(import_ts_morph3.SyntaxKind.ObjectLiteralExpression);
    if (!depsInit) {
      return { sourceFile, candidates: [] };
    }
    const integrationsProp = depsInit.getProperty("integrations");
    if (!integrationsProp) {
      return { sourceFile, candidates: [] };
    }
    const integrationsInit = integrationsProp.getInitializerIfKind(import_ts_morph3.SyntaxKind.ObjectLiteralExpression);
    if (!integrationsInit) {
      return { sourceFile, candidates: [] };
    }
    const candidates = integrationsInit.getProperties().flatMap((prop) => {
      if (!prop.isKind(import_ts_morph3.SyntaxKind.PropertyAssignment)) {
        return [];
      }
      const assignment = prop;
      const initializer = assignment.getInitializerIfKind(import_ts_morph3.SyntaxKind.ObjectLiteralExpression);
      if (!initializer) {
        return [];
      }
      const hasConfigProperty = initializer.getProperty("config") !== undefined;
      const versionProp = initializer.getProperty("version");
      const versionInitializer = versionProp?.getInitializer();
      const versionInitializerText = versionInitializer && (versionInitializer.isKind(import_ts_morph3.SyntaxKind.StringLiteral) || versionInitializer.isKind(import_ts_morph3.SyntaxKind.NoSubstitutionTemplateLiteral)) ? versionInitializer.getText() : undefined;
      return [{ alias: assignment.getName(), assignment, hasConfigProperty, versionInitializerText }];
    });
    return { sourceFile, candidates };
  }
  async updateDependencies(dependencies) {
    const { sourceFile, configObject } = this.loadConfig();
    let dependenciesProperty = configObject.getProperty("dependencies");
    if (dependenciesProperty) {
      dependenciesProperty.setInitializer(JSON.stringify(dependencies, null, 2));
    } else {
      dependenciesProperty = configObject.addPropertyAssignment({
        name: "dependencies",
        initializer: JSON.stringify(dependencies)
      });
    }
    await this.saveConfig(sourceFile);
  }
  async updateName(name) {
    const { sourceFile, configObject } = this.loadConfig();
    const nameProperty = configObject.getProperty("name");
    if (nameProperty) {
      nameProperty.setInitializer(`'${name.replace(/'/g, "\\'")}'`);
    }
    await this.saveConfig(sourceFile);
  }
  async updateDefaultModels(updates) {
    const requestedEntries = Object.entries(updates).filter(([, value]) => value !== undefined);
    if (requestedEntries.length === 0) {
      return;
    }
    const { sourceFile, configObject } = this.loadConfig();
    let defaultModelsProperty = configObject.getProperty("defaultModels");
    if (!defaultModelsProperty) {
      defaultModelsProperty = configObject.addPropertyAssignment({
        name: "defaultModels",
        initializer: "{}"
      });
    }
    const defaultModelsObject = defaultModelsProperty.getInitializerIfKind(import_ts_morph3.SyntaxKind.ObjectLiteralExpression);
    if (!defaultModelsObject) {
      throw new AdkError({
        code: "CONFIG_AST_INVALID",
        expected: true,
        message: "defaultModels must be an object literal in agent.config.ts"
      });
    }
    for (const [key, value] of requestedEntries) {
      const existingProperty = defaultModelsObject.getProperty(key);
      const initializer = this.serializeDefaultModelSelection(value);
      if (existingProperty) {
        existingProperty.setInitializer(initializer);
      } else {
        defaultModelsObject.addPropertyAssignment({
          name: key,
          initializer
        });
      }
    }
    await this.saveConfig(sourceFile);
  }
  async migrateIntegrationsToStringFormat() {
    const { sourceFile, candidates } = this.getIntegrationConfigMigrationCandidates();
    const migrated = [];
    for (const candidate of candidates) {
      if (!candidate.versionInitializerText || candidate.hasConfigProperty) {
        continue;
      }
      candidate.assignment.setInitializer(candidate.versionInitializerText);
      migrated.push(candidate.alias);
    }
    if (migrated.length > 0) {
      await this.saveConfig(sourceFile);
    }
    return migrated;
  }
  getIntegrationConfigMigrationState() {
    try {
      const { candidates } = this.getIntegrationConfigMigrationCandidates();
      const deprecatedAliases = candidates.map((candidate) => candidate.alias);
      const migratableAliases = candidates.filter((candidate) => candidate.versionInitializerText && !candidate.hasConfigProperty).map((candidate) => candidate.alias);
      return { deprecatedAliases, migratableAliases };
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      console.error(`Configuration update failed with error: ${message} \u2014 please verify that there are no syntax errors in your agent.config.ts`);
      return { deprecatedAliases: [], migratableAliases: [] };
    }
  }
  getObjectFormatIntegrations() {
    return this.getIntegrationConfigMigrationState().deprecatedAliases;
  }
  serializeStringLiteral(value) {
    return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
  }
  buildSecretInitializer(update) {
    const parts = [];
    if (update.description !== undefined) {
      parts.push(`description: ${this.serializeStringLiteral(update.description)}`);
    }
    if (update.optional !== undefined) {
      parts.push(`optional: ${update.optional ? "true" : "false"}`);
    }
    return `{ ${parts.join(", ")} }`;
  }
  async updateSecrets(updates) {
    const { sourceFile, configObject } = this.loadConfig();
    const hasAdds = updates.some((u) => u.action === "add");
    let secretsProp = configObject.getProperty("secrets");
    if (!secretsProp) {
      if (!hasAdds)
        return;
      secretsProp = configObject.addPropertyAssignment({
        name: "secrets",
        initializer: "{}"
      });
    }
    const secretsObject = secretsProp.getInitializerIfKind(import_ts_morph3.SyntaxKind.ObjectLiteralExpression);
    if (!secretsObject)
      return;
    for (const update of updates) {
      const existing = secretsObject.getProperty(update.field);
      switch (update.action) {
        case "add":
          if (!existing) {
            secretsObject.addPropertyAssignment({
              name: update.field,
              initializer: this.buildSecretInitializer(update)
            });
          }
          break;
        case "update": {
          if (!existing)
            break;
          const existingInit = existing.getInitializerIfKind(import_ts_morph3.SyntaxKind.ObjectLiteralExpression);
          if (!existingInit) {
            existing.setInitializer(this.buildSecretInitializer(update));
            break;
          }
          if (update.description !== undefined) {
            const descProp = existingInit.getProperty("description");
            const initializer = this.serializeStringLiteral(update.description);
            if (descProp) {
              descProp.setInitializer(initializer);
            } else {
              existingInit.addPropertyAssignment({ name: "description", initializer });
            }
          }
          if (update.optional !== undefined) {
            const optionalProp = existingInit.getProperty("optional");
            const initializer = update.optional ? "true" : "false";
            if (optionalProp) {
              optionalProp.setInitializer(initializer);
            } else {
              existingInit.addPropertyAssignment({ name: "optional", initializer });
            }
          }
          break;
        }
        case "remove":
          if (existing) {
            existing.remove();
          }
          break;
      }
    }
    await this.saveConfig(sourceFile);
  }
  async updateConfiguration(updates) {
    const { sourceFile, configObject } = this.loadConfig();
    const hasAdds = updates.some((u) => u.action === "add");
    let configProp = configObject.getProperty("configuration");
    if (!configProp) {
      if (!hasAdds)
        return;
      configProp = configObject.addPropertyAssignment({
        name: "configuration",
        initializer: "{ schema: z.object({}) }"
      });
    }
    const configInit = configProp.getInitializerIfKind(import_ts_morph3.SyntaxKind.ObjectLiteralExpression);
    if (!configInit)
      return;
    let schemaProp = configInit.getProperty("schema");
    if (!schemaProp) {
      if (!hasAdds)
        return;
      schemaProp = configInit.addPropertyAssignment({
        name: "schema",
        initializer: "z.object({})"
      });
    }
    const schemaCall = schemaProp.getInitializerIfKind(import_ts_morph3.SyntaxKind.CallExpression);
    if (!schemaCall)
      return;
    const schemaArg = schemaCall.getArguments()[0];
    if (!schemaArg || !schemaArg.isKind(import_ts_morph3.SyntaxKind.ObjectLiteralExpression))
      return;
    const schemaObject = schemaArg;
    for (const update of updates) {
      const existing = schemaObject.getProperty(update.field);
      switch (update.action) {
        case "add":
          if (!existing && update.definition) {
            schemaObject.addPropertyAssignment({
              name: update.field,
              initializer: update.definition
            });
          }
          break;
        case "update":
          if (existing && update.definition) {
            existing.setInitializer(update.definition);
          }
          break;
        case "remove":
          if (existing) {
            existing.remove();
          }
          break;
      }
    }
    await this.saveConfig(sourceFile);
  }
  async removeDependenciesField() {
    const { sourceFile, configObject } = this.loadConfig();
    const dependenciesProp = configObject.getProperty("dependencies");
    if (dependenciesProp) {
      dependenciesProp.remove();
      await this.saveConfig(sourceFile);
    }
  }
}
init_agent_project();
init_snapshot_store();

class DependencyMigrationManager {
  projectPath;
  client;
  snapshotStore;
  integrationRegistry;
  pluginRegistry;
  integrationResolver;
  pluginResolver;
  constructor(opts) {
    this.projectPath = opts.projectPath;
    this.client = opts.client;
    this.snapshotStore = new DependencySnapshotStore({ projectPath: opts.projectPath });
    this.integrationRegistry = new IntegrationRegistry;
    this.pluginRegistry = new PluginRegistry;
    this.integrationResolver = opts.integrationResolver ?? new IntegrationResolver({ registry: this.integrationRegistry, client: this.client });
    this.pluginResolver = opts.pluginResolver ?? new PluginResolver({
      registry: this.pluginRegistry,
      integrationRegistry: this.integrationRegistry,
      client: this.client
    });
  }
  async run() {
    const result = {
      migrated: [],
      warnings: [],
      skipped: [],
      legacySources: [],
      snapshotWrites: [],
      cloudWrites: []
    };
    if (await this.snapshotStore.hasMigrationMarker()) {
      for (const env of ["dev", "prod"]) {
        await this.deleteLegacyLock(env, result);
        result.skipped.push({ env, reason: "migration already completed" });
      }
      return result;
    }
    const project = await AgentProject.load(this.projectPath, { noCache: true });
    const info = project.agentInfo;
    const agentConfigDependencies = await readDependenciesFromConfig(this.projectPath);
    const hasAgentConfigDependencies = hasDependencies(agentConfigDependencies);
    if (hasAgentConfigDependencies) {
      result.legacySources?.push("agentConfig");
    }
    if (!info) {
      result.warnings.push({
        code: "CLOUD_FETCH_PARTIAL",
        message: "No agent.json found; cannot migrate dependencies to Cloud-backed snapshots."
      });
      for (const env of ["dev", "prod"]) {
        result.skipped.push({ env, reason: "no agent.json" });
      }
      return result;
    }
    const markerSources = new Set;
    for (const env of ["dev", "prod"]) {
      const botId = env === "dev" ? info.devId ?? info.botId : info.botId;
      if (!botId) {
        result.warnings.push({
          code: "NO_PROD_BOT",
          message: "No prod bot configured in agent.json. Prod dependency snapshot was not written."
        });
        result.skipped.push({ env, reason: "no prod bot configured" });
        continue;
      }
      const legacy = await this.readLegacyState(env, agentConfigDependencies);
      if (legacy?.source === "lock" && !result.legacySources?.includes("lock")) {
        result.legacySources?.push("lock");
      }
      let bot = await this.fetchBot(botId, env, result);
      if (!bot)
        continue;
      if (!cloudHasDependencies(bot) && legacy) {
        await this.importLegacyToCloud({ botId, legacy: legacy.data });
        result.cloudWrites?.push(env);
        markerSources.add(legacy.source);
        bot = await this.fetchBot(botId, env, result);
        if (!bot)
          continue;
      } else {
        markerSources.add("cloud");
      }
      await this.snapshotStore.write(dependencySnapshotFromBot({
        bot,
        botId,
        env,
        fetchedAt: new Date,
        previous: await this.snapshotStore.read(env, { tolerant: true })
      }));
      result.snapshotWrites?.push(env);
      result.migrated.push(env);
      await this.deleteLegacyLock(env, result);
    }
    if (hasAgentConfigDependencies && result.migrated.length > 0) {
      const writer = new ConfigWriter(this.projectPath);
      await writer.removeDependenciesField();
    }
    if (result.migrated.length > 0) {
      await this.snapshotStore.writeMigrationMarker({
        version: 1,
        migratedAt: new Date().toISOString(),
        sources: [...markerSources]
      });
      result.warnings.push({
        code: "MIGRATED_DEPENDENCIES",
        message: `Migrated dependencies to .adk snapshots for ${result.migrated.join(", ")}. Cloud is now the source of truth.`
      });
    }
    return result;
  }
  async deleteLegacyLock(env, result) {
    try {
      await new LegacyDependencyLockFile({ projectPath: this.projectPath, env }).delete();
    } catch (err) {
      result.warnings.push({
        code: "LEGACY_LOCK_DELETE_FAILED",
        message: `Migrated ${env} dependencies, but could not delete dependencies.${env}.lock.json: ${err.message}`
      });
    }
  }
  async readLegacyState(env, agentConfigDependencies) {
    const legacyLock = new LegacyDependencyLockFile({ projectPath: this.projectPath, env });
    if (await legacyLock.exists()) {
      return { source: "lock", data: await legacyLock.read() };
    }
    if (hasDependencies(agentConfigDependencies)) {
      return { source: "agentConfig", data: { ...agentConfigDependencies, env } };
    }
    return null;
  }
  async fetchBot(botId, env, result) {
    try {
      const { bot } = await this.client.getBot({ id: botId });
      return bot;
    } catch (err) {
      result.warnings.push({
        code: "CLOUD_FETCH_PARTIAL",
        message: `Could not fetch cloud state for ${env}: ${err.message}`
      });
      result.skipped.push({ env, reason: "cloud fetch failed" });
      return null;
    }
  }
  async importLegacyToCloud(opts) {
    for (const [alias, entry] of Object.entries(opts.legacy.integrations)) {
      await this.integrationResolver.applyToCloud({ botId: opts.botId, alias, entry });
    }
    for (const [alias, entry] of Object.entries(opts.legacy.plugins)) {
      await this.pluginResolver.applyToCloud({ botId: opts.botId, alias, entry, state: opts.legacy });
    }
  }
}
async function migrateFromConfig(opts) {
  return new DependencyMigrationManager(opts).run();
}
async function readDependenciesFromConfig(projectPath) {
  const configPath = path15.join(projectPath, "agent.config.ts");
  const empty = { version: 1, env: "dev", integrations: {}, plugins: {} };
  try {
    await fs11.access(configPath);
  } catch {
    return empty;
  }
  try {
    const project = new import_ts_morph2.Project({ useInMemoryFileSystem: false });
    const sourceFile = project.addSourceFileAtPath(configPath);
    const callExpr = sourceFile.getDescendantsOfKind(import_ts_morph2.SyntaxKind.CallExpression).find((c) => c.getExpression().getText() === "defineConfig");
    const obj = callExpr?.getArguments()[0]?.asKind(import_ts_morph2.SyntaxKind.ObjectLiteralExpression);
    if (!obj)
      return empty;
    const depsProp = obj.getProperty("dependencies");
    if (!depsProp?.isKind(import_ts_morph2.SyntaxKind.PropertyAssignment))
      return empty;
    const depsObj = depsProp.getInitializer()?.asKind(import_ts_morph2.SyntaxKind.ObjectLiteralExpression);
    if (!depsObj)
      return empty;
    readDependencyField(depsObj, "integrations", empty);
    readDependencyField(depsObj, "plugins", empty);
  } catch {
    return empty;
  }
  return empty;
}
function readDependencyField(depsObj, field, data) {
  const innerProp = depsObj.getProperty(field);
  if (!innerProp?.isKind(import_ts_morph2.SyntaxKind.PropertyAssignment))
    return;
  const inner = innerProp.getInitializer()?.asKind(import_ts_morph2.SyntaxKind.ObjectLiteralExpression);
  if (!inner)
    return;
  for (const aliasProp of inner.getProperties()) {
    if (!aliasProp.isKind(import_ts_morph2.SyntaxKind.PropertyAssignment))
      continue;
    const alias = aliasProp.getName().replace(/['"]/g, "");
    const version = readVersionLiteral(aliasProp.getInitializer());
    if (!version)
      continue;
    const at = version.indexOf("@");
    if (at < 0)
      continue;
    const name = version.slice(0, at);
    const semver3 = version.slice(at + 1);
    if (field === "integrations") {
      data.integrations[alias] = { name, version: semver3, enabled: true, config: {} };
    } else {
      data.plugins[alias] = { name, version: semver3, enabled: true, config: {}, dependencies: {} };
    }
  }
}
function readVersionLiteral(node) {
  if (node?.isKind(import_ts_morph2.SyntaxKind.StringLiteral)) {
    return node.getLiteralText();
  }
  if (node?.isKind(import_ts_morph2.SyntaxKind.ObjectLiteralExpression)) {
    const versionProp = node.getProperty("version");
    if (versionProp?.isKind(import_ts_morph2.SyntaxKind.PropertyAssignment)) {
      const value = versionProp.getInitializer();
      if (value?.isKind(import_ts_morph2.SyntaxKind.StringLiteral))
        return value.getLiteralText();
    }
  }
  return null;
}
function hasDependencies(data) {
  return Object.keys(data.integrations).length > 0 || Object.keys(data.plugins).length > 0;
}
function cloudHasDependencies(bot) {
  return Object.keys(bot.integrations ?? {}).length > 0 || Object.keys(bot.plugins ?? {}).length > 0;
}
export { sortKeysDeep, jsonEqual, dependencyStateSchema, DEPENDENCY_ERROR_CODES, DependencyError, DEPENDENCY_WARNING_CODES, computeIntegrationStatus, computePluginStatus, isCallable, DependencySnapshotStore, emptyDependencySnapshot, dependencySnapshotFromBot, IntegrationResolver, PluginResolver, IntegrationRegistry, PluginRegistry, DependencyManager, resolveDependencyStatuses, InterfaceRegistry, DependencyMigrationManager, migrateFromConfig };