Skip to content

Dev --> Prod#133

Merged
bharathk08 merged 3 commits into
mainfrom
dev
May 21, 2026
Merged

Dev --> Prod#133
bharathk08 merged 3 commits into
mainfrom
dev

Conversation

@sainath-testsigma
Copy link
Copy Markdown
Contributor

@sainath-testsigma sainath-testsigma commented May 19, 2026

Feat: Add LLM friendly docs

Summary by CodeRabbit

  • New Features

    • Added "Copy page" menu with options to copy markdown content to clipboard, open in a new tab, and share with ChatGPT, Claude, and Perplexity
    • Documentation pages now expose markdown format links for accessibility
  • Chores

    • Configured S3 to properly serve markdown files with correct content type

Review Change Stack

sainath-testsigma and others added 3 commits May 18, 2026 14:55
Emit per-page <slug>.md companions, an llms.txt index, and a hand-authored
home .md for /docs/test-management/ during gatsby build. Add
<link rel="alternate" type="text/markdown"> to every page's head, configure
S3 Content-Type for .md, and ship a "Copy page" dropdown next to the page
title with Copy / View / Open in ChatGPT / Claude / Perplexity actions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CopyPageMenu: coerce non-string slug to '' and read window.location.origin
(with prod URL fallback for SSR) so the .md URL works in local dev and
staging without hardcoding a production host.

seo.jsx: default slug to '' in the alternate link href so the SEO render
won't crash if a future caller forgets to pass slug.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add LLM-friendly markdown outputs and Copy page menu
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

📝 Walkthrough

Walkthrough

This PR implements a complete markdown companion export pipeline: the build process now generates LLM-friendly markdown companions for test-management documentation, serves them from S3 with correct MIME types, advertises them via SEO link tags, and provides a "Copy Page" UI menu for users to copy/share markdown and open content in external LLM services.

Changes

LLM-Friendly Markdown Companion Export and Copy Menu

Layer / File(s) Summary
Documentation Markdown Companion Generation Pipeline
gatsby-node.js
Post-build pipeline defines helper functions to transform markdown content (blockquotes, Storylane embeds, HTML anchors, scripts), derives URL slugs from source paths, parses/generates minimal frontmatter with canonical URLs, and emits cleaned .md companions and a sorted llms.txt index to public/docs/test-management/.
S3 Content-Type Configuration for Markdown Files
gatsby-config.js
Updates gatsby-plugin-s3 to serve **/*.md files with ContentType: text/markdown; charset=utf-8 for proper browser/client handling.
Markdown URL Advertisement via SEO Link Tag
src/components/seo.jsx
Injects <link rel="alternate" type="text/markdown"> element advertising the generated markdown companion URL, enabling external tools and LLMs to discover markdown versions.
Copy Page Menu UI Component
src/components/CopyPageMenu.jsx
Implements React component with inline SVG icons, dropdown state, async markdown fetch + clipboard copy (with textarea fallback), and external service link generation for ChatGPT, Claude, and Perplexity with URL-encoded markdown prompts.
Copy Page Menu Styles
src/components/CopyPageMenu.scss
Defines trigger button layout, dropdown panel positioning, flex-based menu list, and aggressive !important style resets to prevent ancestor list/anchor styles from contaminating menu appearance.
Page Template Integration
src/templates/page.jsx
Imports and renders CopyPageMenu in page header, replacing simple title <h1> with flex-based header container that displays title and action menu together.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • testsigmahq/TMSDocs#132: Implements the same "LLM-friendly markdown outputs + Copy page menu" feature—including the expanded gatsby-node.js onPostBuild, S3 ContentType param, and CopyPageMenu/page/SEO wiring.
  • testsigmahq/TMSDocs#18: Adds interactive Storylane demo sections to test-management markdown pages, which are now subject to the markdown transformation pipeline that rewrites Storylane embed markup.
  • testsigmahq/TMSDocs#17: Introduces Storylane/embedded JS content in test-management documentation that will be transformed and stripped by the new onPostBuild markdown emission pipeline.

Suggested reviewers

  • Santhosh-testsigma
  • bharathk08

Poem

🐰 A menu to copy, a link to declare,
Markdown companions float through the air,
LLMs feast on our docs—pristine, clean—
The finest test-management ever seen!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Dev --> Prod' is not descriptive of the changeset. It only indicates a branch merge direction, not the actual feature or functionality being introduced. The real changes involve adding LLM-friendly documentation features, markdown exports, and a copy page menu—none of which are conveyed by the title. Use a descriptive title that reflects the main feature, such as 'Add LLM-friendly markdown exports and copy page menu' or 'Enable markdown document serving for LLM integration'.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

Copy link
Copy Markdown

@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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/CopyPageMenu.jsx`:
- Around line 89-95: The mdUrl construction uses safeSlug that can be empty and
yields an invalid URL like "https://testsigma.com.md"; normalize/fallback slug
before building mdUrl by creating a normalizedSlug: if slug is a non-empty
string ensure it begins with a single leading "/" (add one if missing) and strip
any trailing "/" (use safeSlug logic), otherwise fall back to "/" (root). Then
build mdUrl with `${origin}${normalizedSlug.replace(/\/$/, '')}.md` (or more
simply concatenate origin + normalizedSlug ensuring a separator) so
functions/variables referenced (slug, safeSlug, mdUrl, prompt) produce a valid
URL for Copy/View/Open actions.
- Around line 116-118: The setTimeout created after calling setCopied(true) (in
the copy handler) can fire after the component unmounts; store the timeout id
(from setTimeout) in a ref or component state inside the copy handler (e.g.,
timeoutRef or copyTimeoutId) and assign the result of setTimeout to it, then add
a useEffect cleanup that clears that timeout via
clearTimeout(timeoutRef.current) on unmount; also clear any existing timeout
before setting a new one in the copy handler to avoid multiple pending timers.
Ensure you update the handler name where used (e.g., handleCopy / setCopied) and
reference the timeoutRef in the cleanup.

In `@src/components/seo.jsx`:
- Around line 204-208: The markdown alternate link in src/components/seo.jsx
currently renders for every page and when slug is falsy can produce invalid
URLs; change the rendering so the <link rel='alternate' type='text/markdown'
.../> is only output when slug is truthy and matches the docs/test-management
paths (e.g. test the slug with a startsWith or a regex like
^/docs/test-management(/|$)); use that guarded slug value instead of
unconditionally using (slug || '') so you never emit "https://testsigma.com.md"
or alternates for pages that don't have emitted .md files.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97a11a12-34ca-42ef-955f-9afa4c25f31c

📥 Commits

Reviewing files that changed from the base of the PR and between 1623794 and 9ee5d05.

📒 Files selected for processing (6)
  • gatsby-config.js
  • gatsby-node.js
  • src/components/CopyPageMenu.jsx
  • src/components/CopyPageMenu.scss
  • src/components/seo.jsx
  • src/templates/page.jsx

Comment on lines +89 to +95
const safeSlug = typeof slug === 'string' ? slug : '';
const origin =
typeof window !== 'undefined'
? window.location.origin
: 'https://testsigma.com';
const mdUrl = `${origin}${safeSlug.replace(/\/$/, '')}.md`;
const prompt = `Read ${mdUrl} and help me with: `;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Normalize/fallback slug before constructing mdUrl.

If slug is empty/non-string, Line 94 builds an invalid URL (https://testsigma.com.md), so Copy/View/Open actions break instead of degrading gracefully.

Proposed fix
-  const safeSlug = typeof slug === 'string' ? slug : '';
+  const safeSlug = typeof slug === 'string' ? slug.trim() : '';
+  const pathFromLocation =
+    typeof window !== 'undefined' ? window.location.pathname : '';
+  const rawPath = safeSlug || pathFromLocation;
+  const normalizedPath = rawPath
+    ? (rawPath.startsWith('/') ? rawPath : `/${rawPath}`).replace(/\/$/, '')
+    : '';
   const origin =
     typeof window !== 'undefined'
       ? window.location.origin
       : 'https://testsigma.com';
-  const mdUrl = `${origin}${safeSlug.replace(/\/$/, '')}.md`;
+  const mdUrl = normalizedPath ? `${origin}${normalizedPath}.md` : '';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const safeSlug = typeof slug === 'string' ? slug : '';
const origin =
typeof window !== 'undefined'
? window.location.origin
: 'https://testsigma.com';
const mdUrl = `${origin}${safeSlug.replace(/\/$/, '')}.md`;
const prompt = `Read ${mdUrl} and help me with: `;
const safeSlug = typeof slug === 'string' ? slug.trim() : '';
const pathFromLocation =
typeof window !== 'undefined' ? window.location.pathname : '';
const rawPath = safeSlug || pathFromLocation;
const normalizedPath = rawPath
? (rawPath.startsWith('/') ? rawPath : `/${rawPath}`).replace(/\/$/, '')
: '';
const origin =
typeof window !== 'undefined'
? window.location.origin
: 'https://testsigma.com';
const mdUrl = normalizedPath ? `${origin}${normalizedPath}.md` : '';
const prompt = `Read ${mdUrl} and help me with: `;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/CopyPageMenu.jsx` around lines 89 - 95, The mdUrl construction
uses safeSlug that can be empty and yields an invalid URL like
"https://testsigma.com.md"; normalize/fallback slug before building mdUrl by
creating a normalizedSlug: if slug is a non-empty string ensure it begins with a
single leading "/" (add one if missing) and strip any trailing "/" (use safeSlug
logic), otherwise fall back to "/" (root). Then build mdUrl with
`${origin}${normalizedSlug.replace(/\/$/, '')}.md` (or more simply concatenate
origin + normalizedSlug ensuring a separator) so functions/variables referenced
(slug, safeSlug, mdUrl, prompt) produce a valid URL for Copy/View/Open actions.

Comment on lines +116 to +118
setCopied(true);
setTimeout(() => setCopied(false), 1500);
} catch (err) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clear the copied-state timeout on unmount.

Line 117 schedules state updates without cleanup; navigating away quickly can trigger stale updates after unmount.

Proposed fix
-import React, { useState } from 'react';
+import React, { useEffect, useRef, useState } from 'react';
@@
   const [open, setOpen] = useState(false);
   const [copied, setCopied] = useState(false);
+  const copiedTimerRef = useRef(null);
@@
-      setCopied(true);
-      setTimeout(() => setCopied(false), 1500);
+      setCopied(true);
+      clearTimeout(copiedTimerRef.current);
+      copiedTimerRef.current = setTimeout(() => setCopied(false), 1500);
@@
+  useEffect(() => {
+    return () => clearTimeout(copiedTimerRef.current);
+  }, []);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/CopyPageMenu.jsx` around lines 116 - 118, The setTimeout
created after calling setCopied(true) (in the copy handler) can fire after the
component unmounts; store the timeout id (from setTimeout) in a ref or component
state inside the copy handler (e.g., timeoutRef or copyTimeoutId) and assign the
result of setTimeout to it, then add a useEffect cleanup that clears that
timeout via clearTimeout(timeoutRef.current) on unmount; also clear any existing
timeout before setting a new one in the copy handler to avoid multiple pending
timers. Ensure you update the handler name where used (e.g., handleCopy /
setCopied) and reference the timeoutRef in the cleanup.

Comment thread src/components/seo.jsx
Comment on lines +204 to +208
<link
rel='alternate'
type='text/markdown'
href={`https://testsigma.com${(slug || '').replace(/\/$/, '')}.md`}
/>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Gate markdown alternate links to pages that actually have emitted .md files.

Line 207 currently emits a markdown alternate URL for every page. The build only generates companion markdown for /docs/test-management/**, so this creates broken alternates on other pages; with missing slug, it can also produce https://testsigma.com.md.

Suggested fix
+  const safeSlug = typeof slug === 'string' ? slug : '';
+  const isMarkdownCompanionPage = safeSlug.startsWith('/docs/test-management/');
+  const markdownHref = isMarkdownCompanionPage
+    ? `https://testsigma.com${safeSlug.replace(/\/$/, '')}.md`
+    : null;
...
-        <link
-          rel='alternate'
-          type='text/markdown'
-          href={`https://testsigma.com${(slug || '').replace(/\/$/, '')}.md`}
-        />
+        {markdownHref && (
+          <link rel='alternate' type='text/markdown' href={markdownHref} />
+        )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/seo.jsx` around lines 204 - 208, The markdown alternate link
in src/components/seo.jsx currently renders for every page and when slug is
falsy can produce invalid URLs; change the rendering so the <link
rel='alternate' type='text/markdown' .../> is only output when slug is truthy
and matches the docs/test-management paths (e.g. test the slug with a startsWith
or a regex like ^/docs/test-management(/|$)); use that guarded slug value
instead of unconditionally using (slug || '') so you never emit
"https://testsigma.com.md" or alternates for pages that don't have emitted .md
files.

@bharathk08 bharathk08 merged commit 62aeaf1 into main May 21, 2026
3 checks passed
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