Files
ClaudeDo/src/ClaudeDo.Data/Models/SshWorkspace.cs
T

30 lines
1.4 KiB
C#

using System.Text.RegularExpressions;
namespace ClaudeDo.Data.Models;
/// <summary>A server an interactive claude session can be started on via ssh; connection details live in the user's ssh config.</summary>
public sealed record SshWorkspace(string Id, string Name, string Host, string RemotePath)
{
// A leading '-' would make ssh parse the alias as an option (-oProxyCommand=... runs local code).
private static readonly Regex HostPattern = new(@"^[A-Za-z0-9._@][A-Za-z0-9._@-]*$", RegexOptions.Compiled);
/// <summary>Returns the first invalid field ("name", "host", "path") or null when valid.</summary>
public static string? Validate(SshWorkspace w)
{
if (string.IsNullOrWhiteSpace(w.Name)) return "name";
if (string.IsNullOrEmpty(w.Host) || !HostPattern.IsMatch(w.Host)) return "host";
var p = w.RemotePath ?? "";
if (!(p.StartsWith('/') || p.StartsWith('~')) || p.Contains('\'') || p.Contains('\n') || p.Contains('\r'))
return "path";
return null;
}
/// <summary>Single-quotes a validated remote path for a POSIX shell, leaving a leading <c>~</c> unquoted so it still expands.</summary>
public static string QuoteRemotePath(string path)
{
if (path == "~") return "~";
if (path.StartsWith("~/")) return "~/'" + path[2..] + "'";
return "'" + path + "'";
}
}