Shrink leadtype dependency closure#32
Conversation
Swap heavier deps out of the published `leadtype` package and clean up adjacent monorepo hygiene: - `gray-matter` → `vfile-matter` + `yaml` (drops js-yaml@3 + 4 transitive deps) - `jiti` moved from `dependencies` to optional `peerDependencies`, lazy-imported only for `.ts` docs configs - `decode-named-character-reference` → small inline named-entity map - `mdast-util-to-markdown` → existing `remark()` processor - `mdast-util-compact` → 15-line inline adjacent-node merger - `unist-builder` → mdast object literals - `unist-util-is` → `node.type === "type"` direct checks - Round-trip YAML timestamps now use the `yaml` package's timestamp tag (date-only scalars emit compact `2026-04-19` instead of full ISO; values remain `Date` instances in JS) Monorepo hygiene: bump `evals` vitest 2.x → 4.x to match the rest; drop `prettier` in favor of ultracite/Biome for the `format` script; hoist `ultracite` to the root only.
|
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (5)
📜 Recent review details🧰 Additional context used📓 Path-based instructions (2)**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{js,ts,jsx,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🔇 Additional comments (6)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR reduces dependency weight by replacing gray-matter and several mdast/unist utilities with a vfile-matter/yaml frontmatter abstraction, inlining small helpers (entity decoding, tree compaction), converting u(...) calls to mdast literals, centralizing remark stringification, and updating editor/CI metadata. ChangesDependency Optimization
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 @.changeset/optimize-dependencies.md:
- Line 5: Add a top-level H1 heading to the Markdown body so markdownlint MD041
is satisfied: insert a single line starting with "# " (e.g., "# Optimize
dependencies") immediately after the existing frontmatter and before the current
paragraph text in the .changeset file so the document begins with an H1 heading.
In `@packages/leadtype/src/remark/plugins/cards.remark.ts`:
- Around line 95-99: The object literal creating linkNode uses unnecessary type
assertions (the "as Text" on children) — remove those assertions and let
TypeScript infer the child text node type from the Link type and
PhrasingContent[]; update the linkNode literal (and any similar literal nearby
that uses "as Text") so children: [{ type: "text", value: item.text }] is used
without casting, relying on the existing Link and Text types to provide correct
typing.
🪄 Autofix (Beta)
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
Run ID: aa0fab09-ffae-437f-aff3-a545890b81d7
⛔ Files ignored due to path filters (4)
apps/example/src/generated/agent-readability.jsonis excluded by!**/generated/**apps/example/src/generated/docs-search-content.jsonis excluded by!**/generated/**apps/example/src/generated/docs-search-index.jsonis excluded by!**/generated/**bun.lockis excluded by!**/*.lock
📒 Files selected for processing (18)
.changeset/optimize-dependencies.md.vscode/settings.jsonevals/package.jsonpackage.jsonpackages/leadtype/package.jsonpackages/leadtype/src/cli/generate.tspackages/leadtype/src/convert/convert.tspackages/leadtype/src/internal/frontmatter.tspackages/leadtype/src/lint/runner.tspackages/leadtype/src/llm/llm.tspackages/leadtype/src/remark/libs/content-processor.tspackages/leadtype/src/remark/plugins/cards.remark.tspackages/leadtype/src/remark/plugins/prompt.remark.tspackages/leadtype/src/remark/plugins/steps.remark.tspackages/leadtype/src/remark/plugins/topic-switcher.remark.tspackages/leadtype/src/remark/plugins/type-table.remark.tspackages/leadtype/src/remark/remark-output.test.tspackages/leadtype/src/search/node.ts
📜 Review details
🧰 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
Preferunknownoveranywhen 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/remark/libs/content-processor.tspackages/leadtype/src/search/node.tspackages/leadtype/src/remark/plugins/cards.remark.tspackages/leadtype/src/internal/frontmatter.tspackages/leadtype/src/remark/plugins/steps.remark.tspackages/leadtype/src/remark/plugins/prompt.remark.tspackages/leadtype/src/remark/plugins/type-table.remark.tspackages/leadtype/src/lint/runner.tspackages/leadtype/src/cli/generate.tspackages/leadtype/src/llm/llm.tspackages/leadtype/src/convert/convert.tspackages/leadtype/src/remark/remark-output.test.tspackages/leadtype/src/remark/plugins/topic-switcher.remark.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
Preferfor...ofloops over.forEach()and indexedforloops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Useconstby default,letonly when reassignment is needed, nevervar
Alwaysawaitpromises in async functions - don't forget to use the return value
Useasync/awaitsyntax 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
Removeconsole.log,debugger, andalertstatements from production code
ThrowErrorobjects with descriptive messages, not strings or other values
Usetry-catchblocks 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 useeval()or assign directly todocument.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/remark/libs/content-processor.tspackages/leadtype/src/search/node.tspackages/leadtype/src/remark/plugins/cards.remark.tspackages/leadtype/src/internal/frontmatter.tspackages/leadtype/src/remark/plugins/steps.remark.tspackages/leadtype/src/remark/plugins/prompt.remark.tspackages/leadtype/src/remark/plugins/type-table.remark.tspackages/leadtype/src/lint/runner.tspackages/leadtype/src/cli/generate.tspackages/leadtype/src/llm/llm.tspackages/leadtype/src/convert/convert.tspackages/leadtype/src/remark/remark-output.test.tspackages/leadtype/src/remark/plugins/topic-switcher.remark.ts
**/*.{test,spec}.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions insideit()ortest()blocks
Avoid done callbacks in async tests - use async/await instead
Don't use.onlyor.skipin committed code
Keep test suites reasonably flat - avoid excessivedescribenesting
Files:
packages/leadtype/src/remark/remark-output.test.ts
🪛 LanguageTool
.changeset/optimize-dependencies.md
[style] ~11-~11: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...rk()processor. -mdast-util-compactdropped insteps.remark` — small in-tree adjac...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.22.1)
.changeset/optimize-dependencies.md
[warning] 5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🔇 Additional comments (20)
evals/package.json (1)
16-16: Vitest upgrade looks scoped and consistent.No blocking concerns in this manifest change.
package.json (1)
19-19: Formatter script switch is coherent with repo tooling direction.No issues on this script update.
.vscode/settings.json (1)
2-2: Default formatter update is aligned with the new formatting stack.Looks good.
packages/leadtype/src/remark/plugins/type-table.remark.ts (1)
870-870: DirectTableliteral construction is clean and type-safe here.No concerns with this replacement.
packages/leadtype/src/remark/plugins/prompt.remark.ts (1)
2-3: Stringifier refactor is cohesive and keeps markdown settings centralized.Looks good from correctness and maintainability perspectives.
Also applies to: 13-20, 31-33
packages/leadtype/package.json (1)
102-105: Dependency realignment is consistent with the optional-peer loading model.No blocking issues in this manifest update.
Also applies to: 114-114, 130-130, 147-149
packages/leadtype/src/remark/plugins/topic-switcher.remark.ts (1)
79-83: Direct mdast node literals here are clear and behavior-preserving.This change looks solid.
Also applies to: 87-87, 90-90
packages/leadtype/src/remark/libs/content-processor.ts (2)
19-45: Type-guard simplification and block-structure preservation are good.The direct
node.typebranching is clear, and preservingtable/listnodes avoids flattening structured content.
72-76: Code-node object construction is clean and equivalent.The literal
codenode construction with safe defaults is straightforward and keeps behavior predictable.packages/leadtype/src/remark/plugins/steps.remark.ts (2)
16-69: Entity decoding replacement is implemented defensively.Numeric entity bounds/surrogate checks and named-entity passthrough behavior are handled clearly.
280-307: In-place compaction logic is well-guarded.The merge conditions and index-adjusted splice flow are careful and readable for this compacting pass.
packages/leadtype/src/internal/frontmatter.ts (1)
5-24: Shared frontmatter utility is a solid abstraction.The parser/stringifier split and typed return shape make downstream call sites simpler and consistent.
packages/leadtype/src/llm/llm.ts (1)
22-22: Frontmatter parser migration is clean and consistent.Both ingestion paths now use the same internal parser, which reduces parsing divergence across features.
Also applies to: 530-530, 586-586
packages/leadtype/src/search/node.ts (1)
13-13: Search indexing frontmatter read path looks good.Using the shared parser here aligns search metadata extraction with the rest of the pipeline.
Also applies to: 98-98
packages/leadtype/src/convert/convert.ts (2)
16-19: Frontmatter utility integration at import boundary is well-structured.The dependency swap is localized and keeps module boundaries clean.
304-327: Enrichment and placeholder resolution flow remains clear after migration.Parsing to data, transforming, then stringifying is consistent and easy to reason about.
packages/leadtype/src/remark/remark-output.test.ts (1)
485-485: Timestamp expectation update is appropriate for the parser/stringifier change.The adjusted assertion keeps this regression test aligned with the new frontmatter serialization behavior.
Also applies to: 494-494
packages/leadtype/src/lint/runner.ts (1)
16-16: Lint frontmatter parsing migration is consistent and safe.Using the shared parser in both validation and link-check phases improves consistency across tooling.
Also applies to: 395-397, 417-417
packages/leadtype/src/cli/generate.ts (2)
240-242: Frontmatter inference migration looks solid.Using
parseFrontmatter(...)here keeps group inference aligned with the new shared frontmatter path and preserves existing normalization behavior.
317-335: Config loading refactor is clean and well-contained.The
.tsoptional-peer path and nativeimport()fallback for.js/.mjs/.cjsare integrated clearly, and validation remains centralized inloadDocsConfig.Also applies to: 349-353
| "leadtype": patch | ||
| --- | ||
|
|
||
| Shrink published install closure by swapping out heavier deps: |
There was a problem hiding this comment.
Add a top-level heading to satisfy markdownlint MD041.
This file currently starts with plain text after frontmatter; promoting it to an H1 will clear the warning with minimal churn.
Proposed diff
-Shrink published install closure by swapping out heavier deps:
+# Shrink published install closure by swapping out heavier deps📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Shrink published install closure by swapping out heavier deps: | |
| # Shrink published install closure by swapping out heavier deps |
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🤖 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 @.changeset/optimize-dependencies.md at line 5, Add a top-level H1 heading to
the Markdown body so markdownlint MD041 is satisfied: insert a single line
starting with "# " (e.g., "# Optimize dependencies") immediately after the
existing frontmatter and before the current paragraph text in the .changeset
file so the document begins with an H1 heading.
…ze-deps # Conflicts: # bun.lock # evals/package.json # packages/leadtype/package.json # packages/leadtype/src/cli/generate.ts # packages/leadtype/src/convert/convert.ts # packages/leadtype/src/lint/runner.ts
Summary
Swaps heavier deps out of the published
leadtypepackage, mirroring the PR #29fast-glob → tinyglobbyswap. Multiple drop-ins so they ride one PR rather than 6 separate ones.Consumer-facing (leadtype)
gray-mattervfile-matter+yamljs-yaml@3,section-matter,kind-of,strip-bom-string,extend-shallow,is-extendable,argparse@1,sprintf-js. Shared helper insrc/internal/frontmatter.ts.jitidocs.config.ts..js/.mjs/.cjsconfigs load via nativeimport(). Throws with install hint if a.tsconfig is loaded without jiti installed.decode-named-character-referencesteps.remark; rare ones fall through unchanged (same behavior as before for unrecognized entities).mdast-util-to-markdownremark()processorprompt.remarkstringifies via the unified pipeline.mdast-util-compactsteps.remarkrelied on (merge adjacent text + blockquote).unist-builderu(...)call sites →{ type, ...props, children }.unist-util-isnode.type === "..."Closure delta (per
packages/leadtypeinstall).tsdocs config save the full ~1 MB; with.tsconfig they still save ~700 KB.Behavior change worth flagging
YAML frontmatter timestamps now round-trip through the
yamlpackage's timestamp tag. Date-only scalars like2026-04-19emit as2026-04-19(compact) instead of2026-04-19T00:00:00.000Z. Datetime scalars without sub-second precision emit as2026-04-19T12:00:00instead of2026-04-19T12:00:00.000Z. The values remainDateinstances in JS, so consuming code is unaffected. One test (remark-output.test.ts) updated to assert the new wire format.Monorepo hygiene (dev-only, no consumer impact)
evals/: vitest^2.1.8→^4.1.5to match root +packages/leadtype.prettier.formatscript now runsultracite fix. VSCodeeditor.defaultFormatterswitched tobiomejs.biome(every file-type override was already pointing at Biome).packages/leadtype/: droppedultracitefrom devDeps (uses the root-hoisted one).Backed out from the original plan
typescript+@typescript/native-previewto root-only triggered a bun resolution swap on@tanstack/ai(0.15.0 → 0.14.0 won the hoist), breakingexample#check-typeswith a duplicate-install type error. Underlying tangle:@tanstack/ai-client@0.8.0pins@tanstack/aito exactly0.14.0whileleadtypepeer-requires>=0.15.0. The committedbun.lockpapered over this. Worth a separate PR — bump the@tanstack/ai-*family to a release that uses@tanstack/ai@0.15, then the hoist becomes safe.@mdx-js/reactstays at root devDeps —docs/index.mdxat repo root isn't a workspace package and resolves modules via rootnode_modules.Test plan
bun x ultracite check— clean (217 files)bun run check-types— passes (leadtype + example)bun run testinpackages/leadtype— 146/146 passbun run testinevals— 17/17 passapps/exampledev server boots and servesdocs/index.mdx🤖 Generated with Claude Code