Skip to content

Polish: theme, animation, non-TTY purity, robustness - #282

Merged
Patel230 merged 116 commits into
mainfrom
fix/eco-integrity
Sep 7, 2026
Merged

Patel230 merged 116 commits into
mainfrom
fix/eco-integrity

Conversation

@Patel230

@Patel230 Patel230 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Modernizes and hardens the graycode CLI across four dimensions:

Theming

  • Semantic color across ~55 commands, summaries, status reports, and stderr diagnostics via a shared auditTint helper + self-contained internal/theme for non-cmd packages.
  • Honors NO_COLOR/FORCE_COLOR/--quiet; tables/JSON/markdown/streams stay byte-clean.

Animation

  • CLIProgress (themed progress bar + ETA) wired into every slow flow: review run/analyze, audit, harness, verify, eval, models, doctor, preflight, cloud login, context --output, mission.
  • LLM-streaming commands use the stream itself as progress.

Non-TTY purity

  • Persistent --quiet; onboarding honors NO_COLOR; doctor --json now emits real JSON; pad-then-colorize alignment.

Robustness

  • verify 10-min timeout; gh issue create 60s timeout; BrailleSpinner one-shot panic fix.

Modern UX

  • config set/provider/model old→new transitions; config get (unset); verify elapsed time.

All tests pass (go test ./...), build/vet/gofmt clean.

The index URL referenced GrayCodeAI/starling, a repo renamed to
graycode-skills whose registry.json is generated and never committed,
so the URL 404d under either name. It now reads the rolling release
asset published by graycode-skills' publish-registry.yml.

Claude-Session: https://claude.ai/code/session_01MTUKadN91fcmuhxGWYVe2k
plugins-registry.json is generated by nothing in any of the four
GrayCode repos; the only reference anywhere was this default source.
FetchAll with no sources returns an empty list rather than erroring.

Claude-Session: https://claude.ai/code/session_01MTUKadN91fcmuhxGWYVe2k
The wire contract's servers.url is the browser BFF, which rejects a
device token; the worker itself has no route or custom domain.

Claude-Session: https://claude.ai/code/session_01MTUKadN91fcmuhxGWYVe2k
check-support-repo-coupling.sh built its regex from an empty peer
list, degenerating to a pattern matching nothing. The engine-boundary
script ran in CI but not on pre-push. Both AST tests carried a
gateway->credentials exception that no production file uses.

Claude-Session: https://claude.ai/code/session_01MTUKadN91fcmuhxGWYVe2k
Also replaces GrayCodeAI/starling test fixtures with the repo's
current name, and fixes an 'execution swift' typo left by an earlier
substring rename in the generated GitNexus tables.

Claude-Session: https://claude.ai/code/session_01MTUKadN91fcmuhxGWYVe2k
- eval list --json: project BenchmarkTask (func fields) to a JSON-safe struct
- stream: use a single RawMessages() snapshot (fixes len()+copy reallocation race)
- crash_unix: drop unreachable nil-return branch from raiseSignal
- tool: replace deprecated strings.Title with x/text cases.Title
- daemon: replace no-arg fmt.Sprintf with string literals
- fuzzyfind: replace deprecated filepath.HasPrefix with strings.HasPrefix
- memory: thread context.Context through MemoryRecaller.Remember so background
  remember goroutines honor their timeout (fixes goroutine leak from discarded rCtx)
- contracts/types: remove deprecated fail-open ParseSeverity (zero callers)
Wire the previously-unused ProgressTracker into real command flows via a
new CLIProgress helper:

- cmd/progress_cli.go: TTY-aware progress renderer. On a terminal it
  repaints the active step in place with a braille spinner, theme-colored
  progress bar, and live N/M counter; piped/CI output is one clean static
  line per step with no ANSI. Completion prints a themed summary with the
  final bar (errorCoral when any step failed). Glyphs come from
  internal/ui/icons; block glyphs stay in the audit-permitted U+2500-U+25FF
  range.
- cmd/review_run.go: progress over Building model / Reviewing code /
  Saving results, silent in background/hook mode.
- cmd/audit.go: per-session progress, gated to TTY + text output so --json
  stays pure and piped output isn't spammed.
- cmd/progress_cli_test.go: non-TTY, TTY, fail-step, and multi-step
  regression tests (the multi-step test covers a fresh-spinner-per-step fix
  for BrailleSpinner's one-shot Start/Stop panic).
Wire CLIProgress into the harness command over Evaluating workspace /
Writing markdown / Writing HTML / Writing JSON. Reports are written to
files (not stdout), so progress never corrupts structured output; piped
runs get clean static lines, TTY runs get in-place animation.
Run project test/verify commands can be slow with no feedback until each
finishes. Show a TTY-only animated indicator while they execute, then
clear it before printing the structured [OK]/[FAIL]/[SKIP] results, so
piped and structured output stay untouched.
Append a live ETA to the animated line once the tracker has completed
steps to extrapolate from (ProgressTracker.EstimateRemaining). Hidden
until meaningful, so the first step shows no spurious ETA.
Extract the per-session progress gate into auditProgressEnabled(format,
tty) and cover it: JSON output must stay pure on any terminal, and piped
text must not be spammed with per-session lines.
Colorize the report title (brand gold), section headers (infoSky), and
severity column (semantic colors: high/critical errorCoral, medium
warnAmber, info/low infoSky) on a TTY only. Piped output stays plain.
Severity is padded to the column width before colorizing so zero-width
ANSI escapes don't break the fixed-width alignment.
Show a TTY-only animated indicator around the slow full agent loop. It
clears before the JSON report prints, so piped and structured output stay
pure.
Wire the canonical ShouldColor()/IsQuiet() gates into CLIProgress and the
audit report so the new animated/theme output respects the same controls as
the rest of the CLI. --quiet now fully suppresses spinners, progress lines,
and decoration (the documented contract) and produces plain output; NO_COLOR
strips color while keeping the TTY animation; FORCE_COLOR colors piped
output.

Make --quiet a persistent root flag so it is usable on subcommands
(graycode audit --quiet, verify --quiet, eval loop --quiet) instead of only
the interactive root. Previously subcommands rejected it with 'unknown flag'.

Add tests for quiet suppression, NO_COLOR, and FORCE_COLOR.
Insert a 'Repairing harness' progress step around FixWorkspaceHarness (and
the post-fix re-evaluation) when --fix is used. Report-write steps reindex
dynamically so the animation stays correct in both modes.
Add an optional Progress callback to the eval Runner, invoked before each
task with its index, total, and ID. runEval wires it to a CLIProgress with
one step per benchmark task, closing the previous step and opening the next.
Quiet mode suppresses the animation. Backward-compatible: no existing
Runner construction breaks (keyed literals), and the callback is nil by
default.
Colorize the review summary to match the audit report: green check for a
clean review, coral alert with semantic severity colors for findings. Honors
ShouldColor() so --quiet/NO_COLOR/FORCE_COLOR behave consistently.
Theme the summary labels (muted) and the total-hits count (green when
clean, coral when findings exist); the empty-detectors success line is now
green. Consistent with the themed title and severity columns.
Gold completion banner; semantic status color (green EXCELLENT/GOOD, amber
NEEDS_IMPROVEMENT, coral POOR); labels in textPrimary. Honors ShouldColor().
Colorize the [OK]/[FAIL]/[SKIP] markers (green/coral/muted) and the
'verification passed' line. Markers are padded to a fixed width before
colorizing so ANSI escapes don't break column alignment. Plain when piped
via ShouldColor().
Gold title, muted header/separator, violet cost column (pad-then-colorize
to preserve alignment), textPrimary total label. Honors ShouldColor() so
piped output stays plain.
Gold title, sky section headers, muted labels/headers, violet cost figures,
teal top-tool bars. Consistent with the audit report. Honors ShouldColor().
Green check / coral close / amber alert statuses, textPrimary names, and
status-colored messages. Honors ShouldColor() so piped output stays plain.
Gold title, muted labels, textPrimary values. Honors ShouldColor() so
piped/JSON output stays plain.
Green OK marker, textPrimary count, muted path. Honors ShouldColor().
Muted label, status-colored counts (open sky, passed green, fixed teal,
failed coral), and severity-colored open-review lines. Honors ShouldColor().
Muted header, state-colored STATE column (active green, failed coral,
disabled dim, discovered/loaded sky). Honors ShouldColor().
Green running, muted not-running, amber unknown/stale; muted labels with
textPrimary values. JSON output stays pure.
models refresh (slow 60s network discover) and models list --live (live
provider fetch) now show a CLIProgress step. JSON/raw list output stays
pure. Honors --quiet/NO_COLOR.
graycode mission's per-feature output was themed but the final Mission
summary line stayed plain. Colorize it textPrimary to match the rest of
the command's visual identity.
graycode sandbox status printed a plain multi-line report while every
other CLI status report was themed. Colorize the header, per-change type
tags, and stats line using the semantic theme colors, honoring
NO_COLOR/FORCE_COLOR/TTY via theme.Tint. The Summary method is CLI-only.
The 'Installed <shell> completion to <path>' status line was the last
plain confirmation in the CLI. Colorize 'Installed' in doneGreen and the
target path in textPrimary, honoring ShouldColor() via auditTint.
The 'System prompt fragment that would be injected:' heading and its
separator were plain. Colorize the heading in textPrimary and the
separator in textMuted via auditTint; the injected fragment itself stays
plain (it is data).
The review list row printed the status text and findings bracket in
plain text while the status glyph was already colored. Colorize the
status via reviewStatusColor and the [maxSeverity] bracket via
severityStyle, keeping the row layout intact.
The trending skill list printed plain numeric prefixes. Colorize the
index in textMuted via auditTint; the shared FormatSkillEntry body stays
plain.
The findings list printed plain indices and file:line locations. Colorize
the index in textMuted and the file path in textPrimary via auditTint,
matching the themed severity bracket and message lines.
The modern help template rendered command descriptions in plain text
while headers were gold and names textPrimary. Colorize descriptions in
textMuted via a new gcDesc template func for clearer visual hierarchy.
Descriptions are the last column, so zero-width ANSI cannot break the
padded name alignment; under NO_COLOR auditTint keeps them plain, so the
golden help files stay unchanged.
After an exec run prints its response, emit a muted token/turn/duration/
model summary to stderr so stdout stays byte-clean for piping and the
model output remains the sole data. Gated by --quiet; color honors
ShouldColor() via auditTint.
The issue command ran 'gh issue create' with context.Background() and no
deadline, so a stalled GitHub call could hang the CLI indefinitely. Wrap
it in a 60s context timeout and report a clear deadline-exceeded error.
review fix iterates open reviews and runs a multi-turn graycode exec for
each. It printed only the completion status after each exec, so with
--all the user could not tell which review was being worked on. Print a
themed 'Fixing review #N (sha)...' line (gold bolt + textPrimary) before
each exec run.
review analyze ran a single kestrel model call (up to the 3-minute
analyze timeout) behind a static 'Analyzing...' line. Replace it with a
CLIProgress animation (rainbow spinner + themed bar + ETA) so the wait
has live feedback, matching review run. Gated by --quiet; findings
output stays clean after the step completes.
The mission command ran up to 30 minutes of parallel LLM workers behind a
static 'Executing with N parallel workers...' line with no live feedback.
Wrap the run in a single-step CLIProgress animation (rainbow spinner +
themed bar) showing the feature/worker count. Gated by --quiet; the
per-feature results still print cleanly after the step completes.
The best-of-N fanout loop printed each attempt header to stderr in plain
text. Theme them with the info-sky accent so each attempt reads as a
distinct phase, matching the themed exec usage summary. Stderr-only, so
the model output on stdout stays byte-clean.
The best-of-N comparison report printed each attempt's ok/failed status in
plain text. Colorize the status (green ok / coral failed, with the error
appended in coral) and the report header in the info-sky accent, matching
the themed attempt headers. Stderr-only; stdout stays byte-clean.
The exec command printed error/hint/warning diagnostics to stderr in plain
text. Colorize them with semantic accents — errors in coral, hints in
muted, and warnings (untrusted GitHub autonomy cap, session-persist
failure) in amber — matching the themed usage summary and fanout headers.
Stderr-only; the model output on stdout stays byte-clean.
Theme the one-off stderr diagnostics in ai-comments (directive dispatch and
token-strip failures in coral) and chat (ignored --session-id notice in
muted, plugin load failure warning in amber). Consistent with the themed
exec diagnostics; stderr-only.
The interactive chat REPL printed errors to stderr in plain text. Colorize
them in coral. The REPL's streamed tool output stays plain (data).
Theme the daemon telemetry/file-logging fallback warnings and the eval
results-save warning in amber. Consistent with the themed exec and chat
diagnostics; stderr-only.
config set now reads the current value before writing and, when it changes,
prints a modern old → new transition (key: old → new (updated)) instead of
the bare 'updated key'. Falls back to the plain confirmation when there is
no prior value or the value is unchanged. Settable keys are non-secret
(API keys error out before reaching here), so no secret is exposed.
Honors NO_COLOR via auditTint.
Extract the old → new transition rendering into printConfigSetResult and
use it for the config set, config provider, and config model paths so all
three show the same modern transition (key: old → new (updated)) with the
plain fallback when there is no prior value.
config get printed a blank line when a valid key had no value. Print
'(unset)' in muted instead, so an empty result is distinguishable from a
missing key (which still errors).
verify now reports how long the check run took (verification passed in
Xs), which is genuinely useful in non-TTY mode where no animation shows
the elapsed time. The duration is muted so the done-green confirmation
stays the visual anchor.
- Apply gofumpt to cmd/exec.go and two internal/intelligence/memory files
  (formatting-only) to satisfy the CI format check.
- Remove docs/plans/2026-09-05-graycode-eco-integrity.md from the branch:
  it is a working planning note (not a CLI deliverable) whose malformed
  code fences and hard tabs fail the repo's markdownlint gate. Kept
  locally as untracked.
- progress_cli.go: explicitly discard fmt.Fprintf/Fprintln return values
  (errcheck) in the spinner frame callback and writeLine.
- developer_path.go: omit redundant color.Color type annotation (ST1023);
  theme.ReportWarn is already color.Color and all switch assignments share
  that type.
Use := instead of var for the first declaration of statusColor so the file
passes the CI gofumpt gate.
@Patel230
Patel230 merged commit f7d9641 into main Sep 7, 2026
25 of 26 checks passed
@Patel230
Patel230 deleted the fix/eco-integrity branch September 7, 2026 04:30
Patel230 added a commit that referenced this pull request Oct 2, 2026
* fix: point the skill index at the published registry release

The index URL referenced GrayCodeAI/starling, a repo renamed to
graycode-skills whose registry.json is generated and never committed,
so the URL 404d under either name. It now reads the rolling release
asset published by graycode-skills' publish-registry.yml.

Claude-Session: https://claude.ai/code/session_01MTUKadN91fcmuhxGWYVe2k

* fix: drop the phantom marketplace source

plugins-registry.json is generated by nothing in any of the four
GrayCode repos; the only reference anywhere was this default source.
FetchAll with no sources returns an empty list rather than erroring.

Claude-Session: https://claude.ai/code/session_01MTUKadN91fcmuhxGWYVe2k

* docs: state that graycode cloud requires an explicit endpoint

The wire contract's servers.url is the browser BFF, which rejects a
device token; the worker itself has no route or custom domain.

Claude-Session: https://claude.ai/code/session_01MTUKadN91fcmuhxGWYVe2k

* docs: correct the router boundary guard comment

Claude-Session: https://claude.ai/code/session_01MTUKadN91fcmuhxGWYVe2k

* fix: repair two boundary guards that could not fail

check-support-repo-coupling.sh built its regex from an empty peer
list, degenerating to a pattern matching nothing. The engine-boundary
script ran in CI but not on pre-push. Both AST tests carried a
gateway->credentials exception that no production file uses.

Claude-Session: https://claude.ai/code/session_01MTUKadN91fcmuhxGWYVe2k

* docs: align the ecosystem section with ecosystem.yaml

Also replaces GrayCodeAI/starling test fixtures with the repo's
current name, and fixes an 'execution swift' typo left by an earlier
substring rename in the generated GitNexus tables.

Claude-Session: https://claude.ai/code/session_01MTUKadN91fcmuhxGWYVe2k

* fix: resolve code-review findings across engine, memory, tool, daemon

- eval list --json: project BenchmarkTask (func fields) to a JSON-safe struct
- stream: use a single RawMessages() snapshot (fixes len()+copy reallocation race)
- crash_unix: drop unreachable nil-return branch from raiseSignal
- tool: replace deprecated strings.Title with x/text cases.Title
- daemon: replace no-arg fmt.Sprintf with string literals
- fuzzyfind: replace deprecated filepath.HasPrefix with strings.HasPrefix
- memory: thread context.Context through MemoryRecaller.Remember so background
  remember goroutines honor their timeout (fixes goroutine leak from discarded rCtx)
- contracts/types: remove deprecated fail-open ParseSeverity (zero callers)

* feat: animate review run and audit with TTY-aware progress

Wire the previously-unused ProgressTracker into real command flows via a
new CLIProgress helper:

- cmd/progress_cli.go: TTY-aware progress renderer. On a terminal it
  repaints the active step in place with a braille spinner, theme-colored
  progress bar, and live N/M counter; piped/CI output is one clean static
  line per step with no ANSI. Completion prints a themed summary with the
  final bar (errorCoral when any step failed). Glyphs come from
  internal/ui/icons; block glyphs stay in the audit-permitted U+2500-U+25FF
  range.
- cmd/review_run.go: progress over Building model / Reviewing code /
  Saving results, silent in background/hook mode.
- cmd/audit.go: per-session progress, gated to TTY + text output so --json
  stays pure and piped output isn't spammed.
- cmd/progress_cli_test.go: non-TTY, TTY, fail-step, and multi-step
  regression tests (the multi-step test covers a fresh-spinner-per-step fix
  for BrailleSpinner's one-shot Start/Stop panic).

* feat: animate harness evaluation and report-writing stages

Wire CLIProgress into the harness command over Evaluating workspace /
Writing markdown / Writing HTML / Writing JSON. Reports are written to
files (not stdout), so progress never corrupts structured output; piped
runs get clean static lines, TTY runs get in-place animation.

* feat: animate slow project-check phase of verify

Run project test/verify commands can be slow with no feedback until each
finishes. Show a TTY-only animated indicator while they execute, then
clear it before printing the structured [OK]/[FAIL]/[SKIP] results, so
piped and structured output stay untouched.

* feat: show ETA estimate in progress animation

Append a live ETA to the animated line once the tracker has completed
steps to extrapolate from (ProgressTracker.EstimateRemaining). Hidden
until meaningful, so the first step shows no spurious ETA.

* test: guard audit JSON purity with auditProgressEnabled

Extract the per-session progress gate into auditProgressEnabled(format,
tty) and cover it: JSON output must stay pure on any terminal, and piped
text must not be spammed with per-session lines.

* feat: theme the audit text report

Colorize the report title (brand gold), section headers (infoSky), and
severity column (semantic colors: high/critical errorCoral, medium
warnAmber, info/low infoSky) on a TTY only. Piped output stays plain.
Severity is padded to the column width before colorizing so zero-width
ANSI escapes don't break the fixed-width alignment.

* feat: animate the eval loop agent run

Show a TTY-only animated indicator around the slow full agent loop. It
clears before the JSON report prints, so piped and structured output stay
pure.

* feat: honor --quiet/NO_COLOR/FORCE_COLOR in progress and theme

Wire the canonical ShouldColor()/IsQuiet() gates into CLIProgress and the
audit report so the new animated/theme output respects the same controls as
the rest of the CLI. --quiet now fully suppresses spinners, progress lines,
and decoration (the documented contract) and produces plain output; NO_COLOR
strips color while keeping the TTY animation; FORCE_COLOR colors piped
output.

Make --quiet a persistent root flag so it is usable on subcommands
(graycode audit --quiet, verify --quiet, eval loop --quiet) instead of only
the interactive root. Previously subcommands rejected it with 'unknown flag'.

Add tests for quiet suppression, NO_COLOR, and FORCE_COLOR.

* feat: animate the harness --fix repair step

Insert a 'Repairing harness' progress step around FixWorkspaceHarness (and
the post-fix re-evaluation) when --fix is used. Report-write steps reindex
dynamically so the animation stays correct in both modes.

* feat: per-task progress for eval benchmark suites

Add an optional Progress callback to the eval Runner, invoked before each
task with its index, total, and ID. runEval wires it to a CLIProgress with
one step per benchmark task, closing the previous step and opening the next.
Quiet mode suppresses the animation. Backward-compatible: no existing
Runner construction breaks (keyed literals), and the callback is nil by
default.

* feat: theme the review run summary

Colorize the review summary to match the audit report: green check for a
clean review, coral alert with semantic severity colors for findings. Honors
ShouldColor() so --quiet/NO_COLOR/FORCE_COLOR behave consistently.

* feat: colorize audit summary block

Theme the summary labels (muted) and the total-hits count (green when
clean, coral when findings exist); the empty-detectors success line is now
green. Consistent with the themed title and severity columns.

* feat: theme the harness final summary

Gold completion banner; semantic status color (green EXCELLENT/GOOD, amber
NEEDS_IMPROVEMENT, coral POOR); labels in textPrimary. Honors ShouldColor().

* feat: theme verify check markers

Colorize the [OK]/[FAIL]/[SKIP] markers (green/coral/muted) and the
'verification passed' line. Markers are padded to a fixed width before
colorizing so ANSI escapes don't break column alignment. Plain when piped
via ShouldColor().

* feat: theme the usage report

Gold title, muted header/separator, violet cost column (pad-then-colorize
to preserve alignment), textPrimary total label. Honors ShouldColor() so
piped output stays plain.

* feat: theme the usage statistics report

Gold title, sky section headers, muted labels/headers, violet cost figures,
teal top-tool bars. Consistent with the audit report. Honors ShouldColor().

* feat: theme the doctor health check report

Green check / coral close / amber alert statuses, textPrimary names, and
status-colored messages. Honors ShouldColor() so piped output stays plain.

* feat: theme the status snapshot report

Gold title, muted labels, textPrimary values. Honors ShouldColor() so
piped/JSON output stays plain.

* feat: theme the security log verify result

Green OK marker, textPrimary count, muted path. Honors ShouldColor().

* feat: theme the review status report

Muted label, status-colored counts (open sky, passed green, fixed teal,
failed coral), and severity-colored open-review lines. Honors ShouldColor().

* feat: theme the plugin status table

Muted header, state-colored STATE column (active green, failed coral,
disabled dim, discovered/loaded sky). Honors ShouldColor().

* feat: theme the daemon status output

Green running, muted not-running, amber unknown/stale; muted labels with
textPrimary values. JSON output stays pure.

* feat: animate the models catalog flows

models refresh (slow 60s network discover) and models list --live (live
provider fetch) now show a CLIProgress step. JSON/raw list output stays
pure. Honors --quiet/NO_COLOR.

* feat: animate doctor and preflight --live

doctor (network health checks) and preflight --live (provider verification)
now show a CLIProgress step. JSON output stays pure. Honors --quiet.

* feat: theme the version line

textPrimary name, gold version, muted build date. Honors ShouldColor().

* feat: theme the governance explain decision

Muted labels, textPrimary values, ALLOW green / DENY coral verdict.
Honors ShouldColor().

* feat: theme context export and review hook install confirmations

Green check + textPrimary message, muted hints. Honors ShouldColor().

* feat: theme the learn command output

Green check on lesson add, textPrimary store summary, gold category tags,
muted labels. Honors ShouldColor().

* feat: theme the governance show/validate reports

Muted labels, textPrimary values, infoSky Capabilities header, allow green
/ deny coral action column, green valid marker. Honors ShouldColor().

* feat: theme feedback, sandbox, cloud, and cost output

Green confirmations, muted empty-states and hints, amber experimental
banner. Honors ShouldColor().

* feat: animate cloud login browser approval

The device-login poll (up to 10 min waiting for browser approval) now shows
a CLIProgress step with ETA. Approved/expired/error all resolve the step
cleanly. Honors --quiet.

* feat: theme the update command output

Green up-to-date, amber update-available with textPrimary version pair,
muted URL, coral failure. Honors ShouldColor().

* feat: theme the recover command output

textPrimary resume line with gold session id and muted message count,
muted next-step hints. Honors ShouldColor().

* feat: theme the tape status/commit reports

Muted labels with textPrimary values, green commit confirmation.
JSON status stays pure. Honors ShouldColor().

* feat: theme the config update confirmations

Green updated markers with textPrimary key names. Honors ShouldColor().

* feat: theme the plugin command confirmations

Green activate/install/scaffold, textPrimary deactivate/reload/uninstall,
muted scaffold file listing. Honors ShouldColor().

* feat: theme session export and migrate confirmations

Green export/migrate markers with textPrimary ids, muted already-current
message. Honors ShouldColor().

* feat: theme skills and curator output

Muted empty-states and hints, textPrimary skill names, green pinned status
and archive count. Honors ShouldColor().

* feat: theme the features report

Gold header, green ENABLED / muted DISABLED status, textPrimary flag names,
muted metadata. Honors ShouldColor().

* feat: theme review analyze/fix/refine output

Green success and red failure markers, gold iteration headers, muted
empty-states and hints, textPrimary status lines. Honors ShouldColor().

* feat: theme the daemon stop confirmation

Green stopped-daemon confirmation. Honors ShouldColor().

* feat: theme the credentials remove/migrate confirmations

Green removed/migrated confirmations, muted already-secure message.
Honors ShouldColor().

* feat: theme marketplace and agent command output

Green marketplace/agent create/install confirmations, muted empty-states
and hints, muted agent show labels with textPrimary values and gold prompt
header. Honors ShouldColor().

* feat: theme the plan command output

Muted empty-states and hints, textPrimary plan titles, green done progress
and task-done confirmation, gold section headers. Honors ShouldColor().

* feat: theme the trust command output

Green trusted confirmation, textPrimary removed-trust, muted empty-state
and enforcement, green/red trusted check value. Honors ShouldColor().

* feat: theme the securitylog show and toolset output

Severity-colored security events, muted timestamps/details, textPrimary
summary. Honors ShouldColor().

* feat: theme the harness auto-repair results

Amber repair header, green repair items. Honors ShouldColor().

* feat: theme the checkpoint save/list/restore/delete output

Green save/restore confirmations, muted resume hints and metadata,
textPrimary checkpoint names. Honors ShouldColor().

* feat: theme the background session start/attach output

Green session-started confirmation, muted hints, textPrimary attach lines
with amber non-running status. Honors ShouldColor().

* feat: theme the rules detect/import/export output

Green import/export confirmations, muted empty-states and format labels,
textPrimary paths and rule names. Honors ShouldColor().

* feat: theme the snapshot list/restore/diff output

Green restore confirmation, muted empty-states, status-colored diff rows,
textPrimary hashes/files. Honors ShouldColor().

* feat: theme the eval command output

Green cache-cleared and results-saved, textPrimary run/summary headers,
green pass rates. Honors ShouldColor().

* feat: theme the cloud login device instructions

URL in infoSky, one-time code in gold, muted browser-open fallback.
Honors ShouldColor().

* feat: theme the feedback prompt and browser fallback

textPrimary prompt, muted fallback label with infoSky URL.
Honors ShouldColor().

* feat: theme the daemon stale-pid status line

Amber stale-PID status, matching the other status branches.
Honors ShouldColor().

* feat: theme the interrupted-session recovery notice

Amber notice with textPrimary session ID and muted metadata.
Honors ShouldColor().

* feat: theme agent, cmdhistory, permissions, pr, issue, mission, plugin, governance, models output

Green confirmations for saved/reset/created/posted actions, amber dry-run
and not-installed notices, muted labels/empty-states, textPrimary values.
Honors ShouldColor().

* feat: theme audit empty-state, cmdhistory entries, cloud graph sync

Muted empty-states, exit-code colored history rows, green graph sync
confirmation. Honors ShouldColor().

* feat: theme the review close confirmation

Green check icon with textPrimary closed-review line.
Honors ShouldColor().

* feat: theme cost summary, review run/refine/list, search output

Amber experimental/alert notices, green all-clean confirmations, status-
colored review rows via new reviewStatusColor helper, muted empty-states.
Honors ShouldColor().

* feat: animate context export to file

Spinner during project-context build when writing to --output; stdout stays
free so the file gets clean data. Honors IsQuiet().

* feat: honor ShouldColor in review show and severity labels

Replace raw lipgloss Bold/Faint severity styles with auditTint-based theming
via reviewSeverityColor, so review show and severity badges respect
NO_COLOR/--quiet in non-TTY/scripted mode.

* feat: modern colorized help output

Theme-aware help via a custom usage template: section headers in brand gold,
command names in textPrimary, descriptions/flags plain. Pad-then-colorize
keeps column alignment; honors ShouldColor() (NO_COLOR/--quiet/non-TTY).
Subcommands inherit via rootCmd usage template.

* feat: theme review show empty-state and daemon WARNING

Muted no-open-reviews message; amber non-localhost security warning in the
daemon start banner. Honors ShouldColor().

* feat: theme REPL startup banner

textPrimary title with muted usage hint on the interactive REPL banner.
Honors ShouldColor().

* feat: theme taste and vibe command output

Green taste export/import confirmations, textPrimary reset; colorized vibe
iteration status (complete/green, failed/amber). Honors ShouldColor().

* feat: colorize top-level CLI errors

Top-level failures print in brand error coral on color-capable stderr
(NO_COLOR/FORCE_COLOR/TTY detection mirroring cmd.ShouldColor); scripts
piping diagnostics still see plain text.

* feat: theme swift-report confirmations

Green save/copy confirmations with textPrimary path and muted redaction
hint. Honors ShouldColor().

* feat: theme review finding rows and skills info

Muted no-reviews empty state and finding message bodies; labeled skills info
(Skill/Description/Repo/Installs). Honors ShouldColor().

* feat: theme print-mode tool and countdown indicators

stderr tool-use/tool-result names in infoSky and the time-remaining countdown
in warnAmber; stdout model output stays byte-clean. Honors ShouldColor().

* feat: theme watch-mode status indicators

textPrimary watching banner and directive-processing lines, warnAmber
fsnotify fallback, errorCoral initial-run failure. Honors ShouldColor().

* feat: theme background-session list

Muted empty state, textPrimary header/IDs, status-colored status
(running/completed/failed/killed), muted labels. Honors ShouldColor().

* feat: theme stats empty-state

Muted 'No session data found' hint. Honors ShouldColor().

* feat: theme internal ecosystem panel and credentials status

Add a self-contained theme.Tint helper (honors NO_COLOR/FORCE_COLOR/TTY,
no cmd dependency) and apply it to the two most user-facing internal
status reports: the ecosystem panel (doctor/status) and credentials
status. Statuses colorize (green ready, amber not-ready, sky info,
muted labels) while staying plain under NO_COLOR so scripted output and
existing substring assertions are unaffected.

* feat: theme catalog health and config summary reports

Theme the model catalog health report (doctor) and the config summary
family (mcp/sessions/tools summaries, api key config). Labels muted,
statuses colorized (green set/ready, amber stale/not-ready, muted empty)
while staying plain under NO_COLOR for scripted output.

* feat: theme config summary report

Theme the config command's primary output: textPrimary headers
(Setup/Current), muted labels, sky provider/model values, and muted
(none) keys. Stays plain under NO_COLOR for scripted output.

* fix: plan list shows plan name instead of duplicate title

The plan list printed the plan title twice (a pre-existing bug carried
through theming). Capture each plan's file name and show it muted in
place of the duplicate title, giving users the identifier used by
'graycode plan show <name>'.

* fix: cap verify workspace checks at 10m

graycode verify ran each discovered project test/verify command with no
timeout, so a hanging test suite would block verify forever. Wrap each
check in a 10-minute context deadline and report a timed-out check as a
clear failure instead.

* fix: doctor --json now emits real JSON

graycode doctor --json claimed to 'output diagnostics as JSON' but
printed the plain-text doctorOutput report instead. Add a structured
doctorJSON that mirrors the report fields as machine-parseable JSON and
wire the flag to it. Add a regression test asserting valid JSON with the
expected fields.

* feat: show active step name in CLIProgress animation frame

The in-place TTY animation previously showed only the spinner, progress
bar, step counter, and ETA — the user could not tell which step of a
multi-step flow was currently running. Render the active step name
(tinted textPrimary) in the frame so long-running steps are identifiable
at a glance.

* feat: theme the developer path readiness report

graycode path printed a plain-text readiness report while every other
internal status report (ecosystem panel, credentials, catalog health) was
themed. Colorize the title, status, section headers, per-check glyphs,
and fix hints using the semantic theme colors, matching the rest of the
CLI's visual identity. Honors NO_COLOR/FORCE_COLOR/TTY via theme.Tint.

* feat: honor NO_COLOR in the onboarding wizard

The first-run setup wizard and welcome banner emitted hardcoded ANSI
escapes unconditionally, breaking the CLI's non-TTY purity (colored
output even under NO_COLOR). Gate the color codes on theme.ColorEnabled()
and use the theme's brand ANSI for the banner, so scripted or NO_COLOR
environments get plain text. Update TestColorConstants to assert the
gating behavior.

* feat: theme the mission final summary line

graycode mission's per-feature output was themed but the final Mission
summary line stayed plain. Colorize it textPrimary to match the rest of
the command's visual identity.

* feat: theme the sandbox status report

graycode sandbox status printed a plain multi-line report while every
other CLI status report was themed. Colorize the header, per-change type
tags, and stats line using the semantic theme colors, honoring
NO_COLOR/FORCE_COLOR/TTY via theme.Tint. The Summary method is CLI-only.

* feat: theme the shell completion install confirmation

The 'Installed <shell> completion to <path>' status line was the last
plain confirmation in the CLI. Colorize 'Installed' in doneGreen and the
target path in textPrimary, honoring ShouldColor() via auditTint.

* feat: theme the taste prompt-fragment header

The 'System prompt fragment that would be injected:' heading and its
separator were plain. Colorize the heading in textPrimary and the
separator in textMuted via auditTint; the injected fragment itself stays
plain (it is data).

* feat: theme the review list view status and findings

The review list row printed the status text and findings bracket in
plain text while the status glyph was already colored. Colorize the
status via reviewStatusColor and the [maxSeverity] bracket via
severityStyle, keeping the row layout intact.

* feat: theme the skills trending list number prefix

The trending skill list printed plain numeric prefixes. Colorize the
index in textMuted via auditTint; the shared FormatSkillEntry body stays
plain.

* feat: theme the review findings detail index and file:line

The findings list printed plain indices and file:line locations. Colorize
the index in textMuted and the file path in textPrimary via auditTint,
matching the themed severity bracket and message lines.

* feat: mute command descriptions in help output

The modern help template rendered command descriptions in plain text
while headers were gold and names textPrimary. Colorize descriptions in
textMuted via a new gcDesc template func for clearer visual hierarchy.
Descriptions are the last column, so zero-width ANSI cannot break the
padded name alignment; under NO_COLOR auditTint keeps them plain, so the
golden help files stay unchanged.

* feat: show a muted usage summary after exec completes

After an exec run prints its response, emit a muted token/turn/duration/
model summary to stderr so stdout stays byte-clean for piping and the
model output remains the sole data. Gated by --quiet; color honors
ShouldColor() via auditTint.

* fix: bound the gh issue create call with a 60s timeout

The issue command ran 'gh issue create' with context.Background() and no
deadline, so a stalled GitHub call could hang the CLI indefinitely. Wrap
it in a 60s context timeout and report a clear deadline-exceeded error.

* feat: announce which review is being fixed before running exec

review fix iterates open reviews and runs a multi-turn graycode exec for
each. It printed only the completion status after each exec, so with
--all the user could not tell which review was being worked on. Print a
themed 'Fixing review #N (sha)...' line (gold bolt + textPrimary) before
each exec run.

* feat: animate review analyze model call

review analyze ran a single kestrel model call (up to the 3-minute
analyze timeout) behind a static 'Analyzing...' line. Replace it with a
CLIProgress animation (rainbow spinner + themed bar + ETA) so the wait
has live feedback, matching review run. Gated by --quiet; findings
output stays clean after the step completes.

* feat: animate mission execution

The mission command ran up to 30 minutes of parallel LLM workers behind a
static 'Executing with N parallel workers...' line with no live feedback.
Wrap the run in a single-step CLIProgress animation (rainbow spinner +
themed bar) showing the feature/worker count. Gated by --quiet; the
per-feature results still print cleanly after the step completes.

* feat: theme exec fanout attempt headers

The best-of-N fanout loop printed each attempt header to stderr in plain
text. Theme them with the info-sky accent so each attempt reads as a
distinct phase, matching the themed exec usage summary. Stderr-only, so
the model output on stdout stays byte-clean.

* feat: theme exec fanout comparison report status

The best-of-N comparison report printed each attempt's ok/failed status in
plain text. Colorize the status (green ok / coral failed, with the error
appended in coral) and the report header in the info-sky accent, matching
the themed attempt headers. Stderr-only; stdout stays byte-clean.

* feat: theme exec stderr diagnostics

The exec command printed error/hint/warning diagnostics to stderr in plain
text. Colorize them with semantic accents — errors in coral, hints in
muted, and warnings (untrusted GitHub autonomy cap, session-persist
failure) in amber — matching the themed usage summary and fanout headers.
Stderr-only; the model output on stdout stays byte-clean.

* feat: theme ai-comments and chat diagnostics

Theme the one-off stderr diagnostics in ai-comments (directive dispatch and
token-strip failures in coral) and chat (ignored --session-id notice in
muted, plugin load failure warning in amber). Consistent with the themed
exec diagnostics; stderr-only.

* feat: theme chat REPL error lines

The interactive chat REPL printed errors to stderr in plain text. Colorize
them in coral. The REPL's streamed tool output stays plain (data).

* feat: theme daemon and eval stderr warnings

Theme the daemon telemetry/file-logging fallback warnings and the eval
results-save warning in amber. Consistent with the themed exec and chat
diagnostics; stderr-only.

* feat: show old-to-new transition in config set

config set now reads the current value before writing and, when it changes,
prints a modern old → new transition (key: old → new (updated)) instead of
the bare 'updated key'. Falls back to the plain confirmation when there is
no prior value or the value is unchanged. Settable keys are non-secret
(API keys error out before reaching here), so no secret is exposed.
Honors NO_COLOR via auditTint.

* refactor: unify config set/provider/model transition display

Extract the old → new transition rendering into printConfigSetResult and
use it for the config set, config provider, and config model paths so all
three show the same modern transition (key: old → new (updated)) with the
plain fallback when there is no prior value.

* feat: show (unset) for unset config values

config get printed a blank line when a valid key had no value. Print
'(unset)' in muted instead, so an empty result is distinguishable from a
missing key (which still errors).

* feat: show elapsed time on verify completion

verify now reports how long the check run took (verification passed in
Xs), which is genuinely useful in non-TTY mode where no animation shows
the elapsed time. The duration is muted so the done-green confirmation
stays the visual anchor.

* docs: record graycode-eco integrity plan

* fix: gofumpt formatting; drop non-deliverable plan doc from merge

- Apply gofumpt to cmd/exec.go and two internal/intelligence/memory files
  (formatting-only) to satisfy the CI format check.
- Remove docs/plans/2026-09-05-graycode-eco-integrity.md from the branch:
  it is a working planning note (not a CLI deliverable) whose malformed
  code fences and hard tabs fail the repo's markdownlint gate. Kept
  locally as untracked.

* fix: resolve golangci-lint errcheck + staticcheck findings

- progress_cli.go: explicitly discard fmt.Fprintf/Fprintln return values
  (errcheck) in the spinner frame callback and writeLine.
- developer_path.go: omit redundant color.Color type annotation (ST1023);
  theme.ReportWarn is already color.Color and all switch assignments share
  that type.

* fix: gofumpt short declaration for statusColor

Use := instead of var for the first declaration of statusColor so the file
passes the CI gofumpt gate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant