You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Session shards are rewritten on every export because exportedAt uses Date.now() #3
opencode-github-sync 3.0.1 rewrites every exported session shard on each push even when the OpenCode session itself has not changed.
The shard currently sets:
exportedAt: Date.now(),
Because that value changes on every export, the JSON payload changes, the .json.gz bytes change, and Git sees the shard as modified.
With autoPushOnIdle enabled this can generate repeated commits touching many or all session shards even when no session data changed.
Environment
opencode-github-sync: 3.0.1
OpenCode Desktop / CLI: 1.18.30
Node.js: 24.x
Windows 11
Reproduction
Enable session sync.
Ensure there is at least one eligible session.
Run opencode-sync push.
Make no changes to the session.
Run opencode-sync push --dry-run or another normal push.
Observed: the session shard is reported as modified again.
In a test with 11 eligible sessions, an unchanged export could show all 11 .json.gz shards as modified purely because export metadata was regenerated.
Expected result
If the underlying session and related rows did not change, exporting the same session again should produce identical shard bytes and Git should stay clean.
Tested fix
Using the session's own stable update timestamp instead of wall-clock export time makes repeated exports deterministic:
exportedAt: Number(sessionRow.time_updated??0),
After that change, running opencode-sync push --dry-run twice with no session changes reports Already up to date on the second run.
Suggested regression test
Export a session to a shard.
Export the same unchanged session again.
Assert the shard bytes are identical.
Assert the second sync has no Git diff.
Related: #2 is a separate session-import data-loss issue.
Confirming this on two Linux machines with ~912 shards. Every push and startup pull carried all 912 files. After deriving exportedAt from the session's own time_updated, a repeat export is byte-identical (914 shards exported twice: 914 identical, 0 different) and pushes carry only the sessions actually in use (0–2 files, ~13 s instead of ~65 s).
One extra finding while verifying this: the regression test never ran under vitest — await import("node:sqlite") throws ("Failed to load url sqlite") in that runner, sqliteAvailable() reports false, and every session test returns early via if (!available) return, so it passed silently. A createRequire(import.meta.url)("node:sqlite") fallback makes the driver detectable and the tests actually execute (suite went from ~15 ms to ~95 ms).
Activity
feat: session-sync fork — deterministic exports, progress UI, import …
aquelejota commentedon Sep 20, 2026
Confirming this on two Linux machines with ~912 shards. Every push and startup pull carried all 912 files. After deriving
exportedAtfrom the session's owntime_updated, a repeat export is byte-identical (914 shards exported twice: 914 identical, 0 different) and pushes carry only the sessions actually in use (0–2 files, ~13 s instead of ~65 s).One extra finding while verifying this: the regression test never ran under vitest —
await import("node:sqlite")throws ("Failed to load url sqlite") in that runner,sqliteAvailable()reportsfalse, and every session test returns early viaif (!available) return, so it passed silently. AcreateRequire(import.meta.url)("node:sqlite")fallback makes the driver detectable and the tests actually execute (suite went from ~15 ms to ~95 ms).I sent both changes as a PR: #5