UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

58 lines • 2.39 kB
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= const ESCAPABLE = new Set(['$', '`', '\\']); /** * Split a backtick region into its commands and the text between them, * each with its span in the region. * * The node's subtree is not what runs: bash removes the backslashes of a * backtick body before it parses it, so the body is lexed again from the * node's own text. The evaluator runs each command as a line of its own * and the judging pass reads it the same way, so this is the one lexer * both share, and the spans are what place each command on the line. * * Inside a command, POSIX keeps the backslash literal except before * `$`, `` ` `` and `\\`, where it escapes. Consuming those pairs whole * is what makes the parity right: `\\\\` is one escaped backslash, so a * backtick straight after it still closes the region rather than * reading as an escaped backtick. */ export function splitBacktickRegion(raw) { const segments = []; let buf = ''; let inCommand = false; let start = 0; let i = 0; while (i < raw.length) { const next = raw[i + 1]; if (raw[i] === '\\' && inCommand && next !== undefined && ESCAPABLE.has(next)) { buf += next; i += 2; continue; } if (raw[i] === '`') { segments.push({ text: buf, command: inCommand, start, end: i }); buf = ''; inCommand = !inCommand; i += 1; start = i; continue; } buf += raw.charAt(i); i += 1; } segments.push({ text: buf, command: inCommand, start, end: raw.length }); return segments.filter((s) => s.text !== '' || s.command); } //# sourceMappingURL=backticks.js.map