@orkestrel/probe 0.0.5 → 0.0.8
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/src/core/index.cjs +12 -4
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +31 -12
- package/dist/src/core/index.d.ts +31 -12
- package/dist/src/core/index.js +12 -4
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +155 -291
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +80 -24
- package/dist/src/server/index.d.ts +80 -24
- package/dist/src/server/index.js +157 -292
- package/dist/src/server/index.js.map +1 -1
- package/package.json +6 -5
|
@@ -202,6 +202,29 @@ export declare interface Inspection {
|
|
|
202
202
|
readonly claim: Claim;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Carries the bound a caller holds over one stage inspection.
|
|
207
|
+
*
|
|
208
|
+
* @remarks
|
|
209
|
+
* `LintStageInterface.inspect` is the only inspection in this package that reads the signal. Its
|
|
210
|
+
* wait is a foreign language server's silence, and abandoning that wait would leave the client
|
|
211
|
+
* holding a pending diagnostics request. The type and runtime stages accept no options and honor no
|
|
212
|
+
* cancellation: a coordinator abandons an overrunning one and replaces it, which is what `Probe`
|
|
213
|
+
* does when its own deadline expires.
|
|
214
|
+
*
|
|
215
|
+
* Supply the signal a coordinator already armed rather than minting a second bound here. A bound
|
|
216
|
+
* minted beside the coordinator's races it, and which one answers then depends on scheduling.
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* const options: InspectionOptions = { signal: AbortSignal.timeout(30_000) }
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
export declare interface InspectionOptions {
|
|
224
|
+
/** Aborts the inspection's wait for the resident tool's answer. */
|
|
225
|
+
readonly signal: AbortSignal;
|
|
226
|
+
}
|
|
227
|
+
|
|
205
228
|
/**
|
|
206
229
|
* Reports whether a fault means the host refuses the name a caller supplied for a file to create.
|
|
207
230
|
*
|
|
@@ -243,13 +266,22 @@ export declare function isRefusedName(file: string, error: unknown): boolean;
|
|
|
243
266
|
* Inspects virtual documents through one resident Oxlint language server.
|
|
244
267
|
*
|
|
245
268
|
* @remarks
|
|
246
|
-
* Construction starts the target workspace's Oxlint binary with its Language Server Protocol
|
|
247
|
-
*
|
|
248
|
-
*
|
|
269
|
+
* Construction starts the target workspace's Oxlint binary with its Language Server Protocol mode
|
|
270
|
+
* and hands the conversation to `@orkestrel/lsp`: `createStdioTransport` owns the child process and
|
|
271
|
+
* its bytes, and `createLSPClient` owns the framing, the request correlation, the capabilities this
|
|
272
|
+
* stage advertises, and the choice between pulled and pushed diagnostics. This stage owns the
|
|
273
|
+
* workspace, the candidate identity, and the projection from a diagnostic to an `Issue`.
|
|
274
|
+
*
|
|
275
|
+
* Each inspection opens the supplied text by URI, waits for the client's diagnostics, and closes the
|
|
276
|
+
* document without writing it to disk. The caller's own signal is what bounds that wait, so a server
|
|
277
|
+
* that admits a document and publishes nothing refuses the inspection when the caller's bound
|
|
278
|
+
* expires rather than holding it for the life of the process. This stage mints no bound of its own
|
|
279
|
+
* for the wait: a second one would race the caller's, and the answer would depend on scheduling.
|
|
249
280
|
*
|
|
250
281
|
* Teardown is bounded at both ends. Warming waits for the server's `initialize` response and the
|
|
251
|
-
* ending waits for its `shutdown` reply, and the protocol leaves both answers to the server, so
|
|
252
|
-
*
|
|
282
|
+
* ending waits for its `shutdown` reply, and the protocol leaves both answers to the server, so the
|
|
283
|
+
* client's deadline bounds each exchange and the transport's cooperative window takes the ending
|
|
284
|
+
* back with a signal when that window passes.
|
|
253
285
|
*
|
|
254
286
|
* The URI is the path the candidate declared, so the candidate receives exactly the rule set the
|
|
255
287
|
* workspace's own lint gate applies to that path, including an override anchored to one directory,
|
|
@@ -262,11 +294,11 @@ export declare function isRefusedName(file: string, error: unknown): boolean;
|
|
|
262
294
|
* @example
|
|
263
295
|
* ```ts
|
|
264
296
|
* const stage = new LintStage('/srv/checkout')
|
|
265
|
-
* const check = await stage.inspect(subject)
|
|
297
|
+
* const check = await stage.inspect(subject, { signal: AbortSignal.timeout(30_000) })
|
|
266
298
|
* await stage.destroy()
|
|
267
299
|
* ```
|
|
268
300
|
*/
|
|
269
|
-
export declare class LintStage implements
|
|
301
|
+
export declare class LintStage implements LintStageInterface {
|
|
270
302
|
#private;
|
|
271
303
|
/**
|
|
272
304
|
* Starts warming the target workspace's Oxlint language server.
|
|
@@ -276,10 +308,42 @@ export declare class LintStage implements StageInterface {
|
|
|
276
308
|
constructor(workspace?: string);
|
|
277
309
|
get stage(): Stage_2;
|
|
278
310
|
get progress(): number;
|
|
279
|
-
inspect(subject: Case_2): Promise<Check_2>;
|
|
311
|
+
inspect(subject: Case_2, options?: InspectionOptions): Promise<Check_2>;
|
|
280
312
|
destroy(): Promise<void>;
|
|
281
313
|
}
|
|
282
314
|
|
|
315
|
+
/**
|
|
316
|
+
* Inspects one case under a bound the caller supplies.
|
|
317
|
+
*
|
|
318
|
+
* @remarks
|
|
319
|
+
* The lint stage carries a member the shared stage contract cannot. Its inspection waits for a
|
|
320
|
+
* foreign language server to publish, and only the caller knows how long that wait may run, so the
|
|
321
|
+
* bound belongs here rather than on `StageInterface`. The type and runtime stages read no signal
|
|
322
|
+
* and keep the shared one-argument `inspect`.
|
|
323
|
+
*
|
|
324
|
+
* `options` is optional because `StageInterface.inspect` accepts one argument and this contract
|
|
325
|
+
* extends it. An inspection that omits `options` is refused rather than served: a bound this stage
|
|
326
|
+
* minted for itself would race the coordinator's, and the client's own `timeout` covers the
|
|
327
|
+
* lifecycle exchanges alone.
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```ts
|
|
331
|
+
* const check = await stage.inspect(subject, { signal: AbortSignal.timeout(30_000) })
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
export declare interface LintStageInterface extends StageInterface {
|
|
335
|
+
/**
|
|
336
|
+
* Inspects one case, under the bound the caller supplies.
|
|
337
|
+
*
|
|
338
|
+
* @param subject - The candidate drafts and test to inspect
|
|
339
|
+
* @param options - The bound this inspection waits under
|
|
340
|
+
* @returns One outcome for this stage
|
|
341
|
+
* @throws When the caller supplies no bound, when the resident language server cannot start, or
|
|
342
|
+
* when the stage has already been destroyed
|
|
343
|
+
*/
|
|
344
|
+
inspect(subject: Case, options?: InspectionOptions): Promise<Check>;
|
|
345
|
+
}
|
|
346
|
+
|
|
283
347
|
/**
|
|
284
348
|
* Holds the listeners one emitter carried for a set of events at the moment it was captured.
|
|
285
349
|
*
|
|
@@ -505,12 +569,18 @@ export declare interface OverlayInterface {
|
|
|
505
569
|
* A containment walk and the write that follows it are separate calls, so a process that swaps the
|
|
506
570
|
* final component between them decides where the bytes land. `writeFileSync` opens with the default
|
|
507
571
|
* `w` flag, which follows a symbolic link at that component and creates the file when it is absent,
|
|
508
|
-
* so the walk's reading does not bind the write. Opening `O_WRONLY |
|
|
509
|
-
*
|
|
572
|
+
* so the walk's reading does not bind the write. Opening `O_WRONLY | O_NOFOLLOW` moves that
|
|
573
|
+
* decision into the call that writes: a link at the final component refuses the open, and the
|
|
510
574
|
* omitted `O_CREAT` fails `ENOENT` for a target that has gone since the walk saw it. This is the
|
|
511
575
|
* mutating counterpart of the `wx` flag every create in this package uses. Which code the refusal
|
|
512
576
|
* carries is the host's; Linux with Node v22.22.2 reported `ELOOP` on 2026-08-24.
|
|
513
577
|
*
|
|
578
|
+
* Truncation runs through the held descriptor rather than through an `O_TRUNC` flag, so it reaches
|
|
579
|
+
* the file the open bound. A Windows host refuses the numeric `O_TRUNC` without `O_CREAT` outright:
|
|
580
|
+
* measured on 2026-08-26 on Windows 11 with Node v24.19.0 over NTFS, `openSync` reported `EINVAL`
|
|
581
|
+
* for `O_WRONLY | O_TRUNC` and for `O_RDWR | O_TRUNC` while `O_WRONLY` alone opened, and adding
|
|
582
|
+
* `O_CREAT` would trade that refusal for the create this function must never perform.
|
|
583
|
+
*
|
|
514
584
|
* A directory component stays open, because Node exposes no descriptor-relative call to walk and
|
|
515
585
|
* write through one set of descriptors. Where a host's Node build defines no `O_NOFOLLOW`, that flag
|
|
516
586
|
* contributes nothing to the flag set and the final component is open on that host too.
|
|
@@ -531,20 +601,6 @@ export declare interface OverlayInterface {
|
|
|
531
601
|
*/
|
|
532
602
|
export declare function overwriteFile(file: string, text: string): void;
|
|
533
603
|
|
|
534
|
-
/**
|
|
535
|
-
* Reads a JSON-RPC frame's declared byte length.
|
|
536
|
-
*
|
|
537
|
-
* @param header - The frame header text without its terminating empty line
|
|
538
|
-
* @returns The non-negative content length, or `undefined` for an invalid header
|
|
539
|
-
*
|
|
540
|
-
* @example
|
|
541
|
-
* ```ts
|
|
542
|
-
* parseContentLength('Content-Length: 128') // 128
|
|
543
|
-
* parseContentLength('Content-Type: application/json') // undefined
|
|
544
|
-
* ```
|
|
545
|
-
*/
|
|
546
|
-
export declare function parseContentLength(header: string): number | undefined;
|
|
547
|
-
|
|
548
604
|
/**
|
|
549
605
|
* Answers claims through resident TypeScript, Oxlint, and Vitest stages.
|
|
550
606
|
*
|
|
@@ -202,6 +202,29 @@ export declare interface Inspection {
|
|
|
202
202
|
readonly claim: Claim;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Carries the bound a caller holds over one stage inspection.
|
|
207
|
+
*
|
|
208
|
+
* @remarks
|
|
209
|
+
* `LintStageInterface.inspect` is the only inspection in this package that reads the signal. Its
|
|
210
|
+
* wait is a foreign language server's silence, and abandoning that wait would leave the client
|
|
211
|
+
* holding a pending diagnostics request. The type and runtime stages accept no options and honor no
|
|
212
|
+
* cancellation: a coordinator abandons an overrunning one and replaces it, which is what `Probe`
|
|
213
|
+
* does when its own deadline expires.
|
|
214
|
+
*
|
|
215
|
+
* Supply the signal a coordinator already armed rather than minting a second bound here. A bound
|
|
216
|
+
* minted beside the coordinator's races it, and which one answers then depends on scheduling.
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* const options: InspectionOptions = { signal: AbortSignal.timeout(30_000) }
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
export declare interface InspectionOptions {
|
|
224
|
+
/** Aborts the inspection's wait for the resident tool's answer. */
|
|
225
|
+
readonly signal: AbortSignal;
|
|
226
|
+
}
|
|
227
|
+
|
|
205
228
|
/**
|
|
206
229
|
* Reports whether a fault means the host refuses the name a caller supplied for a file to create.
|
|
207
230
|
*
|
|
@@ -243,13 +266,22 @@ export declare function isRefusedName(file: string, error: unknown): boolean;
|
|
|
243
266
|
* Inspects virtual documents through one resident Oxlint language server.
|
|
244
267
|
*
|
|
245
268
|
* @remarks
|
|
246
|
-
* Construction starts the target workspace's Oxlint binary with its Language Server Protocol
|
|
247
|
-
*
|
|
248
|
-
*
|
|
269
|
+
* Construction starts the target workspace's Oxlint binary with its Language Server Protocol mode
|
|
270
|
+
* and hands the conversation to `@orkestrel/lsp`: `createStdioTransport` owns the child process and
|
|
271
|
+
* its bytes, and `createLSPClient` owns the framing, the request correlation, the capabilities this
|
|
272
|
+
* stage advertises, and the choice between pulled and pushed diagnostics. This stage owns the
|
|
273
|
+
* workspace, the candidate identity, and the projection from a diagnostic to an `Issue`.
|
|
274
|
+
*
|
|
275
|
+
* Each inspection opens the supplied text by URI, waits for the client's diagnostics, and closes the
|
|
276
|
+
* document without writing it to disk. The caller's own signal is what bounds that wait, so a server
|
|
277
|
+
* that admits a document and publishes nothing refuses the inspection when the caller's bound
|
|
278
|
+
* expires rather than holding it for the life of the process. This stage mints no bound of its own
|
|
279
|
+
* for the wait: a second one would race the caller's, and the answer would depend on scheduling.
|
|
249
280
|
*
|
|
250
281
|
* Teardown is bounded at both ends. Warming waits for the server's `initialize` response and the
|
|
251
|
-
* ending waits for its `shutdown` reply, and the protocol leaves both answers to the server, so
|
|
252
|
-
*
|
|
282
|
+
* ending waits for its `shutdown` reply, and the protocol leaves both answers to the server, so the
|
|
283
|
+
* client's deadline bounds each exchange and the transport's cooperative window takes the ending
|
|
284
|
+
* back with a signal when that window passes.
|
|
253
285
|
*
|
|
254
286
|
* The URI is the path the candidate declared, so the candidate receives exactly the rule set the
|
|
255
287
|
* workspace's own lint gate applies to that path, including an override anchored to one directory,
|
|
@@ -262,11 +294,11 @@ export declare function isRefusedName(file: string, error: unknown): boolean;
|
|
|
262
294
|
* @example
|
|
263
295
|
* ```ts
|
|
264
296
|
* const stage = new LintStage('/srv/checkout')
|
|
265
|
-
* const check = await stage.inspect(subject)
|
|
297
|
+
* const check = await stage.inspect(subject, { signal: AbortSignal.timeout(30_000) })
|
|
266
298
|
* await stage.destroy()
|
|
267
299
|
* ```
|
|
268
300
|
*/
|
|
269
|
-
export declare class LintStage implements
|
|
301
|
+
export declare class LintStage implements LintStageInterface {
|
|
270
302
|
#private;
|
|
271
303
|
/**
|
|
272
304
|
* Starts warming the target workspace's Oxlint language server.
|
|
@@ -276,10 +308,42 @@ export declare class LintStage implements StageInterface {
|
|
|
276
308
|
constructor(workspace?: string);
|
|
277
309
|
get stage(): Stage_2;
|
|
278
310
|
get progress(): number;
|
|
279
|
-
inspect(subject: Case_2): Promise<Check_2>;
|
|
311
|
+
inspect(subject: Case_2, options?: InspectionOptions): Promise<Check_2>;
|
|
280
312
|
destroy(): Promise<void>;
|
|
281
313
|
}
|
|
282
314
|
|
|
315
|
+
/**
|
|
316
|
+
* Inspects one case under a bound the caller supplies.
|
|
317
|
+
*
|
|
318
|
+
* @remarks
|
|
319
|
+
* The lint stage carries a member the shared stage contract cannot. Its inspection waits for a
|
|
320
|
+
* foreign language server to publish, and only the caller knows how long that wait may run, so the
|
|
321
|
+
* bound belongs here rather than on `StageInterface`. The type and runtime stages read no signal
|
|
322
|
+
* and keep the shared one-argument `inspect`.
|
|
323
|
+
*
|
|
324
|
+
* `options` is optional because `StageInterface.inspect` accepts one argument and this contract
|
|
325
|
+
* extends it. An inspection that omits `options` is refused rather than served: a bound this stage
|
|
326
|
+
* minted for itself would race the coordinator's, and the client's own `timeout` covers the
|
|
327
|
+
* lifecycle exchanges alone.
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```ts
|
|
331
|
+
* const check = await stage.inspect(subject, { signal: AbortSignal.timeout(30_000) })
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
export declare interface LintStageInterface extends StageInterface {
|
|
335
|
+
/**
|
|
336
|
+
* Inspects one case, under the bound the caller supplies.
|
|
337
|
+
*
|
|
338
|
+
* @param subject - The candidate drafts and test to inspect
|
|
339
|
+
* @param options - The bound this inspection waits under
|
|
340
|
+
* @returns One outcome for this stage
|
|
341
|
+
* @throws When the caller supplies no bound, when the resident language server cannot start, or
|
|
342
|
+
* when the stage has already been destroyed
|
|
343
|
+
*/
|
|
344
|
+
inspect(subject: Case, options?: InspectionOptions): Promise<Check>;
|
|
345
|
+
}
|
|
346
|
+
|
|
283
347
|
/**
|
|
284
348
|
* Holds the listeners one emitter carried for a set of events at the moment it was captured.
|
|
285
349
|
*
|
|
@@ -505,12 +569,18 @@ export declare interface OverlayInterface {
|
|
|
505
569
|
* A containment walk and the write that follows it are separate calls, so a process that swaps the
|
|
506
570
|
* final component between them decides where the bytes land. `writeFileSync` opens with the default
|
|
507
571
|
* `w` flag, which follows a symbolic link at that component and creates the file when it is absent,
|
|
508
|
-
* so the walk's reading does not bind the write. Opening `O_WRONLY |
|
|
509
|
-
*
|
|
572
|
+
* so the walk's reading does not bind the write. Opening `O_WRONLY | O_NOFOLLOW` moves that
|
|
573
|
+
* decision into the call that writes: a link at the final component refuses the open, and the
|
|
510
574
|
* omitted `O_CREAT` fails `ENOENT` for a target that has gone since the walk saw it. This is the
|
|
511
575
|
* mutating counterpart of the `wx` flag every create in this package uses. Which code the refusal
|
|
512
576
|
* carries is the host's; Linux with Node v22.22.2 reported `ELOOP` on 2026-08-24.
|
|
513
577
|
*
|
|
578
|
+
* Truncation runs through the held descriptor rather than through an `O_TRUNC` flag, so it reaches
|
|
579
|
+
* the file the open bound. A Windows host refuses the numeric `O_TRUNC` without `O_CREAT` outright:
|
|
580
|
+
* measured on 2026-08-26 on Windows 11 with Node v24.19.0 over NTFS, `openSync` reported `EINVAL`
|
|
581
|
+
* for `O_WRONLY | O_TRUNC` and for `O_RDWR | O_TRUNC` while `O_WRONLY` alone opened, and adding
|
|
582
|
+
* `O_CREAT` would trade that refusal for the create this function must never perform.
|
|
583
|
+
*
|
|
514
584
|
* A directory component stays open, because Node exposes no descriptor-relative call to walk and
|
|
515
585
|
* write through one set of descriptors. Where a host's Node build defines no `O_NOFOLLOW`, that flag
|
|
516
586
|
* contributes nothing to the flag set and the final component is open on that host too.
|
|
@@ -531,20 +601,6 @@ export declare interface OverlayInterface {
|
|
|
531
601
|
*/
|
|
532
602
|
export declare function overwriteFile(file: string, text: string): void;
|
|
533
603
|
|
|
534
|
-
/**
|
|
535
|
-
* Reads a JSON-RPC frame's declared byte length.
|
|
536
|
-
*
|
|
537
|
-
* @param header - The frame header text without its terminating empty line
|
|
538
|
-
* @returns The non-negative content length, or `undefined` for an invalid header
|
|
539
|
-
*
|
|
540
|
-
* @example
|
|
541
|
-
* ```ts
|
|
542
|
-
* parseContentLength('Content-Length: 128') // 128
|
|
543
|
-
* parseContentLength('Content-Type: application/json') // undefined
|
|
544
|
-
* ```
|
|
545
|
-
*/
|
|
546
|
-
export declare function parseContentLength(header: string): number | undefined;
|
|
547
|
-
|
|
548
604
|
/**
|
|
549
605
|
* Answers claims through resident TypeScript, Oxlint, and Vitest stages.
|
|
550
606
|
*
|