@orkestrel/probe 0.0.26 → 0.0.28

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.
@@ -5,14 +5,14 @@ import { createHash, randomUUID } from "node:crypto";
5
5
  import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
6
6
  import { fileURLToPath, pathToFileURL } from "node:url";
7
7
  import { attempt, compileGuard, compileSchema, isArray, isError, isFunction, isNumber, isObject, isRecord, isString, parseJSON, schemaToParameters } from "@orkestrel/contract";
8
- import { CLAIM_SHAPE, LINT_DEADLINE, LINT_TEARDOWN, PROBE_DEADLINE, PROBE_KEYS, PROBE_RESTARTS, PROBE_SPECIFICATIONS, PROBE_WARM, ProbeError, RUNTIME_PLUGIN, TYPE_MIRROR, computeReceipt, createDestroyedError, formatCheck, formatReceipt, formatSpecification, formatVerdict, isClaim, isDraft, isProbeError, isVerdict, matchesSpecification } from "../core/index.js";
8
+ import { CLAIM_SHAPE, LINT_DEADLINE, LINT_TEARDOWN, PROBE_DEADLINE, PROBE_KEYS, PROBE_RESTARTS, PROBE_SPECIFICATIONS, PROBE_WARM, ProbeError, RUNTIME_PLUGIN, TYPE_MIRROR, computeReceipt, createDestroyedError, formatReceipt, formatSpecification, formatStageResult, formatVerdict, isClaim, isDraft, isProbeError, isVerdict, matchesSpecification } from "../core/index.js";
9
9
  import { inspectProcess, killTree } from "@orkestrel/process/server";
10
10
  import { Emitter } from "@orkestrel/emitter";
11
11
  import { createPool, isPoolError } from "@orkestrel/pool";
12
12
  import { createLSPClient, isLSPError } from "@orkestrel/lsp";
13
13
  import { addAbortListener } from "node:events";
14
14
  import { createTimeout } from "@orkestrel/timeout";
15
- import { createStdioClientTransport } from "@orkestrel/lsp/server";
15
+ import { createLSPStdioTransport } from "@orkestrel/lsp/server";
16
16
  import { PassThrough } from "node:stream";
17
17
  import { AsyncLocalStorage } from "node:async_hooks";
18
18
  import { spawn } from "node:child_process";
@@ -729,8 +729,12 @@ function matchesLiveProcess(id) {
729
729
  * Collects every regular file a target workspace holds, skipping the trees no inspection reads.
730
730
  *
731
731
  * @remarks
732
- * Skips a directory named `.git`, `dist`, or `node_modules` at any depth, and the directory
733
- * {@link TYPE_MIRROR} names, which would otherwise carry this package's own mirror into the walk. A
732
+ * Skips a directory named `.git`, `dist`, or `node_modules` at any depth. Of the workspace-root
733
+ * `tmp` directory it walks only `tmp/probes`: the scaffold tmp layout holds the runtime probes there
734
+ * and nothing else an inspection reads, so a consumer's ignored data under `tmp/` is never read or
735
+ * copied. The match is the lowercase `tmp` spelling exactly, and a `tmp` directory below the root is
736
+ * walked like any other. The directory {@link TYPE_MIRROR} names is skipped as well, so this
737
+ * package's own mirror stays out of the walk if it ever moves outside `tmp`. A
734
738
  * directory this host cannot list is skipped rather than raised, so one unreadable directory in a
735
739
  * consumer's tree is not a reason to refuse the whole walk. A symbolic link is not carried, whether
736
740
  * it names a file or a directory, so a file reached only through one is absent from the result; a
@@ -747,7 +751,9 @@ function matchesLiveProcess(id) {
747
751
  function collectWorkspaceFiles(workspace) {
748
752
  const excluded = normalizePath(resolveWorkspaceFile(workspace, TYPE_MIRROR));
749
753
  const files = [];
750
- const directories = [resolve(workspace)];
754
+ const root = resolve(workspace);
755
+ const scratch = join(root, "tmp");
756
+ const directories = [root];
751
757
  while (directories.length > 0) {
752
758
  const directory = directories.pop();
753
759
  if (directory === void 0) break;
@@ -755,6 +761,7 @@ function collectWorkspaceFiles(workspace) {
755
761
  const entries = reading.success ? reading.value : [];
756
762
  for (const entry of entries) {
757
763
  if (entry.name === ".git" || entry.name === "dist" || entry.name === "node_modules") continue;
764
+ if (directory === scratch && entry.name !== "probes") continue;
758
765
  const path = join(directory, entry.name);
759
766
  if (entry.isDirectory()) {
760
767
  if (normalizePath(path) !== excluded) directories.push(path);
@@ -814,12 +821,12 @@ async function guardStage(stage, operation) {
814
821
  *
815
822
  * @remarks
816
823
  * The published claim schema constrains `Draft.path` to a non-empty string and nothing else, while
817
- * `isDraft` also refuses an absolute path and one that escapes the workspace. That one member is
818
- * the whole of the difference between the advertised contract and the enforced one, so a caller
819
- * refused after satisfying the schema is refused here and nowhere else. The whole input must first
820
- * satisfy that schema. Each draft is then tested with `isDraft` itself rather than with a second
821
- * copy of its rule. Reports nothing for a value carrying no draft member, including one refused for
822
- * a member this contract does not declare.
824
+ * `isDraft` also refuses an absolute path and one that resolves outside the workspace. That one
825
+ * member is the whole of the difference between the advertised contract and the enforced one, so a
826
+ * caller refused after satisfying the schema is refused here and nowhere else. The whole input must
827
+ * first satisfy that schema. Each draft is then tested with `isDraft` itself rather than with a
828
+ * second copy of its rule. Reports nothing for a value carrying no draft member, including one
829
+ * refused for a member this contract does not declare.
823
830
  *
824
831
  * This function lives in the server helpers rather than in core: core's leaf pair, `helpers.ts` and
825
832
  * `validators.ts`, may not consume the shapes module this function reads `CLAIM_SHAPE` from, and
@@ -854,10 +861,11 @@ function findRefusedPaths(value) {
854
861
  * `tsc --showConfig` spells a path relative to the project file, so a printed record carries an
855
862
  * absolute path only where a project itself declares one. Rewriting a contained absolute path to
856
863
  * its relative form keeps one commit checked out at two roots reading to one digest. A path that
857
- * escapes the workspace is left as it stands, because rewriting it would name a file outside the
858
- * tree by a relative spelling. Key order is the compiler's own and it differs between the supported
859
- * majors, so sorting removes a difference that means nothing. A `__proto__` key is dropped, as
860
- * the earlier assignment-built record dropped it, so a digest stays the same across releases.
864
+ * resolves outside the workspace is left as it stands, because rewriting it would name a file
865
+ * outside the tree by a relative spelling. Key order is the compiler's own and it differs between
866
+ * the supported majors, so sorting removes a difference that means nothing. A `__proto__` key is
867
+ * dropped, as the earlier assignment-built record dropped it, so a digest stays the same across
868
+ * releases.
861
869
  *
862
870
  * @param workspace - The target workspace root
863
871
  * @param value - The value to rewrite
@@ -896,10 +904,10 @@ function normalizeValue(workspace, value) {
896
904
  *
897
905
  * @example
898
906
  * ```ts
899
- * computeDigest('/srv/checkout', { strict: true }).length // 32
907
+ * computeWorkspaceDigest('/srv/checkout', { strict: true }).length // 32
900
908
  * ```
901
909
  */
902
- function computeDigest(workspace, value) {
910
+ function computeWorkspaceDigest(workspace, value) {
903
911
  return createHash("sha256").update(JSON.stringify(normalizeValue(workspace, value))).digest("hex").slice(0, 32);
904
912
  }
905
913
  /**
@@ -1093,7 +1101,7 @@ var Overlay = class {
1093
1101
  }
1094
1102
  };
1095
1103
  // package.json
1096
- var version = "0.0.26";
1104
+ var version = "0.0.28";
1097
1105
  var peerDependencies = {
1098
1106
  "typescript": "^6.0.3 || ^7.0.2",
1099
1107
  "vitest": "^4.1.12 || ^5.0.5"
@@ -1104,7 +1112,7 @@ var peerDependencies = {
1104
1112
  *
1105
1113
  * @remarks
1106
1114
  * Starting launches the target workspace's Oxlint binary with its Language Server Protocol mode
1107
- * and hands the conversation to `@orkestrel/lsp`: `createStdioClientTransport` owns the child
1115
+ * and hands the conversation to `@orkestrel/lsp`: `createLSPStdioTransport` owns the child
1108
1116
  * process and its bytes, and `createLSPClient` owns the framing, the request correlation, the
1109
1117
  * capabilities this stage advertises, and the choice between pulled and pushed diagnostics. This
1110
1118
  * stage owns the workspace, the candidate identity, and the projection from a diagnostic to an
@@ -1132,7 +1140,7 @@ var peerDependencies = {
1132
1140
  * @example
1133
1141
  * ```ts
1134
1142
  * const stage = new LintStage('/srv/checkout')
1135
- * const check = await stage.inspect(subject, { signal: AbortSignal.timeout(30_000) })
1143
+ * const result = await stage.inspect(subject, { signal: AbortSignal.timeout(30_000) })
1136
1144
  * await stage.destroy()
1137
1145
  * ```
1138
1146
  */
@@ -1205,7 +1213,7 @@ var LintStage = class {
1205
1213
  }
1206
1214
  async #warm() {
1207
1215
  const binary = resolveWorkspaceBinary(this.#workspace, "oxlint");
1208
- const transport = createStdioClientTransport({
1216
+ const transport = createLSPStdioTransport({
1209
1217
  server: {
1210
1218
  command: [
1211
1219
  process.execPath,
@@ -1345,10 +1353,10 @@ var LintStage = class {
1345
1353
  * Vitest service after 64 specifications rather than deleting from each map that service owns. Any
1346
1354
  * bound holds the retention flat, because the replacement releases everything the instance held,
1347
1355
  * and 64 is the value chosen. The inspection that crosses the bound pays the replacement
1348
- * synchronously: it closes the resident service and warms a new one before it runs. On 2026-08-20,
1349
- * over this package's own workspace on the host `guides/probe.md` § Cost names, two runs of 66
1350
- * inspections put that one at 480 ms and 269 ms against median inspections of 156 ms and 155 ms, so
1351
- * budget one call in 64 at 110 ms to 330 ms above the rest.
1356
+ * synchronously: it closes the resident service and warms a fresh service before it runs. On
1357
+ * 2026-08-20, over this package's own workspace on the host `guides/probe.md` § Cost names, two
1358
+ * runs of 66 inspections put that one at 480 ms and 269 ms against median inspections of 156 ms and
1359
+ * 155 ms, so budget one call in 64 at 110 ms to 330 ms above the rest.
1352
1360
  *
1353
1361
  * Every issue this stage emits names its party, and the stage emits an issue for every party
1354
1362
  * `Party` declares. An `origin: 'claimant'` issue is a failure Vitest reported about the candidate.
@@ -1373,7 +1381,7 @@ var LintStage = class {
1373
1381
  * @example
1374
1382
  * ```ts
1375
1383
  * const stage = new RuntimeStage('/srv/checkout')
1376
- * const check = await stage.inspect(subject)
1384
+ * const result = await stage.inspect(subject)
1377
1385
  * await stage.destroy()
1378
1386
  * ```
1379
1387
  */
@@ -2019,7 +2027,7 @@ var RuntimeStage = class {
2019
2027
  * @example
2020
2028
  * ```ts
2021
2029
  * const stage = new TypeStage('/srv/checkout')
2022
- * const check = await stage.inspect(subject, 'configs/src/tsconfig.core.json')
2030
+ * const result = await stage.inspect(subject, 'configs/src/tsconfig.core.json')
2023
2031
  * await stage.destroy()
2024
2032
  * ```
2025
2033
  */
@@ -2088,8 +2096,8 @@ var TypeStage = class {
2088
2096
  *
2089
2097
  * @param project - The workspace-relative TypeScript project to resolve
2090
2098
  * @returns The resolved workspace-relative path and the digest of its compiler options
2091
- * @throws When the project escapes the workspace, when the compiler refuses it, or when the
2092
- * stage has already been destroyed
2099
+ * @throws When the project resolves outside the workspace, when the compiler refuses it, or when
2100
+ * the stage has already been destroyed
2093
2101
  */
2094
2102
  resolve(project) {
2095
2103
  return guardStage(this.stage, this.#resolve(project));
@@ -2158,7 +2166,7 @@ var TypeStage = class {
2158
2166
  }
2159
2167
  return {
2160
2168
  path: contained,
2161
- digest: computeDigest(this.#workspace, config.compilerOptions)
2169
+ digest: computeWorkspaceDigest(this.#workspace, config.compilerOptions)
2162
2170
  };
2163
2171
  }
2164
2172
  async #destroy() {
@@ -2609,7 +2617,7 @@ var Probe = class {
2609
2617
  const started = performance.now();
2610
2618
  const id = randomUUID();
2611
2619
  const project = await this.#resolve(claim);
2612
- const digest = computeDigest(this.#workspace, {
2620
+ const digest = computeWorkspaceDigest(this.#workspace, {
2613
2621
  case: claim.case,
2614
2622
  control: claim.control
2615
2623
  });
@@ -2773,21 +2781,21 @@ var Probe = class {
2773
2781
  const beforeType = await this.#inspect(typeClaim.case, typeClaim);
2774
2782
  const beforeRuntime = await this.#inspect(runtimeClaim.case, runtimeClaim);
2775
2783
  const before = [...beforeType, ...beforeRuntime];
2776
- if (before.some((check) => check.issues.length > 0)) throw new ProbeError(`The probe boot control did not begin clean\n${before.map(formatCheck).join("\n")}`, {
2784
+ if (before.some((result) => result.issues.length > 0)) throw new ProbeError(`The probe boot control did not begin clean\n${before.map(formatStageResult).join("\n")}`, {
2777
2785
  origin: "instrument",
2778
2786
  code: "malformed"
2779
2787
  });
2780
2788
  resolveWorkspaceFile(this.#workspace, relative(this.#workspace, typeDependency), true);
2781
2789
  overwriteFile(typeDependency, formatSpecification("export type Signal = number\n", revision));
2782
2790
  const afterType = await this.#inspect(typeClaim.control, typeClaim);
2783
- const type = afterType.find((check) => check.stage === typeClaim.control.stage);
2784
- const tolerant = afterType.find((check) => check.stage === "runtime");
2785
- if (type === void 0 || type.issues.length === 0) throw new ProbeError(`The probe boot type control did not detect a mutated dependency\n${afterType.map(formatCheck).join("\n")}`, {
2791
+ const type = afterType.find((result) => result.stage === typeClaim.control.stage);
2792
+ const tolerant = afterType.find((result) => result.stage === "runtime");
2793
+ if (type === void 0 || type.issues.length === 0) throw new ProbeError(`The probe boot type control did not detect a mutated dependency\n${afterType.map(formatStageResult).join("\n")}`, {
2786
2794
  origin: "instrument",
2787
2795
  code: "malformed",
2788
2796
  context: { stage: typeClaim.control.stage }
2789
2797
  });
2790
- if (tolerant === void 0 || tolerant.issues.length > 0) throw new ProbeError(`The probe boot type control did not remain runtime-clean\n${afterType.map(formatCheck).join("\n")}`, {
2798
+ if (tolerant === void 0 || tolerant.issues.length > 0) throw new ProbeError(`The probe boot type control did not remain runtime-clean\n${afterType.map(formatStageResult).join("\n")}`, {
2791
2799
  origin: "instrument",
2792
2800
  code: "malformed",
2793
2801
  context: { stage: "runtime" }
@@ -2795,8 +2803,8 @@ var Probe = class {
2795
2803
  resolveWorkspaceFile(this.#workspace, relative(this.#workspace, runtimeDependency), true);
2796
2804
  overwriteFile(runtimeDependency, formatSpecification("export const SIGNAL = 'after'\n", revision));
2797
2805
  const afterRuntime = await this.#inspect(runtimeClaim.control, runtimeClaim);
2798
- const runtime = afterRuntime.find((check) => check.stage === runtimeClaim.control.stage);
2799
- if (runtime === void 0 || runtime.issues.length === 0) throw new ProbeError(`The probe boot runtime control did not detect a mutated dependency\n${afterRuntime.map(formatCheck).join("\n")}`, {
2806
+ const runtime = afterRuntime.find((result) => result.stage === runtimeClaim.control.stage);
2807
+ if (runtime === void 0 || runtime.issues.length === 0) throw new ProbeError(`The probe boot runtime control did not detect a mutated dependency\n${afterRuntime.map(formatStageResult).join("\n")}`, {
2800
2808
  origin: "instrument",
2801
2809
  code: "malformed",
2802
2810
  context: { stage: runtimeClaim.control.stage }
@@ -3251,6 +3259,6 @@ var ProbeServer = class {
3251
3259
  ] : [rendered, minimal]).find((arm) => isBoundedJSON(arm, bounds)) ?? minimal;
3252
3260
  }
3253
3261
  };
3254
- export { LintStage, Overlay, Probe, ProbeServer, RuntimeStage, TypeStage, buildRevisionPath, captureListeners, collectWorkspaceFiles, computeDigest, createHandshakeError, describeUnknown, escapesRoot, filterUniqueIssues, findRefusedPaths, guardStage, inferDocumentLanguage, inferTestProject, inferTypeProject, isRefusedName, loadWorkspaceVitest, matchesLiveProcess, matchesWorkspaceModule, normalizePath, normalizeValue, overwriteFile, parseProjectConfig, parseRevisionOwner, readFaultCode, readWorkspaceManifest, relativeWorkspaceFile, relativeWorkspaceMessage, releaseListeners, resolveWorkspaceBinary, resolveWorkspaceFile, resolveWorkspaceModule, scanDiagnostics };
3262
+ export { LintStage, Overlay, Probe, ProbeServer, RuntimeStage, TypeStage, buildRevisionPath, captureListeners, collectWorkspaceFiles, computeWorkspaceDigest, createHandshakeError, describeUnknown, escapesRoot, filterUniqueIssues, findRefusedPaths, guardStage, inferDocumentLanguage, inferTestProject, inferTypeProject, isRefusedName, loadWorkspaceVitest, matchesLiveProcess, matchesWorkspaceModule, normalizePath, normalizeValue, overwriteFile, parseProjectConfig, parseRevisionOwner, readFaultCode, readWorkspaceManifest, relativeWorkspaceFile, relativeWorkspaceMessage, releaseListeners, resolveWorkspaceBinary, resolveWorkspaceFile, resolveWorkspaceModule, scanDiagnostics };
3255
3263
 
3256
3264
  //# sourceMappingURL=index.js.map