codex-sync 0.2.3

Sync and merge Codex conversations across computers, LAN, SSH, and offline storage
1
2
3
4
5
6
7
8
<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>Codex Sync</title><style>
:root{color-scheme:dark;font:16px system-ui;background:#0b1020;color:#e8ecf4}body{max-width:900px;margin:48px auto;padding:0 20px}header{display:flex;justify-content:space-between;align-items:center}.card{background:#151c31;border:1px solid #29334f;border-radius:14px;padding:20px;margin:16px 0}button{background:#6d5dfc;color:white;border:0;border-radius:8px;padding:10px 16px;cursor:pointer}button:disabled{opacity:.5}.muted{color:#98a3ba}table{width:100%;border-collapse:collapse}td,th{text-align:left;padding:10px;border-bottom:1px solid #29334f}code{color:#86e1fc}
</style></head><body><header><div><h1>Codex Sync</h1><p class="muted">局域网聊天记录与配置同步</p></div><button onclick="refresh()">刷新</button></header><section class="card" id="status">载入中…</section><section class="card"><h2>局域网节点</h2><div id="peers">正在发现…</div></section><script>
const esc=s=>String(s).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
async function refresh(){let s=await fetch('/api/status').then(r=>r.json());document.querySelector('#status').innerHTML=`<b>${esc(s.node_name)}</b><p><code>${s.files.length}</code> 个同步文件</p>`;let ps=await fetch('/api/peers').then(r=>r.json());document.querySelector('#peers').innerHTML=ps.length?`<table><tr><th>名称</th><th>地址</th><th></th></tr>${ps.map(p=>`<tr><td>${esc(p.name)}</td><td><code>${esc(p.address)}</code></td><td><button onclick="pull('${encodeURIComponent(p.address)}')">拉取</button></td></tr>`).join('')}</table>`:'<p class="muted">暂未发现其他节点。请确认它们正在运行且位于同一局域网。</p>'}
async function pull(peer){if(!confirm('从该节点拉取?有冲突的文件会另存副本。'))return;let r=await fetch('/api/pull',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({peer:decodeURIComponent(peer)})});alert(r.ok?JSON.stringify(await r.json()):await r.text());refresh()}refresh();
</script></body></html>