feat: initial LexAI Chrome extension scaffold
Some checks failed
CI — Test & Build / Unit Tests (push) Failing after 54s
CI — Test & Build / Build Extension (push) Has been skipped

- WXT + React 18 + TypeScript setup
- Background service worker (LLM API proxy)
- Content script (floating toolbar + text selection)
- Options page (provider/model/API key config)
- Popup UI
- Gitea Actions workflows (CI, preview, release)
- Vitest unit tests + Playwright E2E setup
- Supports: OpenAI, Anthropic, Groq, OpenRouter
This commit is contained in:
Nemo
2026-03-06 09:34:15 +08:00
commit b04076081c
20 changed files with 6254 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
import React, { useEffect, useState } from 'react';
import { createRoot } from 'react-dom/client';
function Popup() {
const [configured, setConfigured] = useState(false);
const [provider, setProvider] = useState('');
const [model, setModel] = useState('');
useEffect(() => {
chrome.storage.local.get(['provider', 'apiKey', 'model'], (result) => {
if (result.apiKey) {
setConfigured(true);
setProvider(result.provider || 'openai');
setModel(result.model || '');
}
});
}, []);
const openSettings = () => chrome.runtime.openOptionsPage();
return (
<div style={{ padding: 16, fontFamily: 'system-ui, sans-serif', color: '#1e1e2e' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 }}>
<span style={{ fontSize: 20 }}></span>
<span style={{ fontSize: 16, fontWeight: 700 }}>LexAI</span>
</div>
{configured ? (
<div>
<div style={{ background: '#e8f5e9', borderRadius: 8, padding: '8px 12px', marginBottom: 12 }}>
<div style={{ fontSize: 12, color: '#388e3c', fontWeight: 600 }}> Active</div>
<div style={{ fontSize: 12, color: '#555', marginTop: 2 }}>{provider} / {model}</div>
</div>
<p style={{ fontSize: 12, color: '#6c6f85', marginBottom: 12 }}>
Select any text on a webpage to see LexAI options appear.
</p>
</div>
) : (
<div style={{ background: '#fff3e0', borderRadius: 8, padding: '8px 12px', marginBottom: 12 }}>
<div style={{ fontSize: 12, color: '#e65100', fontWeight: 600 }}> Setup Required</div>
<div style={{ fontSize: 12, color: '#555', marginTop: 2 }}>Add your API key to get started</div>
</div>
)}
<button
onClick={openSettings}
style={{
width: '100%',
background: '#89b4fa',
color: '#1e1e2e',
border: 'none',
borderRadius: 8,
padding: '8px',
fontSize: 13,
fontWeight: 600,
cursor: 'pointer',
}}
>
Open Settings
</button>
</div>
);
}
createRoot(document.getElementById('app')!).render(<Popup />);

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>LexAI</title>
<style>body { margin: 0; width: 320px; }</style>
</head>
<body>
<div id="app"></div>
<script type="module" src="./Popup.tsx"></script>
</body>
</html>