tx sync
Git-backed synchronization via append-only stream event logs
Purpose
tx sync keeps local state portable across machines by writing append-only event logs under .tx/streams/ and replaying them into SQLite.
This gives you:
- Git-friendly sync artifacts
- Cross-machine collaboration
- Deterministic rebuilds from event history
- Local-first operation (SQLite remains the runtime store)
At A Glance
Cross-Machine Sync
Rebuild Path
Sync Model (Default)
tx sync uses a stream event log model:
.tx/
├── stream.json # Local stream identity
└── streams/
└── <stream-id>/
└── events-YYYY-MM-DD.jsonl # Append-only eventsEach event is a JSON object with envelope metadata and payload:
{
"event_id": "01JZ...",
"stream_id": "01JY...",
"seq": 184,
"ts": "2026-03-05T13:12:04.123Z",
"type": "task.upsert",
"entity_id": "tx-abc123",
"v": 2,
"payload": { "id": "tx-abc123", "title": "Implement auth" }
}Subcommands
| Command | Description |
|---|---|
tx sync export | Emit current state as stream events |
tx sync import | Incrementally apply stream events |
tx sync stream | Show local stream ID + sequence state |
tx sync hydrate | Rebuild materialized state from event logs |
tx sync status | Show sync health and dirty status |
tx sync auto | Enable/disable automatic export on mutations |
tx sync export
Write events to the local stream log.
tx sync export [--json]# Export events
tx sync export
# JSON output
tx sync export --jsonCLI output (human mode):
Events: 42 event(s) → .tx/streams/<stream-id>/events-2026-03-05.jsonlimport { TxClient } from '@jamesaphoenix/tx-agent-sdk'
const tx = new TxClient({ dbPath: '.tx/tasks.db' })
const result = await tx.sync.export()
console.log(result.eventCount, result.streamId, result.path)Tool: tx_sync_export
{
"name": "tx_sync_export",
"arguments": {}
}POST /api/sync/exportcurl -X POST http://localhost:3456/api/sync/export \
-H "Content-Type: application/json" \
-d '{}'Response:
{
"eventCount": 42,
"streamId": "01JY...",
"path": ".tx/streams/01JY.../events-2026-03-05.jsonl"
}tx sync import
Read stream event logs and apply unseen events.
tx sync import [--json]tx sync import
tx sync import --jsonCLI output (human mode):
Events: imported=42, applied=42, streams=1const result = await tx.sync.import()
console.log(result.importedEvents, result.appliedEvents, result.streamCount)Tool: tx_sync_import
{
"name": "tx_sync_import",
"arguments": {}
}POST /api/sync/importcurl -X POST http://localhost:3456/api/sync/import \
-H "Content-Type: application/json" \
-d '{}'Response:
{
"importedEvents": 42,
"appliedEvents": 42,
"streamCount": 1
}tx sync stream
Inspect local stream identity and sequence progress.
tx sync stream [--json]Stream: 01JY...
nextSeq: 185
lastSeq: 184
eventsDir: /.../.tx/streams/01JY...const stream = await tx.sync.stream()
console.log(stream.streamId, stream.nextSeq, stream.lastSeq, stream.eventsDir)Tool: tx_sync_stream
{
"name": "tx_sync_stream",
"arguments": {}
}GET /api/sync/streamcurl http://localhost:3456/api/sync/streamtx sync hydrate
Clear and rebuild materialized task state by replaying event logs.
tx sync hydrate [--json]const hydrated = await tx.sync.hydrate()
console.log(hydrated.importedEvents, hydrated.appliedEvents, hydrated.rebuilt)Tool: tx_sync_hydrate
{
"name": "tx_sync_hydrate",
"arguments": {}
}POST /api/sync/hydratecurl -X POST http://localhost:3456/api/sync/hydratetx sync status
Show high-level sync state.
tx sync status [--json]Sync Status:
Tasks in database: 156
Events in stream logs: 312
Last export: 2026-03-05T12:40:33.000Z
Last import: 2026-03-05T12:41:18.000Z
Dirty (unexported changes): no
Auto-sync: enabledconst status = await tx.sync.status()
console.log(status.dbTaskCount, status.isDirty, status.autoSyncEnabled)Tool: tx_sync_status
{
"name": "tx_sync_status",
"arguments": {}
}GET /api/sync/statuscurl http://localhost:3456/api/sync/statustx sync auto
Enable or disable automatic export on mutations.
tx sync auto --enable
tx sync auto --disable
tx sync auto --jsonWhen enabled, mutating operations trigger sync export automatically.
Sync Constraints
- Legacy single-file sync arguments are no longer supported.
Git Workflow
# Before commit
tx sync export
git add .tx/stream.json .tx/streams
git commit -m "chore: sync stream events"
git push
# On another machine
git pull
tx sync import.gitignore Recommendation
# Keep database local
.tx/tasks.db
.tx/tasks.db-wal
.tx/tasks.db-shm
# Track sync stream identity + event logs
!.tx/stream.json
!.tx/streams/
!.tx/streams/**