Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions cmd/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ Use --fix to automatically repair missing AGENTS.md, skills, or spec directories
}

if harnessFix || (len(args) > 0 && args[0] == "fix") {
fixResult, err := harness.FixWorkspaceHarness(ctx, targetDir, report)
if err != nil {
return fmt.Errorf("harness auto-fix failed: %w", err)
fixResult, fixErr := harness.FixWorkspaceHarness(ctx, targetDir, report)
if fixErr != nil {
return fmt.Errorf("harness auto-fix failed: %w", fixErr)
}
fmt.Printf("🔧 Hawk Harness Auto-Repair Results:\n")
fmt.Printf("[FIX] Hawk Harness Auto-Repair Results:\n")
for _, repair := range fixResult.RepairsPerformed {
fmt.Printf(" %s\n", repair)
fmt.Printf(" + %s\n", repair)
}
// Re-evaluate workspace after fix
report, _ = harness.EvaluateWorkspace(ctx, targetDir, opts)
Expand All @@ -63,38 +63,38 @@ Use --fix to automatically repair missing AGENTS.md, skills, or spec directories
outDir = filepath.Join(targetDir, ".hawk", "harness")
}

if err := os.MkdirAll(outDir, 0o755); err != nil {
return fmt.Errorf("failed to create harness output directory: %w", err)
if mkdirErr := os.MkdirAll(outDir, 0o755); mkdirErr != nil {
return fmt.Errorf("failed to create harness output directory: %w", mkdirErr)
}

// Write Markdown report
mdPath := filepath.Join(outDir, "report.md")
mdContent := harness.RenderMarkdown(report)
if err := os.WriteFile(mdPath, []byte(mdContent), 0o644); err != nil {
return fmt.Errorf("failed to write report.md: %w", err)
if writeErr := os.WriteFile(mdPath, []byte(mdContent), 0o644); writeErr != nil {
return fmt.Errorf("failed to write report.md: %w", writeErr)
}

// Write HTML report
htmlPath := filepath.Join(outDir, "report.html")
htmlContent := harness.RenderHTML(report)
if err := os.WriteFile(htmlPath, []byte(htmlContent), 0o644); err != nil {
return fmt.Errorf("failed to write report.html: %w", err)
if writeErr := os.WriteFile(htmlPath, []byte(htmlContent), 0o644); writeErr != nil {
return fmt.Errorf("failed to write report.html: %w", writeErr)
}

// Write JSON report
jsonPath := filepath.Join(outDir, "findings.json")
jsonContent, err := harness.RenderJSON(report)
if err != nil {
return fmt.Errorf("failed to serialize findings.json: %w", err)
jsonContent, renderErr := harness.RenderJSON(report)
if renderErr != nil {
return fmt.Errorf("failed to serialize findings.json: %w", renderErr)
}
if err := os.WriteFile(jsonPath, jsonContent, 0o644); err != nil {
return fmt.Errorf("failed to write findings.json: %w", err)
if writeErr := os.WriteFile(jsonPath, jsonContent, 0o644); writeErr != nil {
return fmt.Errorf("failed to write findings.json: %w", writeErr)
}

// Journal quality observation to Hawk execution graph
_ = harness.JournalHarnessReport(report, "")

fmt.Printf("🦅 Hawk Harness Evaluation Complete\n")
fmt.Printf("[HAWK] Hawk Harness Evaluation Complete\n")
fmt.Printf(" Overall Score : %d/100 (%s)\n", report.OverallScore, report.OverallStatus)
fmt.Printf(" Findings : %d prioritized issues\n", len(report.Findings))
fmt.Printf(" HTML Report : %s\n", htmlPath)
Expand Down
2 changes: 1 addition & 1 deletion external/hawk-core-contracts
2 changes: 1 addition & 1 deletion go.mod

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions internal/harness/harness_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,21 @@ func TestEvaluateWorkspace(t *testing.T) {
- Build with make
- Run tests before opening PR
`
if err := os.WriteFile(agentsPath, []byte(agentsContent), 0o644); err != nil {
t.Fatalf("Failed to write AGENTS.md: %v", err)
if writeErr := os.WriteFile(agentsPath, []byte(agentsContent), 0o644); writeErr != nil {
t.Fatalf("Failed to write AGENTS.md: %v", writeErr)
}

makefileContent := `test:
go test ./...
lint:
golangci-lint run
`
if err := os.WriteFile(filepath.Join(tmpDir, "Makefile"), []byte(makefileContent), 0o644); err != nil {
t.Fatalf("Failed to write Makefile: %v", err)
if writeErr := os.WriteFile(filepath.Join(tmpDir, "Makefile"), []byte(makefileContent), 0o644); writeErr != nil {
t.Fatalf("Failed to write Makefile: %v", writeErr)
}

if err := os.WriteFile(filepath.Join(tmpDir, ".golangci.yml"), []byte("linters:\n enable:\n - errcheck\n"), 0o644); err != nil {
t.Fatalf("Failed to write .golangci.yml: %v", err)
if writeErr := os.WriteFile(filepath.Join(tmpDir, ".golangci.yml"), []byte("linters:\n enable:\n - errcheck\n"), 0o644); writeErr != nil {
t.Fatalf("Failed to write .golangci.yml: %v", writeErr)
}

// 3. Re-evaluate with assets present
Expand Down
14 changes: 7 additions & 7 deletions internal/harness/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ func RenderJSON(report *HarnessReport) ([]byte, error) {
func RenderMarkdown(report *HarnessReport) string {
var sb strings.Builder

sb.WriteString("# 🦅 Hawk Agent Harness Review Report\n\n")
sb.WriteString("# Hawk Agent Harness Review Report\n\n")
sb.WriteString(fmt.Sprintf("**Target Workspace:** `%s` \n", report.TargetPath))
sb.WriteString(fmt.Sprintf("**Generated At:** %s \n", report.GeneratedAt.Format(time.RFC1123)))
sb.WriteString(fmt.Sprintf("**Overall Harness Health Score:** **%d / 100** (%s)\n\n", report.OverallScore, report.OverallStatus))

sb.WriteString("## Executive Summary\n\n")
sb.WriteString(report.Summary + "\n\n")

sb.WriteString("## 📊 Agent Work Loop Dimensions\n\n")
sb.WriteString("## Agent Work Loop Dimensions\n\n")
sb.WriteString("| Dimension | Score | Status | Summary |\n")
sb.WriteString("| :--- | :---: | :---: | :--- |\n")

Expand All @@ -43,7 +43,7 @@ func RenderMarkdown(report *HarnessReport) string {
}
sb.WriteString("\n")

sb.WriteString("## 🔍 Detected Harness Assets\n\n")
sb.WriteString("## Detected Harness Assets\n\n")
sb.WriteString(fmt.Sprintf("- **AGENTS.md**: %v\n", report.Assets.AgentsMD))
if report.Assets.AgentsMDPath != "" {
sb.WriteString(fmt.Sprintf(" - *Path*: `%s`\n", report.Assets.AgentsMDPath))
Expand All @@ -55,9 +55,9 @@ func RenderMarkdown(report *HarnessReport) string {
sb.WriteString(fmt.Sprintf("- **Hooks**: %s\n", strings.Join(report.Assets.Hooks, ", ")))
sb.WriteString(fmt.Sprintf("- **Autonomy Policy**: `%s` tier (Sandbox: `%s`)\n\n", report.Assets.AutonomyTier, report.Assets.SandboxPolicy))

sb.WriteString("## ⚠️ Prioritized Findings & Repair Recommendations\n\n")
sb.WriteString("## Prioritized Findings & Repair Recommendations\n\n")
if len(report.Findings) == 0 {
sb.WriteString("**No critical harness findings detected!** Your project is well-configured for AI agent workflows.\n")
sb.WriteString("**No critical harness findings detected!** Your project is well-configured for AI agent workflows.\n")
} else {
for i, f := range report.Findings {
sb.WriteString(fmt.Sprintf("### %d. [%s] %s (%s)\n\n", i+1, f.Severity, f.Title, f.Dimension))
Expand Down Expand Up @@ -208,7 +208,7 @@ func RenderHTML(report *HarnessReport) string {
<div class="container">
<div class="header">
<div class="title-area">
<h1>🦅 Hawk Agent Harness Review</h1>
<h1>Hawk Agent Harness Review</h1>
<div class="meta-info">Workspace: <code>` + report.TargetPath + `</code> | Generated: ` + report.GeneratedAt.Format(time.RFC1123) + `</div>
</div>
<div class="score-badge">
Expand Down Expand Up @@ -264,7 +264,7 @@ func RenderHTML(report *HarnessReport) string {
<h2>Prioritized Findings & Repair Plans</h2>`)

if len(report.Findings) == 0 {
sb.WriteString(`<p><strong>No critical findings!</strong> Workspace harness is well-configured.</p>`)
sb.WriteString(`<p><strong>No critical findings!</strong> Workspace harness is well-configured.</p>`)
} else {
for _, f := range report.Findings {
sb.WriteString(fmt.Sprintf(`
Expand Down
Loading