From 03cc6972cfdfd12c831dfda7fb4bafb13ec23020 Mon Sep 17 00:00:00 2001 From: Jeremy Levartovsky <140487034+JayOfTheKeyboard@users.noreply.github.com> Date: Sat, 26 Sep 2026 23:50:23 +1000 Subject: [PATCH 1/2] fix(context): skip test/example-style directories only at the repo root `IGNORED_DIRS` was applied at every depth regardless of where the scan started. In a whole-repo scan that is right: `test/`, `examples/` and `internal/` hold code, fixtures and notes. Inside a `docs_path` folder the same names are ordinary sections, and 135 of the 140 definitions set one. Measured against every git definition in the registry (GitHub trees API, default branch): 15 definitions lose real pages this way. The largest are docker (`content/manuals/build/`, 100 pages, the entire Docker Build manual), wrangler (49 Workers examples), kysely (40 of 67 pages) and bun (32 test-runner guides under `docs/guides/test/`). The set is split in two. Tooling and generated output (`node_modules`, `dist`, `out`, `.next`, `.nuxt`, `fixtures` and the `__x__` test dirs) is still skipped everywhere. The rest is skipped only when `atRepoRoot` is set, the flag #125 introduced for the same reason. vue's docs keep 27 playground code fragments (`App/template.html` and the like) under `src/examples/src/`, which the directory rule had been hiding by accident. `registry/npm/vue.yaml` now excludes `examples/src/**`, so they stay out and `examples/index.md` comes in. Three tests, each mutation-checked: removing the `atRepoRoot` guard fails the docs-folder case, disabling the root-only set fails the repo-root case, and disabling the always set fails the tooling case. Real clones agree with the tree count: kysely 27 -> 67 files, bun 303 -> 335. 230/230 in context, 93/93 in registry, package lint clean. --- .changeset/quiet-docs-sections.md | 5 +++ packages/context/src/git.test.ts | 54 +++++++++++++++++++++++++++++++ packages/context/src/git.ts | 43 ++++++++++++++++-------- registry/npm/vue.yaml | 4 +++ 4 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 .changeset/quiet-docs-sections.md diff --git a/.changeset/quiet-docs-sections.md b/.changeset/quiet-docs-sections.md new file mode 100644 index 0000000..454df16 --- /dev/null +++ b/.changeset/quiet-docs-sections.md @@ -0,0 +1,5 @@ +--- +"@neuledge/context": patch +--- + +Keep documentation sections whose folder shares a name with a skipped repo directory (`build`, `examples`, `test`, `dev`, `internal`, `plans`, `spec`, and the rest) when the scan starts inside a docs folder. These names were skipped at every depth, so with `docs_path` set a real section vanished and the build still reported success: `docker/docs` lost its whole Docker Build manual (`content/manuals/build/`, 100 pages), `cloudflare-docs` lost 49 Workers examples, `kysely` lost 40 of its 67 pages and `bun` lost its 32 test-runner guides. Tooling directories (`node_modules`, `dist`, `out`, `fixtures`, `__tests__` and similar) are still skipped everywhere, and a whole-repo scan skips everything it did before. diff --git a/packages/context/src/git.test.ts b/packages/context/src/git.test.ts index e21d61d..767c865 100644 --- a/packages/context/src/git.test.ts +++ b/packages/context/src/git.test.ts @@ -242,3 +242,57 @@ describe("readLocalDocsFiles — repo-meta filenames", () => { expect(paths.sort()).toEqual(["docs/guide.md", "docs/security.md"]); }); }); + +describe("readLocalDocsFiles — directory filters", () => { + let dir: string; + + beforeEach(() => { + dir = mkdtempSync(join(tmpdir(), "ctx-localdirs-")); + }); + + afterEach(() => { + rmSync(dir, { recursive: true, force: true }); + }); + + const write = (rel: string, body: string): void => { + const full = join(dir, rel); + mkdirSync(join(full, ".."), { recursive: true }); + writeFileSync(full, body); + }; + + it("skips test and example directories when scanning a repo root", () => { + write("README.md", "# Project\n\nContent.\n"); + write("test/README.md", "# Test notes\n\nFixture setup.\n"); + write("examples/basic/README.md", "# Basic example\n\nRun it.\n"); + write("src/internal/NOTES.md", "# Internal\n\nScratch.\n"); + + const paths = readLocalDocsFiles(dir).map((f) => f.path); + + expect(paths).toEqual(["README.md"]); + }); + + it("keeps doc sections named like non-doc directories inside a docs folder", () => { + write("docs/manuals/build/bake.md", "# Bake\n\nBuild with bake.\n"); + write("docs/guides/test/bail.md", "# Bail\n\nStop after failures.\n"); + write("docs/workers/examples/ab-testing.md", "# A/B testing\n\nSplit.\n"); + + const paths = readLocalDocsFiles(dir, { path: "docs" }).map((f) => f.path); + + expect(paths.sort()).toEqual([ + "docs/guides/test/bail.md", + "docs/manuals/build/bake.md", + "docs/workers/examples/ab-testing.md", + ]); + }); + + it("still skips tooling directories inside a docs folder", () => { + write("docs/guide.md", "# Guide\n\nContent.\n"); + write("docs/node_modules/pkg/README.md", "# Dependency\n\nVendored.\n"); + write("docs/__tests__/page.md", "# Test page\n\nFixture.\n"); + write("docs/bench/fixtures/blog-post.html", "

Fixture

\n"); + + const paths = readLocalDocsFiles(dir, { path: "docs" }).map((f) => f.path); + + expect(paths).toEqual(["docs/guide.md"]); + }); +}); diff --git a/packages/context/src/git.ts b/packages/context/src/git.ts index 12571dc..df93da1 100755 --- a/packages/context/src/git.ts +++ b/packages/context/src/git.ts @@ -127,32 +127,44 @@ const DOCUMENTATION_EXTENSIONS = [ ]; /** - * Directories to ignore during markdown indexing. - * Includes test directories, internal docs, and other non-user-facing content. + * Directories to ignore during markdown indexing, wherever the scan starts. + * Tooling and generated output: these never hold authored documentation. */ const IGNORED_DIRS = new Set([ - // Test directories + // Test tooling "__tests__", "__test__", + "fixtures", + "__fixtures__", + "__mocks__", + // Build/generated directories + "node_modules", + "dist", + "out", + ".next", + ".nuxt", +]); + +/** + * Directories to ignore only when the scan starts at the repo root. + * In a code repo these hold tests, internal notes, and code samples; inside a + * docs folder they are ordinary sections — docker's content/manuals/build/ is + * the whole Docker Build manual, and bun's docs/guides/test/ documents its + * test runner. + */ +const REPO_ROOT_IGNORED_DIRS = new Set([ + // Test directories "test", "tests", "spec", "specs", - "fixtures", - "__fixtures__", - "__mocks__", // Internal/development directories "internal", "dev", "plans", ".plans", - // Build/generated directories - "node_modules", - "dist", + // Build directories "build", - "out", - ".next", - ".nuxt", // Other non-doc directories "examples", // Often contains code samples, not docs "benchmarks", @@ -446,13 +458,16 @@ function findMarkdownFiles( if (entry.isDirectory()) { // Skip test, internal, and other non-doc directories - if (IGNORED_DIRS.has(entry.name.toLowerCase())) { + const dirName = entry.name.toLowerCase(); + if ( + IGNORED_DIRS.has(dirName) || + (options.atRepoRoot && REPO_ROOT_IGNORED_DIRS.has(dirName)) + ) { continue; } // Filter locale directories unless --lang all or specific lang matches if (isLocaleDir(entry.name)) { - const dirName = entry.name.toLowerCase(); // Include if: all languages, matching lang, or default to English if ( lang === "all" || diff --git a/registry/npm/vue.yaml b/registry/npm/vue.yaml index 47a8a32..742f8c6 100644 --- a/registry/npm/vue.yaml +++ b/registry/npm/vue.yaml @@ -6,3 +6,7 @@ source: type: git url: https://github.com/vuejs/docs docs_path: src + # examples/src holds the playground code fragments (App/template.html and + # the like); examples/index.md is the page that describes them. + exclude_paths: + - "examples/src/**" From 2d504349563c02f3eed895bed569c0fa0cea7ddd Mon Sep 17 00:00:00 2001 From: Jeremy Levartovsky <140487034+JayOfTheKeyboard@users.noreply.github.com> Date: Mon, 28 Sep 2026 14:34:40 +1000 Subject: [PATCH 2/2] fix(registry): leave angular's examples and docusaurus's test pages out of their docs With test/example-style directories no longer skipped below the repo root, adev/src/content/examples/ (212 files, mostly embedded component templates) and website/_dogfooding/ (66 test pages) were pulled in. --- registry/npm/@angular/core.yaml | 4 ++++ registry/npm/@docusaurus/core.yaml | 3 +++ 2 files changed, 7 insertions(+) diff --git a/registry/npm/@angular/core.yaml b/registry/npm/@angular/core.yaml index 80367bc..5eefc10 100644 --- a/registry/npm/@angular/core.yaml +++ b/registry/npm/@angular/core.yaml @@ -10,4 +10,8 @@ versions: type: git url: https://github.com/angular/angular docs_path: adev/src/content + # examples/ holds the component templates and code the guides embed, + # not pages of their own. + exclude_paths: + - "examples/**" tag_pattern: "v{version}" diff --git a/registry/npm/@docusaurus/core.yaml b/registry/npm/@docusaurus/core.yaml index 5952d3c..67d1be0 100644 --- a/registry/npm/@docusaurus/core.yaml +++ b/registry/npm/@docusaurus/core.yaml @@ -8,4 +8,7 @@ versions: type: git url: https://github.com/facebook/docusaurus docs_path: website + # _dogfooding/ is the site's own test pages, not documentation. + exclude_paths: + - "_dogfooding/**" tag_pattern: "v{version}"