@overkill-dev/run 0.0.92 → 0.0.93

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 (202) hide show
  1. package/config/config.d.ts +3 -1
  2. package/config/config.d.ts.map +1 -1
  3. package/config/config.js +9 -11
  4. package/config/config.js.map +1 -1
  5. package/config/defaults.js +4 -0
  6. package/config/defaults.js.map +1 -1
  7. package/config/history-policy.d.ts +14 -0
  8. package/config/history-policy.d.ts.map +1 -0
  9. package/config/history-policy.js +24 -0
  10. package/config/history-policy.js.map +1 -0
  11. package/config/normalized-microtest-schema.js +1 -0
  12. package/config/normalized-microtest-schema.js.map +1 -1
  13. package/config/profile-normalization.js +4 -1
  14. package/config/profile-normalization.js.map +1 -1
  15. package/config/schema.d.ts +59 -0
  16. package/config/schema.d.ts.map +1 -1
  17. package/config/schema.js +6 -0
  18. package/config/schema.js.map +1 -1
  19. package/config/snapshot.js +5 -0
  20. package/config/snapshot.js.map +1 -1
  21. package/config/types.d.ts +15 -0
  22. package/config/types.d.ts.map +1 -1
  23. package/config/validation.js +3 -0
  24. package/config/validation.js.map +1 -1
  25. package/package.json +10 -2
  26. package/packages/run/command-line.entry-point.d.ts +1 -1
  27. package/packages/run/command-line.entry-point.d.ts.map +1 -1
  28. package/packages/run/command-line.entry-point.js +3 -0
  29. package/packages/run/command-line.entry-point.js.map +1 -1
  30. package/packages/run/config.entry-point.d.ts +1 -0
  31. package/packages/run/config.entry-point.d.ts.map +1 -1
  32. package/packages/run/run.entry-point.d.ts +3 -0
  33. package/packages/run/run.entry-point.d.ts.map +1 -1
  34. package/packages/run/run.entry-point.js +1 -0
  35. package/packages/run/run.entry-point.js.map +1 -1
  36. package/readme.md +79 -1
  37. package/reporters/failure-summary.js +29 -0
  38. package/reporters/failure-summary.js.map +1 -1
  39. package/reporters/human-reporter-rendering.js +5 -1
  40. package/reporters/human-reporter-rendering.js.map +1 -1
  41. package/run/attachment-record.js +7 -3
  42. package/run/attachment-record.js.map +1 -1
  43. package/run/attachment-run.js +14 -7
  44. package/run/attachment-run.js.map +1 -1
  45. package/run/collected-run-execution.js +4 -26
  46. package/run/collected-run-execution.js.map +1 -1
  47. package/run/collected-run-invocation.js +39 -0
  48. package/run/collected-run-invocation.js.map +1 -0
  49. package/run/collected-run.js +1 -1
  50. package/run/collected-run.js.map +1 -1
  51. package/run/command-line-command-namespace.d.ts +2 -0
  52. package/run/command-line-command-namespace.d.ts.map +1 -1
  53. package/run/command-line-command-namespace.js +25 -0
  54. package/run/command-line-command-namespace.js.map +1 -1
  55. package/run/command-line-command.d.ts +5 -0
  56. package/run/command-line-command.d.ts.map +1 -1
  57. package/run/command-line-config.js +2 -0
  58. package/run/command-line-config.js.map +1 -1
  59. package/run/command-line-execution.js +1 -0
  60. package/run/command-line-execution.js.map +1 -1
  61. package/run/command-line-runner.d.ts +2 -1
  62. package/run/command-line-runner.d.ts.map +1 -1
  63. package/run/command-line-runner.js +1 -0
  64. package/run/command-line-runner.js.map +1 -1
  65. package/run/compact-history-schema.d.ts +20 -0
  66. package/run/compact-history-schema.d.ts.map +1 -0
  67. package/run/compact-history-schema.js +32 -0
  68. package/run/compact-history-schema.js.map +1 -0
  69. package/run/compact-history.js +100 -0
  70. package/run/compact-history.js.map +1 -0
  71. package/run/coverage-run-record.js +2 -9
  72. package/run/coverage-run-record.js.map +1 -1
  73. package/run/duration-history-schema.js +3 -1
  74. package/run/duration-history-schema.js.map +1 -1
  75. package/run/duration-history-storage.js +170 -0
  76. package/run/duration-history-storage.js.map +1 -0
  77. package/run/duration-history-types.js +2 -0
  78. package/run/duration-history-types.js.map +1 -0
  79. package/run/duration-history.js +24 -92
  80. package/run/duration-history.js.map +1 -1
  81. package/run/freeze-run-policy.js +1 -0
  82. package/run/freeze-run-policy.js.map +1 -1
  83. package/run/frozen-policy-validation.js +1 -0
  84. package/run/frozen-policy-validation.js.map +1 -1
  85. package/run/frozen-run-policy-schema.js +3 -0
  86. package/run/frozen-run-policy-schema.js.map +1 -1
  87. package/run/frozen-run-policy.d.ts.map +1 -1
  88. package/run/frozen-run-policy.js +1 -0
  89. package/run/frozen-run-policy.js.map +1 -1
  90. package/run/history-commands.d.ts +4 -0
  91. package/run/history-commands.d.ts.map +1 -0
  92. package/run/history-commands.js +76 -0
  93. package/run/history-commands.js.map +1 -0
  94. package/run/history-confirmation.js +33 -0
  95. package/run/history-confirmation.js.map +1 -0
  96. package/run/history-outcomes.js +78 -0
  97. package/run/history-outcomes.js.map +1 -0
  98. package/run/history-pruning.js +97 -0
  99. package/run/history-pruning.js.map +1 -0
  100. package/run/history-reader.js +32 -0
  101. package/run/history-reader.js.map +1 -0
  102. package/run/history-record.js +48 -0
  103. package/run/history-record.js.map +1 -0
  104. package/run/history-repair.d.ts +7 -0
  105. package/run/history-repair.d.ts.map +1 -0
  106. package/run/history-repair.js +158 -0
  107. package/run/history-repair.js.map +1 -0
  108. package/run/history-retention-records.js +130 -0
  109. package/run/history-retention-records.js.map +1 -0
  110. package/run/history-state-access.js +147 -0
  111. package/run/history-state-access.js.map +1 -0
  112. package/run/history-state-error.js +35 -0
  113. package/run/history-state-error.js.map +1 -0
  114. package/run/history-storage-types.d.ts +11 -0
  115. package/run/history-storage-types.d.ts.map +1 -0
  116. package/run/history-storage.js +55 -0
  117. package/run/history-storage.js.map +1 -0
  118. package/run/history-types.d.ts +36 -0
  119. package/run/history-types.d.ts.map +1 -0
  120. package/run/history.d.ts +3 -0
  121. package/run/history.d.ts.map +1 -0
  122. package/run/history.js +97 -0
  123. package/run/history.js.map +1 -0
  124. package/run/local-run-collection.js +31 -0
  125. package/run/local-run-collection.js.map +1 -0
  126. package/run/node-history-storage.js +118 -0
  127. package/run/node-history-storage.js.map +1 -0
  128. package/run/node-run-execution.js +2 -0
  129. package/run/node-run-execution.js.map +1 -1
  130. package/run/prepared-run.js +42 -0
  131. package/run/prepared-run.js.map +1 -0
  132. package/run/property-evidence-schema.js +46 -0
  133. package/run/property-evidence-schema.js.map +1 -0
  134. package/run/recorded-coverage-run.js +2 -12
  135. package/run/recorded-coverage-run.js.map +1 -1
  136. package/run/recorded-run.js +32 -0
  137. package/run/recorded-run.js.map +1 -0
  138. package/run/reporter-event-schema.js +3 -0
  139. package/run/reporter-event-schema.js.map +1 -1
  140. package/run/request-snapshot.js +1 -0
  141. package/run/request-snapshot.js.map +1 -1
  142. package/run/run-artifact-schema.d.ts.map +1 -1
  143. package/run/run-artifact-schema.js +2 -0
  144. package/run/run-artifact-schema.js.map +1 -1
  145. package/run/run-collected-resolution.js +3 -3
  146. package/run/run-collected-resolution.js.map +1 -1
  147. package/run/run-execution.js +21 -49
  148. package/run/run-execution.js.map +1 -1
  149. package/run/run-facts.js +54 -1
  150. package/run/run-facts.js.map +1 -1
  151. package/run/run-if-main.d.ts.map +1 -1
  152. package/run/run-if-main.js +2 -0
  153. package/run/run-if-main.js.map +1 -1
  154. package/run/run-isolated-process.js +11 -2
  155. package/run/run-isolated-process.js.map +1 -1
  156. package/run/run-local-command.js +13 -33
  157. package/run/run-local-command.js.map +1 -1
  158. package/run/run-local-planning.js +5 -5
  159. package/run/run-local-planning.js.map +1 -1
  160. package/run/run-local-resolution.js +0 -4
  161. package/run/run-local-resolution.js.map +1 -1
  162. package/run/run-operations.js +1 -0
  163. package/run/run-operations.js.map +1 -1
  164. package/run/run-orchestrator-dependencies.d.ts +3 -2
  165. package/run/run-orchestrator-dependencies.d.ts.map +1 -1
  166. package/run/run-profile-facts.js +12 -0
  167. package/run/run-profile-facts.js.map +1 -1
  168. package/run/run-record-input.js +13 -0
  169. package/run/run-record-input.js.map +1 -1
  170. package/run/run-record-storage.js +15 -2
  171. package/run/run-record-storage.js.map +1 -1
  172. package/run/run-record.js +57 -19
  173. package/run/run-record.js.map +1 -1
  174. package/run/run-result-schema.d.ts.map +1 -1
  175. package/run/run-result-schema.js +2 -0
  176. package/run/run-result-schema.js.map +1 -1
  177. package/run/run-supervised-process.js +2 -1
  178. package/run/run-supervised-process.js.map +1 -1
  179. package/run/run-support.js +1 -0
  180. package/run/run-support.js.map +1 -1
  181. package/run/run-types.d.ts +5 -3
  182. package/run/run-types.d.ts.map +1 -1
  183. package/run/run-types.js.map +1 -1
  184. package/run/run-validation.js +3 -0
  185. package/run/run-validation.js.map +1 -1
  186. package/run/runtime-attachment-boundary.js +3 -3
  187. package/run/runtime-attachment-boundary.js.map +1 -1
  188. package/run/supervised-protocol.js.map +1 -1
  189. package/run/supervised-run-runtime.js +5 -0
  190. package/run/supervised-run-runtime.js.map +1 -1
  191. package/run/supervised-run-state.js +10 -1
  192. package/run/supervised-run-state.js.map +1 -1
  193. package/run/supervised-run.js +3 -2
  194. package/run/supervised-run.js.map +1 -1
  195. package/run/worker-pool-placement-planning.js.map +1 -1
  196. package/run/worker-pool-run.js +1 -1
  197. package/run/worker-pool-run.js.map +1 -1
  198. package/software-bill-of-materials.cyclonedx.json +26 -9
  199. package/run/attachment-eligibility.js +0 -37
  200. package/run/attachment-eligibility.js.map +0 -1
  201. package/run/duration-history.d.ts +0 -6
  202. package/run/duration-history.d.ts.map +0 -1
@@ -0,0 +1,130 @@
1
+ import { lstat } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { z } from 'zod';
4
+ import { historyStateError } from "./history-state-error.js";
5
+ import { historyRecordSchema } from "./history-record.js";
6
+ import { historyRunStatus } from "./history-outcomes.js";
7
+ import { historyDirectoryNames, compareHistoryRuns, assertHistoryRunId } from "./history-state-access.js";
8
+ const millisecondsPerDay = 86_400_000;
9
+ const manifestSchema = z.object({
10
+ version: z.literal(1),
11
+ id: z.string(),
12
+ startedAt: z.iso.datetime({ offset: true }),
13
+ status: z.enum(['passed', 'failed', 'runner-error', 'interrupted', 'inconclusive'])
14
+ });
15
+ async function artifactMetadata(store, target, fallback, name) {
16
+ const source = await store.read(path.join(target, 'retention.json'));
17
+ const value = source === null ? fallback : JSON.parse(source);
18
+ if (value === undefined) {
19
+ throw new Error(`Missing artifact retention metadata: ${target}`);
20
+ }
21
+ const parsed = manifestSchema.parse(value);
22
+ if (parsed.id !== name) {
23
+ throw new Error(`Artifact identity does not match path: ${target}`);
24
+ }
25
+ return parsed;
26
+ }
27
+ function assertRecordCommitted(record, input) {
28
+ if (record.status !== 'completed') {
29
+ return;
30
+ }
31
+ const cutoff = Date.parse(input.now) - input.policy.staleIdentityRetentionDays * millisecondsPerDay;
32
+ if (Date.parse(record.startedAt) < cutoff) {
33
+ return;
34
+ }
35
+ const receipt = input.index.receipts.find(function (value) {
36
+ return value.id === record.id;
37
+ });
38
+ if (receipt?.state !== 'completed') {
39
+ throw historyStateError(`Run ${record.id} has an incomplete history commit.`);
40
+ }
41
+ }
42
+ async function recordMetadata(input, recordPath) {
43
+ const { store } = input;
44
+ const record = historyRecordSchema.parse(JSON.parse(await store.read(recordPath) ?? 'null'));
45
+ if (path.basename(recordPath) !== `${record.id}.json`) {
46
+ throw new Error(`Record identity does not match path: ${recordPath}`);
47
+ }
48
+ assertRecordCommitted(record, input);
49
+ return manifestSchema.parse({
50
+ version: 1,
51
+ id: record.id,
52
+ startedAt: record.startedAt,
53
+ status: historyRunStatus(record)
54
+ });
55
+ }
56
+ async function readRecords(input, records, retain) {
57
+ for (const recordPath of records) {
58
+ const record = await recordMetadata(input, recordPath);
59
+ retain(record.id, record);
60
+ }
61
+ }
62
+ async function artifactDirectory(input, metadata, retain, name) {
63
+ const target = path.join(input.runs, name);
64
+ const status = await lstat(target);
65
+ if (!status.isDirectory()) {
66
+ return null;
67
+ }
68
+ const parsed = await artifactMetadata(input.store, target, metadata.get(name), name);
69
+ if (!metadata.has(name)) {
70
+ retain(name, parsed);
71
+ }
72
+ return target;
73
+ }
74
+ async function readArtifacts(input, metadata, retain) {
75
+ const names = await historyDirectoryNames(input.runs);
76
+ const directories = await Promise.all(names.map(async function inspectArtifact(name) {
77
+ return await artifactDirectory(input, metadata, retain, name);
78
+ }));
79
+ return directories.filter(function existingDirectory(directory) {
80
+ return directory !== null;
81
+ });
82
+ }
83
+ export async function readRetentionCatalog(input) {
84
+ const metadata = new Map(input.index.summaries.map(function retainedSummary(summary) {
85
+ assertHistoryRunId(summary.id);
86
+ return [summary.id, manifestSchema.parse({ version: 1, ...summary })];
87
+ }));
88
+ function retainRunMetadata(key, value) {
89
+ metadata.set(key, value);
90
+ }
91
+ const records = await input.store.list(input.runs);
92
+ await readRecords(input, records, retainRunMetadata);
93
+ const artifactDirectories = await readArtifacts(input, metadata, retainRunMetadata);
94
+ return { metadata, records, artifactDirectories };
95
+ }
96
+ export function selectHistoryRemovals(catalog, runs, policy, now) {
97
+ const { metadata, records, artifactDirectories } = catalog;
98
+ const ordered = Array.from(metadata.values()).toSorted(compareHistoryRuns);
99
+ const retainedRecords = new Set(ordered
100
+ .filter(function (value) {
101
+ return records.includes(path.join(runs, `${value.id}.json`));
102
+ })
103
+ .slice(0, policy.detailedRunLimit)
104
+ .map(function (value) {
105
+ return value.id;
106
+ }));
107
+ const successful = new Set(ordered
108
+ .filter(function (value) {
109
+ return value.status === 'passed';
110
+ })
111
+ .slice(0, policy.successfulArtifactRunLimit)
112
+ .map(function (value) {
113
+ return value.id;
114
+ }));
115
+ const removedRecords = records.filter(function (value) {
116
+ return !retainedRecords.has(path.basename(value, '.json'));
117
+ });
118
+ const removedArtifacts = artifactDirectories.filter(function expired(target) {
119
+ const value = metadata.get(path.basename(target));
120
+ if (value === undefined) {
121
+ throw new Error(`Missing metadata: ${target}`);
122
+ }
123
+ return value.status === 'passed'
124
+ ? !successful.has(value.id)
125
+ : Date.parse(value.startedAt) <
126
+ Date.parse(now) - policy.failingArtifactRetentionDays * millisecondsPerDay;
127
+ });
128
+ return { retainedRecords, removedRecords, removedArtifacts, successfulRuns: successful };
129
+ }
130
+ //# sourceMappingURL=history-retention-records.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-retention-records.js","sourceRoot":"","sources":["../../../../source/run/history-retention-records.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,147 @@
1
+ import { readdir, lstat, realpath, rm } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { hostname } from 'node:os';
4
+ import lockfile from 'proper-lockfile';
5
+ import { z } from 'zod';
6
+ import { RunCollectionError } from "./run-errors.js";
7
+ import { createNodeHistoryStorage } from "./node-history-storage.js";
8
+ function ownerAlive(pid) {
9
+ try {
10
+ process.kill(pid, 0);
11
+ return true;
12
+ }
13
+ catch (error) {
14
+ if (error instanceof Error && Reflect.get(error, 'code') === 'ESRCH') {
15
+ return false;
16
+ }
17
+ throw error;
18
+ }
19
+ }
20
+ async function assertOwnerInactive(store, ownerPath, options) {
21
+ const owner = z
22
+ .object({ pid: z.number().int().positive(), host: z.string() })
23
+ .parse(JSON.parse(await store.read(ownerPath) ?? 'null'));
24
+ if (owner.host !== hostname()) {
25
+ const live = await lockfile.check(ownerPath, {
26
+ lockfilePath: `${ownerPath}.lease`,
27
+ stale: options.config.history.staleLockMilliseconds
28
+ });
29
+ if (live) {
30
+ throw new Error('History is owned by a run on another host.');
31
+ }
32
+ return;
33
+ }
34
+ if (ownerAlive(owner.pid)) {
35
+ throw new Error('Persisted runs are active. Finish them before history maintenance.');
36
+ }
37
+ }
38
+ async function existingStatus(target) {
39
+ try {
40
+ return await lstat(target);
41
+ }
42
+ catch (error) {
43
+ if (error instanceof Error && Reflect.get(error, 'code') === 'ENOENT') {
44
+ return null;
45
+ }
46
+ throw error;
47
+ }
48
+ }
49
+ export async function detailedRecordState(filePath) {
50
+ const status = await existingStatus(filePath);
51
+ if (status === null) {
52
+ return 'pruned';
53
+ }
54
+ return status.isFile() ? 'available' : 'unavailable';
55
+ }
56
+ async function assertNotLinked(target) {
57
+ const status = await existingStatus(target);
58
+ if (status?.isSymbolicLink() === true) {
59
+ throw new Error(`History directory is a symbolic link: ${target}`);
60
+ }
61
+ }
62
+ export async function historyDirectoryNames(directory) {
63
+ try {
64
+ return await readdir(directory);
65
+ }
66
+ catch (error) {
67
+ if (error instanceof Error && Reflect.get(error, 'code') === 'ENOENT') {
68
+ return [];
69
+ }
70
+ throw error;
71
+ }
72
+ }
73
+ function containsProject(directory, projectRoot) {
74
+ const relative = path.relative(directory, projectRoot);
75
+ return relative === '' ||
76
+ relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
77
+ }
78
+ export function createHistoryAccess(options) {
79
+ const directory = path.resolve(options.projectRoot, options.config.runtimeStateDir);
80
+ const policy = options.config.history;
81
+ const store = createNodeHistoryStorage(directory, policy);
82
+ const runs = path.join(directory, 'runs');
83
+ const abandonedOwners = new Set();
84
+ async function guarded(operation) {
85
+ try {
86
+ return await store.withLock(operation);
87
+ }
88
+ catch (error) {
89
+ if (error instanceof RunCollectionError) {
90
+ throw error;
91
+ }
92
+ throw new RunCollectionError(`History operation failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error }, 'runtime-state');
93
+ }
94
+ }
95
+ async function assertIdle() {
96
+ abandonedOwners.clear();
97
+ const listed = await historyDirectoryNames(path.join(directory, 'active-runs'));
98
+ const names = listed.filter(function ownerMetadata(name) {
99
+ return name.endsWith('.json');
100
+ });
101
+ for (const name of names) {
102
+ await assertOwnerInactive(store, path.join(directory, 'active-runs', name), options);
103
+ abandonedOwners.add(name);
104
+ }
105
+ }
106
+ async function assertOwnedLocation() {
107
+ for (const name of ['runs', 'history', 'duration-history', 'active-runs']) {
108
+ const target = path.join(directory, name);
109
+ await assertNotLinked(target);
110
+ }
111
+ const resolved = await realpath(directory);
112
+ if (resolved === path.parse(resolved).root || containsProject(resolved, await realpath(options.projectRoot))) {
113
+ throw new Error('History state must have its own directory.');
114
+ }
115
+ }
116
+ return {
117
+ directory,
118
+ policy,
119
+ store,
120
+ runs,
121
+ guarded,
122
+ assertIdle,
123
+ async removeAbandonedOwners() {
124
+ for (const name of abandonedOwners) {
125
+ const ownerPath = path.join(directory, 'active-runs', name);
126
+ await rm(`${ownerPath}.lease`, { recursive: true, force: true });
127
+ await rm(ownerPath, { force: true });
128
+ }
129
+ },
130
+ assertOwnedLocation,
131
+ diagnostics() {
132
+ return Array.from(abandonedOwners, function (name) {
133
+ return `Abandoned run ownership: ${name}`;
134
+ });
135
+ }
136
+ };
137
+ }
138
+ export function assertHistoryRunId(id) {
139
+ if (id === '' || path.basename(id) !== id || id === '..' || id === '.') {
140
+ throw new Error('Invalid history run identity.');
141
+ }
142
+ }
143
+ export function compareHistoryRuns(left, right) {
144
+ const time = Date.parse(right.startedAt) - Date.parse(left.startedAt);
145
+ return time === 0 ? left.id.localeCompare(right.id) : time;
146
+ }
147
+ //# sourceMappingURL=history-state-access.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-state-access.js","sourceRoot":"","sources":["../../../../source/run/history-state-access.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { RunCollectionError } from "./run-errors.js";
2
+ export function historyStateError(cause) {
3
+ if (cause instanceof RunCollectionError) {
4
+ return cause;
5
+ }
6
+ return new RunCollectionError('History state is unavailable. Run overkill history compact to repair it.', { cause }, 'runtime-state');
7
+ }
8
+ export class UnsupportedHistoryVersionError extends RunCollectionError {
9
+ constructor(version, options) {
10
+ super(`Unsupported history schema version ${version}. Use a compatible Overkill version.`, options, 'runtime-state');
11
+ this.name = 'UnsupportedHistoryVersionError';
12
+ }
13
+ }
14
+ function parsedSchemaVersion(value) {
15
+ if (typeof value !== 'object' || value === null) {
16
+ return null;
17
+ }
18
+ const version = Reflect.get(value, 'version');
19
+ return typeof version === 'number' ? version : null;
20
+ }
21
+ export function historySchemaVersion(source) {
22
+ try {
23
+ return parsedSchemaVersion(JSON.parse(source));
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
29
+ export function assertSupportedHistoryVersion(source, maximum) {
30
+ const version = historySchemaVersion(source);
31
+ if (version !== null && version > maximum) {
32
+ throw new UnsupportedHistoryVersionError(version, { cause: null });
33
+ }
34
+ }
35
+ //# sourceMappingURL=history-state-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-state-error.js","sourceRoot":"","sources":["../../../../source/run/history-state-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC5C,IAAI,KAAK,YAAY,kBAAkB,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,kBAAkB,CACzB,0EAA0E,EAC1E,EAAE,KAAK,EAAE,EACT,eAAe,CAClB,CAAC;AACN,CAAC;AAED,MAAM,OAAO,8BAA+B,SAAQ,kBAAkB;IAClE,YAAmB,OAAe,EAAE,OAA+B;QAC/D,KAAK,CACD,sCAAsC,OAAO,sCAAsC,EACnF,OAAO,EACP,eAAe,CAClB,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IACjD,CAAC;CACJ;AAED,SAAS,mBAAmB,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,OAAO,GAAY,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACvD,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc;IAC/C,IAAI,CAAC;QACD,OAAO,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,MAAc,EAAE,OAAe;IACzE,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;QACxC,MAAM,IAAI,8BAA8B,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC;AACL,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { HistoryPolicy } from '../config/history-policy.ts';
2
+ export type HistoryStorage = {
3
+ readonly beginRun: (id: string) => Promise<() => Promise<void>>;
4
+ readonly list: (directory: string) => Promise<readonly string[]>;
5
+ readonly read: (filePath: string) => Promise<string | null>;
6
+ readonly write: (filePath: string, content: string) => Promise<void>;
7
+ readonly withLock: <T>(operation: () => Promise<T>) => Promise<T>;
8
+ };
9
+ export type RuntimeStateStore = Pick<HistoryStorage, 'read' | 'write'>;
10
+ export type HistoryStorageFactory = (directory: string, policy: HistoryPolicy) => HistoryStorage;
11
+ //# sourceMappingURL=history-storage-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-storage-types.d.ts","sourceRoot":"","sources":["../../../../source/run/history-storage-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,MAAM,cAAc,GAAG;IACzB,QAAQ,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,QAAQ,CAAC,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IACjE,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5D,QAAQ,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CACrE,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;AACvE,MAAM,MAAM,qBAAqB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,KAAK,cAAc,CAAC"}
@@ -0,0 +1,55 @@
1
+ import path from 'node:path';
2
+ import { repairHistory } from "./history-repair.js";
3
+ import { recordDurationContributions } from "./history-outcomes.js";
4
+ import { durationHistoryStateSchema, durationStatePath, emptyDurationState, ingestDurationState, readDurationState } from "./duration-history-storage.js";
5
+ import { emptyCompactHistory, ingestCompactRecord } from "./compact-history.js";
6
+ import { compactHistorySchema } from "./compact-history-schema.js";
7
+ import { historyStateError, historySchemaVersion, assertSupportedHistoryVersion } from "./history-state-error.js";
8
+ async function parsedCompactHistory(store, directory) {
9
+ const content = await store.read(path.join(directory, 'history', 'index.json'));
10
+ if (content === null) {
11
+ return null;
12
+ }
13
+ assertSupportedHistoryVersion(content, 1);
14
+ return compactHistorySchema.parse(JSON.parse(content));
15
+ }
16
+ export async function readCompactHistory(store, directory) {
17
+ try {
18
+ return await parsedCompactHistory(store, directory);
19
+ }
20
+ catch (error) {
21
+ throw historyStateError(error);
22
+ }
23
+ }
24
+ export async function updateCompactHistory(store, record, context) {
25
+ const { directory, policy, now, testFamily } = context;
26
+ const source = await store.read(path.join(directory, 'history', 'index.json'));
27
+ if (source !== null && historySchemaVersion(source) === 0) {
28
+ const retained = {
29
+ ...store,
30
+ async list(recordDirectory) {
31
+ const files = await store.list(recordDirectory);
32
+ return files.filter(function previousRun(filePath) {
33
+ return path.basename(filePath) !== `${record.id}.json`;
34
+ });
35
+ }
36
+ };
37
+ await repairHistory(retained, { directory, policy, now, mode: 'automatic' });
38
+ }
39
+ await store.withLock(async function commitHistory() {
40
+ const current = await readCompactHistory(store, directory) ?? emptyCompactHistory(now);
41
+ if (record.status === 'completed') {
42
+ const state = await readDurationState(store, directory, now) ?? emptyDurationState(now);
43
+ const nextDurations = ingestDurationState(state, recordDurationContributions(record), {
44
+ run: { id: record.id, startedAt: record.startedAt },
45
+ source: 'run',
46
+ policy,
47
+ now
48
+ });
49
+ await store.write(durationStatePath(directory), JSON.stringify(durationHistoryStateSchema.parse(nextDurations)));
50
+ }
51
+ const next = ingestCompactRecord(current, record, { policy, now, testFamily });
52
+ await store.write(path.join(directory, 'history', 'index.json'), `${JSON.stringify(compactHistorySchema.parse(next))}\n`);
53
+ });
54
+ }
55
+ //# sourceMappingURL=history-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-storage.js","sourceRoot":"","sources":["../../../../source/run/history-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { Except } from 'type-fest';
2
+ import type { NormalizedConfig } from '../config/types.ts';
3
+ import type { HistoryRepairResult } from './history-repair.ts';
4
+ import type { HistoryRunSummary as StoredSummary } from './compact-history-schema.ts';
5
+ export type HistoryOptions = {
6
+ readonly projectRoot: string;
7
+ readonly config: Pick<NormalizedConfig, 'history' | 'runtimeStateDir'>;
8
+ };
9
+ export type HistoryRunSummary = Except<StoredSummary, 'replayable'> & {
10
+ readonly replay: 'available' | 'available-interrupted' | 'pruned' | 'unavailable';
11
+ };
12
+ export type HistoryPruneResult = {
13
+ readonly diagnostics: readonly string[];
14
+ readonly kind: 'applied' | 'dry-run';
15
+ readonly paths: readonly string[];
16
+ readonly removedSummaries: number;
17
+ readonly removedCases: number;
18
+ readonly removedWorkEntries: number;
19
+ };
20
+ export type HistoryClearResult = {
21
+ readonly paths: readonly string[];
22
+ readonly diagnostics: readonly string[];
23
+ };
24
+ export type HistoryPruneRequest = {
25
+ readonly dryRun: boolean;
26
+ };
27
+ export type HistoryClearRequest = {
28
+ readonly confirmed: true;
29
+ };
30
+ export type History = {
31
+ readonly list: () => Promise<readonly HistoryRunSummary[]>;
32
+ readonly prune: (request: HistoryPruneRequest) => Promise<HistoryPruneResult>;
33
+ readonly clear: (request: HistoryClearRequest) => Promise<HistoryClearResult>;
34
+ readonly compact: () => Promise<HistoryRepairResult>;
35
+ };
36
+ //# sourceMappingURL=history-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-types.d.ts","sourceRoot":"","sources":["../../../../source/run/history-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,IAAI,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEtF,MAAM,MAAM,cAAc,GAAG;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,iBAAiB,CAAC,CAAC;CAC1E,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,GAAG;IAClE,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,uBAAuB,GAAG,QAAQ,GAAG,aAAa,CAAC;CACrF,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG;IAC7B,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACvC,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAAE,CAAC;AACjH,MAAM,MAAM,mBAAmB,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAAE,CAAC;AAChE,MAAM,MAAM,mBAAmB,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;CAAE,CAAC;AAEhE,MAAM,MAAM,OAAO,GAAG;IAClB,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;IAC3D,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC9E,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC9E,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACxD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { HistoryOptions, History } from './history-types.ts';
2
+ export declare function createHistory(options: HistoryOptions): History;
3
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../../../source/run/history.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACR,cAAc,EAMd,OAAO,EACV,MAAM,oBAAoB,CAAC;AAqB5B,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAsF9D"}
package/run/history.js ADDED
@@ -0,0 +1,97 @@
1
+ import { rm } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { z } from 'zod';
4
+ import { createHistoryAccess, compareHistoryRuns, assertHistoryRunId, detailedRecordState } from "./history-state-access.js";
5
+ import { readCompactHistory } from "./history-storage.js";
6
+ import { historyStateError, historySchemaVersion } from "./history-state-error.js";
7
+ import { repairHistory } from "./history-repair.js";
8
+ import { pruneHistory } from "./history-pruning.js";
9
+ function replayAvailability(availability, replayable, status) {
10
+ if (availability === 'pruned') {
11
+ return 'pruned';
12
+ }
13
+ if (availability === 'unavailable' || !replayable) {
14
+ return 'unavailable';
15
+ }
16
+ return status === 'interrupted' ? 'available-interrupted' : 'available';
17
+ }
18
+ function currentTimestamp() {
19
+ const now = new Date();
20
+ return now.toISOString();
21
+ }
22
+ export function createHistory(options) {
23
+ const { directory, policy, store, runs, guarded, assertIdle, assertOwnedLocation, diagnostics, removeAbandonedOwners } = createHistoryAccess(options);
24
+ async function repair(mode) {
25
+ const result = await repairHistory({
26
+ ...store,
27
+ async withLock(operation) {
28
+ return await guarded(async function repairIdleHistory() {
29
+ await assertOwnedLocation();
30
+ await assertIdle();
31
+ const operationResult = await operation();
32
+ if (mode === 'explicit') {
33
+ await removeAbandonedOwners();
34
+ }
35
+ return operationResult;
36
+ });
37
+ }
38
+ }, { directory, policy, now: currentTimestamp(), mode });
39
+ return { ...result, diagnostics: [...diagnostics(), ...result.diagnostics] };
40
+ }
41
+ return {
42
+ async list() {
43
+ const source = await guarded(async function readHistorySource() {
44
+ return await store.read(path.join(directory, 'history', 'index.json'));
45
+ });
46
+ if (source !== null && historySchemaVersion(source) === 0) {
47
+ await repair('automatic');
48
+ }
49
+ return await guarded(async function listHistory() {
50
+ const index = await readCompactHistory(store, directory);
51
+ if (index === null) {
52
+ throw historyStateError('Compact history is missing.');
53
+ }
54
+ return await Promise.all(index
55
+ .summaries
56
+ .toSorted(compareHistoryRuns)
57
+ .map(async function publicSummary(summary) {
58
+ const { replayable, ...fields } = summary;
59
+ assertHistoryRunId(summary.id);
60
+ const availability = await detailedRecordState(path.join(runs, `${summary.id}.json`));
61
+ const replay = replayAvailability(availability, replayable, summary.status);
62
+ return { ...fields, replay };
63
+ }));
64
+ });
65
+ },
66
+ async compact() {
67
+ return await repair('explicit');
68
+ },
69
+ async clear(request) {
70
+ z.literal(true).parse(request.confirmed);
71
+ return await guarded(async function clearHistory() {
72
+ await assertOwnedLocation();
73
+ await assertIdle();
74
+ const paths = ['runs', 'history', 'duration-history', 'active-runs']
75
+ .map(function ownedPath(name) {
76
+ return path.join(directory, name);
77
+ });
78
+ for (const target of paths) {
79
+ await rm(target, { recursive: true, force: true });
80
+ }
81
+ return { paths, diagnostics: diagnostics() };
82
+ });
83
+ },
84
+ async prune(request) {
85
+ return await guarded(async function pruneIdleHistory() {
86
+ await assertOwnedLocation();
87
+ await assertIdle();
88
+ const result = await pruneHistory({ directory, policy, store }, request);
89
+ if (!request.dryRun) {
90
+ await removeAbandonedOwners();
91
+ }
92
+ return { ...result, diagnostics: diagnostics() };
93
+ });
94
+ }
95
+ };
96
+ }
97
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../../../source/run/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { createResultFromResolutionError } from "./run-collection-error-result.js";
2
+ import { createLocalRunOrEmptySelectionResultFromInput } from "./run-local-resolution.js";
3
+ import { emptyTimingSpanMetadata } from "./run-timing-collection.js";
4
+ export function isRunResult(value) {
5
+ return Object.hasOwn(value, 'summary');
6
+ }
7
+ async function resolveRunWithRuntimePolicy(resolveRun, runtimePolicy) {
8
+ return runtimePolicy === null ? await resolveRun() : await runtimePolicy.runLoad(resolveRun);
9
+ }
10
+ export async function createLocalRunResult(command, dependencies, runtimePolicy, options) {
11
+ const resolveRun = async function resolveLocalRunInsidePolicy() {
12
+ return await options.timing.measureAsync('collection.resolve', emptyTimingSpanMetadata(), async function createTimedLocalRunOrEmptySelectionResult() {
13
+ const resolved = await createLocalRunOrEmptySelectionResultFromInput(command, dependencies, options.input, options.source);
14
+ await options.record?.recordFacts(resolved.facts);
15
+ return resolved.run;
16
+ });
17
+ };
18
+ try {
19
+ return await resolveRunWithRuntimePolicy(resolveRun, runtimePolicy);
20
+ }
21
+ catch (error) {
22
+ try {
23
+ return createResultFromResolutionError(error, runtimePolicy);
24
+ }
25
+ catch {
26
+ runtimePolicy?.takeRunErrors();
27
+ throw error;
28
+ }
29
+ }
30
+ }
31
+ //# sourceMappingURL=local-run-collection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-run-collection.js","sourceRoot":"","sources":["../../../../source/run/local-run-collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AAEnF,OAAO,EACH,6CAA6C,EAEhD,MAAM,2BAA2B,CAAC;AAInC,OAAO,EAAE,uBAAuB,EAA6B,MAAM,4BAA4B,CAAC;AAYhG,MAAM,UAAU,WAAW,CAAC,KAA8B;IACtD,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AAC3C,CAAC;AAED,KAAK,UAAU,2BAA2B,CACtC,UAAmC,EACnC,aAAsC;IAEtC,OAAO,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AACjG,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACtC,OAAmB,EACnB,YAAyC,EACzC,aAAsC,EACtC,OAAwB;IAExB,MAAM,UAAU,GAAG,KAAK,UAAU,2BAA2B;QACzD,OAAO,MAAM,OAAO,CAAC,MAAM,CAAC,YAAY,CACpC,oBAAoB,EACpB,uBAAuB,EAAE,EACzB,KAAK,UAAU,yCAAyC;YACpD,MAAM,QAAQ,GAAG,MAAM,6CAA6C,CAChE,OAAO,EACP,YAAY,EACZ,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,MAAM,CACjB,CAAC;YACF,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAClD,OAAO,QAAQ,CAAC,GAAG,CAAC;QACxB,CAAC,CACJ,CAAC;IACN,CAAC,CAAC;IAEF,IAAI,CAAC;QACD,OAAO,MAAM,2BAA2B,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACtB,IAAI,CAAC;YACD,OAAO,+BAA+B,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;QACjE,CAAC;QAAC,MAAM,CAAC;YACL,aAAa,EAAE,aAAa,EAAE,CAAC;YAC/B,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;AACL,CAAC"}