@codometer/configuration 0.0.1

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,1204 @@
1
+ import { CodeStatisticsResult } from '@codometer/core';
2
+ import { CodometerSeverity } from '@codometer/core';
3
+ import { CodometerStatisticGroup } from '@codometer/core';
4
+ import { CodometerSymbolKind } from '@codometer/core';
5
+ import { CodometerSymbolModifier } from '@codometer/core';
6
+ import { z } from 'zod';
7
+
8
+ /** What `--check limits` asks the run to fail on: a breached failing limit. */
9
+ export declare const CHECK_LIMITS = "limits";
10
+
11
+ /**
12
+ * Everything `--check` accepts, in the order an error message lists them.
13
+ *
14
+ * Named here rather than spelled into each message, so the list a mistake is
15
+ * measured against and the list it is told about can never drift apart.
16
+ */
17
+ export declare const CHECK_NAMES: string[];
18
+
19
+ /** What `--check reports` asks the run to fail on: a stale written report. */
20
+ export declare const CHECK_REPORTS = "reports";
21
+
22
+ /** How a `--check` value is written: one comma-separated set, no spaces needed. */
23
+ export declare const CHECK_SEPARATOR = ",";
24
+
25
+ /** Analyses an input may ask to have run over it. */
26
+ export declare const CODOMETER_ANALYSES: readonly ["language", "size"];
27
+
28
+ /** Languages a `comment` selector may narrow itself to. */
29
+ export declare const CODOMETER_COMMENT_LANGUAGES: readonly ["css", "hcl", "python", "shell", "sql", "toml", "typescript", "yaml"];
30
+
31
+ /** Compressions an input may ask its size to be measured under. */
32
+ export declare const CODOMETER_COMPRESSIONS: readonly ["brotli", "gzip", "none"];
33
+
34
+ /** Units a documentation limit may measure a comment's length in. */
35
+ export declare const CODOMETER_DOCUMENTATION_UNITS: readonly ["characters", "lines", "words"];
36
+
37
+ /** Report shapes a run may produce. */
38
+ export declare const CODOMETER_FORMATS: readonly ["json", "markdown"];
39
+
40
+ /**
41
+ * An analysis codometer can run over an input.
42
+ *
43
+ * `language` parses the matched files and counts what they declare; `size`
44
+ * compresses them and counts bytes. Which of them an input runs is the only
45
+ * thing separating a source tree from build output.
46
+ */
47
+ export declare type CodometerAnalysis = "language" | "size";
48
+
49
+ /**
50
+ * A language a `comment` custom-statistic selector may narrow itself to.
51
+ *
52
+ * The same eight languages that used to carry their own `comments` override:
53
+ * every language this tool reads comments from except the JSDoc-style
54
+ * documentation a `kind` narrows to, which is not tied to one language.
55
+ */
56
+ export declare type CodometerCommentLanguage = "css" | "hcl" | "python" | "shell" | "sql" | "toml" | "typescript" | "yaml";
57
+
58
+ /**
59
+ * One comment measured against the limit its kind carries.
60
+ *
61
+ * Shared by every analyzer that measures comment length, so a JSDoc block and
62
+ * a YAML comment block reach the report through one channel and render with
63
+ * one line of markdown. `kind` is a plain string for that reason: a symbol
64
+ * kind and a comment kind are both written into it, and narrowing it here
65
+ * would make the union the property of whichever analyzer was added first.
66
+ */
67
+ export declare interface CodometerCommentMeasurement {
68
+ breached: boolean;
69
+ /** What the comment documents: a declaration's name, or the comment itself. */
70
+ declaration: string;
71
+ file: string;
72
+ kind: string;
73
+ limit: number;
74
+ /** 1-indexed line the measured thing starts on. */
75
+ line: number;
76
+ measured: number;
77
+ severity: CodometerSeverity;
78
+ unit: CodometerDocumentationUnit;
79
+ }
80
+
81
+ /**
82
+ * Selects a comment budget for a `CodometerCustomStatistic` to measure.
83
+ *
84
+ * A matching custom statistic's `value` counts the blocks that broke this
85
+ * selector's own maxima, and its `instances` names each one's file and line.
86
+ * No selector inherits from another: a general budget and a narrower
87
+ * exception are both written out in full, rather than one merging over the
88
+ * other.
89
+ *
90
+ * Omitting `language` applies the budget to every language that has comments.
91
+ * Naming `kind` narrows the budget to a documented declaration's JSDoc-style
92
+ * comment for that kind, rather than a plain comment block.
93
+ */
94
+ export declare interface CodometerCommentSelector {
95
+ kind?: CodometerSymbolKind | undefined;
96
+ language?: CodometerCommentLanguage | undefined;
97
+ /** How many characters a block may hold, markers and newlines and all. */
98
+ maximumCharacters?: number | undefined;
99
+ /** How many lines a block may span. */
100
+ maximumLines?: number | undefined;
101
+ /** How many words of prose a block may hold, once markers are stripped. */
102
+ maximumWords?: number | undefined;
103
+ /** How loudly a breach is reported. Defaults to `fail`, as limits do. */
104
+ severity?: CodometerSeverity | undefined;
105
+ }
106
+
107
+ /**
108
+ * How a target's files are compressed before size analysis counts them.
109
+ *
110
+ * `none` reports the bytes on disk. Named explicitly rather than inferred from
111
+ * which options are absent, because a compression nobody chose is a byte count
112
+ * nobody can explain.
113
+ */
114
+ export declare type CodometerCompression = "brotli" | "gzip" | "none";
115
+
116
+ /**
117
+ * Configuration authored in a `codometer.config.ts` file.
118
+ *
119
+ * Every field but `format` is optional, so a repository can leave its
120
+ * exclusions and output destinations unwritten until it has decided what they
121
+ * should be. `format` is the one thing every run must be told, and there is no
122
+ * built-in fallback for it — so a directory with no configuration file
123
+ * anywhere above it does not measure at all: it fails on the missing `format`
124
+ * exactly as a file that forgot to write one does. A shared default object,
125
+ * spread by each project's own file, is how a workspace states it once.
126
+ */
127
+ export declare interface CodometerConfiguration {
128
+ /**
129
+ * Every counter this configuration measures, regardless of where — or
130
+ * whether — any of them is rendered.
131
+ *
132
+ * Declaring a counter here is what measures it; an `outputs[].custom` entry
133
+ * then only *selects* which of these labels that destination renders. A
134
+ * label an output selects that is not declared here is refused: selection
135
+ * cannot conjure a counter that was never measured.
136
+ */
137
+ custom?: CodometerCustomStatistic[] | undefined;
138
+ /**
139
+ * Input an unqualified limit's metric path belongs to.
140
+ *
141
+ * A limit addresses its metric by input name followed by metric path.
142
+ * Naming a default lets the input that dominates a repository's limits go
143
+ * unwritten, leaving `typescript.interfaces` where every line would
144
+ * otherwise repeat the same input name. A path that could be read either
145
+ * way is rejected rather than resolved, so the shorthand can never bind
146
+ * somewhere unintended.
147
+ */
148
+ defaultInput?: string | undefined;
149
+ exclude?: string[] | undefined;
150
+ /**
151
+ * Ignore files, in gitignore syntax, whose patterns also exclude files.
152
+ *
153
+ * For the committed-but-generated files no glob list should have to restate —
154
+ * lockfiles, vendored bundles, anything a repository already tells its other
155
+ * tools to skip. Files the repository's own `.gitignore` claims need no
156
+ * mention at all: discovery reads those files itself.
157
+ */
158
+ excludeFrom?: string[] | undefined;
159
+ /**
160
+ * Which report shape a run produces.
161
+ *
162
+ * Required, with no code-level fallback: a shared default object — spread
163
+ * by every project's own `codometer.config.ts` — is what sets it once for a
164
+ * workspace, and a configuration reaching neither it nor its own value
165
+ * fails to resolve rather than silently picking one.
166
+ */
167
+ format: CodometerFormat;
168
+ /**
169
+ * Named sets of files measured alongside — or instead of — the codebase.
170
+ *
171
+ * A built-in entry named `codebase` — the whole-tree scan, running the
172
+ * `language` analysis — is always present unless this array declares an
173
+ * entry of its own by that name, which replaces it outright. A
174
+ * configuration declaring no `inputs` at all gets exactly that built-in
175
+ * entry and nothing else, which is today's implicit whole-tree behavior.
176
+ */
177
+ inputs?: CodometerInput[] | undefined;
178
+ /**
179
+ * How high each measured metric may go.
180
+ *
181
+ * A metric nothing here names is measured and reported like every other one,
182
+ * and gated by nothing.
183
+ */
184
+ limits?: CodometerLimit[] | undefined;
185
+ /**
186
+ * Destinations the measured statistics are written to.
187
+ *
188
+ * An array of typed entries rather than a fixed-key object, so each entry
189
+ * carries its own `custom` counters independently of every other one.
190
+ *
191
+ * At most one entry per `type`: a second entry of a kind is refused rather
192
+ * than silently ignored, because `--output-json [path]` and
193
+ * `--output-markdown [path]` each name one path, so nothing on the command
194
+ * line could ever address a second destination of the same kind.
195
+ */
196
+ outputs?: CodometerOutput[] | undefined;
197
+ python?: CodometerPythonConfiguration | undefined;
198
+ }
199
+
200
+ /**
201
+ * Validates a configuration file's contents.
202
+ *
203
+ * Zod strips unknown keys rather than rejecting them, so a configuration
204
+ * written for a newer codometer still loads under an older one instead of
205
+ * failing on a field it has no opinion about. That is also what makes a
206
+ * removed field — `comments`, `documentation`, a per-language override —
207
+ * silently absent from the resolved configuration rather than a validation
208
+ * error.
209
+ */
210
+ export declare const codometerConfigurationSchema: z.ZodObject<{
211
+ custom: z.ZodOptional<z.ZodArray<z.ZodObject<{
212
+ color: z.ZodOptional<z.ZodString>;
213
+ comment: z.ZodOptional<z.ZodObject<{
214
+ kind: z.ZodOptional<z.ZodEnum<{
215
+ function: "function";
216
+ class: "class";
217
+ enum: "enum";
218
+ getter: "getter";
219
+ interface: "interface";
220
+ method: "method";
221
+ property: "property";
222
+ setter: "setter";
223
+ }>>;
224
+ language: z.ZodOptional<z.ZodEnum<{
225
+ css: "css";
226
+ hcl: "hcl";
227
+ python: "python";
228
+ shell: "shell";
229
+ sql: "sql";
230
+ toml: "toml";
231
+ typescript: "typescript";
232
+ yaml: "yaml";
233
+ }>>;
234
+ maximumCharacters: z.ZodOptional<z.ZodNumber>;
235
+ maximumLines: z.ZodOptional<z.ZodNumber>;
236
+ maximumWords: z.ZodOptional<z.ZodNumber>;
237
+ severity: z.ZodOptional<z.ZodEnum<{
238
+ fail: "fail";
239
+ warn: "warn";
240
+ }>>;
241
+ }, z.core.$strip>>;
242
+ group: z.ZodOptional<z.ZodEnum<{
243
+ json: "json";
244
+ markdown: "markdown";
245
+ conventions: "conventions";
246
+ css: "css";
247
+ hcl: "hcl";
248
+ jupyter: "jupyter";
249
+ python: "python";
250
+ repository: "repository";
251
+ shell: "shell";
252
+ sql: "sql";
253
+ toml: "toml";
254
+ typescript: "typescript";
255
+ yaml: "yaml";
256
+ }>>;
257
+ label: z.ZodString;
258
+ patterns: z.ZodOptional<z.ZodArray<z.ZodString>>;
259
+ symbols: z.ZodOptional<z.ZodObject<{
260
+ kinds: z.ZodArray<z.ZodEnum<{
261
+ function: "function";
262
+ class: "class";
263
+ enum: "enum";
264
+ getter: "getter";
265
+ interface: "interface";
266
+ method: "method";
267
+ property: "property";
268
+ setter: "setter";
269
+ }>>;
270
+ modifiers: z.ZodOptional<z.ZodArray<z.ZodEnum<{
271
+ abstract: "abstract";
272
+ async: "async";
273
+ export: "export";
274
+ override: "override";
275
+ private: "private";
276
+ protected: "protected";
277
+ public: "public";
278
+ readonly: "readonly";
279
+ static: "static";
280
+ }>>>;
281
+ }, z.core.$strip>>;
282
+ }, z.core.$strip>>>;
283
+ defaultInput: z.ZodOptional<z.ZodString>;
284
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
285
+ excludeFrom: z.ZodOptional<z.ZodArray<z.ZodString>>;
286
+ format: z.ZodEnum<{
287
+ json: "json";
288
+ markdown: "markdown";
289
+ }>;
290
+ inputs: z.ZodOptional<z.ZodArray<z.ZodObject<{
291
+ analyses: z.ZodArray<z.ZodEnum<{
292
+ language: "language";
293
+ size: "size";
294
+ }>>;
295
+ compression: z.ZodOptional<z.ZodEnum<{
296
+ brotli: "brotli";
297
+ gzip: "gzip";
298
+ none: "none";
299
+ }>>;
300
+ directory: z.ZodOptional<z.ZodString>;
301
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
302
+ include: z.ZodArray<z.ZodString>;
303
+ name: z.ZodString;
304
+ }, z.core.$strip>>>;
305
+ limits: z.ZodOptional<z.ZodArray<z.ZodObject<{
306
+ label: z.ZodOptional<z.ZodString>;
307
+ metric: z.ZodString;
308
+ severity: z.ZodOptional<z.ZodEnum<{
309
+ fail: "fail";
310
+ warn: "warn";
311
+ }>>;
312
+ value: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
313
+ }, z.core.$strip>>>;
314
+ outputs: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
315
+ custom: z.ZodOptional<z.ZodArray<z.ZodString>>;
316
+ indentation: z.ZodOptional<z.ZodNumber>;
317
+ path: z.ZodString;
318
+ type: z.ZodLiteral<"json">;
319
+ }, z.core.$strip>, z.ZodObject<{
320
+ custom: z.ZodOptional<z.ZodArray<z.ZodString>>;
321
+ description: z.ZodOptional<z.ZodString>;
322
+ endMarker: z.ZodOptional<z.ZodString>;
323
+ path: z.ZodOptional<z.ZodString>;
324
+ startMarker: z.ZodOptional<z.ZodString>;
325
+ type: z.ZodLiteral<"markdown">;
326
+ write: z.ZodOptional<z.ZodType<WriteMarkdownOutput, unknown, z.core.$ZodTypeInternals<WriteMarkdownOutput, unknown>>>;
327
+ }, z.core.$strip>]>>>;
328
+ python: z.ZodOptional<z.ZodObject<{
329
+ command: z.ZodOptional<z.ZodString>;
330
+ }, z.core.$strip>>;
331
+ }, z.core.$strip>;
332
+
333
+ /**
334
+ * One configured counter.
335
+ *
336
+ * A counter measures one of three things. With `patterns` alone it counts
337
+ * *files* whose repository-relative path matches at least one glob. With
338
+ * `symbols` it counts *declarations* in TypeScript and JavaScript sources
339
+ * matching the AST criteria, and `patterns` then narrows which files are
340
+ * searched rather than being what is counted. With `comment` it counts
341
+ * *comment blocks* that broke the selector's own budget, instead of files or
342
+ * declarations.
343
+ *
344
+ * Either way a match is counted once, however many patterns claim it.
345
+ */
346
+ export declare interface CodometerCustomStatistic {
347
+ /** Badge color, as a shields.io hexadecimal triplet. */
348
+ color?: string | undefined;
349
+ comment?: CodometerCommentSelector | undefined;
350
+ /**
351
+ * Which badge group the counter is rendered into.
352
+ *
353
+ * Defaults to `conventions`, the group that exists for these counters and
354
+ * is omitted entirely when none are configured. Naming a language group
355
+ * instead puts the badge beside the built-in counters it belongs with.
356
+ */
357
+ group?: CodometerStatisticGroup | undefined;
358
+ label: string;
359
+ patterns?: string[] | undefined;
360
+ symbols?: CodometerSymbolMatcher | undefined;
361
+ }
362
+
363
+ /** Unit a documentation length is measured in. */
364
+ export declare type CodometerDocumentationUnit = "characters" | "lines" | "words";
365
+
366
+ /** Which report shape a run produces. */
367
+ export declare type CodometerFormat = "json" | "markdown";
368
+
369
+ /**
370
+ * A named set of files, declared by include and exclude globs.
371
+ *
372
+ * Globs are relative to `directory`, which itself is relative to the
373
+ * process's working directory — not to the configuration file's own
374
+ * directory — and a leading `!` on an include glob excludes instead of
375
+ * including. Negations are collected rather than applied in order, so moving
376
+ * one within the array cannot change which files the input holds.
377
+ *
378
+ * Ignore files are not consulted, except for the entry named `codebase`,
379
+ * whose files are every one the repository's ignore files leave behind
380
+ * rather than a glob match. An entry declared under that name replaces the
381
+ * built-in one, which is what lets a repository measure the whole tree under
382
+ * a compression or a different set of analyses — but only its `compression`
383
+ * and `analyses` are read. Its `include` and `exclude` globs are not
384
+ * consulted at all, because the whole-tree scan is discovered by ignore-file
385
+ * walking rather than by matching globs; to measure a subset of the tree,
386
+ * declare an input under some other name.
387
+ */
388
+ export declare interface CodometerInput {
389
+ /** Which analyses run over the matched files. At least one. */
390
+ analyses: CodometerAnalysis[];
391
+ compression?: CodometerCompression | undefined;
392
+ /**
393
+ * Where the input's globs start, relative to the process's working
394
+ * directory.
395
+ *
396
+ * Defaults to the working directory itself. A repository that builds into
397
+ * one tree while measuring a project in another names the way out here —
398
+ * `"../.."` for a project two levels down from a workspace-level `dist` —
399
+ * so that codometer never has to know a build output convention to find the
400
+ * files an input claims.
401
+ */
402
+ directory?: string | undefined;
403
+ exclude?: string[] | undefined;
404
+ include: string[];
405
+ name: string;
406
+ }
407
+
408
+ /**
409
+ * Where and how the JSON statistics report is written.
410
+ *
411
+ * `custom` selects, by label, which of the top-level `custom` counters this
412
+ * destination renders — independently of any other output's own selection.
413
+ * Selecting a label the top level never declared is refused.
414
+ */
415
+ export declare interface CodometerJsonOutput {
416
+ custom?: string[] | undefined;
417
+ indentation?: number | undefined;
418
+ path: string;
419
+ type: "json";
420
+ }
421
+
422
+ /**
423
+ * How high one measured metric may go.
424
+ *
425
+ * Limits are absolute: the metric is compared against `value` and nothing
426
+ * else, with no baseline and no floor. A metric that stays under its limit is
427
+ * reported the same way it would be without one.
428
+ */
429
+ export declare interface CodometerLimit {
430
+ /** What to call the limit in a report, when the path itself reads poorly. */
431
+ label?: string | undefined;
432
+ /**
433
+ * The metric this limits, as a dotted path.
434
+ *
435
+ * Written as the input's name followed by the metric's path within it —
436
+ * `codebase.typescript.interfaces`, `codebase.markdown.files`, or
437
+ * `Compiled JavaScript.size`. With a `defaultInput` configured, a path
438
+ * naming no input is read as that input's. A path that resolves to more
439
+ * than one metric, or to none, fails the run rather than binding to
440
+ * whichever came first.
441
+ */
442
+ metric: string;
443
+ /**
444
+ * How loudly a breach is reported. Defaults to `fail`.
445
+ *
446
+ * Defaulted to the strict one on purpose: a limit exists to gate, and one
447
+ * that quietly warned because nobody said otherwise would be a gate in name
448
+ * only.
449
+ */
450
+ severity?: CodometerSeverity | undefined;
451
+ /**
452
+ * How high the metric may go, as a number or a string carrying a unit.
453
+ *
454
+ * Units are decimal and their trailing `b` is required: `"8 KB"` is 8000 and
455
+ * `"1 MB"` is 1000000, while `"8 K"` is not a size and is rejected. A value
456
+ * nothing can read fails the run rather than being taken as zero, which
457
+ * would gate every metric at nothing.
458
+ */
459
+ value: number | string;
460
+ }
461
+
462
+ /**
463
+ * Where and how the markdown report is written.
464
+ *
465
+ * `write` is the whole of the customizable behavior: it turns the measured
466
+ * statistics into markdown and decides which file that markdown lands in and
467
+ * how, replacing what used to be two separate callbacks. Leaving it unset
468
+ * keeps the built-in rendering and writing.
469
+ *
470
+ * `path` is optional because a `write` function may choose the file itself —
471
+ * but one of the two must be present, or there is no markdown output at all.
472
+ * `custom` selects, by label, which of the top-level `custom` counters this
473
+ * destination renders — independently of any other output's own selection.
474
+ * Selecting a label the top level never declared is refused.
475
+ */
476
+ export declare interface CodometerMarkdownOutput {
477
+ custom?: string[] | undefined;
478
+ description?: string | undefined;
479
+ endMarker?: string | undefined;
480
+ path?: string | undefined;
481
+ startMarker?: string | undefined;
482
+ type: "markdown";
483
+ write?: undefined | WriteMarkdownOutput;
484
+ }
485
+
486
+ /** Destination the measured statistics are written to, one report shape each. */
487
+ export declare type CodometerOutput = CodometerJsonOutput | CodometerMarkdownOutput;
488
+
489
+ /** How Python sources are analyzed. */
490
+ export declare interface CodometerPythonConfiguration {
491
+ command?: string | undefined;
492
+ }
493
+
494
+ /**
495
+ * Which TypeScript and JavaScript declarations a counter claims.
496
+ *
497
+ * A declaration counts when its kind is one of `kinds` and it carries every
498
+ * modifier in `modifiers`. An empty or absent `modifiers` asks for the kind
499
+ * alone.
500
+ */
501
+ export declare interface CodometerSymbolMatcher {
502
+ kinds: CodometerSymbolKind[];
503
+ modifiers?: CodometerSymbolModifier[] | undefined;
504
+ }
505
+
506
+ /**
507
+ * File names searched for when no configuration path is given.
508
+ *
509
+ * Searched in order, so a repository carrying both a TypeScript and a JSON
510
+ * configuration file gets the TypeScript one — the richer format, and the one
511
+ * a type-checked configuration was written in.
512
+ */
513
+ export declare const CONFIGURATION_FILE_NAMES: readonly ["codometer.config.ts", "codometer.config.mts", "codometer.config.cts", "codometer.config.js", "codometer.config.mjs", "codometer.config.cjs", "codometer.config.json", "codometer.config.jsonc"];
514
+
515
+ /**
516
+ * Reads the command line `ConfigurationService` answers a run from.
517
+ *
518
+ * Not exported. The configuration layer has one public entry point, and this
519
+ * is the half of it that reads flags rather than files.
520
+ *
521
+ * `codometer`, `changes` and `configuration` share the rules for the flags
522
+ * they hold in common, and those rules are subtle enough to be worth stating
523
+ * once: commander hands a valueless flag through as `true` without ever
524
+ * calling its parser, so a command that narrows text and one that does not
525
+ * disagree about what `--flag "$UNSET"` meant. A flag only one command takes
526
+ * keeps its own parser.
527
+ */
528
+ declare class ConfigurationFlagsService {
529
+ constructor();
530
+ /** States what `--check` accepts, in front of whatever went wrong. */
531
+ private describeAcceptedCheckNames;
532
+ /**
533
+ * Reads the `--check` value into the set of things the run fails on.
534
+ *
535
+ * A flag passed without a value arrives as `true` and is a mistake rather
536
+ * than a shorthand: it used to mean "check everything", and a set with
537
+ * nothing in it looks exactly like the flag having been left off.
538
+ */
539
+ private readCheckNames;
540
+ /** Keeps the names `--check` knows and complains about the rest. */
541
+ private validateCheckNames;
542
+ /**
543
+ * Reads an option that carries a default when it was left off.
544
+ *
545
+ * The fallback belongs to the command rather than here: two commands that
546
+ * share the parsing rule for `--format` need not share what they render
547
+ * when nobody said.
548
+ */
549
+ parseDefaultedOption(value: unknown, fallback: string): string;
550
+ /**
551
+ * Reads a directory option, falling back to the working directory.
552
+ *
553
+ * The fallback is the process's working directory as it stands when the
554
+ * option is read, which is what every command means by "here" — no command
555
+ * changes it mid-run, and one that did would want the new one.
556
+ */
557
+ parseDirectoryOption(value: unknown): string;
558
+ /**
559
+ * Reads an option that carries text, or nothing at all.
560
+ *
561
+ * A flag written `--baseline-url "$EMPTY"` can reach commander with no
562
+ * value at all, which it reports as `true` without calling the option's
563
+ * parser. So anything but a non-empty string counts as absent — passing
564
+ * that boolean through renders a link to the word `true`.
565
+ *
566
+ * Deliberately does not trim, unlike `callidescope`'s same-named method: a
567
+ * codometer option is a path, and a path whose surrounding spaces were
568
+ * silently dropped is a different path from the one that was asked for.
569
+ */
570
+ parseOptionalOption(value: unknown): string | undefined;
571
+ /**
572
+ * Reads `--format` into what the run prints, falling back to the resolved
573
+ * configuration's own `format` when the flag was left off.
574
+ *
575
+ * The fallback never infers from which other flags are present — omitting
576
+ * `--format` always reads the same value the configuration declares,
577
+ * whether or not this run also writes a file.
578
+ */
579
+ resolveFormat(value: string | undefined, configuredFormat: CodometerFormat, errors: string[]): MeasureFormat | undefined;
580
+ /**
581
+ * Reads the flags into what the run writes and what it fails on.
582
+ *
583
+ * Writing is answered per output, by whether that output's own
584
+ * `--output-*` flag was passed at all. `--output-json`/`--output-markdown`
585
+ * together with `--check reports` is refused rather than obeyed: nothing
586
+ * can be stale immediately after being written, so a run asking for both on
587
+ * the same output has misunderstood one of them and would silently compare
588
+ * instead of writing.
589
+ */
590
+ selectMode(options: MeasureCommandOptions): ModeSelection;
591
+ }
592
+
593
+ /**
594
+ * Finds and reads a codometer configuration file.
595
+ *
596
+ * Owns locating the file and turning whatever it exports into a plain,
597
+ * unvalidated configuration object — parsing JSON/JSONC by hand, everything
598
+ * else through `jiti`. What the object means is `ConfigurationService`'s to
599
+ * validate and resolve, kept apart so a file finding no configuration reads
600
+ * exactly like one that found an empty object.
601
+ */
602
+ declare class ConfigurationLoaderService {
603
+ constructor();
604
+ /**
605
+ * Walks upward from a directory looking for a configuration file.
606
+ *
607
+ * Returns `undefined` when the search reaches the filesystem root without
608
+ * finding one: a repository that never wrote a configuration file is
609
+ * measured with the defaults rather than told to write one.
610
+ */
611
+ private findConfigurationFile;
612
+ /**
613
+ * Walks upward from the process cwd looking for the repository root.
614
+ *
615
+ * Used to resolve a configuration path given relative to that root even when
616
+ * the command was invoked from a nested directory, which is what a task
617
+ * runner does whenever it sets the cwd to the project rather than the
618
+ * workspace.
619
+ */
620
+ private findRepositoryRoot;
621
+ /** Loads a configuration module, choosing the reader by extension. */
622
+ private loadConfigurationModule;
623
+ /** Reads a JSON or JSONC configuration file. */
624
+ private loadJsonConfiguration;
625
+ /**
626
+ * Reads what a configuration module exported, through either interop shape.
627
+ *
628
+ * Anything that is not a plain object — including a function, since a
629
+ * configuration file authored as one is no longer supported — falls back to
630
+ * an empty object, the same way a configuration file exporting `42` does:
631
+ * the schema then applies to that empty object exactly as it would to a
632
+ * genuinely empty configuration file.
633
+ */
634
+ private readDefaultExport;
635
+ /**
636
+ * Resolves a configuration path against the cwd, then the repository root.
637
+ */
638
+ private resolveConfigurationPath;
639
+ /**
640
+ * Loads a configuration file's raw export, or `undefined` when none exists.
641
+ *
642
+ * Unvalidated on purpose: the caller runs the result through the schema
643
+ * before trusting any of it, so this service never has to know the shape a
644
+ * configuration is supposed to have.
645
+ */
646
+ load(args?: LoadConfigurationArguments): Promise<LoadedConfigurationModule | undefined>;
647
+ }
648
+
649
+ /**
650
+ * Provides the configuration layer's one public service.
651
+ *
652
+ * `ConfigurationLoaderService`, `ConfigurationResolverService` and
653
+ * `ConfigurationFlagsService` are providers rather than exports: they are how
654
+ * `ConfigurationService` finds a file, fills it in, and reads the command line
655
+ * beside it, and nothing outside this package injects any of them.
656
+ */
657
+ export declare class ConfigurationModule {
658
+ }
659
+
660
+ /**
661
+ * Fills a validated configuration in, field by field, with what it left out.
662
+ *
663
+ * Not exported from this package. The configuration layer has exactly one
664
+ * public entry point, and this is the half of it that turns a file's contents
665
+ * into the resolved object every analyzer reads — held apart from
666
+ * `ConfigurationService` so that class states what the layer answers rather
667
+ * than how each default is arrived at.
668
+ */
669
+ declare class ConfigurationResolverService {
670
+ constructor();
671
+ /**
672
+ * Validates a configuration object, refusing it in prose rather than in JSON.
673
+ *
674
+ * Every load goes through here — a file's contents and the empty object a
675
+ * directory with no configuration file stands in with alike — so the two
676
+ * fail identically and a reader gets the same sentence either way.
677
+ */
678
+ private parseConfigurationInternal;
679
+ /**
680
+ * Reads a limit's value, in decimal units when it was written as a string.
681
+ *
682
+ * Everything unreadable is refused: a negative number, a unit missing its
683
+ * `b`, a word, an empty string. The tool this replaces coerced an unreadable
684
+ * limit to nothing and then failed every target holding a single byte.
685
+ */
686
+ private parseLimitValue;
687
+ /**
688
+ * Reads a limit written as a string, unit and all.
689
+ *
690
+ * A unit multiplies and then rounds: `"1.5 KB"` is 1500, and the rounding is
691
+ * what keeps `"0.1 KB"` from arriving as the 100.00000000000001 floating
692
+ * point makes of it. A string carrying no unit at all is the plain number,
693
+ * which is what a limit on a count of interfaces or files is written as.
694
+ */
695
+ private parseLimitValueText;
696
+ /**
697
+ * Gives every configured counter a color and a group, and its `comment`
698
+ * selector a severity.
699
+ *
700
+ * Colors are handed out by position within a group rather than within the
701
+ * whole list, so adding a counter to one group does not recolor the badges
702
+ * of another — which would rewrite a report that had not otherwise changed.
703
+ * A `comment` selector's own defaulting is inlined here rather than given
704
+ * its own method: this list already runs one call deep inside
705
+ * `resolveConfiguration`, and a further call would push the whole chain
706
+ * past what this package's callidescope gate allows.
707
+ *
708
+ * Runs once, over the top-level `custom` declaration — never per output.
709
+ * An output only selects labels back out of what this resolves, so a
710
+ * counter is never resolved twice just because two outputs both render it.
711
+ */
712
+ private resolveCustomStatistics;
713
+ /**
714
+ * Fills in every input's compression and directory, and splits its globs
715
+ * into what they add and what they remove.
716
+ *
717
+ * A `!` prefix in `include` is what the tool this replaced used to subtract
718
+ * a file, and there it mattered where in the array it sat. Here the
719
+ * negations join the exclude globs in a single set, so an input holds the
720
+ * same files however its patterns are arranged.
721
+ */
722
+ private resolveInput;
723
+ /**
724
+ * Resolves every declared input, and the built-in `codebase` one.
725
+ *
726
+ * The built-in entry is prepended unless the configuration already declares
727
+ * one by that name, which replaces it outright — the only way a
728
+ * configuration reaches the built-in whole-tree scan under a compression or
729
+ * a different set of analyses.
730
+ */
731
+ private resolveInputs;
732
+ /** Applies defaults to one JSON output destination. */
733
+ private resolveJsonOutput;
734
+ /**
735
+ * Gives every limit its severity and a value read as a number.
736
+ *
737
+ * Which metric a limit lands on is decided where the measurement is, since
738
+ * nothing here knows what was measured — the only thing settled at this
739
+ * point is what the limit says.
740
+ */
741
+ private resolveLimits;
742
+ /** Applies defaults to one markdown output destination. */
743
+ private resolveMarkdownOutput;
744
+ /** Applies defaults to every declared output destination. */
745
+ private resolveOutputs;
746
+ /**
747
+ * Picks out the top-level custom statistics an output's own `custom` array
748
+ * selected, by label.
749
+ *
750
+ * The schema already refuses a label naming no top-level declaration, so a
751
+ * label failing to resolve here is dropped rather than treated as another
752
+ * way to fail: this method's job is the lookup, not re-validating what the
753
+ * schema already guarantees.
754
+ */
755
+ private selectCustomStatistics;
756
+ /** Validates a configuration object, refusing it in prose rather than in JSON. */
757
+ parseConfiguration(configuration: unknown): CodometerConfiguration;
758
+ /**
759
+ * Fills in every field a configuration file may leave out.
760
+ *
761
+ * Exposed so a host embedding codometer can hand over a configuration object
762
+ * it assembled itself and get the same shape a configuration file produces.
763
+ */
764
+ resolveConfiguration(configuration: CodometerConfiguration): ResolvedCodometerConfiguration;
765
+ }
766
+
767
+ /**
768
+ * Answers what a codometer run is configured to do.
769
+ *
770
+ * The configuration layer's one public entry point. The file says what to
771
+ * measure, and the flags beside it say what to do about what was measured;
772
+ * both are answered here, so a command injects this and nothing else from
773
+ * this package.
774
+ *
775
+ * It composes rather than implements. Finding and reading a file is
776
+ * `ConfigurationLoaderService`, filling one in is
777
+ * `ConfigurationResolverService`, and reading a command line is
778
+ * `ConfigurationFlagsService` — three package-internal collaborators, none of
779
+ * them reachable from outside. What the configuration *means* — which files an
780
+ * exclusion glob removes, where a badge block is spliced in — belongs to the
781
+ * analyzers that read it, so that reading a configuration stays free of any
782
+ * knowledge of the repository being measured.
783
+ */
784
+ export declare class ConfigurationService {
785
+ private readonly configurationLoaderService;
786
+ private readonly configurationResolverService;
787
+ private readonly configurationFlagsService;
788
+ constructor(configurationLoaderService: ConfigurationLoaderService, configurationResolverService: ConfigurationResolverService, configurationFlagsService: ConfigurationFlagsService);
789
+ /**
790
+ * Loads and validates a codometer configuration file.
791
+ *
792
+ * A path that was named explicitly must exist — a typo in a task runner's
793
+ * arguments should fail rather than quietly measure the repository with
794
+ * defaults it never asked for. A path that was not named is searched for
795
+ * from the measured directory upward, and its absence is legal.
796
+ *
797
+ * The nearest configuration file wins outright: nothing from a further
798
+ * ancestor is folded into it. Merging the two would leave a limit that never
799
+ * applied looking exactly like one that did, and the only way to tell them
800
+ * apart would be to know which of several files each field came from.
801
+ */
802
+ loadConfiguration(args?: LoadConfigurationArguments): Promise<ResolvedCodometerConfiguration>;
803
+ /**
804
+ * Loads a configuration and says which file answered.
805
+ *
806
+ * The same work as `loadConfiguration`, keeping the path the upward walk
807
+ * settled on. A caller measuring one directory has no use for it — the
808
+ * configuration is the whole answer — but one listing what a repository
809
+ * configures has to attribute each answer to the file that gave it, and
810
+ * nothing downstream of the walk can still tell.
811
+ */
812
+ loadConfigurationFile(args?: LoadConfigurationArguments): Promise<LoadedConfiguration>;
813
+ /** Validates a configuration object, refusing it in prose rather than JSON. */
814
+ parseConfiguration(configuration: unknown): CodometerConfiguration;
815
+ /** Reads an option that carries a default when it was left off. */
816
+ parseDefaultedOption(value: unknown, fallback: string): string;
817
+ /** Reads a directory option, falling back to the working directory. */
818
+ parseDirectoryOption(value: unknown): string;
819
+ /** Reads an option that carries text, or nothing at all. */
820
+ parseOptionalOption(value: unknown): string | undefined;
821
+ /** Fills in every field a configuration file may leave out. */
822
+ resolveConfiguration(configuration: CodometerConfiguration): ResolvedCodometerConfiguration;
823
+ /** Reads `--format` into what the run prints, or the configured format. */
824
+ resolveFormat(value: string | undefined, configuredFormat: CodometerFormat, errors: string[]): MeasureFormat | undefined;
825
+ /** Reads the flags into what the run writes and what it fails on. */
826
+ selectMode(options: MeasureCommandOptions): ModeSelection;
827
+ }
828
+
829
+ /**
830
+ * The built-in `codebase` input, present unless a configuration's `inputs`
831
+ * names an entry of its own by that name.
832
+ */
833
+ export declare const DEFAULT_CODEBASE_INPUT: CodometerInput;
834
+
835
+ /**
836
+ * Badge colors handed to configured counters that name none, in order.
837
+ *
838
+ * Cycled rather than exhausted, so a repository can configure as many counters
839
+ * as it likes and each still gets a color that is stable between runs.
840
+ */
841
+ export declare const DEFAULT_CUSTOM_STATISTIC_COLORS: readonly ["7c3aed", "0284c7", "16a34a", "ea580c", "db2777", "0ea5e9", "059669", "ca8a04"];
842
+
843
+ /** Badge group a configured counter is rendered into when it names none. */
844
+ export declare const DEFAULT_CUSTOM_STATISTIC_GROUP = "conventions";
845
+
846
+ /**
847
+ * Path globs excluded from measurement when a configuration names none.
848
+ *
849
+ * Only the directories every ecosystem generates. Everything a specific
850
+ * repository considers noise — ingested corpora, generated documentation,
851
+ * scratch notes — belongs in that repository's own configuration file.
852
+ */
853
+ export declare const DEFAULT_EXCLUDE_GLOBS: readonly ["**/.nx/**", "**/build/**", "**/coverage/**", "**/dist/**", "**/node_modules/**"];
854
+
855
+ /**
856
+ * Compression applied to an input that names none.
857
+ *
858
+ * Gzip rather than the best available, because a compressed size is only worth
859
+ * measuring against what a server would actually send, and gzip is what every
860
+ * client understands. An input measuring bytes on disk asks for `none`.
861
+ */
862
+ export declare const DEFAULT_INPUT_COMPRESSION = "gzip";
863
+
864
+ /**
865
+ * Where an input's globs start when it names no directory of its own.
866
+ *
867
+ * The process's working directory. An input that means to reach outside it
868
+ * says so, which keeps "measure what I was pointed at" the thing that needs
869
+ * no writing down.
870
+ */
871
+ export declare const DEFAULT_INPUT_DIRECTORY = ".";
872
+
873
+ /**
874
+ * Name of the input every run measures unless a configuration replaces it:
875
+ * the codebase itself.
876
+ *
877
+ * Its files are every one the repository's ignore files leave behind rather
878
+ * than a glob match — `include` here is a placeholder a glob-based reader
879
+ * never consults for this one entry — which is what makes this input
880
+ * different from every other one a configuration declares.
881
+ */
882
+ export declare const DEFAULT_INPUT_NAME = "codebase";
883
+
884
+ /** Spaces used to indent the JSON report when a configuration names none. */
885
+ export declare const DEFAULT_JSON_INDENTATION = 2;
886
+
887
+ /**
888
+ * Severity a limit that names none carries.
889
+ *
890
+ * The strict one. A limit is written to gate, so one that quietly warned
891
+ * because nobody spelled out the severity would be a gate in name only —
892
+ * `warn` is the deliberate choice, not the accidental one.
893
+ */
894
+ export declare const DEFAULT_LIMIT_SEVERITY = "fail";
895
+
896
+ /** Closing marker of the generated badge block. */
897
+ export declare const DEFAULT_MARKDOWN_END_MARKER = "<!-- codometer:end -->";
898
+
899
+ /** Opening marker of the generated badge block. */
900
+ export declare const DEFAULT_MARKDOWN_START_MARKER = "<!-- codometer:start -->";
901
+
902
+ /**
903
+ * Interpreter used for Python analysis when a configuration names none.
904
+ *
905
+ * A repository whose Python lives in a managed environment overrides this with
906
+ * the command that enters it — `uv run python`, `poetry run python`, or the
907
+ * path to a virtual environment's interpreter.
908
+ */
909
+ export declare const DEFAULT_PYTHON_COMMAND = "python3";
910
+
911
+ /** What `--format json` prints: the report, as a document something can parse. */
912
+ export declare const FORMAT_JSON = "json";
913
+
914
+ /** What `--format markdown` prints: the rendered badge document. */
915
+ export declare const FORMAT_MARKDOWN = "markdown";
916
+
917
+ /**
918
+ * Everything `--format` accepts, in the order an error message lists them.
919
+ *
920
+ * Named here rather than spelled into each message, so the list a mistake is
921
+ * measured against and the list it is told about can never drift apart. A
922
+ * format added here is accepted everywhere the moment it is rendered.
923
+ */
924
+ export declare const FORMAT_NAMES: readonly ["json", "markdown"];
925
+
926
+ /** Arguments accepted when loading a configuration file. */
927
+ export declare interface LoadConfigurationArguments {
928
+ configurationPath?: string | undefined;
929
+ searchDirectory?: string | undefined;
930
+ }
931
+
932
+ /**
933
+ * A resolved configuration and the file it was resolved from.
934
+ *
935
+ * `path` stays `undefined` when the upward walk reached the filesystem root
936
+ * without finding a file, which is legal and leaves every default in place.
937
+ */
938
+ export declare interface LoadedConfiguration {
939
+ configuration: ResolvedCodometerConfiguration;
940
+ path: string | undefined;
941
+ }
942
+
943
+ /** What `ConfigurationLoaderService.load` found, unvalidated. */
944
+ declare interface LoadedConfigurationModule {
945
+ configuration: unknown;
946
+ /**
947
+ * Absolute path of the file it came from.
948
+ *
949
+ * Carried because a caller listing what a repository configures has to say
950
+ * where each answer was written, and the upward walk is the only thing that
951
+ * knows: by the time a configuration is resolved, the file it came from is
952
+ * indistinguishable from one three directories higher.
953
+ */
954
+ path: string;
955
+ }
956
+
957
+ /**
958
+ * The anchor mechanics a `write` function would otherwise have to reimplement.
959
+ *
960
+ * Splicing a generated block between two HTML comments is the common case, so
961
+ * it is one call away even for a writer that picks its own file.
962
+ */
963
+ export declare interface MarkdownAnchorHelpers {
964
+ endMarker: string;
965
+ startMarker: string;
966
+ /**
967
+ * Splices the anchored block into a file, appending it when the markers are
968
+ * absent, and creating the file when it does not exist.
969
+ *
970
+ * In check mode nothing is written and the return value reports whether the
971
+ * file already holds the current block. Defaults to the rendered content and
972
+ * the configured path; pass either to override.
973
+ */
974
+ syncAnchoredBlock: (overrides?: {
975
+ content?: string | undefined;
976
+ path?: string | undefined;
977
+ }) => boolean;
978
+ /** The content wrapped in the configured markers, ready to place anywhere. */
979
+ wrapInAnchors: (content?: string) => string;
980
+ }
981
+
982
+ /**
983
+ * Options accepted by the measure command.
984
+ *
985
+ * `--output-json` and `--output-markdown` are each independent: passing one
986
+ * never implicitly writes the other, and neither implies `--check reports`.
987
+ * There is no `--write` — passing an `--output-*` flag at all is what makes
988
+ * this run produce that destination.
989
+ */
990
+ export declare interface MeasureCommandOptions {
991
+ /** The comma-separated set of things to fail on, as it was written. */
992
+ check?: string | true | undefined;
993
+ config?: string | undefined;
994
+ /** What to print to standard output, as it was written. */
995
+ format?: string | undefined;
996
+ /**
997
+ * The glob array that replaces every configured input for this run, as
998
+ * written. `undefined` when the flag was never passed at all.
999
+ */
1000
+ inputs?: string[] | undefined;
1001
+ /**
1002
+ * The report's destination, as it was written.
1003
+ *
1004
+ * `true` for a bare flag naming no path, a string for an explicit one, and
1005
+ * `undefined` when the flag was never passed.
1006
+ */
1007
+ outputJson?: string | true | undefined;
1008
+ /**
1009
+ * The markdown destination, as it was written.
1010
+ *
1011
+ * `true` for a bare flag naming no path, a string for an explicit one, and
1012
+ * `undefined` when the flag was never passed.
1013
+ */
1014
+ outputMarkdown?: string | true | undefined;
1015
+ }
1016
+
1017
+ /**
1018
+ * What a run prints to standard output, when it prints anything.
1019
+ *
1020
+ * Derived from the list `--format` is validated against, so a format added
1021
+ * there is one this accepts rather than two lists to keep in step.
1022
+ */
1023
+ export declare type MeasureFormat = (typeof FORMAT_NAMES)[number];
1024
+
1025
+ /**
1026
+ * What a configuration reaching no `format` is told — written out rather than
1027
+ * left as the schema's own "expected one of" line, because it is the first
1028
+ * thing a newcomer to codometer sees.
1029
+ */
1030
+ export declare const MISSING_FORMAT_MESSAGE = "A codometer configuration must name a `format` of \"json\" or \"markdown\", and nothing supplies one for it. Set it in this file, or spread a shared default object that sets it \u2014 every run has to be told which report shape it produces, and a directory with no configuration file anywhere above it fails here rather than measuring with a format nobody chose.";
1031
+
1032
+ /**
1033
+ * What the command line asked the run to do, and what it could not make sense
1034
+ * of.
1035
+ *
1036
+ * Every complaint is collected before any of them is reported, so a command
1037
+ * line with two mistakes in it is two mistakes to fix rather than two runs.
1038
+ */
1039
+ export declare interface ModeSelection {
1040
+ errors: string[];
1041
+ mode: RunMode;
1042
+ }
1043
+
1044
+ /**
1045
+ * Marks the repository root during an upward search from the process cwd.
1046
+ *
1047
+ * A package manifest is deliberately not one of them: every package in a
1048
+ * monorepo carries one, so the search would stop at the nearest project rather
1049
+ * than the root a configuration path was written relative to.
1050
+ */
1051
+ export declare const REPOSITORY_ROOT_MARKERS: readonly [".git", "pnpm-workspace.yaml"];
1052
+
1053
+ /** A `comment` selector with its severity filled in. */
1054
+ export declare interface ResolvedCodometerCommentSelector {
1055
+ kind: CodometerSymbolKind | undefined;
1056
+ language: CodometerCommentLanguage | undefined;
1057
+ maximumCharacters: number | undefined;
1058
+ maximumLines: number | undefined;
1059
+ maximumWords: number | undefined;
1060
+ severity: CodometerSeverity;
1061
+ }
1062
+
1063
+ /**
1064
+ * Configuration with every default applied.
1065
+ *
1066
+ * Consumers read this shape rather than the authored one, so no analyzer has
1067
+ * to know which fields a configuration file may omit.
1068
+ */
1069
+ export declare interface ResolvedCodometerConfiguration {
1070
+ /** Every counter this configuration measures, with defaults applied. */
1071
+ custom: ResolvedCodometerCustomStatistic[];
1072
+ /** Stays `undefined` when nothing named one, so every path must qualify. */
1073
+ defaultInput: string | undefined;
1074
+ exclude: string[];
1075
+ excludeFrom: string[];
1076
+ format: CodometerFormat;
1077
+ inputs: ResolvedCodometerInput[];
1078
+ limits: ResolvedCodometerLimit[];
1079
+ outputs: ResolvedCodometerOutput[];
1080
+ python: ResolvedCodometerPythonConfiguration;
1081
+ }
1082
+
1083
+ /** A configured counter with its badge color and group filled in. */
1084
+ export declare interface ResolvedCodometerCustomStatistic {
1085
+ color: string;
1086
+ comment: ResolvedCodometerCommentSelector | undefined;
1087
+ group: CodometerStatisticGroup;
1088
+ label: string;
1089
+ /** Empty for a symbol or comment counter naming none, which then searches every file. */
1090
+ patterns: string[];
1091
+ symbols?: CodometerSymbolMatcher | undefined;
1092
+ }
1093
+
1094
+ /**
1095
+ * A named set of files with its compression filled in and its negations
1096
+ * collected.
1097
+ *
1098
+ * `include` holds only patterns that add files and `exclude` only patterns
1099
+ * that remove them, whichever list they were authored in. Order carries no
1100
+ * meaning in either: a file is in the input when some include glob claims it
1101
+ * and no exclude glob does.
1102
+ */
1103
+ export declare interface ResolvedCodometerInput {
1104
+ analyses: CodometerAnalysis[];
1105
+ compression: CodometerCompression;
1106
+ /** `"."` when the input never named one, meaning the process's working directory. */
1107
+ directory: string;
1108
+ exclude: string[];
1109
+ include: string[];
1110
+ name: string;
1111
+ }
1112
+
1113
+ /** JSON output destination with defaults applied. */
1114
+ export declare interface ResolvedCodometerJsonOutput {
1115
+ custom: ResolvedCodometerCustomStatistic[];
1116
+ indentation: number;
1117
+ path: string;
1118
+ type: "json";
1119
+ }
1120
+
1121
+ /**
1122
+ * A limit with its severity filled in and its value read as a number.
1123
+ *
1124
+ * The unit is gone by this point: a limit written `"8 KB"` arrives here as
1125
+ * 8000, so nothing downstream has to know that limits can be written with
1126
+ * units at all.
1127
+ */
1128
+ export declare interface ResolvedCodometerLimit {
1129
+ /** Stays `undefined` when none was written; a report falls back to the path. */
1130
+ label: string | undefined;
1131
+ metric: string;
1132
+ severity: CodometerSeverity;
1133
+ value: number;
1134
+ }
1135
+
1136
+ /**
1137
+ * Markdown output destination with defaults applied.
1138
+ *
1139
+ * `write` stays `undefined` when the configuration supplies none: the
1140
+ * built-in rendering and writing live in the CLI that calls it, so "unset" is
1141
+ * what selects it rather than a default named here.
1142
+ */
1143
+ export declare interface ResolvedCodometerMarkdownOutput {
1144
+ custom: ResolvedCodometerCustomStatistic[];
1145
+ description: string | undefined;
1146
+ endMarker: string;
1147
+ path: string | undefined;
1148
+ startMarker: string;
1149
+ type: "markdown";
1150
+ write: undefined | WriteMarkdownOutput;
1151
+ }
1152
+
1153
+ /** Destination the measured statistics are written to, with defaults applied. */
1154
+ export declare type ResolvedCodometerOutput = ResolvedCodometerJsonOutput | ResolvedCodometerMarkdownOutput;
1155
+
1156
+ /** Python analysis settings with defaults applied. */
1157
+ export declare interface ResolvedCodometerPythonConfiguration {
1158
+ command: string;
1159
+ }
1160
+
1161
+ /**
1162
+ * What the run does with what it measures.
1163
+ *
1164
+ * Checking staleness gates on `checksReports` alone and a breach on
1165
+ * `checksLimits` alone. Writing is answered per output: `writesJson` and
1166
+ * `writesMarkdown` are each true only when that output's own `--output-*`
1167
+ * flag was passed, so no flag ever quietly writes a destination the command
1168
+ * line never named.
1169
+ */
1170
+ export declare interface RunMode {
1171
+ checksLimits: boolean;
1172
+ checksReports: boolean;
1173
+ writesJson: boolean;
1174
+ writesMarkdown: boolean;
1175
+ }
1176
+
1177
+ /**
1178
+ * Decides what the markdown report says, which file it lands in, and how.
1179
+ *
1180
+ * Return `false` to report the destination as stale — in check mode that is
1181
+ * what fails the command. Anything else counts as up to date.
1182
+ */
1183
+ export declare type WriteMarkdownOutput = (args: WriteMarkdownOutputArguments) => boolean;
1184
+
1185
+ /** What a `write` function is handed. */
1186
+ export declare interface WriteMarkdownOutputArguments {
1187
+ anchors: MarkdownAnchorHelpers;
1188
+ /** True when nothing may be written and the file is only being inspected. */
1189
+ check: boolean;
1190
+ /** The configured description, for a writer that wants to place it itself. */
1191
+ description: string | undefined;
1192
+ /** The configured path, resolved against the measured directory. */
1193
+ path: string | undefined;
1194
+ /**
1195
+ * The built-in badge rendering of these same statistics.
1196
+ *
1197
+ * Call it to build the default report's content, or to add to it, rather
1198
+ * than reimplementing it.
1199
+ */
1200
+ renderBadges: () => string;
1201
+ statistics: CodeStatisticsResult;
1202
+ }
1203
+
1204
+ export { }