Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Each skill still lives in its own `github.com/lovstudio/{name}-skill` repo. This
## Skills

<!-- COUNT:START -->
> **11 skills** — 11 Free + 0 Paid.
> **12 skills** — 12 Free + 0 Paid.
<!-- COUNT:END -->

<!-- SKILLS:START -->
Expand All @@ -43,6 +43,7 @@ Each skill still lives in its own `github.com/lovstudio/{name}-skill` repo. This
| ![Free](https://img.shields.io/badge/Free-green) | [`auto-context`](https://github.com/lovstudio/auto-context-skill) | Watch your Claude Code context for pollution and suggest when to fork or reset. |
| ![Free](https://img.shields.io/badge/Free-green) | [`cc-migrate-session`](https://github.com/lovstudio/cc-migrate-session) | Keep your Claude Code session history working after you move a project folder. |
| ![Free](https://img.shields.io/badge/Free-green) | [`deploy-to-vercel`](https://github.com/lovstudio/deploy-to-vercel-skill) | Ship a frontend to Vercel with custom domain and Cloudflare DNS wired up automatically. |
| ![Free](https://img.shields.io/badge/Free-green) | [`dev-blog`](https://github.com/lovstudio/dev-blog-skill) | Turn a development session into a practical blog post and publish it to LovStudio's blog feed. |
| ![Free](https://img.shields.io/badge/Free-green) | [`finder-action`](https://github.com/lovstudio/finder-action-skill) | Add a custom right-click action to macOS Finder in minutes. |
| ![Free](https://img.shields.io/badge/Free-green) | [`gh-access`](https://github.com/lovstudio/gh-access-skill) | Grant, revoke, or audit collaborator access on private GitHub repos in one command. |
| ![Free](https://img.shields.io/badge/Free-green) | [`gh-contribute`](https://github.com/lovstudio/gh-contribute-skill) | Ship a clean PR to any upstream GitHub repo — fork, branch, push, and open PR for you. |
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
## 技能列表

<!-- COUNT:START -->
> **11 个技能** — 11 个免费 + 0 个付费。
> **12 个技能** — 12 个免费 + 0 个付费。
<!-- COUNT:END -->

<!-- SKILLS:START -->
Expand All @@ -43,6 +43,7 @@
| ![Free](https://img.shields.io/badge/Free-green) | [上下文体检 · `auto-context`](https://github.com/lovstudio/auto-context-skill) | 监测 Claude Code 上下文是否被污染,适时提示你 /fork 或 /btw。 |
| ![Free](https://img.shields.io/badge/Free-green) | [会话迁移 · `cc-migrate-session`](https://github.com/lovstudio/cc-migrate-session) | 项目目录搬家后,让 Claude Code 的历史会话还能正常 `--resume`。 |
| ![Free](https://img.shields.io/badge/Free-green) | [部署到 Vercel · `deploy-to-vercel`](https://github.com/lovstudio/deploy-to-vercel-skill) | 一键把前端部署到 Vercel,自动配好 Cloudflare DNS 和自定义域名。 |
| ![Free](https://img.shields.io/badge/Free-green) | [开发博客 · `dev-blog`](https://github.com/lovstudio/dev-blog-skill) | 把一次开发会话沉淀成中文技术博客,并发布到 LovStudio 网站博客列表。 |
| ![Free](https://img.shields.io/badge/Free-green) | [访达右键动作 · `finder-action`](https://github.com/lovstudio/finder-action-skill) | 几分钟给 macOS 访达右键菜单加一个你自己的动作。 |
| ![Free](https://img.shields.io/badge/Free-green) | [GitHub 协作者管理 · `gh-access`](https://github.com/lovstudio/gh-access-skill) | 一条命令给私有 GitHub 仓库加减协作者权限,或盘点现有访问清单。 |
| ![Free](https://img.shields.io/badge/Free-green) | [GitHub 投稿 PR · `gh-contribute`](https://github.com/lovstudio/gh-contribute-skill) | 给任意上游 GitHub 仓库提一份干净的 PR——fork、分支、推送、开 PR 一站搞定。 |
Expand Down
11 changes: 11 additions & 0 deletions skills.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ skills:
tagline_en: Watch your Claude Code context for pollution and suggest when to fork
or reset.
tagline_zh: 监测 Claude Code 上下文是否被污染,适时提示你 /fork 或 /btw。
- name: dev-blog
repo: lovstudio/dev-blog-skill
name_zh: 开发博客
paid: false
category: Dev Tools
version: 0.1.0
description: Summarize a development session into a practical Chinese blog post
and publish it to LovStudio's Supabase blog feed.
tagline_en: Turn a development session into a practical blog post and publish it
to LovStudio's blog feed.
tagline_zh: 把一次开发会话沉淀成中文技术博客,并发布到 LovStudio 网站博客列表。
- name: cc-migrate-session
repo: lovstudio/cc-migrate-session
name_zh: 会话迁移
Expand Down
9 changes: 9 additions & 0 deletions skills/dev-blog/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
__pycache__/
*.pyc
*.pyo
.DS_Store
.venv/
venv/
node_modules/
.env
.env.local
73 changes: 73 additions & 0 deletions skills/dev-blog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# lovstudio:dev-blog

![Version](https://img.shields.io/badge/version-0.1.0-CC785C)

Summarize a development session into a practical Chinese blog post and publish
it to LovStudio's Supabase-backed website blog feed.

Part of [lovstudio skills](https://github.com/lovstudio/skills) — by [lovstudio.ai](https://lovstudio.ai)

## Install

```bash
git clone https://github.com/lovstudio/dev-blog-skill ~/.claude/skills/lovstudio-dev-blog
```

Requires Python 3.8+. No third-party Python packages are needed.

## Usage

Ask Claude Code:

```text
/lovstudio:dev-blog 总结这次开发过程,生成一篇博客并同步到网站
```

The skill will gather context, draft a Chinese article, save a local Markdown
draft, run a dry-run payload check, then publish to Supabase `blog_posts`.

You can also run the publisher directly:

```bash
python3 ~/.claude/skills/lovstudio-dev-blog/scripts/publish_blog_post.py \
--input .output/dev-blog/example.md \
--title "一次开发上下文如何变成可复用博客" \
--slug "dev-context-to-blog" \
--excerpt "把开发过程沉淀成网站博客,关键在于先结构化上下文,再用 Supabase 作为发布源。" \
--tags "dev,lovstudio,blog" \
--env-file /Users/mark/lovstudio/coding/web/.env.local
```

## Options

| Option | Default | Description |
|--------|---------|-------------|
| `--input` | (required) | Markdown/MDX post body. |
| `--title` | (required) | Blog post title. |
| `--slug` | generated from title | URL slug. |
| `--excerpt` | first paragraph | Blog card summary. |
| `--tags` | `dev,lovstudio` | Comma-separated tags. |
| `--author` | `Mark` | Author name. |
| `--cover` | empty | Optional cover image URL. |
| `--published-at` | now | ISO timestamp. |
| `--source-kind` | `dev-skill` | Stored in `blog_posts.source_kind`. |
| `--source-path` | `dev-blog:<slug>` | Stable source key. |
| `--draft` | false | Publish as hidden draft. |
| `--hide-from-index` | false | Keep visible detail page but omit from `/blog`. |
| `--env-file` | empty | Optional env file containing Supabase credentials. |
| `--dry-run` | false | Print payload without writing. |

## Supabase Target

The script upserts into `blog_posts` by `slug` and sets:

- `is_visible=true`
- `show_in_index=true`
- `source_kind=dev-skill`

It requires `NEXT_PUBLIC_SUPABASE_URL` and `SUPABASE_SERVICE_ROLE_KEY` in the
environment or in the file passed through `--env-file`.

## License

MIT
161 changes: 161 additions & 0 deletions skills/dev-blog/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
---
name: lovstudio:dev-blog
category: Dev Tools
tagline: "Summarize a development session into a practical blog post and publish it to LovStudio's Supabase blog feed."
description: >
Summarize the current development context, code changes, decisions, and
lessons into a practical Chinese blog post for yourself and developers facing
similar issues, then publish it to LovStudio's Supabase `blog_posts` table so
it appears on the website blog list. Trigger when the user says "生成博客",
"同步到网站博客", "总结上下文写博文", "开发日志", "generate blog post",
"sync to website blog", or "summarize context as blog".
license: MIT
compatibility: >
Requires Python 3.8+. Publishing requires Supabase service-role credentials
available in environment variables or a local .env file.
metadata:
author: lovstudio
version: "0.1.0"
tags: dev blog supabase writing
---

# Dev Blog

Turn the current development session into a useful Chinese technical blog post
and publish it to LovStudio's website blog feed.

## When to Use

- The user asks to summarize current context and write a blog post.
- The user wants a development log, incident write-up, or lessons learned article.
- The user asks to sync a generated post to the LovStudio website blog list.
- Trigger phrases: "生成博客", "同步到网站博客", "总结上下文写博文", "开发日志", "generate blog post", "sync to website blog".

## Workflow (MANDATORY)

**You MUST follow these steps in order:**

### Step 1: Gather Context

Collect the source material before writing:

- Recent user intent and constraints from the conversation.
- Relevant files, diffs, commands, errors, and verification output.
- The final decision or implementation, including tradeoffs.
- What a future reader should learn from this case.

If the topic, audience, or publish target is unclear, ask one concise question.
Do not ask for fields that can be inferred from the current context.

### Step 2: Draft the Article

Write in Chinese for two audiences:

- Primary: Mark, as a durable record of the work.
- Secondary: developers or AI builders who may hit a similar issue.

Use this structure unless the context clearly calls for a different one:

1. `# <title>`
2. Opening: what problem triggered the work and why it mattered.
3. Context: project/background, only enough for the reader to orient.
4. Process: the key investigation path, failed assumptions, and turning points.
5. Solution: what changed, why this shape fits the system.
6. Takeaways: reusable engineering lessons.

Style rules:

- Prefer concrete nouns, file/table names, commands, and exact constraints.
- Avoid generic AI productivity claims.
- Do not include secrets, tokens, private customer details, or raw `.env` values.
- Keep code excerpts short and only when they explain the decision.
- The post body must be valid Markdown/MDX.

### Step 3: Prepare Metadata

Derive these fields:

| Field | Rule |
|-------|------|
| `title` | Specific, readable Chinese title. |
| `slug` | ASCII lowercase kebab-case; if Chinese title has no ASCII, use a short English slug. |
| `excerpt` | 1-2 sentence summary under 180 chars. |
| `tags` | 2-5 tags, include `dev` and a concrete domain tag. |
| `author` | Default `Mark`. |
| `source_kind` | Default `dev-skill`. |

### Step 4: Save Draft Locally

Create a temporary Markdown file in the current project, normally:

```bash
mkdir -p .output/dev-blog
```

Use a filename based on the slug, for example:

```text
.output/dev-blog/<slug>.md
```

Report the absolute path of the draft if publishing is skipped or fails.

### Step 5: Publish to Supabase

Run a dry run first and inspect the payload:

```bash
python3 ~/.claude/skills/lovstudio-dev-blog/scripts/publish_blog_post.py \
--input .output/dev-blog/<slug>.md \
--title "<title>" \
--slug "<slug>" \
--excerpt "<excerpt>" \
--tags "dev,lovstudio" \
--env-file /Users/mark/lovstudio/coding/web/.env.local \
--dry-run
```

Then publish:

```bash
python3 ~/.claude/skills/lovstudio-dev-blog/scripts/publish_blog_post.py \
--input .output/dev-blog/<slug>.md \
--title "<title>" \
--slug "<slug>" \
--excerpt "<excerpt>" \
--tags "dev,lovstudio" \
--env-file /Users/mark/lovstudio/coding/web/.env.local
```

The script upserts by `slug`, sets `is_visible=true`, `show_in_index=true`, and
uses `source_kind=dev-skill`. A successful publish returns `/blog/<slug>`.

## CLI Reference

| Argument | Default | Description |
|----------|---------|-------------|
| `--input` | (required) | Markdown/MDX post body. |
| `--title` | (required) | Blog post title. |
| `--slug` | generated from title | URL slug. Use ASCII kebab-case. |
| `--excerpt` | first paragraph | Blog card summary. |
| `--tags` | `dev,lovstudio` | Comma-separated tags. |
| `--author` | `Mark` | Author name. |
| `--cover` | empty | Optional cover image URL. |
| `--published-at` | now | ISO timestamp. |
| `--source-kind` | `dev-skill` | Stored in `blog_posts.source_kind`. |
| `--source-path` | `dev-blog:<slug>` | Stable source key for traceability. |
| `--draft` | false | Set `is_visible=false`. |
| `--hide-from-index` | false | Set `show_in_index=false`. |
| `--env-file` | empty | Local `.env` file to load credentials from. |
| `--dry-run` | false | Print payload without writing to Supabase. |

## Dependencies

No third-party Python dependencies.

Publishing requires:

- `NEXT_PUBLIC_SUPABASE_URL`
- `SUPABASE_SERVICE_ROLE_KEY`

Never print or copy these values into the article or final response.
Loading