# Save Conversation Plugin Specification

## Overview

The Save Conversation Plugin provides the `/save` command to export conversations to file or clipboard in various formats (transcript, markdown, jsonl). Perfect for archiving, sharing, or processing conversations outside of Kollabor CLI.

**Location:** `plugins/save_conversation_plugin.py`

**Version:** 1.0.0

## Features

### Export Formats

- **Transcript**: Plain text format with timestamps
- **Markdown**: Rendered markdown with code blocks and formatting
- **JSONL**: JSON Lines format for programmatic processing
- **Clipboard**: Copy directly to system clipboard (macOS only)

### Destination Options

- **File**: Save to specified file path
- **Clipboard**: Copy to system clipboard (using `pbcopy` on macOS)
- **Auto-named**: Generate filename based on timestamp if not specified

### Slash Commands

| Command | Description |
|---------|-------------|
| `/save` | Save conversation with interactive options |
| `/save transcript [file]` | Save as plain text transcript |
| `/save markdown [file]` | Save as markdown |
| `/save jsonl [file]` | Save as JSON Lines |
| `/save clipboard` | Copy to clipboard |

### Status Bar Integration

Displays "Save" indicator in status bar with current save count.

## Architecture

### Plugin Structure

```python
class SaveConversationPlugin:
    - initialize(event_bus, config, **kwargs) -> None
    - shutdown() -> None
    - register_hooks() -> None
    - get_default_config() -> Dict[str, Any]
    - _register_commands() -> None
    - _register_status_view() -> None
    - _save_transcript(filepath: str) -> str
    - _save_markdown(filepath: str) -> str
    - _save_jsonl(filepath: str) -> str
    - _save_to_clipboard(content: str) -> str
    - _generate_filename(format: str) -> str
    - _format_transcript(messages: List[Message]) -> str
    - _format_markdown(messages: List[Message]) -> str
    - _format_jsonl(messages: List[Message]) -> str
```

### Command Registration

```python
CommandDefinition(
    name="save",
    description="Save conversation to file or clipboard",
    category=CommandCategory.CONVERSATION,
    mode=CommandMode.INTERACTIVE,
    handler=self._handle_save_command,
    aliases=[]
)
```

## Slash Commands

### `/save` (Main Command)

Interactive save with format selection.

```bash
# Interactive mode (prompts for format and destination)
/save

# Specify format
/save markdown
/save transcript
/save jsonl

# Specify file path
/save markdown conversation.md
/save transcript output.txt
/save jsonl data.jsonl

# Copy to clipboard
/save clipboard
```

### Command Flow

1. User enters `/save`
2. Plugin prompts for format (transcript/markdown/jsonl/clipboard)
3. If clipboard: copies and confirms
4. If file: prompts for filename (auto-generates default)
5. Saves and displays confirmation

## Configuration

### Configuration Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enabled` | boolean | `true` | Enable the plugin |
| `default_format` | string | `"transcript"` | Default export format |
| `default_directory` | string | `"~/kollabor/saves"` | Default save directory |
| `auto_timestamp` | boolean | `true` | Include timestamp in auto-generated filenames |
| `show_status` | boolean | `true` | Show save status in bar |

### Configuration File

Edit `~/.kollabor-cli/config.json`:

```json
{
  "plugins": {
    "save_conversation": {
      "enabled": true,
      "default_format": "transcript",
      "default_directory": "~/kollabor/saves",
      "auto_timestamp": true,
      "show_status": true
    }
  }
}
```

## Export Formats

### Transcript Format

Plain text with role indicators and timestamps.

```
Conversation saved: 2024-01-14 17:45:22

[USER] 2024-01-14 17:30:15
What is the capital of France?

[ASSISTANT] 2024-01-14 17:30:16
The capital of France is Paris.

[USER] 2024-01-14 17:31:00
Can you tell me more about it?

[ASSISTANT] 2024-01-14 17:31:02
Paris is the capital and largest city of France...
```

### Markdown Format

Rendered markdown with proper formatting.

```markdown
# Conversation

Saved: 2024-01-14 17:45:22

---

## User (2024-01-14 17:30:15)

What is the capital of France?

## Assistant (2024-01-14 17:30:16)

The capital of France is Paris.

## User (2024-01-14 17:31:00)

Can you tell me more about it?

## Assistant (2024-01-14 17:31:02)

Paris is the capital and largest city of France...
```

### JSONL Format

JSON Lines format for programmatic processing.

```json
{"role": "user", "timestamp": "2024-01-14T17:30:15Z", "content": "What is the capital of France?"}
{"role": "assistant", "timestamp": "2024-01-14T17:30:16Z", "content": "The capital of France is Paris."}
{"role": "user", "timestamp": "2024-01-14T17:31:00Z", "content": "Can you tell me more about it?"}
{"role": "assistant", "timestamp": "2024-01-14T17:31:02Z", "content": "Paris is the capital and largest city of France..."}
```

## Status Display

### Agnoster Segment

```
Save Active
```

With save count:
```
Save: 3 saved
```

Colors:
- "Save" - cyan
- Active/Count - neutral on dark

## Implementation Details

### File Generation

Auto-generated filenames follow pattern:
```
kollabor-conversation-20240114-174522.{ext}
```

Pattern components:
- `kollabor-conversation-` - prefix
- `YYYYMMDD-HHMMSS` - timestamp
- `.ext` - format extension

### Clipboard Support

Uses macOS `pbcopy` command:

```python
import subprocess

def copy_to_clipboard(text: str):
    subprocess.run(["pbcopy"], input=text.encode(), check=True)
```

For cross-platform support (future):
- macOS: `pbcopy`
- Linux: `xclip` or `xsel`
- Windows: `clip`

### Directory Handling

- Creates default directory if it doesn't exist
- Expands `~` to home directory
- Uses absolute paths for all saves

## Error Handling

### Common Errors

| Error | Cause | Resolution |
|-------|-------|------------|
| Permission denied | Can't write to specified path | Check file permissions |
| Directory not found | Custom directory doesn't exist | Create directory or use default |
| Clipboard command failed | `pbcopy` not available (non-macOS) | Save to file instead |
| Empty conversation | No messages to save | Start a conversation first |
| Invalid format | Format not recognized | Use transcript/markdown/jsonl/clipboard |

## Usage Examples

### Quick Save to File

```bash
/save transcript
# Prompts: "Save as: ~/kollabor/saves/kollabor-conversation-20240114-174522.txt"
# Press Enter to confirm

[Saved: 23 messages to ~/kollabor/saves/kollabor-conversation-20240114-174522.txt]
```

### Save with Custom Path

```bash
/save markdown my-conversation.md

[Saved: 23 messages to my-conversation.md]
```

### Copy to Clipboard

```bash
/save clipboard

[Copied 23 messages to clipboard]
```

### Programmatic Processing with JSONL

```bash
/save jsonl data.jsonl

[Saved: 23 messages to data.jsonl]

# Process in Python
import json
with open('data.jsonl') as f:
    messages = [json.loads(line) for line in f]
```

## Implementation Checklist

### Core Functionality
- [x] Transcript format export
- [x] Markdown format export
- [x] JSONL format export
- [x] Clipboard support (macOS)
- [x] Auto-named files
- [x] Custom file paths

### Status Integration
- [x] Status bar display
- [x] Save count tracking

### Configuration
- [x] Default format
- [x] Default directory
- [x] Timestamp in filename
- [x] Status display toggle

### Future Enhancements
- [ ] Cross-platform clipboard support
- [ ] Custom format templates
- [ ] Export range (first N messages, date range)
- [ ] Export specific messages by ID
- [ ] Compression option (gzip)

## Related Documentation

- /docs/reference/slash-commands-guide.md - Slash command system
- /docs/features/conversation-management.md - Conversation history
- /docs/reference/formats.md - Export format specifications

## Best Practices

### When to Use Each Format

| Format | Use Case |
|--------|----------|
| **Transcript** | Human-readable, quick reference |
| **Markdown** | Documentation, sharing, rendering in MD viewers |
| **JSONL** | Programmatic processing, data analysis |
| **Clipboard** | Quick copy-paste to other apps |

### File Organization

Organize saves by project or topic:

```bash
/save ~/docs/project-alpha/transcript-001.txt
/save ~/docs/project-alpha/markdown-001.md
```

### Archiving

Use JSONL for archival and search:

```bash
# Save all conversations
/save jsonl ~/archive/conversations.jsonl

# Search with jq
jq '.[] | select(.content | contains("France"))' ~/archive/conversations.jsonl
```

## Advanced Usage

### Custom Processing Script

Process exported conversations:

```python
import json
import sys

def process_jsonl(filepath):
    with open(filepath) as f:
        for line in f:
            msg = json.loads(line)
            # Custom processing
            print(f"{msg['role']}: {msg['content'][:50]}...")

if __name__ == '__main__':
    process_jsonl(sys.argv[1])
```

### Batch Export

Future enhancement: export multiple conversations at once.

## Troubleshooting

### Save Not Working

1. Check if plugin is enabled
2. Verify write permissions for target directory
3. Check available disk space
4. Review logs for specific error

### Clipboard Issues

1. Verify macOS (pbcopy required)
2. Check if `pbcopy` is in PATH
3. Try saving to file instead

### Format Issues

1. Verify format name (transcript/markdown/jsonl/clipboard)
2. Check conversation has messages
3. Try different format
