clarity-theme 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +276 -0
- package/README.zh-CN.md +297 -0
- package/app/app.config.ts +110 -0
- package/app/app.vue +5 -0
- package/app/assets/css/_variable.scss +8 -0
- package/app/assets/css/animation.scss +50 -0
- package/app/assets/css/article.scss +152 -0
- package/app/assets/css/color.scss +58 -0
- package/app/assets/css/font.scss +35 -0
- package/app/assets/css/main.scss +230 -0
- package/app/assets/css/reusable.scss +186 -0
- package/app/assets/icons/solar-rewind-back-bold-duotone.svg +1 -0
- package/app/assets/icons/solar-rewind-forward-bold-duotone.svg +1 -0
- package/app/components/blog/BlogAside.vue +63 -0
- package/app/components/blog/BlogFooter.vue +61 -0
- package/app/components/blog/BlogHeader.global.vue +146 -0
- package/app/components/blog/BlogPanel.vue +79 -0
- package/app/components/blog/BlogSidebar.vue +160 -0
- package/app/components/blog/BlogWidget.vue +134 -0
- package/app/components/blog/Mask.vue +42 -0
- package/app/components/blog/SkipToContent.vue +22 -0
- package/app/components/blog/ThemeToggle.vue +50 -0
- package/app/components/content/Alert.vue +96 -0
- package/app/components/content/Badge.vue +90 -0
- package/app/components/content/Blur.vue +22 -0
- package/app/components/content/CardList.vue +32 -0
- package/app/components/content/Chat.vue +79 -0
- package/app/components/content/Copy.vue +134 -0
- package/app/components/content/EmojiClock.vue +53 -0
- package/app/components/content/FeedCard.vue +212 -0
- package/app/components/content/FeedGroup.vue +130 -0
- package/app/components/content/Folding.vue +69 -0
- package/app/components/content/Key.vue +164 -0
- package/app/components/content/LinkBanner.vue +59 -0
- package/app/components/content/LinkCard.vue +74 -0
- package/app/components/content/MdTitle.vue +26 -0
- package/app/components/content/Mermaid.vue +133 -0
- package/app/components/content/MusicScore.vue +178 -0
- package/app/components/content/Pic.vue +55 -0
- package/app/components/content/Poetry.vue +41 -0
- package/app/components/content/ProseA.vue +40 -0
- package/app/components/content/ProseCode.vue +95 -0
- package/app/components/content/ProsePre.vue +291 -0
- package/app/components/content/ProseTable.vue +70 -0
- package/app/components/content/Quote.vue +51 -0
- package/app/components/content/Tab.vue +100 -0
- package/app/components/content/Timeline.vue +73 -0
- package/app/components/content/Tip.vue +52 -0
- package/app/components/content/VideoEmbed.vue +127 -0
- package/app/components/partial/Button.vue +98 -0
- package/app/components/partial/DlGroup.vue +69 -0
- package/app/components/partial/Dropdown.vue +54 -0
- package/app/components/partial/Error.vue +70 -0
- package/app/components/partial/Expand.vue +51 -0
- package/app/components/partial/IconNavList.vue +42 -0
- package/app/components/partial/Pagination.vue +113 -0
- package/app/components/partial/RadioGroup.vue +77 -0
- package/app/components/partial/Secret.vue +23 -0
- package/app/components/partial/Slider.vue +96 -0
- package/app/components/partial/Toggle.vue +70 -0
- package/app/components/popover/Lightbox.vue +77 -0
- package/app/components/popover/Search.vue +214 -0
- package/app/components/popover/SearchItem.vue +64 -0
- package/app/components/post/Archive.vue +104 -0
- package/app/components/post/Article.vue +138 -0
- package/app/components/post/Comment.vue +275 -0
- package/app/components/post/Excerpt.vue +66 -0
- package/app/components/post/OrderToggle.vue +101 -0
- package/app/components/post/PostFooter.vue +80 -0
- package/app/components/post/PostHeader.vue +147 -0
- package/app/components/post/PostSurround.vue +111 -0
- package/app/components/post/Slide.vue +215 -0
- package/app/components/util/Date.vue +62 -0
- package/app/components/util/HydrateSafe.vue +10 -0
- package/app/components/util/Img.vue +38 -0
- package/app/components/util/Link.vue +11 -0
- package/app/components/widget/BlogLog.vue +27 -0
- package/app/components/widget/BlogStats.vue +39 -0
- package/app/components/widget/BlogTech.vue +65 -0
- package/app/components/widget/Empty.vue +3 -0
- package/app/components/widget/Toc.vue +129 -0
- package/app/composables/useArticle.ts +118 -0
- package/app/composables/useAvoid.ts +87 -0
- package/app/composables/useCopy.ts +21 -0
- package/app/composables/usePagination.ts +70 -0
- package/app/composables/useShiki.ts +129 -0
- package/app/composables/useToc.ts +57 -0
- package/app/composables/useWidgets.ts +56 -0
- package/app/error.vue +34 -0
- package/app/layouts/default.vue +66 -0
- package/app/pages/[...slug].vue +59 -0
- package/app/pages/archive.vue +207 -0
- package/app/pages/index.vue +83 -0
- package/app/pages/link.vue +65 -0
- package/app/pages/preview.vue +59 -0
- package/app/plugins/easter-egg.ts +23 -0
- package/app/plugins/init.ts +6 -0
- package/app/plugins/tippy.ts +22 -0
- package/app/shiki.config.ts +8 -0
- package/app/stores/layout.ts +34 -0
- package/app/stores/search.ts +37 -0
- package/app/types/article.ts +16 -0
- package/app/types/feed.ts +1 -0
- package/app/types/index.ts +14 -0
- package/app/types/modal.ts +16 -0
- package/app/types/nav.ts +11 -0
- package/app/utils/anim.ts +37 -0
- package/app/utils/img.ts +83 -0
- package/config/app.ts +88 -0
- package/config/content.d.mts +1 -0
- package/config/content.mjs +69 -0
- package/config/content.ts +91 -0
- package/config/define.mjs +21 -0
- package/config/define.ts +23 -0
- package/config/feed.ts +42 -0
- package/config/feeds.empty.ts +4 -0
- package/config/index.d.mts +1 -0
- package/config/index.mjs +6 -0
- package/config/index.ts +6 -0
- package/config/public.ts +71 -0
- package/config/schema.d.mts +1 -0
- package/config/schema.mjs +103 -0
- package/config/schema.ts +129 -0
- package/config/server.ts +35 -0
- package/img/index.d.mts +1 -0
- package/img/index.mjs +78 -0
- package/img/index.ts +8 -0
- package/modules/clarity-config/anti-mirror-client.ts +11 -0
- package/modules/clarity-config/index.ts +324 -0
- package/nuxt.config.ts +225 -0
- package/package.json +148 -0
- package/public/assets/atom.css +274 -0
- package/public/assets/atom.xsl +110 -0
- package/public/fonts/AlimamaFangYuanTi.woff2 +0 -0
- package/remark-plugins/rehype-meta-slots.d.mts +1 -0
- package/remark-plugins/rehype-meta-slots.mjs +49 -0
- package/remark-plugins/rehype-meta-slots.ts +58 -0
- package/remark-plugins/remark-code-component.d.mts +1 -0
- package/remark-plugins/remark-code-component.mjs +25 -0
- package/remark-plugins/remark-code-component.ts +41 -0
- package/server/api/stats.get.ts +109 -0
- package/server/routes/atom.xml.get.ts +101 -0
- package/server/routes/subscriptions.opml.get.ts +70 -0
- package/server/utils/clarity.ts +11 -0
- package/shared/types/content.ts +30 -0
- package/shared/utils/clarity.ts +34 -0
- package/shared/utils/icon.ts +218 -0
- package/shared/utils/link.ts +52 -0
- package/shared/utils/str.ts +88 -0
- package/shared/utils/time.ts +116 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Zhilu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# Clarity Theme
|
|
2
|
+
|
|
3
|
+
**English** | [简体中文](./README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
Clarity Theme is a reusable **Nuxt 4 Layer blog theme** extracted from [L33Z22L11/blog-v3](https://github.com/L33Z22L11/blog-v3). It provides the generic blog UI, page structure, Markdown/MDC rendering, SEO integration, and feed/server outputs; your project provides all site data and content.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Nuxt 4 Layer installation through one `extends` entry
|
|
10
|
+
- Validated site configuration with defaults and strict unknown-field rejection
|
|
11
|
+
- Nuxt Content collection factory for article metadata and sitemap data
|
|
12
|
+
- Markdown, MDC components, Shiki code highlighting, KaTeX, Mermaid, ABC music scores, and rich images
|
|
13
|
+
- Article list, archive, pagination, TOC, search, theme toggle, widgets, preview, and 404 routing
|
|
14
|
+
- Atom, OPML, statistics, robots, sitemap, and LLMs outputs
|
|
15
|
+
- Twikoo, head scripts, and anti-mirror integrations driven by consumer configuration
|
|
16
|
+
- UI defaults, app config overrides, custom Shiki themes, and same-path component overrides
|
|
17
|
+
- Automated workspace, tarball-consumer, SSR, browser, hydration, purity, contract, peer, and upstream-sync checks
|
|
18
|
+
|
|
19
|
+
## Requirements
|
|
20
|
+
|
|
21
|
+
| Runtime | Version |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| Node.js | `^22.19 \|\| ^24.11 \|\| >=26` |
|
|
24
|
+
| pnpm | 12.4.1 or a compatible package manager for your project |
|
|
25
|
+
| Nuxt peer | `^4.5.2` |
|
|
26
|
+
| Vue peer | `^3.5.42` |
|
|
27
|
+
|
|
28
|
+
The package is not currently available from the npm registry. Install it as a Git dependency pinned to a reviewed commit until the first package release is published. Clarity is part of your application runtime, so install it as a regular dependency rather than a development dependency.
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add github:iicemeta/clarity-theme#<commit>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
### 1. Extend the Layer
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
// nuxt.config.ts
|
|
42
|
+
export default defineNuxtConfig({
|
|
43
|
+
extends: ['clarity-theme'],
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Define site configuration
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
// clarity.config.ts
|
|
51
|
+
import { defineClarityConfig } from 'clarity-theme/config'
|
|
52
|
+
|
|
53
|
+
export default defineClarityConfig({
|
|
54
|
+
site: {
|
|
55
|
+
title: 'My Blog',
|
|
56
|
+
description: 'Notes about technology and life',
|
|
57
|
+
url: 'https://example.com/',
|
|
58
|
+
author: {
|
|
59
|
+
name: 'My Name',
|
|
60
|
+
avatar: '/avatar.webp',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`site.title`, `site.description`, `site.url`, and `site.author.name` are required. Article, feed, stats, integration, feature, and changelog groups are optional and receive documented defaults.
|
|
67
|
+
|
|
68
|
+
### 3. Create the Content schema
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
// content.config.ts
|
|
72
|
+
import { createClarityContentConfig } from 'clarity-theme/content'
|
|
73
|
+
import clarityConfig from './clarity.config'
|
|
74
|
+
|
|
75
|
+
export default createClarityContentConfig(clarityConfig)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Place articles under `content/posts/` and other Content pages under `content/`.
|
|
79
|
+
|
|
80
|
+
### 4. Optionally provide friend data
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
// feeds.ts
|
|
84
|
+
import type { FeedGroup } from 'clarity-theme/config'
|
|
85
|
+
|
|
86
|
+
export default [] satisfies FeedGroup[]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Without this file, the friend page and OPML output use empty data and the build logs a warning.
|
|
90
|
+
|
|
91
|
+
### 5. Generate or develop
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pnpm dev
|
|
95
|
+
pnpm generate
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
For a complete walkthrough from an existing blog-v3 project, see [Migration](./docs/MIGRATION.md). Theme data and user content are deliberately separate: the package never carries your articles, friend links, redirects, deployment settings, or package patches.
|
|
99
|
+
|
|
100
|
+
## Basic Configuration
|
|
101
|
+
|
|
102
|
+
| File | Responsibility |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| `clarity.config.ts` | Site identity, article semantics, feeds, stats, integrations, feature flags, changelog |
|
|
105
|
+
| `app/app.config.ts` | Optional reactive UI overrides only |
|
|
106
|
+
| `content.config.ts` | Nuxt Content collection/schema |
|
|
107
|
+
| `feeds.ts` | Optional friend data |
|
|
108
|
+
| consumer `runtimeConfig` | Environment-specific values and the only valid place for secrets |
|
|
109
|
+
|
|
110
|
+
Field-by-field defaults, visibility, and examples are documented in [Configuration](./docs/CONFIGURATION.md).
|
|
111
|
+
|
|
112
|
+
Example optional groups:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
export default defineClarityConfig({
|
|
116
|
+
site: {
|
|
117
|
+
title: 'My Blog',
|
|
118
|
+
description: 'A Nuxt blog',
|
|
119
|
+
url: 'https://example.com/',
|
|
120
|
+
author: { name: 'My Name' },
|
|
121
|
+
},
|
|
122
|
+
article: {
|
|
123
|
+
defaultCategory: 'Uncategorized',
|
|
124
|
+
categories: {
|
|
125
|
+
Tech: { icon: 'tabler:code', color: '#7777ff' },
|
|
126
|
+
},
|
|
127
|
+
types: { tech: {}, story: {} },
|
|
128
|
+
},
|
|
129
|
+
feed: { limit: 50, enableStyle: true },
|
|
130
|
+
features: {
|
|
131
|
+
atom: true,
|
|
132
|
+
opml: true,
|
|
133
|
+
stats: true,
|
|
134
|
+
antiMirror: false,
|
|
135
|
+
},
|
|
136
|
+
})
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Never place tokens or private deployment credentials in `clarity.config.ts` or `app/app.config.ts`; both can affect generated client output.
|
|
140
|
+
|
|
141
|
+
## Public API
|
|
142
|
+
|
|
143
|
+
| Entry | API |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| `clarity-theme` | Nuxt Layer root |
|
|
146
|
+
| `clarity-theme/config` | `defineClarityConfig()` and configuration/schema types |
|
|
147
|
+
| `clarity-theme/content` | `createClarityContentConfig()` and `ArticleSchema` |
|
|
148
|
+
| `clarity-theme/schema` | All `clarity*` Zod schemas and derived types |
|
|
149
|
+
| `clarity-theme/img` | Avatar/favicon/image URL helpers |
|
|
150
|
+
|
|
151
|
+
The Layer also exposes the `useClarityConfig()`, `useClaritySite()`, `useClarityArticle()`, and `useClaritySiteFeedEntry()` runtime auto-imports, plus the `#clarity/feeds` injection. They are Layer contracts rather than standalone package subpaths.
|
|
152
|
+
|
|
153
|
+
The exact export/type boundary is documented in [docs/API.md](./docs/API.md).
|
|
154
|
+
|
|
155
|
+
## Customization
|
|
156
|
+
|
|
157
|
+
### UI configuration
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
// app/app.config.ts
|
|
161
|
+
export default defineAppConfig({
|
|
162
|
+
clarity: {
|
|
163
|
+
header: { emojiTail: ['📝'] },
|
|
164
|
+
pagination: { perPage: 10 },
|
|
165
|
+
nav: [
|
|
166
|
+
{
|
|
167
|
+
title: '',
|
|
168
|
+
items: [
|
|
169
|
+
{ icon: 'tabler:files', text: 'Articles', url: '/' },
|
|
170
|
+
{ icon: 'tabler:link', text: 'Friends', url: '/link' },
|
|
171
|
+
{ icon: 'tabler:archive', text: 'Archive', url: '/archive' },
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
})
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Objects merge deeply; arrays replace the Theme value entirely.
|
|
180
|
+
|
|
181
|
+
### Components
|
|
182
|
+
|
|
183
|
+
Create a Layer-relative component at the same path to replace it, for example:
|
|
184
|
+
|
|
185
|
+
```text
|
|
186
|
+
app/components/content/Badge.vue
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Consumer components take precedence over Layer components. Nuxt currently emits a duplicate-name warning for this intentional override pattern.
|
|
190
|
+
|
|
191
|
+
### Shiki themes
|
|
192
|
+
|
|
193
|
+
Provide `app/shiki.config.ts` in the consumer project. The Theme fallback is used only when this file does not exist.
|
|
194
|
+
|
|
195
|
+
UI groups, same-path component overrides, CSS overrides, server/route customization, and Shiki ownership are described together in [Customization](./docs/CUSTOMIZATION.md).
|
|
196
|
+
|
|
197
|
+
## Compatibility and Verification
|
|
198
|
+
|
|
199
|
+
The verification suite is designed to cover:
|
|
200
|
+
|
|
201
|
+
- Playground static generation
|
|
202
|
+
- Independent `pnpm pack` consumer installation
|
|
203
|
+
- Five package exports in Node and TypeScript
|
|
204
|
+
- Three configuration branches
|
|
205
|
+
- Markdown/MDC/code/math/Mermaid/music/image rendering
|
|
206
|
+
- Production SSR, real browser rendering, and dev hydration
|
|
207
|
+
- Search, pagination, archive, TOC, SEO, robots, sitemap, LLMs, Atom, OPML, stats, permalink, 404, Twikoo branches, anti-mirror injection, UI override, and component override
|
|
208
|
+
- Theme purity, peer dependencies, sync tooling, and upstream drift
|
|
209
|
+
|
|
210
|
+
The generated release matrix lives in [Compatibility](./docs/COMPATIBILITY.md). Current exact counts, known limitations, technical debt, and release blockers live in [Project status](./docs/PROJECT-STATUS.md) and [Roadmap](./docs/ROADMAP.md). A release must rerun the ordered suite on the exact commit; earlier results are not a substitute.
|
|
211
|
+
|
|
212
|
+
Site-specific dependency patches are intentionally owned by consumers; see [Patches](./docs/PATCHES.md).
|
|
213
|
+
|
|
214
|
+
## Documentation
|
|
215
|
+
|
|
216
|
+
All documents are also available in 简体中文 as sibling `*.zh-CN.md` files.
|
|
217
|
+
|
|
218
|
+
| Document | Purpose |
|
|
219
|
+
| --- | --- |
|
|
220
|
+
| [Project status](./docs/PROJECT-STATUS.md) | Current snapshot, verified capabilities, limitations, debt, gaps, and milestone |
|
|
221
|
+
| [Roadmap](./docs/ROADMAP.md) | Prioritized P0/P1/P2 debt register, deferred decisions, and milestone order |
|
|
222
|
+
| [Migration](./docs/MIGRATION.md) | Preserve blog-v3 content, configuration, redirects, patches, custom code, and assets while adopting Clarity |
|
|
223
|
+
| [Architecture](./docs/ARCHITECTURE.md) | Theme/consumer boundary and build/runtime data flows |
|
|
224
|
+
| [API](./docs/API.md) | Public package/Layer API versus internal implementation |
|
|
225
|
+
| [Configuration](./docs/CONFIGURATION.md) | Field-level Clarity configuration contract and examples |
|
|
226
|
+
| [Customization](./docs/CUSTOMIZATION.md) | UI, component, Shiki, CSS, server, and route overrides |
|
|
227
|
+
| [Compatibility](./docs/COMPATIBILITY.md) | Generated release compatibility matrix |
|
|
228
|
+
| [Upstream sync](./docs/UPSTREAM.md) | Baseline, manifest, commands, conflicts, and workflow |
|
|
229
|
+
| [Patches](./docs/PATCHES.md) | Consumer patch ownership and current conclusions |
|
|
230
|
+
| [Release audit](./docs/RELEASE-AUDIT.md) | Pre-closing engineering audit and remaining release gates |
|
|
231
|
+
| [Release checklist](./docs/RELEASE-CHECKLIST.md) | Exact final checks, remaining blockers, and verification evidence |
|
|
232
|
+
| [Extraction history](./docs/history/2026-09-layer-extraction.md) | Historical phases and one-time differential validation |
|
|
233
|
+
|
|
234
|
+
## Development
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
pnpm install # Theme + playground workspace
|
|
238
|
+
pnpm dev # Playground dev server
|
|
239
|
+
pnpm generate # Playground static generation
|
|
240
|
+
pnpm lint
|
|
241
|
+
pnpm typecheck
|
|
242
|
+
pnpm verify # Purity/static leak checks
|
|
243
|
+
pnpm peers check
|
|
244
|
+
pnpm test:sync
|
|
245
|
+
pnpm test:migration
|
|
246
|
+
pnpm test:contract
|
|
247
|
+
pnpm test:consumer
|
|
248
|
+
pnpm test:compatibility
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
CI derives Node and pnpm versions from package metadata. It runs lint/typecheck/verify/sync/migration/contract/peers on the fixed Node matrix, then playground generate, real consumer acceptance, and rendering compatibility on the primary Node version. A separate weekly workflow only detects and reports upstream drift.
|
|
252
|
+
|
|
253
|
+
See [Project status → CI](./docs/PROJECT-STATUS.md#10-ci) for the exact CI stages and permissions.
|
|
254
|
+
|
|
255
|
+
## Upstream Synchronization
|
|
256
|
+
|
|
257
|
+
Clarity is extracted from an upstream Nuxt blog and records the exact reviewed baseline in `sync-manifest.json`. The synchronization tooling separates directly includable paths, consumer-owned exclusions, transformed Theme contracts, and manual review paths; unknown upstream changes block apply. Use:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
pnpm sync:check # compare manifest baseline with remote
|
|
261
|
+
pnpm sync:diff # classify upstream changes
|
|
262
|
+
pnpm sync:apply # transactionally apply reviewed include-only changes
|
|
263
|
+
pnpm sync:verify # rerun Theme purity and baseline checks
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
The weekly workflow only detects and reports drift. It never applies, commits, or pushes changes. See [Upstream sync](./docs/UPSTREAM.md).
|
|
267
|
+
|
|
268
|
+
## Release Status
|
|
269
|
+
|
|
270
|
+
Clarity Theme is a **v0.1.0 pre-publish Layer candidate**. The Layer/package boundary, validated configuration, Content factory, rendering pipeline, server outputs, playground, real-consumer acceptance, compatibility matrix, three-layer CI, and upstream-sync baseline are implemented.
|
|
271
|
+
|
|
272
|
+
The first npm release is intentionally still blocked by the P0 correctness items in [Roadmap](./docs/ROADMAP.md)—especially the server/client configuration split, feature-off route semantics, anti-mirror navigation verification, and the no-op random-permalink contract—and by an exact-commit release run. Migration documentation and repeatability are being completed in this release-closing phase.
|
|
273
|
+
|
|
274
|
+
## License
|
|
275
|
+
|
|
276
|
+
Theme code is MIT. The upstream blog's articles are not included in this package.
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# Clarity Theme
|
|
2
|
+
|
|
3
|
+
[English](./README.md) | **简体中文**
|
|
4
|
+
|
|
5
|
+
Clarity Theme 是一个从 [L33Z22L11/blog-v3](https://github.com/L33Z22L11/blog-v3) 抽取出来的可复用 **Nuxt 4 Layer 博客主题**。它提供通用的博客 UI、页面结构、Markdown/MDC 渲染、SEO 集成以及 feed/服务端输出;你的项目只需要提供全部站点数据与内容。
|
|
6
|
+
|
|
7
|
+
## 功能特性
|
|
8
|
+
|
|
9
|
+
- 通过一条 `extends` 配置即可完成 Nuxt 4 Layer 安装
|
|
10
|
+
- 带默认值校验的站点配置,并严格拒绝未知字段
|
|
11
|
+
- 用于文章元数据与站点地图数据的 Nuxt Content 集合工厂
|
|
12
|
+
- Markdown、MDC 组件、Shiki 代码高亮、KaTeX、Mermaid、ABC 乐谱与富图片
|
|
13
|
+
- 文章列表、归档、分页、目录(TOC)、搜索、主题切换、小部件、预览与 404 路由
|
|
14
|
+
- Atom、OPML、统计、robots、sitemap 与 LLMs 输出
|
|
15
|
+
- 由使用方配置驱动的 Twikoo、head 脚本与反镜像集成
|
|
16
|
+
- UI 默认值、app config 覆盖、自定义 Shiki 主题与同路径组件覆盖
|
|
17
|
+
- 自动化的 workspace、tarball 消费者、SSR、浏览器、水合、纯度、契约、peer 与上游同步检查
|
|
18
|
+
|
|
19
|
+
## 环境要求
|
|
20
|
+
|
|
21
|
+
| 运行时 | 版本 |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| Node.js | `^22.19 \|\| ^24.11 \|\| >=26` |
|
|
24
|
+
| pnpm | 12.4.1,或适用于你项目的兼容包管理器 |
|
|
25
|
+
| Nuxt peer | `^4.5.2` |
|
|
26
|
+
| Vue peer | `^3.5.42` |
|
|
27
|
+
|
|
28
|
+
该包目前尚未发布到 npm 注册表。在第一个包版本发布之前,请以锁定到已审查 commit 的 Git 依赖方式安装。Clarity 属于应用运行时的一部分,因此请将其安装为常规依赖(dependency),而不是开发依赖(devDependency)。
|
|
29
|
+
|
|
30
|
+
## 安装
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add github:iicemeta/clarity-theme#<commit>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 快速开始
|
|
37
|
+
|
|
38
|
+
### 1. 继承 Layer
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
// nuxt.config.ts
|
|
42
|
+
export default defineNuxtConfig({
|
|
43
|
+
extends: ['clarity-theme'],
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. 定义站点配置
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
// clarity.config.ts
|
|
51
|
+
import { defineClarityConfig } from 'clarity-theme/config'
|
|
52
|
+
|
|
53
|
+
export default defineClarityConfig({
|
|
54
|
+
site: {
|
|
55
|
+
title: 'My Blog',
|
|
56
|
+
description: 'Notes about technology and life',
|
|
57
|
+
url: 'https://example.com/',
|
|
58
|
+
author: {
|
|
59
|
+
name: 'My Name',
|
|
60
|
+
avatar: '/avatar.webp',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`site.title`、`site.description`、`site.url` 与 `site.author.name` 为必填项。article、feed、stats、integration、feature 与 changelog 分组均为可选,并使用文档中记载的默认值。
|
|
67
|
+
|
|
68
|
+
### 3. 创建 Content schema
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
// content.config.ts
|
|
72
|
+
import { createClarityContentConfig } from 'clarity-theme/content'
|
|
73
|
+
import clarityConfig from './clarity.config'
|
|
74
|
+
|
|
75
|
+
export default createClarityContentConfig(clarityConfig)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
文章放在 `content/posts/` 下,其他 Content 页面放在 `content/` 下。
|
|
79
|
+
|
|
80
|
+
### 4. 可选:提供友链数据
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
// feeds.ts
|
|
84
|
+
import type { FeedGroup } from 'clarity-theme/config'
|
|
85
|
+
|
|
86
|
+
export default [] satisfies FeedGroup[]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
如果没有这个文件,友链页面和 OPML 输出会使用空数据,并且构建时会记录一条警告。
|
|
90
|
+
|
|
91
|
+
### 5. 生成或开发
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pnpm dev
|
|
95
|
+
pnpm generate
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
从现有 blog-v3 项目完整迁移的操作流程,见[迁移指南](./docs/MIGRATION.zh-CN.md)。主题数据与用户内容是被刻意分开的:这个包永远不会携带你的文章、友链、重定向、部署配置或包补丁。
|
|
99
|
+
|
|
100
|
+
## 从 blog-v3 迁移
|
|
101
|
+
|
|
102
|
+
完整的人工迁移指南见[迁移指南](./docs/MIGRATION.zh-CN.md)。如果你希望让当前 Agent 使用 `migrate-blog-v3-to-clarity` Skill 自动执行迁移,可以直接使用下面的提示词:
|
|
103
|
+
|
|
104
|
+
```markdown
|
|
105
|
+
请使用 `migrate-blog-v3-to-clarity` Skill,把当前这个 blog-v3 项目迁移到 Clarity Theme。
|
|
106
|
+
|
|
107
|
+
要求:
|
|
108
|
+
|
|
109
|
+
1. 先只读扫描项目,不立即修改。
|
|
110
|
+
2. 判断当前项目是否属于支持的 blog-v3 结构。
|
|
111
|
+
3. 检查 blog.config.ts、app/app.config.ts、content.config.ts、nuxt.config.ts、feeds.ts、redirects.json、patches、content、public、custom components、server、modules。
|
|
112
|
+
4. 生成迁移计划,并把所有风险项标出来。
|
|
113
|
+
5. 不修改文章正文和 frontmatter。
|
|
114
|
+
6. 不删除 content、public、redirects、patches 或未知自定义代码。
|
|
115
|
+
7. 能自动迁移的部分自动处理。
|
|
116
|
+
8. 需要人工判断的部分暂停修改并记录原因。
|
|
117
|
+
9. 迁移完成后执行 typecheck、generate 和兼容性验证。
|
|
118
|
+
10. 最后输出完整 migration report,包括修改文件、保留配置、人工处理项和测试结果。
|
|
119
|
+
|
|
120
|
+
整个过程只使用当前 Agent 串行执行,不启动并行 Agent。
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## 基础配置
|
|
124
|
+
|
|
125
|
+
| 文件 | 职责 |
|
|
126
|
+
| --- | --- |
|
|
127
|
+
| `clarity.config.ts` | 站点身份、文章语义、友链、统计、集成、功能开关、更新日志 |
|
|
128
|
+
| `app/app.config.ts` | 仅限可选的响应式 UI 覆盖 |
|
|
129
|
+
| `content.config.ts` | Nuxt Content 集合/schema |
|
|
130
|
+
| `feeds.ts` | 可选的友链数据 |
|
|
131
|
+
| 使用方 `runtimeConfig` | 环境相关配置,以及唯一合法的密钥存放位置 |
|
|
132
|
+
|
|
133
|
+
逐字段的默认值、可见性与示例见[配置说明](./docs/CONFIGURATION.zh-CN.md)。
|
|
134
|
+
|
|
135
|
+
可选分组示例:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
export default defineClarityConfig({
|
|
139
|
+
site: {
|
|
140
|
+
title: 'My Blog',
|
|
141
|
+
description: 'A Nuxt blog',
|
|
142
|
+
url: 'https://example.com/',
|
|
143
|
+
author: { name: 'My Name' },
|
|
144
|
+
},
|
|
145
|
+
article: {
|
|
146
|
+
defaultCategory: 'Uncategorized',
|
|
147
|
+
categories: {
|
|
148
|
+
Tech: { icon: 'tabler:code', color: '#7777ff' },
|
|
149
|
+
},
|
|
150
|
+
types: { tech: {}, story: {} },
|
|
151
|
+
},
|
|
152
|
+
feed: { limit: 50, enableStyle: true },
|
|
153
|
+
features: {
|
|
154
|
+
atom: true,
|
|
155
|
+
opml: true,
|
|
156
|
+
stats: true,
|
|
157
|
+
antiMirror: false,
|
|
158
|
+
},
|
|
159
|
+
})
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
绝不要把 token 或私有部署凭据放在 `clarity.config.ts` 或 `app/app.config.ts` 中;这两者都可能影响生成的客户端产物。
|
|
163
|
+
|
|
164
|
+
## 公共 API
|
|
165
|
+
|
|
166
|
+
| 入口 | API |
|
|
167
|
+
| --- | --- |
|
|
168
|
+
| `clarity-theme` | Nuxt Layer 根入口 |
|
|
169
|
+
| `clarity-theme/config` | `defineClarityConfig()` 与配置/schema 类型 |
|
|
170
|
+
| `clarity-theme/content` | `createClarityContentConfig()` 与 `ArticleSchema` |
|
|
171
|
+
| `clarity-theme/schema` | 全部 `clarity*` Zod schema 及派生类型 |
|
|
172
|
+
| `clarity-theme/img` | 头像/favicon/图片 URL 辅助函数 |
|
|
173
|
+
|
|
174
|
+
Layer 还暴露了 `useClarityConfig()`、`useClaritySite()`、`useClarityArticle()` 与 `useClaritySiteFeedEntry()` 运行时自动导入,以及 `#clarity/feeds` 注入。它们是 Layer 契约,而不是独立的包子路径。
|
|
175
|
+
|
|
176
|
+
确切的导出/类型边界记录在 [API 文档](./docs/API.zh-CN.md) 中。
|
|
177
|
+
|
|
178
|
+
## 自定义
|
|
179
|
+
|
|
180
|
+
### UI 配置
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
// app/app.config.ts
|
|
184
|
+
export default defineAppConfig({
|
|
185
|
+
clarity: {
|
|
186
|
+
header: { emojiTail: ['📝'] },
|
|
187
|
+
pagination: { perPage: 10 },
|
|
188
|
+
nav: [
|
|
189
|
+
{
|
|
190
|
+
title: '',
|
|
191
|
+
items: [
|
|
192
|
+
{ icon: 'tabler:files', text: 'Articles', url: '/' },
|
|
193
|
+
{ icon: 'tabler:link', text: 'Friends', url: '/link' },
|
|
194
|
+
{ icon: 'tabler:archive', text: 'Archive', url: '/archive' },
|
|
195
|
+
],
|
|
196
|
+
},
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
对象会深度合并;数组会整体替换主题的值。
|
|
203
|
+
|
|
204
|
+
### 组件
|
|
205
|
+
|
|
206
|
+
在使用方项目中创建同路径的 Layer 相对组件即可替换,例如:
|
|
207
|
+
|
|
208
|
+
```text
|
|
209
|
+
app/components/content/Badge.vue
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
使用方组件优先于 Layer 组件。Nuxt 目前会针对这种有意的覆盖模式输出重名警告。
|
|
213
|
+
|
|
214
|
+
### Shiki 主题
|
|
215
|
+
|
|
216
|
+
在使用方项目中提供 `app/shiki.config.ts`。只有当该文件不存在时,才会使用主题的回退配置。
|
|
217
|
+
|
|
218
|
+
UI 分组、同路径组件覆盖、CSS 覆盖、服务端/路由自定义与 Shiki 归属详见[自定义说明](./docs/CUSTOMIZATION.zh-CN.md)。
|
|
219
|
+
|
|
220
|
+
## 兼容性与验证
|
|
221
|
+
|
|
222
|
+
验证套件覆盖:
|
|
223
|
+
|
|
224
|
+
- Playground 静态生成
|
|
225
|
+
- 独立的 `pnpm pack` 消费者安装
|
|
226
|
+
- Node 与 TypeScript 中的五个包导出
|
|
227
|
+
- 三种配置分支
|
|
228
|
+
- Markdown/MDC/代码/数学公式/Mermaid/乐谱/图片渲染
|
|
229
|
+
- 生产 SSR、真实浏览器渲染与开发水合
|
|
230
|
+
- 搜索、分页、归档、TOC、SEO、robots、sitemap、LLMs、Atom、OPML、统计、固定链接、404、Twikoo 分支、反镜像注入、UI 覆盖与组件覆盖
|
|
231
|
+
- 主题纯度、peer 依赖、同步工具与上游漂移
|
|
232
|
+
|
|
233
|
+
生成的发布矩阵见[兼容性说明](./docs/COMPATIBILITY.zh-CN.md)。当前的精确数量、已知限制、技术债与发布阻塞项见[项目状态](./docs/PROJECT-STATUS.zh-CN.md)与[路线图](./docs/ROADMAP.zh-CN.md)。发布前必须在确切的 commit 上重新按顺序运行整套验证;早先的结果不能替代。
|
|
234
|
+
|
|
235
|
+
站点相关的依赖补丁刻意由使用方持有;见[补丁说明](./docs/PATCHES.zh-CN.md)。
|
|
236
|
+
|
|
237
|
+
## 文档
|
|
238
|
+
|
|
239
|
+
| 文档 | 用途 |
|
|
240
|
+
| --- | --- |
|
|
241
|
+
| [项目状态](./docs/PROJECT-STATUS.zh-CN.md) | 当前快照、已验证能力、限制、技术债、缺口与里程碑 |
|
|
242
|
+
| [路线图](./docs/ROADMAP.zh-CN.md) | 按优先级排序的 P0/P1/P2 技术债清单、延后决策与里程碑顺序 |
|
|
243
|
+
| [迁移指南](./docs/MIGRATION.zh-CN.md) | 在采用 Clarity 的同时保留 blog-v3 的内容、配置、重定向、补丁、自定义代码与资源 |
|
|
244
|
+
| [架构](./docs/ARCHITECTURE.zh-CN.md) | 主题/使用方边界与构建/运行时数据流 |
|
|
245
|
+
| [API](./docs/API.zh-CN.md) | 公共包/Layer API 与内部实现的边界 |
|
|
246
|
+
| [配置说明](./docs/CONFIGURATION.zh-CN.md) | 字段级 Clarity 配置契约与示例 |
|
|
247
|
+
| [自定义说明](./docs/CUSTOMIZATION.zh-CN.md) | UI、组件、Shiki、CSS、服务端与路由覆盖 |
|
|
248
|
+
| [兼容性说明](./docs/COMPATIBILITY.zh-CN.md) | 生成的发布兼容性矩阵 |
|
|
249
|
+
| [上游同步](./docs/UPSTREAM.zh-CN.md) | 基线、manifest、命令、冲突与工作流 |
|
|
250
|
+
| [补丁说明](./docs/PATCHES.zh-CN.md) | 使用方补丁归属与当前结论 |
|
|
251
|
+
| [发布审计](./docs/RELEASE-AUDIT.zh-CN.md) | 收尾前工程审计与剩余发布门槛 |
|
|
252
|
+
| [发布清单](./docs/RELEASE-CHECKLIST.zh-CN.md) | 确切的最终检查、剩余阻塞项与验证证据 |
|
|
253
|
+
| [抽取历史](./docs/history/2026-09-layer-extraction.zh-CN.md) | 历史阶段与一次性差分验证 |
|
|
254
|
+
|
|
255
|
+
## 开发
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
pnpm install # 主题 + playground workspace
|
|
259
|
+
pnpm dev # Playground 开发服务器
|
|
260
|
+
pnpm generate # Playground 静态生成
|
|
261
|
+
pnpm lint
|
|
262
|
+
pnpm typecheck
|
|
263
|
+
pnpm verify # 纯度/静态泄漏检查
|
|
264
|
+
pnpm peers check
|
|
265
|
+
pnpm test:sync
|
|
266
|
+
pnpm test:migration
|
|
267
|
+
pnpm test:contract
|
|
268
|
+
pnpm test:consumer
|
|
269
|
+
pnpm test:compatibility
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
CI 从包元数据推导 Node 与 pnpm 版本。它先在固定的 Node 矩阵上运行 lint/typecheck/verify/sync/migration/contract/peers,再在主 Node 版本上运行 playground 生成、真实消费者验收与渲染兼容性。另有一个每周工作流只检测并报告上游漂移。
|
|
273
|
+
|
|
274
|
+
确切的 CI 阶段与权限见[项目状态 → CI](./docs/PROJECT-STATUS.zh-CN.md#10-ci)。
|
|
275
|
+
|
|
276
|
+
## 上游同步
|
|
277
|
+
|
|
278
|
+
Clarity 从一个上游 Nuxt 博客抽取而来,并在 `sync-manifest.json` 中记录确切的已审查基线。同步工具区分可直接包含的路径、使用方持有的排除项、经过转换的主题契约与人工审查路径;未知的上游变更会阻止 apply。使用:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
pnpm sync:check # 比较 manifest 基线与远端
|
|
282
|
+
pnpm sync:diff # 对上游变更分类
|
|
283
|
+
pnpm sync:apply # 事务式应用已审查的 include-only 变更
|
|
284
|
+
pnpm sync:verify # 重新运行主题纯度与基线检查
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
每周工作流只检测并报告漂移,绝不会 apply、commit 或 push 变更。见[上游同步](./docs/UPSTREAM.zh-CN.md)。
|
|
288
|
+
|
|
289
|
+
## 发布状态
|
|
290
|
+
|
|
291
|
+
Clarity Theme 是一个 **v0.1.0 发布前 Layer 候选版本**。Layer/包边界、已校验配置、Content 工厂、渲染管线、服务端输出、playground、真实消费者验收、兼容性矩阵、三层 CI 与上游同步基线均已实现。
|
|
292
|
+
|
|
293
|
+
首次 npm 发布仍被[路线图](./docs/ROADMAP.zh-CN.md)中的 P0 正确性事项刻意阻塞——尤其是服务端/客户端配置拆分、功能关闭时的路由语义、反镜像导航验证与 no-op 随机固定链接契约——同时还需要一次在确切 commit 上的发布运行。迁移文档与可复现性正在本次收尾阶段完成。
|
|
294
|
+
|
|
295
|
+
## 许可证
|
|
296
|
+
|
|
297
|
+
主题代码采用 MIT 许可证。上游博客的文章不包含在本包中。
|