diff --git a/features/steps/ticket_steps.py b/features/steps/ticket_steps.py index 276eb27..92b75a3 100644 --- a/features/steps/ticket_steps.py +++ b/features/steps/ticket_steps.py @@ -424,6 +424,15 @@ def step_created_ticket_contains(context, text): assert text in content, f"Ticket does not contain '{text}'\nContent: {content}" +@then(r'the created ticket should not contain "(?P[^"]+)"') +def step_created_ticket_not_contains(context, text): + """Assert the most recently created ticket does not contain text.""" + ticket_id = context.last_created_id + ticket_path = Path(context.test_dir) / '.tickets' / f'{ticket_id}.md' + content = ticket_path.read_text() + assert text not in content, f"Ticket should not contain '{text}'\nContent: {content}" + + @then(r'the created ticket should have field "(?P[^"]+)" with value "(?P[^"]+)"') def step_created_ticket_has_field(context, field, value): """Assert the most recently created ticket has a field with value.""" diff --git a/features/ticket_creation.feature b/features/ticket_creation.feature index 7cc0776..eb2d944 100644 --- a/features/ticket_creation.feature +++ b/features/ticket_creation.feature @@ -96,3 +96,14 @@ Feature: Ticket Creation When I run "ticket create 'First ticket'" Then the command should succeed And the tickets directory should exist + + Scenario: Design headings are adjusted to proper nesting level + When I run "ticket create 'Design doc' --design '# Main Plan\n\nThis is the plan.\n\n## Section 1\n\nDetails here.'" + Then the command should succeed + And the created ticket should contain "### Main Plan" + And the created ticket should contain "#### Section 1" + + Scenario: Design without headings is unchanged + When I run "ticket create 'Simple design' --design 'Just plain text here'" + Then the command should succeed + And the created ticket should contain "Just plain text here" diff --git a/ticket b/ticket index 452adda..2248f46 100755 --- a/ticket +++ b/ticket @@ -77,6 +77,25 @@ _sed_i() { sed "$@" "$file" > "$tmp" && mv "$tmp" "$file" } +# Adjust markdown heading levels for design documents +# Design docs are nested under ## Design, so all headings need to be h3 or deeper +adjust_design_headings() { + local content="$1" + + # Convert literal \n to actual newlines for processing + content=$(echo -e "$content") + + # Check if content has any h1 or h2 headings + if ! echo "$content" | grep -q '^##\? '; then + # No h1/h2 headings found, assume already properly formatted + echo "$content" + return + fi + + # Add two levels to all headings (# -> ###, ## -> ####, etc.) + echo "$content" | sed 's/^#/###/' +} + # Generate ticket ID from directory name + random string generate_id() { local dir_name @@ -217,7 +236,7 @@ cmd_create() { if [[ -n "$design" ]]; then echo "## Design" echo "" - echo "$design" + adjust_design_headings "$design" echo "" fi if [[ -n "$acceptance" ]]; then @@ -1422,9 +1441,31 @@ cmd_migrate_beads() { file = dir "/" id ".md" count++ print "Migrated: " id + in_design = 0 next } - file { print > file } + file { + # Check if this is a top-level section header (exits Design section) + if ($0 ~ /^## (Acceptance Criteria|Notes|Blockers|Blocking|Children|Linked)$/) { + in_design = 0 + print > file + next + } + + # Track when we enter Design section + if ($0 == "## Design") { + in_design = 1 + print > file + next + } + + # Adjust heading levels inside Design section + if (in_design && $0 ~ /^##? /) { + gsub(/^#/, "###", $0) + } + + print > file + } END { if (file) close(file); print "Migrated " count " tickets from beads" } ' }