# ChatTwo Debug

> Use this skill to read ChatTwo chat logs as a debug console. Covers querying the SQLite database, finding script runs, and extracting debug evidence for bug analysis.

- Skill: `majiayu000/chattwo-debug` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/chattwo-debug`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/chattwo-debug/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/chattwo-debug

---


# ChatTwo Debug Log Analysis

This skill enables reading and analyzing debug output from SND scripts stored in the ChatTwo plugin's SQLite database.

## Prerequisites

The SQLite MCP server must be configured in `.mcp.json` to connect to the ChatTwo database.

### Project Configuration (Recommended)

The database path is configured in `.mcp.json`:

```json
{
  "mcpServers": {
    "sqlite": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-server-sqlite-npx",
        "PATH_TO_YOUR_CHATTWO_DB"
      ]
    }
  }
}
```

**To change the database path:** Edit the last argument in the `args` array in `.mcp.json`.

### Default Path

The typical ChatTwo database location is:
```
{XIVLauncher}/pluginConfigs/ChatTwo/chat-sqlite.db
```

### Alternative: Global Configuration

You can also configure via CLI (adds to user-level config):
```bash
claude mcp add sqlite -- npx -y mcp-server-sqlite-npx "PATH_TO_CHAT_DB"
```

## Database Schema

The ChatTwo database has a single `messages` table:

| Column | Type | Description |
|--------|------|-------------|
| Id | BLOB | Primary key |
| Receiver | INTEGER | Character ID receiving the message |
| ContentId | INTEGER | Content identifier |
| Date | INTEGER | Timestamp (milliseconds since epoch) |
| Code | INTEGER | Chat channel code |
| Sender | BLOB | Sender name (binary encoded) |
| Content | BLOB | Message content (binary encoded with prefix) |
| SenderSource | BLOB | Original sender data |
| ContentSource | BLOB | Original content data |
| SortCode | INTEGER | Sorting order |
| ExtraChatChannel | BLOB | Extra channel info |
| Deleted | BOOLEAN | Soft delete flag |

## Important Chat Codes

| Code | Channel | Description |
|------|---------|-------------|
| 56 | Echo | SND script `/echo` output - **Primary debug channel** |
| 57 | System | Game system messages (gearset changes, etc.) |
| 1 | Say | Public chat |
| 2105 | System | Job change notifications |

## Reading Debug Output

### Basic Query - Recent Echo Messages

```sql
SELECT Date, CAST(Content AS TEXT) as Content
FROM messages
WHERE Code = 56
ORDER BY Date DESC
LIMIT 100
```

**IMPORTANT:** Content is stored as BLOB with a binary prefix. The readable text appears after the prefix characters. Example raw output:
```
���\u0000\u0000\u0000\u0000�\u0002�8��½[CosmicLeveling] === Done ===
```
The actual message is `[CosmicLeveling] === Done ===`.

### Finding Script Runs by Header

Most SND scripts output a header when starting. Use this to find complete runs:

```sql
-- Find all script starts
SELECT Date, CAST(Content AS TEXT) as Content
FROM messages
WHERE Code = 56
ORDER BY Date DESC
LIMIT 500
```

Then filter for headers like:
- `[CosmicLeveling] === Cosmic Exploration Auto-Leveling ===`
- `[ScriptName] === Starting ===`

### Getting a Complete Script Run

Once you find a header timestamp, get all messages from that run:

```sql
SELECT Date, CAST(Content AS TEXT) as Content
FROM messages
WHERE Code = 56
  AND Date >= {HEADER_TIMESTAMP}
  AND Date <= {HEADER_TIMESTAMP + 60000}  -- Within 1 minute
ORDER BY Date ASC
```

### Querying Limitations

**LIKE queries don't work well with BLOB content:**
```sql
-- This may return empty results even when data exists:
WHERE CAST(Content AS TEXT) LIKE '%DEBUG%'
```

**Workaround:** Fetch larger result sets and filter in your analysis.

## Common Debug Patterns

### Script Header/Footer Pattern

Scripts output a versioned header at start and footer at end:

```
[ScriptName] === Script Title vX.Y.Z ===   <- Header with VERSION (start of run)
[ScriptName] Mode: Catch-up
[ScriptName] [DEBUG] ...                    <- Debug messages
[ScriptName] ...                            <- Status messages
[ScriptName] === Done ===                   <- Footer (end of run)
```

**The version in the header is critical for correlating debug output with the correct script code.**

### Finding Bug Evidence

1. **Get recent runs:** Query last 500 Code=56 messages
2. **Identify headers:** Look for `=== ... ===` patterns
3. **Group by run:** Messages between header and footer belong to same run
4. **Analyze flow:** Check if debug output matches expected behavior

### Example: CosmicLeveling Debug Analysis

Headers to look for:
- `[CosmicLeveling] === Cosmic Exploration Auto-Leveling v2.13.2 ===` - Run start (note version!)
- `[CosmicLeveling] === Done ===` - Run end

Key debug messages:
- `[DEBUG] Reference level: X | Reached breakpoint: Y`
- `[DEBUG] JobAbbr is Lv.X`
- `[DEBUG] Enabled Crafters: X/8`
- `[Catch-up] ...` or `[Strict] ...` - Mode-specific logic

## Workflow for Bug Analysis

### Step 0: VERIFY SCRIPTS ARE SYNCED (CRITICAL - DO THIS FIRST!)

**Before analyzing ANY debug output, ensure the local scripts match what's in SND:**

```bash
# Check sync status
node sync.js status

# Push local scripts to SND (ensures SND has latest code)
node sync.js push
```

**Why this matters:**
- Debug logs come from the script version running IN SND
- If local files differ from SND, you're analyzing the wrong code!
- The sync tool shows `[updated]` for files that were out of sync

**Example output showing out-of-sync scripts:**
```
  [updated]   CosmicLeveling.lua -> CosmicLeveling    <- WAS OUT OF SYNC!
  [unchanged] New_Macro.lua                           <- Already synced
```

**If scripts were out of sync:**
1. The bug may already be fixed in the local version
2. Push first, then have the user run the script again
3. Only analyze debug logs from AFTER the push

### Step 1: Query recent echo messages

```sql
SELECT Date, CAST(Content AS TEXT) as Content
FROM messages WHERE Code = 56
ORDER BY Date DESC LIMIT 500
```

### Step 2: Find the script run header

Look for `=== ... vX.Y.Z ===` pattern. **The version is critical!**

**Red flag:** If header has NO version (e.g., `=== Cosmic Exploration Auto-Leveling ===` without `vX.Y.Z`), the script is an old version that predates versioned headers.

### Step 3: Extract version from header

e.g., `v2.13.2`

### Step 4: Verify version matches current script

- Read the script file and check `SCRIPT_VERSION` constant
- If mismatch, retrieve the correct version from git history
- **If no version in header:** Script in SND is outdated - push and retest

### Step 5: Extract the run's messages

Use timestamp range (header to footer)

### Step 6: Compare debug output to expected behavior

Based on the CORRECT version's logic

### Step 7: Identify discrepancies

Between what debug says happened vs what should have happened

## Script Version Correlation

**CRITICAL:** Always correlate the version in debug output with the script source code.

### Version Location

Scripts embed version in two places:
1. **Header output:** `[ScriptName] === Title vX.Y.Z ===` (in chat logs)
2. **Source code:** `local SCRIPT_VERSION = "X.Y.Z"` (at top of script)

### Correlation Workflow

1. **Extract version from debug header:**
   ```
   [CosmicLeveling] === Cosmic Exploration Auto-Leveling v2.13.2 ===
   ```
   Version = `2.13.2`

2. **Check current script version:**
   ```lua
   -- In PlayRoom/CosmicLeveling.lua
   local SCRIPT_VERSION = "2.13.2"
   ```

3. **If versions match:** Analyze using current script source
4. **If versions differ:**
   - Debug output is from an older/different version
   - Use `git log` or `git show` to find the correct version's code
   - Or check if the bug was already fixed in a newer version

### Git History for Old Versions

```bash
# Find commits that changed the script
git log --oneline -- PlayRoom/ScriptName.lua

# View script at a specific commit
git show <commit>:PlayRoom/ScriptName.lua
```

### Why This Matters

A bug report from debug output is only useful if you're looking at the same code that produced it. Example:
- Debug shows `v2.12.0` behavior
- Current script is `v2.13.2`
- The bug might already be fixed, or the code path changed entirely

## Tips

- **High volume database:** ChatTwo stores ALL chat history. Query with LIMIT to avoid overwhelming results.
- **Timestamps:** Date column is milliseconds since epoch. Convert for human-readable times.
- **Binary prefix:** Always expect ~15-20 garbage characters before readable content in BLOB fields.
- **Code 56 only:** For SND debug analysis, focus on Code=56 (Echo channel).

