> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sudocode.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# sudocode sync

> Synchronize data between markdown, JSONL, and database

## Syntax

```bash theme={null}
sudocode sync [options]
```

## Description

The `sync` command manages data flow between sudocode's 3-layer storage system:

**Markdown Files** ↔ **JSONL Files** ↔ **SQLite Database**

Use `sync` to:

* Synchronize after git pull (update local database)
* Sync after manual markdown edits
* Force a specific sync direction
* Watch for changes and auto-sync
* Troubleshoot sync issues

<Note>
  Most commands automatically sync when needed. Use manual sync after external changes (git pull, manual file edits) or when troubleshooting.
</Note>

## Storage Architecture

sudocode uses a 3-layer storage system:

<Steps>
  <Step title="Layer 1: Markdown Files">
    Human-readable spec and issue files in `.sudocode/specs/` and `.sudocode/issues/`

    **Purpose:** Version control, human editing, readability
  </Step>

  <Step title="Layer 2: JSONL Files">
    Line-delimited JSON in `.sudocode/specs.jsonl` and `.sudocode/issues.jsonl`

    **Purpose:** Git-friendly structured data, source of truth
  </Step>

  <Step title="Layer 3: SQLite Database">
    Local database `.sudocode/sudocode.db`

    **Purpose:** Fast queries, relationships, views
  </Step>
</Steps>

**Data flow:**

* **User edits markdown** → Sync to JSONL → Import to database
* **CLI updates database** → Export to JSONL → Sync to markdown

## Options

<ParamField path="--watch" type="boolean">
  Watch for file changes and auto-sync

  **Example:** `--watch`

  Starts a file watcher that automatically syncs when files change. Press Ctrl+C to stop.

  **Debounce:** 2000ms (2 seconds) delay to batch rapid changes
</ParamField>

<ParamField path="--from-markdown" type="boolean">
  Force sync FROM markdown TO database

  **Example:** `--from-markdown`

  Always syncs in this direction, regardless of file modification times.

  Use after: Manual markdown edits, git pull with markdown changes
</ParamField>

<ParamField path="--to-markdown" type="boolean">
  Force sync FROM database TO markdown

  **Example:** `--to-markdown`

  Always syncs in this direction, regardless of file modification times.

  Use after: CLI operations that updated database only
</ParamField>

## Examples

### Automatic Direction Detection

Let sudocode determine sync direction:

```bash theme={null}
sudocode sync
```

<Accordion title="Expected output (markdown is newer)">
  ```
  Detecting sync direction...
    Spec markdown files are newer (2025-10-29 14:30:00 > 2025-10-29 14:00:00)

  → Syncing FROM markdown TO database (markdown is newer)

  Syncing from markdown to database...
    Found 12 spec files
    ✓ updated spec SPEC-001
    ✓ updated spec SPEC-002
    ...
    Found 47 issue files
    ✓ updated issue ISSUE-001
    ✓ updated issue ISSUE-002
    ...

  ✓ Synced 59 files to database
  ```
</Accordion>

<Accordion title="Expected output (already in sync)">
  ```
  Detecting sync direction...
    Specs are in sync; Issues are in sync

  ✓ Everything is in sync
    Use --from-markdown or --to-markdown to force a specific direction
  ```
</Accordion>

### After Git Pull

Sync database with pulled changes:

```bash theme={null}
git pull
sudocode sync
```

<Accordion title="Expected output">
  ```
  Detecting sync direction...
    Issues JSONL is newer (2025-10-29 15:00:00 > 2025-10-29 14:30:00)

  → Syncing FROM database TO markdown (database is newer)

  Syncing from database to markdown...
    Found 47 issues in database
    ✓ updated issue ISSUE-001
    ✓ created issue ISSUE-050
    ...

  ✓ Synced 48 entities to markdown
  ```
</Accordion>

### Force Sync from Markdown

After manually editing markdown files:

```bash theme={null}
vim .sudocode/specs/authentication-system.md
sudocode sync --from-markdown
```

<Accordion title="Expected output">
  ```
  Syncing from markdown to database...
    Found 12 spec files
    ✓ updated spec SPEC-001
    Found 47 issue files

  ✓ Synced 12 files to database
  ```
</Accordion>

### Force Sync to Markdown

Regenerate markdown from database:

```bash theme={null}
sudocode sync --to-markdown
```

<Accordion title="Expected output">
  ```
  Syncing from database to markdown...
    Found 12 specs in database
    ✓ updated spec SPEC-001 → authentication-system.md
    ✓ updated spec SPEC-002 → api-design.md
    ...
    Found 47 issues in database
    ✓ updated issue ISSUE-001
    ✓ updated issue ISSUE-002
    ...

  ✓ Synced 59 entities to markdown
  ```
</Accordion>

### Watch Mode

Auto-sync on file changes:

```bash theme={null}
sudocode sync --watch
```

<Accordion title="Expected output">
  ```
  Starting file watcher...
    Watching: /Users/alice/project/.sudocode
    Press Ctrl+C to stop

    [watch] Detected change in specs/authentication-system.md
    [watch] Syncing...
    [watch] ✓ Synced 1 file to database
    [watch] Exported to JSONL

    [watch] Detected change in issues/ISSUE-001.md
    [watch] Syncing...
    [watch] ✓ Synced 1 file to database
    [watch] Exported to JSONL
  ```
</Accordion>

Press Ctrl+C to stop the watcher.

### JSON Output

Get machine-readable output:

```bash theme={null}
sudocode --json sync
```

<Accordion title="JSON output">
  ```json theme={null}
  {
    "success": true,
    "direction": "from-markdown",
    "syncedCount": 59,
    "errorCount": 0
  }
  ```
</Accordion>

## How Sync Direction is Determined

When you run `sync` without flags, it automatically detects the correct direction:

<Steps>
  <Step title="Compare file modification times">
    For both specs and issues:

    * Get most recent markdown file modification time
    * Get JSONL file modification time
  </Step>

  <Step title="Determine direction for each type">
    * If markdown is newer → sync FROM markdown
    * If JSONL is newer → sync TO markdown
    * If timestamps match → no sync needed
  </Step>

  <Step title="Handle conflicts">
    If specs and issues want different directions:

    * Prefer FROM markdown (preserves user edits)
    * Reason: User edits in markdown take precedence
  </Step>
</Steps>

### Decision Matrix

| Markdown State | JSONL State | Direction       | Reason                      |
| -------------- | ----------- | --------------- | --------------------------- |
| Newer          | Older       | `from-markdown` | User edited markdown        |
| Older          | Newer       | `to-markdown`   | Database updated (git pull) |
| Same           | Same        | `no-sync`       | Already in sync             |
| Missing        | Exists      | `to-markdown`   | Regenerate markdown         |
| Exists         | Missing     | `from-markdown` | Import to JSONL             |
| Mixed          | Mixed       | `from-markdown` | Prefer user edits           |

## Common Workflows

### Daily Development

<Steps>
  <Step title="Start work">
    Pull latest changes:

    ```bash theme={null}
    git pull
    sudocode sync
    ```
  </Step>

  <Step title="Make changes">
    Edit specs or issues via CLI or markdown:

    ```bash theme={null}
    sudocode issue update ISSUE-001 --status in_progress
    # or
    vim .sudocode/specs/auth-spec.md
    ```
  </Step>

  <Step title="Sync before commit">
    ```bash theme={null}
    sudocode sync
    git add .sudocode/
    git commit -m "Update authentication spec"
    ```
  </Step>
</Steps>

### After Manual Markdown Edits

<Steps>
  <Step title="Edit markdown">
    ```bash theme={null}
    vim .sudocode/specs/authentication-system.md
    ```
  </Step>

  <Step title="Sync to database">
    ```bash theme={null}
    sudocode sync --from-markdown
    ```
  </Step>

  <Step title="Verify changes">
    ```bash theme={null}
    sudocode spec show SPEC-001
    ```
  </Step>
</Steps>

### Troubleshoot Sync Issues

<Steps>
  <Step title="Force resync from JSONL">
    ```bash theme={null}
    # Regenerate everything from JSONL (source of truth)
    sudocode sync --to-markdown
    ```
  </Step>

  <Step title="Check for errors">
    Look for sync errors in output
  </Step>

  <Step title="Manually inspect">
    ```bash theme={null}
    # Compare markdown and JSONL
    cat .sudocode/specs/auth-spec.md
    cat .sudocode/specs.jsonl | grep SPEC-001
    ```
  </Step>
</Steps>

### Development with Watch Mode

For active development:

```bash theme={null}
# Terminal 1: Watch and auto-sync
sudocode sync --watch

# Terminal 2: Edit files
vim .sudocode/specs/authentication-system.md

# Terminal 1: See auto-sync messages
# [watch] Detected change...
# [watch] Synced...
```

## Understanding Sync Behavior

### Auto-Sync in Commands

Most commands auto-sync as needed:

* **Creating entities**: Database → JSONL → Markdown
* **Updating entities**: Database → JSONL → Markdown
* **After operations**: JSONL export triggered automatically

**When manual sync is needed:**

* After `git pull` (external changes)
* After manual markdown edits
* Troubleshooting inconsistencies

### Sync Operations

**From Markdown:**

<Steps>
  <Step title="Read markdown files">
    Parse frontmatter and content from `.sudocode/specs/` and `.sudocode/issues/`
  </Step>

  <Step title="Update database">
    Insert or update records in SQLite database
  </Step>

  <Step title="Export to JSONL">
    Write updated data to `specs.jsonl` and `issues.jsonl`
  </Step>
</Steps>

**To Markdown:**

<Steps>
  <Step title="Read from database">
    Query all specs and issues from SQLite
  </Step>

  <Step title="Generate markdown">
    Create markdown files with frontmatter and content
  </Step>

  <Step title="Write files">
    Save to `.sudocode/specs/` and `.sudocode/issues/`
  </Step>
</Steps>

## Watch Mode Details

Watch mode monitors file changes and auto-syncs:

**Configuration:**

* **Debounce delay**: 2000ms (2 seconds)
  * Waits 2 seconds after last change before syncing
  * Prevents excessive syncs during rapid edits
* **Watched directories**:
  * `.sudocode/specs/`
  * `.sudocode/issues/`
  * `.sudocode/*.jsonl`

**Events detected:**

* File creation
* File modification
* File deletion

**Graceful shutdown:**

* Press Ctrl+C to stop
* Ensures clean exit

## Common Questions

<AccordionGroup>
  <Accordion title="When do I need to run sync manually?">
    Manual sync is needed when:

    * After `git pull` (pulled JSONL changes)
    * After editing markdown files directly
    * Troubleshooting sync inconsistencies
    * Regenerating markdown from database

    Most CLI operations auto-sync automatically.
  </Accordion>

  <Accordion title="What's the difference between sync, export, and import?">
    * **sync**: Bidirectional, auto-detects direction, handles markdown ↔ database
    * **export**: Database → JSONL only
    * **import**: JSONL → Database only

    Use `sync` for normal operations, `export`/`import` for manual data migration.
  </Accordion>

  <Accordion title="Can sync cause data loss?">
    Generally no, but:

    * Syncing FROM markdown overwrites database changes
    * Syncing TO markdown overwrites markdown edits
    * Always commit to git before major sync operations
    * JSONL files are the source of truth - never deleted
  </Accordion>

  <Accordion title="Why does sync prefer from-markdown in conflicts?">
    User edits in markdown are considered intentional and take precedence over database state. This protects manual work.
  </Accordion>

  <Accordion title="How do I recover from bad sync?">
    Use git:

    ```bash theme={null}
    git checkout .sudocode/  # Restore from git
    sudocode sync             # Resync
    ```

    Or restore from JSONL:

    ```bash theme={null}
    sudocode import --input .sudocode/
    sudocode sync --to-markdown
    ```
  </Accordion>

  <Accordion title="Can I sync individual files?">
    Not directly. Sync operates on all files. For selective updates, use specific commands:

    ```bash theme={null}
    sudocode spec update SPEC-001 --title "New Title"
    ```
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Sync says 'everything in sync' but files differ">
    **Cause:** Modification times are equal despite content differences

    **Solution:**
    Force specific direction:

    ```bash theme={null}
    sudocode sync --from-markdown
    # or
    sudocode sync --to-markdown
    ```
  </Accordion>

  <Accordion title="Sync errors on specific files">
    **Cause:** Invalid markdown format or corrupted data

    **Solution:**

    1. Check file format:
       ```bash theme={null}
       head -20 .sudocode/specs/problematic-file.md
       ```
    2. Fix frontmatter issues
    3. Resync:
       ```bash theme={null}
       sudocode sync --from-markdown
       ```
  </Accordion>

  <Accordion title="Watch mode not detecting changes">
    **Cause:** File system watcher issues or editor behavior

    **Solution:**

    1. Restart watch mode
    2. Use manual sync instead
    3. Check editor settings (some use atomic writes that may not trigger watchers)
  </Accordion>

  <Accordion title="Sync takes very long">
    **Cause:** Large number of files

    **Solution:**
    Normal for large projects. Consider:

    * Archiving old entities
    * Splitting into multiple projects
    * Using watch mode instead of manual sync
  </Accordion>

  <Accordion title="Database out of sync after git merge conflict">
    **Cause:** Merge conflict in JSONL files

    **Solution:**

    1. Resolve JSONL conflicts in git
    2. Force import from JSONL:
       ```bash theme={null}
       sudocode import --input .sudocode/
       sudocode sync --to-markdown
       ```
  </Accordion>
</AccordionGroup>

## Related Commands

<CardGroup cols={3}>
  <Card title="export" icon="file-export" href="/cli/export">
    Export to JSONL
  </Card>

  <Card title="import" icon="file-import" href="/cli/import">
    Import from JSONL
  </Card>

  <Card title="status" icon="chart-simple" href="/cli/status">
    Check sync status
  </Card>
</CardGroup>

## Next Steps

<Steps>
  <Step title="Pull latest changes">
    ```bash theme={null}
    git pull
    ```
  </Step>

  <Step title="Sync database">
    ```bash theme={null}
    sudocode sync
    ```
  </Step>

  <Step title="Verify sync">
    ```bash theme={null}
    sudocode status
    ```
  </Step>

  <Step title="Start work">
    Use CLI commands normally - auto-sync handles the rest
  </Step>
</Steps>

<Card title="Storage Model" icon="book" href="/concepts/storage">
  Learn more about sudocode's 3-layer storage architecture
</Card>
