Skip to content
Marketing
Skill

/product-update-logger

Tell the skill what your product shipped. It writes a polished dated entry to a living docs/changelog.md and produces a ready-to-use content package: tweet thread, LinkedIn post, email snippet, and one-liner.

From plugin
opendirectory-gtm-skills
58364 skills
Install
$ npx -y skills add Varnan-Tech/opendirectory --skill product-update-logger --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/product-update-logger

Context preview

The summary Claude sees to decide when to auto-load this skill.

Tell the skill what your product shipped. It writes a polished dated entry to a living docs/changelog.md and produces a ready-to-use content package: tweet thread, LinkedIn post, email snippet, and one-liner.

SKILL.md

product-update-logger.SKILL.md
name: product-update-logger
description: "Tell the skill what your product shipped. It writes a polished dated entry to a living docs/changelog.md and produces a ready-to-use content package: tweet thread, LinkedIn post, email snippet, and one-liner."

product-update-logger

Tell this skill what your product shipped. It writes a polished changelog entry to `docs/changelog.md` (a living log, newest entry first) and simultaneously produces a content package: tweet thread, LinkedIn post, email snippet, and one-liner.

Input sources: free text from your message, git commits auto-read from the local repo, or GitHub PRs if you provide a repo. Any combination works.

Reference Files

Read these files before each run:

cat references/changelog-format.md
cat references/content-rules.md
cat references/noise-filter.md

---

Step 1: Setup Check

echo "GITHUB_TOKEN: ${GITHUB_TOKEN:-not set -- GitHub PR fetching disabled}"
echo "Git:          $(git rev-parse --is-inside-work-tree 2>/dev/null && echo 'repo detected' || echo 'not a git repo')"
echo "Changelog:    $(ls docs/changelog.md 2>/dev/null && echo 'exists' || echo 'will be created')"

Note whether git is available and whether a changelog already exists. This determines the version label format.

---

Step 2: Parse Input

Collect from the conversation:

  • `items` -- free text description of what shipped (pipe-separated if multiple). Optional if git is available.
  • `since` -- how many days back to look. Default: 7. User may say "last 2 weeks" (14) or "since last release."
  • `repo` -- GitHub "owner/repo" for PR fetching. Optional.
  • `version_label` -- custom label like "v2.1.0" or "The Speed Update." Optional; default is date-based.

**If the user said nothing about items AND there is no git repo:** Ask "What did you ship? List the features, fixes, or improvements -- one per line."

**If git is available and user said nothing specific:** Proceed with git auto-read in Step 3. Show the user what was found and confirm before transforming.

Write parsed input:

python3 << 'PYEOF'
import json, os, re

inp = {
    "items": "",          # FILL: pipe-separated free text, or "" if none
    "since": 7,           # FILL: integer days
    "repo": "",           # FILL: "owner/repo" or ""
    "version_label": ""   # FILL: "" means auto (date-based), or custom string
}

with open("/tmp/pul-input.json", "w") as f:
    json.dump(inp, f, indent=2)
print(f"Since: {inp['since']} days")
print(f"Free text items: {inp['items'] or 'none (will use git/GitHub)'}")
print(f"GitHub repo: {inp['repo'] or 'none'}")
print(f"Version label: {inp['version_label'] or 'auto (date-based)'}")
PYEOF

---

Step 3: Run the Gather Script

ls scripts/gather.py 2>/dev/null && echo "script found" || echo "ERROR: scripts/gather.py not found"
GITHUB_TOKEN="${GITHUB_TOKEN:-}" python3 scripts/gather.py \
    --since "$(python3 -c "import json; print(json.load(open('/tmp/pul-input.json'))['since'])")" \
    --repo "$(python3 -c "import json; print(json.load(open('/tmp/pul-input.json'))['repo'])")" \
    --items "$(python3 -c "import json; print(json.load(open('/tmp/pul-input.json'))['items'])")" \
    --output /tmp/pul-raw.json

Verify output:

python3 -c "
import json
with open('/tmp/pul-raw.json') as f:
    d = json.load(f)
print(f'Items found:      {d[\"total_items\"]}')
print(f'Noise filtered:   {d[\"noise_filtered\"]}')
print(f'Git available:    {d[\"git_available\"]}')
print(f'GitHub available: {d[\"github_available\"]}')
print(f'Sources: git={sum(1 for i in d[\"items\"] if i[\"source\"]==\"git_commit\")}, '
      f'prs={sum(1 for i in d[\"items\"] if i[\"source\"]==\"github_pr\")}, '
      f'text={sum(1 for i in d[\"items\"] if i[\"source\"]==\"free_text\")}')
print()
print('Items:')
for item in d['items']:
    print(f'  [{item[\"source\"]}] {item[\"subject\"]}')
"

**If total_items == 0:** Stop. Tell the user: "No shipped items found. Either describe what you shipped, point me to a git repo with recent commits, or add a GitHub repo with `repo: owner/repo` and a GITHUB_TOKEN."

**Show the item list to the user and ask: "These are the items I found. Anything to add or remove before I write the changelog?"**

Wait for confirmation or edits. If the user says "looks good", "proceed", or makes no changes, continue. If the user adds or removes items, update `/tmp/pul-raw.json` accordingly before Step 4.

---

Step 4: Generate Changelog Entry

Print items for context:

python3 -c "
import json
with open('/tmp/pul-raw.json') as f:
    d = json.load(f)
print(json.dumps(d['items'], indent=2))
print()
print(f'Existing changelog format: {d[\"existing_changelog\"][\"format\"]}')
print(f'Last label: {d[\"existing_changelog\"][\"last_label\"]}')
print(f'Today: {d[\"date\"]}')
"

**AI instructions:** Transform each raw item from technical language to user-facing benefit language. Follow `references/changelog-format.md` for transformation rules and examples.

Rules:

  • **Do NOT invent outcomes or metrics.** "40% faster" must come from the source data. If no number is in the commit or PR, do not add one.
  • **Use past tense:** "Added", "Fixed", "Improved" -- not "Adds", "Fixes"
  • **Assign exactly one category** to each item: New, Improved, Fixed, or Under the hood
  • **Under the hood:** Only include if developer-relevant (API changes, breaking changes). Omit empty sections.
  • **Omit** anything that maps to: test changes, CI changes, documentation-only commits

Determine version label:

  • If user specified one: use it exactly
  • If `existing_changelog.format == "semver"`: increment based on changes (patch for fixes only, minor for any new feature)
  • Default: `Week of [Month Day, Year]` using today's date

Write the entry to `/tmp/pul-entry.json`:

{
  "label": "Week of April 23, 2026",
  "date": "2026-04-23",
  "new": [
    {"title": "Dark mode", "description": "Toggle in Settings > Appearance. Work
Read more
Ships withopendirectory-gtm-skills

AI Agent Skills built for Founders who hate Marketing

Get the whole plugin