feat(cli): add initial CLI implementation with argument parsing and prompt handling
Some checks failed
CI — Test & Build / Test & Build (pull_request) Has been cancelled
Preview — PR Build Check / PR Preview Build (pull_request) Has been cancelled

- Created package.json and package-lock.json for CLI package.
- Implemented argument parsing in args.ts to handle various flags and commands.
- Developed main CLI logic in cli.ts to execute commands and handle errors.
- Added configuration loading from a JSON file in config.ts, with environment variable support.
- Implemented prompt resolution and provider interaction in prompt.ts.
- Added usage documentation for the CLI.
- Configured TypeScript settings in tsconfig.json for the CLI package.
- Updated README in vscode package to reflect the new CLI functionality.
- Refactored root tsconfig.json to streamline project structure.
This commit is contained in:
john kevin asprec
2026-08-13 19:19:42 +08:00
parent d63d698b57
commit 2c00d2e431
37 changed files with 9303 additions and 166 deletions

49
packages/chrome/README.md Normal file
View File

@@ -0,0 +1,49 @@
# LexAI for Chrome
Grammarly-like **Manifest V3** writing assistant powered by **your own LLM API key**. No LexAI account, no subscription, no LexAI servers.
**Chrome Web Store:** [LexAI — AI Writing Assistant](https://chromewebstore.google.com/detail/bagpcheidbkfgijnnmolnkgagibbjfnk)
## Features
- Select text on any page → **Fix / Rephrase / Shorten / Expand / Explain / Make Prompt**
- Writing styles: Formal, Casual, Academic, Creative, Concise
- Floating toolbar + right-click context menu + popup editor
- Prompt Builder (patterns, persona, format)
- Providers: OpenAI · Anthropic · Groq · OpenRouter
- API key encrypted locally (`tweetnacl` secretbox)
## Develop
From the **repo root**:
```bash
npm run chrome:install
npm run chrome:dev # hot reload
npm run chrome:build # → packages/chrome/.output/chrome-mv3/
npm run chrome:zip # store package
npm run chrome:test
npm run chrome:typecheck
```
Or inside this package:
```bash
npm install
npm run dev
npm run build
```
### Load unpacked
1. `npm run chrome:build`
2. Chrome → `chrome://extensions` → Developer Mode
3. **Load unpacked** → select `packages/chrome/.output/chrome-mv3`
## Shared core
Provider adapters and prompts live in [`../../src/lib`](../../src/lib) (`@lib/*`). Do not import `@lib/crypto` or `@lib/messaging` from the VS Code or CLI packages.
## Version
Bump `version` in this packages `package.json` only — the extension manifest follows it via `wxt.config.ts`.

7018
packages/chrome/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
{
"name": "lexai-chrome",
"version": "1.1.0",
"description": "LexAI Chrome extension (Manifest V3) — BYO-LLM writing assistant",
"private": true,
"type": "module",
"engines": {
"node": ">=22"
},
"scripts": {
"dev": "wxt",
"build": "wxt build",
"zip": "wxt zip",
"postinstall": "wxt prepare",
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
"test": "vitest",
"test:e2e": "playwright test"
},
"dependencies": {
"@wxt-dev/module-react": "^1.1.5",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"tweetnacl": "^1.0.3",
"wxt": "^0.20.18"
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@types/chrome": "^0.1.37",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.1",
"jsdom": "^28.1.0",
"typescript": "^5.7.3",
"vitest": "^3.0.7"
}
}

View File

@@ -0,0 +1,23 @@
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: '../../tests/e2e',
timeout: 30000,
use: {
channel: 'chrome',
},
projects: [
{
name: 'chromium-extension',
use: {
browserName: 'chromium',
launchOptions: {
args: [
'--disable-extensions-except=.output/chrome-mv3',
'--load-extension=.output/chrome-mv3',
],
},
},
},
],
});

View File

@@ -0,0 +1,28 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"lib": ["ESNext", "DOM"],
"jsx": "react-jsx",
"strict": true,
"noEmit": true,
"skipLibCheck": true,
"types": ["chrome"],
"esModuleInterop": true,
"resolveJsonModule": true,
"allowImportingTsExtensions": true,
"paths": {
"@lib/*": ["../../src/lib/*"]
}
},
"include": [
"entrypoints/**/*",
"../../src/lib/**/*",
".wxt/types/**/*"
],
"exclude": [
"node_modules",
".output"
]
}

View File

@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": ["chrome", "vitest/globals"]
},
"include": [
"../../tests/**/*",
"../../src/lib/**/*"
]
}

View File

@@ -0,0 +1,17 @@
import { fileURLToPath } from 'node:url';
import { defineConfig } from 'vitest/config';
export default defineConfig({
resolve: {
alias: {
'@lib': fileURLToPath(new URL('../../src/lib', import.meta.url)),
},
},
test: {
environment: 'jsdom',
globals: true,
setupFiles: ['../../tests/unit/setup.ts'],
include: ['../../tests/unit/**/*.test.ts'],
exclude: ['../../tests/e2e/**/*'],
},
});

View File

@@ -5,16 +5,15 @@ import pkg from './package.json';
export default defineConfig({
extensionApi: 'chrome',
// Shared-code alias. Deliberately NOT "~" or "@" — WXT force-overwrites those
// to srcDir (the project root here), so they cannot point at ./src.
// to srcDir, so they cannot point at the monorepo shared lib.
alias: {
'@lib': resolve(__dirname, 'src/lib'),
'@lib': resolve(__dirname, '../../src/lib'),
},
modules: ['@wxt-dev/module-react'],
manifest: {
name: 'LexAI - AI Writing Assistant',
description: 'Grammar checking and writing assistance powered by your own LLM API key',
// Single source of truth: manifest version always follows package.json,
// so a release bump is a one-file edit and versions can never drift.
// Single source of truth: manifest version always follows package.json.
version: pkg.version,
icons: {
'16': 'icon-16.png',