window.__ModuleLoader__.load({ id: "dsh-open-in-smerge", factory: (require) => { var module = { exports: {} }; var exports = module.exports; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const react = require("react"); const jsx = require("react/jsx-runtime"); const TRANSPORT_ERROR = { code: "route-unavailable", message: "Git target route unavailable" }; const STYLE_ID = "dsh-open-in-smerge-style"; const STYLE_TEXT = ".dsh-open-in-smerge{border:1px solid var(--dsw-alias-border-l2);max-width:260px;height:32px;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);cursor:pointer;background:transparent;border-radius:18px;display:inline-flex;align-items:center;justify-content:center;gap:5px;padding:6px 12px;font-size:13px;font-weight:400;line-height:20px;white-space:nowrap}.dsh-open-in-smerge:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.dsh-open-in-smerge:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.dsh-open-in-smerge[data-failed=true]{color:var(--dsw-alias-status-error,var(--dsw-alias-label-primary));border-color:currentColor}.dsh-open-in-smerge__kind{font-weight:600}.dsh-open-in-smerge__directory{min-width:0;overflow:hidden;text-overflow:ellipsis}.dsh-open-in-smerge__separator{color:var(--dsw-alias-label-tertiary)}"; function installStyle() { if (document.getElementById(STYLE_ID) !== null) return; const style = document.createElement("style"); style.id = STYLE_ID; style.dataset.plugin = "dsh-open-in-smerge"; style.textContent = STYLE_TEXT; document.head.appendChild(style); } async function request(path, options) { let response; try { response = await fetch(path, options); } catch { return { ok: false, error: TRANSPORT_ERROR }; } try { const envelope = await response.json(); if (typeof envelope !== "object" || envelope === null) return { ok: false, error: TRANSPORT_ERROR }; if (envelope.ok === true) return { ok: true, value: envelope.value }; return { ok: false, error: envelope.error ?? TRANSPORT_ERROR }; } catch { return { ok: false, error: TRANSPORT_ERROR }; } } function directoryName(path) { const trimmed = path.replace(/[/\\]+$/, ""); const parts = trimmed.split(/[/\\]/); return parts[parts.length - 1] || trimmed; } function OpenInSmergeButton(props) { const [busy, setBusy] = react.useState(false); const [error, setError] = react.useState(null); const [value, setValue] = react.useState(null); const refresh = react.useCallback(async () => { const result = await props.target(props.sessionId); if (result.ok) { setValue(result.value); setError(null); return; } setError(result.error); }, [props.sessionId]); react.useEffect(() => { let active = true; const update = async () => { if (!active || document.visibilityState === "hidden") return; await refresh(); }; const onVisibilityChange = () => { if (document.visibilityState === "visible") void update(); }; void update(); const timer = window.setInterval(() => { void update(); }, 2500); document.addEventListener("visibilitychange", onVisibilityChange); return () => { active = false; window.clearInterval(timer); document.removeEventListener("visibilitychange", onVisibilityChange); }; }, [refresh]); const onClick = async () => { if (busy) return; setBusy(true); setError(null); const result = await props.open(props.sessionId); setBusy(false); if (result.ok) { setValue(result.value); return; } setError(result.error); }; const isSet = value !== null && value.set === true; const name = isSet ? directoryName(value.workingDirectory) : ""; const title = error !== null ? `Git target error: ${error.message}` : isSet ? `Working directory: ${value.workingDirectory}\nRepository: ${value.repository}\nClick to open in Sublime Merge` : "No Git working directory set — the agent sets it with set_active_git_directory"; return jsx.jsxs("button", { type: "button", className: "dsh-open-in-smerge", disabled: busy || !isSet, "aria-busy": busy, "aria-label": isSet ? `Open Git working directory ${name}` : "Git working directory not set", "data-failed": error !== null, title, onClick, children: [ jsx.jsx("span", { className: "dsh-open-in-smerge__kind", children: "Git" }), isSet ? jsx.jsxs(react.Fragment, { children: [ jsx.jsx("span", { className: "dsh-open-in-smerge__separator", "aria-hidden": true, children: "·" }), jsx.jsx("span", { className: "dsh-open-in-smerge__directory", children: busy ? "Opening…" : name }), ] }) : null, ], }); } const inject = ["slots"]; function apply(ctx) { installStyle(); ctx.slots.inject("conversation.session.header.utilities", () => ctx.slots.register({ name: "conversation.session.header.utilities", id: "open-in-smerge", order: 80, label: "Git working directory", inject: () => ({ target: (sessionId) => request(`/smerge/target?sessionId=${encodeURIComponent(sessionId)}`), open: (sessionId) => request("/smerge/open", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ sessionId }), }), }), }, OpenInSmergeButton)); } exports.apply = apply; exports.inject = inject; return module.exports; }, });