Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
6e68b30
fix: point the skill index at the published registry release
Patel230 Sep 5, 2026
74f322c
fix: drop the phantom marketplace source
Patel230 Sep 5, 2026
9c44a5f
docs: state that graycode cloud requires an explicit endpoint
Patel230 Sep 5, 2026
c9fc666
docs: correct the router boundary guard comment
Patel230 Sep 5, 2026
f5022a1
fix: repair two boundary guards that could not fail
Patel230 Sep 5, 2026
7926c4b
docs: align the ecosystem section with ecosystem.yaml
Patel230 Sep 5, 2026
f8621fd
fix: resolve code-review findings across engine, memory, tool, daemon
Patel230 Sep 6, 2026
09460f1
feat: animate review run and audit with TTY-aware progress
Patel230 Sep 6, 2026
f7b378a
feat: animate harness evaluation and report-writing stages
Patel230 Sep 6, 2026
5035549
feat: animate slow project-check phase of verify
Patel230 Sep 6, 2026
e085a22
feat: show ETA estimate in progress animation
Patel230 Sep 6, 2026
0ea8cbe
test: guard audit JSON purity with auditProgressEnabled
Patel230 Sep 6, 2026
9ee240d
feat: theme the audit text report
Patel230 Sep 6, 2026
f4ac169
feat: animate the eval loop agent run
Patel230 Sep 6, 2026
937148c
feat: honor --quiet/NO_COLOR/FORCE_COLOR in progress and theme
Patel230 Sep 6, 2026
574201d
feat: animate the harness --fix repair step
Patel230 Sep 6, 2026
9b998ce
feat: per-task progress for eval benchmark suites
Patel230 Sep 6, 2026
4601d1f
feat: theme the review run summary
Patel230 Sep 6, 2026
5ff8118
feat: colorize audit summary block
Patel230 Sep 6, 2026
c411d96
feat: theme the harness final summary
Patel230 Sep 6, 2026
98441d8
feat: theme verify check markers
Patel230 Sep 6, 2026
012dbce
feat: theme the usage report
Patel230 Sep 6, 2026
f776acf
feat: theme the usage statistics report
Patel230 Sep 6, 2026
19b1960
feat: theme the doctor health check report
Patel230 Sep 6, 2026
62a5f47
feat: theme the status snapshot report
Patel230 Sep 6, 2026
c52af33
feat: theme the security log verify result
Patel230 Sep 6, 2026
28f43b2
feat: theme the review status report
Patel230 Sep 6, 2026
c997d67
feat: theme the plugin status table
Patel230 Sep 6, 2026
34e4ad6
feat: theme the daemon status output
Patel230 Sep 6, 2026
cefeaa8
feat: animate the models catalog flows
Patel230 Sep 6, 2026
a55787f
feat: animate doctor and preflight --live
Patel230 Sep 6, 2026
bef3b64
feat: theme the version line
Patel230 Sep 6, 2026
e80073c
feat: theme the governance explain decision
Patel230 Sep 6, 2026
12d1022
feat: theme context export and review hook install confirmations
Patel230 Sep 6, 2026
8f37fba
feat: theme the learn command output
Patel230 Sep 6, 2026
bed3520
feat: theme the governance show/validate reports
Patel230 Sep 6, 2026
af684b8
feat: theme feedback, sandbox, cloud, and cost output
Patel230 Sep 6, 2026
dd73274
feat: animate cloud login browser approval
Patel230 Sep 6, 2026
d7d443b
feat: theme the update command output
Patel230 Sep 6, 2026
c25ed7f
feat: theme the recover command output
Patel230 Sep 6, 2026
8ff94f8
feat: theme the tape status/commit reports
Patel230 Sep 6, 2026
72f02b4
feat: theme the config update confirmations
Patel230 Sep 6, 2026
41b5b62
feat: theme the plugin command confirmations
Patel230 Sep 6, 2026
a468736
feat: theme session export and migrate confirmations
Patel230 Sep 6, 2026
fd81c76
feat: theme skills and curator output
Patel230 Sep 6, 2026
4e95595
feat: theme the features report
Patel230 Sep 6, 2026
68eeec1
feat: theme review analyze/fix/refine output
Patel230 Sep 6, 2026
74e30dc
feat: theme the daemon stop confirmation
Patel230 Sep 6, 2026
cda483c
feat: theme the credentials remove/migrate confirmations
Patel230 Sep 6, 2026
37a8d48
feat: theme marketplace and agent command output
Patel230 Sep 6, 2026
d2cf75f
feat: theme the plan command output
Patel230 Sep 6, 2026
9b91771
feat: theme the trust command output
Patel230 Sep 6, 2026
8e500f6
feat: theme the securitylog show and toolset output
Patel230 Sep 7, 2026
dcfaf3e
feat: theme the harness auto-repair results
Patel230 Sep 7, 2026
ffc5c86
feat: theme the checkpoint save/list/restore/delete output
Patel230 Sep 7, 2026
1311c92
feat: theme the background session start/attach output
Patel230 Sep 7, 2026
aa37fae
feat: theme the rules detect/import/export output
Patel230 Sep 7, 2026
27eb5b7
feat: theme the snapshot list/restore/diff output
Patel230 Sep 7, 2026
f6094a9
feat: theme the eval command output
Patel230 Sep 7, 2026
d3ce7db
feat: theme the cloud login device instructions
Patel230 Sep 7, 2026
619c7db
feat: theme the feedback prompt and browser fallback
Patel230 Sep 7, 2026
f9ab7ef
feat: theme the daemon stale-pid status line
Patel230 Sep 7, 2026
2459c0e
feat: theme the interrupted-session recovery notice
Patel230 Sep 7, 2026
2c9e0ea
feat: theme agent, cmdhistory, permissions, pr, issue, mission, plugi…
Patel230 Sep 7, 2026
1391aca
feat: theme audit empty-state, cmdhistory entries, cloud graph sync
Patel230 Sep 7, 2026
284d1e0
feat: theme the review close confirmation
Patel230 Sep 7, 2026
3050475
feat: theme cost summary, review run/refine/list, search output
Patel230 Sep 7, 2026
14b2245
feat: animate context export to file
Patel230 Sep 7, 2026
baf6b45
feat: honor ShouldColor in review show and severity labels
Patel230 Sep 7, 2026
151b1f8
feat: modern colorized help output
Patel230 Sep 7, 2026
2b6e93b
feat: theme review show empty-state and daemon WARNING
Patel230 Sep 7, 2026
1d76fd8
feat: theme REPL startup banner
Patel230 Sep 7, 2026
9dbea1c
feat: theme taste and vibe command output
Patel230 Sep 7, 2026
eeae07a
feat: colorize top-level CLI errors
Patel230 Sep 7, 2026
a31aef0
feat: theme swift-report confirmations
Patel230 Sep 7, 2026
f5a01ee
feat: theme review finding rows and skills info
Patel230 Sep 7, 2026
de66198
feat: theme print-mode tool and countdown indicators
Patel230 Sep 7, 2026
f137233
feat: theme watch-mode status indicators
Patel230 Sep 7, 2026
8f810f1
feat: theme background-session list
Patel230 Sep 7, 2026
fa05f25
feat: theme stats empty-state
Patel230 Sep 7, 2026
582f5d0
feat: theme internal ecosystem panel and credentials status
Patel230 Sep 7, 2026
49511fb
feat: theme catalog health and config summary reports
Patel230 Sep 7, 2026
14e928d
feat: theme config summary report
Patel230 Sep 7, 2026
04e6442
fix: plan list shows plan name instead of duplicate title
Patel230 Sep 7, 2026
794fa7e
fix: cap verify workspace checks at 10m
Patel230 Sep 7, 2026
404d2c2
fix: doctor --json now emits real JSON
Patel230 Sep 7, 2026
0441bcc
feat: show active step name in CLIProgress animation frame
Patel230 Sep 7, 2026
0425770
feat: theme the developer path readiness report
Patel230 Sep 7, 2026
b433333
feat: honor NO_COLOR in the onboarding wizard
Patel230 Sep 7, 2026
6ba1e6b
feat: theme the mission final summary line
Patel230 Sep 7, 2026
5fb858e
feat: theme the sandbox status report
Patel230 Sep 7, 2026
4f17ee3
feat: theme the shell completion install confirmation
Patel230 Sep 7, 2026
30d2aba
feat: theme the taste prompt-fragment header
Patel230 Sep 7, 2026
01d024c
feat: theme the review list view status and findings
Patel230 Sep 7, 2026
a082249
feat: theme the skills trending list number prefix
Patel230 Sep 7, 2026
ea41a19
feat: theme the review findings detail index and file:line
Patel230 Sep 7, 2026
6651658
feat: mute command descriptions in help output
Patel230 Sep 7, 2026
0027ffc
feat: show a muted usage summary after exec completes
Patel230 Sep 7, 2026
b97baf0
fix: bound the gh issue create call with a 60s timeout
Patel230 Sep 7, 2026
7e18d2b
feat: announce which review is being fixed before running exec
Patel230 Sep 7, 2026
4a622f5
feat: animate review analyze model call
Patel230 Sep 7, 2026
1d04c23
feat: animate mission execution
Patel230 Sep 7, 2026
6ef8c08
feat: theme exec fanout attempt headers
Patel230 Sep 7, 2026
8cc777e
feat: theme exec fanout comparison report status
Patel230 Sep 7, 2026
8281007
feat: theme exec stderr diagnostics
Patel230 Sep 7, 2026
969b0d5
feat: theme ai-comments and chat diagnostics
Patel230 Sep 7, 2026
8a599a9
feat: theme chat REPL error lines
Patel230 Sep 7, 2026
8c5adb5
feat: theme daemon and eval stderr warnings
Patel230 Sep 7, 2026
71102b8
feat: show old-to-new transition in config set
Patel230 Sep 7, 2026
73cdee2
refactor: unify config set/provider/model transition display
Patel230 Sep 7, 2026
6aaae62
feat: show (unset) for unset config values
Patel230 Sep 7, 2026
aff801a
feat: show elapsed time on verify completion
Patel230 Sep 7, 2026
662e832
docs: record graycode-eco integrity plan
Patel230 Sep 7, 2026
e37ba1f
fix: gofumpt formatting; drop non-deliverable plan doc from merge
Patel230 Sep 7, 2026
c0ec80d
fix: resolve golangci-lint errcheck + staticcheck findings
Patel230 Sep 7, 2026
bc3a8f0
fix: gofumpt short declaration for statusColor
Patel230 Sep 7, 2026
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
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ This project is indexed by GitNexus as **graycode** (97743 symbols, 322940 relat
| `gitnexus://repo/graycode/context` | Codebase overview, check index freshness |
| `gitnexus://repo/graycode/clusters` | All functional areas |
| `gitnexus://repo/graycode/processes` | All execution flows |
| `gitnexus://repo/graycode/process/{name}` | Step-by-step execution swift |
| `gitnexus://repo/graycode/process/{name}` | Step-by-step execution trace |

## CLI

Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This project is indexed by GitNexus as **graycode** (97743 symbols, 322940 relat
| `gitnexus://repo/graycode/context` | Codebase overview, check index freshness |
| `gitnexus://repo/graycode/clusters` | All functional areas |
| `gitnexus://repo/graycode/processes` | All execution flows |
| `gitnexus://repo/graycode/process/{name}` | Step-by-step execution swift |
| `gitnexus://repo/graycode/process/{name}` | Step-by-step execution trace |

## CLI

Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ graycode cloud graph sync <session-id>
graycode cloud graph sync --mission-dir /path/to/mission
```

Cloud commands require an endpoint. There is no default: pass `--endpoint` or
set `GRAYCODE_CLOUD_URL` to your Graycode Cloud worker URL before running
`graycode cloud login`. `https://api.graycodeai.com` is the browser BFF and
will reject a device token.

The export contains metadata and hashes, not prompts, tool arguments/results,
policy reasons, verification evidence, or runtime output. Swift remains
available separately as `graycode swift graph export`. Persisted chat sessions
Expand Down Expand Up @@ -483,6 +488,14 @@ You may keep a **personal** parent **`go.work`** that lists alternate clones on
|---|---|---|
| **graycode** | This repo | AI coding agent |
| **graycode-router** | [GrayCodeAI/graycode-router](https://github.com/GrayCodeAI/graycode-router) | LLM provider runtime |
| **graycode-skills** | [GrayCodeAI/graycode-skills](https://github.com/GrayCodeAI/graycode-skills) | Community skill registry |
| **graycode-platform** | [GrayCodeAI/graycode-platform](https://github.com/GrayCodeAI/graycode-platform) | Web, BFF, and Graycode Cloud |

`ecosystem.yaml` is the canonical inventory of repositories cloned as
siblings in this local workspace; tooling reads it rather than carrying its
own repo-name list. `harrier`, `shrike`, `swift`, `kestrel`, `merlin` and
`falcon` above are consumed as pinned `go.mod` module dependencies rather
than local workspace clones, so they are not listed there.

For the consolidated repo map and the current-vs-proposed architecture diagrams, see [docs/architecture/graycode-current-vs-proposed.md](docs/architecture/graycode-current-vs-proposed.md).
For execution-graph ownership, automatic capture seams, export/sync commands,
Expand Down
20 changes: 10 additions & 10 deletions cmd/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ func runAgentList(cmd *cobra.Command, _ []string) error {
return nil
}
if len(all) == 0 {
fmt.Printf("No agents found. Create one with: graycode agent create <name>\n")
fmt.Printf("Agent directory: %s\n", agents.DefaultDir())
fmt.Printf("%s\n", auditTint("No agents found. Create one with: graycode agent create <name>", textMuted))
fmt.Printf("%s\n", auditTint("Agent directory: "+agents.DefaultDir(), textPrimary))
return nil
}

Expand Down Expand Up @@ -146,8 +146,8 @@ You are a specialized agent. Complete tasks according to your expertise.
return err
}

fmt.Printf("Created agent %q at %s\n", name, path)
fmt.Printf("Edit the file to customize the system prompt.\n")
fmt.Printf("%s\n", auditTint("Created agent "+name+" at ", doneGreen)+auditTint(path, textPrimary))
fmt.Printf("%s\n", auditTint("Edit the file to customize the system prompt.", textMuted))
return nil
}

Expand All @@ -157,15 +157,15 @@ func runAgentShow(_ *cobra.Command, args []string) error {
return err
}

fmt.Printf("Name: %s\n", a.Name)
fmt.Printf("Description: %s\n", a.Description)
fmt.Printf("%s %s\n", auditTint("Name:", textMuted), auditTint(a.Name, textPrimary))
fmt.Printf("%s %s\n", auditTint("Description:", textMuted), auditTint(a.Description, textPrimary))
model := a.Model
if model == "" {
model = "(inherit from session)"
}
fmt.Printf("Model: %s\n", model)
fmt.Printf("File: %s\n", a.FilePath)
fmt.Printf("\n--- Prompt ---\n%s\n", a.Prompt)
fmt.Printf("%s %s\n", auditTint("Model:", textMuted), auditTint(model, textPrimary))
fmt.Printf("%s %s\n", auditTint("File:", textMuted), auditTint(a.FilePath, textPrimary))
fmt.Printf("\n%s\n%s\n", auditTint("--- Prompt ---", graycodeColor), a.Prompt)
return nil
}

Expand All @@ -178,6 +178,6 @@ func runAgentRemove(_ *cobra.Command, args []string) error {
if err := os.Remove(a.FilePath); err != nil {
return fmt.Errorf("remove %s: %w", a.FilePath, err)
}
fmt.Printf("Removed agent %q (%s)\n", a.Name, a.FilePath)
fmt.Printf("%s\n", auditTint("Removed agent "+a.Name+" ("+a.FilePath+")", textPrimary))
return nil
}
4 changes: 2 additions & 2 deletions cmd/ai_comments.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func processAIDirectives(dir string, ignore []string) int {
processed := 0
for _, d := range directives {
if err := aiDispatchFn(d); err != nil {
fmt.Fprintf(os.Stderr, "AI directive %s:%d failed: %v\n", d.Path, d.Line, err)
fmt.Fprintf(os.Stderr, "%s\n", auditTint(fmt.Sprintf("AI directive %s:%d failed: %v", d.Path, d.Line, err), errorCoral))
continue
}
// Resolve back to an absolute path for removal; scan returns paths
Expand All @@ -160,7 +160,7 @@ func processAIDirectives(dir string, ignore []string) int {
full = filepath.Join(dir, d.Path)
}
if err := removeAIComment(full, d.Line); err != nil {
fmt.Fprintf(os.Stderr, "AI directive %s:%d: failed to strip token: %v\n", d.Path, d.Line, err)
fmt.Fprintf(os.Stderr, "%s\n", auditTint(fmt.Sprintf("AI directive %s:%d: failed to strip token: %v", d.Path, d.Line, err), errorCoral))
continue
}
processed++
Expand Down
86 changes: 76 additions & 10 deletions cmd/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package cmd
import (
"encoding/json"
"fmt"
"image/color"
"os"
"path/filepath"
"sort"
"strings"
"time"

lipgloss "charm.land/lipgloss/v2"
"github.com/GrayCodeAI/graycode-cli/internal/hooks/audit"
"github.com/GrayCodeAI/graycode-cli/internal/storage"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -65,6 +67,13 @@ type AuditResult struct {
Detectors []AuditCount `json:"detectors"`
}

// auditProgressEnabled reports whether per-session progress should be shown.
// JSON output must stay pure (progress lines would corrupt it) and piped
// text should not be spammed with per-session lines.
func auditProgressEnabled(format string, tty bool) bool {
return format != "json" && tty
}

func runAudit(cmd *cobra.Command, args []string) error {
if auditJSON {
auditFormat = "json"
Expand All @@ -77,18 +86,37 @@ func runAudit(cmd *cobra.Command, args []string) error {
}

if len(sessions) == 0 {
cmd.Println("No session transcripts found for the specified time period.")
cmd.Println(auditTint("No session transcripts found for the specified time period.", textMuted))
return nil
}

// Animated per-session progress only on a TTY and only for text output.
// JSON output must stay pure (progress lines would corrupt it) and piped
// text should not be spammed with per-session lines.
var prog *CLIProgress
if auditProgressEnabled(auditFormat, stdoutIsTerminal()) && !IsQuiet() {
names := make([]string, len(sessions))
for i := range sessions {
names[i] = fmt.Sprintf("Scanning session %d/%d", i+1, len(sessions))
}
prog = NewCLIProgress("Audit", names)
defer prog.Abort()
}

// Run audit detectors on each session
detectors := audit.AllDetectors()
counts := make(map[string]*AuditCount)
totalHits := 0

for _, sess := range sessions {
for i, sess := range sessions {
if prog != nil {
prog.StartStep(i)
}
events, err := loadSessionEvents(sess.Path)
if err != nil {
if prog != nil {
prog.FailStep(i, "load failed")
}
continue
}

Expand Down Expand Up @@ -125,6 +153,12 @@ func runAudit(cmd *cobra.Command, args []string) error {
}
}
}
if prog != nil {
prog.CompleteStep(i)
}
}
if prog != nil {
prog.Done()
}

// Count unique projects per detector
Expand Down Expand Up @@ -250,25 +284,54 @@ func loadSessionEvents(path string) ([]audit.ToolEvent, error) {
return events, nil
}

// auditTint applies a theme foreground color when color output is appropriate
// (honors --quiet, NO_COLOR, FORCE_COLOR, and TTY state via ShouldColor).
// Piped output stays plain so scripts never see stray ANSI escapes.
func auditTint(s string, color color.Color) string {
if !ShouldColor() || s == "" {
return s
}
return lipgloss.NewStyle().Foreground(color).Render(s)
}

// auditSeverityColor maps a detector severity to a semantic theme color.
func auditSeverityColor(sev string) color.Color {
switch sev {
case "high", "critical":
return errorCoral
case "medium":
return warnAmber
default: // info, low
return infoSky
}
}

func printAuditText(cmd *cobra.Command, result AuditResult) {
w := cmd.OutOrStdout()

_, _ = fmt.Fprintf(w, "\n")
_, _ = fmt.Fprintf(w, "═══════════════════════════════════════════════════════════════\n")
_, _ = fmt.Fprintf(w, " Graycode Audit Report\n")
_, _ = fmt.Fprintf(w, " %s\n", auditTint("Graycode Audit Report", graycodeColor))
_, _ = fmt.Fprintf(w, "═══════════════════════════════════════════════════════════════\n")
_, _ = fmt.Fprintf(w, "\n")
_, _ = fmt.Fprintf(w, " Scanned: %d sessions (last %d days)\n", result.Sessions, result.Days)
_, _ = fmt.Fprintf(w, " Total hits: %d\n", result.TotalHits)
_, _ = fmt.Fprintf(w, " Scanned at: %s\n", result.ScannedAt)
_, _ = fmt.Fprintf(w, " %s %d sessions (last %d days)\n",
auditTint("Scanned:", textMuted), result.Sessions, result.Days)
hitsColor := doneGreen
if result.TotalHits > 0 {
hitsColor = errorCoral
}
_, _ = fmt.Fprintf(w, " %s %s\n",
auditTint("Total hits:", textMuted), auditTint(fmt.Sprintf("%d", result.TotalHits), hitsColor))
_, _ = fmt.Fprintf(w, " %s %s\n",
auditTint("Scanned at:", textMuted), auditTint(result.ScannedAt, textPrimary))

if len(result.Detectors) == 0 {
_, _ = fmt.Fprintf(w, "\n No wasteful patterns detected. Great job!\n\n")
_, _ = fmt.Fprintf(w, "\n %s\n\n", auditTint("No wasteful patterns detected. Great job!", doneGreen))
return
}

_, _ = fmt.Fprintf(w, "\n")
_, _ = fmt.Fprintf(w, "─── Detected Patterns ───\n\n")
_, _ = fmt.Fprintf(w, "─── %s ───\n\n", auditTint("Detected Patterns", infoSky))
_, _ = fmt.Fprintf(w, " %-30s %6s %8s %s\n", "DETECTOR", "HITS", "SEVERITY", "EXAMPLE")
_, _ = fmt.Fprintf(w, " %-30s %6s %8s %s\n", strings.Repeat("─", 30), strings.Repeat("─", 6), strings.Repeat("─", 8), strings.Repeat("─", 30))

Expand All @@ -277,11 +340,14 @@ func printAuditText(cmd *cobra.Command, result AuditResult) {
if len(d.Examples) > 0 {
example = d.Examples[0]
}
_, _ = fmt.Fprintf(w, " %-30s %6d %8s %s\n", d.Name, d.Hits, d.Severity, example)
// Pad to the column width first, then colorize, so ANSI escapes
// (zero-width) don't break the fixed-width alignment.
sev := auditTint(fmt.Sprintf("%8s", d.Severity), auditSeverityColor(d.Severity))
_, _ = fmt.Fprintf(w, " %-30s %6d %s %s\n", d.Name, d.Hits, sev, example)
}

_, _ = fmt.Fprintf(w, "\n")
_, _ = fmt.Fprintf(w, "─── Remediation Tips ───\n\n")
_, _ = fmt.Fprintf(w, "─── %s ───\n\n", auditTint("Remediation Tips", infoSky))

for _, d := range result.Detectors {
switch d.Name {
Expand Down
46 changes: 46 additions & 0 deletions cmd/audit_progress_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cmd

import "testing"

// TestAuditProgressEnabled guards the JSON-purity contract: per-session
// progress must never render when output is JSON (it would corrupt the
// payload) or when stdout is piped (it would spam the report).
func TestAuditProgressEnabled(t *testing.T) {
cases := []struct {
format string
tty bool
want bool
}{
{"json", true, false}, // JSON output must stay pure even on a TTY
{"json", false, false}, // JSON + piped: never
{"text", false, false}, // piped text: no per-session spam
{"text", true, true}, // interactive text: animate
{"", true, true}, // default format on a TTY: animate
{"", false, false}, // default format piped: no spam
}
for _, c := range cases {
if got := auditProgressEnabled(c.format, c.tty); got != c.want {
t.Errorf("auditProgressEnabled(%q, %v) = %v, want %v", c.format, c.tty, got, c.want)
}
}
}

// TestAuditSeverityColor verifies severity maps to the expected semantic
// theme color so the report's severity column reads consistently.
func TestAuditSeverityColor(t *testing.T) {
if auditSeverityColor("high") != errorCoral {
t.Error("high should map to errorCoral")
}
if auditSeverityColor("critical") != errorCoral {
t.Error("critical should map to errorCoral")
}
if auditSeverityColor("medium") != warnAmber {
t.Error("medium should map to warnAmber")
}
if auditSeverityColor("low") != infoSky {
t.Error("low should map to infoSky")
}
if auditSeverityColor("info") != infoSky {
t.Error("info should map to infoSky")
}
}
Loading
Loading