feat: add roadmap communicator skill with changelog generator
This commit is contained in:
92
product-team/roadmap-communicator/SKILL.md
Normal file
92
product-team/roadmap-communicator/SKILL.md
Normal file
@@ -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.
|
||||
@@ -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:
|
||||
@@ -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.
|
||||
98
product-team/roadmap-communicator/scripts/changelog_generator.py
Executable file
98
product-team/roadmap-communicator/scripts/changelog_generator.py
Executable file
@@ -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())
|
||||
Reference in New Issue
Block a user