From fa9aafce83c0b620fe21dc8ec4b0b5ad47c52ea4 Mon Sep 17 00:00:00 2001 From: Roshan Singh Date: Fri, 16 Jan 2026 05:25:13 +0000 Subject: [PATCH] Fix systemd ExecStart parsing whitespace --- src/daemon/systemd-unit.test.ts | 38 +++++++++++++++++++++++++++++++++ src/daemon/systemd-unit.ts | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/daemon/systemd-unit.test.ts diff --git a/src/daemon/systemd-unit.test.ts b/src/daemon/systemd-unit.test.ts new file mode 100644 index 000000000..b7eced7c0 --- /dev/null +++ b/src/daemon/systemd-unit.test.ts @@ -0,0 +1,38 @@ +import { describe, expect, it } from "vitest"; + +import { parseSystemdExecStart } from "./systemd-unit.js"; + +describe("parseSystemdExecStart", () => { + it("splits on whitespace outside quotes", () => { + const execStart = "/usr/bin/clawdbot gateway start --foo bar"; + expect(parseSystemdExecStart(execStart)).toEqual([ + "/usr/bin/clawdbot", + "gateway", + "start", + "--foo", + "bar", + ]); + }); + + it("preserves quoted arguments", () => { + const execStart = "/usr/bin/clawdbot gateway start --name \"My Bot\""; + expect(parseSystemdExecStart(execStart)).toEqual([ + "/usr/bin/clawdbot", + "gateway", + "start", + "--name", + "My Bot", + ]); + }); + + it("supports backslash-escaped characters", () => { + const execStart = "/usr/bin/clawdbot gateway start --path \/tmp\/clawdbot"; + expect(parseSystemdExecStart(execStart)).toEqual([ + "/usr/bin/clawdbot", + "gateway", + "start", + "--path", + "/tmp/clawdbot", + ]); + }); +}); diff --git a/src/daemon/systemd-unit.ts b/src/daemon/systemd-unit.ts index 50979e55d..003e0867c 100644 --- a/src/daemon/systemd-unit.ts +++ b/src/daemon/systemd-unit.ts @@ -76,7 +76,7 @@ export function parseSystemdExecStart(value: string): string[] { inQuotes = !inQuotes; continue; } - if (!inQuotes && /\\s/.test(char)) { + if (!inQuotes && /\s/.test(char)) { if (current) { args.push(current); current = "";