@loucompanion/forge-bridge 0.1.3-dev.f66395c3ac21 → 0.1.4-dev.1ff37038366e
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 +165 -1
- package/dist/bridge/bridge-chat.types.d.ts +111 -0
- package/dist/bridge/bridge-chat.types.js +401 -0
- package/dist/bridge/bridge.base.d.ts +9 -1
- package/dist/bridge/bridge.service.d.ts +129 -3
- package/dist/bridge/bridge.service.js +2427 -70
- package/dist/bridge/bridge.types.d.ts +218 -2
- package/dist/bridge/dispatch-result-outbox.d.ts +25 -0
- package/dist/bridge/dispatch-result-outbox.js +62 -0
- package/dist/bridge/dispatch-result-worker.d.ts +2 -0
- package/dist/bridge/dispatch-result-worker.js +122 -0
- package/dist/bridge/internals.d.ts +2 -0
- package/dist/bridge/internals.js +1 -0
- package/dist/bridge/readiness-result-outbox.d.ts +21 -0
- package/dist/bridge/readiness-result-outbox.js +54 -0
- package/dist/bridge/readiness-result-worker.d.ts +2 -0
- package/dist/bridge/readiness-result-worker.js +121 -0
- package/dist/bridge/runner-host-capabilities.d.ts +15 -0
- package/dist/bridge/runner-host-capabilities.js +93 -0
- package/dist/cleanup/cleanup.service.d.ts +14 -2
- package/dist/cleanup/cleanup.service.js +496 -3
- package/dist/cleanup/cleanup.types.d.ts +10 -0
- package/dist/cleanup/index.d.ts +1 -1
- package/dist/cleanup/index.js +1 -1
- package/dist/cleanup/internals.d.ts +2 -2
- package/dist/cleanup/internals.js +1 -1
- package/dist/cli/cli.help.d.ts +2 -0
- package/dist/cli/cli.help.js +217 -0
- package/dist/cli/cli.service.d.ts +55 -7
- package/dist/cli/cli.service.js +429 -219
- package/dist/cli/local-config.d.ts +7 -0
- package/dist/cli/local-config.js +51 -3
- package/dist/runtime/aspnet-runtime-prebuild.d.ts +36 -0
- package/dist/runtime/aspnet-runtime-prebuild.js +341 -0
- package/dist/runtime/attempt-database-broker.d.ts +89 -0
- package/dist/runtime/attempt-database-broker.js +390 -0
- package/dist/runtime/attempt-node-runtime-launcher.d.ts +18 -0
- package/dist/runtime/attempt-node-runtime-launcher.js +140 -0
- package/dist/runtime/attempt-path-operation.d.ts +21 -0
- package/dist/runtime/attempt-path-operation.js +94 -0
- package/dist/runtime/attempt-private-directory.d.ts +6 -0
- package/dist/runtime/attempt-private-directory.js +54 -0
- package/dist/runtime/attempt-process-supervisor-registry.d.ts +20 -0
- package/dist/runtime/attempt-process-supervisor-registry.js +64 -0
- package/dist/runtime/attempt-process-supervisor.d.ts +97 -0
- package/dist/runtime/attempt-process-supervisor.js +397 -0
- package/dist/runtime/canonical-source-file.d.ts +3 -0
- package/dist/runtime/canonical-source-file.js +54 -0
- package/dist/runtime/docker-engine-probe.d.ts +90 -0
- package/dist/runtime/docker-engine-probe.js +333 -0
- package/dist/runtime/generated-output-reset.d.ts +20 -0
- package/dist/runtime/generated-output-reset.js +157 -0
- package/dist/runtime/host-database-capability-boundary.d.ts +16 -0
- package/dist/runtime/host-database-capability-boundary.js +62 -0
- package/dist/runtime/host-diagnostics.d.ts +11 -0
- package/dist/runtime/host-diagnostics.js +191 -0
- package/dist/runtime/host-execution-root.d.ts +4 -0
- package/dist/runtime/host-execution-root.js +39 -0
- package/dist/runtime/host-listener-inspector.d.ts +51 -0
- package/dist/runtime/host-listener-inspector.js +385 -0
- package/dist/runtime/host-port-broker.d.ts +76 -0
- package/dist/runtime/host-port-broker.js +333 -0
- package/dist/runtime/host-runtime-contract.d.ts +58 -0
- package/dist/runtime/host-runtime-contract.js +813 -0
- package/dist/runtime/host-runtime-lease.d.ts +217 -0
- package/dist/runtime/host-runtime-lease.js +2487 -0
- package/dist/runtime/host-runtime-promotion.d.ts +32 -0
- package/dist/runtime/host-runtime-promotion.js +206 -0
- package/dist/runtime/memory-capacity.d.ts +70 -0
- package/dist/runtime/memory-capacity.js +123 -0
- package/dist/runtime/native-test-postgres-fallback.d.ts +25 -0
- package/dist/runtime/native-test-postgres-fallback.js +91 -0
- package/dist/runtime/node-host-runtime-adapter.d.ts +54 -0
- package/dist/runtime/node-host-runtime-adapter.js +285 -0
- package/dist/runtime/pinned-directory-process.d.ts +9 -0
- package/dist/runtime/pinned-directory-process.js +61 -0
- package/dist/runtime/pinned-source-directory.d.ts +17 -0
- package/dist/runtime/pinned-source-directory.js +94 -0
- package/dist/runtime/playwright-host-runtime-adapter.d.ts +21 -0
- package/dist/runtime/playwright-host-runtime-adapter.js +268 -0
- package/dist/runtime/prepared-runtime-identity.d.ts +6 -0
- package/dist/runtime/prepared-runtime-identity.js +218 -0
- package/dist/runtime/prepared-runtime-readiness.d.ts +30 -0
- package/dist/runtime/prepared-runtime-readiness.js +285 -0
- package/dist/runtime/runtime-isolation-lease.d.ts +67 -0
- package/dist/runtime/runtime-isolation-lease.js +161 -0
- package/dist/runtime/workspace-resource-estimator.d.ts +17 -0
- package/dist/runtime/workspace-resource-estimator.js +174 -0
- package/dist/sandbox/command-runner.d.ts +4 -0
- package/dist/sandbox/command-runner.js +47 -0
- package/dist/sandbox/contract.d.ts +5 -0
- package/dist/sandbox/contract.js +276 -0
- package/dist/sandbox/event-budget.d.ts +11 -0
- package/dist/sandbox/event-budget.js +27 -0
- package/dist/sandbox/image-policy.d.ts +35 -0
- package/dist/sandbox/image-policy.js +247 -0
- package/dist/sandbox/index.d.ts +5 -0
- package/dist/sandbox/index.js +5 -0
- package/dist/sandbox/lease-watchdog.d.ts +18 -0
- package/dist/sandbox/lease-watchdog.js +67 -0
- package/dist/sandbox/preflight.d.ts +84 -0
- package/dist/sandbox/preflight.js +521 -0
- package/dist/sandbox/process.d.ts +20 -0
- package/dist/sandbox/process.js +209 -0
- package/dist/sandbox/provider-auth/codex.d.ts +26 -0
- package/dist/sandbox/provider-auth/codex.js +212 -0
- package/dist/sandbox/repository-lock.d.ts +6 -0
- package/dist/sandbox/repository-lock.js +128 -0
- package/dist/sandbox/runtime.d.ts +302 -0
- package/dist/sandbox/runtime.js +2367 -0
- package/dist/sandbox/sandbox.types.d.ts +93 -0
- package/dist/sandbox/sandbox.types.js +1 -0
- package/dist/sandbox/smoke.d.ts +76 -0
- package/dist/sandbox/smoke.js +380 -0
- package/dist/sandbox/worker-supervisor.d.ts +13 -0
- package/dist/sandbox/worker-supervisor.js +36 -0
- package/dist/sandbox/worker.d.ts +1 -0
- package/dist/sandbox/worker.js +225 -0
- package/dist/sandbox/workspace.service.d.ts +13 -0
- package/dist/sandbox/workspace.service.js +74 -0
- package/dist/session/managed-attempt-tools.d.ts +28 -0
- package/dist/session/managed-attempt-tools.js +1015 -0
- package/dist/session/managed-build-coordinator.d.ts +5 -0
- package/dist/session/managed-build-coordinator.js +105 -0
- package/dist/session/managed-build-receipt.d.ts +21 -0
- package/dist/session/managed-build-receipt.js +337 -0
- package/dist/session/managed-verification-timeouts.d.ts +8 -0
- package/dist/session/managed-verification-timeouts.js +17 -0
- package/dist/session/phase-completion.artifacts.d.ts +27 -0
- package/dist/session/phase-completion.artifacts.js +829 -0
- package/dist/session/phase-completion.d.ts +53 -42
- package/dist/session/phase-completion.helpers.d.ts +117 -0
- package/dist/session/phase-completion.helpers.js +707 -0
- package/dist/session/phase-completion.js +125 -3007
- package/dist/session/phase-completion.prompts.d.ts +14 -0
- package/dist/session/phase-completion.prompts.js +233 -0
- package/dist/session/phase-completion.runtime.d.ts +49 -0
- package/dist/session/phase-completion.runtime.js +840 -0
- package/dist/session/phase-completion.schemas.d.ts +3 -0
- package/dist/session/phase-completion.schemas.js +859 -0
- package/dist/session/phase-completion.validation.d.ts +38 -0
- package/dist/session/phase-completion.validation.js +918 -0
- package/dist/session/pre-publication-validation.d.ts +75 -0
- package/dist/session/pre-publication-validation.js +661 -0
- package/dist/session/provider-cli/bridge-cli.conformance-fixtures.d.ts +72 -0
- package/dist/session/provider-cli/bridge-cli.conformance-fixtures.js +462 -0
- package/dist/session/provider-cli/ci-repair-readiness.d.ts +16 -0
- package/dist/session/provider-cli/ci-repair-readiness.js +110 -0
- package/dist/session/provider-cli/provider-cli.artifacts.d.ts +95 -0
- package/dist/session/provider-cli/provider-cli.artifacts.js +812 -0
- package/dist/session/provider-cli/provider-cli.base.d.ts +1 -0
- package/dist/session/provider-cli/provider-cli.deterministic-payloads.d.ts +12 -0
- package/dist/session/provider-cli/provider-cli.deterministic-payloads.js +279 -0
- package/dist/session/provider-cli/provider-cli.deterministic.d.ts +14 -0
- package/dist/session/provider-cli/provider-cli.deterministic.js +407 -0
- package/dist/session/provider-cli/provider-cli.process.d.ts +99 -0
- package/dist/session/provider-cli/provider-cli.process.js +874 -0
- package/dist/session/provider-cli/provider-cli.prompts.d.ts +52 -0
- package/dist/session/provider-cli/provider-cli.prompts.js +715 -0
- package/dist/session/provider-cli/provider-cli.qa-sidecars.d.ts +11 -0
- package/dist/session/provider-cli/provider-cli.qa-sidecars.js +66 -0
- package/dist/session/provider-cli/provider-cli.repair-epoch.d.ts +6 -0
- package/dist/session/provider-cli/provider-cli.repair-epoch.js +11 -0
- package/dist/session/provider-cli/provider-cli.runtime.d.ts +16 -0
- package/dist/session/provider-cli/provider-cli.runtime.js +81 -0
- package/dist/session/provider-cli/provider-cli.service.d.ts +47 -53
- package/dist/session/provider-cli/provider-cli.service.js +1257 -2497
- package/dist/session/provider-cli/provider-cli.types.d.ts +8 -0
- package/dist/session/provider-cli/provider-output-state.d.ts +32 -0
- package/dist/session/provider-cli/provider-output-state.js +817 -0
- package/dist/session/provider-cli/provider-usage.d.ts +7 -0
- package/dist/session/provider-cli/provider-usage.js +28 -5
- package/dist/session/session-redaction.d.ts +3 -0
- package/dist/session/session-redaction.js +448 -0
- package/dist/session/session.base.d.ts +6 -1
- package/dist/session/session.service.d.ts +8 -2
- package/dist/session/session.service.js +586 -59
- package/dist/session/session.types.d.ts +324 -3
- package/dist/session/session.types.js +939 -10
- package/dist/session/unreferenced-exports.d.ts +12 -0
- package/dist/session/unreferenced-exports.js +59 -0
- package/dist/shared/format/format-bytes.d.ts +1 -0
- package/dist/shared/format/format-bytes.js +9 -0
- package/dist/shared/git/git.js +2 -1
- package/dist/shared/path/path.d.ts +1 -0
- package/dist/shared/path/path.js +21 -1
- package/dist/shared/process/dotnet-toolchain.d.ts +17 -0
- package/dist/shared/process/dotnet-toolchain.js +307 -0
- package/dist/shared/process/host-process-recovery.d.ts +12 -0
- package/dist/shared/process/host-process-recovery.js +78 -0
- package/dist/shared/process/host-process-supervisor.d.ts +59 -0
- package/dist/shared/process/host-process-supervisor.js +330 -0
- package/dist/shared/process/process.d.ts +3 -0
- package/dist/shared/process/process.js +13 -7
- package/dist/shared/process/windows-launch.d.ts +8 -0
- package/dist/shared/process/windows-launch.js +41 -0
- package/dist/shared/provider-capabilities.d.ts +4 -0
- package/dist/shared/provider-capabilities.js +88 -0
- package/dist/shared/redaction/redaction.d.ts +1 -0
- package/dist/shared/redaction/redaction.js +47 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worktree/artifact-injector.d.ts +3 -2
- package/dist/worktree/artifact-injector.js +82 -10
- package/dist/worktree/dependency-warmer.d.ts +53 -1
- package/dist/worktree/dependency-warmer.js +619 -11
- package/dist/worktree/index.d.ts +2 -1
- package/dist/worktree/index.js +1 -0
- package/dist/worktree/prior-phase-artifact-hydrator.d.ts +2 -0
- package/dist/worktree/prior-phase-artifact-hydrator.js +136 -0
- package/dist/worktree/story-qa-reference-hydrator.d.ts +4 -0
- package/dist/worktree/story-qa-reference-hydrator.js +253 -0
- package/dist/worktree/worktree-paths.d.ts +4 -0
- package/dist/worktree/worktree-paths.js +30 -0
- package/dist/worktree/worktree.base.d.ts +3 -0
- package/dist/worktree/worktree.service.d.ts +16 -3
- package/dist/worktree/worktree.service.js +334 -54
- package/dist/worktree/worktree.types.d.ts +9 -1
- package/package.json +12 -7
- package/runtime/windows-job-supervisor.ps1 +722 -0
- package/runtime/windows-listener-owner.ps1 +33 -0
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import type { RunOnceDispatchPacket, RunnerDispatchEvent } from "../session.types.js";
|
|
2
2
|
export type UsageSource = "provider_reported" | "cli_reported" | "estimated" | "unknown";
|
|
3
|
+
export type InputTokenSemantics = "includes_cached_input" | "excludes_cache_tokens" | "unknown";
|
|
4
|
+
export declare const PROVIDER_USAGE_SCHEMA_VERSION = 1;
|
|
3
5
|
/**
|
|
4
6
|
* Normalized, provider-agnostic token usage accumulated for a dispatch. Cost is never computed
|
|
5
7
|
* here; the API recomputes cost from these tokens x model rates (ADR-0006).
|
|
6
8
|
*/
|
|
7
9
|
export interface ProviderUsage {
|
|
10
|
+
/** Normalized total input. Cached input is a subset, never an additive peer. */
|
|
8
11
|
readonly inputTokens: number;
|
|
12
|
+
readonly uncachedInputTokens: number | null;
|
|
9
13
|
readonly outputTokens: number;
|
|
10
14
|
readonly cacheReadTokens: number;
|
|
11
15
|
readonly cacheCreationTokens: number;
|
|
12
16
|
readonly reasoningOutputTokens: number;
|
|
13
17
|
readonly providerDurationMs: number | null;
|
|
14
18
|
readonly source: UsageSource;
|
|
19
|
+
readonly inputTokenSemantics: InputTokenSemantics;
|
|
20
|
+
/** Exact provider usage objects retained for audit/re-normalization. */
|
|
21
|
+
readonly rawUsage: readonly Record<string, unknown>[];
|
|
15
22
|
}
|
|
16
23
|
export declare function emptyUsage(source?: UsageSource): ProviderUsage;
|
|
17
24
|
export declare function addUsage(base: ProviderUsage, next: Partial<ProviderUsage>): ProviderUsage;
|
|
@@ -1,27 +1,38 @@
|
|
|
1
|
+
export const PROVIDER_USAGE_SCHEMA_VERSION = 1;
|
|
1
2
|
export function emptyUsage(source = "unknown") {
|
|
2
3
|
return {
|
|
3
4
|
inputTokens: 0,
|
|
5
|
+
uncachedInputTokens: 0,
|
|
4
6
|
outputTokens: 0,
|
|
5
7
|
cacheReadTokens: 0,
|
|
6
8
|
cacheCreationTokens: 0,
|
|
7
9
|
reasoningOutputTokens: 0,
|
|
8
10
|
providerDurationMs: null,
|
|
9
|
-
source
|
|
11
|
+
source,
|
|
12
|
+
inputTokenSemantics: "unknown",
|
|
13
|
+
rawUsage: []
|
|
10
14
|
};
|
|
11
15
|
}
|
|
12
16
|
export function addUsage(base, next) {
|
|
17
|
+
const nextUncached = next.uncachedInputTokens;
|
|
18
|
+
const uncachedInputTokens = base.uncachedInputTokens === null || nextUncached === null
|
|
19
|
+
? null
|
|
20
|
+
: base.uncachedInputTokens + nonNegative(nextUncached);
|
|
13
21
|
return {
|
|
14
22
|
inputTokens: base.inputTokens + nonNegative(next.inputTokens),
|
|
23
|
+
uncachedInputTokens,
|
|
15
24
|
outputTokens: base.outputTokens + nonNegative(next.outputTokens),
|
|
16
25
|
cacheReadTokens: base.cacheReadTokens + nonNegative(next.cacheReadTokens),
|
|
17
26
|
cacheCreationTokens: base.cacheCreationTokens + nonNegative(next.cacheCreationTokens),
|
|
18
27
|
reasoningOutputTokens: base.reasoningOutputTokens + nonNegative(next.reasoningOutputTokens),
|
|
19
28
|
providerDurationMs: next.providerDurationMs ?? base.providerDurationMs,
|
|
20
|
-
source: next.source ?? base.source
|
|
29
|
+
source: next.source ?? base.source,
|
|
30
|
+
inputTokenSemantics: mergeSemantics(base.inputTokenSemantics, next.inputTokenSemantics),
|
|
31
|
+
rawUsage: [...base.rawUsage, ...(next.rawUsage ?? [])]
|
|
21
32
|
};
|
|
22
33
|
}
|
|
23
34
|
export function totalTokens(usage) {
|
|
24
|
-
return usage.inputTokens + usage.outputTokens
|
|
35
|
+
return usage.inputTokens + usage.outputTokens;
|
|
25
36
|
}
|
|
26
37
|
export function hasUsage(usage) {
|
|
27
38
|
return usage !== null && totalTokens(usage) > 0;
|
|
@@ -37,20 +48,26 @@ export function buildProviderUsageEvent(dispatch, usage) {
|
|
|
37
48
|
lane: dispatch.execution.lane,
|
|
38
49
|
phase: dispatch.cycleRun.phase,
|
|
39
50
|
attempt: dispatch.cycleRun.attempt,
|
|
51
|
+
usage_schema_version: PROVIDER_USAGE_SCHEMA_VERSION,
|
|
52
|
+
input_token_semantics: usage.inputTokenSemantics,
|
|
40
53
|
input_tokens: usage.inputTokens,
|
|
54
|
+
uncached_input_tokens: usage.uncachedInputTokens,
|
|
41
55
|
output_tokens: usage.outputTokens,
|
|
42
56
|
cache_read_tokens: usage.cacheReadTokens,
|
|
43
57
|
cache_creation_tokens: usage.cacheCreationTokens,
|
|
44
58
|
reasoning_output_tokens: usage.reasoningOutputTokens,
|
|
45
59
|
metered: dispatch.execution.authKind === "api_key",
|
|
46
60
|
usage_source: usage.source,
|
|
47
|
-
provider_duration_ms: usage.providerDurationMs
|
|
61
|
+
provider_duration_ms: usage.providerDurationMs,
|
|
62
|
+
normalized_total_tokens: totalTokens(usage),
|
|
63
|
+
normalized_total_formula: "total_input + output; cached_input is a subset of total_input",
|
|
64
|
+
raw_usage: usage.rawUsage
|
|
48
65
|
};
|
|
49
66
|
const total = totalTokens(usage);
|
|
50
67
|
return {
|
|
51
68
|
role: "runner",
|
|
52
69
|
kind: "checkpoint",
|
|
53
|
-
content: `Provider usage: ${total} tokens (${usage.inputTokens} in / ${usage.outputTokens} out) for ${dispatch.execution.model}.`,
|
|
70
|
+
content: `Provider usage: ${total} tokens (${usage.inputTokens} total in, including ${usage.cacheReadTokens} cached / ${usage.outputTokens} out) for ${dispatch.execution.model}.`,
|
|
54
71
|
eventType: "provider_usage",
|
|
55
72
|
data: JSON.stringify(data)
|
|
56
73
|
};
|
|
@@ -62,3 +79,9 @@ export function readUsageNumber(source, key) {
|
|
|
62
79
|
function nonNegative(value) {
|
|
63
80
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
64
81
|
}
|
|
82
|
+
function mergeSemantics(base, next) {
|
|
83
|
+
if (!next || next === "unknown") {
|
|
84
|
+
return base;
|
|
85
|
+
}
|
|
86
|
+
return base === "unknown" || base === next ? next : "unknown";
|
|
87
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { RunOnceResultPacket, RunnerDispatchEvent } from "./session.types.js";
|
|
2
|
+
export declare function redactRunnerDispatchEvent(event: RunnerDispatchEvent, exactSecrets?: readonly string[]): RunnerDispatchEvent;
|
|
3
|
+
export declare function redactRunOnceResultPacket(result: RunOnceResultPacket, exactSecrets?: readonly string[]): RunOnceResultPacket;
|
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
import { redactText, shouldRedactJsonProperty } from "../shared/redaction/redaction.js";
|
|
2
|
+
import { TextDecoder } from "node:util";
|
|
3
|
+
const integrityProtectedEventDataTypes = new Set(["sandbox_started"]);
|
|
4
|
+
const structuralSecretMessage = "runner result structural metadata contains protected secret material and cannot be redacted without changing protocol identity.";
|
|
5
|
+
const sidecarSecretMessage = "runner result sidecar contains protected secret material and cannot be redacted without invalidating integrity metadata.";
|
|
6
|
+
const artifactJsonMessage = "runner result artifact JSON is invalid or exceeds safe inspection limits; transport was rejected.";
|
|
7
|
+
const artifactJsonKeySecretMessage = "runner result artifact JSON property name contains protected secret material and cannot be redacted without changing protocol identity.";
|
|
8
|
+
const artifactJsonPrimitiveSecretMessage = "runner result artifact JSON primitive contains protected secret material and cannot be redacted without changing protocol identity.";
|
|
9
|
+
const maximumIntegrityJsonBytes = 8 * 1024 * 1024;
|
|
10
|
+
const maximumIntegrityJsonDepth = 128;
|
|
11
|
+
const maximumIntegrityJsonTokens = 262_144;
|
|
12
|
+
export function redactRunnerDispatchEvent(event, exactSecrets = []) {
|
|
13
|
+
assertStructuralFieldsDoNotContainSecrets([
|
|
14
|
+
event.role,
|
|
15
|
+
event.kind,
|
|
16
|
+
event.eventType,
|
|
17
|
+
event.wait?.kind,
|
|
18
|
+
event.wait?.scope,
|
|
19
|
+
event.wait?.wakeCondition,
|
|
20
|
+
event.wait?.contractOrigin,
|
|
21
|
+
...(event.wait?.resourceKeys ?? []),
|
|
22
|
+
], exactSecrets);
|
|
23
|
+
if (event.data !== undefined
|
|
24
|
+
&& event.data !== null
|
|
25
|
+
&& integrityProtectedEventDataTypes.has(event.eventType)) {
|
|
26
|
+
// Integrity-protected data cannot be rewritten because the runtime lease repeats the
|
|
27
|
+
// dispatch fence. Check the complete serialized payload so current and future resource
|
|
28
|
+
// identity fields cannot carry pending secret material across this boundary.
|
|
29
|
+
assertSerializedJsonDoesNotContainSecrets(event.data, exactSecrets, structuralSecretMessage);
|
|
30
|
+
}
|
|
31
|
+
// sandbox_started data is runner-authored protocol metadata. Its runtime
|
|
32
|
+
// lease repeats the dispatch fence so the API can validate ownership. The
|
|
33
|
+
// transcript redactor treats any serialized `*Token` field as a secret and
|
|
34
|
+
// must not rewrite that identity before transport or result persistence.
|
|
35
|
+
return {
|
|
36
|
+
...event,
|
|
37
|
+
content: redactContent(event.content, exactSecrets),
|
|
38
|
+
...(event.wait === undefined
|
|
39
|
+
? {}
|
|
40
|
+
: { wait: event.wait === null ? null : redactWait(event.wait, exactSecrets) }),
|
|
41
|
+
...(event.data === undefined || event.data === null
|
|
42
|
+
? {}
|
|
43
|
+
: {
|
|
44
|
+
data: integrityProtectedEventDataTypes.has(event.eventType)
|
|
45
|
+
? event.data
|
|
46
|
+
: redactContent(event.data, exactSecrets),
|
|
47
|
+
}),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function redactWait(wait, exactSecrets) {
|
|
51
|
+
return {
|
|
52
|
+
...wait,
|
|
53
|
+
...(wait.blockerTitle === undefined || wait.blockerTitle === null
|
|
54
|
+
? {}
|
|
55
|
+
: { blockerTitle: redactContent(wait.blockerTitle, exactSecrets).slice(0, 500) }),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export function redactRunOnceResultPacket(result, exactSecrets = []) {
|
|
59
|
+
assertStructuralFieldsDoNotContainSecrets([result.resultCommitSha, result.publishedCommitSha], exactSecrets);
|
|
60
|
+
return {
|
|
61
|
+
...result,
|
|
62
|
+
summary: redactContent(result.summary, exactSecrets),
|
|
63
|
+
...(result.failure !== undefined
|
|
64
|
+
? { failure: result.failure === null ? null : redactFailure(result.failure, exactSecrets) }
|
|
65
|
+
: {}),
|
|
66
|
+
...(result.spec !== undefined
|
|
67
|
+
? { spec: result.spec === null ? null : redactSpec(result.spec, exactSecrets) }
|
|
68
|
+
: {}),
|
|
69
|
+
...(result.artifact !== undefined
|
|
70
|
+
? { artifact: result.artifact === null ? null : redactArtifact(result.artifact, exactSecrets) }
|
|
71
|
+
: {}),
|
|
72
|
+
...(result.artifacts !== undefined
|
|
73
|
+
? {
|
|
74
|
+
artifacts: result.artifacts === null
|
|
75
|
+
? null
|
|
76
|
+
: result.artifacts.map(item => redactArtifact(item, exactSecrets)),
|
|
77
|
+
}
|
|
78
|
+
: {}),
|
|
79
|
+
events: result.events.map(event => redactRunnerDispatchEvent(event, exactSecrets)),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function redactFailure(failure, exactSecrets) {
|
|
83
|
+
assertStructuralFieldsDoNotContainSecrets([failure.code, ...failure.causalChain.map(cause => cause.code)], exactSecrets);
|
|
84
|
+
return {
|
|
85
|
+
...failure,
|
|
86
|
+
message: redactContent(failure.message, exactSecrets),
|
|
87
|
+
causalChain: failure.causalChain.map(cause => ({
|
|
88
|
+
...cause,
|
|
89
|
+
message: redactContent(cause.message, exactSecrets),
|
|
90
|
+
})),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function redactSpec(spec, exactSecrets) {
|
|
94
|
+
assertStructuralFieldsDoNotContainSecrets([spec.repoPath, spec.path, spec.producedBy, spec.status], exactSecrets);
|
|
95
|
+
return { ...spec, body: redactContent(spec.body, exactSecrets) };
|
|
96
|
+
}
|
|
97
|
+
function redactArtifact(artifact, exactSecrets) {
|
|
98
|
+
assertStructuralFieldsDoNotContainSecrets([artifact.repoPath, artifact.path, artifact.producedBy, artifact.status, artifact.phase], exactSecrets);
|
|
99
|
+
assertSidecarsDoNotContainSecrets(artifact.sidecars, exactSecrets);
|
|
100
|
+
return {
|
|
101
|
+
...artifact,
|
|
102
|
+
verdictJson: redactArtifactJson(artifact.verdictJson, exactSecrets),
|
|
103
|
+
...(artifact.planJson === undefined || artifact.planJson === null
|
|
104
|
+
? {}
|
|
105
|
+
: { planJson: redactArtifactJson(artifact.planJson, exactSecrets) }),
|
|
106
|
+
...(artifact.evidenceJson === undefined || artifact.evidenceJson === null
|
|
107
|
+
? {}
|
|
108
|
+
: { evidenceJson: redactArtifactJson(artifact.evidenceJson, exactSecrets) }),
|
|
109
|
+
...(artifact.findingsJson === undefined || artifact.findingsJson === null
|
|
110
|
+
? {}
|
|
111
|
+
: { findingsJson: redactArtifactJson(artifact.findingsJson, exactSecrets) }),
|
|
112
|
+
...(artifact.implementationPlanJson === undefined || artifact.implementationPlanJson === null
|
|
113
|
+
? {}
|
|
114
|
+
: { implementationPlanJson: redactArtifactJson(artifact.implementationPlanJson, exactSecrets) }),
|
|
115
|
+
...(artifact.qaPlanJson === undefined || artifact.qaPlanJson === null
|
|
116
|
+
? {}
|
|
117
|
+
: { qaPlanJson: redactArtifactJson(artifact.qaPlanJson, exactSecrets) }),
|
|
118
|
+
report: redactContent(artifact.report, exactSecrets),
|
|
119
|
+
// These bytes already passed the QA path/hash/size checks. The generic
|
|
120
|
+
// redactor strips contentBase64 fields and must not corrupt the payload.
|
|
121
|
+
...(artifact.sidecars !== undefined ? { sidecars: artifact.sidecars } : {}),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function redactArtifactJson(value, exactSecrets) {
|
|
125
|
+
// Validate the original before redaction. Replacing an invalid value must never
|
|
126
|
+
// turn a malformed evidence bundle into an apparently valid QA artifact.
|
|
127
|
+
inspectJsonStringTokens(value, [], artifactJsonMessage);
|
|
128
|
+
const chunks = [];
|
|
129
|
+
let unchangedStart = 0;
|
|
130
|
+
let index = 0;
|
|
131
|
+
const replace = (start, end, replacement) => {
|
|
132
|
+
if (value.slice(start, end) === replacement)
|
|
133
|
+
return;
|
|
134
|
+
chunks.push(value.slice(unchangedStart, start), replacement);
|
|
135
|
+
unchangedStart = end;
|
|
136
|
+
};
|
|
137
|
+
while (index < value.length) {
|
|
138
|
+
if (value.charCodeAt(index) !== 0x22) {
|
|
139
|
+
const code = value.charCodeAt(index);
|
|
140
|
+
if (isJsonWhitespace(code) || isJsonPunctuation(code)) {
|
|
141
|
+
index += 1;
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
const end = jsonValueEnd(value, index);
|
|
145
|
+
// Numeric credentials and other exact primitive matches are still secrets.
|
|
146
|
+
// Fail closed instead of silently changing evidence types to strings.
|
|
147
|
+
assertJsonStringDoesNotContainSecrets(value.slice(index, end), exactSecrets, artifactJsonPrimitiveSecretMessage);
|
|
148
|
+
index = end;
|
|
149
|
+
}
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const token = decodeJsonStringToken(value, index, artifactJsonMessage);
|
|
153
|
+
const afterToken = skipJsonWhitespace(value, token.nextIndex);
|
|
154
|
+
if (value.charCodeAt(afterToken) === 0x3a) {
|
|
155
|
+
assertJsonStringDoesNotContainSecrets(token.decoded, exactSecrets, artifactJsonKeySecretMessage);
|
|
156
|
+
if (redactText(token.decoded, exactSecrets) !== token.decoded)
|
|
157
|
+
throw new Error(artifactJsonKeySecretMessage);
|
|
158
|
+
if (shouldRedactJsonProperty(token.decoded)) {
|
|
159
|
+
const valueStart = skipJsonWhitespace(value, afterToken + 1);
|
|
160
|
+
const valueEnd = jsonValueEnd(value, valueStart);
|
|
161
|
+
if (value[valueStart] !== '"'
|
|
162
|
+
|| decodeJsonStringToken(value, valueStart, artifactJsonMessage).decoded !== "[REDACTED]") {
|
|
163
|
+
replace(valueStart, valueEnd, '"[REDACTED]"');
|
|
164
|
+
}
|
|
165
|
+
index = valueEnd;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
const redacted = redactText(token.decoded, exactSecrets);
|
|
171
|
+
if (redacted !== token.decoded)
|
|
172
|
+
replace(index, token.nextIndex, JSON.stringify(redacted));
|
|
173
|
+
}
|
|
174
|
+
index = token.nextIndex;
|
|
175
|
+
}
|
|
176
|
+
if (chunks.length === 0)
|
|
177
|
+
return value;
|
|
178
|
+
chunks.push(value.slice(unchangedStart));
|
|
179
|
+
const redacted = chunks.join("");
|
|
180
|
+
// Retain the same bounded contract even when a short exact secret expands into
|
|
181
|
+
// a longer redaction marker. No raw JSON regex or parse/stringify round-trip:
|
|
182
|
+
// untouched escapes, whitespace, duplicate properties and numeric text survive.
|
|
183
|
+
inspectJsonStringTokens(redacted, [], artifactJsonMessage);
|
|
184
|
+
return redacted;
|
|
185
|
+
}
|
|
186
|
+
function skipJsonWhitespace(value, start) {
|
|
187
|
+
let index = start;
|
|
188
|
+
while (index < value.length && isJsonWhitespace(value.charCodeAt(index)))
|
|
189
|
+
index += 1;
|
|
190
|
+
return index;
|
|
191
|
+
}
|
|
192
|
+
// Called only after bounded JSON validation. Locate a credential property's whole
|
|
193
|
+
// value (including objects/arrays) without decoding or rewriting adjacent data.
|
|
194
|
+
function jsonValueEnd(value, start) {
|
|
195
|
+
if (value.charCodeAt(start) === 0x22) {
|
|
196
|
+
return decodeJsonStringToken(value, start, artifactJsonMessage).nextIndex;
|
|
197
|
+
}
|
|
198
|
+
if (value[start] === "{" || value[start] === "[") {
|
|
199
|
+
let depth = 0;
|
|
200
|
+
for (let index = start; index < value.length; index += 1) {
|
|
201
|
+
if (value[index] === '"') {
|
|
202
|
+
index = decodeJsonStringToken(value, index, artifactJsonMessage).nextIndex - 1;
|
|
203
|
+
}
|
|
204
|
+
else if (value[index] === "{" || value[index] === "[") {
|
|
205
|
+
depth += 1;
|
|
206
|
+
}
|
|
207
|
+
else if (value[index] === "}" || value[index] === "]") {
|
|
208
|
+
depth -= 1;
|
|
209
|
+
if (depth === 0)
|
|
210
|
+
return index + 1;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
throw new Error(artifactJsonMessage);
|
|
214
|
+
}
|
|
215
|
+
let index = start;
|
|
216
|
+
while (index < value.length
|
|
217
|
+
&& !isJsonWhitespace(value.charCodeAt(index))
|
|
218
|
+
&& value[index] !== "," && value[index] !== "}" && value[index] !== "]")
|
|
219
|
+
index += 1;
|
|
220
|
+
return index;
|
|
221
|
+
}
|
|
222
|
+
function redactContent(value, exactSecrets) {
|
|
223
|
+
return typeof value === "string" ? redactText(value, exactSecrets) : value;
|
|
224
|
+
}
|
|
225
|
+
function assertStructuralFieldsDoNotContainSecrets(fields, exactSecrets) {
|
|
226
|
+
for (const field of fields) {
|
|
227
|
+
if (field === undefined || field === null)
|
|
228
|
+
continue;
|
|
229
|
+
for (const secret of exactSecrets) {
|
|
230
|
+
if (secret.length > 0 && field.includes(secret)) {
|
|
231
|
+
throw new Error(structuralSecretMessage);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function assertSidecarsDoNotContainSecrets(sidecars, exactSecrets) {
|
|
237
|
+
if (!sidecars || exactSecrets.length === 0)
|
|
238
|
+
return;
|
|
239
|
+
for (const sidecar of sidecars) {
|
|
240
|
+
const decoded = Buffer.from(sidecar.contentBase64, "base64");
|
|
241
|
+
for (const secret of exactSecrets) {
|
|
242
|
+
if (secret.length === 0)
|
|
243
|
+
continue;
|
|
244
|
+
if (sidecar.path.includes(secret)
|
|
245
|
+
|| sidecar.contentBase64.includes(secret)
|
|
246
|
+
|| sidecar.contentHash.includes(secret)
|
|
247
|
+
|| decoded.indexOf(Buffer.from(secret, "utf8")) >= 0) {
|
|
248
|
+
throw new Error(sidecarSecretMessage);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
assertSidecarJsonDoesNotContainSecrets(decoded, sidecar.path, exactSecrets, sidecarSecretMessage);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function assertSerializedJsonDoesNotContainSecrets(value, exactSecrets, errorMessage) {
|
|
255
|
+
if (exactSecrets.length === 0)
|
|
256
|
+
return;
|
|
257
|
+
assertJsonStringDoesNotContainSecrets(value, exactSecrets, errorMessage);
|
|
258
|
+
inspectJsonStringTokens(value, exactSecrets, errorMessage);
|
|
259
|
+
}
|
|
260
|
+
function assertSidecarJsonDoesNotContainSecrets(value, path, exactSecrets, errorMessage) {
|
|
261
|
+
let decoded;
|
|
262
|
+
try {
|
|
263
|
+
decoded = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(value);
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
if (path.toLowerCase().endsWith(".json"))
|
|
267
|
+
throw new Error(errorMessage);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (!looksLikeJson(decoded, path))
|
|
271
|
+
return;
|
|
272
|
+
const hasUtf8Bom = value.length >= 3
|
|
273
|
+
&& value[0] === 0xef
|
|
274
|
+
&& value[1] === 0xbb
|
|
275
|
+
&& value[2] === 0xbf;
|
|
276
|
+
if (hasUtf8Bom)
|
|
277
|
+
throw new Error(errorMessage);
|
|
278
|
+
inspectJsonStringTokens(decoded, exactSecrets, errorMessage);
|
|
279
|
+
}
|
|
280
|
+
function inspectJsonStringTokens(value, exactSecrets, errorMessage) {
|
|
281
|
+
if (Buffer.byteLength(value, "utf8") > maximumIntegrityJsonBytes) {
|
|
282
|
+
throw new Error(errorMessage);
|
|
283
|
+
}
|
|
284
|
+
const containers = [];
|
|
285
|
+
let index = 0;
|
|
286
|
+
let tokenCount = 0;
|
|
287
|
+
const countToken = () => {
|
|
288
|
+
tokenCount += 1;
|
|
289
|
+
if (tokenCount > maximumIntegrityJsonTokens)
|
|
290
|
+
throw new Error(errorMessage);
|
|
291
|
+
};
|
|
292
|
+
while (index < value.length) {
|
|
293
|
+
const code = value.charCodeAt(index);
|
|
294
|
+
if (code === 0x22) {
|
|
295
|
+
countToken();
|
|
296
|
+
const token = decodeJsonStringToken(value, index, errorMessage);
|
|
297
|
+
assertJsonStringDoesNotContainSecrets(token.decoded, exactSecrets, errorMessage);
|
|
298
|
+
index = token.nextIndex;
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
if (code === 0x7b || code === 0x5b) {
|
|
302
|
+
countToken();
|
|
303
|
+
containers.push(code);
|
|
304
|
+
if (containers.length > maximumIntegrityJsonDepth)
|
|
305
|
+
throw new Error(errorMessage);
|
|
306
|
+
index += 1;
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
if (code === 0x7d || code === 0x5d) {
|
|
310
|
+
countToken();
|
|
311
|
+
const expected = code === 0x7d ? 0x7b : 0x5b;
|
|
312
|
+
if (containers.pop() !== expected)
|
|
313
|
+
throw new Error(errorMessage);
|
|
314
|
+
index += 1;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (code === 0x2c || code === 0x3a) {
|
|
318
|
+
index += 1;
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (isJsonWhitespace(code)) {
|
|
322
|
+
index += 1;
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
countToken();
|
|
326
|
+
do {
|
|
327
|
+
index += 1;
|
|
328
|
+
} while (index < value.length
|
|
329
|
+
&& !isJsonWhitespace(value.charCodeAt(index))
|
|
330
|
+
&& !isJsonPunctuation(value.charCodeAt(index)));
|
|
331
|
+
}
|
|
332
|
+
if (containers.length !== 0)
|
|
333
|
+
throw new Error(errorMessage);
|
|
334
|
+
try {
|
|
335
|
+
JSON.parse(value);
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
throw new Error(errorMessage);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function decodeJsonStringToken(value, openingQuoteIndex, errorMessage) {
|
|
342
|
+
const chunks = [];
|
|
343
|
+
let segmentStart = openingQuoteIndex + 1;
|
|
344
|
+
let index = segmentStart;
|
|
345
|
+
while (index < value.length) {
|
|
346
|
+
const code = value.charCodeAt(index);
|
|
347
|
+
if (code === 0x22) {
|
|
348
|
+
chunks.push(value.slice(segmentStart, index));
|
|
349
|
+
const decoded = chunks.join("");
|
|
350
|
+
if (!isWellFormedUnicode(decoded))
|
|
351
|
+
throw new Error(errorMessage);
|
|
352
|
+
return { decoded, nextIndex: index + 1 };
|
|
353
|
+
}
|
|
354
|
+
if (code < 0x20)
|
|
355
|
+
throw new Error(errorMessage);
|
|
356
|
+
if (code !== 0x5c) {
|
|
357
|
+
index += 1;
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
chunks.push(value.slice(segmentStart, index));
|
|
361
|
+
index += 1;
|
|
362
|
+
if (index >= value.length)
|
|
363
|
+
throw new Error(errorMessage);
|
|
364
|
+
const escaped = value[index];
|
|
365
|
+
switch (escaped) {
|
|
366
|
+
case "\"":
|
|
367
|
+
chunks.push("\"");
|
|
368
|
+
index += 1;
|
|
369
|
+
break;
|
|
370
|
+
case "\\":
|
|
371
|
+
chunks.push("\\");
|
|
372
|
+
index += 1;
|
|
373
|
+
break;
|
|
374
|
+
case "/":
|
|
375
|
+
chunks.push("/");
|
|
376
|
+
index += 1;
|
|
377
|
+
break;
|
|
378
|
+
case "b":
|
|
379
|
+
chunks.push("\b");
|
|
380
|
+
index += 1;
|
|
381
|
+
break;
|
|
382
|
+
case "f":
|
|
383
|
+
chunks.push("\f");
|
|
384
|
+
index += 1;
|
|
385
|
+
break;
|
|
386
|
+
case "n":
|
|
387
|
+
chunks.push("\n");
|
|
388
|
+
index += 1;
|
|
389
|
+
break;
|
|
390
|
+
case "r":
|
|
391
|
+
chunks.push("\r");
|
|
392
|
+
index += 1;
|
|
393
|
+
break;
|
|
394
|
+
case "t":
|
|
395
|
+
chunks.push("\t");
|
|
396
|
+
index += 1;
|
|
397
|
+
break;
|
|
398
|
+
case "u": {
|
|
399
|
+
const hex = value.slice(index + 1, index + 5);
|
|
400
|
+
if (!/^[0-9a-fA-F]{4}$/u.test(hex))
|
|
401
|
+
throw new Error(errorMessage);
|
|
402
|
+
chunks.push(String.fromCharCode(Number.parseInt(hex, 16)));
|
|
403
|
+
index += 5;
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
default: throw new Error(errorMessage);
|
|
407
|
+
}
|
|
408
|
+
segmentStart = index;
|
|
409
|
+
}
|
|
410
|
+
throw new Error(errorMessage);
|
|
411
|
+
}
|
|
412
|
+
function isWellFormedUnicode(value) {
|
|
413
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
414
|
+
const code = value.charCodeAt(index);
|
|
415
|
+
if (code >= 0xd800 && code <= 0xdbff) {
|
|
416
|
+
if (index + 1 >= value.length)
|
|
417
|
+
return false;
|
|
418
|
+
const next = value.charCodeAt(index + 1);
|
|
419
|
+
if (next < 0xdc00 || next > 0xdfff)
|
|
420
|
+
return false;
|
|
421
|
+
index += 1;
|
|
422
|
+
}
|
|
423
|
+
else if (code >= 0xdc00 && code <= 0xdfff) {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
function looksLikeJson(value, path) {
|
|
430
|
+
if (path.toLowerCase().endsWith(".json"))
|
|
431
|
+
return true;
|
|
432
|
+
const candidate = value.trimStart().replace(/^\uFEFF/u, "").trimStart();
|
|
433
|
+
return candidate.startsWith("{") || candidate.startsWith("[") || candidate.startsWith("\"");
|
|
434
|
+
}
|
|
435
|
+
function isJsonWhitespace(code) {
|
|
436
|
+
return code === 0x20 || code === 0x09 || code === 0x0a || code === 0x0d;
|
|
437
|
+
}
|
|
438
|
+
function isJsonPunctuation(code) {
|
|
439
|
+
return code === 0x7b || code === 0x7d || code === 0x5b || code === 0x5d
|
|
440
|
+
|| code === 0x2c || code === 0x3a || code === 0x22;
|
|
441
|
+
}
|
|
442
|
+
function assertJsonStringDoesNotContainSecrets(value, exactSecrets, errorMessage) {
|
|
443
|
+
for (const secret of exactSecrets) {
|
|
444
|
+
if (secret.length > 0 && value.includes(secret)) {
|
|
445
|
+
throw new Error(errorMessage);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import type { RunOnceDispatchPacket, RunOnceResultPacket, RunnerDispatchEvent } from "./session.types.js";
|
|
1
|
+
import type { HostRuntimeReadinessProbeRequest, HostRuntimeReadinessProbeResult, RunOnceDispatchPacket, RunOnceResultPacket, RunnerDispatchEvent } from "./session.types.js";
|
|
2
|
+
import type { HostRuntimeCapacitySnapshot, HostRuntimeReapOptions, HostRuntimeReapReport } from "../runtime/host-runtime-lease.js";
|
|
2
3
|
export interface SessionEventSink {
|
|
3
4
|
emit(event: RunnerDispatchEvent): Promise<void>;
|
|
4
5
|
}
|
|
5
6
|
export interface SessionService {
|
|
6
7
|
runOnce(dispatch: RunOnceDispatchPacket, sink: SessionEventSink, signal?: AbortSignal): Promise<RunOnceResultPacket>;
|
|
8
|
+
updateLease?(dispatchAttemptId: string, fencingToken: string, expiresAt: string): Promise<void>;
|
|
9
|
+
reapHostRuntime?(options: HostRuntimeReapOptions): Promise<HostRuntimeReapReport | null>;
|
|
10
|
+
runtimeCapacity?(): HostRuntimeCapacitySnapshot | null;
|
|
11
|
+
probeHostRuntime?(request: HostRuntimeReadinessProbeRequest, signal?: AbortSignal): Promise<HostRuntimeReadinessProbeResult>;
|
|
7
12
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import type { ProviderCliService } from "./provider-cli/provider-cli.base.js";
|
|
2
2
|
import type { SessionEventSink, SessionService } from "./session.base.js";
|
|
3
|
-
import type { RunOnceDispatchPacket, RunOnceResultPacket } from "./session.types.js";
|
|
3
|
+
import type { HostRuntimeReadinessProbeRequest, HostRuntimeReadinessProbeResult, RunOnceDispatchPacket, RunOnceResultPacket } from "./session.types.js";
|
|
4
4
|
import type { WorktreeService } from "../worktree/worktree.base.js";
|
|
5
|
+
import { type HostRuntimeCapacitySnapshot, type HostRuntimeLeaseRuntime, type HostRuntimeReapOptions, type HostRuntimeReapReport } from "../runtime/host-runtime-lease.js";
|
|
5
6
|
export declare class BridgeSessionService implements SessionService {
|
|
6
7
|
private readonly worktrees;
|
|
7
8
|
private readonly providerCli;
|
|
8
|
-
|
|
9
|
+
private readonly hostRuntime?;
|
|
10
|
+
constructor(worktrees?: WorktreeService, providerCli?: ProviderCliService, hostRuntime?: HostRuntimeLeaseRuntime | undefined);
|
|
11
|
+
updateLease(dispatchAttemptId: string, fencingToken: string, expiresAt: string): Promise<void>;
|
|
12
|
+
reapHostRuntime(options: HostRuntimeReapOptions): Promise<HostRuntimeReapReport | null>;
|
|
13
|
+
runtimeCapacity(): HostRuntimeCapacitySnapshot | null;
|
|
14
|
+
probeHostRuntime(request: HostRuntimeReadinessProbeRequest, signal?: AbortSignal): Promise<HostRuntimeReadinessProbeResult>;
|
|
9
15
|
runOnce(dispatch: RunOnceDispatchPacket, sink: SessionEventSink, signal?: AbortSignal): Promise<RunOnceResultPacket>;
|
|
10
16
|
}
|