From bed0f41aff54372a2595441d4894a67b69f9814f Mon Sep 17 00:00:00 2001 From: Leo Date: Sun, 8 Mar 2026 15:35:18 +0100 Subject: [PATCH] feat: add roadmap communicator skill with changelog generator --- product-team/roadmap-communicator/SKILL.md | 92 +++++++++++++++++ .../references/communication-templates.md | 63 ++++++++++++ .../references/roadmap-templates.md | 44 +++++++++ .../scripts/changelog_generator.py | 98 +++++++++++++++++++ 4 files changed, 297 insertions(+) create mode 100644 product-team/roadmap-communicator/SKILL.md create mode 100644 product-team/roadmap-communicator/references/communication-templates.md create mode 100644 product-team/roadmap-communicator/references/roadmap-templates.md create mode 100755 product-team/roadmap-communicator/scripts/changelog_generator.py diff --git a/product-team/roadmap-communicator/SKILL.md b/product-team/roadmap-communicator/SKILL.md new file mode 100644 index 0000000..f450187 --- /dev/null +++ b/product-team/roadmap-communicator/SKILL.md @@ -0,0 +1,92 @@ +--- +name: roadmap-communicator +description: Use when preparing roadmap narratives, release notes, changelogs, or stakeholder updates tailored for executives, engineering teams, and customers. +--- + +# Roadmap Communicator + +Create clear roadmap communication artifacts for internal and external stakeholders. + +## When To Use + +Use this skill for: +- Building roadmap presentations in different formats +- Writing stakeholder updates (board, engineering, customers) +- Producing release notes (user-facing and internal) +- Generating changelogs from git history +- Structuring feature announcements + +## Roadmap Formats + +1. Now / Next / Later +- Best for uncertainty and strategic flexibility. +- Communicate direction without false precision. + +2. Timeline roadmap +- Best for fixed-date commitments and launch coordination. +- Requires active risk and dependency management. + +3. Theme-based roadmap +- Best for outcome-led planning and cross-team alignment. +- Groups initiatives by problem space or strategic objective. + +See `references/roadmap-templates.md` for templates. + +## Stakeholder Update Patterns + +### Board / Executive +- Outcome and risk oriented +- Focus on progress against strategic goals +- Highlight trade-offs and required decisions + +### Engineering +- Scope, dependencies, and sequencing clarity +- Status, blockers, and resourcing implications + +### Customers +- Value narrative and timing window +- What is available now vs upcoming +- Clear expectation setting + +See `references/communication-templates.md` for reusable templates. + +## Release Notes Guidance + +### User-Facing Release Notes +- Lead with user value, not internal implementation details. +- Group by workflows or user jobs. +- Include migration/behavior changes explicitly. + +### Internal Release Notes +- Include technical details, operational impact, and known issues. +- Capture rollout plan, rollback criteria, and monitoring notes. + +## Changelog Generation + +Use: +```bash +python3 scripts/changelog_generator.py --from v1.0.0 --to HEAD +``` + +Features: +- Reads git log range +- Parses conventional commit prefixes +- Groups entries by type (`feat`, `fix`, `chore`, etc.) +- Outputs markdown or plain text + +## Feature Announcement Framework + +1. Problem context +2. What changed +3. Why it matters +4. Who benefits most +5. How to get started +6. Call to action and feedback channel + +## Communication Quality Checklist + +- [ ] Audience-specific framing is explicit. +- [ ] Outcomes and trade-offs are clear. +- [ ] Terminology is consistent across artifacts. +- [ ] Risks and dependencies are not hidden. +- [ ] Next actions and owners are specified. diff --git a/product-team/roadmap-communicator/references/communication-templates.md b/product-team/roadmap-communicator/references/communication-templates.md new file mode 100644 index 0000000..407437d --- /dev/null +++ b/product-team/roadmap-communicator/references/communication-templates.md @@ -0,0 +1,63 @@ +# Communication Templates + +## Stakeholder Update Email + +Subject: Product roadmap update - [Period] + +Hi [Audience], + +Here is the [weekly/monthly/quarterly] product update. + +- Progress: +- KPI movement: +- Risks/blockers: +- Decisions needed: +- Next period focus: + +Thanks, +[Owner] + +## User-Facing Release Notes Template + +# Release [Version/Date] + +## Highlights +- [User value outcome] + +## New +- [Feature + benefit] + +## Improved +- [Improvement + impact] + +## Fixed +- [Issue + user-facing resolution] + +## Known Limitations +- [If applicable] + +## Internal Release Notes Template + +# Internal Release [Version/Date] + +## Scope +- Included workstreams and commit range + +## Operational Notes +- Rollout plan +- Monitoring checks +- Rollback criteria + +## Risks +- Known issues and mitigations + +## Feature Announcement Template + +Title: [Outcome-focused headline] + +1. The problem: +2. The new capability: +3. Why this matters: +4. Who should use it: +5. How to start: +6. Feedback channel: diff --git a/product-team/roadmap-communicator/references/roadmap-templates.md b/product-team/roadmap-communicator/references/roadmap-templates.md new file mode 100644 index 0000000..e227f21 --- /dev/null +++ b/product-team/roadmap-communicator/references/roadmap-templates.md @@ -0,0 +1,44 @@ +# Roadmap Templates + +## Now / Next / Later Template + +### Now (0-1 quarter) +- Committed initiatives in active execution +- Success metrics and owners +- Dependencies and known risks + +### Next (1-2 quarters) +- Prioritized bets with confidence levels +- Discovery items needed before commit +- Resource assumptions + +### Later (2+ quarters) +- Strategic themes and directional intent +- Explicitly marked as non-commitment + +## Quarterly Roadmap Template + +| Quarter | Theme | Key Initiatives | Success Metrics | Risks | +|---|---|---|---|---| +| Q1 | | | | | +| Q2 | | | | | +| Q3 | | | | | +| Q4 | | | | | + +## Theme-Based Roadmap Template + +| Theme | Problem Statement | Initiatives | KPI Link | Owner | +|---|---|---|---|---| +| Activation | | | | | +| Retention | | | | | +| Expansion | | | | | + +## OKR-Aligned Roadmap Template + +| Objective | Key Result | Initiative | Milestone | Team | +|---|---|---|---|---| +| | | | | | + +Guideline: +- Every initiative should map to an objective or key result. +- Mark items without alignment as candidate de-scope. diff --git a/product-team/roadmap-communicator/scripts/changelog_generator.py b/product-team/roadmap-communicator/scripts/changelog_generator.py new file mode 100755 index 0000000..6e50535 --- /dev/null +++ b/product-team/roadmap-communicator/scripts/changelog_generator.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +"""Generate changelog sections from git log using conventional commit prefixes.""" + +import argparse +import subprocess +from collections import defaultdict + + +SECTIONS = { + "feat": "Features", + "fix": "Fixes", + "docs": "Documentation", + "refactor": "Refactors", + "test": "Tests", + "chore": "Chores", + "perf": "Performance", + "ci": "CI", + "build": "Build", + "style": "Style", + "revert": "Reverts", +} + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Generate changelog from git commits.") + parser.add_argument("--from", dest="from_ref", default="HEAD~50") + parser.add_argument("--to", dest="to_ref", default="HEAD") + parser.add_argument("--format", choices=["markdown", "text"], default="markdown") + return parser.parse_args() + + +def get_git_log(from_ref: str, to_ref: str) -> list[str]: + commit_range = f"{from_ref}..{to_ref}" + cmd = ["git", "log", "--pretty=format:%s", commit_range] + result = subprocess.run(cmd, check=True, capture_output=True, text=True) + lines = [line.strip() for line in result.stdout.splitlines() if line.strip()] + return lines + + +def group_commits(subjects: list[str]) -> dict[str, list[str]]: + grouped = defaultdict(list) + grouped["other"] = [] + + for subject in subjects: + commit_type = "other" + for prefix in SECTIONS: + if subject.startswith(f"{prefix}:"): + commit_type = prefix + break + grouped[commit_type].append(subject) + + return grouped + + +def render_markdown(grouped: dict[str, list[str]]) -> str: + out = ["# Changelog", ""] + ordered_types = list(SECTIONS.keys()) + ["other"] + for commit_type in ordered_types: + commits = grouped.get(commit_type, []) + if not commits: + continue + header = SECTIONS.get(commit_type, "Other") + out.append(f"## {header}") + for item in commits: + out.append(f"- {item}") + out.append("") + return "\n".join(out).rstrip() + "\n" + + +def render_text(grouped: dict[str, list[str]]) -> str: + out = [] + ordered_types = list(SECTIONS.keys()) + ["other"] + for commit_type in ordered_types: + commits = grouped.get(commit_type, []) + if not commits: + continue + header = SECTIONS.get(commit_type, "Other") + out.append(header.upper()) + for item in commits: + out.append(f"* {item}") + out.append("") + return "\n".join(out).rstrip() + "\n" + + +def main() -> int: + args = parse_args() + subjects = get_git_log(args.from_ref, args.to_ref) + grouped = group_commits(subjects) + + if args.format == "markdown": + print(render_markdown(grouped), end="") + else: + print(render_text(grouped), end="") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())