@conformetry/cli 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.
package/README.md ADDED
@@ -0,0 +1,1301 @@
1
+ # 👔 Conformetry
2
+
3
+ **Scaffold from a template, then hold the result to it.**
4
+
5
+ Conformetry is a code generation toolchain whose templates keep working after
6
+ generation. The same template folder that produces a new module is the
7
+ specification that module is later checked against, so scaffolding conventions
8
+ and enforcing them are one artifact instead of two that drift apart.
9
+
10
+ ```bash
11
+ npm install --save-dev @conformetry/cli
12
+ ```
13
+
14
+ ```bash
15
+ # Scaffold a new module from the `nestjs-service-module` template
16
+ conformetry generate --template nestjs-service-module --name billing
17
+
18
+ # Check every existing instance still matches the template it came from
19
+ conformetry validate
20
+ ```
21
+
22
+ ## Why
23
+
24
+ Scaffolding tools stop caring the moment the files are written. A month later
25
+ a module has lost its `constants.ts`, a service dropped its section comments,
26
+ and nobody notices until someone reads it. Linters can't help — the convention
27
+ isn't a rule about syntax, it's a rule about the shape of a template that only
28
+ exists in a generator's output directory.
29
+
30
+ Conformetry closes the loop. Templates are rendered twice: once to create
31
+ files, and again — with the same substitutions, by the same renderer — to
32
+ compare against the files that already exist. A file that would not be
33
+ regenerated the way it is written today is a finding.
34
+
35
+ Comparison is **structural, not textual**. A TypeScript instance is compared as
36
+ a syntax tree, markdown as an mdast tree, Python through Python's own `ast`
37
+ module. Reformatting a file, renaming a local, or adding a method does not fail
38
+ validation; deleting a required export, dropping a declared file, or losing a
39
+ section comment does.
40
+
41
+ ## Install
42
+
43
+ | Package | Install when |
44
+ | ------- | ------------ |
45
+ | `@conformetry/cli` | You want the `conformetry` command |
46
+ | `@conformetry/nx` | Your workspace is an Nx monorepo |
47
+ | `@conformetry/generation` + `@conformetry/validation` | You are embedding conformetry in your own tool |
48
+
49
+ ```bash
50
+ npm install --save-dev @conformetry/cli
51
+ # or
52
+ pnpm add --save-dev @conformetry/cli
53
+ ```
54
+
55
+ Node.js 20 or newer. Validating Python or Jupyter instances additionally needs
56
+ `python3` on `PATH` — the Python validator compares through the interpreter's
57
+ own `ast` module rather than reimplementing a parser.
58
+
59
+ ## Commands
60
+
61
+ ### `conformetry generate`
62
+
63
+ Renders one template folder into a target directory.
64
+
65
+ | Flag | Purpose |
66
+ | ---- | ------- |
67
+ | `--template [name]` | Which template from the registry to render. Asked for when omitted |
68
+ | `--config [path]` | Configuration file to read. Defaults to `configuration/conformetry.config.ts` |
69
+ | `--directory [path]` | Where to write the rendered files |
70
+
71
+ A template's own inputs are passed as flags alongside these:
72
+
73
+ ```bash
74
+ conformetry generate --template react-component --name search-bar
75
+ ```
76
+
77
+ **Omitting `--template` at a terminal offers a picker** — an autocomplete over
78
+ every configured template, each shown with its description, filtering as you
79
+ type. A name like `nestjs-service-module` is long by design, and typing
80
+ `service` is what makes it cheap to reach; nobody has to break off and run
81
+ `conformetry templates` to look one up. Passing `--template` skips the picker
82
+ entirely, because supplying a value is itself how a caller opts out of being
83
+ asked.
84
+
85
+ With no terminal, a missing template is **refused** — listing every available
86
+ name — rather than waited on, so a CI job fails immediately instead of hanging
87
+ until it times out.
88
+
89
+ **`--generator` was removed rather than kept as an alias**, and passing it is
90
+ refused by name. Unknown flags are accepted here so a template's own inputs can
91
+ be passed as flags, which means commander would otherwise read `--generator` as
92
+ an input nothing declares and drop it silently — the "appears to work" the
93
+ rename set out to avoid.
94
+
95
+ Unknown flags are accepted deliberately. Which inputs exist is not known until
96
+ the template is chosen, so they are matched against that template's schema
97
+ rather than declared ahead of time. This is also why the template is selected
98
+ with `--template` and not `--name`: almost every template takes a `name`, and
99
+ reserving that flag would leave no way to supply it.
100
+
101
+ **Missing inputs are prompted for whenever stdin is a terminal**, and there is
102
+ no flag to turn that off — an attached terminal is the whole condition, so a
103
+ script, a hook, or a CI job is never prompted.
104
+
105
+ **Every input a template declares is required.** A template substitutes each
106
+ of its placeholders, and mustache renders a missing one as an empty string
107
+ rather than failing, so an optional input would quietly produce a hole in the
108
+ generated file. `nx g conformetry:<template>` has always taken that line; this
109
+ command now does too, so the same template asks for the same values whichever
110
+ way it is run.
111
+
112
+ With no terminal, a missing input is therefore **refused** — naming the flag to
113
+ pass — and the run exits non-zero. That refusal is the load-bearing half.
114
+ `prompts` does not fail on a non-terminal stdin: it draws its menu, never
115
+ resolves, and lets the process **exit 0 having generated nothing**, which is how
116
+ this command used to hang in CI. It now asserts a terminal before prompting at
117
+ all and reports a rejected command line instead.
118
+
119
+ ### `conformetry templates`
120
+
121
+ Names every template the loaded configuration declares, with its description
122
+ and folder. `generate` and `validate` both offer that list as a picker now, so
123
+ this command is for reading it rather than for looking a name up before typing
124
+ one.
125
+
126
+ | Flag | Purpose |
127
+ | ---- | ------- |
128
+ | `--config [path]` | Configuration file to read |
129
+ | `--instances [globs]` | Comma-separated paths or globs; report only the templates that explain them |
130
+ | `--json` | Write the listing as JSON |
131
+
132
+ With `--instances` it answers the other direction — which templates explain a
133
+ given path:
134
+
135
+ ```bash
136
+ conformetry templates --instances packages/billing/src/modules/billing
137
+ ```
138
+
139
+ ```text
140
+ nestjs-service-module (nsm)
141
+ Generate a NestJS service module
142
+ Template: configuration/conformetry-templates/nestjs-service-module
143
+ Instances:
144
+ packages/billing/src/modules/billing 5/5 files 100%
145
+ nestjs-command-module (ncm)
146
+ Generate a NestJS command module
147
+ Template: configuration/conformetry-templates/nestjs-command-module
148
+ Instances:
149
+ packages/billing/src/modules/billing 3/5 files 60%
150
+ ```
151
+
152
+ **Every template that explains the path is listed**, because a path can belong
153
+ to more than one. Nothing records where an instance came from — attribution is
154
+ inferred from how much of a template's structure the path already has — so a
155
+ single verdict would hide the tie that makes an ambiguous instance ambiguous.
156
+
157
+ A bare listing omits the instances; they appear only when you narrow by path, so
158
+ the registry stays readable.
159
+
160
+ ### `conformetry instances`
161
+
162
+ Lists every instance the configured globs find, and which templates explain each
163
+ one. The complement of the command above: that one asks what standard a path
164
+ answers to, this one asks what generated code exists.
165
+
166
+ ```bash
167
+ conformetry instances --templates nestjs-service-module
168
+ ```
169
+
170
+ ```text
171
+ packages/billing/src/modules/billing
172
+ Templates:
173
+ nestjs-service-module 5/5 files 100%
174
+ ```
175
+
176
+ | Flag | Purpose |
177
+ | ---- | ------- |
178
+ | `--config [path]` | Configuration file to read |
179
+ | `--json` | Write the listing as JSON |
180
+ | `--templates [names]` | Comma-separated template names; report only the instances they explain |
181
+
182
+ Each path printed is usable as the `--instances` argument above, so the two
183
+ compose without reformatting. `--templates` is how you find every instance a
184
+ template change would affect.
185
+
186
+ Note that instances located by **project tags** rather than globs are invisible
187
+ here: tag resolution belongs to the Nx plugin, and the command-line host locates
188
+ instances by glob alone.
189
+
190
+ ### `conformetry validate`
191
+
192
+ Expands the configured instance globs and compares everything it finds against
193
+ the template it was generated from.
194
+
195
+ | Flag | Purpose |
196
+ | ---- | ------- |
197
+ | `--config [path]` | Configuration file to read |
198
+ | `--instances [globs]` | Comma-separated globs to validate, overriding the configuration |
199
+ | `--languages [names]` | Comma-separated languages to run — `typescript`, `markdown`, `python`, `json`, `jupyter`, `text` |
200
+ | `--templates [names]` | Comma-separated template names to narrow the run to, or `all` for every one |
201
+ | `--threshold [ratio]` | Lowest conformance score an instance may have, 0 to 1. The weakest of the three threshold levels |
202
+
203
+ Every flag is optional; an absent filter means "everything". The command exits
204
+ non-zero when any instance scores below its threshold, which is what makes it
205
+ usable as a pre-merge gate.
206
+
207
+ **`--templates` and `--instances` are two independent filters**, and a run
208
+ is their intersection — each removes candidates from one side before templates
209
+ and instances are paired:
210
+
211
+ | `--instances` | `--templates` | What is validated |
212
+ | ------------- | ------------- | ----------------- |
213
+ | absent | `all`, or absent with no terminal | Every template against every configured instance |
214
+ | present | `all`, or absent with no terminal | The globbed instances against every applicable template |
215
+ | absent | named | Every instance belonging to those templates, against them |
216
+ | present | named | The globbed instances narrowed to those templates' instances |
217
+
218
+ Omitting `--templates` at a terminal offers the same picker `generate` does,
219
+ ticking more than one, with `all` offered alongside the names. With no terminal
220
+ it falls back to every template rather than asking — which is exactly what an
221
+ invocation predating this flag already did, so scripts and CI jobs are
222
+ unaffected. `all` is reserved: a configuration cannot declare a template of
223
+ that name.
224
+
225
+ **A template whose instances are scoped by project tags cannot be located by
226
+ this host**, and a narrowed run says so rather than reporting nothing found. A
227
+ group carrying `tags` reads its globs _inside each project the tags select_, so
228
+ `src/modules/*` has no meaning until a project root is joined to it — which
229
+ only a host with a project graph can do. Such a group is left out rather than
230
+ expanded from the working directory, where it would match whatever happened to
231
+ sit at the same relative path and measure it against a template scoped to other
232
+ projects. Run those through [`@conformetry/nx`](../conformetry-nx/README.md),
233
+ or pass `--instances` with the paths to check.
234
+
235
+ Naming a template that does not exist is **refused**, listing the real names,
236
+ rather than silently narrowing to nothing. A selection that matches no
237
+ instances is reported as _"no instances belong to …"_ rather than as a clean
238
+ report, so "nothing to check" can be told apart from "everything checks out".
239
+
240
+ ## Scoring
241
+
242
+ Validation reports **how much** of its template an instance honours, not just
243
+ whether it does. Every template element the comparison weighs is one
244
+ requirement, and a missing element costs the whole subtree it stood for — so
245
+ deleting a class costs far more than dropping an import, without anyone
246
+ maintaining a table of weights.
247
+
248
+ The same three numbers — met, total, percentage — are reported at every level:
249
+
250
+ ```text
251
+ Conformance scores:
252
+ ✗ packages/logger/src/modules/logger (nestjs-service-module) — 149/151 requirements met (98.7%), below threshold 100.0%
253
+ ✗ packages/logger/src/modules/logger/logger (nestjs-service-file) — 108/109 requirements met (99.1%), below threshold 100.0%
254
+ Total — 257/260 requirements met (98.8%) across 2 instance(s), 2 below threshold
255
+
256
+ 1. file: logger.types.ts — 1/2 requirements met (50.0%)
257
+ Instance: packages/logger/src/modules/logger/logger.types.ts
258
+ Template: configuration/conformetry-templates/nestjs-service-module/{{nameKebabCase}}/{{nameKebabCase}}.types.ts
259
+
260
+ 1. Missing comment // 🏷️ Types
261
+ Template: Line 1, Column 1
262
+ Expected: `// 🏷️ Types`
263
+ Weight : 1 of the 2 requirements in this file
264
+ Fix : Add the comment // 🏷️ Types to the instance file.
265
+ ```
266
+
267
+ | Level | Answers |
268
+ | ----- | ------- |
269
+ | File | How much of _this file_ drifted — a small file can lose half of itself to one finding |
270
+ | Instance | Whether this instance clears its threshold; this is the level thresholds apply to |
271
+ | Total | How the whole run did, across every instance/template pair |
272
+
273
+ The fraction is printed alongside the percentage because a percentage hides its
274
+ own scale: 99.3% reads the same whether one requirement of 151 went missing or
275
+ thirty of four thousand did, and only the first is a five-minute fix.
276
+
277
+ The total is counted in instance/template pairs rather than files. A file
278
+ governed by two templates owes both of them, so its requirements genuinely
279
+ count once per template.
280
+
281
+ A finding that stands in for more than itself says so, which is what tells the
282
+ expensive drift from the trivial — a missing class carries the weight of every
283
+ member it held.
284
+
285
+ An instance must score at or above its **threshold** to pass. The default is
286
+ `1` — a perfect match, which is what conformetry has always demanded — so
287
+ adding scoring changes nothing until a threshold is lowered deliberately.
288
+
289
+ Three levels set it, narrowest first:
290
+
291
+ | Level | Where | Applies to |
292
+ | ----- | ----- | ---------- |
293
+ | Instance group | `instances[].threshold` | Only the paths that group's globs locate |
294
+ | Generator | `threshold` on the generator | Every instance of that template |
295
+ | Run | `--threshold` | Every instance the run touches |
296
+
297
+ That is what makes introducing a template bearable. A new template can be
298
+ adopted with the directory still being migrated held to `0.75` while every
299
+ other instance of it stays strict, instead of having to bring the whole
300
+ workspace over in one change.
301
+
302
+ Findings print either way. A lowered threshold is permission to ship the drift,
303
+ not a reason to stop showing it.
304
+
305
+ Differences are grouped by file and each one carries the location on **both**
306
+ sides — where the instance is wrong and where the template says so — plus the
307
+ expected value and a concrete fix:
308
+
309
+ ```text
310
+ 1. file: billing.service.ts
311
+ Instance: packages/billing/src/modules/billing/billing.service.ts
312
+ Template: configuration/conformetry-templates/nestjs-service-module/…
313
+
314
+ 1. Missing required comment
315
+ Instance: line 24
316
+ Template: line 31
317
+ Expected: `// 🌎 Public Methods`
318
+ Fix : Add the `// 🌎 Public Methods` section comment above the first public method.
319
+ ```
320
+
321
+ The `fix` field is the point of the format: reports are meant to be actionable
322
+ by whoever — or whatever — has to make the file conform.
323
+
324
+ ## Configuration
325
+
326
+ A single `conformetry.config.ts` declares every generator: the template folder
327
+ it renders, the inputs it takes, and the paths its output already occupies.
328
+
329
+ ```ts
330
+ import { type ConformetryConfiguration } from "@conformetry/configuration";
331
+
332
+ const conformetryConfiguration: ConformetryConfiguration = [
333
+ {
334
+ description: "Generate a NestJS service module",
335
+ inputs: {
336
+ name: { description: "Module name in kebab-case", type: "string" },
337
+ },
338
+ instances: [{ patterns: ["packages/*/src/modules/*"] }],
339
+ name: "nestjs-service-module",
340
+ templatePath: "templates/nestjs-service-module",
341
+ },
342
+ ];
343
+
344
+ export default conformetryConfiguration;
345
+ ```
346
+
347
+ `instances` is what makes validation possible: it says where this generator's
348
+ output already lives, so validation knows what to check without being told
349
+ twice. The full field reference — instance groups, tag selectors, input
350
+ schemas, discovery, and the supported file formats — is in
351
+ [**@conformetry/configuration**](../conformetry-configuration/README.md).
352
+
353
+ ## Templates
354
+
355
+ A template is an ordinary folder of ordinary files. Both file contents and file
356
+ _paths_ are rendered with [mustache](https://mustache.github.io), so a folder
357
+ named `{{nameKebabCase}}` becomes `billing` and a file named
358
+ `{{namePascalCase}}.tsx` becomes `SearchBar.tsx`:
359
+
360
+ ```text
361
+ templates/nestjs-service-module/
362
+ └── {{nameKebabCase}}/
363
+ ├── {{nameKebabCase}}.constants.ts
364
+ ├── {{nameKebabCase}}.module.ts
365
+ ├── {{nameKebabCase}}.service.ts
366
+ ├── {{nameKebabCase}}.service.unit.test.ts
367
+ └── {{nameKebabCase}}.types.ts
368
+ ```
369
+
370
+ Every generator's `name` input is expanded into four case variants
371
+ automatically, so a template never has to case-convert by hand:
372
+
373
+ | Placeholder | `search bar` becomes |
374
+ | ----------- | -------------------- |
375
+ | `{{nameCamelCase}}` | `searchBar` |
376
+ | `{{nameKebabCase}}` | `search-bar` |
377
+ | `{{namePascalCase}}` | `SearchBar` |
378
+ | `{{nameSnakeCase}}` | `search_bar` |
379
+
380
+ An explicit input of the same name always wins over the derived variant. Full
381
+ mustache is available — sections, inverted sections, partials — with HTML
382
+ escaping disabled so substituted values cannot corrupt source code.
383
+
384
+ > **Supply every placeholder a template uses.** An interpolated placeholder
385
+ > nobody supplied fails the run with `MissingSubstitutionError`, naming the
386
+ > placeholder and the template file. Mustache would otherwise render it as an
387
+ > empty string, and since validation renders exactly as generation does, both
388
+ > sides would lose the same value and report nothing.
389
+ >
390
+ > Sections are the exception, and are how a template asks for something
391
+ > optional: `{{#owner}}Owner: {{owner}}{{/owner}}` renders nothing when `owner`
392
+ > is absent, rather than refusing.
393
+
394
+ ## Validators
395
+
396
+ Which validator handles a file is decided by its extension, and only the
397
+ packages a run actually needs are loaded.
398
+
399
+ | Validator | Extensions | Compares |
400
+ | --------- | ---------- | -------- |
401
+ | `typescript` | `.ts`, `.tsx` | Syntax tree structure and required section comments |
402
+ | `markdown` | `.md` | mdast structure — headings, lists, tables — rather than prose |
403
+ | `python` | `.py` | Structure via Python's own `ast` module |
404
+ | `json` | `.json`, `.jsonc` | Key structure and values |
405
+ | `jupyter` | `.ipynb` | Notebook envelope, delegating cells to the markdown and Python validators |
406
+ | `text` | everything else | Duplicate-aware line conformance — the floor, so no extension goes unchecked |
407
+
408
+ Before any of them runs, every file the template declares is checked to
409
+ **exist**. That pass covers extensions no validator claims — `.gitignore`,
410
+ `.env.default`, `pyproject.toml` — which would otherwise be deletable without
411
+ failing anything. A missing directory is reported once rather than as twenty
412
+ missing files.
413
+
414
+ A template comment containing `TODO` is treated as a prompt rather than text to
415
+ copy, so any instance comment satisfies it.
416
+
417
+ ## Nx workspaces
418
+
419
+ [`@conformetry/nx`](../conformetry-nx/README.md) is a second host over the same
420
+ runtime. It adds two things the standalone CLI cannot offer:
421
+
422
+ - **A `conformetry-validate` target inferred onto every project** that holds
423
+ instances, so validation is cached and participates in `nx affected`.
424
+ - **Generators addressed by name** — `nx g conformetry:nestjs-service-module` —
425
+ with Nx prompting for inputs and writing through its virtual `Tree`.
426
+
427
+ Because which generators exist is a property of _your_ configuration rather
428
+ than of the package, the plugin exposing them is emitted at install time rather
429
+ than shipped:
430
+
431
+ ```json
432
+ { "scripts": { "postinstall": "conformetry-nx-bootstrap-generators" } }
433
+ ```
434
+
435
+ Instance groups may additionally select projects by Nx tag, with their globs
436
+ read inside each matching project:
437
+
438
+ ```ts
439
+ instances: [{ patterns: ["src/modules/*"], tags: ["framework:nestjs"] }];
440
+ ```
441
+
442
+ ## Packages
443
+
444
+ Conformetry is deliberately split so that embedding it does not mean depending
445
+ on a CLI. `@conformetry/core` is the leaf — it depends on nothing else in the
446
+ graph — and every other package declares exactly which siblings it may import.
447
+
448
+ ### Hosts
449
+
450
+ | Package | Role |
451
+ | ------- | ---- |
452
+ | [`@conformetry/cli`](README.md) | The `conformetry` command: expands globs, prompts for inputs, prints reports |
453
+ | [`@conformetry/nx`](../conformetry-nx/README.md) | Nx plugin: inferred validation targets, tag-scoped instances, emitted generators |
454
+
455
+ ### Runtime
456
+
457
+ | Package | Role |
458
+ | ------- | ---- |
459
+ | [`@conformetry/core`](../conformetry-core/README.md) | Contracts leaf: the structured difference shape, the score, the inventory, and the language validator contract |
460
+ | [`@conformetry/configuration`](../conformetry-configuration/README.md) | Config loading, template discovery, instance matching, input resolution, placeholder rendering |
461
+ | [`@conformetry/generation`](../conformetry-generation/README.md) | The generator lifecycle, rendering each template through the configuration layer |
462
+ | [`@conformetry/validation`](../conformetry-validation/README.md) | Validation orchestration, language routing, finding deduplication |
463
+ | [`@conformetry/languages`](../conformetry-languages/README.md) | Every Language module, the facade that resolves extensions to them, the existence check for every declared file, and the difference and scoring primitives they share |
464
+ | [`@conformetry/output`](../conformetry-output/README.md) | Every render target: the validation report and the template and instance inventory |
465
+
466
+ ### Languages
467
+
468
+ `@conformetry/languages` holds one module per Language, all reached through its
469
+ single `LanguagesModule` facade rather than as separate packages.
470
+
471
+ | Module | Extensions |
472
+ | ------ | ---------- |
473
+ | `typescript` | `.ts`, `.tsx` |
474
+ | `markdown` | `.md` |
475
+ | `python` | `.py` |
476
+ | `json` | `.json`, `.jsonc` |
477
+ | `jupyter` | `.ipynb` |
478
+ | `text` | the fallback for everything else |
479
+
480
+ Nothing depends on `@conformetry/cli`. Embedding conformetry means depending on
481
+ the runtime packages directly — the CLI is one host among others, and holds no
482
+ logic of its own.
483
+
484
+ ## Embedding
485
+
486
+ Both runtimes are NestJS providers, so a host wires them the way it wires
487
+ anything else:
488
+
489
+ ```ts
490
+ import { GenerationService } from "@conformetry/generation";
491
+
492
+ const result = await generationService.runGenerator({
493
+ definition: {
494
+ name: "nestjs-service-module",
495
+ templateDirectoryPath: "templates/nestjs-service-module",
496
+ },
497
+ inputs: { name: "billing" },
498
+ instancePath: "packages/billing/src/modules",
499
+ });
500
+ ```
501
+
502
+ Filesystem and formatter access go through adapters, which is how
503
+ `@conformetry/nx` reuses this runtime unchanged against a virtual `Tree`.
504
+ Rendering deliberately is _not_ an adapter: validation must substitute exactly
505
+ as generation does, or validation would flag the files the generator itself
506
+ produced.
507
+
508
+ ## Agent skills
509
+
510
+ Agent skills for coding agents working with conformetry are published in
511
+ [`@conformetry/agents`](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/conformetry/conformetry-agents):
512
+
513
+ | Skill | Description |
514
+ | ----- | ----------- |
515
+ | [`conformetry-generate`](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/conformetry/conformetry-agents/skills/conformetry-generate) | Scaffold code from templates using conformetry generators |
516
+ | [`conformetry-configure`](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/conformetry/conformetry-agents/skills/conformetry-configure) | Configure generators, templates, and validation rules in `conformetry.config.ts` |
517
+ | [`conformetry-validate`](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/conformetry/conformetry-agents/skills/conformetry-validate) | Run structural conformance checks against templates |
518
+
519
+ ## Examples
520
+
521
+ Worked examples and sandboxes are in
522
+ [`@conformetry/examples`](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/conformetry/conformetry-examples) — eleven self-contained
523
+ examples covering template authoring, case variants, structural comparison, drift detection, and Nx integration. An agent arriving from a conformance report can use
524
+ [`AGENTS.md`](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/conformetry/conformetry-examples/AGENTS.md) to find the example that explains each finding.
525
+
526
+ ## Start
527
+
528
+ Run the CLI from source:
529
+
530
+ ```bash
531
+ nx run conformetry-cli:start
532
+ ```
533
+
534
+ Pass a subcommand and its flags after `--`:
535
+
536
+ ```bash
537
+ nx run conformetry-cli:start -- validate --languages typescript
538
+ ```
539
+
540
+ ## Test
541
+
542
+ ```bash
543
+ nx run conformetry-cli:vitest
544
+ ```
545
+
546
+ ## Build
547
+
548
+ ```bash
549
+ nx run conformetry-cli:build
550
+ ```
551
+
552
+ ## License
553
+
554
+ MIT — see [LICENSE](../../../../LICENSE).
555
+
556
+ ## 👔 Conformetry
557
+
558
+ This project was generated from the [nestjs-command-project](../../../../configuration/conformetry-templates/nestjs-command-project) conformetry template.
559
+
560
+ <!-- callidescope:start -->
561
+
562
+ ## 🔭 Callidescope
563
+
564
+ Call stacks traced through `packages/ic-suite/conformetry/conformetry-cli`, deepest first. Each frame shows what it takes, what it returns, and what its documentation says.
565
+
566
+ | Measure | Value |
567
+ | --- | --- |
568
+ | Callables | 59 |
569
+ | Files | 27 |
570
+ | Calls traced | 72 |
571
+ | Call stacks | 16 |
572
+ | Deepest stack | 15 |
573
+ | Stacks through recursion | 0 |
574
+ | Unfollowable calls | 4 |
575
+
576
+ ### Limits
577
+
578
+ What this project is judged against, as declared in its own `callidescope.config.ts`.
579
+
580
+ | Limit | Value |
581
+ | --- | --- |
582
+ | `maximumDepth` | 15 |
583
+ | `maximumBreadth` | 9 |
584
+
585
+ ### Call stacks (depth)
586
+
587
+ **1. `InstancesCommand.run`** — depth ≥ 15 · decorated-method
588
+
589
+ ```text
590
+ 🚀 InstancesCommand.run(_passedParameters: string[], options: InstancesCommandOptions): Promise<void> [packages/ic-suite/conformetry/conformetry-cli/src/modules/instances/instances.command.ts:84]
591
+ ↳ Writes every instance found, filtered to the given templates.
592
+ └─> ConfigurationService.resolveInventoriedInstances(…): InventoriedInstance[] [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:345]
593
+ ↳ Lists every instance found, paired with the templates that explain it.
594
+ └─> InstanceDiscoveryService.resolveInventoriedInstances(args: ResolveInventoryArguments): InventoriedInstance[] [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:191]
595
+ ↳ Lists every instance found, paired with the templates that explain it. `templateNames` narrows the pairing rather than…
596
+ └─> InstanceDiscoveryService.takeInventory(…): { templates: TemplateDefinition[]; weighed: { instance: Instance; pairings: InventoriedPairing[]; }[]; } [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:255]
597
+ ↳ Weighs every instance the globs find against every declared template.
598
+ └─> InstanceDiscoveryService.map(…)(instance: Instance): { instance: Instance; pairings: InventoriedPairing[]; } [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:277]
599
+ └─> InstanceDiscoveryService.weighInstance(…): { instance: Instance; pairings: InventoriedPairing[]; } [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:56]
600
+ ↳ Weighs one instance against every template, best fit first.
601
+ └─> InstanceDiscoveryMatchingService.matchTemplates(…): TemplateMatch[] [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery-matching.service.ts:154]
602
+ ↳ Weighs every template that shares at least one file with the instance, best-first.
603
+ └─> InstanceDiscoveryMatchingService.map(…)(…): { matchedFileCount: number; matchRatio: number; template: TemplateDefinition; } [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery-matching.service.ts:160]
604
+ └─> TemplateDiscoveryService.countMatchingFiles(…): number [packages/ic-suite/conformetry/conformetry-configuration/src/modules/template-discovery/template-discovery.service.ts:121]
605
+ ↳ Counts how many of a template's files the instance path already has.
606
+ └─> TemplateDiscoveryService.filter(…)(templateFilePath: string): boolean [packages/ic-suite/conformetry/conformetry-configuration/src/modules/template-discovery/template-discovery.service.ts:130]
607
+ └─> TemplateDiscoveryService.resolveInstanceFilePath(…): string [packages/ic-suite/conformetry/conformetry-configuration/src/modules/template-discovery/template-discovery.service.ts:179]
608
+ ↳ Maps a template file path to the instance file path it governs.
609
+ └─> RenderingService.renderPath(…): string [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:142]
610
+ ↳ Renders a template path with mustache, the same way contents are rendered.
611
+ └─> RenderingService.assertEverySubstitutionSupplied(…): void [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:35]
612
+ ↳ Refuses to render a template asking for a value nobody supplied.
613
+ └─> RenderingService.collectInterpolatedNames(template: string): string[] [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:61]
614
+ ↳ Every placeholder a template interpolates, deduplicated.
615
+ └─> RenderingService.walk(spans: TemplateSpans): void [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:63]
616
+ ```
617
+
618
+ **2. `TemplatesCommand.run`** — depth ≥ 15 · decorated-method
619
+
620
+ ```text
621
+ 🚀 TemplatesCommand.run(_passedParameters: string[], options: TemplatesCommandOptions): Promise<void> [packages/ic-suite/conformetry/conformetry-cli/src/modules/templates/templates.command.ts:85]
622
+ ↳ Writes every declared template, filtered to the given instances.
623
+ └─> ConfigurationService.resolveInventoriedTemplates(…): InventoriedTemplate[] [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:352]
624
+ ↳ Lists every template declared, paired with the instances it explains.
625
+ └─> InstanceDiscoveryService.resolveInventoriedTemplates(args: ResolveInventoryArguments): InventoriedTemplate[] [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:216]
626
+ ↳ Lists every template declared, paired with the instances it explains. `instancePatterns` narrows which instances are…
627
+ └─> InstanceDiscoveryService.takeInventory(…): { templates: TemplateDefinition[]; weighed: { instance: Instance; pairings: InventoriedPairing[]; }[]; } [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:255]
628
+ ↳ Weighs every instance the globs find against every declared template.
629
+ └─> InstanceDiscoveryService.map(…)(instance: Instance): { instance: Instance; pairings: InventoriedPairing[]; } [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:277]
630
+ └─> InstanceDiscoveryService.weighInstance(…): { instance: Instance; pairings: InventoriedPairing[]; } [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:56]
631
+ ↳ Weighs one instance against every template, best fit first.
632
+ └─> InstanceDiscoveryMatchingService.matchTemplates(…): TemplateMatch[] [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery-matching.service.ts:154]
633
+ ↳ Weighs every template that shares at least one file with the instance, best-first.
634
+ └─> InstanceDiscoveryMatchingService.map(…)(…): { matchedFileCount: number; matchRatio: number; template: TemplateDefinition; } [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery-matching.service.ts:160]
635
+ └─> TemplateDiscoveryService.countMatchingFiles(…): number [packages/ic-suite/conformetry/conformetry-configuration/src/modules/template-discovery/template-discovery.service.ts:121]
636
+ ↳ Counts how many of a template's files the instance path already has.
637
+ └─> TemplateDiscoveryService.filter(…)(templateFilePath: string): boolean [packages/ic-suite/conformetry/conformetry-configuration/src/modules/template-discovery/template-discovery.service.ts:130]
638
+ └─> TemplateDiscoveryService.resolveInstanceFilePath(…): string [packages/ic-suite/conformetry/conformetry-configuration/src/modules/template-discovery/template-discovery.service.ts:179]
639
+ ↳ Maps a template file path to the instance file path it governs.
640
+ └─> RenderingService.renderPath(…): string [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:142]
641
+ ↳ Renders a template path with mustache, the same way contents are rendered.
642
+ └─> RenderingService.assertEverySubstitutionSupplied(…): void [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:35]
643
+ ↳ Refuses to render a template asking for a value nobody supplied.
644
+ └─> RenderingService.collectInterpolatedNames(template: string): string[] [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:61]
645
+ ↳ Every placeholder a template interpolates, deduplicated.
646
+ └─> RenderingService.walk(spans: TemplateSpans): void [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:63]
647
+ ```
648
+
649
+ **3. `ValidateCommand.run`** — depth ≥ 14 · decorated-method
650
+
651
+ ```text
652
+ 🚀 ValidateCommand.run(_passedParameters: string[], options: ValidateCommandOptions): Promise<void> [packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:364]
653
+ ↳ Runs validation and reports every difference found.
654
+ └─> ValidationService.validate(args: RunValidationArguments): RunValidationResult [packages/ic-suite/conformetry/conformetry-validation/src/modules/validation/validation.service.ts:136]
655
+ ↳ Validates every instance and returns the differences found.
656
+ └─> ConfigurationService.matchInstances(…): ResolvedInstances [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:263]
657
+ ↳ Resolves every instance to the template, or templates, that explain it.
658
+ └─> InstanceDiscoveryService.matchInstances(…): ResolvedInstances [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:95]
659
+ ↳ Resolves every instance to the template, or templates, that explain it.
660
+ └─> InstanceDiscoveryMatchingService.matchInstances(…): ResolvedInstances [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery-matching.service.ts:93]
661
+ ↳ Resolves every instance to the template — or templates — that explain it.
662
+ └─> InstanceDiscoveryMatchingService.matchTemplates(…): TemplateMatch[] [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery-matching.service.ts:154]
663
+ ↳ Weighs every template that shares at least one file with the instance, best-first.
664
+ └─> InstanceDiscoveryMatchingService.map(…)(…): { matchedFileCount: number; matchRatio: number; template: TemplateDefinition; } [packages/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery-matching.service.ts:160]
665
+ └─> TemplateDiscoveryService.countMatchingFiles(…): number [packages/ic-suite/conformetry/conformetry-configuration/src/modules/template-discovery/template-discovery.service.ts:121]
666
+ ↳ Counts how many of a template's files the instance path already has.
667
+ └─> TemplateDiscoveryService.filter(…)(templateFilePath: string): boolean [packages/ic-suite/conformetry/conformetry-configuration/src/modules/template-discovery/template-discovery.service.ts:130]
668
+ └─> TemplateDiscoveryService.resolveInstanceFilePath(…): string [packages/ic-suite/conformetry/conformetry-configuration/src/modules/template-discovery/template-discovery.service.ts:179]
669
+ ↳ Maps a template file path to the instance file path it governs.
670
+ └─> RenderingService.renderPath(…): string [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:142]
671
+ ↳ Renders a template path with mustache, the same way contents are rendered.
672
+ └─> RenderingService.assertEverySubstitutionSupplied(…): void [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:35]
673
+ ↳ Refuses to render a template asking for a value nobody supplied.
674
+ └─> RenderingService.collectInterpolatedNames(template: string): string[] [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:61]
675
+ ↳ Every placeholder a template interpolates, deduplicated.
676
+ └─> RenderingService.walk(spans: TemplateSpans): void [packages/ic-suite/conformetry/conformetry-configuration/src/modules/rendering/rendering.service.ts:63]
677
+ ```
678
+
679
+ <details>
680
+ <summary>13 more call stacks</summary>
681
+
682
+ **4. `GenerateCommand.run`** — depth ≥ 11 · decorated-method
683
+
684
+ ```text
685
+ 🚀 GenerateCommand.run(passedParameters: string[], options: GenerateCommandOptions): Promise<void> [packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:254]
686
+ ↳ Renders the template, reporting a refused command line as one.
687
+ └─> GenerateCommand.generate(…): Promise<void> [packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:64]
688
+ ↳ Resolves the template's inputs and writes its files.
689
+ └─> ConfigurationService.resolveGeneratorInputs(args: ResolveGeneratorInputsArguments): Promise<Record<string, string>> [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:333]
690
+ ↳ Resolves generator inputs from raw command-line arguments.
691
+ └─> InputService.resolveGeneratorInputs(args: ResolveGeneratorInputsArguments): Promise<Record<string, string>> [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:180]
692
+ ↳ Resolves generator inputs from raw command-line arguments.
693
+ └─> InputService.resolveInputs(…): Promise<Record<string, string>> [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:53]
694
+ ↳ Walks a schema, taking each value from the resolver or a prompt.
695
+ └─> InputService.acceptProvidedValue(args: { input: SchemaInput; value: string; }): string [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:39]
696
+ ↳ Validates a value the caller already had, throwing if it is invalid.
697
+ └─> InputSchemaService.validateValue(args: { input: SchemaInput; value: unknown; }): string | true [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input-schema.service.ts:158]
698
+ ↳ Validates a value, returning `true` or the reason it failed.
699
+ └─> InputSchemaService.validateEnum(args: { input: SchemaInput; value: string; }): string | true [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input-schema.service.ts:39]
700
+ ↳ Validates a value against a schema `enum`, when one is declared.
701
+ └─> InputSchemaService.readEnumValues(propertySchema: unknown): string[] [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input-schema.service.ts:123]
702
+ ↳ Reads the string members of a schema `enum`.
703
+ └─> InputSchemaService.readSchemaProperty(propertySchema: unknown, key: string): unknown [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input-schema.service.ts:26]
704
+ ↳ Reads one property off a schema fragment when it is an object.
705
+ └─> InputSchemaService.find(…)([entryKey]: [string, any]): boolean [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input-schema.service.ts:31]
706
+ ```
707
+
708
+ **5. `InstancesCommand.parseTemplates`** — depth 4 · decorated-method
709
+
710
+ ```text
711
+ 🚀 InstancesCommand.parseTemplates(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/instances/instances.command.ts:74]
712
+ ↳ Parses the optional template filter.
713
+ └─> ConfigurationService.parseCommaDelimitedOption(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:271]
714
+ ↳ Splits a comma-delimited filter option into its values.
715
+ └─> InputService.parseCommaDelimitedOption(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:118]
716
+ ↳ Splits a comma-delimited filter option into its values.
717
+ └─> InputService.filter(…)(item: string): boolean [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:128]
718
+ ```
719
+
720
+ **6. `TemplatesCommand.parseInstances`** — depth 4 · decorated-method
721
+
722
+ ```text
723
+ 🚀 TemplatesCommand.parseInstances(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/templates/templates.command.ts:66]
724
+ ↳ Parses the optional instance filter.
725
+ └─> ConfigurationService.parseCommaDelimitedOption(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:271]
726
+ ↳ Splits a comma-delimited filter option into its values.
727
+ └─> InputService.parseCommaDelimitedOption(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:118]
728
+ ↳ Splits a comma-delimited filter option into its values.
729
+ └─> InputService.filter(…)(item: string): boolean [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:128]
730
+ ```
731
+
732
+ **7. `ValidateCommand.parseInstances`** — depth 4 · decorated-method
733
+
734
+ ```text
735
+ 🚀 ValidateCommand.parseInstances(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:321]
736
+ ↳ Parses the optional instance glob override.
737
+ └─> ConfigurationService.parseCommaDelimitedOption(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:271]
738
+ ↳ Splits a comma-delimited filter option into its values.
739
+ └─> InputService.parseCommaDelimitedOption(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:118]
740
+ ↳ Splits a comma-delimited filter option into its values.
741
+ └─> InputService.filter(…)(item: string): boolean [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:128]
742
+ ```
743
+
744
+ **8. `ValidateCommand.parseLanguages`** — depth 4 · decorated-method
745
+
746
+ ```text
747
+ 🚀 ValidateCommand.parseLanguages(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:331]
748
+ ↳ Parses the optional language filter.
749
+ └─> ConfigurationService.parseCommaDelimitedOption(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:271]
750
+ ↳ Splits a comma-delimited filter option into its values.
751
+ └─> InputService.parseCommaDelimitedOption(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:118]
752
+ ↳ Splits a comma-delimited filter option into its values.
753
+ └─> InputService.filter(…)(item: string): boolean [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:128]
754
+ ```
755
+
756
+ **9. `ValidateCommand.parseTemplates`** — depth 4 · decorated-method
757
+
758
+ ```text
759
+ 🚀 ValidateCommand.parseTemplates(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:345]
760
+ ↳ Parses the optional template filter.
761
+ └─> ConfigurationService.parseCommaDelimitedOption(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:271]
762
+ ↳ Splits a comma-delimited filter option into its values.
763
+ └─> InputService.parseCommaDelimitedOption(value: string | undefined): string[] | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:118]
764
+ ↳ Splits a comma-delimited filter option into its values.
765
+ └─> InputService.filter(…)(item: string): boolean [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:128]
766
+ ```
767
+
768
+ **10. `ValidateCommand.parseThreshold`** — depth 4 · decorated-method
769
+
770
+ ```text
771
+ 🚀 ValidateCommand.parseThreshold(value: string | undefined): number | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:354]
772
+ ↳ Parses the optional run-level conformance threshold.
773
+ └─> ConfigurationService.parseThresholdOption(value: string | undefined): number | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:283]
774
+ ↳ Parses a threshold option as a ratio from 0 to 1.
775
+ └─> InputService.parseThresholdOption(value: string | undefined): number | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:161]
776
+ ↳ Parses a threshold option as a ratio from 0 to 1.
777
+ └─> InputService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:134]
778
+ ↳ Trims an optional string option, treating blank as absent.
779
+ ```
780
+
781
+ **11. `GenerateCommand.parseConfig`** — depth 3 · decorated-method
782
+
783
+ ```text
784
+ 🚀 GenerateCommand.parseConfig(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:216]
785
+ ↳ Parses the optional configuration path.
786
+ └─> ConfigurationService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:278]
787
+ ↳ Trims an optional string option, treating blank as absent.
788
+ └─> InputService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:134]
789
+ ↳ Trims an optional string option, treating blank as absent.
790
+ ```
791
+
792
+ **12. `GenerateCommand.parseDirectory`** — depth 3 · decorated-method
793
+
794
+ ```text
795
+ 🚀 GenerateCommand.parseDirectory(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:225]
796
+ ↳ Parses the output directory override.
797
+ └─> ConfigurationService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:278]
798
+ ↳ Trims an optional string option, treating blank as absent.
799
+ └─> InputService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:134]
800
+ ↳ Trims an optional string option, treating blank as absent.
801
+ ```
802
+
803
+ **13. `GenerateCommand.parseTemplate`** — depth 3 · decorated-method
804
+
805
+ ```text
806
+ 🚀 GenerateCommand.parseTemplate(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:239]
807
+ ↳ Parses the name of the template to render.
808
+ └─> ConfigurationService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:278]
809
+ ↳ Trims an optional string option, treating blank as absent.
810
+ └─> InputService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:134]
811
+ ↳ Trims an optional string option, treating blank as absent.
812
+ ```
813
+
814
+ **14. `InstancesCommand.parseConfig`** — depth 3 · decorated-method
815
+
816
+ ```text
817
+ 🚀 InstancesCommand.parseConfig(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/instances/instances.command.ts:56]
818
+ ↳ Parses the optional configuration path.
819
+ └─> ConfigurationService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:278]
820
+ ↳ Trims an optional string option, treating blank as absent.
821
+ └─> InputService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:134]
822
+ ↳ Trims an optional string option, treating blank as absent.
823
+ ```
824
+
825
+ **15. `TemplatesCommand.parseConfig`** — depth 3 · decorated-method
826
+
827
+ ```text
828
+ 🚀 TemplatesCommand.parseConfig(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/templates/templates.command.ts:57]
829
+ ↳ Parses the optional configuration path.
830
+ └─> ConfigurationService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:278]
831
+ ↳ Trims an optional string option, treating blank as absent.
832
+ └─> InputService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:134]
833
+ ↳ Trims an optional string option, treating blank as absent.
834
+ ```
835
+
836
+ **16. `ValidateCommand.parseConfig`** — depth 3 · decorated-method
837
+
838
+ ```text
839
+ 🚀 ValidateCommand.parseConfig(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:312]
840
+ ↳ Parses the optional configuration path.
841
+ └─> ConfigurationService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:278]
842
+ ↳ Trims an optional string option, treating blank as absent.
843
+ └─> InputService.parseOptionalOption(value: string | undefined): string | undefined [packages/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.service.ts:134]
844
+ ↳ Trims an optional string option, treating blank as absent.
845
+ ```
846
+
847
+ </details>
848
+
849
+ ### Breadth
850
+
851
+ | Callable | Breadth | Calls directly | Location |
852
+ | --- | --- | --- | --- |
853
+ | `GenerateCommand.generate` | 9 | `GenerateCommand.rejectRemovedGeneratorOption`, `ConfigurationService.loadConformetryConfiguration`, `GenerateCommand.resolveTemplateName`, `GenerateCommand.find(…)`, `unknownTemplateError`, `GenerateCommand.map(…)`, `ConfigurationService.resolveGeneratorInputs`, `GenerationService.runGenerator`, `GenerateCommand.map(…)` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:64` |
854
+ | `ValidateCommand.run` | 7 | `ConfigurationService.loadConformetryConfiguration`, `ValidateCommand.selectTemplates`, `ValidateCommand.selectInstances`, `ValidateCommand.reportEmptySelection`, `ValidationService.validate`, `ConfigurationService.collectTemplates`, `ValidateCommand.reportResult` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:364` |
855
+ | `GenerateCommand.resolveTemplateName` | 4 | `GenerateCommand.map(…)`, `ConfigurationService.isAtTerminal`, `missingTemplateError`, `ConfigurationService.promptForTemplate` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:183` |
856
+
857
+ <details>
858
+ <summary>28 more callables</summary>
859
+
860
+ | Callable | Breadth | Calls directly | Location |
861
+ | --- | --- | --- | --- |
862
+ | `InstancesCommand.run` | 4 | `ConfigurationService.loadConformetryConfiguration`, `InventoryService.shortenInstancePaths`, `ConfigurationService.resolveInventoriedInstances`, `InventoryService.describeInstances` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/instances/instances.command.ts:84` |
863
+ | `TemplatesCommand.run` | 4 | `ConfigurationService.loadConformetryConfiguration`, `InventoryService.shortenTemplatePairings`, `ConfigurationService.resolveInventoriedTemplates`, `InventoryService.describeTemplates` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/templates/templates.command.ts:85` |
864
+ | `ValidateCommand.selectInstances` | 4 | `ValidateCommand.findInstances`, `ValidateCommand.flatMap(…)`, `ValidateCommand.map(…)`, `ValidateCommand.filter(…)` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:230` |
865
+ | `ValidateCommand.reportEmptySelection` | 3 | `ValidateCommand.map(…)`, `ValidateCommand.map(…)`, `ValidateCommand.filter(…)` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:151` |
866
+ | `ValidateCommand.reportResult` | 3 | `ReportingService.formatReport`, `ValidateCommand.filter(…)`, `ValidateCommand.describeFailure` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:192` |
867
+ | `ValidateCommand.map(…)` | 3 | `ValidateCommand.find(…)`, `unknownTemplateError`, `ValidateCommand.map(…)` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:288` |
868
+ | `GenerateCommand.rejectRemovedGeneratorOption` | 2 | `GenerateCommand.some(…)`, `removedGeneratorOptionError` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:161` |
869
+ | `GenerateCommand.run` | 2 | `GenerateCommand.generate`, `GenerateCommand.rejectCommandLine` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:254` |
870
+ | `ValidateCommand.describeFailure` | 2 | `ValidateCommand.filter(…)`, `ValidateCommand.map(…)` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:73` |
871
+ | `ValidateCommand.findInstances` | 2 | `ValidateCommand.flatMap(…)`, `ConfigurationService.readWorkspaceGroups` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:97` |
872
+ | `ValidateCommand.promptForTemplateNames` | 2 | `ConfigurationService.isAtTerminal`, `ConfigurationService.promptForTemplates` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:133` |
873
+ | `ValidateCommand.selectTemplates` | 2 | `ValidateCommand.promptForTemplateNames`, `ValidateCommand.map(…)` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:273` |
874
+ | `missingTemplateError` | 1 | `InputError.constructor` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.constants.ts:15` |
875
+ | `GenerateCommand.parseConfig` | 1 | `ConfigurationService.parseOptionalOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:216` |
876
+ | `GenerateCommand.parseDirectory` | 1 | `ConfigurationService.parseOptionalOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:225` |
877
+ | `GenerateCommand.parseTemplate` | 1 | `ConfigurationService.parseOptionalOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/generate/generate.command.ts:239` |
878
+ | `InstancesCommand.parseConfig` | 1 | `ConfigurationService.parseOptionalOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/instances/instances.command.ts:56` |
879
+ | `InstancesCommand.parseTemplates` | 1 | `ConfigurationService.parseCommaDelimitedOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/instances/instances.command.ts:74` |
880
+ | `TemplatesCommand.parseConfig` | 1 | `ConfigurationService.parseOptionalOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/templates/templates.command.ts:57` |
881
+ | `TemplatesCommand.parseInstances` | 1 | `ConfigurationService.parseCommaDelimitedOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/templates/templates.command.ts:66` |
882
+ | `ValidateCommand.map(…)` | 1 | `ReportingService.formatPercentage` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:76` |
883
+ | `ValidateCommand.flatMap(…)` | 1 | `ConfigurationService.findInstances` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:105` |
884
+ | `ValidateCommand.filter(…)` | 1 | `ConfigurationService.readWorkspaceGroups` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:159` |
885
+ | `ValidateCommand.parseConfig` | 1 | `ConfigurationService.parseOptionalOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:312` |
886
+ | `ValidateCommand.parseInstances` | 1 | `ConfigurationService.parseCommaDelimitedOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:321` |
887
+ | `ValidateCommand.parseLanguages` | 1 | `ConfigurationService.parseCommaDelimitedOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:331` |
888
+ | `ValidateCommand.parseTemplates` | 1 | `ConfigurationService.parseCommaDelimitedOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:345` |
889
+ | `ValidateCommand.parseThreshold` | 1 | `ConfigurationService.parseThresholdOption` | `packages/ic-suite/conformetry/conformetry-cli/src/modules/validate/validate.command.ts:354` |
890
+
891
+ </details>
892
+ <!-- callidescope:end -->
893
+
894
+ ## 🕸️ Codependix
895
+
896
+ Dependency graphs exported by [codependix](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/codependix/codependix-cli), regenerated by `nx run codebase:codependix:write`.
897
+
898
+ ### Nx Neighborhood
899
+
900
+ <!-- codependix:start name="codependix-nx-projects" -->
901
+ ```mermaid
902
+ graph LR
903
+ conformetry_cli["conformetry-cli"]
904
+ conformetry_configuration["conformetry-configuration"]
905
+ conformetry_core["conformetry-core"]
906
+ conformetry_examples["conformetry-examples"]
907
+ conformetry_generation["conformetry-generation"]
908
+ conformetry_output["conformetry-output"]
909
+ conformetry_validation["conformetry-validation"]
910
+ logger["logger"]
911
+ conformetry_cli --> conformetry_configuration
912
+ conformetry_cli --> conformetry_core
913
+ conformetry_cli --> conformetry_generation
914
+ conformetry_cli --> conformetry_output
915
+ conformetry_cli --> conformetry_validation
916
+ conformetry_cli --> logger
917
+ conformetry_examples -.-> conformetry_cli
918
+ classDef subject fill:#7c3aed,color:#fff,stroke:#4c1d95,stroke-width:2px
919
+ class conformetry_cli subject
920
+ ```
921
+
922
+ _Dashed edges are dependencies Nx inferred from configuration rather than from code._
923
+ <!-- codependix:end name="codependix-nx-projects" -->
924
+
925
+ ### NestJS Module Graph
926
+
927
+ <!-- codependix:start name="codependix-nestjs-modules" -->
928
+ ```mermaid
929
+ flowchart LR
930
+ ConfigModule([ConfigModule])
931
+ ConfigurationModule
932
+ DifferencesModule
933
+ DiscoveryModule
934
+ FilesModule
935
+ GenerateModule
936
+ GenerationModule
937
+ InputModule
938
+ InstanceDiscoveryModule
939
+ InstanceGroupModule
940
+ InstancesModule
941
+ InventoryModule
942
+ JsonModule
943
+ JupyterModule
944
+ LanguagesModule
945
+ LoggerModule([LoggerModule])
946
+ MainModule
947
+ MarkdownModule
948
+ PythonModule
949
+ RenderingModule
950
+ ReportingModule
951
+ RunnerModule
952
+ ScoringModule
953
+ TemplateDiscoveryModule
954
+ TemplatesModule
955
+ TextModule
956
+ TypescriptModule
957
+ ValidateModule
958
+ ValidationModule
959
+ ConfigurationModule --> InputModule
960
+ ConfigurationModule --> InstanceDiscoveryModule
961
+ ConfigurationModule --> InstanceGroupModule
962
+ ConfigurationModule --> RenderingModule
963
+ ConfigurationModule --> TemplateDiscoveryModule
964
+ FilesModule --> ConfigurationModule
965
+ FilesModule --> DifferencesModule
966
+ GenerateModule --> ConfigurationModule
967
+ GenerateModule --> GenerationModule
968
+ GenerationModule --> ConfigurationModule
969
+ InstanceDiscoveryModule --> InstanceGroupModule
970
+ InstanceDiscoveryModule --> RenderingModule
971
+ InstanceDiscoveryModule --> TemplateDiscoveryModule
972
+ InstancesModule --> ConfigurationModule
973
+ InstancesModule --> InventoryModule
974
+ JsonModule --> ScoringModule
975
+ JupyterModule --> JsonModule
976
+ JupyterModule --> MarkdownModule
977
+ JupyterModule --> PythonModule
978
+ LanguagesModule --> JsonModule
979
+ LanguagesModule --> JupyterModule
980
+ LanguagesModule --> MarkdownModule
981
+ LanguagesModule --> PythonModule
982
+ LanguagesModule --> TextModule
983
+ LanguagesModule --> TypescriptModule
984
+ MainModule --> DiscoveryModule
985
+ MainModule --> GenerateModule
986
+ MainModule --> InstancesModule
987
+ MainModule --> TemplatesModule
988
+ MainModule --> ValidateModule
989
+ MarkdownModule --> ScoringModule
990
+ PythonModule --> DifferencesModule
991
+ PythonModule --> ScoringModule
992
+ ReportingModule --> ScoringModule
993
+ TemplateDiscoveryModule --> RenderingModule
994
+ TemplatesModule --> ConfigurationModule
995
+ TemplatesModule --> InventoryModule
996
+ TypescriptModule --> ScoringModule
997
+ ValidateModule --> ConfigurationModule
998
+ ValidateModule --> ReportingModule
999
+ ValidateModule --> ValidationModule
1000
+ ValidationModule --> ConfigurationModule
1001
+ ValidationModule --> FilesModule
1002
+ ValidationModule --> LanguagesModule
1003
+ ValidationModule --> RunnerModule
1004
+ ValidationModule --> ScoringModule
1005
+ ```
1006
+
1007
+ _Rounded modules are global: every module can inject them, so their edges are left out._
1008
+ <!-- codependix:end name="codependix-nestjs-modules" -->
1009
+
1010
+ ### File Imports
1011
+
1012
+ <!-- codependix:start name="codependix-file-imports" -->
1013
+ ```mermaid
1014
+ graph LR
1015
+ file_callidescope_config_ts["callidescope.config.ts"]
1016
+ file_codependix_config_ts["codependix.config.ts"]
1017
+ file_codometer_config_ts["codometer.config.ts"]
1018
+ file_eslint_config_ts["eslint.config.ts"]
1019
+ file_src_constants_ts["src/constants.ts"]
1020
+ file_src_index_ts["src/index.ts"]
1021
+ file_src_main_end_to_end_test_ts["src/main.end-to-end.test.ts"]
1022
+ file_src_main_integration_test_ts["src/main.integration.test.ts"]
1023
+ file_src_main_module_ts["src/main.module.ts"]
1024
+ file_src_main_ts["src/main.ts"]
1025
+ file_src_main_unit_test_ts["src/main.unit.test.ts"]
1026
+ file_src_modules_generate_generate_command_ts["src/modules/generate/generate.command.ts"]
1027
+ file_src_modules_generate_generate_command_unit_test_ts["src/modules/generate/generate.command.unit.test.ts"]
1028
+ file_src_modules_generate_generate_constants_ts["src/modules/generate/generate.constants.ts"]
1029
+ file_src_modules_generate_generate_module_ts["src/modules/generate/generate.module.ts"]
1030
+ file_src_modules_generate_generate_types_ts["src/modules/generate/generate.types.ts"]
1031
+ file_src_modules_instances_instances_command_ts["src/modules/instances/instances.command.ts"]
1032
+ file_src_modules_instances_instances_command_unit_test_ts["src/modules/instances/instances.command.unit.test.ts"]
1033
+ file_src_modules_instances_instances_constants_ts["src/modules/instances/instances.constants.ts"]
1034
+ file_src_modules_instances_instances_module_ts["src/modules/instances/instances.module.ts"]
1035
+ file_src_modules_instances_instances_types_ts["src/modules/instances/instances.types.ts"]
1036
+ file_src_modules_templates_templates_command_ts["src/modules/templates/templates.command.ts"]
1037
+ file_src_modules_templates_templates_command_unit_test_ts["src/modules/templates/templates.command.unit.test.ts"]
1038
+ file_src_modules_templates_templates_constants_ts["src/modules/templates/templates.constants.ts"]
1039
+ file_src_modules_templates_templates_module_ts["src/modules/templates/templates.module.ts"]
1040
+ file_src_modules_templates_templates_types_ts["src/modules/templates/templates.types.ts"]
1041
+ file_src_modules_validate_validate_command_ts["src/modules/validate/validate.command.ts"]
1042
+ file_src_modules_validate_validate_command_unit_test_ts["src/modules/validate/validate.command.unit.test.ts"]
1043
+ file_src_modules_validate_validate_constants_ts["src/modules/validate/validate.constants.ts"]
1044
+ file_src_modules_validate_validate_module_ts["src/modules/validate/validate.module.ts"]
1045
+ file_src_modules_validate_validate_types_ts["src/modules/validate/validate.types.ts"]
1046
+ file_src_repl_ts["src/repl.ts"]
1047
+ file_src_repl_unit_test_ts["src/repl.unit.test.ts"]
1048
+ file_testing_mocks_ts["testing/mocks.ts"]
1049
+ file_testing_setup_ts["testing/setup.ts"]
1050
+ file_vite_config_ts["vite.config.ts"]
1051
+ file_vitest_config_ts["vitest.config.ts"]
1052
+ file_src_main_end_to_end_test_ts --> file_src_constants_ts
1053
+ file_src_main_integration_test_ts --> file_src_main_module_ts
1054
+ file_src_main_integration_test_ts --> file_src_modules_generate_generate_command_ts
1055
+ file_src_main_integration_test_ts --> file_src_modules_instances_instances_command_ts
1056
+ file_src_main_integration_test_ts --> file_src_modules_templates_templates_command_ts
1057
+ file_src_main_integration_test_ts --> file_src_modules_validate_validate_command_ts
1058
+ file_src_main_module_ts --> file_src_constants_ts
1059
+ file_src_main_module_ts --> file_src_modules_generate_generate_module_ts
1060
+ file_src_main_module_ts --> file_src_modules_instances_instances_module_ts
1061
+ file_src_main_module_ts --> file_src_modules_templates_templates_module_ts
1062
+ file_src_main_module_ts --> file_src_modules_validate_validate_module_ts
1063
+ file_src_main_ts --> file_src_main_module_ts
1064
+ file_src_modules_generate_generate_command_ts --> file_src_constants_ts
1065
+ file_src_modules_generate_generate_command_ts --> file_src_modules_generate_generate_constants_ts
1066
+ file_src_modules_generate_generate_command_ts --> file_src_modules_generate_generate_types_ts
1067
+ file_src_modules_generate_generate_command_unit_test_ts --> file_src_modules_generate_generate_command_ts
1068
+ file_src_modules_generate_generate_module_ts --> file_src_modules_generate_generate_command_ts
1069
+ file_src_modules_instances_instances_command_ts --> file_src_constants_ts
1070
+ file_src_modules_instances_instances_command_ts --> file_src_modules_instances_instances_constants_ts
1071
+ file_src_modules_instances_instances_command_ts --> file_src_modules_instances_instances_types_ts
1072
+ file_src_modules_instances_instances_command_unit_test_ts --> file_src_modules_instances_instances_command_ts
1073
+ file_src_modules_instances_instances_module_ts --> file_src_modules_instances_instances_command_ts
1074
+ file_src_modules_templates_templates_command_ts --> file_src_constants_ts
1075
+ file_src_modules_templates_templates_command_ts --> file_src_modules_templates_templates_constants_ts
1076
+ file_src_modules_templates_templates_command_ts --> file_src_modules_templates_templates_types_ts
1077
+ file_src_modules_templates_templates_command_unit_test_ts --> file_src_modules_templates_templates_command_ts
1078
+ file_src_modules_templates_templates_module_ts --> file_src_modules_templates_templates_command_ts
1079
+ file_src_modules_validate_validate_command_ts --> file_src_constants_ts
1080
+ file_src_modules_validate_validate_command_ts --> file_src_modules_validate_validate_types_ts
1081
+ file_src_modules_validate_validate_command_unit_test_ts --> file_src_modules_validate_validate_command_ts
1082
+ file_src_modules_validate_validate_module_ts --> file_src_modules_validate_validate_command_ts
1083
+ file_src_repl_ts --> file_src_main_module_ts
1084
+ ```
1085
+ <!-- codependix:end name="codependix-file-imports" -->
1086
+
1087
+ <!-- codometer:start -->
1088
+
1089
+ ## ⏲️ Codometer
1090
+
1091
+ ### Project
1092
+
1093
+ ![Lines of Code](https://img.shields.io/badge/Lines_of_Code-3240-22c55e?style=flat-square)
1094
+ ![Repository Size](https://img.shields.io/badge/Repository_Size-119.65_kB-6b7280?style=flat-square)
1095
+ ![Folders](https://img.shields.io/badge/Folders-7-4a4a4a?style=flat-square)
1096
+ ![Source Files](https://img.shields.io/badge/Source_Files-37-3178c6?style=flat-square)
1097
+
1098
+ ### Measured Targets
1099
+
1100
+ ![Compiled JavaScript Size](https://img.shields.io/badge/Compiled_JavaScript_Size-6.31_kB_gzip-6b7280?style=flat-square)
1101
+
1102
+ ### TypeScript
1103
+
1104
+ ![TypeScript Files](https://img.shields.io/badge/TypeScript_Files-37-3178c6?style=flat-square)
1105
+ ![Interfaces](https://img.shields.io/badge/Interfaces-5-0ea5e9?style=flat-square)
1106
+ ![Generic Declarations](https://img.shields.io/badge/Generic_Declarations-0-0369a1?style=flat-square)
1107
+ ![Enums](https://img.shields.io/badge/Enums-0-f97316?style=flat-square)
1108
+ ![Decorators](https://img.shields.io/badge/Decorators-27-db2777?style=flat-square)
1109
+ ![Doc Comments](https://img.shields.io/badge/Doc_Comments-61-6366f1?style=flat-square)
1110
+ ![Static Methods](https://img.shields.io/badge/Static_Methods-0-166534?style=flat-square)
1111
+
1112
+ ### JavaScript
1113
+
1114
+ ![JavaScript Files](https://img.shields.io/badge/JavaScript_Files-0-f7df1e?style=flat-square)
1115
+ ![Test Files](https://img.shields.io/badge/Test_Files-8-10b981?style=flat-square)
1116
+ ![External Packages](https://img.shields.io/badge/External_Packages-18-8b5cf6?style=flat-square)
1117
+ ![Classes](https://img.shields.io/badge/Classes-10-7c3aed?style=flat-square)
1118
+ ![Functions](https://img.shields.io/badge/Functions-168-16a34a?style=flat-square)
1119
+ ![Methods](https://img.shields.io/badge/Methods-50-15803d?style=flat-square)
1120
+ ![Sync Functions](https://img.shields.io/badge/Sync_Functions-115-4ade80?style=flat-square)
1121
+ ![Async Functions](https://img.shields.io/badge/Async_Functions-103-059669?style=flat-square)
1122
+ ![Constants](https://img.shields.io/badge/Constants-103-dc2626?style=flat-square)
1123
+ ![Imports](https://img.shields.io/badge/Imports-136-0284c7?style=flat-square)
1124
+ ![Exported Symbols](https://img.shields.io/badge/Exported_Symbols-26-ea580c?style=flat-square)
1125
+ ![Comments](https://img.shields.io/badge/Comments-215-64748b?style=flat-square)
1126
+ ![Comment Lines](https://img.shields.io/badge/Comment_Lines-391-475569?style=flat-square)
1127
+ ![TODO Comments](https://img.shields.io/badge/TODO_Comments-0-ca8a04?style=flat-square)
1128
+
1129
+ ### Python
1130
+
1131
+ ![Python Files](https://img.shields.io/badge/Python_Files-0-3776ab?style=flat-square)
1132
+ ![Python Lines](https://img.shields.io/badge/Python_Lines-0-4b8bbe?style=flat-square)
1133
+ ![Python Classes](https://img.shields.io/badge/Python_Classes-0-7c3aed?style=flat-square)
1134
+ ![Python Functions](https://img.shields.io/badge/Python_Functions-0-16a34a?style=flat-square)
1135
+ ![Python Protocols](https://img.shields.io/badge/Python_Protocols-0-0ea5e9?style=flat-square)
1136
+ ![Python Constants](https://img.shields.io/badge/Python_Constants-0-dc2626?style=flat-square)
1137
+ ![Python Imports](https://img.shields.io/badge/Python_Imports-0-0284c7?style=flat-square)
1138
+ ![Python Decorators](https://img.shields.io/badge/Python_Decorators-0-db2777?style=flat-square)
1139
+ ![Docstrings](https://img.shields.io/badge/Docstrings-0-6366f1?style=flat-square)
1140
+ ![Docstring Lines](https://img.shields.io/badge/Docstring_Lines-0-818cf8?style=flat-square)
1141
+ ![Python Comments](https://img.shields.io/badge/Python_Comments-0-64748b?style=flat-square)
1142
+ ![Python Comment Lines](https://img.shields.io/badge/Python_Comment_Lines-0-475569?style=flat-square)
1143
+
1144
+ ### JSON
1145
+
1146
+ ![JSON Files](https://img.shields.io/badge/JSON_Files-4-a16207?style=flat-square)
1147
+ ![JSON Lines](https://img.shields.io/badge/JSON_Lines-191-ca8a04?style=flat-square)
1148
+ ![JSON Objects](https://img.shields.io/badge/JSON_Objects-42-7c3aed?style=flat-square)
1149
+ ![JSON Arrays](https://img.shields.io/badge/JSON_Arrays-13-8b5cf6?style=flat-square)
1150
+ ![JSON Properties](https://img.shields.io/badge/JSON_Properties-123-0284c7?style=flat-square)
1151
+ ![JSON Strings](https://img.shields.io/badge/JSON_Strings-107-16a34a?style=flat-square)
1152
+ ![JSON Numbers](https://img.shields.io/badge/JSON_Numbers-1-059669?style=flat-square)
1153
+ ![JSON Booleans](https://img.shields.io/badge/JSON_Booleans-8-0ea5e9?style=flat-square)
1154
+ ![JSON Nulls](https://img.shields.io/badge/JSON_Nulls-0-64748b?style=flat-square)
1155
+ ![JSON Items](https://img.shields.io/badge/JSON_Items-44-475569?style=flat-square)
1156
+ ![JSON Nodes](https://img.shields.io/badge/JSON_Nodes-171-dc2626?style=flat-square)
1157
+ ![JSON Max Depth](https://img.shields.io/badge/JSON_Max_Depth-6-ea580c?style=flat-square)
1158
+
1159
+ ### YAML
1160
+
1161
+ ![YAML Files](https://img.shields.io/badge/YAML_Files-0-cb171e?style=flat-square)
1162
+ ![YAML Lines](https://img.shields.io/badge/YAML_Lines-0-e34c26?style=flat-square)
1163
+ ![YAML Documents](https://img.shields.io/badge/YAML_Documents-0-f97316?style=flat-square)
1164
+ ![YAML Mappings](https://img.shields.io/badge/YAML_Mappings-0-7c3aed?style=flat-square)
1165
+ ![YAML Sequences](https://img.shields.io/badge/YAML_Sequences-0-8b5cf6?style=flat-square)
1166
+ ![YAML Keys](https://img.shields.io/badge/YAML_Keys-0-0284c7?style=flat-square)
1167
+ ![YAML Scalars](https://img.shields.io/badge/YAML_Scalars-0-16a34a?style=flat-square)
1168
+ ![YAML Anchors](https://img.shields.io/badge/YAML_Anchors-0-059669?style=flat-square)
1169
+ ![YAML Aliases](https://img.shields.io/badge/YAML_Aliases-0-10b981?style=flat-square)
1170
+ ![YAML Comments](https://img.shields.io/badge/YAML_Comments-0-64748b?style=flat-square)
1171
+ ![YAML Max Depth](https://img.shields.io/badge/YAML_Max_Depth-0-ea580c?style=flat-square)
1172
+
1173
+ ### TOML
1174
+
1175
+ ![TOML Files](https://img.shields.io/badge/TOML_Files-0-9c4221?style=flat-square)
1176
+ ![TOML Lines](https://img.shields.io/badge/TOML_Lines-0-b45309?style=flat-square)
1177
+ ![TOML Tables](https://img.shields.io/badge/TOML_Tables-0-7c3aed?style=flat-square)
1178
+ ![TOML Array Tables](https://img.shields.io/badge/TOML_Array_Tables-0-8b5cf6?style=flat-square)
1179
+ ![TOML Keys](https://img.shields.io/badge/TOML_Keys-0-0284c7?style=flat-square)
1180
+ ![TOML Arrays](https://img.shields.io/badge/TOML_Arrays-0-16a34a?style=flat-square)
1181
+ ![TOML Comments](https://img.shields.io/badge/TOML_Comments-0-64748b?style=flat-square)
1182
+
1183
+ ### Shell
1184
+
1185
+ ![Shell Files](https://img.shields.io/badge/Shell_Files-0-89e051?style=flat-square)
1186
+ ![Shell Lines](https://img.shields.io/badge/Shell_Lines-0-4eaa25?style=flat-square)
1187
+ ![Shell Functions](https://img.shields.io/badge/Shell_Functions-0-16a34a?style=flat-square)
1188
+ ![Shell Variables](https://img.shields.io/badge/Shell_Variables-0-0284c7?style=flat-square)
1189
+ ![Shell Exports](https://img.shields.io/badge/Shell_Exports-0-ea580c?style=flat-square)
1190
+ ![Shell Conditionals](https://img.shields.io/badge/Shell_Conditionals-0-7c3aed?style=flat-square)
1191
+ ![Shell Loops](https://img.shields.io/badge/Shell_Loops-0-8b5cf6?style=flat-square)
1192
+ ![Shell Pipelines](https://img.shields.io/badge/Shell_Pipelines-0-059669?style=flat-square)
1193
+ ![Shebangs](https://img.shields.io/badge/Shebangs-0-6b7280?style=flat-square)
1194
+ ![Shell Comments](https://img.shields.io/badge/Shell_Comments-0-64748b?style=flat-square)
1195
+ ![Shell Comment Lines](https://img.shields.io/badge/Shell_Comment_Lines-0-475569?style=flat-square)
1196
+
1197
+ ### SQL
1198
+
1199
+ ![SQL Files](https://img.shields.io/badge/SQL_Files-0-e38c00?style=flat-square)
1200
+ ![SQL Lines](https://img.shields.io/badge/SQL_Lines-0-f29111?style=flat-square)
1201
+ ![SQL Statements](https://img.shields.io/badge/SQL_Statements-0-7c3aed?style=flat-square)
1202
+ ![SQL Selects](https://img.shields.io/badge/SQL_Selects-0-16a34a?style=flat-square)
1203
+ ![SQL Inserts](https://img.shields.io/badge/SQL_Inserts-0-22c55e?style=flat-square)
1204
+ ![SQL Updates](https://img.shields.io/badge/SQL_Updates-0-0ea5e9?style=flat-square)
1205
+ ![SQL Deletes](https://img.shields.io/badge/SQL_Deletes-0-dc2626?style=flat-square)
1206
+ ![SQL Creates](https://img.shields.io/badge/SQL_Creates-0-0284c7?style=flat-square)
1207
+ ![SQL Joins](https://img.shields.io/badge/SQL_Joins-0-8b5cf6?style=flat-square)
1208
+ ![SQL CTEs](https://img.shields.io/badge/SQL_CTEs-0-059669?style=flat-square)
1209
+ ![SQL Comments](https://img.shields.io/badge/SQL_Comments-0-64748b?style=flat-square)
1210
+
1211
+ ### HCL
1212
+
1213
+ ![HCL Files](https://img.shields.io/badge/HCL_Files-0-844fba?style=flat-square)
1214
+ ![HCL Lines](https://img.shields.io/badge/HCL_Lines-0-a78bfa?style=flat-square)
1215
+ ![HCL Blocks](https://img.shields.io/badge/HCL_Blocks-0-7c3aed?style=flat-square)
1216
+ ![HCL Resources](https://img.shields.io/badge/HCL_Resources-0-0284c7?style=flat-square)
1217
+ ![HCL Variables](https://img.shields.io/badge/HCL_Variables-0-16a34a?style=flat-square)
1218
+ ![HCL Outputs](https://img.shields.io/badge/HCL_Outputs-0-059669?style=flat-square)
1219
+ ![HCL Attributes](https://img.shields.io/badge/HCL_Attributes-0-0ea5e9?style=flat-square)
1220
+ ![HCL Interpolations](https://img.shields.io/badge/HCL_Interpolations-0-db2777?style=flat-square)
1221
+ ![HCL Comments](https://img.shields.io/badge/HCL_Comments-0-64748b?style=flat-square)
1222
+
1223
+ ### CSS
1224
+
1225
+ ![CSS Files](https://img.shields.io/badge/CSS_Files-0-264de4?style=flat-square)
1226
+ ![CSS Lines](https://img.shields.io/badge/CSS_Lines-0-2965f1?style=flat-square)
1227
+ ![CSS Rules](https://img.shields.io/badge/CSS_Rules-0-7c3aed?style=flat-square)
1228
+ ![CSS Selectors](https://img.shields.io/badge/CSS_Selectors-0-8b5cf6?style=flat-square)
1229
+ ![CSS Declarations](https://img.shields.io/badge/CSS_Declarations-0-0284c7?style=flat-square)
1230
+ ![CSS At Rules](https://img.shields.io/badge/CSS_At_Rules-0-f97316?style=flat-square)
1231
+ ![CSS Media Queries](https://img.shields.io/badge/CSS_Media_Queries-0-ea580c?style=flat-square)
1232
+ ![CSS Custom Properties](https://img.shields.io/badge/CSS_Custom_Properties-0-16a34a?style=flat-square)
1233
+ ![CSS Comments](https://img.shields.io/badge/CSS_Comments-0-64748b?style=flat-square)
1234
+
1235
+ ### Conventions
1236
+
1237
+ ![Module Files](https://img.shields.io/badge/Module_Files-5-7c3aed?style=flat-square)
1238
+ ![Service Files](https://img.shields.io/badge/Service_Files-0-0284c7?style=flat-square)
1239
+ ![Command Files](https://img.shields.io/badge/Command_Files-4-16a34a?style=flat-square)
1240
+ ![Constants Files](https://img.shields.io/badge/Constants_Files-4-ea580c?style=flat-square)
1241
+ ![Types Files](https://img.shields.io/badge/Types_Files-4-db2777?style=flat-square)
1242
+ ![Utilities Files](https://img.shields.io/badge/Utilities_Files-0-0ea5e9?style=flat-square)
1243
+ ![TypeORM Entities](https://img.shields.io/badge/TypeORM_Entities-0-059669?style=flat-square)
1244
+ ![Unit Tests](https://img.shields.io/badge/Unit_Tests-6-ca8a04?style=flat-square)
1245
+ ![Integration Tests](https://img.shields.io/badge/Integration_Tests-1-7c3aed?style=flat-square)
1246
+ ![End To End Tests](https://img.shields.io/badge/End_To_End_Tests-1-0284c7?style=flat-square)
1247
+ ![CSS Comment Budget](https://img.shields.io/badge/CSS_Comment_Budget-0-16a34a?style=flat-square)
1248
+ ![HCL Comment Budget](https://img.shields.io/badge/HCL_Comment_Budget-0-ea580c?style=flat-square)
1249
+ ![Python Comment Budget](https://img.shields.io/badge/Python_Comment_Budget-0-db2777?style=flat-square)
1250
+ ![SQL Comment Budget](https://img.shields.io/badge/SQL_Comment_Budget-0-0ea5e9?style=flat-square)
1251
+ ![TOML Comment Budget](https://img.shields.io/badge/TOML_Comment_Budget-0-059669?style=flat-square)
1252
+ ![TypeScript Comment Budget](https://img.shields.io/badge/TypeScript_Comment_Budget-0-ca8a04?style=flat-square)
1253
+ ![YAML Comment Budget](https://img.shields.io/badge/YAML_Comment_Budget-0-7c3aed?style=flat-square)
1254
+ ![Shell Comment Budget](https://img.shields.io/badge/Shell_Comment_Budget-0-0284c7?style=flat-square)
1255
+
1256
+ ### Jupyter
1257
+
1258
+ ![Notebooks](https://img.shields.io/badge/Notebooks-0-f37626?style=flat-square)
1259
+ ![Notebook Cells](https://img.shields.io/badge/Notebook_Cells-0-e8a33d?style=flat-square)
1260
+ ![Code Cells](https://img.shields.io/badge/Code_Cells-0-3776ab?style=flat-square)
1261
+ ![Markdown Cells](https://img.shields.io/badge/Markdown_Cells-0-083fa1?style=flat-square)
1262
+ ![Raw Cells](https://img.shields.io/badge/Raw_Cells-0-9ca3af?style=flat-square)
1263
+ ![Executed Cells](https://img.shields.io/badge/Executed_Cells-0-16a34a?style=flat-square)
1264
+ ![Cell Outputs](https://img.shields.io/badge/Cell_Outputs-0-059669?style=flat-square)
1265
+ ![Notebook Code Lines](https://img.shields.io/badge/Notebook_Code_Lines-0-4b8bbe?style=flat-square)
1266
+ ![Notebook Classes](https://img.shields.io/badge/Notebook_Classes-0-7c3aed?style=flat-square)
1267
+ ![Notebook Functions](https://img.shields.io/badge/Notebook_Functions-0-22c55e?style=flat-square)
1268
+ ![Notebook Imports](https://img.shields.io/badge/Notebook_Imports-0-0284c7?style=flat-square)
1269
+ ![Notebook Decorators](https://img.shields.io/badge/Notebook_Decorators-0-db2777?style=flat-square)
1270
+ ![Notebook Prose Lines](https://img.shields.io/badge/Notebook_Prose_Lines-0-1f6feb?style=flat-square)
1271
+ ![Notebook Headings](https://img.shields.io/badge/Notebook_Headings-0-a78bfa?style=flat-square)
1272
+ ![Notebook Links](https://img.shields.io/badge/Notebook_Links-0-10b981?style=flat-square)
1273
+ ![Notebook Images](https://img.shields.io/badge/Notebook_Images-0-34d399?style=flat-square)
1274
+ ![Notebook Code Blocks](https://img.shields.io/badge/Notebook_Code_Blocks-0-dc2626?style=flat-square)
1275
+ ![Notebook Properties](https://img.shields.io/badge/Notebook_Properties-0-ca8a04?style=flat-square)
1276
+ ![Notebook Nodes](https://img.shields.io/badge/Notebook_Nodes-0-a16207?style=flat-square)
1277
+ ![Notebook Max Depth](https://img.shields.io/badge/Notebook_Max_Depth-0-ea580c?style=flat-square)
1278
+
1279
+ ### Markdown
1280
+
1281
+ ![Markdown Files](https://img.shields.io/badge/Markdown_Files-1-083fa1?style=flat-square)
1282
+ ![Markdown Lines](https://img.shields.io/badge/Markdown_Lines-247-1f6feb?style=flat-square)
1283
+ ![H1](https://img.shields.io/badge/H1-1-7c3aed?style=flat-square)
1284
+ ![H2](https://img.shields.io/badge/H2-7-8b5cf6?style=flat-square)
1285
+ ![H3](https://img.shields.io/badge/H3-14-a78bfa?style=flat-square)
1286
+ ![H4](https://img.shields.io/badge/H4-0-c4b5fd?style=flat-square)
1287
+ ![H5](https://img.shields.io/badge/H5-0-ddd6fe?style=flat-square)
1288
+ ![H6](https://img.shields.io/badge/H6-0-ede9fe?style=flat-square)
1289
+ ![Paragraphs](https://img.shields.io/badge/Paragraphs-49-64748b?style=flat-square)
1290
+ ![Lists](https://img.shields.io/badge/Lists-6-16a34a?style=flat-square)
1291
+ ![List Items](https://img.shields.io/badge/List_Items-28-22c55e?style=flat-square)
1292
+ ![Task List Items](https://img.shields.io/badge/Task_List_Items-0-4ade80?style=flat-square)
1293
+ ![Tables](https://img.shields.io/badge/Tables-2-0284c7?style=flat-square)
1294
+ ![Table Rows](https://img.shields.io/badge/Table_Rows-10-0ea5e9?style=flat-square)
1295
+ ![Links](https://img.shields.io/badge/Links-9-059669?style=flat-square)
1296
+ ![Images](https://img.shields.io/badge/Images-0-10b981?style=flat-square)
1297
+ ![Code Blocks](https://img.shields.io/badge/Code_Blocks-13-dc2626?style=flat-square)
1298
+ ![Inline Code](https://img.shields.io/badge/Inline_Code-78-ef4444?style=flat-square)
1299
+ ![Block Quotes](https://img.shields.io/badge/Block_Quotes-0-ca8a04?style=flat-square)
1300
+ ![Thematic Breaks](https://img.shields.io/badge/Thematic_Breaks-0-a16207?style=flat-square)
1301
+ <!-- codometer:end -->