diff --git a/AnchorCli.csproj b/AnchorCli.csproj
index 371ec96..366e3b8 100644
--- a/AnchorCli.csproj
+++ b/AnchorCli.csproj
@@ -12,6 +12,12 @@
anchor
+
+ $(DefineConstants);WINDOWS
+
+ false
+
+
diff --git a/Program.cs b/Program.cs
index f112982..5a8d1d2 100644
--- a/Program.cs
+++ b/Program.cs
@@ -145,7 +145,7 @@ if (modelInfo != null)
// ── Chat history with system prompt ─────────────────────────────────────
List history =
[
- new(ChatRole.System, """
+ new(ChatRole.System, $$"""
You are anchor, a coding assistant that edits files using the Hashline technique.
## Reading files
@@ -166,6 +166,7 @@ List history =
4. If an anchor fails validation, re-read the file to get fresh anchors.
Keep responses concise. You have access to the current working directory.
+ You are running on: {{System.Runtime.InteropServices.RuntimeInformation.OSDescription}}
""")
];
diff --git a/Tools/CommandTool.cs b/Tools/CommandTool.cs
index d66f5be..87d9110 100644
--- a/Tools/CommandTool.cs
+++ b/Tools/CommandTool.cs
@@ -11,7 +11,11 @@ internal static class CommandTool
{
public static Action Log { get; set; } = Console.WriteLine;
- [Description("Execute a shell command after user approval. Prompts with [Y/n] before running. Note: For file editing and operations, use the built-in file tools (ReadFile, ReplaceLines, InsertAfter, DeleteRange, CreateFile, etc.) instead of shell commands.")]
+#if WINDOWS
+ [Description("Execute a PowerShell command after user approval. Prompts with [Y/n] before running. Note: For file editing and operations, use the built-in file tools (ReadFile, ReplaceLines, InsertAfter, DeleteRange, CreateFile, etc.) instead of shell commands.")]
+#else
+ [Description("Execute a Bash shell command after user approval. Prompts with [Y/n] before running. Note: For file editing and operations, use the built-in file tools (ReadFile, ReplaceLines, InsertAfter, DeleteRange, CreateFile, etc.) instead of shell commands.")]
+#endif
public static string ExecuteCommand(
[Description("The shell command to execute.")] string command)
{
@@ -41,8 +45,13 @@ internal static class CommandTool
{
var startInfo = new ProcessStartInfo
{
+#if WINDOWS
+ FileName = "powershell.exe",
+ Arguments = $"-NoProfile -Command \"{command}\"",
+#else
FileName = "/bin/bash",
Arguments = $"-c \"{command}\"",
+#endif
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
diff --git a/installer.ps1 b/installer.ps1
new file mode 100644
index 0000000..31fbcb7
--- /dev/null
+++ b/installer.ps1
@@ -0,0 +1,39 @@
+$ErrorActionPreference = "Stop"
+
+Write-Host "Publishing project..."
+dotnet publish -c Release -r win-x64 -p:PublishSingleFile=true -o ./publish
+
+Write-Host "Finding binary..."
+$binary = Get-ChildItem -Path ./publish -Filter "anchor.exe" -File | Select-Object -First 1
+
+if (-not $binary) {
+ Write-Host "Error: Could not find anchor.exe in ./publish" -ForegroundColor Red
+ exit 1
+}
+
+Write-Host "Found binary: $($binary.FullName)"
+
+# Define the installation directory in the user's profile
+$installDir = Join-Path $env:USERPROFILE ".anchor\bin"
+
+if (-not (Test-Path $installDir)) {
+ Write-Host "Creating installation directory: $installDir"
+ New-Item -ItemType Directory -Path $installDir | Out-Null
+}
+
+Write-Host "Copying to $installDir..."
+Copy-Item -Path $binary.FullName -Destination $installDir -Force
+
+# Check if the installation directory is in the User PATH
+$userPath = [Environment]::GetEnvironmentVariable("PATH", "User")
+if ($userPath -split ';' -notcontains $installDir) {
+ Write-Host "Adding $installDir to User PATH..."
+ $newPath = if ($userPath) { "$userPath;$installDir" } else { $installDir }
+ [Environment]::SetEnvironmentVariable("PATH", $newPath, "User")
+ Write-Host "PATH updated. You may need to restart your terminal for changes to take effect." -ForegroundColor Yellow
+}
+else {
+ Write-Host "$installDir is already in the PATH."
+}
+
+Write-Host "Installation complete!" -ForegroundColor Green