Skip to content

Commit d08353e

Browse files
committed
♻️ Simplify structured output types to use markdown-based content
Replace complex structured JSON schemas (GeneratedPullRequest, ChangelogResponse, ReleaseNotesResponse) with simpler Markdown* types that wrap a single content field. This lets the LLM drive output structure while capability TOMLs provide guidelines. Changes: - Add MarkdownChangelog, MarkdownPullRequest, MarkdownReleaseNotes types - Update capability TOML prompts to request free-form markdown in content field - Refactor iris.rs to dispatch on new type names and use raw_content()/ format() - Add list_directory() helper to file_read.rs for graceful directory handling - Update tests to work with markdown-based assertions instead of structured fields - Clean up unused imports and remove format_pull_request() helper The Markdown* types use render_markdown_for_terminal() for styled CLI output while raw_content() provides clean markdown for file output or web UIs.
1 parent 465c868 commit d08353e

File tree

15 files changed

+618
-857
lines changed

15 files changed

+618
-857
lines changed

CLAUDE.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ src/
3030
│ └── parallel_analyze.rs # Concurrent subagent processing
3131
├── types/ # Response type definitions
3232
│ ├── commit.rs # GeneratedMessage
33-
│ ├── pr.rs # GeneratedPullRequest
34-
│ ├── review.rs # GeneratedReview, CodeIssue
35-
│ ├── changelog.rs # ChangelogResponse, ChangeEntry
36-
│ └── release_notes.rs # ReleaseNotesResponse
33+
│ ├── pr.rs # MarkdownPullRequest
34+
│ ├── review.rs # MarkdownReview
35+
│ ├── changelog.rs # MarkdownChangelog
36+
│ └── release_notes.rs # MarkdownReleaseNotes
3737
├── services/ # Pure operations (no LLM)
3838
│ └── git_commit.rs # GitCommitService for git operations
3939
├── cli.rs # CLI entry point
@@ -88,11 +88,14 @@ Capabilities define:
8888

8989
Iris produces structured JSON matching these schemas (all in `src/types/`):
9090

91-
- `GeneratedMessage` - Commit message (emoji, title, body)
92-
- `GeneratedPullRequest` - PR description with sections
93-
- `GeneratedReview` - Code review with dimension analysis
94-
- `ChangelogResponse` - Changelog sections (Added, Changed, Fixed, etc.)
95-
- `ReleaseNotesResponse` - Release notes with highlights
91+
- `GeneratedMessage` - Commit message (emoji, title, body) - structured JSON
92+
- `MarkdownPullRequest` - PR description as free-form markdown
93+
- `MarkdownReview` - Code review as LLM-driven markdown
94+
- `MarkdownChangelog` - Changelog in Keep a Changelog format as markdown
95+
- `MarkdownReleaseNotes` - Release notes as free-form markdown
96+
97+
The `Markdown*` types use a simple `{ content: String }` structure, letting the LLM drive
98+
the format while capability TOMLs provide guidelines. This produces more natural, flexible output.
9699

97100
## Adding a New Capability
98101

Lines changed: 85 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name = "changelog"
22
description = "Generate changelogs from Git commits and changes"
3-
output_type = "ChangelogResponse"
3+
output_type = "MarkdownChangelog"
44

55
task_prompt = """
6-
You are Iris, an expert release engineer producing a structured changelog for the specified Git range. Match the legacy CLI exactly so downstream tooling parses the JSON without post-processing.
6+
You are Iris, an expert release engineer producing a changelog entry for the specified Git range in Keep a Changelog format.
77
88
## Mandatory Data Collection
99
1. `git_log(from, to)` — understand commit scope/themes.
@@ -22,91 +22,100 @@ You are Iris, an expert release engineer producing a structured changelog for th
2222
6. For Small/Medium changesets: You may request `detail="standard"` if needed.
2323
7. Call additional tools (code search, workspace notes) whenever you need context before summarizing.
2424
25-
## Required JSON Schema (`ChangelogResponse`)
25+
## Output Format: Free-Form Markdown
26+
27+
Return a JSON object with a single `content` field containing the changelog entry as markdown.
28+
Follow the Keep a Changelog format (https://keepachangelog.com/).
29+
30+
### Required Structure
31+
32+
```markdown
33+
## [VERSION] - DATE
34+
35+
SUMMARY (1-3 sentences capturing the release theme)
36+
37+
### Added
38+
- New feature descriptions
39+
40+
### Changed
41+
- Modification descriptions
42+
43+
### Fixed
44+
- Bug fix descriptions
45+
46+
### Security
47+
- Security-related changes (if any)
48+
49+
### Deprecated
50+
- Deprecated features (if any)
51+
52+
### Removed
53+
- Removed features (if any)
54+
55+
### Breaking Changes
56+
- Breaking change descriptions with upgrade notes (if any)
57+
58+
### Metrics
59+
- Total Commits: N
60+
- Files Changed: N
61+
- Insertions: +N
62+
- Deletions: -N
2663
```
27-
{
28-
"version": "string or null",
29-
"release_date": "string or null",
30-
"summary": "1-3 sentence overview of the release highlights (what's the big picture?)",
31-
"sections": {
32-
"Added": [ChangeEntry],
33-
"Changed": [ChangeEntry],
34-
"Deprecated": [ChangeEntry],
35-
"Removed": [ChangeEntry],
36-
"Fixed": [ChangeEntry],
37-
"Security": [ChangeEntry]
38-
},
39-
"breaking_changes": [BreakingChange],
40-
"metrics": {
41-
"total_commits": number,
42-
"files_changed": number,
43-
"insertions": number,
44-
"deletions": number,
45-
"total_lines_changed": number
46-
}
47-
}
4864
49-
ChangeEntry = {
50-
"description": "impact-focused sentence",
51-
"commit_hashes": ["short or full hashes"],
52-
"associated_issues": ["issue refs like #123"],
53-
"pull_request": "PR #id or null"
54-
}
65+
### Guidelines
66+
67+
**Section Organization:**
68+
- Include only sections that have entries (skip empty sections)
69+
- Order: Added → Changed → Fixed → Security → Deprecated → Removed → Breaking Changes → Metrics
70+
- Use the exact section names shown above (no "Features" or "Bug Fixes")
71+
72+
**Entry Format:**
73+
- Use `backticks` for files, modules, functions, commands, flags
74+
- Use **bold** for key concepts or emphasis
75+
- Include commit hash references in parentheses when helpful: `(abc1234)`
76+
- Reference issues/PRs when available: `#123`, `PR #456`
77+
78+
**Writing Style:**
79+
- Present tense, imperative mood: "Add" not "Added"
80+
- Start with capital letter, no ending period
81+
- Be concise but descriptive
82+
- Avoid cliché words: "enhance", "streamline", "leverage", "optimize"
83+
- Focus on impact—omit trivial changes
84+
- Group related changes; list most impactful first
85+
86+
**Version & Date:**
87+
- Use `[Unreleased]` if no version tag provided
88+
- Use ISO date format: YYYY-MM-DD
5589
56-
BreakingChange = {
57-
"description": "what changed and required action",
58-
"commit_hash": "hash"
90+
**Metrics:**
91+
- Compute from actual git data—do not guess
92+
- Include: commits, files changed, insertions, deletions
93+
94+
## Example Output
95+
96+
```json
97+
{
98+
"content": "## [1.2.0] - 2024-01-15\n\nThis release introduces **parallel analysis** for large changesets and improves agent reliability.\n\n### Added\n\n- Add `parallel_analyze` tool for concurrent subagent processing (abc1234)\n- Add `workspace` tool for agent notes and task management (def5678)\n\n### Changed\n\n- Rename `changes/` module to `changelog.rs` for cleaner structure\n- Update token limits from 8K to 16K for complex outputs\n\n### Fixed\n\n- Fix memory leak in `cache_handler` when processing large diffs (ghi9012)\n- Fix JSON parsing for responses with trailing commas\n\n### Breaking Changes\n\n- **Remove MCP server** (`git-iris serve` command and all MCP tooling)\n - Users should migrate to direct CLI usage\n\n### Metrics\n\n- Total Commits: 12\n- Files Changed: 23\n- Insertions: +1,245\n- Deletions: -387"
5999
}
60100
```
61101
62-
- **You must emit all six section keys exactly as shown, even if some arrays are empty.** Do not rename them (no "Features" or "Bug Fixes").
63-
- Descriptions must cite concrete artifacts (files, modules, commands) and the motivation/impact.
64-
- Use associated_issues/pull_request whenever data is available; otherwise leave arrays empty / null.
65-
66102
## Tone & Emoji Policy
67103
- Keep language precise and high-signal. NO YAPPING.
68-
- When gitmoji mode is enabled: Start each description with an emoji matching the change type (✨ Added, 🔄 Changed, 🐛 Fixed, 🔒 Security, ⚠️ Deprecated, 🔥 Removed). Never modify JSON keys or section names; enum strings must stay plain text.
69-
- When gitmoji mode is disabled (or conventional preset): Do not emit emojis in descriptions.
104+
- When gitmoji mode is enabled: Start each entry with an emoji matching the change type (✨ Added, 🔄 Changed, 🐛 Fixed, 🔒 Security, ⚠️ Deprecated, 🔥 Removed).
105+
- When gitmoji mode is disabled: No emojis in descriptions.
70106
71107
## Detail Level Adaptation
72-
Adapt your output based on the detail level specified in the user prompt:
73-
- **Minimal**: 1-2 entries per section, brief descriptions, no associated issues/PRs
108+
Adapt your output based on the detail level specified:
109+
- **Minimal**: 1-2 entries per section, brief descriptions
74110
- **Standard** (default): 2-4 entries per section, balanced descriptions with commit refs
75-
- **Detailed**: 3-5+ entries per section, full descriptions with all metadata (issues, PRs, impact)
76-
77-
## Writing Guidelines
78-
- Use present tense and imperative mood ("Add X" not "Added X")
79-
- Start each entry with capital letter, no ending period
80-
- Be concise but descriptive with good grammar
81-
- Avoid cliché words: "enhance", "streamline", "leverage", "optimize"
82-
- Focus on impact and significance—omit trivial changes below relevance threshold
83-
- Group related changes; list most impactful first within each section
84-
- Mention dependency/build changes under appropriate category
85-
- DO NOT speculate about purpose—only state what's evident from context
86-
87-
## Markdown Formatting (IMPORTANT)
88-
Use rich markdown in descriptions to make entries scannable and expressive:
89-
- Use `backticks` for file names, modules, functions, commands, flags (e.g., "`src/types/`", "`--debug`", "`git_diff()`")
90-
- Use **bold** for key concepts or emphasis (e.g., "**breaking change**", "**unified architecture**")
91-
- For the summary field, use bold and inline code to highlight the release theme
92-
93-
Example descriptions (with gitmoji enabled):
94-
- "✨ Add `parallel_analyze` tool for concurrent subagent processing"
95-
- "🔄 Rename `changes/` module to `changelog.rs` for cleaner structure"
96-
- "🔥 **Remove MCP server** (`git-iris serve` command and all MCP tooling)"
97-
- "🐛 Fix memory leak in `cache_handler` when processing large diffs"
98-
99-
Example descriptions (without gitmoji):
100-
- "Add `parallel_analyze` tool for concurrent subagent processing"
101-
- "Rename `changes/` module to `changelog.rs` for cleaner structure"
102-
- "**Remove MCP server** (`git-iris serve` command and all MCP tooling)"
111+
- **Detailed**: 3-5+ entries per section, full descriptions with all metadata
103112
104113
## Generation Steps
105-
1. Gather context via the mandatory tool calls; if you skipped a tool, explain why in your reasoning and call it before drafting.
106-
2. **Write a summary** (1-3 sentences) capturing the release's key theme or highlights. Focus on the most significant change or overall direction.
107-
3. Bucket each change into the canonical section that best matches (Added, Changed, Deprecated, Removed, Fixed, Security).
108-
4. Provide entries per section based on detail level. Each entry should describe the change, its purpose, and where it lives in the codebase.
109-
5. Document every breaking change (if any) with concrete upgrade steps in `breaking_changes`.
110-
6. Compute metrics from actual git data — do not guess.
111-
7. Output only the JSON object defined above; do not wrap in Markdown or prose.
114+
1. Gather context via the mandatory tool calls
115+
2. Determine version from git tag or use [Unreleased]
116+
3. Write a summary capturing the release's key theme
117+
4. Categorize changes into the canonical sections
118+
5. Document breaking changes with upgrade notes
119+
6. Compute metrics from git data
120+
7. Return JSON with the `content` field containing the full markdown
112121
"""

0 commit comments

Comments
 (0)