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", "