fix(worker): strip trailing separator from the list repo in ConPTY launch args
The ConPTY host flattens LaunchSpec.Args into one Windows command line and quotes each token, so a list working dir stored as "C:\repo\" produced the token "C:\repo\" -- whose trailing backslash escapes its own closing quote. Everything after it collapsed into --add-dir's variadic list, including --append-system-prompt-file and the positional kickoff, so "Let Claude handle it" opened a session with no prompt at all and the CLI warned that brief.md is not a directory. Only user-supplied working dirs can carry a trailing separator; the session dirs the worker builds never do.
This commit is contained in:
@@ -223,6 +223,7 @@ public sealed class InteractiveLaunchSpecService : IInteractiveLaunchSpecService
|
||||
var repoDir = list.WorkingDir;
|
||||
if (string.IsNullOrEmpty(repoDir) || !Directory.Exists(repoDir))
|
||||
throw new InvalidOperationException($"list '{list.Name}' has no existing working directory");
|
||||
repoDir = TrimTrailingSeparator(repoDir);
|
||||
|
||||
var briefLines = new List<string>();
|
||||
foreach (var id in taskIds)
|
||||
@@ -300,6 +301,7 @@ public sealed class InteractiveLaunchSpecService : IInteractiveLaunchSpecService
|
||||
var repoDir = list.WorkingDir;
|
||||
if (string.IsNullOrEmpty(repoDir) || !Directory.Exists(repoDir))
|
||||
throw new InvalidOperationException($"list '{list.Name}' has no existing working directory");
|
||||
repoDir = TrimTrailingSeparator(repoDir);
|
||||
|
||||
var briefLines = new List<string>();
|
||||
foreach (var id in survivingTaskIds)
|
||||
@@ -349,6 +351,19 @@ public sealed class InteractiveLaunchSpecService : IInteractiveLaunchSpecService
|
||||
return new LaunchSpec(repoDir, resolvedClaude, args, env);
|
||||
}
|
||||
|
||||
// Strips a trailing directory separator off a path bound for the CLI argument list. The ConPTY
|
||||
// host flattens Args into ONE Windows command line and quotes each token, so a token ending in
|
||||
// '\' escapes its own closing quote ("C:\repo\" parses as C:\repo" ...) and every following
|
||||
// argument is absorbed into the preceding variadic flag -- for a list handler that means
|
||||
// --add-dir swallows --append-system-prompt-file AND the positional kickoff, and the session
|
||||
// opens with no prompt at all. Only user-supplied list working dirs can carry one; the session
|
||||
// dirs we build never do. A bare root ("C:\", "/") is all separator and is left untouched.
|
||||
private static string TrimTrailingSeparator(string dir)
|
||||
{
|
||||
var trimmed = dir.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||||
return trimmed.Length == 0 || trimmed.EndsWith(':') ? dir : trimmed;
|
||||
}
|
||||
|
||||
// Renders one task as a brief list item. A description can itself be arbitrary Markdown
|
||||
// (headings, lists, fenced code) — those must not merge into the brief's own task list, so
|
||||
// the description is placed in a fenced code block indented to the list item's continuation
|
||||
|
||||
Reference in New Issue
Block a user