@orkestrel/probe 0.0.24 → 0.0.25
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.
|
@@ -14,6 +14,7 @@ let node_events = require("node:events");
|
|
|
14
14
|
let _orkestrel_timeout = require("@orkestrel/timeout");
|
|
15
15
|
let _orkestrel_lsp_server = require("@orkestrel/lsp/server");
|
|
16
16
|
let node_stream = require("node:stream");
|
|
17
|
+
let node_async_hooks = require("node:async_hooks");
|
|
17
18
|
let node_child_process = require("node:child_process");
|
|
18
19
|
let _orkestrel_mcp_server = require("@orkestrel/mcp/server");
|
|
19
20
|
let _orkestrel_tool = require("@orkestrel/tool");
|
|
@@ -533,6 +534,8 @@ function readWorkspaceManifest(workspace, name) {
|
|
|
533
534
|
* @remarks
|
|
534
535
|
* A package publishes its binaries under keys of its own choosing, and that key is often not the
|
|
535
536
|
* package name: `typescript` publishes `tsc`. Name the key as `command` wherever the two differ.
|
|
537
|
+
* Resolution reads `package.json` and its `bin` field, so TypeScript 6 and 7 need no exported
|
|
538
|
+
* `typescript/bin/tsc` subpath.
|
|
536
539
|
* Default: the package name.
|
|
537
540
|
*
|
|
538
541
|
* @param workspace - The target workspace root
|
|
@@ -975,7 +978,7 @@ function captureListeners(emitter, events) {
|
|
|
975
978
|
*/
|
|
976
979
|
function releaseListeners(emitter, capture) {
|
|
977
980
|
for (const [event, captured] of capture) for (const listener of emitter.listeners(event)) {
|
|
978
|
-
if (captured.includes(listener)) continue;
|
|
981
|
+
if (captured.includes(listener) || !(0, _orkestrel_contract.isFunction)(listener)) continue;
|
|
979
982
|
emitter.removeListener(event, listener);
|
|
980
983
|
}
|
|
981
984
|
}
|
|
@@ -1124,10 +1127,10 @@ var Overlay = class {
|
|
|
1124
1127
|
};
|
|
1125
1128
|
//#endregion
|
|
1126
1129
|
//#region package.json
|
|
1127
|
-
var version = "0.0.
|
|
1130
|
+
var version = "0.0.25";
|
|
1128
1131
|
var peerDependencies = {
|
|
1129
|
-
"typescript": "^6.0.3",
|
|
1130
|
-
"vitest": "^4.1.12"
|
|
1132
|
+
"typescript": "^6.0.3 || ^7.0.2",
|
|
1133
|
+
"vitest": "^4.1.12 || ^5.0.5"
|
|
1131
1134
|
};
|
|
1132
1135
|
//#endregion
|
|
1133
1136
|
//#region src/server/stages/LintStage.ts
|
|
@@ -1349,6 +1352,11 @@ var LintStage = class {
|
|
|
1349
1352
|
* Inspects tests through one resident Vitest service from the target workspace.
|
|
1350
1353
|
*
|
|
1351
1354
|
* @remarks
|
|
1355
|
+
* Vitest 4.1.12 and 5.0.5 share the mode-first `createVitest` overload used by this stage.
|
|
1356
|
+
* Result eviction removes one file from Vitest 4's results cache. Vitest 5 exposes only a full
|
|
1357
|
+
* cache clear, so eviction clears its results, dependency, and filesystem module caches.
|
|
1358
|
+
* Warming removes termination handlers registered within the factory's async context before
|
|
1359
|
+
* signal delivery, while retaining handlers the host registers outside that context.
|
|
1352
1360
|
* Starting launches Vitest with the threads pool and instruments each inline or function-declared
|
|
1353
1361
|
* project with a Vite plugin that reads the active inspection's candidate overlay. A selected
|
|
1354
1362
|
* string-declared project reports a workspace issue because its configuration carries no runtime
|
|
@@ -1573,38 +1581,46 @@ var RuntimeStage = class {
|
|
|
1573
1581
|
this.#sweep();
|
|
1574
1582
|
const output = new node_stream.PassThrough();
|
|
1575
1583
|
output.resume();
|
|
1584
|
+
const scope = new node_async_hooks.AsyncLocalStorage();
|
|
1585
|
+
const listener = this.#captureSignal.bind(this, scope);
|
|
1576
1586
|
const signals = captureListeners(process, ["SIGINT", "SIGTERM"]);
|
|
1577
|
-
|
|
1587
|
+
process.on("newListener", listener);
|
|
1578
1588
|
try {
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1589
|
+
return await scope.run(true, () => {
|
|
1590
|
+
try {
|
|
1591
|
+
return factory("test", {
|
|
1592
|
+
root: this.#workspace,
|
|
1593
|
+
config: resolveWorkspaceFile(this.#workspace, "vite.config.ts"),
|
|
1594
|
+
watch: false,
|
|
1595
|
+
run: true,
|
|
1596
|
+
pool: "threads",
|
|
1597
|
+
reporters: [{
|
|
1598
|
+
onInit() {},
|
|
1599
|
+
onTestRunEnd() {}
|
|
1600
|
+
}]
|
|
1601
|
+
}, { plugins: [{
|
|
1602
|
+
name: "orkestrel-project-instrumentation",
|
|
1603
|
+
enforce: "post",
|
|
1604
|
+
config: this.#configure.bind(this)
|
|
1605
|
+
}] }, {
|
|
1606
|
+
stdout: output,
|
|
1607
|
+
stderr: process.stderr
|
|
1608
|
+
});
|
|
1609
|
+
} finally {
|
|
1610
|
+
releaseListeners(process, signals);
|
|
1611
|
+
}
|
|
1596
1612
|
});
|
|
1597
1613
|
} catch (error) {
|
|
1598
1614
|
throw this.#configuration(error);
|
|
1599
1615
|
} finally {
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
try {
|
|
1603
|
-
return await warming;
|
|
1604
|
-
} catch (error) {
|
|
1605
|
-
throw this.#configuration(error);
|
|
1616
|
+
process.off("newListener", listener);
|
|
1617
|
+
scope.disable();
|
|
1606
1618
|
}
|
|
1607
1619
|
}
|
|
1620
|
+
#captureSignal(scope, event, listener) {
|
|
1621
|
+
if (scope.getStore() !== true || event !== "SIGINT" && event !== "SIGTERM") return;
|
|
1622
|
+
queueMicrotask(() => process.off(event, listener));
|
|
1623
|
+
}
|
|
1608
1624
|
#configure(config) {
|
|
1609
1625
|
const test = config.test;
|
|
1610
1626
|
if (test?.projects === void 0) return;
|
|
@@ -1798,8 +1814,16 @@ var RuntimeStage = class {
|
|
|
1798
1814
|
}
|
|
1799
1815
|
vitest.watcher.onFileDelete(file);
|
|
1800
1816
|
vitest.watcher.invalidates.delete(file);
|
|
1801
|
-
vitest.cache.results
|
|
1802
|
-
|
|
1817
|
+
const results = "results" in vitest.cache ? vitest.cache.results : void 0;
|
|
1818
|
+
if ((0, _orkestrel_contract.isObject)(results) && "removeFromCache" in results && typeof results.removeFromCache === "function" && "writeToCache" in results && typeof results.writeToCache === "function") {
|
|
1819
|
+
results.removeFromCache(normalizePath((0, node_path.relative)(this.#workspace, file)));
|
|
1820
|
+
await results.writeToCache();
|
|
1821
|
+
} else if ("clearCache" in vitest && typeof vitest.clearCache === "function") await vitest.clearCache();
|
|
1822
|
+
else throw new _src_core.ProbeError("Vitest exposes no cache eviction API", {
|
|
1823
|
+
origin: "instrument",
|
|
1824
|
+
code: "malformed",
|
|
1825
|
+
context: { stage: this.stage }
|
|
1826
|
+
});
|
|
1803
1827
|
return [];
|
|
1804
1828
|
} catch (error) {
|
|
1805
1829
|
return [{
|
|
@@ -2008,6 +2032,8 @@ var RuntimeStage = class {
|
|
|
2008
2032
|
* Inspects TypeScript source by running the target workspace's own compiler over a mirror of it.
|
|
2009
2033
|
*
|
|
2010
2034
|
* @remarks
|
|
2035
|
+
* TypeScript 6 and 7 run through the `tsc` entry in their package manifest; neither a compiler API
|
|
2036
|
+
* nor an exported binary subpath is required.
|
|
2011
2037
|
* The compiler is a process this stage spawns rather than a module it loads, so nothing here holds
|
|
2012
2038
|
* a resident program and the host's event loop is free for the whole check. Starting sweeps a
|
|
2013
2039
|
* mirror an earlier host left behind, copies the workspace into a fresh one under
|
|
@@ -2045,6 +2071,7 @@ var TypeStage = class {
|
|
|
2045
2071
|
#revision = `${process.pid}-${(0, node_crypto.randomUUID)()}`;
|
|
2046
2072
|
#mirror;
|
|
2047
2073
|
#configs = /* @__PURE__ */ new Map();
|
|
2074
|
+
#validated = /* @__PURE__ */ new Set();
|
|
2048
2075
|
#mirrored = /* @__PURE__ */ new Map();
|
|
2049
2076
|
#drafts = /* @__PURE__ */ new Set();
|
|
2050
2077
|
#children = /* @__PURE__ */ new Set();
|
|
@@ -2098,6 +2125,8 @@ var TypeStage = class {
|
|
|
2098
2125
|
* refreshed from the workspace first on a cache miss, so the digest names the configuration the
|
|
2099
2126
|
* check applies. The reading is cached per project for the life of the stage, so a draft written
|
|
2100
2127
|
* afterward cannot move it.
|
|
2128
|
+
* Before returning the identity, validates the project with `--noEmit` unless an unoverlaid check
|
|
2129
|
+
* already validated it. TypeScript 7's `--showConfig` can succeed for a malformed project.
|
|
2101
2130
|
*
|
|
2102
2131
|
* @param project - The workspace-relative TypeScript project to resolve
|
|
2103
2132
|
* @returns The resolved workspace-relative path and the digest of its compiler options
|
|
@@ -2157,6 +2186,10 @@ var TypeStage = class {
|
|
|
2157
2186
|
const contained = this.#contain(project);
|
|
2158
2187
|
this.#progress += 1;
|
|
2159
2188
|
const config = await this.#configure(contained);
|
|
2189
|
+
if (!this.#validated.has(contained)) {
|
|
2190
|
+
this.#refresh();
|
|
2191
|
+
await this.#check(contained, []);
|
|
2192
|
+
}
|
|
2160
2193
|
return {
|
|
2161
2194
|
path: contained,
|
|
2162
2195
|
digest: computeDigest(this.#workspace, config.compilerOptions)
|
|
@@ -2176,6 +2209,7 @@ var TypeStage = class {
|
|
|
2176
2209
|
});
|
|
2177
2210
|
} catch {}
|
|
2178
2211
|
this.#configs.clear();
|
|
2212
|
+
this.#validated.clear();
|
|
2179
2213
|
this.#mirrored.clear();
|
|
2180
2214
|
this.#drafts.clear();
|
|
2181
2215
|
}
|
|
@@ -2349,7 +2383,9 @@ var TypeStage = class {
|
|
|
2349
2383
|
}
|
|
2350
2384
|
});
|
|
2351
2385
|
}
|
|
2352
|
-
|
|
2386
|
+
const issues = this.#issues(diagnostics, project, scratch);
|
|
2387
|
+
if (this.#drafts.size === 0) this.#validated.add(this.#contain(project));
|
|
2388
|
+
return issues;
|
|
2353
2389
|
}
|
|
2354
2390
|
#scratch(project, config, drafts) {
|
|
2355
2391
|
const directory = (0, node_path.dirname)(project);
|
|
@@ -2374,13 +2410,13 @@ var TypeStage = class {
|
|
|
2374
2410
|
(0, node_fs.writeFileSync)(target, `${JSON.stringify(body, void 0, " ")}\n`, "utf8");
|
|
2375
2411
|
return contained;
|
|
2376
2412
|
}
|
|
2377
|
-
#issues(diagnostics, project) {
|
|
2413
|
+
#issues(diagnostics, project, scratch) {
|
|
2378
2414
|
const issues = [];
|
|
2379
2415
|
for (const diagnostic of diagnostics) {
|
|
2380
2416
|
const message = this.#translate(diagnostic.message);
|
|
2381
2417
|
const resolved = diagnostic.path === void 0 ? void 0 : (0, node_path.resolve)(this.#mirror, diagnostic.path);
|
|
2382
2418
|
const drafted = resolved !== void 0 && this.#drafts.has(escapesRoot(this.#mirror, resolved) ? relativeWorkspaceFile(this.#workspace, resolved) : relativeWorkspaceFile(this.#mirror, resolved));
|
|
2383
|
-
if (resolved === void 0 || !drafted && (0, node_path.extname)(resolved) === ".json") throw new _src_core.ProbeError(message, {
|
|
2419
|
+
if (resolved === void 0 || !drafted && (0, node_path.extname)(resolved) === ".json") throw new _src_core.ProbeError(message.replaceAll(normalizePath(scratch), normalizePath(project)), {
|
|
2384
2420
|
origin: "workspace",
|
|
2385
2421
|
code: "malformed",
|
|
2386
2422
|
context: {
|
|
@@ -2490,6 +2526,8 @@ var TypeStage = class {
|
|
|
2490
2526
|
* Answers claims through its type, lint, and runtime stages.
|
|
2491
2527
|
*
|
|
2492
2528
|
* @remarks
|
|
2529
|
+
* The workspace peers are TypeScript `^6.0.3 || ^7.0.2` and Vitest `^4.1.12 || ^5.0.5`.
|
|
2530
|
+
* Starting refuses TypeScript majors outside 6 and 7 before a stage starts.
|
|
2493
2531
|
* Construction resolves the target workspace's toolchain. Starting warms every stage and waits
|
|
2494
2532
|
* for lint and runtime; type warming and the boot controls continue behind that gate. The boot
|
|
2495
2533
|
* controls mutate imported dependencies and refuse service unless the type and runtime stages
|
|
@@ -2538,7 +2576,7 @@ var TypeStage = class {
|
|
|
2538
2576
|
* const probe = new Probe({ workspace: process.cwd() })
|
|
2539
2577
|
* const verdict = await probe.prove(claim)
|
|
2540
2578
|
* verdict.digest // 'bdf03e5dfd6bd413ead671c7a2940fcf'
|
|
2541
|
-
* verdict.receipt //
|
|
2579
|
+
* verdict.receipt?.startsWith(`probe:${verdict.digest}:type:`) // true
|
|
2542
2580
|
* await probe.destroy()
|
|
2543
2581
|
* ```
|
|
2544
2582
|
*/
|
|
@@ -3014,9 +3052,9 @@ var Probe = class {
|
|
|
3014
3052
|
#support() {
|
|
3015
3053
|
const version = this.#toolchain.typescript;
|
|
3016
3054
|
const range = peerDependencies.typescript;
|
|
3017
|
-
const supported = /^\^(\d+)\./u.exec(range)?.[1];
|
|
3018
3055
|
const found = /^(\d+)\./u.exec(version)?.[1];
|
|
3019
|
-
|
|
3056
|
+
const supported = range.split(" || ").some((entry) => /^\^(\d+)\./u.exec(entry)?.[1] === found);
|
|
3057
|
+
if (found === void 0 || !supported) throw new _src_core.ProbeError(`The supported TypeScript range is ${range}; found ${version}`, {
|
|
3020
3058
|
origin: "workspace",
|
|
3021
3059
|
code: "malformed",
|
|
3022
3060
|
context: {
|