Skip to main content

Bidirectional Comment Synchronization

Overview

The sync tool now supports bidirectional comment sync between JPD and GitHub with full author attribution. Since native author sync isn't possible (comments posted via API use the API token's identity), we format comments with clear author references.


Features

Bidirectional Sync - JPD ↔ GitHub
Author Attribution - Clear links to original author profiles
Deduplication - Hidden markers prevent infinite loops
ADF Support - Converts Jira's Atlassian Document Format to Markdown
Formatting Preservation - Maintains bold, italic, links, code blocks
Automatic Detection - Only syncs new comments, not already-synced ones


Comment Format

JPD → GitHub

**[Jane Doe](https://your-domain.atlassian.net/people/USER_ID)** commented in JPD:

This is the original comment text from JPD with **formatting** preserved.

<!-- comment-sync:{"synced_from":"jpd","source_comment_id":"12345","sync_hash":"abc...","synced_at":"2025-12-23T21:00:00.000Z"}-->

GitHub → JPD

**[john-dev](https://github.com/john-dev)** commented in GitHub:

This is the original comment text from GitHub with **formatting** preserved.

<!-- comment-sync:{"synced_from":"github","source_comment_id":"67890","sync_hash":"def...","synced_at":"2025-12-23T21:00:00.000Z"}-->

How It Works

1. Comment Detection

On each sync run, the system:

  1. Fetches all comments from both JPD and GitHub
  2. Parses them into a standardized format
  3. Checks for sync markers to identify already-synced comments
  4. Identifies new comments that need syncing

2. Author Attribution

Since we can't post comments as the original author, we format them with:

  • Author name as a link to their profile
  • Source system indicator (JPD or GitHub)
  • Original comment body with formatting preserved

3. Deduplication

Each synced comment includes a hidden HTML marker with:

  • synced_from: Source system (jpd/github)
  • source_comment_id: Original comment ID
  • sync_hash: MD5 hash of content (for change detection)
  • synced_at: Timestamp

This prevents:

  • Syncing the same comment multiple times
  • Creating infinite loops (A→B→A→B...)
  • Re-syncing unchanged comments

4. Format Conversion

JPD (ADF) → Markdown:

  • Paragraphs
  • Headings (H1-H6)
  • Bold, italic, code
  • Bullet and ordered lists
  • Code blocks with syntax highlighting
  • Links

Markdown → JPD (ADF):

  • Paragraphs
  • Basic text formatting
  • Simplified structure (complex Markdown may be flattened)

Configuration

Comment sync is automatically enabled when using bidirectional sync mode:

sync:
direction: bidirectional # Required for comment sync

No additional configuration needed!


Usage Examples

Example 1: PM Comment in JPD

Scenario: PM adds a comment in JPD

  1. PM opens PROJ-10 in JPD
  2. PM adds comment: "We need to prioritize the mobile UI first"
  3. Sync runs
  4. Comment appears in GitHub issue #5:
**[Sarah Johnson](https://your-domain.atlassian.net/people/USER_ID)** commented in JPD:

We need to prioritize the mobile UI first

Example 2: Dev Comment in GitHub

Scenario: Developer adds implementation notes in GitHub

  1. Dev opens GitHub issue #5
  2. Dev adds comment: "I've broken this into 3 subtasks, see #12, #13, #14"
  3. Sync runs
  4. Comment appears in JPD PROJ-10:
**[john-dev](https://github.com/john-dev)** commented in GitHub:

I've broken this into 3 subtasks, see #12, #13, #14

Example 3: Threaded Discussion

Scenario: PM and Dev discuss implementation

  1. PM in JPD: "Should we use React Native or Flutter?"
  2. ✅ Syncs to GitHub
  3. Dev in GitHub: "@pm-user I recommend React Native for better integration"
  4. ✅ Syncs to JPD
  5. PM in JPD: "Agreed, let's proceed with React Native"
  6. ✅ Syncs to GitHub

Result: Full conversation visible in both systems!


Testing Comment Sync

Step 1: Add Comment in JPD

# Manually add a comment in JPD UI:
# https://your-domain.atlassian.net/jira/polaris/projects/YOUR_PROJECT/ideas/view/ISSUE_ID

# Or via API:
curl -X POST -u "$JPD_EMAIL:$JPD_API_KEY" \
-H "Content-Type: application/json" \
"$JPD_BASE_URL/rest/api/3/issue/PROJ-10/comment" \
-d '{
"body": {
"type": "doc",
"version": 1,
"content": [{
"type": "paragraph",
"content": [{
"type": "text",
"text": "Test comment from JPD API"
}]
}]
}
}'

Step 2: Run Sync

cd /Users/james/Sites/Expedition/jpd-to-github-connector
pnpm run dev

Step 3: Verify in GitHub

# Check comments on GitHub issue
gh issue view 5 --comments

Or visit: https://github.com/YOUR_ORG/YOUR_REPO/issues/5

Step 4: Add Comment in GitHub

# Via GitHub UI or API
gh issue comment 5 --body "Test comment from GitHub CLI"

Step 5: Run Sync Again

pnpm run dev

Step 6: Verify in JPD

Visit JPD and check PROJ-10 for the new comment.


Sync Behavior

What Gets Synced

✅ New comments added after last sync
✅ Original author name and profile link
✅ Comment formatting (bold, italic, links, code)
✅ Comment timestamp (in metadata)

What Doesn't Get Synced

❌ Comment edits (only initial post)
❌ Comment deletions
❌ Comment reactions/likes
❌ @mentions (preserved as text, not functional)
❌ Attachments/images (would need separate handling)

Limitations

  1. Native Author: Comments appear as the API user, not original author
  2. One-Way Edits: If someone edits a comment after sync, edits don't propagate
  3. @Mentions: Mentions like @username are preserved but don't notify across systems
  4. Attachments: File attachments need manual handling
  5. Threading: Reply threads are flattened (all comments at top level)

Advanced: Comment Sync Internals

CommentSyncManager Class

Located in src/comments/comment-sync-manager.ts

Key methods:

// Format a comment for cross-posting
CommentSyncManager.formatComment(comment, targetSystem)

// Extract sync metadata from comment body
CommentSyncManager.extractSyncMetadata(commentBody)

// Check if comment should be synced
CommentSyncManager.shouldSyncComment(comment, existingSyncedComments)

// Parse JPD comment to standard format
CommentSyncManager.parseJpdComment(jpdComment, jpdBaseUrl)

// Parse GitHub comment to standard format
CommentSyncManager.parseGitHubComment(githubComment)

// Convert ADF to Markdown
CommentSyncManager.convertJiraTextToMarkdown(jiraBody)

Sync Flow

┌─────────────────────────────────────────────────┐
│ Comment Sync Process │
└─────────────────────────────────────────────────┘

1. Get all synced issue pairs (JPD key ↔ GitHub #)
2. For each pair:
├─ Fetch JPD comments
├─ Fetch GitHub comments
├─ Parse both to standard format
├─ Filter out already-synced comments
├─ Sync JPD → GitHub (new JPD comments)
└─ Sync GitHub → JPD (new GitHub comments)
3. Add sync markers to prevent duplicates
4. Log sync status

Data Structures

interface Comment {
id: string;
author: {
name: string;
displayName?: string;
profileUrl: string;
avatarUrl?: string;
};
body: string;
created: string;
updated?: string;
source: 'jpd' | 'github';
sourceId: string;
}

interface CommentSyncMetadata {
synced_from: 'jpd' | 'github';
source_comment_id: string;
sync_hash: string;
synced_at: string;
}

Troubleshooting

Comments Not Syncing

Check 1: Bidirectional mode enabled?

sync:
direction: bidirectional # Not just "jpd-to-github"

Check 2: Debug logging

DEBUG=true pnpm run dev

Look for: Syncing JPD comment X to GitHub issue #Y

Duplicate Comments

Cause: Sync markers may be missing or corrupted

Solution: Hidden markers should be present in comment text. Check:

# In GitHub comment body
<!-- comment-sync:{...}-->

Format Issues

Problem: ADF not converting correctly

Solution: Update convertAdfToMarkdown in CommentSyncManager for specific formatting needs

Permission Errors

JPD: Ensure API user has "Add Comments" permission
GitHub: Token needs repo scope (includes commenting)


Future Enhancements

Potential improvements:

  • Comment Edit Sync - Track and sync comment edits
  • Comment Deletion Sync - Delete comments when source is deleted
  • Attachment Sync - Upload and link attachments
  • @Mention Translation - Convert mentions across systems
  • Reaction Sync - Sync emoji reactions/likes
  • Thread Preservation - Maintain comment threading
  • Selective Sync - Config option to enable/disable comment sync per issue type

Summary

Comment sync provides:

  • Full visibility - All discussions visible in both systems
  • Clear attribution - Always know who said what
  • No duplicates - Smart deduplication prevents loops
  • Format preservation - Markdown and ADF handled correctly
  • Zero configuration - Works automatically in bidirectional mode

PM's stay in JPD, devs stay in GitHub, everyone sees all comments! 🎉