diff --git a/.gitea/workflows/ci-chrome.yml b/.gitea/workflows/ci-chrome.yml new file mode 100644 index 0000000..c2cb80d --- /dev/null +++ b/.gitea/workflows/ci-chrome.yml @@ -0,0 +1,80 @@ +name: CI — Chrome + +on: + push: + branches: [main, develop] + paths: + - 'packages/chrome/**' + - 'src/lib/**' + - 'tests/**' + - '.gitea/workflows/ci-chrome.yml' + pull_request: + branches: [main] + paths: + - 'packages/chrome/**' + - 'src/lib/**' + - 'tests/**' + - '.gitea/workflows/ci-chrome.yml' + +jobs: + chrome: + name: Chrome — typecheck, test, build + runs-on: ubuntu-latest + timeout-minutes: 15 + container: + image: node:22-bookworm + + steps: + - name: Install system deps + run: apt-get update -qq && apt-get install -y git ca-certificates -qq + + - name: Clone repository + run: | + git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git /tmp/lexai + cd /tmp/lexai + if [ "${{ gitea.event_name }}" = "pull_request" ]; then + git fetch origin pull/${{ gitea.event.pull_request.number }}/head:pr + git checkout pr + else + git checkout ${{ gitea.sha }} + fi + + - name: Install dependencies + run: npm ci --prefer-offline --no-audit --no-fund + working-directory: /tmp/lexai/packages/chrome + + - name: Prepare WXT types + run: npx wxt prepare + working-directory: /tmp/lexai/packages/chrome + + - name: Typecheck + run: npm run typecheck + working-directory: /tmp/lexai/packages/chrome + + - name: Unit tests + run: npm test -- --run + working-directory: /tmp/lexai/packages/chrome + + - name: Build + run: npm run build + working-directory: /tmp/lexai/packages/chrome + + - name: Verify output + run: ls -la .output/chrome-mv3/ + working-directory: /tmp/lexai/packages/chrome + + - name: Notify Success + if: success() + run: | + SHA=$(echo "${{ gitea.sha }}" | cut -c1-7) + curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ + -d "chat_id=${{ secrets.TELEGRAM_CHAT_ID }}" \ + -d "text=✅ LexAI CI Chrome Passed%0ABranch: ${{ gitea.ref_name }}%0ACommit: ${SHA}" + + - name: Notify Failure + if: failure() + run: | + SHA=$(echo "${{ gitea.sha }}" | cut -c1-7) + curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ + -d "chat_id=${{ secrets.TELEGRAM_CHAT_ID }}" \ + -d "text=❌ LexAI CI Chrome FAILED%0ABranch: ${{ gitea.ref_name }}%0ACommit: ${SHA}%0Ahttps://git.juankibin.space/kibin/LexAI/actions" diff --git a/.gitea/workflows/ci-cli.yml b/.gitea/workflows/ci-cli.yml new file mode 100644 index 0000000..b94edbc --- /dev/null +++ b/.gitea/workflows/ci-cli.yml @@ -0,0 +1,72 @@ +name: CI — CLI + +on: + push: + branches: [main, develop] + paths: + - 'packages/cli/**' + - 'src/lib/**' + - '.gitea/workflows/ci-cli.yml' + pull_request: + branches: [main] + paths: + - 'packages/cli/**' + - 'src/lib/**' + - '.gitea/workflows/ci-cli.yml' + +jobs: + cli: + name: CLI — typecheck, build, smoke + runs-on: ubuntu-latest + timeout-minutes: 10 + container: + image: node:22-bookworm + + steps: + - name: Install system deps + run: apt-get update -qq && apt-get install -y git ca-certificates -qq + + - name: Clone repository + run: | + git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git /tmp/lexai + cd /tmp/lexai + if [ "${{ gitea.event_name }}" = "pull_request" ]; then + git fetch origin pull/${{ gitea.event.pull_request.number }}/head:pr + git checkout pr + else + git checkout ${{ gitea.sha }} + fi + + - name: Install dependencies + run: npm ci --prefer-offline --no-audit --no-fund + working-directory: /tmp/lexai/packages/cli + + - name: Typecheck + run: npm run typecheck + working-directory: /tmp/lexai/packages/cli + + - name: Build + run: npm run build + working-directory: /tmp/lexai/packages/cli + + - name: Smoke (help + list, no API key) + run: | + node out/cli.js --help + node out/cli.js prompt --list + working-directory: /tmp/lexai/packages/cli + + - name: Notify Success + if: success() + run: | + SHA=$(echo "${{ gitea.sha }}" | cut -c1-7) + curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ + -d "chat_id=${{ secrets.TELEGRAM_CHAT_ID }}" \ + -d "text=✅ LexAI CI CLI Passed%0ABranch: ${{ gitea.ref_name }}%0ACommit: ${SHA}" + + - name: Notify Failure + if: failure() + run: | + SHA=$(echo "${{ gitea.sha }}" | cut -c1-7) + curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ + -d "chat_id=${{ secrets.TELEGRAM_CHAT_ID }}" \ + -d "text=❌ LexAI CI CLI FAILED%0ABranch: ${{ gitea.ref_name }}%0ACommit: ${SHA}%0Ahttps://git.juankibin.space/kibin/LexAI/actions" diff --git a/.gitea/workflows/ci-vscode.yml b/.gitea/workflows/ci-vscode.yml new file mode 100644 index 0000000..ae3e4a1 --- /dev/null +++ b/.gitea/workflows/ci-vscode.yml @@ -0,0 +1,70 @@ +name: CI — VS Code + +on: + push: + branches: [main, develop] + paths: + - 'packages/vscode/**' + - 'src/lib/**' + - '.gitea/workflows/ci-vscode.yml' + pull_request: + branches: [main] + paths: + - 'packages/vscode/**' + - 'src/lib/**' + - '.gitea/workflows/ci-vscode.yml' + +jobs: + vscode: + name: VS Code — typecheck, build + runs-on: ubuntu-latest + timeout-minutes: 15 + container: + image: node:22-bookworm + + steps: + - name: Install system deps + run: apt-get update -qq && apt-get install -y git ca-certificates -qq + + - name: Clone repository + run: | + git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git /tmp/lexai + cd /tmp/lexai + if [ "${{ gitea.event_name }}" = "pull_request" ]; then + git fetch origin pull/${{ gitea.event.pull_request.number }}/head:pr + git checkout pr + else + git checkout ${{ gitea.sha }} + fi + + - name: Install dependencies + run: npm ci --prefer-offline --no-audit --no-fund + working-directory: /tmp/lexai/packages/vscode + + - name: Typecheck + run: npm run typecheck + working-directory: /tmp/lexai/packages/vscode + + - name: Build + run: npm run build + working-directory: /tmp/lexai/packages/vscode + + - name: Verify output + run: ls -la out/extension.js + working-directory: /tmp/lexai/packages/vscode + + - name: Notify Success + if: success() + run: | + SHA=$(echo "${{ gitea.sha }}" | cut -c1-7) + curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ + -d "chat_id=${{ secrets.TELEGRAM_CHAT_ID }}" \ + -d "text=✅ LexAI CI VS Code Passed%0ABranch: ${{ gitea.ref_name }}%0ACommit: ${SHA}" + + - name: Notify Failure + if: failure() + run: | + SHA=$(echo "${{ gitea.sha }}" | cut -c1-7) + curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ + -d "chat_id=${{ secrets.TELEGRAM_CHAT_ID }}" \ + -d "text=❌ LexAI CI VS Code FAILED%0ABranch: ${{ gitea.ref_name }}%0ACommit: ${SHA}%0Ahttps://git.juankibin.space/kibin/LexAI/actions" diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml deleted file mode 100644 index 40e1624..0000000 --- a/.gitea/workflows/ci.yml +++ /dev/null @@ -1,100 +0,0 @@ -name: CI — Test & Build - -on: - push: - branches: [main, develop] - pull_request: - branches: [main] - -jobs: - test-and-build: - name: Test & Build - runs-on: ubuntu-latest - timeout-minutes: 15 - container: - image: node:22-bookworm - - steps: - - name: Install system deps - run: apt-get update -qq && apt-get install -y zip curl git ca-certificates -qq - - - name: Clone repository (triggering ref) - run: | - git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git /tmp/lexai - cd /tmp/lexai - if [ "${{ gitea.event_name }}" = "pull_request" ]; then - git fetch origin pull/${{ gitea.event.pull_request.number }}/head:pr - git checkout pr - else - git checkout ${{ gitea.sha }} - fi - - - name: Install Chrome package dependencies - run: npm ci --prefer-offline --no-audit --no-fund - working-directory: /tmp/lexai/packages/chrome - - # Generates .wxt/types (ImportMeta.env etc.) required by typecheck. - - name: Prepare WXT types - run: npx wxt prepare - working-directory: /tmp/lexai/packages/chrome - - - name: Type check - run: npm run typecheck - working-directory: /tmp/lexai/packages/chrome - - - name: Run unit tests - run: npm test -- --run - working-directory: /tmp/lexai/packages/chrome - - - name: Build extension - run: npm run build - working-directory: /tmp/lexai/packages/chrome - - - name: Verify build output - run: ls -la .output/chrome-mv3/ - working-directory: /tmp/lexai/packages/chrome - - - name: Package as ZIP - run: | - SHA=$(echo "${{ gitea.sha }}" | cut -c1-7) - TS=$(date +%Y%m%d%H%M%S) - VERSION=$(node -p "require('./package.json').version")-${SHA}-${TS} - zip -r /tmp/lexai-chrome-mv3-${VERSION}.zip .output/chrome-mv3/ - echo "PACKAGE_VERSION=${VERSION}" >> $GITHUB_ENV - echo "✅ Packaged: lexai-chrome-mv3-${VERSION}.zip" - working-directory: /tmp/lexai/packages/chrome - - - name: Publish to Gitea Package Registry - if: gitea.event_name == 'push' - run: | - RESPONSE=$(curl -s -w "\n%{http_code}" -X PUT \ - "${{ gitea.server_url }}/api/packages/kibin/generic/lexai-extension/${PACKAGE_VERSION}/lexai-chrome-mv3-${PACKAGE_VERSION}.zip" \ - -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ - -T "/tmp/lexai-chrome-mv3-${PACKAGE_VERSION}.zip") - HTTP_CODE=$(echo "$RESPONSE" | tail -n 1) - BODY=$(echo "$RESPONSE" | sed '$d') - echo "HTTP: $HTTP_CODE | Response: $BODY" - if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then - echo "✅ Published: https://git.juankibin.space/kibin/-/packages" - else - echo "⚠️ Package publish returned $HTTP_CODE: $BODY" - exit 1 - fi - env: - PACKAGE_VERSION: ${{ env.PACKAGE_VERSION }} - - - name: Notify Success - if: success() - run: | - SHA=$(echo "${{ gitea.sha }}" | cut -c1-7) - curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ - -d "chat_id=${{ secrets.TELEGRAM_CHAT_ID }}" \ - -d "text=✅ LexAI CI Passed%0A%0ABranch: ${{ gitea.ref_name }}%0ACommit: ${SHA}%0A%0AAll steps green — new build published to packages." - - - name: Notify Failure - if: failure() - run: | - SHA=$(echo "${{ gitea.sha }}" | cut -c1-7) - curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ - -d "chat_id=${{ secrets.TELEGRAM_CHAT_ID }}" \ - -d "text=❌ LexAI CI FAILED%0A%0ABranch: ${{ gitea.ref_name }}%0ACommit: ${SHA}%0A%0ACheck: https://git.juankibin.space/kibin/LexAI/actions" diff --git a/.gitea/workflows/deploy-chrome.yml b/.gitea/workflows/deploy-chrome.yml deleted file mode 100644 index df88041..0000000 --- a/.gitea/workflows/deploy-chrome.yml +++ /dev/null @@ -1,132 +0,0 @@ -name: Deploy — Chrome Web Store - -on: - push: - tags: - - 'v*.*.*' - workflow_dispatch: - inputs: - publish: - description: 'Publish after upload? (yes/no)' - required: false - default: 'yes' - -jobs: - deploy: - name: Build & Deploy to Chrome Web Store - runs-on: ubuntu-latest - timeout-minutes: 20 - container: - image: node:22-bookworm - - steps: - - name: Install deps - run: apt-get update -qq && apt-get install -y zip curl - - - name: Checkout - run: | - git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git . - git checkout ${{ gitea.sha }} - - - name: Install dependencies - run: npm ci - working-directory: packages/chrome - - # Same gates as CI — a release must never check less than a push. - - name: Prepare WXT types - run: npx wxt prepare - working-directory: packages/chrome - - - name: Type check - run: npm run typecheck - working-directory: packages/chrome - - - name: Run tests - run: npm test -- --run - working-directory: packages/chrome - - - name: Build extension - run: npm run build - working-directory: packages/chrome - - - name: Package as ZIP - run: | - VERSION=${{ gitea.ref_name || 'manual' }} - ZIPFILE="$(cd ../.. && pwd)/lexai-chrome-mv3-${VERSION}.zip" - # Verify manifest exists and check version - node -e "console.log('Manifest version:', require('./.output/chrome-mv3/manifest.json').version)" - # Zip from inside the chrome-mv3 dir so manifest.json is at root - cd .output/chrome-mv3 && zip -r "$ZIPFILE" . && cd - - echo "ZIP_FILE=${ZIPFILE}" >> $GITHUB_ENV - echo "VERSION=${VERSION}" >> $GITHUB_ENV - echo "✅ Packaged: lexai-chrome-mv3-${VERSION}.zip" - working-directory: packages/chrome - - - - name: Get Chrome Web Store OAuth2 Token - run: | - TOKEN_RESPONSE=$(curl -s -X POST "https://oauth2.googleapis.com/token" \ - -d "client_id=${{ secrets.CWS_CLIENT_ID }}" \ - -d "client_secret=${{ secrets.CWS_CLIENT_SECRET }}" \ - -d "refresh_token=${{ secrets.CWS_REFRESH_TOKEN }}" \ - -d "grant_type=refresh_token") - ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | node -e "let s='';process.stdin.on('data',d=>s+=d);process.stdin.on('end',()=>{let d;try{d=JSON.parse(s)}catch(e){console.error('Invalid JSON token response:',s);process.exit(1)};if(!d.access_token){console.error('No access_token in response:',s);process.exit(1)};console.log(d.access_token)})") - if [ -z "$ACCESS_TOKEN" ]; then - echo "❌ Failed to get access token. Response: $TOKEN_RESPONSE" - exit 1 - fi - echo "CWS_ACCESS_TOKEN=${ACCESS_TOKEN}" >> $GITHUB_ENV - echo "✅ OAuth2 token obtained" - - - name: Upload to Chrome Web Store - run: | - UPLOAD_BODY=$(curl -s -X PUT \ - "https://www.googleapis.com/upload/chromewebstore/v1.1/items/${{ secrets.CWS_EXTENSION_ID }}" \ - -H "Authorization: Bearer ${{ env.CWS_ACCESS_TOKEN }}" \ - -H "x-goog-api-version: 2" \ - -T "${{ env.ZIP_FILE }}") - echo "Upload Response: $UPLOAD_BODY" - UPLOAD_STATE=$(echo "$UPLOAD_BODY" | node -e "let s='';process.stdin.on('data',d=>s+=d);process.stdin.on('end',()=>{let d;try{d=JSON.parse(s)}catch(e){console.error('Invalid JSON upload response:',s);process.exit(1)};console.log(d.uploadState||'')})") - echo "Upload state: $UPLOAD_STATE" - if [ "$UPLOAD_STATE" != "SUCCESS" ]; then - echo "❌ Upload failed — state: $UPLOAD_STATE" - exit 1 - fi - echo "✅ Uploaded to Chrome Web Store" - - - name: Publish to Chrome Web Store - if: ${{ gitea.event_name == 'push' || github.event.inputs.publish == 'yes' }} - run: | - PUBLISH_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \ - "https://www.googleapis.com/chromewebstore/v1.1/items/${{ secrets.CWS_EXTENSION_ID }}/publish" \ - -H "Authorization: Bearer ${{ env.CWS_ACCESS_TOKEN }}" \ - -H "x-goog-api-version: 2" \ - -H "Content-Length: 0") - HTTP_CODE=$(echo "$PUBLISH_RESPONSE" | tail -n 1) - BODY=$(echo "$PUBLISH_RESPONSE" | sed '$d') - echo "Publish HTTP: $HTTP_CODE" - echo "Publish Response: $BODY" - STATUS=$(echo "$BODY" | grep -o '"status":\["[^"]*"\]' | head -1) - echo "Publish status: $STATUS" - if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then - echo "✅ Published to Chrome Web Store!" - else - echo "❌ Publish failed: HTTP $HTTP_CODE" - exit 1 - fi - - - name: Notify Success - if: success() - run: | - VERSION=${{ env.VERSION }} - curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ - -d "chat_id=${{ secrets.TELEGRAM_CHAT_ID }}" \ - -d "text=🚀 LexAI ${VERSION} deployed to Chrome Web Store!%0A%0A✅ Built%0A✅ Packaged%0A✅ Uploaded%0A✅ Published%0A%0Ahttps://chromewebstore.google.com/detail/${{ secrets.CWS_EXTENSION_ID }}" - - - name: Notify Failure - if: failure() - run: | - VERSION=${{ env.VERSION }} - curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ - -d "chat_id=${{ secrets.TELEGRAM_CHAT_ID }}" \ - -d "text=❌ LexAI CWS Deploy FAILED%0A%0AVersion: ${VERSION}%0A%0ACheck: https://git.juankibin.space/kibin/LexAI/actions" diff --git a/.gitea/workflows/preview.yml b/.gitea/workflows/preview.yml deleted file mode 100644 index ed46ee4..0000000 --- a/.gitea/workflows/preview.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Preview — PR Build Check - -on: - pull_request: - types: [opened, synchronize, reopened] - -jobs: - preview-build: - name: PR Preview Build - runs-on: ubuntu-latest - container: - image: node:22-bookworm - - steps: - - name: Install zip curl - run: apt-get update -qq && apt-get install -y zip curl - - - name: Checkout PR - run: | - git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git . - git fetch origin pull/${{ gitea.event.pull_request.number }}/head:pr - git checkout pr - - - name: Install dependencies - run: npm ci - working-directory: packages/chrome - - - name: Type check - run: npm run typecheck - working-directory: packages/chrome - - - name: Run unit tests - run: npm test -- --run - working-directory: packages/chrome - - - name: Build extension - run: npm run build - working-directory: packages/chrome - - - name: Package preview ZIP - run: | - PR_NUM=${{ gitea.event.pull_request.number }} - zip -r ../../lexai-pr-${PR_NUM}-preview.zip .output/chrome-mv3/ - echo "✅ PR #${PR_NUM} build successful" - working-directory: packages/chrome - - - name: Comment on PR - run: | - PR_NUM=${{ gitea.event.pull_request.number }} - curl -s -X POST "${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/issues/${PR_NUM}/comments" \ - -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ - -H "Content-Type: application/json" \ - -d "{\"body\": \"## ⚡ LexAI Preview Build Ready\n\n✅ Tests passed\n✅ Build successful\n✅ TypeScript clean\n\nCommit: \`${{ gitea.sha }}\`\"}" diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml deleted file mode 100644 index dfe43ea..0000000 --- a/.gitea/workflows/release.yml +++ /dev/null @@ -1,102 +0,0 @@ -name: Release — Package & Publish - -on: - push: - tags: - - 'v*.*.*' - -jobs: - release: - name: Build & Package Release - runs-on: ubuntu-latest - container: - image: node:22-bookworm - - steps: - - name: Install zip - run: apt-get update -qq && apt-get install -y zip curl - - - name: Checkout - run: | - git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git . - git checkout ${{ gitea.sha }} - - - name: Install dependencies - run: npm ci - working-directory: packages/chrome - - - name: Run tests - run: npm test -- --run - working-directory: packages/chrome - - - name: Build extension - run: npm run build - working-directory: packages/chrome - - - name: Package as ZIP - run: | - VERSION=${{ gitea.ref_name }} - ZIPFILE="$(cd ../.. && pwd)/lexai-chrome-mv3-${VERSION}.zip" - # Zip from inside the chrome-mv3 dir so manifest.json is at root of the archive - cd .output/chrome-mv3 && zip -r "$ZIPFILE" . && cd - - echo "ZIP_FILE=${ZIPFILE}" >> $GITHUB_ENV - working-directory: packages/chrome - - - name: Create Release - run: | - VERSION=${{ gitea.ref_name }} - cat > build-release-payload.js <<'EOF' - const fs = require('fs'); - const tag = process.env.VERSION; - const version = tag.replace(/^v/, ''); - const installSteps = '### Installation\n1. Download ZIP below\n2. Extract it\n3. Open Chrome → chrome://extensions\n4. Enable Developer Mode\n5. Click Load unpacked → select the extracted folder'; - let body = '## LexAI ' + tag + '\n\n' + installSteps; - try { - const changelog = fs.readFileSync('CHANGELOG.md', 'utf8'); - const headingRe = new RegExp('^## \\[' + version.replace(/\./g, '\\.') + '\\].*$', 'm'); - const match = headingRe.exec(changelog); - if (match) { - const rest = changelog.slice(match.index + match[0].length); - const nextStop = rest.search(/^(## \[|\[[^\]]+\]:\s)/m); - const section = (nextStop === -1 ? rest : rest.slice(0, nextStop)).trim(); - body = match[0] + '\n\n' + section + '\n\n' + installSteps; - } else { - console.error('No CHANGELOG.md section found for ' + version + ', falling back to generic body'); - } - } catch (e) { - console.error('Could not read CHANGELOG.md, falling back to generic body:', e.message); - } - const payload = { - tag_name: tag, - name: 'LexAI ' + tag, - body, - draft: false, - prerelease: false, - }; - fs.writeFileSync('payload.json', JSON.stringify(payload)); - EOF - VERSION="$VERSION" node build-release-payload.js - curl -s -X POST "${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases" \ - -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ - -H "Content-Type: application/json" \ - -d @payload.json > release.json - cat release.json - RELEASE_ID=$(node -e "const r=require('./release.json'); if(!r.id) { console.error('No release id in response:', JSON.stringify(r)); process.exit(1); } console.log(r.id)") - echo "RELEASE_ID=${RELEASE_ID}" >> $GITHUB_ENV - - - name: Upload ZIP to Release - run: | - RELEASE_ID=${{ env.RELEASE_ID }} - curl -s -X POST "${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases/${RELEASE_ID}/assets" \ - -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ - -F "attachment=@${{ env.ZIP_FILE }}" - echo "✅ Release ${{ gitea.ref_name }} published!" - - - name: Publish to Gitea Package Registry - run: | - VERSION=${{ gitea.ref_name }} - curl -s -X PUT "https://git.juankibin.space/api/packages/kibin/generic/lexai-extension/${VERSION}/lexai-chrome-mv3-${VERSION}.zip" \ - -H "Authorization: token ${{ secrets.GITEATOKEN }}" \ - -T "${{ env.ZIP_FILE }}" - echo "✅ Published lexai-chrome-mv3-${VERSION}.zip to package registry" - echo "📦 Download: https://git.juankibin.space/kibin/LexAI/packages" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cd8c23a..b4a00ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,6 +42,18 @@ Shared code lives in `src/lib/`. **Do not** import `@lib/crypto` or `@lib/messag - **VS Code:** build then F5 or Install from VSIX (`packages/vscode`). - **CLI:** set `LEXAI_API_KEY`; never commit keys or put them in `~/.lexai/config.json`. +## CI + +Gitea Actions runs one workflow per package (path-filtered): + +| Workflow | Package | +| --- | --- | +| `.gitea/workflows/ci-chrome.yml` | `packages/chrome` (+ `src/lib`, `tests`) | +| `.gitea/workflows/ci-vscode.yml` | `packages/vscode` (+ `src/lib`) | +| `.gitea/workflows/ci-cli.yml` | `packages/cli` (+ `src/lib`) | + +Deploy / preview / release workflows are not enabled yet. + ## Pull request process 1. Fork / branch from `main` (or `develop` if that is the active integration branch). diff --git a/README.md b/README.md index c27421f..0c5ebb2 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ LexAI/ ├── src/lib/ # Shared providers, actions, types ├── tests/ # Unit + e2e tests (run via chrome package) ├── docs/ # Project operating docs (agents / planning) -└── .gitea/ # CI workflows + issue/PR templates +└── .gitea/ # CI (ci-chrome / ci-vscode / ci-cli) + issue/PR templates ``` ## Supported providers diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 751b3fc..dc71677 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -4,7 +4,8 @@ ## Current state -- **Outcome:** Monorepo OSS layout — Chrome in `packages/chrome`; VS Code + CLI alongside; root LICENSE/README/CONTRIBUTING/CODE_OF_CONDUCT; Gitea issue/PR templates. -- **Verified:** run `npm run chrome:install` + typecheck/test/build after pull (session in progress). -- **CI:** workflows use `packages/chrome` for install/build/zip paths. -- **Next smallest action:** `npm run chrome:install && npm run chrome:typecheck && npm run chrome:test && npm run chrome:build` then commit when ready. +- **Outcome:** Open-source monorepo laid out — Chrome moved to `packages/chrome`; OSS docs + Gitea templates added. +- **Verified:** `chrome:typecheck` OK; `chrome:test` 64/64; `chrome:build` → `packages/chrome/.output/chrome-mv3/`. +- **Artifacts:** root `LICENSE`, `README.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`; `.gitea/ISSUE_TEMPLATE/bug_report.md`; `.gitea/PULL_REQUEST_TEMPLATE.md`; package READMEs for chrome/vscode/cli. +- **CI:** per-package workflows `ci-chrome.yml`, `ci-vscode.yml`, `ci-cli.yml` only; deploy/preview/release removed for later. +- **Next smallest action:** Commit when ready. diff --git a/docs/MEMORY.md b/docs/MEMORY.md index 4e12587..d783850 100644 --- a/docs/MEMORY.md +++ b/docs/MEMORY.md @@ -34,6 +34,7 @@ | CLI | `packages/cli/` | | OSS meta | root `README.md`, `LICENSE`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md` | | Issue/PR templates | `.gitea/ISSUE_TEMPLATE/`, `.gitea/PULL_REQUEST_TEMPLATE.md` | +| CI workflows | `.gitea/workflows/ci-{chrome,vscode,cli}.yml` (no deploy/release yet) | ## Expiring notes diff --git a/packages/chrome/vitest.config.ts b/packages/chrome/vitest.config.ts index a4363c0..f92d064 100644 --- a/packages/chrome/vitest.config.ts +++ b/packages/chrome/vitest.config.ts @@ -1,17 +1,27 @@ import { fileURLToPath } from 'node:url'; import { defineConfig } from 'vitest/config'; +const repoRoot = fileURLToPath(new URL('../..', import.meta.url)); +const libRoot = fileURLToPath(new URL('../../src/lib', import.meta.url)); +const setupFile = fileURLToPath(new URL('../../tests/unit/setup.ts', import.meta.url)); + export default defineConfig({ + root: repoRoot, resolve: { alias: { - '@lib': fileURLToPath(new URL('../../src/lib', import.meta.url)), + '@lib': libRoot, + }, + }, + server: { + fs: { + allow: [repoRoot], }, }, test: { environment: 'jsdom', globals: true, - setupFiles: ['../../tests/unit/setup.ts'], - include: ['../../tests/unit/**/*.test.ts'], - exclude: ['../../tests/e2e/**/*'], + setupFiles: [setupFile], + include: ['tests/unit/**/*.test.ts'], + exclude: ['tests/e2e/**/*', 'packages/**'], }, });