"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// tools/warp_grep/agent/runner.ts
var runner_exports = {};
__export(runner_exports, {
  runWarpGrep: () => runWarpGrep,
  runWarpGrepStreaming: () => runWarpGrepStreaming
});
module.exports = __toCommonJS(runner_exports);

// tools/warp_grep/agent/config.ts
var parseEnvTimeout = (envValue, defaultMs) => {
  if (!envValue) return defaultMs;
  const parsed = parseInt(envValue, 10);
  return isNaN(parsed) || parsed <= 0 ? defaultMs : parsed;
};
var AGENT_CONFIG = {
  MAX_TURNS: 6,
  /** Default timeout for model calls. Can be overridden via MORPH_WARP_GREP_TIMEOUT env var (in ms) */
  TIMEOUT_MS: parseEnvTimeout(process.env.MORPH_WARP_GREP_TIMEOUT, 3e4),
  MAX_CONTEXT_CHARS: 321600,
  MAX_OUTPUT_LINES: 200,
  MAX_LIST_RESULTS: 500,
  MAX_READ_LINES: 800,
  MAX_LIST_DEPTH: 3,
  LIST_TIMEOUT_MS: 2e3
};
var BUILTIN_EXCLUDES = [
  // Version control
  ".git",
  ".svn",
  ".hg",
  ".bzr",
  // Dependencies
  "node_modules",
  "bower_components",
  ".pnpm",
  ".yarn",
  "vendor",
  "packages",
  "Pods",
  ".bundle",
  // Python
  "__pycache__",
  ".pytest_cache",
  ".mypy_cache",
  ".ruff_cache",
  ".venv",
  "venv",
  ".tox",
  ".nox",
  ".eggs",
  "*.egg-info",
  // Build outputs
  "dist",
  "build",
  "out",
  "output",
  "target",
  "_build",
  ".next",
  ".nuxt",
  ".output",
  ".vercel",
  ".netlify",
  // Cache directories
  ".cache",
  ".parcel-cache",
  ".turbo",
  ".nx",
  ".gradle",
  // IDE/Editor
  ".idea",
  ".vscode",
  ".vs",
  // Coverage
  "coverage",
  ".coverage",
  "htmlcov",
  ".nyc_output",
  // Temporary
  "tmp",
  "temp",
  ".tmp",
  ".temp",
  // Lock files
  "package-lock.json",
  "yarn.lock",
  "pnpm-lock.yaml",
  "bun.lockb",
  "Cargo.lock",
  "Gemfile.lock",
  "poetry.lock",
  // Binary/minified
  "*.min.js",
  "*.min.css",
  "*.bundle.js",
  "*.wasm",
  "*.so",
  "*.dll",
  "*.pyc",
  "*.map",
  "*.js.map",
  // Hidden directories catch-all
  ".*"
];
var DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || "").split(",").map((s) => s.trim()).filter(Boolean).concat(BUILTIN_EXCLUDES);
var DEFAULT_MODEL = "morph-warp-grep-v2.1";

// tools/warp_grep/agent/parser.ts
function parseReadLines(linesStr) {
  const ranges = [];
  for (const rangeStr of linesStr.split(",")) {
    const trimmed = rangeStr.trim();
    if (!trimmed) continue;
    const parts = trimmed.split("-").map((v) => parseInt(v.trim(), 10));
    if (parts.length >= 2 && Number.isFinite(parts[0]) && Number.isFinite(parts[1])) {
      ranges.push([parts[0], parts[1]]);
    } else if (Number.isFinite(parts[0])) {
      ranges.push([parts[0], parts[0]]);
    }
  }
  if (ranges.length === 1) return { start: ranges[0][0], end: ranges[0][1] };
  if (ranges.length > 1) return { lines: ranges };
  return {};
}
function parseFinishFiles(filesStr) {
  const files = [];
  for (const line of filesStr.trim().split(/\s+/)) {
    const trimmed = line.trim();
    if (!trimmed) continue;
    const searchFrom = /^[A-Za-z]:/.test(trimmed) ? 2 : 0;
    const colonIdx = trimmed.indexOf(":", searchFrom);
    if (colonIdx === -1) {
      files.push({ path: trimmed, lines: "*" });
      continue;
    }
    const filePath = trimmed.slice(0, colonIdx);
    const rangesPart = trimmed.slice(colonIdx + 1);
    if (!rangesPart.trim() || rangesPart.trim() === "*") {
      files.push({ path: filePath, lines: "*" });
      continue;
    }
    const ranges = [];
    for (const rangeStr of rangesPart.split(",")) {
      const rt = rangeStr.trim();
      if (!rt) continue;
      const parts = rt.split("-").map((v) => parseInt(v.trim(), 10));
      if (parts.length >= 2 && Number.isFinite(parts[0]) && Number.isFinite(parts[1])) {
        ranges.push([parts[0], parts[1]]);
      } else if (Number.isFinite(parts[0])) {
        ranges.push([parts[0], parts[0]]);
      }
    }
    files.push({ path: filePath, lines: ranges.length > 0 ? ranges : "*" });
  }
  return files;
}
function extractPathFromCommand(command) {
  const tokens = command.trim().split(/\s+/);
  const pathTokens = tokens.slice(1).filter((t) => !t.startsWith("-") && !t.startsWith("|") && !t.startsWith("\\("));
  return pathTokens[0] || ".";
}

// tools/warp_grep/agent/tools/grep.ts
async function toolGrep(provider, args) {
  const res = await provider.grep(args);
  if (res.error) {
    return { output: res.error };
  }
  if (!res.lines.length) {
    return { output: "no matches" };
  }
  return { output: res.lines.join("\n") };
}

// tools/warp_grep/agent/tools/read.ts
function isValidRange(start, end) {
  return typeof start === "number" && typeof end === "number" && Number.isFinite(start) && Number.isFinite(end) && start > 0 && end >= start;
}
async function toolRead(provider, args) {
  if (args.lines && Array.isArray(args.lines) && args.lines.length > 0) {
    const validRanges = [];
    for (const range of args.lines) {
      if (Array.isArray(range) && range.length >= 2 && isValidRange(range[0], range[1])) {
        validRanges.push([range[0], range[1]]);
      }
    }
    if (validRanges.length === 0) {
      const res2 = await provider.read({ path: args.path });
      if (res2.error) return res2.error;
      if (!res2.lines.length) return "(empty file)";
      return res2.lines.join("\n");
    }
    const chunks = [];
    for (const [start, end] of validRanges) {
      const res2 = await provider.read({ path: args.path, start, end });
      if (res2.error) return res2.error;
      chunks.push(res2.lines.join("\n"));
    }
    if (chunks.every((c) => c === "")) return "(empty file)";
    return chunks.join("\n...\n");
  }
  const res = await provider.read({ path: args.path, start: args.start, end: args.end });
  if (res.error) {
    return res.error;
  }
  if (!res.lines.length) return "(empty file)";
  return res.lines.join("\n");
}

// tools/warp_grep/agent/tools/list_directory.ts
var import_path = __toESM(require("path"), 1);
async function toolListDirectory(provider, args, repoRoot) {
  const maxResults = args.maxResults ?? AGENT_CONFIG.MAX_LIST_RESULTS;
  const maxDepth = args.maxDepth ?? AGENT_CONFIG.MAX_LIST_DEPTH;
  const entries = await provider.listDirectory({
    path: args.path,
    pattern: args.pattern ?? null,
    maxResults,
    maxDepth
  });
  if (!entries.length) return "empty";
  if (repoRoot) {
    const absRoot = repoRoot;
    const lines = entries.map((e) => import_path.default.join(absRoot, e.path));
    return lines.join("\n");
  }
  return entries.map((e) => e.path).join("\n");
}

// tools/warp_grep/agent/tools/glob.ts
async function toolGlob(provider, args) {
  const res = await provider.glob(args);
  if (res.error) {
    return res.error;
  }
  if (!res.files.length) {
    return "no matches";
  }
  const header = `Found ${res.totalFound} file(s) matching "${args.pattern}" within ${res.searchDir}, sorted by modification time (newest first):`;
  const body = res.files.join("\n");
  const truncated = res.totalFound > res.files.length ? `
[${res.totalFound - res.files.length} files truncated]` : "";
  return `${header}
---
${body}
---${truncated}`;
}

// tools/warp_grep/agent/tools/finish.ts
function isValidRange2(range) {
  return Array.isArray(range) && range.length >= 2 && typeof range[0] === "number" && typeof range[1] === "number" && Number.isFinite(range[0]) && Number.isFinite(range[1]) && range[0] > 0 && range[1] >= range[0];
}
function extractValidRanges(lines) {
  if (!Array.isArray(lines)) return null;
  const valid = [];
  for (const range of lines) {
    if (isValidRange2(range)) {
      valid.push([range[0], range[1]]);
    }
  }
  return valid.length > 0 ? valid : null;
}
async function readFinishFiles(repoRoot, files, reader) {
  const out = [];
  for (const f of files) {
    const validRanges = f.lines === "*" ? null : extractValidRanges(f.lines);
    if (f.lines === "*" || !validRanges) {
      const lines = await reader(f.path);
      out.push({ path: f.path, ranges: "*", content: lines.join("\n") });
    } else {
      const ranges = mergeRanges(validRanges);
      const chunks = [];
      for (let i = 0; i < ranges.length; i++) {
        const [s, e] = ranges[i];
        if (i === 0 && s > 1) {
          chunks.push(`// ... existing code, block starting at line ${s} ...`);
        } else if (i > 0) {
          chunks.push(`// ... existing code, block starting at line ${s} ...`);
        }
        const lines = await reader(f.path, s, e);
        chunks.push(lines.join("\n"));
      }
      out.push({ path: f.path, ranges, content: chunks.join("\n") });
    }
  }
  return out;
}
function mergeRanges(ranges) {
  if (!ranges.length) return [];
  const sorted = [...ranges].sort((a, b) => a[0] - b[0]);
  const merged = [];
  let [cs, ce] = sorted[0];
  for (let i = 1; i < sorted.length; i++) {
    const [s, e] = sorted[i];
    if (s <= ce + 1) {
      ce = Math.max(ce, e);
    } else {
      merged.push([cs, ce]);
      cs = s;
      ce = e;
    }
  }
  merged.push([cs, ce]);
  return merged;
}

// tools/warp_grep/agent/helpers.ts
var import_path2 = __toESM(require("path"), 1);
var TRUNCATED_MARKER = "[truncated for context limit]";
function getMessageSize(m) {
  if (m.role === "tool") return m.content.length;
  if (m.role === "assistant") {
    let size = typeof m.content === "string" ? m.content.length : 0;
    if (m.tool_calls) {
      size += m.tool_calls.reduce((s, tc) => s + tc.function.name.length + tc.function.arguments.length, 0);
    }
    return size;
  }
  return m.content.length;
}
function formatTurnMessage(turnsUsed, maxTurns) {
  const turnsRemaining = maxTurns - turnsUsed;
  if (turnsRemaining === 1) {
    return `
You have used ${turnsUsed} turns, you only have 1 turn remaining. You have run out of turns to explore the code base and MUST call the finish tool now`;
  }
  return `
You have used ${turnsUsed} turn${turnsUsed === 1 ? "" : "s"} and have ${turnsRemaining} remaining`;
}
function calculateContextBudget(messages) {
  const totalChars = messages.reduce((sum, m) => sum + getMessageSize(m), 0);
  const maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS;
  const percent = Math.floor(totalChars / maxChars * 100);
  const usedK = Math.floor(totalChars / 1e3);
  const maxK = Math.floor(maxChars / 1e3);
  return `<context_budget>${percent}% (${usedK}K/${maxK}K chars)</context_budget>`;
}
async function buildInitialState(repoRoot, searchTerm, provider, options) {
  const budget = calculateContextBudget([]);
  const turnTag = `You have used 0 turns and have ${AGENT_CONFIG.MAX_TURNS} remaining`;
  const treeDepth = options?.search_type === "node_modules" ? 1 : 2;
  const absRoot = repoRoot;
  try {
    const entries = await provider.listDirectory({
      path: ".",
      maxResults: AGENT_CONFIG.MAX_OUTPUT_LINES,
      maxDepth: treeDepth
    });
    const lines = [absRoot];
    for (const e of entries) {
      lines.push(import_path2.default.join(absRoot, e.path));
    }
    return `<repo_structure>
${lines.join("\n")}
</repo_structure>

<search_string>
${searchTerm}
</search_string>
${budget}
${turnTag}`;
  } catch {
    return `<repo_structure>
${absRoot}
</repo_structure>

<search_string>
${searchTerm}
</search_string>
${budget}
${turnTag}`;
  }
}
function enforceContextLimit(messages, maxChars = AGENT_CONFIG.MAX_CONTEXT_CHARS) {
  const getTotalChars = () => messages.reduce((sum, m) => sum + getMessageSize(m), 0);
  if (getTotalChars() <= maxChars) {
    return messages;
  }
  const truncatableIndices = [];
  let firstUserSkipped = false;
  for (let i = 0; i < messages.length; i++) {
    const m = messages[i];
    if (m.role === "tool") {
      truncatableIndices.push(i);
    } else if (m.role === "user") {
      if (!firstUserSkipped) {
        firstUserSkipped = true;
        continue;
      }
      truncatableIndices.push(i);
    }
  }
  for (const idx of truncatableIndices) {
    if (getTotalChars() <= maxChars) {
      break;
    }
    const m = messages[idx];
    if (m.role === "tool" && m.content !== TRUNCATED_MARKER) {
      messages[idx] = { role: "tool", tool_call_id: m.tool_call_id, content: TRUNCATED_MARKER };
    } else if (m.role === "user" && m.content !== TRUNCATED_MARKER) {
      messages[idx] = { role: "user", content: TRUNCATED_MARKER };
    }
  }
  return messages;
}

// tools/warp_grep/agent/runner.ts
var import_openai = __toESM(require("openai"), 1);

// package.json
var package_default = {
  name: "@morphllm/morphsdk",
  version: "0.2.168",
  description: "TypeScript SDK and CLI for Morph Fast Apply integration",
  type: "module",
  main: "./dist/index.cjs",
  module: "./dist/index.js",
  types: "./dist/index.d.ts",
  exports: {
    ".": {
      types: "./dist/index.d.ts",
      import: "./dist/index.js",
      require: "./dist/index.cjs"
    },
    "./logger": {
      types: "./dist/logger.d.ts",
      import: "./dist/logger.js",
      require: "./dist/logger.cjs"
    },
    "./edge": {
      types: "./dist/edge.d.ts",
      import: "./dist/edge.js",
      require: "./dist/edge.cjs"
    },
    "./tools/warp-grep": {
      types: "./dist/tools/warp_grep/index.d.ts",
      import: "./dist/tools/warp_grep/index.js",
      require: "./dist/tools/warp_grep/index.cjs"
    },
    "./tools/warp-grep/openai": {
      types: "./dist/tools/warp_grep/openai.d.ts",
      import: "./dist/tools/warp_grep/openai.js",
      require: "./dist/tools/warp_grep/openai.cjs"
    },
    "./tools/warp-grep/anthropic": {
      types: "./dist/tools/warp_grep/anthropic.d.ts",
      import: "./dist/tools/warp_grep/anthropic.js",
      require: "./dist/tools/warp_grep/anthropic.cjs"
    },
    "./tools/warp-grep/vercel": {
      types: "./dist/tools/warp_grep/vercel.d.ts",
      import: "./dist/tools/warp_grep/vercel.js",
      require: "./dist/tools/warp_grep/vercel.cjs"
    },
    "./tools/warp-grep/client": {
      types: "./dist/tools/warp_grep/client.d.ts",
      import: "./dist/tools/warp_grep/client.js",
      require: "./dist/tools/warp_grep/client.cjs"
    },
    "./tools/warp-grep/gemini": {
      types: "./dist/tools/warp_grep/gemini.d.ts",
      import: "./dist/tools/warp_grep/gemini.js",
      require: "./dist/tools/warp_grep/gemini.cjs"
    },
    "./tools/warp-grep/harness": {
      types: "./dist/tools/warp_grep/harness.d.ts",
      import: "./dist/tools/warp_grep/harness.js",
      require: "./dist/tools/warp_grep/harness.cjs"
    },
    "./tools/fastapply": {
      types: "./dist/tools/fastapply/index.d.ts",
      import: "./dist/tools/fastapply/index.js",
      require: "./dist/tools/fastapply/index.cjs"
    },
    "./tools/fastapply/anthropic": {
      types: "./dist/tools/fastapply/anthropic.d.ts",
      import: "./dist/tools/fastapply/anthropic.js",
      require: "./dist/tools/fastapply/anthropic.cjs"
    },
    "./tools/fastapply/openai": {
      types: "./dist/tools/fastapply/openai.d.ts",
      import: "./dist/tools/fastapply/openai.js",
      require: "./dist/tools/fastapply/openai.cjs"
    },
    "./tools/fastapply/vercel": {
      types: "./dist/tools/fastapply/vercel.d.ts",
      import: "./dist/tools/fastapply/vercel.js",
      require: "./dist/tools/fastapply/vercel.cjs"
    },
    "./tools/codebase-search": {
      types: "./dist/tools/codebase_search/index.d.ts",
      import: "./dist/tools/codebase_search/index.js",
      require: "./dist/tools/codebase_search/index.cjs"
    },
    "./tools/codebase-search/anthropic": {
      types: "./dist/tools/codebase_search/anthropic.d.ts",
      import: "./dist/tools/codebase_search/anthropic.js",
      require: "./dist/tools/codebase_search/anthropic.cjs"
    },
    "./tools/codebase-search/openai": {
      types: "./dist/tools/codebase_search/openai.d.ts",
      import: "./dist/tools/codebase_search/openai.js",
      require: "./dist/tools/codebase_search/openai.cjs"
    },
    "./tools/codebase-search/vercel": {
      types: "./dist/tools/codebase_search/vercel.d.ts",
      import: "./dist/tools/codebase_search/vercel.js",
      require: "./dist/tools/codebase_search/vercel.cjs"
    },
    "./tools/git": {
      types: "./dist/git/index.d.ts",
      import: "./dist/git/index.js",
      require: "./dist/git/index.cjs"
    },
    "./tools/browser": {
      types: "./dist/tools/browser/index.d.ts",
      import: "./dist/tools/browser/index.js",
      require: "./dist/tools/browser/index.cjs"
    },
    "./tools/browser/anthropic": {
      types: "./dist/tools/browser/anthropic.d.ts",
      import: "./dist/tools/browser/anthropic.js",
      require: "./dist/tools/browser/anthropic.cjs"
    },
    "./tools/browser/openai": {
      types: "./dist/tools/browser/openai.d.ts",
      import: "./dist/tools/browser/openai.js",
      require: "./dist/tools/browser/openai.cjs"
    },
    "./tools/browser/vercel": {
      types: "./dist/tools/browser/vercel.d.ts",
      import: "./dist/tools/browser/vercel.js",
      require: "./dist/tools/browser/vercel.cjs"
    },
    "./tools/browser/profiles": {
      types: "./dist/tools/browser/profiles/index.d.ts",
      import: "./dist/tools/browser/profiles/index.js",
      require: "./dist/tools/browser/profiles/index.cjs"
    },
    "./modelrouter": {
      types: "./dist/modelrouter/index.d.ts",
      import: "./dist/modelrouter/index.js",
      require: "./dist/modelrouter/index.cjs"
    },
    "./tools/compact": {
      types: "./dist/tools/compact/index.d.ts",
      import: "./dist/tools/compact/index.js",
      require: "./dist/tools/compact/index.cjs"
    },
    "./subagents": {
      types: "./dist/subagents/index.d.ts",
      import: "./dist/subagents/index.js",
      require: "./dist/subagents/index.cjs"
    },
    "./subagents/vercel": {
      types: "./dist/subagents/vercel.d.ts",
      import: "./dist/subagents/vercel.js",
      require: "./dist/subagents/vercel.cjs"
    },
    "./subagents/anthropic": {
      types: "./dist/subagents/anthropic.d.ts",
      import: "./dist/subagents/anthropic.js",
      require: "./dist/subagents/anthropic.cjs"
    }
  },
  files: [
    "dist/**/*.js",
    "dist/**/*.cjs",
    "dist/**/*.d.ts",
    "dist/**/*.map",
    "!dist/**/__tests__/**",
    "!dist/**/*.test.*"
  ],
  scripts: {
    build: "tsup version.ts index.ts edge.ts client.ts tools/index.ts tools/fastapply/index.ts tools/fastapply/core.ts tools/fastapply/apply.ts tools/fastapply/types.ts tools/fastapply/prompts.ts tools/fastapply/anthropic.ts tools/fastapply/openai.ts tools/fastapply/vercel.ts tools/codebase_search/index.ts tools/codebase_search/core.ts tools/codebase_search/types.ts tools/codebase_search/prompts.ts tools/codebase_search/anthropic.ts tools/codebase_search/openai.ts tools/codebase_search/vercel.ts tools/warp_grep/index.ts tools/warp_grep/client.ts tools/warp_grep/openai.ts tools/warp_grep/anthropic.ts tools/warp_grep/vercel.ts tools/warp_grep/gemini.ts tools/warp_grep/harness.ts tools/warp_grep/agent/config.ts tools/warp_grep/agent/parser.ts tools/warp_grep/agent/runner.ts tools/warp_grep/agent/types.ts tools/warp_grep/agent/formatter.ts tools/warp_grep/providers/types.ts tools/warp_grep/providers/local.ts tools/warp_grep/providers/remote.ts tools/warp_grep/providers/code_storage_http.ts tools/warp_grep/tools/grep.ts tools/warp_grep/tools/analyse.ts tools/warp_grep/tools/read.ts tools/warp_grep/tools/finish.ts tools/warp_grep/utils/paths.ts tools/warp_grep/utils/github.ts tools/warp_grep/utils/ripgrep.ts tools/warp_grep/utils/format.ts tools/warp_grep/utils/files.ts git/index.ts git/client.ts git/config.ts git/types.ts tools/browser/index.ts tools/browser/core.ts tools/browser/types.ts tools/browser/prompts.ts tools/browser/anthropic.ts tools/browser/openai.ts tools/browser/vercel.ts tools/browser/live.ts tools/browser/errors.ts tools/browser/profiles/index.ts tools/browser/profiles/core.ts tools/browser/profiles/types.ts modelrouter/index.ts modelrouter/core.ts modelrouter/types.ts tools/compact/index.ts tools/compact/core.ts tools/compact/types.ts tools/utils/resilience.ts subagents/index.ts subagents/types.ts subagents/prompts.ts subagents/vercel.ts subagents/anthropic.ts --format esm,cjs --sourcemap --clean --dts --dts-resolve",
    prepare: "npm run build",
    typecheck: "tsc --noEmit",
    lint: "eslint .",
    test: "vitest run",
    "test:watch": "vitest watch",
    "test:anthropic": "vitest run anthropic",
    "test:openai": "vitest run openai",
    "test:vercel": "vitest run vercel",
    "test:git": "vitest run git",
    "test:browser": "vitest run browser",
    "test:agent": "npx tsx tests/fullAgentTest.ts",
    "test:integration": "npx tsx tests/fullIntegrationTest.ts",
    "test:e2e": "vitest run --config vitest.e2e.config.ts",
    "release:patch": "npm version patch && npm publish",
    "release:minor": "npm version minor && npm publish",
    "release:major": "npm version major && npm publish"
  },
  keywords: [
    "morph",
    "fast-apply",
    "cli",
    "sdk",
    "edit-file"
  ],
  engines: {
    node: ">=18"
  },
  license: "MIT",
  dependencies: {
    "@vscode/ripgrep": "^1.17.0",
    ai: ">=5.0.0",
    diff: "^7.0.0",
    "isomorphic-git": "^1.25.10",
    openai: "^4.52.7",
    zod: ">=3.23.0"
  },
  devDependencies: {
    "@ai-sdk/anthropic": "^2.0.70",
    "@ai-sdk/openai": "^2.0.35",
    "@anthropic-ai/sdk": "^0.30.1",
    "@google/generative-ai": "^0.24.1",
    "@types/diff": "^7.0.2",
    "@types/node": "^20.14.10",
    "@typescript-eslint/eslint-plugin": "^7.18.0",
    "@typescript-eslint/parser": "^7.18.0",
    dotenv: "^16.4.5",
    eslint: "^8.57.0",
    shx: "^0.3.4",
    tsup: "^8.5.0",
    tsx: "^4.16.2",
    typescript: "^5.5.4",
    vitest: "^2.1.6"
  },
  peerDependencies: {
    "@anthropic-ai/sdk": ">=0.25.0",
    "@google/generative-ai": ">=0.21.0",
    ai: ">=5.0.0",
    zod: ">=3.23.0"
  },
  peerDependenciesMeta: {
    "@anthropic-ai/sdk": {
      optional: true
    },
    "@google/generative-ai": {
      optional: true
    },
    ai: {
      optional: true
    },
    zod: {
      optional: true
    }
  },
  publishConfig: {
    access: "public"
  }
};

// version.ts
var SDK_VERSION = package_default.version;

// tools/warp_grep/agent/runner.ts
var import_path3 = __toESM(require("path"), 1);

// logger.ts
var MorphLogger = class {
  enabled;
  fileStream;
  /** Resolves once the file stream is initialized (or immediately if no file logging). */
  ready;
  constructor() {
    this.enabled = typeof process !== "undefined" && (process.env.MORPH_DEBUG === "1" || !!process.env.MORPH_LOG_FILE);
    this.fileStream = null;
    const f = typeof process !== "undefined" ? process.env.MORPH_LOG_FILE : void 0;
    if (f) {
      this.ready = import("fs").then((fs) => {
        this.fileStream = fs.createWriteStream(f, { flags: "a" });
      }).catch(() => {
      });
    } else {
      this.ready = Promise.resolve();
    }
  }
  debug(component, msg, data) {
    this._log("debug", component, msg, data);
  }
  info(component, msg, data) {
    this._log("info", component, msg, data);
  }
  warn(component, msg, data) {
    this._log("warn", component, msg, data);
  }
  error(component, msg, data) {
    this._log("error", component, msg, data);
  }
  enable() {
    this.enabled = true;
  }
  get isEnabled() {
    return this.enabled;
  }
  _log(level, component, msg, data) {
    if (level !== "error" && !this.enabled) return;
    const ts = (/* @__PURE__ */ new Date()).toISOString();
    const prefix = `[${ts}] [${level.toUpperCase()}] [${component}]`;
    console.error(data ? `${prefix} ${msg} ${JSON.stringify(data)}` : `${prefix} ${msg}`);
    this.fileStream?.write(JSON.stringify({ ts, level, component, msg, ...data && { data } }) + "\n");
  }
};
var logger = new MorphLogger();

// tools/warp_grep/agent/runner.ts
var DEFAULT_API_URL = "https://api.morphllm.com";
var TOOL_SPECS = [
  {
    type: "function",
    function: {
      name: "list_directory",
      description: "Execute ls or find commands to explore directory structure. Max 500 results. Common junk directories are excluded automatically.",
      parameters: {
        type: "object",
        properties: {
          command: {
            type: "string",
            description: "Full ls or find command (e.g. ls -la src/, find . -maxdepth 2 -type f -name '*.py', find . -type d, ls -d */)."
          }
        },
        required: ["command"]
      }
    }
  },
  {
    type: "function",
    function: {
      name: "grep_search",
      description: "Search for a regex pattern in file contents. Returns matching lines with file paths and line numbers. Case-insensitive. Respects .gitignore.",
      parameters: {
        type: "object",
        properties: {
          pattern: {
            type: "string",
            description: "Regex pattern to search for in file contents (e.g. 'class\\s+\\w+Error', 'import|require|from', 'def (get|set|update)_user')."
          },
          path: {
            type: "string",
            description: "File or directory to search in. Defaults to current working directory."
          },
          glob: {
            type: "string",
            description: "Glob pattern to filter files (e.g. '*.py', '*.{ts,tsx,js,jsx,py,go}', 'src/**/*.go', '!*.test.*')."
          },
          limit: {
            type: "integer",
            description: "Limit output to first N matching lines. Shows all matches if not specified."
          }
        },
        required: ["pattern"]
      }
    }
  },
  {
    type: "function",
    function: {
      name: "glob",
      description: "Find files by name/extension using glob patterns. Returns absolute paths sorted by modification time (newest first). Respects .gitignore. Max 100 results.",
      parameters: {
        type: "object",
        properties: {
          pattern: {
            type: "string",
            description: "Glob pattern to match files (e.g. '*.py', 'src/**/*.js', '*.{ts,tsx}', 'test_*.py')."
          },
          path: {
            type: "string",
            description: "Directory to search in. Defaults to repository root."
          }
        },
        required: ["pattern"]
      }
    }
  },
  {
    type: "function",
    function: {
      name: "read",
      description: "Read entire files or specific line ranges using absolute paths.",
      parameters: {
        type: "object",
        properties: {
          path: {
            type: "string",
            description: "File path to read, using absolute path (e.g. '/home/ubuntu/repo/src/main.py' or windows path)."
          },
          lines: {
            type: "string",
            description: "Optional line range (e.g. '1-50' or '1-20,45-80'). Omit to read entire file."
          }
        },
        required: ["path"]
      }
    }
  },
  {
    type: "function",
    function: {
      name: "finish",
      description: "Submit final answer with all relevant code locations. Include imports and over-include rather than miss context.",
      parameters: {
        type: "object",
        properties: {
          files: {
            type: "string",
            description: "One file per line as path:lines (e.g. 'src/auth.py:1-15,25-50\\nsrc/user.py'). Omit line range to include entire file."
          }
        },
        required: ["files"]
      }
    }
  }
];
async function callModel(messages, model, options = {}) {
  const baseUrl = options.morphApiUrl || DEFAULT_API_URL;
  const apiKey = options.morphApiKey || process.env.MORPH_API_KEY || "";
  const timeoutMs = options.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
  const parsedUrl = new URL(baseUrl);
  const baseURL = parsedUrl.pathname === "/" ? `${baseUrl}/v1` : baseUrl;
  const client = new import_openai.default({
    apiKey,
    baseURL,
    maxRetries: options.retryConfig?.maxRetries,
    timeout: timeoutMs,
    defaultHeaders: { "X-Morph-SDK-Version": SDK_VERSION }
  });
  const MAX_EMPTY_RETRIES = 1;
  logger.debug("WarpGrep", "model_call", { url: baseURL, model, message_count: messages.length });
  const callStartTime = Date.now();
  for (let attempt = 0; attempt <= MAX_EMPTY_RETRIES; attempt++) {
    let data;
    try {
      data = await client.chat.completions.create({
        model,
        temperature: 0,
        max_tokens: 2048,
        messages,
        tools: TOOL_SPECS,
        ...options.search_type ? { search_type: options.search_type } : {}
      });
    } catch (error) {
      const callLatencyMs = Date.now() - callStartTime;
      if (error instanceof import_openai.default.APIError) {
        logger.error("WarpGrep", "model_call_error", { status: error.status, error: error.message, latency_ms: callLatencyMs });
        if (error.status === 404) {
          const defaultMsg = "The endpoint you are trying to call is likely deprecated. Please update with: npm cache clean --force && npx -y @morphllm/morphmcp@latest or visit: https://morphllm.com/mcp";
          const errorText = error.message?.trim();
          throw new Error(errorText || defaultMsg);
        }
      } else {
        logger.error("WarpGrep", "model_call_error", { status: void 0, error: error instanceof Error ? error.message : String(error), latency_ms: callLatencyMs });
      }
      throw error;
    }
    const choice = data?.choices?.[0];
    const message = choice?.message;
    if (!message) {
      if (attempt === MAX_EMPTY_RETRIES) {
        throw new Error("Invalid response from model: no message in response");
      }
      await new Promise((resolve) => setTimeout(resolve, 200));
      continue;
    }
    const toolCalls = (message.tool_calls || []).map((tc) => ({
      id: tc.id,
      type: "function",
      function: { name: tc.function.name, arguments: tc.function.arguments }
    }));
    if (message.content || toolCalls.length > 0) {
      logger.debug("WarpGrep", "model_call_complete", { latency_ms: Date.now() - callStartTime, tool_calls_count: toolCalls.length, finish_reason: choice?.finish_reason ?? "unknown" });
      return { content: message.content ?? null, tool_calls: toolCalls };
    }
    if (attempt === MAX_EMPTY_RETRIES) {
      const finishReason = choice?.finish_reason ?? "unknown";
      throw new Error(
        `Invalid response from model: no content and no tool_calls, finish_reason=${finishReason}`
      );
    }
    await new Promise((resolve) => setTimeout(resolve, 200));
  }
  throw new Error("Invalid response from model");
}
function safeParseJSON(s) {
  try {
    return JSON.parse(s);
  } catch {
    return {};
  }
}
async function executeTool(provider, name, args, repoRoot) {
  switch (name) {
    case "grep_search": {
      const grepArgs = {
        pattern: args.pattern,
        path: args.path || "."
      };
      if (args.glob) grepArgs.glob = args.glob;
      if (args.case_sensitive !== void 0) grepArgs.case_sensitive = args.case_sensitive;
      const result = await toolGrep(provider, grepArgs);
      let output = result.output;
      if (args.limit && typeof args.limit === "number") {
        const lines = output.split("\n");
        if (lines.length > args.limit) {
          output = lines.slice(0, args.limit).join("\n") + `
... (truncated at ${args.limit} lines)`;
        }
      }
      return output;
    }
    case "glob": {
      return toolGlob(provider, {
        pattern: args.pattern,
        path: args.path
      });
    }
    case "list_directory": {
      const dirPath = extractPathFromCommand(args.command || ".");
      return toolListDirectory(provider, { path: dirPath }, repoRoot);
    }
    case "read": {
      const readArgs = {
        path: args.path
      };
      if (args.lines && typeof args.lines === "string") {
        Object.assign(readArgs, parseReadLines(args.lines));
      }
      return toolRead(provider, readArgs);
    }
    default:
      return `Unknown tool: ${name}`;
  }
}
async function* runWarpGrepStreaming(config) {
  const totalStart = Date.now();
  const timeoutMs = config.timeout ?? AGENT_CONFIG.TIMEOUT_MS;
  const timings = { turns: [], timeout_ms: timeoutMs };
  const repoRoot = config.repoRoot || process.cwd();
  const model = config.model || DEFAULT_MODEL;
  const messages = [];
  const maxTurns = AGENT_CONFIG.MAX_TURNS;
  logger.debug("WarpGrep", "session_start", { search_term: config.searchTerm, model, max_turns: maxTurns });
  const initialStateStart = Date.now();
  const initialState = await buildInitialState(repoRoot, config.searchTerm, config.provider, { search_type: config.search_type });
  timings.initial_state_ms = Date.now() - initialStateStart;
  logger.debug("WarpGrep", "initial_state", { system_prompt_len: initialState.length, user_message_len: initialState.length });
  messages.push({ role: "user", content: initialState });
  const provider = config.provider;
  const errors = [];
  let finishMeta;
  let terminationReason = "terminated";
  for (let turn = 1; turn <= maxTurns; turn += 1) {
    const turnMetrics = { turn, morph_api_ms: 0, local_tools_ms: 0 };
    logger.debug("WarpGrep", "turn_start", { turn, message_count: messages.length });
    const beforeChars = messages.reduce((sum, m) => sum + (typeof m.content === "string" ? m.content.length : 0), 0);
    enforceContextLimit(messages);
    const afterChars = messages.reduce((sum, m) => sum + (typeof m.content === "string" ? m.content.length : 0), 0);
    if (afterChars < beforeChars) {
      logger.debug("WarpGrep", "context_truncated", { before_chars: beforeChars, after_chars: afterChars });
    }
    const modelCallStart = Date.now();
    const response = await callModel(messages, model, {
      morphApiKey: config.morphApiKey,
      morphApiUrl: config.morphApiUrl,
      retryConfig: config.retryConfig,
      timeout: timeoutMs,
      search_type: config.search_type
    }).catch((e) => {
      const errMsg = e instanceof Error ? e.message : String(e);
      console.error(`[warp_grep] Morph API call failed on turn ${turn}:`, errMsg);
      logger.error("WarpGrep", "error", { turn, error: errMsg, phase: "model_call" });
      errors.push({ message: errMsg });
      return null;
    });
    turnMetrics.morph_api_ms = Date.now() - modelCallStart;
    if (!response) {
      timings.turns.push(turnMetrics);
      break;
    }
    const toolCalls = response.tool_calls;
    logger.debug("WarpGrep", "model_response", { turn, tool_calls: toolCalls.map((tc) => tc.function.name), latency_ms: turnMetrics.morph_api_ms });
    messages.push({
      role: "assistant",
      content: response.content,
      ...toolCalls.length > 0 ? { tool_calls: toolCalls } : {}
    });
    if (toolCalls.length === 0) {
      console.error(`[warp_grep] No tool calls on turn ${turn}. Content: ${(response.content || "").slice(0, 500)}`);
      errors.push({ message: "No tool calls produced by the model." });
      terminationReason = "terminated";
      timings.turns.push(turnMetrics);
      break;
    }
    yield {
      turn,
      toolCalls: toolCalls.map((tc) => ({
        name: tc.function.name,
        arguments: safeParseJSON(tc.function.arguments)
      }))
    };
    const finishCall = toolCalls.find((tc) => tc.function.name === "finish");
    if (finishCall) {
      const args = safeParseJSON(finishCall.function.arguments);
      const filesStr = args.files || "";
      const files = parseFinishFiles(filesStr);
      finishMeta = { files };
      terminationReason = "completed";
      logger.debug("WarpGrep", "finish", { turns: turn, files: files.map((f) => f.path) });
      if (files.length === 0) {
        const payload2 = filesStr || "No relevant code found.";
        timings.turns.push(turnMetrics);
        timings.total_ms = Date.now() - totalStart;
        return {
          terminationReason: "completed",
          messages,
          finish: { payload: payload2, metadata: finishMeta },
          timings
        };
      }
      timings.turns.push(turnMetrics);
      break;
    }
    const toolExecStart = Date.now();
    const results = await Promise.all(
      toolCalls.map(async (tc) => {
        const args = safeParseJSON(tc.function.arguments);
        const argsSummary = Object.fromEntries(Object.entries(args).map(([k, v]) => [k, typeof v === "string" && v.length > 100 ? v.slice(0, 100) + "..." : v]));
        logger.debug("WarpGrep", "tool_exec", { turn, tool: tc.function.name, args_summary: argsSummary });
        const toolStart = Date.now();
        const output = await executeTool(provider, tc.function.name, args, repoRoot).catch((err) => String(err));
        logger.debug("WarpGrep", "tool_result", { turn, tool: tc.function.name, result_len: output.length, latency_ms: Date.now() - toolStart });
        return { tool_call_id: tc.id, content: output };
      })
    );
    turnMetrics.local_tools_ms = Date.now() - toolExecStart;
    for (const result of results) {
      messages.push({ role: "tool", tool_call_id: result.tool_call_id, content: result.content });
    }
    const turnMsg = formatTurnMessage(turn, maxTurns);
    const budget = calculateContextBudget(messages);
    messages.push({ role: "user", content: turnMsg + "\n" + budget });
    timings.turns.push(turnMetrics);
  }
  if (terminationReason !== "completed" || !finishMeta) {
    timings.total_ms = Date.now() - totalStart;
    return { terminationReason, messages, errors, timings };
  }
  const parts = ["Relevant context found:"];
  for (const f of finishMeta.files) {
    const ranges = f.lines === "*" ? "*" : Array.isArray(f.lines) ? f.lines.map(([s, e]) => `${s}-${e}`).join(", ") : "*";
    parts.push(`- ${f.path}: ${ranges}`);
  }
  const payload = parts.join("\n");
  const finishResolutionStart = Date.now();
  const fileReadErrors = [];
  const resolved = await readFinishFiles(
    repoRoot,
    finishMeta.files,
    async (p, s, e) => {
      let resolvedPath = p;
      if (!p.startsWith(repoRoot)) {
        const relative = p.startsWith("/") ? p.slice(1) : p;
        resolvedPath = import_path3.default.join(repoRoot, relative);
      }
      try {
        const rr = await provider.read({ path: resolvedPath, start: s, end: e });
        return rr.lines.map((l) => {
          const idx = l.indexOf("|");
          return idx >= 0 ? l.slice(idx + 1) : l;
        });
      } catch (err) {
        const errorMsg = err instanceof Error ? err.message : String(err);
        fileReadErrors.push({ path: resolvedPath, error: errorMsg });
        console.error(`[warp_grep] Failed to read file: ${resolvedPath} - ${errorMsg}`);
        return [`[couldn't find: ${resolvedPath}]`];
      }
    }
  );
  timings.finish_resolution_ms = Date.now() - finishResolutionStart;
  if (fileReadErrors.length > 0) {
    errors.push(...fileReadErrors.map((e) => ({ message: `File read error: ${e.path} - ${e.error}` })));
  }
  timings.total_ms = Date.now() - totalStart;
  return {
    terminationReason: "completed",
    messages,
    finish: { payload, metadata: finishMeta, resolved },
    timings
  };
}
async function runWarpGrep(config) {
  const gen = runWarpGrepStreaming(config);
  let result = await gen.next();
  while (!result.done) {
    result = await gen.next();
  }
  return result.value;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  runWarpGrep,
  runWarpGrepStreaming
});
//# sourceMappingURL=runner.cjs.map