import com.qoder.taskdeck.LedgerFile; import com.qoder.taskdeck.LocalStore; import com.qoder.taskdeck.Task; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Writes a ledger through the Android store so the Mac's own tooling can be * pointed at it. Android -> Mac is the risky direction: the Mac quarantines any * file its decoder rejects, so a missing field here is silent data loss there. */ public class InteropCheck { public static void main(String[] args) throws Exception { File dir = new File(args[0]); if (!dir.exists() && !dir.mkdirs()) throw new IllegalStateException("cannot create " + dir); File store = new File(dir, "tasks.json"); long base = 1_800_000_000_000L; LocalStore local = new LocalStore(store); local.mutate(new LocalStore.Mutation() { public void apply(LedgerFile f) { Task plain = new Task("taaaa1", "Reply to Ruth about the gateway draft"); plain.notes = "she asked twice already"; plain.tags = new ArrayList(Arrays.asList("gateway", "client")); plain.priority = "high"; plain.source = "voice"; plain.createdAt = base; plain.updatedAt = base + 1000; plain.order = 10; Task logged = new Task("taaaa2", "Audit Gemini web-chat models inside Claude Code"); logged.dueMillis = base + 86_400_000L; logged.timed = true; logged.createdAt = base; logged.updatedAt = base + 2000; logged.order = 20; logged.log = new ArrayList(Arrays.asList( new Task.Log(base + 500, "user", "blocked on the tool-use parity check"), new Task.Log(base + 600, "qoder", "note: unicode \u2014 em dash, \u00e9 accents, \"quotes\", back\\slash"))); Task recurring = new Task("taaaa3", "Weekly ledger review"); recurring.recur = "weekly"; recurring.dueMillis = base + 3 * 86_400_000L; recurring.timed = false; recurring.createdAt = base; recurring.updatedAt = base + 3000; recurring.order = 30; Task parked = new Task("taaaa4", "Someday: rewrite the router in Rust"); parked.status = Task.SOMEDAY; parked.tags = new ArrayList(Arrays.asList("rust")); parked.createdAt = base; parked.updatedAt = base + 4000; parked.order = 40; Task finished = new Task("taaaa5", "Retired experiment"); finished.status = Task.DONE; finished.completedAt = base + 5000; finished.createdAt = base; finished.updatedAt = base + 5000; finished.order = 50; f.tasks.add(plain); f.tasks.add(logged); f.tasks.add(recurring); f.tasks.add(parked); f.tasks.add(finished); } }); // A tombstone, because that is the other thing the Mac must agree about. local.mutate(new LocalStore.Mutation() { public void apply(LedgerFile f) { Task doomed = new Task("taaaa6", "This one gets deleted on the phone"); doomed.createdAt = base; doomed.updatedAt = base + 6000; f.tasks.add(doomed); } }); local.mutate(new LocalStore.Mutation() { public void apply(LedgerFile f) { for (java.util.Iterator it = f.tasks.iterator(); it.hasNext(); ) { if ("taaaa6".equals(it.next().id)) it.remove(); } f.deleted.put("taaaa6", Long.valueOf(base + 7000)); } }); String err = local.lastError(); System.out.println("android wrote " + local.snapshot().tasks.size() + " tasks" + (err == null ? "" : " lastError=" + err)); System.out.println("file: " + store.getAbsolutePath()); } }