Skip to content

Update to support reference architectures - #5

Merged
Andriy Knysh (aknysh) merged 7 commits into
masterfrom
update-for-reference-architectures
Nov 12, 2020
Merged

Andriy Knysh (aknysh) merged 7 commits into
masterfrom
update-for-reference-architectures

Conversation

@aknysh

Copy link
Copy Markdown
Member

what

  • Update to support reference architectures

why

  • Rename opsctl to atmos
  • Rename projects/ to components/
  • Add vendor CLI for synching reference architecture components
  • Add terraform-backend CLI to generate Terraform S3 backends for Terraform components

@aknysh
Andriy Knysh (aknysh) merged commit 2f876cc into master Nov 12, 2020
@aknysh
Andriy Knysh (aknysh) deleted the update-for-reference-architectures branch November 12, 2020 19:11
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Oct 6, 2025
Update developer and PRD documentation to reflect the new structured markdown
error formatting with explanations and examples.

## Changes

### Developer Guide (docs/errors.md)

**Error Builder API**:
- Document `WithExplanation()` and `WithExplanationf()` methods
- Document `WithExample()` and `WithExampleFile()` methods
- Add embedded markdown example pattern with `//go:embed`
- Update Quick Start with complete example using all features

**Error Formatting**:
- Add "Structured Markdown Output" section showing 6 sections
- Document section order and conditional rendering
- Provide complete example with all sections
- Update configuration options to reflect context table in all modes

### PRD (docs/prd/atmos-error-handling.md)

**Design Decisions**:
- Update "Builder Pattern for Complex Errors" with new methods
- Add "Structured Markdown Error Presentation" as Decision #5
- Document section hierarchy and visual design rationale
- Provide formatted example output

**Error Categories**:
- Update "Builder-Enhanced Errors" with rich error example
- Show explanations, examples, hints, and context together
- Document use cases for structured error presentation

**Migration Path**:
- Add Phase 6: Structured Markdown Error Formatting (Complete)
- Document all implementation details:
  - New builder methods
  - Formatter refactoring with 6 sections
  - Workflow error conversions
  - Exit code handling updates
  - 21 comprehensive tests
  - Golden snapshot regeneration

All documentation now reflects the complete structured markdown error system.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Dec 18, 2025
- Fix broken documentation links in blog and update.mdx
  - Change /core-concepts/vendor/vendor-manifest to /vendor/vendor-config
  - Change /core-concepts/vendor to /vendor/vendor-config and /cheatsheets/vendoring
- Document vendor update stub as known limitation with detailed TODOs

Note: Comments #1, #3, #4, #5 were already addressed in previous commits.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Dec 21, 2025
- Fix broken documentation links in blog and update.mdx
  - Change /core-concepts/vendor/vendor-manifest to /vendor/vendor-config
  - Change /core-concepts/vendor to /vendor/vendor-config and /cheatsheets/vendoring
- Document vendor update stub as known limitation with detailed TODOs

Note: Comments #1, #3, #4, #5 were already addressed in previous commits.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Dec 23, 2025
1. delete.go: Require --force flag for deletion (returns error instead
   of silently exiting), using static error ErrPlanfileDeleteRequireForce
2. list.go: Add global flag parsing (--base-path, --config, etc.)
3. show.go: Add global flag parsing (--base-path, --config, etc.)
4. check.go: Add Name field to UpdateCheckRunOptions (distinct from Title)
5. checks.go: Use opts.Name instead of opts.Title for GitHub API

Note: Comment #5 about template field access was investigated and found
to be a false positive. The templates correctly access fields from
TerraformTemplateContext which provides .Resources, .HasChanges() etc.
at the top level (not under .Result).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Dec 26, 2025
1. delete.go: Require --force flag for deletion (returns error instead
   of silently exiting), using static error ErrPlanfileDeleteRequireForce
2. list.go: Add global flag parsing (--base-path, --config, etc.)
3. show.go: Add global flag parsing (--base-path, --config, etc.)
4. check.go: Add Name field to UpdateCheckRunOptions (distinct from Title)
5. checks.go: Use opts.Name instead of opts.Title for GitHub API

Note: Comment #5 about template field access was investigated and found
to be a false positive. The templates correctly access fields from
TerraformTemplateContext which provides .Resources, .HasChanges() etc.
at the top level (not under .Result).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Dec 26, 2025
- Fix broken documentation links in blog and update.mdx
  - Change /core-concepts/vendor/vendor-manifest to /vendor/vendor-config
  - Change /core-concepts/vendor to /vendor/vendor-config and /cheatsheets/vendoring
- Document vendor update stub as known limitation with detailed TODOs

Note: Comments #1, #3, #4, #5 were already addressed in previous commits.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Dec 29, 2025
1. delete.go: Require --force flag for deletion (returns error instead
   of silently exiting), using static error ErrPlanfileDeleteRequireForce
2. list.go: Add global flag parsing (--base-path, --config, etc.)
3. show.go: Add global flag parsing (--base-path, --config, etc.)
4. check.go: Add Name field to UpdateCheckRunOptions (distinct from Title)
5. checks.go: Use opts.Name instead of opts.Title for GitHub API

Note: Comment #5 about template field access was investigated and found
to be a false positive. The templates correctly access fields from
TerraformTemplateContext which provides .Resources, .HasChanges() etc.
at the top level (not under .Result).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Dec 29, 2025
- Fix Comment #3: Parse global flags before InitCliConfig in all auth
  commands by adding BuildConfigAndStacksInfo helper to pkg/flags and
  cmd/auth/helpers.go

- Fix Comment #4: Add guard for empty selectable array in configure.go
  to prevent index out of bounds when no AWS user identities found

- Fix Comment #5: Remove duplicate IdentityFlagName constants by using
  cfg.IdentityFlagName from pkg/config/const.go as canonical source

- Remove unused schema imports from login.go, exec.go, shell.go
- Remove unnecessary nolint:gosec directives from env.go

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Dec 29, 2025
1. delete.go: Require --force flag for deletion (returns error instead
   of silently exiting), using static error ErrPlanfileDeleteRequireForce
2. list.go: Add global flag parsing (--base-path, --config, etc.)
3. show.go: Add global flag parsing (--base-path, --config, etc.)
4. check.go: Add Name field to UpdateCheckRunOptions (distinct from Title)
5. checks.go: Use opts.Name instead of opts.Title for GitHub API

Note: Comment #5 about template field access was investigated and found
to be a false positive. The templates correctly access fields from
TerraformTemplateContext which provides .Resources, .HasChanges() etc.
at the top level (not under .Result).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Dec 30, 2025
1. delete.go: Require --force flag for deletion (returns error instead
   of silently exiting), using static error ErrPlanfileDeleteRequireForce
2. list.go: Add global flag parsing (--base-path, --config, etc.)
3. show.go: Add global flag parsing (--base-path, --config, etc.)
4. check.go: Add Name field to UpdateCheckRunOptions (distinct from Title)
5. checks.go: Use opts.Name instead of opts.Title for GitHub API

Note: Comment #5 about template field access was investigated and found
to be a false positive. The templates correctly access fields from
TerraformTemplateContext which provides .Resources, .HasChanges() etc.
at the top level (not under .Result).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Dec 31, 2025
1. Fix hydration mismatch: Initialize isFullscreen/isMobile to false,
   then set mobile state after mount in useEffect (Comment #1)

2. Fix stale closure in resize handler: Use ref to track current
   fullscreen state instead of closure value (Comment #2)

3. Remove unused import: Remove createPortal from SlideNotesPopout
   (Comment #3)

4. Fix popout window recreation: Remove currentSlide/totalSlides/
   currentNotes from dependency array so window isn't recreated
   on every slide change (Comment #4)

5. Fix XSS vulnerability: Use textContent instead of innerHTML
   when setting notes content in popout window (Comment #5)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Andriy Knysh (aknysh) added a commit that referenced this pull request Jan 1, 2026
…omization (#1925)

* feat: Improve slide deck mobile responsiveness and fullscreen behavior

- Auto-enter fullscreen mode on mobile/tablet devices (touch + width ≤ 1024px)
- Detect device orientation and screen dimensions for responsive behavior
- Remove forced dark mode styling; fullscreen now respects current theme
- Add responsive breakpoints for tablet (996px) and mobile (768px)
- Implement viewport-based scaling for text and images on mobile
- Maintain 2-column split layouts on mobile with scaled content
- Increase z-index to 99999 to prevent navbar overlap in fullscreen
- Improve padding and spacing for mobile screens
- Use clamp() with viewport units (vw) for fluid typography

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* feat: Add responsive scaling for desktop fullscreen mode

- Remove max-width constraint (1600px) on fullscreen slide wrapper
- Use viewport-based sizing to fill entire screen while maintaining 16:9
- Scale slide content width from 800px to 85-90% in fullscreen
- Add clamp() with vw units for text scaling in fullscreen:
  - Titles scale from 2.5rem to 4rem (4vw)
  - Title slides scale from 3.5rem to 5.5rem (5vw)
  - Content/lists scale from 1.25rem to 2rem (2vw)
  - Code scales from 0.9rem to 1.3rem (1.2vw)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: Increase bomb image width from 180px to 280px

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Allow vertical scrolling in fullscreen slides for long content

Changes overflow from hidden to overflow-y: auto so YAML code blocks
and other long content can be scrolled within the slide.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Make mobile fullscreen fill entire viewport without black borders

Remove 16:9 aspect ratio constraint on mobile so the slide background
extends to fill the entire screen instead of showing black bars.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Remove dark borders on mobile fullscreen by making containers transparent

Make all fullscreen containers transparent so the slide's background
extends to fill the entire viewport without visible borders.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Restore solid background and visible controls on mobile fullscreen

- Use solid background color instead of transparent to hide page behind
- Add fixed positioning for toolbar at bottom of screen
- Add fixed positioning for nav buttons with semi-transparent background
- Add padding-bottom to slide content to avoid toolbar overlap

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Hide left-area container in mobile fullscreen mode

The left-area container was taking up space in the flex layout even
though the nav buttons were fixed positioned, causing a dark strip
on the left side of the slide.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Improve vertical centering in mobile fullscreen mode

- Changed container align-items from stretch to center
- Added flexbox centering to slide-wrapper
- Changed slide height from 100% to auto with min-height: 100%
- Added explicit flexbox centering to slide element

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Keep prev navigation button visible in mobile fullscreen

Instead of hiding the left-area container completely (which also hides
the prev button), collapse it to width: 0 but keep overflow: visible
so the fixed-positioned nav button still renders.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Ensure vertical centering for content layout slides on mobile

- Changed slide height back to 100% (from auto with min-height)
- Added explicit centering override for content layout slides
- Keep text-align: left for content readability

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Enable vertical scrolling on mobile fullscreen slides

- Changed slide from flexbox to block display to allow overflow scrolling
- Moved vertical centering to slide__inner using min-height + flexbox
- margin: auto centers content when it's shorter than viewport
- Long content can now scroll properly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Use absolute positioning for mobile slide to enable scrolling

- Removed flexbox from slide-wrapper (was preventing scroll)
- Used absolute positioning on slide to fill container
- Slide now has fixed dimensions and can scroll content

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Use 'justify-content: safe center' for vertical centering with scroll

- Use 'safe center' which centers when content fits, aligns to start when overflow
- Keep flexbox display for proper centering
- Remove conflicting display: block from Slide.css

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Use margin:auto on slide__inner for vertical centering

- Removed 'justify-content: safe center' (limited browser support)
- Use margin: auto on slide__inner with flex-shrink: 0
- This centers when content is short, scrolls when content overflows

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Remove top padding from mobile fullscreen slide

Changed padding from '1.5rem 2rem' to '0 2rem' to eliminate the
top offset that was pushing content down.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Remove all top padding from mobile fullscreen slides

- Added !important to slide padding override (0 1.5rem)
- Explicitly set margin: auto and padding: 0 on slide__inner

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Add horizontal padding to slide__inner on mobile fullscreen

Changed padding from 0 to '0 1rem' for left/right spacing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Add customizable speaker notes with position, display mode, and popout options

- Add notes preferences state (position, displayMode, isPopout) to context with localStorage persistence
- Add bottom position for notes panel (Google Slides style) with 25vh height
- Add shrink display mode that resizes slides instead of overlaying
- Add toolbar controls to toggle position, display mode, and popout (desktop only)
- Add popout window component with BroadcastChannel sync for cross-window navigation
- Fix navigation buttons z-index to work when notes overlay is present
- Ensure notes content is scrollable with proper min-height: 0 on flex child

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: Move notes preference controls to SlideNotesPanel header

Move the position toggle, display mode toggle, and popout button
from the main toolbar into the SlideNotesPanel header. The main
toolbar now only shows a single notes button that toggles notes
or brings them back from popout mode.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Add horizontal padding to bottom position speaker notes

The notes content was flush against the left/right edges when in
bottom position. Added 2rem padding to both header and content
for better visual spacing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Extend progress bar to full width in page mode

The progress bar was respecting the container padding, leaving gaps
on the sides. Now uses negative margins to extend edge-to-edge.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address CodeRabbit review comments for SlideDeck

1. Fix hydration mismatch: Initialize isFullscreen/isMobile to false,
   then set mobile state after mount in useEffect (Comment #1)

2. Fix stale closure in resize handler: Use ref to track current
   fullscreen state instead of closure value (Comment #2)

3. Remove unused import: Remove createPortal from SlideNotesPopout
   (Comment #3)

4. Fix popout window recreation: Remove currentSlide/totalSlides/
   currentNotes from dependency array so window isn't recreated
   on every slide change (Comment #4)

5. Fix XSS vulnerability: Use textContent instead of innerHTML
   when setting notes content in popout window (Comment #5)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Improve popout window slide state synchronization

- Add refs to track current slide state for immediate popout initialization
- Create updatePopoutContent helper to consolidate DOM update logic
- Immediately update popout content after document.close() to avoid "Loading..." flash
- Add popup=yes to window.open() for better browser compatibility
- Note: Arc browser opens popups as tabs by design, but BroadcastChannel sync still works

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Add slide-notes-extractor plugin for TTS export

Creates plain text files from SlideNotes content at build time for
OpenAI TTS. Files are output to build/slides/{deck-name}/slide{N}.txt
and sync to S3 with the rest of the build.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Add TTS player for speaker notes

Implement a full-featured Text-to-Speech player for slide speaker notes:

- Play/Pause/Stop controls in both toolbar and player bar
- Mute toggle with visual feedback (red icon when muted)
- Voice selector with 6 OpenAI voices (alloy, echo, fable, nova, onyx, shimmer)
- Speed control (0.5x to 2x)
- Progress bar with seek capability
- Auto-advance to next slide when audio completes
- Auto-continue playback when manually navigating slides
- Preferences persistence (voice, speed, mute) in localStorage
- Keyboard shortcuts: P (play/pause), M (mute)

Uses the Cloud Posse TTS API which converts slide notes .txt files
(generated at build time by slide-notes-extractor plugin) to speech.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address security and accessibility review comments

- Fix XSS vulnerability in slide-notes-extractor by using iterative
  tag stripping and removing any remaining < or > characters
- Add keyboard support to TTSPlayer progress bar (ArrowLeft/Right
  for 5s seek, Home/End for start/end)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* fix: Auto-play TTS continues after slide advance

The TTS auto-play feature was not continuing playback after auto-advancing
to the next slide because the "was playing" state was cleared before the
slide change occurred.

Changed to use a dedicated autoPlayRef that:
- Gets set to true when user starts playing
- Stays true across slide transitions (so next slide auto-plays)
- Gets cleared on pause, stop, or reaching the last slide

Also wired up TTSPlayer callbacks so pause/stop/resume properly
update the auto-play state.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Use text extraction approach for HTML sanitization

Changed from iterative tag stripping to text extraction approach
to address CodeQL "incomplete multi-character sanitization" alert.

The new approach:
1. Extracts text content between HTML tags
2. Joins with spaces to preserve word boundaries
3. Removes any stray angle brackets as final cleanup

This avoids the regex replacement pitfall where removing one tag
could leave fragments that combine into new tags.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Add 2-second delay between slides during TTS auto-play

When auto-playing speaker notes, there's now a 2-second pause between
slides to give listeners time to absorb the content before the next
slide's audio begins.

The delay is:
- Configurable via AUTO_ADVANCE_DELAY constant (currently 2000ms)
- Cancelled when user pauses or stops playback
- Cleaned up on component unmount

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: Split TTS auto-advance delay into 1s after + 1s before

Split the 2-second delay between slides into two parts:
- 1 second after the current slide's audio ends
- 1 second before the next slide's audio starts

This provides a more balanced pause that gives time for both
the current slide to sink in and for the visual transition
to the next slide before audio begins.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: Rename TTS delay constants for clarity

Rename AUTO_ADVANCE_DELAY_AFTER/BEFORE to AUTO_ADVANCE_DELAY and
AUTO_PLAY_DELAY for clearer semantics:
- AUTO_ADVANCE_DELAY: delay before advancing to next slide
- AUTO_PLAY_DELAY: delay before starting audio on new slide

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Keep TTS player bar visible during slide transitions

Add isAutoPlaying state to track auto-play mode for UI updates.
Previously, the TTSPlayer bar would disappear during the 1-second
delay between slides because neither isPlaying nor isPaused was true.

Now the bar stays visible when navigating via the drawer or during
auto-advance transitions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Show loading spinner during TTS slide transitions

The play button now shows a loading spinner during the delay between
slides when in auto-play mode. Previously it would briefly show the
play icon which was jarring.

Changes:
- Always show the TTS button (not conditional on currentNotes)
- Show spinner when isAutoPlaying but not yet playing/paused
- Button stays active during auto-play transitions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Reuse Audio element for iOS autoplay compatibility

iOS Safari blocks audio playback that isn't directly triggered by user
interaction. Creating a new Audio() element for each slide broke the
user-activation chain, causing "request is not allowed by the user agent"
errors on mobile.

Fix: Reuse a single persistent Audio element and update its src property
instead of creating new elements. This preserves the user-activation
state established on the first tap.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Prefetch TTS audio in parallel with delay

Start the TTS API call immediately when a slide changes, running it in
parallel with the AUTO_PLAY_DELAY. This way the delay is:
  max(delay, api_call_time)
instead of:
  delay + api_call_time

Added prefetch() function to useTTS that returns a playPrefetched()
function, allowing the fetch and delay to run concurrently.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Prefetch next slide audio while current slide plays

Add background prefetching of n+1 slide audio to eliminate API latency
between slides during auto-play.

Changes:
- Add prefetch cache (Map keyed by slide+voice)
- Add prefetchInBackground() for silent background fetching
- Update play() and prefetch() to check cache first
- Trigger background prefetch when audio starts playing

Now while slide N plays, slide N+1 audio is fetched in parallel. When
advancing, the cached audio is used immediately.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Handle unhandled promise rejection in TTS resume

The resume callback was calling audio.play() without handling the
returned Promise, which could lead to unhandled rejections when
autoplay is blocked or other playback errors occur.

Now properly chains .then/.catch to update state appropriately on
success or failure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Improve mobile portrait fullscreen layout for slides

Address issues in mobile Safari portrait mode:
- Use dvh units to account for dynamic browser UI (URL bar)
- Add safe-area-inset padding for notched devices
- Reduce font sizes for narrow portrait viewports
- Stack split layouts vertically in portrait
- Align content to top instead of center to prevent overlap

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Center slide content vertically in mobile portrait mode

Reverted to centered vertical alignment for slides in portrait mode.
The previous top-alignment looked unbalanced for shorter content.
Content will scroll if it overflows.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Andriy Knysh <aknysh@users.noreply.github.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Jan 2, 2026
- cmd/auth/shell.go: Use envpkg.MergeGlobalEnv() for consistency with exec.go
  (addresses CodeRabbit comment #3 about env merging inconsistency)

- cmd/auth/whoami.go: Use %w for error wrapping to preserve error chain
  (addresses CodeRabbit comment #4 about error wrapping)

- tests/cli_describe_component_test.go: Use cross-platform TTY detection
  with term.IsTTYSupportForStdout() and close file handle properly
  (addresses CodeRabbit comments #5, #6)

- tests/describe_test.go: Add skipIfNoTTY helper with cross-platform
  TTY detection and proper file handle cleanup
  (addresses CodeRabbit comments #7, #8)

Note: Comments #1 and #2 (codeql clear-text logging) are false positives -
the atmos auth env command intentionally outputs credentials for shell
sourcing, similar to `aws configure export-credentials`. Suppression
comments are already in place.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Jan 3, 2026
1. delete.go: Require --force flag for deletion (returns error instead
   of silently exiting), using static error ErrPlanfileDeleteRequireForce
2. list.go: Add global flag parsing (--base-path, --config, etc.)
3. show.go: Add global flag parsing (--base-path, --config, etc.)
4. check.go: Add Name field to UpdateCheckRunOptions (distinct from Title)
5. checks.go: Use opts.Name instead of opts.Title for GitHub API

Note: Comment #5 about template field access was investigated and found
to be a false positive. The templates correctly access fields from
TerraformTemplateContext which provides .Resources, .HasChanges() etc.
at the top level (not under .Result).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Jan 4, 2026
1. delete.go: Require --force flag for deletion (returns error instead
   of silently exiting), using static error ErrPlanfileDeleteRequireForce
2. list.go: Add global flag parsing (--base-path, --config, etc.)
3. show.go: Add global flag parsing (--base-path, --config, etc.)
4. check.go: Add Name field to UpdateCheckRunOptions (distinct from Title)
5. checks.go: Use opts.Name instead of opts.Title for GitHub API

Note: Comment #5 about template field access was investigated and found
to be a false positive. The templates correctly access fields from
TerraformTemplateContext which provides .Resources, .HasChanges() etc.
at the top level (not under .Result).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Jan 4, 2026
- Fix Comment #3: Parse global flags before InitCliConfig in all auth
  commands by adding BuildConfigAndStacksInfo helper to pkg/flags and
  cmd/auth/helpers.go

- Fix Comment #4: Add guard for empty selectable array in configure.go
  to prevent index out of bounds when no AWS user identities found

- Fix Comment #5: Remove duplicate IdentityFlagName constants by using
  cfg.IdentityFlagName from pkg/config/const.go as canonical source

- Remove unused schema imports from login.go, exec.go, shell.go
- Remove unnecessary nolint:gosec directives from env.go

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Jan 4, 2026
- cmd/auth/shell.go: Use envpkg.MergeGlobalEnv() for consistency with exec.go
  (addresses CodeRabbit comment #3 about env merging inconsistency)

- cmd/auth/whoami.go: Use %w for error wrapping to preserve error chain
  (addresses CodeRabbit comment #4 about error wrapping)

- tests/cli_describe_component_test.go: Use cross-platform TTY detection
  with term.IsTTYSupportForStdout() and close file handle properly
  (addresses CodeRabbit comments #5, #6)

- tests/describe_test.go: Add skipIfNoTTY helper with cross-platform
  TTY detection and proper file handle cleanup
  (addresses CodeRabbit comments #7, #8)

Note: Comments #1 and #2 (codeql clear-text logging) are false positives -
the atmos auth env command intentionally outputs credentials for shell
sourcing, similar to `aws configure export-credentials`. Suppression
comments are already in place.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Jan 5, 2026
- Fix Comment #3: Parse global flags before InitCliConfig in all auth
  commands by adding BuildConfigAndStacksInfo helper to pkg/flags and
  cmd/auth/helpers.go

- Fix Comment #4: Add guard for empty selectable array in configure.go
  to prevent index out of bounds when no AWS user identities found

- Fix Comment #5: Remove duplicate IdentityFlagName constants by using
  cfg.IdentityFlagName from pkg/config/const.go as canonical source

- Remove unused schema imports from login.go, exec.go, shell.go
- Remove unnecessary nolint:gosec directives from env.go

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Jan 5, 2026
- cmd/auth/shell.go: Use envpkg.MergeGlobalEnv() for consistency with exec.go
  (addresses CodeRabbit comment #3 about env merging inconsistency)

- cmd/auth/whoami.go: Use %w for error wrapping to preserve error chain
  (addresses CodeRabbit comment #4 about error wrapping)

- tests/cli_describe_component_test.go: Use cross-platform TTY detection
  with term.IsTTYSupportForStdout() and close file handle properly
  (addresses CodeRabbit comments #5, #6)

- tests/describe_test.go: Add skipIfNoTTY helper with cross-platform
  TTY detection and proper file handle cleanup
  (addresses CodeRabbit comments #7, #8)

Note: Comments #1 and #2 (codeql clear-text logging) are false positives -
the atmos auth env command intentionally outputs credentials for shell
sourcing, similar to `aws configure export-credentials`. Suppression
comments are already in place.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Jan 23, 2026
1. delete.go: Require --force flag for deletion (returns error instead
   of silently exiting), using static error ErrPlanfileDeleteRequireForce
2. list.go: Add global flag parsing (--base-path, --config, etc.)
3. show.go: Add global flag parsing (--base-path, --config, etc.)
4. check.go: Add Name field to UpdateCheckRunOptions (distinct from Title)
5. checks.go: Use opts.Name instead of opts.Title for GitHub API

Note: Comment #5 about template field access was investigated and found
to be a false positive. The templates correctly access fields from
TerraformTemplateContext which provides .Resources, .HasChanges() etc.
at the top level (not under .Result).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Jan 23, 2026
1. delete.go: Require --force flag for deletion (returns error instead
   of silently exiting), using static error ErrPlanfileDeleteRequireForce
2. list.go: Add global flag parsing (--base-path, --config, etc.)
3. show.go: Add global flag parsing (--base-path, --config, etc.)
4. check.go: Add Name field to UpdateCheckRunOptions (distinct from Title)
5. checks.go: Use opts.Name instead of opts.Title for GitHub API

Note: Comment #5 about template field access was investigated and found
to be a false positive. The templates correctly access fields from
TerraformTemplateContext which provides .Resources, .HasChanges() etc.
at the top level (not under .Result).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Jan 30, 2026
- Use filepath.Join for OS-safe test paths (Comments #1, #6)
- Route FileCache operations through injected FileSystem interface (Comment #2)
- Add ErrCacheFetch sentinel and wrap fetch() errors (Comment #3)
- Fix misleading "log" comment in GetOrFetch (Comment #4)
- Add missing BrowserSessionWarningShown assertion (Comment #5)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Erik Osterman (Cloud Posse) (osterman) added a commit that referenced this pull request Jan 30, 2026
- Use filepath.Join for OS-safe test paths (Comments #1, #6)
- Route FileCache operations through injected FileSystem interface (Comment #2)
- Add ErrCacheFetch sentinel and wrap fetch() errors (Comment #3)
- Fix misleading "log" comment in GetOrFetch (Comment #4)
- Add missing BrowserSessionWarningShown assertion (Comment #5)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Ben (Benbentwo) added a commit that referenced this pull request Feb 23, 2026
- Update security note #5 to reflect deterministic identity binding
  via --identity flag (no longer "ambient AWS credentials")
- Fix diagram: "STS GetCallerID" → "GetCallerIdentity"
- Clarify that auth subcommands use authCmd.AddCommand(), not
  CommandProvider (which is for top-level commands only)
- Distinguish existing --role-arn flag (generation-time) from future
  exec plugin role assumption (runtime) in Future Enhancements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ben (Benbentwo) added a commit that referenced this pull request Mar 4, 2026
* docs: Add EKS kubeconfig authentication integration PRD

This PRD defines the design for integrating EKS kubeconfig generation into Atmos's
authentication system via the integration pattern. EKS kubeconfig generation will be
automatic on identity login and available via `atmos auth eks-kubeconfig` command.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* docs: Update EKS PRD based on review feedback

Changes based on PR review:
- Use `atmos aws eks update-kubeconfig` instead of `atmos auth eks-kubeconfig`
- Update kubeconfig schema to use nested structure with path/mode/update fields
- Simplify KUBECONFIG env var example to use `atmos auth env --format=export`
- Add note clarifying exec credential plugin is standard AWS CLI format

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* docs: Sync EKS kubeconfig PRD with current codebase

Align the PRD with the actual integration infrastructure after
rebasing onto main. Fixes incorrect interface definition, method
names, file paths, and dependency status.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: Use atmos as exec credential plugin, simplify XDG path

Replace `aws eks get-token` with `atmos auth eks-token` as the
kubeconfig exec credential plugin, eliminating the AWS CLI dependency.
Simplify XDG path usage to call GetXDGConfigDir directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: Update architecture diagram to show kubectl exec flow

Add the kubectl-time exec flow showing atmos auth eks-token
being invoked by kubectl to generate bearer tokens via STS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: Add identity resolution, KUBECONFIG append, Mode parsing to EKS PRD

- Add --identity flag and interactiveMode: Never to exec plugin spec
  for deterministic credential selection with multiple identities
- Specify KUBECONFIG colon-separated append semantics (idempotent)
- Fix eks-token command path to cmd/auth_eks_token.go matching existing
  auth subcommand pattern (not CommandProvider)
- Specify KubeconfigSettings.Mode octal parsing via strconv.ParseUint
- Replace custom MergeKubeconfig with k8s.io/client-go/tools/clientcmd

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: Fix security note, diagram label, Role ARN scope in EKS PRD

- Update security note #5 to reflect deterministic identity binding
  via --identity flag (no longer "ambient AWS credentials")
- Fix diagram: "STS GetCallerID" → "GetCallerIdentity"
- Clarify that auth subcommands use authCmd.AddCommand(), not
  CommandProvider (which is for top-level commands only)
- Distinguish existing --role-arn flag (generation-time) from future
  exec plugin role assumption (runtime) in Future Enhancements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: Sync EKS PRD with current codebase

- Add validation spec for KubeconfigSettings.Update (reject invalid
  values at config-load time, default "merge")
- Add k8s.io/client-go and PR #1903 to Dependencies section
- Fix `atmos auth env --format=export` to `atmos auth env` (bash is
  the default; "export" is not a valid format)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: Rewrite EKS PRD intro, add Terraform provider documentation

Rewrite the executive summary and problem statement to better frame
the motivation: Atmos already manages cloud auth, so extending to
Kubernetes config is a natural next step. Add Terraform Kubernetes
provider section showing kubeconfig-based and exec-based approaches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: Clarify exec plugin mechanism in Terraform provider section

Explain that the kubeconfig's exec spec contains `command: atmos`
which the Terraform provider invokes on demand for token refresh.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: Add integration lifecycle, env var composition, and flag docs to EKS PRD

- Show --identity and --profile flags in Desired Workflow examples
- Extend Integration interface with Cleanup() and Environment() methods
- Add Integration Cleanup on Logout section (logout undoes login effects)
- Add Integration Environment Variables section with composition strategy
  for multi-integration scenarios (blue/green clusters, mixed EKS+ECR)
- Update CLI command flags with env var bindings and flag disambiguation
- Replace kubeconfig cleanup future enhancement with CI/CD workflow item
- Add test cases for cleanup, environment composition, and logout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
Igor Rodionov (goruha) added a commit that referenced this pull request Mar 16, 2026
…cle (#2079)

* feat: Add CI Summary Templates and --ci flag for automated pipelines

Implement comprehensive CI integration with rich tfcmt-style templates for terraform plan/apply outputs. Auto-generates job summaries, outputs, and artifact management.

- Add CIProvider interface for extensible CI component support
- Implement terraform CI provider with JSON-based output parsing
- Create embedded default templates (plan.md, apply.md) with resource counts, badges, and collapsible sections
- Add template loader with atmos.yaml override support (base_path, per-component templates)
- Add generic CI provider for local testing (--ci flag without platform detection)
- Implement unified CI executor with hook bindings and declarative actions
- Add golden file tests for template regression testing
- Add --ci flag to plan/apply commands (respects CI env var precedence)
- Wire CI hooks through terraform PostRunE for automatic execution

Template features match existing GitHub Actions with tfcmt formatting:
- Plan summaries with resource change badges (CREATE, CHANGE, REPLACE, DESTROY)
- Caution warning when resources will be deleted
- Terraform output variables table after apply
- Error/warning extraction from command output
- Markdown rendering with collapsible sections

CI integration is controlled by:
1. ci.enabled in atmos.yaml (enables/disables integration)
2. CI environment detection (GitHub Actions auto-detected)
3. --ci flag on plan/apply (forces CI mode for testing)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* fix: Add perf.Track and linting fixes for CI package

- Add defer perf.Track() to all public functions in CI package
- Fix import ordering (go-fumpt)
- Fix octal literal formatting (0644 → 0o644)
- Update golangci.yml to exclude pkg/ci/github/ from depguard
- Update lintroller to exclude pkg/ci/ from some checks
- Fix test file permission literals

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: Add blog post announcing native CI integration

Announces the new native CI integration feature with:
- Simple GitHub Actions workflow examples
- Explanation of auto-detection and --ci flag
- Matrix strategy for multiple components
- Local testing instructions
- Configuration options

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Add missing planfile packages and fix broken blog link

The planfile command and pkg/ci/planfile packages were not committed
because .gitignore had a rule `**/planfile` which ignored any directory
named "planfile". Changed the rule to only ignore files matching
`*.planfile` pattern (already covered by existing rules).

Also:
- Fixed broken link in CI integration blog post that referenced /ci
- Added pkg/ci/planfile/s3/ to golangci exclusions for AWS SDK imports
- Fixed lint issues in internal/exec/describe_affected.go

Note: The newly tracked files have pre-existing lint issues that will
need to be addressed in a follow-up commit.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Remove duplicate defaultFilePermissions constant

The constant was already defined in docs_generate.go in the same package.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address all lint issues in CI integration code

Refactored CI integration code to resolve all lint issues without
using nolint directives:

- Extract helper functions to reduce cyclomatic/cognitive complexity
- Use pointer parameters for large structs (hugeParam fixes)
- Extract constants for magic numbers
- Refactor nested if blocks into early returns
- Split long functions into focused helpers

Files refactored:
- cmd/ci/status.go: Split getRepoContext into helper functions
- cmd/terraform/planfile/*.go: Extract format/download helpers
- pkg/ci/executor.go: Extract platform detection and binding logic
- pkg/ci/terraform/parser.go: Extract resource processing functions
- pkg/ci/planfile/github/store.go: Extract repo info and zip handling
- pkg/ci/templates/loader.go: Extract template loading by source

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Update golden snapshots for CI integration

Regenerated golden snapshots to reflect new CI integration features:
- New `ci` command in atmos --help output
- New `planfile` subcommand under `terraform`
- New `--ci` flag for terraform plan/apply commands
- New CI configuration fields in describe config output

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Make TestLoaderResolvePath cross-platform compatible

Use filepath.FromSlash() for path literals in test expectations to
ensure the test passes on both Unix and Windows, where path separators
differ.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: Update CI PRDs with implementation status

- native-ci-integration.md: Added Implementation Status section showing
  Phase 1 complete, Phase 2 ~70%, and Phases 3-6 pending. Updated
  package structure and Files to Create table with status indicators.
  Documented additional components implemented beyond original PRD.

- ci-summary-templates.md: Marked as complete with all files implemented.
  Added missing test files to the implementation table.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: Clarify CI mode activation in blog post

Address review comment: clarify that ci.enabled: true in atmos.yaml
is respected as a way to enable CI mode. Added numbered list of
activation conditions and clarified precedence order.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address CodeRabbit review comments on CI integration

This commit addresses multiple CodeRabbit review comments:

- cmd/terraform/planfile/download.go: Fix double %w error wrapping using
  errors.Join, fix Windows path handling using filepath.Base()
- cmd/terraform/planfile/upload.go: Fix unreachable GitHub Actions detection
  by reordering store type logic
- pkg/ci/github/checks.go: Add documentation for completed status mapping,
  remove unused mapGitHubConclusionToCheckRunState function
- pkg/ci/planfile/github/store.go: Add HTTP timeout (30s) for artifact
  downloads, fix error wrapping with errors.Join
- pkg/ci/planfile/local/store.go: Fix file filter to only skip .metadata.json
  files
- pkg/ci/planfile/s3/store.go: Simplify error check functions by removing
  unused second parameter
- pkg/ci/terraform/provider.go: Add nil check for result parameter in
  GetOutputVariables
- tools/lintroller/rule_perf_track.go: Add pkg/template exclusion with proper
  documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address additional CodeRabbit review comments on CI integration

This commit addresses the second round of CodeRabbit review comments:

Comment #1 - Global flags in planfile commands:
- Add global flag parsing (--base-path, --config, --config-path, --profile)
  to delete.go, download.go, and upload.go using flags.ParseGlobalFlags()
- Refactored upload.go to extract helper functions and reduce function length

Comment #3 - GenerateKey placeholder validation:
- Add validation for required fields (Stack, Component, SHA) when used in pattern
- Return ErrPlanfileKeyInvalid error instead of leaving placeholders unreplaced
- Update interface_test.go with new test cases for validation behavior

Comments #4-5 - Golden file anchor mismatches:
- Update templates to use user-content- prefix on anchor IDs for proper
  markdown link fragment resolution
- Regenerate all golden files to match new template output

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Add comprehensive CI integration test coverage

Add test files for CI integration packages to improve code coverage:

- pkg/ci/planfile/github/store_test.go: GitHub Artifacts store tests
- pkg/ci/planfile/s3/store_test.go: S3 store helper function tests
- pkg/ci/github/status_test.go: GitHub status fetching tests
- pkg/ci/github/checks_test.go: Check run creation/update tests
- cmd/ci/status_test.go: CI status command helper tests
- pkg/ci/output_test.go: Output writer tests
- cmd/terraform/planfile/upload_test.go: Upload command helper tests
- cmd/terraform/planfile/list_test.go: List formatting tests
- Expanded pkg/ci/executor_test.go with data structure tests
- Expanded pkg/ci/planfile/local/store_test.go with edge cases

Also removes accidentally committed lintroller binary and adds it to
.gitignore.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: Restructure CI config schema for provider-agnostic naming

Reorganize CI configuration from confusing nested structure to a cleaner,
provider-agnostic structure with four top-level capabilities:

- output: key=value pairs for downstream jobs (GitHub: $GITHUB_OUTPUT)
- summary: markdown job summary (GitHub: $GITHUB_STEP_SUMMARY)
- checks: commit status checks (GitHub: Check Runs API)
- comments: PR/MR comments (GitHub: PR comments, GitLab: MR notes)

Key changes:
- Rename status_checks -> checks
- Rename pr_comment -> comments
- Move variables under output where it belongs
- Remove outputs wrapper (was conflating concepts)
- Add template field to summary and comments configs

This structure supports GitHub Actions, GitLab CI, and other CI providers
with consistent, intuitive naming.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: Wire up CI config settings to executor implementation

- Add isActionEnabled() to check if CI actions are enabled based on config
- Summary and Output enabled by default, Checks disabled by default
- Upload/Download always enabled (controlled by planfile config)
- Add filterVariables() to filter output variables by CI.Output.Variables
- Update executeSummaryAction() to support custom template from config
- Add comprehensive tests for config-aware behavior

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address CodeRabbit review comments on CI integration

- Use ErrNotImplemented for GitHub Artifacts upload limitation
- Fix broken internal link fragment in plan_no_changes.md template
- Remove non-deterministic TestGetDefaultProvider test
- Remove tautological TestTableHeaderWidth and TestPlanfileInfoSorting tests
- Use errors.Is() for specific error sentinel verification in upload_test.go
- Handle JSON decode errors in checks_test.go mock handlers
- Check url.Parse errors in checks_test.go
- Fix config key names in PRD docs (ci.checks.enabled, ci.comments.enabled)
- Add Screengrab component to ci/status.mdx per documentation standards

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address error handling patterns in CI and config code

Changes:
- Use consistent fmt.Errorf("%w: ...") pattern in planfile store instead
  of errors.Join() for consistency with other methods
- Make error messages unique to avoid linter warning about duplicate
  string literals
- Fix type switch on error to use errors.As() in config loading
- Add nolint comment for ATMOS_CLI_CONFIG_PATH os.Getenv (bootstrap config)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: Move ATMOS_PROFILE/ATMOS_IDENTITY env vars to job level

Move environment variables from step level to job level in workflow
examples for better practice. This ensures all steps in the job have
access to the environment variables without repetition.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: Restructure PRD and blog with reproducibility narrative

Lead with WHY before WHAT: complex bash scripts in CI workflows signal
hidden complexity from tools not designed for CI. The reproducibility
principle—same command, same behavior everywhere—is now the core
narrative for native CI integration.

PRD changes:
- Add Executive Summary with key insight
- Expand Problem Statement with Hidden Complexity Problem
- Add The Reproducibility Principle section with before/after examples
- Rename "What You Get" to "What This Enables" (after context)
- Remove duplicate Problem Statement section

Blog post changes:
- Lead with reproducibility narrative
- Add "The Problem with CI Glue Code" section
- Add "The Reproducibility Principle" with concrete examples
- Add "What This Enables" to connect solution to problem

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: Add formal functional requirements and fix matrix examples

Add Functional Requirements (FR-1 through FR-9):
- FR-1: CI Environment Detection
- FR-2: Job Summary Output
- FR-3: CI Output Variables
- FR-4: Status Checks
- FR-5: Planfile Storage
- FR-6: Plan Verification
- FR-7: Command Parity
- FR-8: Describe Affected Matrix Format
- FR-9: CI Status Command

Add Non-Functional Requirements (NFR-1 through NFR-4):
- NFR-1: Performance targets
- NFR-2: Reliability (graceful degradation)
- NFR-3: Security boundaries
- NFR-4: Extensibility

Fix matrix examples to use --output-file flag:
- Add --output-file="$GITHUB_OUTPUT" usage pattern
- Show complete workflow example with affected job
- Document key=value output format for $GITHUB_OUTPUT

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Remove pkg/template from perf-track exclusions

The pkg/template package performs template.Parse and recursive AST
tree traversal, which are non-trivial operations requiring perf
tracking per coding guidelines. Only trivial String() methods qualify
for exclusion.

Addresses CodeRabbit review comment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address CodeRabbit review comments on CI integration

- Parse global flags before loading config in ci status command
- Add static error sentinels for planfile operations
- Add validation to planfile registry Register function
- Wrap errors with static sentinels in local and S3 stores
- Fix MD028 violations in markdown templates with HTML comments

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Update golden snapshots for CI schema and terraform flags

Update snapshots to reflect:
- CI config schema changes (outputs->output, status_checks->checks,
  pr_comment->comments, added summary section)
- New terraform apply flags (--auto-generate-backend-file,
  --init-run-reconfigure)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Regenerate terraform plan help snapshot

Update snapshot for terraform plan --help to include new flags:
- --auto-generate-backend-file
- --init-run-reconfigure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Use platform-specific absolute paths in TestLoaderResolvePath

On Windows, filepath.IsAbs() requires a drive letter (e.g., C:\) for a
path to be considered absolute. The test was using Unix-style paths
(/absolute/path) which become \absolute\path on Windows - not absolute.

This fix uses runtime.GOOS to select appropriate absolute paths for
each platform, ensuring the test works correctly on both Windows and
Unix systems.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address CodeRabbit review comments on planfile commands

1. delete.go: Require --force flag for deletion (returns error instead
   of silently exiting), using static error ErrPlanfileDeleteRequireForce
2. list.go: Add global flag parsing (--base-path, --config, etc.)
3. show.go: Add global flag parsing (--base-path, --config, etc.)
4. check.go: Add Name field to UpdateCheckRunOptions (distinct from Title)
5. checks.go: Use opts.Name instead of opts.Title for GitHub API

Note: Comment #5 about template field access was investigated and found
to be a false positive. The templates correctly access fields from
TerraformTemplateContext which provides .Resources, .HasChanges() etc.
at the top level (not under .Result).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: Use StandardParser pattern and pkg/list for planfile commands

Refactor all 5 planfile commands (list, show, delete, download, upload) to:
1. Use StandardParser pattern for flag handling (instead of package-level variables)
2. Use pkg/list infrastructure for list output formatting (instead of custom formatters)

Benefits:
- Automatic environment variable support (ATMOS_PLANFILE_*)
- Proper precedence handling (CLI > ENV > config > defaults)
- Type-safe options structs
- Consistent output formatting with TTY detection
- Less code to maintain

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: Add .claude/plans/ to .gitignore

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Rename shadowed fmt variable to outputFmt in list.go

The local variable `fmt` was shadowing the imported fmt package.
Renamed to `outputFmt` to avoid the shadowing issue.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address CodeRabbit review comments on CI integration

- Use *bool pointer types for CI config Enabled fields to distinguish
  "not set" from "explicitly false" (fixes isActionEnabled defaults)
- Document Detect() non-deterministic map iteration order in registry.go
- Replace manual mock with mockgen-generated MockComponentCIProvider
- Add validation for empty Stack/ComponentFromArg in GetArtifactKey
- Add perf.Track() to RunCIHooks function per coding guidelines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: Add TODO comment for GetArtifactKey interface consideration

Address CodeRabbit feedback about aligning with planfile.GenerateKey
validation pattern. The current defensive approach with placeholders
is appropriate since the key is only used for debug logging, but noted
for future consideration if the interface is used for actual operations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Remove unused PlanFile and Content fields from Hook struct

These fields were placeholders for deprecated CI hook commands
(ci.upload, ci.download, ci.summary). The modern approach uses
RunCIHooks which delegates to ci.Execute() with provider bindings.

Added comment explaining the deprecation and pointing to pkg/ci/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address CodeRabbit review comments on CI integration (part 2)

- GenericProvider: Return ErrCIOperationNotSupported error instead of
  (nil, nil) for GetStatus, CreateCheckRun, and UpdateCheckRun methods
  to prevent nil dereference panics at call sites
- s3/store.go: Wrap loadMetadata errors with ErrPlanfileMetadataFailed
  sentinel for consistent error handling
- loader_test.go: Handle fs.Sub error explicitly with panic for the
  (impossible) failure case since the directory is compile-time embedded

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address CodeRabbit review comments on CI integration (part 3)

Security fixes:
- Add path traversal validation in local planfile store to prevent
  directory escape attacks via malicious keys

Bug fixes:
- Fix type assertion panic in hooks.go when "hooks" section is missing
- Replace custom errorAs with stdlib errors.As in S3 store

Code quality improvements:
- Replace custom replaceAll/indexOf functions with strings.ReplaceAll
- Fix comment/constant name mismatch in status.go
- Add error logging in GitHub provider init
- Simplify error wrapping in download.go using errUtils.Build()
- Use errUtils.Build() pattern in delete.go for consistency
- Refactor store detection into helper functions in upload.go

Implementation:
- Implement actual upload/download actions in executor.go instead of
  no-op placeholders. Actions now read/write planfiles to configured
  storage backends with proper metadata.

Documentation:
- Add thread-safety documentation for regex compilation in parser.go
- Add comment about file permissions in describe_affected.go
- Add planfile subcommand documentation (upload, download, list,
  delete, show)

Testing:
- Add path traversal prevention tests for local store
- Remove obsolete tests for deleted custom helper functions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Wrap errors with static sentinels per CodeRabbit review

- Wrap file open errors in output.go with ErrCIOutputWriteFailed and
  ErrCISummaryWriteFailed sentinels
- Wrap JSON unmarshal errors in parser.go with ErrParseFile sentinel

This ensures consistent error checking using errors.Is() throughout
the codebase.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Wrap write errors with static sentinels per CodeRabbit review

- Wrap fmt.Fprintf error in WriteOutput with ErrCIOutputWriteFailed
- Wrap WriteString error in WriteSummary with ErrCISummaryWriteFailed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Regenerate golden snapshots for CI/terraform features

Update golden snapshot files to include new features added to this branch:
- ci command (CI/CD integration)
- planfile subcommand for terraform
- --ci flag for terraform plan
- planfiles configuration section

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Update ui.* calls to match new void-return API

Main branch merged #1980 which removed error returns from ui.* functions.
Updated cmd/ci/status.go and cmd/terraform/planfile/*.go to match the
new API that doesn't return values.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* [autofix.ci] apply automated fixes

* fix: Wrap CI status fetch failures with sentinel error

Address CodeRabbit feedback: Wrap provider.GetStatus errors with
ErrCIStatusFetchFailed sentinel so callers can reliably detect the
failure class, following coding guidelines for error handling.

Also fixes:
- gofumpt formatting in schema.go
- godot (comment periods) in log_utils.go

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* [autofix.ci] apply automated fixes

* Added native ci fixtures

* Added test to clarify atmos terraform planfile list works

* Added terraform planfile cmd

* Move planfile name from options to flags

* Added planfile storage on terraform plan

* Regenerate snapshots for planfile subcommand in terraform help

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Regenerate secrets-masking snapshot for planfiles and ci config sections

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix readme and tests

* Refactor ci pkg - defnine providers and plugins

* Move generic provider to separate package

* [autofix.ci] apply automated fixes

* Separate provider and plugin interfaces

* Refactor code

* Refactor

* Refactor

* Refactoring

* Added before.terraform.plan hook

* Added before.terraform.plan

* Add CI failure test case and refactor generic provider UI output

Refactor UpdateCheckRun to use consistent UI method per status (success,
error, warning) for title and summary lines. Add mock-failure component
and acceptance test verifying check run failure reporting with --ci flag.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Added error checks

* Prepare cancel check test case

* Added outputs

* Fix outputs

* Fix tests

* Fix hooks

* Fix hooks

* Force local storage usage

* Force local storage usage

* Force local storage usage

* Added debug logs

* Fix golden snapshot

* Fix golden snapshot

* Install GHA

* Fix mock component

* Fix ci summary

* Fix tests

* Fix markdown

* Fix outputs parse

* [autofix.ci] apply automated fixes

* Fix parser

* Fix warning

* [autofix.ci] apply automated fixes

* Fix templating

* Fix templating

* Macos Tests takes more the 45 minutes

* Macos Tests takes more the 45 minutes

* Fix macos longs running tests

* Fix macos atmos vendor pull

* [autofix.ci] apply automated fixes

* Added native ci fixtures

* Added test to clarify atmos terraform planfile list works

* Added terraform planfile cmd

* Move planfile name from options to flags

* Added planfile storage on terraform plan

* Regenerate snapshots for planfile subcommand in terraform help

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Regenerate secrets-masking snapshot for planfiles and ci config sections

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix readme and tests

* Refactor ci pkg - defnine providers and plugins

* Move generic provider to separate package

* Separate provider and plugin interfaces

* [autofix.ci] apply automated fixes

* Refactor code

* Refactor

* Refactor

* Refactoring

* Added before.terraform.plan hook

* Added before.terraform.plan

* Add CI failure test case and refactor generic provider UI output

Refactor UpdateCheckRun to use consistent UI method per status (success,
error, warning) for title and summary lines. Add mock-failure component
and acceptance test verifying check run failure reporting with --ci flag.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Added error checks

* Prepare cancel check test case

* Added outputs

* Fix outputs

* Fix tests

* Fix hooks

* Fix hooks

* Force local storage usage

* Force local storage usage

* Force local storage usage

* Added debug logs

* Fix golden snapshot

* Install GHA

* Fix mock component

* Fix ci summary

* Fix tests

* Fix markdown

* Fix outputs parse

* Fix parser

* [autofix.ci] apply automated fixes

* Fix warning

* Fix templating

* [autofix.ci] apply automated fixes

* Fix templating

* Macos Tests takes more the 45 minutes

* Macos Tests takes more the 45 minutes

* Fix macos longs running tests

* Fix macos atmos vendor pull

* Fix git toolchain

* Added summary output

* [autofix.ci] apply automated fixes

* Improve terraform output parse

* Change release workflow to use feature release file

* Change release workflow to use auto-release script

* Fix plugin terraform outputs

* Fix terraform summary output

* Fix no changes template

* Fix test

* Fix ci summary

* Fix summary template

* Added test

* Added failure summary

* Parse errors

* Fix test

* Fix test

* Added github upload implementation

* [autofix.ci] apply automated fixes

* Added github upload implementation

* Fix github storage

* [autofix.ci] apply automated fixes

* Fix github storage

* Added md5

* Added artifacts storage

* Update PRD

* Update PRD

* FR-6: CI-integrated stored vs fresh plan verification (#2147)

* Added artifacts storage

* Update PRD

* Update PRD

* Accept artifact storage interface

* Updated PRD

* Implement phase 2

* Added planfile storage

* Update atmos in native-ci

* Update PRD

* Update native-ci-integration PRD

* Added deceompose PRD

* Decompose PRD

* Clarify questions

* Decompose clarification

* Decompose clarification

* Decompose clarification

* Decompose clarification

* Decompose clarification

* Update implemented features

* Update implemented features

* Update implemented features

* Update implemented features

* Update implemented features

* Update implemented features

* Update implemented features

* Update implemented features

* Update implemented features

* Update implemented features

* Update implemented features

* Update implemented features

* Refactor executor-plugin

* Refactor executor-plugin

* Refactor executor-plugin

* Update PRDs

* Update PRDs

* Move checkrun storage to github implementation

* planfile storage validation PRD

* Make local get sha from git

* Added PRD to fix planfile storage metadata

* Fix planfile storage medatada

* Store planfile with lock file

* Store planfile with lock file

* Store planfile with lock file

* Added planfile artifact store multiple files

* Added planfile artifact store multiple files

* Added planfile artifact store multiple files

* Added planfile artifact store multiple files

* Planfile and artifact store integration

* Define responsibility between planfile storage, artifact storage and backend storage

* Move github and s3 storage to artifact package

* Generaliza github storage

* Generaliza github storage

* Improve planfile cli

* Update status

* Added terraform apply ci

* Update prds

* Apply terraform outputs

* Update PRds with the status

* Apply CI plan verfication step 1

* planfile download fix prd

* Fix planfile download

* Fix planfile download

* Added apply verification plan

* [autofix.ci] apply automated fixes

* Fix CI test failures: update snapshots and stderr patterns

- Add --verify-plan flag to apply help golden snapshots
- Fix CI test stderr patterns: "CI action failed" → "CI hook" to match
  actual warning output ("CI hook handler failed", "CI check run creation failed")

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Update apply planfile storage prd

* Clarify PRds

* Added apply ci integration

* [autofix.ci] apply automated fixes

* Fix tests

* fix tests

* fix tests

* Set atmos.config ci.enabled top priority

* Update PRD

* Fix auth problem

* Fix outputs

* Fix output

* Added outputs parser

* [autofix.ci] apply automated fixes

* Fix github provider detection

* Fix apply output summary

* Enrich apply summary with resource lists and per-action badges

Rewrite apply.md template to match plan.md style: CloudPosse logo,
per-action-type badges (CREATE/CHANGE/DESTROY), CAUTION block for
destroys, and resource lists by action type in diff code blocks.

Parse resource names from apply progress lines (Creating/Modifying/
Destroying) to populate CreatedResources, UpdatedResources, and
DeletedResources. Downgrade check run token errors to Debug level.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Render badges inline on a single line in plan and apply summaries

Use right-trimming (-}}) on badge template blocks so multiple badges
(CREATE/CHANGE/REPLACE/DESTROY) render on the same line instead of
each appearing on a separate line.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Show plan diffs in apply summary instead of just result line

Rework cleanApplyOutput to strip pre-plan noise and apply progress
lines while keeping the plan resource diffs, apply result, and
outputs. This gives the apply summary the same detail as the plan
summary.

Add OpenTofu marker support for plan output stripping. Use
case-insensitive regex for progress lines since terraform outputs
"Still modifying..." with lowercase after Still.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Added apply warnings

* Skip planfile storages if prirorities are empty

* Fix github statuses update

* Make CI experementatl

* [autofix.ci] apply automated fixes

* Decrease timeout for jobs in test workflow

Reduced timeout for job and acceptance tests from 60 to 45 minutes.

* Fix tests with experimental message

* Update implementation status

* Fix tests

* Update documentation

* Update documentation

* Fix links

* Fix documentation

* Fix broken links

* Update documentation

* Address documentation comments

* Address documentation comments

* Fix tests

* Create PRD for storage rename

* Rename storage

* Update website documentation

* Resolve sha based on git for github

* Fix tests

* [autofix.ci] apply automated fixes

* Rollback generate command

* Rollback generate command

* PRD for commit statuses (#2206)

* PRD for commit statuses

* Added checks based on github commit status

* Fix tests

* [autofix.ci] apply automated fixes

* Fix tests

* Fix status check url

* Fix status check url

* Update website docs

* Update website docs

* Update website docs

---------

Co-authored-by: Erik Osterman <erik@cloudposse.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Copilot AI added a commit that referenced this pull request Mar 18, 2026
…elpers file to 3 files <600 lines each

- Remove dead `varFile string` param from printAndWriteVarFiles (CodeRabbit 🔴 #1)
- Remove setupTerraformAuthCreator, reuse defaultAuthManagerCreator (CodeRabbit 🔴 #2)
- Split terraform_execute_helpers.go (786 lines) into 3 files all <600 lines (CodeRabbit 🔴 #3):
  - terraform_execute_helpers.go: auth/env/init/validation helpers (488 lines)
  - terraform_execute_helpers_args.go: arg builders (156 lines)
  - terraform_execute_helpers_exec.go: execution pipeline + workspace/TTY/cleanup (320 lines)
- Add mutual exclusion comments to buildInitSubcommandArgs + executeTerraformInitPhase (CodeRabbit 🟡 #4)
- Document buildInitArgs vs buildInitSubcommandArgs workspace/reconfigure asymmetry (CodeRabbit 🟡 #5)
- Restore 'Resolving auth config for terraform command' debug entry log (CodeRabbit 🟡 #6)
- Restore 'Stored authenticated identity for hooks' suffix in utils_auth.go (CodeRabbit 🟡 #7)
- Extract prepareComponentExecution + executeCommandPipeline from ExecuteTerraform,
  reducing cyclomatic complexity from 25 → 9 (well below the 15 target)
- Add tests: resolveExitCode (nil/ExitCodeError/generic/wrapped), buildWorkspaceSubcommandArgs
  (delete/select/no-subcommand2), buildTerraformCommandArgs (validate subcommand),
  prepareComponentExecution (no path error), executeCommandPipeline (TTY error via nil stdin)

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>
Andriy Knysh (aknysh) added a commit that referenced this pull request Mar 20, 2026
…e test coverage (#2226)

* Initial plan

* refactor: extract helpers from ExecuteTerraform (complexity 160→26) with unit tests

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>

* docs: add blog post, roadmap entry, CLAUDE.md update for ExecuteTerraform refactor

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>

* [autofix.ci] apply automated fixes

* fix: address CodeRabbit issues and improve test coverage for ExecuteTerraform helpers

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>

* fix: address all CodeRabbit issues, reduce complexity to ≤12, split helpers file to 3 files <600 lines each

- Remove dead `varFile string` param from printAndWriteVarFiles (CodeRabbit 🔴 #1)
- Remove setupTerraformAuthCreator, reuse defaultAuthManagerCreator (CodeRabbit 🔴 #2)
- Split terraform_execute_helpers.go (786 lines) into 3 files all <600 lines (CodeRabbit 🔴 #3):
  - terraform_execute_helpers.go: auth/env/init/validation helpers (488 lines)
  - terraform_execute_helpers_args.go: arg builders (156 lines)
  - terraform_execute_helpers_exec.go: execution pipeline + workspace/TTY/cleanup (320 lines)
- Add mutual exclusion comments to buildInitSubcommandArgs + executeTerraformInitPhase (CodeRabbit 🟡 #4)
- Document buildInitArgs vs buildInitSubcommandArgs workspace/reconfigure asymmetry (CodeRabbit 🟡 #5)
- Restore 'Resolving auth config for terraform command' debug entry log (CodeRabbit 🟡 #6)
- Restore 'Stored authenticated identity for hooks' suffix in utils_auth.go (CodeRabbit 🟡 #7)
- Extract prepareComponentExecution + executeCommandPipeline from ExecuteTerraform,
  reducing cyclomatic complexity from 25 → 9 (well below the 15 target)
- Add tests: resolveExitCode (nil/ExitCodeError/generic/wrapped), buildWorkspaceSubcommandArgs
  (delete/select/no-subcommand2), buildTerraformCommandArgs (validate subcommand),
  prepareComponentExecution (no path error), executeCommandPipeline (TTY error via nil stdin)

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>

* [autofix.ci] apply automated fixes

* Fix setupTerraformAuth error wrapping and document pre-hook termination behavior

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>

* Add setupTerraformAuth unit tests to fix unused import compile error

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>

* fix(tests): address CodeRabbit Pass 4 feedback — strengthen assertions, add ErrInvalidAuthConfig test, clean up empty section

- Add require.Error(t, err) to TestPrepareComponentExecution_NoComponentPath_ReturnsError
  (was coverage theater: _ = err with no assertion)
- Add defaultMergedAuthConfigGetter injectable var to setupTerraformAuth so the
  ErrInvalidAuthConfig wrap branch is testable without requiring a real MergeComponentAuthFromConfig failure
- Add TestSetupTerraformAuth_MergedConfigError_WrapsWithInvalidAuthConfig covering the
  previously-untested ErrInvalidAuthConfig wrap path (non-ErrInvalidComponent errors)
- Remove empty addRegionEnvVarForImport section placeholder from coverage test file
  (those 3 tests already exist in terraform_execute_helpers_test.go)
- Update coverage test file header to reflect the correct list of covered functions

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>

* fix(tests): address CodeRabbit Pass 5 — split oversized test files, fix misleading wsOpts comment, add wsOpts branch test, document defaultMergedAuthConfigGetter injection layers

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>

* [autofix.ci] apply automated fixes

* fix(tests): remove unused 'os' import from terraform_execute_helpers_test.go after file split

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>

* fix: audit ExecuteTerraform refactor — lint fixes, test cleanup, fix doc

Lint fixes (16 issues):
- Fix hugeParam: handleVersionSubcommand now takes pointers
- Fix unlambda: defaultMergedAuthConfigGetter uses direct function ref
- Fix filepathJoin: split "infra/networking" into separate segments
- Fix unparam: remove unused planFile from buildApplySubcommandArgs
- Fix forbidigo: add nolint for TF_WORKSPACE (Terraform convention)
- Fix nestif: extract handlePlanStatusUpload from executeMainTerraformCommand
- Fix argument-limit: add nolint for variadic opts parameter
- Fix cyclomatic: extract shouldSkipWorkspaceSetup from runWorkspaceSetup
- Fix cyclomatic: extract runPreExecutionSteps from prepareComponentExecution
- Fix cyclomatic: extract autoGenerateComponentFiles, provisionComponentSource
- Fix cyclomatic/funlen: extract logAndWriteComponentVars, logCliVarsOverrides
- Fix add-constant: add subcommandApply/Deploy/Init/Workspace, dirPermissions

Test cleanup:
- Remove 4 duplicate resolveExitCode tests from _pipeline_test.go
- Clarify tautological cleanup test comment
- Remove unused writeTestFile helper

Add fix doc documenting all audit findings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address CodeRabbit audit pass 7 — remove duplicates, add coverage

- Remove duplicate TestBuildWorkspaceSubcommandArgs_NoSubCommand2 from _pipeline_test.go
- Remove tautological cleanup tests from _args_test.go (real tests in _coverage_test.go)
- Remove redundant TestWarnOnConflictingEnvVars_NoConflictsNoError
- Add TestAssembleComponentEnvVars_NonNilTenv (tenv != nil branch coverage)
- Add TestBuildTerraformCommandArgs_Init (init switch-case dispatch)
- Add comment to generateConfigFiles re: double GenerateFilesForComponent invocation
- Document logTerraformContext tests as logging-only (not coverage theater)
- Update fix doc with all 10 audit pass 7 items and resolutions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address audit pass 8 — debug-level branch coverage, final cleanup

- Add TestPrintAndWriteVarFiles_DebugLogLevel_Success (item 8)
- Add TestPrintAndWriteVarFiles_DebugLogLevel_CliVarsSection (item 8)
- Add TestPrintAndWriteVarFiles_TraceLogLevel (item 8)
- Validate item 5: storeAutoDetectedIdentity already tested in utils_auth_test.go
  (gomock strict controller implicitly verifies GetChain not called)
- Validate item 10: generateConfigFiles comment already added in previous commit
- Update fix doc with all audit pass 8 resolutions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address audit pass 9 — explicit identity guard test, call-site comment

- Add TestStoreAutoDetectedIdentity_ExistingIdentity_NotOverwritten with
  explicit GetChain().Times(0) assertion (item 5)
- Add double-invocation comment at generateConfigFiles call site in
  runPreExecutionSteps (item 10)
- Update fix doc with pass 9 resolutions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address CodeRabbit review — error masking, empty workdir, cross-platform test

- Separate provisioning errors from "component does not exist" in
  resolveAndProvisionComponentPath — propagate original error directly
- Guard empty _workdir_path in provisionComponentSource to match
  prepareInitExecution behavior
- Replace Unix-only "false" command with cross-platform "go run" in
  TestResolveExitCode_OsExecExitError
- Remove warnOnConflictingEnvVars coverage theater tests (logging-only
  function, NotPanics assertions add no value)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: aknysh <andriy.knysh@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI added a commit that referenced this pull request Mar 22, 2026
… stacks

Critical #1: Fail closed when --stack filter finds no matching raw manifests
Critical #2: Normalize non-glob relative imports to absolute paths in buildImportGraph
High #3: Use cfg.TerraformSectionName/cfg.HelmfileSectionName in L-05
High #4: Key L-02 baseVars by '<stack>/<component>' to prevent cross-stack collisions
High #5: Add test for ATMOS_LINT_RULE env binding in cmd/lint
High #6: Build StackNameToFileIndex in LintStacks for reliable L-08 file attribution
Medium #7: Add CohesionMaxGroups to schema for configurable L-05 threshold
Medium #8: Add golden test for rulesRelNorm consistency with L-07 relNorm
Medium #9: Clarify L-03 depth semantics (node-count vs edge-count) in description
Low #12: Add ui.Error call before returning from renderLintJSON error path
Update authors.yml to fix duplicate nitrocode entry (RB, CEO @ Infralicious)

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>
Agent-Logs-Url: https://github.com/cloudposse/atmos/sessions/9708e2c0-9c09-48c8-a447-323fe5ad065d
Copilot AI added a commit that referenced this pull request Apr 2, 2026
…e $USER, tighten tests)

Finding 4: Make DisableCache unexported (closes data race)
- Rename var DisableCache to disableCache (unexported)
- Rename local var disableCache in Dir() to dcache to avoid shadowing
- Update SetDisableCache/GetDisableCache bodies accordingly
- Update all comments referencing DisableCache

Finding 3: Validate $USER in shellGetUsernameFunc before returning
- Call validateUsername() on the $USER env var value before returning it
- Fall through to whoami if $USER contains invalid characters

Finding 2: Tighten getDarwinHomeDir test assertion
- Replace if/else err check with require.NoError + assert.Equal

Finding 5: Save/restore original DisableCache in homedir_test.go
- Replace SetDisableCache(true)/defer SetDisableCache(false) with save/restore pattern
- Replace direct DisableCache = true/false with SetDisableCache throughout test file

Finding 9: Use package-level applyEnvTimeout() in TestExternalCmdTimeoutEnvOverride
- Remove local closure that duplicated package-level applyEnvTimeout()

Finding 10: Simplify stub test assertions
- Remove assert.Contains calls from TestShellGetUsernameFunc_BothFailIncludeBothStderr

Finding 6: Update README.md example with save/restore pattern

Finding 1: Update docs markdown for CI Additions
- Add test-homedir-macos job description
- Update audit table entry #5 to addressed

Finding 8: Fix darwin test
- Remove redundant assert.NotEqual (filepath.IsAbs already covers this)

External test files: replace homedir.DisableCache = with homedir.SetDisableCache()

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>
Andriy Knysh (aknysh) added a commit that referenced this pull request Apr 14, 2026
Eight live runs against a Cloud Posse-style multi-org Geodesic-hosted refarch
surfaced gaps in detection, generation, PR creation, and module-level support.
All gaps now have shipped fixes; PRD captures every run with verification.

SKILL.md
- step 2: prescribe Geodesic config-path resolution (rootfs/usr/local/etc/atmos)
  before any probe that reads atmos.yaml
- step 5: five-source account-ID resolution chain (atmos describe component →
  static catalog → repo docs grep → cross-account ARN grep → user prompt) with
  cache moved to .git/atmos-pro/account-map.json (never tracked)
- new step 5.5: detect repo vendoring convention (commit vs ondemand) and
  team_permission_sets_enabled module support; emit four module patches when the
  variable is missing from the underlying Terraform code
- step 6: baseline atmos validate stacks against main to avoid false-positive
  blocking on pre-existing repo errors; tolerate atmos-not-on-PATH outside Geodesic
- step 7: detect repo's PULL_REQUEST_TEMPLATE.md (4 standard locations); map skill
  content into the repo's section names; fall back to skill default only if absent;
  PR body file at .git/atmos-pro/pr-body.md (never tracked)
- safety rail #5: redact tokens from remote URLs (extract owner/repo only)

References (8 .md files updated)
- auth-profiles.md: multi-namespace identity prefixing rule
  (<namespace>-<tenant>-<stage>/<role>) with detection by unique-namespace count
- iam-trust-model.md: multi-namespace tfstate ARN listing pattern;
  team_permission_sets_enabled module-level support requirements with the four
  patch templates spelled out
- onboarding-playbook.md: step 4.5 (account-map resolution chain), step 4.6
  (tfstate-backend tenant detection), step 7 (PR template detection + section-name
  mapping)
- starting-conditions.md: deterministic probe package linkage
- troubleshooting.md: new entries for ls atmos.yaml on Geodesic repos, embedded
  PAT in remote URL, account-ID resolution missed accounts the README has,
  .account-map.json shows up in PR, PR body ignores PULL_REQUEST_TEMPLATE.md
- templates/README.md: customer-namespace examples sanitized to Cloud Posse
  conventions (dev/stg/prd, core/plat, 111111111111-style placeholders)
- catalog/iam-role-gha-tf.yaml.tmpl: tfstate tenant default core (was gov);
  golden snapshot regenerated
- new templates/profiles/README.md.tmpl: explainer doc for profiles/ directory;
  registered in renderer

PRD (docs/prd/atmos-pro-skill.md)
- "Lessons Learned in Production" section with each finding's root cause and
  shipped fix
- "Live Test Transcripts" section with sanitized Run 1 through Run 8 transcripts
  (customer namespaces e98d/s/p replaced with dev/stg/prd; account IDs replaced
  with 111111111111-style placeholders; owner/repo replaced with <owner>/<repo>)
- "Comparison Against Human Reference Implementation" — 10/14 artifacts matched
  on first pass; 4 gaps surfaced and fixed (vendored sources via step 5.5,
  team_permission_sets_enabled plumbing via step 5.5, profiles/README.md template,
  per-repo skill copy deferred); agent's diffs were smaller and cleaner than the
  reference for the module patches
- "Final Status Table — All Runs" — canonical Run 0-8 record with prompts,
  outcomes, and skill changes shipped per run
- "Path B End-to-End Closure" — production-ready signoff

Renderer
- pkg/ai/skills/atmospro/render.go: register profiles/README.md.tmpl in the
  template-to-output map; golden snapshot for the new file added

All Go tests pass: pkg/atmospro/detect, pkg/ai/skills (and four sub-packages).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Andriy Knysh (aknysh) added a commit that referenced this pull request May 12, 2026
…1919)

* Fix markdown code fence in Nerd Fonts installation instructions (#1917)

* Simplify Nerd Fonts installation instructions

Removed Homebrew tap and search commands from installation instructions. Cask-fonts has been deprecated.

* Fix markdown code fence formatting

The previous commit accidentally removed the opening code fence when deleting
the deprecated Homebrew tap commands.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Matt Topper <matt.topper@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andriy Knysh <aknysh@users.noreply.github.com>

* Address PR review comments for auth registry refactor

- Fix Comment #3: Parse global flags before InitCliConfig in all auth
  commands by adding BuildConfigAndStacksInfo helper to pkg/flags and
  cmd/auth/helpers.go

- Fix Comment #4: Add guard for empty selectable array in configure.go
  to prevent index out of bounds when no AWS user identities found

- Fix Comment #5: Remove duplicate IdentityFlagName constants by using
  cfg.IdentityFlagName from pkg/config/const.go as canonical source

- Remove unused schema imports from login.go, exec.go, shell.go
- Remove unnecessary nolint:gosec directives from env.go

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix NoOptDefVal preprocessing for identity flag in auth commands

The identity flag uses Cobra's NoOptDefVal feature which only works with
equals syntax (--identity=value), not space-separated syntax (--identity value).
This caused explicit identity values to be ignored, falling back to interactive
selection which fails without a TTY.

Fix by adding NoOptDefVal preprocessing in preprocessCompatibilityFlags() to
rewrite --identity value → --identity=value before Cobra parses. This ensures
explicit identity values work correctly in all environments (CI, piped output,
redirected stdin).

Fixes:
- TestInteractiveIdentitySelection/explicit_identity_value_should_work_even_with_piped_output
- TestExplicitIdentityAlwaysWorks/with_CI=true

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add documentation for --identity flag placement best practices

Document recommended usage patterns for the --identity flag:
- Use equals syntax (--identity=admin) for clarity
- Place flag before -- separator and positional arguments
- Both auth and terraform command docs updated

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Address PR review comments: constants and security annotations

1. Remove redundant constant aliases in cmd/identity_helpers.go
   - Use cfg.IdentityFlagName and cfg.IdentityFlagSelectValue directly
   - Eliminates duplicate definitions (CodeRabbit feedback)

2. Add CodeQL suppression comments in cmd/auth/env.go
   - Document intentional credential output for shell sourcing
   - Add codeql[go/clear-text-logging] annotations
   - Similar to aws configure export-credentials behavior

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add --identity flag documentation to global flags reference

Document the --identity flag in the Command-Specific Flags section:
- Available in auth, terraform, and describe commands
- Supports multiple modes: explicit value, interactive selector, disabled
- Add ATMOS_IDENTITY environment variable reference
- Include flag placement best practice tip (equals syntax recommended)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Refactor preprocessing architecture with preprocessArgs orchestrator

Separate NoOptDefVal preprocessing and compatibility flag translation into
sibling operations orchestrated by a new preprocessArgs() function.

Architecture:
- preprocessArgs() orchestrates all argument preprocessing
- preprocessNoOptDefValFlags() rewrites --flag value → --flag=value for NoOptDefVal flags
- preprocessCompatibilityFlags() separates Atmos flags from pass-through flags

Key fixes:
- Call SetArgs when NoOptDefVal changes args but no compat flags exist
- This ensures --identity value works correctly for auth commands

New pkg/flags/preprocess/ package:
- Pipeline interface for extensible preprocessing
- NoOptDefValPreprocessor with fixed hasSeparatedValue() using strings.Contains
- FlagInfo interface to avoid circular imports

Tests:
- All auth tests pass (29 tests)
- All preprocess package tests pass
- Pager tests skip gracefully when TTY unavailable

Also fixes pre-existing lint errors in:
- errors/errors.go: Add ErrComponentPathNotFound sentinel
- internal/exec/helmfile.go: Use sentinel errors instead of dynamic errors
- internal/exec/stack_processor_merge.go: Use %w instead of %v for errors
- pkg/downloader/file_downloader.go: Use %w instead of %v for errors
- internal/exec/path_utils_test.go: Use constants for paths with separators

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Address PR review comments

- cmd/auth/shell.go: Use envpkg.MergeGlobalEnv() for consistency with exec.go
  (addresses CodeRabbit comment #3 about env merging inconsistency)

- cmd/auth/whoami.go: Use %w for error wrapping to preserve error chain
  (addresses CodeRabbit comment #4 about error wrapping)

- tests/cli_describe_component_test.go: Use cross-platform TTY detection
  with term.IsTTYSupportForStdout() and close file handle properly
  (addresses CodeRabbit comments #5, #6)

- tests/describe_test.go: Add skipIfNoTTY helper with cross-platform
  TTY detection and proper file handle cleanup
  (addresses CodeRabbit comments #7, #8)

Note: Comments #1 and #2 (codeql clear-text logging) are false positives -
the atmos auth env command intentionally outputs credentials for shell
sourcing, similar to `aws configure export-credentials`. Suppression
comments are already in place.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add unit tests for cmd/auth package to improve coverage

Add 15 new test files covering pure functions and mock-based tests:
- helpers_test.go: formatDuration, displayAuthSuccess, BuildConfigAndStacksInfo
- whoami_test.go: redactHomeDir, sanitizeEnvMap, buildWhoamiTableRows, validateCredentials
- list_test.go: parseCommaSeparatedNames, filter functions, render functions
- env_test.go: outputEnvAsExport, outputEnvAsDotenv
- login_test.go: authenticateIdentity with MockAuthManager
- shell_test.go: getSeparatedArgs, viper fallback tests
- exec_test.go: getSeparatedArgsForExec, executeCommandWithEnv
- console_test.go: resolveIdentityName, retrieveCredentials, resolveConsoleDuration
- auth_test.go: AuthCommandProvider, GetIdentityFromFlags
- completion_test.go: completion functions
- validate_test.go: command structure
- identity_resolution_test.go: shared identity resolution test helper
- user/user_test.go: AuthUserCmd structure
- user/configure_test.go: command structure
- user/helpers_test.go: selectAWSUserIdentities, extractAWSUserInfo

Coverage improved from ~25.57% to ~36.2% for cmd/auth package.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix cross-platform compatibility for exec tests

- Replace Unix-specific "true" command with cross-platform "go version"
- Move "false" command test to exec_unix_test.go with build constraint
- Addresses CodeRabbit review comment about Windows compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Add tests for --profile flag in auth commands (fixes #1973)

Add tests to verify that the --profile global flag is properly extracted
into ProfilesFromArg when using auth exec and auth shell commands.

Test cases:
- Single profile (--profile dev)
- Multiple profiles (--profile dev --profile staging)
- No profile
- Profile with special characters (us-east-1/prod)
- Environment variable fallback (ATMOS_PROFILE)

These tests verify the fix for issue #1973 where --profile didn't work
with auth exec and auth shell commands.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: Reorganize terraform usage examples into distinct sections

Split the "Clean Examples" section into three distinct subsections:
- Clean Examples: terraform clean commands only
- Workspace Examples: terraform workspace commands
- Additional Flag Examples: plan commands with --/--append-user-agent flags

This improves documentation readability by grouping related commands together.

Addresses CodeRabbit review comment on PR #1919.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Regenerate auth command golden snapshots

Update snapshots for auth command refactoring:
- auth exec --help: Updated usage format and added aws CLI example
- auth invalid-command: Removed ecr-login from valid subcommands list

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Windows test failures and website build

- Make TestRedactHomeDir cross-platform using filepath.Join
- Make TestRedactHomeDirWithOsPathSeparator use consistent path construction
- Fix TestFormatExpiration flaky assertion (timing-dependent)
- Add missing File component import to terraform/usage.mdx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Add IsExperimental method to AuthCommandProvider

The CommandProvider interface now requires IsExperimental() after main
branch updates. This fixes CI build failures across Linux, macOS, and
Windows by implementing the required interface method.

Auth commands return true as they are part of Pro Features.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* [autofix.ci] apply automated fixes (attempt 3/3)

* [autofix.ci] apply automated fixes

* fix: Address CodeRabbit review comments for auth-registry-refactor

- Remove undocumented IDENTITY env var fallback (comment #10)
  Only ATMOS_IDENTITY is documented and should be used

- Make HOME path test cases OS-portable (comment #11)
  Use filepath.Join instead of hardcoded Unix paths in tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: Regenerate golden snapshots for experimental auth command

The auth command now returns IsExperimental() = true, which adds:
- [EXPERIMENTAL] tag in command listings
- Experimental feature warning message in stderr output

Regenerated all affected golden snapshots to match the new output.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Address CodeRabbit review findings in auth commands

- console.go: Use data.Writeln/ui.Writef/ui.Success/ui.Warning instead of
  fmt.Fprintf(os.Stdout/Stderr) to follow Atmos I/O conventions
- env.go: Wrap config/manager init errors with sentinel errors
  (ErrFailedToInitializeAtmosConfig, ErrFailedToInitializeAuthManager)
- exec.go: Remove duplicate os.Environ() in executeCommandWithEnv; use
  envpkg.ConvertMapToSlice since prepareAuthenticatedEnv already includes
  the full OS environment
- helpers.go: Stop scanning for --help at "--" separator so pass-through
  commands like `atmos auth exec -- terraform --help` work correctly
- logout.go: Fix misleading --all-realms flag description to accurately
  reflect keychain cleanup scope

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: Migrate auth commands from legacy u.Print* to ui/data layer and fix test failures

Replace all antiquated u.PrintfMarkdownToTUI/u.PrintfMessageToTUI calls in auth commands
with the proper ui.MarkdownMessagef/ui.Writef functions. Replace u.PrintAsJSON with
data.WriteJSON. Add missing Realm row to displayAuthSuccess output. Regenerate golden
snapshots to match corrected stderr output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(auth): port main features to refactored cmd/auth package

Backports features from main's cmd/auth_*.go that were not yet present in
HEAD's refactored cmd/auth/* tree. Each item references the upstream PR.

cmd/auth/env.go (#1984):
- Add `--format=github` for $GITHUB_ENV with heredoc multiline support.
- Add `--format=env` (lowercase env-style key=value).
- Add `-o, --output-file` flag (with $GITHUB_ENV auto-detect for github).
- Route formatting through pkg/env.Output() while keeping outputEnvAsExport
  and outputEnvAsDotenv helpers for unit-test coverage.
- Bind ATMOS_AUTH_ENV_FORMAT and ATMOS_AUTH_ENV_OUTPUT_FILE env vars.
- Extract loadAuthManagerForEnv, resolveIdentityNameForEnv, loginIfNeeded,
  resolveEnvOutputTarget, and resolveEnvOutputFile helpers to keep
  executeAuthEnvCommand within complexity and length budgets.

cmd/auth/login.go (provider fallback, #2333):
- Change authenticateIdentity signature to (whoami, needsProviderFallback,
  err). On ErrNoIdentitiesAvailable / ErrNoDefaultIdentity, return the
  fallback flag instead of wrapping; caller routes to provider auth.
- Treat ErrUserAborted as a clean abort (no ErrAuthenticationFailed wrap).
- Add getProviderForFallback / promptForProvider / isInteractive helpers
  for the auto-provision-identities first-login path.
- Wire maybeOfferProfileFallbackOnAuthConfigError around identity-flow
  errors.

cmd/auth/exec.go, cmd/auth/shell.go:
- Surface identity-resolution errors through
  maybeOfferProfileFallbackOnAuthConfigError so a stale base profile no
  longer dead-ends with `no default identity`.

Tests:
- env_test.go: add TestGitHubEnvAutoDetect (auto-detect $GITHUB_ENV +
  heredoc framing), update TestSupportedFormats to expect 5 formats.
- login_test.go: update TestAuthenticateIdentity for the new
  needsProviderFallback signal; add ErrNoIdentitiesAvailable case.
- integration_test.go (new): TestAuthEnvFormatCompletion,
  TestAuthWhoamiOutputCompletion, TestAuthCommandCompletion_FlagInheritance.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* updates

* [autocommit] formatting fixes

* test(auth): add regression tests for issues #1973 and #2392

Both issues are addressed by the cmd/auth/* registry refactor + terraform
StandardParser registration of --identity. These tests guard the contracts
so a future regression cannot reintroduce either silent flag-drop bug.

Issue #1973 (--profile global flag silently dropped on auth exec/shell):
- cmd/auth/exec_test.go::TestAuthExec_ProfileFlagAppliedToConfig
- cmd/auth/shell_test.go::TestAuthShell_ProfileFlagAppliedToConfig

  Both call BuildConfigAndStacksInfo(cmd, v) — the helper that exec.go
  and shell.go now use before cfg.InitCliConfig — and assert that the
  --profile values round-trip into ConfigAndStacksInfo.ProfilesFromArg
  for single, multiple, and absent profile cases.

Issue #2392 (--identity silently dropped on atmos terraform plan):
- internal/exec/cli_utils_test.go::TestProcessCommandLineArgs_TerraformIdentityFlag_Issue2392

  Reproduces the bug-report arg shape verbatim — `terraform plan
  account-map -s core-gbl-root --identity core-root/admin` — and asserts
  ProcessCommandLineArgs populates info.Identity = "core-root/admin".

- internal/exec/terraform_execute_helpers_auth_test.go::TestSetupTerraformAuth_IdentityFlagPropagatesToAuthCreator

  Builds a merged auth config containing both a `default: true` identity
  ("core-identity/devops") and a non-default identity ("core-root/admin")
  and asserts that setupTerraformAuth passes the explicit --identity
  value verbatim to the auth manager creator — not the profile default.
  This is the exact override that the issue described as silently
  happening at v1.216.0.

- internal/exec/terraform_execute_helpers_auth_test.go::TestSetupTerraformAuth_EmptyIdentity_AllowsAutoDetection

  Inverse guard: with no --identity flag, info.Identity is empty and the
  creator receives the empty string so pkg/auth.resolveIdentityName can
  auto-detect the profile default. Prevents an over-eager fix from
  breaking the default-identity path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* updates

* test(auth): boost cmd/auth coverage from 33% to 47%

Adds focused unit tests for the testable helpers exposed by the cmd/auth
registry refactor. Targets the lowest-coverage files flagged by Codecov:

cmd/auth/auth.go (CommandProvider getters):
- TestAuthCommandProvider_OptionalMethods covers GetPositionalArgsBuilder,
  GetCompatibilityFlags, GetAliases, IsExperimental.
- TestGetAuthCmd_ReturnsAuthCmd guards the public accessor used by cmd/ai
  to attach subcommands.

cmd/auth/env.go (env command helpers):
- TestResolveEnvOutputFile covers all four branches of the GitHub auto-
  detect: non-github pass-through, explicit output-file, $GITHUB_ENV
  detect, and the missing-GITHUB_ENV error sentinel.
- TestResolveEnvOutputTarget exercises viper-backed format/output-file
  resolution including the bash default and the github auto-detect.
- TestLoginIfNeeded covers cache-hit (no Authenticate), missing-cache
  (Authenticate triggered), ErrUserAborted unwrapping, and generic-
  error wrapping with ErrAuthenticationFailed.
- TestResolveIdentityNameForEnv covers the explicit-flag, viper-fallback,
  default-auto-detect, and __SELECT__ interactive paths.

cmd/auth/console.go (browser isolation helpers):
- TestConsoleSessionDir asserts the deterministic XDG path is stable
  across calls, diverges by identity, and diverges by realm.
- TestResolveConsoleIsolated covers default false, auth.console.isolated
  config honoured, flag overrides config in both directions.
- TestPrintConsoleHelpers smoke-covers printConsoleURL and printConsoleInfo
  with full + showURL=true paths.
- TestRetrieveCredentials_NoCredentialsAvailable covers the
  ErrAuthConsole sentinel for the no-credentials-anywhere branch.

cmd/auth/login.go (provider-fallback helpers):
- TestGetProviderForFallback covers ErrNoProvidersAvailable for empty
  list, single-provider auto-select (no prompt), and multi-provider
  non-interactive ErrNoDefaultProvider.
- TestIsInteractive guards determinism (same env → same answer).

cmd/auth/whoami.go (whoami helpers):
- TestAddGCPReauthExplanation covers nil pass-through, unrelated-error
  pass-through, invalid_grant alone (no enrichment), and invalid_grant
  + invalid_rapt enrichment with gcloud reauth hint.
- TestPrintWhoamiJSON_RedactsCredentials guards the contract that the
  JSON output never mutates the caller's Environment map.
- TestPrintWhoamiHuman covers valid/invalid/no-expiration table render.

cmd/auth/list.go (list command helpers):
- TestParseFilterFlags covers the default, --providers (with comma
  list), --identities (with comma list), and the mutually-exclusive
  ErrMutuallyExclusiveFlags branch.
- TestRenderOutput_InvalidFormatErrors guards the default-case
  ErrInvalidFlag path.
- TestListFlagCompletions_NoConfig covers the no-atmos.yaml early-return
  path of listProvidersFlagCompletion / listIdentitiesFlagCompletion.

cmd/auth/logout.go (new logout_test.go):
- TestBuildKeychainDeletionMessage covers the pure prompt formatter.
- TestConfirmKeychainDeletion_ForceShortCircuit covers --force bypass.
- TestConfirmKeychainDeletion_NonTTYWithoutForceErrors covers the
  ErrKeychainDeletionRequiresConfirmation branch.
- TestDetectExternalCredentials covers GCP/Azure/AWS env-var detection.
- TestBuildLogoutOptions covers the empty-config, identities+providers,
  and provider-cascade-label branches.
- TestExecuteLogoutOption_InvalidType covers ErrInvalidLogoutOption.
- TestDiscoverRealms covers missing dir (no error), no-provider-subdir
  filter, and aws/azure realm reporting.

cmd/auth/completion.go (completion helpers):
- TestIdentityFlagCompletion covers the no-atmos.yaml branch.
- TestAddIdentityCompletion_NoFlag covers the no-flag-registered no-op.

cmd/auth/user/helpers.go (form-builder helper):
- TestBuildCredentialFormField covers all six branches: YAML-managed
  Note, DefaultValue pre-fill, password mode, optional, custom
  ValidateFunc wired, description message wired.

Infra:
- New testmain_test.go initialises pkg/data and pkg/ui formatters once
  for the package so tests that exercise printWhoamiJSON/printWhoamiHuman
  don't panic with "data.InitWriter() must be called".
- Snapshot tests/snapshots/TestCLICommands_atmos_auth_validate_--verbose
  picks up an env-dependent debug line drop (gh CLI not authenticated).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style: apply gofumpt v0.10 multiline call wrapping

CI's pre-commit hook installs `gofumpt@latest` which is now v0.10.0.
That release tightened the multiline-call rule: when arguments span
multiple lines, the function name + opening paren go on their own
line and the closing paren goes on its own line as well. Local toolchain
was on v0.9.1 which didn't enforce this, so the changes only surfaced
on CI.

Files affected (only PR-touched files reformatted):

- cmd/auth/env.go: env.Output(...) call.
- cmd/describe_dependents.go: getRunnableDescribeDependentsCmd(...) call.
- cmd/describe_stacks.go: PersistentFlags().StringP(...) call.

No behaviour change. Matches the auto-fix diff produced by the
cloudposse/github-action-pre-commit job.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(auth): boost cmd/auth coverage from 47% to 69%

Adds smoke and branch-coverage tests across the auth command tree to lift
patch coverage from the post-merge baseline (47.8%) to ~69%.

Orchestrator smoke tests (no-atmos.yaml tempdir, no-panic contract):
- TestExecuteAuthLoginCommand_SmokeNoConfig
- TestExecuteAuthWhoamiCommand_SmokeNoConfig
- TestExecuteAuthListCommand_SmokeNoConfig
- TestExecuteAuthValidateCommand_SmokeNoConfig
- TestExecuteAuthConsoleCommand_SmokeNoConfig
- TestExecuteAuthEnvCommand_SmokeNoConfig
- TestExecuteAuthExecCommand_SmokeNoConfig
- TestExecuteAuthShellCommand_SmokeNoConfig
- TestExecuteAuthLogoutCommand_SmokeNoConfig
- TestExecuteAuthUserConfigureCommand_SmokeNoConfig (cmd/auth/user)

These cover the config-load error wrap path in each orchestrator and
guard against panics for invalid setup. Where a specific error sentinel
is documented (e.g. ErrInvalidAuthConfig, ErrFailedToInitializeAtmosConfig,
ErrAuthConsole), the test asserts the wrap when an error surfaces.

loadAuthManager* helpers (config init + auth manager init):
- TestLoadAuthManager_SmokeFromEmptyTempDir (whoami)
- TestLoadAuthManagerForEnv_SmokeFromEmptyTempDir (env)
- TestLoadAuthManagerForList_SmokeFromEmptyTempDir (list)
- TestInitializeAuthManager_SmokeFromEmptyTempDir (console)
- TestSuggestProfilesForAuth_NoProfilesReturnsNil

prepareShellEnvironment (cmd/auth/shell.go) — mocked-AuthManager test
covering cache-hit, fresh-auth-success, ErrUserAborted, generic-error
wrap with ErrAuthenticationFailed, PrepareShellEnvironment error, and
atmosConfig.Env propagation through MergeGlobalEnv:
- TestPrepareShellEnvironment (six subtests)

prepareAuthenticatedEnv (cmd/auth/exec.go) — smoke from empty tempdir:
- TestPrepareAuthenticatedEnv_SmokeNoConfig

Display + handleBrowserOpen helpers (smoke):
- TestDisplayExternalCredentialWarnings (with-warnings + clean branch)
- TestDisplayBrowserWarning (first-call + cached-skip branches)
- TestHandleBrowserOpen (skipOpen=true, nil opener, success, error)

Logout perform helpers — mocked AuthManager branch coverage:
- TestPerformIdentityLogout_NotFound (ErrIdentityNotInConfig)
- TestPerformIdentityLogout_DryRun (no Logout call)
- TestPerformProviderLogout_NotFound (missing provider in config)
- TestPerformLogoutAll_DryRun (no LogoutAll call)
- TestPerformLogoutAll_Success (happy path, two identities)

renderOutput dispatcher coverage:
- TestRenderOutput_AllValidFormats covers all 9 valid format branches
  (table/tree/json/yaml/graphviz/dot/mermaid/markdown/md).

Coverage summary:
- cmd/auth: 47.6% → 69.7%
- cmd/auth/user: 51.0% → 58.7%
- combined: 47.8% → 68.9%

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(auth): address review comments and push coverage from 47% to 78%

Addresses CodeRabbit review comments and substantially increases test
coverage of the cmd/auth package using a shared mock-auth fixture.

Review fixes:
- cmd/auth/completion.go, cmd/auth/list.go: all five shell-completion
  helpers now honour --base-path, --config, --config-path, and --profile
  by routing through BuildConfigAndStacksInfo(cmd, v) instead of using
  an empty ConfigAndStacksInfo{}.
- cmd/auth/console.go: --print-only now propagates the data.Writeln
  write error so broken-pipe / stdout failures exit non-zero. The
  empty-identity branch of resolveIdentityName now uses multi-%w so
  ErrNoDefaultIdentity stays in the chain for the profile-fallback
  dispatcher.
- cmd/auth/exec.go: prepareAuthenticatedEnv now returns []string
  directly (was []string → map → []string round-trip) so environment
  ordering is preserved and Windows drive-scoped vars (=C:=...) don't
  collide on the empty key.
- cmd/auth/shell.go: fail fast when positional args are not preceded
  by `--` (`atmos auth shell bash` previously silently dropped "bash").
- cmd/auth/logout.go: add cobra.MaximumNArgs(1) so extra positional
  args are rejected up front.
- cmd/auth/validate.go: wrap config-load failure with the static
  ErrFailedToInitializeAtmosConfig sentinel.
- cmd/auth/login.go: introduce isInteractiveFn package var so
  getProviderForFallback tests can force the non-interactive branch
  deterministically.
- cmd/auth/markdown/*.md: every opening fence now has the `shell`
  language identifier (MD040). The `$ ` prefix on commands is kept
  for consistency with the rest of cmd/markdown/.
- cmd/auth/user/configure.go: switch user-facing messages from
  fmt.Fprintf(cmd.ErrOrStderr()) to ui.Writef / ui.Writeln per the
  I/O layer convention.
- cmd/identity_helpers.go: add the missing perf.Track in
  CreateAuthManagerFromIdentityWithStackScan to match its sibling
  helpers.

Coverage improvements (cmd/auth 47.6% → 79.3%; combined 47.8% → 77.8%):

New shared helpers (helpers_test.go):
- setupMockAuthFixture(t): writes a minimal atmos.yaml wired to the
  mock/aws provider and isolates keyring + XDG env to a tempdir, used
  by 9 deep-coverage tests to exercise the full orchestrator pipeline
  without touching the host's credential store.
- runProfileFlagAppliedRegressionTest(t, commandName): shared
  table-driven driver for the issue #1973 regression so the
  exec_test.go and shell_test.go wrappers feed the same cases through
  one body (and dupl-lint stays clean).
- newTestCommandWithGlobalParser: parser-returning variant of the
  global-flags helper so regression tests can drive the real
  Cobra → Viper binding path (cmd.ParseFlags → BindFlagsToViper).

End-to-end orchestrator tests against the mock fixture:
- TestExecuteAuthEnvCommand_WithMockAuth
- TestExecuteAuthLoginCommand_WithMockAuth
- TestExecuteAuthListCommand_WithMockAuth / _JSONFormat
- TestExecuteAuthValidateCommand_WithMockAuth
- TestExecuteAuthWhoamiCommand_WithMockAuth
- TestExecuteAuthConsoleCommand_WithMockAuth (covers
  ErrProviderNotSupported for mock/aws)
- TestExecuteAuthLogoutCommand_WithMockAuthDryRun
- TestPrepareAuthenticatedEnv_WithMockAuth (asserts AWS_PROFILE +
  AWS_REGION injection)
- TestExecuteAuthExecCommand_NoCommand (ErrNoCommandSpecified guard)

Logout perform-helper branch coverage:
- TestPerformIdentityLogout_Success / _PartialLogout / _LogoutError
- TestPerformProviderLogout_Success / _DryRun
- TestExecuteLogoutOption_DispatchAll / _DispatchIdentity / _DispatchProvider
- TestPerformInteractiveLogout_NoIdentities (empty-identities branch)
- TestPerformLogoutAllRealms_NoRealms / _DryRun / _RealRemove

Pure / smoke helpers:
- TestRetrieveCredentials_InlineCredentials (success path)
- TestPromptForProvider_EmptyList (ErrNoProvidersAvailable guard)
- TestExecuteCommandWithEnv_NonZeroExit (errUtils.ExitCodeError
  propagation via the test-binary subprocess pattern)
- TestExecuteCommandWithEnv_WithValidCommand rewritten to use
  os.Executable() + _ATMOS_AUTH_TEST_EXIT_OK=1 (cross-platform,
  no PATH dependency on `go` / `true` / `false`).
- Subprocess env-flag handlers added to TestMain.

Test infrastructure:
- TestAuthExec_ProfileFlagAppliedToConfig and the shell equivalent
  now use --profile=devops style CLI args + ParseFlags +
  BindFlagsToViper, exercising the full production binding chain
  rather than seeding viper directly.
- Identity-resolution shared test table gains a "flag takes
  precedence over env" case so the precedence rule (flags > env >
  default) is regression-covered for both auth shell and auth exec.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(auth): address review comments — fence repair, helpers, sentinel

Addresses six CodeRabbit review comments from the latest batch:

1. cmd/auth/console_test.go — drop tautological constant tests.
   TestConsoleLabelWidth and TestConsoleOutputFormat just asserted that
   a literal equals itself. The constants are exported but only used
   internally; not part of an external API contract.

2. cmd/auth/console_test.go — fragile test-name dispatch.
   TestResolveConsoleDuration's "invalid provider duration format" case
   keyed its assertion off tt.name. Renaming the case would silently
   skip the error check. Added an explicit `expectParseError bool`
   field; switch case now keys off that.

3. cmd/auth/exec_test.go — single-case table replaced.
   TestGetSeparatedArgsForExec was a one-case table that duplicated the
   sibling TestGetSeparatedArgsForExec_EmptyCommand. Rewrote with five
   meaningful cases (no separator, positional-without-sep, separator+
   single command, separator+command+args, separator-only). Deleted the
   now-redundant sibling test.

4. cmd/auth/env_test.go — safe stdout-capture helper.
   Five sites used the same fragile capture pattern: if require.NoError
   aborted before restoration, os.Stdout stayed redirected and the read
   end of os.Pipe was never closed. Added captureStdout(t) helper in
   helpers_test.go that registers t.Cleanup to guarantee restoration
   and close both pipe ends even when intervening assertions abort.
   All five sites now use `read := captureStdout(t)` / `output := read()`.

5. cmd/auth/env_test.go — replace hardcoded Unix paths with t.TempDir().
   Three paths (/tmp/out.sh, /explicit/path, /path/to/.env) replaced
   with filepath.Join(t.TempDir(), ...) so the tests don't bake in a
   Unix separator.

6. cmd/auth/markdown/atmos_auth_console_usage.md +
   cmd/auth/markdown/atmos_auth_logout_usage.md — fix malformed
   closers. An earlier awk script that added the shell language
   identifier to opening fences had a state-machine flaw on files that
   already mixed labeled/unlabeled fences; six closing fences across
   two files were rewritten as ```shell instead of plain ```. Repaired
   to keep the rest of the doc rendering correctly. Audited all four
   auth markdown files; the other two were already correctly paired.

7. cmd/auth/logout_test.go + sibling _WithMockAuth tests — add a
   cmd-state isolation helper. Tests that mutate package-level
   auth*Cmd via ParseFlags could leak flag.Changed / flag values to
   subsequent tests. cmd.NewTestKit isn't reachable from cmd/auth
   without a circular import, so added a local equivalent
   resetAuthCmdFlags(t, cmd) that snapshots and restores every flag's
   (Value, Changed) pair via t.Cleanup. Applied to all 8 tests that
   ParseFlags a shared cmd: TestExecuteAuthLogoutCommand_SmokeNoConfig
   and _WithMockAuthDryRun (the two reviewer-flagged sites), plus
   _WithMockAuth variants for console, env, exec
   (TestPrepareAuthenticatedEnv_WithMockAuth + TestExecuteAuthExecCommand_NoCommand),
   list (tree + JSON), login, validate, whoami.

8. cmd/auth/shell.go — tighten the pre-dash arg check and fix the hint.
   The previous check only caught the no-separator case; `atmos auth
   shell bash -- -lc env` had ArgsLenAtDash() == 1 and slipped through
   while getSeparatedArgs silently dropped "bash". Condition is now
   `dashIndex == -1 || dashIndex > 0` so positional args appearing
   before "--" are also rejected. The error message no longer suggests
   `-- bash` (which would just feed "bash" as the first arg to the
   default shell) — it points at `--shell` for the shell-binary
   override and "--" only for the shell args.
   Extracted into validateAuthShellArgs to keep executeAuthShellCommand
   under the 60-line revive limit. Added TestValidateAuthShellArgs with
   5 subtests covering the three acceptable and two rejected arg
   shapes plus the ErrInvalidArguments sentinel contract.

9. cmd/auth/shell.go + cmd/auth/exec.go — wrap PrepareShellEnvironment
   failures with a static sentinel. Both helpers had a raw
   fmt.Errorf("failed to prepare ...: %w", err) that didn't satisfy the
   repo-wide "All errors MUST be wrapped using static errors defined in
   errors/errors.go" rule. Added new sentinel
   errUtils.ErrPrepareShellEnvironment and applied to both call sites.
   Updated TestPrepareShellEnvironment to assert the sentinel is in the
   chain (errors.Is) plus the original underlying error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(auth): apply resetAuthCmdFlags across all smoke tests for state isolation

Add `resetAuthCmdFlags(t, cmd)` to every test that uses a package-level
`auth*Cmd` so flag/Changed state cannot leak across tests under shuffled
runs. This is the in-package equivalent of `cmd.NewTestKit(t)` —
`cmd/auth` cannot import `cmd` (cmd/root.go blank-imports cmd/auth) and
`NewTestKit` is `_test.go`-scoped, so the local helper enforces the same
auto-cleanup contract via t.Cleanup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Matt Topper <matt.topper@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andriy Knysh <aknysh@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: aknysh <andriy.knysh@gmail.com>
Co-authored-by: atmos-pro[bot] <atmos-pro[bot]@users.noreply.github.com>
Andriy Knysh (aknysh) added a commit that referenced this pull request May 25, 2026
* feat: implement remote stack imports

Add support for importing stack configurations from remote URLs using go-getter.
Stack imports now work consistently with remote atmos.yaml imports.

## What Changed

- New pkg/stack/imports package with URL detection and remote downloading
- Stack imports detect remote URLs (HTTP, Git, S3, GCS) and download via go-getter
- Integration with stack_processor_utils.go for unified import handling
- New sentinel errors for remote import failures
- Comprehensive unit tests with mock HTTP server
- Integration tests verifying end-to-end functionality
- Complete example demonstrating local and remote imports
- Blog post announcing the feature and roadmap update

## Architecture

- pkg/stack/imports/uri.go: URL detection functions (IsLocalPath, IsGitURI, IsHTTPURI, IsS3URI, IsGCSURI)
- pkg/stack/imports/remote.go: Remote downloading with caching
- pkg/stack/imports/imports.go: Main ProcessImportPath entry point
- stack_processor_utils.go: Updated to use remote import logic

## Testing

All 60+ unit tests pass:
- URL detection for local vs remote paths
- Remote imports from mock HTTP server
- Graceful handling of missing remotes with skip_if_missing
- End-to-end integration tests

Closes #2036

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: extract generic cache infrastructure into pkg/cache

Extract the robust file-based caching infrastructure from pkg/config into
a reusable pkg/cache package. This includes:

- pkg/cache/filelock.go: Platform-agnostic FileLock interface
- pkg/cache/filelock_unix.go: Unix flock implementation with retries
- pkg/cache/filelock_windows.go: Windows graceful degradation
- pkg/cache/file_cache.go: Generic FileCache with atomic writes and locking

Update pkg/config/cache.go to use the new pkg/cache.FileLock interface.

Update pkg/stack/imports/remote.go to properly use FileCache.GetOrFetch()
for thread-safe caching with atomic writes, instead of bypassing the
cache's locking mechanism.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address PR feedback for remote stack imports

- Fix isDomainLikeURI incorrectly flagging version paths (e.g., configs/v1.0/base)
- Preserve file extension in cached filenames for proper template processing
- Use errors.Is() for sentinel error assertions in tests
- Use httptest mock server for skip_if_missing test instead of real network
- Add PR 2037 link to roadmap milestone
- Clarify go-getter URL format coverage in blog post

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: ignore kubernetes.io and runatlantis.io in link checker

These sites block automated requests but URLs are manually verified as valid:
- https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/
- https://www.runatlantis.io/docs/pre-workflow-hooks.html

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address PR review comments for remote imports

- Add periods to example comments in uri.go for godot lint compliance
- Use errors.Is() with sentinel error in TestRemoteImporter_Download_NotFound
- Change assert.Error to require.Error for proper test flow

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: ensure cache directory exists after options applied

When WithBaseDir is used to specify a custom cache path, the directory
might not exist. This adds directory creation after options are applied
to handle custom paths correctly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: ignore cache read errors on Windows

On Windows, file locking is a no-op for graceful degradation. Cache read
errors from corrupted files should also be silently ignored so they don't
block normal operation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: improve coverage for cache and stack imports packages

Add comprehensive tests to reach 80%+ coverage threshold:
- pkg/stack/imports: Test ResolveImportPaths function (35% → 86%)
- pkg/cache: Add filelock_unix tests and file_cache edge cases (64% → 86%)
- pkg/config: Test cache edge cases (64% → 87%)
- internal/exec: Test ProcessImportSection edge cases (79% → 80%)

Fix bugs discovered during testing:
- file_cache.go: Create lock after options applied so WithBaseDir works
- cache.go: Return empty CacheConfig consistently on Windows read errors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: handle deleted cache directory in Clear() method

Add early return in Clear() when the cache directory doesn't exist,
avoiding lock acquisition errors when the directory was deleted
externally.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address CodeRabbit review comments

- Use filepath.Join for OS-safe test paths (Comments #1, #6)
- Route FileCache operations through injected FileSystem interface (Comment #2)
- Add ErrCacheFetch sentinel and wrap fetch() errors (Comment #3)
- Fix misleading "log" comment in GetOrFetch (Comment #4)
- Add missing BrowserSessionWarningShown assertion (Comment #5)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: persist BrowserSessionWarningShown in cache

Add missing browser_session_warning_shown field to SaveCache and
UpdateCache data maps so the field is properly persisted to disk.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: preserve lock file during cache Clear() and improve test coverage

Fix a bug where FileCache.Clear() would delete the lock file (cache.lock)
while walking the cache directory, breaking mutual exclusion for concurrent
processes. Add lockFilePath field to FileCache and skip it during Clear().

Improve test coverage across cache, imports, and config packages:
- pkg/cache: 72%/70% -> 91.7% (lock error paths, retry exhaustion, fallback)
- pkg/stack/imports: 85%/89% -> 95.7% (memory cache invalidation, URI helpers)
- pkg/config: 72% -> 86.8% (corrupted file handling, docstring for CacheConfig)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: data race on downloadCount and improve test coverage

Use atomic.Int32 for downloadCount in TestRemoteImporter_Download_MemoryCacheInvalidation
to fix race between httptest handler goroutine and test goroutine.

Add test coverage for error paths:
- FileCache.Get() with non-NotExist read errors
- FileCache.Set() with write errors on read-only directory
- FileCache.Clear() with file removal errors
- IsGitURI() with malformed URL containing invalid escape sequence

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: clarify ignored cache write errors

* chore: retrigger ci

* fix: stabilize vendor acceptance test

* fix: harden import and cache path handling

* fix: preserve template cache extensions

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andriy Knysh <aknysh@users.noreply.github.com>
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.

2 participants