From a9f565cf00bf4fa60b8d5ea92a8e52b2e96d6845 Mon Sep 17 00:00:00 2001 From: Francis Batac <15894826+francisfuzz@users.noreply.github.com> Date: Thu, 9 Apr 2026 20:48:04 -0700 Subject: [PATCH 1/5] Add post scaffold script and agent skill docs --- scripts/new-post.sh | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 scripts/new-post.sh diff --git a/scripts/new-post.sh b/scripts/new-post.sh new file mode 100644 index 0000000..429bea3 --- /dev/null +++ b/scripts/new-post.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ ${1:-} == "" ]]; then + echo "Usage: scripts/new-post.sh \"Post Title\" [description]" + exit 1 +fi + +TITLE="$1" +DESCRIPTION="${2:-}" +DATE="$(date +%F)" +SLUG="$(printf '%s' "$TITLE" \ + | tr '[:upper:]' '[:lower:]' \ + | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//; s/-+/-/g')" +FILE="_posts/${DATE}-${SLUG}.md" + +if [[ -e "$FILE" ]]; then + echo "Refusing to overwrite existing file: $FILE" + exit 1 +fi + +cat > "$FILE" < Date: Thu, 9 Apr 2026 20:50:27 -0700 Subject: [PATCH 2/5] Add agentconfig-style skill for scaffolding new blog posts --- .agents/skills/add-post-skill/SKILL.md | 107 +++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 .agents/skills/add-post-skill/SKILL.md diff --git a/.agents/skills/add-post-skill/SKILL.md b/.agents/skills/add-post-skill/SKILL.md new file mode 100644 index 0000000..b656f0d --- /dev/null +++ b/.agents/skills/add-post-skill/SKILL.md @@ -0,0 +1,107 @@ +--- +name: add-post-skill +description: Create a new Jekyll blog post in _posts/ using the site's filename convention, required front matter, and a starter content shell. +--- + +# Add Post Skill + +## When to use +Use this skill when asked to create, initialize, scaffold, or draft a new blog post for this site. + +## Goal +Create a new Markdown file in `_posts/` that matches this repository's Jekyll conventions: +- filename: `YYYY-MM-DD-slug.md` +- front matter includes `layout: post`, `title`, and `date` +- optional `description` when provided +- content includes a practical starter shell for writing + +## Repository conventions +- Posts live in `_posts/` +- Post layout is `post` +- Permalinks are generated automatically by Jekyll from the global config +- The current layout only requires `title` and `date` for rendering + +## Inputs +- `title` (required) +- `description` (optional) +- `date` (optional; default to current date in `YYYY-MM-DD`) + +## Steps +1. Normalize the title into a slug: + - lowercase + - replace runs of non-alphanumeric characters with `-` + - trim leading/trailing `-` +2. Choose the date: + - use the provided date if present + - otherwise use today's date in `YYYY-MM-DD` +3. Build the destination path: + - `_posts/-.md` +4. Refuse to overwrite an existing post unless explicitly asked +5. Write the file with this template: + +```md +--- +layout: post +title: +date: <YYYY-MM-DD> +description: <DESCRIPTION> +--- + +Write your introduction here. + +## Key points + +- Add your first point +- Add your second point +- Add your third point + +## Details + +Add the main body of the post here. + +## Closing + +Wrap up with the takeaway or next step. +``` + +6. If no description was provided, omit the `description` line entirely +7. Return the created file path + +## Notes +- Do not add `permalink` unless explicitly requested; the site config already handles this +- Do not add extra metadata fields unless asked, because the current layout does not use them +- Keep the shell lightweight and editable + +## Example +Input: +- title: `A Better Way to Debug CI Failures` +- description: `Notes on narrowing CI issues quickly` + +Output path: +- `_posts/2026-04-09-a-better-way-to-debug-ci-failures.md` + +Output file: +```md +--- +layout: post +title: A Better Way to Debug CI Failures +date: 2026-04-09 +description: Notes on narrowing CI issues quickly +--- + +Write your introduction here. + +## Key points + +- Add your first point +- Add your second point +- Add your third point + +## Details + +Add the main body of the post here. + +## Closing + +Wrap up with the takeaway or next step. +``` From 4a6ef995c502582241e71562d388cc769757eae9 Mon Sep 17 00:00:00 2001 From: Francis Batac <15894826+francisfuzz@users.noreply.github.com> Date: Thu, 9 Apr 2026 20:59:21 -0700 Subject: [PATCH 3/5] Make new-post.sh executable (set mode 100755) --- scripts/new-post.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) mode change 100644 => 100755 scripts/new-post.sh diff --git a/scripts/new-post.sh b/scripts/new-post.sh old mode 100644 new mode 100755 index 429bea3..1a66d31 --- a/scripts/new-post.sh +++ b/scripts/new-post.sh @@ -9,9 +9,7 @@ fi TITLE="$1" DESCRIPTION="${2:-}" DATE="$(date +%F)" -SLUG="$(printf '%s' "$TITLE" \ - | tr '[:upper:]' '[:lower:]' \ - | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//; s/-+/-/g')" +SLUG="$(printf '%s' "$TITLE" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//; s/-+/-/g')" FILE="_posts/${DATE}-${SLUG}.md" if [[ -e "$FILE" ]]; then From ef49ea63d14221a98db3f3b6e1d1fbc94fcf6444 Mon Sep 17 00:00:00 2001 From: Francis Batac <15894826+francisfuzz@users.noreply.github.com> Date: Fri, 10 Apr 2026 19:09:00 -0700 Subject: [PATCH 4/5] Improve post scaffold: safe YAML quoting, optional date, draft support, slug validation --- .agents/skills/add-post-skill/SKILL.md | 101 ++++++------------------- scripts/new-post.sh | 92 ++++++++++++++++------ 2 files changed, 90 insertions(+), 103 deletions(-) diff --git a/.agents/skills/add-post-skill/SKILL.md b/.agents/skills/add-post-skill/SKILL.md index b656f0d..9b6396c 100644 --- a/.agents/skills/add-post-skill/SKILL.md +++ b/.agents/skills/add-post-skill/SKILL.md @@ -9,99 +9,44 @@ description: Create a new Jekyll blog post in _posts/ using the site's filename Use this skill when asked to create, initialize, scaffold, or draft a new blog post for this site. ## Goal -Create a new Markdown file in `_posts/` that matches this repository's Jekyll conventions: -- filename: `YYYY-MM-DD-slug.md` -- front matter includes `layout: post`, `title`, and `date` -- optional `description` when provided -- content includes a practical starter shell for writing - -## Repository conventions -- Posts live in `_posts/` -- Post layout is `post` -- Permalinks are generated automatically by Jekyll from the global config -- The current layout only requires `title` and `date` for rendering +Create a new Markdown file in `_posts/` that matches this repository's Jekyll conventions. ## Inputs -- `title` (required) -- `description` (optional) -- `date` (optional; default to current date in `YYYY-MM-DD`) - -## Steps -1. Normalize the title into a slug: - - lowercase - - replace runs of non-alphanumeric characters with `-` - - trim leading/trailing `-` -2. Choose the date: - - use the provided date if present - - otherwise use today's date in `YYYY-MM-DD` -3. Build the destination path: - - `_posts/<date>-<slug>.md` -4. Refuse to overwrite an existing post unless explicitly asked -5. Write the file with this template: +- title (required) +- description (optional) +- date (optional, YYYY-MM-DD) +- draft flag (optional) + +## Behavior +- Slugify title (lowercase, hyphenated) +- Use provided date or default to current date +- If draft flag is set, create file in `_drafts/slug.md` +- Otherwise create `_posts/YYYY-MM-DD-slug.md` +- Validate slug is non-empty +- Quote YAML values safely +- Do not overwrite existing files + +## Template -```md --- layout: post -title: <TITLE> +title: "<TITLE>" date: <YYYY-MM-DD> -description: <DESCRIPTION> +description: "<OPTIONAL>" --- Write your introduction here. ## Key points -- Add your first point -- Add your second point -- Add your third point +- +- +- ## Details -Add the main body of the post here. - ## Closing -Wrap up with the takeaway or next step. -``` - -6. If no description was provided, omit the `description` line entirely -7. Return the created file path - ## Notes -- Do not add `permalink` unless explicitly requested; the site config already handles this -- Do not add extra metadata fields unless asked, because the current layout does not use them -- Keep the shell lightweight and editable - -## Example -Input: -- title: `A Better Way to Debug CI Failures` -- description: `Notes on narrowing CI issues quickly` - -Output path: -- `_posts/2026-04-09-a-better-way-to-debug-ci-failures.md` - -Output file: -```md ---- -layout: post -title: A Better Way to Debug CI Failures -date: 2026-04-09 -description: Notes on narrowing CI issues quickly ---- - -Write your introduction here. - -## Key points - -- Add your first point -- Add your second point -- Add your third point - -## Details - -Add the main body of the post here. - -## Closing - -Wrap up with the takeaway or next step. -``` +- Permalinks handled by `_config.yml` +- Script available: `scripts/new-post.sh` diff --git a/scripts/new-post.sh b/scripts/new-post.sh index 1a66d31..a875403 100755 --- a/scripts/new-post.sh +++ b/scripts/new-post.sh @@ -1,45 +1,87 @@ #!/usr/bin/env bash set -euo pipefail +usage() { + echo 'Usage: scripts/new-post.sh [--draft] "Post Title" [description] [date]' +} + +yaml_escape() { + local value="${1:-}" + value=${value//\\/\\\\} + value=${value//\"/\\\"} + printf '%s' "$value" +} + +DRAFT=false + +if [[ ${1:-} == "--draft" ]]; then + DRAFT=true + shift +fi + if [[ ${1:-} == "" ]]; then - echo "Usage: scripts/new-post.sh \"Post Title\" [description]" + usage exit 1 fi TITLE="$1" DESCRIPTION="${2:-}" -DATE="$(date +%F)" -SLUG="$(printf '%s' "$TITLE" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//; s/-+/-/g')" -FILE="_posts/${DATE}-${SLUG}.md" +DATE="${3:-$(date +%F)}" -if [[ -e "$FILE" ]]; then - echo "Refusing to overwrite existing file: $FILE" +if [[ ! "$DATE" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then + echo "Invalid date: $DATE (expected YYYY-MM-DD)" exit 1 fi -cat > "$FILE" <<EOF ---- -layout: post -title: ${TITLE} -date: ${DATE} -${DESCRIPTION:+description: ${DESCRIPTION}} ---- - -Write your introduction here. +SLUG="$(printf '%s' "$TITLE" \ + | tr '[:upper:]' '[:lower:]' \ + | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//; s/-+/-/g')" -## Key points - -- Add your first point -- Add your second point -- Add your third point +if [[ -z "$SLUG" ]]; then + echo "Unable to generate slug from title: $TITLE" + exit 1 +fi -## Details +if [[ "$DRAFT" == "true" ]]; then + DIR="_drafts" + FILE="${DIR}/${SLUG}.md" +else + DIR="_posts" + FILE="${DIR}/${DATE}-${SLUG}.md" +fi -Add the main body of the post here. +mkdir -p "$DIR" -## Closing +if [[ -e "$FILE" ]]; then + echo "Refusing to overwrite existing file: $FILE" + exit 1 +fi -Wrap up with the takeaway or next step. -EOF +{ + echo "---" + echo "layout: post" + printf 'title: "%s"\n' "$(yaml_escape "$TITLE")" + printf 'date: %s\n' "$DATE" + if [[ -n "$DESCRIPTION" ]]; then + printf 'description: "%s"\n' "$(yaml_escape "$DESCRIPTION")" + fi + echo "---" + echo + echo "Write your introduction here." + echo + echo "## Key points" + echo + echo "- Add your first point" + echo "- Add your second point" + echo "- Add your third point" + echo + echo "## Details" + echo + echo "Add the main body of the post here." + echo + echo "## Closing" + echo + echo "Wrap up with the takeaway or next step." +} > "$FILE" echo "Created $FILE" From 19b818cd7cec15887a313c5ad1ad4a38a6d5d92f Mon Sep 17 00:00:00 2001 From: Francis Batac <15894826+francisfuzz@users.noreply.github.com> Date: Fri, 10 Apr 2026 19:11:13 -0700 Subject: [PATCH 5/5] Polish scaffold: arg validation, spacing, improved skill docs --- .agents/skills/add-post-skill/SKILL.md | 7 +++++++ scripts/new-post.sh | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.agents/skills/add-post-skill/SKILL.md b/.agents/skills/add-post-skill/SKILL.md index 9b6396c..d96b4af 100644 --- a/.agents/skills/add-post-skill/SKILL.md +++ b/.agents/skills/add-post-skill/SKILL.md @@ -17,6 +17,13 @@ Create a new Markdown file in `_posts/` that matches this repository's Jekyll co - date (optional, YYYY-MM-DD) - draft flag (optional) +## Implementation +Use the helper script: + +``` +scripts/new-post.sh "<title>" "<description>" "<date>" +``` + ## Behavior - Slugify title (lowercase, hyphenated) - Use provided date or default to current date diff --git a/scripts/new-post.sh b/scripts/new-post.sh index a875403..2cff591 100755 --- a/scripts/new-post.sh +++ b/scripts/new-post.sh @@ -19,7 +19,7 @@ if [[ ${1:-} == "--draft" ]]; then shift fi -if [[ ${1:-} == "" ]]; then +if [[ $# -lt 1 || $# -gt 3 ]]; then usage exit 1 fi