@clowder-ai/plugin-contract 0.1.0-beta.1 → 0.1.0-beta.3
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/codegen/generate-contract.d.ts +1 -0
- package/dist/codegen/generate-contract.d.ts.map +1 -1
- package/dist/codegen/generate-contract.js +26 -2
- package/dist/codegen/generate-contract.js.map +1 -1
- package/dist/conformance/behavior-executor.d.ts +18 -0
- package/dist/conformance/behavior-executor.d.ts.map +1 -0
- package/dist/conformance/behavior-executor.js +52 -0
- package/dist/conformance/behavior-executor.js.map +1 -0
- package/dist/conformance/index.d.ts +3 -0
- package/dist/conformance/index.d.ts.map +1 -1
- package/dist/conformance/index.js +3 -0
- package/dist/conformance/index.js.map +1 -1
- package/dist/conformance/messaging-loopback-adapter.d.ts +23 -0
- package/dist/conformance/messaging-loopback-adapter.d.ts.map +1 -0
- package/dist/conformance/messaging-loopback-adapter.js +389 -0
- package/dist/conformance/messaging-loopback-adapter.js.map +1 -0
- package/dist/conformance/messaging-loopback-state.d.ts +22 -0
- package/dist/conformance/messaging-loopback-state.d.ts.map +1 -0
- package/dist/conformance/messaging-loopback-state.js +101 -0
- package/dist/conformance/messaging-loopback-state.js.map +1 -0
- package/dist/conformance/runner.d.ts +18 -1
- package/dist/conformance/runner.d.ts.map +1 -1
- package/dist/conformance/runner.js +133 -64
- package/dist/conformance/runner.js.map +1 -1
- package/dist/conformance/stdio-harness/child-process-harness.d.ts +59 -0
- package/dist/conformance/stdio-harness/child-process-harness.d.ts.map +1 -0
- package/dist/conformance/stdio-harness/child-process-harness.js +279 -0
- package/dist/conformance/stdio-harness/child-process-harness.js.map +1 -0
- package/dist/conformance/stdio-harness/dual-transport-oracle.d.ts +26 -0
- package/dist/conformance/stdio-harness/dual-transport-oracle.d.ts.map +1 -0
- package/dist/conformance/stdio-harness/dual-transport-oracle.js +32 -0
- package/dist/conformance/stdio-harness/dual-transport-oracle.js.map +1 -0
- package/dist/conformance/stdio-harness/harness-process-spawn.d.ts +27 -0
- package/dist/conformance/stdio-harness/harness-process-spawn.d.ts.map +1 -0
- package/dist/conformance/stdio-harness/harness-process-spawn.js +43 -0
- package/dist/conformance/stdio-harness/harness-process-spawn.js.map +1 -0
- package/dist/conformance/stdio-harness/index.d.ts +5 -0
- package/dist/conformance/stdio-harness/index.d.ts.map +1 -0
- package/dist/conformance/stdio-harness/index.js +4 -0
- package/dist/conformance/stdio-harness/index.js.map +1 -0
- package/dist/conformance/stdio-harness/ndjson-frame.d.ts +26 -0
- package/dist/conformance/stdio-harness/ndjson-frame.d.ts.map +1 -0
- package/dist/conformance/stdio-harness/ndjson-frame.js +119 -0
- package/dist/conformance/stdio-harness/ndjson-frame.js.map +1 -0
- package/dist/conformance/stdio-harness/node-process-tree-runtime.d.ts +15 -0
- package/dist/conformance/stdio-harness/node-process-tree-runtime.d.ts.map +1 -0
- package/dist/conformance/stdio-harness/node-process-tree-runtime.js +78 -0
- package/dist/conformance/stdio-harness/node-process-tree-runtime.js.map +1 -0
- package/dist/conformance/stdio-harness/process-tree-controller.d.ts +51 -0
- package/dist/conformance/stdio-harness/process-tree-controller.d.ts.map +1 -0
- package/dist/conformance/stdio-harness/process-tree-controller.js +162 -0
- package/dist/conformance/stdio-harness/process-tree-controller.js.map +1 -0
- package/dist/conformance/stdio-harness/windows-sentinel.d.ts +15 -0
- package/dist/conformance/stdio-harness/windows-sentinel.d.ts.map +1 -0
- package/dist/conformance/stdio-harness/windows-sentinel.js +160 -0
- package/dist/conformance/stdio-harness/windows-sentinel.js.map +1 -0
- package/dist/conformance/stdio-harness/wire-shape.d.ts +18 -0
- package/dist/conformance/stdio-harness/wire-shape.d.ts.map +1 -0
- package/dist/conformance/stdio-harness/wire-shape.js +2 -0
- package/dist/conformance/stdio-harness/wire-shape.js.map +1 -0
- package/dist/generated/contract.generated.d.ts +129 -1
- package/dist/generated/contract.generated.d.ts.map +1 -1
- package/dist/generated/contract.generated.js +1 -1
- package/dist/generated/contract.generated.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/wire/constants.d.ts +36 -0
- package/dist/wire/constants.d.ts.map +1 -0
- package/dist/wire/constants.js +36 -0
- package/dist/wire/constants.js.map +1 -0
- package/dist/wire/disposition-fixtures.d.ts +99 -0
- package/dist/wire/disposition-fixtures.d.ts.map +1 -0
- package/dist/wire/disposition-fixtures.js +623 -0
- package/dist/wire/disposition-fixtures.js.map +1 -0
- package/dist/wire/disposition.d.ts +100 -0
- package/dist/wire/disposition.d.ts.map +1 -0
- package/dist/wire/disposition.js +205 -0
- package/dist/wire/disposition.js.map +1 -0
- package/dist/wire/envelope.d.ts +253 -0
- package/dist/wire/envelope.d.ts.map +1 -0
- package/dist/wire/envelope.js +19 -0
- package/dist/wire/envelope.js.map +1 -0
- package/dist/wire/errors.d.ts +222 -0
- package/dist/wire/errors.d.ts.map +1 -0
- package/dist/wire/errors.js +153 -0
- package/dist/wire/errors.js.map +1 -0
- package/dist/wire/grants.d.ts +57 -0
- package/dist/wire/grants.d.ts.map +1 -0
- package/dist/wire/grants.js +59 -0
- package/dist/wire/grants.js.map +1 -0
- package/dist/wire/handshake.d.ts +100 -0
- package/dist/wire/handshake.d.ts.map +1 -0
- package/dist/wire/handshake.js +70 -0
- package/dist/wire/handshake.js.map +1 -0
- package/dist/wire/index.d.ts +26 -0
- package/dist/wire/index.d.ts.map +1 -0
- package/dist/wire/index.js +45 -0
- package/dist/wire/index.js.map +1 -0
- package/dist/wire/registry.d.ts +90 -0
- package/dist/wire/registry.d.ts.map +1 -0
- package/dist/wire/registry.js +232 -0
- package/dist/wire/registry.js.map +1 -0
- package/dist/wire/request-id.d.ts +34 -0
- package/dist/wire/request-id.d.ts.map +1 -0
- package/dist/wire/request-id.js +40 -0
- package/dist/wire/request-id.js.map +1 -0
- package/dist/wire/row-shapes.d.ts +212 -0
- package/dist/wire/row-shapes.d.ts.map +1 -0
- package/dist/wire/row-shapes.js +59 -0
- package/dist/wire/row-shapes.js.map +1 -0
- package/dist/wire/wire-uint53.d.ts +26 -0
- package/dist/wire/wire-uint53.d.ts.map +1 -0
- package/dist/wire/wire-uint53.js +32 -0
- package/dist/wire/wire-uint53.js.map +1 -0
- package/fixtures/behavior/messaging/adversarial-invariants.json +56 -5
- package/package.json +7 -3
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface OracleTransport<Input, Result, Observation> {
|
|
2
|
+
/** Harness-local control-plane setup; never sent over the plugin wire. */
|
|
3
|
+
setup(): Promise<void>;
|
|
4
|
+
/** The sole semantic operation path being compared across transports. */
|
|
5
|
+
execute(input: Input): Promise<Result>;
|
|
6
|
+
/** Harness-local observation; never exposed as a production wire method. */
|
|
7
|
+
observe(): Promise<Observation>;
|
|
8
|
+
}
|
|
9
|
+
export interface DualTransportOracleCase<Input> {
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly input: Input;
|
|
12
|
+
}
|
|
13
|
+
export interface TransportTranscript<Result, Observation> {
|
|
14
|
+
readonly before: Observation;
|
|
15
|
+
readonly result: Result;
|
|
16
|
+
readonly after: Observation;
|
|
17
|
+
}
|
|
18
|
+
export interface DualTransportOracleReport<Result, Observation> {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly passed: boolean;
|
|
21
|
+
readonly failures: readonly string[];
|
|
22
|
+
readonly inProcess: TransportTranscript<Result, Observation>;
|
|
23
|
+
readonly wire: TransportTranscript<Result, Observation>;
|
|
24
|
+
}
|
|
25
|
+
export declare function runDualTransportOracle<Input, Result, Observation>(oracleCase: DualTransportOracleCase<Input>, inProcessTransport: OracleTransport<Input, Result, Observation>, wireTransport: OracleTransport<Input, Result, Observation>): Promise<DualTransportOracleReport<Result, Observation>>;
|
|
26
|
+
//# sourceMappingURL=dual-transport-oracle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dual-transport-oracle.d.ts","sourceRoot":"","sources":["../../../src/conformance/stdio-harness/dual-transport-oracle.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW;IACzD,0EAA0E;IAC1E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,yEAAyE;IACzE,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,4EAA4E;IAC5E,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,uBAAuB,CAAC,KAAK;IAC5C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB,CAAC,MAAM,EAAE,WAAW;IACtD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB,CAAC,MAAM,EAAE,WAAW;IAC5D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC7D,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACzD;AAaD,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EACrE,UAAU,EAAE,uBAAuB,CAAC,KAAK,CAAC,EAC1C,kBAAkB,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAC/D,aAAa,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,GACzD,OAAO,CAAC,yBAAyB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAwBzD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
2
|
+
async function captureTranscript(input, transport) {
|
|
3
|
+
await transport.setup();
|
|
4
|
+
const before = structuredClone(await transport.observe());
|
|
5
|
+
const result = structuredClone(await transport.execute(structuredClone(input)));
|
|
6
|
+
const after = structuredClone(await transport.observe());
|
|
7
|
+
return { before, result, after };
|
|
8
|
+
}
|
|
9
|
+
export async function runDualTransportOracle(oracleCase, inProcessTransport, wireTransport) {
|
|
10
|
+
const [inProcess, wire] = await Promise.all([
|
|
11
|
+
captureTranscript(oracleCase.input, inProcessTransport),
|
|
12
|
+
captureTranscript(oracleCase.input, wireTransport),
|
|
13
|
+
]);
|
|
14
|
+
const failures = [];
|
|
15
|
+
if (!isDeepStrictEqual(inProcess.before, wire.before)) {
|
|
16
|
+
failures.push('before observation mismatch');
|
|
17
|
+
}
|
|
18
|
+
if (!isDeepStrictEqual(inProcess.result, wire.result)) {
|
|
19
|
+
failures.push('result mismatch');
|
|
20
|
+
}
|
|
21
|
+
if (!isDeepStrictEqual(inProcess.after, wire.after)) {
|
|
22
|
+
failures.push('after observation mismatch');
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
id: oracleCase.id,
|
|
26
|
+
passed: failures.length === 0,
|
|
27
|
+
failures,
|
|
28
|
+
inProcess,
|
|
29
|
+
wire,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=dual-transport-oracle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dual-transport-oracle.js","sourceRoot":"","sources":["../../../src/conformance/stdio-harness/dual-transport-oracle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AA8B9C,KAAK,UAAU,iBAAiB,CAC9B,KAAY,EACZ,SAAsD;IAEtD,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,SAAS,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAChF,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;IACzD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,UAA0C,EAC1C,kBAA+D,EAC/D,aAA0D;IAE1D,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC1C,iBAAiB,CAAC,UAAU,CAAC,KAAK,EAAE,kBAAkB,CAAC;QACvD,iBAAiB,CAAC,UAAU,CAAC,KAAK,EAAE,aAAa,CAAC;KACnD,CAAC,CAAC;IACH,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,QAAQ,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,QAAQ,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO;QACL,EAAE,EAAE,UAAU,CAAC,EAAE;QACjB,MAAM,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC;QAC7B,QAAQ;QACR,SAAS;QACT,IAAI;KACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ChildProcessWithoutNullStreams } from 'node:child_process';
|
|
2
|
+
import { type ProcessTreeRuntime } from './process-tree-controller.js';
|
|
3
|
+
export interface SpawnHarnessChildOptions {
|
|
4
|
+
readonly command: string;
|
|
5
|
+
readonly args?: readonly string[];
|
|
6
|
+
readonly cwd?: string;
|
|
7
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
8
|
+
}
|
|
9
|
+
export interface HarnessTargetLifecycle {
|
|
10
|
+
readonly onTargetError: (listener: (error: Error) => void) => void;
|
|
11
|
+
readonly onTargetExit: (listener: (code: number | null, signal: NodeJS.Signals | null) => void) => void;
|
|
12
|
+
readonly signalTarget: (signal: NodeJS.Signals) => void;
|
|
13
|
+
}
|
|
14
|
+
/** @internal Injectable platform boundary for cross-platform conformance tests. */
|
|
15
|
+
export interface HarnessPlatformAdapter {
|
|
16
|
+
readonly platform: NodeJS.Platform;
|
|
17
|
+
readonly createProcessTreeRuntime: (signalTarget: (signal: NodeJS.Signals) => void) => ProcessTreeRuntime;
|
|
18
|
+
}
|
|
19
|
+
export interface SpawnedHarnessProcess {
|
|
20
|
+
readonly root: ChildProcessWithoutNullStreams;
|
|
21
|
+
readonly target: HarnessTargetLifecycle;
|
|
22
|
+
readonly runtime: ProcessTreeRuntime;
|
|
23
|
+
}
|
|
24
|
+
export declare function spawnHarnessProcess(options: SpawnHarnessChildOptions): SpawnedHarnessProcess;
|
|
25
|
+
export declare function spawnHarnessProcessWithAdapter(options: SpawnHarnessChildOptions, adapter: HarnessPlatformAdapter): SpawnedHarnessProcess;
|
|
26
|
+
export declare function createDirectTargetLifecycle(child: ChildProcessWithoutNullStreams): HarnessTargetLifecycle;
|
|
27
|
+
//# sourceMappingURL=harness-process-spawn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-process-spawn.d.ts","sourceRoot":"","sources":["../../../src/conformance/stdio-harness/harness-process-spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAGhF,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAClC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,KAAK,IAAI,CAAC;IACnE,QAAQ,CAAC,YAAY,EAAE,CACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,KAAK,IAAI,KACnE,IAAI,CAAC;IACV,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;CACzD;AAED,mFAAmF;AACnF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IACnC,QAAQ,CAAC,wBAAwB,EAAE,CACjC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,KAC3C,kBAAkB,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,8BAA8B,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;CACtC;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,wBAAwB,GAChC,qBAAqB,CAMvB;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,wBAAwB,EACjC,OAAO,EAAE,sBAAsB,GAC9B,qBAAqB,CAsBvB;AACD,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,8BAA8B,GACpC,sBAAsB,CAQxB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { createNodeProcessTreeRuntime } from './node-process-tree-runtime.js';
|
|
3
|
+
import {} from './process-tree-controller.js';
|
|
4
|
+
import { spawnWindowsSentinel } from './windows-sentinel.js';
|
|
5
|
+
export function spawnHarnessProcess(options) {
|
|
6
|
+
return spawnHarnessProcessWithAdapter(options, {
|
|
7
|
+
platform: process.platform,
|
|
8
|
+
createProcessTreeRuntime: (signalTarget) => createNodeProcessTreeRuntime(process.platform, signalTarget),
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export function spawnHarnessProcessWithAdapter(options, adapter) {
|
|
12
|
+
const args = [...(options.args ?? [])];
|
|
13
|
+
if (adapter.platform === 'win32') {
|
|
14
|
+
const target = spawnWindowsSentinel({ ...options, args });
|
|
15
|
+
return {
|
|
16
|
+
root: target.root,
|
|
17
|
+
target,
|
|
18
|
+
runtime: adapter.createProcessTreeRuntime(target.signalTarget),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const root = spawn(options.command, args, {
|
|
22
|
+
cwd: options.cwd,
|
|
23
|
+
detached: true,
|
|
24
|
+
env: options.env,
|
|
25
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
26
|
+
});
|
|
27
|
+
const target = createDirectTargetLifecycle(root);
|
|
28
|
+
return {
|
|
29
|
+
root,
|
|
30
|
+
target,
|
|
31
|
+
runtime: adapter.createProcessTreeRuntime(target.signalTarget),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function createDirectTargetLifecycle(child) {
|
|
35
|
+
return {
|
|
36
|
+
onTargetError: (listener) => child.once('error', listener),
|
|
37
|
+
onTargetExit: (listener) => child.once('exit', listener),
|
|
38
|
+
signalTarget: (signal) => {
|
|
39
|
+
child.kill(signal);
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=harness-process-spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-process-spawn.js","sourceRoot":"","sources":["../../../src/conformance/stdio-harness/harness-process-spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAuC,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAA2B,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AA+B7D,MAAM,UAAU,mBAAmB,CACjC,OAAiC;IAEjC,OAAO,8BAA8B,CAAC,OAAO,EAAE;QAC7C,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,wBAAwB,EAAE,CAAC,YAAY,EAAE,EAAE,CACzC,4BAA4B,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,CAAC;KAC/D,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,OAAiC,EACjC,OAA+B;IAE/B,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,oBAAoB,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM;YACN,OAAO,EAAE,OAAO,CAAC,wBAAwB,CAAC,MAAM,CAAC,YAAY,CAAC;SAC/D,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE;QACxC,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,QAAQ,EAAE,IAAI;QACd,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;KAChC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,2BAA2B,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO;QACL,IAAI;QACJ,MAAM;QACN,OAAO,EAAE,OAAO,CAAC,wBAAwB,CAAC,MAAM,CAAC,YAAY,CAAC;KAC/D,CAAC;AACJ,CAAC;AACD,MAAM,UAAU,2BAA2B,CACzC,KAAqC;IAErC,OAAO;QACL,aAAa,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC1D,YAAY,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC;QACxD,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE;YACvB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { HarnessChild, HarnessChildExitedError, HarnessCleanupError, HarnessFrameBacklogError, HarnessTimeoutError, MAX_HARNESS_QUEUED_FRAMES, runHarnessCase, spawnHarnessChild, type HarnessChildExit, type HarnessReceiveOptions, type RunHarnessCaseOptions, type SpawnHarnessChildOptions, } from './child-process-harness.js';
|
|
2
|
+
export { runDualTransportOracle, type DualTransportOracleCase, type DualTransportOracleReport, type OracleTransport, type TransportTranscript, } from './dual-transport-oracle.js';
|
|
3
|
+
export { MAX_NDJSON_FRAME_BYTES, NdjsonFrameDecoder, NdjsonFrameError, encodeNdjsonFrame, type DecodedNdjsonFrame, type JsonObject, type NdjsonFrameErrorCode, } from './ndjson-frame.js';
|
|
4
|
+
export type { HarnessWireShape } from './wire-shape.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/conformance/stdio-harness/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,yBAAyB,EACzB,cAAc,EACd,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,GAC9B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,sBAAsB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,eAAe,EACpB,KAAK,mBAAmB,GACzB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { HarnessChild, HarnessChildExitedError, HarnessCleanupError, HarnessFrameBacklogError, HarnessTimeoutError, MAX_HARNESS_QUEUED_FRAMES, runHarnessCase, spawnHarnessChild, } from './child-process-harness.js';
|
|
2
|
+
export { runDualTransportOracle, } from './dual-transport-oracle.js';
|
|
3
|
+
export { MAX_NDJSON_FRAME_BYTES, NdjsonFrameDecoder, NdjsonFrameError, encodeNdjsonFrame, } from './ndjson-frame.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/conformance/stdio-harness/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,yBAAyB,EACzB,cAAc,EACd,iBAAiB,GAKlB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,sBAAsB,GAKvB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,GAIlB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare const MAX_NDJSON_FRAME_BYTES = 1048576;
|
|
2
|
+
export type JsonObject = Readonly<Record<string, unknown>>;
|
|
3
|
+
export interface DecodedNdjsonFrame {
|
|
4
|
+
/** Exact bytes before LF; retained for pre-parse contract validation. */
|
|
5
|
+
readonly raw: Uint8Array;
|
|
6
|
+
/** Convenience parse only; contract validation must still inspect raw. */
|
|
7
|
+
readonly value: JsonObject;
|
|
8
|
+
}
|
|
9
|
+
export type NdjsonFrameErrorCode = 'FRAME_TOO_LARGE' | 'INVALID_UTF8' | 'INVALID_JSON' | 'INVALID_FRAME' | 'TRUNCATED_FRAME' | 'DECODER_CLOSED';
|
|
10
|
+
export declare class NdjsonFrameError extends Error {
|
|
11
|
+
readonly code: NdjsonFrameErrorCode;
|
|
12
|
+
constructor(code: NdjsonFrameErrorCode, message: string);
|
|
13
|
+
}
|
|
14
|
+
export declare function encodeNdjsonFrame(value: JsonObject, maxFrameBytes?: number): Uint8Array;
|
|
15
|
+
export declare class NdjsonFrameDecoder {
|
|
16
|
+
private readonly maxFrameBytes;
|
|
17
|
+
private buffered;
|
|
18
|
+
private closed;
|
|
19
|
+
private failed;
|
|
20
|
+
constructor(maxFrameBytes?: number);
|
|
21
|
+
push(chunk: Uint8Array): readonly DecodedNdjsonFrame[];
|
|
22
|
+
end(): readonly DecodedNdjsonFrame[];
|
|
23
|
+
private assertOpen;
|
|
24
|
+
private fail;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=ndjson-frame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ndjson-frame.d.ts","sourceRoot":"","sources":["../../../src/conformance/stdio-harness/ndjson-frame.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,UAAY,CAAC;AAEhD,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3D,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,MAAM,oBAAoB,GAC5B,iBAAiB,GACjB,cAAc,GACd,cAAc,GACd,eAAe,GACf,iBAAiB,GACjB,gBAAgB,CAAC;AAErB,qBAAa,gBAAiB,SAAQ,KAAK;IAEvC,QAAQ,CAAC,IAAI,EAAE,oBAAoB;gBAA1B,IAAI,EAAE,oBAAoB,EACnC,OAAO,EAAE,MAAM;CAKlB;AAyCD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EACjB,aAAa,SAAyB,GACrC,UAAU,CAmBZ;AAED,qBAAa,kBAAkB;IAKjB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAJ1C,OAAO,CAAC,QAAQ,CAAmB;IACnC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;gBAEM,aAAa,SAAyB;IAInE,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,kBAAkB,EAAE;IAkDtD,GAAG,IAAI,SAAS,kBAAkB,EAAE;IAapC,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,IAAI;CAIb"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
export const MAX_NDJSON_FRAME_BYTES = 1_048_576;
|
|
2
|
+
export class NdjsonFrameError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
constructor(code, message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.name = 'NdjsonFrameError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function validateMaxFrameBytes(maxFrameBytes) {
|
|
11
|
+
if (!Number.isSafeInteger(maxFrameBytes) ||
|
|
12
|
+
maxFrameBytes <= 0 ||
|
|
13
|
+
maxFrameBytes > MAX_NDJSON_FRAME_BYTES) {
|
|
14
|
+
throw new RangeError(`NDJSON maxFrameBytes must be a positive safe integer no greater than ${MAX_NDJSON_FRAME_BYTES}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function assertJsonObject(value) {
|
|
18
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
19
|
+
throw new NdjsonFrameError('INVALID_FRAME', 'NDJSON frames must contain one non-array JSON object');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function decodeFrame(frame) {
|
|
23
|
+
let text;
|
|
24
|
+
try {
|
|
25
|
+
text = new TextDecoder('utf-8', { fatal: true }).decode(frame);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new NdjsonFrameError('INVALID_UTF8', 'NDJSON frame is not valid UTF-8');
|
|
29
|
+
}
|
|
30
|
+
let value;
|
|
31
|
+
try {
|
|
32
|
+
value = JSON.parse(text);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
throw new NdjsonFrameError('INVALID_JSON', 'NDJSON frame is not valid JSON');
|
|
36
|
+
}
|
|
37
|
+
assertJsonObject(value);
|
|
38
|
+
return { raw: Buffer.from(frame), value };
|
|
39
|
+
}
|
|
40
|
+
export function encodeNdjsonFrame(value, maxFrameBytes = MAX_NDJSON_FRAME_BYTES) {
|
|
41
|
+
validateMaxFrameBytes(maxFrameBytes);
|
|
42
|
+
assertJsonObject(value);
|
|
43
|
+
const serialized = JSON.stringify(value);
|
|
44
|
+
if (serialized === undefined) {
|
|
45
|
+
throw new NdjsonFrameError('INVALID_FRAME', 'NDJSON frames must serialize to one non-array JSON object');
|
|
46
|
+
}
|
|
47
|
+
assertJsonObject(JSON.parse(serialized));
|
|
48
|
+
const frame = Buffer.from(serialized, 'utf8');
|
|
49
|
+
if (frame.byteLength > maxFrameBytes) {
|
|
50
|
+
throw new NdjsonFrameError('FRAME_TOO_LARGE', `NDJSON frame is ${frame.byteLength} bytes; limit is ${maxFrameBytes}`);
|
|
51
|
+
}
|
|
52
|
+
return Buffer.concat([frame, Buffer.from('\n')], frame.byteLength + 1);
|
|
53
|
+
}
|
|
54
|
+
export class NdjsonFrameDecoder {
|
|
55
|
+
maxFrameBytes;
|
|
56
|
+
buffered = Buffer.alloc(0);
|
|
57
|
+
closed = false;
|
|
58
|
+
failed = false;
|
|
59
|
+
constructor(maxFrameBytes = MAX_NDJSON_FRAME_BYTES) {
|
|
60
|
+
this.maxFrameBytes = maxFrameBytes;
|
|
61
|
+
validateMaxFrameBytes(maxFrameBytes);
|
|
62
|
+
}
|
|
63
|
+
push(chunk) {
|
|
64
|
+
this.assertOpen();
|
|
65
|
+
if (chunk.byteLength === 0) {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
const incoming = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
69
|
+
const combined = this.buffered.byteLength === 0
|
|
70
|
+
? incoming
|
|
71
|
+
: Buffer.concat([this.buffered, incoming], this.buffered.byteLength + incoming.byteLength);
|
|
72
|
+
const frames = [];
|
|
73
|
+
let frameStart = 0;
|
|
74
|
+
try {
|
|
75
|
+
let newline = combined.indexOf(0x0a, frameStart);
|
|
76
|
+
while (newline !== -1) {
|
|
77
|
+
const frameLength = newline - frameStart;
|
|
78
|
+
if (frameLength > this.maxFrameBytes) {
|
|
79
|
+
throw new NdjsonFrameError('FRAME_TOO_LARGE', `NDJSON frame is ${frameLength} bytes; limit is ${this.maxFrameBytes}`);
|
|
80
|
+
}
|
|
81
|
+
if (frameLength === 0) {
|
|
82
|
+
throw new NdjsonFrameError('INVALID_FRAME', 'blank NDJSON frames are not allowed');
|
|
83
|
+
}
|
|
84
|
+
frames.push(decodeFrame(combined.subarray(frameStart, newline)));
|
|
85
|
+
frameStart = newline + 1;
|
|
86
|
+
newline = combined.indexOf(0x0a, frameStart);
|
|
87
|
+
}
|
|
88
|
+
const remainder = combined.subarray(frameStart);
|
|
89
|
+
if (remainder.byteLength > this.maxFrameBytes) {
|
|
90
|
+
throw new NdjsonFrameError('FRAME_TOO_LARGE', `unterminated NDJSON frame exceeded ${this.maxFrameBytes} bytes`);
|
|
91
|
+
}
|
|
92
|
+
this.buffered = Buffer.from(remainder);
|
|
93
|
+
return frames;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
this.fail();
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
end() {
|
|
101
|
+
this.assertOpen();
|
|
102
|
+
this.closed = true;
|
|
103
|
+
if (this.buffered.byteLength === 0) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
this.buffered = Buffer.alloc(0);
|
|
107
|
+
throw new NdjsonFrameError('TRUNCATED_FRAME', 'NDJSON stream ended before the final LF delimiter');
|
|
108
|
+
}
|
|
109
|
+
assertOpen() {
|
|
110
|
+
if (this.closed || this.failed) {
|
|
111
|
+
throw new NdjsonFrameError('DECODER_CLOSED', 'NDJSON decoder is closed');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
fail() {
|
|
115
|
+
this.failed = true;
|
|
116
|
+
this.buffered = Buffer.alloc(0);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=ndjson-frame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ndjson-frame.js","sourceRoot":"","sources":["../../../src/conformance/stdio-harness/ndjson-frame.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ProcessTreeRuntime, type TaskkillOutcome } from './process-tree-controller.js';
|
|
2
|
+
export interface TaskkillProcess {
|
|
3
|
+
readonly kill: () => boolean;
|
|
4
|
+
readonly once: {
|
|
5
|
+
(event: 'close', listener: (code: number | null) => void): TaskkillProcess;
|
|
6
|
+
(event: 'error', listener: (error: Error) => void): TaskkillProcess;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export type TaskkillSpawner = (command: string, args: readonly string[], options: {
|
|
10
|
+
readonly stdio: 'ignore';
|
|
11
|
+
readonly windowsHide: true;
|
|
12
|
+
}) => TaskkillProcess;
|
|
13
|
+
export declare function runTaskkill(rootPid: number, timeoutMs: number, spawnTaskkill?: TaskkillSpawner): Promise<TaskkillOutcome>;
|
|
14
|
+
export declare function createNodeProcessTreeRuntime(platform: NodeJS.Platform, signalTarget: (signal: NodeJS.Signals) => void, killProcess?: typeof process.kill): ProcessTreeRuntime;
|
|
15
|
+
//# sourceMappingURL=node-process-tree-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-process-tree-runtime.d.ts","sourceRoot":"","sources":["../../../src/conformance/stdio-harness/node-process-tree-runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACrB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE;QACb,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,eAAe,CAAC;QAC3E,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,eAAe,CAAC;KACrE,CAAC;CACH;AAED,MAAM,MAAM,eAAe,GAAG,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAA;CAAE,KAC9D,eAAe,CAAC;AAKrB,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,aAAa,GAAE,eAAwC,GACtD,OAAO,CAAC,eAAe,CAAC,CAqC1B;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,EAC9C,WAAW,GAAE,OAAO,OAAO,CAAC,IAAmB,GAC9C,kBAAkB,CAiCpB"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import {} from './process-tree-controller.js';
|
|
3
|
+
const defaultTaskkillSpawner = (command, args, options) => spawn(command, [...args], options);
|
|
4
|
+
export function runTaskkill(rootPid, timeoutMs, spawnTaskkill = defaultTaskkillSpawner) {
|
|
5
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) {
|
|
6
|
+
throw new RangeError('taskkill timeoutMs must be a positive safe integer');
|
|
7
|
+
}
|
|
8
|
+
let child;
|
|
9
|
+
try {
|
|
10
|
+
child = spawnTaskkill('taskkill', ['/pid', String(rootPid), '/t', '/f'], { stdio: 'ignore', windowsHide: true });
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
return Promise.resolve({
|
|
14
|
+
status: 'spawn-error',
|
|
15
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
let settled = false;
|
|
20
|
+
const settle = (outcome) => {
|
|
21
|
+
if (settled) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
settled = true;
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
resolve(outcome);
|
|
27
|
+
};
|
|
28
|
+
const timer = setTimeout(() => {
|
|
29
|
+
child.kill();
|
|
30
|
+
settle({ status: 'timeout' });
|
|
31
|
+
}, timeoutMs);
|
|
32
|
+
child.once('error', (error) => settle({ status: 'spawn-error', error }));
|
|
33
|
+
child.once('close', (code) => settle(code === 0 ? { status: 'success' } : { status: 'nonzero', code }));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export function createNodeProcessTreeRuntime(platform, signalTarget, killProcess = process.kill) {
|
|
37
|
+
return {
|
|
38
|
+
platform,
|
|
39
|
+
now: Date.now,
|
|
40
|
+
sleep: (delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs)),
|
|
41
|
+
signalTarget,
|
|
42
|
+
signalTree: (rootPid, signal) => {
|
|
43
|
+
try {
|
|
44
|
+
killProcess(-rootPid, signal);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (isNoSuchProcessError(error)) {
|
|
48
|
+
signalTarget(signal);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
treeIsAlive: (rootPid) => {
|
|
55
|
+
try {
|
|
56
|
+
killProcess(platform === 'win32' ? rootPid : -rootPid, 0);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (isNoSuchProcessError(error)) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
if (isPermissionError(error)) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
runTaskkill,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function isNoSuchProcessError(error) {
|
|
73
|
+
return error instanceof Error && 'code' in error && error.code === 'ESRCH';
|
|
74
|
+
}
|
|
75
|
+
function isPermissionError(error) {
|
|
76
|
+
return error instanceof Error && 'code' in error && error.code === 'EPERM';
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=node-process-tree-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-process-tree-runtime.js","sourceRoot":"","sources":["../../../src/conformance/stdio-harness/node-process-tree-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export type HarnessProcessState = 'spawned' | 'running' | 'terminating' | 'exited' | 'reaped' | 'cleanup-failed';
|
|
2
|
+
export type TaskkillOutcome = {
|
|
3
|
+
readonly status: 'success';
|
|
4
|
+
} | {
|
|
5
|
+
readonly status: 'nonzero';
|
|
6
|
+
readonly code: number | null;
|
|
7
|
+
} | {
|
|
8
|
+
readonly status: 'spawn-error';
|
|
9
|
+
readonly error: Error;
|
|
10
|
+
} | {
|
|
11
|
+
readonly status: 'timeout';
|
|
12
|
+
};
|
|
13
|
+
export interface ProcessTreeRuntime {
|
|
14
|
+
readonly platform: NodeJS.Platform;
|
|
15
|
+
readonly now: () => number;
|
|
16
|
+
readonly sleep: (delayMs: number) => Promise<void>;
|
|
17
|
+
readonly signalTarget: (signal: NodeJS.Signals) => void;
|
|
18
|
+
readonly signalTree: (rootPid: number, signal: NodeJS.Signals) => void;
|
|
19
|
+
readonly treeIsAlive: (rootPid: number) => boolean;
|
|
20
|
+
readonly runTaskkill: (rootPid: number, timeoutMs: number) => Promise<TaskkillOutcome>;
|
|
21
|
+
}
|
|
22
|
+
export interface ReapProcessTreeOptions {
|
|
23
|
+
readonly timeoutMs: number;
|
|
24
|
+
readonly probeIntervalMs: number;
|
|
25
|
+
readonly taskkillTimeoutMs: number;
|
|
26
|
+
readonly targetExitGraceMs: number;
|
|
27
|
+
}
|
|
28
|
+
export declare class HarnessCleanupError extends Error {
|
|
29
|
+
readonly rootPid: number | undefined;
|
|
30
|
+
constructor(rootPid: number | undefined, message: string, options?: ErrorOptions);
|
|
31
|
+
}
|
|
32
|
+
export declare class ProcessTreeController {
|
|
33
|
+
readonly rootPid: number | undefined;
|
|
34
|
+
readonly runtime: ProcessTreeRuntime;
|
|
35
|
+
private currentState;
|
|
36
|
+
private targetExited;
|
|
37
|
+
private streamsClosed;
|
|
38
|
+
private hardKillRequested;
|
|
39
|
+
private terminationError;
|
|
40
|
+
private reapPromise;
|
|
41
|
+
constructor(rootPid: number | undefined, runtime: ProcessTreeRuntime);
|
|
42
|
+
get state(): HarnessProcessState;
|
|
43
|
+
markRunning(): void;
|
|
44
|
+
requestTermination(signal: NodeJS.Signals): void;
|
|
45
|
+
markTargetExited(): void;
|
|
46
|
+
markStreamsClosed(): void;
|
|
47
|
+
treeIsAlive(): boolean;
|
|
48
|
+
reap(options: ReapProcessTreeOptions): Promise<void>;
|
|
49
|
+
private reapOnce;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=process-tree-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree-controller.d.ts","sourceRoot":"","sources":["../../../src/conformance/stdio-harness/process-tree-controller.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAC3B,SAAS,GACT,SAAS,GACT,aAAa,GACb,QAAQ,GACR,QAAQ,GACR,gBAAgB,CAAC;AAErB,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAEnC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;IACvE,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACnD,QAAQ,CAAC,WAAW,EAAE,CACpB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,eAAe,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAE1C,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS;gBAA3B,OAAO,EAAE,MAAM,GAAG,SAAS,EACpC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,YAAY;CAKzB;AAED,qBAAa,qBAAqB;IAS9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS;IACpC,QAAQ,CAAC,OAAO,EAAE,kBAAkB;IATtC,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,gBAAgB,CAAoB;IAC5C,OAAO,CAAC,WAAW,CAA4B;gBAGpC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,kBAAkB;IAGtC,IAAI,KAAK,IAAI,mBAAmB,CAE/B;IAED,WAAW,IAAI,IAAI;IAMnB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI;IA0BhD,gBAAgB,IAAI,IAAI;IAWxB,iBAAiB,IAAI,IAAI;IAIzB,WAAW,IAAI,OAAO;IAItB,IAAI,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;YAStC,QAAQ;CA6FvB"}
|