Skip to content

Commit 4e61aff

Browse files
committed
Merge branch 'master' of https://github.com/layer5io/layer5
2 parents 9ce7c30 + b81facf commit 4e61aff

File tree

5 files changed

+78
-7
lines changed

5 files changed

+78
-7
lines changed

.claude/skills/layer5-blog-writer/SKILL.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ Write like an experienced engineer talking to peers. The voice is:
2727
- **American English.** color, analyze, recognize, center.
2828
- **Hyphens only, never em dashes.** Use `-` wherever you'd be tempted to use ``. Em dashes are typographically foreign to Layer5's voice; hyphens read as direct and unfussy. This applies everywhere: prose, titles, subtitles, callouts, code comments.
2929

30+
**Brand names are case-sensitive.** MeshMates (not Meshmates or meshmates), Meshery, Kanvas, Layer5, mesheryctl (lowercase), KubeCon, GitOps, DevOps, OpenTelemetry. When in doubt, grep the codebase for the canonical spelling. Getting these wrong looks careless to the community.
31+
3032
**Cut without mercy:** buzzword soup ("holistic," "synergize," "leverage"), passive voice, filler transitions ("It is worth noting that," "In conclusion," "Simply put"), press-release prose, hedging language that adds length without adding information.
3133

3234
**Open strong.** The first paragraph is a hook. Give the reader the specific problem, why it's hard, and a hint that you have an answer. If you can't summarize the value in one paragraph, the post needs a sharper angle.
@@ -58,7 +60,11 @@ grep -r "YOUR_TOPIC" ~/code/docs/content/en/ --include="*.md" -l | head -8
5860

5961
See `references/docs-sources.md` for the full path-to-URL mapping and search patterns.
6062

61-
**Key rule:** If you can't find a claim in the docs, either qualify it ("as of this writing") or omit it. Blog posts extend the docs — they don't contradict them.
63+
**Key rule:** If you can't find a claim in the docs, either qualify it ("as of this writing") or omit it. Blog posts extend the docs - they don't contradict them.
64+
65+
**Verify every command sequence end-to-end.** Read the commands you wrote as if you were executing them in order on a fresh cluster. If step 2 disables a component, step 5 cannot reference that component. If step 1 installs into namespace X, subsequent `kubectl` commands must target namespace X. Contradictory commands (e.g. `--set query.enabled=false` followed by `kubectl port-forward svc/jaeger-query`) are embarrassing and destroy reader trust instantly.
66+
67+
**Pin versions in install commands.** Never use `releases/latest`, `:latest` tags, or unversioned URLs in tutorials. Pin to a specific release (e.g. `v0.104.0`, `v1.23.0`). Unpinned commands break silently weeks later when upstream ships a breaking change, and the reader blames the blog post. If you don't know the current version, grep the docs or check the project's GitHub releases page and use the latest stable version explicitly.
6268

6369
### Step 3 — Plan the post
6470

@@ -127,8 +133,11 @@ darkthumbnail: ./hero-image.svg
127133
128134
### Step 6 — Final quality check
129135
130-
- [ ] All frontmatter fields present
136+
**Structure and components:**
137+
138+
- [ ] All frontmatter fields present (see `references/blog-structure.md` for the complete list)
131139
- [ ] `published: true` (or `false` for draft)
140+
- [ ] Date format exactly: `YYYY-MM-DD HH:MM:SS +/-HHMM` (quoted in frontmatter)
132141
- [ ] At least one image with descriptive alt text
133142
- [ ] At least one `<CTA_FullWidth>` or `<KanvasCTA>`
134143
- [ ] At least one `<Blockquote>` for emphasis
@@ -139,7 +148,21 @@ darkthumbnail: ./hero-image.svg
139148
- [ ] Opening lede wrapped in `<div className="intro">`
140149
- [ ] Closing next-steps wrapped in `<div className="outro">`
141150
- [ ] Technical posts: consider `resource: true`
142-
- [ ] Tags and categories from the approved list
151+
- [ ] Tags and categories from the approved list (see `references/tags-categories.md`)
152+
153+
**Technical accuracy (tutorials and how-to posts):**
154+
155+
- [ ] Every shell command sequence is internally consistent - read them top to bottom as if executing on a fresh cluster. If step N disables or skips a component, no later step can reference that component
156+
- [ ] Install commands pin explicit versions (`v0.104.0`, not `releases/latest` or `:latest`)
157+
- [ ] Namespace, service name, and label selectors are consistent across all commands
158+
- [ ] `kubectl port-forward`, `kubectl get`, and `kubectl logs` commands reference resources that were actually created by preceding steps
159+
- [ ] If the post references a Meshery or Kanvas feature, grep the docs repos to confirm the feature name and CLI flags are current
160+
161+
**Brand and taxonomy:**
162+
163+
- [ ] Brand names use exact capitalization: MeshMates, Meshery, mesheryctl, Kanvas, Layer5, KubeCon, GitOps, DevOps, OpenTelemetry
164+
- [ ] Tags match the approved list casing exactly (e.g. `ai` is lowercase, `Open Source` is title case) - see `references/tags-categories.md`
165+
- [ ] Category is exactly one from the approved list
143166

144167
## Reference files
145168

.claude/skills/layer5-blog-writer/references/blog-structure.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,40 @@ The closing section wrapper. Visually distinct from `intro` - solid teal top/bot
278278
</div>
279279
```
280280

281-
The `outro` style is defined in `Blog.style.js` alongside `intro`. Both use the teal brand color from `theme.primaryLightColor`, but `intro` uses dashed borders with an italic voice while `outro` uses solid borders with a direct, action-forward tone.
281+
The `outro` style is defined in `Blog.style.js` alongside `intro`. Key differences from `intro`:
282+
283+
| Property | `div.intro` | `div.outro` |
284+
| ------------ | -------------------------- | ---------------------- |
285+
| Border style | `1px dashed` (teal) | `1px solid` (teal) |
286+
| Font style | `italic` | Normal (not italic) |
287+
| Font size | `0.8rem` | `1rem` |
288+
| Padding L/R | `3rem` | `1rem` |
289+
| Tone | Reflective, sets the scene | Direct, action-forward |
290+
291+
**Do not** copy intro's padding or font-size values for outro. The outro is a call to action, not a lede - it should feel normal-weight and not cramped on mobile.
292+
293+
## Code Examples and CLI Commands
294+
295+
When a post includes shell commands, `kubectl` invocations, Helm installs, or any executable steps:
296+
297+
**Pin versions.** Every install command must reference an explicit version number. Never use `releases/latest`, `:latest`, or an unversioned URL. Examples:
298+
299+
```bash
300+
# WRONG - breaks when upstream ships a new version
301+
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml
302+
303+
# RIGHT - reproducible for readers months later
304+
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.4/cert-manager.yaml
305+
```
306+
307+
**Verify internal consistency.** Read every command in the post top-to-bottom as if executing on a fresh cluster. Check:
308+
309+
- If a Helm `--set` flag disables a component (e.g. `--set query.enabled=false`), no later command can reference that component (e.g. `kubectl port-forward svc/jaeger-query` would fail)
310+
- Namespaces must match across install and access commands
311+
- Service names in `port-forward`, `get`, and `logs` commands must match what the install actually creates
312+
- If the post uses a custom release name (`helm install my-release ...`), subsequent references must use that name, not the chart default
313+
314+
**Show expected output where helpful.** For commands where success isn't obvious (e.g. `kubectl get pods`), show a brief expected output block so readers can verify they're on track.
282315
283316
## Writing Style
284317

.claude/skills/layer5-blog-writer/references/tags-categories.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Always prefer existing values. Introduce a new one only if nothing fits.
44

5+
**Casing matters.** Tags and categories must match the exact casing shown below. Inconsistent casing (e.g. `AI` vs `ai`, `Opensource` vs `Open Source`) fragments the taxonomy and breaks tag-based filtering on the site. Copy the tag string exactly as listed.
6+
57
## Categories (exactly one per post)
68

79
| Category | Use for |
@@ -38,7 +40,7 @@ Always prefer existing values. Introduce a new one only if nothing fits.
3840
- `Meshery` — anything involving the Meshery platform
3941
- `Community` — events, contributor stories, programs
4042
- `Kubernetes` — Kubernetes tutorials, operations
41-
- `ai` AI/ML topics, LLMs, AI tools (lowercasematches codebase convention)
43+
- `ai` - AI/ML topics, LLMs, AI tools (**lowercase** - this is intentional and matches the existing codebase convention; do NOT use `AI` or `Ai`)
4244
- `Meet The Maintainer` — interview series
4345
- `docker` — containers, Docker ecosystem
4446
- `Service Mesh` — service mesh topics

.claude/skills/layer5-blog-writer/scripts/generate_hero_image.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,9 +635,9 @@ def generate_hero_svg(title, subtitle, category, output_path, repo_root,
635635
<stop offset="55%" stop-color="{EERIE_BLACK}" stop-opacity="0.22"/>
636636
<stop offset="100%" stop-color="{EERIE_BLACK}" stop-opacity="0"/>
637637
</linearGradient>
638-
{bg_filter_def}
638+
{bg_gradient_defs}
639639
{glow_filter_def}
640-
<!-- Note: bg_filter_def now contains gradient definitions, not a blur filter -->
640+
<!-- Note: bg_gradient_defs contains background gradient definitions -->
641641
</defs>
642642
643643
{bg_svg}

src/collections/blog/Blog.style.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ export const BlogWrapper = styled.div`
2323
}
2424
}
2525
26+
div.outro {
27+
display: flex;
28+
padding-left: 1rem;
29+
padding-right: 1rem;
30+
font-size: 1rem;
31+
border-top: 1px solid ${(props) => props.theme.primaryLightColor};
32+
border-bottom: 1px solid ${(props) => props.theme.primaryLightColor};
33+
margin-top: 1rem;
34+
padding-top: 1rem;
35+
padding-bottom: 1rem;
36+
background-color: ${(props) => props.theme.secondaryLightColorTwo};
37+
}
38+
2639
div.tip {
2740
position: relative;
2841
float: right;

0 commit comments

Comments
 (0)