@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.
Files changed (2) hide show
  1. package/CHANGELOG.md +191 -0
  2. 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": "1.2.5",
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.5",
23
- "@systemfsoftware/effect-cell-types": "^1.0.1",
24
- "@systemfsoftware/stryker-js-mutation-run": "^1.2.5",
25
- "@systemfsoftware/stryker-js-plugin-api": "^0.1.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.5.1",
39
- "@systemfsoftware/effect-schema-law": "^0.6.1",
40
- "@systemfsoftware/effect-schema-vite": "^1.5.1",
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/oxlint-plugin-cell-vocabulary": "^1.0.0",
43
- "@systemfsoftware/oxlint-plugin-effect-entrypoint": "^1.0.2",
44
- "@systemfsoftware/oxlint-plugin-test-placement": "^1.2.2",
45
- "@systemfsoftware/tsconfig": "^1.3.1",
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"