Browse Source

refactor(multiplexer): extract normalizePathForShell helper

Remove duplicated Windows backslash normalization across shared.ts and
herdr spawnPane; normalize once and reuse. Pin non-Windows test to
linux platform and re-wrap an over-long comment to fit 80 cols.

Review fixes for PR #710.
Michael Henke 4 weeks ago
parent
commit
237669b67f
3 changed files with 30 additions and 13 deletions
  1. 7 5
      src/multiplexer/herdr/index.ts
  2. 15 3
      src/multiplexer/shared.test.ts
  3. 8 5
      src/multiplexer/shared.ts

+ 7 - 5
src/multiplexer/herdr/index.ts

@@ -19,6 +19,7 @@ import {
   buildOpencodeAttachCommand,
   findBinary,
   gracefulClosePane,
+  normalizePathForShell,
 } from '../shared';
 import type { Multiplexer, PaneResult } from '../types';
 
@@ -74,6 +75,10 @@ export class HerdrMultiplexer implements Multiplexer {
     }
 
     try {
+      // Normalize Windows backslashes→/ so sh -lc (MSYS2) doesn't
+      // corrupt --cwd (issue #568).
+      const attachDir = normalizePathForShell(directory);
+
       // 1. Split the parent pane to create a new one
       const splitArgs = [
         herdr,
@@ -83,10 +88,7 @@ export class HerdrMultiplexer implements Multiplexer {
         '--direction',
         this.paneDirection,
         '--cwd',
-        // Normalize Windows backslashes→/ so sh -lc (MSYS2) doesn't corrupt --cwd (issue #568)
-        process.platform === 'win32'
-          ? directory.replace(/\\/g, '/')
-          : directory,
+        attachDir,
         '--no-focus',
       ];
 
@@ -128,7 +130,7 @@ export class HerdrMultiplexer implements Multiplexer {
       const opencodeCmd = buildOpencodeAttachCommand(
         sessionId,
         serverUrl,
-        directory,
+        attachDir,
       );
 
       log('[herdr] spawnPane: running attach command', {

+ 15 - 3
src/multiplexer/shared.test.ts

@@ -127,8 +127,20 @@ describe('buildOpencodeAttachCommand', () => {
   });
 
   test('leaves non-Windows paths unchanged', async () => {
-    const { buildOpencodeAttachCommand } = await importShared();
-    const cmd = buildOpencodeAttachCommand('sess', 'url', '/home/user/repo');
-    expect(cmd).toContain('/home/user/repo');
+    const original = process.platform;
+    Object.defineProperty(process, 'platform', {
+      value: 'linux',
+      configurable: true,
+    });
+    try {
+      const { buildOpencodeAttachCommand } = await importShared();
+      const cmd = buildOpencodeAttachCommand('sess', 'url', '/home/user/repo');
+      expect(cmd).toContain('/home/user/repo');
+    } finally {
+      Object.defineProperty(process, 'platform', {
+        value: original,
+        configurable: true,
+      });
+    }
   });
 });

+ 8 - 5
src/multiplexer/shared.ts

@@ -12,16 +12,19 @@ export function quoteShellArg(value: string): string {
   return `'${value.replace(/'/g, `'\\''`)}'`;
 }
 
+/** Normalize Windows backslashes to / so sh -lc (MSYS2/Git Bash) doesn't treat them as escape chars. */
+export function normalizePathForShell(directory: string): string {
+  return process.platform === 'win32'
+    ? directory.replace(/\\/g, '/')
+    : directory;
+}
+
 export function buildOpencodeAttachCommand(
   sessionId: string,
   serverUrl: string,
   directory: string,
 ): string {
-  // Normalize backslashes to forward slashes on Windows: when the command runs
-  // under sh -lc (MSYS2/Git Bash), backslashes are treated as escape chars and
-  // corrupt the --dir path (issue #568).
-  const attachDir =
-    process.platform === 'win32' ? directory.replace(/\\/g, '/') : directory;
+  const attachDir = normalizePathForShell(directory);
   return [
     'opencode',
     'attach',