Skip to content

Creating Multi-line Ticket Descriptions: Gemini-Compatible Approaches

This guide addresses the specific constraints that Gemini faces when creating multi-line ticket descriptions, based on the limitations of the run_shell_command tool which executes commands via bash -c.

Understanding the Constraint

Gemini's execution environment has a key limitation: - Commands are executed via bash -c <command> - Complex shell constructs like heredocs cause "syntax error: unexpected end of file" - Escape sequences in echo -e are interpreted literally rather than as newlines

Primary Method: Write to File, Then Read

# Step 1: Write multi-line content to a temporary file
write_file(
    content="""## Bug Description
Application crashes on startup with specific configuration.

## Steps to Reproduce
1. Set DEBUG=true in environment
2. Launch application v2.1.0
3. Observe immediate crash

## Expected Behavior
Application should start normally.

## Actual Behavior
Segmentation fault occurs.

## Error Log
Segmentation fault (core dumped) Exit code: 139
## Environment
- OS: Ubuntu 22.04
- Version: 2.1.0""",
    file_path="/tmp/ticket_description.md"
)

# Step 2: Create ticket using the file content
run_shell_command(
    command='gira ticket create "Bug: Application crashes on startup" --description "$(cat /tmp/ticket_description.md)" --type bug --priority high'
)

# Step 3: Clean up
run_shell_command(command="rm /tmp/ticket_description.md")

Alternative: Using stdin (if supported)

Some CLIs support reading from stdin with -:

# Write to file
write_file(content="Multi-line\ndescription\nhere", file_path="/tmp/desc.txt")

# Try piping to stdin
run_shell_command(command="cat /tmp/desc.txt | gira ticket create 'My Ticket' --description -")

# Clean up
run_shell_command(command="rm /tmp/desc.txt")

Alternative Approaches for Gemini

1. JSON File Approach

If Gira supports JSON input:

# Create a JSON file with the ticket data
ticket_data = {
    "title": "Feature: New API Endpoint",
    "description": """## Summary
Implement user profile management endpoint.

## Requirements
- Support GET, PUT, DELETE
- Include authentication
- Return JSON responses""",
    "type": "feature",
    "priority": "high"
}

write_file(
    content=json.dumps(ticket_data, indent=2),
    file_path="/tmp/ticket.json"
)

# If Gira supports JSON input
run_shell_command(command="gira ticket create --from-json /tmp/ticket.json")

# Clean up
run_shell_command(command="rm /tmp/ticket.json")

2. Multiple Update Commands

Breaking down the description into multiple updates:

# Create ticket first
run_shell_command(
    command='gira ticket create "Complex Feature" --type feature --priority medium'
)

# Assume it returns GCM-XXX
ticket_id = "GCM-XXX"  # Would need to parse from output

# Build description in parts
parts = [
    "## Overview",
    "This feature implements a new API endpoint.",
    "",
    "## Technical Details",
    "- RESTful design",
    "- JSON responses",
    "- Bearer token auth"
]

# Create description file
write_file(content="\n".join(parts), file_path="/tmp/desc.md")

# Update ticket
run_shell_command(
    command=f'gira ticket update {ticket_id} --description "$(cat /tmp/desc.md)"'
)

# Clean up
run_shell_command(command="rm /tmp/desc.md")

3. Template-Based Approach

Create reusable templates:

# Bug report template
def create_bug_ticket(title, description, steps, expected, actual, priority="high"):
    template = f"""## Bug Description
{description}

## Steps to Reproduce
{steps}

## Expected Behavior
{expected}

## Actual Behavior
{actual}

## Additional Information
Report generated: {datetime.now().isoformat()}
"""

    # Write to temp file
    write_file(content=template, file_path="/tmp/bug_desc.md")

    # Create ticket
    run_shell_command(
        command=f'gira ticket create "{title}" --description "$(cat /tmp/bug_desc.md)" --type bug --priority {priority}'
    )

    # Clean up
    run_shell_command(command="rm /tmp/bug_desc.md")

# Usage
create_bug_ticket(
    title="Login fails with special characters",
    description="Users cannot login when password contains certain special characters",
    steps="1. Enter username\n2. Enter password with & or |\n3. Click login",
    expected="User should be logged in successfully",
    actual="Login fails with 'Invalid credentials' error"
)

Best Practices for Gemini

1. Always Use Temporary Files

  • Most reliable method in Gemini's environment
  • Preserves formatting exactly
  • Handles all special characters

2. Use Unique Filenames

import time
timestamp = int(time.time() * 1000)
temp_file = f"/tmp/gira_desc_{timestamp}.md"

3. Always Clean Up

try:
    write_file(content=description, file_path=temp_file)
    run_shell_command(command=f'gira ticket create "..." --description "$(cat {temp_file})"')
finally:
    run_shell_command(command=f"rm -f {temp_file}")

4. Verify File Creation

# Write file
write_file(content=description, file_path="/tmp/desc.md")

# Verify it exists
result = run_shell_command(command="ls -la /tmp/desc.md")
if "desc.md" in result:
    # Proceed with ticket creation
    pass

Comparison: Claude vs Gemini Approaches

Feature Claude (Heredoc) Gemini (Temp File)
Syntax Complexity High Low
Reliability High (in standard shell) High (in any environment)
Performance Better (no file I/O) Slightly slower (file I/O)
Special Characters Handled perfectly Handled perfectly
Debugging Harder Easier (can inspect file)
Cleanup Required No Yes

Example: Creating an Epic with Complex Description

# Gemini-compatible epic creation
epic_description = """## Project: E-commerce Platform Redesign

### Overview
Complete overhaul of the e-commerce platform to improve performance, user experience, and scalability.

### Goals
1. **Performance**: Achieve <100ms page load times
2. **Scalability**: Support 10x current traffic
3. **User Experience**: Implement modern, responsive design
4. **Security**: Enhance payment processing security

### Technical Scope

#### Backend
- Migrate from monolith to microservices
- Implement GraphQL API
- Add Redis caching layer
- PostgreSQL optimization

#### Frontend
- React 18 with TypeScript
- Server-side rendering
- Progressive Web App features
- Accessibility (WCAG 2.1 AA)

### Timeline
- **Phase 1** (Q1): Architecture design and planning
- **Phase 2** (Q2): Backend development
- **Phase 3** (Q3): Frontend development
- **Phase 4** (Q4): Testing and deployment

### Success Metrics
| Metric | Current | Target |
|--------|---------|--------|
| Page Load | 3.2s | <100ms |
| Conversion | 2.1% | 3.5% |
| Uptime | 99.5% | 99.99% |

### Dependencies
- [ ] Infrastructure team approval
- [ ] Security audit completion
- [ ] Design system finalization
- [ ] Budget approval ($2.5M)

### Risks
1. **Technical Debt**: Legacy system integration challenges
2. **Timeline**: Aggressive Q4 deadline
3. **Resources**: Limited senior developers
4. **Migration**: Zero-downtime requirement"""

# Write to file
write_file(content=epic_description, file_path="/tmp/epic_desc.md")

# Create epic
run_shell_command(
    command='gira epic create "E-commerce Platform Redesign" --description "$(cat /tmp/epic_desc.md)"'
)

# Clean up
run_shell_command(command="rm /tmp/epic_desc.md")

Conclusion

While Claude's heredoc approach is elegant and efficient in standard shell environments, Gemini's constraints require a different strategy. The temporary file method, though requiring cleanup, provides:

  1. 100% reliability in Gemini's execution environment
  2. Perfect formatting preservation
  3. Easy debugging (can inspect the temp file if needed)
  4. Compatibility with any shell environment

This approach ensures that Gemini can create rich, multi-line ticket descriptions reliably, maintaining all the formatting and structure needed for comprehensive project management.