@svelte-vitals/core 0.43.0 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,883 @@
1
+ import { C as ComponentFacts, S as SuppressionDirective, R as Runtime, K as KitAlias, a as KitModuleFacts, V as Value, b as Rule, c as RuleContext, d as Result, e as Category, f as Severity, F as Fix, g as RuleOptionSpec, H as HeadTag, h as ResolvedHead, I as ImageInfo, i as Config, J as JsonReport } from './index-CWWQEu8q.js';
2
+ export { A as A11yOccurrenceInfo, B as BranchStep, j as Classification, k as CompiledOverride, E as EachBlockFact, l as EffectFact, m as HeadProvider, n as HeadingInfo, o as HealthResult, p as IDREF_ATTRS, L as LANDMARK_ROLES, O as OrphanEffectFact, P as Project, q as READ_CONCURRENCY, r as ResolvedA11y, s as ResolvedHeadings, t as ResolvedImages, u as RuleOptionsSpec, v as Scope, w as ScoreOptions, x as ScoreResult, y as SourceSpan, z as applyOverrides, D as applyRuleSeverities, G as buildJsonReport, M as classify, N as compileOverrides, Q as computeHealth, T as computeScore, U as decodeFragmentId, W as defaultConfig, X as defaultProject, Y as docsUrlFor, Z as effectiveSeverity, _ as foldOccurrences, $ as formatFailedRuleWarning, a0 as formatJsonReport, a1 as hasFailureAtOrAbove, a2 as intOption, a3 as isMentionedAnywhere, a4 as isPenalized, a5 as isTopFragment, a6 as listOption, a7 as mapOption, a8 as overrideMatches, a9 as resolveRuleOptions, aa as scoresByCategory, ab as selectRules, ac as settingOptions, ad as settingSeverity, ae as shouldSkipRangeCheck, af as skippedFileWarnings, ag as splitTokens, ah as stripTextDirective, ai as summarize, aj as validateRuleOptions, ak as validateRuleSetting, al as withFailedRulesOff, am as withReadLimit } from './index-CWWQEu8q.js';
3
+ import { AST } from 'svelte/compiler';
4
+
5
+ /** What the per-file parsers produce — `ComponentFacts` minus `file`, with `suppressions` always present. */
6
+ type ParsedFacts = Omit<ComponentFacts, 'file' | 'suppressions'> & {
7
+ suppressions: SuppressionDirective[];
8
+ };
9
+ /**
10
+ * Parse one source file's facts (CLI/static + vite build mode): a `.svelte` component's
11
+ * reactivity/correctness + security + architecture facts, or a `.svelte.ts`/`.svelte.js`
12
+ * runes module's orphan-$effect facts (correctness/orphan-effect).
13
+ */
14
+ declare function parseComponentFacts(source: string, filename: string): ParsedFacts;
15
+
16
+ /**
17
+ * Fallback facts for a file that fails to read or parse (dev tooling must never
18
+ * throw). This is the single source of truth for the empty-facts shape — add new
19
+ * `ComponentFacts` fields HERE so TypeScript catches every call site that still
20
+ * needs updating.
21
+ */
22
+ declare function emptyComponentFacts(file: string): ComponentFacts;
23
+ /**
24
+ * Scan every `.svelte` component and `.svelte.ts`/`.svelte.js` runes module under `src/`
25
+ * for Correctness/Security/Architecture/Bundle-Performance/Accessibility facts. Independent
26
+ * of route resolution — covers `$lib` and non-route components too. A file that fails to
27
+ * read or parse contributes empty facts instead of aborting the whole scan (dev tooling
28
+ * must never throw).
29
+ */
30
+ declare function collectComponentFacts(rt: Runtime, cwd: string): Promise<ComponentFacts[]>;
31
+
32
+ /**
33
+ * Every file under `src/`, as project-relative paths, sorted. Paths only — nothing is
34
+ * read, so this is the cheaper of the two passes over `src/` (the component collector
35
+ * already walks the same tree and reads every `.svelte`).
36
+ *
37
+ * Directory-shaped rules derive their directory set from these paths' ancestor prefixes
38
+ * rather than globbing a second time; see `architecture/unit-entry-file`. The list is
39
+ * sorted so anything that picks "the first file under a directory" is deterministic.
40
+ *
41
+ * Two properties of the result the directory-shaped rules depend on: a directory containing no file
42
+ * at any depth does not appear among these paths' ancestor prefixes and so does not exist as far as
43
+ * those rules are concerned, and dot directories never appear at all (see `Runtime.glob`).
44
+ */
45
+ declare function collectSourceFiles(rt: Runtime, cwd: string): Promise<string[]>;
46
+
47
+ /**
48
+ * Resolve an import specifier to a path relative to the analyzed project's root (the
49
+ * cwd svelte-vitals runs from — not necessarily a repo root; in a monorepo the project
50
+ * may live at e.g. `apps/web/`) against the importing file, or undefined when it cannot
51
+ * be a project-local module: the caller's `aliases` list decides which non-relative
52
+ * specifiers resolve, defaulting to `$lib` → `src/lib`; `./`/`../` resolve against the
53
+ * importing file's directory; bare packages and other aliases are skipped (they can't
54
+ * be resolved to a project-local path at all). Also undefined when a relative
55
+ * specifier's `..` segments escape the project root (see `normalizePosix`), or when a
56
+ * matched alias's value is itself absolute (e.g. `/opt/shared/src`, or a posixified Windows
57
+ * drive-letter path like `C:/shared/src`): an absolute target is outside the analyzed project by
58
+ * definition, and without this check `normalizePosix` would quietly drop the leading empty
59
+ * segment and hand back a project-relative-LOOKING path that actually names a different file.
60
+ *
61
+ * Exported from the package's public barrel because `architecture/private-scope-import`
62
+ * and `architecture/route-component-import` (inside `packages/core`) both need resolution
63
+ * that is not restricted to runes modules, unlike `resolveRunesModuleSpecifier` — and
64
+ * because `resolveComponentPath` (`packages/cli/src/providers/source/resolve.ts`), which
65
+ * drives transitive `<head>`/heading resolution, delegates its alias/`$lib`/relative
66
+ * mapping here too, rather than duplicating it. This is the single site for every
67
+ * repo-local specifier resolution in the repo.
68
+ */
69
+ declare function resolveRepoLocalPath(spec: string, importerFile: string, aliases?: readonly KitAlias[]): string | undefined;
70
+ /**
71
+ * Resolve an import specifier to a repo-relative `.svelte.ts`/`.svelte.js` path, or
72
+ * undefined when it cannot be a runes module: delegates to `resolveRepoLocalPath` with
73
+ * `aliases` (defaulting to `$lib` → `src/lib` when omitted), so a project's declared
74
+ * `kit.alias`/`kit.files.lib` resolve here exactly as they do at rule time; `./`/`../`
75
+ * resolve against the importing file's directory; bare packages, unmatched aliases, and
76
+ * a relative specifier whose `..` segments escape the repo root are skipped. An
77
+ * extensionless `…/x.svelte` specifier canonicalises to `….svelte.ts` (security/shared-state-import also
78
+ * tries the `.js` sibling when matching).
79
+ */
80
+ declare function resolveRunesModuleSpecifier(spec: string, importerFile: string, aliases?: readonly KitAlias[]): string | undefined;
81
+ /**
82
+ * Parse one SvelteKit route/hooks file's SSR shared-state facts (the security kit-module rules). Uses
83
+ * the shared wrap parser (`parseModuleProgram`), so reported lines subtract the
84
+ * 1-line wrap prefix; suppressions are scanned on the unwrapped source.
85
+ */
86
+ declare function parseKitModuleFacts(source: string, filename: string, aliases?: readonly KitAlias[]): Omit<KitModuleFacts, 'file' | 'kind'>;
87
+
88
+ /** Fallback facts for a Kit file that fails to read or parse (dev tooling must never throw). */
89
+ declare function emptyKitModuleFacts(file: string, kind: KitModuleFacts['kind']): KitModuleFacts;
90
+ /**
91
+ * Scan SvelteKit route/hooks files for SSR shared-state facts (the security kit-module rules): route
92
+ * `+page`/`+layout` server and universal modules, `+server` endpoints, and
93
+ * `src/hooks.server`. `src/lib/server/**` is deliberately NOT scanned — legitimate
94
+ * module singletons (DB connections, clients) live there (design). A file that
95
+ * fails to read or parse contributes empty facts instead of aborting the scan.
96
+ *
97
+ * `aliases` is the project's compiled alias list (`Project.kitAliases`); omitted,
98
+ * specifiers resolve through `$lib` → `src/lib` only.
99
+ */
100
+ declare function collectKitModuleFacts(rt: Runtime, cwd: string, aliases?: readonly KitAlias[]): Promise<KitModuleFacts[]>;
101
+
102
+ /**
103
+ * The `build: { minify: false }` override, when present as a literal: returns the
104
+ * `minify` property's 1-based line in the ORIGINAL source. Undefined for clean,
105
+ * dynamic, or unparsable configs (never throws).
106
+ */
107
+ declare function findMinifyDisabled(source: string): {
108
+ line: number;
109
+ } | undefined;
110
+
111
+ /** What a Vite config says about SvelteKit's own configuration. */
112
+ type ViteKitConfigResult =
113
+ /** No `sveltekit()` call, or one with no argument — `svelte.config` still applies. */
114
+ {
115
+ kind: 'no-plugin-config';
116
+ }
117
+ /** `sveltekit(<something we can't resolve>)` — the effective config is unknowable AND
118
+ * `svelte.config` is provably ignored, so the caller must stay quiet. */
119
+ | {
120
+ kind: 'unresolvable';
121
+ }
122
+ /** `sveltekit({…})` resolved. `base` is unset when the config declares no non-empty base. */
123
+ | {
124
+ kind: 'resolved';
125
+ base?: {
126
+ value?: string;
127
+ };
128
+ };
129
+ /** `kit.alias` and `kit.files.lib` as written, before Kit compiles them into ordered entries. */
130
+ type RawKitAliases = {
131
+ /**
132
+ * `kit.alias` entries in declaration order, `value: null` where the config's value is not a
133
+ * string literal. **Undefined means the key set is unknowable** — a spread or a computed key
134
+ * puts an unknown key at a known position, and an unknown key could shadow anything after it,
135
+ * with no `find` to record that with. The caller then discards every user entry.
136
+ */
137
+ entries?: {
138
+ key: string;
139
+ value: string | null;
140
+ }[];
141
+ /**
142
+ * `kit.files.lib`, in three distinct states: **absent** (`undefined`) — there is no `lib`
143
+ * property, or `files` itself does not resolve to an object literal; a **literal** (the
144
+ * string) — `files.lib` is a string literal; **present but unreadable** (`null`) — the `lib`
145
+ * property exists but its value is not statically a string (e.g. a computed expression). The
146
+ * `null` state must not collapse into "absent": the caller cannot fall back to `src/lib`
147
+ * without risking a wrong answer, because the project may have moved `$lib` to something this
148
+ * parser simply couldn't read.
149
+ */
150
+ filesLib?: string | null;
151
+ };
152
+ /** `kit.alias` and `kit.files.lib` from a `svelte.config.{js,ts}` source. */
153
+ declare function findKitAliasesInSvelteConfig(source: string): RawKitAliases;
154
+ /**
155
+ * The project's compiled alias list, following SvelteKit's config precedence: options passed to
156
+ * the `sveltekit()` Vite plugin make `svelte.config` irrelevant (Kit logs "svelte.config.js is
157
+ * ignored when options are passed via your Vite config"), so aliases are read from
158
+ * `svelte.config` only when the Vite config carries no plugin config. Reading `kit.alias` out of
159
+ * a plugin config is deliberately not done — that costs reach, not correctness, and such a
160
+ * project keeps the resolver's default `$lib` behaviour. Undefined means "no config was read".
161
+ */
162
+ declare function resolveKitAliases(viteConfig: {
163
+ source: string;
164
+ } | undefined, svelteConfig: {
165
+ source: string;
166
+ } | undefined): KitAlias[] | undefined;
167
+ /** `kit.paths.base` from a `svelte.config.{js,ts}` source. */
168
+ declare function findKitPathsBaseInSvelteConfig(source: string): {
169
+ value?: string;
170
+ } | undefined;
171
+ /** SvelteKit config passed to the `sveltekit()` plugin in a Vite config source (since Kit 2.62). */
172
+ declare function findKitPathsBaseInViteConfig(source: string): ViteKitConfigResult;
173
+ /**
174
+ * The project's effective `kit.paths.base`, following SvelteKit's precedence: the `sveltekit()`
175
+ * plugin config when it carries one, otherwise `svelte.config`. `file` is the config the base
176
+ * came from (as passed in by the caller). Undefined means "no base path" — the gate stays shut.
177
+ */
178
+ declare function resolveKitPathsBase(viteConfig: {
179
+ file: string;
180
+ source: string;
181
+ } | undefined, svelteConfig: {
182
+ file: string;
183
+ source: string;
184
+ } | undefined): {
185
+ value?: string;
186
+ file: string;
187
+ } | undefined;
188
+
189
+ /**
190
+ * Parse a `.svelte` source, tolerating style blocks written in a CSS dialect.
191
+ *
192
+ * Svelte parses a `<style>` body as CSS whatever its `lang` says, so one `<style lang="scss">`
193
+ * makes a component unparseable — and one unparseable route file fails the entire run. On failure
194
+ * the dialect bodies are blanked to spaces of the same length (nothing here reads CSS, and equal
195
+ * length keeps every byte offset, so reported lines are unchanged) and the parse is retried.
196
+ *
197
+ * The retry, not the substitution, is the design: a file that parses today is never rewritten, so
198
+ * the text scan's imprecision cannot reach it. A file that does not parse is already a hard failure,
199
+ * which the retry can only improve on.
200
+ */
201
+ declare function parseSvelte(source: string, filename: string): AST.Root;
202
+ /** A template fragment's child node relevant to value classification: literal text or a `{expr}`. */
203
+ type TextOrExpr = AST.Text | AST.ExpressionTag;
204
+ /**
205
+ * All keys that can bear child nodes in a Svelte AST node.
206
+ * Covers if/each/await blocks (pending/then/catch/fallback) as well as
207
+ * the standard fragment, nodes, consequent, alternate, and body keys.
208
+ */
209
+ declare const CHILD_NODE_KEYS: string[];
210
+ declare function valueFromNodes(nodes: TextOrExpr[]): Value;
211
+ /** The literal text of a node list when fully static (no ExpressionTag), else undefined. */
212
+ declare function textFromNodes(nodes: TextOrExpr[]): string | undefined;
213
+ /** Static string of an attribute (e.g. name="description"), or undefined if dynamic/absent. */
214
+ declare function attrText(attributes: AST.Attribute[], name: string): string | undefined;
215
+ /** Value kind of an attribute's content (e.g. the `content` of a <meta>). */
216
+ declare function attrValue(attributes: AST.Attribute[], name: string): Value;
217
+ declare function lineOf(source: string, offset: unknown): number;
218
+ /**
219
+ * An element's attribute by name, matched **case-insensitively**: HTML attribute names are, so
220
+ * `ARIA-LABEL` and `Type` are the same attributes as `aria-label` and `type` once the document is
221
+ * parsed. The Svelte AST keeps the source spelling, so the normalisation has to happen here.
222
+ *
223
+ * Only ever called with an HTML element's attributes. A component's props are case-**sensitive**
224
+ * (`<Foo titleTemplate>` is not `<Foo titletemplate>`) and are read through the adapters' own
225
+ * lookup, which must stay exact.
226
+ */
227
+ declare function findAttr(attributes: AST.Attribute[], name: string): AST.Attribute | undefined;
228
+ /** Value kind of a single attribute (e.g. a component prop). */
229
+ declare function attrValueOf(attr: AST.Attribute): Value;
230
+ /** Literal static text of a single attribute node (e.g. a component prop), or undefined if dynamic/absent. */
231
+ declare function attrTextOf(attr: AST.Attribute): string | undefined;
232
+
233
+ /**
234
+ * Source-file locations that satisfy the project-scope rules, shared by every
235
+ * mode so the static (CLI) and rendered (plugin) collectors never drift. This
236
+ * module is pure data: no I/O, no `node:` imports (design §8).
237
+ */
238
+ /** Locations that satisfy the robots.txt project rule (seo/robots-txt). */
239
+ declare const ROBOTS_SOURCE_PATHS: readonly ["static/robots.txt", "src/routes/robots.txt/+server.ts", "src/routes/robots.txt/+server.js"];
240
+ /** Locations that satisfy the sitemap.xml project rule (seo/sitemap-xml). */
241
+ declare const SITEMAP_SOURCE_PATHS: readonly ["static/sitemap.xml", "src/routes/sitemap.xml/+server.ts", "src/routes/sitemap.xml/+server.js"];
242
+ /** Vite's own config resolution order — only the first existing file is the one Vite loads. */
243
+ declare const VITE_CONFIG_FILES: readonly ["vite.config.js", "vite.config.mjs", "vite.config.ts", "vite.config.cjs", "vite.config.mts", "vite.config.cts"];
244
+ /** SvelteKit's config resolution order (`@sveltejs/kit` checks js before ts). */
245
+ declare const SVELTE_CONFIG_FILES: readonly ["svelte.config.js", "svelte.config.ts"];
246
+
247
+ interface FailedRule {
248
+ id: string;
249
+ message: string;
250
+ }
251
+ /**
252
+ * Run a set of rules against a shared context and collect their findings.
253
+ * Rules are independent, so they run concurrently; results are flattened in
254
+ * rule order for stable output. A rule that throws (sync or async) contributes
255
+ * no results instead of taking the whole run down with it — dev tooling must
256
+ * never throw — and is reported in `failedRules` instead.
257
+ */
258
+ declare function runRules(rules: Rule[], ctx: RuleContext): Promise<{
259
+ results: Result[];
260
+ examined: Record<string, Record<string, number>>;
261
+ failedRules: FailedRule[];
262
+ }>;
263
+
264
+ /**
265
+ * seo/title-presence — every route should resolve a non-empty <title> (design §11).
266
+ * A dynamic title (`{data.title}`) is the most common correct pattern and must
267
+ * never be flagged as missing; it surfaces as value 'dynamic' (design §4).
268
+ */
269
+ declare const seoTitlePresence: Rule;
270
+
271
+ declare const seoDescriptionPresence: Rule;
272
+
273
+ declare const seoCanonicalUrl: Rule;
274
+
275
+ declare const seoOgImage: Rule;
276
+
277
+ declare const seoOgTitle: Rule;
278
+
279
+ declare const seoJsonLd: Rule;
280
+
281
+ declare const seoRobotsTxt: Rule;
282
+
283
+ declare const seoSitemapXml: Rule;
284
+
285
+ declare const seoHtmlLang: Rule;
286
+
287
+ declare const performanceImageDimensions: Rule;
288
+
289
+ declare const performanceImageLoadingHint: Rule;
290
+
291
+ declare const performanceResponsiveImage: Rule;
292
+
293
+ declare const performancePreloadMissingAs: Rule;
294
+
295
+ declare const performanceFontPreloadCrossorigin: Rule;
296
+
297
+ /**
298
+ * performance/lcp-image — LCP image not lazy-loaded. Lazy-loading the largest contentful paint
299
+ * image delays it. Analysis approximates the LCP as the first <img> in document
300
+ * order for the route; if that image is loading="lazy", flag it. Runs in both
301
+ * static (CLI) and rendered (vite) mode, since both providers collect <img>.
302
+ */
303
+ declare const performanceLcpImage: Rule;
304
+
305
+ /**
306
+ * performance/render-blocking-script — Render-blocking <script> in <head>. A <script src> without
307
+ * defer/async/type=module blocks the parser. SvelteKit's own scripts are
308
+ * module/deferred, so this catches hand-added blocking scripts — in app.html
309
+ * (rendered mode) or in <svelte:head> (static mode). A head with no <script>
310
+ * emits nothing (no signal), like the image rules.
311
+ */
312
+ declare const performanceRenderBlockingScript: Rule;
313
+
314
+ /**
315
+ * performance/preconnect — Preconnect for third-party origins. A resource from a well-known
316
+ * third-party origin (e.g. Google Fonts) without a preconnect/dns-prefetch pays a
317
+ * connection-setup round-trip. Opt-in by construction: only origins in the
318
+ * allowlist are checked; routes referencing none emit nothing.
319
+ */
320
+ declare const performancePreconnect: Rule;
321
+
322
+ declare const seoIndexability: Rule;
323
+
324
+ declare const seoTwitterCard: Rule;
325
+
326
+ declare const seoOgDescription: Rule;
327
+
328
+ declare const seoOgUrl: Rule;
329
+
330
+ declare const seoViewport: Rule;
331
+
332
+ declare const seoSitemapInRobots: Rule;
333
+
334
+ declare const seoJsonLdValidity: Rule;
335
+
336
+ declare const seoJsonLdDeprecatedType: Rule;
337
+
338
+ declare const seoJsonLdRelativeUrl: Rule;
339
+
340
+ declare const seoJsonLdDateFormat: Rule;
341
+
342
+ declare const seoJsonLdPlaceholder: Rule;
343
+
344
+ declare const seoJsonLdRequiredProps: Rule;
345
+
346
+ declare const seoTitleLength: Rule;
347
+
348
+ declare const seoDescriptionLength: Rule;
349
+
350
+ /**
351
+ * seo/charset — Character encoding. The charset meta lives in `src/app.html`, so it is
352
+ * only visible to rendered analysis (`appliesTo: rendered`), exactly like seo/viewport
353
+ * (viewport). Static route analysis emits nothing instead of false-flagging it.
354
+ */
355
+ declare const seoCharset: Rule;
356
+
357
+ /**
358
+ * seo/image-alt — Image alt text. Reuses the <img> collection from both providers — the
359
+ * static (CLI) source parser and the rendered (vite) HTML parser — like performance/image-dimensions, performance/image-loading-hint.
360
+ * Presence only: an explicit empty `alt=""` is a valid decorative-image signal and
361
+ * passes; a spread `{...rest}` may supply alt, so it is not flagged.
362
+ */
363
+ declare const seoImageAlt: Rule;
364
+
365
+ /**
366
+ * seo/hreflang — hreflang / x-default validity. Opt-in: a route with no
367
+ * `<link rel="alternate" hreflang>` emits nothing (monolingual sites are never
368
+ * flagged). When alternates exist, every code must be well-formed and a set of
369
+ * two or more must declare an x-default. Works in both modes.
370
+ */
371
+ declare const seoHreflang: Rule;
372
+
373
+ /**
374
+ * seo/single-h1 — Heading hierarchy (single H1). Reads the per-route page-body headings
375
+ * channel (collected by both providers), counting `headings` plus `componentHeadings`
376
+ * (static mode only — headings found transitively in rendered child components) as one
377
+ * combined list. Zero <h1> (no primary heading) is a `warning`: defensible, a page needs
378
+ * a primary heading. Two or more is only `info`: a single <h1> is the conventional
379
+ * signal, but no official source documents a ranking penalty for several (2026-08-09 v1
380
+ * rule-validity review, P2 #11) — so it's flagged as a style nit, not a defect. Exactly
381
+ * one passes. A route whose headings were not collected (channel unset) emits nothing. A
382
+ * global `rules: { 'seo/single-h1': <severity> }` override flattens both arms to one
383
+ * severity (design, `applyRuleSeverities`).
384
+ */
385
+ declare const seoSingleH1: Rule;
386
+
387
+ declare const seoDuplicateTitle: Rule;
388
+
389
+ declare const seoDuplicateDescription: Rule;
390
+
391
+ /**
392
+ * seo/heading-level-skip — Skipped heading level. Walking a route's body headings in
393
+ * document order, a level that jumps more than +1 over the previous heading (e.g.
394
+ * h2 → h4) breaks the outline. The first heading has no predecessor (missing/multiple
395
+ * <h1> stays seo/single-h1's concern). A route with no headings emits nothing.
396
+ */
397
+ declare const seoHeadingLevelSkip: Rule;
398
+
399
+ declare const seoSsrDisabled: Rule;
400
+
401
+ declare const correctnessEachKey: Rule;
402
+
403
+ declare const correctnessEachIndexKey: Rule;
404
+
405
+ declare const correctnessEffectAsDerived: Rule;
406
+
407
+ declare const correctnessEffectAsOnMount: Rule;
408
+
409
+ declare const correctnessUnmutatedState: Rule;
410
+
411
+ /**
412
+ * correctness/prop-mutation — mutating a prop directly is a silent bug in both Svelte modes,
413
+ * for different reasons: in runes mode, a non-$bindable prop mutation doesn't propagate to the
414
+ * parent; in legacy mode (export let), Svelte's reactivity is assignment-based, so a mutating
415
+ * method call (`.push(...)`, etc.) doesn't trigger an update at all without a following
416
+ * reassignment. The two modes can't be mixed in one component, so a given finding is always
417
+ * exactly one or the other — see `legacy` on `ComponentFacts.mutatedProps` (component-parse.ts).
418
+ */
419
+ declare const correctnessPropMutation: Rule;
420
+
421
+ /**
422
+ * correctness/stale-prop-derivation — a value computed from a prop without $derived (runes
423
+ * mode) or $: (legacy mode) is evaluated once, at init, and silently stops tracking the
424
+ * parent. Svelte's own guidance: treat props as though they will change. The two modes can't
425
+ * be mixed in one component, so a given finding is always exactly one or the other — see
426
+ * `legacy` on `ComponentFacts.stalePropDerivations` (component-parse.ts).
427
+ */
428
+ declare const correctnessStalePropDerivation: Rule;
429
+
430
+ /**
431
+ * correctness/nonreactive-builtin-state — $state's deep proxy covers plain
432
+ * objects and arrays only. A plain Map/Set/Date/URL/URLSearchParams in $state
433
+ * keeps working as data, but its mutations never reach effects, deriveds, or
434
+ * the template: the UI silently stops updating. svelte/reactivity ships
435
+ * drop-in reactive equivalents for exactly this.
436
+ */
437
+ declare const correctnessNonreactiveBuiltinState: Rule;
438
+
439
+ /**
440
+ * correctness/checkable-bind-value — bind:value binds the DOM value property. A
441
+ * checkbox/radio's user interaction toggles checkedness, which bind:value never observes. A
442
+ * checkbox throws bind_invalid_checkbox_value in dev (silently tracks value instead of
443
+ * checkedness in prod); a radio throws nothing and its bound state silently never updates.
444
+ * bind:checked (single checkbox) / bind:group (checkbox list, radio group) are the correct
445
+ * bindings.
446
+ */
447
+ declare const correctnessCheckableBindValue: Rule;
448
+
449
+ declare const correctnessOrphanEffect: Rule;
450
+
451
+ /**
452
+ * correctness/orphan-lifecycle — svelte lifecycle/context calls guaranteed to run outside component
453
+ * initialisation: module scope in runes modules / `<script module>`, the constructor of
454
+ * a module-scope-instantiated class, and Kit load/handler/`init` bodies. A custom check
455
+ * because the facts live on BOTH the component channel and the Kit-module channel.
456
+ */
457
+ declare const correctnessOrphanLifecycle: Rule;
458
+
459
+ /**
460
+ * correctness/base-path-navigation — root-relative navigation literals in a project that sets
461
+ * `kit.paths.base`. A custom check because it is gated on a PROJECT fact and its own facts live
462
+ * on BOTH the component channel (`<a href>`, `goto()`) and the Kit-module channel (`redirect()`).
463
+ * With no base path configured the rule emits nothing at all — the gate is the whole point.
464
+ */
465
+ declare const correctnessBasePathNavigation: Rule;
466
+
467
+ /**
468
+ * correctness/server-browser-global — browser globals read in server-executed MODULE code: module scope of
469
+ * runes modules / `<script module>`, and Kit route/hooks files (top level, handler
470
+ * bodies, the `init` hook). All of it runs on the server, where these globals do not
471
+ * exist — SSR crashes with a ReferenceError. Instance-script reads are correctness/instance-browser-global's
472
+ * (warning) territory. A custom check because the facts live on both channels.
473
+ */
474
+ declare const correctnessServerBrowserGlobal: Rule;
475
+
476
+ declare const correctnessInstanceBrowserGlobal: Rule;
477
+
478
+ declare const securityRawHtml: Rule;
479
+
480
+ declare const securityJavascriptUrl: Rule;
481
+
482
+ declare const securityHandlerStateWrite: Rule;
483
+
484
+ declare const securityServerModuleState: Rule;
485
+
486
+ declare const securitySharedStateImport: Rule;
487
+
488
+ declare const architectureComponentSize: Rule;
489
+
490
+ declare const architecturePropCount: Rule;
491
+
492
+ /**
493
+ * architecture/private-scope-import — a unit inside a declared private scope must not be
494
+ * imported from outside that scope (design 2026-07-28). L3: the scopes are declared by the
495
+ * project via the `scopes` option and never inferred, so the rule is inert until then.
496
+ *
497
+ * Findings are reported at the import site, not at the imported unit: `--diff` filters
498
+ * results to the files that changed, and the author of the violation edited the importer.
499
+ */
500
+ declare const architecturePrivateScopeImport: Rule;
501
+
502
+ /**
503
+ * architecture/unit-entry-file — a directory declared to be a unit must contain a file named
504
+ * after it (design 2026-07-28). L3: the declarations come from the project's own `units`,
505
+ * `pascalCaseUnits` and `exclude` options and are never inferred, so the rule is inert until then.
506
+ *
507
+ * The directory set is every ancestor path prefix of every file, so a directory holding only
508
+ * subdirectories is checked too. Violations report at a file inside the directory rather than at
509
+ * the directory, because `filterToChangedFiles` keeps only locations git lists as changed.
510
+ */
511
+ declare const architectureUnitEntryFile: Rule;
512
+
513
+ /**
514
+ * architecture/directory-naming — a directory must be named in the casing its location declares
515
+ * (design 2026-07-29). L3: the declarations come from the project's own `directories` and `exclude`
516
+ * options and are never inferred, so the rule is inert until then.
517
+ *
518
+ * Violations report at a file inside the directory rather than at the directory, because
519
+ * `filterToChangedFiles` keeps only locations git lists as changed and git never lists a directory.
520
+ *
521
+ * There are no pass results. `architecture/unit-entry-file` emits one per conforming unit and can
522
+ * afford to, because it keys the pass on the unit's entry file — a `.svelte` path already present as
523
+ * a score key. This rule's subject is the directory itself, with no such pre-existing key, and
524
+ * `computeScore` seeds every distinct `route` at 100 and averages: a pass per directory would add
525
+ * hundreds of 100s from one `'src/routes/**'` declaration and dilute every real finding.
526
+ */
527
+ declare const architectureDirectoryNaming: Rule;
528
+
529
+ /**
530
+ * architecture/reserved-directory-names — a directory's immediate subdirectories may only take names
531
+ * the project declared for that position (design 2026-07-29, extended 2026-08-08 for lowercase units —
532
+ * issue #386).
533
+ *
534
+ * The option maps differ in what their keys name. A `scopes` key names the parent directly. A
535
+ * `unitScopes` key names a root, and the rule governs the children of whichever directories beneath
536
+ * it are units whose name begins A–Z — the shape a glob cannot reach, because units nest to arbitrary
537
+ * depth. An `anyCaseUnitScopes` key names a root the same way, but governs units of *either* case:
538
+ * `isUnitDir`'s letter test — A–Z plus a same-stemmed entry file, whatever its extension — excludes a
539
+ * lowercase unit, so without this map no generic unit-map declaration governed one's children (a
540
+ * `scopes` key naming the parent directly could still reach one) — measured at 129 of 299 units (43%)
541
+ * on a real tree. Neither map is named with the bare word "unit": the
542
+ * sibling rule `architecture/reserved-name-placement` records why that word alone is ambiguous between
543
+ * the two predicates once both exist.
544
+ *
545
+ * There are no pass results. `computeScore` seeds every distinct `route` at 100 and averages, and the
546
+ * subject here is a directory with no pre-existing score key, so a pass per directory would add
547
+ * hundreds of 100s from one broad declaration and dilute every real finding.
548
+ */
549
+ declare const architectureReservedDirectoryNames: Rule;
550
+
551
+ /**
552
+ * architecture/reserved-name-placement — a reserved directory name may appear only in the places
553
+ * declared for it (design 2026-08-06). L3: inert until a placement is declared.
554
+ *
555
+ * The sibling `architecture/reserved-directory-names` says "at this position, only these names"; it
556
+ * cannot say "this name, only at these positions", which for a name appearing in several kinds of
557
+ * place is what a convention actually states.
558
+ *
559
+ * All three maps match the same directory — the reserved-name directory's parent — and differ only in
560
+ * what else they require of it: nothing, that it is a capitalised unit, that it is a unit of either
561
+ * case. A name's permitted positions are the UNION of its entries across the three, because a real
562
+ * convention permits one name under a unit, under a grouping and under a route directory at once.
563
+ *
564
+ * There are no pass results, for the reason the sibling records: `computeScore` seeds every distinct
565
+ * `route` at 100 and averages, and a directory has no pre-existing score key.
566
+ */
567
+ declare const architectureReservedNamePlacement: Rule;
568
+
569
+ declare const architectureRouteComponentImport: Rule;
570
+
571
+ declare const architectureDocLinkTarget: Rule;
572
+
573
+ declare const performanceHeavyImport: Rule;
574
+
575
+ declare const performanceNamespaceImport: Rule;
576
+
577
+ /**
578
+ * performance/minify-disabled — a `build.minify: false` left in vite.config ships unminified JS/CSS
579
+ * to production. Project-scope: the fact is produced by the CLI's static parse
580
+ * of vite.config.* (literal-only) or by the Vite plugin's resolved config
581
+ * (exact). Emits a finding only when the fact is set — no pass result.
582
+ */
583
+ declare const performanceMinifyDisabled: Rule;
584
+
585
+ /**
586
+ * performance/load-waterfall — dependent await chains in universal loads. Server loads are exempt:
587
+ * a dependent chain cannot be parallelized, and on the server there is no better
588
+ * placement to suggest. csr = false files are exempt too — without a client
589
+ * runtime the universal load only runs during SSR.
590
+ */
591
+ declare const performanceLoadWaterfall: Rule;
592
+
593
+ /**
594
+ * performance/sequential-awaits — independent sequential awaits in any load. Info severity: static
595
+ * data flow cannot see side-effect ordering (e.g. a setup call an API relies
596
+ * on), so the parallelize suggestion stays advisory.
597
+ */
598
+ declare const performanceSequentialAwaits: Rule;
599
+
600
+ /**
601
+ * performance/state-raw — deep $state proxies every property access; a binding
602
+ * that is only ever reassigned never uses that machinery. Svelte's guidance:
603
+ * large reassign-only objects (API responses, canonically) belong in $state.raw.
604
+ * "Large" is not statically knowable, so a non-primitive literal initializer is
605
+ * the proxy condition.
606
+ */
607
+ declare const performanceStateRaw: Rule;
608
+
609
+ declare const a11yInvalidRole: Rule;
610
+
611
+ declare const a11yUnknownAriaAttribute: Rule;
612
+
613
+ declare const a11yRequiredAriaProps: Rule;
614
+
615
+ declare const a11yInvalidAriaValue: Rule;
616
+
617
+ declare const a11yInteractiveNesting: Rule;
618
+
619
+ declare const a11yAccessibleName: Rule;
620
+
621
+ declare const a11yLabelHasControl: Rule;
622
+
623
+ declare const a11yUseList: Rule;
624
+
625
+ declare const a11yPlaceholderLabelOption: Rule;
626
+
627
+ declare const a11yRequireDatetime: Rule;
628
+
629
+ declare const a11yDoctype: Rule;
630
+
631
+ /**
632
+ * a11y/duplicate-landmark — a composed route (layout chain + page) yields more than one
633
+ * `main` / `banner` / `contentinfo` landmark. `ctx.a11y[].landmarks` already holds the
634
+ * branch-aware-folded representatives, so this rule only counts them per kind, in the
635
+ * fixed KINDS order (it decides emission order and the PASS anchor).
636
+ */
637
+ declare const a11yDuplicateLandmark: Rule;
638
+
639
+ /**
640
+ * a11y/top-level-landmark — a landmark (`main`/`banner`/`complementary`/`contentinfo`) that
641
+ * composition places inside another landmark. `ctx.a11y[].nestedLandmarks` already carries one
642
+ * entry per nested occurrence, so this rule only reports them.
643
+ */
644
+ declare const a11yTopLevelLandmark: Rule;
645
+
646
+ /**
647
+ * a11y/id-duplication — a literal id repeated within a composed route. `ctx.a11y[].ids`
648
+ * already holds the branch-aware-folded representatives per id, so this rule only counts them.
649
+ */
650
+ declare const a11yIdDuplication: Rule;
651
+
652
+ /**
653
+ * a11y/no-missing-id-ref — a `for`/`aria-labelledby`/`aria-describedby`/`aria-controls`/
654
+ * `aria-activedescendant`/same-page `href="#…"` referencing an `id` absent from the composed
655
+ * route. Universal ("no element anywhere defines this id") needs a closed world, so this rule
656
+ * runs only on routes `ctx.a11y[].fullyResolved` marks fully resolved — see the rule docs.
657
+ */
658
+ declare const a11yNoMissingIdRef: Rule;
659
+
660
+ declare const allRules: Rule[];
661
+
662
+ /** One configurable option of a rule, flattened for `svelte-vitals explain`'s output. */
663
+ interface RuleOptionInfo {
664
+ name: string;
665
+ /** `integer` replaces the default; `string-list`/`string-map` are ADDED to it. */
666
+ kind: RuleOptionSpec['kind'];
667
+ default: number | readonly string[] | Readonly<Record<string, string>>;
668
+ min?: number;
669
+ max?: number;
670
+ }
671
+ interface RuleInfo {
672
+ id: string;
673
+ title: string;
674
+ category: Category;
675
+ severity: Severity;
676
+ rationale: string;
677
+ docsUrl: string;
678
+ fix?: Fix;
679
+ /**
680
+ * The rule's configurable options, omitted when it takes none. An agent that
681
+ * judges a finding to be a threshold disagreement rather than a defect needs
682
+ * to know the knob exists and what it is called before it can suggest one.
683
+ */
684
+ options?: RuleOptionInfo[];
685
+ }
686
+ /** Look up a rule's static metadata, as `svelte-vitals explain` renders it (issue #24). Rule ids are matched exactly (case-sensitive, e.g. "seo/ssr-disabled"). */
687
+ declare function explainRule(id: string): RuleInfo | undefined;
688
+
689
+ interface HeadTagRuleOptions {
690
+ id: string;
691
+ title: string;
692
+ severity: Severity;
693
+ /** Identifies the tag this rule looks for. */
694
+ match: (tag: HeadTag) => boolean;
695
+ /** Short human label, e.g. 'description'. */
696
+ label: string;
697
+ recommendation: string;
698
+ /** Why this rule matters — surfaced by `svelte-vitals explain` (issue #24). */
699
+ rationale: string;
700
+ /** Agent-actionable remediation attached to every finding (issue #18). */
701
+ fix?: Fix;
702
+ /**
703
+ * When set, only heads for which this returns true are evaluated; others emit
704
+ * nothing. Use for tags whose canonical location is invisible to a given mode
705
+ * (e.g. viewport lives in app.html → only checkable in rendered mode), so the
706
+ * rule stays silent instead of false-flagging "missing".
707
+ */
708
+ appliesTo?: (head: ResolvedHead) => boolean;
709
+ }
710
+ /** Build a route-scope rule asserting the presence of a single head tag (design §11). */
711
+ declare function headTagRule(opts: HeadTagRuleOptions): Rule;
712
+
713
+ interface ImageRuleOptions {
714
+ id: string;
715
+ title: string;
716
+ severity: Severity;
717
+ /** Vitals category (default 'performance'); seo/image-alt (alt text) reports under 'seo'. */
718
+ category?: Category;
719
+ /** Noun phrase for messages, e.g. '<img> width/height'. */
720
+ label: string;
721
+ recommendation: string;
722
+ rationale: string;
723
+ fix?: Fix;
724
+ /** Returns true when the image satisfies the rule (passes). */
725
+ ok: (img: ImageInfo) => boolean;
726
+ }
727
+ /** Build a route-scoped <img> rule that checks each image against `ok` (issue #10). */
728
+ declare function imageRule(opts: ImageRuleOptions): Rule;
729
+
730
+ interface LinkRuleOptions {
731
+ id: string;
732
+ title: string;
733
+ severity: Severity;
734
+ /** Noun phrase for messages, e.g. '`as` on a preloaded `<link>`'. */
735
+ label: string;
736
+ recommendation: string;
737
+ rationale: string;
738
+ fix?: Fix;
739
+ /** Which link tags this rule evaluates (e.g. rel === 'preload'). */
740
+ relevant: (tag: HeadTag) => boolean;
741
+ /** Returns true when a relevant link satisfies the rule (passes). */
742
+ ok: (tag: HeadTag) => boolean;
743
+ }
744
+ /** Build a route-scoped Performance rule that checks each relevant <link> in the effective head. */
745
+ declare function linkRule(opts: LinkRuleOptions): Rule;
746
+
747
+ /** String decorators for the console reporter. Injected so core stays pure/dep-free. */
748
+ interface Palette {
749
+ bold: (s: string) => string;
750
+ dim: (s: string) => string;
751
+ red: (s: string) => string;
752
+ yellow: (s: string) => string;
753
+ green: (s: string) => string;
754
+ cyan: (s: string) => string;
755
+ }
756
+ /** Default: no decoration (identity) — output is byte-identical to plain text. */
757
+ declare const noColorPalette: Palette;
758
+ /** Green ≥ 90, yellow ≥ 70, red otherwise — for a 0–100 score. */
759
+ declare function scoreColor(p: Palette, score: number): (s: string) => string;
760
+
761
+ interface ConsoleReportOptions {
762
+ byRoute?: boolean;
763
+ /** Mode label shown in the header (default 'static mode'). */
764
+ mode?: string;
765
+ /** Color decorators; defaults to no color. */
766
+ palette?: Palette;
767
+ /** Show every failing/passed/route entry uncapped and ungrouped, exactly as before this option existed. Default false (capped, grouped by rule). */
768
+ verbose?: boolean;
769
+ /** Internal: set by the CLI when it has already animated the Health header itself — skips the brand/Health lines (category score lines still print). Default false. */
770
+ omitHeader?: boolean;
771
+ }
772
+ /**
773
+ * Render results as a console report string (design §7). Pure: returns a string,
774
+ * the caller is responsible for printing. Prepends a score header; when byRoute is
775
+ * set, adds a per-route score tree.
776
+ */
777
+ declare function formatConsoleReport(results: Result[], config: Config, options?: ConsoleReportOptions): string;
778
+
779
+ /**
780
+ * Strip ANSI/OSC escape sequences and C0 control characters (except `\n`/`\t`) from a
781
+ * string before it reaches a terminal. POSIX file/route names can contain almost any
782
+ * byte, so a hostile repo can smuggle a terminal-title rewrite, cursor move, or other
783
+ * escape-sequence trick into what looks like plain report text.
784
+ *
785
+ * Only OSC and CSI sequences are pattern-matched and removed whole (payload included) —
786
+ * those cover title-bar writes and cursor/screen control, the two classes with a real
787
+ * blast radius. Any other `ESC` byte (rarer single/two-byte forms like reset or
788
+ * save-cursor) falls through to the final C0 sweep below, which drops the lone `ESC`
789
+ * but — deliberately, not swallowing an adjacent legitimate character — leaves whatever
790
+ * printable byte follows it as stray text.
791
+ * ponytail: doesn't special-case every Fe escape form; broaden the CSI/OSC patterns if a
792
+ * concrete non-CSI/OSC sequence turns out to matter.
793
+ */
794
+ declare function terminalSafe(text: string): string;
795
+
796
+ /** Render failing findings as an agent-actionable Markdown remediation document (issue #18). */
797
+ declare function formatAgentReport(results: Result[], config: Config): string;
798
+
799
+ /** Render penalized findings as a SARIF 2.1.0 log string (issue #18, design slice 5). */
800
+ declare function formatSarifReport(results: Result[], config: Config, meta: {
801
+ version: string;
802
+ }): string;
803
+
804
+ /**
805
+ * Render penalized findings as GitHub Actions workflow commands (issue #18, design slice 5).
806
+ * GitHub turns these into inline PR annotations and run-annotation entries. Returns '' when clean.
807
+ */
808
+ declare function formatGithubReport(results: Result[], config: Config): string;
809
+
810
+ /**
811
+ * Render a compact Markdown summary — Health score, per-category table, severity counts, and
812
+ * a findings table — suitable for a GitHub Actions job summary or a sticky PR comment
813
+ * (`svelte-vitals ci install`). Delegates all aggregation to `buildJsonReport` so the numbers
814
+ * never drift from the JSON/console reporters.
815
+ */
816
+ declare function formatMarkdownReport(results: Result[], config: Config, meta: {
817
+ version: string;
818
+ }): string;
819
+
820
+ type Band = 'good' | 'warn' | 'poor';
821
+ declare const BAND_COLOR: Record<Band, string>;
822
+ declare function scoreBand(score: number): Band;
823
+ declare function escapeHtml(s: string): string;
824
+ /**
825
+ * Return the URL only when it uses a safe http/https scheme, else null.
826
+ * Guards a finding's `docsUrl` against `javascript:`/`data:` hrefs — escapeHtml
827
+ * neutralizes attribute breakout but not a malicious scheme. Browsers strip
828
+ * ASCII whitespace (tab/newline/CR) from a URL before resolving its scheme (so
829
+ * `java\tscript:` runs as `javascript:`), so strip whitespace first; anything not
830
+ * plainly http(s):// afterward is rejected. Pure string work — no `URL` global,
831
+ * keeping core runtime-agnostic and lib-minimal.
832
+ */
833
+ declare function safeHref(url: string): string | null;
834
+ /** Provenance of a route's findings: real rendered page vs. source-only analysis. */
835
+ type RouteBadge = 'measured' | 'static';
836
+ interface AppSnapshot {
837
+ report: JsonReport;
838
+ badges: Record<string, RouteBadge>;
839
+ analyzing: boolean;
840
+ /** Monotonically increasing; lets the client discard an out-of-order /data.json response. */
841
+ sequence: number;
842
+ /** Whether a dev server is behind this page (SSE updates, /data.json refetch, connection dot). */
843
+ live: boolean;
844
+ meta: {
845
+ version: string;
846
+ coreVersion?: string;
847
+ };
848
+ }
849
+ /**
850
+ * Hand-authored CSS for the master/detail shell. Reuses the same design-token
851
+ * names/values as the rest of the project, and adds a dark theme via
852
+ * `:root[data-theme="dark"]` plus a `prefers-color-scheme` fallback for a
853
+ * first-ever visit with no stored preference.
854
+ */
855
+ declare const APP_STYLE: string;
856
+ /**
857
+ * Hand-authored client script for the shell — no bundler, no framework. Parses the
858
+ * AppSnapshot embedded by renderAppShell, then owns all rendering: sidebar
859
+ * (search/sort/route list) and detail pane (Overview or a selected route). When the
860
+ * snapshot says `live`, it additionally re-fetches /data.json on every SSE `update`
861
+ * and on the EventSource's `open` event (covers the initial connection and every
862
+ * auto-reconnect, since EventSource replays no missed events) — discarding any
863
+ * response whose `sequence` isn't newer than what's already rendered.
864
+ */
865
+ declare const APP_SCRIPT: string;
866
+ /** The shell HTML: empty sidebar/detail/topbar containers, the stylesheet, the
867
+ * client script, and the snapshot embedded as JSON for the client's first paint. */
868
+ declare function renderAppShell(snapshot: AppSnapshot): string;
869
+ /**
870
+ * Static (non-live) document over a prebuilt JsonReport — kept as the public name the
871
+ * html reporter has always exported.
872
+ */
873
+ declare function buildHtmlDocument(report: JsonReport, meta: {
874
+ version: string;
875
+ coreVersion?: string;
876
+ }): string;
877
+ /** Render results as the self-contained HTML report (the CLI's `--reporter html`). */
878
+ declare function formatHtmlReport(results: Result[], config: Config, meta: {
879
+ version: string;
880
+ coreVersion?: string;
881
+ }): string;
882
+
883
+ export { APP_SCRIPT, APP_STYLE, type AppSnapshot, BAND_COLOR, CHILD_NODE_KEYS, ComponentFacts, type ConsoleReportOptions, type FailedRule, HeadTag, ImageInfo, KitAlias, KitModuleFacts, type Palette, ROBOTS_SOURCE_PATHS, type RawKitAliases, ResolvedHead, type RouteBadge, Rule, RuleContext, type RuleInfo, type RuleOptionInfo, RuleOptionSpec, Runtime, SITEMAP_SOURCE_PATHS, SVELTE_CONFIG_FILES, SuppressionDirective, VITE_CONFIG_FILES, type ViteKitConfigResult, a11yAccessibleName, a11yDoctype, a11yDuplicateLandmark, a11yIdDuplication, a11yInteractiveNesting, a11yInvalidAriaValue, a11yInvalidRole, a11yLabelHasControl, a11yNoMissingIdRef, a11yPlaceholderLabelOption, a11yRequireDatetime, a11yRequiredAriaProps, a11yTopLevelLandmark, a11yUnknownAriaAttribute, a11yUseList, allRules, architectureComponentSize, architectureDirectoryNaming, architectureDocLinkTarget, architecturePrivateScopeImport, architecturePropCount, architectureReservedDirectoryNames, architectureReservedNamePlacement, architectureRouteComponentImport, architectureUnitEntryFile, attrText, attrTextOf, attrValue, attrValueOf, buildHtmlDocument, collectComponentFacts, collectKitModuleFacts, collectSourceFiles, correctnessBasePathNavigation, correctnessCheckableBindValue, correctnessEachIndexKey, correctnessEachKey, correctnessEffectAsDerived, correctnessEffectAsOnMount, correctnessInstanceBrowserGlobal, correctnessNonreactiveBuiltinState, correctnessOrphanEffect, correctnessOrphanLifecycle, correctnessPropMutation, correctnessServerBrowserGlobal, correctnessStalePropDerivation, correctnessUnmutatedState, emptyComponentFacts, emptyKitModuleFacts, escapeHtml, explainRule, findAttr, findKitAliasesInSvelteConfig, findKitPathsBaseInSvelteConfig, findKitPathsBaseInViteConfig, findMinifyDisabled, formatAgentReport, formatConsoleReport, formatGithubReport, formatHtmlReport, formatMarkdownReport, formatSarifReport, headTagRule, imageRule, lineOf, linkRule, noColorPalette, parseComponentFacts, parseKitModuleFacts, parseSvelte, performanceFontPreloadCrossorigin, performanceHeavyImport, performanceImageDimensions, performanceImageLoadingHint, performanceLcpImage, performanceLoadWaterfall, performanceMinifyDisabled, performanceNamespaceImport, performancePreconnect, performancePreloadMissingAs, performanceRenderBlockingScript, performanceResponsiveImage, performanceSequentialAwaits, performanceStateRaw, renderAppShell, resolveKitAliases, resolveKitPathsBase, resolveRepoLocalPath, resolveRunesModuleSpecifier, runRules, safeHref, scoreBand, scoreColor, securityHandlerStateWrite, securityJavascriptUrl, securityRawHtml, securityServerModuleState, securitySharedStateImport, seoCanonicalUrl, seoCharset, seoDescriptionLength, seoDescriptionPresence, seoDuplicateDescription, seoDuplicateTitle, seoHeadingLevelSkip, seoHreflang, seoHtmlLang, seoImageAlt, seoIndexability, seoJsonLd, seoJsonLdDateFormat, seoJsonLdDeprecatedType, seoJsonLdPlaceholder, seoJsonLdRelativeUrl, seoJsonLdRequiredProps, seoJsonLdValidity, seoOgDescription, seoOgImage, seoOgTitle, seoOgUrl, seoRobotsTxt, seoSingleH1, seoSitemapInRobots, seoSitemapXml, seoSsrDisabled, seoTitleLength, seoTitlePresence, seoTwitterCard, seoViewport, terminalSafe, textFromNodes, valueFromNodes };