Uh oh!
There was an error while loading. Please reload this page.
Publish JSDoc-derived type declarations (icebird-style, no copy) - #185
Merged
Conversation
Consumers of the package got real types only for the two entry points that
happened to have a hand-written sibling .d.ts (`.`/`./core` and `./integration`);
the other four (`./core/observability`, `./core/sinks`, `./core/query`, `./tui`)
resolved to implicit `any`, because TypeScript does not read JSDoc out of an
installed package's `.js` and there was no declaration build.
Add a declaration build modeled on icebird: `tsconfig.build.json` emits `.d.ts`
(+ maps) from JSDoc with `rootDir: src` -> `outDir: types`, run via
`build:types` and wired to `prepare` so it runs before pack/publish. `types/` is
gitignored and shipped through the `files` allowlist; `exports` gains a `types`
condition per entry (generated `types/...` for JSDoc-only entries, the
hand-written `src/...d.ts` for the barrel entries).
The icebird mechanism needs every type-import specifier to resolve identically
from both `src/<P>/x.js` and the parallel generated `types/<P>/x.d.ts`. Anchor
all 159 such specifiers to repo-root `.js` paths (e.g. `../../src/core/types.js`)
so tsc keeps them verbatim and they resolve from both trees. Documented as the
project convention in AGENTS.md.
Three targeted fixes remove the only hand-written-.d.ts -> JSDoc-module
couplings that the two-tree split cannot bridge:
- cli/types.d.ts: use the named `KernelRuntime` instead of
`ReturnType<typeof createKernelRuntime>` (drops the activation.js dependency).
- observability/types.d.ts: declare `ObservabilityHandle` as an explicit
interface instead of deriving it from `typeof installObservability`; the
precise provider types still reach consumers via the generated `index.d.ts`.
- observability/tracer.js: `@import { Span }` so the emitted tracer declaration
resolves `Span` from its sibling generated `runtime.d.ts`.
One dynamic `hypaware-core` import in core_commands.js is indirected through a
variable so the declaration build (rootDir: src) does not pull that module under
src's emit root (TS6059).
Verified with an external-consumer probe (strict, nodenext) importing all six
entry points: types resolve for every entry (negative control errors as
expected). typecheck, lint (423 files), and npm test (1473 pass) all green.The hand-written cli/integration.d.ts exposed the instance fields but no
constructor, so consumers (resolving the public ./integration entry) inherited
Error's (message, options) signature and could not construct the error with its
{code, stdout, stderr, json} detail under types. Declare the real constructor so
the public type matches integration.js. Validated against the packed tarball: a
clean consumer can now construct it with typed detail and mistyped detail is
rejected.Uh oh!
There was an error while loading. Please reload this page.
platypii added a commit
that referenced
this pull request
Jun 28, 2026
blob-io.d.ts and maintenance.d.ts were emitted in-place by an early rootDir=src declaration-build experiment (those hypaware-core modules fell outside the emit root, so tsc wrote their declarations next to the source) and got swept into #185 by git add -A. They shadow the JSDoc and are build cruft. The shipped build emits only to types/ and, with the core_commands dynamic import indirected, no longer pulls these hypaware-core modules into the src emit, so removing them is safe: typecheck, build:types (does not regenerate them), and tests (1473 pass) all stay green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #184 (auto-closed when its stacked base branch, the phase-2 PR #183, was merged and deleted). Rebased onto master; this diff is publish-types only.
Publish real types to consumers
Consumers got real types only for the two entries with a hand-written sibling
.d.ts(././core,./integration); the other four (./core/observability,./core/sinks,./core/query,./tui) resolved to implicitany, because TypeScript does not read JSDoc out of an installed package's.jsand there was no declaration build.Approach (icebird-style, no copy)
tsconfig.build.jsonemits.d.ts(+ maps) from JSDoc withrootDir: src->outDir: types, run viabuild:typesand wired toprepare.types/is gitignored and shipped through thefilesallowlist.exportsgains atypescondition per entry: generatedtypes/...for JSDoc-only entries, the hand-writtensrc/...d.tsfor the barrel entries..jspath (e.g.../../src/core/types.js) so the same import resolves identically from bothsrc/<P>/x.jsand the generatedtypes/<P>/x.d.ts. Documented as the project convention in AGENTS.md.Targeted fixes (the only hand-written-
.d.ts-> JSDoc-module couplings the split can't bridge)cli/types.d.ts: use the namedKernelRuntimeinstead ofReturnType<typeof createKernelRuntime>.observability/types.d.ts: declareObservabilityHandleas an explicit interface (precise provider types still reach consumers via the generatedindex.d.ts).observability/tracer.js:@import { Span }so the emitted declaration resolvesSpanfrom its sibling generatedruntime.d.ts.hypaware-coreimport incore_commands.jsindirected through a variable so the build (rootDir: src) does not pull it under src's emit root (TS6059).cli/integration.d.ts: declare theHypAwareCommandErrorconstructor so its{code,stdout,stderr,json}detail is part of the public type.Verification
External-consumer probe (strict, nodenext) importing all six entry points resolves real types (negative control +
@ts-expect-errorguards confirm notany). Validated against the actualnpm packtarball installed into a clean consumer: types resolve andnodeimports all six entries with live exports.typecheck,lint(423 files), andnpm test(1473 pass) all green.