jsdoc-scribe API/lib/project-factsv2.5.3
Functions(19)
#readJsonSafe
line 55
Read and JSON-parse a file, returning `fallback` on any error.
ParameterTypeOptionalDescription
filePathstring
fallback*
Returns: *
Signature
readJsonSafe(filePath: any, fallback: any): any
#getNodeVersions
line 70
Node version facts: the package's declared minimum vs. what CI actually tests against. Surfaced separately and explicitly -- not collapsed into one answer -- because they may legitimately differ (see story-dev-onboarding-dashboard AC1).
ParameterTypeOptionalDescription
rootDirstring
Returns: {declaredMin: (string|null), ciTested: number[], matches: boolean}
Signature
getNodeVersions(rootDir: any): any
#getPackageManager
line 96
Which package manager this repo uses, detected from lockfile presence.
ParameterTypeOptionalDescription
rootDirstring
Returns: {manager: string, lockfile: (string|null)}
Signature
getPackageManager(rootDir: any): any
#getGlobalDependencies
line 120
Global (machine-wide) dependencies required to work on this repo. Static, but reasoned from the same repo-state signals as the rest of this module -- zero devDependencies historically meant zero global tooling beyond Node/npm/git; the new code-multivitals devDependency doesn't change that (it's invoked via its programmatic API, never a global install or npx network fetch in CI since `npm ci` already resolves it).
ParameterTypeOptionalDescription
rootDirstring
Returns: {required: string[], conditionallyRequired: string[]}
Signature
getGlobalDependencies(rootDir: any): any
#summarizeFileExtensions
line 136
Count files directly inside `dirPath`, grouped by extension (e.g. `{ ".ts": 12, ".test.js": 3 }`). Non-recursive -- one directory's own files only, computed in the same readdir pass the walk already does.
ParameterTypeOptionalDescription
dirPathstring
Returns: object
Signature
summarizeFileExtensions(dirPath: any): any
#describeDirectory
line 167
Recursively describe one directory: its known/fallback description, a file-extension summary, and (while under `maxDepth`) its child directories in the same shape.
ParameterTypeOptionalDescription
dirPathstring
namestring
depthnumber- 1-based depth of this directory from rootDir.
maxDepthnumber
Returns: object
Signature
describeDirectory(dirPath: any, name: any, depth: any, maxDepth: any): any
#getProjectStructure
line 198
Nested map of the project structure, generated by walking the actual filesystem (not hand-maintained). Each entry reports its own description, a per-extension file-count summary, and -- while under the configured depth -- its child directories in the same shape.
ParameterTypeOptionalDescription
rootDirstring
options{depth: number}yes- max walk depth from rootDir, default 3.
Returns: {name: string, description: string, files: object, children: (Array|undefined)}[]
Signature
getProjectStructure(rootDir: any, options: any): any
#getWorkspacePackages
line 221
Resolve npm workspace packages declared in the root `package.json`'s `workspaces` field into concrete facts, read from each package's own `package.json` -- never hand-typed. Supports `"dir/*"` glob-style patterns (this repo's own convention, and the overwhelmingly common shape in practice) plus exact directory entries.
ParameterTypeOptionalDescription
rootDirstring
Returns: {name: string, path: string, description: (string|null)}[]
Signature
getWorkspacePackages(rootDir: any): any
#addIfPackage
line 227
ParameterTypeOptionalDescription
pkgDirany
Signature
addIfPackage(pkgDir: any)
#collectDependencyNames
line 292
Collect every `dependencies`/`devDependencies`/`peerDependencies` key from one `package.json`.
ParameterTypeOptionalDescription
pkgJsonPathstring
Returns: Set<string>
Signature
collectDependencyNames(pkgJsonPath: any): any
#collectExtensionsFromStructure
line 311
Walk a `getProjectStructure()` result (including nested `children`) collecting every extension key seen, so the file-heuristic fallback can reuse Phase 1's already-computed walk instead of touching the filesystem a second time.
ParameterTypeOptionalDescription
structureobject[]
Returns: Set<string>
Signature
collectExtensionsFromStructure(structure: any): any
#getFrameworkSignals
line 339
Dependency-based framework/stack detection: which of a fixed set of frameworks (React, Next.js, Angular, Vue, Express, NestJS) this project appears to use, with evidence for every signal -- never a bare label. Reads `package.json` dependency fields (root + every workspace package from `getWorkspacePackages`) as primary evidence; falls back to `getProjectStructure`'s existing file-extension counts (no second filesystem walk) when a framework-shaped file extension is present but no matching dependency was found anywhere. reuse instead of walking the tree again (2026-07-31: getAllFacts() already walks once at depth 4 for the `structure` field -- passing it through here avoids a second, redundant filesystem walk). Falls back to its own walk when called standalone (e.g. directly from tests).
ParameterTypeOptionalDescription
rootDirstring
precomputedStructureobject[]yes- a `getProjectStructure()` result to
Returns: {name: string, confidence: ("dependency"|"file-heuristic"), evidence: string}[]
Signature
getFrameworkSignals(rootDir: any, precomputedStructure: any): any
#collectDirectoryNamesFromStructure
line 398
Collect every directory name appearing anywhere in a `getProjectStructure()` result (including nested `children`, recursively) into a Set. Reused by getArchitectureSignals() instead of a second filesystem walk.
ParameterTypeOptionalDescription
structureobject[]
Returns: Set<string>
Signature
collectDirectoryNamesFromStructure(structure: any): any
#getArchitectureSignals
line 422
Architecture-pattern signals: independent, evidence-backed observations (never a single forced "the architecture is X" label -- see adr-architecture-pattern-signals.md). Every rule is deterministic and reuses Phase 1 (`getProjectStructure`, `getWorkspacePackages`) and Phase 2 (`getFrameworkSignals`) output -- zero new filesystem calls. param doc -- threaded through to both the local dirName check and the internal getFrameworkSignals() call so this function costs zero extra filesystem walks when called from getAllFacts().
ParameterTypeOptionalDescription
rootDirstring
precomputedStructureobject[]yes- see getFrameworkSignals()'s
Returns: {name: string, evidence: string}[]
Signature
getArchitectureSignals(rootDir: any, precomputedStructure: any): any
#findStructureNodeByName
line 781
Recursively find the first structure node matching `name` at any depth (e.g. "features" nested as src/features/, not just a rootDir-level directory) -- most real projects put this kind of folder under src/, not at the repo root, so a depth-1-only search would miss them.
ParameterTypeOptionalDescription
structureobject[]
namestring
Returns: object|null
Signature
findStructureNodeByName(structure: any, name: any): any
#isVerticalSliceNode
line 806
A features/modules node "is" Vertical Slice (rather than plain Feature-Based) when at least one of its own child directories itself contains 2+ of the layer-shaped subdirectory names above.
ParameterTypeOptionalDescription
nodeobject- a getProjectStructure() node (already has .children).
Returns: boolean
Signature
isVerticalSliceNode(node: any): any
#getArchitecturePatterns
line 839
Detects which of a fixed reference catalog of common architectural patterns (ARCHITECTURE_PATTERN_DEFINITIONS) this project's own directory names, dependencies, and root-level files match. Every returned entry carries the same evidence-or-nothing discipline as getArchitectureSignals() -- a pattern only appears here when `detect()` found real, cited evidence, never a guess. This is the deeper companion to getArchitectureSignals()'s lighter "what kind of project is this" signals -- "what architecture pattern does this codebase actually use". to reuse instead of walking the filesystem again (getAllFacts() passes its own already-computed `structure` field here). Falls back to a fresh depth-4 walk when omitted, e.g. when this function is called standalone. Depth is capped at 4, not deeper: measured directly against this repo's own tree, depth 3->4 cost ~700ms extra (709ms -> 1413ms) but depth 4->5 cost ~6.4s more (7.8s) and depth 6 took ~19s -- a generated/versioned output directory sitting inside the scanned root (this repo's own docs-dashboard/site-versions/, which nests full copies of prior site generations) blows up combinatorially past depth 4. A real user's --out directory can just as easily live inside the directory being documented, so this cap protects every caller, not just this repo's own dogfooding case.
ParameterTypeOptionalDescription
rootDirstring
precomputedStructureobject[]yes- a `getProjectStructure()` result
Returns: {name: string, description: string, link: string, evidence: string}[]
Signature
getArchitecturePatterns(rootDir: any, precomputedStructure: any): any
#getTestInfo
line 885
Test-tooling facts: no framework, hand-rolled runner, no HTTP API.
ParameterTypeOptionalDescription
rootDirstring
Returns: {framework: (string|null), runner: string, suiteCount: (number|null), hasHttpApi: boolean}
Signature
getTestInfo(rootDir: any): any
#getAllFacts
line 907
Compose all onboarding facts into one object for the dashboard renderer.
ParameterTypeOptionalDescription
rootDirstringyes- defaults to process.cwd().
Returns: object
Signature
getAllFacts(rootDir: any): any
Variables & Constants(91)
const fs: any
const
lib/project-facts.js ---------------------------------------- Onboarding-facts generator for the internal project dashboard (Track A, see docs/backlog/adr-phase-j-project-dashboard.md). Every fact is derived by reading the repo's actual current state -- package.json, CI workflow YAML, the real directory tree -- never hand-typed prose that can drift out of sync with reality.
Signature
const fs: any
const path: any
const
Signature
const path: any
#KNOWN_DIR_DESCRIPTIONS
line 16
const KNOWN_DIR_DESCRIPTIONS: Object
const
Signature
const KNOWN_DIR_DESCRIPTIONS: Object
#IGNORE_DIR_NAMES
line 47
const IGNORE_DIR_NAMES: Set
const
Signature
const IGNORE_DIR_NAMES: Set
const pkg: any
const
Signature
const pkg: any
#declaredMin
line 72
const declaredMin: any
const
Signature
const declaredMin: any
#ciTested
line 74
let ciTested: Array
var
Signature
let ciTested: Array
#ciText
line 76
const ciText: any
const
Signature
const ciText: any
const match: any
const
Signature
const match: any
#declaredMinNumber
line 85
const declaredMinNumber: any
const
Signature
const declaredMinNumber: any
#matches
line 86
const matches: any
const
Signature
const matches: any
#candidates
line 97
const candidates: Array
const
Signature
const candidates: Array
#entries
line 137
let entries: any
var
Signature
let entries: any
#counts
line 143
const counts: Object
const
Signature
const counts: Object
const base: any
const
Signature
const base: any
#twoPart
line 150
const twoPart: any
const
Signature
const twoPart: any
const ext: any
const
Signature
const ext: any
const node: Object
const
Signature
const node: Object
#entries
line 174
let entries: any
var
Signature
let entries: any
#children
line 180
const children: any
const
Signature
const children: any
#maxDepth
line 199
const maxDepth: any
const
Signature
const maxDepth: any
#entries
line 200
let entries: any
var
Signature
let entries: any
const pkg: any
const
Signature
const pkg: any
const raw: any
const
Signature
const raw: any
#patterns
line 224
const patterns: any
const
Signature
const patterns: any
#results
line 225
const results: Array
const
Signature
const results: Array
#pkgJson
line 228
const pkgJson: any
const
Signature
const pkgJson: any
#baseDir
line 239
const baseDir: any
const
Signature
const baseDir: any
#entries
line 240
let entries: any
var
Signature
let entries: any
#FRAMEWORK_MARKERS
line 264
const FRAMEWORK_MARKERS: Object
const
Signature
const FRAMEWORK_MARKERS: Object
#FILE_HEURISTIC_RULES
line 276
const FILE_HEURISTIC_RULES: Array
const
Signature
const FILE_HEURISTIC_RULES: Array
const pkg: any
const
Signature
const pkg: any
const names: Set
const
Signature
const names: Set
const exts: Set
const
Signature
const exts: Set
#signals
line 340
const signals: Array
const
Signature
const signals: Array
#foundNames
line 341
const foundNames: Set
const
Signature
const foundNames: Set
const roots: any
const
Signature
const roots: any
const names: any
const
Signature
const names: any
#displayName
line 352
const displayName: any
const
Signature
const displayName: any
#structure
line 362
const structure: any
const
Signature
const structure: any
#extensionsSeen
line 363
const extensionsSeen: any
const
Signature
const extensionsSeen: any
#matchedExt
line 365
const matchedExt: any
const
Signature
const matchedExt: any
#MVC_DIR_NAMES
line 384
const MVC_DIR_NAMES: Array
const
Signature
const MVC_DIR_NAMES: Array
#LAYERED_DIR_NAME_GROUPS
line 385
const LAYERED_DIR_NAME_GROUPS: Array
const
Signature
const LAYERED_DIR_NAME_GROUPS: Array
const names: Set
const
Signature
const names: Set
#signals
line 423
const signals: Array
const
Signature
const signals: Array
const pkg: any
const
Signature
const pkg: any
#binNames
line 427
const binNames: any
const
Signature
const binNames: any
#workspacePackages
line 435
const workspacePackages: any
const
Signature
const workspacePackages: any
#dependencyFrameworks
line 443
const dependencyFrameworks: any
const
Signature
const dependencyFrameworks: any
#dependencyNames
line 444
const dependencyNames: any
const
Signature
const dependencyNames: any
#backendFrameworks
line 446
const backendFrameworks: any
const
Signature
const backendFrameworks: any
#frontendFrameworks
line 451
const frontendFrameworks: any
const
Signature
const frontendFrameworks: any
#dirNames
line 456
const dirNames: any
const
Signature
const dirNames: any
#matchedMvc
line 458
const matchedMvc: any
const
Signature
const matchedMvc: any
#matchedLayeredGroups
line 467
const matchedLayeredGroups: any
const
Signature
const matchedLayeredGroups: any
#ARCHITECTURE_PATTERN_DEFINITIONS
line 492
const ARCHITECTURE_PATTERN_DEFINITIONS: Array
const
Signature
const ARCHITECTURE_PATTERN_DEFINITIONS: Array
#matched
line 499
const matched: any
const
Signature
const matched: any
#matched
line 510
const matched: any
const
Signature
const matched: any
#hasUseCases
line 535
const hasUseCases: any
const
Signature
const hasUseCases: any
#hasEvents
line 590
const hasEvents: any
const
Signature
const hasEvents: any
#eventLibs
line 594
const eventLibs: any
const
Signature
const eventLibs: any
#serverish
line 606
const serverish: any
const
Signature
const serverish: any
#modulesNode
line 634
const modulesNode: any
const
Signature
const modulesNode: any
#matched
line 647
const matched: any
const
Signature
const matched: any
#serverlessDeps
line 662
const serverlessDeps: any
const
Signature
const serverlessDeps: any
#matched
line 683
const matched: any
const
Signature
const matched: any
#pubsubDeps
line 696
const pubsubDeps: any
const
Signature
const pubsubDeps: any
const node: any
const
Signature
const node: any
const node: any
const
Signature
const node: any
#dirMatch
line 750
const dirMatch: any
const
Signature
const dirMatch: any
#pkgMatch
line 752
const pkgMatch: any
const
Signature
const pkgMatch: any
#pkgMatch
line 765
const pkgMatch: any
const
Signature
const pkgMatch: any
const found: any
const
Signature
const found: any
#VERTICAL_SLICE_LAYER_DIR_NAMES
line 797
const VERTICAL_SLICE_LAYER_DIR_NAMES: Array
const
Signature
const VERTICAL_SLICE_LAYER_DIR_NAMES: Array
#childDirNames
line 808
const childDirNames: any
const
Signature
const childDirNames: any
#matched
line 809
const matched: any
const
Signature
const matched: any
const pkg: any
const
Signature
const pkg: any
#workspacePackages
line 841
const workspacePackages: any
const
Signature
const workspacePackages: any
#structureDeep
line 845
const structureDeep: any
const
Signature
const structureDeep: any
#dirNames
line 846
const dirNames: any
const
Signature
const dirNames: any
#rootFileNames
line 848
let rootFileNames: Array
var
Signature
let rootFileNames: Array
#rootFiles
line 856
const rootFiles: Set
const
Signature
const rootFiles: Set
#dependencyNames
line 858
const dependencyNames: Set
const
Signature
const dependencyNames: Set
const ctx: Object
const
Signature
const ctx: Object
#evidence
line 873
const evidence: any
const
Signature
const evidence: any
#suiteCount
line 886
let suiteCount: any
var
Signature
let suiteCount: any
#runnerText
line 888
const runnerText: any
const
Signature
const runnerText: any
#matches
line 889
const matches: any
const
Signature
const matches: any
const dir: any
const
Signature
const dir: any
#structure
line 918
const structure: any
const
Signature
const structure: any