Gate JSDoc completeness on every package export

New doc-sync gate verify-export-jsdoc walks every module-level exported
name under packages/*/*/src and requires description prose everywhere,
plus @param per parameter and @returns on non-void annotated returns for
function-like exports, public class methods, properties, and accessors.
The parsing + check helpers move out of gen-cordis-catalog.ts into a
shared scripts/jsdoc.ts so 'documented' means one thing on both gated
surfaces.

Deliberate exemptions (documented in the RFC): heritage-declared class
members (the seam declaration is the doc's one home — the one checker
query in an otherwise pure-AST walk), cordis plugin-protocol slots
(name/inject/reusable/Config/apply, top-level and static), constructors,
overload implementations, declare-module augmentation bodies, and
re-export statements (checked at the defining module).

The 203 under-documented exports the gate found at adoption are filled
in this change, so the gate lands green; generated catalogs/graphs are
regenerated for the shifted line pointers.

RFC: docs/rfc/implemented/process/2026-07-06-export-surface-jsdoc-gate.md
This commit is contained in:
Tianyi Cui
2026-07-06 22:09:30 +08:00
parent 1c999804d8
commit cd9737d569
92 files changed
+1802 -289

No files matched your search

+33 -5
View File
@@ -14,7 +14,13 @@ import { assertNever } from '@deepseek-ai/dsh-llm'
import type {} from '@deepseek-ai/dsh-system-prompt'
import { htmlToMarkdown } from './html.ts'
/** Validate value constraints the schema DSL can't express. */
/**
* Validate value constraints the schema DSL can't express: a non-blank `url`,
* and a positive `timeout_ms` when present. Throws a plain `Error` otherwise.
*
* @param args - the schema-validated `web_fetch` arguments.
* @returns the arguments renamed to the seam's camelCase request fields.
*/
export function parseFetchArgs(args: { url: string; timeout_ms?: number }): { url: string; timeoutMs?: number } {
if (args.url.trim().length === 0) throw new Error('url must be a non-empty string')
if (args.timeout_ms !== undefined && (!Number.isFinite(args.timeout_ms) || args.timeout_ms <= 0)) {
@@ -23,7 +29,13 @@ export function parseFetchArgs(args: { url: string; timeout_ms?: number }): { ur
return { url: args.url, ...args.timeout_ms !== undefined ? { timeoutMs: args.timeout_ms } : {} }
}
/** Render a fetched body to model-facing markdown text. */
/**
* Render a fetched body to model-facing markdown text.
*
* @param body - the decoded body; `html` is converted via
* {@link htmlToMarkdown}, `text` passes through verbatim.
* @returns the text for the tool's output block.
*/
export function renderBody(body: WebFetchBody): string {
switch (body.kind) {
case 'html':
@@ -36,19 +48,35 @@ export function renderBody(body: WebFetchBody): string {
}
}
/** Format a fetch result as one model-facing text block. */
/**
* Format a fetch result as one model-facing text block.
*
* @param result - the seam's fetch outcome.
* @returns a `Fetched <url> (HTTP <status>)` header, the rendered body, and a
* fetch-something-narrower notice when the provider truncated the content.
*/
export function formatFetchOutput(result: WebFetchResult): string {
const header = `Fetched ${result.url} (HTTP ${result.statusCode})`
const footer = result.truncated ? '\n\n(Content truncated. Fetch a more specific URL or section for the full text.)' : ''
return `${header}\n\n${renderBody(result.body)}${footer}`
}
/** Pending-call presentation: a fetch card titled by the URL. */
/**
* Pending-call presentation: a fetch card titled by the URL.
*
* @param args - the raw tool arguments; only `url` feeds the view.
* @returns the generic card view (`kind: 'fetch'`) shown while the call runs.
*/
export function presentFetchCall(args: { url: string; timeout_ms?: number }): GenericCallView {
return { card: 'generic', title: args.url, kind: 'fetch', rawInput: args.url }
}
/** Register the `web_fetch` tool and its system-prompt guidance. */
/**
* Register the `web_fetch` tool and its system-prompt guidance.
*
* @param ctx - context whose `tools` and `systemPrompt` registries receive the
* registrations; both are effect-scoped and unregister on plugin dispose.
*/
export function applyWebFetchTool(ctx: Context): void {
ctx.systemPrompt.section({
name: 'tool:web_fetch',