@joshuafolkken/kit 1.3092.0 → 1.3099.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/dist/.inputs-verified.json +1 -1
- package/dist/commands/backlog-drive-cli.js +17 -17
- package/dist/commands/backlogrun-cli.js +21 -20
- package/dist/commands/check-related.js +18 -18
- package/dist/commands/{chunk-VXE3V3OC.js → chunk-2CNVIA35.js} +2 -2
- package/dist/commands/{chunk-374XGAWD.js → chunk-36XHHYNU.js} +1 -1
- package/dist/commands/{chunk-W3MDLQZF.js → chunk-3LUPGBW4.js} +1 -1
- package/dist/commands/{chunk-T6OUNP7E.js → chunk-3VLDFM5I.js} +6 -6
- package/dist/commands/{chunk-4K7KLR7L.js → chunk-6AHAY5VZ.js} +1 -1
- package/dist/commands/{chunk-ET6IRQ3L.js → chunk-6FN37DER.js} +3 -3
- package/dist/commands/{chunk-LBMAJDGN.js → chunk-6JD4VNO4.js} +2 -2
- package/dist/commands/{chunk-KD3SEAMV.js → chunk-7HYYHCTN.js} +2 -2
- package/dist/commands/{chunk-4GUGC4IW.js → chunk-7K5ITPHR.js} +2 -2
- package/dist/commands/{chunk-XTJA34ND.js → chunk-7ULYLGUK.js} +10 -10
- package/dist/commands/{chunk-IEKW3ON6.js → chunk-ABM2MZBF.js} +1 -1
- package/dist/commands/{chunk-IOKOHB7P.js → chunk-BBLEC4YQ.js} +1 -1
- package/dist/commands/{chunk-V2T5DP3B.js → chunk-C7FGDZWP.js} +1 -1
- package/dist/commands/{chunk-MHXIJKGP.js → chunk-EHPTXSAT.js} +20 -9
- package/dist/commands/{chunk-PF3PMT2Q.js → chunk-EPICTV2P.js} +1 -1
- package/dist/commands/{chunk-GVDRRBHZ.js → chunk-EVVQJJFV.js} +2 -2
- package/dist/commands/{chunk-NOSG3RUP.js → chunk-F57LACNC.js} +2 -2
- package/dist/commands/{chunk-BAEDHPXW.js → chunk-FA7CN75F.js} +4 -4
- package/dist/commands/{chunk-62NYXZCC.js → chunk-FDASVHZD.js} +1 -1
- package/dist/commands/{chunk-YMAEYY5R.js → chunk-FEYZ575X.js} +1 -1
- package/dist/commands/{chunk-PILH72AV.js → chunk-FTAWHAI7.js} +1 -1
- package/dist/commands/{chunk-MK4CARBI.js → chunk-G3BBCAAH.js} +1 -1
- package/dist/commands/{chunk-Z6QLFPFB.js → chunk-GABDPTDK.js} +4 -4
- package/dist/commands/{chunk-VHLDQ3PH.js → chunk-HHS3LYLV.js} +2 -2
- package/dist/commands/{chunk-EE4VOZJP.js → chunk-HQZ65PJE.js} +3 -3
- package/dist/commands/{chunk-KHGDZQRG.js → chunk-HSZECERZ.js} +2 -2
- package/dist/commands/{chunk-BLUAO4QW.js → chunk-IY3DSDRW.js} +1 -1
- package/dist/commands/{chunk-2XZF3YFY.js → chunk-J2RUI4KN.js} +1 -1
- package/dist/commands/{chunk-2Q7MGFYB.js → chunk-J3PCRUVY.js} +27 -12
- package/dist/commands/{chunk-RDUFVQVJ.js → chunk-JU2MAYQ3.js} +7 -7
- package/dist/commands/{chunk-ZEUKX3RZ.js → chunk-KJPZPTS4.js} +1 -1
- package/dist/commands/{chunk-7E43YW53.js → chunk-MHF6BDQI.js} +1 -1
- package/dist/commands/{chunk-BE6F4YK2.js → chunk-OHN3QARP.js} +10 -10
- package/dist/commands/{chunk-AT46EY7H.js → chunk-OKBZGLD5.js} +1 -1
- package/dist/commands/{chunk-XCCT6GKA.js → chunk-OZN4HOZT.js} +2 -2
- package/dist/commands/{chunk-ZJ5S4VFD.js → chunk-RAQ3E6OT.js} +1 -1
- package/dist/commands/{chunk-XSKJAG72.js → chunk-S5GX3H4P.js} +1 -1
- package/dist/commands/{chunk-HESWKELD.js → chunk-SC57VV6A.js} +1 -1
- package/dist/commands/{chunk-EZYW54OQ.js → chunk-SOETJZWH.js} +221 -118
- package/dist/commands/{chunk-HNFBEB4L.js → chunk-UUA63LCI.js} +1 -1
- package/dist/commands/{chunk-ZGBXUY7R.js → chunk-UZDKCGDC.js} +1 -1
- package/dist/commands/{chunk-B5XYAWNN.js → chunk-VPRQFM2T.js} +1 -1
- package/dist/commands/{chunk-M4WG74Q7.js → chunk-VUCDGQ6Y.js} +1 -1
- package/dist/commands/{chunk-UX3HCPLX.js → chunk-W7X7MZZN.js} +1 -1
- package/dist/commands/{chunk-EN65ZS3S.js → chunk-WORHUJ6T.js} +1 -1
- package/dist/commands/chunk-WRHMYSW7.js +36 -0
- package/dist/commands/{chunk-K5H3CLZZ.js → chunk-YANDBVAT.js} +1 -1
- package/dist/commands/{chunk-GWTBIGYC.js → chunk-YD7XK2TX.js} +1 -1
- package/dist/commands/{chunk-M5HA2ZCG.js → chunk-YT5JR2CB.js} +2 -2
- package/dist/commands/{chunk-EWCUT7U2.js → chunk-Z2NUK47W.js} +1 -1
- package/dist/commands/{chunk-4MGTNY2L.js → chunk-ZI3SABMH.js} +1 -1
- package/dist/commands/{chunk-TTTZZN7F.js → chunk-ZJJLROJY.js} +3 -3
- package/dist/commands/disposition-cli.js +15 -15
- package/dist/commands/git-followup-workflow.js +18 -7
- package/dist/commands/inputs.json +1637 -1632
- package/dist/commands/issue-already-done-cli.js +8 -8
- package/dist/commands/issue-measured-cli.js +9 -9
- package/dist/commands/issue-plan-cli.js +16 -16
- package/dist/commands/issue-premise-unmet-cli.js +8 -8
- package/dist/commands/lane-breakdown-cli.js +17 -17
- package/dist/commands/lane-cli.js +20 -20
- package/dist/commands/lane-measure-cli.js +23 -23
- package/dist/commands/lane-plan-cli.js +15 -15
- package/dist/commands/lane-restart-cli.js +20 -20
- package/dist/commands/lane-why-cli.js +4 -4
- package/dist/commands/lint-parallel-main.js +2 -2
- package/dist/commands/lint-related.js +6 -6
- package/dist/commands/lint-rule.js +2 -2
- package/dist/commands/plan-scaffold-cli.js +20 -20
- package/dist/commands/pre-commit-type-check.js +7 -7
- package/dist/commands/pre-push-unit.js +9 -9
- package/dist/commands/prose-stale-cli.js +5 -5
- package/dist/commands/review-brief-main.js +23 -23
- package/dist/commands/review-pair-cli.js +19 -19
- package/dist/commands/review-record-main.js +19 -19
- package/dist/commands/review-round2-cli.js +4 -4
- package/dist/commands/review-submit-cli.js +23 -23
- package/dist/commands/run-board-main.js +2 -1
- package/dist/commands/run-chain-cli.js +19 -19
- package/dist/commands/run-cut-cli.js +19 -19
- package/dist/commands/run-entry-cli.js +27 -27
- package/dist/commands/run-hold-main.js +7 -7
- package/dist/commands/run-next-cli.js +20 -20
- package/dist/commands/run-park-cli.js +8 -8
- package/dist/commands/run-pause-cli.js +8 -8
- package/dist/commands/run-prep-main.js +20 -20
- package/dist/commands/run-prime-cli.js +10 -10
- package/dist/commands/run-review-cli.js +26 -26
- package/dist/commands/run-ship-cli.js +29 -29
- package/dist/commands/run-ship-evidence-cli.js +4 -4
- package/dist/commands/run-ship-wait-main.js +5 -5
- package/dist/commands/run-split-cli.js +8 -8
- package/dist/commands/run-step-cli.js +27 -27
- package/dist/commands/run-wake-main.js +19 -19
- package/dist/commands/selfcheck-cli.js +8 -8
- package/dist/commands/stop-guard.js +7 -7
- package/dist/commands/test-e2e-guard.js +6 -6
- package/dist/commands/test-pinned-main.js +8 -8
- package/dist/commands/test-reach-cli.js +4 -4
- package/dist/commands/{test-related-Z6YY2GFH.js → test-related-XBDH2IOH.js} +11 -11
- package/dist/commands/test-related-main.js +13 -13
- package/dist/commands/verification-gate.js +17 -17
- package/dist/hooks/inputs.json +571 -570
- package/dist/hooks/stop-guard.js +68 -59
- package/dist/inputs.json +78 -78
- package/package.json +1 -1
- package/scripts/followup/git-followup-finish.ts +16 -1
- package/scripts/gate/verification-inputs.ts +2 -1
- package/scripts/run/board/run-board-layout.ts +9 -4
- package/scripts/run/board/run-board-read.ts +29 -69
- package/scripts/run/board/run-board-render-lanes.ts +26 -9
- package/scripts/run/board/run-board-render-lead.ts +9 -0
- package/scripts/run/board/run-board-root-layout.ts +69 -0
- package/scripts/run/board/run-board-single.ts +69 -4
- package/scripts/run/board/run-board-span-read.ts +85 -0
- package/scripts/run/board/run-board-tick.ts +12 -4
- package/scripts/run/hold/run-hold-ended.ts +50 -0
- package/scripts/test/test-pinned-cache-logic.ts +13 -7
- package/scripts/test/test-pinned-cache.ts +33 -11
- package/scripts/test/test-runner-config.ts +19 -0
|
@@ -17,13 +17,14 @@ import type { RedProbe, RedVerdict } from './test-red-logic'
|
|
|
17
17
|
// failed before the revert reads red too — and a red kept past any of those, or past an edit to the test
|
|
18
18
|
// that failed, would pass an unpinned hunk. A test added or edited elsewhere cannot make that test
|
|
19
19
|
// pass, so it keeps the red. A red with no failed file recorded holds only while no test file changed either.
|
|
20
|
-
// **A `green` or `no-test` one holds while no test file's path or content changed
|
|
21
|
-
//
|
|
22
|
-
//
|
|
20
|
+
// **A `green` or `no-test` one holds while no test file's path or content changed, nor the test
|
|
21
|
+
// runner's configuration** (`test_contents`, joshuafolkken/kit#7521 — a widened `include` runs a test
|
|
22
|
+
// that never ran): it is only rechecked when a test could have come to reach it, and a stale one stops a
|
|
23
|
+
// lane rather than passing it.
|
|
23
24
|
// **Past those tree-wide digests, a verdict also holds while its own `basis` is the same**
|
|
24
25
|
// (joshuafolkken/kit#4873): for a `red`, the base commit, the changed non-code and whole-suite files,
|
|
25
26
|
// and each failed test's import closure; for any other, the tests whose imports reach the hunk's file,
|
|
26
|
-
// with their content. An edit outside them keeps the verdict; with no basis — no import graph, no
|
|
27
|
+
// with their content, and the test runner's configuration. An edit outside them keeps the verdict; with no basis — no import graph, no
|
|
27
28
|
// failed file recorded — only the tree-wide digests hold it, as before.
|
|
28
29
|
// **A `red` verdict also holds while `pruned` reads the same** (joshuafolkken/kit#5004): the code
|
|
29
30
|
// change since differs only by lines removed from `green` hunks (`test-pinned-prune-logic.ts`).
|
|
@@ -219,11 +220,16 @@ function fresh_verdict(
|
|
|
219
220
|
return { verdict: entry.verdict, failed: Object.keys(entry.tests) }
|
|
220
221
|
}
|
|
221
222
|
|
|
222
|
-
// A `green` or `no-test` verdict's basis: each test whose imports reach the hunk's file, with its content
|
|
223
|
-
|
|
223
|
+
// A `green` or `no-test` verdict's basis: each test whose imports reach the hunk's file, with its content,
|
|
224
|
+
// and `config`, the test runner's configuration — which of those tests a run collects.
|
|
225
|
+
function related_basis(
|
|
226
|
+
tests: ReadonlyArray<string>,
|
|
227
|
+
digests: ReadonlyMap<string, string>,
|
|
228
|
+
config: string,
|
|
229
|
+
): Basis {
|
|
224
230
|
const pairs = sorted(tests).map((file) => [file, digests.get(file) ?? ''] as const)
|
|
225
231
|
|
|
226
|
-
return { digest: digest_of(JSON.stringify(pairs)), related: Object.fromEntries(pairs) }
|
|
232
|
+
return { digest: digest_of(JSON.stringify([config, pairs])), related: Object.fromEntries(pairs) }
|
|
227
233
|
}
|
|
228
234
|
|
|
229
235
|
// The tests added or edited since `before` was read; `undefined` once one of its tests is gone or no
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs'
|
|
2
2
|
import { readFile } from 'node:fs/promises'
|
|
3
3
|
import path from 'node:path'
|
|
4
|
+
import { config_fingerprint } from '#eslint/config-fingerprint.js'
|
|
4
5
|
import { changed_paths } from '#scripts/git/changed-paths'
|
|
5
6
|
import { git_spawn } from '#scripts/git/git-spawn'
|
|
6
7
|
import { run_record_path } from '#scripts/josh/run-record-path'
|
|
@@ -18,6 +19,7 @@ import type { Hunk } from './test-pinned-logic'
|
|
|
18
19
|
import { test_pinned_prune_logic, type CodeChange } from './test-pinned-prune-logic'
|
|
19
20
|
import { test_pinned_reach, type Reach } from './test-pinned-reach'
|
|
20
21
|
import type { RedProbe } from './test-red-logic'
|
|
22
|
+
import { test_runner_config } from './test-runner-config'
|
|
21
23
|
|
|
22
24
|
// The reads and writes of `josh test:pinned`'s verdict cache (joshuafolkken/kit#4706); what a key is and
|
|
23
25
|
// when an entry holds is `test-pinned-cache-logic.ts`. `josh run:review` calls the same `test_pinned.run`,
|
|
@@ -31,9 +33,11 @@ const LINE_BREAK = '\n'
|
|
|
31
33
|
// Peels a ref or tag to the commit it names, so a branch name and its SHA key the same change.
|
|
32
34
|
const AS_COMMIT = '^{commit}'
|
|
33
35
|
|
|
36
|
+
// `config` is one digest over the test runner's configuration files, which `test_contents` covers too.
|
|
34
37
|
interface TreeRead {
|
|
35
38
|
test_digests: ReadonlyMap<string, string>
|
|
36
39
|
code: CodeChange
|
|
40
|
+
config: string
|
|
37
41
|
test_contents: string
|
|
38
42
|
change: string
|
|
39
43
|
}
|
|
@@ -45,6 +49,7 @@ interface LoadedCache extends VerdictCache {
|
|
|
45
49
|
base: string
|
|
46
50
|
freshness: Freshness
|
|
47
51
|
test_digests: ReadonlyMap<string, string>
|
|
52
|
+
config: string
|
|
48
53
|
reach: Reach
|
|
49
54
|
code: CodeChange
|
|
50
55
|
hunks: ReadonlyArray<Hunk>
|
|
@@ -79,11 +84,11 @@ async function contents_of(files: ReadonlyArray<string>): Promise<Map<string, st
|
|
|
79
84
|
return new Map(existing.map((file, index) => [file, texts[index] ?? '']))
|
|
80
85
|
}
|
|
81
86
|
|
|
82
|
-
// Every
|
|
83
|
-
async function
|
|
87
|
+
// Every file in the work tree `is_kept` accepts, tracked or untracked but not ignored.
|
|
88
|
+
async function work_tree_files(is_kept: (file: string) => boolean): Promise<Array<string>> {
|
|
84
89
|
const listed = await test_pinned_reach.work_tree_files()
|
|
85
90
|
|
|
86
|
-
return listed.filter((file) =>
|
|
91
|
+
return listed.filter((file) => is_kept(file))
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
// The digest of each named file the work tree still holds.
|
|
@@ -95,9 +100,20 @@ async function digests_of(files: ReadonlyArray<string>): Promise<Map<string, str
|
|
|
95
100
|
)
|
|
96
101
|
}
|
|
97
102
|
|
|
98
|
-
// Each
|
|
99
|
-
async function
|
|
100
|
-
return await digests_of(await
|
|
103
|
+
// Each work tree file's content digest `is_kept` accepts, keyed by its path.
|
|
104
|
+
async function kept_digests_of(is_kept: (file: string) => boolean): Promise<Map<string, string>> {
|
|
105
|
+
return await digests_of(await work_tree_files(is_kept))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Each test runner configuration file and every local module it imports — where an `include` list may
|
|
109
|
+
// sit, as `tools/test/vitest-include-globs.ts` does here — with its content digest.
|
|
110
|
+
async function config_digests_of(): Promise<Map<string, string>> {
|
|
111
|
+
const configs = await work_tree_files((file) => test_runner_config.is_config(file))
|
|
112
|
+
const reached = config_fingerprint.list_reachable_modules(
|
|
113
|
+
configs.map((file) => path.resolve(file)),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
return await digests_of([...reached].map((file) => path.relative(process.cwd(), file)))
|
|
101
117
|
}
|
|
102
118
|
|
|
103
119
|
// One digest over every test file's path and content.
|
|
@@ -123,13 +139,19 @@ async function code_change(base: string): Promise<CodeChange> {
|
|
|
123
139
|
return { commit: commit.trim(), code, digests: await digests_of(code) }
|
|
124
140
|
}
|
|
125
141
|
|
|
126
|
-
// The work tree's tree-wide digests, with what they were read off.
|
|
142
|
+
// The work tree's tree-wide digests, with what they were read off. A test runner configuration change
|
|
143
|
+
// can make a test run that never ran, so it moves `test_contents` as a test file would
|
|
144
|
+
// (joshuafolkken/kit#7521).
|
|
127
145
|
async function read_tree(base: string): Promise<TreeRead> {
|
|
128
|
-
const [test_digests, code] = await Promise.all([
|
|
129
|
-
|
|
146
|
+
const [test_digests, configs, code] = await Promise.all([
|
|
147
|
+
kept_digests_of((file) => test_declared_logic.is_test_file(file)),
|
|
148
|
+
config_digests_of(),
|
|
149
|
+
code_change(base),
|
|
150
|
+
])
|
|
151
|
+
const test_contents = contents_digest(new Map([...test_digests, ...configs]))
|
|
130
152
|
const change = test_pinned_cache_logic.change_of(code.commit, code.code, code.digests)
|
|
131
153
|
|
|
132
|
-
return { test_digests, code, test_contents, change }
|
|
154
|
+
return { test_digests, code, config: contents_digest(configs), test_contents, change }
|
|
133
155
|
}
|
|
134
156
|
|
|
135
157
|
// The cache file's text and what the work tree holds now, with the files `hunks` and the recorded
|
|
@@ -176,7 +198,7 @@ async function basis_of(
|
|
|
176
198
|
if (probe.verdict !== 'red') {
|
|
177
199
|
const tests = await cache.reach.related(file)
|
|
178
200
|
|
|
179
|
-
return tests && test_pinned_cache_logic.related_basis(tests, cache.test_digests)
|
|
201
|
+
return tests && test_pinned_cache_logic.related_basis(tests, cache.test_digests, cache.config)
|
|
180
202
|
}
|
|
181
203
|
|
|
182
204
|
const digest = await cache.reach.failed(probe.failed)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
|
|
3
|
+
// The test runner's configuration files (joshuafolkken/kit#7521): which tests a run collects is theirs
|
|
4
|
+
// to decide (`include`, projects), so a change to one can make a test run that never ran before. A
|
|
5
|
+
// leaf module, so `verification-inputs.ts` and `josh test:pinned`'s verdict cache share the names.
|
|
6
|
+
|
|
7
|
+
// A file name starting with one of these configures vitest.
|
|
8
|
+
const PREFIXES: ReadonlyArray<string> = ['vitest.config.', 'vitest.workspace.', 'vite.config.']
|
|
9
|
+
|
|
10
|
+
// A configuration vitest reads from the repository root; one nested deeper is a fixture or a package's own.
|
|
11
|
+
function is_config(relative: string): boolean {
|
|
12
|
+
if (path.dirname(relative) !== '.') return false
|
|
13
|
+
|
|
14
|
+
return PREFIXES.some((prefix) => relative.startsWith(prefix))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const test_runner_config = { is_config, PREFIXES }
|
|
18
|
+
|
|
19
|
+
export { test_runner_config }
|