2026-04-18 14:08:01 +00:00
|
|
|
// Package sanitize strips third-party AI branding, telemetry headers, and
|
|
|
|
|
// identifying metadata from prompts before they are forwarded to the Cursor
|
|
|
|
|
// CLI. Without this, the Cursor agent sees "You are Claude Code..." style
|
|
|
|
|
// system prompts and behaves confusingly (trying to use tools it doesn't
|
|
|
|
|
// own, reasoning about being "Anthropic's CLI", etc.).
|
|
|
|
|
//
|
|
|
|
|
// Ported from cursor-api-proxy/src/lib/sanitize.ts.
|
|
|
|
|
package sanitize
|
|
|
|
|
|
|
|
|
|
import "regexp"
|
|
|
|
|
|
|
|
|
|
type rule struct {
|
|
|
|
|
pattern *regexp.Regexp
|
|
|
|
|
replace string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Note: Go regexp is RE2, no lookbehind/lookahead, but these rules don't need any.
|
|
|
|
|
// (?i) enables case-insensitive for that single rule.
|
|
|
|
|
var rules = []rule{
|
|
|
|
|
// Strip x-anthropic-billing-header line (injected by Claude Code CLI).
|
|
|
|
|
{regexp.MustCompile(`(?i)x-anthropic-billing-header:[^\n]*\n?`), ""},
|
|
|
|
|
// Strip individual telemetry tokens that may appear in headers or text.
|
|
|
|
|
{regexp.MustCompile(`(?i)\bcc_version=[^\s;,\n]+[;,]?\s*`), ""},
|
|
|
|
|
{regexp.MustCompile(`(?i)\bcc_entrypoint=[^\s;,\n]+[;,]?\s*`), ""},
|
|
|
|
|
{regexp.MustCompile(`(?i)\bcch=[a-f0-9]+[;,]?\s*`), ""},
|
2026-04-25 13:18:22 +00:00
|
|
|
|
|
|
|
|
// --- Sandbox / capability limitation stripping ---
|
|
|
|
|
// Claude Desktop's system prompt tells the model it's in a sandbox,
|
|
|
|
|
// cannot access the filesystem, is in "Ask mode" / "Cowork mode", etc.
|
|
|
|
|
// These phrases cause the model to refuse helpful responses. We strip
|
|
|
|
|
// them so the model still sees tool definitions but not the restrictions.
|
|
|
|
|
|
|
|
|
|
// "you cannot access ...", "you do not have access to ...", etc.
|
|
|
|
|
{regexp.MustCompile(`(?i)[^\n]*(?:you (?:cannot|can ?not|do not|don[''\x{2019}]t|are unable to) (?:access|read|write|modify|execute|run|create|delete|move|open))[^\n]*\n?`), ""},
|
|
|
|
|
// "you are in a sandboxed environment", "running in a sandbox", etc.
|
|
|
|
|
{regexp.MustCompile(`(?i)[^\n]*(?:sandbox(?:ed)?|isolated) (?:environment|mode|context)[^\n]*\n?`), ""},
|
|
|
|
|
// "you are in Ask mode" / "Cowork mode" / "read-only mode"
|
|
|
|
|
{regexp.MustCompile(`(?i)[^\n]*(?:Ask mode|Cowork(?:er)? mode|read[- ]only mode)[^\n]*\n?`), ""},
|
|
|
|
|
// "you don't have filesystem access" / "no filesystem access"
|
|
|
|
|
{regexp.MustCompile(`(?i)[^\n]*(?:no|without|lack(?:s|ing)?|limited) (?:file ?system|file|terminal|shell|command[- ]line) access[^\n]*\n?`), ""},
|
|
|
|
|
// "you cannot run commands on the user's machine"
|
|
|
|
|
{regexp.MustCompile(`(?i)[^\n]*cannot (?:run|execute) (?:commands?|scripts?|code) (?:on|in)[^\n]*\n?`), ""},
|
|
|
|
|
|
|
|
|
|
// --- Branding replacement ---
|
2026-04-18 14:08:01 +00:00
|
|
|
// Replace "Claude Code" product name with "Cursor" (case-sensitive on purpose).
|
|
|
|
|
{regexp.MustCompile(`\bClaude Code\b`), "Cursor"},
|
|
|
|
|
// Replace full Anthropic CLI description. Handle both straight and curly apostrophes.
|
|
|
|
|
{regexp.MustCompile(`(?i)Anthropic['\x{2019}]s official CLI for Claude`), "Cursor AI assistant"},
|
|
|
|
|
// Replace remaining Anthropic brand references.
|
|
|
|
|
{regexp.MustCompile(`\bAnthropic\b`), "Cursor"},
|
|
|
|
|
// Known Anthropic domains.
|
|
|
|
|
{regexp.MustCompile(`(?i)anthropic\.com`), "cursor.com"},
|
|
|
|
|
{regexp.MustCompile(`(?i)claude\.ai`), "cursor.sh"},
|
|
|
|
|
// Normalise leftover leading semicolons/whitespace at start of content.
|
|
|
|
|
{regexp.MustCompile(`^[;,\s]+`), ""},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Text applies all sanitization rules to s.
|
|
|
|
|
func Text(s string) string {
|
|
|
|
|
if s == "" {
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
for _, r := range rules {
|
|
|
|
|
s = r.pattern.ReplaceAllString(s, r.replace)
|
|
|
|
|
}
|
|
|
|
|
return s
|
|
|
|
|
}
|