Skip to content

Conversation

@orionmiz
Copy link
Collaborator

No description provided.

@changeset-bot
Copy link

changeset-bot bot commented Oct 24, 2025

🦋 Changeset detected

Latest commit: 73fc502

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@stackflow/docs Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Oct 24, 2025

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
stackflow-docs 73fc502 Commit Preview URL Nov 25 2025, 03:46 AM

@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

Warning

Rate limit exceeded

@orionmiz has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 16 minutes and 14 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 6382698 and 73fc502.

📒 Files selected for processing (1)
  • docs/scripts/generate-changelog.ts (1 hunks)
📝 Walkthrough

Summary by CodeRabbit

  • Documentation

    • Added new "Changelog" documentation section.
    • Added new "AI Integration" documentation section with LLMs.txt support for AI tools like Cursor.
  • Chores

    • Updated build workflow to auto-generate changelog content.
    • Added dependencies and scripts for changelog generation and LLMs.txt file generation.

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

Walkthrough

Adds AI-integration docs and changelog pages, new scripts/utilities to generate LLMs.txt and changelog content, updates docs build scripts and dependencies, updates gitignore, and introduces a large Yarn PnP runtime patch that implements a virtual ZIP-backed filesystem and module resolution overlay.

Changes

Cohort / File(s) Summary
Changeset & Navigation metadata
\.changeset/chatty-breads-watch.md, docs/pages/docs/_meta.en.json, docs/pages/docs/_meta.ko.json
New changeset entry; added "ai-integration" and "changelog" keys to docs navigation metadata.
Changelog pages
docs/pages/docs/changelog.en.mdx, docs/pages/docs/changelog.ko.mdx
New English and Korean changelog MDX pages that render the ChangelogContent component.
AI Integration docs
docs/pages/docs/ai-integration/_meta.en.json, docs/pages/docs/ai-integration/_meta.ko.json, docs/pages/docs/ai-integration/llms-txt.en.mdx, docs/pages/docs/ai-integration/llms-txt.ko.mdx
New AI Integration section and LLMs.txt documentation in English and Korean.
LLMs & Changelog generators
docs/scripts/generate-llms-txt.ts, docs/scripts/generate-changelog.ts
New TypeScript scripts: generate LLMs text files (index/full/changelog) and generate changelog MDX from changesets & release plan, with git/commit linking and markdown processing.
Docs utilities
docs/utils/get-all-pages.ts, docs/utils/constants.ts
New utility to collect MD/MDX pages (getAllPages) using gray-matter, and exported baseUrl constant depending on NODE_ENV / NEXT_PUBLIC_SITE_URL.
Docs package & gitignore
docs/package.json, docs/.gitignore
Added scripts (generate:changelog, build:llms), new deps/devDeps (gray-matter, remark, @changesets/*, @manypkg/get-packages, tsx), updated build to run LLM generation; gitignore now excludes generated public/llms*.txt.
Repository package.json
package.json
Updated changeset:version script to run yarn workspace @stackflow/docs generate:changelog before versioning.
Yarn PnP runtime / module resolution
\.pnp.cjs
Large overhaul: introduces virtual filesystem and ZIP archive overlay (ZipFS/ZipOpenFS/etc.), patches Node resolution hooks (require/_resolveFilename/_findPath), implements virtual-path-aware resolution, archive management, and related utilities.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as build / scripts
    participant Gen as generate-llms-txt.ts
    participant Pages as docs pages
    participant FS as public dir (fs)
    CLI->>Gen: run generate:llms
    Gen->>Pages: getAllPages()
    Pages-->>Gen: list of Page objects (frontmatter + content)
    Gen->>FS: write llms-full.txt, llms-changelog.txt, llms.txt
    FS-->>CLI: files created
Loading
sequenceDiagram
    autonumber
    participant Node as Node.js loader
    participant PnP as .pnp.cjs resolver
    participant VFS as VirtualFS/ZipFS
    participant NativeFS as native fs
    Node->>PnP: module request (require/import)
    PnP->>VFS: try resolve via virtual ZIP overlay
    alt Found in virtual ZIP
        VFS-->>PnP: resolved virtual path / buffer
        PnP->>Node: load module from virtual buffer
    else Not found in virtual
        PnP->>NativeFS: fallback resolution
        NativeFS-->>PnP: resolved native path
        PnP->>Node: load module from native path
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Pay special attention to:
    • .pnp.cjs — module resolution hooks, ZipFS/ZipOpenFS implementations, caching, native fallback, security/sandboxing, and Node patch correctness.
    • docs/scripts/generate-changelog.ts — changeset parsing, release plan logic, git/commit lookup, and merge/preservation of manual changelog blocks.
    • docs/scripts/generate-llms-txt.ts and docs/utils/get-all-pages.ts — file traversal, frontmatter parsing, and markdown processing (remark).
    • docs/package.json and root package.json script changes and docs/.gitignore entries.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive No description was provided by the author, making it impossible to assess relevance to the changeset. Add a pull request description explaining the purpose, motivation, and key changes of this PR.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: adding LLMs.txt documentation and a Changelog section to the docs.

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.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Oct 24, 2025

Deploying stackflow-demo with  Cloudflare Pages  Cloudflare Pages

Latest commit: 73fc502
Status:⚡️  Build in progress...

View logs

Copy link

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

🧹 Nitpick comments (12)
docs/pages/docs/get-started/ai-integration.ko.mdx (2)

1-3: Add a short description to frontmatter for SEO/social cards.

 ---
 title: AI 통합
+description: LLMs.txt, llms-full.txt, llms-changelog.txt를 통해 Stackflow 문서를 LLM에 제공하고 AI 도구에서 활용하는 방법을 소개합니다.
 ---

15-17: Use relative URLs to work on preview/local environments.
Absolute links lock to production. Relative paths keep docs portable.

-- [llms.txt](https://stackflow.so/api/llms.txt): LLMs.txt 파일들의 구조를 제공하는 메인 파일입니다.
-- [llms-full.txt](https://stackflow.so/api/llms-full.txt): Stackflow의 모든 문서를 포함합니다.
-- [llms-changelog.txt](https://stackflow.so/api/llms-changelog.txt): 최신 업데이트와 변경사항을 포함하여 버전별 변경 내역을 확인할 수 있습니다.
+- [llms.txt](/api/llms.txt): LLMs.txt 파일들의 구조를 제공하는 메인 파일입니다.
+- [llms-full.txt](/api/llms-full.txt): Stackflow의 모든 문서를 포함합니다.
+- [llms-changelog.txt](/api/llms-changelog.txt): 최신 업데이트와 변경사항을 포함하여 버전별 변경 내역을 확인할 수 있습니다.
docs/pages/docs/get-started/ai-integration.en.mdx (2)

1-3: Add a concise description to frontmatter.

 ---
 title: AI Integration
+description: Introduces LLMs.txt, llms-full.txt, and llms-changelog.txt and how to use them with AI tools like Cursor.
 ---

15-17: Prefer relative URLs for portability across preview/local.

-- [llms.txt](https://stackflow.so/api/llms.txt): The main file that describes the structure of all LLMs.txt files.
-- [llms-full.txt](https://stackflow.so/api/llms-full.txt): Includes all Stackflow documentation.
-- [llms-changelog.txt](https://stackflow.so/api/llms-changelog.txt): Contains the latest updates and changes so you can review version-by-version history.
+- [llms.txt](/api/llms.txt): The main file that describes the structure of all LLMs.txt files.
+- [llms-full.txt](/api/llms-full.txt): Includes all Stackflow documentation.
+- [llms-changelog.txt](/api/llms-changelog.txt): Contains the latest updates and changes so you can review version-by-version history.
docs/pages/api/llms-full.txt.ts (2)

8-14: Tighten handler: remove unnecessary await, add try/catch, charset, and caching.
Current code awaits a sync function, lacks error handling, and omits charset/cache headers.

-import type { NextApiRequest, NextApiResponse } from "next";
-import { getAllPages } from "../../utils/get-all-pages";
+import type { NextApiRequest, NextApiResponse } from "next";
+import { getAllPages } from "../../utils/get-all-pages";
 
-export default async function handler(
-  req: NextApiRequest,
-  res: NextApiResponse,
-) {
-  const pages = await getAllPages();
-  const content = pages
-    .map((page) => `# ${page.title}\n\n${page.content}`)
-    .join("\n\n");
-
-  res.setHeader("Content-Type", "text/plain");
-  res.status(200).send(content);
-}
+export default async function handler(
+  _req: NextApiRequest,
+  res: NextApiResponse,
+) {
+  try {
+    const pages = getAllPages();
+    const content = pages
+      .map((page) => `# ${page.title || page.path}\n\n${page.content}`)
+      .join("\n\n");
+
+    res.setHeader("Content-Type", "text/plain; charset=utf-8");
+    // Cache for 1 day at the edge; allow 1 day stale-while-revalidate
+    res.setHeader("Cache-Control", "public, s-maxage=86400, stale-while-revalidate=86400");
+    res.status(200).send(content);
+  } catch (error) {
+    console.error("LLMs full generation error:", error);
+    res.status(500).send("Error generating LLMs full document");
+  }
+}

10-11: Optional: convert MDX to plain text for consistency with llms-changelog.
If desired, process MD/MDX into plain text like the changelog route to reduce markup noise. Based on the referenced pattern in docs/pages/api/llms-changelog.txt.ts.

+// import { processContent } from "../../utils/process-content";
-    const content = pages
-      .map((page) => `# ${page.title || page.path}\n\n${page.content}`)
-      .join("\n\n");
+    const parts = await Promise.all(
+      pages.map(async (page) => {
+        const body = await processContent(page.content);
+        return `# ${page.title || page.path}\n\n${body}`;
+      }),
+    );
+    const content = parts.join("\n\n");
docs/utils/constants.ts (1)

1-4: Port 6006 confirmed. Consider deriving base URL from request for better preview/staging support.

  • Verified: docs/package.json has "dev": "next -p 6006" — port is correct.
  • The baseUrl constant is used in docs/pages/api/llms.txt.ts (an API handler with access to req), making request-scoped derivation feasible and beneficial. Current static constant works but won't adapt if deployed to preview/staging URLs.
  • Fallback scheme is correct (https://stackflow.so); no issues with env setup.

Optional improvement:

// docs/utils/url.ts
import type { NextApiRequest } from "next";
export function absoluteUrlFromReq(req: NextApiRequest): URL {
  const proto = (req.headers["x-forwarded-proto"] as string) || "https";
  const host =
    (req.headers["x-forwarded-host"] as string) ||
    (req.headers.host as string) ||
    "localhost:6006";
  return new URL(`${proto}://${host}`);
}

Then call absoluteUrlFromReq(req) in the handler instead of the static constant to handle preview/staging environments correctly.

docs/pages/api/llms.txt.ts (1)

4-6: Set UTF-8 and tidy unused param

  • Add charset to Content-Type for safer text decoding.
  • req is unused; prefix with underscore to satisfy noUnusedParameters.
-export default function handler(req: NextApiRequest, res: NextApiResponse) {
-  res.setHeader("Content-Type", "text/plain");
+export default function handler(_req: NextApiRequest, res: NextApiResponse) {
+  res.setHeader("Content-Type", "text/plain; charset=utf-8");
docs/utils/get-all-pages.ts (1)

5-11: Tighten types for frontmatter

Use unknown instead of any to preserve strictness and force narrowing at use-sites.

-  data: Record<string, any>;
+  data: Record<string, unknown>;
docs/pages/api/llms-changelog.txt.ts (2)

21-26: Remove unused frontmatter data or use it

data is parsed but unused. Drop it or surface metadata in the response header.

-    const { data, content } = matter(fileContent);
+    const { content } = matter(fileContent);

9-13: Method guard and basic caching (optional)

Restrict to GET and add a modest cache to reduce cold starts.

 export default async function handler(
   req: NextApiRequest,
   res: NextApiResponse,
 ) {
+  if (req.method !== "GET") {
+    res.setHeader("Allow", "GET");
+    return res.status(405).end("Method Not Allowed");
+  }
@@
-    res.setHeader("Content-Type", "text/plain; charset=utf-8");
+    res.setHeader("Content-Type", "text/plain; charset=utf-8");
+    res.setHeader("Cache-Control", "public, max-age=0, s-maxage=3600, stale-while-revalidate=86400");

Also applies to: 31-36

scripts/generate-changelog.ts (1)

56-59: Escape user-controlled parts of regex (correctness and ReDoS hygiene)

date includes dots and optional suffix; escape it before constructing the regex.

-  const dateRegex = new RegExp(`## ${date}(?: #\\d+)?`, "g");
+  const escaped = date.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
+  const dateRegex = new RegExp(`## ${escaped}(?: #\\d+)?`, "g");
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories
  • 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 f4a2fb5 and 2ce34d1.

⛔ Files ignored due to path filters (43)
  • .yarn/cache/@changesets-assemble-release-plan-npm-6.0.9-e01af97ef4-f84656eabb.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@changesets-git-npm-3.0.4-c1d351b2f6-4f5a1f3354.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@changesets-read-npm-0.6.5-fc55502eb7-fec0ac2880.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-find-and-replace-npm-3.0.2-700884f061-446561aa95.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-from-markdown-npm-2.0.2-b327f875e3-69b207913f.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-autolink-literal-npm-2.0.1-dd870d9308-d933b42feb.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-footnote-npm-2.1.0-d8da32ba7c-5fac0f64d1.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-npm-3.1.0-933de2cdb5-d66809a070.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-strikethrough-npm-2.0.0-d16d95c318-b1abc137d7.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-table-npm-2.0.0-45a74f064b-a043d60d72.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-task-list-item-npm-2.0.0-cb1270a10f-679a3ff09b.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-phrasing-npm-4.1.0-30939ebbcd-3a97533e8a.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-to-markdown-npm-2.1.2-40d984eac3-ab494a32f1.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-to-string-npm-4.0.0-fc8d9714a5-f4a5dbb9ea.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-core-commonmark-npm-2.0.3-5e317c62b2-2b98b9eba1.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-autolink-literal-npm-2.1.0-8fcb271412-933b9b96ca.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-footnote-npm-2.1.0-1cf783dd36-7e019414e3.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-npm-3.0.0-d154ab531f-8493d10417.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-strikethrough-npm-2.1.0-b2aa188eba-eaf2c7b1e3.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-table-npm-2.1.1-7b9f4422c9-0391ead408.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-tagfilter-npm-2.0.0-c5ad486636-c5e3f8cdf2.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-task-list-item-npm-2.1.0-b717607894-c5f72929f0.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-factory-destination-npm-2.0.1-2b4ab89121-9c4baa9ca2.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-factory-label-npm-2.0.1-2ce9fdcfd2-bd03f5a75f.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-factory-space-npm-2.0.1-36b4717310-1bd68a017c.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-factory-title-npm-2.0.1-a5f7a4ac37-b4d2e4850a.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-factory-whitespace-npm-2.0.1-2d7cfaf8ae-67b3944d01.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-npm-4.0.2-99b2e4c11c-1b85e49c8f.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-chunked-npm-2.0.1-27444b1e7b-f8cb2a67bc.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-classify-character-npm-2.0.1-127a4a9c2a-4d8bbe3a6d.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-combine-extensions-npm-2.0.1-9810c0bf8d-5d22fb9ee3.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-decode-numeric-character-reference-npm-2.0.2-c2d481632e-ee11c8bde5.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-decode-string-npm-2.0.1-72716f39ea-2f517e4c61.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-html-tag-name-npm-2.0.1-eb560993c8-dea365f5ad.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-normalize-identifier-npm-2.0.1-336335e80e-1eb9a289d7.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-resolve-all-npm-2.0.1-50f997ec4c-9275f3ddb6.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-subtokenize-npm-2.1.0-2452c9ae9b-5f18c70cb9.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/remark-gfm-npm-4.0.1-f55aaba8ef-86899862cf.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/remark-npm-15.0.1-0f67091876-671eae3a44.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/remark-parse-npm-11.0.0-6484fba69e-59d584be56.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/remark-stringify-npm-11.0.0-b41a557b8d-32b2f6093b.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/unified-npm-11.0.5-ac5333017e-d9e6e88900.zip is excluded by !**/.yarn/**, !**/*.zip
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (19)
  • .changeset/chatty-breads-watch.md (1 hunks)
  • .pnp.cjs (46 hunks)
  • docs/package.json (1 hunks)
  • docs/pages/api/llms-changelog.txt.ts (1 hunks)
  • docs/pages/api/llms-full.txt.ts (1 hunks)
  • docs/pages/api/llms.txt.ts (1 hunks)
  • docs/pages/docs/_meta.en.json (1 hunks)
  • docs/pages/docs/_meta.ko.json (1 hunks)
  • docs/pages/docs/changelog.en.mdx (1 hunks)
  • docs/pages/docs/changelog.ko.mdx (1 hunks)
  • docs/pages/docs/get-started/_meta.en.json (1 hunks)
  • docs/pages/docs/get-started/_meta.ko.json (1 hunks)
  • docs/pages/docs/get-started/ai-integration.en.mdx (1 hunks)
  • docs/pages/docs/get-started/ai-integration.ko.mdx (1 hunks)
  • docs/tsconfig.json (1 hunks)
  • docs/utils/constants.ts (1 hunks)
  • docs/utils/get-all-pages.ts (1 hunks)
  • package.json (2 hunks)
  • scripts/generate-changelog.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
.changeset/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Include a Changeset entry for any user-facing package change

Files:

  • .changeset/chatty-breads-watch.md
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Write source in TypeScript with strict typing enabled across the codebase

Files:

  • docs/pages/api/llms-full.txt.ts
  • docs/pages/api/llms.txt.ts
  • docs/utils/constants.ts
  • docs/pages/api/llms-changelog.txt.ts
  • scripts/generate-changelog.ts
  • docs/utils/get-all-pages.ts
🧬 Code graph analysis (4)
docs/pages/api/llms-full.txt.ts (3)
docs/pages/api/llms-changelog.txt.ts (1)
  • handler (9-37)
docs/pages/api/llms.txt.ts (1)
  • handler (4-14)
docs/utils/get-all-pages.ts (1)
  • getAllPages (13-39)
docs/pages/api/llms.txt.ts (3)
docs/pages/api/llms-changelog.txt.ts (1)
  • handler (9-37)
docs/pages/api/llms-full.txt.ts (1)
  • handler (4-15)
docs/utils/constants.ts (1)
  • baseUrl (1-4)
docs/utils/constants.ts (1)
.pnp.cjs (1)
  • URL (21065-21065)
docs/pages/api/llms-changelog.txt.ts (2)
docs/pages/api/llms-full.txt.ts (1)
  • handler (4-15)
docs/pages/api/llms.txt.ts (1)
  • handler (4-14)
🪛 ast-grep (0.39.6)
scripts/generate-changelog.ts

[warning] 55-55: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(## ${date}(?: #\\d+)?, "g")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🪛 LanguageTool
docs/pages/docs/get-started/ai-integration.ko.mdx

[grammar] ~7-~7: El plural de les sigles no es marca gràficament.
Context: --- title: AI 통합 --- # AI 통합 ## LLMs.txt 대규모 언어 모델(LLM)이 Stackflow를 쉽게 이해할 ...

(SIGLES)


[grammar] ~9-~9: El plural de les sigles no es marca gràficament.
Context: ...대규모 언어 모델(LLM)이 Stackflow를 쉽게 이해할 수 있도록 LLMs.txt를 제공합니다. ### 구조 다음과 같은 LLMs.txt 파일...

(SIGLES)


[grammar] ~13-~13: El plural de les sigles no es marca gràficament.
Context: ... 수 있도록 LLMs.txt를 제공합니다. ### 구조 다음과 같은 LLMs.txt 파일들을 제공합니다: - [llms.txt](https://s...

(SIGLES)


[typographical] ~15-~15: Símbol sense parella: sembla que falta «[».
Context: ...다음과 같은 LLMs.txt 파일들을 제공합니다: - llms.txt: LLM...

(UNPAIRED_BRACKETS)


[grammar] ~15-~15: El plural de les sigles no es marca gràficament.
Context: ...xt](https://stackflow.so/api/llms.txt): LLMs.txt 파일들의 구조를 제공하는 메인 파일입니다. - [llms-ful...

(SIGLES)


[typographical] ~16-~16: Símbol sense parella: sembla que falta «[».
Context: ...파일들의 구조를 제공하는 메인 파일입니다. - llms-full.txt...

(UNPAIRED_BRACKETS)


[typographical] ~17-~17: Símbol sense parella: sembla que falta «[».
Context: ...low의 모든 문서를 포함합니다. - [llms-changelog.txt](https://stackflow.so/api/llms-changelog...

(UNPAIRED_BRACKETS)


[grammar] ~21-~21: El plural de les sigles no es marca gràficament.
Context: ...### Cursor Cursor의 @docs 기능을 사용하여 프로젝트에 LLMs.txt 파일을 포함할 수 있습니다. [**Cursor @docs에 대...

(SIGLES)


[typographical] ~23-~23: Símbol sense parella: sembla que falta «[».
Context: ...함할 수 있습니다. [Cursor @docs에 대해 자세히 알아보기](https://docs.cursor.com/context/@-symbo...

(UNPAIRED_BRACKETS)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Workers Builds: stackflow-docs
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (12)
.pnp.cjs (1)

118-130: This is an auto-generated file; review should focus on source files instead.

The .pnp.cjs file is Yarn's auto-generated Plug'n'Play manifest and should not be manually reviewed for code quality. The changes reflect dependency tree updates from modifications to package.json.

The added dependencies align with the PR objectives (changesets for changelog generation, remark/mdast for markdown processing, gray-matter for frontmatter parsing), but to properly review this PR, we need to examine:

  • package.json changes and dependency version rationale
  • New/modified source files for LLMs.txt and Changelog feature implementation
  • Build system updates (as mentioned in the AI summary)
  • Documentation pages and utility functions for reading docs

Please provide the source files that directly implement the LLMs.txt and Changelog functionality, along with the package.json modifications.

Also applies to: 2539-2766, 6192-6209, 6285-6297, 12790-13074, 13121-13157, 13282-13390, 13400-13545, 13647-13970, 14008-14021, 15932-16055, 17425-17442

.changeset/chatty-breads-watch.md (1)

1-5: Changeset entry follows correct structure.

The changeset correctly documents the minor release for @stackflow/docs with an appropriate description of the user-facing changes.

docs/tsconfig.json (1)

1-28: TypeScript configuration looks good.

The tsconfig.json follows standard Next.js/React patterns with appropriate settings for a TypeScript documentation site.

docs/pages/docs/get-started/_meta.en.json (1)

1-9: Metadata entry for AI integration documentation is properly added.

The new navigation entry follows the existing pattern and maintains valid JSON structure.

package.json (2)

22-28: Ensure generate-changelog script is integrated correctly.

The changeset:version script now depends on generate:changelog running successfully. Any failure in changelog generation will block the release process.

Verify that:

  1. scripts/generate-changelog.ts exists and implements the changelog generation logic
  2. The script runs without errors: yarn generate:changelog
  3. Output is correctly written to docs/pages/docs/changelog.en.mdx (and .ko.mdx if applicable)

37-43: New changesets dependencies are well-scoped.

The added @changesets packages support the automated changelog generation workflow and appear appropriately versioned.

docs/pages/docs/_meta.ko.json (1)

1-5: Korean metadata changelog entry is correctly added.

The translation "변경 이력" (Changelog) is appropriate and the JSON structure is valid.

docs/pages/docs/_meta.en.json (1)

1-5: English metadata changelog entry is correctly added.

The navigation entry properly introduces the Changelog section to the documentation structure.

docs/pages/docs/changelog.ko.mdx (1)

1-1: The file structure is valid, but the review comment misdiagnosed the issue.

The changelog.ko.mdx file is a symbolic link pointing to changelog.en.mdx, not a file containing only the string "changelog.en.mdx". The actual MDX content is valid with proper frontmatter and structure.

However, there is a legitimate localization concern: Korean users receive English-language changelog content (title: "Changelog", entries in English) instead of Korean translations. For proper i18n support, the Korean changelog should contain Korean translations rather than linking to the English version.

Likely an incorrect or invalid review comment.

docs/pages/docs/get-started/_meta.ko.json (1)

7-8: LGTM.
Key "ai-integration" matches the new page slug; JSON is valid.

docs/package.json (1)

7-15: generate:changelog script already wired in root package.json

Verification confirms the generate:changelog script has been successfully added to the root package.json (line 7). The original concern has been addressed—the generator is now invokable via npm.

docs/utils/get-all-pages.ts (1)

1-2: Review comment is based on incorrect premise; however, a separate async/await inconsistency exists.

The project is properly configured for Cloudflare Workers deployment: wrangler.jsonc has compatibility_date: "2025-04-23" and compatibility_flags: ["nodejs_compat"]. With nodejs_compat enabled, synchronous Node.js fs APIs like readFileSync are available on Cloudflare Workers. The getAllPages() utility's use of fs.readFileSync, fs.readdirSync, and fs.statSync will function correctly with this configuration.

However, fix the async/await inconsistency: getAllPages() is not an async function but is awaited in the API handler at docs/pages/api/llms-full.txt.ts:8. Either make the function async or remove the await.

Likely an incorrect or invalid review comment.

Comment on lines 1 to 3
import fs from "node:fs";
import path from "node:path";
import matter from "gray-matter";
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

API route will break on Cloudflare Workers (fs/path at runtime)

This route reads the MDX file with fs at request-time. Cloudflare Workers don’t support Node fs/path; the endpoint will 500 in production unless deployed on a Node runtime. Options:

  • Build-time: generate a plain-text artifact (or JSON) and import/serve it.
  • Static asset: emit the MDX-processed text to public/ and stream it.
  • If unavoidable, pin this route to a Node runtime and exclude from Worker deploys.

Also applies to: 15-20





---

🏁 Script executed:

```shell
#!/bin/bash
# View the complete file to understand how fs/path are used
cat docs/pages/api/llms-changelog.txt.ts

Length of output: 1263


🏁 Script executed:

#!/bin/bash
# Check if there's a build configuration or deployment config that clarifies the target
fd -t f "(vercel|next|wrangler|cloudflare|deploy)" --type f | head -20

Length of output: 140


🏁 Script executed:

#!/bin/bash
# Search for usage of fs or path in the file to understand runtime vs build-time usage
rg -n "fs\.|path\." docs/pages/api/llms-changelog.txt.ts

Length of output: 107


🌐 Web query:

Cloudflare Workers Node.js fs module support runtime

💡 Result:

Short answer: Cloudflare Workers now implements a Node.js-compatible virtual file system exposed via the node:fs module. It's available in Node.js compatibility mode (set compatibility flag nodejs_compat) and is enabled by default for Workers with a compatibility_date of 2025-09-01 or later (it can also be enabled/disabled with the enable_nodejs_fs_module / disable_nodejs_fs_module flags). [1][2]

Key points:

  • How to enable: set compatibility_date ≥ 2025-09-01 and add compatibility_flags: ["nodejs_compat"] (or enable the fs flag on earlier dates). [1][2]
  • Usage: import using the node: prefix, e.g. import { readFileSync } from "node:fs". [1][2]
  • Behavior: the fs is a per-request in-memory virtual file system (ephemeral — not persisted across requests). [1][2]
  • Limits & known restrictions: max file size 128 MB, path length and segment limits, timestamps currently always the Unix epoch, no fs.watch/fs.watchFile, some glob and force options not implemented, file permissions/ownership not supported; temporary files count against Worker memory. [1]
  • Rationale: implemented natively in the Workers runtime as part of Cloudflare’s Node.js compatibility improvements. [3]

Sources:
[1] Cloudflare Workers docs — fs / Node.js fs info.
[2] Cloudflare changelog post (Aug 15, 2025) announcing node:fs in Workers.
[3] Cloudflare blog post on Node.js compatibility in Workers.



---

🏁 Script executed:

```shell
#!/bin/bash
# Check wrangler config to understand deployment strategy
cat docs/wrangler.jsonc

Length of output: 650


🏁 Script executed:

#!/bin/bash
# Search for changelog-related build or static asset generation
rg -i "changelog" docs/ --type ts --type js --type mjs --type json -B2 -A2

Length of output: 27


🏁 Script executed:

#!/bin/bash
# Check if pages/docs/changelog.en.mdx exists and if there's build processing
fd -t f "changelog" docs/

Length of output: 87


API route breaks on Cloudflare Workers with current deployment config (fs/path not available)

The route uses fs.readFileSync() at request-time (line 19), but wrangler.jsonc specifies compatibility_date: "2025-04-23", which does not support Node.js fs/path modules. The endpoint will error in production.

Even if upgraded to compatibility_date: "2025-09-01" or later (when nodejs_compat fs became available), the fs module in Workers is an ephemeral per-request virtual filesystem — not disk I/O — so this pattern remains incompatible.

Recommendations:

  • Generate the changelog at build-time and import/serve as static content
  • Emit processed output to public/ and serve via static asset
  • If this route must remain dynamic, pin it to a Node.js runtime and exclude from Cloudflare Workers deployment
🤖 Prompt for AI Agents
In docs/pages/api/llms-changelog.txt.ts around lines 1 to 3, the route imports
node fs/path and calls fs.readFileSync at request time which breaks on
Cloudflare Workers (no Node fs/path at the configured compatibility_date and
even newer nodejs_compat is an ephemeral VFS); change the implementation to
produce the changelog at build time and serve static content instead: move file
reading/gray-matter parsing into your build step (or a script) that writes the
processed output into public/ (or generates a module you can import), update
this API route to either import the generated static file or return the static
asset, or alternatively mark this route to run on a Node.js runtime and exclude
it from Workers deployment if it truly must remain dynamic.

package.json Outdated
"packages/*",
"extensions/*"
],
"type": "module",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify ESM compatibility across the monorepo before merging.

Adding "type": "module" converts the entire monorepo to ES modules, which is a breaking change. Ensure all workspaces, build scripts, and dependencies properly support ESM before merging.


🏁 Script executed:

#!/bin/bash
# Description: Verify generate-changelog.ts exists and check ESM compatibility indicators

# Check if generate-changelog.ts exists
if [ -f scripts/generate-changelog.ts ]; then
  echo "✓ scripts/generate-changelog.ts exists"
  head -20 scripts/generate-changelog.ts
else
  echo "✗ scripts/generate-changelog.ts NOT FOUND"
fi

# Verify the script doesn't use CommonJS requires
if [ -f scripts/generate-changelog.ts ]; then
  if grep -q "require(" scripts/generate-changelog.ts; then
    echo "⚠ WARNING: Script appears to use CommonJS require() - may not work with type:module"
  else
    echo "✓ Script appears to use ES imports"
  fi
fi

# Check for any .ts config or build files that might conflict
fd -e ts -e mjs -e cjs scripts/ 2>/dev/null | head -10

Length of output: 785



🏁 Script executed:

#!/bin/bash
# Description: Verify ESM compatibility across workspaces and build configuration

# Check workspace package.json files for type field
echo "=== Checking workspace configurations ==="
fd -e package.json -path '*/packages/*/package.json' | head -20 | while read -r pkg; do
  echo "File: $pkg"
  grep -E '"type"|"module"' "$pkg" || echo "  (no type field)"
done

# Check root tsconfig.json for module settings
echo -e "\n=== Checking TypeScript module configuration ==="
if [ -f tsconfig.json ]; then
  echo "Root tsconfig.json:"
  grep -A2 -B2 '"module"' tsconfig.json || echo "  (no module field)"
else
  echo "tsconfig.json not found"
fi

# Look for any build/test scripts that might use CommonJS syntax
echo -e "\n=== Checking for CommonJS patterns in build context ==="
grep -r "require\.resolve\|module\.exports\|CommonJS" . --include="*.ts" --include="*.js" -l 2>/dev/null | grep -E "(build|test|scripts)" | head -10 || echo "  (no obvious CommonJS patterns in build scripts)"

# Check if .mocharc or similar test config exists and uses ESM
echo -e "\n=== Checking test configuration ==="
fd -E node_modules '.mocharc*' -o '.babelrc*' -o 'jest.config*' | head -5

Length of output: 679


🏁 Script executed:

#!/bin/bash
# Check if there are documented ESM breaking changes or migration notes
echo "=== Checking for ESM migration documentation ==="
fd -e md -e txt -E node_modules | xargs grep -l "ESM\|module.*type\|CommonJS" 2>/dev/null | head -5

Length of output: 100


🏁 Script executed:

#!/bin/bash
# Description: Verify ESM compatibility across workspaces and build configuration

# Check workspace package.json files for type field
echo "=== Checking workspace configurations ==="
fd -e package.json -path '*/packages/*/package.json' | head -20 | while read -r pkg; do
  echo "File: $pkg"
  grep -E '"type"' "$pkg" || echo "  (no type field)"
done

# Check root tsconfig.json for module settings
echo -e "\n=== Checking TypeScript module configuration ==="
if [ -f tsconfig.json ]; then
  echo "Root tsconfig.json:"
  grep -A2 -B2 '"module"' tsconfig.json || echo "  (no module field)"
fi

# Check for .mts files or explicit ESM markers
echo -e "\n=== Checking for ESM file extensions in scripts ==="
fd -e mts -o -e mjs scripts/ 2>/dev/null || echo "  (no .mts or .mjs files in scripts)"

# Look for common ESM incompatibilities in scripts directory
echo -e "\n=== Checking script files for ESM compatibility ==="
fd -type f scripts/ 2>/dev/null | while read -r script; do
  if file "$script" | grep -q "JavaScript"; then
    if grep -l "module.exports\|require(" "$script" 2>/dev/null; then
      echo "⚠ POTENTIAL ISSUE: $script uses CommonJS"
    fi
  fi
done

Length of output: 555



🏁 Script executed:

#!/bin/bash
# Description: Check esbuild-config usage and build process compatibility

# Verify how esbuild-config is imported/used
echo "=== Searching for esbuild-config imports ==="
rg -n "esbuild-config" --type ts --type js -B2 -A2 | head -30

# Check package.json to see if esbuild-config is a package or internal config
echo -e "\n=== Checking esbuild-config package structure ==="
if [ -f packages/esbuild-config/package.json ]; then
  echo "esbuild-config package.json:"
  cat packages/esbuild-config/package.json | head -15
fi

# Check root package.json build scripts more closely
echo -e "\n=== Build and script commands from root package.json ==="
grep -E '"(build|dev|test|prepare|postinstall)"' package.json | head -10

Length of output: 2698



🏁 Script executed:

#!/bin/bash
# Description: Verify if esbuild configs have been migrated to ESM or .mjs/.mts

# Check for .mjs or .mts versions of esbuild config files
echo "=== Checking for ESM versions of esbuild config ==="
fd -e mjs -e mts | grep esbuild || echo "  (no .mjs or .mts esbuild configs found)"

# Check if any esbuild.config.js files have been converted to import syntax
echo -e "\n=== Checking if any esbuild.config.js use import syntax ==="
fd -name "esbuild.config.js" | while read -r file; do
  if head -5 "$file" | grep -q "^import\|^export"; then
    echo "✓ ESM: $file"
  else
    echo "✗ CommonJS: $file"
  fi
done

# Check if git shows these files as modified in this PR
echo -e "\n=== Checking git status of esbuild config files ==="
git diff HEAD --name-only 2>/dev/null | grep -i esbuild || echo "  (no esbuild files modified in this PR)"

Length of output: 479


Migrate esbuild.config.js files to ESM before setting "type": "module".

Adding "type": "module" at the root converts all .js files to ESM. However, multiple esbuild.config.js files throughout the monorepo (extensions/react-ui-core/, extensions/plugin-basic-ui/, extensions/plugin-stack-depth-change/, extensions/plugin-map-initial-activity/, extensions/plugin-history-sync/, extensions/plugin-preload/, and others) still use CommonJS require() syntax. These will fail when parsed as ESM.

Either migrate these build config files to ESM (.mjs or import syntax) or add "type": "commonjs" to their respective package.json files to override the root setting.

🤖 Prompt for AI Agents
In package.json around line 14, adding "type": "module" will make all .js files
ESM and will break existing esbuild.config.js files that still use CommonJS
require() in the listed extension packages (extensions/react-ui-core,
extensions/plugin-basic-ui, extensions/plugin-stack-depth-change,
extensions/plugin-map-initial-activity, extensions/plugin-history-sync,
extensions/plugin-preload, etc.); fix by either (A) migrating each
esbuild.config.js to ESM: rename to .mjs or convert require()/module.exports to
import/export syntax and adjust any synchronous require usage to ESM-compatible
patterns, or (B) add a package.json in each extension folder with "type":
"commonjs" to keep those configs as CommonJS; pick one approach per package and
apply consistently so the root "type": "module" does not break their build
configs.

Comment on lines 445 to 446
const existingContent = await readFile(changelogPath, "utf-8");

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Handle first-run when changelog doesn’t exist

readFile will throw if docs/pages/docs/changelog.en.mdx is missing. Default to empty and start fresh.

-    const existingContent = await readFile(changelogPath, "utf-8");
+    let existingContent = "";
+    try {
+      existingContent = await readFile(changelogPath, "utf-8");
+    } catch {
+      console.log("🆕 No existing changelog; starting fresh");
+    }
🤖 Prompt for AI Agents
In scripts/generate-changelog.ts around lines 445 to 446, reading the changelog
with readFile will throw if docs/pages/docs/changelog.en.mdx is missing; wrap
the readFile call in a try/catch, on ENOENT set existingContent = "" (start
fresh) and for any other error rethrow it so real failures surface; ensure
subsequent logic uses the default empty string when the file doesn't exist.

@orionmiz orionmiz force-pushed the llms-txt branch 2 times, most recently from 0c3cf2b to 2ce34d1 Compare October 24, 2025 09:38
Copy link

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

♻️ Duplicate comments (3)
scripts/generate-changelog.ts (3)

441-452: Handle first‑run when changelog doesn’t exist (EN)

readFile will throw if the file is missing.

-    const existingContent = await readFile(changelogEnPath, "utf-8");
+    let existingContent = "";
+    try {
+      existingContent = await readFile(changelogEnPath, "utf-8");
+    } catch (e: any) {
+      if (e?.code !== "ENOENT") throw e;
+      console.log("🆕 No existing changelog.en.mdx; starting fresh");
+    }

120-168: Don’t cap to 10 and avoid Unix‑only pipeline; derive from release plan IDs

The find|grep|head|cut chain is non‑portable and silently drops after 10 files. Build from releasePlan.changesets IDs and filter “Version Packages” in JS.

-async function getChangesetCommits(): Promise<Record<string, string>> {
+async function getChangesetCommits(ids: string[]): Promise<Record<string, string>> {
   try {
-    // .changeset 폴더의 .md 파일들 찾기 (README.md 제외)
-    const files = await execCommand(
-      "find .changeset -name '*.md' -not -name 'README.md' | head -10",
-    );
-
-    if (!files) {
-      console.log("📝 No changeset files found in .changeset folder");
-
-      return {};
-    }
-
-    const fileList = files.split("\n").filter((file) => file.trim());
-    console.log(`📊 Found ${fileList.length} changeset files:`, fileList);
-
-    // 각 파일별로 main 브랜치에 머지된 commit 찾기
+    const fileList = ids.map((id) => `.changeset/${id}.md`);
+    console.log(`📊 Resolving ${fileList.length} changeset files from release plan`);
     const commitMap: Record<string, string> = {};
-    for (const file of fileList) {
-      // changeset ID 추출 (파일명에서 .md 제거)
-      const changesetId = file.split("/").pop()?.replace(".md", "") || "";
-
-      // Version Packages 커밋을 제외하고 main 브랜치에 머지된 커밋 찾기
-      const commit = await execCommand(
-        `git log --oneline --first-parent main -- "${file}" | grep -v "Version Packages" | head -1 | cut -d' ' -f1`,
-      );
-      if (commit) {
-        // 전체 커밋 해시 가져오기
-        const fullCommit = await execCommand(`git rev-parse ${commit}`);
-        if (fullCommit) {
-          commitMap[changesetId] = fullCommit;
-          console.log(`  📄 ${changesetId} → ${fullCommit.slice(0, 7)}`);
-        }
-      }
-    }
+    for (const id of ids) {
+      const file = `.changeset/${id}.md`;
+      // Hash<TAB>Subject on first-parent main for the file
+      const log = await execCommand(
+        `git log --first-parent main --pretty=format:%H%x09%s -- "${file}"`
+      );
+      if (!log) continue;
+      const line = log.split("\n").find((l) => !l.includes("Version Packages"));
+      if (!line) continue;
+      const hash = line.split("\t")[0];
+      const fullCommit = await execCommand(`git rev-parse ${hash}`);
+      if (fullCommit) {
+        commitMap[id] = fullCommit;
+        console.log(`  📄 ${id} → ${fullCommit.slice(0, 7)}`);
+      }
+    }

219-239: Pass changeset IDs to the new helper; keep filtering out “Version Packages” in JS

Aligns with the portable helper above.

-    const commitMap = await getChangesetCommits();
+    const commitMap = await getChangesetCommits(
+      releasePlan.changesets.map((c) => c.id),
+    );
🧹 Nitpick comments (4)
scripts/generate-changelog.ts (4)

52-59: Anchor the date regex; reduce backtracking risk

Use start-of-line anchor and multiline flag; simpler and safer matching.

-  const dateRegex = new RegExp(`## ${date}(?: #\\d+)?`, "g");
+  const dateRegex = new RegExp(`^## ${date}(?: #\\d+)?$`, "gm");

97-101: Avoid hard‑coding repo; read from env with fallback

Helps forks/CI and local clones.

-function createCommitLink(commitHash: string): string {
-  const repo = "daangn/stackflow";
+function createCommitLink(commitHash: string): string {
+  const repo = process.env.GITHUB_REPOSITORY || "daangn/stackflow";
   const shortHash = commitHash.slice(0, 7);
   return `[\`${shortHash}\`](https://github.com/${repo}/commit/${commitHash})`;
}

106-114: Harden git exec: set timeout and larger buffer

Prevents hanging and buffer overflows on large logs.

-  try {
-    const { stdout } = await execAsync(command);
+  try {
+    const { stdout } = await execAsync(command, {
+      timeout: 30000,
+      maxBuffer: 10 * 1024 * 1024,
+    });
     return stdout.trim();

287-323: Inject manual content blocks into the markdown

Preserve curated notes per date.

   for (const entry of sortedEntries) {
     markdown += `## ${entry.date}\n\n`;
+
+    // Optional manual content block
+    if (entry.manualContent && entry.manualContent.trim()) {
+      markdown += `<!-- MANUAL_CONTENT_START -->\n${entry.manualContent}\n<!-- MANUAL_CONTENT_END -->\n\n`;
+    }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories
  • 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 2ce34d1 and d110157.

📒 Files selected for processing (2)
  • docs/next.config.mjs (1 hunks)
  • scripts/generate-changelog.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Write source in TypeScript with strict typing enabled across the codebase

Files:

  • scripts/generate-changelog.ts
🪛 ast-grep (0.39.6)
scripts/generate-changelog.ts

[warning] 55-55: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(## ${date}(?: #\\d+)?, "g")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: stackflow-docs

Comment on lines +241 to +244
date: dateKey,
changesets: changesetEntries,
manualContent: manualContents[dateKey],
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Collected manualContent is never rendered

You store manualContent but generateChangelogMarkdown doesn’t inject it, so it’s dropped.

Add rendering in generateChangelogMarkdown (see suggestion below).

🤖 Prompt for AI Agents
In scripts/generate-changelog.ts around lines 241–244, the collected
manualContent is added to the per-date payload but generateChangelogMarkdown
never uses it, so manual notes are dropped; update generateChangelogMarkdown (or
the template it uses) to accept a manualContent field and render its markdown
for each date entry (preferably immediately after the changesets list for that
date), skipping if empty; ensure the function signature and callers are updated
to pass the manualContent and that the rendered output preserves raw markdown
(no double-escaping) and is included in the final changelog output.

Copy link

@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

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories
  • 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 d110157 and 0d91294.

📒 Files selected for processing (1)
  • docs/pages/docs/changelog.ko.mdx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: stackflow-docs

Copy link

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

🧹 Nitpick comments (4)
docs/scripts/generate-llms-txt.ts (4)

10-19: Consider making file operations async or removing async keyword.

The function is declared as async but uses synchronous file operations (writeFileSync). For consistency and better I/O performance, consider using the async fs.promises API. Alternatively, if synchronous operations are preferred, remove the async keyword since no await is used.

Apply this diff to use async file operations:

-async function generateLlmsFull() {
+async function generateLlmsFull(): Promise<void> {
   const pages = getAllPages();
   const content = pages
     .map((page) => `# ${page.title}\n\n${page.content}`)
     .join("\n\n");
 
   const outputPath = path.join(process.cwd(), "public/llms-full.txt");
-  fs.writeFileSync(outputPath, content);
+  await fs.promises.writeFile(outputPath, content, "utf-8");
   console.log(`Generated ${outputPath}`);
 }

As per coding guidelines, TypeScript with strict typing should be used across the codebase.


21-36: Add return type annotation for strict typing.

The function correctly uses async/await for the remark processing, but lacks an explicit return type annotation.

Apply this diff:

-async function generateLlmsChangelog() {
+async function generateLlmsChangelog(): Promise<void> {
   const changelogPath = path.join(process.cwd(), "pages/docs/changelog.en.mdx");
   const fileContent = fs.readFileSync(changelogPath, "utf-8");
   const { content } = matter(fileContent);

As per coding guidelines, strict typing should be enabled across the codebase.


38-51: Consider making file operations async or removing async keyword.

Similar to generateLlmsFull, this function is declared as async but uses synchronous operations. Apply the same consistency improvement here.

Apply this diff:

-async function generateLlmsIndex() {
+async function generateLlmsIndex(): Promise<void> {
   const content = `
 # Stackflow Documentation for LLMs
 
 ## Documentation Sets
 
 - [llms-full.txt](${new URL("/llms-full.txt", baseUrl)}): Complete documentation of Stackflow
 - [llms-changelog.txt](${new URL("/llms-changelog.txt", baseUrl)}): Latest updates and version history
 `.trim();
 
   const outputPath = path.join(process.cwd(), "public/llms.txt");
-  fs.writeFileSync(outputPath, content);
+  await fs.promises.writeFile(outputPath, content, "utf-8");
   console.log(`Generated ${outputPath}`);
 }

As per coding guidelines, strict typing should be applied.


53-70: Good error handling and directory management.

The main function properly ensures the output directory exists and includes appropriate error handling with logging and exit code. The sequential execution of generators is clear and correct.

For consistency with strict typing guidelines, consider adding a return type annotation:

-async function main() {
+async function main(): Promise<void> {
   try {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories
  • 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 0d91294 and 5df7462.

⛔ Files ignored due to path filters (10)
  • .yarn/cache/@esbuild-darwin-arm64-npm-0.25.12-2a5a9f9710-10.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@esbuild-darwin-x64-npm-0.25.12-157b2f4f8a-10.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@esbuild-linux-arm64-npm-0.25.12-a5aaa0e70e-10.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@esbuild-linux-ia32-npm-0.25.12-3b5addbfbb-10.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@esbuild-linux-x64-npm-0.25.12-07c7c22cce-10.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/esbuild-npm-0.25.12-352393c4bd-bc9c03d64e.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/get-tsconfig-npm-4.13.0-009b232bdd-3603c6da30.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/resolve-pkg-maps-npm-1.0.0-135b70c854-0763150adf.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/tsx-npm-4.20.6-78231068b5-16396df25c.zip is excluded by !**/.yarn/**, !**/*.zip
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (4)
  • .pnp.cjs (76 hunks)
  • docs/.gitignore (1 hunks)
  • docs/package.json (3 hunks)
  • docs/scripts/generate-llms-txt.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/package.json
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Write source in TypeScript with strict typing enabled across the codebase

Files:

  • docs/scripts/generate-llms-txt.ts
🧬 Code graph analysis (1)
docs/scripts/generate-llms-txt.ts (2)
docs/utils/get-all-pages.ts (1)
  • getAllPages (13-39)
docs/utils/constants.ts (1)
  • baseUrl (1-4)
🪛 GitHub Actions: Integration
docs/scripts/generate-llms-txt.ts

[error] 1-1: Command tsx failed with Error: spawn tsx ENOENT. Is the command on your path?

🪛 GitHub Actions: Release
docs/scripts/generate-llms-txt.ts

[error] 1-1: Command 'tsx scripts/generate-llms-txt.ts' failed. spawn ENOENT: 'tsx' not found on PATH. Install 'tsx' or adjust build to use an available runner (e.g., node).

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Workers Builds: stackflow-docs
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (4)
docs/.gitignore (1)

3-6: LGTM! Appropriate ignore patterns for generated LLMS artifacts.

The gitignore entries correctly exclude the generated LLMS documentation files (llms-full.txt, llms-changelog.txt, llms.txt) that are created by the new build script.

docs/scripts/generate-llms-txt.ts (2)

1-8: Imports are well-organized and appropriate.

The use of the node: protocol prefix for built-in modules is a modern best practice, and the dependencies align with the script's markdown processing requirements.


1-1: ****

The original concern about a missing tsx command is not valid. Verification confirms:

  • tsx is already declared as a devDependency in docs/package.json at version ^4.20.6
  • All GitHub Actions workflows (build.yml, integration.yml, release.yml) run yarn install --immutable before executing any build steps
  • The script is correctly invoked via yarn build:llms, which resolves tsx from node_modules/.bin/
  • The hardcoded path to pages/docs/changelog.en.mdx is correct for the execution context (resolves to docs/pages/docs/changelog.en.mdx when the script runs from the docs folder)

No pipeline failures related to the missing tsx command should occur with the current configuration.

Likely an incorrect or invalid review comment.

.pnp.cjs (1)

118-130: Auto-generated dependency manifest—verify package.json changes instead.

This file is auto-generated by Yarn and reflects the current lock state. The hunks show legitimate dependency additions (e.g., @changesets/* for changelog generation, remark/mdast/micromark for markdown processing) and version bumps (esbuild to 0.25.12) that align with the PR's documentation infrastructure goals.

However, reviewing this file directly is not actionable. To verify these changes are correct:

  • Review the corresponding package.json changes to see which dependencies were explicitly added and which versions were specified.
  • Confirm that @changesets/*, remark, and related markdown packages are pinned to intentional versions (e.g., are they dev-only dependencies?).
  • Verify no breaking version jumps in transitive dependencies.

Also applies to: 2541-2555, 10163-10195, 16160-16283, 17506-17517

Copy link

@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

♻️ Duplicate comments (5)
scripts/generate-changelog.ts (4)

120-168: Don't cap to 10 changesets; use release plan IDs and avoid Unix-only commands.

The pipeline find .changeset -name '*.md' -not -name 'README.md' | head -10 silently limits processing to 10 changesets and relies on Unix-specific tools (find, grep, head, cut). Instead, derive the list of changeset files from releasePlan.changesets.map(c => c.id) and use only Git commands for portability.

Based on past review comments, this is a known issue that remains unresolved.

Apply the suggested fix from the previous review to pass changeset IDs to the function and build paths programmatically:

-async function getChangesetCommits(): Promise<Record<string, string>> {
+async function getChangesetCommits(ids: string[]): Promise<Record<string, string>> {
   try {
-    // .changeset 폴더의 .md 파일들 찾기 (README.md 제외)
-    const files = await execCommand(
-      "find .changeset -name '*.md' -not -name 'README.md' | head -10",
-    );
-
-    if (!files) {
-      console.log("📝 No changeset files found in .changeset folder");
-
-      return {};
-    }
-
-    const fileList = files.split("\n").filter((file) => file.trim());
-    console.log(`📊 Found ${fileList.length} changeset files:`, fileList);
-
-    // 각 파일별로 main 브랜치에 머지된 commit 찾기
+    // Release plan에 등장하는 changeset ID들만 처리
+    const fileList = ids.map((id) => `.changeset/${id}.md`);
+    console.log(`📊 Resolving ${fileList.length} changeset files from release plan`);
+
     const commitMap: Record<string, string> = {};
     for (const file of fileList) {
-      // changeset ID 추출 (파일명에서 .md 제거)
       const changesetId = file.split("/").pop()?.replace(".md", "") || "";
-
-      // Version Packages 커밋을 제외하고 main 브랜치에 머지된 커밋 찾기
+      // main 브랜치 첫 머지 커밋 (Version Packages 제외)
       const commit = await execCommand(
         `git log --oneline --first-parent main -- "${file}" | grep -v "Version Packages" | head -1 | awk '{print $1}'`,
       );

Then update the call site at line 221:

-    const commitMap = await getChangesetCommits();
+    const commitMap = await getChangesetCommits(releasePlan.changesets.map((c) => c.id));

241-244: Render manualContent in the generated changelog.

The manualContent is collected from existing changelogs but generateChangelogMarkdown never outputs it, so manual notes are silently dropped.

Based on past review comments, this is a known issue that remains unresolved. Update generateChangelogMarkdown to render the manualContent field for each entry (preferably after the changesets list), ensuring it's included in the final output.


451-451: Handle first-run when changelog file doesn't exist.

readFile will throw if docs/pages/docs/changelog.en.mdx is missing. Wrap in try-catch and default to empty string for initial runs.

Based on past review comments, this is a known issue that remains unresolved.

-    const existingContent = await readFile(changelogEnPath, "utf-8");
+    let existingContent = "";
+    try {
+      existingContent = await readFile(changelogEnPath, "utf-8");
+    } catch (e: any) {
+      if (e?.code !== "ENOENT") throw e;
+      console.log("🆕 No existing changelog; starting fresh");
+    }

469-473: Read Korean changelog separately to preserve KO content.

Currently, markdownKo is built using English existingContent, which overwrites Korean frontmatter and manual blocks.

Based on past review comments, this issue was marked as addressed but the code still uses existingContent (English) for both EN and KO generation. Read the Korean file separately:

+    // Read KO content and manual blocks
+    let existingContentKo = "";
+    try {
+      existingContentKo = await readFile(changelogKoPath, "utf-8");
+    } catch (e: any) {
+      if (e?.code !== "ENOENT") throw e;
+      console.log("🆕 No existing changelog.ko.mdx; starting fresh");
+    }
+    const manualContentsKo = await extractManualContent(changelogKoPath);
+
+    // Build entries separately so KO manual content for today's date is preserved
+    const entriesKo = await organizeChangelogEntries(
+      releasePlan,
+      manualContentsKo,
+      existingContentKo,
+    );
+
     const markdownKo = generateChangelogMarkdown(
-      entries,
-      existingContent,
+      entriesKo,
+      existingContentKo,
       "변경 이력",
     );
package.json (1)

14-14: Migrate esbuild configs or add per-package type overrides before setting "type": "module".

Adding "type": "module" converts all .js files to ESM, but multiple esbuild.config.js files across the monorepo still use CommonJS require() syntax and will fail when parsed as ESM.

Based on past review comments, this is a known issue that remains unresolved. Either:

  • Migrate each esbuild.config.js to .mjs or use ESM import/export syntax, or
  • Add "type": "commonjs" to each extension's package.json to override the root setting

Verify all affected packages before merging.

🧹 Nitpick comments (1)
docs/tsconfig.json (1)

10-10: Consider enabling TypeScript strict mode.

The configuration disables strict mode ("strict": false), which reduces type safety during compilation. While this is pragmatic for documentation-only build scripts, enabling strict mode would catch more potential issues early.

Apply this diff to enable strict mode:

-    "strict": false,
+    "strict": true,

Alternatively, if you prefer a phased approach, you can keep the current setting for now and enable it incrementally as the docs tooling matures.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories
  • 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 ce59936 and af6e8f4.

⛔ Files ignored due to path filters (52)
  • .yarn/cache/@changesets-assemble-release-plan-npm-6.0.9-e01af97ef4-f84656eabb.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@changesets-git-npm-3.0.4-c1d351b2f6-4f5a1f3354.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@changesets-read-npm-0.6.5-fc55502eb7-fec0ac2880.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@esbuild-darwin-arm64-npm-0.25.12-2a5a9f9710-10.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@esbuild-darwin-x64-npm-0.25.12-157b2f4f8a-10.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@esbuild-linux-arm64-npm-0.25.12-a5aaa0e70e-10.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@esbuild-linux-ia32-npm-0.25.12-3b5addbfbb-10.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/@esbuild-linux-x64-npm-0.25.12-07c7c22cce-10.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/esbuild-npm-0.25.12-352393c4bd-bc9c03d64e.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/get-tsconfig-npm-4.13.0-009b232bdd-3603c6da30.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-find-and-replace-npm-3.0.2-700884f061-446561aa95.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-from-markdown-npm-2.0.2-b327f875e3-69b207913f.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-autolink-literal-npm-2.0.1-dd870d9308-d933b42feb.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-footnote-npm-2.1.0-d8da32ba7c-5fac0f64d1.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-npm-3.1.0-933de2cdb5-d66809a070.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-strikethrough-npm-2.0.0-d16d95c318-b1abc137d7.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-table-npm-2.0.0-45a74f064b-a043d60d72.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-gfm-task-list-item-npm-2.0.0-cb1270a10f-679a3ff09b.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-phrasing-npm-4.1.0-30939ebbcd-3a97533e8a.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-to-markdown-npm-2.1.2-40d984eac3-ab494a32f1.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/mdast-util-to-string-npm-4.0.0-fc8d9714a5-f4a5dbb9ea.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-core-commonmark-npm-2.0.3-5e317c62b2-2b98b9eba1.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-autolink-literal-npm-2.1.0-8fcb271412-933b9b96ca.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-footnote-npm-2.1.0-1cf783dd36-7e019414e3.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-npm-3.0.0-d154ab531f-8493d10417.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-strikethrough-npm-2.1.0-b2aa188eba-eaf2c7b1e3.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-table-npm-2.1.1-7b9f4422c9-0391ead408.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-tagfilter-npm-2.0.0-c5ad486636-c5e3f8cdf2.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-extension-gfm-task-list-item-npm-2.1.0-b717607894-c5f72929f0.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-factory-destination-npm-2.0.1-2b4ab89121-9c4baa9ca2.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-factory-label-npm-2.0.1-2ce9fdcfd2-bd03f5a75f.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-factory-space-npm-2.0.1-36b4717310-1bd68a017c.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-factory-title-npm-2.0.1-a5f7a4ac37-b4d2e4850a.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-factory-whitespace-npm-2.0.1-2d7cfaf8ae-67b3944d01.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-npm-4.0.2-99b2e4c11c-1b85e49c8f.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-chunked-npm-2.0.1-27444b1e7b-f8cb2a67bc.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-classify-character-npm-2.0.1-127a4a9c2a-4d8bbe3a6d.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-combine-extensions-npm-2.0.1-9810c0bf8d-5d22fb9ee3.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-decode-numeric-character-reference-npm-2.0.2-c2d481632e-ee11c8bde5.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-decode-string-npm-2.0.1-72716f39ea-2f517e4c61.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-html-tag-name-npm-2.0.1-eb560993c8-dea365f5ad.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-normalize-identifier-npm-2.0.1-336335e80e-1eb9a289d7.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-resolve-all-npm-2.0.1-50f997ec4c-9275f3ddb6.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/micromark-util-subtokenize-npm-2.1.0-2452c9ae9b-5f18c70cb9.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/remark-gfm-npm-4.0.1-f55aaba8ef-86899862cf.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/remark-npm-15.0.1-0f67091876-671eae3a44.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/remark-parse-npm-11.0.0-6484fba69e-59d584be56.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/remark-stringify-npm-11.0.0-b41a557b8d-32b2f6093b.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/resolve-pkg-maps-npm-1.0.0-135b70c854-0763150adf.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/tsx-npm-4.20.6-78231068b5-16396df25c.zip is excluded by !**/.yarn/**, !**/*.zip
  • .yarn/cache/unified-npm-11.0.5-ac5333017e-d9e6e88900.zip is excluded by !**/.yarn/**, !**/*.zip
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (21)
  • .changeset/chatty-breads-watch.md (1 hunks)
  • .pnp.cjs (76 hunks)
  • docs/.gitignore (1 hunks)
  • docs/next.config.mjs (1 hunks)
  • docs/package.json (3 hunks)
  • docs/pages/docs/_meta.en.json (1 hunks)
  • docs/pages/docs/_meta.ko.json (1 hunks)
  • docs/pages/docs/ai-integration/_meta.en.json (1 hunks)
  • docs/pages/docs/ai-integration/_meta.ko.json (1 hunks)
  • docs/pages/docs/ai-integration/llms-txt.en.mdx (1 hunks)
  • docs/pages/docs/ai-integration/llms-txt.ko.mdx (1 hunks)
  • docs/pages/docs/changelog.en.mdx (1 hunks)
  • docs/pages/docs/changelog.ko.mdx (1 hunks)
  • docs/pages/docs/get-started/_meta.en.json (1 hunks)
  • docs/pages/docs/get-started/_meta.ko.json (1 hunks)
  • docs/scripts/generate-llms-txt.ts (1 hunks)
  • docs/tsconfig.json (1 hunks)
  • docs/utils/constants.ts (1 hunks)
  • docs/utils/get-all-pages.ts (1 hunks)
  • package.json (2 hunks)
  • scripts/generate-changelog.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • docs/pages/docs/ai-integration/_meta.ko.json
🚧 Files skipped from review as they are similar to previous changes (6)
  • docs/scripts/generate-llms-txt.ts
  • docs/pages/docs/changelog.ko.mdx
  • docs/pages/docs/get-started/_meta.en.json
  • docs/utils/get-all-pages.ts
  • docs/pages/docs/changelog.en.mdx
  • docs/next.config.mjs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Write source in TypeScript with strict typing enabled across the codebase

Files:

  • docs/utils/constants.ts
  • scripts/generate-changelog.ts
.changeset/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Include a Changeset entry for any user-facing package change

Files:

  • .changeset/chatty-breads-watch.md
🧬 Code graph analysis (1)
docs/utils/constants.ts (1)
.pnp.cjs (1)
  • URL (21314-21314)
🪛 ast-grep (0.40.0)
scripts/generate-changelog.ts

[warning] 55-55: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(## ${date}(?: #\\d+)?, "g")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🪛 LanguageTool
docs/pages/docs/ai-integration/llms-txt.ko.mdx

[grammar] ~5-~5: El plural de les sigles no es marca gràficament.
Context: --- title: LLMs.txt --- # LLMs.txt 대규모 언어 모델(LLM)이 Stackflow를 쉽게 이해할 ...

(SIGLES)


[grammar] ~7-~7: El plural de les sigles no es marca gràficament.
Context: ...대규모 언어 모델(LLM)이 Stackflow를 쉽게 이해할 수 있도록 LLMs.txt를 제공합니다. ### 구조 다음과 같은 LLMs.txt 파일...

(SIGLES)


[grammar] ~11-~11: El plural de les sigles no es marca gràficament.
Context: ... 수 있도록 LLMs.txt를 제공합니다. ### 구조 다음과 같은 LLMs.txt 파일들을 제공합니다: - [llms.txt](https://s...

(SIGLES)


[typographical] ~13-~13: Símbol sense parella: sembla que falta «[».
Context: ...다음과 같은 LLMs.txt 파일들을 제공합니다: - llms.txt: LLMs.tx...

(UNPAIRED_BRACKETS)


[grammar] ~13-~13: El plural de les sigles no es marca gràficament.
Context: ...ms.txt](https://stackflow.so/llms.txt): LLMs.txt 파일들의 구조를 제공하는 메인 파일입니다. - [llms-ful...

(SIGLES)


[typographical] ~14-~14: Símbol sense parella: sembla que falta «[».
Context: ...파일들의 구조를 제공하는 메인 파일입니다. - llms-full.txt: St...

(UNPAIRED_BRACKETS)


[typographical] ~15-~15: Símbol sense parella: sembla que falta «[».
Context: ...low의 모든 문서를 포함합니다. - [llms-changelog.txt](https://stackflow.so/llms-changelog.txt...

(UNPAIRED_BRACKETS)


[grammar] ~19-~19: El plural de les sigles no es marca gràficament.
Context: ...### Cursor Cursor의 @docs 기능을 사용하여 프로젝트에 LLMs.txt 파일을 포함할 수 있습니다. [**Cursor @docs에 대...

(SIGLES)


[typographical] ~21-~21: Símbol sense parella: sembla que falta «[».
Context: ...함할 수 있습니다. [Cursor @docs에 대해 자세히 알아보기](https://docs.cursor.com/context/@-symbo...

(UNPAIRED_BRACKETS)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Workers Builds: stackflow-docs
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (13)
.pnp.cjs (1)

118-130: This is an auto-generated file; verify dependency updates align with PR objectives.

The .pnp.cjs file is auto-generated by Yarn and reflects package dependency updates. The changes include:

  • Changesets packages (assemble-release-plan, cli, config, pre, read, types): Used for changelog automation, supporting the PR goal of adding changelog functionality.
  • Remark/markdown packages (remark, remark-gfm, remark-parse, remark-stringify, mdast-util-, micromark-): Required for markdown processing, supporting LLMs.txt and documentation generation.
  • Build tooling (esbuild 0.25.12, tsx 4.20.6, get-tsconfig 4.13.0): Updated versions with appropriate dependency resolution.
  • New packages (resolve-pkg-maps, gray-matter): gray-matter enables YAML/frontmatter parsing, useful for documentation headers.

These updates appear intentional and aligned with the PR's documentation infrastructure goals. However, ensure that:

  1. Any major version bumps (especially in changesets and remark) don't introduce breaking changes to your tooling.
  2. This file is regenerated as part of your CI/build process rather than manually maintained.

Also applies to: 2541-2555, 6373-6397, 10160-10195, 16160-16283, 17506-17517

docs/.gitignore (1)

5-6: LGTM!

The ignore patterns correctly exclude generated LLMs.txt files from version control.

docs/pages/docs/get-started/_meta.ko.json (1)

7-8: LGTM!

The Korean translation metadata is correctly added with proper JSON formatting.

docs/pages/docs/_meta.en.json (1)

4-5: LGTM!

The English metadata entries are correctly added for the new AI Integration and Changelog sections.

docs/pages/docs/ai-integration/llms-txt.ko.mdx (1)

1-21: LGTM!

The Korean documentation correctly describes the LLMs.txt structure and usage with AI tools. The static analysis warnings are false positives (Catalan grammar rules incorrectly applied to Korean text).

docs/utils/constants.ts (1)

1-4: LGTM!

The baseUrl constant correctly handles development and production environments with appropriate fallback. The localhost port 6006 aligns with the dev script configuration.

docs/package.json (2)

8-9: LGTM!

The build workflow correctly chains LLMs generation before the Next.js build, and tsx is properly added as a devDependency to execute the TypeScript generation script.


31-41: LGTM!

The added dependencies (gray-matter for frontmatter parsing, remark ecosystem for Markdown processing, and tsx for TypeScript execution) appropriately support the LLMs text generation workflow.

package.json (1)

33-33: Patch is compatible with version 6.0.9—no action needed.

There are no breaking changes between version 6.0.6 and 6.0.9; these were patch releases only. The patch file targets the compiled dist code, which remains stable across patch releases. The resolution selector @changesets/assemble-release-plan@npm:^6.0.6 correctly matches version 6.0.9, and the patch will apply cleanly without issues.

docs/pages/docs/_meta.ko.json (1)

1-6: Korean metadata keys added correctly.

The translations for the new AI integration and changelog sections are semantically accurate and follow the existing metadata structure.

.changeset/chatty-breads-watch.md (1)

1-5: Changeset entry correctly formatted and required.

The changeset properly documents a user-facing documentation package change with an appropriate "minor" version bump. The description is clear and concise. This satisfies the coding guideline for user-facing package changes.

docs/pages/docs/ai-integration/_meta.en.json (1)

1-3: AI integration metadata added correctly.

The metadata properly maps the LLMs.txt documentation route to its display name. Structure is consistent with framework conventions.

docs/pages/docs/ai-integration/llms-txt.en.mdx (1)

1-21: Documentation page is well-structured and clearly written.

The content effectively explains the LLMs.txt setup with clear sections for structure and usage. The three file variants are well-differentiated, and the Cursor integration example provides practical value to users.

Please verify during deployment testing that the three LLMs.txt files (llms.txt, llms-full.txt, llms-changelog.txt) will be generated and available at the URLs referenced in lines 13-15. Also confirm the external Cursor documentation link remains valid.

Copy link

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

♻️ Duplicate comments (4)
package.json (1)

14-14: Verify ESM migration is complete before merging.

This change converts the entire monorepo to ES modules. As flagged in previous reviews, multiple esbuild.config.js files throughout the codebase still use CommonJS require() syntax and will fail when parsed as ESM. Ensure all affected build configuration files have been migrated to ESM syntax or have local "type": "commonjs" overrides in their package.json files.

docs/scripts/generate-changelog.ts (3)

123-171: Remove 10-entry cap and use cross-platform approach to derive changeset commits.

The current implementation has two critical issues:

  1. head -10 on line 127 silently limits processing to 10 changesets, potentially dropping entries
  2. The Unix pipeline (find, grep, head, cut) won't work on Windows

As previously suggested, derive the changeset file list from releasePlan.changesets by mapping IDs to .changeset/<id>.md paths, then use git commands directly without shell pipelines. This ensures all changesets are processed and improves cross-platform compatibility.


243-247: Manual content is collected but never rendered in the output.

The manualContent field is added to entries but generateChangelogMarkdown (lines 260-329) doesn't render it. Manual notes from MANUAL_CONTENT_START/END blocks will be silently dropped.

Update generateChangelogMarkdown to render entry.manualContent (if present) within each date section, preferably after the changesets list.


466-470: Korean changelog may lose locale-specific front-matter and manual content.

Lines 466-470 generate markdownKo using the same existingContent (from English file, line 448) and manualContents (from English file, lines 450-451). This means Korean-specific front-matter and manual content blocks will be overwritten with English content.

Read changelogKoPath separately and extract its manual content to preserve Korean locale-specific information.

+    console.log("📖 Reading existing Korean changelog...");
+    let existingContentKo = "";
+    try {
+      existingContentKo = await readFile(changelogKoPath, "utf-8");
+    } catch (e: any) {
+      if (e?.code !== "ENOENT") throw e;
+      console.log("🆕 No existing Korean changelog; starting fresh");
+    }
+
+    console.log("📖 Extracting Korean manual content...");
+    const manualContentsKo = await extractManualContent(changelogKoPath);
+
+    console.log("🗂️ Organizing Korean changelog entries...");
+    const entriesKo = await organizeChangelogEntries(
+      releasePlan,
+      manualContentsKo,
+      existingContentKo,
+    );
+
     console.log("📝 Generating changelog markdown...");
     const markdownEn = generateChangelogMarkdown(
       entries,
       existingContent,
       "Changelog",
     );
     const markdownKo = generateChangelogMarkdown(
-      entries,
-      existingContent,
+      entriesKo,
+      existingContentKo,
       "변경 이력",
     );
🧹 Nitpick comments (1)
.pnp.cjs (1)

118-127: This is an auto-generated lock file—verify updates came from package.json changes.

The .pnp.cjs file is Yarn's auto-generated Plug'n'Play runtime manifest and should not be manually edited. All changes shown here should result from updates to package.json and running yarn install or similar commands.

The hunks indicate significant dependency additions and version bumps that align with the PR objectives:

Verify that these dependency updates (especially version bumps) have been intentionally made in package.json and that yarn.lock was regenerated to produce this .pnp.cjs manifest.

Also applies to: 2539-2767, 2974-10201, 10976-10985, 13024-14209, 16166-16289, 17512-17523, 17684-17697

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories
  • 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 b1f6d1b and d7266b7.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (4)
  • .pnp.cjs (77 hunks)
  • docs/package.json (2 hunks)
  • docs/scripts/generate-changelog.ts (1 hunks)
  • package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/package.json
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Write source in TypeScript with strict typing enabled across the codebase

Files:

  • docs/scripts/generate-changelog.ts
🪛 ast-grep (0.40.0)
docs/scripts/generate-changelog.ts

[warning] 58-58: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(## ${date}(?: #\\d+)?, "g")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Workers Builds: stackflow-docs
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (1)
package.json (1)

22-22: LGTM! Changelog generation properly integrated into version workflow.

The script correctly prepends changelog generation before version bumping, ensuring the changelog is updated as part of the versioning process.

@orionmiz orionmiz enabled auto-merge (squash) November 25, 2025 03:40
@orionmiz orionmiz merged commit 89813a6 into main Nov 25, 2025
5 of 7 checks passed
@orionmiz orionmiz deleted the llms-txt branch November 25, 2025 03:41
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