@systemfsoftware/stryker-js-cli 1.2.5 → 3.0.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 +191 -0
- package/package.json +15 -15
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# @systemfsoftware/stryker-js-cli
|
|
2
|
+
|
|
3
|
+
## 3.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- Pass capabilities as arguments instead of requiring them through a projection tag, in these two packages
|
|
8
|
+
|
|
9
|
+
Wlaschin's second approach — dependency parameterization — is preferred over the
|
|
10
|
+
Reader, and it removes the requirement from the signature entirely rather than
|
|
11
|
+
relocating it. Each operation in `effect-daemon-spec` and `stryker-js-cli` that
|
|
12
|
+
previously reached into the context for a projection now receives what it uses,
|
|
13
|
+
and the composition root is the single place that acquires the port.
|
|
14
|
+
|
|
15
|
+
The remaining `*ExecutorDeps` projections live in `omp/**/src/internal/`, fenced
|
|
16
|
+
behind each package's own `exports` map, so they are unreachable from any consumer;
|
|
17
|
+
the exported-wiring gate scans `src/` outside `src/internal/`, so internal composition
|
|
18
|
+
stays internal and is not a migration target here.
|
|
19
|
+
|
|
20
|
+
- `effect-daemon-spec` — `withLeaderLock` takes `lock: LeaderLock['Type']`, and the
|
|
21
|
+
supervisor body takes `reporter: DaemonReporter['Type']`. Every `yield* LeaderLock`
|
|
22
|
+
and `yield* DaemonReporter` now lands in `mod.ts`; the exported `worker` and
|
|
23
|
+
`supervisor` shapes are unchanged, and `withLeaderLock` loses `LeaderLock` from `R`.
|
|
24
|
+
- `stryker-js-cli` — `StrykerCliExecutorDeps` and its service interface are gone.
|
|
25
|
+
`runStrykerCli` and the handler take `detectMode` and `createRunEventStream`, typed
|
|
26
|
+
as indexed accesses off the two port services, and both lose the requirement from
|
|
27
|
+
`R`. `main.ts` acquires both ports and passes the members down.
|
|
28
|
+
|
|
29
|
+
For these two packages, a caller that provided the projection layer now provides
|
|
30
|
+
nothing, because the operation no longer requires anything.
|
|
31
|
+
|
|
32
|
+
- `AdmitSurvivorsRunInput` moved to `survivors.kernel.js` — import it from there. `SurvivorsAdmissionTypeId`, `SurvivorsRejectReason`, `Admitted`, `NoSurvivors`, `SurvivorsAdmission`, `SurvivorsRejection` and `admitSurvivorsRun` are unchanged.
|
|
33
|
+
|
|
34
|
+
The admission's guard chain moved into `admissionVerdict`, a kernel classifier returning `reject` / `no-survivors` / `admit`; the workflow assigns channels to those three. All 69 existing tests pass unchanged, including the six that pin each rejection's remediation prose.
|
|
35
|
+
|
|
36
|
+
Two measured findings shaped it. `Match.when({ kind: 'admit' }, …)` left a surviving mutant: `ObjectLiteral` widens the pattern to `{}`, which by elimination the last arm before `Match.exhaustive` only ever reaches with `admit` values, so the mutant is equivalent and unkillable — score 95.83 against a 100 break threshold. The workflow uses `Match.discriminator`, whose tag is a _string_ argument with no object literal to widen; the gate is back to 100 with zero survivors.
|
|
37
|
+
|
|
38
|
+
Second, the relocation moved decisions out of the mutation surface — `mutate` is `src/survivors.workflow.ts` — dropping the mutant population from 47 to 24. Exactly one new law compensates: `∀r_SurvivorsSourced_→MismatchReject`, that provenance pre-empts emptiness (KTD7). Five further laws were written and deleted after measuring that the existing suite already fails on each of their defects; hoisting the emptiness check above the provenance check is the one defect that leaves the whole pre-existing suite green.
|
|
39
|
+
|
|
40
|
+
### Minor Changes
|
|
41
|
+
|
|
42
|
+
- cut over to effect v4 (4.0.0-rc.108): public surface derives from effect types; peers flip effect ^3→^4
|
|
43
|
+
|
|
44
|
+
- The Workflow brand: `make` is the only door to a decide slot.
|
|
45
|
+
|
|
46
|
+
`Workflow<C, D, E>` and `Cell.DecidePhase<P>` carry a phantom `WorkflowBrand` conjunct applied
|
|
47
|
+
solely by `Workflow.make` through the existing assertion narrowing — no runtime property, `make`
|
|
48
|
+
stays the identity it always was. The consumer's signature is the forcing function: a bare
|
|
49
|
+
function handed where a decide run is demanded is now a compile error naming the brand, so a
|
|
50
|
+
decision cannot reach production without passing through the constructor every gate keys on.
|
|
51
|
+
|
|
52
|
+
Breaking by design (`REPO-R1`): the two inline adapter sites (cli's admission adapter,
|
|
53
|
+
claude-compat's submit-hook adapter) become `make`-wrapped, and the cell-gen either-pass
|
|
54
|
+
fixture reshapes to one exhaustive path with the failure injection decided before the boundary.
|
|
55
|
+
|
|
56
|
+
### Patch Changes
|
|
57
|
+
|
|
58
|
+
- Array types are spelled one way. `Array<T>` and `ReadonlyArray<T>` in emitted
|
|
59
|
+
declarations become `T[]` and `readonly T[]`, which the type checker cannot tell
|
|
60
|
+
apart: no exported type changes, only how it is written.
|
|
61
|
+
|
|
62
|
+
- Repair the CLI the effect v4 cutover left unable to run
|
|
63
|
+
|
|
64
|
+
The parser's Stdio layer was the test layer, whose sinks drain to nowhere, so help and version documents never rendered; the entrypoint passed the full process.argv to a parser that takes the arguments after the program name; the run-event stream's close could race the drain fiber's mailbox registration and hang the process forever; and a consumer closing the pipe crashed the whole process on the stream's unhandled error event. The stream now drains through the platform's Stdio sink, which owns backpressure, the scoped error listener, and the final flush, and every invocation — version, help, the agent manifest, a full run with its reader gone — completes with its classed exit code
|
|
65
|
+
|
|
66
|
+
- New version is published through npm trusted publishing, so it carries a provenance attestation you can verify.
|
|
67
|
+
|
|
68
|
+
- Express each executor's sandwich as a `Cell` description.
|
|
69
|
+
|
|
70
|
+
Every call site that previously sequenced the phases by hand now builds one description and hands it to the interpreter, so the order these executors run in is carried by the phase types instead of by the order the statements happen to appear in. Behaviour is preserved and no public surface moves: the change is confined to `src/internal/*.executor.ts`, and each package's golden API report is unchanged.
|
|
71
|
+
|
|
72
|
+
One site needed a real fix rather than a translation. `supervisor-body.executor.ts` wrote before it could classify — it recorded a restart, then read the resulting rate — which is a read that depends on an earlier decision. Its read now gathers the restart record and the resulting rate as one product, which keeps that site a single layer, with the intensity tracker passed as the read's command rather than captured from the surrounding scope.
|
|
73
|
+
|
|
74
|
+
- Build the `bin` target during install. Both CLIs point `bin` at gitignored build output, which pnpm's two bin-link passes skip when it is absent, leaving a fresh clone without the command and never retrying. A `prepare` script now builds the target between the passes; `arethetypeswrong-cli` drops its committed `bin/attw.mjs` launcher in favour of the same pattern.
|
|
75
|
+
|
|
76
|
+
- Produce every workflow through `Workflow.make`.
|
|
77
|
+
|
|
78
|
+
`decideRestart`, `interpretHookResult`, and `admitSurvivorsRun` are now built by the constructor rather
|
|
79
|
+
than annotated with `Workflow<Command, Decision, Error>`. Each decision is behaviourally identical —
|
|
80
|
+
`make` is the identity at runtime — but the channels are now inferred from the decider instead of
|
|
81
|
+
asserted by hand, so a total decision resolves to `UninhabitedError` and becomes uncallable rather than
|
|
82
|
+
compiling as a workflow that cannot fail.
|
|
83
|
+
|
|
84
|
+
`effect-daemon-spec` takes a minor bump because the change is consumer-visible beyond its own source:
|
|
85
|
+
`@systemfsoftware/effect-cell-types` moves from `devDependencies` to `dependencies`, so installing this
|
|
86
|
+
package now installs it. That reclassification is required, not incidental — `make` is a runtime call,
|
|
87
|
+
and `scripts/guards/check-runtime-deps.mjs` fails a runtime import declared only as a dev dependency.
|
|
88
|
+
`omp-claude-compat` gains the same dependency; `stryker-js-cli` already declared it.
|
|
89
|
+
|
|
90
|
+
`RestartDecisionWorkflow` survives as a type-only export: one in-repo consumer, its own property test,
|
|
91
|
+
references it through `ReturnType<…>`.
|
|
92
|
+
|
|
93
|
+
- Updated dependencies:
|
|
94
|
+
- @systemfsoftware/effect-cell-types@3.0.0
|
|
95
|
+
- @systemfsoftware/stryker-js-mutation-run@3.0.0
|
|
96
|
+
- @systemfsoftware/stryker-js-plugin-api@2.0.0
|
|
97
|
+
|
|
98
|
+
## 2.0.0
|
|
99
|
+
|
|
100
|
+
### Major Changes
|
|
101
|
+
|
|
102
|
+
- Pass capabilities as arguments instead of requiring them through a projection tag, in these two packages
|
|
103
|
+
|
|
104
|
+
Wlaschin's second approach — dependency parameterization — is preferred over the
|
|
105
|
+
Reader, and it removes the requirement from the signature entirely rather than
|
|
106
|
+
relocating it. Each operation in `effect-daemon-spec` and `stryker-js-cli` that
|
|
107
|
+
previously reached into the context for a projection now receives what it uses,
|
|
108
|
+
and the composition root is the single place that acquires the port.
|
|
109
|
+
|
|
110
|
+
The remaining `*ExecutorDeps` projections live in `omp/**/src/internal/`, fenced
|
|
111
|
+
behind each package's own `exports` map, so they are unreachable from any consumer;
|
|
112
|
+
the exported-wiring gate scans `src/` outside `src/internal/`, so internal composition
|
|
113
|
+
stays internal and is not a migration target here.
|
|
114
|
+
|
|
115
|
+
- `effect-daemon-spec` — `withLeaderLock` takes `lock: LeaderLock['Type']`, and the
|
|
116
|
+
supervisor body takes `reporter: DaemonReporter['Type']`. Every `yield* LeaderLock`
|
|
117
|
+
and `yield* DaemonReporter` now lands in `mod.ts`; the exported `worker` and
|
|
118
|
+
`supervisor` shapes are unchanged, and `withLeaderLock` loses `LeaderLock` from `R`.
|
|
119
|
+
- `stryker-js-cli` — `StrykerCliExecutorDeps` and its service interface are gone.
|
|
120
|
+
`runStrykerCli` and the handler take `detectMode` and `createRunEventStream`, typed
|
|
121
|
+
as indexed accesses off the two port services, and both lose the requirement from
|
|
122
|
+
`R`. `main.ts` acquires both ports and passes the members down.
|
|
123
|
+
|
|
124
|
+
For these two packages, a caller that provided the projection layer now provides
|
|
125
|
+
nothing, because the operation no longer requires anything.
|
|
126
|
+
|
|
127
|
+
- `AdmitSurvivorsRunInput` moved to `survivors.kernel.js` — import it from there. `SurvivorsAdmissionTypeId`, `SurvivorsRejectReason`, `Admitted`, `NoSurvivors`, `SurvivorsAdmission`, `SurvivorsRejection` and `admitSurvivorsRun` are unchanged.
|
|
128
|
+
|
|
129
|
+
The admission's guard chain moved into `admissionVerdict`, a kernel classifier returning `reject` / `no-survivors` / `admit`; the workflow assigns channels to those three. All 69 existing tests pass unchanged, including the six that pin each rejection's remediation prose.
|
|
130
|
+
|
|
131
|
+
Two measured findings shaped it. `Match.when({ kind: 'admit' }, …)` left a surviving mutant: `ObjectLiteral` widens the pattern to `{}`, which by elimination the last arm before `Match.exhaustive` only ever reaches with `admit` values, so the mutant is equivalent and unkillable — score 95.83 against a 100 break threshold. The workflow uses `Match.discriminator`, whose tag is a _string_ argument with no object literal to widen; the gate is back to 100 with zero survivors.
|
|
132
|
+
|
|
133
|
+
Second, the relocation moved decisions out of the mutation surface — `mutate` is `src/survivors.workflow.ts` — dropping the mutant population from 47 to 24. Exactly one new law compensates: `∀r_SurvivorsSourced_→MismatchReject`, that provenance pre-empts emptiness (KTD7). Five further laws were written and deleted after measuring that the existing suite already fails on each of their defects; hoisting the emptiness check above the provenance check is the one defect that leaves the whole pre-existing suite green.
|
|
134
|
+
|
|
135
|
+
### Minor Changes
|
|
136
|
+
|
|
137
|
+
- cut over to effect v4 (4.0.0-rc.108): public surface derives from effect types; peers flip effect ^3→^4
|
|
138
|
+
|
|
139
|
+
- The Workflow brand: `make` is the only door to a decide slot.
|
|
140
|
+
|
|
141
|
+
`Workflow<C, D, E>` and `Cell.DecidePhase<P>` carry a phantom `WorkflowBrand` conjunct applied
|
|
142
|
+
solely by `Workflow.make` through the existing assertion narrowing — no runtime property, `make`
|
|
143
|
+
stays the identity it always was. The consumer's signature is the forcing function: a bare
|
|
144
|
+
function handed where a decide run is demanded is now a compile error naming the brand, so a
|
|
145
|
+
decision cannot reach production without passing through the constructor every gate keys on.
|
|
146
|
+
|
|
147
|
+
Breaking by design (`REPO-R1`): the two inline adapter sites (cli's admission adapter,
|
|
148
|
+
claude-compat's submit-hook adapter) become `make`-wrapped, and the cell-gen either-pass
|
|
149
|
+
fixture reshapes to one exhaustive path with the failure injection decided before the boundary.
|
|
150
|
+
|
|
151
|
+
### Patch Changes
|
|
152
|
+
|
|
153
|
+
- Array types are spelled one way. `Array<T>` and `ReadonlyArray<T>` in emitted
|
|
154
|
+
declarations become `T[]` and `readonly T[]`, which the type checker cannot tell
|
|
155
|
+
apart: no exported type changes, only how it is written.
|
|
156
|
+
|
|
157
|
+
- Repair the CLI the effect v4 cutover left unable to run
|
|
158
|
+
|
|
159
|
+
The parser's Stdio layer was the test layer, whose sinks drain to nowhere, so help and version documents never rendered; the entrypoint passed the full process.argv to a parser that takes the arguments after the program name; the run-event stream's close could race the drain fiber's mailbox registration and hang the process forever; and a consumer closing the pipe crashed the whole process on the stream's unhandled error event. The stream now drains through the platform's Stdio sink, which owns backpressure, the scoped error listener, and the final flush, and every invocation — version, help, the agent manifest, a full run with its reader gone — completes with its classed exit code
|
|
160
|
+
|
|
161
|
+
- New version is published through npm trusted publishing, so it carries a provenance attestation you can verify.
|
|
162
|
+
|
|
163
|
+
- Express each executor's sandwich as a `Cell` description.
|
|
164
|
+
|
|
165
|
+
Every call site that previously sequenced the phases by hand now builds one description and hands it to the interpreter, so the order these executors run in is carried by the phase types instead of by the order the statements happen to appear in. Behaviour is preserved and no public surface moves: the change is confined to `src/internal/*.executor.ts`, and each package's golden API report is unchanged.
|
|
166
|
+
|
|
167
|
+
One site needed a real fix rather than a translation. `supervisor-body.executor.ts` wrote before it could classify — it recorded a restart, then read the resulting rate — which is a read that depends on an earlier decision. Its read now gathers the restart record and the resulting rate as one product, which keeps that site a single layer, with the intensity tracker passed as the read's command rather than captured from the surrounding scope.
|
|
168
|
+
|
|
169
|
+
- Build the `bin` target during install. Both CLIs point `bin` at gitignored build output, which pnpm's two bin-link passes skip when it is absent, leaving a fresh clone without the command and never retrying. A `prepare` script now builds the target between the passes; `arethetypeswrong-cli` drops its committed `bin/attw.mjs` launcher in favour of the same pattern.
|
|
170
|
+
|
|
171
|
+
- Produce every workflow through `Workflow.make`.
|
|
172
|
+
|
|
173
|
+
`decideRestart`, `interpretHookResult`, and `admitSurvivorsRun` are now built by the constructor rather
|
|
174
|
+
than annotated with `Workflow<Command, Decision, Error>`. Each decision is behaviourally identical —
|
|
175
|
+
`make` is the identity at runtime — but the channels are now inferred from the decider instead of
|
|
176
|
+
asserted by hand, so a total decision resolves to `UninhabitedError` and becomes uncallable rather than
|
|
177
|
+
compiling as a workflow that cannot fail.
|
|
178
|
+
|
|
179
|
+
`effect-daemon-spec` takes a minor bump because the change is consumer-visible beyond its own source:
|
|
180
|
+
`@systemfsoftware/effect-cell-types` moves from `devDependencies` to `dependencies`, so installing this
|
|
181
|
+
package now installs it. That reclassification is required, not incidental — `make` is a runtime call,
|
|
182
|
+
and `scripts/guards/check-runtime-deps.mjs` fails a runtime import declared only as a dev dependency.
|
|
183
|
+
`omp-claude-compat` gains the same dependency; `stryker-js-cli` already declared it.
|
|
184
|
+
|
|
185
|
+
`RestartDecisionWorkflow` survives as a type-only export: one in-repo consumer, its own property test,
|
|
186
|
+
references it through `ReturnType<…>`.
|
|
187
|
+
|
|
188
|
+
- Updated dependencies:
|
|
189
|
+
- @systemfsoftware/effect-cell-types@2.0.0
|
|
190
|
+
- @systemfsoftware/stryker-js-mutation-run@2.0.0
|
|
191
|
+
- @systemfsoftware/stryker-js-plugin-api@1.0.0
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@systemfsoftware/stryker-js-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/systemfsoftware/systemfsoftware.git",
|
|
7
|
-
"directory": "packages/stryker-js/cli"
|
|
7
|
+
"directory": "packages/testing/mutation/stryker-js/cli"
|
|
8
8
|
},
|
|
9
|
-
"homepage": "https://github.com/systemfsoftware/systemfsoftware/tree/main/packages/stryker-js/cli#readme",
|
|
9
|
+
"homepage": "https://github.com/systemfsoftware/systemfsoftware/tree/main/packages/testing/mutation/stryker-js/cli#readme",
|
|
10
10
|
"bugs": "https://github.com/systemfsoftware/systemfsoftware/issues",
|
|
11
11
|
"description": "The stryker command-line interface — terminal framing, run-event stream, and exit handling for the @systemfsoftware Stryker fork.",
|
|
12
12
|
"type": "module",
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
"@stryker-mutator/util": "^9.6.1",
|
|
20
20
|
"effect": "4.0.0-rc.108",
|
|
21
21
|
"semver": "^7.7.0",
|
|
22
|
-
"@systemfsoftware/stryker-js-mutation-report": "^1.2.
|
|
23
|
-
"@systemfsoftware/effect-cell-types": "^
|
|
24
|
-
"@systemfsoftware/stryker-js-mutation-run": "^
|
|
25
|
-
"@systemfsoftware/stryker-js-plugin-api": "^0.
|
|
22
|
+
"@systemfsoftware/stryker-js-mutation-report": "^1.2.7",
|
|
23
|
+
"@systemfsoftware/effect-cell-types": "^3.0.0",
|
|
24
|
+
"@systemfsoftware/stryker-js-mutation-run": "^3.0.0",
|
|
25
|
+
"@systemfsoftware/stryker-js-plugin-api": "^2.0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@systemfsoftware/arethetypeswrong-cli": "^1.1.1",
|
|
@@ -35,15 +35,15 @@
|
|
|
35
35
|
"tsdown": "^0.22.14",
|
|
36
36
|
"vite-tsconfig-paths": "^6.1.1",
|
|
37
37
|
"vitest": "^4.1.10",
|
|
38
|
-
"@systemfsoftware/effect-gherkin-spec": "^0.
|
|
39
|
-
"@systemfsoftware/effect-schema-law": "^0.
|
|
40
|
-
"@systemfsoftware/
|
|
38
|
+
"@systemfsoftware/effect-gherkin-spec": "^2.0.0",
|
|
39
|
+
"@systemfsoftware/effect-schema-law": "^0.8.0",
|
|
40
|
+
"@systemfsoftware/oxlint-plugin-cell-vocabulary": "^1.2.0",
|
|
41
|
+
"@systemfsoftware/effect-schema-vite": "^1.5.3",
|
|
41
42
|
"@systemfsoftware/oxlint-config": "^0.1.0",
|
|
42
|
-
"@systemfsoftware/
|
|
43
|
-
"@systemfsoftware/oxlint-plugin-effect-entrypoint": "^1.0.
|
|
44
|
-
"@systemfsoftware/
|
|
45
|
-
"@systemfsoftware/
|
|
46
|
-
"@systemfsoftware/vitest-config": "^0.1.0"
|
|
43
|
+
"@systemfsoftware/tsconfig": "^1.3.3",
|
|
44
|
+
"@systemfsoftware/oxlint-plugin-effect-entrypoint": "^1.0.4",
|
|
45
|
+
"@systemfsoftware/vitest-config": "^0.1.0",
|
|
46
|
+
"@systemfsoftware/oxlint-plugin-test-placement": "^3.0.0"
|
|
47
47
|
},
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=20.0.0"
|