diff --git a/.claude/commands/xhs-copy.md b/.claude/commands/xhs-copy.md new file mode 100644 index 00000000..fb10b2bc --- /dev/null +++ b/.claude/commands/xhs-copy.md @@ -0,0 +1,190 @@ +--- +description: 根据文章生成小红书文案和标题 +allowed-tools: Read, Glob, Grep, Write +argument-hint: <文章路径> [--images <配图目录>] +--- + +# 小红书文案生成器 + +根据指定文章生成小红书风格的文案和标题,支持关联已生成的配图。 + +## 参数说明 + +| 参数 | 必填 | 说明 | 示例 | +|------|------|------|------| +| `<文章路径>` | 是 | 要生成文案的文章 | `posts/article.md` | +| `--images <目录>` | 否 | 已生成的配图目录 | `--images xhs-images/topic/` | + +**示例**: +```bash +# 只生成文案 +/xhs-copy posts/article.md + +# 生成文案 + 关联配图 +/xhs-copy posts/article.md --images xhs-images/slash-command-firecrawl/ +``` + +## 风格定义:实用派技术博主风格 + +融合苏洋(Soulteary)的写作风格,适配小红书短文案场景。 + +### 核心原则 + +| 原则 | 说明 | +|------|------| +| **实用主义** | 解决问题为先,不堆砌概念 | +| **对话感** | 像和朋友聊技术,不像写论文 | +| **有立场** | 敢于推荐或否定,不骑墙 | +| **适量 emoji** | 点缀而非堆砌,每个段落标题一个 | + +### 语言规范 + +**推荐用法**: +- 推荐方案:"我选择"、"我的做法是"、"个人用够了" +- 步骤引导:"先...再..."、"确认 X 之后" +- 踩坑分享:"返回空?加个 timeout,有些网页加载慢" +- 效果验证:"如果看到 X 输出,说明配置成功" +- 口语化:"够用了"、"一下就完事"、"选哪个不用说了吧" + +**禁止用法**: +- 空洞开场:"在当今数字化时代"、"随着技术发展" +- 过度修饰:"非常"、"极其"、"令人惊叹" +- 假装互动:"让我们一起"、"接下来我们将" +- 踩一捧一:不要贬低其他工具来抬高自己的方案 +- 过多 emoji:不要每句话都加 emoji + +### 结构模板 + +``` +{开头:场景 + 动机,1-2句} + +📌 {核心概念解释} +{简短说明,2-3句} + +🤔 {为什么选这个方案} +{对比或原因,不踩一捧一} +{一句话总结优势} + +📝 {怎么用}: +① 步骤一 +② 步骤二 +③ ... + +⚠️ 踩过的坑: +• {问题}?{解决方案},{原因} +• ... + +{一句话核心思路} ✨ +{收尾} + +💬 {互动引导} +``` + +### 标题模板 + +提供 2 个标题选项: + +| 类型 | 格式 | 示例 | +|------|------|------| +| 方案型 | 用 X 实现 Y + emoji | 用 Slash Command 给 Claude Code 加个「抓网页」功能 🔧 | +| 个人视角 | 我给 X 写了个 Y + emoji | 我给 Claude Code 写了个快捷指令,一条命令抓网页 ⚡ | + +**避免**: +- "保姆级教程"、"最全指南"(营销味) +- "深入理解"、"完全掌握"(太虚) +- "震惊!"、"居然可以这样"(标题党) + +### 标签模板 + +``` +#主题标签1 #主题标签2 #技术干货 #效率提升 #程序员日常 +``` + +--- + +## 执行步骤 + +1. **读取文章**:读取用户指定的文章路径 +2. **扫描配图**(如指定 `--images`): + - 列出目录下所有 `.png` / `.jpg` 图片 + - 按文件名排序(01-, 02-, ...) + - 读取 `outline.md` 获取每张图的描述(如存在) +3. **分析内容**: + - 提取核心主题和价值点 + - 识别目标受众 + - 找出可视化/对比点 + - 提取踩坑经验 +4. **生成文案**:按照上述风格和结构生成小红书文案 +5. **生成标题**:提供 2 个标题选项 +6. **生成标签**:5-7 个相关标签 +7. **输出结果**:以 Markdown 格式输出完整文案 + 配图清单 + +--- + +## 输出格式 + +```markdown +## 小红书文案 + +### 标题选项 + +**方案 A**: +> {方案型标题} + +**方案 B**: +> {个人视角标题} + +--- + +### 正文 + +{完整文案} + +--- + +### 标签 + +{标签列表} + +--- + +### 配图清单(如指定 --images) + +| # | 文件名 | 描述 | 建议 | +|---|--------|------|------| +| 1 | 01-cover-xxx.png | 封面 | 作为小红书封面 | +| 2 | 02-content-xxx.png | 内容页 | 第2张图 | +| ... | ... | ... | ... | + +**配图目录**:`{配图目录路径}` +**图片数量**:{N} 张 +**发布顺序**:按文件名序号 01 → 0N + +### 发布建议 + +| 项目 | 建议 | +|------|------| +| 封面 | 第1张图 | +| 发布时间 | 工作日 12:00-13:00 或 21:00-23:00 | +| 互动 | 评论区放完整代码/文章链接 | +``` + +--- + +## 示例输入 + +```bash +# 只生成文案 +/xhs-copy posts/slash-command-firecrawl.md + +# 生成文案 + 关联配图 +/xhs-copy posts/article.md --images xhs-images/slash-command-firecrawl/ +``` + +## 注意事项 + +- 文案长度控制在 300-500 字 +- 步骤不超过 5 步 +- 踩坑点 2-4 个 +- 保持口语化,像和朋友聊天 +- 不要贬低其他方案,只说自己方案的优点 diff --git a/.gitignore b/.gitignore index bbf2d227..f113710c 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,5 @@ scripts/migrate-images/reports/ # ossutil output ossutil_output/ + +xhs-images/ diff --git a/README.md b/README.md index 6e38e146..96991349 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,22 @@ xkcoding 的代码成长日记 - 基于 [Astro](https://astro.build/) + [AstroPaper](https://github.com/satnaing/astro-paper) 主题构建。 +## 特性 + +- 🚀 基于 Astro 5.x 构建,性能优异 +- 🎨 基于 AstroPaper 主题定制,简洁美观 +- 🔍 Pagefind 全文搜索 +- 📖 目录侧边栏(TOC) +- 🖼️ 文章封面图 & 动态 OG 图片 +- 📝 查看原文(跳转 GitHub raw 文件) +- ⚖️ CC BY-NC-SA 4.0 协议声明 +- 🌙 深色模式支持 + ## 技术栈 - **框架**: Astro 5.x - **主题**: AstroPaper +- **样式**: Tailwind CSS 4.x - **搜索**: Pagefind - **部署**: GitHub Pages + GitHub Actions @@ -36,11 +48,27 @@ pnpm run preview │ ├── data/blog/ # 博客文章 (Markdown) │ ├── layouts/ # 布局组件 │ ├── pages/ # 页面路由 +│ ├── utils/ # 工具函数 │ └── config.ts # 站点配置 +├── openspec/ # OpenSpec 规范文档 ├── astro.config.ts # Astro 配置 └── package.json ``` +## 配置说明 + +站点配置位于 `src/config.ts`,主要配置项: + +- `website`: 站点 URL +- `author`: 作者信息 +- `showToc`: 是否显示目录 +- `dynamicOgImage`: 是否启用动态 OG 图片 +- `editPost`: 编辑文章链接配置 +- `viewSource`: 查看原文链接配置 +- `license`: 协议声明配置 + ## License -MIT +文章内容采用 [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh-hans) 协议 + +代码采用 MIT 协议 diff --git a/openspec/changes/archive/2026-01-20-add-source-link-and-license/proposal.md b/openspec/changes/archive/2026-01-20-add-source-link-and-license/proposal.md new file mode 100644 index 00000000..6fd4ca9f --- /dev/null +++ b/openspec/changes/archive/2026-01-20-add-source-link-and-license/proposal.md @@ -0,0 +1,23 @@ +# Change: 新增查看原文链接和 CC 协议声明 + +## Why + +当前博客文章页面只有"编辑"链接(指向 GitHub edit 页面),缺少以下功能: +1. 读者无法快速查看文章的 Markdown 原始内容(source 模式) +2. 没有明确的版权协议声明,不利于内容保护和合规转载 + +## What Changes + +- 新增"查看原文"链接组件,跳转到 GitHub 仓库文件的 blob 页面(只读模式) +- 新增 CC BY-NC-SA 4.0 协议声明组件,显示在文章正文下方 +- 在 `config.ts` 中添加相关配置项(协议类型、仓库 URL 等) +- 修改 `PostDetails.astro` 布局,集成新组件 + +## Impact + +- Affected code: + - `src/config.ts` - 新增配置项 + - `src/components/ViewSource.astro` - 新建组件 + - `src/components/License.astro` - 新建组件 + - `src/layouts/PostDetails.astro` - 集成新组件 + - `src/assets/icons/` - 可能需要新增图标 diff --git a/openspec/changes/archive/2026-01-20-add-source-link-and-license/specs/post-details/spec.md b/openspec/changes/archive/2026-01-20-add-source-link-and-license/specs/post-details/spec.md new file mode 100644 index 00000000..8a04d8c9 --- /dev/null +++ b/openspec/changes/archive/2026-01-20-add-source-link-and-license/specs/post-details/spec.md @@ -0,0 +1,63 @@ +## ADDED Requirements + +### Requirement: View Source Link + +The system SHALL provide a "View Source" link on article detail pages that opens the raw Markdown file in the GitHub repository (blob view, not edit mode). + +#### Scenario: User clicks View Source link + +- **WHEN** user clicks the "View Source" link on an article page +- **THEN** a new tab opens with the GitHub blob URL for the article's Markdown file +- **AND** the URL format is `https://github.com/{owner}/{repo}/blob/{branch}/{filePath}` + +#### Scenario: View Source link visibility + +- **WHEN** `SITE.viewSource.enabled` is `true` +- **THEN** the View Source link is displayed on the article page +- **WHEN** `SITE.viewSource.enabled` is `false` +- **THEN** the View Source link is hidden + +### Requirement: CC License Declaration + +The system SHALL display a Creative Commons license declaration (CC BY-NC-SA 4.0) at the bottom of each article's content area. + +#### Scenario: License display position + +- **WHEN** an article page is rendered +- **THEN** the CC license declaration appears after the article content +- **AND** before the share links section + +#### Scenario: License content elements + +- **WHEN** the license component is rendered +- **THEN** it displays: + - The CC BY-NC-SA 4.0 license icon/badge + - A brief license description in Chinese + - A link to the full license text on Creative Commons website + +#### Scenario: License visibility control + +- **WHEN** `SITE.license.enabled` is `true` +- **THEN** the license declaration is displayed +- **WHEN** `SITE.license.enabled` is `false` +- **THEN** the license declaration is hidden + +### Requirement: Configuration Options + +The system SHALL provide configuration options in `src/config.ts` for View Source and License features. + +#### Scenario: viewSource configuration + +- **WHEN** configuring the View Source feature +- **THEN** the following options are available: + - `enabled`: boolean to show/hide the link + - `text`: display text for the link (default: "查看原文") + - `url`: base URL for the repository blob path + +#### Scenario: license configuration + +- **WHEN** configuring the License feature +- **THEN** the following options are available: + - `enabled`: boolean to show/hide the license + - `type`: license type identifier (e.g., "CC BY-NC-SA 4.0") + - `url`: URL to the full license text diff --git a/openspec/changes/archive/2026-01-20-add-source-link-and-license/tasks.md b/openspec/changes/archive/2026-01-20-add-source-link-and-license/tasks.md new file mode 100644 index 00000000..e135bedb --- /dev/null +++ b/openspec/changes/archive/2026-01-20-add-source-link-and-license/tasks.md @@ -0,0 +1,28 @@ +## 1. 配置扩展 + +- [x] 1.1 在 `src/config.ts` 中添加 `viewSource` 配置项(enabled、text、url) +- [x] 1.2 在 `src/config.ts` 中添加 `license` 配置项(enabled、type、url) + +## 2. 组件开发 + +- [x] 2.1 创建 `src/components/ViewSource.astro` 组件 + - 接收 `post` 参数,生成 raw URL + - 使用 GitHub 图标 + - 样式与 EditPost 保持一致 +- [x] 2.2 创建 `src/components/License.astro` 组件 + - 显示 CC BY-NC-SA 4.0 协议信息 + - 包含协议图标和链接 + - 简洁的版权声明文案 + +## 3. 布局集成 + +- [x] 3.1 修改 `src/layouts/PostDetails.astro` + - 在文章正文后、分享链接前添加 License 组件 + - 在元信息区添加 ViewSource 链接 +- [x] 3.2 确保移动端和桌面端响应式显示正常 + +## 4. 验证 + +- [x] 4.1 本地构建测试,确保无类型错误 +- [x] 4.2 验证链接跳转正确(raw 页面) +- [x] 4.3 检查暗色/亮色模式下样式正常 diff --git a/openspec/project.md b/openspec/project.md index 3da5119d..bd14ef8d 100644 --- a/openspec/project.md +++ b/openspec/project.md @@ -1,31 +1,60 @@ # Project Context ## Purpose -[Describe your project's purpose and goals] +xkcoding 的个人技术博客,记录代码成长历程、技术分享和学习笔记。 ## Tech Stack -- [List your primary technologies] -- [e.g., TypeScript, React, Node.js] +- **框架**: Astro 5.x +- **主题**: 基于 AstroPaper 定制 +- **样式**: Tailwind CSS 4.x +- **搜索**: Pagefind (静态搜索) +- **部署**: GitHub Pages + GitHub Actions +- **包管理**: pnpm ## Project Conventions ### Code Style -[Describe your code style preferences, formatting rules, and naming conventions] +- 使用 Prettier 格式化代码 +- 组件文件使用 PascalCase 命名 (如 `ViewSource.astro`) +- 工具函数使用 camelCase 命名 (如 `getPath.ts`) +- 中文注释,英文变量名 ### Architecture Patterns -[Document your architectural decisions and patterns] +- Astro 组件位于 `src/components/` +- 布局组件位于 `src/layouts/` +- 博客文章位于 `src/data/blog/`(Markdown 格式) +- 全局配置位于 `src/config.ts` +- 工具函数位于 `src/utils/` ### Testing Strategy -[Explain your testing approach and requirements] +- 依赖 TypeScript 类型检查 +- 使用 `pnpm run build` 验证构建 +- 通过 GitHub Actions CI 自动检查 ### Git Workflow -[Describe your branching strategy and commit conventions] +- 主分支: `master` +- 功能分支: `feature/xxx` +- 提交信息使用中文,格式: `类型: 描述` + - feat: 新功能 + - fix: 修复 + - style: 样式调整 + - docs: 文档更新 + - chore: 其他 ## Domain Context -[Add domain-specific knowledge that AI assistants need to understand] +- 博客文章使用 Markdown 编写,支持 frontmatter 配置 +- 支持动态 OG 图片生成 +- 支持文章封面图(用户设置 ogImage 时显示) +- 支持目录(TOC)侧边栏 +- 支持 CC BY-NC-SA 4.0 协议声明 +- 支持查看原文(跳转 GitHub raw 文件) ## Important Constraints -[List any technical, business, or regulatory constraints] +- 保持与 AstroPaper 主题的兼容性 +- 图片资源优先使用 WebP 格式 +- 文章 URL 使用日期格式(如 /2024-01-01-title) ## External Dependencies -[Document key external services, APIs, or systems] +- GitHub API: 用于部署和 raw 文件访问 +- Creative Commons: CC 协议徽章图片 +- Google Fonts: 字体资源 diff --git a/openspec/specs/post-details/spec.md b/openspec/specs/post-details/spec.md new file mode 100644 index 00000000..a52862ce --- /dev/null +++ b/openspec/specs/post-details/spec.md @@ -0,0 +1,67 @@ +# post-details Specification + +## Purpose +TBD - created by archiving change add-source-link-and-license. Update Purpose after archive. +## Requirements +### Requirement: View Source Link + +The system SHALL provide a "View Source" link on article detail pages that opens the raw Markdown file in the GitHub repository (blob view, not edit mode). + +#### Scenario: User clicks View Source link + +- **WHEN** user clicks the "View Source" link on an article page +- **THEN** a new tab opens with the GitHub blob URL for the article's Markdown file +- **AND** the URL format is `https://github.com/{owner}/{repo}/blob/{branch}/{filePath}` + +#### Scenario: View Source link visibility + +- **WHEN** `SITE.viewSource.enabled` is `true` +- **THEN** the View Source link is displayed on the article page +- **WHEN** `SITE.viewSource.enabled` is `false` +- **THEN** the View Source link is hidden + +### Requirement: CC License Declaration + +The system SHALL display a Creative Commons license declaration (CC BY-NC-SA 4.0) at the bottom of each article's content area. + +#### Scenario: License display position + +- **WHEN** an article page is rendered +- **THEN** the CC license declaration appears after the article content +- **AND** before the share links section + +#### Scenario: License content elements + +- **WHEN** the license component is rendered +- **THEN** it displays: + - The CC BY-NC-SA 4.0 license icon/badge + - A brief license description in Chinese + - A link to the full license text on Creative Commons website + +#### Scenario: License visibility control + +- **WHEN** `SITE.license.enabled` is `true` +- **THEN** the license declaration is displayed +- **WHEN** `SITE.license.enabled` is `false` +- **THEN** the license declaration is hidden + +### Requirement: Configuration Options + +The system SHALL provide configuration options in `src/config.ts` for View Source and License features. + +#### Scenario: viewSource configuration + +- **WHEN** configuring the View Source feature +- **THEN** the following options are available: + - `enabled`: boolean to show/hide the link + - `text`: display text for the link (default: "查看原文") + - `url`: base URL for the repository blob path + +#### Scenario: license configuration + +- **WHEN** configuring the License feature +- **THEN** the following options are available: + - `enabled`: boolean to show/hide the license + - `type`: license type identifier (e.g., "CC BY-NC-SA 4.0") + - `url`: URL to the full license text + diff --git a/src/components/BackToTopButton.astro b/src/components/BackToTopButton.astro index 0b1e654a..cc2a466f 100644 --- a/src/components/BackToTopButton.astro +++ b/src/components/BackToTopButton.astro @@ -1,74 +1,44 @@ --- -import IconChevronLeft from "@/assets/icons/IconChevronLeft.svg"; import IconArrowNarrowUp from "@/assets/icons/IconArrowNarrowUp.svg"; ---