Skip to content

feat(ts-adapter): surface type-reference-reachable types as public API#44

Merged
zmaril merged 3 commits into
mainfrom
feat/analyze-reexport-type-surface
Jul 21, 2026
Merged

feat(ts-adapter): surface type-reference-reachable types as public API#44
zmaril merged 3 commits into
mainfrom
feat/analyze-reexport-type-surface

Conversation

@zmaril

@zmaril zmaril commented Jul 21, 2026

Copy link
Copy Markdown
Owner

gap-2: surface export { type … } re-exported types as public API

Two additive pieces for the pi-API parity effort: a concrete TS-extractor fidelity fix, and a design note for a future schema evolution.

Before / After

Before. The TypeScript hinzu api extractor computed the public surface as only the symbols named-re-exported from a package's entry points. A type reachable solely because a public item names it in a type position was invisible: it showed up in rendered type strings as a mention, with zero defined items. In pi's coding-agent, export { type BashResult } (src/core/bash-executor.ts:29) and RpcSlashCommand (src/modes/rpc/rpc-types.ts:79) are referenced by the public RpcResponse / BashToolDetails but never named-re-exported from an entry point, so they emitted 0 items. Downstream, the hinzu api-fluessig converter's cross-package --context pass could not resolve those references (they stayed unresolved type reference and fell back to Json) even with coding-agent in context.

After. The extractor closes the public surface over type references: lowering an item enqueues the in-package, module-exported type symbols it names in its type positions (interface members, alias targets, class heritage/members, function params + return), transitively, via a worklist. BashResult and RpcSlashCommand are now first-class public items with full field shapes, so downstream cross-package resolution finds them.

No regression (measured on pi)

  • coding-agent: +146 items, 0 removed, 0 existing items mutated (strict superset). BashResult (5 fields) and RpcSlashCommand (4 fields) now present. Internal-only fidelity count drops 506 → 388 — the newly type-reachable types are no longer counted as internal-only; types nothing public references stay excluded.
  • orchestrator: report is byte-identical before/after (it has no type-reference-only reachable types).
  • The walk skips executable bodies (never promotes a value sharing a type's name) and only promotes types their own module marks export (private helpers stay out).

Measured unresolved-ref delta

Full-context conversion (hinzu api-fluessig on the orchestrator report with the coding-agent / agent / ai reports as --context):

  • unresolved type reference: 10 → 8
  • converter's context_expandable: {BashResult, RpcSlashCommand}{} — both now resolve to real models.
  • The orchestrator op/item plateau (33/39 ops, 70/72 items) is unchanged; this is a resolution/robustness gain, not a coverage-count gain.

Design note

Adds notes/api-structured-type-refs.md — an additive v2 ApiReport proposal that emits structured typeRefs alongside today's rendered type strings, so the converter and api-diff (#34) resolve references by id instead of re-parsing strings (HINZU_API_VERSION 1 → 2 as a capability signal, v1 consumers unaffected). It states honestly that it is 0 orchestrator parity gain — the plateau is already reached via string-parsing — its value is robustness, not coverage. Design only, not an implementation.

Dependency

Base is main. Depends on #36 (declaration-less-symbol guard) — needed to extract coding-agent/ai without crashing; #36 also targets main and its guard dedups when it lands.

Gates

cargo test -p hinzu-core (86 passed) · cargo fmt --check · cargo clippy · hinzu check crates/hinzu-core --policy hinzu-self.toml (no violations) · straitjacket v0.2.3 whole-tree on a clean clone (ok — no findings) · analyze.mjs 1337 lines (under 1500).

claude added 2 commits July 21, 2026 16:17
The TS API extractor computed the public surface as only the symbols
*named-re-exported* from a package's entry points. A type reachable
solely because a public item names it in a type position — e.g.
`BashResult` and `RpcSlashCommand`, referenced by the public
`RpcResponse`/`BashToolDetails` but never named-re-exported from an
entry point — was dropped: it appeared in rendered type strings as a
mention only, with zero defined items. Downstream, the api-fluessig
converter's cross-package `--context` pass could not resolve such a
reference (it stayed `unresolved type reference` and fell back to Json)
even with the owning package in context.

Close the public surface over type references. Lowering an item now
enqueues the in-package, module-exported *type* symbols it names in its
type positions (interface members, alias targets, class heritage/members,
function params + return), transitively, via a worklist. The walk skips
executable bodies so it never promotes a value that merely shares a name
with a type, and only promotes types their own module marks `export`, so
truly-internal helper types stay excluded and the internal-only fidelity
count keeps working.

For pi's coding-agent this adds 146 items (0 removed, 0 existing items
mutated), including `BashResult` and `RpcSlashCommand` with full field
shapes; orchestrator's report is byte-identical (it has no such refs).
End to end, full-context conversion drops unresolved type references
10 -> 8 and both types resolve to real models.

Also adds notes/api-structured-type-refs.md, a design note proposing an
additive v2 of the ApiReport schema (structured `typeRefs` alongside
today's rendered strings) so consumers resolve references without
re-parsing strings.

Depends on #36 (declaration-less-symbol guard) to extract coding-agent
without crashing; both target main.
@zmaril
zmaril force-pushed the feat/analyze-reexport-type-surface branch from 48a2d7b to 3cc484d Compare July 21, 2026 16:18
@zmaril
zmaril marked this pull request as ready for review July 21, 2026 21:31
@zmaril
zmaril enabled auto-merge (squash) July 21, 2026 21:31
@zmaril
zmaril merged commit 83cc70b into main Jul 21, 2026
11 checks passed
@zmaril
zmaril deleted the feat/analyze-reexport-type-surface branch July 21, 2026 21:33
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