#!/usr/bin/env node

// src/index.ts
import { Command } from "commander";
import { readFileSync as readFileSync2 } from "fs";
import { fileURLToPath as fileURLToPath3 } from "url";
import { dirname, join } from "path";

// src/core/logger.ts
import chalk from "chalk";
function createLogger(options = {}) {
  const { verbose = false, silent = false, json = false } = options;
  const shouldLog = !silent && !json;
  const shouldDebug = verbose && !silent && !json;
  return {
    log: (color, ...args) => {
      if (shouldLog) {
        const message = args.map((arg) => String(arg)).join(" ");
        const colorMap = {
          red: chalk.red,
          green: chalk.green,
          blue: chalk.blue,
          yellow: chalk.yellow,
          gray: chalk.gray,
          grey: chalk.gray,
          cyan: chalk.cyan,
          magenta: chalk.magenta,
          white: chalk.white,
          black: chalk.black
        };
        const colorFn = colorMap[color];
        const coloredMessage = colorFn ? colorFn(message) : message;
        console.log(coloredMessage);
      }
    },
    info: (...args) => {
      if (shouldLog) {
        const message = args.map((arg) => String(arg)).join(" ");
        console.log(chalk.blue(message));
      }
    },
    success: (...args) => {
      if (shouldLog) {
        const message = args.map((arg) => String(arg)).join(" ");
        console.log(chalk.green(message));
      }
    },
    warning: (...args) => {
      if (shouldLog) {
        const message = args.map((arg) => String(arg)).join(" ");
        console.log(chalk.yellow(message));
      }
    },
    warn: (...args) => {
      if (shouldLog) {
        const message = args.map((arg) => String(arg)).join(" ");
        console.log(chalk.yellow(message));
      }
    },
    error: (...args) => {
      if (!json) {
        const message = args.map((arg) => String(arg)).join(" ");
        console.error(chalk.red(message));
      }
    },
    debug: (...args) => {
      if (shouldDebug) {
        const message = args.map((arg) => String(arg)).join(" ");
        console.log(chalk.gray(message));
      }
    },
    gray: (...args) => {
      if (shouldLog) {
        const message = args.map((arg) => String(arg)).join(" ");
        console.log(chalk.gray(message));
      }
    }
  };
}
function createCommandLogger(options) {
  return createLogger({
    verbose: options.verbose,
    silent: options.silent ?? false,
    json: options.json
  });
}

// src/core/timer.ts
function createTimer() {
  let startTime = 0;
  let endTime = 0;
  return {
    start() {
      startTime = Date.now();
      endTime = 0;
    },
    end() {
      endTime = Date.now();
      return endTime - startTime;
    },
    getElapsed() {
      const currentTime = endTime || Date.now();
      return currentTime - startTime;
    },
    format() {
      const elapsed = this.getElapsed();
      return (elapsed / 1e3).toFixed(2) + "s";
    }
  };
}

// src/core/output.ts
function createJsonOutput(success, data, error, duration) {
  return {
    success,
    ...data && { data },
    ...error && { error },
    ...duration && { duration }
  };
}
function createSuccessOutput(data, duration) {
  return createJsonOutput(true, data, void 0, duration);
}
function createErrorOutput(error, duration) {
  return createJsonOutput(false, void 0, error, duration);
}
function formatBytes(bytes) {
  return (bytes / 1024).toFixed(2);
}

// src/core/docker.ts
import { spawn } from "child_process";
import path2 from "path";
import { readFileSync } from "fs";
import { fileURLToPath } from "url";
import { VERSION as DOCKER_VERSION } from "@walkeros/docker";

// src/config/utils.ts
import fs from "fs-extra";
import path from "path";
import os from "os";
function isUrl(str) {
  try {
    const url = new URL(str);
    return url.protocol === "http:" || url.protocol === "https:";
  } catch {
    return false;
  }
}
async function downloadFromUrl(url) {
  if (!isUrl(url)) {
    throw new Error(`Invalid URL: ${url}`);
  }
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(
        `Failed to download ${url}: ${response.status} ${response.statusText}`
      );
    }
    const content = await response.text();
    const urlObj = new URL(url);
    const urlFilename = path.basename(urlObj.pathname);
    const extension = path.extname(urlFilename) || ".json";
    const randomId = Math.random().toString(36).substring(2, 11);
    const filename = `walkeros-download-${Date.now()}-${randomId}${extension}`;
    const tempPath = path.join(os.tmpdir(), filename);
    await fs.writeFile(tempPath, content, "utf-8");
    return tempPath;
  } catch (error) {
    if (error instanceof Error) {
      throw new Error(`Failed to download from URL: ${error.message}`);
    }
    throw error;
  }
}
async function loadJsonConfig(configPath) {
  let absolutePath;
  let isTemporary = false;
  if (isUrl(configPath)) {
    absolutePath = await downloadFromUrl(configPath);
    isTemporary = true;
  } else {
    absolutePath = path.resolve(configPath);
    if (!await fs.pathExists(absolutePath)) {
      throw new Error(`Configuration file not found: ${absolutePath}`);
    }
  }
  try {
    const rawConfig = await fs.readJson(absolutePath);
    return rawConfig;
  } catch (error) {
    throw new Error(
      `Invalid JSON in config file: ${configPath}. ${error instanceof Error ? error.message : error}`
    );
  } finally {
    if (isTemporary) {
      try {
        await fs.remove(absolutePath);
      } catch {
      }
    }
  }
}
function getTempDir(tempDir = ".tmp") {
  const randomId = Math.random().toString(36).substring(2, 11);
  const basePath = path.isAbsolute(tempDir) ? tempDir : path.join(process.cwd(), tempDir);
  return path.join(basePath, `cli-${Date.now()}-${randomId}`);
}
async function loadJsonFromSource(source, options) {
  const paramName = options?.name || "input";
  if (!source || source.trim() === "") {
    if (options?.required) {
      throw new Error(`${paramName} is required`);
    }
    if (options?.fallback !== void 0) {
      return options.fallback;
    }
    return {};
  }
  const trimmedSource = source.trim();
  if (isUrl(trimmedSource)) {
    try {
      const tempPath = await downloadFromUrl(trimmedSource);
      try {
        const data = await fs.readJson(tempPath);
        return data;
      } finally {
        try {
          await fs.remove(tempPath);
        } catch {
        }
      }
    } catch (error) {
      throw new Error(
        `Failed to load ${paramName} from URL ${trimmedSource}: ${getErrorMessage(error)}`
      );
    }
  }
  const resolvedPath = path.resolve(trimmedSource);
  if (await fs.pathExists(resolvedPath)) {
    try {
      const data = await fs.readJson(resolvedPath);
      return data;
    } catch (error) {
      throw new Error(
        `Failed to parse ${paramName} from file ${trimmedSource}: ${getErrorMessage(error)}`
      );
    }
  }
  try {
    const parsed = JSON.parse(trimmedSource);
    return parsed;
  } catch (jsonError) {
    if (!trimmedSource.startsWith("{") && !trimmedSource.startsWith("[")) {
      return { name: trimmedSource };
    }
    throw new Error(
      `Failed to parse ${paramName}. Input appears to be JSON but contains errors: ${jsonError instanceof Error ? jsonError.message : String(jsonError)}`
    );
  }
}

// src/core/docker.ts
function readPackageVersion() {
  const moduleFilename = fileURLToPath(import.meta.url);
  const moduleDir = path2.dirname(moduleFilename);
  const prodPath = path2.join(moduleDir, "../package.json");
  try {
    const pkg = JSON.parse(readFileSync(prodPath, "utf-8"));
    return pkg.version;
  } catch {
    const devPath = path2.join(moduleDir, "../../package.json");
    const pkg = JSON.parse(readFileSync(devPath, "utf-8"));
    return pkg.version;
  }
}
var CLI_VERSION = readPackageVersion();
var CLI_DOCKER_IMAGE = process.env.WALKEROS_CLI_DOCKER_IMAGE || `walkeros/cli:${CLI_VERSION}`;
var RUNTIME_DOCKER_IMAGE = process.env.WALKEROS_RUNTIME_DOCKER_IMAGE || `walkeros/docker:${DOCKER_VERSION}`;
function buildCommonDockerArgs(options) {
  const args = [options.config];
  if (options.json) args.push("--json");
  if (options.verbose) args.push("--verbose");
  if (options.silent) args.push("--silent");
  return args;
}
function buildDockerCommand(command, args, options = {}, configFile) {
  const cwd = process.cwd();
  const cmd = ["docker", "run", "--rm"];
  if (configFile && !isUrl(configFile)) {
    const configPath = path2.resolve(cwd, configFile);
    cmd.push("-v", `${configPath}:/config/flow.json:ro`);
    args = args.map((arg) => arg === configFile ? "/config/flow.json" : arg);
  }
  cmd.push("-v", `${cwd}:/workspace`);
  cmd.push("-w", "/workspace");
  if (process.platform !== "win32") {
    try {
      const uid = process.getuid?.();
      const gid = process.getgid?.();
      if (uid !== void 0 && gid !== void 0) {
        cmd.push("--user", `${uid}:${gid}`);
      }
    } catch {
    }
  }
  if (options.verbose) {
    cmd.push("-e", "VERBOSE=true");
  }
  if (options.silent) {
    cmd.push("-e", "SILENT=true");
  }
  cmd.push(CLI_DOCKER_IMAGE);
  cmd.push(command, ...args);
  return cmd;
}
async function executeInDocker(command, args, options = {}, configFile) {
  const containerArgs = [...args, "--local"];
  const dockerCmd = buildDockerCommand(
    command,
    containerArgs,
    options,
    configFile
  );
  return new Promise((resolve, reject) => {
    const proc = spawn(dockerCmd[0], dockerCmd.slice(1), {
      stdio: options.silent ? "ignore" : "inherit",
      shell: false
    });
    proc.on("error", (error) => {
      reject(new Error(`Docker execution failed: ${error.message}`));
    });
    proc.on("exit", (code) => {
      if (code === 0) {
        resolve();
      } else {
        reject(new Error(`Docker command exited with code ${code}`));
      }
    });
  });
}
async function isDockerAvailable() {
  return new Promise((resolve) => {
    const proc = spawn("docker", ["--version"], {
      stdio: "ignore"
    });
    proc.on("error", () => resolve(false));
    proc.on("exit", (code) => resolve(code === 0));
  });
}
function buildDockerRunCommand(mode, flowPath, options = {}) {
  const cwd = process.cwd();
  const cmd = ["docker", "run", "--rm"];
  cmd.push("-e", `MODE=${mode}`);
  if (mode === "collect" && flowPath) {
    const absoluteFlowPath = path2.resolve(cwd, flowPath);
    cmd.push("-v", `${absoluteFlowPath}:/app/flow.mjs:ro`);
    cmd.push("-e", "FLOW=/app/flow.mjs");
  }
  if (mode === "serve" && flowPath) {
    const absoluteFilePath = path2.resolve(cwd, flowPath);
    cmd.push("-v", `${absoluteFilePath}:/app/bundle.mjs:ro`);
    cmd.push("-e", "FILE_PATH=/app/bundle.mjs");
  }
  const port = options.port !== void 0 ? options.port : 8080;
  cmd.push("-p", `${port}:${port}`);
  cmd.push("-e", `PORT=${port}`);
  if (options.host) {
    cmd.push("-e", `HOST=${options.host}`);
  }
  if (options.serveName) {
    cmd.push("-e", `SERVE_NAME=${options.serveName}`);
  }
  if (options.servePath) {
    cmd.push("-e", `SERVE_PATH=${options.servePath}`);
  }
  if (process.platform !== "win32") {
    try {
      const uid = process.getuid?.();
      const gid = process.getgid?.();
      if (uid !== void 0 && gid !== void 0) {
        cmd.push("--user", `${uid}:${gid}`);
      }
    } catch {
    }
  }
  cmd.push(RUNTIME_DOCKER_IMAGE);
  return cmd;
}
async function executeRunInDocker(mode, flowPath, options = {}) {
  const dockerCmd = buildDockerRunCommand(mode, flowPath, options);
  return new Promise((resolve, reject) => {
    const proc = spawn(dockerCmd[0], dockerCmd.slice(1), {
      stdio: options.silent ? "ignore" : "inherit",
      shell: false
    });
    proc.on("error", (error) => {
      reject(new Error(`Docker execution failed: ${error.message}`));
    });
    proc.on("exit", (code) => {
      if (code === 0) {
        resolve();
      } else {
        reject(new Error(`Docker command exited with code ${code}`));
      }
    });
  });
}

// src/core/execution.ts
function getExecutionMode(options) {
  if (options.local || process.env.WALKEROS_CONTAINER === "true") {
    return "local";
  }
  return "docker";
}
async function executeCommand(localHandler, dockerCommand, dockerArgs, options, logger, configFile) {
  const mode = getExecutionMode(options);
  if (options.dryRun) {
    if (mode === "docker") {
      const cmd = `docker run walkeros/cli:latest ${dockerCommand} ${dockerArgs.join(" ")}`;
      logger?.info(`[DRY-RUN] Would execute: ${cmd}`);
    } else {
      logger?.info(
        `[DRY-RUN] Would execute locally: ${dockerCommand} ${dockerArgs.join(" ")}`
      );
    }
    return;
  }
  if (mode === "local") {
    if (logger && !options.silent) {
      logger.info("\u{1F5A5}\uFE0F  Executing locally...");
    }
    await localHandler();
  } else {
    const dockerAvailable = await isDockerAvailable();
    if (!dockerAvailable) {
      throw new Error(
        "Docker is not available. Please install Docker or use --local flag to execute locally."
      );
    }
    if (logger && !options.silent) {
      logger.info("\u{1F433} Executing in Docker container...");
    }
    await executeInDocker(dockerCommand, dockerArgs, options, configFile);
  }
}

// src/core/temp-manager.ts
import { getHashServer } from "@walkeros/server-core";
import fs2 from "fs-extra";

// src/core/asset-resolver.ts
import { fileURLToPath as fileURLToPath2 } from "url";
import path3 from "path";
function getPackageRoot() {
  const currentFile = fileURLToPath2(import.meta.url);
  if (currentFile.includes("/src/")) {
    const srcIndex = currentFile.indexOf("/src/");
    return currentFile.substring(0, srcIndex);
  }
  if (currentFile.includes("/dist/")) {
    const distIndex = currentFile.indexOf("/dist/");
    return currentFile.substring(0, distIndex);
  }
  return path3.resolve(currentFile, "../..");
}
function resolveAsset(assetPath, assetType, baseDir) {
  const packageRoot = getPackageRoot();
  if (!assetPath.includes("/") && !assetPath.includes("\\")) {
    if (assetType === "template") {
      return path3.join(packageRoot, "templates", assetPath);
    }
    return path3.join(packageRoot, "examples", assetPath);
  }
  if (path3.isAbsolute(assetPath)) {
    return assetPath;
  }
  const resolveBase = baseDir || process.cwd();
  return path3.resolve(resolveBase, assetPath);
}

// src/core/utils.ts
function getErrorMessage(error) {
  return error instanceof Error ? error.message : String(error);
}

// src/config/validators.ts
function isObject(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
}
function validatePlatform(platform) {
  return platform === "web" || platform === "server";
}
function isMultiEnvConfig(data) {
  return isObject(data) && "version" in data && data.version === 1 && "environments" in data && isObject(data.environments);
}
function isSingleEnvConfig(data) {
  return isObject(data) && "flow" in data && "build" in data && isObject(data.flow) && isObject(data.build) && "platform" in data.flow;
}

// src/config/parser.ts
import path4 from "path";
function parseConfigStructure(rawConfig, options = {}) {
  if (isMultiEnvConfig(rawConfig)) {
    const setup = rawConfig;
    const availableEnvironments = Object.keys(setup.environments);
    if (!options.environment) {
      throw new Error(
        `Multi-environment configuration detected. Please specify an environment using --env flag.
Available environments: ${availableEnvironments.join(", ")}`
      );
    }
    const selectedEnv = options.environment;
    if (!setup.environments[selectedEnv]) {
      throw new Error(
        `Environment "${selectedEnv}" not found in configuration.
Available environments: ${availableEnvironments.join(", ")}`
      );
    }
    const envConfig = setup.environments[selectedEnv];
    return {
      flowConfig: envConfig.flow,
      buildOptions: envConfig.build,
      metadata: {
        environment: selectedEnv,
        isMultiEnvironment: true,
        availableEnvironments
      }
    };
  }
  if (isSingleEnvConfig(rawConfig)) {
    const config = rawConfig;
    return {
      flowConfig: config.flow,
      buildOptions: config.build,
      metadata: {
        environment: "default",
        isMultiEnvironment: false
      }
    };
  }
  const configPath = options.configPath || "configuration";
  const configType = isObject(rawConfig) ? "platform" in rawConfig ? `invalid platform value: "${rawConfig.platform}"` : 'missing "flow" and "build" fields' : `not an object (got ${typeof rawConfig})`;
  throw new Error(
    `Invalid configuration format at ${configPath}.
Configuration ${configType}.

Expected either:
  1. Multi-environment: { version: 1, environments: { prod: { flow: {...}, build: {...} } } }
  2. Single-environment: { flow: { platform: "web" | "server", ... }, build: { packages: {...}, ... } }`
  );
}
function normalizeAndValidate(flowConfig, buildOptions, configPath) {
  if (!isObject(flowConfig) || !("platform" in flowConfig)) {
    throw new Error(
      `Invalid flow config: missing "platform" field. Expected "web" or "server".`
    );
  }
  const platform = flowConfig.platform;
  if (!validatePlatform(platform)) {
    throw new Error(
      `Invalid platform "${platform}". Must be "web" or "server".`
    );
  }
  if (!isObject(buildOptions)) {
    throw new Error(
      `Invalid build options: expected object, got ${typeof buildOptions}`
    );
  }
  const platformDefaults = platform === "web" ? {
    platform: "browser",
    format: "iife",
    target: "es2020",
    minify: false,
    sourcemap: false,
    tempDir: ".tmp",
    cache: true
  } : {
    platform: "node",
    format: "esm",
    target: "node20",
    minify: false,
    sourcemap: false,
    tempDir: ".tmp",
    cache: true
  };
  const merged = {
    ...platformDefaults,
    ...buildOptions
  };
  if (merged.template === void 0) {
    merged.template = platform === "server" ? "server.hbs" : "web.hbs";
  }
  if (merged.format === "iife" && merged.platform === "browser") {
    if (merged.windowCollector === void 0) {
      merged.windowCollector = "collector";
    }
    if (merged.windowElb === void 0) {
      merged.windowElb = "elb";
    }
  }
  if (configPath && merged.template && !path4.isAbsolute(merged.template) && (merged.template.startsWith("./") || merged.template.startsWith("../"))) {
    const configDir = path4.dirname(configPath);
    merged.template = path4.resolve(configDir, merged.template);
  }
  if (!merged.output || merged.output === "") {
    merged.output = platform === "web" ? "./dist/walker.js" : "./dist/bundle.js";
  }
  if (configPath && configPath !== "/unknown/path" && merged.output && !path4.isAbsolute(merged.output)) {
    const configDir = path4.dirname(configPath);
    merged.output = path4.resolve(configDir, merged.output);
  }
  if (!merged.packages) {
    merged.packages = {};
  }
  if (merged.code === void 0 || merged.code === "") {
    merged.code = "";
  }
  return {
    flowConfig,
    buildOptions: merged
  };
}
function parseBundleConfig(data) {
  if (!isObject(data)) {
    throw new Error(`Invalid config: expected object, got ${typeof data}`);
  }
  if (!("flow" in data) || !isObject(data.flow)) {
    throw new Error(
      `Invalid config: missing "flow" field. Expected format: { flow: { platform: "web" | "server", ... }, build: { ... } }`
    );
  }
  if (!("build" in data) || !isObject(data.build)) {
    throw new Error(
      `Invalid config: missing "build" field. Expected format: { flow: { platform: "web" | "server", ... }, build: { ... } }`
    );
  }
  const buildData = data.build;
  if ("packages" in buildData && !isObject(buildData.packages)) {
    throw new Error(
      `Invalid config: build.packages must be an object, got ${typeof buildData.packages}`
    );
  }
  return normalizeAndValidate(data.flow, data.build, "/unknown/path");
}
function normalizeConfigs(config, configPath) {
  return normalizeAndValidate(config.flow, config.build, configPath);
}

// src/config/loader.ts
function loadBundleConfig(rawConfig, options) {
  const { flowConfig, buildOptions, metadata } = parseConfigStructure(
    rawConfig,
    {
      configPath: options.configPath,
      environment: options.environment
    }
  );
  const normalized = normalizeAndValidate(
    flowConfig,
    buildOptions,
    options.configPath
  );
  if (metadata.isMultiEnvironment && options.logger) {
    options.logger.info(
      `\u{1F4E6} Using environment: ${metadata.environment} (${metadata.availableEnvironments?.length || 0} total)`
    );
  }
  if (!metadata.isMultiEnvironment && options.environment && options.logger) {
    options.logger.warn(
      `--env flag specified but configuration is single-environment. Ignoring flag.`
    );
  }
  return {
    ...normalized,
    ...metadata
  };
}
function loadMultiEnvironmentConfig(setup, options) {
  const availableEnvironments = Object.keys(setup.environments);
  if (!options.environment) {
    throw new Error(
      `Multi-environment configuration detected. Please specify an environment using --env flag.
Available environments: ${availableEnvironments.join(", ")}`
    );
  }
  const selectedEnv = options.environment;
  if (!setup.environments[selectedEnv]) {
    throw new Error(
      `Environment "${selectedEnv}" not found in configuration.
Available environments: ${availableEnvironments.join(", ")}`
    );
  }
  const envConfig = setup.environments[selectedEnv];
  const { flowConfig, buildOptions } = normalizeConfigs(
    envConfig,
    options.configPath
  );
  if (options.logger) {
    options.logger.info(
      `\u{1F4E6} Using environment: ${selectedEnv} (${availableEnvironments.length} total)`
    );
  }
  return {
    flowConfig,
    buildOptions,
    environment: selectedEnv,
    isMultiEnvironment: true,
    availableEnvironments
  };
}
function loadAllEnvironments(rawConfig, options) {
  if (!isMultiEnvConfig(rawConfig)) {
    throw new Error(
      `--all flag requires a multi-environment configuration (Setup format).
Your configuration appears to be single-environment.`
    );
  }
  const setup = rawConfig;
  const environments = Object.keys(setup.environments);
  if (options.logger) {
    options.logger.info(
      `\u{1F4E6} Loading all ${environments.length} environments: ${environments.join(", ")}`
    );
  }
  return environments.map(
    (envName) => loadMultiEnvironmentConfig(setup, {
      ...options,
      environment: envName
    })
  );
}

// src/commands/bundle/bundler.ts
import esbuild from "esbuild";
import path6 from "path";
import fs5 from "fs-extra";

// src/commands/bundle/package-manager.ts
import pacote from "pacote";
import path5 from "path";
import fs3 from "fs-extra";
function getPackageDirectory(baseDir, packageName, version) {
  return path5.join(baseDir, "node_modules", packageName);
}
function getCachedPackagePath(pkg, tempDir) {
  const cacheDir = path5.join(".tmp", "cache", "packages");
  const safeName = pkg.name.replace(/\//g, "-").replace(/@/g, "");
  return path5.join(cacheDir, `${safeName}-${pkg.version}`);
}
async function isPackageCached(pkg, tempDir) {
  const cachedPath = getCachedPackagePath(pkg, tempDir);
  return fs3.pathExists(cachedPath);
}
function validateNoDuplicatePackages(packages) {
  const packageMap = /* @__PURE__ */ new Map();
  for (const pkg of packages) {
    if (!packageMap.has(pkg.name)) {
      packageMap.set(pkg.name, []);
    }
    packageMap.get(pkg.name).push(pkg.version);
  }
  const conflicts = [];
  for (const [name, versions] of packageMap.entries()) {
    const uniqueVersions = [...new Set(versions)];
    if (uniqueVersions.length > 1) {
      conflicts.push(`${name}: [${uniqueVersions.join(", ")}]`);
    }
  }
  if (conflicts.length > 0) {
    throw new Error(
      `Version conflicts detected:
${conflicts.map((c) => `  - ${c}`).join("\n")}

Each package must use the same version across all declarations. Please update your configuration to use consistent versions.`
    );
  }
}
async function resolveDependencies(pkg, packageDir, logger, visited = /* @__PURE__ */ new Set()) {
  const dependencies = [];
  const pkgKey = `${pkg.name}@${pkg.version}`;
  if (visited.has(pkgKey)) {
    return dependencies;
  }
  visited.add(pkgKey);
  try {
    const packageJsonPath = path5.join(packageDir, "package.json");
    if (await fs3.pathExists(packageJsonPath)) {
      const packageJson2 = await fs3.readJson(packageJsonPath);
      const deps = {
        ...packageJson2.dependencies,
        ...packageJson2.peerDependencies
      };
      for (const [name, versionSpec] of Object.entries(deps)) {
        if (typeof versionSpec === "string") {
          dependencies.push({ name, version: versionSpec });
        }
      }
    }
  } catch (error) {
    logger.debug(`Failed to read dependencies for ${pkgKey}: ${error}`);
  }
  return dependencies;
}
async function downloadPackages(packages, targetDir, logger, useCache = true) {
  const packagePaths = /* @__PURE__ */ new Map();
  const downloadQueue = [...packages];
  const processed = /* @__PURE__ */ new Set();
  validateNoDuplicatePackages(packages);
  await fs3.ensureDir(targetDir);
  while (downloadQueue.length > 0) {
    const pkg = downloadQueue.shift();
    const pkgKey = `${pkg.name}@${pkg.version}`;
    if (processed.has(pkgKey)) {
      continue;
    }
    processed.add(pkgKey);
    const packageSpec = `${pkg.name}@${pkg.version}`;
    const packageDir = getPackageDirectory(targetDir, pkg.name, pkg.version);
    const cachedPath = getCachedPackagePath(pkg, targetDir);
    if (useCache && await isPackageCached(pkg, targetDir)) {
      logger.debug(`Using cached ${packageSpec}...`);
      try {
        await fs3.ensureDir(path5.dirname(packageDir));
        await fs3.copy(cachedPath, packageDir);
        packagePaths.set(pkg.name, packageDir);
        const deps = await resolveDependencies(pkg, packageDir, logger);
        for (const dep of deps) {
          const depKey = `${dep.name}@${dep.version}`;
          if (!processed.has(depKey)) {
            downloadQueue.push(dep);
          }
        }
        continue;
      } catch (error) {
        logger.debug(
          `Failed to use cache for ${packageSpec}, downloading fresh: ${error}`
        );
      }
    }
    logger.debug(`Downloading ${packageSpec}...`);
    try {
      await fs3.ensureDir(path5.dirname(packageDir));
      const cacheDir = process.env.NPM_CACHE_DIR || path5.join(process.cwd(), ".npm-cache");
      await pacote.extract(packageSpec, packageDir, {
        // Force npm registry download, prevent workspace resolution
        registry: "https://registry.npmjs.org",
        // Force online fetching from registry (don't use cached workspace packages)
        preferOnline: true,
        // Cache for performance
        cache: cacheDir,
        // Don't resolve relative to workspace context
        where: void 0
      });
      if (useCache) {
        try {
          await fs3.ensureDir(path5.dirname(cachedPath));
          await fs3.copy(packageDir, cachedPath);
          logger.debug(`Cached ${packageSpec} for future use`);
        } catch (cacheError) {
          logger.debug(`Failed to cache ${packageSpec}: ${cacheError}`);
        }
      }
      packagePaths.set(pkg.name, packageDir);
      const deps = await resolveDependencies(pkg, packageDir, logger);
      for (const dep of deps) {
        const depKey = `${dep.name}@${dep.version}`;
        if (!processed.has(depKey)) {
          downloadQueue.push(dep);
        }
      }
    } catch (error) {
      throw new Error(`Failed to download ${packageSpec}: ${error}`);
    }
  }
  return packagePaths;
}

// src/commands/bundle/template-engine.ts
import fs4 from "fs-extra";
import Handlebars from "handlebars";

// src/commands/bundle/serializer.ts
function serializeToJS(value, options = {}) {
  const { indent = 2, singleQuotes = false } = options;
  const quote = singleQuotes ? "'" : '"';
  function serialize(val, currentIndent = 0) {
    if (val === null) return "null";
    if (val === void 0) return "undefined";
    if (typeof val === "boolean" || typeof val === "number") {
      return String(val);
    }
    if (typeof val === "string") {
      if (val.includes("=>")) {
        const arrowPatterns = [
          /^\s*\([^)]*\)\s*=>/,
          // (param) => or () =>
          /^\s*\w+\s*=>/,
          // param =>
          /^\s*\([^)]*\)\s*=>\s*\{/,
          // (param) => {
          /^\s*\w+\s*=>\s*\{/
          // param => {
        ];
        if (arrowPatterns.some((pattern) => pattern.test(val))) {
          return val;
        }
      }
      return quote + val.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"') + quote;
    }
    if (Array.isArray(val)) {
      if (val.length === 0) return "[]";
      const nextIndent = currentIndent + indent;
      const spacing = " ".repeat(nextIndent);
      const items = val.map((item) => spacing + serialize(item, nextIndent)).join(",\n");
      return `[
${items}
${" ".repeat(currentIndent)}]`;
    }
    if (isObject(val)) {
      const entries = Object.entries(val);
      if (entries.length === 0) return "{}";
      const nextIndent = currentIndent + indent;
      const spacing = " ".repeat(nextIndent);
      const props = entries.map(([key, value2]) => {
        const needsQuotes = /[^a-zA-Z0-9_$]/.test(key) || /^[0-9]/.test(key);
        const keyStr = needsQuotes ? quote + key + quote : key;
        return spacing + keyStr + ": " + serialize(value2, nextIndent);
      }).join(",\n");
      return `{
${props}
${" ".repeat(currentIndent)}}`;
    }
    return String(val);
  }
  return serialize(value);
}
function serializeConfig(config) {
  if (!config || Object.keys(config).length === 0) {
    return "{}";
  }
  return serializeToJS(config, { indent: 2, singleQuotes: true });
}
function processTemplateVariables(variables) {
  const processed = { ...variables };
  if (isObject(processed.sources)) {
    const sourcesObj = processed.sources;
    const processedSources = {};
    for (const [name, source] of Object.entries(sourcesObj)) {
      const typedSource = source;
      const { env: _, ...sourceWithoutEnv } = typedSource;
      processedSources[name] = {
        ...sourceWithoutEnv,
        config: isObject(typedSource.config) ? serializeConfig(typedSource.config) : typedSource.config,
        // Pass through string configs unchanged
        ...typedSource.env !== void 0 && { env: typedSource.env }
      };
    }
    processed.sources = processedSources;
  }
  if (isObject(processed.destinations)) {
    const destinationsObj = processed.destinations;
    const processedDestinations = {};
    for (const [name, dest] of Object.entries(destinationsObj)) {
      const typedDest = dest;
      const { env: _, ...destWithoutEnv } = typedDest;
      processedDestinations[name] = {
        ...destWithoutEnv,
        config: isObject(typedDest.config) ? serializeConfig(typedDest.config) : typedDest.config,
        ...typedDest.env !== void 0 && { env: typedDest.env }
      };
    }
    processed.destinations = processedDestinations;
  }
  if (isObject(processed.collector)) {
    processed.collector = serializeConfig(
      processed.collector
    );
  }
  return processed;
}

// src/commands/bundle/template-engine.ts
var TemplateEngine = class {
  handlebars;
  constructor() {
    this.handlebars = Handlebars.create();
    this.handlebars.registerHelper("eq", (a, b) => a === b);
  }
  /**
   * Load template content from file path
   *
   * @param templatePath - Template path (bare name, relative, or absolute)
   */
  async loadTemplate(templatePath) {
    const resolvedPath = resolveAsset(templatePath, "template");
    if (!await fs4.pathExists(resolvedPath)) {
      throw new Error(`Template file not found: ${resolvedPath}`);
    }
    return await fs4.readFile(resolvedPath, "utf-8");
  }
  /**
   * Apply template with user code and variable substitution
   */
  applyTemplate(template, userCode, sources, destinations, collector, build) {
    const processedVariables = processTemplateVariables({
      sources,
      destinations,
      collector
    });
    const templateData = {
      CODE: userCode,
      build: build || {},
      ...processedVariables
    };
    const compiledTemplate = this.handlebars.compile(template);
    return compiledTemplate(templateData);
  }
  /**
   * Process template with user code
   */
  async process(templatePath, userCode, sources, destinations, collector, build) {
    const template = await this.loadTemplate(templatePath);
    return this.applyTemplate(
      template,
      userCode,
      sources,
      destinations,
      collector,
      build
    );
  }
};

// src/commands/bundle/bundler.ts
async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
  const bundleStartTime = Date.now();
  const TEMP_DIR = buildOptions.tempDir ? path6.isAbsolute(buildOptions.tempDir) ? buildOptions.tempDir : path6.resolve(buildOptions.tempDir) : getTempDir();
  try {
    if (!buildOptions.tempDir) {
      await fs5.emptyDir(TEMP_DIR);
    }
    logger.debug("Cleaned temporary directory");
    logger.info("\u{1F4E5} Downloading packages...");
    const packagesArray = Object.entries(buildOptions.packages).map(
      ([name, packageConfig]) => ({
        name,
        version: packageConfig.version || "latest"
      })
    );
    const packagePaths = await downloadPackages(
      packagesArray,
      TEMP_DIR,
      logger,
      buildOptions.cache
    );
    for (const [pkgName, pkgPath] of packagePaths.entries()) {
      if (pkgName.startsWith("@walkeros/")) {
        const pkgJsonPath = path6.join(pkgPath, "package.json");
        const pkgJson = await fs5.readJSON(pkgJsonPath);
        if (!pkgJson.exports && pkgJson.module) {
          pkgJson.exports = {
            ".": {
              import: pkgJson.module,
              require: pkgJson.main
            }
          };
          await fs5.writeJSON(pkgJsonPath, pkgJson, { spaces: 2 });
        }
      }
    }
    const packageJsonPath = path6.join(TEMP_DIR, "package.json");
    await fs5.writeFile(
      packageJsonPath,
      JSON.stringify({ type: "module" }, null, 2)
    );
    logger.info("\u{1F4DD} Creating entry point...");
    const entryContent = await createEntryPoint(
      flowConfig,
      buildOptions,
      packagePaths
    );
    const entryPath = path6.join(TEMP_DIR, "entry.js");
    await fs5.writeFile(entryPath, entryContent);
    logger.info("\u26A1 Bundling with esbuild...");
    const outputPath = path6.resolve(buildOptions.output);
    await fs5.ensureDir(path6.dirname(outputPath));
    const esbuildOptions = createEsbuildOptions(
      buildOptions,
      entryPath,
      outputPath,
      TEMP_DIR,
      packagePaths,
      logger
    );
    try {
      await esbuild.build(esbuildOptions);
    } catch (buildError) {
      throw createBuildError(
        buildError,
        buildOptions.code || ""
      );
    }
    logger.gray(`Output: ${outputPath}`);
    let stats;
    if (showStats) {
      stats = await collectBundleStats(
        outputPath,
        buildOptions.packages,
        bundleStartTime,
        entryContent
      );
    }
    if (!buildOptions.tempDir) {
      await fs5.remove(TEMP_DIR);
      logger.debug("Cleaned up temporary files");
    }
    return stats;
  } catch (error) {
    if (!buildOptions.tempDir) {
      await fs5.remove(TEMP_DIR).catch(() => {
      });
    }
    throw error;
  }
}
async function collectBundleStats(outputPath, packages, startTime, entryContent) {
  const stats = await fs5.stat(outputPath);
  const totalSize = stats.size;
  const buildTime = Date.now() - startTime;
  const packageStats = Object.entries(packages).map(([name, pkg]) => {
    const importPattern = new RegExp(`from\\s+['"]${name}['"]`, "g");
    const namedImportPattern = new RegExp(
      `import\\s+\\{[^}]*\\}\\s+from\\s+['"]${name}['"]`,
      "g"
    );
    const hasImports = importPattern.test(entryContent) || namedImportPattern.test(entryContent);
    const packagesCount = Object.keys(packages).length;
    const estimatedSize = hasImports ? Math.floor(totalSize / packagesCount) : 0;
    return {
      name: `${name}@${pkg.version || "latest"}`,
      size: estimatedSize
    };
  });
  const hasWildcardImports = /import\s+\*\s+as\s+\w+\s+from/.test(entryContent);
  const treeshakingEffective = !hasWildcardImports;
  return {
    totalSize,
    packages: packageStats,
    buildTime,
    treeshakingEffective
  };
}
function createEsbuildOptions(buildOptions, entryPath, outputPath, tempDir, packagePaths, logger) {
  const alias = {};
  const baseOptions = {
    entryPoints: [entryPath],
    bundle: true,
    format: buildOptions.format,
    platform: buildOptions.platform,
    outfile: outputPath,
    absWorkingDir: tempDir,
    // Resolve modules from temp directory
    // alias removed - not needed with absWorkingDir
    mainFields: ["module", "main"],
    // Prefer ESM over CJS
    treeShaking: true,
    logLevel: "error",
    minify: buildOptions.minify,
    sourcemap: buildOptions.sourcemap,
    resolveExtensions: [".mjs", ".js", ".ts", ".json"],
    // Prefer .mjs
    // Enhanced minification options when minify is enabled
    ...buildOptions.minify && {
      minifyWhitespace: buildOptions.minifyOptions?.whitespace ?? true,
      minifyIdentifiers: buildOptions.minifyOptions?.identifiers ?? true,
      minifySyntax: buildOptions.minifyOptions?.syntax ?? true,
      legalComments: buildOptions.minifyOptions?.legalComments ?? "none",
      keepNames: buildOptions.minifyOptions?.keepNames ?? false,
      charset: "utf8"
    }
  };
  if (buildOptions.platform === "browser") {
    baseOptions.define = {
      "process.env.NODE_ENV": '"production"',
      global: "globalThis"
    };
    baseOptions.external = buildOptions.external || [];
  } else if (buildOptions.platform === "node") {
    const nodeBuiltins = [
      "crypto",
      "fs",
      "path",
      "os",
      "util",
      "stream",
      "buffer",
      "events",
      "http",
      "https",
      "url",
      "querystring",
      "zlib"
    ];
    const npmPackages = ["express", "express/*", "cors", "cors/*"];
    baseOptions.external = buildOptions.external ? [...nodeBuiltins, ...npmPackages, ...buildOptions.external] : [...nodeBuiltins, ...npmPackages];
  }
  if (buildOptions.target) {
    baseOptions.target = buildOptions.target;
  } else if (buildOptions.platform === "node") {
    baseOptions.target = "node18";
  } else {
    baseOptions.target = "es2018";
  }
  return baseOptions;
}
function packageNameToVariable(packageName) {
  return packageName.replace("@", "_").replace(/[/-]/g, "_").split("_").map(
    (part, i) => i === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)
  ).join("");
}
function detectDestinationPackages(flowConfig) {
  const destinationPackages = /* @__PURE__ */ new Set();
  const destinations = flowConfig.destinations;
  if (destinations) {
    for (const [destKey, destConfig] of Object.entries(destinations)) {
      if (typeof destConfig === "object" && destConfig !== null && "package" in destConfig && typeof destConfig.package === "string") {
        destinationPackages.add(destConfig.package);
      }
    }
  }
  return destinationPackages;
}
function generateImportStatements(packages, destinationPackages) {
  const importStatements = [];
  const examplesMappings = [];
  for (const [packageName, packageConfig] of Object.entries(packages)) {
    if (packageConfig.imports && packageConfig.imports.length > 0) {
      const uniqueImports = [...new Set(packageConfig.imports)];
      const defaultImports = [];
      const namedImports = [];
      for (const imp of uniqueImports) {
        if (imp.startsWith("default as ")) {
          defaultImports.push(imp.replace("default as ", ""));
        } else {
          namedImports.push(imp);
        }
      }
      if (defaultImports.length > 0) {
        for (const defaultImport of defaultImports) {
          importStatements.push(
            `import ${defaultImport} from '${packageName}';`
          );
        }
      }
      if (namedImports.length > 0) {
        const importList = namedImports.join(", ");
        importStatements.push(
          `import { ${importList} } from '${packageName}';`
        );
      }
      const examplesImport = uniqueImports.find(
        (imp) => imp.includes("examples as ")
      );
      if (examplesImport) {
        const examplesVarName = examplesImport.split(" as ")[1];
        const destinationMatch = packageName.match(
          /@walkeros\/web-destination-(.+)$/
        );
        if (destinationMatch) {
          const destinationName = destinationMatch[1];
          examplesMappings.push(
            `  ${destinationName}: typeof ${examplesVarName} !== 'undefined' ? ${examplesVarName} : undefined`
          );
        }
      }
    } else {
      const varName = packageNameToVariable(packageName);
      importStatements.push(
        `import * as ${varName} from '${packageName}'; // Consider specifying explicit imports`
      );
    }
  }
  return { importStatements, examplesMappings };
}
async function processTemplate(flowConfig, buildOptions) {
  if (buildOptions.template) {
    const templateEngine = new TemplateEngine();
    const flowWithProps = flowConfig;
    return await templateEngine.process(
      buildOptions.template,
      buildOptions.code || "",
      // Pass user code as parameter (empty if undefined)
      flowWithProps.sources || {},
      flowWithProps.destinations || {},
      flowWithProps.collector || {},
      buildOptions
      // Pass build config to template
    );
  } else {
    return buildOptions.code || "";
  }
}
function wrapCodeForFormat(code, format, hasTemplate) {
  if (hasTemplate) {
    return code;
  }
  if (format === "esm") {
    const hasExport = /^\s*export\s/m.test(code);
    if (!hasExport) {
      return `export default ${code}`;
    }
  }
  return code;
}
function assembleFinalCode(importStatements, examplesObject, wrappedCode, format) {
  const importsCode = importStatements.join("\n");
  let finalCode = importsCode ? `${importsCode}

${examplesObject}${wrappedCode}` : `${examplesObject}${wrappedCode}`;
  if (examplesObject && format === "esm") {
    finalCode += `

export { examples };`;
  }
  return finalCode;
}
async function createEntryPoint(flowConfig, buildOptions, packagePaths) {
  const destinationPackages = detectDestinationPackages(flowConfig);
  const { importStatements } = generateImportStatements(
    buildOptions.packages,
    destinationPackages
  );
  const examplesObject = "";
  const templatedCode = await processTemplate(flowConfig, buildOptions);
  const wrappedCode = wrapCodeForFormat(
    templatedCode,
    buildOptions.format,
    !!buildOptions.template
  );
  return assembleFinalCode(
    importStatements,
    examplesObject,
    wrappedCode,
    buildOptions.format
  );
}
function createBuildError(buildError, code) {
  if (!buildError.errors || buildError.errors.length === 0) {
    return new Error(`Build failed: ${buildError.message || buildError}`);
  }
  const firstError = buildError.errors[0];
  const location = firstError.location;
  if (location && location.file && location.file.includes("entry.js")) {
    const line = location.line;
    const column = location.column;
    const codeLines = code.split("\n");
    const errorLine = codeLines[line - 1] || "";
    return new Error(
      `Code syntax error at line ${line}, column ${column}:
  ${errorLine}
  ${" ".repeat(column - 1)}^
${firstError.text}`
    );
  }
  return new Error(
    `Build error: ${firstError.text}
` + (location ? `  at ${location.file}:${location.line}:${location.column}` : "")
  );
}

// src/commands/bundle/stats.ts
function displayStats(stats, logger) {
  logger.info("\n\u{1F4CA} Bundle Statistics");
  logger.info("\u2500".repeat(50));
  const sizeKB = formatBytes(stats.totalSize);
  logger.info(`Total Size: ${sizeKB} KB`);
  const timeSeconds = (stats.buildTime / 1e3).toFixed(2);
  logger.info(`Build Time: ${timeSeconds}s`);
  const treeshakingStatus = stats.treeshakingEffective ? "\u2705 Effective" : "\u26A0\uFE0F  Not optimal (consider using named imports)";
  logger.info(`Tree-shaking: ${treeshakingStatus}`);
  if (stats.packages.length > 0) {
    logger.info(`
Package Breakdown:`);
    stats.packages.forEach((pkg) => {
      if (pkg.size > 0) {
        const pkgSizeKB = formatBytes(pkg.size);
        logger.info(`  \u2022 ${pkg.name}: ${pkgSizeKB} KB`);
      }
    });
  }
  logger.info("\u2500".repeat(50));
}

// src/commands/bundle/index.ts
async function bundleCommand(options) {
  const timer = createTimer();
  timer.start();
  const logger = createCommandLogger(options);
  const dockerArgs = buildCommonDockerArgs(options);
  if (options.env) dockerArgs.push("--env", options.env);
  if (options.all) dockerArgs.push("--all");
  if (options.stats) dockerArgs.push("--stats");
  if (options.cache === false) dockerArgs.push("--no-cache");
  await executeCommand(
    async () => {
      try {
        if (options.env && options.all) {
          throw new Error("Cannot use both --env and --all flags together");
        }
        logger.info("\u{1F4E6} Reading configuration...");
        const configPath = options.config;
        const rawConfig = await loadJsonConfig(configPath);
        const configsToBundle = options.all ? loadAllEnvironments(rawConfig, { configPath, logger }) : [
          loadBundleConfig(rawConfig, {
            configPath,
            environment: options.env,
            logger
          })
        ];
        const results = [];
        for (const {
          flowConfig,
          buildOptions,
          environment,
          isMultiEnvironment
        } of configsToBundle) {
          try {
            if (options.cache !== void 0) {
              buildOptions.cache = options.cache;
            }
            if (isMultiEnvironment || options.all) {
              logger.info(`
\u{1F527} Building environment: ${environment}`);
            } else {
              logger.info("\u{1F527} Starting bundle process...");
            }
            const shouldCollectStats = options.stats || options.json;
            const stats = await bundleCore(
              flowConfig,
              buildOptions,
              logger,
              shouldCollectStats
            );
            results.push({
              environment,
              success: true,
              stats
            });
            if (!options.json && !options.all && options.stats && stats) {
              displayStats(stats, logger);
            }
          } catch (error) {
            const errorMessage = getErrorMessage(error);
            results.push({
              environment,
              success: false,
              error: errorMessage
            });
            if (!options.all) {
              throw error;
            }
          }
        }
        const duration = timer.end() / 1e3;
        const successCount = results.filter((r) => r.success).length;
        const failureCount = results.filter((r) => !r.success).length;
        if (options.json) {
          const outputLogger = createLogger({ silent: false, json: false });
          const output = failureCount === 0 ? createSuccessOutput(
            {
              environments: results,
              summary: {
                total: results.length,
                success: successCount,
                failed: failureCount
              }
            },
            duration
          ) : createErrorOutput(
            `${failureCount} environment(s) failed to build`,
            duration
          );
          outputLogger.log("white", JSON.stringify(output, null, 2));
        } else {
          if (options.all) {
            logger.info(`
\u{1F4CA} Build Summary:`);
            logger.info(`   Total: ${results.length}`);
            logger.success(`   \u2705 Success: ${successCount}`);
            if (failureCount > 0) {
              logger.error(`   \u274C Failed: ${failureCount}`);
            }
          }
          if (failureCount === 0) {
            logger.success(
              `
\u2705 Bundle created successfully in ${timer.format()}`
            );
          } else {
            throw new Error(`${failureCount} environment(s) failed to build`);
          }
        }
      } catch (error) {
        const duration = timer.getElapsed() / 1e3;
        const errorMessage = getErrorMessage(error);
        if (options.json) {
          const outputLogger = createLogger({ silent: false, json: false });
          const output = createErrorOutput(errorMessage, duration);
          outputLogger.log("white", JSON.stringify(output, null, 2));
        } else {
          logger.error("\u274C Bundle failed:");
          logger.error(errorMessage);
        }
        process.exit(1);
      }
    },
    "bundle",
    dockerArgs,
    options,
    logger,
    options.config
  );
}
async function bundle(configOrPath, options = {}) {
  let rawConfig;
  if (typeof configOrPath === "string") {
    rawConfig = await loadJsonConfig(configOrPath);
  } else {
    rawConfig = configOrPath;
  }
  const { flowConfig, buildOptions } = parseBundleConfig(rawConfig);
  if (options.cache !== void 0) {
    buildOptions.cache = options.cache;
  }
  const logger = createCommandLogger(options);
  return await bundleCore(
    flowConfig,
    buildOptions,
    logger,
    options.stats ?? false
  );
}

// src/commands/simulate/simulator.ts
import path7 from "path";
import fs7 from "fs-extra";

// src/commands/simulate/tracker.ts
var CallTracker = class {
  calls = /* @__PURE__ */ new Map();
  /**
   * Wrap a function to track its calls
   */
  wrapFunction(name, fn) {
    const self = this;
    const targetFn = fn || (() => {
    });
    return new Proxy(targetFn, {
      apply(_target, thisArg, args) {
        self.logCall(name, args);
        return targetFn.apply(thisArg, args);
      }
    });
  }
  /**
   * Wrap an environment object, tracking specified paths
   *
   * @param env - Environment object (from destination's examples/env.ts)
   * @param paths - Paths to track (e.g., ['gtag:window.gtag', 'gtag:window.dataLayer.push'])
   */
  wrapEnv(env, paths) {
    const wrapped = {};
    for (const [key, value] of Object.entries(env)) {
      if (typeof value === "object" && value !== null) {
        wrapped[key] = Array.isArray(value) ? [...value] : { ...value };
      } else {
        wrapped[key] = value;
      }
    }
    for (const fullPath of paths) {
      const [destKey, ...pathParts] = fullPath.split(":");
      const path11 = pathParts.join(":");
      if (!path11) continue;
      const cleanPath = path11.replace(/^call:/, "");
      const parts = cleanPath.split(".");
      let current = wrapped;
      let source = env;
      for (let i = 0; i < parts.length - 1; i++) {
        const part = parts[i];
        if (!current[part]) {
          current[part] = {};
        }
        current = current[part];
        source = source && typeof source[part] === "object" && source[part] !== null ? source[part] : void 0;
      }
      const finalKey = parts[parts.length - 1];
      const originalFn = source?.[finalKey];
      current[finalKey] = this.wrapFunction(
        `${destKey}:${cleanPath}`,
        typeof originalFn === "function" ? originalFn : void 0
      );
    }
    return wrapped;
  }
  logCall(fullPath, args) {
    const [destKey, ...pathParts] = fullPath.split(":");
    const apiPath = pathParts.join(":");
    if (!this.calls.has(destKey)) {
      this.calls.set(destKey, []);
    }
    this.calls.get(destKey).push({
      type: "call",
      path: apiPath,
      args,
      timestamp: Date.now()
    });
  }
  getCalls() {
    return Object.fromEntries(this.calls);
  }
  reset() {
    this.calls.clear();
  }
};

// src/commands/simulate/jsdom-executor.ts
import { JSDOM, VirtualConsole } from "jsdom";
import fs6 from "fs-extra";
function buildSandboxFromEnvs(envs, destinations, tracker) {
  const baseBrowserMocks = {
    Image: class MockImage {
      src = "";
      onload = (() => {
      });
      onerror = (() => {
      });
    },
    fetch: async () => ({ ok: true, json: async () => ({}) }),
    location: { href: "http://localhost" },
    navigator: { userAgent: "Mozilla/5.0 (walkerOS Simulation)" }
  };
  const sandbox = {
    window: { ...baseBrowserMocks },
    document: {}
  };
  for (const [destKey, destConfig] of Object.entries(destinations)) {
    const destEnv = envs[destKey];
    if (!destEnv?.push) continue;
    const mockEnv = destEnv.push;
    const trackPaths = destEnv.simulation || [];
    const trackedEnv = tracker.wrapEnv(
      mockEnv,
      trackPaths.map((p) => `${destKey}:${p}`)
    );
    if (trackedEnv.window && typeof trackedEnv.window === "object") {
      Object.assign(sandbox.window, trackedEnv.window);
    }
    if (trackedEnv.document && typeof trackedEnv.document === "object") {
      Object.assign(sandbox.document, trackedEnv.document);
    }
  }
  return sandbox;
}
function waitForWindowProperty(window, prop, timeout = 5e3) {
  return new Promise((resolve, reject) => {
    const start = Date.now();
    const check = () => {
      if (window[prop] !== void 0) {
        resolve();
      } else if (Date.now() - start > timeout) {
        reject(
          new Error(
            `Timeout waiting for window.${prop}. IIFE may have failed to execute or assign to window.`
          )
        );
      } else {
        setImmediate(check);
      }
    };
    check();
  });
}
async function executeInJSDOM(bundlePath, destinations, event, tracker, envs, timeout = 1e4) {
  const start = Date.now();
  const virtualConsole = new VirtualConsole();
  const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>", {
    url: "http://localhost",
    runScripts: "dangerously",
    // Allow script execution
    resources: "usable",
    virtualConsole
  });
  const { window } = dom;
  const sandbox = buildSandboxFromEnvs(envs, destinations, tracker);
  Object.assign(window, sandbox.window);
  Object.assign(window.document, sandbox.document);
  const bundleCode = await fs6.readFile(bundlePath, "utf8");
  try {
    window.eval(bundleCode);
  } catch (error) {
    throw new Error(`Bundle execution failed: ${getErrorMessage(error)}`);
  }
  try {
    await waitForWindowProperty(
      window,
      "collector",
      timeout
    );
    await waitForWindowProperty(
      window,
      "elb",
      timeout
    );
  } catch (error) {
    throw new Error(
      `Window property assignment failed: ${getErrorMessage(error)}`
    );
  }
  const { collector, elb } = window;
  let elbResult;
  try {
    elbResult = await elb(event.name, event.data);
  } catch (error) {
    throw new Error(`Event execution failed: ${getErrorMessage(error)}`);
  }
  return {
    collector,
    elb,
    elbResult,
    usage: tracker.getCalls(),
    duration: Date.now() - start
  };
}

// src/commands/simulate/env-loader.ts
async function loadDestinationEnvs(destinations) {
  const envs = {};
  for (const [destKey, destConfig] of Object.entries(destinations)) {
    const typedConfig = destConfig;
    if (!typedConfig.package) {
      continue;
    }
    try {
      const packageName = typedConfig.package;
      const isDemoPackage = packageName.includes("-demo");
      const importPath = isDemoPackage ? packageName : `${packageName}/dev`;
      const module = await import(importPath);
      const examplesModule = module.examples || module.default?.examples;
      const envModule = examplesModule?.env;
      if (envModule?.push) {
        envs[destKey] = {
          init: envModule.init,
          push: envModule.push,
          simulation: envModule.simulation || []
        };
      }
    } catch (error) {
      console.warn(
        `Warning: Could not load env for destination "${destKey}": ${error instanceof Error ? error.message : String(error)}`
      );
    }
  }
  return envs;
}

// src/commands/simulate/simulator.ts
function generateId() {
  return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
}
async function simulateCore(configPath, event, options = {}) {
  const logger = createLogger({
    verbose: options.verbose || false,
    silent: options.silent || false,
    json: options.json || false
  });
  try {
    logger.info("\u{1F3AF} Starting walkerOS simulation...");
    logger.info("\u{1F4E6} Loading bundle configuration...");
    const fullConfigPath = path7.resolve(configPath);
    const rawConfig = await loadJsonConfig(fullConfigPath);
    parseBundleConfig(rawConfig);
    logger.info(`\u{1F680} Executing simulation with event: ${JSON.stringify(event)}`);
    const result = await executeSimulation(event, fullConfigPath);
    if (result.success) {
      logger.info(`\u2705 Simulation completed successfully`);
    } else {
      logger.error(`\u274C Simulation failed: ${result.error}`);
    }
    return result;
  } catch (error) {
    const errorMessage = getErrorMessage(error);
    logger.error(`\u{1F4A5} Simulation error: ${errorMessage}`);
    return {
      success: false,
      error: errorMessage
    };
  }
}
function formatSimulationResult(result, options = {}) {
  if (options.json) {
    const output = {
      result: result.elbResult,
      usage: result.usage,
      duration: result.duration
    };
    return JSON.stringify(output, null, 2);
  }
  if (result.success) {
    return "\u2705 Simulation completed successfully";
  } else {
    return `\u274C Simulation failed: ${result.error}`;
  }
}
async function executeSimulation(event, configPath) {
  const startTime = Date.now();
  let bundlePath;
  const tempDir = getTempDir();
  try {
    if (!isObject(event) || !("name" in event) || typeof event.name !== "string") {
      throw new Error(
        'Event must be an object with a "name" property of type string'
      );
    }
    const typedEvent = event;
    await fs7.ensureDir(tempDir);
    const rawConfig = await loadJsonConfig(configPath);
    const { flowConfig, buildOptions } = parseBundleConfig(rawConfig);
    const packagesArray = Object.entries(buildOptions.packages).map(
      ([name, packageConfig]) => ({
        name,
        version: (typeof packageConfig === "object" && packageConfig !== null && "version" in packageConfig && typeof packageConfig.version === "string" ? packageConfig.version : void 0) || "latest"
      })
    );
    const packagePaths = await downloadPackages(
      packagesArray,
      tempDir,
      // downloadPackages will add 'node_modules' subdirectory itself
      createLogger({ silent: true }),
      buildOptions.cache
    );
    const tracker = new CallTracker();
    const tempOutput = path7.join(
      tempDir,
      `simulation-bundle-${generateId()}.js`
    );
    const destinations = flowConfig.destinations;
    const simulationBuildOptions = {
      ...buildOptions,
      code: buildOptions.code || "",
      // No code modification - use original
      output: tempOutput,
      tempDir,
      // Use same temp dir for bundle
      format: "iife",
      // ← Test actual production format!
      platform: "browser",
      // ← Browser platform for IIFE
      windowCollector: "collector",
      // ← Ensure window assignment
      windowElb: "elb"
    };
    await bundleCore(
      flowConfig,
      simulationBuildOptions,
      createLogger({ silent: true }),
      false
    );
    bundlePath = tempOutput;
    const envs = await loadDestinationEnvs(destinations || {});
    const result = await executeInJSDOM(
      tempOutput,
      destinations || {},
      typedEvent,
      tracker,
      envs,
      // Pass dynamically loaded envs
      1e4
      // 10s timeout
    );
    const elbResult = result.elbResult;
    const usage = result.usage;
    const duration = Date.now() - startTime;
    return {
      success: true,
      elbResult,
      usage,
      duration,
      logs: []
    };
  } catch (error) {
    const duration = Date.now() - startTime;
    return {
      success: false,
      error: getErrorMessage(error),
      duration
    };
  } finally {
    if (tempDir) {
      await fs7.remove(tempDir).catch(() => {
      });
    }
  }
}

// src/commands/simulate/index.ts
async function simulateCommand(options) {
  const logger = createCommandLogger(options);
  const dockerArgs = buildCommonDockerArgs(options);
  if (options.event) dockerArgs.push("--event", options.event);
  await executeCommand(
    async () => {
      const startTime = Date.now();
      try {
        const event = await loadJsonFromSource(options.event, {
          name: "event"
        });
        const result = await simulateCore(options.config, event, {
          json: options.json,
          verbose: options.verbose,
          silent: options.silent
        });
        const resultWithDuration = {
          ...result,
          duration: (Date.now() - startTime) / 1e3
        };
        const outputLogger = createLogger({ silent: false, json: false });
        const output = formatSimulationResult(resultWithDuration, {
          json: options.json
        });
        outputLogger.log("white", output);
        if (!result.success) {
          process.exit(1);
        }
      } catch (error) {
        const errorMessage = getErrorMessage(error);
        if (options.json) {
          const outputLogger = createLogger({ silent: false, json: false });
          const errorOutput = JSON.stringify(
            {
              success: false,
              error: errorMessage,
              duration: (Date.now() - startTime) / 1e3
            },
            null,
            2
          );
          outputLogger.log("white", errorOutput);
        } else {
          const errorLogger = createLogger({ silent: false, json: false });
          errorLogger.error(`\u274C Simulate command failed: ${errorMessage}`);
        }
        process.exit(1);
      }
    },
    "simulate",
    dockerArgs,
    options,
    logger,
    options.config
  );
}
async function simulate(configOrPath, event, options = {}) {
  if (typeof configOrPath !== "string") {
    throw new Error(
      "simulate() currently only supports config file paths. Config object support will be added in a future version. Please provide a path to a configuration file."
    );
  }
  return await simulateCore(configOrPath, event, {
    json: options.json ?? false,
    verbose: options.verbose ?? false
  });
}

// src/commands/push/index.ts
import path8 from "path";
import os2 from "os";
import { JSDOM as JSDOM2, VirtualConsole as VirtualConsole2 } from "jsdom";
import fs8 from "fs-extra";
async function pushCommand(options) {
  const logger = createCommandLogger(options);
  const dockerArgs = buildCommonDockerArgs(options);
  dockerArgs.push("--event", options.event);
  if (options.env) dockerArgs.push("--env", options.env);
  await executeCommand(
    async () => {
      const startTime = Date.now();
      try {
        logger.info("\u{1F4E5} Loading event...");
        const event = await loadJsonFromSource(options.event, {
          name: "event"
        });
        if (!event || typeof event !== "object" || !("name" in event) || typeof event.name !== "string") {
          throw new Error(
            'Event must be an object with a "name" property (string)'
          );
        }
        if (!event.name.includes(" ")) {
          logger.warn(
            `Event name "${event.name}" should follow "ENTITY ACTION" format (e.g., "page view")`
          );
        }
        logger.info("\u{1F4E6} Loading flow configuration...");
        const configPath = path8.resolve(options.config);
        const rawConfig = await loadJsonConfig(configPath);
        const { flowConfig, buildOptions, environment, isMultiEnvironment } = loadBundleConfig(rawConfig, {
          configPath: options.config,
          environment: options.env,
          logger
        });
        const platform = flowConfig.platform;
        logger.info("\u{1F528} Bundling flow configuration...");
        const tempPath = path8.join(
          os2.tmpdir(),
          `walkeros-push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.${platform === "web" ? "js" : "mjs"}`
        );
        const configWithOutput = {
          flow: flowConfig,
          build: {
            ...buildOptions,
            output: tempPath,
            // Web uses IIFE for browser-like execution, server uses ESM
            format: platform === "web" ? "iife" : "esm",
            platform: platform === "web" ? "browser" : "node",
            ...platform === "web" && {
              windowCollector: "collector",
              windowElb: "elb"
            }
          }
        };
        await bundle(configWithOutput, {
          cache: true,
          verbose: options.verbose,
          silent: !options.verbose
        });
        logger.debug(`Bundle created: ${tempPath}`);
        let result;
        if (platform === "web") {
          logger.info("\u{1F310} Executing in web environment (JSDOM)...");
          result = await executeWebPush(tempPath, event, logger);
        } else if (platform === "server") {
          logger.info("\u{1F5A5}\uFE0F  Executing in server environment (Node.js)...");
          result = await executeServerPush(tempPath, event, logger);
        } else {
          throw new Error(`Unsupported platform: ${platform}`);
        }
        const duration = Date.now() - startTime;
        if (options.json) {
          const outputLogger = createLogger({ silent: false, json: false });
          outputLogger.log(
            "white",
            JSON.stringify(
              {
                success: result.success,
                event: result.elbResult,
                duration
              },
              null,
              2
            )
          );
        } else {
          if (result.success) {
            logger.success("\u2705 Event pushed successfully");
            if (result.elbResult && typeof result.elbResult === "object") {
              const pushResult = result.elbResult;
              if ("id" in pushResult && pushResult.id) {
                logger.info(`   Event ID: ${pushResult.id}`);
              }
              if ("entity" in pushResult && pushResult.entity) {
                logger.info(`   Entity: ${pushResult.entity}`);
              }
              if ("action" in pushResult && pushResult.action) {
                logger.info(`   Action: ${pushResult.action}`);
              }
            }
            logger.info(`   Duration: ${duration}ms`);
          } else {
            logger.error(`\u274C Push failed: ${result.error}`);
            process.exit(1);
          }
        }
        try {
          await fs8.remove(tempPath);
        } catch {
        }
      } catch (error) {
        const duration = Date.now() - startTime;
        const errorMessage = getErrorMessage(error);
        if (options.json) {
          const outputLogger = createLogger({ silent: false, json: false });
          outputLogger.log(
            "white",
            JSON.stringify(
              {
                success: false,
                error: errorMessage,
                duration
              },
              null,
              2
            )
          );
        } else {
          logger.error(`\u274C Push command failed: ${errorMessage}`);
        }
        process.exit(1);
      }
    },
    "push",
    dockerArgs,
    options,
    logger,
    options.config
  );
}
async function executeWebPush(bundlePath, event, logger) {
  const startTime = Date.now();
  try {
    const virtualConsole = new VirtualConsole2();
    const dom = new JSDOM2("<!DOCTYPE html><html><body></body></html>", {
      url: "http://localhost",
      runScripts: "dangerously",
      resources: "usable",
      virtualConsole
    });
    const { window } = dom;
    logger.debug("Loading bundle...");
    const bundleCode = await fs8.readFile(bundlePath, "utf8");
    window.eval(bundleCode);
    logger.debug("Waiting for elb...");
    await waitForWindowProperty2(
      window,
      "elb",
      5e3
    );
    const windowObj = window;
    const elb = windowObj.elb;
    logger.info(`Pushing event: ${event.name}`);
    const eventData = event.data || {};
    const elbResult = await elb(event.name, eventData);
    return {
      success: true,
      elbResult,
      duration: Date.now() - startTime
    };
  } catch (error) {
    return {
      success: false,
      duration: Date.now() - startTime,
      error: getErrorMessage(error)
    };
  }
}
async function executeServerPush(bundlePath, event, logger, timeout = 6e4) {
  const startTime = Date.now();
  try {
    const timeoutPromise = new Promise((_, reject) => {
      setTimeout(
        () => reject(new Error(`Server push timeout after ${timeout}ms`)),
        timeout
      );
    });
    const executePromise = (async () => {
      logger.debug("Importing bundle...");
      const flowModule = await import(bundlePath);
      if (!flowModule.default || typeof flowModule.default !== "function") {
        throw new Error("Bundle does not export default factory function");
      }
      logger.debug("Calling factory function...");
      const result = await flowModule.default();
      if (!result || !result.elb || typeof result.elb !== "function") {
        throw new Error(
          "Factory function did not return valid result with elb"
        );
      }
      const { elb } = result;
      logger.info(`Pushing event: ${event.name}`);
      const eventData = event.data || {};
      const elbResult = await elb(event.name, eventData);
      return {
        success: true,
        elbResult,
        duration: Date.now() - startTime
      };
    })();
    return await Promise.race([executePromise, timeoutPromise]);
  } catch (error) {
    return {
      success: false,
      duration: Date.now() - startTime,
      error: getErrorMessage(error)
    };
  }
}
function waitForWindowProperty2(window, prop, timeout = 5e3) {
  return new Promise((resolve, reject) => {
    const start = Date.now();
    const check = () => {
      if (window[prop] !== void 0) {
        resolve();
      } else if (Date.now() - start > timeout) {
        reject(
          new Error(
            `Timeout waiting for window.${prop}. IIFE may have failed to execute.`
          )
        );
      } else {
        setImmediate(check);
      }
    };
    check();
  });
}

// src/commands/run/index.ts
import path10 from "path";

// src/commands/run/validators.ts
import { existsSync } from "fs";
var VALID_MODES = ["collect", "serve"];
function validateMode(mode) {
  if (!VALID_MODES.includes(mode)) {
    throw new Error(
      `Invalid mode: "${mode}"
   Valid modes: ${VALID_MODES.join(", ")}
   Example: walkeros run collect ./flow.json`
    );
  }
}
function validateFlowFile(filePath) {
  const absolutePath = resolveAsset(filePath, "bundle");
  if (!existsSync(absolutePath)) {
    throw new Error(
      `Flow file not found: ${filePath}
   Resolved path: ${absolutePath}
   Make sure the file exists and the path is correct`
    );
  }
  return absolutePath;
}
function validatePort(port) {
  if (!Number.isInteger(port) || port < 1 || port > 65535) {
    throw new Error(
      `Invalid port: ${port}
   Port must be an integer between 1 and 65535
   Example: --port 8080`
    );
  }
}

// src/commands/run/utils.ts
import path9 from "path";
import os3 from "os";
async function prepareBundleForRun(configPath, options) {
  const rawConfig = await loadJsonConfig(configPath);
  const tempPath = path9.join(
    os3.tmpdir(),
    `walkeros-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.mjs`
  );
  const existingBuild = typeof rawConfig === "object" && rawConfig !== null && "build" in rawConfig && typeof rawConfig.build === "object" ? rawConfig.build : {};
  const configWithOutput = {
    ...rawConfig,
    build: {
      ...existingBuild,
      output: tempPath
    }
  };
  await bundle(configWithOutput, {
    cache: true,
    verbose: options.verbose,
    silent: options.silent
  });
  return tempPath;
}
function isPreBuiltConfig(configPath) {
  return configPath.endsWith(".mjs") || configPath.endsWith(".js") || configPath.endsWith(".cjs");
}

// src/commands/run/execution.ts
import { runFlow, runServeMode } from "@walkeros/docker";
async function executeRunLocal(mode, flowPath, options) {
  switch (mode) {
    case "collect": {
      if (!flowPath) {
        throw new Error("Flow path is required for collect mode");
      }
      const config = {
        port: options.port,
        host: options.host
      };
      await runFlow(flowPath, config);
      break;
    }
    case "serve": {
      const config = {
        port: options.port,
        host: options.host,
        serveName: options.serveName,
        servePath: options.servePath,
        filePath: flowPath || void 0
      };
      await runServeMode(config);
      break;
    }
    default:
      throw new Error(`Unknown mode: ${mode}`);
  }
}

// src/commands/run/index.ts
async function runCommand(mode, options) {
  const timer = createTimer();
  timer.start();
  const logger = createCommandLogger(options);
  try {
    validateMode(mode);
    const configPath = validateFlowFile(options.config);
    if (options.port !== void 0) {
      validatePort(options.port);
    }
    const isPreBuilt = isPreBuiltConfig(configPath);
    let flowPath = null;
    if (mode === "collect") {
      if (isPreBuilt) {
        flowPath = path10.resolve(configPath);
        if (!options.json && !options.silent) {
          logger.info(`\u{1F4E6} Using pre-built flow: ${path10.basename(flowPath)}`);
        }
      } else {
        if (!options.json && !options.silent) {
          logger.info("\u{1F528} Building flow bundle...");
        }
        flowPath = await prepareBundleForRun(configPath, {
          verbose: options.verbose,
          silent: options.json || options.silent
        });
        if (!options.json && !options.silent) {
          logger.success("\u2705 Bundle ready");
        }
      }
    }
    const executionMode = getExecutionMode(options);
    if (options.dryRun) {
      if (executionMode === "docker") {
        logger.info(
          `[DRY-RUN] Would execute in Docker: run ${mode} with runtime image`
        );
      } else {
        logger.info(`[DRY-RUN] Would execute locally: run ${mode}`);
      }
      return;
    }
    if (executionMode === "docker") {
      const dockerAvailable = await isDockerAvailable();
      if (!dockerAvailable) {
        throw new Error(
          "Docker is not available. Please install Docker or use --local flag to execute locally."
        );
      }
      if (!options.json && !options.silent) {
        logger.info("\u{1F433} Executing in production runtime container...");
      }
      await executeRunInDocker(mode, flowPath, {
        port: options.port,
        host: options.host,
        serveName: options.serveName,
        servePath: options.servePath,
        silent: options.silent
      });
    } else {
      if (!options.json && !options.silent) {
        const modeLabel = mode === "collect" ? "Collector" : "Server";
        logger.info(`\u{1F5A5}\uFE0F  Starting ${modeLabel} locally...`);
      }
      await executeRunLocal(mode, flowPath, {
        port: options.port,
        host: options.host,
        serveName: options.serveName,
        servePath: options.servePath
      });
    }
  } catch (error) {
    const duration = timer.getElapsed() / 1e3;
    const errorMessage = getErrorMessage(error);
    if (options.json) {
      const output = {
        success: false,
        mode,
        error: errorMessage,
        duration
      };
      console.log(JSON.stringify(output, null, 2));
    } else {
      logger.error("\u274C Run failed:");
      logger.error(errorMessage);
    }
    process.exit(1);
  }
}
async function run(mode, options) {
  const startTime = Date.now();
  try {
    validateMode(mode);
    let flowFile;
    if (typeof options.config === "string") {
      flowFile = validateFlowFile(options.config);
    } else {
      throw new Error("Programmatic run() requires config file path");
    }
    if (options.port !== void 0) {
      validatePort(options.port);
    }
    const isPreBuilt = isPreBuiltConfig(flowFile);
    let flowPath;
    if (isPreBuilt) {
      flowPath = path10.resolve(flowFile);
    } else {
      flowPath = await prepareBundleForRun(flowFile, {
        verbose: options.verbose,
        silent: true
      });
    }
    await executeRunLocal(mode, flowPath, {
      port: options.port,
      host: options.host,
      serveName: options.serveName,
      servePath: options.servePath
    });
    return {
      success: true,
      exitCode: 0,
      duration: Date.now() - startTime
    };
  } catch (error) {
    return {
      success: false,
      exitCode: 1,
      duration: Date.now() - startTime,
      error: getErrorMessage(error)
    };
  }
}

// src/index.ts
var __filename = fileURLToPath3(import.meta.url);
var __dirname = dirname(__filename);
var packageJson = JSON.parse(
  readFileSync2(join(__dirname, "../package.json"), "utf-8")
);
var VERSION = packageJson.version;
var program = new Command();
program.name("walkeros").description("walkerOS CLI - Bundle and deploy walkerOS components").version(VERSION);
program.command("bundle [file]").description("Bundle NPM packages with custom code").option(
  "-e, --env <name>",
  "environment to build (for multi-environment configs)"
).option("--all", "build all environments (for multi-environment configs)").option("-s, --stats", "show bundle statistics").option("--json", "output statistics in JSON format (implies --stats)").option("--no-cache", "disable package caching and download fresh packages").option("-v, --verbose", "verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
  await bundleCommand({
    config: file || "bundle.config.json",
    env: options.env,
    all: options.all,
    stats: options.stats,
    json: options.json,
    cache: options.cache,
    verbose: options.verbose,
    local: options.local,
    dryRun: options.dryRun,
    silent: options.silent
  });
});
program.command("simulate [file]").description("Simulate event processing and capture API calls").option(
  "-e, --event <source>",
  "Event to simulate (JSON string, file path, or URL)"
).option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
  await simulateCommand({
    config: file || "bundle.config.json",
    event: options.event,
    json: options.json,
    verbose: options.verbose,
    local: options.local,
    dryRun: options.dryRun,
    silent: options.silent
  });
});
program.command("push [file]").description("Push an event through the flow with real API execution").requiredOption(
  "-e, --event <source>",
  "Event to push (JSON string, file path, or URL)"
).option("--env <name>", "Environment name (for multi-environment configs)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("-s, --silent", "Suppress output").option("--local", "Execute in local Node.js instead of Docker").action(async (file, options) => {
  await pushCommand({
    config: file || "bundle.config.json",
    event: options.event,
    env: options.env,
    json: options.json,
    verbose: options.verbose,
    silent: options.silent,
    local: options.local
  });
});
var runCmd = program.command("run").description("Run walkerOS flows in collect or serve mode");
runCmd.command("collect [file]").description(
  "Run collector mode (event collection endpoint). Defaults to server-collect.mjs if no file specified."
).option("-p, --port <number>", "Port to listen on (default: 8080)", parseInt).option("-h, --host <address>", "Host address (default: 0.0.0.0)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
  await runCommand("collect", {
    config: file || "server-collect.mjs",
    port: options.port,
    host: options.host,
    json: options.json,
    verbose: options.verbose,
    local: options.local,
    dryRun: options.dryRun,
    silent: options.silent
  });
});
runCmd.command("serve [file]").description(
  "Run serve mode (single-file server for browser bundles). Defaults to baked-in web-serve.js if no file specified."
).option("-p, --port <number>", "Port to listen on (default: 8080)", parseInt).option("-h, --host <address>", "Host address (default: 0.0.0.0)").option("--name <filename>", "Filename in URL (default: walker.js)").option("--path <directory>", "URL directory path (e.g., libs/v1)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
  await runCommand("serve", {
    config: file || "web-serve.js",
    port: options.port,
    host: options.host,
    serveName: options.name,
    servePath: options.path,
    json: options.json,
    verbose: options.verbose,
    local: options.local,
    dryRun: options.dryRun,
    silent: options.silent
  });
});
program.parse();
export {
  bundle,
  bundleCommand,
  pushCommand,
  run,
  runCommand,
  simulate,
  simulateCommand
};
//# sourceMappingURL=index.js.map