26382a7ac6
CI / Clippy (push) Failing after 15m13s
CI / Test (ubuntu-latest) (push) Failing after 16m1s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (no embeddings / no ORT) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Cookbook (Node) (push) Has been cancelled
CI / Pi Extension (Node) (push) Has been cancelled
CI / Rust SDK (lean-ctx-client) (push) Has been cancelled
CI / Embed SDK (lean-ctx-sdk) (push) Has been cancelled
CI / Python SDK (leanctx) (push) Has been cancelled
CI / Hermes Plugin (Python) (push) Has been cancelled
CI / SDK Conformance Matrix (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / cargo-deny (push) Has been cancelled
CI / Adversarial Safety (push) Has been cancelled
CI / Benchmarks (push) Has been cancelled
CI / Output-Quality Gate (eval A/B) (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / CI Green (push) Has been cancelled
JetBrains Plugin / Actionlint (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
JetBrains Plugin / Validation (push) Has been cancelled
JetBrains Plugin / Build (push) Has been cancelled
JetBrains Plugin / Test (push) Has been cancelled
Security Check / Security Scan (push) Has been cancelled
126 lines
3.4 KiB
Python
Executable File
126 lines
3.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""lean-ctx native messaging bridge for Chrome.
|
|
|
|
One-shot mode: reads a single JSON message from Chrome via stdin
|
|
(length-prefixed), processes it, returns the result, then exits.
|
|
"""
|
|
import json
|
|
import struct
|
|
import subprocess
|
|
import sys
|
|
import os
|
|
import traceback
|
|
|
|
LOG_PATH = os.path.expanduser("~/.lean-ctx/bridge-debug.log")
|
|
|
|
|
|
def log(msg):
|
|
try:
|
|
os.makedirs(os.path.dirname(LOG_PATH), exist_ok=True)
|
|
with open(LOG_PATH, "a") as f:
|
|
f.write(msg + "\n")
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def find_lean_ctx():
|
|
for candidate in [
|
|
os.path.expanduser("~/.cargo/bin/lean-ctx"),
|
|
"/usr/local/bin/lean-ctx",
|
|
"/opt/homebrew/bin/lean-ctx",
|
|
]:
|
|
if os.path.isfile(candidate) and os.access(candidate, os.X_OK):
|
|
return candidate
|
|
import shutil
|
|
return shutil.which("lean-ctx")
|
|
|
|
|
|
def read_message():
|
|
raw = sys.stdin.buffer.read(4)
|
|
log(f"header bytes: {len(raw)}")
|
|
if len(raw) < 4:
|
|
return None
|
|
length = struct.unpack("I", raw)[0]
|
|
log(f"message length: {length}")
|
|
if length > 1024 * 1024:
|
|
return None
|
|
data = sys.stdin.buffer.read(length)
|
|
log(f"body bytes: {len(data)}")
|
|
if len(data) < length:
|
|
return None
|
|
return json.loads(data.decode("utf-8"))
|
|
|
|
|
|
def send_message(obj):
|
|
encoded = json.dumps(obj, ensure_ascii=False).encode("utf-8")
|
|
sys.stdout.buffer.write(struct.pack("I", len(encoded)))
|
|
sys.stdout.buffer.write(encoded)
|
|
sys.stdout.buffer.flush()
|
|
log(f"sent: {len(encoded)} bytes")
|
|
|
|
|
|
def compress(text, binary_path):
|
|
try:
|
|
env = os.environ.copy()
|
|
env.pop("LEAN_CTX_ACTIVE", None)
|
|
env.pop("LEAN_CTX_DISABLED", None)
|
|
env["NO_COLOR"] = "1"
|
|
result = subprocess.run(
|
|
[binary_path, "-c", "cat"],
|
|
input=text,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=10,
|
|
env=env,
|
|
)
|
|
compressed = result.stdout.strip() if result.returncode == 0 else text
|
|
except (subprocess.TimeoutExpired, FileNotFoundError) as e:
|
|
log(f"compress error: {e}")
|
|
compressed = text
|
|
|
|
input_tokens = len(text) // 4
|
|
output_tokens = len(compressed) // 4
|
|
savings = ((input_tokens - output_tokens) / max(input_tokens, 1)) * 100
|
|
|
|
return {
|
|
"compressed": compressed,
|
|
"inputTokens": input_tokens,
|
|
"outputTokens": output_tokens,
|
|
"savings": round(savings, 1),
|
|
}
|
|
|
|
|
|
def main():
|
|
log("--- bridge started ---")
|
|
try:
|
|
msg = read_message()
|
|
if msg is None:
|
|
log("no input received")
|
|
send_message({"error": "no input"})
|
|
return
|
|
|
|
binary = find_lean_ctx()
|
|
action = msg.get("action", "")
|
|
log(f"action: {action}, binary: {binary}")
|
|
|
|
if action == "ping":
|
|
send_message({"status": "ok", "binary": binary or "not found"})
|
|
elif action == "compress":
|
|
text = msg.get("text", "")
|
|
if binary and text:
|
|
send_message(compress(text, binary))
|
|
else:
|
|
send_message({"error": "lean-ctx not found or empty text"})
|
|
else:
|
|
send_message({"error": f"unknown action: {action}"})
|
|
except Exception as e:
|
|
log(f"EXCEPTION: {traceback.format_exc()}")
|
|
try:
|
|
send_message({"error": str(e)})
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|