// Force strict mode and setup for ESM
"use strict";
import {
  ToolNames
} from "./chunk-G763GDO6.js";
import {
  init_esbuild_shims
} from "./chunk-A4BMJM77.js";
import {
  __name
} from "./chunk-J2S4EL5Y.js";

// packages/core/src/tools/priorReadEnforcement.ts
init_esbuild_shims();
import * as fs from "node:fs";
var StructuredToolError = class extends Error {
  constructor(message, errorType) {
    super(message);
    this.errorType = errorType;
  }
  static {
    __name(this, "StructuredToolError");
  }
  name = "StructuredToolError";
};
async function checkPriorRead(cache, filePath, verb, options = {}) {
  let stats;
  try {
    stats = await fs.promises.stat(filePath);
  } catch (err) {
    const code = err?.code;
    if (code === "ENOENT") {
      if (options.expectExisting) {
        const raw3 = `File ${filePath} disappeared after the model read it (stat now returns ENOENT). Re-read with the ${ToolNames.READ_FILE} tool \u2014 the path may have been deleted or moved \u2014 before retrying ${verb} it.`;
        return {
          ok: false,
          type: "file_changed_since_read" /* FILE_CHANGED_SINCE_READ */,
          rawMessage: raw3,
          displayMessage: `file disappeared after last read; re-run ${ToolNames.READ_FILE} first.`
        };
      }
      return { ok: true };
    }
    const raw2 = `Could not stat ${filePath} to verify prior read (${code ?? "unknown error"}). Re-read with the ${ToolNames.READ_FILE} tool, then retry ${verb} it.`;
    const verbDisplay2 = verb === "editing" ? "editing this file" : "overwriting this file";
    return {
      ok: false,
      type: "prior_read_verification_failed" /* PRIOR_READ_VERIFICATION_FAILED */,
      rawMessage: raw2,
      displayMessage: `cannot verify prior read of ${filePath}; re-run ${ToolNames.READ_FILE} before ${verbDisplay2}.`
    };
  }
  if (stats.isDirectory()) {
    const verbBare2 = verb === "editing" ? "edit" : "overwrite";
    const raw2 = `${filePath} is a directory. The Edit / WriteFile tools only operate on regular files. Use a different mechanism (e.g. the shell tool) if you need to ${verbBare2} the contents of this directory.`;
    return {
      ok: false,
      type: "target_is_directory" /* TARGET_IS_DIRECTORY */,
      rawMessage: raw2,
      displayMessage: `path is a directory; cannot ${verbBare2} via this tool.`
    };
  }
  if (!stats.isFile()) {
    const verbBare2 = verb === "editing" ? "edit" : "overwrite";
    const raw2 = `${filePath} is a FIFO / socket / character or block device. The Edit / WriteFile tools only operate on regular files; the ${ToolNames.READ_FILE} tool also rejects these targets. Use a different mechanism (e.g. shell tool with the appropriate command) if you need to ${verbBare2} this path.`;
    return {
      ok: false,
      type: "edit_requires_prior_read" /* EDIT_REQUIRES_PRIOR_READ */,
      rawMessage: raw2,
      displayMessage: `special file; cannot ${verbBare2} via this tool.`
    };
  }
  const status = cache.check(stats);
  if (status.state === "fresh" && status.entry.lastReadAt !== void 0 && status.entry.lastReadCacheable) {
    return { ok: true };
  }
  if (status.state === "stale") {
    const raw2 = `File ${filePath} has been modified since you last read it (mtime or size changed). Re-read it with the ${ToolNames.READ_FILE} tool before ${verb} it to ensure your changes are based on current content.`;
    return {
      ok: false,
      type: "file_changed_since_read" /* FILE_CHANGED_SINCE_READ */,
      rawMessage: raw2,
      displayMessage: `file changed since last read; re-run ${ToolNames.READ_FILE} first.`
    };
  }
  if (status.state === "fresh" && status.entry.lastReadAt !== void 0 && !status.entry.lastReadCacheable) {
    const verbBare2 = verb === "editing" ? "edit" : "overwrite";
    const raw2 = `File ${filePath} is a binary / image / audio / video / PDF / notebook payload that the ${ToolNames.READ_FILE} tool returns as a structured value rather than as plain text. The Edit / WriteFile tools cannot mutate that payload safely \u2014 re-reading it would not change this. If this is a Jupyter notebook (.ipynb), use the ${ToolNames.NOTEBOOK_EDIT} tool for cell-level edits after reading it. For other non-text files, use a different mechanism (e.g. shell tool with an appropriate writer) if you need to ${verbBare2} it.`;
    return {
      ok: false,
      type: "edit_requires_prior_read" /* EDIT_REQUIRES_PRIOR_READ */,
      rawMessage: raw2,
      displayMessage: `non-text payload; cannot ${verbBare2} via this tool.`
    };
  }
  const verbBare = verb === "editing" ? "edit" : "overwrite";
  const verbDisplay = verb === "editing" ? "editing this file" : "overwriting this file";
  const partialReadGuidance = verb === "editing" ? `(a partial read with offset / limit is fine \u2014 you only need to have seen the bytes you intend to ${verbBare})` : `(read the full file \u2014 overwriting replaces every byte, so any unseen bytes would be discarded)`;
  const raw = `File ${filePath} has not been read in this session. Use the ${ToolNames.READ_FILE} tool first to load the current content ${partialReadGuidance} before ${verb} it.`;
  return {
    ok: false,
    type: "edit_requires_prior_read" /* EDIT_REQUIRES_PRIOR_READ */,
    rawMessage: raw,
    displayMessage: `${ToolNames.READ_FILE} required before ${verbDisplay}.`
  };
}
__name(checkPriorRead, "checkPriorRead");

export {
  StructuredToolError,
  checkPriorRead
};
/**
 * @license
 * Copyright 2026 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 */
