@kitschpatrol/shared-config 8.10.1 → 8.12.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/bin/cli.js +10 -10
- package/package.json +18 -17
- package/readme.md +39 -2
- package/skills/ksc/SKILL.md +113 -0
- package/skills/ksc-update/SKILL.md +686 -0
- package/skills/ksc-update/references/verification.md +168 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Consumer verification recipes
|
|
2
|
+
|
|
3
|
+
Use these recipes during Setup and step 5. Save commands, versions, raw logs,
|
|
4
|
+
and results under `node_modules/.cache/ksc-update/`. Run pnpm commands as separate
|
|
5
|
+
bare invocations; save their captured output in a later operation so sandbox
|
|
6
|
+
command exclusions still match.
|
|
7
|
+
|
|
8
|
+
## Production-tree engines
|
|
9
|
+
|
|
10
|
+
For each published package, run in its directory before and after updates:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pnpm list --prod --depth Infinity --json
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Save stdout as `production-tree.json` in the corresponding baseline or updated
|
|
17
|
+
results folder. If stdout contains lines beginning with `[WARN]`, preserve those
|
|
18
|
+
warnings separately and remove only those lines before parsing. Require a
|
|
19
|
+
successful command and valid JSON; do not extract an arbitrary JSON-looking
|
|
20
|
+
substring from failed output. In a monorepo, include every published package,
|
|
21
|
+
not only a private root with no production dependencies.
|
|
22
|
+
|
|
23
|
+
The list supplies installed paths; read each installed `package.json` for its
|
|
24
|
+
actual engine declaration. Save this helper in the run's cache as
|
|
25
|
+
`production-engines.mjs` and run it with the saved JSON path as its argument:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
import { readFileSync } from 'node:fs'
|
|
29
|
+
import { join } from 'node:path'
|
|
30
|
+
|
|
31
|
+
const roots = JSON.parse(readFileSync(process.argv[2], 'utf8'))
|
|
32
|
+
if (!Array.isArray(roots)) {
|
|
33
|
+
throw new TypeError('Expected pnpm list JSON array')
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const manifests = new Map()
|
|
37
|
+
const rows = new Set()
|
|
38
|
+
|
|
39
|
+
function visit(pkg) {
|
|
40
|
+
if (!pkg.path) {
|
|
41
|
+
throw new Error(`Missing installed path: ${pkg.name ?? pkg.version}`)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!manifests.has(pkg.path)) {
|
|
45
|
+
manifests.set(pkg.path, JSON.parse(readFileSync(join(pkg.path, 'package.json'), 'utf8')))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const manifest = manifests.get(pkg.path)
|
|
49
|
+
rows.add(
|
|
50
|
+
JSON.stringify({
|
|
51
|
+
name: manifest.name,
|
|
52
|
+
node: manifest.engines?.node,
|
|
53
|
+
version: manifest.version,
|
|
54
|
+
}),
|
|
55
|
+
)
|
|
56
|
+
for (const group of ['dependencies', 'optionalDependencies']) {
|
|
57
|
+
const children = Object.values(pkg[group] ?? {})
|
|
58
|
+
for (const child of children) {
|
|
59
|
+
visit(child)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
for (const root of roots) {
|
|
65
|
+
visit(root)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
process.stdout.write(`${[...rows].toSorted().join('\n')}\n`)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Save the resulting inventory and diff it after resolution and deduplication.
|
|
72
|
+
Investigate missing installed paths instead of omitting them. An omitted `node`
|
|
73
|
+
field means undeclared support, not proof of compatibility. Check full semver ranges
|
|
74
|
+
against every supported consumer Node.js line; check platform-specific optional
|
|
75
|
+
dependencies and shipped/bundled code separately because one host's installed
|
|
76
|
+
tree cannot prove their compatibility. This inventory does not replace the
|
|
77
|
+
newest-in-range registry review.
|
|
78
|
+
|
|
79
|
+
## Known consumers and packed builds
|
|
80
|
+
|
|
81
|
+
Read confirmed consumers from the repository's existing `CLAUDE.md` or
|
|
82
|
+
`AGENTS.md`. A useful `Known consumers` entry contains the consumer's name and
|
|
83
|
+
path, which package/imports/CLI it uses, its test command, and representative
|
|
84
|
+
CLI commands and fixture inputs. Preserve existing instructions; add only facts
|
|
85
|
+
confirmed by the user or repository evidence.
|
|
86
|
+
|
|
87
|
+
1. Create a temporary directory under `${TMPDIR:-/tmp}`. Clone each local
|
|
88
|
+
consumer into it with `git clone --no-hardlinks <consumer-path> <temp-copy>`.
|
|
89
|
+
Record the commit. A clone excludes uncommitted changes; if those matter,
|
|
90
|
+
explicitly copy the needed working-tree files and record that baseline.
|
|
91
|
+
Do not modify the consumer's original checkout.
|
|
92
|
+
2. Install and test the copied consumer with its starting lockfile. Save
|
|
93
|
+
its tests' results and representative CLI stdout, stderr, and exit codes.
|
|
94
|
+
Preserve this copy for baseline comparison.
|
|
95
|
+
3. Build the updated package with its development Node.js version and run
|
|
96
|
+
`pnpm pack` as a bare command in that package. Inspect the archive's contents
|
|
97
|
+
and manifest, including exported entrypoints, engines, and dependency ranges.
|
|
98
|
+
4. In a second consumer copy, replace the consumed dependency with a `file:`
|
|
99
|
+
specifier pointing to that tarball, using a direct manifest edit. Install
|
|
100
|
+
and rerun the same tests and CLI fixtures. If a workspace-local dependency
|
|
101
|
+
or alias is involved, replace the actual consuming edge and verify the
|
|
102
|
+
resolved path/version; do not assume a root-only edit reaches it. A linked
|
|
103
|
+
built package is useful for iteration, but the tarball verifies what ships
|
|
104
|
+
and avoids a link silently borrowing the producer's `node_modules`.
|
|
105
|
+
5. Diff CLI output and fixture results. Inspect semantic differences, including
|
|
106
|
+
behavior JSON may hide, such as object prototypes, missing versus undefined
|
|
107
|
+
values, ordering, and error handling. Explain each change against accepted
|
|
108
|
+
migrations and consumer expectations.
|
|
109
|
+
|
|
110
|
+
Also test a fresh isolated install of the published release with the newest
|
|
111
|
+
dependencies its ranges allow. Keep this distinct from the published release
|
|
112
|
+
running on its old dependencies: reproduce the latter from a known historical
|
|
113
|
+
lockfile or preserved installation where possible. A registry tarball alone
|
|
114
|
+
does not recover the old transitive tree. If it cannot be reconstructed, report
|
|
115
|
+
that gap instead of labeling a fresh install the historical baseline.
|
|
116
|
+
|
|
117
|
+
## Exact Node.js floor
|
|
118
|
+
|
|
119
|
+
Use the exact minimum supported release, not just the same major or the active
|
|
120
|
+
developer runtime. For disjoint supported Node.js lines, check each relevant
|
|
121
|
+
minimum. For an approved engine bump, compare the old release at its old floor
|
|
122
|
+
with the updated package at its new floor and on an overlapping supported
|
|
123
|
+
runtime where available.
|
|
124
|
+
|
|
125
|
+
If the version manager has no suitable installed binary, download the exact
|
|
126
|
+
official archive from `https://nodejs.org/dist/v<version>/` for the host's OS and
|
|
127
|
+
architecture into a temporary folder, alongside `SHASUMS256.txt`. Verify the
|
|
128
|
+
archive's SHA-256 against that file, then extract it there. Use the resulting
|
|
129
|
+
Node binary by absolute path; do not install globally or change the user's
|
|
130
|
+
default runtime. Record `<absolute-node-path> --version` with the results.
|
|
131
|
+
|
|
132
|
+
Install/build with the development runtime if the tooling requires it, then
|
|
133
|
+
invoke the packed package's built JavaScript entrypoint and runtime fixtures
|
|
134
|
+
with the exact-floor binary. For subprocesses that use `env node`, put that
|
|
135
|
+
binary's directory first in the test process's `PATH` only. Confirm which
|
|
136
|
+
binary the child process uses. If the test runner itself requires newer Node,
|
|
137
|
+
run a small fixture harness or the built CLI directly at the floor; running
|
|
138
|
+
only the newer test runner is not floor validation. Report when installation
|
|
139
|
+
or execution on the exact runtime could not be verified.
|
|
140
|
+
|
|
141
|
+
Record stdout, stderr, exit codes, and relevant API results for identical
|
|
142
|
+
fixtures across runtimes and dependency baselines. Normalize only known
|
|
143
|
+
nondeterministic fields using the same documented transformation for all runs.
|
|
144
|
+
Save SHA-256 digests of normalized fixture output for quick comparison, retain
|
|
145
|
+
the actual output for reviewing differences, and add targeted assertions for
|
|
146
|
+
behavior that serialization omits.
|
|
147
|
+
|
|
148
|
+
## Tool references
|
|
149
|
+
|
|
150
|
+
Check these primary sources or the installed tool's help when behavior differs:
|
|
151
|
+
|
|
152
|
+
- [GitHub Actions variables](https://docs.github.com/en/actions/reference/workflows-and-actions/variables):
|
|
153
|
+
`GITHUB_ACTIONS` and `CI` identify unattended execution in Actions.
|
|
154
|
+
- [pnpm update](https://pnpm.io/cli/update): manifest/catalog writes and selectors.
|
|
155
|
+
This workflow uses a bare update for its full dependency refresh; do not
|
|
156
|
+
assume exclusion syntax works identically in every pnpm implementation.
|
|
157
|
+
- [pnpm dedupe](https://pnpm.io/cli/dedupe) and
|
|
158
|
+
[pnpm list](https://pnpm.io/cli/list): deduplication checks and tree inventories.
|
|
159
|
+
- [pnpm settings](https://pnpm.io/settings) and
|
|
160
|
+
[peer rules](https://pnpm.io/settings/peer-dependencies#peerdependencyrulesallowedversions):
|
|
161
|
+
current configuration locations and scoped warning allowances. Current pnpm
|
|
162
|
+
uses `.npmrc` for registry/auth settings, not all policy settings.
|
|
163
|
+
- [Taze](https://github.com/antfu-collective/taze): candidate filters and maturity.
|
|
164
|
+
- [Actions Up](https://github.com/azat-io/actions-up#update-style): SHA pinning.
|
|
165
|
+
- [tsdown target](https://tsdown.dev/options/target): implicit engine-derived
|
|
166
|
+
targets affect emitted syntax and do not provide API polyfills.
|
|
167
|
+
- [Node.js release archives](https://nodejs.org/dist/): exact runtime downloads
|
|
168
|
+
and checksum manifests.
|