mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-30 05:43:38 +00:00
Summary: - This replacement PR marks the Linux node daemon gateway token as file-backed, writes it to `node.systemd.env`, sanitizes and migrates systemd env artifacts, adds regression tests, and updates the changelog. - Reproducibility: yes. from source inspection: current `main` copies `OPENCLAW_GATEWAY_TOKEN` into the node s ... e-backed before systemd rendering. I did not run a local live systemd install during this read-only review. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(systemd): scrub single-quoted env tokens - PR branch already contained follow-up commit before automerge: [Fix] Keep node systemd tokens out of unit files Validation: - ClawSweeper review passed for headf626b66c09. - Required merge gates passed before the squash merge. Prepared head SHA:f626b66c09Review: https://github.com/openclaw/openclaw/pull/84815#issuecomment-4505012292 Co-authored-by: samzong <samzong.lu@gmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
64 lines
1.6 KiB
TypeScript
64 lines
1.6 KiB
TypeScript
type ArgSplitEscapeMode = "none" | "backslash" | "backslash-quote-only";
|
|
type ArgSplitQuoteChar = '"' | "'";
|
|
type ArgSplitQuoteStart = "anywhere" | "item-start";
|
|
|
|
export function splitArgsPreservingQuotes(
|
|
value: string,
|
|
options?: {
|
|
escapeMode?: ArgSplitEscapeMode;
|
|
quoteChars?: readonly ArgSplitQuoteChar[];
|
|
quoteStart?: ArgSplitQuoteStart;
|
|
},
|
|
): string[] {
|
|
const args: string[] = [];
|
|
let current = "";
|
|
let quoteChar: ArgSplitQuoteChar | null = null;
|
|
const escapeMode = options?.escapeMode ?? "none";
|
|
const quoteChars = new Set<ArgSplitQuoteChar>(options?.quoteChars ?? ['"']);
|
|
const quoteStart = options?.quoteStart ?? "anywhere";
|
|
|
|
for (let i = 0; i < value.length; i++) {
|
|
const char = value[i];
|
|
if (escapeMode === "backslash" && char === "\\") {
|
|
if (i + 1 < value.length) {
|
|
current += value[i + 1];
|
|
i++;
|
|
}
|
|
continue;
|
|
}
|
|
if (
|
|
escapeMode === "backslash-quote-only" &&
|
|
char === "\\" &&
|
|
i + 1 < value.length &&
|
|
value[i + 1] === '"'
|
|
) {
|
|
current += '"';
|
|
i++;
|
|
continue;
|
|
}
|
|
if (quoteChars.has(char as ArgSplitQuoteChar)) {
|
|
if (quoteChar === char) {
|
|
quoteChar = null;
|
|
continue;
|
|
}
|
|
const canOpenQuote = quoteStart === "anywhere" || current.length === 0;
|
|
if (!quoteChar && canOpenQuote) {
|
|
quoteChar = char as ArgSplitQuoteChar;
|
|
continue;
|
|
}
|
|
}
|
|
if (!quoteChar && /\s/.test(char)) {
|
|
if (current) {
|
|
args.push(current);
|
|
current = "";
|
|
}
|
|
continue;
|
|
}
|
|
current += char;
|
|
}
|
|
if (current) {
|
|
args.push(current);
|
|
}
|
|
return args;
|
|
}
|