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/@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}"
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/**"