quak backup writes each file's ML data into its JSON (closes #163)
check / check (push) Successful in 1m37s

lib.backup() now waits for an ML data fetch, joining the one its refresh
started or starting one, before it writes the per-file JSON, and each
file's JSON carries the cached payload as mlData. When the fetch fails,
each file with no cached ML data gets mlDataError and an entry in
failures.json, so the result counts it as failed and quak backup exits 1;
the next run fetches again.

Judgement call: the wait comes after the originals are downloaded, so the fetch runs alongside the downloads.
Judgement call: a failed ML fetch is recorded per file in failures.json, which is how the exit code goes non-zero without changing src/cli-commands.ts.

Model: opus-5-5
This commit was merged in pull request #172.
This commit is contained in:
2026-10-06 05:13:27 +02:00
parent 14ac7d05ef
commit ab4d5d2cc2
6 changed files with 214 additions and 35 deletions
+16
View File
@@ -732,6 +732,22 @@ describe("backup", () => {
expect(stderr.text).toBe("Starting backup...\n");
});
it("exits 1 and lists each file when the ML data fetch fails", async () => {
const client = {
...fakeClient(),
fetchMLData: async () => {
throw new Error("HTTP 503 from server");
},
} as unknown as Client;
expect(
await backupCommand(context(client), join(root, "backup"), {}),
).toBe(1);
expect(stderr.text).toContain(" Failed: 3\n");
expect(stderr.text).toContain(
" [Vacation] beach.jpg (id 100): ML data: HTTP 503 from server\n",
);
});
it("exits 1 with the error on one line when the refresh fails", async () => {
const client = {
...fakeClient(),