diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 00000000..190a17f3 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,59 @@ +# Releasing OpenLess + +This document defines who may cut releases and how. It is policy, not a how-to for +day-to-day development. + +## Authority: admins only + +**Only repository administrators may create version tags and publish releases.** + +- Only an admin may create a release tag (`v*-tauri`) or publish a GitHub Release. +- Contributors (including AI agents) **must not** create release tags, publish + releases, or trigger release automation. If a release is needed, **request an admin + to cut it** — open an issue or ping a maintainer with the target version and the + channel (Beta or Stable). +- Release automation (CI workflows that build, sign, and publish artifacts, and the + auto-updater feed) must be **admin-triggered only**. Tag-triggered pipelines are + considered admin-triggered because only admins may push the triggering tag. + +## Channels and tags + +Two channels; the branch name equals the channel name: + +- **`beta`** — default development branch and the Beta channel. +- **`main`** — the Stable channel (正式版). Always releasable; only maintainers merge + `beta → main`. + +Release tags (created by an admin only): + +- **Stable release:** push tag `v-tauri`. +- **Beta release:** push tag `v-beta-tauri` (published as a GitHub + pre-release; never auto-updates Stable users). + +## Version-sync gate + +A release fails CI unless **five** files carry the same version. Bump them together +with `1-app/scripts/bump-version.sh `: + +- `openless-all/app/package.json` +- `openless-all/app/package-lock.json` (root and nested `packages.""`) +- `openless-all/app/src-tauri/tauri.conf.json` +- `openless-all/app/src-tauri/Cargo.toml` +- `openless-all/app/src-tauri/Cargo.lock` (the `name = "openless"` block) + +The script takes a plain `X.Y.Z`; for a `-beta` suffix, edit the files by hand. + +## Pre-release checklist (for the admin cutting the release) + +1. Branch is the intended channel (`beta` for Beta, `main` for Stable). +2. All five version files match (version-sync gate green). +3. CI is green on the commit being tagged. +4. Then, and only then, push the release tag. + +## Process summary + +1. Land work on `beta` via PRs (open PRs against `beta`, never `main`). +2. For a Stable release, a maintainer merges `beta → main`. +3. An **admin** bumps the version (five-file sync), verifies CI is green, and pushes + the release tag — which is the only thing that triggers the publish/auto-update + pipeline. diff --git a/docs/superpowers/plans/2026-06-05-openless-aura-skin.md b/docs/superpowers/plans/2026-06-05-openless-aura-skin.md deleted file mode 100644 index 97ebb636..00000000 --- a/docs/superpowers/plans/2026-06-05-openless-aura-skin.md +++ /dev/null @@ -1,541 +0,0 @@ -# OpenLess Aura Skin Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Apply an Aura-inspired visual skin to OpenLess by upgrading the shell, glass treatment, radii, typography, and overview surfaces while preserving the current information architecture and page density. - -**Architecture:** The implementation stays shallow and visual-only. It starts by adding a contract test that defines the new skin hooks, then updates global tokens and chrome, then reskins the main shell and settings modal, and finally aligns shared atoms and the overview page to the new surface system. - -**Tech Stack:** React 18, TypeScript, Vite 5, inline-style component patterns, CSS token files, Node-based contract checks - ---- - -## File Structure - -- Modify: `openless-all/app/package.json` - Purpose: register a repeatable Aura skin contract check command. -- Create: `openless-all/app/scripts/aura-skin-contract.test.mjs` - Purpose: assert the new skin tokens and shell hooks exist before visual work is considered complete. -- Modify: `openless-all/app/src/styles/tokens.css` - Purpose: replace the current light-glass token ladder with the new Aura-inspired radii, surfaces, shadows, and typography. -- Modify: `openless-all/app/src/styles/global.css` - Purpose: add the static layered background and shared shell/panel helper classes without introducing animation. -- Modify: `openless-all/app/src/components/FloatingShell.tsx` - Purpose: reskin the app shell, sidebar, version zone, and main console wrapper. -- Modify: `openless-all/app/src/components/SettingsModal.tsx` - Purpose: align the settings modal shell and left rail with the new skin system. -- Modify: `openless-all/app/src/pages/_atoms.tsx` - Purpose: make cards, buttons, pills, and page headers inherit the new radius and surface vocabulary. -- Modify: `openless-all/app/src/pages/Overview.tsx` - Purpose: make the overview page visibly match the new shell without changing its data structure. - -### Task 1: Add Aura Skin Contract Check - -**Files:** -- Create: `openless-all/app/scripts/aura-skin-contract.test.mjs` -- Modify: `openless-all/app/package.json` -- Test: `openless-all/app/scripts/aura-skin-contract.test.mjs` - -- [ ] **Step 1: Write the failing test** - -Create `openless-all/app/scripts/aura-skin-contract.test.mjs`: - -```js -import { readFile } from 'node:fs/promises'; -import assert from 'node:assert/strict'; - -const root = new URL('../', import.meta.url); - -async function read(relPath) { - return readFile(new URL(relPath, root), 'utf8'); -} - -const [tokens, globalCss, shell, settingsModal, overview] = await Promise.all([ - read('src/styles/tokens.css'), - read('src/styles/global.css'), - read('src/components/FloatingShell.tsx'), - read('src/components/SettingsModal.tsx'), - read('src/pages/Overview.tsx'), -]); - -assert.match(tokens, /--ol-shell-radius:/, 'tokens.css must define --ol-shell-radius'); -assert.match(tokens, /--ol-panel-radius:/, 'tokens.css must define --ol-panel-radius'); -assert.match(tokens, /--ol-aura-shadow:/, 'tokens.css must define --ol-aura-shadow'); -assert.match(tokens, /--ol-font-display:/, 'tokens.css must define --ol-font-display'); - -assert.match(globalCss, /\.ol-app-shell-bg\b/, 'global.css must expose .ol-app-shell-bg'); -assert.match(globalCss, /\.ol-aura-panel\b/, 'global.css must expose .ol-aura-panel'); -assert.doesNotMatch(globalCss, /@keyframes ol-aura-halo/, 'global.css must not add an animated halo'); - -assert.match(shell, /ol-app-shell-bg/, 'FloatingShell must use the app shell background class'); -assert.match(shell, /ol-aura-sidebar/, 'FloatingShell must expose an Aura sidebar hook'); -assert.match(shell, /ol-aura-panel/, 'FloatingShell must expose an Aura panel hook'); - -assert.match(settingsModal, /ol-aura-settings/, 'SettingsModal must expose an Aura settings wrapper'); -assert.match(overview, /ol-overview-hero/, 'Overview must expose a high-visibility overview surface hook'); - -console.log('Aura skin contract OK'); -``` - -- [ ] **Step 2: Register the check in `package.json`** - -Modify `openless-all/app/package.json`: - -```json -{ - "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "preview": "vite preview", - "tauri": "tauri", - "check:aura-skin": "node scripts/aura-skin-contract.test.mjs", - "check:macos-capsule-spaces": "node scripts/macos-capsule-spaces-contract.test.mjs", - "check:hotkey-injection": "node scripts/check-hotkey-injection.mjs" - } -} -``` - -- [ ] **Step 3: Run the test to verify it fails** - -Run: - -```bash -npm run check:aura-skin -``` - -Expected: - -```text -AssertionError [ERR_ASSERTION]: tokens.css must define --ol-shell-radius -``` - -- [ ] **Step 4: Commit the failing test harness** - -```bash -git add openless-all/app/package.json openless-all/app/scripts/aura-skin-contract.test.mjs -git commit -m "test: add aura skin contract" -``` - -### Task 2: Replace Global Tokens and App Chrome - -**Files:** -- Modify: `openless-all/app/src/styles/tokens.css` -- Modify: `openless-all/app/src/styles/global.css` -- Test: `openless-all/app/scripts/aura-skin-contract.test.mjs` - -- [ ] **Step 1: Update the token ladder** - -Replace the current token center in `openless-all/app/src/styles/tokens.css` with the Aura skin ladder: - -```css -:root { - --ol-bg-base: #f3f4f6; - --ol-bg-elevated: #fbfbfc; - --ol-surface: rgba(255, 255, 255, 0.72); - --ol-surface-2: rgba(255, 255, 255, 0.88); - --ol-surface-solid: #ffffff; - - --ol-line: rgba(15, 23, 42, 0.08); - --ol-line-strong: rgba(15, 23, 42, 0.14); - --ol-line-soft: rgba(255, 255, 255, 0.55); - - --ol-ink: #10131a; - --ol-ink-2: #222938; - --ol-ink-3: rgba(16, 19, 26, 0.64); - --ol-ink-4: rgba(16, 19, 26, 0.42); - --ol-ink-5: rgba(16, 19, 26, 0.24); - - --ol-blue: #2f6df6; - --ol-blue-hover: #2458c8; - --ol-blue-soft: rgba(47, 109, 246, 0.10); - --ol-blue-ring: rgba(47, 109, 246, 0.22); - - --ol-shell-radius: 32px; - --ol-panel-radius: 28px; - --ol-card-radius: 22px; - --ol-pill-radius: 999px; - - --ol-aura-shadow: 0 24px 80px -32px rgba(15, 23, 42, 0.24), 0 12px 36px -18px rgba(15, 23, 42, 0.12); - --ol-aura-shadow-soft: 0 10px 30px -18px rgba(15, 23, 42, 0.16), 0 0 0 0.5px rgba(255, 255, 255, 0.55) inset; - - --ol-font-display: "Aptos", "Segoe UI Variable Display", "PingFang SC", "Microsoft YaHei", sans-serif; - --ol-font-sans: "Aptos", "Segoe UI Variable Text", "PingFang SC", "Microsoft YaHei", sans-serif; - --ol-font-mono: "JetBrains Mono", "SF Mono", "Cascadia Code", Consolas, monospace; -} -``` - -- [ ] **Step 2: Add static Aura shell helpers** - -Append shared helpers to `openless-all/app/src/styles/global.css`: - -```css -body { - background: - radial-gradient(circle at 18% 12%, rgba(255, 255, 255, 0.92), rgba(255, 255, 255, 0) 34%), - radial-gradient(circle at 86% 18%, rgba(47, 109, 246, 0.08), rgba(47, 109, 246, 0) 30%), - linear-gradient(180deg, #f6f7fa 0%, #eef1f6 100%); - color: var(--ol-ink); -} - -.ol-app-shell-bg { - background: - radial-gradient(circle at top left, rgba(255, 255, 255, 0.68), rgba(255, 255, 255, 0) 38%), - linear-gradient(180deg, rgba(255, 255, 255, 0.68), rgba(245, 247, 251, 0.58)); -} - -.ol-aura-panel { - background: var(--ol-surface); - backdrop-filter: blur(24px) saturate(150%); - -webkit-backdrop-filter: blur(24px) saturate(150%); - border: 1px solid rgba(255, 255, 255, 0.58); - box-shadow: var(--ol-aura-shadow); -} - -.ol-aura-card { - background: linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(252, 252, 253, 0.82)); - border: 1px solid rgba(255, 255, 255, 0.74); - box-shadow: var(--ol-aura-shadow-soft); -} -``` - -- [ ] **Step 3: Run the contract check** - -Run: - -```bash -npm run check:aura-skin -``` - -Expected: - -```text -AssertionError [ERR_ASSERTION]: FloatingShell must use the app shell background class -``` - -- [ ] **Step 4: Commit the token/chrome layer** - -```bash -git add openless-all/app/src/styles/tokens.css openless-all/app/src/styles/global.css -git commit -m "feat: add aura skin tokens and chrome" -``` - -### Task 3: Reskin the Shell and Settings Modal - -**Files:** -- Modify: `openless-all/app/src/components/FloatingShell.tsx` -- Modify: `openless-all/app/src/components/SettingsModal.tsx` -- Test: `openless-all/app/scripts/aura-skin-contract.test.mjs` - -- [ ] **Step 1: Apply Aura shell hooks in `FloatingShell.tsx`** - -Update the shell wrappers in `openless-all/app/src/components/FloatingShell.tsx`: - -```tsx -
-``` - -Update the sidebar and main panel wrappers: - -```tsx -