{"version":3,"file":"cli.cjs","names":["Logger","AGUIMock","resolveFixturesValue","loadFixturesFromDir","loadFixtureFile","validateFixtures","createServer","watchFixtures"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\nimport { statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { createServer } from \"./server.js\";\nimport { loadFixtureFile, loadFixturesFromDir, validateFixtures } from \"./fixture-loader.js\";\nimport { Logger, type LogLevel } from \"./logger.js\";\nimport { watchFixtures } from \"./watcher.js\";\nimport { AGUIMock } from \"./agui-mock.js\";\nimport { resolveFixturesValue } from \"./fixtures-remote.js\";\nimport type { Fixture, ChaosConfig, RecordConfig } from \"./types.js\";\n\nconst HELP = `\nUsage: aimock [options]\n\nOptions:\n  -p, --port <number>       Port to listen on (default: 4010)\n  -h, --host <string>       Host to bind to (default: 127.0.0.1)\n  -f, --fixtures <value>    Fixture source (repeatable). Accepts:\n                              - filesystem path to a directory or .json file (default: ./fixtures)\n                              - https:// or http:// URL to a .json fixture file\n  -l, --latency <ms>        Latency in ms between SSE chunks (default: 0)\n  -c, --chunk-size <chars>  Chunk size in characters (default: 20)\n  -w, --watch               Watch fixture path for changes and reload\n      --log-level <level>   Log verbosity: silent, warn, info, debug (default: info)\n      --validate-on-load    Validate fixture schemas at startup\n      --metrics             Enable Prometheus metrics at GET /metrics\n      --record              Record mode: proxy unmatched requests and save fixtures\n      --record-full-model-version  Record exact model version without date stripping (default: false)\n      --proxy-only          Proxy mode: forward unmatched requests without saving\n      --strict              Strict mode: fail on unmatched requests (overridable per-request via X-AIMock-Strict header)\n      --journal-max <n>     Max request entries retained in memory (default: 1000, 0 = unbounded)\n      --fixture-counts-max <n>  Max unique testIds retained in fixture match-count map (default: 500, 0 = unbounded)\n      --provider-openai <url>     Upstream URL for OpenAI (used with --record)\n      --provider-anthropic <url>  Upstream URL for Anthropic\n      --provider-gemini <url>     Upstream URL for Gemini\n      --provider-vertexai <url>   Upstream URL for Vertex AI\n      --provider-bedrock <url>    Upstream URL for Bedrock\n      --provider-azure <url>      Upstream URL for Azure OpenAI\n      --provider-ollama <url>     Upstream URL for Ollama\n      --provider-cohere <url>     Upstream URL for Cohere\n      --provider-openrouter <url> Upstream URL for OpenRouter (video record proxy)\n      --upstream-timeout-ms <ms>  Idle timeout (ms) on upstream socket before response (default: 30000)\n      --body-timeout-ms <ms>      Idle timeout (ms) on upstream response body between chunks (default: 30000)\n      --max-proxy-buffer-bytes <n> Cap (bytes) on in-memory proxy-path buffer; full body still relayed (default: 67108864)\n      --max-proxy-buffer-frames <n> Cap (frames) on in-memory proxy-path per-frame state; full body still relayed (default: 5000000)\n      --agui-record              Enable AG-UI recording (proxy unmatched AG-UI requests)\n      --agui-upstream <url>      Upstream AG-UI agent URL (used with --agui-record)\n      --agui-proxy-only          AG-UI proxy mode: forward without saving\n      --replay-speed <n>    Replay speed multiplier (default: 1.0, 2.0 = 2x faster)\n      --chaos-drop <rate>   Probability (0-1) of dropping requests with 500\n      --chaos-malformed <rate>  Probability (0-1) of returning malformed JSON\n      --chaos-disconnect <rate> Probability (0-1) of destroying connection\n      --help                Show this help message\n`.trim();\n\nconst { values } = parseArgs({\n  options: {\n    port: { type: \"string\", short: \"p\", default: \"4010\" },\n    host: { type: \"string\", short: \"h\", default: \"127.0.0.1\" },\n    fixtures: { type: \"string\", short: \"f\", multiple: true },\n    latency: { type: \"string\", short: \"l\", default: \"0\" },\n    \"chunk-size\": { type: \"string\", short: \"c\", default: \"20\" },\n    watch: { type: \"boolean\", short: \"w\", default: false },\n    \"log-level\": { type: \"string\", default: \"info\" },\n    \"validate-on-load\": { type: \"boolean\", default: false },\n    metrics: { type: \"boolean\", default: false },\n    record: { type: \"boolean\", default: false },\n    \"record-full-model-version\": { type: \"boolean\", default: false },\n    \"proxy-only\": { type: \"boolean\", default: false },\n    strict: { type: \"boolean\", default: false },\n    \"provider-openai\": { type: \"string\" },\n    \"provider-anthropic\": { type: \"string\" },\n    \"provider-gemini\": { type: \"string\" },\n    \"provider-vertexai\": { type: \"string\" },\n    \"provider-bedrock\": { type: \"string\" },\n    \"provider-azure\": { type: \"string\" },\n    \"provider-ollama\": { type: \"string\" },\n    \"provider-cohere\": { type: \"string\" },\n    \"provider-openrouter\": { type: \"string\" },\n    \"upstream-timeout-ms\": { type: \"string\" },\n    \"body-timeout-ms\": { type: \"string\" },\n    \"max-proxy-buffer-bytes\": { type: \"string\" },\n    \"max-proxy-buffer-frames\": { type: \"string\" },\n    \"agui-record\": { type: \"boolean\", default: false },\n    \"agui-upstream\": { type: \"string\" },\n    \"agui-proxy-only\": { type: \"boolean\", default: false },\n    \"replay-speed\": { type: \"string\", default: \"1.0\" },\n    \"chaos-drop\": { type: \"string\" },\n    \"chaos-malformed\": { type: \"string\" },\n    \"chaos-disconnect\": { type: \"string\" },\n    \"journal-max\": { type: \"string\", default: \"1000\" },\n    \"fixture-counts-max\": { type: \"string\", default: \"500\" },\n    help: { type: \"boolean\", default: false },\n  },\n  strict: true,\n});\n\nif (values.help) {\n  console.log(HELP);\n  process.exit(0);\n}\n\nconst port = Number(values.port);\nconst host = values.host!;\nconst latency = Number(values.latency);\nconst chunkSize = Number(values[\"chunk-size\"]);\nconst fixtureValues: string[] =\n  values.fixtures && values.fixtures.length > 0 ? values.fixtures : [\"./fixtures\"];\nconst watchMode = values.watch!;\nconst validateOnLoad = values[\"validate-on-load\"]!;\nconst logLevelStr = values[\"log-level\"]!;\n\nif (![\"silent\", \"warn\", \"info\", \"debug\"].includes(logLevelStr)) {\n  console.error(`Invalid log-level: ${logLevelStr} (must be silent, warn, info, or debug)`);\n  process.exit(1);\n}\nconst logLevel = logLevelStr as LogLevel;\n\nif (Number.isNaN(port) || port < 0 || port > 65535) {\n  console.error(`Invalid port: ${values.port}`);\n  process.exit(1);\n}\n\nif (Number.isNaN(latency) || latency < 0) {\n  console.error(`Invalid latency: ${values.latency}`);\n  process.exit(1);\n}\n\nif (Number.isNaN(chunkSize) || chunkSize < 1) {\n  console.error(`Invalid chunk-size: ${values[\"chunk-size\"]}`);\n  process.exit(1);\n}\n\nconst replaySpeed = Number(values[\"replay-speed\"]);\nif (Number.isNaN(replaySpeed) || replaySpeed <= 0) {\n  console.error(\"--replay-speed must be a positive number\");\n  process.exit(1);\n}\n\nconst journalMax = Number(values[\"journal-max\"]);\nif (Number.isNaN(journalMax) || !Number.isInteger(journalMax) || journalMax < 0) {\n  console.error(\n    `Invalid journal-max: ${values[\"journal-max\"]} (must be a non-negative integer; 0 = unbounded)`,\n  );\n  process.exit(1);\n}\n\nconst fixtureCountsMaxStr = values[\"fixture-counts-max\"];\nconst fixtureCountsMax = Number(fixtureCountsMaxStr);\nif (Number.isNaN(fixtureCountsMax) || !Number.isInteger(fixtureCountsMax) || fixtureCountsMax < 0) {\n  console.error(\n    `Invalid fixture-counts-max: ${fixtureCountsMaxStr} (must be a non-negative integer; 0 = unbounded)`,\n  );\n  process.exit(1);\n}\n\nconst upstreamTimeoutMsStr = values[\"upstream-timeout-ms\"];\nlet upstreamTimeoutMs: number | undefined;\nif (upstreamTimeoutMsStr !== undefined) {\n  upstreamTimeoutMs = Number(upstreamTimeoutMsStr);\n  if (!Number.isFinite(upstreamTimeoutMs) || upstreamTimeoutMs <= 0) {\n    console.error(\n      `Invalid upstream-timeout-ms: ${upstreamTimeoutMsStr} (must be a positive finite number)`,\n    );\n    process.exit(1);\n  }\n}\n\nconst bodyTimeoutMsStr = values[\"body-timeout-ms\"];\nlet bodyTimeoutMs: number | undefined;\nif (bodyTimeoutMsStr !== undefined) {\n  bodyTimeoutMs = Number(bodyTimeoutMsStr);\n  if (!Number.isFinite(bodyTimeoutMs) || bodyTimeoutMs <= 0) {\n    console.error(\n      `Invalid body-timeout-ms: ${bodyTimeoutMsStr} (must be a positive finite number)`,\n    );\n    process.exit(1);\n  }\n}\n\nconst maxProxyBufferBytesStr = values[\"max-proxy-buffer-bytes\"];\nlet maxProxyBufferBytes: number | undefined;\nif (maxProxyBufferBytesStr !== undefined) {\n  maxProxyBufferBytes = Number(maxProxyBufferBytesStr);\n  if (!Number.isFinite(maxProxyBufferBytes) || maxProxyBufferBytes <= 0) {\n    console.error(\n      `Invalid max-proxy-buffer-bytes: ${maxProxyBufferBytesStr} (must be a positive finite number)`,\n    );\n    process.exit(1);\n  }\n}\n\nconst maxProxyBufferFramesStr = values[\"max-proxy-buffer-frames\"];\nlet maxProxyBufferFrames: number | undefined;\nif (maxProxyBufferFramesStr !== undefined) {\n  maxProxyBufferFrames = Number(maxProxyBufferFramesStr);\n  if (!Number.isFinite(maxProxyBufferFrames) || maxProxyBufferFrames <= 0) {\n    console.error(\n      `Invalid max-proxy-buffer-frames: ${maxProxyBufferFramesStr} (must be a positive finite number)`,\n    );\n    process.exit(1);\n  }\n}\n\nconst logger = new Logger(logLevel);\n\n// Parse chaos config from CLI flags\nlet chaos: ChaosConfig | undefined;\n{\n  const dropStr = values[\"chaos-drop\"];\n  const malformedStr = values[\"chaos-malformed\"];\n  const disconnectStr = values[\"chaos-disconnect\"];\n\n  if (dropStr !== undefined || malformedStr !== undefined || disconnectStr !== undefined) {\n    chaos = {};\n    if (dropStr !== undefined) {\n      const val = parseFloat(dropStr);\n      if (isNaN(val) || val < 0 || val > 1) {\n        console.error(`Invalid chaos-drop: ${dropStr} (must be 0-1)`);\n        process.exit(1);\n      }\n      chaos.dropRate = val;\n    }\n    if (malformedStr !== undefined) {\n      const val = parseFloat(malformedStr);\n      if (isNaN(val) || val < 0 || val > 1) {\n        console.error(`Invalid chaos-malformed: ${malformedStr} (must be 0-1)`);\n        process.exit(1);\n      }\n      chaos.malformedRate = val;\n    }\n    if (disconnectStr !== undefined) {\n      const val = parseFloat(disconnectStr);\n      if (isNaN(val) || val < 0 || val > 1) {\n        console.error(`Invalid chaos-disconnect: ${disconnectStr} (must be 0-1)`);\n        process.exit(1);\n      }\n      chaos.disconnectRate = val;\n    }\n  }\n}\n\n// Parse record/proxy config from CLI flags\nlet record: RecordConfig | undefined;\nif (values.record || values[\"proxy-only\"]) {\n  const providers: RecordConfig[\"providers\"] = {};\n  if (values[\"provider-openai\"]) providers.openai = values[\"provider-openai\"];\n  if (values[\"provider-anthropic\"]) providers.anthropic = values[\"provider-anthropic\"];\n  if (values[\"provider-gemini\"]) providers.gemini = values[\"provider-gemini\"];\n  if (values[\"provider-vertexai\"]) providers.vertexai = values[\"provider-vertexai\"];\n  if (values[\"provider-bedrock\"]) providers.bedrock = values[\"provider-bedrock\"];\n  if (values[\"provider-azure\"]) providers.azure = values[\"provider-azure\"];\n  if (values[\"provider-ollama\"]) providers.ollama = values[\"provider-ollama\"];\n  if (values[\"provider-cohere\"]) providers.cohere = values[\"provider-cohere\"];\n  if (values[\"provider-openrouter\"]) providers.openrouter = values[\"provider-openrouter\"];\n\n  if (Object.keys(providers).length === 0) {\n    console.error(\n      `Error: --${values[\"proxy-only\"] ? \"proxy-only\" : \"record\"} requires at least one --provider-* flag`,\n    );\n    process.exit(1);\n  }\n\n  // For --record, the first --fixtures value is the base path for the recording\n  // destination and must be a local filesystem path — writing to a URL is not supported.\n  // For --proxy-only, unmatched requests are forwarded without saving, so no writable\n  // destination is required; URL-only --fixtures is valid in that mode.\n  const recordBase = fixtureValues[0];\n  const recordBaseIsUrl = /^https?:\\/\\//i.test(recordBase);\n  if (values.record && recordBaseIsUrl) {\n    console.error(\n      `Error: --record requires a local --fixtures path for the recording destination; got URL ${recordBase}`,\n    );\n    process.exit(1);\n  }\n  record = {\n    providers,\n    // In proxy-only mode with only URL sources, fixturePath is never consumed\n    // (recorder.ts skips disk writes when proxyOnly is set). Leave it undefined\n    // rather than resolving a URL string as a filesystem path.\n    fixturePath: recordBaseIsUrl ? undefined : resolve(recordBase, \"recorded\"),\n    proxyOnly: values[\"proxy-only\"],\n    recordFullModelVersion: values[\"record-full-model-version\"],\n    upstreamTimeoutMs,\n    bodyTimeoutMs,\n    maxProxyBufferBytes,\n    maxProxyBufferFrames,\n  };\n} else {\n  // These flags configure upstream proxying — without --record or\n  // --proxy-only they would be parsed and then silently dropped. Routed\n  // through the constructed logger so --log-level is respected.\n  const droppedProviderFlags = (\n    [\n      \"provider-openai\",\n      \"provider-anthropic\",\n      \"provider-gemini\",\n      \"provider-vertexai\",\n      \"provider-bedrock\",\n      \"provider-azure\",\n      \"provider-ollama\",\n      \"provider-cohere\",\n      \"provider-openrouter\",\n    ] as const\n  ).filter((flag) => values[flag] !== undefined);\n  if (droppedProviderFlags.length > 0) {\n    logger.warn(\n      `--${droppedProviderFlags.join(\"/--\")} only apply to --record/--proxy-only upstream proxying — ignored without one of those flags.`,\n    );\n  }\n  if (\n    upstreamTimeoutMs !== undefined ||\n    bodyTimeoutMs !== undefined ||\n    maxProxyBufferBytes !== undefined ||\n    maxProxyBufferFrames !== undefined\n  ) {\n    logger.warn(\n      \"--upstream-timeout-ms/--body-timeout-ms/--max-proxy-buffer-bytes/--max-proxy-buffer-frames only apply to --record/--proxy-only upstream proxying — ignored without one of those flags.\",\n    );\n  }\n}\n\n// Parse AG-UI record/proxy config from CLI flags\nlet aguiMount: { path: string; handler: AGUIMock } | undefined;\nif (values[\"agui-record\"] || values[\"agui-proxy-only\"]) {\n  if (!values[\"agui-upstream\"]) {\n    console.error(\"Error: --agui-record/--agui-proxy-only requires --agui-upstream\");\n    process.exit(1);\n  }\n  // --agui-record writes recorded AG-UI fixtures to disk, so a URL source is unsupported.\n  // --agui-proxy-only forwards without saving, so URL-only --fixtures is valid.\n  const aguiBase = fixtureValues[0];\n  const aguiBaseIsUrl = /^https?:\\/\\//i.test(aguiBase);\n  if (values[\"agui-record\"] && aguiBaseIsUrl) {\n    console.error(\n      `Error: --agui-record requires a local --fixtures path for the recording destination; got URL ${aguiBase}`,\n    );\n    process.exit(1);\n  }\n  const agui = new AGUIMock();\n  agui.enableRecording({\n    upstream: values[\"agui-upstream\"],\n    // In proxy-only mode with a URL-only --fixtures, the AG-UI recorder never\n    // writes to disk (see agui-recorder.ts). Leave fixturePath undefined rather\n    // than resolving a URL as a filesystem path.\n    fixturePath: aguiBaseIsUrl ? undefined : resolve(aguiBase, \"agui-recorded\"),\n    proxyOnly: values[\"agui-proxy-only\"],\n  });\n  aguiMount = { path: \"/agui\", handler: agui };\n}\n\ninterface ResolvedFixtureSource {\n  source: string;\n  path: string;\n  isDir: boolean;\n}\n\nasync function resolveAllFixtureSources(): Promise<ResolvedFixtureSource[]> {\n  const resolved: ResolvedFixtureSource[] = [];\n  for (const value of fixtureValues) {\n    let local;\n    try {\n      local = await resolveFixturesValue(value, {\n        validateOnLoad,\n        logger,\n      });\n    } catch (err) {\n      const msg = err instanceof Error ? err.message : String(err);\n      console.error(`Failed to resolve --fixtures value \"${value}\": ${msg}`);\n      process.exit(1);\n    }\n    if (!local.path) {\n      // Remote fetch failed without validate-on-load and no cache — already warned; skip.\n      continue;\n    }\n    try {\n      const stat = statSync(local.path);\n      resolved.push({ source: local.source, path: local.path, isDir: stat.isDirectory() });\n    } catch (err) {\n      if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n        console.error(`Fixtures path not found: ${local.path}`);\n      } else {\n        const msg = err instanceof Error ? err.message : String(err);\n        console.error(`Failed to load fixtures from ${local.path}: ${msg}`);\n      }\n      process.exit(1);\n    }\n  }\n  return resolved;\n}\n\nfunction loadSource(source: ResolvedFixtureSource): Fixture[] {\n  return source.isDir\n    ? loadFixturesFromDir(source.path, logger)\n    : loadFixtureFile(source.path, logger);\n}\n\nasync function main() {\n  const sources = await resolveAllFixtureSources();\n\n  const fixtures: Fixture[] = [];\n  for (const src of sources) {\n    fixtures.push(...loadSource(src));\n  }\n\n  if (fixtures.length === 0) {\n    if (validateOnLoad || values.strict) {\n      console.error(\"Error: No fixtures loaded and validation/strict mode is enabled — aborting.\");\n      process.exit(1);\n    }\n    console.warn(\"Warning: No fixtures loaded. The server will return 404 for all requests.\");\n  }\n\n  const sourceLabel = sources.map((s) => s.source).join(\", \") || \"<none>\";\n  logger.info(`Loaded ${fixtures.length} fixture(s) from ${sourceLabel}`);\n\n  // Validate fixtures if requested\n  if (validateOnLoad) {\n    const results = validateFixtures(fixtures);\n    const errors = results.filter((r) => r.severity === \"error\");\n    const warnings = results.filter((r) => r.severity === \"warning\");\n\n    for (const w of warnings) {\n      logger.warn(`Fixture ${w.fixtureIndex}: ${w.message}`);\n    }\n    for (const e of errors) {\n      logger.error(`Fixture ${e.fixtureIndex}: ${e.message}`);\n    }\n\n    if (errors.length > 0) {\n      console.error(`Validation failed: ${errors.length} error(s), ${warnings.length} warning(s)`);\n      process.exit(1);\n    }\n  }\n\n  const mounts = aguiMount ? [aguiMount] : undefined;\n\n  const instance = await createServer(\n    fixtures,\n    {\n      port,\n      host,\n      latency,\n      chunkSize,\n      replaySpeed,\n      logLevel,\n      chaos,\n      metrics: values.metrics,\n      record,\n      strict: values.strict,\n      journalMaxEntries: journalMax,\n      fixtureCountsMaxTestIds: fixtureCountsMax,\n    },\n    mounts,\n  );\n\n  logger.info(`aimock server listening on ${instance.url}`);\n\n  // Start file watcher if requested. Only the first local source is watched —\n  // remote URL sources are fetched once at boot and are not monitored.\n  let watcher: { close: () => void } | null = null;\n  if (watchMode) {\n    const primary = sources[0];\n    if (!primary) {\n      logger.warn(\"--watch requested but no resolvable fixture sources; skipping watcher\");\n    } else {\n      const loadFn = (): Fixture[] => loadSource(primary);\n      watcher = watchFixtures(primary.path, fixtures, loadFn, {\n        logger,\n        validate: validateOnLoad,\n        validateFn: validateFixtures,\n      });\n      logger.info(`Watching ${primary.path} for changes`);\n    }\n  }\n\n  function shutdown() {\n    logger.info(\"Shutting down...\");\n    if (watcher) watcher.close();\n    instance.server.close(() => {\n      process.exit(0);\n    });\n  }\n\n  process.on(\"SIGINT\", shutdown);\n  process.on(\"SIGTERM\", shutdown);\n}\n\nmain().catch((err) => {\n  console.error(err);\n  process.exit(1);\n});\n"],"mappings":"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"}