Files
Pawan Osman 7bb5801a8c Rewrite project as OpenCursor, a VS Code AI coding agent extension
Replace the ChatGPT reverse proxy (Docker/proxy server) entirely with
OpenCursor: a Cursor-like agentic coding extension for VS Code.

- Remove proxy server, Dockerfiles, docker-compose setups, and CI workflows
- Add agent loop with tools (files, shell, search, web, MCP), multi-provider
  LLM support (OpenAI-compatible, Ollama, llama.cpp) with OAuth
- Add semantic indexing, workspace context, and @-mentions
- Add sidebar chat + settings webview UI (React), inline review, personas,
  hooks, and approval policies
- Switch to pnpm, esbuild bundling, and VS Code extension packaging
2026-07-05 22:07:25 +03:00

40 lines
1.4 KiB
TypeScript

/*
* Copyright (c) 2026 Pawan Osman <https://github.com/PawanOsman>
*
* This file is part of OpenCursor — AI coding agent chat inside VS Code.
* https://github.com/PawanOsman/OpenCursor
*
* Licensed under the MIT License. See LICENSE file in the project root.
*/
import { Marked } from "marked";
// GFM markdown (tables, task lists, fenced code, etc.). marked passes raw HTML
// through, so we sanitize the output before injecting into the webview.
const marked = new Marked({ gfm: true, breaks: true });
// Drop dangerous nodes/attributes. AI output is semi-trusted; the webview CSP
// also blocks inline scripts, but defence in depth is cheap here.
function sanitize(html: string): string {
return html
.replace(/<\/?(script|style|iframe|object|embed|link|meta|base)\b[^>]*>/gi, "")
.replace(/\son\w+\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/gi, "")
.replace(/(href|src)\s*=\s*("|')\s*javascript:[^"']*\2/gi, '$1="#"');
}
export function renderMarkdown(srcIn: string): string {
const src = String(srcIn == null ? "" : srcIn);
try {
return sanitize(marked.parse(src, { async: false }) as string);
} catch {
// Fallback: render as escaped plain text on parser failure.
return "<p>" + src.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</p>";
}
}
export function basename(p: string): string {
if (!p) return "";
const parts = String(p).split(/[\\/]/);
return parts[parts.length - 1] || p;
}