no-mistakes 0.102.0 → 0.104.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/index-ci-infra.d.ts +3 -0
- package/index.js +8 -1
- package/index.mjs +1 -0
- package/invocation-errors.js +23 -0
- package/invocation-types.d.ts +45 -0
- package/package.json +6 -5
- package/test-no-live-repository-scan-types.d.ts +29 -0
- package/types.d.ts +1 -0
package/index-ci-infra.d.ts
CHANGED
|
@@ -113,3 +113,6 @@ export function generatePostgresCatalog(
|
|
|
113
113
|
export function analyzeTypeScriptModules(
|
|
114
114
|
options: WithInvocationOptions<TypeScriptModulesOptions>,
|
|
115
115
|
): Promise<WithInvocationResult<TypeScriptModulesReport>>;
|
|
116
|
+
|
|
117
|
+
/** Read-only report of the machine-wide invocation lock; never waits and takes no lock. */
|
|
118
|
+
export function lockStatus(): Promise<import("./invocation-types").LockStatus>;
|
package/index.js
CHANGED
|
@@ -4,6 +4,7 @@ const { resolveNativePackage } = require("./scripts/native-package");
|
|
|
4
4
|
const addonPath = process.env.NO_MISTAKES_TEST_NAPI_ADDON_PATH || resolveNativePackage().addonPath;
|
|
5
5
|
const native = require(addonPath);
|
|
6
6
|
const planning = require("./planning");
|
|
7
|
+
const { decorateInvocationError } = require("./invocation-errors");
|
|
7
8
|
const { writePlanningImpactArtifacts: writeArtifacts } = require("./planning-impact-artifacts");
|
|
8
9
|
const { createPlanningArtifactLock } = require("./planning-impact-artifacts-lock");
|
|
9
10
|
const { createWorkflowTopologyIndex } = require("./workflow-topology-index");
|
|
@@ -11,7 +12,11 @@ const path = require("node:path");
|
|
|
11
12
|
|
|
12
13
|
async function callJson(fn, options) {
|
|
13
14
|
const input = Buffer.from(JSON.stringify(options || {}));
|
|
14
|
-
|
|
15
|
+
try {
|
|
16
|
+
return JSON.parse(await fn(input));
|
|
17
|
+
} catch (error) {
|
|
18
|
+
throw decorateInvocationError(error);
|
|
19
|
+
}
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
function createJsonApis(descriptors) {
|
|
@@ -50,6 +55,7 @@ const jsonApis = createJsonApis({
|
|
|
50
55
|
infraOutputs: "infraOutputsJson",
|
|
51
56
|
infraResourceRefs: "infraResourceRefsJson",
|
|
52
57
|
infraTestFor: "infraTestForJson",
|
|
58
|
+
lockStatus: "lockStatusJson",
|
|
53
59
|
lockfileDiff: "lockfileDiffJson",
|
|
54
60
|
validateMermaidMarkdown: "validateMermaidMarkdownJson",
|
|
55
61
|
playwrightCheck: "playwrightCheckJson",
|
|
@@ -127,6 +133,7 @@ module.exports.writePlanningImpactArtifacts = writePlanningImpactArtifacts;
|
|
|
127
133
|
module.exports.callSites = jsonApis.callSites;
|
|
128
134
|
module.exports.check = jsonApis.check;
|
|
129
135
|
module.exports.resolveConfig = jsonApis.resolveConfig;
|
|
136
|
+
module.exports.lockStatus = jsonApis.lockStatus;
|
|
130
137
|
module.exports.ciEnv = jsonApis.ciEnv;
|
|
131
138
|
module.exports.ciImpact = jsonApis.ciImpact;
|
|
132
139
|
module.exports.ciTopology = ciTopology;
|
package/index.mjs
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const ERROR_JSON_MARKER = "\nno-mistakes-error-json: ";
|
|
4
|
+
|
|
5
|
+
// Lock and deadline failures carry a machine-readable report after a marker line.
|
|
6
|
+
// Expose it as `error.code` ("NO_MISTAKES_LOCK_BUSY", "NO_MISTAKES_LOCK_TIMEOUT",
|
|
7
|
+
// "NO_MISTAKES_DEADLINE") and `error.details` without changing the message text.
|
|
8
|
+
function decorateInvocationError(error) {
|
|
9
|
+
const message = error && typeof error.message === "string" ? error.message : "";
|
|
10
|
+
const at = message.indexOf(ERROR_JSON_MARKER);
|
|
11
|
+
if (at < 0) return error;
|
|
12
|
+
try {
|
|
13
|
+
const details = JSON.parse(message.slice(at + ERROR_JSON_MARKER.length));
|
|
14
|
+
error.message = message.slice(0, at);
|
|
15
|
+
error.code = `NO_MISTAKES_${String(details.kind).toUpperCase()}`;
|
|
16
|
+
error.details = details;
|
|
17
|
+
} catch {
|
|
18
|
+
// Keep the native error as-is when the report cannot be parsed.
|
|
19
|
+
}
|
|
20
|
+
return error;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = { decorateInvocationError };
|
package/invocation-types.d.ts
CHANGED
|
@@ -81,3 +81,48 @@ export interface DiagnosticsProgressSnapshot {
|
|
|
81
81
|
export function diagnosticsSnapshot(options: {
|
|
82
82
|
id: string;
|
|
83
83
|
}): Promise<DiagnosticsProgressSnapshot | null>;
|
|
84
|
+
|
|
85
|
+
/** Who holds the machine-wide invocation lock, as recorded by the holder. */
|
|
86
|
+
export interface LockHolder {
|
|
87
|
+
pid: number;
|
|
88
|
+
/** Working directory of the holder; a pid alone is ambiguous across sandboxes. */
|
|
89
|
+
cwd: string | null;
|
|
90
|
+
/** Executable basename for new records; legacy records may contain arguments. Empty for pid-only records. */
|
|
91
|
+
command: string;
|
|
92
|
+
/** Unix epoch milliseconds when the holder acquired the lock; 0 when unknown. */
|
|
93
|
+
startedAtMs: number;
|
|
94
|
+
/** Whole seconds the lock has been held; null when the start time is unknown. */
|
|
95
|
+
ageSeconds: number | null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Result of `lockStatus()` / `no-mistakes lock status --format json`. */
|
|
99
|
+
export interface LockStatus {
|
|
100
|
+
state: "held" | "free";
|
|
101
|
+
lockFile: string;
|
|
102
|
+
/** Present only while the lock is held. */
|
|
103
|
+
holder: LockHolder | null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Stable `kind` values for invocation failures. */
|
|
107
|
+
export type InvocationErrorKind = "lock_busy" | "lock_timeout" | "deadline";
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The `error` object written to stdout under `--format json`, also exposed as
|
|
111
|
+
* `error.details` on rejected Node API calls. CLI exit codes: `lock_busy` and
|
|
112
|
+
* `lock_timeout` exit 75 (EX_TEMPFAIL); `deadline` exits 124.
|
|
113
|
+
*/
|
|
114
|
+
export interface InvocationErrorDetails {
|
|
115
|
+
kind: InvocationErrorKind;
|
|
116
|
+
/** Phase that was running, for example `invocation.lock` or `check.prepare`. */
|
|
117
|
+
phase: string | null;
|
|
118
|
+
message: string;
|
|
119
|
+
exitCode: 75 | 124;
|
|
120
|
+
/** Present for lock failures when the holder record could be read. */
|
|
121
|
+
holder?: LockHolder;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Rejection from a Node API call that failed on the invocation lock or deadline. */
|
|
125
|
+
export interface InvocationError extends Error {
|
|
126
|
+
code: "NO_MISTAKES_LOCK_BUSY" | "NO_MISTAKES_LOCK_TIMEOUT" | "NO_MISTAKES_DEADLINE";
|
|
127
|
+
details: InvocationErrorDetails;
|
|
128
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "no-mistakes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.104.0",
|
|
4
4
|
"description": "Deterministic impact maps, test plans, Playwright coverage, and repository checks for coding agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"*.d.ts",
|
|
17
17
|
"index.js",
|
|
18
18
|
"index.mjs",
|
|
19
|
+
"invocation-errors.js",
|
|
19
20
|
"planning-impact-artifacts.js",
|
|
20
21
|
"planning-impact-artifacts-errors.js",
|
|
21
22
|
"planning-impact-artifacts-files.js",
|
|
@@ -65,9 +66,9 @@
|
|
|
65
66
|
}
|
|
66
67
|
},
|
|
67
68
|
"optionalDependencies": {
|
|
68
|
-
"no-mistakes-darwin-arm64": "0.
|
|
69
|
-
"no-mistakes-linux-arm64-gnu": "0.
|
|
70
|
-
"no-mistakes-linux-x64-gnu": "0.
|
|
71
|
-
"no-mistakes-win32-x64-msvc": "0.
|
|
69
|
+
"no-mistakes-darwin-arm64": "0.104.0",
|
|
70
|
+
"no-mistakes-linux-arm64-gnu": "0.104.0",
|
|
71
|
+
"no-mistakes-linux-x64-gnu": "0.104.0",
|
|
72
|
+
"no-mistakes-win32-x64-msvc": "0.104.0"
|
|
72
73
|
}
|
|
73
74
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Root selectors shared with `forbidden-calls`; Playwright roots are not accepted. */
|
|
2
|
+
export type TestNoLiveRepositoryScanRoot =
|
|
3
|
+
| { vitest: true | string | string[] }
|
|
4
|
+
| { glob: string | string[] }
|
|
5
|
+
| { file: string }
|
|
6
|
+
| { module: string }
|
|
7
|
+
| { function: { file: string; symbol: string } };
|
|
8
|
+
|
|
9
|
+
/** An import whose call enumerates a directory tree, in addition to the built-in set. */
|
|
10
|
+
export interface TestNoLiveRepositoryScanEnumerator {
|
|
11
|
+
/** Module specifier; a `node:` prefix is ignored. */
|
|
12
|
+
module: string;
|
|
13
|
+
/** Export name; omit to match every export of `module`. */
|
|
14
|
+
export?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Options for `test-no-live-repository-scan`. */
|
|
18
|
+
export interface TestNoLiveRepositoryScanOptions {
|
|
19
|
+
/** Traversal roots. Default: every Vitest project. */
|
|
20
|
+
roots?: TestNoLiveRepositoryScanRoot[];
|
|
21
|
+
/** Glob or globs removed from the root set. */
|
|
22
|
+
excludeRoots?: string | string[];
|
|
23
|
+
/** Path segments marking bounded fixture input; replaces `["fixtures", "__fixtures__"]`. */
|
|
24
|
+
fixtureDirs?: string[];
|
|
25
|
+
/** Extra enumerating imports. */
|
|
26
|
+
enumerators?: TestNoLiveRepositoryScanEnumerator[];
|
|
27
|
+
/** How unresolved scan roots are reported; default: `"advise"`. They are never omitted. */
|
|
28
|
+
unresolvedRoot?: "advise" | "report";
|
|
29
|
+
}
|
package/types.d.ts
CHANGED