Skip to content

Conversation

@TabishB
Copy link
Contributor

@TabishB TabishB commented Oct 24, 2025

Summary

Fixes #225 - Changes now display their change-id instead of "Untitled Change" when no title header is present.

Changes

  • Template update: Added # Change: [description] header to proposal template in agents-template.ts
  • Smarter fallback: Modified extractTitle() to use the change-id (which is already meaningful and kebab-cased) instead of the generic "Untitled Change"
  • API update: Updated all extractTitle() call sites to pass the changeName parameter

Impact

  • New proposals: Will include title header by following updated template
  • Existing proposals: Will display their change-id as title (better UX than "Untitled Change")
  • No breaking changes: Backward compatible with all existing proposals

Test Plan

  • Verify new proposals include title header when following template
  • Verify existing proposals without titles display change-id
  • Verify proposals with titles continue to display correctly
  • Test openspec show <change> --json --deltas-only output format

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Change templates now include a structured "Change" header for clearer documentation.
  • Improvements

    • Title detection for changes is more robust (case-insensitive, multi-line) and now falls back to the change identifier instead of a generic placeholder.
    • Minor formatting cleanups in change display flows with no behavioral differences beyond title resolution.

Fixes #225 by addressing mismatch between proposal template and title extraction:

- Updated proposal template to include `# Change: [description]` header
- Changed extractTitle fallback from "Untitled Change" to change-id
- Updated all extractTitle call sites to pass changeName parameter

This ensures both new and existing proposals display meaningful titles.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 24, 2025

Walkthrough

Refactors title extraction to accept a changeName fallback and updates call sites; adds a "# Change: ..." header line to the agents proposal template so titles are discoverable by the extractor.

Changes

Cohort / File(s) Summary
Title extraction refactor
src/commands/change.ts
extractTitle(content: string)extractTitle(content: string, changeName: string). All callers updated to pass changeName. Fallback now returns changeName when no title header is found; regex uses multi-line/case-insensitive matching.
Proposal template update
src/core/templates/agents-template.ts
Inserted a # Change: [Brief description of change] header line into the agents proposal template text (documentation-only change).

Sequence Diagram(s)

sequenceDiagram
  participant CLI as CLI (change show/list)
  participant ChangeCmd as ChangeCommand
  participant Extract as extractTitle(content, changeName)

  CLI->>ChangeCmd: request show/list for change-id
  ChangeCmd->>Extract: extractTitle(fileContent, change-id)
  alt file contains "# Change: Title" or "# Title"
    Extract-->>ChangeCmd: return parsed Title
  else no header found
    Extract-->>ChangeCmd: return change-id (fallback)
  end
  ChangeCmd-->>CLI: respond with change metadata (includes title)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Pay attention to: extractTitle regex flags and correctness, all updated call sites in src/commands/change.ts, and the template insertion for formatting/whitespace.

Poem

🐰 I hopped through files with a nibble and name,
Found titles adrift in a template's frame,
I stitched a header, taught code to seek,
Now no change is nameless, each one unique,
A tiny hop made the titles tame.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "fix: use change-id as fallback title instead of "Untitled Change"" directly describes the primary code change in the changeset. It clearly communicates the main technical modification—updating the fallback behavior of the extractTitle() method to use the changeName parameter instead of a hardcoded string. The title is specific, concise, and conveys meaningful information about the core fix, avoiding generic or vague language.
Linked Issues Check ✅ Passed The pull request successfully addresses all primary coding objectives from issue #225. The extractTitle() method signature has been updated to accept a changeName parameter, all call sites have been modified to pass this parameter, and the fallback behavior now returns changeName instead of the hardcoded 'Untitled Change' string. Additionally, the agents-template.ts has been updated to include the "# Change: [Brief description of change]" header, resolving the mismatch between the template structure and title extraction logic that was identified as the root cause.
Out of Scope Changes Check ✅ Passed All code changes in this pull request are directly scoped to the objectives of issue #225. The modifications to extractTitle() in src/commands/change.ts implement the required fallback logic fix, the updates to all call sites ensure the changeName parameter is properly propagated, and the template update in agents-template.ts addresses the root cause by including the required Change header. Minor formatting changes around blank lines noted in the summary are incidental cleanup related to the main changes and do not introduce unrelated functionality or out-of-scope modifications.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-untitled-change-fallback

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 68d3481 and 8c6edf9.

📒 Files selected for processing (1)
  • src/commands/change.ts (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/commands/change.ts (1)
src/core/schemas/change.schema.ts (1)
  • Change (42-42)
🔇 Additional comments (3)
src/commands/change.ts (3)

31-31: LGTM!

Formatting adjustments with no functional impact.

Also applies to: 52-52, 54-54, 60-60


70-70: LGTM!

All call sites correctly updated to pass changeName to the refactored extractTitle method. The parameter is guaranteed to be defined at each call site by the surrounding logic.

Also applies to: 127-127, 162-162


261-263: LGTM! Fallback logic now uses meaningful change-id.

The refactored extractTitle method correctly addresses issue #225:

  • Signature updated to accept changeName parameter
  • Regex enhanced with i (case-insensitive) and m (multiline) flags for more robust matching
  • Fallback changed from generic "Untitled Change" to the meaningful changeName (change-id)

The multiline flag makes the matcher more resilient to blank lines at the top of proposals, and the case-insensitive flag handles variations like "# change:" or "# CHANGE:" gracefully.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/commands/change.ts (1)

261-263: LGTM! Fallback logic now uses change-id.

The refactored extractTitle() method correctly uses changeName as the fallback instead of the hardcoded 'Untitled Change' string. The regex pattern /^#\s+(?:Change:\s+)?(.+)$/m properly matches both # Title and # Change: Title formats, and the .+ ensures empty headers won't match.

Optional: Consider case-insensitive matching for "Change:"

For more lenient parsing, you could make "Change:" case-insensitive:

-  const match = content.match(/^#\s+(?:Change:\s+)?(.+)$/m);
+  const match = content.match(/^#\s+(?:Change:\s+)?(.+)$/im);

This would match # change: Title or # CHANGE: Title as well. However, since the template uses Change: with proper casing, the current implementation is acceptable.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ab438f and 68d3481.

📒 Files selected for processing (2)
  • src/commands/change.ts (5 hunks)
  • src/core/templates/agents-template.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/commands/change.ts (1)
src/core/schemas/change.schema.ts (1)
  • Change (42-42)
🔇 Additional comments (2)
src/core/templates/agents-template.ts (1)

163-164: LGTM! Template now includes title header.

The addition of # Change: [Brief description of change] to the proposal template ensures new proposals will include a title header that extractTitle() can parse. This aligns with the fix and addresses the root cause from issue #225.

src/commands/change.ts (1)

70-70: All call sites correctly updated.

All three invocations of extractTitle() have been properly updated to pass the changeName parameter:

  • Line 70: show() method with validated changeName
  • Line 127: list() JSON mode within the map iteration
  • Line 162: list() long format within the for loop

Each call site has changeName available in scope, ensuring the fallback mechanism works correctly.

Also applies to: 127-127, 162-162

TabishB and others added 2 commits October 24, 2025 15:53
Makes the extractTitle regex case-insensitive to handle variations like
"# change:" or "# CHANGE:" in addition to "# Change:".
@TabishB TabishB merged commit 92b4546 into main Oct 25, 2025
7 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Nov 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Changes show as "Untitled Change" when following official proposal template

2 participants