UNPKG

@pstdio/opfs-utils

Version:

Utilities for the browser's OPFS: ls, grep, safe file read, unified diff patching, and MIME helpers.

1,629 lines 65.5 kB
import * as y from "isomorphic-git"; import { fs as Tt, configureSingle as Ct } from "@zenfs/core"; import { WebAccess as Ot } from "@zenfs/dom"; import { applyPatch as Q, parsePatch as It } from "diff"; let B = null, tt = null; function Pt() { if (typeof navigator > "u" || !navigator.storage) return null; const t = navigator.storage.getDirectory; return typeof t == "function" ? t.bind(navigator.storage) : null; } async function lt(t, e) { if (!t) return !1; const n = t; if (typeof n.isSameEntry == "function") try { return await n.isSameEntry(e); } catch { } return t === e; } async function Mt(t) { if (await lt(tt, t)) { B && await B; return; } B && (await B, await lt(tt, t)) || (B = (async () => { try { await Ct({ backend: Ot, handle: t }), tt = t; } finally { B = null; } })(), await B); } async function k() { const t = Pt(); if (!t) throw new Error("OPFS is not supported (navigator.storage.getDirectory unavailable)."); const e = await t(); return await Mt(e), Tt; } async function Lt(t, e) { const { dir: n } = t, i = await k(), s = String(e || "").trim(); if (!s) throw new Error("resolveOid: ref/sha is required"); try { return await y.resolveRef({ fs: i, dir: n, ref: s }); } catch { if (!/^[0-9a-fA-F]{4,40}$/.test(s)) throw new Error(`resolveOid: cannot resolve ref '${e}'`); return s.length === 40 ? s : await y.expandOid({ fs: i, dir: n, oid: s }); } } async function H(t, e = {}) { const { dir: n } = t, i = e.defaultBranch ?? "main", s = await k(); let r = !1, a; try { a = await y.currentBranch({ fs: s, dir: n, fullname: !1 }); } catch { a = void 0; } if (!a) try { await y.resolveRef({ fs: s, dir: n, ref: "HEAD" }), a = await y.currentBranch({ fs: s, dir: n, fullname: !1 }); } catch { await y.init({ fs: s, dir: n, defaultBranch: i }), r = !0, a = i; } if (e.name) try { await y.setConfig({ fs: s, dir: n, path: "user.name", value: e.name }); } catch { } if (e.email) try { await y.setConfig({ fs: s, dir: n, path: "user.email", value: e.email }); } catch { } return { created: r, currentBranch: typeof a == "string" && a ? a : i }; } async function Bt(t) { const { dir: e } = t, n = await k(), i = await y.statusMatrix({ fs: n, dir: e }), s = [], r = [], a = [], l = [], o = [], c = [], u = [], f = [], d = []; for (const m of i) { const [h, p, w, E] = m; if (p === 0 && w === 2 && E === 0) { l.push(h); continue; } if (p === 0 && (E === 2 || E === 3)) { s.push(h), o.push(h); continue; } if (p === 1 && w === 2) { r.push(h), E === 2 ? c.push(h) : E === 1 && f.push(h); continue; } if (p === 1 && w === 0) { a.push(h), E === 0 ? u.push(h) : E === 1 && d.push(h); continue; } } return { added: s, modified: r, deleted: a, untracked: l, stagedAdded: o, stagedModified: c, stagedDeleted: u, unstagedModified: f, unstagedDeleted: d }; } async function zt(t, e) { const { dir: n } = t, { message: i, author: s, branch: r, dryRun: a } = e; if (!i?.trim()) throw new Error("commitAll: commit message is required"); if (!s?.name || !s?.email) throw new Error("commitAll: author { name, email } is required"); const l = await k(); await H(t); const o = await Bt(t), c = [...o.added, ...o.modified, ...o.untracked], u = [...o.deleted]; for (const m of c) a || await y.add({ fs: l, dir: n, filepath: m }); for (const m of u) a || await y.remove({ fs: l, dir: n, filepath: m }); if (c.length === 0 && u.length === 0) return { oid: null, added: [], modified: [], deleted: [], summary: "No changes to commit.", dryRun: a }; let f = null; if (!a) { try { const m = await y.currentBranch({ fs: l, dir: n, fullname: !1 }); r && m !== r && await y.writeRef({ fs: l, dir: n, ref: "HEAD", value: `refs/heads/${r}`, force: !0, symbolic: !0 }); } catch { } f = await y.commit({ fs: l, dir: n, message: i, author: s, committer: s }); } const d = (a ? "[dry-run] " : "") + `Committed ${c.length + u.length} change(s)` + (c.length ? ` (+${c.length})` : "") + (u.length ? ` (-${u.length})` : "") + "."; return { oid: f, added: c, modified: o.modified, deleted: u, summary: d, dryRun: a }; } async function je(t, e = {}) { const { dir: n } = t, { limit: i = 20 } = e, s = await k(); let r = e.ref; return r || (r = await y.currentBranch({ fs: s, dir: n, fullname: !1 }) ?? "HEAD"), (await y.log({ fs: s, dir: n, ref: r, depth: i })).map((l) => { const o = l.commit || {}, c = o.author || {}, u = o.committer || {}, f = typeof u.timestamp == "number" ? new Date(u.timestamp * 1e3).toISOString() : void 0; return { oid: l.oid, message: String(o.message || "").trim(), author: c.name, email: c.email, isoDate: f, parents: Array.isArray(l.parents) ? l.parents : [] }; }); } async function Ue(t, e = {}) { const { dir: n } = t, i = await k(); await H(t); const s = e.perRefDepth ?? 200; let r = e.refs; if (!r) { const o = await y.listBranches({ fs: i, dir: n }), c = e.includeTags ?? !0 ? await y.listTags({ fs: i, dir: n }) : []; r = [...o, ...c]; } const a = /* @__PURE__ */ new Map(); for (const o of r) { let c = []; try { c = await y.log({ fs: i, dir: n, ref: o, depth: s }); } catch { continue; } for (const u of c) { const f = u.oid, d = u.commit || {}, m = d.author || {}, h = d.committer || {}, p = typeof h.timestamp == "number" ? new Date(h.timestamp * 1e3).toISOString() : void 0, w = Array.isArray(u.parents) ? u.parents : [], E = String(d.message || "").trim(), v = a.get(f); v ? v.refs.includes(o) || v.refs.push(o) : a.set(f, { oid: f, message: E, author: m.name, email: m.email, isoDate: p, parents: w, refs: [o] }); } } const l = Array.from(a.values()); return l.sort((o, c) => (c.isoDate || "").localeCompare(o.isoDate || "")), typeof e.limit == "number" ? l.slice(0, e.limit) : l; } async function Wt(t, e) { const { dir: n } = t, { to: i } = e, s = e.mode ?? "hard", r = e.force ?? !0; if (!i || !String(i).trim()) throw new Error("revertToCommit: `to` is required"); const a = await k(); let l = ""; const o = String(i).trim(), c = /^[0-9a-fA-F]{4,40}$/.test(o); try { l = await y.resolveRef({ fs: a, dir: n, ref: o }); } catch { if (!c) throw new Error(`revertToCommit: cannot resolve ref '${i}'`); try { l = o.length === 40 ? o : await y.expandOid({ fs: a, dir: n, oid: o }); } catch { throw new Error(`revertToCommit: cannot resolve OID '${i}'`); } } await H(t); let u = ""; try { u = await y.currentBranch({ fs: a, dir: n, fullname: !1 }) || ""; } catch { u = ""; } if (s === "hard" && u) { await y.writeRef({ fs: a, dir: n, ref: `refs/heads/${u}`, value: l, force: !0 }); try { await y.writeRef({ fs: a, dir: n, ref: "HEAD", value: `refs/heads/${u}`, force: !0, symbolic: !0 }); } catch { } await y.checkout({ fs: a, dir: n, ref: u, force: r }); const d = l.slice(0, 7); return { oid: l, branch: u, detached: !1, summary: `Checked out ${d} on ${u} (hard)` }; } await y.writeRef({ fs: a, dir: n, ref: "HEAD", value: l, force: !0 }), await y.checkout({ fs: a, dir: n, force: r }); const f = l.slice(0, 7); return { oid: l, detached: !0, summary: `Detached HEAD at ${f}` }; } async function qe(t, e, n = !0) { return Wt(t, { to: e, mode: "detached", force: n }); } async function Ge(t, e) { const { dir: n } = t, { at: i } = e, s = e.force ?? !0, r = e.paths && e.paths.length ? e.paths : void 0; if (!i || !String(i).trim()) throw new Error("checkoutAtCommit: `at` is required"); const a = await k(); let l = ""; const o = String(i).trim(), c = /^[0-9a-fA-F]{4,40}$/.test(o); try { l = await y.resolveRef({ fs: a, dir: n, ref: o }); } catch { if (!c) throw new Error(`checkoutAtCommit: cannot resolve ref '${i}'`); try { l = o.length === 40 ? o : await y.expandOid({ fs: a, dir: n, oid: o }); } catch { throw new Error(`checkoutAtCommit: cannot resolve OID '${i}'`); } } await H(t), await y.checkout({ fs: a, dir: n, ref: l, filepaths: r, noUpdateHead: !0, force: s }); const u = l.slice(0, 7); return { oid: l, paths: r, summary: `Checked out ${r ? r.join(", ") : "all files"} from ${u}` }; } async function ut(t) { const { dir: e } = t, n = await k(); let i; try { const s = await y.currentBranch({ fs: n, dir: e, fullname: !1, test: !0 }); typeof s == "string" && s.length > 0 && (i = s); } catch { } if (i) return { currentBranch: i, detached: !1 }; try { return { detached: !0, headOid: await y.resolveRef({ fs: n, dir: e, ref: "HEAD" }) }; } catch { return { detached: !0 }; } } async function Xe(t, e, n = {}) { const { dir: i } = t, { createIfMissing: s = !0, force: r = !0 } = n, a = await k(); if (!e || !e.trim()) throw new Error("attachHeadToBranch: `branch` is required"); await H(t); let l = !0; try { await y.resolveRef({ fs: a, dir: i, ref: `refs/heads/${e}` }); } catch { l = !1; } let o = !1; if (!l) { if (!s) throw new Error(`attachHeadToBranch: branch '${e}' does not exist`); const c = await y.resolveRef({ fs: a, dir: i, ref: "HEAD" }); await y.writeRef({ fs: a, dir: i, ref: `refs/heads/${e}`, value: c, force: !0 }), o = !0; } return await y.writeRef({ fs: a, dir: i, ref: "HEAD", value: `refs/heads/${e}`, force: !0, symbolic: !0 }), await y.checkout({ fs: a, dir: i, ref: e, force: r }), { branch: e, created: o, summary: o ? `Created and attached HEAD to '${e}'` : `Attached HEAD to '${e}'` }; } async function Ht(t, e) { const { dir: n } = t, i = await k(), s = e.force ?? !0, r = e.refuseUpdateExisting ?? !0; await H(t); const a = await Lt(t, e.to), l = a.slice(0, 7), o = await y.listBranches({ fs: i, dir: n }), c = []; for (const h of o) try { await y.resolveRef({ fs: i, dir: n, ref: `refs/heads/${h}` }) === a && c.push(h); } catch { } if (c.length > 0) { const h = c.includes("main") ? "main" : c[0]; return await y.writeRef({ fs: i, dir: n, ref: "HEAD", value: `refs/heads/${h}`, force: !0, symbolic: !0 }), await y.checkout({ fs: i, dir: n, ref: h, force: s }), { branch: h, oid: a, created: !1, summary: `Attached to '${h}' at ${l}` }; } const u = e.branch && e.branch.trim().length ? e.branch : `continue/${l}`; let f = !0, d = ""; try { d = await y.resolveRef({ fs: i, dir: n, ref: `refs/heads/${u}` }); } catch { f = !1; } let m = !1; if (!f) await y.writeRef({ fs: i, dir: n, ref: `refs/heads/${u}`, value: a, force: !0 }), m = !0; else if (d !== a) { if (r) throw new Error( `continueFromCommit: branch '${u}' exists at ${d.slice(0, 7)}; choose a different name` ); await y.writeRef({ fs: i, dir: n, ref: `refs/heads/${u}`, value: a, force: !0 }); } return await y.writeRef({ fs: i, dir: n, ref: "HEAD", value: `refs/heads/${u}`, force: !0, symbolic: !0 }), await y.checkout({ fs: i, dir: n, ref: u, force: s }), { branch: u, oid: a, created: m, summary: `${m ? "Created" : "Attached to"} '${u}' at ${l}` }; } async function Ve({ dir: t, message: e, author: n }) { await H({ dir: t }); const i = await ut({ dir: t }); i.detached && await Ht({ dir: t }, { to: i.headOid || "HEAD", force: !0, refuseUpdateExisting: !0 }); const s = await ut({ dir: t }), r = !s.detached && s.currentBranch ? s.currentBranch : void 0; await zt( { dir: t }, { message: e, author: n, ...r ? { branch: r } : {} } ); } function C(t) { const e = []; for (const n of t.split("/")) { const i = n.trim(); if (!(!i || i === ".")) { if (i === "..") { e.length && e.pop(); continue; } e.push(i); } } return e; } function A(t) { return t.split("/").filter(Boolean).join("/"); } function W(t) { return $t(t).replace(/\\/g, "/").replace(/^\/+/, "").trim(); } function x(t, e) { return A(t ? e ? t + "/" + e : t : e); } function L(t) { const e = t.lastIndexOf("/"); return e === -1 ? "" : t.slice(0, e); } function M(t) { const e = t.lastIndexOf("/"); return e === -1 ? t : t.slice(e + 1); } function jt(t) { if (!t) return !1; const e = t.replace(/\\/g, "/"); return /(?:^|\/)\.\.(?:\/|$)/.test(e); } function Ut(t, e) { const n = C(t).join("/"), i = C(e).join("/"); return !i || n === i ? !0 : n.startsWith(i + "/"); } function Je(t, e) { const n = C(t).join("/"), i = C(e).join("/"), s = n ? `${n}/${i}` : i; if (!Ut(s, n)) throw new Error(`Path escapes workspace: "${e}" not under "${t}"`); return s || "."; } function O(t) { return "/" + C(t.replace(/\\/g, "/")).join("/"); } async function rt(t, e) { const n = await k(); if (e) { await n.promises.mkdir?.(t, { recursive: !0 }); return; } try { if (!(await n.promises.stat(t)).isDirectory()) { const s = new Error(`Not a directory: ${t}`); throw s.name = "TypeMismatchError", s; } } catch (i) { if (i && (i.code === "ENOENT" || i.name === "NotFoundError")) { const s = new Error(`Directory not found: ${t}`); throw s.name = "NotFoundError", s; } throw i; } } async function Ye(t = "") { const e = O(t || ""); return e === "/" || await rt( e, /*create*/ !1 ), e; } async function j(t, e = !1) { const n = O(t || ""); return n === "/" || await rt(n, e), n; } async function at(t, e) { const n = O(t || ""); return n === "/" || await rt(n, e), n; } async function q(t, e) { const n = await k(), i = O(t); O(L(t)); try { if (!(await n.promises.stat(i)).isFile()) { const r = new Error(`Not a file: ${i}`); throw r.name = "TypeMismatchError", r; } return i; } catch (s) { if (s && (s.code === "ENOENT" || s.name === "NotFoundError")) { const r = new Error(`File not found: ${i}`); throw r.name = "NotFoundError", r; } throw s; } } async function G(t) { const e = await k(), n = O(t); try { return await e.promises.readFile(n, "utf8"); } catch (i) { if (i && (i.code === "ENOENT" || i.name === "NotFoundError" || i.code === 1)) return null; throw i; } } async function z(t, e) { const n = await k(), i = O(t), s = O(L(t)); await n.promises.mkdir?.(s, { recursive: !0 }), await n.promises.writeFile(i, e, "utf8"); } async function U(t) { const e = await k(), n = O(t); try { await e.promises.unlink(n); } catch (i) { if (i && (i.code === "ENOENT" || i.name === "NotFoundError" || i.code === 1)) return; throw i; } } function $t(t) { if (typeof t != "string") return t; const e = /[\u001B\u009B][[()#;?]*(?:\d{1,4}(?:;\d{0,4})*)?[0-9A-ORZcf-nqry=><]/g; return t.replace(e, ""); } async function Ke(t) { const { workDir: e = "", diffContent: n, signal: i, git: s, sanitizeAnsiDiff: r = !0, maxOffsetLines: a = 200 } = t, l = r ? $t(n) : n, c = Zt(l) ?? l, u = /^(---|\+\+\+)\s/m.test(c), f = /^@@/m.test(c); if (u && !f) return { success: !0, output: "No changes in patch (no hunks)." }; const d = await j(e, !0); let m; try { m = await Vt({ diffText: c, baseDir: d, maxOffsetLines: a }); } catch (_) { return u && !f ? { success: !0, output: "No changes in patch (no hunks)." } : { success: !1, output: "Failed to parse patch: " + Z(_) }; } if (m = Kt(m), !m.length) return { success: !1, output: "No file hunks found in patch." }; const h = new Yt(), p = new qt(s, e, h), w = []; for (const _ of m) { if (i?.aborted) break; const g = K(_.oldFileName), $ = K(_.newFileName), b = g === null && $ !== null, N = $ === null && g !== null, D = g !== null && $ !== null && g !== $, F = $ ?? g; if (F !== null) try { if (b) { const T = Q("", _); if (T === !1) throw new Error("Hunks failed to apply for creation"); await z(x(d, F), T), h.created.push(F), await p.add(F), w.push(async () => { await U(x(d, F)), await p.remove(F); }); continue; } if (N) { const T = await G(x(d, g)); if (T === null) await U(x(d, g)), h.deleted.push(g), await p.remove(g); else { if (Q(T, _) === !1) throw new Error("Hunks failed to apply for deletion"); await U(x(d, g)), h.deleted.push(g), await p.remove(g), w.push(async () => { await z(x(d, g), T), await p.add(g); }); } continue; } const S = await G(x(d, g)); if (S === null) throw new Error("Target file not found: " + g); const R = Gt(_), I = D && !R ? S : Q(S, _); if (I === !1) throw new Error("Hunks failed to apply"); D ? (await z(x(d, $), I), await U(x(d, g)), h.renamed.push({ from: g, to: $ }), await p.add($), await p.remove(g), w.push(async () => { await z(x(d, g), S), await U(x(d, $)), await p.add(g), await p.remove($); })) : (await z(x(d, g), I), h.modified.push(g), await p.add(g), w.push(async () => { await z(x(d, g), S), await p.add(g); })); } catch (S) { h.failed.push({ path: F, reason: Z(S) }); } } const E = h.failed.length === 0 && !i?.aborted; if (!E) { for (const _ of w.reverse()) try { await _(); } catch { } h.created = [], h.modified = [], h.deleted = [], h.renamed = []; } const v = h.summary(E, i?.aborted) + (E ? "" : " Changes reverted."); return { success: E, output: v, details: { created: h.created, modified: h.modified, deleted: h.deleted, renamed: h.renamed, failed: h.failed } }; } class qt { ctx; shouldStage; workDir; tracker; constructor(e, n, i) { this.ctx = e, this.workDir = n, this.shouldStage = !!(e && (e.stage ?? !0)), this.tracker = i; } async add(e) { if (!(!this.shouldStage || !this.ctx)) try { await this.ctx.git.add({ fs: this.ctx.fs, dir: this.ctx.dir, filepath: ft(this.workDir, e, this.ctx.dir) }); } catch (n) { this.tracker.failed.push({ path: e, reason: "git add failed: " + Z(n) }); } } async remove(e) { if (!(!this.shouldStage || !this.ctx)) try { await this.ctx.git.remove({ fs: this.ctx.fs, dir: this.ctx.dir, filepath: ft(this.workDir, e, this.ctx.dir) }); } catch (n) { this.tracker.failed.push({ path: e, reason: "git remove failed: " + Z(n) }); } } } function ft(t, e, n) { const i = t ? C(t).join("/") : ""; return i ? x(i, e) : e; } function K(t) { if (!t || t === "/dev/null") return null; const e = t.replace(/^[ab]\//, "").replace(/^\/+/, "").replace(/\\/g, "/"); return C(e).join("/"); } function Z(t) { return t instanceof Error ? t.message : String(t); } function Gt(t) { return t.hunks?.some((e) => e.lines?.some((n) => n.startsWith("+") || n.startsWith("-"))) ?? !0; } const Xt = /^@@\s+-([0-9]+)(?:,([0-9]+))?\s+\+([0-9]+)(?:,([0-9]+))?\s+@@/, dt = /^@@/; async function Vt(t) { const { diffText: e, baseDir: n, maxOffsetLines: i } = t; let s = null; try { s = It(e).map((l) => ({ oldFileName: l.oldFileName, newFileName: l.newFileName, hunks: (l.hunks || []).map((o) => ({ header: "", oldStart: typeof o.oldStart == "number" && Number.isFinite(o.oldStart) ? o.oldStart : void 0, oldLines: typeof o.oldLines == "number" && Number.isFinite(o.oldLines) ? o.oldLines : void 0, newStart: typeof o.newStart == "number" && Number.isFinite(o.newStart) ? o.newStart : void 0, newLines: typeof o.newLines == "number" && Number.isFinite(o.newLines) ? o.newLines : void 0, lines: o.lines || [] })) })); } catch { } if (s || (s = Jt(e)), !s.length) return []; const r = []; for (const a of s) { const l = K(a.oldFileName), o = K(a.newFileName), c = l !== null && o === null, u = l ? await G(x(n, l)) : null, f = (u ?? "").split(/\r?\n/), d = []; let m = 0; for (const h of a.hunks) { const p = (h.lines || []).filter((b) => b?.startsWith(" ") || b?.startsWith("+") || b?.startsWith("-")), w = p.filter((b) => b.startsWith(" ") || b.startsWith("-")), E = p.filter((b) => b.startsWith(" ") || b.startsWith("+")), v = w.length, _ = E.length; let g = h.oldStart; if (h.oldStart && l && f.length) { const b = h.oldStart - 1, N = Math.max(0, b - i), D = Math.min(f.length, b + i + 1), F = w.map((R) => R.slice(1)), S = mt(f, F, N, D); S === -1 ? g = b + 1 : g = S + 1; } if (!g) if (!l) g = 1; else if (c && u === null) g = 1; else { const b = w.map((D) => D.slice(1)), N = mt(f, b, 0, f.length); g = (N === -1 ? 0 : N) + 1; } const $ = Math.max(1, g + m); d.push({ oldStart: g, oldLines: v, newStart: $, newLines: _, lines: p }), m += _ - v; } r.push({ oldFileName: a.oldFileName, newFileName: a.newFileName, hunks: d }); } return r; } function Jt(t) { const e = t.split(/\r?\n/), n = []; let i = 0; for (; i < e.length; ) { const s = e[i]; if (s?.startsWith("--- ")) { const r = ht(s.slice(4)), a = e[i + 1] || ""; if (!a.startsWith("+++ ")) { i++; continue; } const l = ht(a.slice(4)); i += 2; const o = []; for (; i < e.length && dt.test(e[i] || ""); ) { const c = e[i] || ""; let u, f, d, m; const h = c.match(Xt); h && (u = Y(h[1]), f = Y(h[2] ?? "1"), d = Y(h[3]), m = Y(h[4] ?? "1")), i++; const p = []; for (; i < e.length; ) { const w = e[i]; if (w?.startsWith("--- ") || dt.test(w || "") || w?.startsWith("diff --git ")) break; if (w?.startsWith("\\ No newline at end of file")) { i++; continue; } if (!w?.startsWith(" ") && !w?.startsWith("+") && !w?.startsWith("-")) break; p.push(w), i++; } o.push({ header: c, oldStart: u, oldLines: f, newStart: d, newLines: m, lines: p }); } n.push({ oldFileName: r, newFileName: l, hunks: o }); continue; } i++; } return n; } function ht(t) { return (t.split(/\t|\s/)[0] ?? t).trim(); } function Y(t) { const e = parseInt(t, 10); return Number.isFinite(e) && e > 0 ? e : 1; } function mt(t, e, n, i) { if (e.length === 0) return n; const s = Math.min(t.length, i); for (let r = n; r <= s - e.length; r++) { let a = !0; for (let l = 0; l < e.length; l++) if (t[r + l] !== e[l]) { a = !1; break; } if (a) return r; } return -1; } class Yt { created = []; modified = []; deleted = []; renamed = []; failed = []; summary(e, n) { return [ n ? "Patch aborted." : e ? "Patch applied successfully." : "Patch completed with errors.", this.created.length ? `Created: ${this.created.length}` : "", this.modified.length ? `Modified: ${this.modified.length}` : "", this.deleted.length ? `Deleted: ${this.deleted.length}` : "", this.renamed.length ? `Renamed: ${this.renamed.length}` : "", this.failed.length ? `Failed: ${this.failed.length}` : "" ].filter(Boolean).join(" "); } } function Kt(t) { return t.map((e) => ({ ...e, hunks: (e.hunks || []).map((n) => ({ ...n, lines: (n.lines || []).filter((i) => typeof i == "string" && /^[ +-]/.test(i)) })) })); } function Zt(t) { if (!/\*\*\*\s+(Begin Patch|Update File:|Add File:|Delete File:)/.test(t)) return null; const n = t.split(/\r?\n/), i = []; let s = 0; for (; s < n.length; ) { const r = n[s] || ""; if (/^\*\*\*\s+Begin Patch/.test(r) || /^\*\*\*\s+End Patch/.test(r)) { s++; continue; } const a = r.match(/^\*\*\*\s+(Update|Add|Delete) File:\s+(.*)$/); if (a) { const l = a[1]; let o = (a[2] || "").trim(), c = null; n[s + 1] && /^\*\*\*\s+Move to:\s+/.test(n[s + 1]) && (c = (n[s + 1].replace(/^\*\*\*\s+Move to:\s+/, "") || "").trim(), s++); const u = (h) => h.replace(/^\/+/, "").replace(/\\/g, "/"); o = u(o); const f = c ? u(c) : null; let d, m; for (l === "Add" ? (d = "/dev/null", m = `b/${o}`) : l === "Delete" ? (d = `a/${o}`, m = "/dev/null") : (d = `a/${o}`, m = f ? `b/${f}` : `b/${o}`), i.push(`--- ${d}`), i.push(`+++ ${m}`), s++; s < n.length; ) { const h = n[s] || ""; if (/^\*\*\*\s+(Update|Add|Delete) File:/.test(h) || /^\*\*\*\s+End Patch/.test(h)) break; if (/^\*\*\*\s+Move to:/.test(h)) { s++; continue; } if (h.startsWith("@@")) { i.push(h), s++; continue; } if (h.startsWith(" ") || h.startsWith("+") || h.startsWith("-")) { i.push(h), s++; continue; } if (h.startsWith("\\ No newline at end of file")) { s++; continue; } if (h.trim() === "") { i.push(""), s++; continue; } break; } i.length && i[i.length - 1] !== "" && i.push(""); continue; } s++; } return i.length ? i.join(` `) : null; } async function Qt(t, e, n) { if (!t.length) return ""; const i = []; for (const s of t) s === "-n" || s === "-e" || s === "-E" || i.push(s); return i.join(" "); } function X(t, e = {}) { const n = e.dot ?? !0, i = e.caseSensitive ?? !0; let s = "^", r = 0; for (; r < t.length; ) { const l = t[r]; if (l === "*") { t[r + 1] === "*" ? (s += ".*", r += 2) : (s += n ? "[^/]*" : "(?!\\.)[^/]*", r++); continue; } if (l === "?") { s += n ? "[^/]" : "(?!\\.)[^/]", r++; continue; } if (l === "[") { const { src: o, newIndex: c } = te(t, r); s += o, r = c; continue; } if (l === "\\") { r + 1 < t.length ? (s += pt(t[r + 1]), r += 2) : (s += "\\\\", r++); continue; } if (l === "/") { s += "/", r++; continue; } s += pt(l), r++; } s += "$"; const a = i ? "" : "i"; return new RegExp(s, a); } function te(t, e) { let n = e + 1, i = !1; t[n] === "!" && (i = !0, n++); let s = ""; for (t[n] === "]" && (s += "\\]", n++); n < t.length && t[n] !== "]"; ) { const l = t[n]; l === "\\" ? n + 1 < t.length ? (s += "\\" + t[n + 1], n += 2) : (s += "\\\\", n++) : "^$.|+(){}".includes(l) ? (s += "\\" + l, n++) : (s += l, n++); } if (n >= t.length || t[n] !== "]") return { src: "\\[", newIndex: e + 1 }; const r = t[n]; return n++, { src: "[" + (i ? "^" : "") + s + r, newIndex: n }; } function pt(t) { return /[\\^$.*+?()[\]{}|]/.test(t) ? "\\" + t : t; } function V(t) { const e = ee(t); if (!e) return [t]; const { start: n, end: i } = e, s = t.slice(0, n), r = t.slice(n + 1, i), a = t.slice(i + 1), l = ne(r); return l.length <= 1 ? [t] : l.map((c) => `${s}${c}${a}`).flatMap(V); } function ee(t) { let e = 0, n = -1; for (let i = 0; i < t.length; i++) { const s = t[i]; if (s === "\\") { i++; continue; } if (s === "{") e === 0 && (n = i), e++; else if (s === "}" && e > 0 && (e--, e === 0)) return { start: n, end: i }; } return null; } function ne(t) { const e = []; let n = "", i = 0; for (let s = 0; s < t.length; s++) { const r = t[s]; if (r === "\\") { n += r, s + 1 < t.length && (n += t[s + 1], s++); continue; } if (r === "{") { i++, n += r; continue; } if (r === "}") { i > 0 && i--, n += r; continue; } if (r === "," && i === 0) { e.push(n), n = ""; continue; } n += r; } return e.push(n), e; } async function ie(t, e) { const { pattern: n, flags: i, include: s, exclude: r, maxFileSize: a = 20 * 1024 * 1024, concurrency: l = 4, encoding: o = "utf-8", signal: c, onMatch: u } = e, f = (s ?? []).flatMap((v) => V(v)).map((v) => X(v)), d = (r ?? []).flatMap((v) => V(v)).map((v) => X(v)), m = se(n, i), h = await j(t || "", !1), p = []; for await (const v of St(h, "", { signal: c })) { if (re(v, f, d)) continue; const _ = x(h, v); p.push({ path: v, abs: _ }); } const w = [], E = await k(); return await ae(p, Math.max(1, l), async (v) => { if (!c?.aborted) try { if (((await E.promises.stat("/" + A(v.abs))).size ?? 0) > a) return; const g = await E.promises.readFile("/" + A(v.abs)), b = (typeof g == "string" ? g : new TextDecoder(o, { fatal: !1 }).decode(g)).split(` `); for (let N = 0; N < b.length; N++) { let D = b[N]; D.endsWith("\r") && (D = D.slice(0, -1)), m.lastIndex = 0; let F; for (; (F = m.exec(D)) !== null; ) { const S = (F.index ?? 0) + 1, R = { file: v.path, line: N + 1, column: S, match: F[0], lineText: D }; w.push(R), u && await u(R), F[0] === "" && m.lastIndex++; } } } catch { } }), w; } async function* St(t, e = "", { signal: n } = {}) { if (n?.aborted) return; const i = await k(), s = "/" + (e ? x(t, e) : A(t)); let r = []; try { r = await i.promises.readdir(s); } catch { return; } for (const a of r) { if (n?.aborted) return; const l = e ? `${e}/${a}` : a, o = "/" + x(t, l); let c; try { c = await i.promises.stat(o); } catch { continue; } if (c.isFile?.()) { yield l; continue; } c.isDirectory?.() && (yield* St(t, l, { signal: n })); } } function se(t, e) { if (t instanceof RegExp) { const s = t.flags.includes("g") ? t.flags : t.flags + "g"; return new RegExp(t.source, s); } const n = e ?? "", i = n.includes("g") ? n : n + "g"; return new RegExp(t, i); } function re(t, e, n) { const i = t.replace(/\\/g, "/"); return !!(n.some((s) => s.test(i)) || e.length > 0 && !e.some((s) => s.test(i))); } async function ae(t, e, n) { let i = 0; const s = Array.from({ length: Math.min(e, t.length || 1) }, async function() { for (; i < t.length; ) { const a = i++; await n(t[a]); } }); await Promise.all(s); } async function et(t, e = {}) { const { maxDepth: n = 1, include: i, exclude: s, showHidden: r = !1, kinds: a = ["file", "directory"], stat: l = !1, concurrency: o = 4, signal: c, onEntry: u, sortBy: f = "name", sortOrder: d = "asc", dirsFirst: m = !0 } = e, h = (i ?? []).flatMap((g) => V(g)).map((g) => X(g, { dot: !0, caseSensitive: !0 })), p = (s ?? []).flatMap((g) => V(g)).map((g) => X(g, { dot: !0, caseSensitive: !0 })), w = [], E = [], v = await j( t || "", /*create*/ !1 ), _ = await k(); return await kt(_, v, "", 0, { maxDepth: n, showHidden: r, excludeREs: p, signal: c, onDir: async (g, $, b) => { const N = $ ? `${$}/${g}` : g; if (a.includes("directory") && !yt(N, h, p, r, g)) { const F = { path: N, name: g, kind: "directory", depth: b }; w.push(F), u && await u(F); } }, onFile: async (g, $, b) => { const N = $ ? `${$}/${g}` : g; if (!(a.includes("file") && !yt(N, h, p, r, g))) return; const F = { path: N, name: g, kind: "file", depth: b }; if (w.push(F), l) { const S = "/" + x(v, N); E.push(async () => { try { const R = await _.promises.stat(S); F.size = Number(R.size ?? 0), F.lastModified = Number(R.mtimeMs ?? 0); } catch { } u && await u(F); }); } else u && await u(F); } }), E.length > 0 && await ue(E, Math.max(1, o), (g) => g()), le(w, { sortBy: f, sortOrder: d, dirsFirst: m }), w; } function oe(t) { if (t == null) return "-"; const e = ["B", "KB", "MB", "GB", "TB"]; let n = 0, i = t; for (; i >= 1024 && n < e.length - 1; ) i /= 1024, n++; return (n === 0 ? i.toString() : i.toFixed(1)) + " " + e[n]; } function ce(t) { if (t == null) return "-"; const e = new Date(t), n = (i) => i < 10 ? "0" + i : "" + i; return e.getFullYear() + "-" + n(e.getMonth() + 1) + "-" + n(e.getDate()) + " " + n(e.getHours()) + ":" + n(e.getMinutes()); } function wt(t) { const e = []; for (const n of t) { const i = n.kind === "directory" ? "d" : "-", s = n.kind === "file" ? oe(n.size) : "-", r = n.kind === "file" ? ce(n.lastModified) : "-"; e.push(`${i} ${s.padStart(10)} ${r} ${n.path}`); } return e.join(` `); } function Ze(t) { const e = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Set(), i = (c) => { const u = c.lastIndexOf("/"); return u === -1 ? c : c.slice(u + 1); }, s = (c) => (e.has(c) || e.set(c, []), e.get(c)), r = (c) => { if (c === "" || n.has(c)) return; const u = gt(c); r(u), s(u).push({ path: c, name: i(c), kind: "directory" }), n.add(c), s(c); }; for (const c of t) { const u = c.path.replace(/\\/g, "/"); if (c.kind === "directory") r(u); else { const f = gt(u); r(f), n.has(u) || (s(f).push({ path: u, name: c.name, kind: "file" }), n.add(u)); } } for (const c of e.values()) c.sort((u, f) => u.kind !== f.kind ? u.kind === "directory" ? -1 : 1 : u.name.localeCompare(f.name)); const a = [], l = (c, u) => { const f = e.get(c) || []; f.forEach((d, m) => { const h = m === f.length - 1, p = h ? "└── " : "├── ", w = u + (h ? " " : "│ "); a.push(u + p + (d.kind === "directory" ? d.name + "/" : d.name)), d.kind === "directory" && l(d.path, w); }); }; return l("", ""), a.join(` `) || "<empty>"; } function gt(t) { const e = t.lastIndexOf("/"); return e === -1 ? "" : t.slice(0, e); } function le(t, e) { const n = e.sortOrder === "asc" ? 1 : -1; t.sort((i, s) => { if (e.dirsFirst && i.kind !== s.kind) return i.kind === "directory" ? -1 : 1; const r = e.sortBy === "name" ? i.name : e.sortBy === "path" ? i.path : e.sortBy === "size" ? i.size ?? -1 : i.lastModified ?? 0, a = e.sortBy === "name" ? s.name : e.sortBy === "path" ? s.path : e.sortBy === "size" ? s.size ?? -1 : s.lastModified ?? 0; return typeof r == "string" && typeof a == "string" ? r.localeCompare(a) * n : (r < a ? -1 : r > a ? 1 : 0) * n; }); } function yt(t, e, n, i, s) { if (!i && s.startsWith(".")) return !0; const r = t.replace(/\\/g, "/"); return !!(n.some((a) => a.test(r)) || e.length > 0 && !e.some((a) => a.test(r))); } async function ue(t, e, n) { let i = 0; const s = Array.from({ length: Math.min(e, t.length || 1) }, async function() { for (; i < t.length; ) { const a = i++; await n(t[a]); } }); await Promise.all(s); } async function kt(t, e, n, i, s) { if (s.signal?.aborted || i >= s.maxDepth) return; const r = "/" + (n ? x(e, n) : e); let a = []; try { a = await t.promises.readdir(r); } catch { return; } for (const l of a) { if (s.signal?.aborted) return; const o = l.startsWith("."), c = n ? `${n}/${l}` : l, u = "/" + x(e, c); let f; try { f = await t.promises.stat(u); } catch { continue; } const d = i + 1; if (f.isDirectory?.()) { if (o && !s.showHidden || s.excludeREs.some((m) => m.test(c))) continue; await s.onDir(l, n, d), await kt(t, e, c, d, s); } else f.isFile?.() && await s.onFile(l, n, d); } } async function fe(t, e) { let n, i, s, r, a = 0; for (let h = 0; h < t.length; h++) { const p = t[h]; if (p === "-name") i = t[++h]; else if (p === "-type") { const w = t[++h]; w === "f" ? s = "file" : w === "d" && (s = "directory"); } else if (p === "-maxdepth") { const w = parseInt(t[++h] ?? "", 10); !Number.isNaN(w) && w >= 0 && (r = w); } else if (p === "-mindepth") { const w = parseInt(t[++h] ?? "", 10); !Number.isNaN(w) && w >= 0 && (a = w); } else p.startsWith("-") || n == null && (n = p); } const o = A(n ?? "."), c = A(x(e.cwd, o)); let u; try { await j( c, /*create*/ !1 ), u = "directory"; } catch { await q( c ), u = "file"; } const f = i ? X(i) : void 0, d = [], m = (h) => !(s && h.kind !== s || f && !f.test(h.name) || h.depth < a || r != null && h.depth > r); if (u === "directory") { a <= 0 && m({ name: o === "." ? "." : M(o), kind: "directory", depth: 0 }) && d.push(o); const h = await et(c, { maxDepth: r == null ? 1 / 0 : Math.max(0, r), showHidden: !0, kinds: ["file", "directory"], stat: !1, dirsFirst: !1 }); for (const p of h) { const w = p.depth, E = { name: p.name, kind: p.kind, depth: w }; if (!m(E)) continue; const v = o === "." ? p.path : `${o}/${p.path}`; d.push(v); } } else a <= 0 && m({ name: M(c), kind: "file", depth: 0 }) && d.push(o); return d.join(` `); } function Nt(t) { return t.startsWith('"') && t.endsWith('"') || t.startsWith("'") && t.endsWith("'") ? t.slice(1, -1) : t; } function de(t) { return t.replace(/[\\*?[\]{}()!+@]/g, (e) => "\\" + e); } async function he(t, e) { const n = A(x(e.cwd, t)); return await j( n, /*create*/ !1 ), { full: n }; } async function Dt(t, e) { const n = A(x(t.cwd, e)); return await q( n ), { full: n }; } async function me(t, e) { let n = !1, i = !1, s = !1; const r = []; for (const u of t) u.startsWith("-") ? (n = n || u.includes("l"), i = i || u.includes("a"), s = s || u.includes("R")) : r.push(u); const a = r[0] ?? ".", l = A(a); if (jt(l)) throw new Error("Parent directory traversal ('..') is not supported"); const o = A(x(e.cwd, l)); let c; try { await j( o, /*create*/ !1 ), c = "directory"; } catch { await q( o ), c = "file"; } if (c === "directory") { const u = await et(o, { maxDepth: s ? 1 / 0 : 1, showHidden: i, stat: n, sortBy: "name", sortOrder: "asc", dirsFirst: !0 }); return n ? wt(u) : u.map((f) => f.path).join(` `); } else if (n) { const u = L(o), f = M(o), d = await et(u, { maxDepth: 1, include: [de(f)], showHidden: !0, stat: !0 }); return wt(d.filter((m) => m.path === f)); } else return M(l); } async function pe(t, e, n) { let i = "t", s = 6, r = " "; const a = []; for (let f = 0; f < t.length; f++) { const d = t[f]; if (!d.startsWith("-")) { a.push(d); continue; } if (d === "-b") { const m = t[++f]; (m === "a" || m === "t") && (i = m); continue; } if (d.startsWith("-b") && d.length > 2) { const m = d.slice(2); (m === "a" || m === "t") && (i = m); continue; } if (d === "-w") { const m = parseInt(t[++f] ?? "", 10); !Number.isNaN(m) && m > 0 && (s = m); continue; } if (d.startsWith("-w") && d.length > 2) { const m = parseInt(d.slice(2), 10); !Number.isNaN(m) && m > 0 && (s = m); continue; } if (d === "-s") { r = t[++f] ?? r; continue; } if (d.startsWith("-s") && d.length > 2) { r = d.slice(2); continue; } } let l; if (a.length > 0) { const f = a[0], { full: d } = await Dt(e, f); l = await (await k()).promises.readFile("/" + d, "utf8"); } else l = n ?? ""; const o = l.split(` `); o.length && o[o.length - 1] === "" && o.pop(); const c = []; let u = 1; for (const f of o) { const d = f.length === 0; if (i === "a" ? !0 : !d) { const h = String(u++).padStart(s, " "); c.push(h + r + f); } else c.push(""); } return c.join(` `); } async function we(t, e) { let n = !1, i = !1; const s = []; for (const f of t) f === "-n" ? n = !0 : f === "-S" ? i = !0 : s.push(f); if (s.length === 0) throw new Error("rg: missing pattern"); const r = Nt(s[0]), a = s[1] ?? "."; let l = ""; i && !/[A-Z]/.test(r) && (l += "i"); const o = new RegExp(r, l.includes("g") ? l : l + "g"), { full: c } = await he(a, e); return (await ie(c, { pattern: o, exclude: ["**/node_modules/**", "**/.git/**"], onMatch: void 0 })).map( (f) => n ? `${f.file}:${f.line}:${f.column}: ${f.lineText}` : `${f.file}:${f.line}:${f.column}: ${f.match}` ).join(` `); } var P = /* @__PURE__ */ ((t) => (t.UNHANDLED_EXCEPTION = "unhandled_exception", t.EXECUTION_FAILED = "execution_failed", t.FILE_NOT_FOUND = "file_not_found", t.FILE_WRITE_FAILURE = "file_write_failure", t.READ_CONTENT_FAILURE = "read_content_failure", t.ATTEMPT_TO_CREATE_EXISTING_FILE = "attempt_to_create_existing_file", t.FILE_TOO_LARGE = "file_too_large", t.PERMISSION_DENIED = "permission_denied", t.NO_SPACE_LEFT = "no_space_left", t.TARGET_IS_DIRECTORY = "target_is_directory", t.PATH_NOT_IN_WORKSPACE = "path_not_in_workspace", t.SEARCH_PATH_NOT_FOUND = "search_path_not_found", t.SEARCH_PATH_NOT_A_DIRECTORY = "search_path_not_a_directory", t.EDIT_PREPARATION_FAILURE = "edit_preparation_failure", t.EDIT_NO_OCCURRENCE_FOUND = "edit_no_occurrence_found", t.EDIT_EXPECTED_OCCURRENCE_MISMATCH = "edit_expected_occurrence_mismatch", t.EDIT_NO_CHANGE = "edit_no_change", t.GLOB_EXECUTION_ERROR = "glob_execution_error", t.GREP_EXECUTION_ERROR = "grep_execution_error", t.LS_EXECUTION_ERROR = "ls_execution_error", t.PATH_IS_NOT_A_DIRECTORY = "path_is_not_a_directory", t.READ_MANY_FILES_SEARCH_ERROR = "read_many_files_search_error", t))(P || {}); const ge = 2e3, ye = 2e3; function nt(t) { return t.replace(/\\/g, "/"); } function it(t) { t = nt(t); const e = t.split("/").filter(Boolean), n = []; for (const i of e) i !== "." && (i === ".." ? n.pop() : n.push(i)); return n.join("/"); } function Et(t) { const e = it(t); return e ? e.split("/") : []; } function vt(t, e) { const n = Et(t), i = Et(e); let s = 0; for (; s < n.length && s < i.length && n[s] === i[s]; ) s++; const r = new Array(n.length - s).fill(".."), a = i.slice(s); return [...r, ...a].join("/") || "."; } const Ee = { // Text txt: "text/plain", md: "text/markdown", markdown: "text/markdown", html: "text/html", htm: "text/html", css: "text/css", csv: "text/csv", tsv: "text/tab-separated-values", sql: "application/sql", xml: "application/xml", json: "application/json", yaml: "application/yaml", yml: "application/yaml", // Scripts js: "application/javascript", mjs: "application/javascript", cjs: "application/javascript", ts: "text/plain", // treat as text (avoid video/MP2T misclassification) tsx: "text/plain", jsx: "text/plain", // Images png: "image/png", jpg: "image/jpeg", jpeg: "image/jpeg", gif: "image/gif", webp: "image/webp", bmp: "image/bmp", avif: "image/avif", ico: "image/x-icon", cur: "image/x-icon", svg: "image/svg+xml", svgz: "image/svg+xml", // Audio mp3: "audio/mpeg", mpeg: "audio/mpeg", wav: "audio/wav", oga: "audio/ogg", ogg: "audio/ogg", m4a: "audio/mp4", aac: "audio/aac", flac: "audio/flac", opus: "audio/opus", // Video mp4: "video/mp4", m4v: "video/mp4", mov: "video/quicktime", webm: "video/webm", ogv: "video/ogg", mkv: "video/x-matroska", // Docs/other pdf: "application/pdf", zip: "application/zip", gz: "application/gzip", tar: "application/x-tar", "7z": "application/x-7z-compressed", wasm: "application/wasm", woff: "font/woff", woff2: "font/woff2", ttf: "font/ttf", otf: "font/otf" }; function ve(t) { const e = t.split("/").pop() || t, n = e.lastIndexOf("."); if (!(n < 0 || n === e.length - 1)) return e.slice(n + 1).toLowerCase(); } function Rt(t) { const e = ve(t); if (e) return Ee[e]; } function Fe(t) { const e = t instanceof Uint8Array ? t : new Uint8Array(t); let n = ""; const i = 32768; for (let s = 0; s < e.length; s += i) n += String.fromCharCode(...e.subarray(s, s + i)); return btoa(n); } async function xe(t, e) { const n = t.toLowerCase(), i = n.lastIndexOf("."), s = i >= 0 ? n.slice(i) : ""; if ([".ts", ".mts", ".cts"].includes(s)) return "text"; if (s === ".svg") return "svg"; const r = Rt(t); if (r) { if (r === "image/svg+xml") return "svg"; if (r.startsWith("image/")) return "image"; if (r.startsWith("audio/")) return "audio"; if (r.startsWith("video/")) return "video"; if (r === "application/pdf") return "pdf"; } return [ ".zip", ".tar", ".gz", ".7z", ".exe", ".dll", ".so", ".class", ".jar", ".war", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".odt", ".ods", ".odp", ".bin", ".dat", ".obj", ".o", ".a", ".lib", ".wasm", ".pyc", ".pyo" ].includes(s) ? "binary" : "text"; } async function be(t, e, n, i, s, r) { const a = it(t), l = it(e); try { let o; try { o = await q( a, /*create*/ !1 ); } catch (p) { if (p?.name === "TypeMismatchError") return { llmContent: "Could not read file because the provided path is a directory, not a file.", returnDisplay: "Path is a directory.", error: `Path is a directory, not a file: ${a}`, errorType: P.TARGET_IS_DIRECTORY }; if (p?.name === "NotFoundError" || p?.code === "ENOENT" || p?.code === 404) return { llmContent: "Could not read file because no file was found at the specified path.", returnDisplay: "File not found.", error: `File not found: ${a}`, errorType: P.FILE_NOT_FOUND }; throw p; } const c = await k(), u = await c.promises.stat(o), f = r?.maxFileSizeMB ?? 20, d = u.size / (1024 * 1024); if (d > f) return { llmContent: `File size exceeds the ${f}MB limit.`, returnDisplay: `File size exceeds the ${f}MB limit.`, error: `File size exceeds the ${f}MB limit: ${a} (${d.toFixed(2)}MB)`, errorType: P.FILE_TOO_LARGE }; const m = await xe(a), h = nt(vt(l, a)); switch (m) { case "binary": return { llmContent: `Cannot display content of binary file: ${h}`, returnDisplay: `Skipped binary file: ${h}` }; case "svg": return u.size > 1048576 ? { llmContent: `Cannot display content of SVG file larger than 1MB: ${h}`, returnDisplay: `Skipped large SVG file (>1MB): ${h}` } : { llmContent: await c.promises.readFile(o, "utf8"), returnDisplay: `Read SVG as text: ${h}` }; case "text": { const w = (await c.promises.readFile(o, "utf8")).split(` `), E = w.length, v = i || 0, _ = r?.defaultMaxLines ?? ge, $ = Math.min(v + (s === void 0 ? _ : s), E), b = Math.min(v, E), N = w.slice(b, $); let D = !1; const F = N.map((J) => { const ct = r?.maxLineLength ?? ye; return J.length > ct ? (D = !0, J.substring(0, ct) + "... [truncated]") : J; }), S = v > 0 || $ < E, R = S || D, I = F.join(` `); let T = ""; return S ? (T = `Read lines ${b + 1}-${$} of ${E} from ${h}`, D && (T += " (some lines were shortened)")) : D && (T = `Read all ${E} lines from ${h} (some lines were shortened)`), { llmContent: I, returnDisplay: T, isTruncated: R, originalLineCount: E, linesShown: [b + 1, $] }; } case "image": case "pdf": case "audio": case "video": { const p = await c.promises.readFile(o); return { llmContent: { inlineData: { data: Fe(p), mimeType: Rt(a) || "application/octet-stream" } }, returnDisplay: `Read ${m} file: ${h}` }; } default: return { llmContent: `Unhandled file type: ${m}`, returnDisplay: `Skipped unhandled file type: ${h}`, error: `Unhandled file type for ${a}` }; } } catch (o) { const c = o instanceof Error ? o.message : String(o), u = nt(vt(l, a)); let f = P.READ_CONTENT_FAILURE; return o?.name === "NotFoundError" ? f = P.FILE_NOT_FOUND : o?.name === "TypeMismatchError" ? f = P.TARGET_IS_DIRECTORY : o?.name === "SecurityError" && (f = P.READ_CONTENT_FAILURE), { llmContent: `Error reading file ${u}: ${c}`, returnDisplay: `Error reading file ${u}: ${c}`, error: `Error reading file ${a}: ${c}`, errorType: f }; } } async function _e(t, e, n) { let i = !1; const s = []; for (const d of t) d === "-n" ? i = !0 : s.push(d); if (s.length === 0) throw new Error("sed: missing script"); const r = Nt(s[0]), a = s[1], l = /^(\d+),\s*(\d+)p$/.exec(r) || /^(\d+)p$/.exec(r); if (!l) throw new Error(`sed: unsupported script "${r}" (use 'N,Mp' or 'Np')`); const o = parseInt(l[1], 10), c = l.length === 3 ? parseInt(l[2], 10) : o, u = Math.max(0, o - 1), f = Math.max(0, c - u); if (a) { const d = A(x(e.cwd, a)), m = await be(d, e.cwd || "", void 0, u, f), h = typeof m.llmContent == "string" ? m.llmContent : St