lib/renderer
lib/renderer.js
Functions(84)
Signature
badge(label: any, cls: any): any
Signature
anchorId(kind: any, name: any): any
True when `s` is a `--fix`-generated placeholder, per `lib/fix.js`'s own
literal templates (`TODO_DESCRIPTION`, `TODO_RETURNS_DESCRIPTION`, the
per-param `TODO: describe parameter "x".` template) -- all start with
"TODO:" by design (see `lib/fix.js`'s own comment: "Every one is
prefixed 'TODO:' on purpose"). Matches that exact, existing convention;
invents nothing new (story-file-detail-redesign, ADR Decision 2).
| Parameter | Type | Optional | Description |
|---|---|---|---|
s | string |
Returns:
boolean Signature
isTodoText(s: any): any
Renders a description string, flagging `--fix`-generated TODO
placeholders with a distinct badge + muted italic text instead of
rendering them identically to real authored prose. The underlying text
is unchanged either way -- this is presentation-only.
| Parameter | Type | Optional | Description |
|---|---|---|---|
s | string |
Returns:
string Signature
descText(s: any): any
Signature
metaHtml(item: any): any
Server-side tokenizer for JS/TS @example blocks.
Returns HTML with tok-* spans. Processes strings, comments, numbers, keywords.
| Parameter | Type | Optional | Description |
|---|---|---|---|
raw | any |
Returns:
any Signature
highlightCode(raw: any): any
Signature
descHtml(item: any, symbolMap: any, filePath: any): any
Signature
renderParams(params: any, jsdocParams: any): any
Signature
renderReturns(returnType: any, returnsTag: any): any
Signature
renderThrows(throws: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
text | any | ||
symbolMap | any | ||
filePath | any | ||
moduleHtmlPathFn | any | ||
modules | any |
Returns:
any Signature
resolveLinks(text: any, symbolMap: any, filePath: any, moduleHtmlPathFn: any, modules: any): any
Signature
sourceLink(item: any, filePath: any, sourceUrl: any): any
Signature
collapsible(label: any, html: any, open: any): any
Signature
buildFnSig(fn: any): any
Signature
buildClassSig(cls: any): any
Signature
buildIfaceSig(iface: any): any
Signature
card(id: any, kindClass: any, proseHtml: any, codeHtml: any): any
Signature
codePanel(item: any, sigText: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
fn | any | ||
filePath | any | ||
sourceUrl | any | ||
symbolMap | any | ||
functionHealthLookup | any |
Returns:
any Signature
renderFunction(fn: any, filePath: any, sourceUrl: any, symbolMap: any, functionHealthLookup: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
cls | any | ||
filePath | any | ||
sourceUrl | any | ||
symbolMap | any | ||
functionHealthLookup | any |
Returns:
any Signature
renderClass(cls: any, filePath: any, sourceUrl: any, symbolMap: any, functionHealthLookup: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
iface | any | ||
filePath | any | ||
sourceUrl | any | ||
symbolMap | any |
Returns:
any Signature
renderInterface(iface: any, filePath: any, sourceUrl: any, symbolMap: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
enm | any | ||
filePath | any | ||
sourceUrl | any | ||
symbolMap | any |
Returns:
any Signature
renderEnum(enm: any, filePath: any, sourceUrl: any, symbolMap: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
ta | any | ||
filePath | any | ||
sourceUrl | any | ||
symbolMap | any |
Returns:
any Signature
renderTypeAlias(ta: any, filePath: any, sourceUrl: any, symbolMap: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
v | any | ||
filePath | any | ||
sourceUrl | any | ||
symbolMap | any |
Returns:
any Signature
renderVariable(v: any, filePath: any, sourceUrl: any, symbolMap: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
title | any | ||
items | any | ||
renderFn | any | ||
filePath | any | ||
sourceUrl | any | ||
symbolMap | any | ||
functionHealthLookup | any |
Returns:
any Signature
section(title: any, items: any, renderFn: any, filePath: any, sourceUrl: any, symbolMap: any, functionHealthLookup: any): any
Signature
commonRoot(modules: any): any
Signature
moduleLabel(filePath: any, modules: any): any
Signature
moduleHtmlPath(filePath: any, modules: any): any
Signature
deeperCommonRoot(labels: any): any
Signature
hasExports(mod: any): any
Builds a synthetic-root N-level tree from module file paths, reusing
deeperCommonRoot as a pre-pass. Single source of truth for buildSidebar
and buildIndexBody (adr-phase-i-tree-nav.md).
| Parameter | Type | Optional | Description |
|---|---|---|---|
modules | object[] |
Returns:
object — synthetic root TreeNode { name, type, children }Signature
pathTree(modules: any): any
Signature
shortLabelFor(label: any): any
Returns the array of ancestor dir TreeNodes (root to, not including, the
leaf) for the given module reference within the given tree.
| Parameter | Type | Optional | Description |
|---|---|---|---|
root | object | ||
targetMod | object |
Returns:
object[] Signature
ancestorChain(root: any, targetMod: any): any
Signature
walk(node: any, path: any): any
Signature
buildBody(item: any): any
Signature
buildSearchIndex(modules: any, prefix: any): any
Signature
push(name: any, kind: any, anchor: any, item: any)
Parses a site-data version-id (the ISO-timestamp segment
`site-data.js`'s `writeSiteData()` already bakes into
`site-data-history/site-data-<id>.json` filenames, dashes standing in for
the colons/dot a raw ISO string can't use in a filename) back into a
fixed, literal locale label -- never an invented relative-time phrase
("2 days ago" is not a preserved fact; story-doc-version-switcher AC4).
Falls back to the raw id string (still a real fact, just less pretty) if
the id doesn't match the expected shape or produces an invalid Date --
e.g. a rare collision-suffixed id like `<ts>-1`.
| Parameter | Type | Optional | Description |
|---|---|---|---|
versionId | string |
Returns:
string Signature
formatVersionLabel(versionId: any): any
Version-switcher control (story-doc-version-switcher): native
`<details>/<summary>` disclosure per ui-ux-designer's spec -- explicitly
NOT a `<select>` (rejected in the spec: needs a JS onchange handler to
navigate, breaking this project's zero/near-zero-script precedent).
Zero-history case renders a plain, non-interactive `<span>` instead of a
`<details>` with an empty menu -- a disclosure that opens to reveal
nothing-new-to-pick is a broken affordance (handoff notes, explicit).
the version-id being viewed when rendering inside a `site-versions/<id>/` snapshot.
rendered back to the output root where `site-versions/` and the live
`index.html` both live (differs from the page's own same-site asset
prefix when the page itself is inside a snapshot -- see buildSite()).
| Parameter | Type | Optional | Description |
|---|---|---|---|
currentVersionId | string|null | - null when rendering the live site; | |
versionIds | string[] | - `site-versions/` directory names, most-recent-first. | |
prefixToOutDirRoot | string | - relative path prefix from the page being |
Returns:
string Signature
buildVersionSwitcher(currentVersionId: any, versionIds: any, prefixToOutDirRoot: any): any
Signature
dirTitle(node: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
node | any | ||
depth | any | ||
modules | any | ||
prefix | any | ||
cache | any |
Signature
precomputeDefaultTree(node: any, depth: any, modules: any, prefix: any, cache: any)
| Parameter | Type | Optional | Description |
|---|---|---|---|
node | any | ||
depth | any | ||
modules | any | ||
activePath | any | ||
prefix | any | ||
activeModule | any | ||
ancestorsOfActive | any | ||
defaultCache | any |
Returns:
any Signature
renderTreeLevel(node: any, depth: any, modules: any, activePath: any, prefix: any, activeModule: any, ancestorsOfActive: any, defaultCache: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
modules | any | ||
projectName | any | ||
version | any | ||
activePath | any | ||
rootPrefix | any | ||
activeModule | any | ||
precomputedTree | any | ||
opts | any |
Returns:
any Signature
buildSidebar(modules: any, projectName: any, version: any, activePath: any, rootPrefix: any, activeModule: any, precomputedTree: any, opts: any): any
Signature
buildToc(mod: any): any
Signature
buildSymbolMap(modules: any): any
Bounded breadcrumb segments for an index card (task-pi-05c): drops the
filename, keeps at most the last 2 directory segments, prefixing an
ellipsis when the path is deeper than that.
| Parameter | Type | Optional | Description |
|---|---|---|---|
sl | string |
Returns:
string[]|null Signature
cardBreadcrumb(sl: any): any
Signature
buildIndexBody(modules: any): any
Signature
_short(label: any): any
Signature
qColor(score: any, kind: any): any
Signature
qCountColor(n: any): any
Signature
qWarnColor(n: any): any
Signature
qSeverityColor(sev: any): any
Display-only letter grade for the Code Health hero gauge
(story-code-health-redesign, ADR Decision 5). This is a purely cosmetic,
finer-grained scale layered ON TOP OF `qColor`'s existing 3-band
thresholds -- it does NOT replace or compete with them. The gauge's arc
color and score text color must still come from `qColor(score, "health")`;
a "B+" and a "B" can legitimately render in the same color, same as two
scores in the same qColor band always have.
| Parameter | Type | Optional | Description |
|---|---|---|---|
score | number | - 0-100 health score (result.averageHealthScore). |
Returns:
string — a letter grade, or "—" if score isn't a finite number.Signature
scoreToGrade(score: any): any
Signature
qStatCard(label: any, value: any, color: any): any
Renders one qcard-row (shared between a card's always-visible preview and
its inline "view more" expansion — same lightweight [label, value, color?]
shape used since story-code-health-drilldown, deliberately NOT the richer
detail-page `<table>` row shape, so smell ids etc. stay detail-page-only,
see story-code-health-redesign's requirement #6).
| Parameter | Type | Optional | Description |
|---|---|---|---|
r | [string, string|number|null, string|null] |
Returns:
string Signature
qCardRow(r: any): any
Renders one focus-area card for the index page's Code Health section
(story-code-health-redesign, restyling story-code-health-drilldown's
original card). Shows up to 5 rows inline; any remaining rows are
reachable via a native `<details>` expand (zero client JS — see ADR
Decision 3) rather than only via the standalone detail page. The
standalone detail-page link ("open full page") remains, unconditionally,
per requirement #6 — this is additive, not a replacement.
| Parameter | Type | Optional | Description |
|---|---|---|---|
opts | {title: string, statLineHtml?: string, rows: Array<[string, string|number|null, string|null]>, moreHref: string, moreLabel: string, tag: string, tagBg: string, tagText: string, tagColor: string, bigValue: string, bigCaption: string} |
Returns:
string Signature
qCard(opts: any): any
Score-of helper for a code-multivitals Snapshot (story-code-health-redesign
ADR Decision 6). Snapshot shape per `node_modules/code-multivitals/dist/snapshots.d.ts`:
`{path, timestamp, result}` — `result` is a full AnalysisResult, same shape
runQuality() returns, so `.averageHealthScore` is already there, no new field.
| Parameter | Type | Optional | Description |
|---|---|---|---|
snapshot | {result?: {averageHealthScore?: number}} |
Returns:
number|null Signature
qSnapshotScore(snapshot: any): any
Renders the hero panel's trend sparkline + delta badge (story-code-health-redesign,
ADR Decision 6). `loadQualitySnapshots()` returns snapshots sorted oldest-first;
this renders up to the last 6. Fewer than 2 usable snapshots -> an honest
"not enough history yet" message, never a fabricated/flat line.
| Parameter | Type | Optional | Description |
|---|---|---|---|
snapshots | Array<object> | - `quality.snapshots` (may be empty/undefined). |
Returns:
string Signature
buildHealthSparkline(snapshots: any): any
Renders the Code Health hero panel (story-code-health-redesign): a
circular CSS `conic-gradient` gauge (grade + score, both derived from
`result.averageHealthScore` and colored via the existing `qColor` bands —
ADR Decision 5), the 6 non-gauge stat entries previously shown as separate
`.qstat-card`s, and the trend sparkline/delta badge (ADR Decision 6).
| Parameter | Type | Optional | Description |
|---|---|---|---|
result | object | - runQuality() AnalysisResult. | |
snapshots | Array<object> | - `quality.snapshots`, may be empty/undefined. |
Returns:
string Signature
buildHealthHero(result: any, snapshots: any): any
Signature
attentionList(result: any): any
Signature
attentionRowsHtml(list: any): any
Signature
cloneRowsHtml(clones: any): any
Signature
importRowsHtml(entries: any): any
Signature
orphanRowsHtml(orphans: any): any
Renders the code-multivitals health summary as an inline section for the
doc site's index page (story-code-health-drilldown, 2026-07-06): 7 stat
cards unchanged, followed by 4 summary cards (previously 4 full inline
tables) each linking to its own uncapped detail page — see
buildHealthDetailPages(). Detail-page hrefs are plain root-relative
filenames, valid whether this section renders on index.html directly or
is exercised standalone in tests.
| Parameter | Type | Optional | Description |
|---|---|---|---|
quality | {result: object, graph?: object, orphans?: string[]} |
Returns:
string — HTML for a <div class="section"> block.Signature
buildQualitySection(quality: any): any
Builds the 4 full-list Code Health detail pages (story-code-health-drilldown
AC3). Placed at the OUTPUT ROOT, sibling to index.html — NOT inside
modules/ (see docs/backlog/story-code-health-drilldown.md's "Correction
caught during verification": module pages live in modules/, these are
extensions of the index page's Code Health section, not per-module
content). Only called when options.quality is present.
| Parameter | Type | Optional | Description |
|---|---|---|---|
quality | {result: object, graph?: object, orphans?: string[]} | ||
modules | object[] | ||
projectName | string | ||
version | string | ||
tree | object | - precomputed pathTree(modules), reused from buildSite. | |
switcherHtml | any | ||
defaultCache | any | ||
parentsLinked | any |
Returns:
{path: string, html: string}[] Signature
buildHealthDetailPages(quality: any, modules: any, projectName: any, version: any, tree: any, switcherHtml: any, defaultCache: any, parentsLinked: any): any
Signature
wrap(slug: any, title: any, tableHtml: any)
Precomputes a filePath-keyed lookup of per-file health data for the
module-page strip (story-code-health-drilldown AC4/AC8). Built once per
buildSite() call, not per module page. Join key is path.resolve(filePath)
— code-multivitals's FileReport.filePath and this project's own
mod.filePath are both whatever string was in the `files` array passed to
extractModule()/runQuality() (same array, same run), so they already
match string-for-string in the common case; resolving both sides is a
defensive normalization, not a fix for a known mismatch.
Per-file error/warning counts and function count are not provided
directly by code-multivitals's FileSummary — they're derived here by
counting existing FunctionReport.metrics[].severity entries and
FileReport.functions.length, reusing data already present in the
analyse() result (no new metrics).
| Parameter | Type | Optional | Description |
|---|---|---|---|
quality | {result: object} |
Returns:
Object<string, object> Signature
buildFileHealthLookup(quality: any): any
Per-function/method Code Health matching (story-function-level-health-drilldown).
Empirical finding (TICKET-1, checked live against sample/container.ts via
runQuality()): code-multivitals emits BARE method names for class members
("constructor", "resolve", "debug", ...) -- never a "ClassName.methodName"
composite, even when multiple classes in the same file share a method name
(three unrelated classes in that fixture each have their own "constructor"
entry at different line ranges). Point-in-range matching against
startLine/endLine is what actually disambiguates same-named methods across
classes, not the name alone -- so no composite-name fallback path is
implemented; it would never be reached.
Matching strategy (solutions-architect decision): name + point-in-range
(extracted.line within [fn.startLine, fn.endLine] inclusive), tightest
(smallest) range wins on ambiguous/nested matches. Returns an object with
a `match(name, line)` method rather than a plain map, since resolution
needs a computed range-containment check per lookup, not a static key --
callers can always call `.match()` safely, never need to null-check the
lookup object itself.
| Parameter | Type | Optional | Description |
|---|---|---|---|
quality | {result: object} | ||
filePath | string |
Returns:
{match: function(string, number): (object|null)} Signature
buildFunctionHealthLookup(quality: any, filePath: any): any
Compact inline per-function/method health chip row (story-function-level-
health-drilldown). Reuses scoreToGrade()/qColor()/qSeverityColor() verbatim
at a smaller, inline scale -- deliberately not a second full gauge (AC2:
must read as subordinate to the per-file hero above it on the same page).
Graceful fallback (AC3/architect Decision 4): no matching FunctionReport ->
a single muted qchip-empty span, never a broken/NaN render, never a silent
fall-back to file-level aggregate data.
| Parameter | Type | Optional | Description |
|---|---|---|---|
name | string | ||
line | number|null | ||
healthLookup | {match: function} |
Returns:
string Signature
functionHealthChip(name: any, line: any, healthLookup: any): any
Signature
qChip(label: any, value: any, color: any, href: any): any
Short, factual one-line summary built purely from real per-file counts
(story-file-detail-redesign AC1). Deliberately NOT the File Detail
mockup's stylized "encouraging" copy ("Nearly there -- clear the 2
clones and this file ships clean.") -- that would be invented,
un-derivable prose, the same category story-code-health-redesign
already declined to build for the index-page hero. Every clause here is
a literal count already in `d`.
| Parameter | Type | Optional | Description |
|---|---|---|---|
d | object | - buildFileHealthLookup() entry for one file. |
Returns:
string Signature
fileHeroNarrative(d: any): any
Per-file hero panel for module pages (story-file-detail-redesign,
replacing the old flat `.qstrip` chip row -- ADR Decision 1). Reuses
story-code-health-redesign's gauge/grade primitives (`scoreToGrade()`,
`qColor()` bands) verbatim, scoped to this one file's
`weightedHealthScore`/`weightedMI` instead of the project-wide average.
Files with no code-multivitals entry keep the same graceful fallback
`buildHealthStrip()` always had -- one muted row, never a broken/zero
gauge.
| Parameter | Type | Optional | Description |
|---|---|---|---|
mod | object | ||
healthLookup | Object<string, object> | - buildFileHealthLookup() output. | |
cloneHref | string | - relative href to health-duplicates.html from a module page. |
Returns:
string Signature
buildFileHero(mod: any, healthLookup: any, cloneHref: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
mod | any | ||
sourceUrl | any | ||
symbolMap | any | ||
functionHealthLookup | any |
Returns:
any Signature
buildModuleBody(mod: any, sourceUrl: any, symbolMap: any, functionHealthLookup: any): any
| Parameter | Type | Optional | Description |
|---|---|---|---|
title | any | ||
sidebarHtml | any | ||
bodyHtml | any | ||
assetPrefix | any | ||
topnavHtml | any | ||
tocHtml | any |
Returns:
any Signature
page(title: any, sidebarHtml: any, bodyHtml: any, assetPrefix: any, topnavHtml: any, tocHtml: any): any
Variables & Constants(270)
Signature
let toOutDirRootFromIndex: any
Signature
let toOutDirRootFromModule: any