Skip to content

feat: Add file-browser plugin for examples directory#1969

Merged
aknysh merged 10 commits intomainfrom
osterman/examples-file-browser
Jan 16, 2026
Merged

feat: Add file-browser plugin for examples directory#1969
aknysh merged 10 commits intomainfrom
osterman/examples-file-browser

Conversation

@osterman
Copy link
Copy Markdown
Member

@osterman osterman commented Jan 15, 2026

what

  • Add Docusaurus plugin to scan /examples/ directory and generate crawlable routes for all files
  • Create React components for GitHub-style file browser with sidebar navigation
  • Support syntax highlighting for code files and markdown rendering for documentation
  • Generate "View on GitHub" links for each file
  • Fix duplicate breadcrumbs, table border radius clipping, and content width inconsistencies

why

Provides users a way to explore example projects directly on the site with full-text search via Algolia. Makes examples more discoverable and improves the documentation experience by showing code examples alongside guides.

references

Implements the file browser for the /examples/ directory as a reusable Docusaurus plugin that can be used for other documentation browsing needs.

Summary by CodeRabbit

  • New Features

    • Added a GitHub-style file browser to the docs with breadcrumb navigation, sidebar tree, file viewer, and "View on GitHub" links.
    • Added an "Examples" item to the site navbar.
  • Documentation

    • Added comprehensive README guides for many example projects (Atlantis, Component Versions, Context, Helmfile, Schemas, Stacks, Vendoring, Workflows, Quick Start).
  • Style

    • Improved syntax highlighting and YAML code styling site-wide.

✏️ Tip: You can customize this high-level summary in your review settings.

Create a Docusaurus plugin and React components for browsing example projects:
- Plugin scans /examples/ directory and generates routes for all files
- FileTree component provides GitHub-style sidebar navigation
- FileViewer renders code with syntax highlighting and markdown
- BreadcrumbNav shows current path
- Supports searching files via Algolia by making each file crawlable

Fixes duplicate breadcrumb display, table border radius clipping, and content width inconsistencies.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@osterman osterman requested a review from a team as a code owner January 15, 2026 00:57
@github-actions github-actions bot added the size/xl Extra large size PR label Jan 15, 2026
@mergify
Copy link
Copy Markdown

mergify bot commented Jan 15, 2026

Warning

This PR exceeds the recommended limit of 1,000 lines.

Large PRs are difficult to review and may be rejected due to their size.

Please verify that this PR does not address multiple issues.
Consider refactoring it into smaller, more focused PRs to facilitate a smoother review process.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 15, 2026

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

  • website/package.json
  • website/pnpm-lock.yaml

- Change grid column from `1fr` to `minmax(0, 1fr)` to prevent content from expanding column
- Add overflow-x: auto to mainContent and markdownContent
- Ensures consistent width regardless of file content

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 15, 2026

Caution

Review failed

The head commit changed during the review from 2354a14 to 1307838.

📝 Walkthrough

Walkthrough

Adds an examples file browser feature and nine new example README files; introduces a Docusaurus plugin that indexes example projects, generates data modules, and new React/TypeScript components, types, utilities, styles, and small website config/dependency updates.

Changes

Cohort / File(s) Summary
Example documentation
examples/demo-atlantis/README.md, examples/demo-component-versions/README.md, examples/demo-context/README.md, examples/demo-helmfile/README.md, examples/demo-schemas/README.md, examples/demo-stacks/README.md, examples/demo-vendoring/README.md, examples/demo-workflows/README.md, examples/quick-start-simple/README.md
Nine new README files describing example projects, usage steps, key files, and try-it snippets.
Docusaurus config & deps
website/docusaurus.config.js, website/package.json
Added file-browser plugin configuration and /examples navbar item; extended Prism languages; added react-markdown and remark-gfm dependencies.
File browser plugin
website/plugins/file-browser/index.js
New plugin that scans sourceDir, builds an examples tree (metadata, README extraction, atmos.yaml detection), computes GitHub URLs, writes data modules, and registers index/directory/file routes.
FileBrowser components & types
website/src/components/FileBrowser/* (IndexPage, DirectoryPage, FilePage, FileTree, FileTreeNode, BreadcrumbNav, DirectoryListing, FileViewer, SourceLink, index.tsx, types.ts, utils.ts)
New React/TS components, types, and utilities for index, directory and file pages, sidebar tree, breadcrumbs, listing, file viewer (markdown, code, binary), icons, traversal helpers, and a public barrel export.
Styles & CSS
website/src/components/FileBrowser/styles.module.css, website/src/css/custom.css
New FileBrowser CSS module (responsive, dark mode, interactive states) and Prism YAML highlight tweaks in custom.css.

Sequence Diagram

sequenceDiagram
    participant Builder as Docusaurus Build
    participant Plugin as FileBrowser Plugin
    participant FS as File System
    participant Data as Generated Data Modules
    participant Router as Docusaurus Router
    participant UI as React FileBrowser Components
    participant User as Site Visitor

    Builder->>Plugin: loadContent()
    Plugin->>FS: scan sourceDir (examples)
    FS-->>Plugin: file/directory tree + file contents (size-limited)
    Plugin->>Plugin: extract metadata (README desc, tags, atmos.yaml), compute github URLs, hash paths
    Plugin->>Data: write tree & options data modules
    Builder->>Plugin: contentLoaded()
    Plugin->>Router: register index, directory, and file routes
    User->>Router: GET /examples
    Router->>UI: render IndexPage (uses data modules)
    User->>UI: click example -> Router navigates to DirectoryPage
    Router->>UI: render DirectoryPage (FileTree + DirectoryListing + optional README)
    User->>UI: click file -> Router navigates to FilePage
    Router->>UI: render FilePage (FileViewer: markdown/code/binary handling)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

no-release

Suggested reviewers

  • aknysh
  • kevcube
  • Gowiem
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 73.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a file-browser plugin for the examples directory. It directly reflects the core objective and primary deliverable of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch osterman/examples-file-browser

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 15, 2026

Caution

Review failed

The head commit changed during the review from b427544 to 36321a7.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch osterman/examples-file-browser

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.50%. Comparing base (806f2e1) to head (1307838).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1969      +/-   ##
==========================================
- Coverage   74.51%   74.50%   -0.01%     
==========================================
  Files         777      777              
  Lines       71044    71044              
==========================================
- Hits        52936    52933       -3     
- Misses      14638    14646       +8     
+ Partials     3470     3465       -5     
Flag Coverage Δ
unittests 74.50% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.
see 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

osterman and others added 2 commits January 15, 2026 08:59
Part 1: UI improvements
- Replace dated table with clean file list (no SIZE column)
- Simplify DirectoryListing component

Part 2: Taxonomy and filtering
- Add 5 categories: Quickstart, Stacks, Components, Automation, DX
- Add filter buttons to index page
- Replace useless badges with category badges

Part 3: Example READMEs
- Add READMEs to 8 examples that were missing them
- Expand demo-context README from placeholder
- Each README has direct capability statement and doc links

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tags allow examples to have multiple classifications while categories
would be mutually exclusive. This change:
- Rename CATEGORY_MAP to TAGS_MAP (arrays instead of strings)
- Update types: category -> tags, categories -> tags
- Update IndexPage filter logic to check tags.includes()
- Update CSS: categoryBadge -> tagBadge with tagList wrapper

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@examples/demo-vendoring/README.md`:
- Around line 1-35: The README contains three broken vendoring
links—`https://atmos.tools/core-concepts/vendoring/`,
`https://atmos.tools/core-concepts/vendoring/vendor-manifest/`, and
`https://atmos.tools/core-concepts/vendoring/#sources`—so update those three
URLs in the README to point to valid documentation endpoints (or remove the
links if the docs don’t exist yet); specifically edit the README.md lines
containing the "Learn more about [Vendoring]...", the "Vendor manifest" link,
and the "vendor sources" link to use the correct, existing doc paths (or plain
text) and then verify each link opens correctly in a browser.
♻️ Duplicate comments (1)
website/plugins/file-browser/index.js (1)

83-92: Glob pattern matching doesn't escape backslash characters.

The regex conversion doesn't escape \ in the input path or pattern. On Windows or with patterns containing literal backslashes, this can cause incorrect matching or regex syntax errors.

🔧 Suggested fix
 function matchesPattern(filePath, pattern) {
   // Convert glob pattern to regex.
+  // Escape special regex characters except * which we handle specially.
   const regexPattern = pattern
+    .replace(/\\/g, '\\\\')           // Escape backslashes first
+    .replace(/[.+?^${}()|[\]]/g, '\\$&') // Escape other regex special chars
     .replace(/\*\*/g, '{{GLOBSTAR}}')
     .replace(/\*/g, '[^/]*')
     .replace(/{{GLOBSTAR}}/g, '.*')
     .replace(/\//g, '\\/');
-  const regex = new RegExp(`^${regexPattern}$`);
+  
+  // Also escape the file path for comparison
+  const escapedPath = filePath.replace(/\\/g, '/');
+  const regex = new RegExp(`^${regexPattern}$`);
-  return regex.test(filePath);
+  return regex.test(escapedPath);
 }
🧹 Nitpick comments (8)
website/src/components/FileBrowser/styles.module.css (2)

303-312: Consider using CSS variables for accent colors.

Hardcoded values like #1e5bb8 and #538ce9 appear throughout. Using var(--ifm-color-primary) and its variants would improve maintainability if brand colors change.

That said, this is a minor consistency nit—functional as-is.


74-100: Consider adding focus states for keyboard accessibility.

Interactive elements like .filterButton, .fileTreeLink, and .breadcrumbLink have hover styles but no explicit :focus or :focus-visible styles. Adding them ensures keyboard users get visual feedback.

.filterButton:focus-visible {
  outline: 2px solid var(--ifm-color-primary);
  outline-offset: 2px;
}
website/src/components/FileBrowser/utils.ts (2)

91-97: Minor edge case in formatFileSize.

Works well for typical files. Two edge cases to consider:

  1. Negative bytes would produce NaN (unlikely but possible with corrupted data)
  2. Files ≥1TB would cause array index overflow

Probably fine for this use case—file browser won't encounter TB files.

Defensive enhancement
 export function formatFileSize(bytes: number): string {
+  if (bytes < 0) return '0 B';
   if (bytes === 0) return '0 B';
-  const units = ['B', 'KB', 'MB', 'GB'];
+  const units = ['B', 'KB', 'MB', 'GB', 'TB'];
   const i = Math.floor(Math.log(bytes) / Math.log(1024));
-  const size = bytes / Math.pow(1024, i);
+  const clampedIndex = Math.min(i, units.length - 1);
+  const size = bytes / Math.pow(1024, clampedIndex);
-  return `${size.toFixed(i > 0 ? 1 : 0)} ${units[i]}`;
+  return `${size.toFixed(clampedIndex > 0 ? 1 : 0)} ${units[clampedIndex]}`;
 }

148-162: getBreadcrumbParts is unused—either refactor BreadcrumbNav to use it or remove it.

getBreadcrumbParts is defined in utils.ts but has no callers. BreadcrumbNav.tsx does similar path splitting and path-building inline (line 19, 28). Consolidate this logic: either refactor BreadcrumbNav to use the utility function, or remove getBreadcrumbParts if it's not needed elsewhere.

website/src/components/FileBrowser/BreadcrumbNav.tsx (1)

21-44: Consider aria attributes for accessibility.

The semantic <nav> element is good. Adding aria-label="Breadcrumb" and aria-current="page" on the current item improves screen reader navigation.

Accessibility enhancement
   return (
-    <nav className={styles.breadcrumb}>
+    <nav className={styles.breadcrumb} aria-label="Breadcrumb">
       <Link to={routeBasePath} className={styles.breadcrumbLink}>
         {rootLabel}
       </Link>
       {parts.map((part, index) => {
         const isLast = index === parts.length - 1;
         const partPath = `${routeBasePath}/${parts.slice(0, index + 1).join('/')}`;

         return (
           <React.Fragment key={partPath}>
             <span className={styles.breadcrumbSeparator}>/</span>
             {isLast ? (
-              <span className={styles.breadcrumbCurrent}>{part}</span>
+              <span className={styles.breadcrumbCurrent} aria-current="page">{part}</span>
             ) : (
               <Link to={partPath} className={styles.breadcrumbLink}>
                 {part}
               </Link>
             )}
           </React.Fragment>
         );
       })}
     </nav>
   );
website/src/components/FileBrowser/IndexPage.tsx (1)

35-51: Consider aria-pressed for filter toggles.

The filter buttons work well functionally. For better screen reader support, consider adding aria-pressed={activeTag === null} on the "All" button and aria-pressed={activeTag === tag} on the tag buttons.

♿ Optional accessibility improvement
          <button
            type="button"
            className={`${styles.filterButton} ${activeTag === null ? styles.filterButtonActive : ''}`}
            onClick={() => setActiveTag(null)}
+           aria-pressed={activeTag === null}
          >
            All
          </button>
          {tags.map((tag) => (
            <button
              key={tag}
              type="button"
              className={`${styles.filterButton} ${activeTag === tag ? styles.filterButtonActive : ''}`}
              onClick={() => setActiveTag(tag)}
+             aria-pressed={activeTag === tag}
            >
              {tag}
            </button>
          ))}
website/src/components/FileBrowser/FileViewer.tsx (1)

80-92: Inline code detection may misclassify code blocks without a language.

The check const isInline = !match assumes that any code without a language-* class is inline. Fenced code blocks without a language specifier (e.g., triple backticks with no lang) will also lack this class, causing them to render as inline <code> instead of a block.

Consider checking the node prop's structure or whether the content contains newlines for better discrimination.

♻️ Suggested approach
-              code({ className, children, ...props }) {
+              code({ className, children, node, ...props }) {
                 const match = /language-(\w+)/.exec(className || '');
-                const isInline = !match;
+                // Check if parent is 'pre' to determine block vs inline
+                const isInline = node?.position == null || 
+                  (typeof children === 'string' && !children.includes('\n') && !match);
                 return isInline ? (

Alternatively, use the pre component to wrap code blocks and keep the code component for inline only.

website/src/components/FileBrowser/FileTreeNode.tsx (1)

27-29: Directory open state won't update when currentPath changes.

shouldBeOpen is only evaluated at initial render. If a user navigates (changing currentPath), ancestor directories won't auto-expand to reveal the new active file. Consider using useEffect to sync state or making it derived.

♻️ Suggested fix
+import React, { useState, useEffect } from 'react';
+
 export default function FileTreeNode({
   node,
   routeBasePath,
   currentPath,
   depth = 0,
   defaultOpen = false,
 }: FileTreeNodeProps): JSX.Element {
-  // Determine if this directory should be open by default.
   const shouldBeOpen = defaultOpen || currentPath.startsWith(node.path);
   const [isOpen, setIsOpen] = useState(shouldBeOpen);
+
+  // Sync open state when navigation changes
+  useEffect(() => {
+    if (currentPath.startsWith(node.path)) {
+      setIsOpen(true);
+    }
+  }, [currentPath, node.path]);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c61842e and cce0a9e.

⛔ Files ignored due to path filters (1)
  • website/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (25)
  • examples/demo-atlantis/README.md
  • examples/demo-component-versions/README.md
  • examples/demo-context/README.md
  • examples/demo-helmfile/README.md
  • examples/demo-schemas/README.md
  • examples/demo-stacks/README.md
  • examples/demo-vendoring/README.md
  • examples/demo-workflows/README.md
  • examples/quick-start-simple/README.md
  • website/docusaurus.config.js
  • website/package.json
  • website/plugins/file-browser/index.js
  • website/src/components/FileBrowser/BreadcrumbNav.tsx
  • website/src/components/FileBrowser/DirectoryListing.tsx
  • website/src/components/FileBrowser/DirectoryPage.tsx
  • website/src/components/FileBrowser/FilePage.tsx
  • website/src/components/FileBrowser/FileTree.tsx
  • website/src/components/FileBrowser/FileTreeNode.tsx
  • website/src/components/FileBrowser/FileViewer.tsx
  • website/src/components/FileBrowser/IndexPage.tsx
  • website/src/components/FileBrowser/SourceLink.tsx
  • website/src/components/FileBrowser/index.tsx
  • website/src/components/FileBrowser/styles.module.css
  • website/src/components/FileBrowser/types.ts
  • website/src/components/FileBrowser/utils.ts
🧰 Additional context used
📓 Path-based instructions (1)
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/src/components/FileBrowser/BreadcrumbNav.tsx
  • website/src/components/FileBrowser/DirectoryPage.tsx
  • website/package.json
  • website/src/components/FileBrowser/FileViewer.tsx
  • website/src/components/FileBrowser/FilePage.tsx
  • website/src/components/FileBrowser/IndexPage.tsx
  • website/src/components/FileBrowser/index.tsx
  • website/docusaurus.config.js
  • website/src/components/FileBrowser/DirectoryListing.tsx
  • website/src/components/FileBrowser/FileTree.tsx
  • website/src/components/FileBrowser/styles.module.css
  • website/src/components/FileBrowser/FileTreeNode.tsx
  • website/src/components/FileBrowser/utils.ts
  • website/src/components/FileBrowser/types.ts
  • website/src/components/FileBrowser/SourceLink.tsx
  • website/plugins/file-browser/index.js
🧠 Learnings (22)
📓 Common learnings
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to website/** : Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to website/** : Update website documentation in the `website/` directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
📚 Learning: 2025-09-10T21:17:55.273Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/http_client_test.go:3-10
Timestamp: 2025-09-10T21:17:55.273Z
Learning: In the cloudposse/atmos repository, imports should never be changed as per samtholiya's coding guidelines.

Applied to files:

  • examples/demo-workflows/README.md
  • examples/quick-start-simple/README.md
📚 Learning: 2025-01-25T03:51:57.689Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.

Applied to files:

  • examples/demo-workflows/README.md
  • examples/quick-start-simple/README.md
📚 Learning: 2024-12-01T00:33:20.298Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml:28-32
Timestamp: 2024-12-01T00:33:20.298Z
Learning: In `examples/tests/stacks/catalog/terraform/template-functions-test2/defaults.yaml`, `!exec atmos terraform output` is used in examples to demonstrate its usage, even though `!terraform.output` is the recommended approach according to the documentation.

Applied to files:

  • examples/demo-workflows/README.md
  • examples/demo-stacks/README.md
  • examples/demo-atlantis/README.md
  • examples/quick-start-simple/README.md
📚 Learning: 2026-01-09T04:49:35.038Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1907
File: demos/fixtures/acme/stacks/catalog/api.yaml:1-29
Timestamp: 2026-01-09T04:49:35.038Z
Learning: In the cloudposse/atmos demos/fixtures, components can provide Terraform outputs via `remote_state_backend.static` configuration blocks instead of traditional Terraform output blocks. This pattern is used for demo/fixture purposes to simulate cross-component state references without deploying actual infrastructure. The `!terraform.state` YAML function reads from these static backends.

Applied to files:

  • examples/demo-workflows/README.md
  • examples/demo-vendoring/README.md
  • examples/demo-component-versions/README.md
  • examples/demo-context/README.md
  • examples/demo-atlantis/README.md
  • examples/quick-start-simple/README.md
📚 Learning: 2024-10-31T01:22:09.586Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 737
File: examples/demo-vendoring/vendor.d/vendor1.yaml:10-11
Timestamp: 2024-10-31T01:22:09.586Z
Learning: In `examples/demo-vendoring/vendor.d/vendor1.yaml`, when specifying the source for the `ipinfo` component, it's acceptable to use `main` as the version reference if pinning to a specific version is not practical.

Applied to files:

  • examples/demo-vendoring/README.md
  • examples/demo-component-versions/README.md
📚 Learning: 2024-10-20T00:57:53.500Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 731
File: internal/exec/validate_stacks.go:0-0
Timestamp: 2024-10-20T00:57:53.500Z
Learning: In `internal/exec/validate_stacks.go`, when downloading the Atmos JSON Schema file to the temp directory, the temporary file is overwritten each time, so explicit removal is not necessary.

Applied to files:

  • examples/demo-schemas/README.md
📚 Learning: 2025-01-08T19:01:56.978Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 899
File: examples/tests/test-vendor/vendor.yaml:39-43
Timestamp: 2025-01-08T19:01:56.978Z
Learning: In example code and test fixtures, using 'latest' version tag is acceptable as it's for demonstration purposes only. This is different from production code where specific version pinning is recommended.

Applied to files:

  • examples/demo-component-versions/README.md
📚 Learning: 2024-12-12T15:15:46.457Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:7-7
Timestamp: 2024-12-12T15:15:46.457Z
Learning: In example configuration files, such as `examples/demo-atmos-cli-imports/atmos.yaml`, it's acceptable to use `refs/heads/main` in remote URLs.

Applied to files:

  • examples/demo-component-versions/README.md
📚 Learning: 2024-11-23T00:13:22.004Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 801
File: examples/quick-start-advanced/Dockerfile:9-9
Timestamp: 2024-11-23T00:13:22.004Z
Learning: When updating the `ATMOS_VERSION` in Dockerfiles, the team prefers to pin to the next future version when the PR merges, even if the version is not yet released.

Applied to files:

  • examples/demo-component-versions/README.md
📚 Learning: 2025-12-24T04:29:23.938Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1891
File: pkg/ci/terraform/templates/apply.md:17-17
Timestamp: 2025-12-24T04:29:23.938Z
Learning: In the cloudposse/atmos repository, Terraform CI templates (pkg/ci/terraform/templates/*.md) are rendered using TerraformTemplateContext (defined in pkg/ci/terraform/context.go), not the base ci.TemplateContext. TerraformTemplateContext provides top-level fields: .Resources (ci.ResourceCounts), .HasChanges() method, and .HasDestroy field, which are correctly accessed directly in templates without a .Result prefix.

Applied to files:

  • examples/demo-context/README.md
📚 Learning: 2024-12-12T15:17:45.245Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos.d/atmos.d/tools/helmfile.yml:10-10
Timestamp: 2024-12-12T15:17:45.245Z
Learning: In `examples/demo-atmos.d/atmos.d/tools/helmfile.yml`, when suggesting changes to `kubeconfig_path`, ensure that the values use valid Go template syntax.

Applied to files:

  • examples/demo-context/README.md
  • examples/demo-helmfile/README.md
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to README.md : Update README.md with new commands and features

Applied to files:

  • examples/demo-atlantis/README.md
📚 Learning: 2025-09-30T00:36:22.219Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-09-30T00:36:22.219Z
Learning: In the Atmos website project using docusaurus-plugin-llms, the postbuild script intentionally copies llms.txt and llms-full.txt from build/ to static/ (reverse of typical Docusaurus flow). This is necessary because: (1) the plugin hardcodes output to build/ directory, (2) files must be in static/ for deployment and dev mode access, (3) the plugin doesn't support configuring output directory. The files are source-controlled in static/ and regenerated on each build.

Applied to files:

  • website/docusaurus.config.js
  • website/plugins/file-browser/index.js
📚 Learning: 2025-01-08T19:01:32.938Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 899
File: examples/tests/test-vendor/test-components/main.tf:1-7
Timestamp: 2025-01-08T19:01:32.938Z
Learning: In the examples/tests directory of the atmos project, code examples are intentionally kept minimal and simple to facilitate understanding. Avoid suggesting additional complexity or validations that might make the examples harder to follow.

Applied to files:

  • examples/quick-start-simple/README.md
📚 Learning: 2025-01-19T15:49:15.593Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 955
File: tests/snapshots/TestCLICommands_atmos_validate_editorconfig_--help.stdout.golden:0-0
Timestamp: 2025-01-19T15:49:15.593Z
Learning: In future commits, the help text for Atmos CLI commands should be limited to only show component and stack parameters for commands that actually use them. This applies to the example usage section in command help text.

Applied to files:

  • examples/quick-start-simple/README.md
📚 Learning: 2024-11-25T17:17:15.703Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 797
File: pkg/list/atmos.yaml:213-214
Timestamp: 2024-11-25T17:17:15.703Z
Learning: The file `pkg/list/atmos.yaml` is primarily intended for testing purposes.

Applied to files:

  • examples/quick-start-simple/README.md
📚 Learning: 2025-11-01T20:24:29.557Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1714
File: NOTICE:0-0
Timestamp: 2025-11-01T20:24:29.557Z
Learning: In the cloudposse/atmos repository, the NOTICE file is programmatically generated and should not be manually edited. Issues with dependency license URLs in NOTICE will be resolved when upstream package metadata is corrected.

Applied to files:

  • examples/quick-start-simple/README.md
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • examples/quick-start-simple/README.md
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.

Applied to files:

  • examples/quick-start-simple/README.md
📚 Learning: 2025-02-18T13:13:11.497Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: tests/snapshots/TestCLICommands_atmos_terraform_help.stdout.golden:59-64
Timestamp: 2025-02-18T13:13:11.497Z
Learning: For Atmos CLI help text, angle brackets in command examples and flag descriptions should be escaped using HTML entities (e.g., `&lt;component&gt;`) rather than converted to backticks or other markdown formatting.

Applied to files:

  • website/plugins/file-browser/index.js
📚 Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.

Applied to files:

  • examples/demo-helmfile/README.md
🧬 Code graph analysis (5)
website/src/components/FileBrowser/BreadcrumbNav.tsx (2)
website/plugins/file-browser/index.js (1)
  • path (8-8)
website/docusaurus.config.js (1)
  • path (8-8)
website/src/components/FileBrowser/DirectoryPage.tsx (6)
website/src/components/FileBrowser/types.ts (3)
  • ExamplesTree (55-61)
  • FileBrowserOptions (66-73)
  • DirectoryNode (23-32)
website/src/components/FileBrowser/utils.ts (2)
  • getExampleNameFromPath (140-143)
  • findExampleByName (130-135)
website/src/components/FileBrowser/FileTree.tsx (1)
  • FileTree (16-44)
website/src/components/FileBrowser/BreadcrumbNav.tsx (1)
  • BreadcrumbNav (14-45)
website/src/components/FileBrowser/FileViewer.tsx (1)
  • FileViewer (16-119)
website/src/components/FileBrowser/DirectoryListing.tsx (1)
  • DirectoryListing (16-52)
website/src/components/FileBrowser/DirectoryListing.tsx (2)
website/src/components/FileBrowser/types.ts (2)
  • DirectoryNode (23-32)
  • TreeNode (37-37)
website/src/components/FileBrowser/utils.ts (1)
  • getFileIcon (47-86)
website/src/components/FileBrowser/FileTree.tsx (2)
website/src/components/FileBrowser/types.ts (1)
  • ExampleProject (42-50)
website/src/components/FileBrowser/FileTreeNode.tsx (1)
  • FileTreeNode (20-81)
website/src/components/FileBrowser/utils.ts (1)
website/src/components/FileBrowser/types.ts (4)
  • TreeNode (37-37)
  • FileNode (8-18)
  • DirectoryNode (23-32)
  • ExampleProject (42-50)
🪛 GitHub Check: CodeQL
website/plugins/file-browser/index.js

[failure] 85-89: Incomplete string escaping or encoding
This does not escape backslash characters in the input.

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Summary
🔇 Additional comments (39)
examples/demo-atlantis/README.md (1)

1-30: Clear and well-structured.

Follows the consistent pattern across example READMEs. Links to relevant documentation, practical commands, and a useful Key Files table. Good alignment with the broader documentation goals.

examples/demo-context/README.md (1)

1-34: Good documentation.

Structure is consistent with other example READMEs. Commands effectively demonstrate context resolution capabilities.

examples/demo-workflows/README.md (1)

1-30: Well done.

Concise, actionable. Commands are straightforward and the Key Files table captures the essentials.

examples/demo-stacks/README.md (1)

1-32: Excellent example documentation.

Clearly demonstrates the inheritance pattern. The side-by-side comparison commands (-s dev vs -s prod) help users understand configuration merging.

website/package.json (1)

54-54: Good addition.

Dependency placement is correct alphabetically between react-image-gallery and react-player. Version specifier ^10.1.0 aligns with the project's pattern and is the latest release.

examples/demo-helmfile/README.md (1)

1-38: Example clearly demonstrates Helmfile workflow with Atmos.

The documentation walks through local k3s setup and stack inheritance properly. Custom commands referenced in the Key Files section are indeed defined in atmos.yaml, and the file structure is consistent with the example's intent.

examples/demo-schemas/README.md (1)

1-33: Documentation covers schema validation approaches well.

The examples effectively demonstrate the three schema source types with clear file mappings. All referenced documentation links are live and current.

examples/quick-start-simple/README.md (1)

1-35: Solid entry-level example.

The README clearly introduces Atmos basics with appropriate simplicity. The command progression (list → describe → plan) guides newcomers logically, and the documented directory structure matches the actual example implementation perfectly.

examples/demo-component-versions/README.md (1)

1-33: Documentation structure is solid.

The README follows a clear pattern with good explanations and practical examples. The commands and file references are consistent with Atmos conventions. All documentation links resolve correctly to their respective sections on vendoring, versioning, and YAML anchors.

website/src/components/FileBrowser/styles.module.css (2)

6-15: Solid grid layout foundation.

The minmax(0, 1fr) pattern correctly prevents content overflow from breaking the grid layout. Good choice for handling variable-width content like code blocks.


240-246: Good responsive handling for the sidebar.

Switching from sticky to relative positioning on smaller screens prevents layout issues. Well done.

website/src/components/FileBrowser/utils.ts (4)

47-86: Clean icon resolution logic.

The layered approach—special files first, then extension-based—is intuitive. Type assertion on line 52 is safe given the preceding directory check.


113-125: Straightforward recursive tree search.

Clean implementation. O(n) complexity is appropriate for typical example project sizes.


175-196: SVG classified as binary.

SVG files are text-based XML. Including them here prevents text preview. If intentional (avoiding raw markup display), consider a comment. If not, SVG could be rendered with syntax highlighting.


210-234: Tree counting utilities look good.

Recursive implementations are clean and handle the DirectoryNode structure correctly.

website/src/components/FileBrowser/DirectoryPage.tsx (3)

29-40: Good fallback for missing examples.

Defensive check prevents crashes when an example can't be resolved. The not-found UI is clear.


42-44: Smart page title derivation.

The conditional logic gives meaningful titles for both root and nested directories. Good for SEO and tab identification.


46-68: Well-composed page structure.

Components are logically ordered: sidebar, breadcrumb, optional README, then directory contents. Props flow correctly.

website/src/components/FileBrowser/SourceLink.tsx (1)

15-28: Clean external link component.

Proper security attributes (noopener noreferrer), clear visual indicators with GitHub and external-link icons. Simple and effective.

website/src/components/FileBrowser/BreadcrumbNav.tsx (1)

14-19: Path handling is solid.

filter(Boolean) correctly handles leading/trailing slashes and empty segments. Empty paths gracefully render just the root link.

website/src/components/FileBrowser/FileTree.tsx (1)

16-43: Clean component structure.

The component is well-organized. One consideration: if example.root.children is ever undefined (e.g., malformed data), the .map() call on Line 32 would throw. Given ExampleProject.root is typed as DirectoryNode with required children: TreeNode[], this should be safe—but a defensive check could add resilience.

website/src/components/FileBrowser/FilePage.tsx (1)

19-57: Solid composition with good error handling.

The not-found case is handled gracefully. The component cleanly wires together FileTree, BreadcrumbNav, and FileViewer. Layout title is descriptive.

website/docusaurus.config.js (2)

463-467: Navbar entry added.

Route matches the plugin's routeBasePath. Placement alongside other main nav items is appropriate.


373-385: Plugin wired correctly.

Config looks good. The sourceDir: '../examples' relative path and routeBasePath: '/examples' align with the navbar item. GitHub integration params are consistent with the repo structure. Plugin file exists at the expected location.

website/src/components/FileBrowser/IndexPage.tsx (1)

54-79: Card grid implementation looks good.

Clean mapping over filtered examples. Fallback description handles missing data gracefully. Keys are stable.

website/src/components/FileBrowser/DirectoryListing.tsx (1)

16-51: Well-structured with proper empty state handling.

The component handles both empty and populated directories cleanly. Icons are context-aware via getFileIcon.

Minor note: the explicit TreeNode type annotation on Line 36 is redundant since TypeScript infers it from directory.children, but it doesn't hurt readability.

website/src/components/FileBrowser/FileViewer.tsx (3)

16-40: LGTM on binary file handling.

Clean early return pattern. The GitHub link is shown twice (header + message body), which is helpful UX for binary files.


42-63: LGTM on missing content handling.

Correctly handles large files by showing size and GitHub link. Consistent with the binary file pattern.


102-118: LGTM on code file rendering.

Uses CodeBlock with showLineNumbers, which is good for code files. Language is pulled from the file node.

website/src/components/FileBrowser/index.tsx (1)

1-18: LGTM.

Clean barrel export consolidating the FileBrowser public API. Good organization.

website/src/components/FileBrowser/FileTreeNode.tsx (2)

35-47: LGTM on file node rendering.

Clean Link usage with active state styling.


51-79: LGTM on directory node rendering.

Good use of aria-expanded for accessibility. Recursive rendering is straightforward.

website/plugins/file-browser/index.js (4)

237-261: Unclosed frontmatter could cause unexpected behavior.

If a README starts with --- but has no closing ---, endIndex will be -1 and the entire content is preserved. That's fine, but a file with --- at position 0 and another --- much later (not frontmatter) could incorrectly strip content.

This is an edge case and current behavior is reasonable - just worth noting.


151-230: LGTM on scanDirectory.

Handles file/directory iteration, exclusions, size limits, and README detection cleanly. Synchronous reads are fine for build-time.


368-417: LGTM on plugin structure and loadContent.

Good defaults, proper source directory validation, and clean data return structure.


419-494: LGTM on contentLoaded route generation.

Routes are generated for index, directories, and files. Data modules are properly wired.

website/src/components/FileBrowser/types.ts (3)

8-18: LGTM on FileNode interface.

Clean definition with appropriate nullability for content and githubUrl.


23-32: LGTM on DirectoryNode interface.

Good use of recursive type via TreeNode[] for children.


75-87: LGTM on type guards.

Clean discriminated union narrowing. These will be useful throughout the codebase.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

- Add YAML, JSON, TOML, Go, Python, Docker to Prism languages
- Add YAML token styling (atrule, scalar) for proper highlighting
- Add remark-gfm for GitHub Flavored Markdown tables in READMEs
- Add markdown rendering for card descriptions (inline code support)
- Fix dockerfile → docker language mapping for Prism

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@website/plugins/file-browser/index.js`:
- Around line 83-92: The glob-to-regex conversion in matchesPattern fails to
escape regex metacharacters (e.g., '.'), so patterns like **/.DS_Store will
match incorrectly; fix matchesPattern by first escaping all regex-special
characters in the incoming pattern (characters like . ^ $ + ? () [] {} | \ etc.)
before performing the glob replacements, then apply the existing replacements
for ** and * and escape slashes as done now, and finally build the RegExp from
the safely-escaped regexPattern.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cce0a9e and 836bb21.

⛔ Files ignored due to path filters (1)
  • website/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • website/docusaurus.config.js
  • website/package.json
  • website/plugins/file-browser/index.js
  • website/src/components/FileBrowser/FileViewer.tsx
  • website/src/components/FileBrowser/IndexPage.tsx
  • website/src/components/FileBrowser/styles.module.css
  • website/src/css/custom.css
🚧 Files skipped from review as they are similar to previous changes (3)
  • website/package.json
  • website/src/components/FileBrowser/styles.module.css
  • website/docusaurus.config.js
🧰 Additional context used
📓 Path-based instructions (1)
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/src/css/custom.css
  • website/src/components/FileBrowser/FileViewer.tsx
  • website/plugins/file-browser/index.js
  • website/src/components/FileBrowser/IndexPage.tsx
🧠 Learnings (3)
📓 Common learnings
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:37.766Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.
📚 Learning: 2025-09-30T00:36:22.219Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-09-30T00:36:22.219Z
Learning: In the Atmos website project using docusaurus-plugin-llms, the postbuild script intentionally copies llms.txt and llms-full.txt from build/ to static/ (reverse of typical Docusaurus flow). This is necessary because: (1) the plugin hardcodes output to build/ directory, (2) files must be in static/ for deployment and dev mode access, (3) the plugin doesn't support configuring output directory. The files are source-controlled in static/ and regenerated on each build.

Applied to files:

  • website/plugins/file-browser/index.js
📚 Learning: 2025-02-18T13:13:11.497Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: tests/snapshots/TestCLICommands_atmos_terraform_help.stdout.golden:59-64
Timestamp: 2025-02-18T13:13:11.497Z
Learning: For Atmos CLI help text, angle brackets in command examples and flag descriptions should be escaped using HTML entities (e.g., `&lt;component&gt;`) rather than converted to backticks or other markdown formatting.

Applied to files:

  • website/plugins/file-browser/index.js
🧬 Code graph analysis (2)
website/src/components/FileBrowser/FileViewer.tsx (3)
website/src/components/FileBrowser/types.ts (1)
  • FileNode (8-18)
website/src/components/FileBrowser/utils.ts (3)
  • isBinaryFile (175-196)
  • formatFileSize (91-97)
  • isMarkdownFile (167-170)
website/src/components/FileBrowser/SourceLink.tsx (1)
  • SourceLink (15-28)
website/src/components/FileBrowser/IndexPage.tsx (3)
website/plugins/file-browser/index.js (5)
  • children (155-155)
  • examples (271-271)
  • description (256-256)
  • description (284-284)
  • tags (309-309)
website/src/components/FileBrowser/types.ts (2)
  • ExamplesTree (55-61)
  • FileBrowserOptions (66-73)
website/plugins/docusaurus-plugin-llms-txt/src/index.js (1)
  • title (84-84)
🪛 GitHub Check: CodeQL
website/plugins/file-browser/index.js

[failure] 85-89: Incomplete string escaping or encoding
This does not escape backslash characters in the input.

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
🔇 Additional comments (9)
website/src/css/custom.css (1)

1020-1036: YAML syntax highlighting additions look solid.

Good coverage for atrule (keys), scalar (values), and punctuation tokens. The dual selectors provide necessary fallback for different Prism rendering contexts. Colors align well with the nightOwl theme.

website/plugins/file-browser/index.js (4)

151-230: Directory scanning logic is well-structured.

Good bounds checking with maxFileSize, proper error handling for binary/unreadable files, and sensible sorting (directories first). Synchronous I/O is fine for build-time execution.


237-261: Description extraction handles frontmatter and headers correctly.

Clean approach to finding the first meaningful paragraph while skipping YAML frontmatter and markdown headers.


368-417: Plugin initialization and content loading are well-designed.

Sensible defaults, graceful handling of missing source directory, and clean data flow to contentLoaded. The 100KB default for maxFileSize is appropriate.


419-494: Route generation is thorough and correct.

Good use of hashed paths for data file uniqueness. The route structure properly covers the index page, directory pages, and individual file pages.

website/src/components/FileBrowser/IndexPage.tsx (2)

17-22: Smart handling of nested link prevention.

Rendering markdown links as plain text and stripping paragraph wrappers prevents invalid nested <a> tags since the entire card is already a Link. Good thinking.


29-96: IndexPage component is well-implemented.

Clean state management for tag filtering, proper key usage throughout, and accessible button elements with explicit type="button". The layout and filtering logic are solid.

website/src/components/FileBrowser/FileViewer.tsx (2)

82-94: Inline code detection heuristic is pragmatic but has a minor edge case.

Code blocks without a language specifier (triple backticks with no language) will render as inline <code> since there's no language-* class. This is a common react-markdown pattern and usually acceptable, but worth noting.


17-121: FileViewer handles all content types cleanly.

Good layered approach: binary files → missing content → markdown → code. The conditional GitHub links and size formatting provide a consistent UX across all file types.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

- Fix regex injection vulnerability in matchesPattern by escaping special
  characters before converting glob patterns to regex
- Fix broken vendoring documentation links in demo-vendoring README
  (paths moved from /core-concepts/vendoring/ to /vendor/)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@website/plugins/file-browser/index.js`:
- Around line 92-103: In matchesPattern, the glob-to-regex substitutions run
before the escaping step which ends up escaping the placeholder braces and
breaking excludes; fix by performing the regex-escape first, then convert glob
tokens: first run the escape replace (the /[.+?^${}()|[\\]\\]/g replacement) on
pattern, then replace ** and * with placeholders ({{GLOBSTAR}} / {{STAR}}) and
finally replace those placeholders with the regex fragments (' .* ' and '[^/]*')
and escape slashes; update the order of the .replace calls around the
placeholders in matchesPattern so placeholders are created after escaping.
🧹 Nitpick comments (1)
website/plugins/file-browser/index.js (1)

81-83: Unused function — consider removing or using it.

escapeRegex is defined but never called. The same pattern appears inline at line 97. Either use this function there for consistency or remove it to avoid dead code.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 836bb21 and ab34f93.

📒 Files selected for processing (2)
  • examples/demo-vendoring/README.md
  • website/plugins/file-browser/index.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/demo-vendoring/README.md
🧰 Additional context used
📓 Path-based instructions (1)
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/plugins/file-browser/index.js
🧠 Learnings (5)
📓 Common learnings
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:37.766Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to website/** : Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases
📚 Learning: 2025-09-30T00:36:22.219Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-09-30T00:36:22.219Z
Learning: In the Atmos website project using docusaurus-plugin-llms, the postbuild script intentionally copies llms.txt and llms-full.txt from build/ to static/ (reverse of typical Docusaurus flow). This is necessary because: (1) the plugin hardcodes output to build/ directory, (2) files must be in static/ for deployment and dev mode access, (3) the plugin doesn't support configuring output directory. The files are source-controlled in static/ and regenerated on each build.

Applied to files:

  • website/plugins/file-browser/index.js
📚 Learning: 2025-02-18T13:13:11.497Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: tests/snapshots/TestCLICommands_atmos_terraform_help.stdout.golden:59-64
Timestamp: 2025-02-18T13:13:11.497Z
Learning: For Atmos CLI help text, angle brackets in command examples and flag descriptions should be escaped using HTML entities (e.g., `&lt;component&gt;`) rather than converted to backticks or other markdown formatting.

Applied to files:

  • website/plugins/file-browser/index.js
📚 Learning: 2025-04-10T21:33:06.447Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1147
File: pkg/filematch/filematch.go:32-32
Timestamp: 2025-04-10T21:33:06.447Z
Learning: The replacement of "*/*" with an empty string in recursive glob patterns (containing "**") is intentional behavior in the filematch package, as confirmed by the developer. This is necessary for proper handling of recursive directory matching when using the gobwas/glob library.

Applied to files:

  • website/plugins/file-browser/index.js
📚 Learning: 2025-04-10T21:33:06.447Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1147
File: pkg/filematch/filematch.go:32-32
Timestamp: 2025-04-10T21:33:06.447Z
Learning: The replacement of "*/*" with an empty string in recursive glob patterns (containing "**") is intentional behavior in the filematch package, as confirmed by the developer.

Applied to files:

  • website/plugins/file-browser/index.js
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Summary
🔇 Additional comments (6)
website/plugins/file-browser/index.js (6)

11-74: LGTM on configuration constants.

Good coverage of exclude patterns and language mappings. The tag categories provide sensible groupings for discovery.


115-153: Helper functions look solid.

hashPath with MD5 is appropriate for unique filename generation (non-cryptographic). generateGitHubUrl gracefully handles missing repo config.


162-241: Solid recursive scanning implementation.

Sync operations are fine for build-time. The try-catch for binary files is appropriate. Sorting directories-first matches typical file browser UX.


248-329: Description extraction and example scanning look good.

Frontmatter stripping is handled correctly. Tag ordering in tagOrder provides predictable display order.


337-377: Collection utilities are clean.

Recursive traversal with spread is idiomatic. Root path edge case handled correctly at line 366.


379-512: Plugin lifecycle implementation is well-structured.

Graceful handling of missing source directory. Route generation with hashed data files is clean. getPathsToWatch enables proper dev mode hot reloading.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

- Add EmbedExample component to embed examples in documentation pages
- Add RelatedDocs component to show related docs on example pages
- Add DOCS_MAP for mapping examples to their documentation pages
- Show RelatedDocs on all file and directory pages within examples
- Embed examples in vendor, workflows, validation, atlantis, and quick-start docs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@mergify
Copy link
Copy Markdown

mergify bot commented Jan 15, 2026

💥 This pull request now has conflicts. Could you fix it @osterman? 🙏

@mergify mergify bot added the conflict This PR has conflicts label Jan 15, 2026
…e-browser

# Conflicts:
#	website/docs/workflows/workflows.mdx
The matchesPattern function was escaping regex metacharacters after
creating placeholders, which caused the placeholder braces to be
escaped. This broke all exclude patterns (e.g., **/.DS_Store,
**/node_modules/**) because the placeholders couldn't be found
for replacement.

Fix by escaping metacharacters first, then converting glob syntax.
The * character is not in the escape list, so it survives escaping
and can be properly converted to regex patterns afterward.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@osterman osterman added the no-release Do not create a new release (wait for additional code changes) label Jan 15, 2026
- Move EmbedExample imports to top of MDX files (7 files)
- Fix duplicate "integrations" sidebar by moving integrations.mdx
  to integrations/index.mdx and updating _category_.json
- Fix empty file message: show "File is empty" instead of
  "File too large to preview" for 0-byte files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 15, 2026
@aknysh aknysh merged commit c5d0f3b into main Jan 16, 2026
57 checks passed
@aknysh aknysh deleted the osterman/examples-file-browser branch January 16, 2026 00:44
@github-actions
Copy link
Copy Markdown

These changes were released in v1.204.1-rc.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-release Do not create a new release (wait for additional code changes) size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants