{"version":3,"file":"index.mjs","names":["env: NodeJS.ProcessEnv","reasoningEffort","websearchProxy: WebsearchProxyHandle | NativeWebsearchProxyHandle | null","host","portRaw","port: number | undefined"],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nconsole.log = console.error;\nconsole.info = console.error;\nconsole.warn = console.error;\nconsole.debug = console.error;\n\nprocess.on(\"unhandledRejection\", (reason, promise) => {\n  console.error(\"Unhandled Rejection at:\", promise, \"reason:\", reason);\n});\n\nimport { spawn } from \"node:child_process\";\nimport { runAcp } from \"./acp-agent.ts\";\nimport { findDroidExecutable, isEnvEnabled, isWindows } from \"./utils.ts\";\nimport { startWebsearchProxy, type WebsearchProxyHandle } from \"./websearch-proxy.ts\";\nimport { startNativeWebsearchProxy, type NativeWebsearchProxyHandle } from \"./websearch-native.ts\";\n\nfunction pickArgValue(argv: string[], names: string[]): string | null {\n  for (let i = 0; i < argv.length; i += 1) {\n    const arg = argv[i] ?? \"\";\n    for (const name of names) {\n      if (arg === name) {\n        const next = argv[i + 1] ?? \"\";\n        if (!next || next.startsWith(\"-\")) return null;\n        return next;\n      }\n      if (arg.startsWith(`${name}=`)) {\n        const value = arg.slice(`${name}=`.length);\n        return value.length > 0 ? value : null;\n      }\n    }\n  }\n  return null;\n}\n\n/**\n * Run droid with native ACP mode (--output-format acp).\n * Note: Native ACP mode does NOT support custom models due to a bug in droid.\n */\nfunction runNativeAcp(): void {\n  const executable = findDroidExecutable();\n  const cwd = process.cwd();\n  const args = [\"exec\", \"--output-format\", \"acp\", \"--cwd\", cwd];\n\n  const env: NodeJS.ProcessEnv = { ...process.env, FORCE_COLOR: \"0\" };\n\n  const reasoningEffort = env.DROID_ACP_REASONING_EFFORT;\n  if (typeof reasoningEffort === \"string\" && reasoningEffort.trim().length > 0) {\n    args.push(\"--reasoning-effort\", reasoningEffort.trim());\n  }\n\n  console.error(`[droid-acp] Starting droid with native ACP: ${executable} ${args.join(\" \")}`);\n  console.error(\"[droid-acp] WARNING: Native ACP mode does not support custom models!\");\n\n  let websearchProxy: WebsearchProxyHandle | NativeWebsearchProxyHandle | null = null;\n  const stopWebsearchProxy = () => {\n    if (!websearchProxy) return;\n    const proxy = websearchProxy;\n    websearchProxy = null;\n    proxy.close().catch((err: unknown) => {\n      console.error(\"[droid-acp] Failed to close websearch proxy:\", err);\n    });\n  };\n\n  const startWebsearchProxyIfEnabled = async () => {\n    // Experimental: Native websearch proxy mode (--websearch-proxy flag)\n    const useNativeWebsearch = isEnvEnabled(env.DROID_ACP_WEBSEARCH_NATIVE);\n\n    if (useNativeWebsearch) {\n      const host = env.DROID_ACP_WEBSEARCH_HOST ?? \"127.0.0.1\";\n      const portRaw = env.DROID_ACP_WEBSEARCH_PORT;\n      let port: number | undefined;\n      if (typeof portRaw === \"string\" && portRaw.length > 0) {\n        const parsed = Number.parseInt(portRaw, 10);\n        if (Number.isNaN(parsed) || parsed < 0 || parsed > 65535) {\n          throw new Error(`Invalid DROID_ACP_WEBSEARCH_PORT: ${portRaw}`);\n        }\n        port = parsed;\n      }\n      const factoryApiUrl =\n        env.DROID_ACP_WEBSEARCH_UPSTREAM_URL ??\n        env.FACTORY_API_BASE_URL ??\n        env.FACTORY_API_BASE_URL_OVERRIDE ??\n        \"https://api.factory.ai\";\n\n      console.error(\"[droid-acp] Starting native provider proxy (experimental)...\");\n      websearchProxy = await startNativeWebsearchProxy({\n        factoryApiUrl,\n        host,\n        port,\n        logger: console,\n      });\n\n      if (!env.FACTORY_API_KEY) {\n        env.FACTORY_API_KEY = \"droid-acp-websearch\";\n      }\n      env.FACTORY_API_BASE_URL_OVERRIDE = websearchProxy.baseUrl;\n      env.FACTORY_API_BASE_URL = websearchProxy.baseUrl;\n      return;\n    }\n\n    // Standard websearch proxy mode\n    const hasExplicitToggle = typeof env.DROID_ACP_WEBSEARCH === \"string\";\n    const smitheryConfigured =\n      typeof env.SMITHERY_API_KEY === \"string\" &&\n      env.SMITHERY_API_KEY.trim().length > 0 &&\n      typeof env.SMITHERY_PROFILE === \"string\" &&\n      env.SMITHERY_PROFILE.trim().length > 0;\n    const forwardConfigured =\n      typeof env.DROID_ACP_WEBSEARCH_FORWARD_URL === \"string\" &&\n      env.DROID_ACP_WEBSEARCH_FORWARD_URL.trim().length > 0;\n\n    const enableWebsearchProxy = hasExplicitToggle\n      ? isEnvEnabled(env.DROID_ACP_WEBSEARCH)\n      : smitheryConfigured || forwardConfigured;\n\n    if (!enableWebsearchProxy) return;\n\n    const upstreamBaseUrl =\n      env.DROID_ACP_WEBSEARCH_UPSTREAM_URL ??\n      env.FACTORY_API_BASE_URL ??\n      env.FACTORY_API_BASE_URL_OVERRIDE ??\n      \"https://api.factory.ai\";\n\n    const forwardModeRaw = env.DROID_ACP_WEBSEARCH_FORWARD_MODE;\n\n    const forwardUrlRaw =\n      typeof env.DROID_ACP_WEBSEARCH_FORWARD_URL === \"string\"\n        ? env.DROID_ACP_WEBSEARCH_FORWARD_URL.trim()\n        : \"\";\n    const forwardPrefixMatch = forwardUrlRaw.match(/^mcp:(.*)$/i);\n    const websearchForwardUrl = forwardUrlRaw.length > 0 ? forwardUrlRaw : undefined;\n    const forwardModeNormalized =\n      typeof forwardModeRaw === \"string\" ? forwardModeRaw.trim().toLowerCase() : \"\";\n    const websearchForwardMode =\n      forwardModeNormalized === \"mcp\"\n        ? (\"mcp\" as const)\n        : forwardModeNormalized === \"http\"\n          ? (\"http\" as const)\n          : forwardPrefixMatch\n            ? (\"mcp\" as const)\n            : (\"http\" as const);\n\n    const host = env.DROID_ACP_WEBSEARCH_HOST ?? \"127.0.0.1\";\n\n    const portRaw = env.DROID_ACP_WEBSEARCH_PORT;\n    let port: number | undefined;\n    if (typeof portRaw === \"string\" && portRaw.length > 0) {\n      const parsed = Number.parseInt(portRaw, 10);\n      if (Number.isNaN(parsed) || parsed < 0 || parsed > 65535) {\n        throw new Error(`Invalid DROID_ACP_WEBSEARCH_PORT: ${portRaw}`);\n      }\n      port = parsed;\n    }\n\n    websearchProxy = await startWebsearchProxy({\n      upstreamBaseUrl,\n      websearchForwardUrl: forwardPrefixMatch ? forwardPrefixMatch[1]?.trim() : websearchForwardUrl,\n      websearchForwardMode,\n      smitheryApiKey: env.SMITHERY_API_KEY,\n      smitheryProfile: env.SMITHERY_PROFILE,\n      host,\n      port,\n      logger: console,\n    });\n\n    // Droid requires an auth header for tool calls (including websearch) and will error early if missing.\n    // Since websearch is intercepted by the local proxy, any non-empty value is sufficient here.\n    if (!env.FACTORY_API_KEY) {\n      env.FACTORY_API_KEY = \"droid-acp-websearch\";\n    }\n\n    env.FACTORY_API_BASE_URL_OVERRIDE = websearchProxy.baseUrl;\n    env.FACTORY_API_BASE_URL = websearchProxy.baseUrl;\n  };\n\n  startWebsearchProxyIfEnabled()\n    .then(() => {\n      const droid = spawn(executable, args, {\n        stdio: [\"pipe\", \"pipe\", \"pipe\"],\n        env,\n        // Windows requires shell: true for proper command execution\n        shell: isWindows,\n        // Windows-specific: hide the console window\n        windowsHide: true,\n      });\n\n      process.stdin.pipe(droid.stdin);\n      droid.stdout.pipe(process.stdout);\n      droid.stderr.on(\"data\", (data: Buffer) => {\n        console.error(`[droid stderr] ${data.toString().trim()}`);\n      });\n\n      let cleanedUp = false;\n      const cleanup = () => {\n        if (cleanedUp) return;\n        cleanedUp = true;\n        stopWebsearchProxy();\n        try {\n          droid.stdin?.end();\n        } catch {}\n        try {\n          droid.kill(\"SIGTERM\");\n        } catch {}\n      };\n\n      droid.on(\"error\", (err) => {\n        console.error(\"[droid-acp] Failed to start droid:\", err.message);\n        cleanup();\n        process.exit(1);\n      });\n\n      droid.on(\"exit\", (code, signal) => {\n        console.error(`[droid-acp] Droid exited with code ${code}, signal ${signal}`);\n        cleanup();\n        process.exit(code ?? 0);\n      });\n\n      // Signal handling (works on Unix, limited on Windows)\n      process.on(\"SIGTERM\", cleanup);\n      process.on(\"SIGINT\", cleanup);\n      if (isWindows) {\n        process.on(\"SIGBREAK\", cleanup);\n      } else {\n        process.on(\"SIGHUP\", cleanup);\n      }\n      process.on(\"exit\", cleanup);\n    })\n    .catch((err: unknown) => {\n      console.error(\"[droid-acp] Failed to start websearch proxy:\", err);\n      stopWebsearchProxy();\n      process.exit(1);\n    });\n}\n\n// Parse command line arguments\nconst useNativeAcp = process.argv.includes(\"--acp\");\nconst enableExperimentSessions = process.argv.includes(\"--experiment-sessions\");\nconst enableWebsearchProxy = process.argv.includes(\"--websearch-proxy\");\n\nconst reasoningEffort = pickArgValue(process.argv, [\"--reasoning-effort\", \"-r\"]);\nif (reasoningEffort) {\n  process.env.DROID_ACP_REASONING_EFFORT = reasoningEffort;\n}\n\nif (enableExperimentSessions) {\n  process.env.DROID_ACP_EXPERIMENT_SESSIONS = \"1\";\n}\n\nif (enableWebsearchProxy) {\n  process.env.DROID_ACP_WEBSEARCH_NATIVE = \"1\";\n}\n\nif (useNativeAcp) {\n  // Native ACP mode: direct pipe to droid (no custom model support)\n  runNativeAcp();\n} else {\n  // Default: stream-jsonrpc mode with custom adapter (supports custom models)\n  runAcp();\n}\n\nprocess.stdin.resume();\n"],"mappings":"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"}