import { createRequire as _cjsReq } from 'module'; if(typeof require === 'undefined') var require = _cjsReq(import.meta.url);
import {
  ChatApp,
  ensureAuthenticated,
  fetchSession,
  fetchSessionEvents,
  render_default,
  require_react,
  suppressScrollbackClear
} from "./chunk-7JJT3RNI.js";
import {
  BuildFailedError,
  BuildTimeoutError,
  BundleNotFoundError,
  GitError,
  buildBundledVersion,
  buildEphemeralVersion,
  formatGitError,
  readAgentFiles
} from "./chunk-EQUW4M5A.js";
import {
  Command,
  Option,
  getOutputMode,
  isQuietMode
} from "./chunk-YQWI6SUV.js";
import {
  open_default
} from "./chunk-56YCMGL3.js";
import "./chunk-6EX6E7WP.js";
import {
  pollForResponse,
  pollForResponseWithEvents
} from "./chunk-F3F5CUO3.js";
import {
  GuildAPIClient,
  getWorkspaceId,
  getWorkspaceSourceLabel,
  loadLocalConfig,
  parseEventFilter
} from "./chunk-RJHD6XTV.js";
import {
  ErrorCodes,
  debug,
  ensureInteractiveStdin,
  format,
  getCliVersion,
  handleAxiosError,
  hyperlink,
  readStdinAsJSON,
  readStdinAsText
} from "./chunk-JQRJ4A4S.js";
import "./chunk-M347HP6M.js";
import "./chunk-ENKEEJ45.js";
import "./chunk-VVSOU6ON.js";
import "./chunk-PNCUR4OB.js";
import "./chunk-X3ADGWOF.js";
import {
  __toESM
} from "./chunk-OYQ476FQ.js";

// src/commands/agent/test.ts
var import_react = __toESM(require_react(), 1);
import { access as access2 } from "fs/promises";
import path2 from "path";

// src/lib/validate-input-schema.ts
import * as fs from "fs/promises";
import * as path from "path";
import * as os from "os";
import { execFile } from "child_process";
import { promisify } from "util";
var execFileAsync = promisify(execFile);
function resolveSourceEntryPoint(agentDir, packageJson) {
  const exports = packageJson.exports;
  if (exports?.["."]) {
    const distPath = exports["."];
    const sourcePath = distPath.replace(/^\.\/dist\//, "").replace(/\.compiled\.js$/, ".ts").replace(/\.js$/, ".ts");
    return path.join(agentDir, sourcePath);
  }
  return path.join(agentDir, "agent.ts");
}
async function fileExists(filePath) {
  return fs.access(filePath).then(() => true).catch(() => false);
}
function extractZodDeclaration(source, match) {
  const startIndex = match.index;
  const afterEquals = match.index + match[0].length;
  let depth = 0;
  let foundOpen = false;
  let endIndex = afterEquals;
  let inString = null;
  for (let charIndex = afterEquals; charIndex < source.length; charIndex++) {
    const char = source[charIndex];
    if (inString) {
      if (char === "\\") {
        charIndex++;
      } else if (char === inString) {
        inString = null;
      }
      continue;
    }
    if (char === '"' || char === "'" || char === "`") {
      inString = char;
    } else if (char === "(") {
      depth++;
      foundOpen = true;
    } else if (char === ")") {
      depth--;
      if (foundOpen && depth === 0) {
        endIndex = charIndex + 1;
        if (source[endIndex] === ";") endIndex++;
        break;
      }
    }
  }
  if (!foundOpen) return null;
  return source.substring(startIndex, endIndex);
}
function extractInputSchema(source) {
  const inputPattern = /const\s+inputSchema\s*=\s*/;
  const inputMatch = inputPattern.exec(source);
  if (!inputMatch) return null;
  const inputBlock = extractZodDeclaration(source, inputMatch);
  if (!inputBlock) return null;
  const blocks = [];
  const zodDeclPattern = /const\s+\w+\s*=\s*z\s*\.\s*/g;
  let declMatch;
  while ((declMatch = zodDeclPattern.exec(source)) !== null) {
    if (declMatch.index >= inputMatch.index) break;
    const block = extractZodDeclaration(source, declMatch);
    if (block) blocks.push(block);
  }
  blocks.push(inputBlock);
  return blocks.join("\n");
}
async function validateInputSchema(agentDir, inputs) {
  const nodeModulesPath = path.join(agentDir, "node_modules");
  if (!await fileExists(nodeModulesPath)) {
    return {
      valid: true,
      skipped: true,
      reason: "run npm install for pre-build input validation"
    };
  }
  const pkgJsonPath = path.join(agentDir, "package.json");
  if (!await fileExists(pkgJsonPath)) {
    return {
      valid: true,
      skipped: true,
      reason: "no package.json found"
    };
  }
  const pkgJson = JSON.parse(await fs.readFile(pkgJsonPath, "utf-8"));
  let entryPoint = resolveSourceEntryPoint(agentDir, pkgJson);
  if (!await fileExists(entryPoint)) {
    const fallback = path.join(agentDir, "agent.ts");
    if (await fileExists(fallback)) {
      entryPoint = fallback;
    } else {
      return {
        valid: true,
        skipped: true,
        reason: `could not find agent source file (tried ${path.basename(entryPoint)})`
      };
    }
  }
  const agentSource = await fs.readFile(entryPoint, "utf-8");
  const schemaBlock = extractInputSchema(agentSource);
  if (!schemaBlock) {
    return {
      valid: true,
      skipped: true,
      reason: "could not find inputSchema definition in agent source"
    };
  }
  const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "guild-validate-"));
  try {
    const extractorSource = [
      `import { z } from "zod";`,
      schemaBlock,
      `const inputs = JSON.parse(process.argv[2]);`,
      `const errors = [];`,
      `for (let i = 0; i < inputs.length; i++) {`,
      `  try {`,
      `    inputSchema.parse(inputs[i]);`,
      `  } catch (e) {`,
      `    const issues = e.issues || [{ message: e.message }];`,
      `    errors.push({ index: i, issues: issues.map(iss => ({ message: iss.message, path: iss.path })) });`,
      `  }`,
      `}`,
      `if (errors.length > 0) {`,
      `  console.log(JSON.stringify({ valid: false, errors }));`,
      `} else {`,
      `  console.log(JSON.stringify({ valid: true }));`,
      `}`
    ].join("\n");
    const extractorPath = path.join(tmpDir, "validate.mjs");
    await fs.writeFile(extractorPath, extractorSource);
    const { build } = await import("esbuild");
    const bundlePath = path.join(tmpDir, "validate-bundle.mjs");
    await build({
      entryPoints: [extractorPath],
      bundle: true,
      format: "esm",
      target: "esnext",
      platform: "node",
      outfile: bundlePath,
      logLevel: "silent",
      nodePaths: [path.join(agentDir, "node_modules")]
    });
    const inputArg = JSON.stringify(inputs);
    const { stdout } = await execFileAsync("node", [bundlePath, inputArg], {
      cwd: agentDir,
      timeout: 1e4
    });
    const result = JSON.parse(stdout.trim());
    if (result.valid) {
      return { valid: true };
    }
    const flatErrors = [];
    for (const entry of result.errors) {
      for (const issue of entry.issues) {
        const prefix = inputs.length > 1 ? `Line ${entry.index + 1}: ` : "";
        flatErrors.push({
          message: `${prefix}${issue.message}`,
          path: issue.path
        });
      }
    }
    return { valid: false, errors: flatErrors };
  } catch (error) {
    debug("Local input validation failed: %s", error);
    return {
      valid: true,
      skipped: true,
      reason: "local validation encountered an error (server-side validation will still run)"
    };
  } finally {
    await fs.rm(tmpDir, { recursive: true, force: true }).catch(() => {
    });
  }
}

// src/commands/agent/test.ts
var cliVersion = getCliVersion();
function createAgentTestCommand() {
  const cmd = new Command("test");
  cmd.description("Test agent in interactive REPL session").option(
    "--workspace <identifier>",
    "Workspace ID or full name (e.g., owner/workspace-name)"
  ).option("--agent-version <id>", "Test a specific version (UUID or version number)").option("--resume <session-id>", "Resume an existing test session").option("--open", "Open session in web dashboard").option(
    "--events <types>",
    "Event types to stream (default: user). Shorthands: none, user, system, all, or comma-separated type names"
  ).option("--bundle <file>", "Path to a pre-built gzip+base64 bundle file").option("--no-cache", "Skip ephemeral build cache (force a fresh build)").addOption(new Option("--mode <format>").hideHelp()).action(
    async (options) => {
      const cwd = process.cwd();
      const eventFilter = options.events ? parseEventFilter(options.events) : void 0;
      try {
        if (options.resume) {
          await ensureAuthenticated();
          const client2 = new GuildAPIClient();
          const resumeSession = await fetchSession(client2, options.resume);
          const resumeEvents = await fetchSessionEvents(client2, options.resume);
          const resumeCommand2 = "guild agent test";
          const isInteractive2 = getOutputMode() === "interactive" && !isQuietMode();
          if (isInteractive2) {
            suppressScrollbackClear();
          }
          const { waitUntilExit: waitUntilExit2 } = render_default(
            import_react.default.createElement(ChatApp, {
              initialPrompt: "",
              version: cliVersion,
              showSplash: false,
              resumeSession,
              resumeEvents,
              resumeCommand: resumeCommand2,
              eventFilter
            }),
            { exitOnCtrlC: false }
          );
          await waitUntilExit2();
          return;
        }
        const guildConfig = await loadLocalConfig(cwd);
        if (!guildConfig) {
          console.error("Error: Not in an agent directory");
          console.error("");
          console.error("guild.json not found in current directory.");
          console.error("");
          console.error("Initialize an agent directory:");
          console.error("  guild agent init --name my-agent");
          console.error("");
          console.error("Or clone an existing agent:");
          console.error("  guild agent clone <agent-id>");
          process.exit(1);
        }
        const outputMode = getOutputMode();
        let inputData;
        let jsonlInputs;
        if (outputMode === "json") {
          try {
            inputData = await readStdinAsJSON();
          } catch (error) {
            const err = error;
            console.error(`Error: ${err.message}`);
            console.error("");
            console.error("Example usage:");
            console.error(
              `  echo '{"prompt": "test"}' | guild agent test --mode json`
            );
            console.error("  guild agent test --mode json < input.json");
            process.exit(1);
          }
        } else if (outputMode === "jsonl") {
          try {
            const stdinContent = await readStdinAsText();
            jsonlInputs = [];
            const lines = stdinContent.split("\n");
            for (let i = 0; i < lines.length; i++) {
              const line = lines[i].trim();
              if (!line) continue;
              try {
                jsonlInputs.push(JSON.parse(line));
              } catch {
                console.error(`Error: Invalid JSON on line ${i + 1}`);
                console.error("");
                console.error("Each line must be valid JSON.");
                console.error("  cat inputs.jsonl | guild agent test --mode jsonl");
                process.exit(1);
              }
            }
            if (jsonlInputs.length === 0) {
              console.error("Error: No JSON input provided");
              console.error("");
              console.error("Example usage:");
              console.error("  cat inputs.jsonl | guild agent test --mode jsonl");
              process.exit(1);
            }
          } catch (error) {
            const err = error;
            console.error(`Error: ${err.message}`);
            process.exit(1);
          }
        }
        const inputsToValidate = inputData !== void 0 ? [inputData] : jsonlInputs ?? [];
        if (inputsToValidate.length > 0 && !options.agentVersion) {
          const validationResult = await validateInputSchema(cwd, inputsToValidate);
          if (!validationResult.valid) {
            console.error("Input validation failed:");
            for (const err of validationResult.errors) {
              const pathStr = err.path?.length ? ` (at ${err.path.join(".")})` : "";
              console.error(`  - ${err.message}${pathStr}`);
            }
            process.exit(1);
          }
          if ("skipped" in validationResult && validationResult.skipped) {
            format.warn(`Skipping local validation: ${validationResult.reason}`);
          }
        }
        if (options.bundle) {
          try {
            await access2(options.bundle);
          } catch {
            console.error(`Error: Bundle file not found: ${options.bundle}`);
            console.error("");
            console.error("Ensure the bundle file exists and the path is correct:");
            console.error("  npm run build");
            console.error("  guild agent test --bundle agent.js.gz");
            process.exit(1);
          }
        }
        let workspaceId = options.workspace;
        let workspaceSourceLabel;
        if (!workspaceId) {
          const resolved = await getWorkspaceId(cwd);
          workspaceId = resolved?.workspaceId;
          workspaceSourceLabel = resolved ? getWorkspaceSourceLabel(resolved.source) : void 0;
          if (!workspaceId) {
            console.error("Error: No default workspace configured");
            console.error("");
            console.error("Set a default workspace interactively:");
            console.error("  guild workspace select");
            console.error("");
            console.error("Or specify a workspace for this test:");
            console.error("  guild agent test --workspace <workspace-id>");
            console.error("");
            console.error("List available workspaces:");
            console.error("  guild workspace list");
            process.exit(1);
          }
        }
        await ensureAuthenticated();
        const client = new GuildAPIClient();
        let version;
        let ephemeralCached = false;
        try {
          if (options.agentVersion) {
            const existingVersions = await client.get(
              `/agents/${guildConfig.agent_id}/versions`
            );
            const match = existingVersions.items.find(
              (v) => v.id === options.agentVersion || v.version_number === options.agentVersion
            );
            if (!match) {
              console.error(`Error: Version not found: ${options.agentVersion}`);
              console.error("");
              console.error("List available versions:");
              console.error(`  guild agent versions ${guildConfig.agent_id}`);
              process.exit(1);
            }
            version = match;
          } else if (options.bundle) {
            const result = await buildBundledVersion(
              client,
              guildConfig.agent_id,
              options.bundle,
              cwd,
              "[Test] Pre-built bundle"
            );
            version = result.version;
          } else {
            const agentFiles = await readAgentFiles(cwd);
            const noCache = options.cache === false;
            const result = await buildEphemeralVersion(
              client,
              guildConfig.agent_id,
              agentFiles,
              cwd,
              "[Test] Ephemeral development version",
              { noCache }
            );
            version = result.version;
            ephemeralCached = result.cached;
          }
        } catch (error) {
          if (error instanceof BundleNotFoundError) {
            console.error(`Error: ${error.message}`);
            console.error("");
            console.error("Ensure the bundle file exists and the path is correct:");
            console.error("  npm run build");
            console.error("  guild agent test --bundle agent.js.gz");
            process.exit(1);
          }
          if (error instanceof BuildTimeoutError) {
            console.error("Error: Build did not complete");
            console.error("");
            console.error(error.message);
            console.error("");
            console.error("Check build status:");
            console.error("  guild agent versions");
            process.exit(1);
          }
          if (error instanceof BuildFailedError) {
            console.error(`Error: ${error.message}`);
            process.exit(1);
          }
          if (error instanceof Error && error.message.startsWith("Missing required")) {
            console.error("Error: Could not read agent files");
            console.error("");
            console.error(error.message);
            console.error("");
            console.error("Ensure you are in an agent directory with:");
            console.error("  - agent.ts (required)");
            console.error("  - package.json (required)");
            process.exit(1);
          }
          const formattedError = handleAxiosError(error);
          if (formattedError.code === ErrorCodes.NOT_FOUND) {
            console.error(`Error: Agent not found: ${guildConfig.agent_id}`);
            console.error("");
            console.error("This agent may have been deleted from the backend.");
            console.error("");
            console.error("Verify the agent exists:");
            console.error(`  guild agent get ${guildConfig.agent_id}`);
            console.error("");
            console.error("Or initialize a new agent:");
            console.error("  guild agent init --name my-agent");
            process.exit(1);
          }
          throw error;
        }
        let session;
        try {
          session = await client.post(`/workspaces/${workspaceId}/sessions`, {
            session_type: "agent_test",
            agent_version_id: version.id
          });
        } catch (error) {
          const formattedError = handleAxiosError(error);
          if (formattedError.code === ErrorCodes.NOT_FOUND) {
            console.error(`Error: Workspace not found: ${workspaceId}`);
            console.error("");
            console.error("Set a different default workspace:");
            console.error("  guild workspace select");
            console.error("");
            console.error("Or list available workspaces:");
            console.error("  guild workspace list");
            process.exit(1);
          }
          throw error;
        }
        const quiet = isQuietMode();
        if (!quiet) {
          console.log(`\u2713 Agent: ${guildConfig.name} (${guildConfig.agent_id})`);
          const versionDisplay = options.agentVersion ? options.agentVersion : options.bundle ? `bundle (${path2.basename(options.bundle)})` : ephemeralCached ? "ephemeral (cached, no changes)" : "ephemeral (working directory)";
          console.log(`\u2713 Version: ${versionDisplay}`);
          const workspaceDisplay = workspaceSourceLabel ? `${workspaceId} (from ${workspaceSourceLabel})` : workspaceId;
          console.log(`\u2713 Workspace: ${workspaceDisplay}`);
          const sessionLink = session.session_url ? hyperlink(session.id, session.session_url) : session.id;
          console.log(`\u2713 Session: ${sessionLink}`);
          console.log("");
        }
        if (options.open && session.session_url) {
          await open_default(session.session_url);
        }
        if (outputMode === "json" && inputData) {
          try {
            await client.post(`/sessions/${session.id}/events`, {
              mode: "json",
              content: inputData
            });
            const { response } = eventFilter ? await pollForResponseWithEvents(
              client,
              session.id,
              eventFilter,
              void 0,
              18e4
            ) : await pollForResponse(client, session.id, void 0, 18e4);
            if (!response) {
              console.error("Error: No response received from agent within timeout");
              console.error("");
              console.error("The agent did not produce a response in time.");
              console.error("");
              console.error("Possible causes:");
              console.error(
                "  - The agent is still processing (try a longer timeout)"
              );
              console.error("  - The agent encountered an error during execution");
              console.error(
                "  - The input format does not match the agent's input schema"
              );
              console.error("");
              console.error(
                "Check agent logs in the web UI or try interactive mode:"
              );
              console.error("  guild agent test");
              process.exit(1);
            }
            if (quiet) {
              console.log(response);
            } else {
              console.log(`< ${response}`);
              console.log("");
            }
            if (!quiet) {
              console.log("\u2713 Test complete");
            }
            process.exit(0);
          } catch (error) {
            const formattedErr = handleAxiosError(error);
            console.error(`Error: ${formattedErr.details}`);
            console.error("");
            if (formattedErr.code === ErrorCodes.SERVER_ERROR) {
              console.error(
                "The server returned an error while processing the event."
              );
              console.error("");
              console.error("Possible causes:");
              console.error(
                "  - The input format does not match the agent's input schema"
              );
              console.error("  - The agent runtime encountered an error");
              console.error("");
              console.error("Try testing interactively to see more detail:");
              console.error("  guild agent test");
            } else {
              console.error("Failed to send event to agent session.");
              console.error("");
              console.error("Example usage:");
              console.error(
                `  echo '{"type":"text","text":"hello"}' | guild agent test --mode json`
              );
              console.error("  guild agent test --mode json < input.json");
            }
            process.exit(1);
          }
        } else if (outputMode === "jsonl" && jsonlInputs) {
          let processedCount = 0;
          let lastEventId;
          for (let inputIndex = 0; inputIndex < jsonlInputs.length; inputIndex++) {
            const jsonInput = jsonlInputs[inputIndex];
            if (!quiet) {
              console.error(
                `Processing input ${inputIndex + 1}/${jsonlInputs.length}...`
              );
            }
            try {
              await client.post(`/sessions/${session.id}/events`, {
                mode: "json",
                content: jsonInput
              });
              const result = eventFilter ? await pollForResponseWithEvents(
                client,
                session.id,
                eventFilter,
                lastEventId,
                18e4
              ) : await pollForResponse(client, session.id, lastEventId, 18e4);
              lastEventId = result.lastEventId;
              if (!result.response) {
                console.error(`Timeout: No response for input ${inputIndex + 1}`);
                continue;
              }
              const response = result.response;
              if (quiet) {
                console.log(response);
              } else {
                console.log(`< ${response}`);
                console.log("");
              }
              processedCount++;
            } catch (error) {
              const formattedErr = handleAxiosError(error);
              console.error(
                `Error processing input ${inputIndex + 1}: ${formattedErr.details}`
              );
            }
          }
          if (!quiet) {
            console.log(`
\u2713 Processed ${processedCount} messages`);
          }
          process.exit(0);
        }
        ensureInteractiveStdin("guild agent test");
        const resumeCommand = "guild agent test";
        const isInteractive = getOutputMode() === "interactive" && !isQuietMode();
        if (isInteractive) {
          suppressScrollbackClear();
        }
        const { waitUntilExit } = render_default(
          import_react.default.createElement(ChatApp, {
            initialPrompt: "",
            version: cliVersion,
            workspaceId,
            versionId: version.id,
            agentName: guildConfig.name,
            showSplash: false,
            resumeSession: session,
            resumeEvents: [],
            resumeCommand,
            eventFilter
          }),
          { exitOnCtrlC: false }
        );
        await waitUntilExit();
      } catch (error) {
        if (error instanceof GitError) {
          console.error("Error: Git operation failed");
          console.error("");
          console.error(formatGitError(error));
          process.exit(1);
        }
        const formattedError = handleAxiosError(error);
        if (formattedError.code === ErrorCodes.AUTH_REQUIRED || formattedError.code === ErrorCodes.AUTH_TOKEN_INVALID) {
          format.error("Not authenticated. Run: guild auth login");
          process.exit(1);
        }
        console.error(`Error: ${formattedError.details}`);
        console.error("");
        console.error("Failed to start test session. Troubleshooting:");
        console.error("  - Verify the agent exists: guild agent get");
        console.error("  - Check your workspace: guild workspace list");
        if (formattedError.code) {
          console.error(`  - Error code: ${formattedError.code}`);
        }
        process.exit(1);
      }
    }
  );
  return cmd;
}
async function handleAgentTestAction(_options) {
  const cmd = createAgentTestCommand();
  await cmd.parseAsync(process.argv.slice(3), { from: "user" });
}
export {
  createAgentTestCommand,
  handleAgentTestAction
};
//# sourceMappingURL=test-VEA4ENOR.js.map
