Skip to content
Merged
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
20 changes: 20 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,26 @@
"source": "./plugins/grill-graph",
"category": "development",
"homepage": "https://github.com/LeaYeh/skills"
},
{
"name": "blog",
"description": "Interactively distill a valuable session into a bilingual (zh + en) technical blog post and stage it as a draft in the lyeh-infra Hugo blog",
"author": {
"name": "Lea Yeh"
},
"source": "./plugins/blog",
"category": "productivity",
"homepage": "https://github.com/LeaYeh/skills"
},
{
"name": "stop-slop",
"description": "Remove AI writing patterns from prose — cut filler, break formulaic structures, score on 5 dimensions. Use when drafting, editing, or reviewing text to eliminate predictable AI tells",
"author": {
"name": "Hardik Pandya"
},
"source": "./plugins/stop-slop",
"category": "productivity",
"homepage": "https://github.com/hardikpandya/stop-slop"
}
]
}
7 changes: 7 additions & 0 deletions plugins/blog/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "blog",
"description": "Interactively distill a valuable session into a bilingual (zh + en) technical blog post and stage it as a draft in the lyeh-infra Hugo blog",
"author": { "name": "Lea Yeh" },
"category": "productivity",
"homepage": "https://github.com/LeaYeh/skills"
}
55 changes: 55 additions & 0 deletions plugins/blog/skills/blog/PUBLISHING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Publishing mechanics (Hugo + Blowfish)

Hugo source: `<blog>/apps/portal/src` (default `~/project/git_dev/lyeh-infra/apps/portal/src`).
Posts live in `content/posts/` as flat files. Existing posts use **YAML** front matter (`---`), not TOML.

## File naming (bilingual)

One slug, two language files in `content/posts/`:

```
content/posts/<slug>.en.md
content/posts/<slug>.zh.md
```

`<slug>` is kebab-case, English, descriptive (e.g. `gitops-self-hosting-on-k3s`).

## Front matter

Identical keys in both files; `title`/`summary` translated, `translationKey` shared so Hugo links the two as translations.

```yaml
---
title: "<title in this file's language>"
date: <YYYY-MM-DD> # get the real date at runtime: `date +%Y-%m-%d` — never hardcode
draft: true # ALWAYS true; the user publishes manually
tags: ["Tag1", "Tag2"] # same tags both languages, English tag names
summary: "<1–2 sentence summary in this file's language>"
translationKey: "<slug>" # SAME value in both .en.md and .zh.md
---
```

## One-time i18n setup (do once, then skip)

The blog ships English-only. Before writing the first zh post, check for `config/_default/languages.zh.toml`. If missing, create it and the matching menu, modelled on the existing `.en.toml` files:

`config/_default/languages.zh.toml`
```toml
locale = "zh-tw"
label = "中文"
weight = 2
title = "Lea Yeh"

[params]
displayName = "中文"
isoCode = "zh-tw"
rtl = false
dateFormat = "2006年1月2日"
description = "資深軟體工程師 · 資料工程 · MLOps · 系統架構"
```

Copy `config/_default/menus.en.toml` to `config/_default/menus.zh.toml`, translating only the visible labels. Leave `hugo.toml`'s `defaultContentLanguage = "en"` as-is — Hugo auto-merges `languages.<lang>.toml`, so adding the file is enough to enable the language switcher. Confirm with the user before editing config; mention it in the hand-off.

## Preview

From the Hugo source dir: `hugo server -D` (the `-D` flag renders drafts). Drafts are excluded from production builds until `draft: true` is removed.
58 changes: 58 additions & 0 deletions plugins/blog/skills/blog/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
name: blog
description: Turn a valuable working session into a polished, bilingual (zh-TW + en) public technical blog post and stage it as a draft in the lyeh-infra Hugo blog. Manually triggered with /blog when the user feels the current session produced an insight worth publishing. Use when the user says "/blog", "write this up", "blog this", "把這個寫成文章", or wants to capture the value/lessons of a session as an article.
---

# Blog

Distill the **value and insight** of the current session into a public technical article, co-written through interview, then stage it as a bilingual Hugo draft. This is a flexible, conversational skill — never auto-publish.

Discussion in Traditional Chinese (zh-TW); article content in both zh-TW and English.

## Blog location

Default Hugo source: `~/project/git_dev/lyeh-infra/apps/portal/src` (posts in `content/posts/`).
If that path does not exist, ask the user for the blog repo path before writing anything.

## Workflow

### 1. Free description
Ask the user to describe, in their own words, what they found valuable about this session. Let them ramble — do not interrupt with questions yet.

### 2. Mine the session
Review the actual conversation/session context and pre-fill a draft of these dimensions. Show the user what you extracted so they can correct it:

1. **Hook** — the problem or itch that drove this; why a reader should care
2. **Context** — the setup, constraints, what was tried before
3. **Turning point / core insight** — the non-obvious thing learned (the heart of the post)
4. **How it works** — the concrete solution, with code/config snippets where they earn their place
5. **Trade-offs / what I'd do differently** — the honesty that makes it credible
6. **Takeaway** — what the reader should remember and can reuse

### 3. Interview to fill gaps
Interview the user **one question at a time**, grill-me style, only on the dimensions still thin or ambiguous after step 2. For each question, offer your recommended answer. Goal: sharpen the angle and surface the insight — not interrogate the design. Stop when the six dimensions are solid and the article's spine is clear.

### 4. Converge on an outline
Propose a title + section outline. Get a thumbs-up before drafting full prose.

### 5. Write the bilingual draft
Write the **English** post first, then the **zh-TW** translation (idiomatic, not literal — adapt examples and phrasing for a Chinese-reading developer). See [PUBLISHING.md](PUBLISHING.md) for exact front matter, file naming, and the one-time i18n setup.

### 6. De-slop — mandatory
Before writing any post to disk, you **MUST** invoke the `stop-slop` skill and run the English prose through its rules and scoring. Revise until it scores ≥ 35/50. Apply the same anti-AI-tell principles to the zh-TW version (cut filler, active voice, varied rhythm, no em dashes, trust the reader). A draft that has not passed stop-slop is not finished — do not skip this step even under time pressure.

### 7. Hand off — never commit
Report:
- the file paths written (both languages)
- how to preview locally (`hugo server -D` from the Hugo source dir)
- a reminder that `draft = true`; the user flips it and commits/pushes themselves when ready

Do not run `git add`, `git commit`, or `git push`.

## Principles

- **Insight over chronology.** A blog post is not a session transcript. Lead with the lesson; cut the dead-ends unless a dead-end *is* the lesson.
- **Show, don't summarize.** Prefer a real code/config snippet or a small table over hand-waving.
- **Honest trade-offs build trust.** Always include what didn't work or what you'd change.
- **Bilingual parity.** Both versions carry the same insight; the zh-TW one reads natively, not as a translation.
- **No slop, ever.** Every draft passes the `stop-slop` skill before it touches disk. No throat-clearing openers, no em dashes, no "not X but Y" contrasts, no narrator-from-a-distance voice.
8 changes: 8 additions & 0 deletions plugins/stop-slop/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "stop-slop",
"description": "Remove AI writing patterns from prose — cut filler, break formulaic structures, score on 5 dimensions. Use when drafting, editing, or reviewing text to eliminate predictable AI tells",
"author": { "name": "Hardik Pandya", "url": "https://hvpandya.com" },
"category": "productivity",
"homepage": "https://github.com/hardikpandya/stop-slop",
"license": "MIT"
}
21 changes: 21 additions & 0 deletions plugins/stop-slop/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 Hardik Pandya

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
68 changes: 68 additions & 0 deletions plugins/stop-slop/skills/stop-slop/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
name: stop-slop
description: Remove AI writing patterns from prose. Use when drafting, editing, or reviewing text to eliminate predictable AI tells.
metadata:
trigger: Writing prose, editing drafts, reviewing content for AI patterns
author: Hardik Pandya (https://hvpandya.com)
---

# Stop Slop

Eliminate predictable AI writing patterns from prose.

## Core Rules

1. **Cut filler phrases.** Remove throat-clearing openers, emphasis crutches, and all adverbs. See [references/phrases.md](references/phrases.md).

2. **Break formulaic structures.** Avoid binary contrasts, negative listings, dramatic fragmentation, rhetorical setups, false agency. See [references/structures.md](references/structures.md).

3. **Use active voice.** Every sentence needs a human subject doing something. No passive constructions. No inanimate objects performing human actions ("the complaint becomes a fix").

4. **Be specific.** No vague declaratives ("The reasons are structural"). Name the specific thing. No lazy extremes ("every," "always," "never") doing vague work.

5. **Put the reader in the room.** No narrator-from-a-distance voice. "You" beats "People." Specifics beat abstractions.

6. **Vary rhythm.** Mix sentence lengths. Two items beat three. End paragraphs differently. No em dashes.

7. **Trust readers.** State facts directly. Skip softening, justification, hand-holding.

8. **Cut quotables.** If it sounds like a pull-quote, rewrite it.

## Quick Checks

Before delivering prose:

- Any adverbs? Kill them.
- Any passive voice? Find the actor, make them the subject.
- Inanimate thing doing a human verb ("the decision emerges")? Name the person.
- Sentence starts with a Wh- word? Restructure it.
- Any "here's what/this/that" throat-clearing? Cut to the point.
- Any "not X, it's Y" contrasts? State Y directly.
- Three consecutive sentences match length? Break one.
- Paragraph ends with punchy one-liner? Vary it.
- Em-dash anywhere? Remove it.
- Vague declarative ("The implications are significant")? Name the specific implication.
- Narrator-from-a-distance ("Nobody designed this")? Put the reader in the scene.
- Meta-joiners ("The rest of this essay...")? Delete. Let the essay move.

## Scoring

Rate 1-10 on each dimension:

| Dimension | Question |
|-----------|----------|
| Directness | Statements or announcements? |
| Rhythm | Varied or metronomic? |
| Trust | Respects reader intelligence? |
| Authenticity | Sounds human? |
| Density | Anything cuttable? |

Below 35/50: revise.

## Examples

See [references/examples.md](references/examples.md) for before/after transformations.

## License

MIT
59 changes: 59 additions & 0 deletions plugins/stop-slop/skills/stop-slop/references/examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Before/After Examples

## Example 1: Throat-Clearing + Binary Contrast

**Before:**
> "Here's the thing: building products is hard. Not because the technology is complex. Because people are complex. Let that sink in."
**After:**
> "Building products is hard. Technology is manageable. People aren't."
**Changes:** Removed opener, binary contrast structure, and emphasis crutch. Direct statements.

---

## Example 2: Filler + Unnecessary Reassurance

**Before:**
> "It turns out that most teams struggle with alignment. The uncomfortable truth is that nobody wants to admit they're confused. And that's okay."
**After:**
> "Teams struggle with alignment. Nobody admits confusion."
**Changes:** Cut hedging ("most"), removed throat-clearing phrases, deleted permission-granting ending.

---

## Example 3: Business Jargon Stack

**Before:**
> "In today's fast-paced landscape, we need to lean into discomfort and navigate uncertainty with clarity. This matters because your competition isn't waiting."
**After:**
> "Move faster. Your competition is."
**Changes:** Eliminated jargon entirely. Core message in six words.

---

## Example 4: Dramatic Fragmentation

**Before:**
> "Speed. Quality. Cost. You can only pick two. That's it. That's the tradeoff."
**After:**
> "Speed, quality, cost—pick two."
**Changes:** Single sentence. No performative emphasis.

---

## Example 5: Rhetorical Setup

**Before:**
> "What if I told you that the best teams don't optimize for productivity? Here's what I mean: they optimize for learning. Think about it."
**After:**
> "The best teams optimize for learning, not productivity."
**Changes:** Direct claim. No rhetorical scaffolding.
Loading
Loading