@descent-vtt/spec-guard 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +162 -0
- package/README.md +201 -14
- package/dist/cli.d.ts +2 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +10 -0
- package/dist/cli.js.map +1 -1
- package/dist/comments.d.ts.map +1 -1
- package/dist/comments.js +41 -19
- package/dist/comments.js.map +1 -1
- package/dist/engine.d.ts +117 -6
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +279 -150
- package/dist/engine.js.map +1 -1
- package/dist/glob.d.ts +11 -1
- package/dist/glob.d.ts.map +1 -1
- package/dist/glob.js +20 -5
- package/dist/glob.js.map +1 -1
- package/dist/graph.d.ts +124 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +241 -0
- package/dist/graph.js.map +1 -0
- package/dist/imports.d.ts.map +1 -1
- package/dist/imports.js +10 -4
- package/dist/imports.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/layers.d.ts +72 -0
- package/dist/layers.d.ts.map +1 -0
- package/dist/layers.js +102 -0
- package/dist/layers.js.map +1 -0
- package/dist/parser.d.ts +36 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +189 -4
- package/dist/parser.js.map +1 -1
- package/dist/polyglot.d.ts +11 -1
- package/dist/polyglot.d.ts.map +1 -1
- package/dist/polyglot.js +21 -17
- package/dist/polyglot.js.map +1 -1
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +62 -5
- package/dist/reporter.js.map +1 -1
- package/dist/runner.d.ts +25 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +318 -93
- package/dist/runner.js.map +1 -1
- package/dist/text.d.ts +9 -1
- package/dist/text.d.ts.map +1 -1
- package/dist/text.js +29 -18
- package/dist/text.js.map +1 -1
- package/dist/types.d.ts +60 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,168 @@ All notable changes to this project are documented here. Versions follow
|
|
|
5
5
|
may change in a minor release — each such change is listed under **Changed**
|
|
6
6
|
with the flag that restores the previous behaviour.
|
|
7
7
|
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`@assert-layers`** - one directive for a layered architecture.
|
|
13
|
+
`order="src/domain, src/application, src/infrastructure"` runs from the layer
|
|
14
|
+
everything may depend on to the layer that may depend on everything; a file
|
|
15
|
+
importing from a layer listed after its own is a violation, reported with both
|
|
16
|
+
layers and the import. Layers are patterns in the `module=` language, so a bare
|
|
17
|
+
`domain` holds Python, Go, Rust and C# code to the same order as TypeScript.
|
|
18
|
+
A layer that matches no file, a file two layers both claim, and a missing
|
|
19
|
+
target all fail rather than pass; files no layer claims are counted in a
|
|
20
|
+
warning. Takes `max`, `types`, `exclude`, `allow-empty` and a debt `baseline`.
|
|
21
|
+
- **`@assert-import-cycle`** - import cycles, counted as strongly connected
|
|
22
|
+
components rather than simple cycles, so a second route around an existing
|
|
23
|
+
knot does not move the count. Each is shown as its shortest loop with the line
|
|
24
|
+
of every import on it. Found with an iterative Tarjan's algorithm: the
|
|
25
|
+
recursive form overflows Node's default stack at 10,000 files.
|
|
26
|
+
`types="ignore"` asks the runtime question. JavaScript and TypeScript only,
|
|
27
|
+
because a cycle needs to know which file an import *is*; imports that should
|
|
28
|
+
have become an edge and did not are reported, and fail under `--strict`.
|
|
29
|
+
See [ADR-0011](docs/adr/0011-layers-and-cycles.md) for the resolution table,
|
|
30
|
+
and for why the other four languages are not in the graph.
|
|
31
|
+
- `buildGraph`, `resolveReference`, `stronglyConnected`, `cyclicComponents`,
|
|
32
|
+
`witness`, `checkLayers` and `referenceForms` are exported, with their types.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- **Mutation score 97.97%** over 5,078 mutants, up from 0.6.0's 97.77%. The two
|
|
37
|
+
new modules are at 99.51% (`graph.ts`) and 96.43% (`layers.ts`), and each of
|
|
38
|
+
their three survivors was shown equivalent by running the mutated build
|
|
39
|
+
against the real one on thousands of random inputs. The first sweep of this
|
|
40
|
+
work found 34 survivors that 37 hand-written negative controls had not; see
|
|
41
|
+
[ADR-0003](docs/adr/0003-mutation-testing.md) for how they were replayed from
|
|
42
|
+
the report and killed.
|
|
43
|
+
- The SARIF fingerprint of an assertion that names neither a symbol nor a file
|
|
44
|
+
now includes its description. Only the two new kinds are affected; every
|
|
45
|
+
existing alert keeps its identity. Without it, two cycle rules on one target
|
|
46
|
+
would have been merged into one alert.
|
|
47
|
+
|
|
48
|
+
## 0.6.0
|
|
49
|
+
|
|
50
|
+
ADRs have a life, and spec-guard now reads it. A proposed ADR can carry live
|
|
51
|
+
assertions without breaking the build, and a superseded one can stay on disk
|
|
52
|
+
without enforcing the rule it records being replaced. Most of the work is in
|
|
53
|
+
making sure a rule that stops running can never look like a rule that passed.
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- **Document lifecycle status.** A Markdown document whose status is `draft`,
|
|
58
|
+
`proposed`, `rejected`, `deprecated` or `superseded` is parsed, validated,
|
|
59
|
+
reported by name - and not executed. A proposed ADR can now be written with
|
|
60
|
+
its assertions live and the build green, and a superseded ADR can stay on
|
|
61
|
+
disk, intact, enforcing nothing. Three spellings are read, because three are
|
|
62
|
+
in use: MADR front-matter (quoted, as MADR's template writes it, or not), a
|
|
63
|
+
Nygard `## Status` section, and a bold `**Status:**` label in the preamble.
|
|
64
|
+
CRLF documents read the same as LF ones. Anything else - an unrecognised
|
|
65
|
+
word, a misspelling, no status at all - keeps enforcing, which is the
|
|
66
|
+
direction that cannot turn a typo into a silently disabled rule.
|
|
67
|
+
|
|
68
|
+
Withholding is never quiet. Every withheld document is named in the human
|
|
69
|
+
report (`○ docs/adr/0011.md is Proposed. - 2 assertions not executed`), in
|
|
70
|
+
`--format json` as `inactiveSpecs`, and in `--format sarif` as a note-level
|
|
71
|
+
execution notification - because a rule that has gone quiet is otherwise
|
|
72
|
+
indistinguishable from a rule that passed. Directives in a withheld document
|
|
73
|
+
are still checked for typos, bad attributes and unresolvable values, so a
|
|
74
|
+
draft's mistake is found on the day it is written rather than on the day
|
|
75
|
+
everyone agrees the rule is right and stops looking at it.
|
|
76
|
+
See [ADR-0010](docs/adr/0010-spec-status.md), which also records why there is
|
|
77
|
+
no per-directive `if-status` attribute.
|
|
78
|
+
- `--ignore-status` executes every directive whatever its document declares -
|
|
79
|
+
how to ask whether a draft would pass if you accepted it today.
|
|
80
|
+
- `parseStatus`, `INACTIVE_STATUSES`, and the `SpecStatus` / `InactiveSpec`
|
|
81
|
+
types are exported from the programmatic API.
|
|
82
|
+
|
|
83
|
+
### Changed
|
|
84
|
+
|
|
85
|
+
- **A run that executed no assertions no longer reports that every assertion
|
|
86
|
+
holds.** It says `no assertion was executed, so nothing was verified`. True
|
|
87
|
+
and useless was the old sentence's problem: it is the exact line someone
|
|
88
|
+
reads as proof their specification is being enforced. Reachable before this
|
|
89
|
+
release through a spec file with no directives in it; withholding made it
|
|
90
|
+
easy to reach.
|
|
91
|
+
- `RunSummary` gains `inactive` and `RunReport` gains `inactiveSpecs`. Both are
|
|
92
|
+
always present; consumers deep-comparing a summary object will see the new
|
|
93
|
+
field.
|
|
94
|
+
- **Mutation score 97.77%** over 4,482 mutants, against the gate of 97 - up
|
|
95
|
+
from the 97.65% 0.5.1 shipped with, and no survivor in the new code. Getting there turned up a way a local sweep overstates a score
|
|
96
|
+
that the timeout warning could not see: a regex constant at module scope runs
|
|
97
|
+
the whole suite per mutant, so on a loaded machine an unrelated test timing
|
|
98
|
+
out is scored as a kill. Those patterns are now verified by applying every
|
|
99
|
+
mutant by hand, `scripts/mutation-regex.mjs`, and the account is in
|
|
100
|
+
[ADR-0003](docs/adr/0003-mutation-testing.md).
|
|
101
|
+
|
|
102
|
+
## 0.5.1
|
|
103
|
+
|
|
104
|
+
Writing down what the code already claimed. Every module was driven to its
|
|
105
|
+
honest mutation-testing ceiling, and the exercise turned up six wrong answers
|
|
106
|
+
rather than six missing tests — which is the argument for doing it at all. No
|
|
107
|
+
new features, and nothing a user has to change.
|
|
108
|
+
|
|
109
|
+
### Fixed
|
|
110
|
+
|
|
111
|
+
- **Two assertions on the same symbol answered each other's comment handling.**
|
|
112
|
+
The result cache keyed on the symbol, the targets and the search flags, but
|
|
113
|
+
not on `comments`. A spec with `<!-- @assert-count symbol="X" ... -->` above
|
|
114
|
+
`<!-- @assert-count symbol="X" ... comments="include" -->` returned whichever
|
|
115
|
+
count ran first for both. The grouping test had the same omission, so the two
|
|
116
|
+
were also merged into a single pass and the second was scanned with the
|
|
117
|
+
first's mask. There is now one definition of "the same question", in three
|
|
118
|
+
nested scopes, and the scope policy is part of it too.
|
|
119
|
+
- **An unreadable directory went unreported on a small repository.** The
|
|
120
|
+
adaptive engine had the walk's skip ledger in hand and returned without it on
|
|
121
|
+
any tree small enough to scan in process, so the same directory was a reported
|
|
122
|
+
gap on a large repository and silence on a small one. Same tree, two answers,
|
|
123
|
+
decided by its size.
|
|
124
|
+
- **Snippets from CRLF files carried a carriage return into the report**, which
|
|
125
|
+
returns the terminal cursor to column 0 and overwrites the line just printed.
|
|
126
|
+
The trim looked for `\r?\n` at the end of a line the caller had already cut at
|
|
127
|
+
the newline, so it could never match.
|
|
128
|
+
- **A bad `regex="true"` pattern was reported as `Invalid regular expression:
|
|
129
|
+
Invalid regular expression: /(/: ...`** — V8's message already says it once.
|
|
130
|
+
|
|
131
|
+
### Changed
|
|
132
|
+
|
|
133
|
+
- **Two requests differing only in `scope` are no longer merged into one
|
|
134
|
+
search pass.** Reachable today only through the programmatic API, where a
|
|
135
|
+
caller may build more than one `ScopePolicy` per run.
|
|
136
|
+
- `enumerateCandidates` takes a `WalkRequest` — a `SearchRequest` without the
|
|
137
|
+
`symbol`, because a walk does not depend on one. Existing callers are
|
|
138
|
+
unaffected; the symbol is now optional rather than required.
|
|
139
|
+
- `CachedEngine` declares `searchBatch` as present rather than optional, which
|
|
140
|
+
`createCachedEngine` has always guaranteed.
|
|
141
|
+
- `KINDS` and `ALLOWED_ATTRIBUTES` are exported from the parser, so the
|
|
142
|
+
directive grammar can be asserted rather than restated.
|
|
143
|
+
- **The mutation gate moves from 85 to 97**, against a CI measurement of 97.65%
|
|
144
|
+
over 4,299 mutants. Every module is above 95% and three are at 100%, where
|
|
145
|
+
0.5.0 ran from 73% to 96%. The 101 mutants still alive have each been applied
|
|
146
|
+
individually and produce byte-identical output, so that figure is the ceiling
|
|
147
|
+
rather than a way-point — and 29 that were assumed equivalent turned out not
|
|
148
|
+
to be, and are now tested. See
|
|
149
|
+
[ADR-0003](docs/adr/0003-mutation-testing.md), which also records a Stryker
|
|
150
|
+
limitation found on the way: a mutant that stops a test file *loading* is
|
|
151
|
+
reported as survived even though the suite is killing it.
|
|
152
|
+
- **`src/imports.ts` went from 73.74% to 95.89%.** The tokenizer was tested as a
|
|
153
|
+
step towards a list of module references rather than as a thing with an
|
|
154
|
+
output, so a template resumption that lost its place, a regex escape that
|
|
155
|
+
skipped a character, and three lookup tables were all unpinned. One
|
|
156
|
+
behaviour-preserving change came with it: the word branch starts its scan one
|
|
157
|
+
character in, so progress is unconditional by construction rather than a
|
|
158
|
+
consequence of a relation nothing enforced. Verified identical on 53.6 MB of
|
|
159
|
+
real JavaScript.
|
|
160
|
+
|
|
161
|
+
### Internal
|
|
162
|
+
|
|
163
|
+
Not user-visible, but this is where the release's weight is: nine new test
|
|
164
|
+
files, 1,770 tests against 1,206 at 0.5.0, 100% line coverage, and the analyser
|
|
165
|
+
verified byte-identical to the published 0.5.0 across 6,976 files of real code.
|
|
166
|
+
Thirty-five negative controls confirm the suite goes red for each defect above,
|
|
167
|
+
and `scripts/mutation-equivalence.mjs` is in the repository so the equivalence
|
|
168
|
+
measurement stays reproducible.
|
|
169
|
+
|
|
8
170
|
## 0.5.0
|
|
9
171
|
|
|
10
172
|
Import assertions covered one language, so a dependency rule pointed at a
|
package/README.md
CHANGED
|
@@ -344,6 +344,84 @@ assertion fails rather than passing on an empty analysis.
|
|
|
344
344
|
[ADR-0005](docs/adr/0005-import-assertions.md) has the measurements and the
|
|
345
345
|
reasoning behind each boundary.
|
|
346
346
|
|
|
347
|
+
### `@assert-layers` - dependencies point one way
|
|
348
|
+
|
|
349
|
+
"Domain must not depend on infrastructure" across three layers is three
|
|
350
|
+
import rules, and across five it is ten - a triangle nobody writes down, and
|
|
351
|
+
the row somebody forgets when a layer is added. One directive states the order:
|
|
352
|
+
|
|
353
|
+
```md
|
|
354
|
+
<!-- @assert-layers target="src" order="src/domain, src/application, src/infrastructure" -->
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**Order runs from the layer everything may depend on to the layer that may
|
|
358
|
+
depend on everything.** A file may import from its own layer and from any layer
|
|
359
|
+
listed before it; importing from a layer listed after it is a violation, and
|
|
360
|
+
the report says which way it went:
|
|
361
|
+
|
|
362
|
+
```text
|
|
363
|
+
✖ docs/architecture.md:12 @assert-layers
|
|
364
|
+
src must keep its layers in order, src/domain < src/application < src/infrastructure
|
|
365
|
+
expected no violating files, found 1
|
|
366
|
+
src/domain/user.ts:3:1 src/domain -> src/infrastructure: import ../infrastructure/db.js
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
A layer is a pattern in the same language as `module=` and `exclude`, which is
|
|
370
|
+
why this works in all five languages above: `src/domain` is anchored at the
|
|
371
|
+
root, and a bare `domain` matches that segment anywhere - in `src/domain/user.ts`,
|
|
372
|
+
in Python's `app.domain.user`, in Rust's `crate::domain::user`. A layer may also
|
|
373
|
+
be a single file; `order="src/parser.ts, src/cli.ts"` understands that
|
|
374
|
+
`./parser.js` is `src/parser.ts`.
|
|
375
|
+
|
|
376
|
+
The unit is files, and `max`, `types`, `exclude` and `baseline` mean what they
|
|
377
|
+
mean on `@assert-import-absence`. Three things fail rather than pass, because
|
|
378
|
+
each is a rule that would otherwise check less than it says: a layer that
|
|
379
|
+
matches no file (`order="domain, aplication"`), a file two layers both claim,
|
|
380
|
+
and a target that does not exist. Files that no layer claims are left alone and
|
|
381
|
+
counted, so a directory nobody assigned shows up as a number rather than as
|
|
382
|
+
silence.
|
|
383
|
+
|
|
384
|
+
### `@assert-import-cycle` - no file depends on itself
|
|
385
|
+
|
|
386
|
+
```md
|
|
387
|
+
<!-- @assert-import-cycle target="src" types="ignore" -->
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
A cycle is reported as one concrete loop, with the line of every import on it:
|
|
391
|
+
|
|
392
|
+
```text
|
|
393
|
+
✖ docs/architecture.md:20 @assert-import-cycle
|
|
394
|
+
src must have no import cycles (type-only imports ignored)
|
|
395
|
+
expected no import cycles, found 1
|
|
396
|
+
src/orders/cart.ts:4:1 src/orders/cart.ts:4 -> src/billing/invoice.ts:2 -> src/orders/cart.ts
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
The count is **knots, not loops**: a set of files each reachable from the others
|
|
400
|
+
counts once however many routes run around it, so adding an import inside a
|
|
401
|
+
tangle that already exists does not move the number. `max="2"` adopts the rule
|
|
402
|
+
on a codebase that already has two, and fails on the third.
|
|
403
|
+
|
|
404
|
+
`types="ignore"` asks the runtime question - erased imports create no load-order
|
|
405
|
+
cycle - and the default asks the coupling one. This repository needs both: its
|
|
406
|
+
`src/` has exactly one cycle, and it is type-only.
|
|
407
|
+
|
|
408
|
+
**Cycles are JavaScript and TypeScript only**, because a cycle needs to know that
|
|
409
|
+
`./b.js` *is* `src/b.ts`, and in the other four languages an import names a
|
|
410
|
+
module, package or namespace rather than a file. A scope with no JavaScript or
|
|
411
|
+
TypeScript in it fails instead of reporting no cycles. The resolver is a short,
|
|
412
|
+
fixed table - the TypeScript source of an emitted `.js`, the path as written,
|
|
413
|
+
the path with each extension, the directory's `index` - checked against files
|
|
414
|
+
the walk already found, never against the disk.
|
|
415
|
+
|
|
416
|
+
It says what it could not follow. An import that should have become an edge and
|
|
417
|
+
did not - a relative path matching no file, or an alias like `@/db` or
|
|
418
|
+
`#internal/db` that cannot be a package - is reported, and fails the run under
|
|
419
|
+
`--strict`. An alias spelled like a real package, `@app/db` through `tsconfig`
|
|
420
|
+
paths, is the one thing it cannot see and cannot report: that would mean
|
|
421
|
+
reading `tsconfig.json`, which is the resolver
|
|
422
|
+
[ADR-0011](docs/adr/0011-layers-and-cycles.md) declines to become, for the
|
|
423
|
+
reasons it gives.
|
|
424
|
+
|
|
347
425
|
### `@assert-present` - this file exists
|
|
348
426
|
|
|
349
427
|
```md
|
|
@@ -368,11 +446,12 @@ Passes when every listed path exists relative to `--root`. Directories count.
|
|
|
368
446
|
| `word` | absence, count | Require word boundaries, so `Primary` does not match `PrimaryButton` |
|
|
369
447
|
| `ignore-case` | absence, count | Case-insensitive matching |
|
|
370
448
|
| `comments` | absence, count | `ignore` (default) or `include` for matches inside comments |
|
|
371
|
-
| `module` | import
|
|
372
|
-
| `
|
|
373
|
-
| `
|
|
374
|
-
| `
|
|
375
|
-
| `
|
|
449
|
+
| `module` | import-absence, import-count | Which dependency, matched like `exclude` |
|
|
450
|
+
| `order` | layers | The layers, from the one everything may depend on to the one that may depend on everything |
|
|
451
|
+
| `types` | import assertions, layers, cycles | `include` (default) or `ignore` for `import type` |
|
|
452
|
+
| `allow-empty` | absence, count, import assertions, layers, cycles | Tolerate a scope that holds no files, or a layer that matches none. Off by default - see below |
|
|
453
|
+
| `baseline` | absence, import-absence, layers | Known violations that do not count: `path` or `path:count` |
|
|
454
|
+
| `ratchet` | absence, import-absence, layers | `two-sided` (default) or `one-way` - see below |
|
|
376
455
|
| `reason` | all | Human-readable justification, printed on failure |
|
|
377
456
|
|
|
378
457
|
Unknown attributes are an error, not a shrug: `expct="1"` fails the run instead
|
|
@@ -441,6 +520,61 @@ paste in. It prints; it does not edit. [ADR-0009](docs/adr/0009-debt-baselines.m
|
|
|
441
520
|
explains why that distinction is the whole design, and why there is no `--fix`
|
|
442
521
|
for architecture rules.
|
|
443
522
|
|
|
523
|
+
## Document status - drafts and superseded ADRs
|
|
524
|
+
|
|
525
|
+
An ADR has a life. It is `Proposed` before anyone agrees to it, and `Superseded`
|
|
526
|
+
long before anyone deletes it - because deleting it deletes the reason a
|
|
527
|
+
decision was made.
|
|
528
|
+
|
|
529
|
+
spec-guard reads that status from the document and honours it. A document whose
|
|
530
|
+
status is `draft`, `proposed`, `rejected`, `deprecated` or `superseded` is
|
|
531
|
+
parsed, validated, reported - and not executed.
|
|
532
|
+
|
|
533
|
+
Three spellings are recognised, because three are in use:
|
|
534
|
+
|
|
535
|
+
<!-- Shown fenced on purpose: spec-guard masks code before reading a status. -->
|
|
536
|
+
|
|
537
|
+
```md
|
|
538
|
+
---
|
|
539
|
+
status: proposed
|
|
540
|
+
---
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
```md
|
|
544
|
+
## Status
|
|
545
|
+
|
|
546
|
+
Accepted (0.3.0).
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
```md
|
|
550
|
+
**Status:** accepted
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
Front-matter wins, then the `## Status` section, then the bold label (which is
|
|
554
|
+
only read above the first `##`). Anything else - `Provisional`, `In review`, a
|
|
555
|
+
misspelled `Supersedded`, or no status at all - keeps enforcing. That asymmetry
|
|
556
|
+
is deliberate: an unanticipated word that keeps enforcing is a visible failure
|
|
557
|
+
with an obvious fix, while one that stops enforcing is a green build over a rule
|
|
558
|
+
nobody is checking.
|
|
559
|
+
|
|
560
|
+
Withholding is never quiet:
|
|
561
|
+
|
|
562
|
+
```text
|
|
563
|
+
○ docs/adr/0011-queues.md is Proposed. - 2 assertions not executed
|
|
564
|
+
|
|
565
|
+
12 passed · 2 not in force · 48ms
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
By name, not by count - the same fact reaches `--format json` as `inactiveSpecs`
|
|
569
|
+
and `--format sarif` as a note-level execution notification. A withheld
|
|
570
|
+
directive is still checked for typos and bad attributes, so a draft's mistake is
|
|
571
|
+
found on the day it is written rather than on the day it is accepted.
|
|
572
|
+
`--ignore-status` runs everything, which is how you ask whether a draft would
|
|
573
|
+
pass if you accepted it today.
|
|
574
|
+
|
|
575
|
+
[ADR-0010](docs/adr/0010-spec-status.md) has the full reasoning, including why
|
|
576
|
+
there is no per-directive `if-status` attribute.
|
|
577
|
+
|
|
444
578
|
## CLI
|
|
445
579
|
|
|
446
580
|
```bash
|
|
@@ -460,6 +594,7 @@ spec-guard [patterns...] [options]
|
|
|
460
594
|
| `--allow-empty-scope` | Warn instead of failing when an assertion inspects no files |
|
|
461
595
|
| `--print-baseline` | Print the `baseline="..."` that would exempt today's violations, and exit |
|
|
462
596
|
| `--no-default-skips` | Search `.git`, `.hg`, `.svn` and `node_modules` too |
|
|
597
|
+
| `--ignore-status` | Execute directives in draft, proposed and superseded documents too |
|
|
463
598
|
| `--include-specs` | Also count matches inside the spec files themselves |
|
|
464
599
|
| `--max-snippets <n>` | Failure snippets per assertion (default 5) |
|
|
465
600
|
| `--concurrency <n>` | Search passes in flight at once (default 8) |
|
|
@@ -611,6 +746,23 @@ session - falls on both equally:
|
|
|
611
746
|
also returned identical counts for all five assertions, which is the more
|
|
612
747
|
useful half of the result.
|
|
613
748
|
|
|
749
|
+
0.5.1 replaced three hand-maintained "are these the same question" field lists
|
|
750
|
+
with one, and the surviving version serialises the exclude set where the old one
|
|
751
|
+
compared it by identity - a hot path made slower on purpose, so it was measured
|
|
752
|
+
rather than assumed. Same tree, same alternating rounds:
|
|
753
|
+
|
|
754
|
+
| | median | min |
|
|
755
|
+
| --- | --- | --- |
|
|
756
|
+
| 0.5.0 | 925.1 ms | 432.1 ms |
|
|
757
|
+
| 0.5.1 | 830.6 ms | 428.5 ms |
|
|
758
|
+
|
|
759
|
+
The medians are 10% apart and the minima are level, which is this machine's
|
|
760
|
+
noise band doing most of the talking - the honest reading is "no regression",
|
|
761
|
+
not "10% faster". The plausible mechanism for any real gain is that the runner
|
|
762
|
+
now groups by the engine's own definition of a shared pass, so a group of five
|
|
763
|
+
where two requests disagree is run as three and two rather than being refused
|
|
764
|
+
whole and run as five. Counts identical across all five assertions, again.
|
|
765
|
+
|
|
614
766
|
Two honest caveats:
|
|
615
767
|
|
|
616
768
|
- **The reported engine is the one that ran, not the one available.** On a small
|
|
@@ -668,6 +820,12 @@ numbers stay exact. (This is subtle: pairing backtick runs the naive way
|
|
|
668
820
|
desynchronises after a stray unmatched run and un-masks real prose. spec-guard
|
|
669
821
|
uses CommonMark's equal-length pairing rule, and there is a regression test.)
|
|
670
822
|
|
|
823
|
+
**A document's lifecycle status is read; a directive's is not.** Status is
|
|
824
|
+
document-level and visible in every rendered Markdown view. A per-directive
|
|
825
|
+
`if-status` attribute would be a switch disabling one assertion inside an
|
|
826
|
+
accepted ADR, invisible to anyone who does not read the raw source - and the
|
|
827
|
+
one thing a mechanism for not running an assertion must never be is invisible.
|
|
828
|
+
|
|
671
829
|
**Malformed directives fail the run.** A typo like `expct="1"` could be ignored
|
|
672
830
|
as "not a directive". It is instead an error, because a spec tool whose typos
|
|
673
831
|
silently assert nothing is worse than no spec tool.
|
|
@@ -773,8 +931,11 @@ prebuilt binary and is never a runtime dependency.
|
|
|
773
931
|
### Mutation testing
|
|
774
932
|
|
|
775
933
|
Coverage says a line ran. It does not say an assertion would notice if the line
|
|
776
|
-
behaved differently. This repository measures the difference:
|
|
777
|
-
4,
|
|
934
|
+
behaved differently. This repository measures the difference: line coverage is
|
|
935
|
+
**100%**, and **97.65%** of 4,299 mutants are killed in CI, with no file below
|
|
936
|
+
95%. The second number is the one worth reading - and it is the ceiling, not a
|
|
937
|
+
way-point: every surviving mutant has been checked individually and the 101 that
|
|
938
|
+
are left produce byte-identical output.
|
|
778
939
|
|
|
779
940
|
That gap is the point. The first run scored 77.23%, and the weakest file was the
|
|
780
941
|
reporter at 65.48% - not because it lacked tests, but because its tests were
|
|
@@ -784,7 +945,30 @@ test still passed. Exact whole-output comparison took it to 87.30%. The engine
|
|
|
784
945
|
and the walker were then rewritten for testability rather than papered over with
|
|
785
946
|
more tests, which is what moved them from 75%/78% to 83%/93%.
|
|
786
947
|
|
|
787
|
-
|
|
948
|
+
The most recent pass took every module to its ceiling, and its value was not the
|
|
949
|
+
number. Writing down four contracts that had only ever been checked through
|
|
950
|
+
their effect on a match count turned up four wrong answers: two assertions on
|
|
951
|
+
one symbol answered each other's comment handling, an unreadable directory went
|
|
952
|
+
unreported on any repository small enough to scan in process, snippets from CRLF
|
|
953
|
+
files carried a carriage return into the terminal, and an invalid pattern was
|
|
954
|
+
reported with its error message twice. Seventeen branches turned out to be
|
|
955
|
+
unable to decide anything and were deleted rather than pinned; thirty-five
|
|
956
|
+
negative controls - each defect reintroduced one at a time - confirm the suite
|
|
957
|
+
goes red for every one, and the changes meant to be invisible were checked
|
|
958
|
+
against 6,976 files of real code, reference for reference, against the published
|
|
959
|
+
0.5.0 build.
|
|
960
|
+
|
|
961
|
+
Then the survivors themselves were checked rather than excused. All 130 were
|
|
962
|
+
applied one at a time and run through a fingerprint of 4,176 observations, and
|
|
963
|
+
**29 of them turned out not to be equivalent at all** - a Rust brace counter
|
|
964
|
+
that only matters when a second statement follows, a type-only test that marks
|
|
965
|
+
`import A, { B } from 'x'` type-only when loosened, a comment check that opens a
|
|
966
|
+
block comment on `2*3`. All 29 are now tested and all 29 die. All of it is in
|
|
967
|
+
[ADR-0003](docs/adr/0003-mutation-testing.md), including a Stryker limitation
|
|
968
|
+
found on the way: a mutant that stops a test file *loading* is reported as
|
|
969
|
+
survived even though the suite is in fact killing it.
|
|
970
|
+
|
|
971
|
+
CI runs it in **two tiers**, both gated at 97%. Branches and pull requests run
|
|
788
972
|
Stryker incrementally, reusing the verdict for any mutant whose source and
|
|
789
973
|
covering tests are both unchanged. Pushes to `main`, the weekly schedule and
|
|
790
974
|
manual runs do the full sweep, which is the authoritative number and the one
|
|
@@ -792,25 +976,28 @@ quoted above; a full sweep is also what publishes the cache the branches start
|
|
|
792
976
|
from, so an incremental verdict can never be built on another incremental
|
|
793
977
|
verdict.
|
|
794
978
|
|
|
795
|
-
The full sweep was 6m54s at 2,118 mutants, 15m51s at 3,493, and is
|
|
796
|
-
4,
|
|
979
|
+
The full sweep was 6m54s at 2,118 mutants, 15m51s at 3,493, and is 17m at
|
|
980
|
+
4,299. That growth is why the tiers exist: a check that gets quietly more
|
|
797
981
|
expensive every release is a check somebody eventually proposes lowering.
|
|
798
982
|
|
|
799
983
|
Run it locally with `npm run test:mutation` if you like, but do not calibrate
|
|
800
984
|
anything on the result: on the Windows machine this was developed on the same
|
|
801
|
-
suite takes over two hours against
|
|
985
|
+
suite takes over two hours against 21 minutes hosted, and it scores *higher*,
|
|
802
986
|
because far more mutants hang there and Stryker counts a hang as a kill. Linux
|
|
803
987
|
CI is the measurement.
|
|
804
988
|
|
|
805
|
-
|
|
989
|
+
Eight cautionary tales are in [ADR-0003](docs/adr/0003-mutation-testing.md): a
|
|
806
990
|
run whose score was pure fiction because the mutants were never activated, a
|
|
807
991
|
tuning knob that lifted the score six points without adding a test, the platform
|
|
808
992
|
gap above, the baseline being re-anchored when a tokenizer arrived, and a score
|
|
809
993
|
that rose partly because code carrying hard-to-kill mutants was deleted rather
|
|
810
994
|
than because tests improved, and the 0.5.0 sweep that failed the build at 83.77%
|
|
811
995
|
because a suite can be thorough about the thing it was written to test and
|
|
812
|
-
silent about the machinery underneath it
|
|
813
|
-
|
|
996
|
+
silent about the machinery underneath it, and the excuse that let the tokenizer
|
|
997
|
+
sit at 73% for three releases because "that kind of code carries more equivalent
|
|
998
|
+
mutants" sounded like judgement rather than an unchecked assumption - along with
|
|
999
|
+
the real bugs that chasing the gate uncovered, and a class of mutant the runner
|
|
1000
|
+
reports as survived while the suite is in fact killing it.
|
|
814
1001
|
|
|
815
1002
|
## Requirements
|
|
816
1003
|
|
package/dist/cli.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export interface CliOptions {
|
|
|
30
30
|
engine: EnginePreference;
|
|
31
31
|
allowMissingTargets: boolean;
|
|
32
32
|
defaultSkips: boolean;
|
|
33
|
+
ignoreStatus: boolean;
|
|
33
34
|
strictTargets: boolean;
|
|
34
35
|
allowEmptyScope: boolean;
|
|
35
36
|
printBaseline: boolean;
|
|
@@ -44,7 +45,7 @@ export interface CliOptions {
|
|
|
44
45
|
export declare class UsageError extends Error {
|
|
45
46
|
}
|
|
46
47
|
export declare function version(): string;
|
|
47
|
-
export declare const HELP = "spec-guard - Executable architecture assertions for Markdown specs & ADRs\n\nUsage\n spec-guard [patterns...] [options]\n\nPatterns\n Globs or paths to the Markdown specs to execute. A directory expands to the\n Markdown files inside it. Defaults to \"docs/**/*.md\" when omitted.\n\nOptions\n -r, --root <path> Codebase root that assertions are resolved against (default: cwd)\n -v, --verbose Print passing assertions too\n --fail-fast Stop at the first failing assertion\n --json Emit a machine-readable JSON report (same as --format json)\n --format <name> human | json | sarif (sarif uploads to GitHub code scanning)\n --engine <name> auto | rg | js (default: auto - scanner for small trees, ripgrep for big ones)\n --strict Treat analysis that could not be completed as a failure\n --allow-missing-targets\n Tolerate target paths that do not exist (they fail by default)\n --allow-empty-scope Tolerate assertions whose scope holds no files (they fail by default)\n --print-baseline Print the baseline=\"...\" that would exempt today's violations, and exit\n --no-default-skips Search .git, .hg, .svn and node_modules too\n --include-specs Also count matches inside the spec files themselves\n --max-snippets <n> Failure snippets per assertion (default: 5)\n --concurrency <n> Assertions executed in parallel (default: 8)\n --allow-empty Exit 0 when no spec files matched (about the run, not an assertion)\n --color/--no-color Force colour on or off (NO_COLOR is honoured)\n -h, --help Show this help\n --version Print the version\n\nDirectives\n <!-- @assert-absence target=\"src/\" symbol=\"LegacyGateway\" exclude=\"src/legacy/**\" -->\n <!-- @assert-count target=\"src/\" symbol=\"SessionManager\" expected=\"1\" -->\n <!-- @assert-present file=\"SECURITY.md\" -->\n\n Matches inside comments do not count; add comments=\"include\" to count them.\n An assertion whose scope holds no files fails; add allow-empty=\"true\" to allow it.\n\nExit codes\n 0 all assertions passed 1 an assertion failed 2 spec-guard could not run";
|
|
48
|
+
export declare const HELP = "spec-guard - Executable architecture assertions for Markdown specs & ADRs\n\nUsage\n spec-guard [patterns...] [options]\n\nPatterns\n Globs or paths to the Markdown specs to execute. A directory expands to the\n Markdown files inside it. Defaults to \"docs/**/*.md\" when omitted.\n\nOptions\n -r, --root <path> Codebase root that assertions are resolved against (default: cwd)\n -v, --verbose Print passing assertions too\n --fail-fast Stop at the first failing assertion\n --json Emit a machine-readable JSON report (same as --format json)\n --format <name> human | json | sarif (sarif uploads to GitHub code scanning)\n --engine <name> auto | rg | js (default: auto - scanner for small trees, ripgrep for big ones)\n --strict Treat analysis that could not be completed as a failure\n --allow-missing-targets\n Tolerate target paths that do not exist (they fail by default)\n --allow-empty-scope Tolerate assertions whose scope holds no files (they fail by default)\n --print-baseline Print the baseline=\"...\" that would exempt today's violations, and exit\n --no-default-skips Search .git, .hg, .svn and node_modules too\n --ignore-status Execute directives in draft, proposed and superseded documents too\n --include-specs Also count matches inside the spec files themselves\n --max-snippets <n> Failure snippets per assertion (default: 5)\n --concurrency <n> Assertions executed in parallel (default: 8)\n --allow-empty Exit 0 when no spec files matched (about the run, not an assertion)\n --color/--no-color Force colour on or off (NO_COLOR is honoured)\n -h, --help Show this help\n --version Print the version\n\nDirectives\n <!-- @assert-absence target=\"src/\" symbol=\"LegacyGateway\" exclude=\"src/legacy/**\" -->\n <!-- @assert-count target=\"src/\" symbol=\"SessionManager\" expected=\"1\" -->\n <!-- @assert-present file=\"SECURITY.md\" -->\n <!-- @assert-import-cycle target=\"src/\" types=\"ignore\" -->\n <!-- @assert-layers target=\"src/\" order=\"domain, application, infrastructure\" -->\n\n Matches inside comments do not count; add comments=\"include\" to count them.\n An assertion whose scope holds no files fails; add allow-empty=\"true\" to allow it.\n A document whose status is draft, proposed, rejected, deprecated or superseded\n is reported and not executed; --ignore-status runs it anyway.\n\nExit codes\n 0 all assertions passed 1 an assertion failed 2 spec-guard could not run";
|
|
48
49
|
/** Minimal, dependency-free argv parser. Supports `--flag value` and `--flag=value`. */
|
|
49
50
|
export declare function parseArgs(argv: readonly string[], cwd: string): CliOptions;
|
|
50
51
|
/** Runs the CLI and resolves to the process exit code. */
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,eAAO,MAAM,OAAO,IAAI,CAAC;AACzB,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB,4EAA4E;IAC5E,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,gBAAgB,CAAC;IACzB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,UAAW,SAAQ,KAAK;CAAG;AAExC,wBAAgB,OAAO,IAAI,MAAM,CAShC;AAED,eAAO,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,eAAO,MAAM,OAAO,IAAI,CAAC;AACzB,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAEtD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB,4EAA4E;IAC5E,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,gBAAgB,CAAC;IACzB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,UAAW,SAAQ,KAAK;CAAG;AAExC,wBAAgB,OAAO,IAAI,MAAM,CAShC;AAED,eAAO,MAAM,IAAI,wlFA4C8D,CAAC;AAgChF,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAkI1E;AAYD,0DAA0D;AAC1D,wBAAsB,IAAI,CAAC,IAAI,GAAE,SAAS,MAAM,EAA0B,EAAE,EAAE,GAAE,KAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4EpH"}
|
package/dist/cli.js
CHANGED
|
@@ -48,6 +48,7 @@ Options
|
|
|
48
48
|
--allow-empty-scope Tolerate assertions whose scope holds no files (they fail by default)
|
|
49
49
|
--print-baseline Print the baseline="..." that would exempt today's violations, and exit
|
|
50
50
|
--no-default-skips Search .git, .hg, .svn and node_modules too
|
|
51
|
+
--ignore-status Execute directives in draft, proposed and superseded documents too
|
|
51
52
|
--include-specs Also count matches inside the spec files themselves
|
|
52
53
|
--max-snippets <n> Failure snippets per assertion (default: ${DEFAULT_MAX_SNIPPETS})
|
|
53
54
|
--concurrency <n> Assertions executed in parallel (default: ${DEFAULT_CONCURRENCY})
|
|
@@ -60,9 +61,13 @@ Directives
|
|
|
60
61
|
<!-- @assert-absence target="src/" symbol="LegacyGateway" exclude="src/legacy/**" -->
|
|
61
62
|
<!-- @assert-count target="src/" symbol="SessionManager" expected="1" -->
|
|
62
63
|
<!-- @assert-present file="SECURITY.md" -->
|
|
64
|
+
<!-- @assert-import-cycle target="src/" types="ignore" -->
|
|
65
|
+
<!-- @assert-layers target="src/" order="domain, application, infrastructure" -->
|
|
63
66
|
|
|
64
67
|
Matches inside comments do not count; add comments="include" to count them.
|
|
65
68
|
An assertion whose scope holds no files fails; add allow-empty="true" to allow it.
|
|
69
|
+
A document whose status is draft, proposed, rejected, deprecated or superseded
|
|
70
|
+
is reported and not executed; --ignore-status runs it anyway.
|
|
66
71
|
|
|
67
72
|
Exit codes
|
|
68
73
|
0 all assertions passed 1 an assertion failed 2 spec-guard could not run`;
|
|
@@ -106,6 +111,7 @@ export function parseArgs(argv, cwd) {
|
|
|
106
111
|
engine: 'auto',
|
|
107
112
|
allowMissingTargets: false,
|
|
108
113
|
defaultSkips: true,
|
|
114
|
+
ignoreStatus: false,
|
|
109
115
|
strictTargets: false,
|
|
110
116
|
allowEmptyScope: false,
|
|
111
117
|
printBaseline: false,
|
|
@@ -179,6 +185,9 @@ export function parseArgs(argv, cwd) {
|
|
|
179
185
|
case '--no-default-skips':
|
|
180
186
|
options.defaultSkips = false;
|
|
181
187
|
break;
|
|
188
|
+
case '--ignore-status':
|
|
189
|
+
options.ignoreStatus = true;
|
|
190
|
+
break;
|
|
182
191
|
case '--include-specs':
|
|
183
192
|
options.includeSpecs = true;
|
|
184
193
|
break;
|
|
@@ -257,6 +266,7 @@ export async function main(argv = process.argv.slice(2), io = defaultIO()) {
|
|
|
257
266
|
allowMissingTargets: options.allowMissingTargets,
|
|
258
267
|
allowEmptyScope: options.allowEmptyScope,
|
|
259
268
|
defaultSkips: options.defaultSkips,
|
|
269
|
+
ignoreStatus: options.ignoreStatus,
|
|
260
270
|
strictTargets: options.strictTargets,
|
|
261
271
|
includeSpecs: options.includeSpecs,
|
|
262
272
|
concurrency: options.concurrency,
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACvH,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGtF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AACzB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAC7B,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/comments.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../src/comments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,0CAA0C;IAC1C,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,uCAAuC;IACvC,MAAM,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;CAChC;
|
|
1
|
+
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../src/comments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,0CAA0C;IAC1C,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,uCAAuC;IACvC,MAAM,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;CAChC;AA6ID,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAEhE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAE9D;AAED,4DAA4D;AAC5D,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AA2CrD,oFAAoF;AACpF,MAAM,WAAW,SAAS;IACxB,4DAA4D;IAC5D,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,gEAAgE;IAChE,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB;;;;;;;OAOG;IACH,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,SAAS,CA2C1E;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,YAAY,EAAE,CAEnF;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CACpC;AAQD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAqB/E"}
|