@hraness/direct 0.7.6 → 0.7.7
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/README.md +37 -9
- package/dist/tooling/bombadil.js +970 -32
- package/dist/tooling/browser-verification-entry.js +37 -5
- package/package.json +1 -1
- package/skills/direct/references/install.md +3 -3
- package/src/tooling/bombadil-campaign.ts +260 -30
- package/src/tooling/bombadil-runner.ts +1406 -27
- package/src/tooling/bombadil.ts +21 -0
- package/src/tooling/browser-verification.ts +55 -5
package/src/tooling/bombadil.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
attestDirectBombadilTrace as attestTrace,
|
|
3
3
|
runDirectBombadilFuzz as runFuzz,
|
|
4
|
+
runDirectBombadilFuzzMatrix as runMatrix,
|
|
5
|
+
summarizeDirectBombadilTrace as summarizeTrace,
|
|
4
6
|
} from "./bombadil-runner.js";
|
|
5
7
|
import type {
|
|
6
8
|
DirectBombadilFuzzConfig,
|
|
9
|
+
DirectBombadilFuzzCampaign,
|
|
10
|
+
DirectBombadilFuzzMatrixResult,
|
|
7
11
|
DirectBombadilFuzzResult,
|
|
8
12
|
} from "./bombadil-runner.js";
|
|
9
13
|
|
|
10
14
|
/** Host-side exact attestation for one bounded Bombadil 0.7.2 JSONL trace. */
|
|
11
15
|
export const attestDirectBombadilTrace: typeof attestTrace = attestTrace;
|
|
12
16
|
|
|
17
|
+
/** Derives bounded diagnostic navigation metadata without replacing the raw trace. */
|
|
18
|
+
export const summarizeDirectBombadilTrace: typeof summarizeTrace = summarizeTrace;
|
|
19
|
+
|
|
13
20
|
/** Runs one bounded local Bombadil campaign and preserves diagnostic artifacts. */
|
|
14
21
|
export function runDirectBombadilFuzz(
|
|
15
22
|
config: DirectBombadilFuzzConfig,
|
|
@@ -18,10 +25,24 @@ export function runDirectBombadilFuzz(
|
|
|
18
25
|
return arguments_ === undefined ? runFuzz(config) : runFuzz(config, arguments_);
|
|
19
26
|
}
|
|
20
27
|
|
|
28
|
+
/** Runs a bounded product campaign matrix serially and selects one for replay. */
|
|
29
|
+
export function runDirectBombadilFuzzMatrix(
|
|
30
|
+
campaigns: readonly DirectBombadilFuzzCampaign[],
|
|
31
|
+
arguments_?: readonly string[],
|
|
32
|
+
): Promise<DirectBombadilFuzzMatrixResult> {
|
|
33
|
+
return arguments_ === undefined ? runMatrix(campaigns) : runMatrix(campaigns, arguments_);
|
|
34
|
+
}
|
|
35
|
+
|
|
21
36
|
export type {
|
|
37
|
+
DirectBombadilActionKind,
|
|
38
|
+
DirectBombadilExplorationPolicy,
|
|
39
|
+
DirectBombadilExplorationSummary,
|
|
40
|
+
DirectBombadilFuzzCampaign,
|
|
22
41
|
DirectBombadilFuzzConfig,
|
|
42
|
+
DirectBombadilFuzzMatrixResult,
|
|
23
43
|
DirectBombadilFuzzResult,
|
|
24
44
|
DirectBombadilServerConfig,
|
|
25
45
|
DirectBombadilTraceAttestation,
|
|
26
46
|
DirectBombadilTraceBinding,
|
|
47
|
+
DirectBombadilViewportConfig,
|
|
27
48
|
} from "./bombadil-runner.js";
|
|
@@ -813,7 +813,38 @@ export async function stopVerificationServer(
|
|
|
813
813
|
await stopVerificationServerWithOutput(server, stopTimeoutMs);
|
|
814
814
|
}
|
|
815
815
|
|
|
816
|
+
function verificationServerAcquisitionAbortError(): Error {
|
|
817
|
+
return new Error("Verification server acquisition was aborted");
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
function throwIfVerificationServerAcquisitionAborted(signal: AbortSignal | undefined): void {
|
|
821
|
+
if (signal?.aborted === true) throw verificationServerAcquisitionAbortError();
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
async function waitForVerificationServerAcquisitionStep<Value>(
|
|
825
|
+
promise: Promise<Value>,
|
|
826
|
+
signal: AbortSignal | undefined,
|
|
827
|
+
): Promise<Value> {
|
|
828
|
+
if (signal === undefined) return await promise;
|
|
829
|
+
throwIfVerificationServerAcquisitionAborted(signal);
|
|
830
|
+
let abortListener: (() => void) | undefined;
|
|
831
|
+
const aborted = new Promise<never>((_resolve, reject) => {
|
|
832
|
+
abortListener = () => reject(verificationServerAcquisitionAbortError());
|
|
833
|
+
signal.addEventListener("abort", abortListener, { once: true });
|
|
834
|
+
if (signal.aborted) abortListener();
|
|
835
|
+
});
|
|
836
|
+
let value: Value;
|
|
837
|
+
try {
|
|
838
|
+
value = await Promise.race([promise, aborted]);
|
|
839
|
+
} finally {
|
|
840
|
+
if (abortListener !== undefined) signal.removeEventListener("abort", abortListener);
|
|
841
|
+
}
|
|
842
|
+
throwIfVerificationServerAcquisitionAborted(signal);
|
|
843
|
+
return value;
|
|
844
|
+
}
|
|
845
|
+
|
|
816
846
|
export async function acquireVerificationServer(options: {
|
|
847
|
+
readonly abortSignal?: AbortSignal;
|
|
817
848
|
readonly baseUrl: string;
|
|
818
849
|
readonly label: string;
|
|
819
850
|
readonly localHosts?: ReadonlySet<string>;
|
|
@@ -837,7 +868,11 @@ export async function acquireVerificationServer(options: {
|
|
|
837
868
|
options.baseUrl,
|
|
838
869
|
options.localHosts,
|
|
839
870
|
);
|
|
840
|
-
|
|
871
|
+
throwIfVerificationServerAcquisitionAborted(options.abortSignal);
|
|
872
|
+
if (await waitForVerificationServerAcquisitionStep(
|
|
873
|
+
Promise.resolve(isReachable(options.baseUrl, probeTimeoutMs, readinessPath)),
|
|
874
|
+
options.abortSignal,
|
|
875
|
+
)) {
|
|
841
876
|
if (canStartLocally && options.reuseExistingLocalServer === false) {
|
|
842
877
|
throw new Error(
|
|
843
878
|
`A local server is already reachable at ${options.baseUrl}; `
|
|
@@ -847,8 +882,15 @@ export async function acquireVerificationServer(options: {
|
|
|
847
882
|
// A verifier-owned command can exit before its child listener has finished
|
|
848
883
|
// shutting down. Require the listener to survive a bounded interval before
|
|
849
884
|
// another verifier trusts it as independently managed infrastructure.
|
|
850
|
-
await
|
|
851
|
-
|
|
885
|
+
await waitForVerificationServerAcquisitionStep(
|
|
886
|
+
Bun.sleep(options.reuseProbeIntervalMs ?? DEFAULT_REUSE_PROBE_INTERVAL_MS),
|
|
887
|
+
options.abortSignal,
|
|
888
|
+
);
|
|
889
|
+
if (await waitForVerificationServerAcquisitionStep(
|
|
890
|
+
Promise.resolve(isReachable(options.baseUrl, probeTimeoutMs, readinessPath)),
|
|
891
|
+
options.abortSignal,
|
|
892
|
+
)) {
|
|
893
|
+
throwIfVerificationServerAcquisitionAborted(options.abortSignal);
|
|
852
894
|
return { source: "reused" };
|
|
853
895
|
}
|
|
854
896
|
}
|
|
@@ -858,6 +900,7 @@ export async function acquireVerificationServer(options: {
|
|
|
858
900
|
);
|
|
859
901
|
}
|
|
860
902
|
|
|
903
|
+
throwIfVerificationServerAcquisitionAborted(options.abortSignal);
|
|
861
904
|
const server = options.startServer();
|
|
862
905
|
let exitedWithCode: number | null = null;
|
|
863
906
|
try {
|
|
@@ -868,10 +911,17 @@ export async function acquireVerificationServer(options: {
|
|
|
868
911
|
exitedWithCode = exitCode;
|
|
869
912
|
break;
|
|
870
913
|
}
|
|
871
|
-
if (await
|
|
914
|
+
if (await waitForVerificationServerAcquisitionStep(
|
|
915
|
+
Promise.resolve(isReachable(options.baseUrl, probeTimeoutMs, readinessPath)),
|
|
916
|
+
options.abortSignal,
|
|
917
|
+
)) {
|
|
918
|
+
throwIfVerificationServerAcquisitionAborted(options.abortSignal);
|
|
872
919
|
return { source: "started", server };
|
|
873
920
|
}
|
|
874
|
-
await
|
|
921
|
+
await waitForVerificationServerAcquisitionStep(
|
|
922
|
+
Bun.sleep(options.pollIntervalMs ?? 200),
|
|
923
|
+
options.abortSignal,
|
|
924
|
+
);
|
|
875
925
|
}
|
|
876
926
|
} catch (error) {
|
|
877
927
|
await stopVerificationServer(server);
|