Add native Windows support (#91)

- Native Windows daemon using TCP loopback endpoints
- Direct-mode fallback for CLI/daemon compatibility
- Comment operations over RPC
- PowerShell installer script
- Go 1.24 requirement
- Cross-OS testing documented

Co-authored-by: danshapiro <danshapiro@users.noreply.github.com>
Amp-Thread-ID: https://ampcode.com/threads/T-c6230265-055f-4af1-9712-4481061886db
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-10-20 21:08:49 -07:00
parent 94a23cae39
commit a86f3e139e
58 changed files with 1707 additions and 729 deletions

View File

@@ -2,6 +2,7 @@ package compact
import (
"context"
"errors"
"fmt"
"sync"
@@ -42,7 +43,11 @@ func New(store *sqlite.SQLiteStorage, apiKey string, config *CompactConfig) (*Co
if !config.DryRun {
haikuClient, err = NewHaikuClient(config.APIKey)
if err != nil {
return nil, fmt.Errorf("failed to create Haiku client: %w", err)
if errors.Is(err, ErrAPIKeyRequired) {
config.DryRun = true
} else {
return nil, fmt.Errorf("failed to create Haiku client: %w", err)
}
}
}
@@ -54,10 +59,10 @@ func New(store *sqlite.SQLiteStorage, apiKey string, config *CompactConfig) (*Co
}
type CompactResult struct {
IssueID string
OriginalSize int
IssueID string
OriginalSize int
CompactedSize int
Err error
Err error
}
func (c *Compactor) CompactTier1(ctx context.Context, issueID string) error {

View File

@@ -22,6 +22,8 @@ const (
initialBackoff = 1 * time.Second
)
var ErrAPIKeyRequired = errors.New("API key required")
// HaikuClient wraps the Anthropic API for issue summarization.
type HaikuClient struct {
client anthropic.Client
@@ -39,7 +41,7 @@ func NewHaikuClient(apiKey string) (*HaikuClient, error) {
apiKey = envKey
}
if apiKey == "" {
return nil, fmt.Errorf("API key required: set ANTHROPIC_API_KEY environment variable or provide via config")
return nil, fmt.Errorf("%w: set ANTHROPIC_API_KEY environment variable or provide via config", ErrAPIKeyRequired)
}
client := anthropic.NewClient(option.WithAPIKey(apiKey))

View File

@@ -17,6 +17,9 @@ func TestNewHaikuClient_RequiresAPIKey(t *testing.T) {
if err == nil {
t.Fatal("expected error when API key is missing")
}
if !errors.Is(err, ErrAPIKeyRequired) {
t.Fatalf("expected ErrAPIKeyRequired, got %v", err)
}
if !strings.Contains(err.Error(), "API key required") {
t.Errorf("unexpected error message: %v", err)
}
@@ -53,13 +56,13 @@ func TestRenderTier1Prompt(t *testing.T) {
}
issue := &types.Issue{
ID: "bd-1",
Title: "Fix authentication bug",
Description: "Users can't log in with OAuth",
Design: "Add error handling to OAuth flow",
ID: "bd-1",
Title: "Fix authentication bug",
Description: "Users can't log in with OAuth",
Design: "Add error handling to OAuth flow",
AcceptanceCriteria: "Users can log in successfully",
Notes: "Related to issue bd-2",
Status: types.StatusClosed,
Notes: "Related to issue bd-2",
Status: types.StatusClosed,
}
prompt, err := client.renderTier1Prompt(issue)