Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,30 @@ describe("toolExecuteBefore", () => {
expect(mockOutput.args.command).toBe("cd /tmp && snip ls")
})
})

describe("redirections with &", () => {
it("should not break 2>&1 redirection", async () => {
mockOutput.args.command = "find / -name \"*.log\" 2>&1"
await toolExecuteBefore(mockInput, mockOutput)
expect(mockOutput.args.command).toBe("snip find / -name \"*.log\" 2>&1")
})

it("should not break 1>&2 redirection", async () => {
mockOutput.args.command = "cmd 1>&2"
await toolExecuteBefore(mockInput, mockOutput)
expect(mockOutput.args.command).toBe("snip cmd 1>&2")
})

it("should handle 2>&1 with pipe", async () => {
mockOutput.args.command = "find / -name \"*.log\" 2>&1 | grep error"
await toolExecuteBefore(mockInput, mockOutput)
expect(mockOutput.args.command).toBe("snip find / -name \"*.log\" 2>&1 | snip grep error")
})

it("should handle 2>&1 with chained commands", async () => {
mockOutput.args.command = "cmd1 2>&1 && cmd2"
await toolExecuteBefore(mockInput, mockOutput)
expect(mockOutput.args.command).toBe("snip cmd1 2>&1 && snip cmd2")
})
})
})
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const ENV_VAR_RE = /^([A-Za-z_][A-Za-z0-9_]*=[^\s]* +)*/
const UNPROXYABLE_COMMANDS = new Set([
"cd", "source", ".", "export", "alias", "unset", "set", "shopt", "eval", "exec",
])
const OPERATOR_RE = /(\s*(?:&&|\|\||[;&|])\s*)/
const OPERATOR_RE = /(\s*(?:&&|\|\||;|\|)\s*|\s&\s?)/

function snipCommand(command: string): string {
const envPrefix = (command.match(ENV_VAR_RE) ?? [""])[0]
Expand Down
Loading