mirror of
https://github.com/openclaw/lobster.git
synced 2026-08-14 08:52:48 +00:00
fix(parser): preserve JSON escapes in quoted args (#16)
Merged via squash. Validated in a fresh checkout with: - pnpm build - node --test dist/test/parser.test.js
This commit is contained in:
+25
-1
@@ -60,18 +60,42 @@ function tokenizeCommand(input) {
|
||||
const ch = input[i];
|
||||
|
||||
if (quote) {
|
||||
if (quote === "'") {
|
||||
if (ch === '\\' && input[i + 1] === quote) {
|
||||
current += quote;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (ch === quote) {
|
||||
quote = null;
|
||||
continue;
|
||||
}
|
||||
current += ch;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Double-quoted mode: preserve unknown escapes (\n, \t, etc) while
|
||||
// unescaping only shell-like quote/backslash escapes.
|
||||
if (ch === '\\') {
|
||||
const next = input[i + 1];
|
||||
if (next) {
|
||||
if (next === '"' || next === '\\' || next === '$' || next === '`') {
|
||||
current += next;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (next === '\n') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
current += ch;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch === quote) {
|
||||
quote = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
current += ch;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -18,3 +18,26 @@ test('parsePipeline keeps quoted pipes', () => {
|
||||
assert.equal(p.length, 2);
|
||||
assert.deepEqual(p[0].args._, ['echo', 'a|b']);
|
||||
});
|
||||
|
||||
test('parsePipeline preserves JSON escapes in double-quoted args', () => {
|
||||
const p = parsePipeline('openclaw.invoke --tool llm-task --action json --args-json "{\\"prompt\\":\\"line1\\\\nline2\\",\\"schema\\":{\\"type\\":\\"object\\"}}"');
|
||||
assert.equal(p.length, 1);
|
||||
const raw = p[0].args['args-json'];
|
||||
const parsed = JSON.parse(raw);
|
||||
assert.equal(parsed.prompt, 'line1\nline2');
|
||||
assert.equal(parsed.schema.type, 'object');
|
||||
});
|
||||
|
||||
test('parsePipeline keeps single-quoted args literal', () => {
|
||||
const p = parsePipeline("openclaw.invoke --args-json '{\"x\":\"a\\\\nb\"}'");
|
||||
assert.equal(p.length, 1);
|
||||
assert.equal(p[0].args['args-json'], '{"x":"a\\\\nb"}');
|
||||
});
|
||||
|
||||
test('parsePipeline preserves escaped apostrophes in single-quoted args', () => {
|
||||
const p = parsePipeline("openclaw.invoke --args-json '{\"prompt\":\"don\\'t\"}'");
|
||||
assert.equal(p.length, 1);
|
||||
const raw = p[0].args['args-json'];
|
||||
const parsed = JSON.parse(raw);
|
||||
assert.equal(parsed.prompt, "don't");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user