From 7adcb47584d3e9575fd23949096a2ced47f216ef Mon Sep 17 00:00:00 2001 From: john kevin asprec Date: Wed, 12 Aug 2026 07:51:15 +0800 Subject: [PATCH] =?UTF-8?q?release:=20v1.1.0=20=E2=80=94=20prompt=20patter?= =?UTF-8?q?ns,=20CHANGELOG-driven=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Prompt Builder: 12 named patterns (Direct/Reasoning/Agentic + Auto), live per-pattern hints in popup and in-page dialog, legacy promptStyle migration, and a 2048-token floor fix so longer patterns stop getting truncated. - CHANGELOG.md added (Keep a Changelog + SemVer); release.yml now builds the Gitea release body from the matching version section, with a generic fallback, plus a zip-root fix so manifest.json sits at the archive root. - package.json/package-lock.json bumped to 1.1.0; CLAUDE.md documents the CHANGELOG-gated release process. --- .gitea/workflows/release.yml | 52 +++++++++++++++++++++++++++--------- CHANGELOG.md | 36 +++++++++++++++++++++++++ CLAUDE.md | 2 +- docs/DECISIONS.md | 10 +++++++ docs/HANDOFF.md | 20 +++++--------- docs/PROGRESS.md | 9 ++++--- package-lock.json | 4 +-- package.json | 2 +- 8 files changed, 101 insertions(+), 34 deletions(-) create mode 100644 CHANGELOG.md diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index edec6c5..eb0ba8c 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -33,40 +33,66 @@ jobs: - name: Package as ZIP run: | VERSION=${{ gitea.ref_name }} - zip -r lexai-chrome-mv3-${VERSION}.zip .output/chrome-mv3/ - echo "ZIP_FILE=lexai-chrome-mv3-${VERSION}.zip" >> $GITHUB_ENV + ZIPFILE="$(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 - 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 "{ - \"tag_name\": \"${VERSION}\", - \"name\": \"LexAI ${VERSION}\", - \"body\": \"## LexAI ${VERSION}\n\n### 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\", - \"draft\": false, - \"prerelease\": false - }" > release.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: | - VERSION=${{ gitea.ref_name }} 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=@lexai-chrome-mv3-${VERSION}.zip" - echo "✅ Release ${VERSION} published!" + -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 lexai-chrome-mv3-${VERSION}.zip + -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/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..36cca9c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,36 @@ +# Changelog + +All notable changes to LexAI are documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.1.0] — 2026-08-12 + +### Added +- Prompt Builder now offers 12 prompting patterns including Auto, grouped into Direct / Reasoning / Agentic — each with a plain-English hint shown under the dropdown, in both the popup's Prompt tab and the in-page "Make Prompt" dialog. + +### Fixed +- Long patterns (Few-shot Examples, ReAct) were being cut off by the response token limit; the `prompt` action now gets a 2048-token floor so full examples and step budgets come through. + +### Changed +- Patterns saved before this update migrate automatically — legacy `promptStyle` values resolve to the new pattern ids, so nothing needs to be redone. + +## [1.0.2] — 2026-07-23 + +### Fixed +- A stored API key carried no record of which provider it belonged to, so switching providers in Options could leave the previous provider's key attached to the new one — every call then failed with that provider's "Invalid API Key" while the UI still showed a key as configured. Saving now stamps the key with its provider and requires a new key if the saved one belongs to a different provider or was rejected. + +## [1.0.1] — 2026-07-15 + +### Added +- Prompt Builder: a new tab in the popup for generating AI prompts, with configurable style, persona, format, and model. +- Live model list per provider, fetched from the provider instead of hard-coded. +- Legacy plaintext API keys stored before the encrypted-key path migrate automatically. + +## [1.0.0] — 2026-03-11 + +### Added +- Initial public release: select text on any page → fix grammar, rephrase, shorten, expand, or explain → Replace or Copy, powered by your own OpenAI/Anthropic/Groq/OpenRouter API key. +- Writing style selector available from the toolbar, popup, and right-click context menu. +- Copy As and Download actions, plus a request timeout so calls to slow providers fail cleanly instead of hanging. diff --git a/CLAUDE.md b/CLAUDE.md index f2cd5e4..e3dc298 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -115,7 +115,7 @@ Workflows live in `.gitea/workflows/`: - `deploy-chrome.yml` — on `v*.*.*` tag: build → upload → publish to Chrome Web Store. - Both send Telegram notifications. Secrets: `GITEATOKEN`, `CWS_*`, `TELEGRAM_*`. -**Version bumps:** edit `version` in `package.json` only — `wxt.config.ts` reads `pkg.version`, so the manifest follows automatically (T-16 done). Use `npm version --no-git-tag-version` so `package-lock.json` stays in sync. A `v*.*.*` git tag triggers the store deploy **and publishes it live** (`deploy-chrome.yml:91`). +**Version bumps:** edit `version` in `package.json` only — `wxt.config.ts` reads `pkg.version`, so the manifest follows automatically (T-16 done). Use `npm version --no-git-tag-version` so `package-lock.json` stays in sync. A `v*.*.*` git tag triggers the store deploy **and publishes it live** (`deploy-chrome.yml:91`). A version bump is not done until `CHANGELOG.md` has that version's section — `release.yml` builds the Gitea release body from it. #### When making changes diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md index 91dfa51..99dfd13 100644 --- a/docs/DECISIONS.md +++ b/docs/DECISIONS.md @@ -68,6 +68,16 @@ - **Known weakness:** workflows `git clone` into `/tmp` and set `http.sslVerify false` (RECOMMENDATIONS #17). Revisit for speed/security. - **Owner / date:** Phase 1, 2026-03-06 +### D-2026-08-12-08 — CHANGELOG.md drives Gitea release notes + +- **Status:** accepted +- **Context:** Releases previously shipped a hardcoded release body (`## LexAI ${VERSION}` + generic install steps) that never said what actually changed in that version. +- **Decision:** Release notes live in `CHANGELOG.md` (Keep a Changelog format, Semantic Versioning). `.gitea/workflows/release.yml` extracts the section matching the pushed tag's version and uses it as the Gitea release body, with a generic fallback if no matching section exists. A version bump is not considered done until `CHANGELOG.md` has that version's section. +- **Alternatives considered:** Auto-generating notes from commit messages (rejected: commit history is not curated for user-facing wording); keeping the hardcoded body (rejected: uninformative to installers). +- **Consequences:** Every version bump now requires a `CHANGELOG.md` entry alongside the `package.json` bump; the release workflow degrades gracefully (generic body + logged warning) if that entry is missed rather than failing the release. +- **Verification:** `release.yml` reviewed by an independent critic; P2 findings fixed. Confirmed locally that the section-extraction logic matches `## [1.1.0]` and stops at the next `## [` heading. +- **Owner / date:** 2026-08-12 + ## Open / proposed ### D-PROPOSED — Narrow host permissions from `` diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 4fd04ac..898ca46 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -1,16 +1,10 @@ # Handoff — LexAI -## Handoff — 2026-08-08 +## Handoff — 2026-08-12 -Outcome: done — Prompt Builder pattern work verified; in-page live hint added. -Delivered: `src/lib/actions.ts` — 12-entry `PROMPT_PATTERNS` (Direct/Reasoning/Agentic groups), "style" now "pattern". -Delivered: `src/lib/providers.ts` `getSystemPrompt` — ROLE+TASK → pattern block (auto rubric or one pattern's skeleton+guard) → persona/format/style modifiers → invariants last. -Delivered: `entrypoints/background.ts:71` — `prompt` action gets a 2048-token `maxTokens` floor (was truncating under the 1024 input-length floor). -Delivered: `src/lib/actions.ts` `resolvePromptPattern` — migrates legacy `promptStyle` storage values. -Delivered: `entrypoints/content.ts:722-733` — in-page dialog now shows the live per-pattern hint (popup already had it); updates on select `change` and after storage prefill. -Verified: `npm run typecheck` — clean. -Verified: `npm test -- --run` — 64 tests, 4 files, all passing. -Verified: `npm run build` — `.output/chrome-mv3/` built, no errors. -Decisions: none new this session. -Known risks: real-page load-unpacked check still outstanding — this is the owner's gate (see `docs/PROGRESS.md`). -Next smallest action: load `.output/chrome-mv3` unpacked and confirm the Pattern dropdown + hint render correctly in both popup and in-page dialog, and a saved pattern preselects. +Outcome: done — v1.1.0 released to `main`. +Shipped: Prompt Builder pattern upgrade (12 patterns, live hints, migration, token-floor fix — from the 2026-08-08 session); `CHANGELOG.md` (Keep a Changelog format); `.gitea/workflows/release.yml` now builds the Gitea release body from the matching `CHANGELOG.md` section (generic fallback if absent) and fixes the zip so `manifest.json` sits at the archive root; `package.json`/`package-lock.json` bumped to 1.1.0; one `CLAUDE.md` line documenting the CHANGELOG-gated release process. +Verified: `npm run typecheck` clean; `npm test -- --run` 64/64 passing; `npm run build` OK; `.output/chrome-mv3/manifest.json` version = 1.1.0; zip at `.output/lexai-1.1.0-chrome.zip`; owner did the load-unpacked real-page check (Prompt dropdown/hint, patterns, migration all confirmed) — closes the item that was open in the prior handoff. Independent critic reviewed the `release.yml` edit; its P2 findings were fixed before merge. +Decisions: see `docs/DECISIONS.md` new entry — release notes live in `CHANGELOG.md`; `release.yml` derives the Gitea release body from it. +Known risks: none new. Standing risks unchanged — T-01 (`` narrowing), T-02 (real key encryption) — see `docs/PROGRESS.md`. +Next smallest action: owner authorizes `git tag v1.1.0 && git push origin v1.1.0`, which publishes live to the Chrome Web Store. diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index df04a82..97cef48 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -2,14 +2,15 @@ > For the owner. What works, how to see it, and what's waiting on you — plain language, no agent jargon. Refreshed at every phase seal and session end. `HANDOFF.md` speaks to the next agent; this page speaks to you. -**Updated:** 2026-08-08 · **Overall:** working MV3 extension (Phase 1 + the 2026-07 fix wave + the Prompt Builder pattern upgrade); operating system on the gauntlet-loop/opus kit (2026-08-07 audit revision). +**Updated:** 2026-08-12 · **Overall:** v1.1.0 released to `main` (Phase 1 + the 2026-07 fix wave + the Prompt Builder pattern upgrade + CHANGELOG-driven release notes); operating system on the gauntlet-loop/opus kit (2026-08-07 audit revision). ## What works now -- The extension itself: selection → floating toolbar → fix/rephrase/shorten/expand/explain/prompt → Replace or Copy; four providers (OpenAI/Anthropic/Groq/OpenRouter); encrypted BYO key; Options with live model listing; 64/64 unit tests, typecheck and build green (2026-08-08). -- Prompt Builder now offers 12 named prompting patterns (grouped Direct / Reasoning / Agentic, plus "Auto"), each with a plain-English hint shown under the dropdown — in both the popup's Prompt tab and the in-page "Make Prompt" dialog you get from selecting text. +- The extension itself: selection → floating toolbar → fix/rephrase/shorten/expand/explain/prompt → Replace or Copy; four providers (OpenAI/Anthropic/Groq/OpenRouter); encrypted BYO key; Options with live model listing; 64/64 unit tests, typecheck and build green (2026-08-12). +- Prompt Builder now offers 12 named prompting patterns (grouped Direct / Reasoning / Agentic, plus "Auto"), each with a plain-English hint shown under the dropdown — in both the popup's Prompt tab and the in-page "Make Prompt" dialog you get from selecting text. Owner-verified by load-unpacked check. - Patterns like Few-shot Examples and ReAct now produce properly structured output (example blocks, step budgets) without getting cut off — a token-limit bug that truncated longer prompt patterns is fixed. - Any pattern you'd saved before this update carries over automatically — nothing to redo. +- Releases now write real release notes: `CHANGELOG.md` tracks what shipped per version, and the Gitea release workflow pulls the matching section into the release body automatically when a version tag is pushed (falls back to a generic body if a section is missing). - The agent operating system: upgraded from the older fable kit — 13 specialists (incl. your custom `lexai-extension-dev`, kept and modernized) + 4 new ones (ux-ui-designer, ux-psychologist, and the fresh-eyes `gauntlet-critic` referee), 12 skills, all your lessons and security-auditor memory preserved. Lead is now `claude --agent opus-orchestrator`. ## See it yourself @@ -21,7 +22,7 @@ | # | Decision | Options (recommended bold) | What it unblocks | | --- | --- | --- | --- | -| 1 | Load-unpacked check of the Prompt Builder pattern upgrade: (a) grouped Pattern dropdown + hint shows in both the popup Prompt tab and the in-page dialog, (b) picking "Few-shot Examples" gives a prompt with example blocks and "ReAct (tools)" gives one with a step budget and a final-answer marker, neither cut off, (c) a pattern you'd saved before still shows selected | **do the 5-min check** / report it already done | closes this update's verification loop — nothing else is blocked meanwhile | +| 1 | Authorize the live Chrome Web Store publish for v1.1.0: `git tag v1.1.0 && git push origin v1.1.0` fires `deploy-chrome.yml` and publishes live | **tag now** / hold | the store listing goes live on v1.1.0 — nothing else is blocked meanwhile | | 2 | Supply reference-bar artifacts (screenshots/recording of Grammarly or your chosen benchmark → `docs/reference/`) | **Grammarly toolbar + card screenshots** / pick another benchmark / defer gauntlets | UI gauntlet rounds | | 3 | Approve the Replace-reliability site matrix in `docs/REFERENCE_BAR.md` (Gmail, GitHub, X, LinkedIn, Google Docs?, Reddit, Notion) | **approve as listed (Docs out of scope)** / edit the list | the behavioral gauntlet — can start without screenshots | | 4 | Set gauntlet budgets on `docs/GAUNTLET.md` | **modest budget on one part first** / several at once | looping | diff --git a/package-lock.json b/package-lock.json index 67b5cf5..3a96cd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "lexai", - "version": "1.0.2", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "lexai", - "version": "1.0.2", + "version": "1.1.0", "hasInstallScript": true, "dependencies": { "@wxt-dev/module-react": "^1.1.5", diff --git a/package.json b/package.json index 9a906f1..9019aa6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lexai", - "version": "1.0.2", + "version": "1.1.0", "description": "A Grammarly-like Chrome Extension powered by your own LLM provider and API key", "engines": { "node": ">=22"