release: v1.1.0 — prompt patterns, CHANGELOG-driven release notes

- 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.
This commit is contained in:
john kevin asprec
2026-08-12 07:51:15 +08:00
parent 444060c3eb
commit 7adcb47584
8 changed files with 101 additions and 34 deletions

View File

@@ -33,40 +33,66 @@ jobs:
- name: Package as ZIP - name: Package as ZIP
run: | run: |
VERSION=${{ gitea.ref_name }} VERSION=${{ gitea.ref_name }}
zip -r lexai-chrome-mv3-${VERSION}.zip .output/chrome-mv3/ ZIPFILE="$(pwd)/lexai-chrome-mv3-${VERSION}.zip"
echo "ZIP_FILE=lexai-chrome-mv3-${VERSION}.zip" >> $GITHUB_ENV # 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 - name: Create Release
run: | run: |
VERSION=${{ gitea.ref_name }} 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" \ curl -s -X POST "${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases" \
-H "Authorization: token ${{ secrets.GITEATOKEN }}" \ -H "Authorization: token ${{ secrets.GITEATOKEN }}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d "{ -d @payload.json > release.json
\"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
cat 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)") 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 echo "RELEASE_ID=${RELEASE_ID}" >> $GITHUB_ENV
- name: Upload ZIP to Release - name: Upload ZIP to Release
run: | run: |
VERSION=${{ gitea.ref_name }}
RELEASE_ID=${{ env.RELEASE_ID }} RELEASE_ID=${{ env.RELEASE_ID }}
curl -s -X POST "${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases/${RELEASE_ID}/assets" \ curl -s -X POST "${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/releases/${RELEASE_ID}/assets" \
-H "Authorization: token ${{ secrets.GITEATOKEN }}" \ -H "Authorization: token ${{ secrets.GITEATOKEN }}" \
-F "attachment=@lexai-chrome-mv3-${VERSION}.zip" -F "attachment=@${{ env.ZIP_FILE }}"
echo "✅ Release ${VERSION} published!" echo "✅ Release ${{ gitea.ref_name }} published!"
- name: Publish to Gitea Package Registry - name: Publish to Gitea Package Registry
run: | run: |
VERSION=${{ gitea.ref_name }} VERSION=${{ gitea.ref_name }}
curl -s -X PUT "https://git.juankibin.space/api/packages/kibin/generic/lexai-extension/${VERSION}/lexai-chrome-mv3-${VERSION}.zip" \ 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 }}" \ -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 "✅ Published lexai-chrome-mv3-${VERSION}.zip to package registry"
echo "📦 Download: https://git.juankibin.space/kibin/LexAI/packages" echo "📦 Download: https://git.juankibin.space/kibin/LexAI/packages"

36
CHANGELOG.md Normal file
View File

@@ -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.

View File

@@ -115,7 +115,7 @@ Workflows live in `.gitea/workflows/`:
- `deploy-chrome.yml` — on `v*.*.*` tag: build → upload → publish to Chrome Web Store. - `deploy-chrome.yml` — on `v*.*.*` tag: build → upload → publish to Chrome Web Store.
- Both send Telegram notifications. Secrets: `GITEATOKEN`, `CWS_*`, `TELEGRAM_*`. - 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 <x.y.z> --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 <x.y.z> --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 #### When making changes

View File

@@ -68,6 +68,16 @@
- **Known weakness:** workflows `git clone` into `/tmp` and set `http.sslVerify false` (RECOMMENDATIONS #17). Revisit for speed/security. - **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 - **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 ## Open / proposed
### D-PROPOSED — Narrow host permissions from `<all_urls>` ### D-PROPOSED — Narrow host permissions from `<all_urls>`

View File

@@ -1,16 +1,10 @@
# Handoff — LexAI # Handoff — LexAI
## Handoff — 2026-08-08 ## Handoff — 2026-08-12
Outcome: done — Prompt Builder pattern work verified; in-page live hint added. Outcome: done — v1.1.0 released to `main`.
Delivered: `src/lib/actions.ts` — 12-entry `PROMPT_PATTERNS` (Direct/Reasoning/Agentic groups), "style" now "pattern". 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.
Delivered: `src/lib/providers.ts` `getSystemPrompt` — ROLE+TASK → pattern block (auto rubric or one pattern's skeleton+guard) → persona/format/style modifiers → invariants last. 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.
Delivered: `entrypoints/background.ts:71``prompt` action gets a 2048-token `maxTokens` floor (was truncating under the 1024 input-length floor). Decisions: see `docs/DECISIONS.md` new entry — release notes live in `CHANGELOG.md`; `release.yml` derives the Gitea release body from it.
Delivered: `src/lib/actions.ts` `resolvePromptPattern` — migrates legacy `promptStyle` storage values. Known risks: none new. Standing risks unchanged — T-01 (`<all_urls>` narrowing), T-02 (real key encryption) — see `docs/PROGRESS.md`.
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. Next smallest action: owner authorizes `git tag v1.1.0 && git push origin v1.1.0`, which publishes live to the Chrome Web Store.
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.

View File

@@ -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. > 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 ## 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). - 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. - 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. - 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. - 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`. - 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 ## See it yourself
@@ -21,7 +22,7 @@
| # | Decision | Options (recommended bold) | What it unblocks | | # | 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 | | 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 | | 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 | | 4 | Set gauntlet budgets on `docs/GAUNTLET.md` | **modest budget on one part first** / several at once | looping |

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "lexai", "name": "lexai",
"version": "1.0.2", "version": "1.1.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "lexai", "name": "lexai",
"version": "1.0.2", "version": "1.1.0",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@wxt-dev/module-react": "^1.1.5", "@wxt-dev/module-react": "^1.1.5",

View File

@@ -1,6 +1,6 @@
{ {
"name": "lexai", "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", "description": "A Grammarly-like Chrome Extension powered by your own LLM provider and API key",
"engines": { "engines": {
"node": ">=22" "node": ">=22"