Commit 78b23f7
Add global --ai and --skill flags for AI-powered command analysis (#2171)
* Add global --ai flag for AI-powered command output analysis
Implement the global `--ai` persistent flag that enables AI-powered analysis
of any Atmos CLI command output. When enabled, stdout/stderr are captured via
os.Pipe tee pattern and sent to the configured AI provider for analysis after
command execution. Errors get explanations with fix instructions; successful
output gets concise summaries.
- Register --ai flag in pkg/flags with ATMOS_AI env var support
- Add pkg/ai/analyze package (capture, validate, analyze, prompt building)
- Wrap Execute() in cmd/root.go for pre/post command AI processing
- Skip AI analysis for `atmos ai` commands to avoid double processing
- Add comprehensive tests (flag, capture, validation, prompt, truncation)
- Update global-flags.mdx, environment-variables.mdx, env.mdx docs
- Update AI example (README.md, ATMOS.md) with --ai flag documentation
- Add PRD for the global --ai flag feature
- Regenerate CLI snapshots reflecting new --ai flag in help output
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Exclude 32-bit FreeBSD from release builds
modernc.org/libc (transitive dependency via modernc.org/sqlite used by
pkg/ai/session) has unresolved type mismatch bugs on 32-bit FreeBSD
platforms where size_t is 32-bit but the code mixes it with uint64.
This affects both freebsd/386 and freebsd/arm. The 64-bit targets
(freebsd/amd64, freebsd/arm64) build fine.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Improve AI analyze package: use pkg/ui, increase test coverage to 95%
- Replace utils.PrintfMessageToTUI/PrintfMarkdown with ui.Info/Warningf/Markdown
- Extract messageSender interface for testable AI client injection
- Add 10 new tests for AnalyzeOutput (mock client, error paths, edge cases)
- Add --ai plan analysis example to AI example README
- Coverage: 73.7% → 94.8%
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix --ai flag error path: propagate errors instead of calling os.Exit()
Replace errUtils.CheckErrorPrintAndExit() calls in terraform command path
with proper error returns so errors flow back through Cobra's RunE to
Execute() where AI analysis can process them. Changes:
- executeSingleComponent: return error instead of CheckErrorPrintAndExit
- terraformRunWithOptions: return errors from checkTerraformFlags,
ExecuteTerraformQuery, NeedHelp, and hook execution
- handleInteractiveIdentitySelection: return error instead of void+exit
- executeAffectedCommand: return error directly
- Remove debug prints from cmd/root.go
- Update PRD to document error propagation approach
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Restore alien emoji and colored markdown for --ai output
- Use 👽 emoji (consistent with atmos ai ask/chat) instead of ℹ
- Use utils.PrintfMarkdownToTUI for colored markdown rendering to stderr
- Use utils.PrintfMessageToTUI for status messages to stderr
- Add AI error analysis example to README
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add blog post, update PRD and examples for --ai flag, fix output ordering
- Add blog post for AI-powered analysis with global --ai flag
- Update PRD with error handling details and ~95% coverage
- Update examples/ai/README.md with error analysis and not-configured examples
- Fix error ordering in root.go: print error before AI analysis
- Add trailing newline after AI response in analyze.go
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix roadmap progress percentages and add --ai flag milestone
- auth: 88% → 80% (20/25 shipped)
- workflows: 100% shipped → 86% in-progress (6/7, one milestone still in-progress)
- extensibility: 89% → 86% (19/22)
- vendoring: 95% → 91% (10/11)
- migration: 85% → 83% (10/12)
- quality: 88% → 80% (8/10)
- ai-assistant: 90% → 94% (17/18, was understated)
- Add global --ai flag as shipped milestone in ai-assistant initiative
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add global --skill flag for domain-specific AI analysis context
The --skill <name> flag works with --ai to provide domain-specific
expertise when analyzing command output. The skill's system prompt
is prepended to the analysis prompt, giving the AI deep knowledge
of the relevant Atmos subsystem (e.g., Terraform, stacks, validation).
Changes:
- Add ErrAISkillRequiresAIFlag sentinel error
- Add Skill string field to global.Flags
- Register --skill flag with ATMOS_SKILL env var in pkg/flags/
- Add parseSkillFlagInternal() for early flag parsing in cmd/root.go
- Add loadAndValidateSkill() to load skill registry and validate name
- Introduce AnalysisInput struct to fix argument-limit lint rule
- Extract writeStream() helper to reduce cyclomatic complexity
- Extract setupAIAnalysis() to reduce nestif complexity
- Add tests for flag parsing, skill prompt injection, flag registration
- Update PRD with --skill requirements and 10-step implementation plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update docs for --skill flag: global flags, env vars, PRD, blog, example
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add tests for --skill flag and fix PRD pseudocode consistency
- Add 6 new analyze tests: skill+error, skill+send error, separator,
both streams, multiple providers, truncate edge case
- Add 4 new parseSkillFlagInternal tests: similar flags, between flags,
hyphenated names, multiple flags
- Update PRD execution flow to match actual setupAIAnalysis() pattern
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Replace static AI analysis message with animated spinner
Use pkg/ui/spinner for the AI analysis indicator. Shows animated
spinner during the AI provider call, then displays success/error
status when complete. Gracefully degrades in non-TTY environments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add empty line before AI spinner for visibility
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Show skill name in AI spinner and success messages for user visibility
Display the active skill name in both the spinner ("Analyzing with AI using
skill 'atmos-terraform'...") and success message ("AI analysis complete
(skill: atmos-terraform)") so users can confirm which skill was sent to the
AI provider. Update PRD with skill prompt injection architecture, add tests,
and update blog post and example docs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Document --ai and --skill global flags in AI command docs
Add references to the global --ai and --skill flags in the AI usage page,
skill management page, and main AI overview page with usage examples.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* updates
* Migrate AI analysis output from utils to ui package with ReinitFormatter
Add ui.ReinitFormatter() to re-detect terminal capabilities after output
capture pipes are restored. This fixes the capture timing issue where
InitFormatter() cached ColorNone during PersistentPreRun while pipes were
active. AI analysis now uses ui.MarkdownMessage() and ui.Writeln() instead
of the legacy utils.PrintfMarkdownToTUI/PrintfMessageToTUI. Update PRD to
document the resolved issue, add tests, and regenerate snapshots.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix blog and example: show success message instead of spinner
Replace static spinner message with final success message in terminal
examples for consistency with actual CLI output after spinner completes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address PR review: idempotent Stop(), t.Cleanup, tee test, debug log
- Add idempotency guard to CaptureSession.Stop() to prevent panic on double call
- Register t.Cleanup(cs.Stop) in all capture tests for safe stream restoration
- Add TestStartCapture_TeesToOriginalStreams to verify tee contract
- Add debug log when marketplace skill loader creation fails
- Fix --skill example in ai.mdx to include component and stack arguments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Remove environment-specific gh auth debug line from golden snapshots
The gh auth token debug log only appears when gh CLI is installed but not
authenticated (local dev). CI has no gh CLI, so the line is absent. Remove
it from snapshots to match CI behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add tests for AI analysis functions to increase patch coverage
Tests cover buildCommandName, runAIAnalysis, setupAIAnalysis, and
loadAndValidateSkill — the main uncovered functions from the --ai flag PR.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Refactor AI tests: table-driven format, behavioral assertions, fix comments
Address CodeRabbit review feedback:
- Fix saveAndRestoreArgs comment to match t.Cleanup behavior
- Collapse individual tests into table-driven format with validAIConfig helper
- Replace tautological "no panic" assertions with behavioral tests that verify
stream restoration, capture buffer contents, and formatted error output
- Add double-stop idempotency test verifying buffered data preservation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Windows CI: close temp file before TempDir cleanup
On Windows, open file handles prevent deletion. Close the temp stderr
file in the cleanup function before t.TempDir() tries to remove it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Convert --skill flag to StringSlice for multi-skill support
Support multiple skills via comma-separated values (--skill a,b) and
repeated flags (--skill a --skill b). Updates all pipeline functions,
tests, golden snapshots, and documentation to reflect the new behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Remove gh auth token debug line from golden snapshots
The "gh auth token failed" debug message is environment-dependent and
should not be captured in golden snapshots.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* update docs
* Address PR review: simplify isAICommand, add panic safety, fix truncation budget
- Simplify isAICommandInternal to skip index 0 explicitly instead of value comparison
- Add defer captureSession.Stop() for panic safety during command execution
- Surface capture errors to user via ui.Warning instead of silent log.Warn
- Split output truncation budget evenly when both stdout and stderr are present
- Remove perf.Track from trivial ValidateAIConfig, pass atmosConfig to AnalyzeOutput
- Update PRD code snippets to reflect multi-skill slice types
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address PR review: env var fallback, perf tracking, truncation fix
- Add ATMOS_AI env var fallback in hasAIFlagInternal for CI/CD env-only usage
- Add ATMOS_SKILL env var fallback in parseSkillFlagInternal with comma splitting
- Extract splitCSV helper to reduce cognitive complexity
- Restore perf.Track on ValidateAIConfig with proper atmosConfig parameter
- Fix truncateOutput to include suffix within the limit (no overshoot)
- Add SkillNames to AnalysisInput in PRD code snippet
- Fix PRD doc to show proper error handling for StartCapture
- Trim blog post, add ActionCard for AI example
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address PR review: CLI precedence, nil guard, sentinel tests
- Respect CLI precedence for --ai flag: --ai=false no longer falls through
to ATMOS_AI env var, uses strconv.ParseBool for all boolean forms
- Track flagSeen for --skill to prevent env var override of explicit empty
- Add nil guard on AnalyzeOutput to prevent panic on nil input
- Extract spinnerMessage/successMessage helpers to stay within function length limit
- Refactor ValidateAIConfig tests to table-driven with errors.Is() sentinels
- Sync PRD snippet with actual parseSkillFlagInternal implementation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Extract AI logic from cmd/ into domain packages with comprehensive tests
Move AI flag parsing, setup, and analysis orchestration out of cmd/root.go
into proper domain packages per review feedback:
- cmd/ai/flags/: pre-Cobra flag parsing (HasAIFlag, ParseSkillFlag, SplitCSV)
- cmd/ai/setup/: AI initialization orchestration (InitAI, IsAISubcommand)
- pkg/ai/analyze/context.go: AI lifecycle management (Setup, RunAnalysis, Cleanup)
- pkg/ai/skills/validate.go: skill validation and prompt building (LoadAndValidate, BuildPrompt)
Fix intermittent capture_test.go failures by redirecting tee output to
os.DevNull instead of go test's captured stdout/stderr.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address CodeRabbit review: security, correctness, and CI fixes
- Last-value-wins for repeated --ai flags (match Cobra semantics)
- Bare --skill suppresses ATMOS_SKILL env var fallback
- Short-circuit --help/-h before AI validation (prevent env var errors)
- Sanitize BuildCommandName: stop at -- to avoid leaking secrets
- Provider-aware error hints (model/env var per provider)
- Remove dead ErrAISkillLoadFailed wrapper (LoadSkills never errors)
- Redirect stderr in AnalyzeOutput tests to fix CI output leaking
- Add nil input guard test for AnalyzeOutput
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix CI test failures: suppress logger output, polish test surface
- Redirect logger to devNull in tests (charm logger caches stderr at
init, so os.Stderr reassignment alone doesn't suppress ERRO lines)
- Unexport buildCommandNameInternal (only used in same-package tests)
- Add perf.Track to BuildCommandName per mandatory convention
- Remove tautological TestBuildCommandName_ReturnsNonEmpty
- Fix TestContext_RunAnalysis_NilContextReturnsFalse to call RunAnalysis
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix CI exit status 2: mock CaptureSession must be pre-stopped
Mock CaptureSession with stopped:false has nil pipe fields. When
Cleanup() calls Stop(), it nils out os.Stdout/os.Stderr, causing the
coverage writer to crash with exit status 2 (only under -coverpkg=./...).
Fix: use stopped:true for mock sessions so Stop() short-circuits.
Also add redirectToDevNull to error-path tests that write to stderr.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Externalize AI system prompt to embedded file, clean example config
- Move system prompt from inline const to //go:embed prompts/system.md
- Remove unused terminal settings block from examples/ai/atmos.yaml
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>1 parent 57c2e21 commit 78b23f7
File tree
76 files changed
+4258
-50
lines changed- cmd
- ai
- flags
- setup
- terraform
- docs/prd
- errors
- examples/ai
- pkg
- ai
- analyze
- prompts
- skills
- flags
- global
- ui
- tests/snapshots
- tools/lintroller
- website
- blog
- docs
- ai
- cli
- commands/ai
- configuration
- src/data
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
76 files changed
+4258
-50
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
0 commit comments