Skip to content

Include referenced package export types - #382

Merged
kentcdodds merged 3 commits into
mainfrom
cursor/-bc-f04ab8e0-4915-407e-8fd1-50f40544c4bf-fa09
May 7, 2026
Merged

kentcdodds merged 3 commits into
mainfrom
cursor/-bc-f04ab8e0-4915-407e-8fd1-50f40544c4bf-fa09

Conversation

@kentcdodds

@kentcdodds kentcdodds commented May 7, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Collect top-level local type/interface/enum declarations from each package export metadata source.
  • Attach only named local types referenced by displayed export function signatures, including shallow nested local references with size/count caps.
  • Render a compact "Referenced types" section in package detail and stop dumping full types files by default.

Validation

  • npx vitest run --project node-unit packages/worker/src/package-registry/manifest.node.test.ts packages/worker/src/mcp/tools/search-format.node.test.ts
  • npm run typecheck
  • npm run lint
  • npm run test
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features
    • Search ranking and relevance improved by indexing referenced type names and definitions.
    • Package detail pages now show a "Referenced types" section rendering local type definitions alongside exports.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@coderabbitai

coderabbitai Bot commented May 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Rate limit exceeded

@cursor[bot] has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 47 minutes and 44 seconds before requesting another review.

To continue reviewing without waiting, purchase usage credits in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9a0bffc2-967e-4f9e-bfdf-b97d3899ea71

📥 Commits

Reviewing files that changed from the base of the PR and between 1276c86 and 6599923.

📒 Files selected for processing (2)
  • packages/worker/src/package-registry/manifest.node.test.ts
  • packages/worker/src/package-registry/manifest.ts
📝 Walkthrough

Walkthrough

The PR extracts locally-declared TypeScript types referenced by exported functions, attaches them as referencedTypes on function and export projections, includes those definitions in package search documents and tertiary aliases, replaces type-source markdown with a "Referenced types" block, and updates tests.

Changes

Referenced Types Extraction & Integration

Layer / File(s) Summary
Type Definitions
packages/worker/src/package-registry/manifest.ts
PackageReferencedTypeProjection added; PackageExportFunctionProjection and PackageExportProjection extended with referencedTypes: Array<PackageReferencedTypeProjection>.
Core Type Extraction
packages/worker/src/package-registry/manifest.ts
AST-driven logic collects local type/interface/enum declarations, traverses function signatures for TSTypeReference nodes, filters builtins via allowlist, and enforces depth/count/size limits on extracted types.
Export Aggregation
packages/worker/src/package-registry/manifest.ts
collectExportedFunctionsFromSource derives referencedTypes from function signatures; summarizePackageExport merges function-level referenced types into export-level lists.
Search Token Enrichment
packages/worker/src/mcp/tools/search.ts
Added flattenReferencedTypeFields; export- and function-level referencedTypes are appended to entity tertiary aliases and candidate searchFields.
Formatting Output
packages/worker/src/mcp/tools/search-format.ts
Structured export output sets typesSource: null and includes referencedTypes; markdown renderer emits a "Referenced types" fenced ts block containing referenced type definitions.
Tests & Assertions
packages/worker/src/package-registry/manifest.node.test.ts, packages/worker/src/mcp/tools/search-format.node.test.ts
Projection and format tests updated to expect referencedTypes on functions and exports; new tests assert only referenced local types are included while unrelated/builtin types are excluded.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • kentcdodds/kody#242: Modifies package search formatting and structured output shapes in search-format.ts and related tests.
  • kentcdodds/kody#252: Uses updated buildPackageSearchProjection and buildPackageSearchDocument for app/jobs/guidance integration.
  • kentcdodds/kody#279: Modifies formatEntityDetailMarkdown for richer type-definition output handling in capability entity details.

Poem

🐇 I hopped through AST roots with cheer,

Found only the types that exports hold dear,
Left builtins and noise at the door,
Kept referenced types, tidy and pure,
Now search and docs hum a bit more.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Include referenced package export types' directly summarizes the main objective of the PR: collecting and displaying local types referenced by package exports.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/-bc-f04ab8e0-4915-407e-8fd1-50f40544c4bf-fa09

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@kentcdodds
kentcdodds marked this pull request as ready for review May 7, 2026 03:25
@github-actions

github-actions Bot commented May 7, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Preview deployed: https://kody-pr-382.kentcdodds.workers.dev

Worker: kody-pr-382
D1: kody-pr-382-db
KV: kody-pr-382-oauth-kv

Mocks:

@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.

🧹 Nitpick comments (3)
packages/worker/src/mcp/tools/search.ts (1)

336-352: 💤 Low value

Optional: extract a small helper for the duplicated referencedTypes flattening.

The same (referencedTypes ?? []).flatMap((rt) => [rt.name, rt.definition]) pattern appears here and again at lines 710-715/720-723. A shared helper would centralize the shape contract.

♻️ Proposed helper
function flattenReferencedTypeFields(
	referencedTypes:
		| ReadonlyArray<{ name: string; definition: string }>
		| undefined,
): Array<string> {
	return (referencedTypes ?? []).flatMap((rt) => [rt.name, rt.definition])
}

Then use at each call site:

-					...(exportDetail.referencedTypes ?? []).flatMap((referencedType) => [
-						referencedType.name,
-						referencedType.definition,
-					]),
+					...flattenReferencedTypeFields(exportDetail.referencedTypes),
🤖 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/worker/src/mcp/tools/search.ts` around lines 336 - 352, Extract a
small helper function named flattenReferencedTypeFields that takes the optional
referencedTypes array (ReadonlyArray<{name:string;definition:string}> |
undefined) and returns (referencedTypes ?? []).flatMap(rt => [rt.name,
rt.definition]); then replace the duplicated patterns in the code (the
flattening inside exportDetail, inside exportDetail.functions (fn), and the
other occurrences around lines with similar patterns) by calling
flattenReferencedTypeFields(exportDetail.referencedTypes) and
flattenReferencedTypeFields(fn.referencedTypes) (and the other sites) so all
repeated (referencedTypes ?? []).flatMap(...) usage is centralized under the new
helper.
packages/worker/src/mcp/tools/search-format.ts (1)

705-717: 💤 Low value

Optional: typesSource is now always null — consider whether the field still belongs in the structured contract.

After this change every export always emits typesSource: null, but the structured type at line 224 still keeps it as string | null. Either drop the field from SearchEntityDetailStructured.exports (tightening the contract since callers can no longer rely on a non-null value) or leave a brief comment explaining why it's retained as a placeholder for future re-introduction. As-is, it reads as dead schema.

🤖 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/worker/src/mcp/tools/search-format.ts` around lines 705 - 717, The
exports objects produced in the package branch (inside the detail.type ===
'package' block using buildPackageSearchProjection and
buildPackageImportSpecifier) always set typesSource to null, so update the
structured contract or the emitted objects: either remove the typesSource
property from SearchEntityDetailStructured.exports (and strip it from the export
objects produced here) to tighten the type, or keep the property but add a clear
comment in the type definition explaining it is intentionally a placeholder for
future non-null type sources; pick one approach and apply it consistently
(adjust the code that constructs exportDetails and the
SearchEntityDetailStructured type declaration to match).
packages/worker/src/package-registry/manifest.ts (1)

430-482: 💤 Low value

Handle namespaced type references like Foo.Bar in readTypeReferenceName

The function currently only recognizes Identifier nodes but silently drops TSQualifiedName references (e.g., Foo.Bar from re-exported namespaces). While uncommon in typical function signatures, supporting this would improve coverage.

The proposed fix recursively resolves to the leftmost identifier:

♻️ Proposed extension
function readTypeReferenceName(node: unknown): string | null {
	if (!node || typeof node !== 'object') return null
	const type = getNodeType(node)
	if (type === 'Identifier') return readIdentifierName(node)
	if (type === 'TSQualifiedName') {
		// Resolve to the leftmost identifier so a local declaration named `Foo`
		// is still picked up when a signature uses `Foo.Bar`.
		return readTypeReferenceName((node as { left?: unknown }).left)
	}
	return null
}
🤖 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/worker/src/package-registry/manifest.ts` around lines 430 - 482,
readTypeReferenceName currently only returns identifiers and drops
TSQualifiedName (namespaced types like Foo.Bar); update readTypeReferenceName to
check getNodeType(node) and if it equals 'TSQualifiedName' recursively call
readTypeReferenceName on (node as { left?: unknown }).left so the leftmost
Identifier (e.g., Foo) is returned; keep existing checks for null/object and
Identifier and ensure pushUniqueTypeName/collectTypeReferenceNamesFromNodes will
then pick up namespaced references.
🤖 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.

Nitpick comments:
In `@packages/worker/src/mcp/tools/search-format.ts`:
- Around line 705-717: The exports objects produced in the package branch
(inside the detail.type === 'package' block using buildPackageSearchProjection
and buildPackageImportSpecifier) always set typesSource to null, so update the
structured contract or the emitted objects: either remove the typesSource
property from SearchEntityDetailStructured.exports (and strip it from the export
objects produced here) to tighten the type, or keep the property but add a clear
comment in the type definition explaining it is intentionally a placeholder for
future non-null type sources; pick one approach and apply it consistently
(adjust the code that constructs exportDetails and the
SearchEntityDetailStructured type declaration to match).

In `@packages/worker/src/mcp/tools/search.ts`:
- Around line 336-352: Extract a small helper function named
flattenReferencedTypeFields that takes the optional referencedTypes array
(ReadonlyArray<{name:string;definition:string}> | undefined) and returns
(referencedTypes ?? []).flatMap(rt => [rt.name, rt.definition]); then replace
the duplicated patterns in the code (the flattening inside exportDetail, inside
exportDetail.functions (fn), and the other occurrences around lines with similar
patterns) by calling flattenReferencedTypeFields(exportDetail.referencedTypes)
and flattenReferencedTypeFields(fn.referencedTypes) (and the other sites) so all
repeated (referencedTypes ?? []).flatMap(...) usage is centralized under the new
helper.

In `@packages/worker/src/package-registry/manifest.ts`:
- Around line 430-482: readTypeReferenceName currently only returns identifiers
and drops TSQualifiedName (namespaced types like Foo.Bar); update
readTypeReferenceName to check getNodeType(node) and if it equals
'TSQualifiedName' recursively call readTypeReferenceName on (node as { left?:
unknown }).left so the leftmost Identifier (e.g., Foo) is returned; keep
existing checks for null/object and Identifier and ensure
pushUniqueTypeName/collectTypeReferenceNamesFromNodes will then pick up
namespaced references.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 142fd7d2-dafc-4e26-a1d2-960d8fa8461d

📥 Commits

Reviewing files that changed from the base of the PR and between efbcfa3 and 50913a7.

📒 Files selected for processing (5)
  • packages/worker/src/mcp/tools/search-format.node.test.ts
  • packages/worker/src/mcp/tools/search-format.ts
  • packages/worker/src/mcp/tools/search.ts
  • packages/worker/src/package-registry/manifest.node.test.ts
  • packages/worker/src/package-registry/manifest.ts

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>

@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: 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 `@packages/worker/src/package-registry/manifest.ts`:
- Around line 549-555: The current loop accepts the first referenced type even
if it alone exceeds maxReferencedTypeCharsPerExport because the guard only
breaks when referencedTypes.length > 0; change the logic in the loop that
computes nextChars (using totalChars + declaration.definition.length and
maxReferencedTypeCharsPerExport) to skip (continue) any single declaration whose
declaration.definition.length exceeds the remaining budget instead of
breaking/accepting it, and only break once no further declarations can fit (or
when budget is exhausted); apply the same correction to the analogous block that
uses the same variables/guard around lines handling referencedTypes and
nextChars (the other block at 581-586).
- Around line 790-797: The referencedTypes list is including types from generic
parameter bounds that getVariableFunctionSignature doesn't render; to fix this
stop collecting typeParameter constraint nodes when building references: modify
getVariableFunctionReferenceNodes (or getFunctionReferenceNodes it calls) so it
does not traverse typeParameters/TypeParameterDeclaration constraint nodes, then
keep using collectTypeReferenceNamesFromNodes -> collectReferencedTypes as is;
alternatively, if you prefer showing those types, update
getVariableFunctionSignature to include the generic clause—pick one approach and
implement it consistently so referencedTypes only contains types actually
rendered in the synthesized signature.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0488f234-ffbc-42cb-9046-5d06da89ed35

📥 Commits

Reviewing files that changed from the base of the PR and between 50913a7 and 1276c86.

📒 Files selected for processing (3)
  • packages/worker/src/mcp/tools/search-format.ts
  • packages/worker/src/mcp/tools/search.ts
  • packages/worker/src/package-registry/manifest.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/worker/src/mcp/tools/search.ts

Comment thread packages/worker/src/package-registry/manifest.ts
Comment thread packages/worker/src/package-registry/manifest.ts
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds
kentcdodds merged commit cd41c2e into main May 7, 2026
9 checks passed
@kentcdodds
kentcdodds deleted the cursor/-bc-f04ab8e0-4915-407e-8fd1-50f40544c4bf-fa09 branch May 7, 2026 04:15
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.

2 participants