add sync orchestrator wrapping mbsync, notmuch

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 11:26:11 +01:00
parent c085ef2b0b
commit e3bd05ca21
2 changed files with 49 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
import { describe, expect, test } from "bun:test";
import { runCommand } from "./orchestrator";
describe("runCommand", () => {
test("runs a command and returns stdout", async () => {
const result = await runCommand("echo", ["hello"]);
expect(result.stdout.trim()).toBe("hello");
expect(result.exitCode).toBe(0);
});
test("returns non-zero exit code on failure", async () => {
const result = await runCommand("false", []);
expect(result.exitCode).not.toBe(0);
});
});
+34
View File
@@ -0,0 +1,34 @@
export interface CommandResult {
stdout: string;
stderr: string;
exitCode: number;
}
export async function runCommand(cmd: string, args: string[]): Promise<CommandResult> {
const proc = Bun.spawn([cmd, ...args], {
stdout: "pipe",
stderr: "pipe",
});
const stdout = await new Response(proc.stdout).text();
const stderr = await new Response(proc.stderr).text();
const exitCode = await proc.exited;
return { stdout, stderr, exitCode };
}
export async function syncMail(channelName: string): Promise<CommandResult> {
return runCommand("mbsync", [channelName]);
}
export async function indexMail(): Promise<CommandResult> {
return runCommand("notmuch", ["new"]);
}
export async function syncAndIndex(channelName: string): Promise<CommandResult> {
const syncResult = await syncMail(channelName);
if (syncResult.exitCode !== 0) {
return syncResult;
}
return indexMail();
}