Skip to content

Fix three pre-existing breakages in the example apps and task graph - #166

Open
KayleeWilliams wants to merge 4 commits into
mainfrom
fix/example-app-build-hygiene
Open

Fix three pre-existing breakages in the example apps and task graph#166
KayleeWilliams wants to merge 4 commits into
mainfrom
fix/example-app-build-hygiene

Conversation

@KayleeWilliams

@KayleeWilliams KayleeWilliams commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Three pre-existing breakages, all surfaced by running bun run build and bun run check-types across the monorepo while working on #157. Independent of that stack, so this is a standalone PR off main.

1. bun run check-types failed on main, differently each run

tanstack, then nuxt-example, then sveltekit-example. Not a type error — every example app's check-types script began with bun run --filter leadtype build, which rm -rfs and rebuilds packages/leadtype/dist. Turbo runs the tasks in parallel, so eight of those raced on one directory and whichever app was reading dist when another deleted it lost.

Turbo already knows the dependency; the scripts were working around it. Adding ^build to the check-types task builds leadtype once, ahead of every dependent, and the per-app self-build comes out.

Verified with three consecutive full runs: 9 successful, 9 total, each time.

2. apps/astro-example could not build at all

satteri — leadtype's MDX parser — is a napi-rs module whose loader picks a platform binding with a bare require("@bruits/satteri-darwin-arm64"). Bundled into Astro's prerender chunk, that require resolves relative to dist/.prerender/chunks/, where the binding isn't reachable:

Cannot find native binding. …
Caused by: Cannot find module '@bruits/satteri-darwin-arm64'
  at requireNative (…/dist/.prerender/chunks/source_BgsvcLQ8.mjs:14045:25)

Two things were needed, and the first alone isn't enough:

  1. A resolveId hook rather than resolve.external. leadtype is a workspace package, so Astro's dependency crawl marks it noExternal — and noExternal wins. Astro 6's Vite 7 environment keys (environments.ssr / environments.prerender) don't get around that either; I tried both.
  2. satteri as an explicit dependency of the app. Under bun's isolated node_modules layout a transitive dep isn't resolvable from apps/astro-example/dist/, so externalizing without declaring just moves the failure to Cannot find package 'satteri'. Pinned at the version leadtype uses.

Verified: 51 pages built, exit 0.

3. SvelteKit ignore drift

The SvelteKit example generates into static/ rather than public/. The two ignore lists had drifted — feeds/, mcp.json, robots.txt, schema-map.xml, and both sitemaps were ignored under public/ but not under static/ — so bun run build left six untracked build artifacts in the tree, one git add -A away from being committed.

The lists now mirror each other and both use apps/*/, so a future example with either output root is covered without a third list to keep in sync.

Two pre-existing breakages, both surfaced by running the monorepo build.

`apps/astro-example` could not build at all. `satteri` — leadtype's MDX parser —
is a napi-rs module whose loader picks a platform binding with a bare
`require("@bruits/satteri-darwin-arm64")`. Bundled into Astro's prerender
chunk that require resolves relative to `dist/.prerender/chunks/`, where the
binding isn't reachable, so static generation died with "Cannot find native
binding".

Declaring it in `resolve.external` does not work: `leadtype` is a workspace
package, so Astro's dependency crawl marks it `noExternal`, and noExternal
wins. A `resolveId` hook is unambiguous. Externalizing it also means the app
has to depend on it directly — under bun's isolated layout a transitive dep is
not resolvable from `apps/astro-example/dist/` — so `satteri` is now an
explicit dependency at the version leadtype pins.

The SvelteKit example generates into `static/` rather than `public/`, and the
two ignore lists had drifted: `feeds/`, `mcp.json`, `robots.txt`,
`schema-map.xml`, and both sitemaps were ignored under `public/` but not under
`static/`, so `bun run build` left six untracked build artifacts behind. The
lists now mirror each other and both use `apps/*/`, so a future example with
either output root is covered.
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added support for the satteri parser in the Astro example application.
    • Improved handling of native components during builds.
  • Chores

    • Updated ignore rules for generated documentation and build output.
    • Streamlined type-checking workflows across example applications.
    • Improved build and validation task ordering for more reliable checks.
  • Tests

    • Improved isolation and reliability of temporary-file cleanup checks.

Walkthrough

The Astro example adds satteri and externalizes its native bindings through Vite. Workspace validation now follows upstream build tasks. The repository ignores generated outputs, and the cleanup test uses an isolated temporary directory.

Changes

Astro native parser and validation updates

Layer / File(s) Summary
Native parser dependency and bundling
apps/astro-example/package.json, apps/astro-example/astro.config.mjs
The Astro example adds satteri version ^0.9.3. Its Vite plugin externalizes satteri imports.
Validation task ordering
apps/*/package.json, turbo.json
Example check-types scripts no longer build leadtype locally. Turbo now orders check-types after upstream build and check-types tasks.
Generated output ignore rules
.gitignore
The ignore file documents separate generated-output roots and adds patterns for generated documentation, feeds, metadata, robots files, schema maps, and sitemaps.
Isolated cleanup test
packages/leadtype/src/cli.test.ts
The cleanup test uses a test-owned TMPDIR, restores the environment, and checks for leftover generated directories there.

Estimated code review effort: 2 (Simple) | ~10 minutes

Poem

A rabbit checks the Astro trail,
Native bindings stay outside the rail.
satteri joins the careful run,
Type checks follow builds already done.
Temporary files leave none behind.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the three primary fixes in the example apps and Turbo task graph.
Description check ✅ Passed The description directly explains the task graph, Astro build, and SvelteKit ignore-list changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/example-app-build-hygiene

Comment @coderabbitai help to get the list of available commands.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ℹ️ Both fixes are sound — a few rough edges inline, none blocking.

Reviewed changes — full review of 888dab2: the Astro native-binding workaround and the .gitignore generalization.

  • Astro build fix — a local Vite plugin (astro.config.mjs 6-33, registered at 36-38) marks satteri and @bruits/satteri-* external from a resolveId hook, keeping leadtype's napi-rs MDX parser out of the prerender chunk.
  • satteri declared on the app — added to apps/astro-example/package.json dependencies at ^0.9.3, so the externalized import resolves from dist/ under bun's isolated layout.
  • .gitignore generalization — the five apps/sveltekit-example/static/* entries become eleven apps/*/static/* entries mirroring the apps/*/public/* list, plus a comment on why two lists exist.
  • bun.lock — records the new dependency and incidentally corrects packages/leadtype 0.3.1 → 0.4.2.

I verified the .gitignore half end-to-end and it is correct and complete. Out roots are public for astro/fumadocs/next/nuxt and static for sveltekit only (c15t and tanstack ignore public/ wholesale locally), so apps/*/public/ + apps/*/static/ is the right pair. Every out-root artifact is now covered under both roots — feeds/schema.jsonl and schema-map.xml (src/nlweb/artifacts.ts:8-9), root mcp.json (src/mcp/card.ts:228), .well-known/, both llms*.txt, robots, both sitemaps — with search-index.json / agent-readability.json covered by docs/ and the configured /changelog/*.xml feeds covered by changelog/. Nothing tracked sits under the broadened glob (apps/astro-example/public/styles.css is the only tracked file there, matched by no pattern).

I also confirmed the plugin's blast radius is safe even though it applies to every Vite environment: the client graph cannot reach satteri, since the app's only client-side leadtype imports are leadtype/webmcp and leadtype/search/client, whose Rollup entries transitively reach none of the four satteri importers.

ℹ️ Nothing builds the example apps in CI, so both of these will regress silently

ci.yml builds, lints, typechecks and tests packages/leadtype only — no job runs astro build or any other example build. That is precisely why both of these breakages sat in main unnoticed until someone ran bun run build by hand, and why nothing stops either from coming back. The .gitignore half is self-healing once merged, but the Astro plugin is a load-bearing workaround with no test pinning it.

Technical details
# Example app builds are not covered by CI

## Affected sites
- `.github/workflows/ci.yml:32-53` — the `validate` job runs `bun run --filter leadtype build`, `lint`, `check-types`, `test`. Every step is scoped to `packages/leadtype`; no example app is ever built.
- `apps/astro-example/astro.config.mjs:24-38` (new) — the workaround this PR adds has no regression guard. If a future refactor drops the plugin, or `leadtype`'s import graph changes so `satteri` arrives by another path, CI stays green.

## Required outcome
- A merge-blocking signal that fails when an example app can no longer build, covering at minimum the Astro example that this PR just repaired.

## Suggested approach (optional)
- Add a job (or matrix leg) that runs `bun run --filter astro-example build` after the `leadtype` build + `Link CLI` steps. Note the example's `build` script already chains `bun run --filter leadtype build && bun run docs:generate`, so it is close to self-contained.
- A matrix over the example apps is the fuller version, but it is meaningfully slower — one Astro leg buys most of the protection for this specific PR.

## Open questions for the human
- Is leaving the examples out of CI a deliberate cost/runtime tradeoff? If so, this is fine to close — but then the Astro workaround is worth a comment noting it is unguarded.
- Would you rather this land as a follow-up issue than expand the scope of this PR?

ℹ️ Nitpicks

  • bun.lock:228 also corrects packages/leadtype 0.3.1 → 0.4.2, drift left behind by release commit b5857b4 rather than anything in this PR. Harmless to carry here, but worth knowing it rode along given ci.yml:30 and release.yml:55 both run bun install --frozen-lockfile.
  • apps/{next,nuxt,sveltekit}-example/test-results/.last-run.json are tracked in git — Playwright output committed in exactly the way this PR's .gitignore comment warns about. test-results/ is ignored only in apps/tanstack/.gitignore:6, and those three apps have no local .gitignore. Pre-existing and out of scope, but adjacent enough to mention; note it needs git rm --cached as well as an ignore entry, so it is not a one-line fix.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Claude Opus𝕏

Comment thread apps/astro-example/astro.config.mjs Outdated
Comment thread apps/astro-example/astro.config.mjs Outdated
Comment thread apps/astro-example/package.json
`bun run check-types` failed on main, and failed a *different* app each run —
tanstack, then nuxt-example, then sveltekit-example. Not a type error: every
example app's `check-types` script began with `bun run --filter leadtype
build`, which rm -rf's and rebuilds `packages/leadtype/dist`. Turbo runs the
tasks in parallel, so eight of those raced on one directory and whichever app
was reading dist when another deleted it lost.

Turbo already knows the dependency; the scripts were working around it. Adding
`^build` to the `check-types` task builds leadtype once, ahead of every
dependent, and the per-app self-build comes out.

Verified with three consecutive full runs: 9 successful, 9 total, each time.
@KayleeWilliams KayleeWilliams changed the title Fix the Astro example build and the SvelteKit ignore drift Fix three pre-existing breakages in the example apps and task graph Aug 4, 2026

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Important

The check-types half of the race is fixed correctly, but the identical rm -rf dist race is still live in turbo run build.

Reviewed changes — delta since the prior review of 888dab2; the new commit 81adabb is the task-graph fix.

  • Moved the leadtype build into turbo's task graphcheck-types becomes dependsOn: ["^build", "^check-types"] (turbo.json:16-18), so packages/leadtype/dist is produced once ahead of every dependent.
  • Dropped the per-app self-build — the bun run --filter leadtype build && prefix comes out of all seven apps' check-types scripts.
  • Refreshed a tracked generated artifactapps/next-example/app/generated/docs-mdx-map.ts is re-sorted and gains nine doc routes (mdxSlugs 41 → 50), which also widens generateStaticParams.

I confirmed the diagnosis rather than taking it from the description: packages/leadtype/rollup.config.ts:66-71 has a cleanDist plugin doing rm("dist", { recursive: true, force: true }) in buildStart, and apps read dist by literal path — apps/next-example's docs:generate runs bun ../../packages/leadtype/dist/cli.js — so concurrent self-builds really do delete dist out from under a sibling mid-read.

The turbo semantics are right. ^build and ^check-types reference only upstream workspace dependencies, so packages/leadtype's own check-types node gets an empty prerequisite set — no self-build, no cycle. Nothing outside turbo invokes an app's check-types either: ci.yml:50 runs bun run --filter leadtype check-types only, .husky/pre-commit runs ultracite fix plus bun test, and root package.json:21 (turbo run check-types) is the sole in-repo consumer. Direct bun run --filter <app> check-types on a clean checkout does now fail, but that is the intended consequence of moving ordering into turbo, not a regression to undo — re-adding the prefix would reintroduce the race.

The docs-mdx-map.ts refresh is genuine generator output, not a hand edit: apps/next-example/scripts/build-mdx-map.mjs sorts with .sort(), the new file is sorted and the old one was not.

⚠️ turbo run build still lets seven parallel self-builds rm -rf the same dist

check-types is fixed; build is untouched. turbo.json:5-9 already had dependsOn: ["^build"], and all seven apps/*/package.json build scripts still begin with bun run --filter leadtype build. Turbo dedupes its own packages/leadtype#build node, not a raw shell command sitting inside a sibling task's script body — so after leadtype builds once, seven concurrent apps/*#build tasks each re-invoke rollup, each hitting cleanDist while a sibling is reading dist/cli.js. That is the same failure this PR exists to fix, in the task where a wiped dist is most likely to be observed.

Technical details
# The `dist` race is fixed for `check-types` but left live for `build`, `dev`, `mcp` and `test:e2e`

## Affected sites
- `turbo.json:5-9` — the `build` task (unmodified) is `dependsOn: ["^build"]`, exactly the shape that made the `check-types` prefix redundant. Nothing was removed from the app scripts to match.
- `apps/astro-example/package.json:9`, `apps/c15t-example/package.json:9`, `apps/fumadocs-example/package.json:9`, `apps/next-example/package.json:10`, `apps/nuxt-example/package.json:9`, `apps/sveltekit-example/package.json:9`, `apps/tanstack/package.json:8` — every `build` script still opens with `bun run --filter leadtype build &&`. None of these lines are in the diff.
- `apps/*/package.json` `dev` (all seven) plus `apps/tanstack/package.json:11` (`mcp`) and `:13` (`test:e2e`) carry the same prefix. `dev` is lower risk in practice because root `package.json:18` filters it to `tanstack` alone.
- `packages/leadtype/rollup.config.ts:66-71``cleanDist` runs `rm("dist", { recursive: true, force: true })` in `buildStart`, so each redundant invocation opens a window where `dist` does not exist.
- `packages/leadtype/package.json` `build` is `rollup -c ... && bun run --silent docs:generate` — a plain bun subprocess when reached via `--filter`, invisible to turbo's graph and cache, so there is no dedup or locking.

## Required outcome
- `turbo run build` must not be able to delete `packages/leadtype/dist` while a sibling app task is reading it — the same guarantee `81adabb` establishes for `check-types`.
- Whatever is decided, the `turbo.json` comment should describe the state the repo is actually in.

## Suggested approach (optional)
- Drop the `bun run --filter leadtype build &&` prefix from the seven `build` scripts and rely on the existing `^build`, mirroring what this commit did for `check-types`. `dev`, `mcp` and `test:e2e` are the same one-line change if you want them consistent.

## Open questions for the human
- Is the prefix kept in `build` deliberately, so `bun run --filter <app> build` stays self-sufficient for someone who bypasses turbo? That goal and race-freedom are in direct conflict, and `check-types` has now picked the other side — worth making the split explicit rather than incidental.
- No CI job runs `turbo run build` or `turbo run check-types`, so neither the fix nor the remaining hazard is exercised anywhere. Does that change how much you want to invest here versus in the CI gap?

ℹ️ Nitpicks

  • apps/c15t-example/README.md:25-26 still says "The dev, build, and check-types scripts all rebuild the local leadtype package", which is no longer true for check-types. It is the only README in the repo making that claim.
  • apps/next-example/app/generated/docs-mdx-map.ts is stamped Generated by scripts/build-mdx-map.mjs — do not edit and is rewritten by docs:prepare before every build and check-types, yet it is tracked — so it re-dirties the working tree on every run, which is how it came to ride along in a commit about the task graph. Same hygiene family as this PR's .gitignore change, and worth deciding whether it should be ignored instead. The refresh itself is a real improvement: nine doc routes were missing from generateStaticParams on main.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Claude Opus𝕏

Comment thread turbo.json Outdated
Comment on lines +13 to +15
// `^build` so turbo builds leadtype's dist once, ahead of every dependent.
// Each app used to run `--filter leadtype build` itself, and eight of those
// in parallel rm -rf the same dist — failing a different app every run.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Two details in this comment do not hold. The count is seven, not eight — at 888dab2 exactly seven app check-types scripts carried the prefix (turbo's 9 successful is 8 check-types tasks plus leadtype's build, which is probably where the eight came from).

And "used to run --filter leadtype build itself" is still present tense for build, dev, mcp and test:e2e, which all keep the prefix — see the body section. A future reader will trust this comment to mean the race is gone repo-wide.

The Astro attribution was wrong, and wrong in the way that matters — it told
the next reader the cause was Astro's dependency crawl marking `leadtype`
noExternal, which cannot happen: that crawl matches only packages with an
astro dep, an astro keyword, or an `astro-` name prefix, and leadtype has none.
The comment now says what is actually true and checkable — this is
monorepo-specific because `leadtype` is a linked workspace package — and
records that the per-environment Vite keys were tried too, so nobody repeats
that.

The `@bruits/satteri-` arm of the resolver was unreachable: the loader reaches
its platform binding through `createRequire`, so those ids are runtime CJS
calls Vite never resolves, and once `satteri` is external its loader is not
parsed at all. Verified by deleting it — 51 pages, exit 0 — so it is deleted.

The satteri dependency now carries a note that externalizing the import makes
it resolve to the app's copy rather than leadtype's, so the two ranges have to
move together.

The turbo comment said eight scripts; it was seven — the ninth task in turbo's
output is leadtype's own `build`. It also read as though the prefix were gone
repo-wide, when `build`, `dev`, `mcp`, and `test:e2e` still carry it. The race
is fixed for `check-types`, which is the one turbo fans out.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Important

Three of the four comment corrections are right. The fourth replaces an imprecise claim with a false one — and the false claim is the reason the remaining dist race won't get fixed.

Reviewed changes — delta since the prior review of 81adabb; the new commit 39223d4 rewrites four comments and deletes one dead code path. Only astro.config.mjs and turbo.json changed.

  • Corrected the Astro plugin's causation comment — the inaccurate noExternal attribution is gone, replaced by "monorepo-specific: leadtype is a linked workspace package, so it is bundled rather than externalized", and the record that resolve.external plus Astro 6's environments.ssr / environments.prerender equivalents were both tried is retained.
  • Deleted the unreachable @bruits/satteri- resolver arm — the hook is now if (id === NATIVE_PARSER) and NATIVE_PARSER_BINDING is removed (astro.config.mjs:38).
  • Documented the satteri version coupling — a comment at astro.config.mjs:6-9 explains that externalizing makes the import resolve to this app's copy, so leadtype's range must be kept in step.
  • Rewrote the turbo.json check-types comment — the count is corrected to seven and the scripts still carrying the self-build prefix are now named.

I verified the resolver-arm deletion is behavior-preserving rather than taking it on the comment's word. satteri/dist/index.js:13-14 statically imports only the #binding subpath, which maps to dist/binding.js; that file reaches its platform binding through createRequire(import.meta.url) followed by a runtime require('@bruits/satteri-*') — a call expression Rollup's static specifier discovery cannot see. Independently, a resolveId returning { external: true } bypasses the load/transform pipeline entirely, so index.js is never parsed once satteri is external. Nothing in the repo, in leadtype's built dist, or in packages/leadtype/src references a binding id statically. The arm was dead before this PR, and removing it is safe.

The count in the turbo.json comment is also now correct: exactly seven app check-types scripts carried the prefix, and none carry it after 81adabb.

ℹ️ Nitpicks

  • apps/astro-example/astro.config.mjs:6-9 — the new coupling comment sits above const NATIVE_PARSER = "satteri", a module specifier rather than a version range, so "Kept in step with packages/leadtype/package.json's range" reads as though this line held the range. Someone bumping satteri at apps/astro-example/package.json:23 never passes it. package.json is strict JSON and cannot carry the note itself, so there may be nowhere strictly better — but naming the dependency line explicitly in the wording would close the gap.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Claude Opus𝕏

Comment thread turbo.json
Comment on lines +16 to +18
// different app every run. Other scripts (`build`, `dev`, `mcp`,
// `test:e2e`) still carry the prefix; they are not run concurrently by
// turbo, so the race is fixed for `check-types`, not repo-wide.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

they are not run concurrently by turbo is false for build, which is the one case that matters. build (turbo.json:5-9) is dependsOn: ["^build"] — upstream-only — so once packages/leadtype#build finishes, the seven apps/*#build tasks are siblings with no edge between them and run in parallel under turbo's default --concurrency of 10. All seven still open with bun run --filter leadtype build &&, a raw shell command turbo cannot dedupe, so seven rollup runs rm -rf the shared dist while siblings read dist/cli.js.

Root package.json:17 is turbo run build, so plain bun run build reaches this. That makes the new wording worse than what it replaced: the previous comment was merely vague, whereas this one tells a future maintainer the race cannot happen here.

Technical details
# `turbo.json`'s new comment asserts a scheduling guarantee turbo does not provide

## Affected sites
- `turbo.json:16-18` — claims `build`, `dev`, `mcp` and `test:e2e` "are not run concurrently by turbo". Not accurate for any of them for the stated reason.
- `turbo.json:5-9``build` is `dependsOn: ["^build"]`, upstream-only; nothing orders the seven `apps/*#build` tasks against each other.
- `package.json:17` — root `build` is `turbo run build`, unfiltered across all workspaces.
- `apps/astro-example/package.json:9`, `apps/c15t-example/package.json:9`, `apps/fumadocs-example/package.json:9`, `apps/next-example/package.json:10`, `apps/nuxt-example/package.json:9`, `apps/sveltekit-example/package.json:9`, `apps/tanstack/package.json:8` — all seven `build` scripts still open with `bun run --filter leadtype build &&`. None of these lines are in the diff.
- `packages/leadtype/rollup.config.ts:66-71``cleanDist` runs `rm("dist", { recursive: true, force: true })` in `buildStart`, opening the window in which `dist` does not exist.

## What is actually true, per script name
- `build`**false.** Seven sibling tasks run concurrently, each re-invoking leadtype's build as a shell command invisible to turbo's graph and cache.
- `dev` — true today, but only because `package.json:18` filters to `tanstack`. `turbo.json:22-25` has no `dependsOn`, so a bare `turbo run dev` fans out to all seven, each carrying the prefix. The safety is a convention in the root script, not turbo scheduling.
- `mcp`, `test:e2e` — vacuously true: neither is a task in `turbo.json` and both exist only in `apps/tanstack`, so turbo never schedules them.

## Required outcome
- The comment must not assert a concurrency guarantee turbo does not make. Either drop the seven `build` prefixes so the claim becomes true, or state plainly that `turbo run build` still races and why that was left alone.

## Suggested approach (optional)
- Dropping `bun run --filter leadtype build &&` from the seven `build` scripts mirrors exactly what `81adabb` did for `check-types`, relying on the `^build` edge `turbo.json:5-9` already has.

## Open questions for the human
- Is the prefix kept in `build` deliberately, so `bun run --filter <app> build` stays self-sufficient for someone bypassing turbo? `check-types` has now picked the other side. If that split is intentional it is worth stating as a tradeoff rather than describing as an absent race.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@turbo.json`:
- Around line 13-20: Remove the nested `bun run --filter leadtype build`
invocation from each app’s `build` script so app builds no longer independently
rebuild `leadtype`. Rely on the root Turbo `build` dependency configuration,
including the existing `^build` behavior, to build `leadtype` once before
dependents.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6ab5f081-dee6-4b56-b2aa-e67ea1d3a17c

📥 Commits

Reviewing files that changed from the base of the PR and between 81adabb and 39223d4.

📒 Files selected for processing (2)
  • apps/astro-example/astro.config.mjs
  • turbo.json
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: pullfrog
🔇 Additional comments (1)
apps/astro-example/astro.config.mjs (1)

6-9: LGTM!

Also applies to: 21-43, 45-48

Comment thread turbo.json
Comment on lines +13 to +20
// `^build` so turbo builds leadtype's dist once, ahead of every dependent.
// Seven app `check-types` scripts used to run `--filter leadtype build`
// themselves, and those in parallel rm -rf the same dist — failing a
// different app every run. Other scripts (`build`, `dev`, `mcp`,
// `test:e2e`) still carry the prefix; they are not run concurrently by
// turbo, so the race is fixed for `check-types`, not repo-wide.
"check-types": {
"dependsOn": ["^check-types"]
"dependsOn": ["^build", "^check-types"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 3 \
  'bun run --filter leadtype build|turbo( run)? build|--concurrency' \
  --glob 'package.json' \
  --glob 'turbo.json' \
  --glob '*.yml' \
  --glob '*.yaml' \
  . || true

Repository: inthhq/leadtype

Length of output: 9595


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- turbo.json ---'
cat -n turbo.json

printf '%s\n' '--- root package.json scripts ---'
python3 - <<'PY'
import json
from pathlib import Path
p = json.loads(Path("package.json").read_text())
print(json.dumps({"scripts": p.get("scripts"), "workspaces": p.get("workspaces")}, indent=2))
PY

printf '%s\n' '--- workspace build scripts and leadtype references ---'
python3 - <<'PY'
import json
from pathlib import Path

for path in sorted(Path(".").glob("**/package.json")):
    try:
        data = json.loads(path.read_text())
    except Exception:
        continue
    scripts = data.get("scripts", {})
    if "build" in scripts or "leadtype" in json.dumps(data):
        print(path)
        for name, value in scripts.items():
            if name in {"build", "dev", "mcp", "test:e2e", "check-types"} or "leadtype" in value:
                print(f"  {name}: {value}")
PY

printf '%s\n' '--- leadtype build implementation and CI invocations ---'
rg -n -C 4 \
  'rm -rf[^\\n]*(dist|packages/leadtype)|["'\'']build["'\'']|turbo( run)? build|--concurrency|bun run --filter leadtype build' \
  --glob 'package.json' \
  --glob 'turbo.json' \
  --glob '*.yml' \
  --glob '*.yaml' \
  --glob '*.sh' \
  --glob '!node_modules' \
  .

Repository: inthhq/leadtype

Length of output: 17771


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- turbo.json ---'
cat -n turbo.json

printf '%s\n' '--- root package.json scripts ---'
python3 - <<'PY'
import json
from pathlib import Path

data = json.loads(Path("package.json").read_text())
print(json.dumps({
    "scripts": data.get("scripts"),
    "workspaces": data.get("workspaces"),
}, indent=2))
PY

printf '%s\n' '--- workspace scripts ---'
python3 - <<'PY'
import json
from pathlib import Path

for path in sorted(Path(".").glob("**/package.json")):
    try:
        data = json.loads(path.read_text())
    except Exception:
        continue

    scripts = data.get("scripts", {})
    if any(
        key in scripts
        for key in ("build", "dev", "mcp", "test:e2e", "check-types")
    ):
        print(path)
        for key in ("build", "dev", "mcp", "test:e2e", "check-types"):
            if key in scripts:
                print(f"  {key}: {scripts[key]}")
PY

printf '%s\n' '--- build cleanup and CI invocations ---'
rg -n -C 4 \
  'rm -rf[^[:cntrl:]]*(dist|packages/leadtype)|"build"|turbo( run)? build|--concurrency|bun run --filter leadtype build' \
  --glob 'package.json' \
  --glob 'turbo.json' \
  --glob '*.yml' \
  --glob '*.yaml' \
  --glob '*.sh' \
  --glob '!node_modules' \
  .

Repository: inthhq/leadtype

Length of output: 16741


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- leadtype build configuration ---'
rg -n -C 5 \
  'output|dir|dist|clean|emptyOutDir|rm -rf|generate-docs' \
  packages/leadtype \
  --glob 'rollup.config.*' \
  --glob 'package.json' \
  --glob '*.ts' \
  --glob '*.js' \
  --glob '*.mjs' \
  --glob '*.cjs' || true

printf '%s\n' '--- tracked CI and task-runner configuration ---'
git ls-files | rg '(^|/)(\.github/workflows/|.*(ci|workflow|turbo|package)\.(yml|yaml|json)$)' || true

printf '%s\n' '--- read-only task-graph verifier ---'
python3 - <<'PY'
import json
from pathlib import Path

root = json.loads(Path("package.json").read_text())
turbo = json.loads(
    Path("turbo.json").read_text().replace(
        "// `^build` so turbo builds leadtype's dist once, ahead of every dependent.\n"
        "// Seven app `check-types` scripts used to run `--filter leadtype build`\n"
        "// themselves, and those in parallel rm -rf the same dist — failing a\n"
        "// different app every run. Other scripts (`build`, `dev`, `mcp`,\n"
        "// `test:e2e`) still carry the prefix; they are not run concurrently by\n"
        "// turbo, so the race is fixed for `check-types`, not repo-wide.\n",
        "",
    )
)

root_build = root.get("scripts", {}).get("build")
build_depends = turbo["tasks"]["build"].get("dependsOn")
nested = []

for path in sorted(Path("apps").glob("*/package.json")):
    data = json.loads(path.read_text())
    script = data.get("scripts", {}).get("build", "")
    if "bun run --filter leadtype build" in script:
        nested.append(str(path))

print(f"root_build={root_build!r}")
print(f"build_dependsOn={build_depends!r}")
print(f"nested_leadtype_builds={len(nested)}")
for path in nested:
    print(f"  {path}")
print(f"turbo_concurrency_configured={'concurrency' in turbo}")
PY

Repository: inthhq/leadtype

Length of output: 50372


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- leadtype build configuration ---'
rg -n -C 5 \
  'output|dir|dist|clean|emptyOutDir|rm -rf|generate-docs' \
  packages/leadtype \
  --glob 'rollup.config.*' \
  --glob 'package.json' \
  --glob '*.ts' \
  --glob '*.js' \
  --glob '*.mjs' \
  --glob '*.cjs' || true

printf '%s\n' '--- tracked CI and task-runner configuration ---'
git ls-files | rg '(^|/)(\.github/workflows/|.*(ci|workflow|turbo|package)\.(yml|yaml|json)$)' || true

printf '%s\n' '--- read-only task-graph verifier ---'
python3 - <<'PY'
import json
from pathlib import Path

root = json.loads(Path("package.json").read_text())
turbo_text = Path("turbo.json").read_text()
turbo_text = "\n".join(
    line for line in turbo_text.splitlines()
    if not line.lstrip().startswith("//")
)
turbo = json.loads(turbo_text)

nested = []
for path in sorted(Path("apps").glob("*/package.json")):
    data = json.loads(path.read_text())
    script = data.get("scripts", {}).get("build", "")
    if "bun run --filter leadtype build" in script:
        nested.append(str(path))

print(f"root_build={root.get('scripts', {}).get('build')!r}")
print(f"build_dependsOn={turbo['tasks']['build'].get('dependsOn')!r}")
print(f"nested_leadtype_builds={len(nested)}")
for path in nested:
    print(f"  {path}")
print(f"turbo_concurrency_configured={'concurrency' in turbo}")
PY

Repository: inthhq/leadtype

Length of output: 50374


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- verifier result ---'
for log in /tmp/coderabbit-shell-logs/shell-output-Pv20ta /tmp/coderabbit-shell-logs/shell-output-YzBcA7; do
  if [ -f "$log" ]; then
    rg -n -A 20 -- '--- read-only task-graph verifier ---|root_build=|nested_leadtype_builds=|turbo_concurrency_configured=' "$log" || true
  fi
done

printf '%s\n' '--- leadtype build-related tracked files ---'
git ls-files packages/leadtype | rg '(^|/)(rollup|vite|tsup|webpack|package)\.[^/]+$|generate-docs|docs.*\.(ts|js|mjs|cjs)$' || true

printf '%s\n' '--- Rollup/build config ---'
for path in $(git ls-files packages/leadtype | rg '(^|/)(rollup|vite|tsup|webpack)\.[^/]+$'); do
  printf '%s\n' "--- $path ---"
  cat -n "$path"
done

printf '%s\n' '--- package scripts and generated output paths ---'
cat -n packages/leadtype/package.json | sed -n '195,207p'
rg -n -C 3 \
  'dist/|dist\b|rm\(|rmSync|outputFile|writeFile|mkdir\(' \
  packages/leadtype/scripts \
  packages/leadtype/src/cli \
  --glob '*.ts' \
  --glob '*.js' \
  --glob '*.mjs' \
  --glob '*.cjs' \
  | head -n 300 || true

Repository: inthhq/leadtype

Length of output: 27075


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- verifier result ---'
for log in /tmp/coderabbit-shell-logs/shell-output-Pv20ta /tmp/coderabbit-shell-logs/shell-output-YzBcA7; do
  if [ -f "$log" ]; then
    rg -n -A 20 \
      -- '--- read-only task-graph verifier ---|root_build=|nested_leadtype_builds=|turbo_concurrency_configured=' \
      "$log" || true
  fi
done

printf '%s\n' '--- leadtype build-related tracked files ---'
git ls-files packages/leadtype |
  rg '(^|/)(rollup|vite|tsup|webpack|package)\.[^/]+$|generate-docs|docs.*\.(ts|js|mjs|cjs)$' || true

printf '%s\n' '--- Rollup/build config ---'
while IFS= read -r path; do
  printf '%s\n' "--- $path ---"
  cat -n "$path"
done < <(
  git ls-files packages/leadtype |
    rg '(^|/)(rollup|vite|tsup|webpack)\.[^/]+$'
)

printf '%s\n' '--- package scripts and generated output paths ---'
cat -n packages/leadtype/package.json | sed -n '195,207p'
rg -n -C 3 \
  'dist/|dist\b|rm\(|rmSync|outputFile|writeFile|mkdir\(' \
  packages/leadtype/scripts \
  packages/leadtype/src/cli \
  --glob '*.ts' \
  --glob '*.js' \
  --glob '*.mjs' \
  --glob '*.cjs' |
  head -n 300 || true

Repository: inthhq/leadtype

Length of output: 1856


Remove nested leadtype builds from app build scripts. The root turbo run build has no concurrency limit, and seven app builds still invoke bun run --filter leadtype build. Each invocation removes and rewrites packages/leadtype/dist, so concurrent tasks can corrupt build outputs. Rely on ^build instead.

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

In `@turbo.json` around lines 13 - 20, Remove the nested `bun run --filter
leadtype build` invocation from each app’s `build` script so app builds no
longer independently rebuild `leadtype`. Rely on the root Turbo `build`
dependency configuration, including the existing `^build` behavior, to build
`leadtype` once before dependents.

The leak detector globbed `leadtype-generate-*` across the shared
os.tmpdir(), snapshotting before and after the run. Both the source
mirror and the generate lock live there, and vitest workers run test
files in parallel, so a concurrent run's lock directory was attributed
to this test and failed it.

The test's own lock cannot be what it caught: generate acquires and
releases it inside the awaited runCli, so it is always gone before the
after-snapshot.

Point the run at a private TMPDIR instead. os.tmpdir() reads TMPDIR per
call, so both the lock path and the mkdtemp mirror land there, and every
`leadtype-generate-*` remaining is provably this run's.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@packages/leadtype/src/cli.test.ts`:
- Around line 2203-2234: Update the temporary-directory setup around runCli to
set TMPDIR, TMP, and TEMP to privateTmpDir, then restore or delete each variable
according to its original value in the finally block. Keep the existing leak
scan unchanged so it checks the directory actually used by the CLI across
platforms.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 283c4945-9be8-47b7-ac7f-7ce6207e70bb

📥 Commits

Reviewing files that changed from the base of the PR and between 39223d4 and add9551.

📒 Files selected for processing (1)
  • packages/leadtype/src/cli.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: pullfrog
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Prefer unknown over any when the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions

Files:

  • packages/leadtype/src/cli.test.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Prefer for...of loops over .forEach() and indexed for loops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Use const by default, let only when reassignment is needed, never var
Always await promises in async functions - don't forget to use the return value
Use async/await syntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Remove console.log, debugger, and alert statements from production code
Throw Error objects with descriptive messages, not strings or other values
Use try-catch blocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't use eval() or assign directly to document.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code

Files:

  • packages/leadtype/src/cli.test.ts
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions inside it() or test() blocks
Avoid done callbacks in async tests - use async/await instead
Don't use .only or .skip in committed code
Keep test suites reasonably flat - avoid excessive describe nesting

Files:

  • packages/leadtype/src/cli.test.ts
🪛 ast-grep (0.45.0)
packages/leadtype/src/cli.test.ts

[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFile } from "node:child_process";
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)

Comment on lines +2203 to +2234
const previousTmpDir = process.env.TMPDIR;
process.env.TMPDIR = privateTmpDir;

let code: number;
try {
code = await runCli(
[
"generate",
"--src",
srcDir,
"--out",
outDir,
"--include",
"guides/**",
"--format",
"json",
],
capture.io
);
} finally {
if (previousTmpDir === undefined) {
delete process.env.TMPDIR;
} else {
process.env.TMPDIR = previousTmpDir;
}
}

const afterTempDirs = new Set(
await fg("leadtype-generate-*", {
absolute: true,
cwd: tmpdir(),
onlyDirectories: true,
})
);
const leakedTempDirs = [...afterTempDirs].filter(
(dir) => !beforeTempDirs.has(dir)
);
const leakedTempDirs = await fg("leadtype-generate-*", {
absolute: true,
cwd: privateTmpDir,
onlyDirectories: true,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Check whether this repository supports or tests Windows.
rg -n -C 3 --hidden \
  --glob '!node_modules/**' \
  --glob '!**/dist/**' \
  '(windows-latest|windows-202|process\.platform|TMPDIR|TEMP|TMP)' \
  .github packages package.json 2>/dev/null || true

# Inspect the full test scope for platform guards or concurrent execution.
sed -n '2160,2260p' packages/leadtype/src/cli.test.ts

Repository: inthhq/leadtype

Length of output: 8288


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- temporary-directory call sites ---'
rg -n -C 4 --hidden \
  --glob '!node_modules/**' \
  --glob '!**/dist/**' \
  'os\.tmpdir|tmpdir\(' packages/leadtype/src

printf '%s\n' '--- relevant package and CI configuration ---'
rg -n -C 3 --hidden \
  --glob '!node_modules/**' \
  --glob '!**/dist/**' \
  'vitest|pool|threads|forks|windows-latest|windows-202|matrix|TMPDIR|TEMP|TMP' \
  .github package.json packages/leadtype/package.json 2>/dev/null || true

printf '%s\n' '--- Node runtime behavior for environment-variable precedence ---'
node - <<'JS'
const os = require("node:os");
const original = {
  TMPDIR: process.env.TMPDIR,
  TMP: process.env.TMP,
  TEMP: process.env.TEMP,
};
const keys = ["TMPDIR", "TMP", "TEMP"];
for (const key of keys) delete process.env[key];
console.log("baseline", os.tmpdir());
for (const key of keys) {
  for (const other of keys) delete process.env[other];
  process.env[key] = `/probe/${key}`;
  console.log(key, os.tmpdir());
}
for (const key of keys) {
  if (original[key] === undefined) delete process.env[key];
  else process.env[key] = original[key];
}
JS

Repository: inthhq/leadtype

Length of output: 42502


Set all temporary-directory environment variables.

On Windows, os.tmpdir() ignores TMPDIR. Set and restore TMPDIR, TMP, and TEMP so the test scans the directory used by the CLI.

🧰 Tools
🪛 ast-grep (0.45.0)

[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFile } from "node:child_process";
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)

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

In `@packages/leadtype/src/cli.test.ts` around lines 2203 - 2234, Update the
temporary-directory setup around runCli to set TMPDIR, TMP, and TEMP to
privateTmpDir, then restore or delete each variable according to its original
value in the finally block. Keep the existing leak scan unchanged so it checks
the directory actually used by the CLI across platforms.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ℹ️ The test change is sound and genuinely falsifiable — two nitpicks, neither blocking.

Reviewed changes — delta since the prior review of 39223d4; the new commit add9551 touches packages/leadtype/src/cli.test.ts and nothing else.

  • Scoped the temp-dir leak assertion to a private TMPDIR — the test "cleans up mirrored sources when the generate pipeline fails" no longer snapshots leadtype-generate-* in the shared os.tmpdir() before and after runCli and diffs the two sets. It creates a private dir, points process.env.TMPDIR at it for the duration of the CLI call, and globs only that dir.
  • Restored the env in a finally — including the originally-unset case, so the mutation cannot outlive the runCli call.

I mutation-tested the assertion rather than trusting that the override lands: patching createSourceMirror's cleanup (packages/leadtype/src/cli/generate.ts:2553) to a no-op makes the test fail with + ["/tmp/leadtype-cli-XXXX/leadtype-generate-XXXX/"]. So the override is effective and the assertion can still catch the leak it exists to catch — the usual failure mode for this refactor, where the glob silently starts pointing at an always-empty directory, is not present here.

No coverage is lost relative to the old glob either. Every tmpdir() call site under src/ sits inside a function rather than a module-level constant (cli/generate.ts:2244,2531, internal/generate-lock.ts:73, source/index.ts:439, openapi/index.ts:2114), so all of them re-read process.env.TMPDIR per call, and this test's code path spawns no subprocess that could inherit a stale env. The comment's stated flake mechanism also checks out: generateLockPath returns leadtype-generate-<key>.lock and tryAcquire creates it with mkdir (internal/generate-lock.ts:167), so despite the suffix it is a directory and did match the old glob's onlyDirectories: true — a concurrent worker's lock landing inside the before/after window really was misattributable. And the env mutation cannot leak: tests in this file are sequential (no .concurrent), and vitest workers hold independent process.env copies. privateTmpDir itself comes from createTempDir() (cli.test.ts:97), so afterEach (cli.test.ts:156) already removes it.

ℹ️ Nitpicks

  • packages/leadtype/src/cli.test.ts:2204os.tmpdir() reads TEMP/TMP on Windows and ignores TMPDIR entirely, so there privateTmpDir stays empty and expect(leakedTempDirs).toEqual([]) passes vacuously rather than failing. CI is ubuntu-only (ci.yml:19) so there is no merge-gate impact, but a Windows contributor loses the assertion silently. Setting TMP/TEMP alongside TMPDIR would close it if the repo cares about that platform.
  • The PR title and body still describe "three pre-existing breakages in the example apps and task graph". This commit is a fourth change, and a test-flake fix in packages/leadtype is neither an example app nor the task graph — worth a line in the body so the merge commit records why it rode along.

Note on scope: add9551 does not touch turbo.json, so the open thread on turbo.json:16-18 from the previous review is unaffected and stays open.

Pullfrog  | Fix it ➔View workflow run | Using Claude Opus𝕏

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.

1 participant