blog-edit
Edit an existing blog post or review on blog.carter2099.com. Find by title/ID, show current content, collaboratively revise, preview changes, then update.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Edit an existing blog post or review on blog.carter2099.com. Find by title/ID, show current content, collaboratively revise, preview changes, then update.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Check health of the homelab-backup service — last run status, next scheduled run, R2 bucket contents, and local archive state. Quick mobile-friendly summary.
Delete a blog post or review from blog.carter2099.com. Soft-deletes the markdown file (moved to deleted/ directory) and destroys the database record.
Create a new blog post on blog.carter2099.com. Collaboratively draft and polish markdown content, preview it, then publish — triggering subscriber email notifications via the Rails app.
Create a new review on blog.carter2099.com (Book, Movie, Show, Product, or Video Game). Collaboratively draft content, preview it, then publish — triggering subscriber email notifications via the Rails app.
Audit the homelab for outdated software and report findings. Use when user says "check for updates", "what's outdated", "audit the homelab", "run update check", or wants a system health report.
Create a new scheduled agent that runs on a systemd timer — recurring maintenance, checks, reports, or any task you want automated. Use when user says "set up a scheduled agent", "automate this to run daily", "I want a cron job for X".
| name | blog-edit |
| description | Edit an existing blog post or review on blog.carter2099.com. Find by title/ID, show current content, collaboratively revise, preview changes, then update. |
Edit an existing blog post or review. This is collaborative — show the user what exists, help them revise it, preview the final result, and only commit changes after explicit confirmation.
The user may refer to content by title, partial title, topic, or ID. Use these to locate it:
docker exec blog-web-1 bin/rails runner "Post.order(created_at: :desc).limit(10).each { |p| puts \"#{p.id}: #{p.title} (#{p.created_at.strftime('%Y-%m-%d')})\" }"
docker exec blog-web-1 bin/rails runner "Review.order(created_at: :desc).limit(10).each { |r| puts \"#{r.id}: #{r.title} [#{r.review_type.name}, #{r.formatted_rating}] (#{r.created_at.strftime('%Y-%m-%d')})\" }"
docker exec blog-web-1 bin/rails runner "Post.where('title LIKE ?', '%<query>%').each { |p| puts \"#{p.id}: #{p.title}\" }"
docker exec blog-web-1 bin/rails runner "Review.where('title LIKE ?', '%<query>%').each { |r| puts \"#{r.id}: #{r.title}\" }"
If the match is ambiguous, show the user the candidates and ask which one.
Once the target is identified, display what currently exists:
For a post:
/home/carter/blog/blog/app/posts/<filename>.md**Post #<id>:** <title>
**File:** <filename>.md
**Created:** <date>
---
<current markdown content>
---
For a review:
/home/carter/blog/blog/app/reviews/<filename>.md (if it has one)**Review #<id>:** <title>
**Type:** <review_type> | **Rating:** <rating>/5
**Author:** <author, if book>
**Main image:** <main_image filename, or "None">
**File:** <filename>.md (or "No body text")
**Created:** <date>
---
<current markdown content, or "(no body text)">
---
Work with the user on what they want to change. This could be:
Show the complete final version (not just the diff) so the user sees exactly what the post/review will look like after the edit:
For a post:
**Title:** <title> (unchanged / changed from "<old>")
---
<full markdown content as it will exist after the edit>
---
**Images to download:** <list, or "None">
For a review:
**Title:** <title> (unchanged / changed)
**Type:** <type> | **Rating:** <rating>/5 (unchanged / changed)
**Author:** <author> (if book)
**Main image:** <filename> (unchanged / changed / new)
---
<full markdown content, or "(no body text)">
---
**Images to download:** <list, or "None">
Ask: "Save these changes?" — do not proceed without explicit confirmation.
curl -fSL "<url>" -o /home/carter/blog/blog/app/assets/images/<filename>
docker exec blog-web-1 bin/rails runner "PostsHelper.load_post_images"
Overwrite the file at its existing path on the host. If the title changed and the user wants the filename updated too, write to the new path and delete the old one.
For a post:
docker exec blog-web-1 bin/rails runner "p = Post.find(<id>); p.update!(title: '<title>', path: '<path>')"
For a review:
docker exec blog-web-1 bin/rails runner "r = Review.find(<id>); r.update!(title: '<title>', review_type: ReviewType.find_by!(name: '<type>'), rating: <rating>, author: <author_or_nil>, path: <path_or_nil>, main_image: <main_image_or_nil>)"
docker exec blog-web-1 bin/rails runner "p = Post.find(<id>); puts \"Updated: #{p.title}\""
Report success with the URL (https://blog.carter2099.com/posts/<id> or /reviews/<id>).
after_create_commit callback only fires on create, not update. This is correct behavior — subscribers shouldn't get re-notified for edits./rails/app/posts/...), but files are read/written on the host path (/home/carter/blog/blog/app/posts/...) since the directory is bind-mounted.rails runner.path in the DB. Delete the old file after confirming the new one exists.The blog uses Redcarpet with hard_wrap: true, which changes how the parser handles certain constructs. Follow these rules when editing markdown content:
<ul>/<li> and will instead render it as literal text with <br> line breaks.##, ###, etc.) — same rule as lists.`code`) renders with a subtle background only (it's now display: inline as of 2025-06-19). Fenced code blocks (```) are for block-level code.