@loucompanion/forge-bridge 0.1.3-dev.1fe428dd78ab → 0.1.3-dev.241aac954744

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.
Files changed (136) hide show
  1. package/README.md +37 -1
  2. package/dist/bridge/bridge.base.d.ts +4 -1
  3. package/dist/bridge/bridge.service.d.ts +49 -3
  4. package/dist/bridge/bridge.service.js +728 -88
  5. package/dist/bridge/bridge.types.d.ts +63 -1
  6. package/dist/cleanup/cleanup.service.d.ts +14 -2
  7. package/dist/cleanup/cleanup.service.js +469 -3
  8. package/dist/cleanup/cleanup.types.d.ts +10 -0
  9. package/dist/cleanup/index.d.ts +1 -1
  10. package/dist/cleanup/index.js +1 -1
  11. package/dist/cleanup/internals.d.ts +2 -2
  12. package/dist/cleanup/internals.js +1 -1
  13. package/dist/cli/cli.help.js +37 -3
  14. package/dist/cli/cli.service.d.ts +30 -2
  15. package/dist/cli/cli.service.js +191 -27
  16. package/dist/cli/local-config.d.ts +4 -0
  17. package/dist/cli/local-config.js +41 -1
  18. package/dist/runtime/aspnet-runtime-prebuild.d.ts +36 -0
  19. package/dist/runtime/aspnet-runtime-prebuild.js +340 -0
  20. package/dist/runtime/attempt-node-runtime-launcher.d.ts +17 -0
  21. package/dist/runtime/attempt-node-runtime-launcher.js +105 -0
  22. package/dist/runtime/attempt-process-supervisor-registry.d.ts +20 -0
  23. package/dist/runtime/attempt-process-supervisor-registry.js +64 -0
  24. package/dist/runtime/attempt-process-supervisor.d.ts +97 -0
  25. package/dist/runtime/attempt-process-supervisor.js +384 -0
  26. package/dist/runtime/generated-output-reset.d.ts +10 -0
  27. package/dist/runtime/generated-output-reset.js +103 -0
  28. package/dist/runtime/host-listener-inspector.d.ts +46 -0
  29. package/dist/runtime/host-listener-inspector.js +349 -0
  30. package/dist/runtime/host-port-broker.d.ts +76 -0
  31. package/dist/runtime/host-port-broker.js +333 -0
  32. package/dist/runtime/host-runtime-contract.d.ts +47 -0
  33. package/dist/runtime/host-runtime-contract.js +700 -0
  34. package/dist/runtime/host-runtime-lease.d.ts +194 -0
  35. package/dist/runtime/host-runtime-lease.js +2137 -0
  36. package/dist/runtime/host-runtime-promotion.d.ts +23 -0
  37. package/dist/runtime/host-runtime-promotion.js +159 -0
  38. package/dist/runtime/memory-capacity.d.ts +68 -0
  39. package/dist/runtime/memory-capacity.js +121 -0
  40. package/dist/runtime/node-host-runtime-adapter.d.ts +54 -0
  41. package/dist/runtime/node-host-runtime-adapter.js +284 -0
  42. package/dist/runtime/playwright-host-runtime-adapter.d.ts +21 -0
  43. package/dist/runtime/playwright-host-runtime-adapter.js +225 -0
  44. package/dist/runtime/runtime-isolation-lease.d.ts +67 -0
  45. package/dist/runtime/runtime-isolation-lease.js +158 -0
  46. package/dist/runtime/workspace-resource-estimator.d.ts +17 -0
  47. package/dist/runtime/workspace-resource-estimator.js +174 -0
  48. package/dist/sandbox/image-policy.d.ts +3 -1
  49. package/dist/sandbox/image-policy.js +4 -2
  50. package/dist/sandbox/preflight.d.ts +49 -1
  51. package/dist/sandbox/preflight.js +314 -32
  52. package/dist/sandbox/process.js +125 -40
  53. package/dist/sandbox/repository-lock.js +37 -1
  54. package/dist/sandbox/runtime.d.ts +85 -6
  55. package/dist/sandbox/runtime.js +806 -140
  56. package/dist/sandbox/sandbox.types.d.ts +10 -0
  57. package/dist/sandbox/smoke.d.ts +76 -0
  58. package/dist/sandbox/smoke.js +380 -0
  59. package/dist/sandbox/worker-supervisor.js +1 -1
  60. package/dist/sandbox/worker.js +2 -5
  61. package/dist/sandbox/workspace.service.d.ts +1 -0
  62. package/dist/sandbox/workspace.service.js +28 -5
  63. package/dist/session/managed-attempt-tools.d.ts +18 -0
  64. package/dist/session/managed-attempt-tools.js +854 -0
  65. package/dist/session/managed-build-coordinator.d.ts +5 -0
  66. package/dist/session/managed-build-coordinator.js +105 -0
  67. package/dist/session/managed-build-receipt.d.ts +21 -0
  68. package/dist/session/managed-build-receipt.js +335 -0
  69. package/dist/session/phase-completion.artifacts.d.ts +17 -0
  70. package/dist/session/phase-completion.artifacts.js +233 -24
  71. package/dist/session/phase-completion.d.ts +11 -2
  72. package/dist/session/phase-completion.helpers.d.ts +5 -0
  73. package/dist/session/phase-completion.helpers.js +51 -10
  74. package/dist/session/phase-completion.js +12 -3
  75. package/dist/session/phase-completion.prompts.d.ts +3 -3
  76. package/dist/session/phase-completion.prompts.js +21 -6
  77. package/dist/session/phase-completion.runtime.d.ts +13 -1
  78. package/dist/session/phase-completion.runtime.js +189 -8
  79. package/dist/session/phase-completion.schemas.js +108 -3
  80. package/dist/session/phase-completion.validation.d.ts +4 -1
  81. package/dist/session/phase-completion.validation.js +151 -21
  82. package/dist/session/provider-cli/ci-repair-readiness.d.ts +14 -0
  83. package/dist/session/provider-cli/ci-repair-readiness.js +105 -0
  84. package/dist/session/provider-cli/provider-cli.artifacts.d.ts +3 -2
  85. package/dist/session/provider-cli/provider-cli.artifacts.js +65 -7
  86. package/dist/session/provider-cli/provider-cli.deterministic.js +47 -1
  87. package/dist/session/provider-cli/provider-cli.process.d.ts +23 -0
  88. package/dist/session/provider-cli/provider-cli.process.js +417 -32
  89. package/dist/session/provider-cli/provider-cli.prompts.d.ts +4 -1
  90. package/dist/session/provider-cli/provider-cli.prompts.js +99 -19
  91. package/dist/session/provider-cli/provider-cli.qa-sidecars.js +1 -0
  92. package/dist/session/provider-cli/provider-cli.runtime.d.ts +1 -1
  93. package/dist/session/provider-cli/provider-cli.runtime.js +6 -3
  94. package/dist/session/provider-cli/provider-cli.service.d.ts +20 -2
  95. package/dist/session/provider-cli/provider-cli.service.js +464 -102
  96. package/dist/session/provider-cli/provider-cli.types.d.ts +5 -0
  97. package/dist/session/provider-cli/provider-output-state.d.ts +2 -0
  98. package/dist/session/provider-cli/provider-output-state.js +91 -16
  99. package/dist/session/provider-cli/provider-usage.d.ts +7 -0
  100. package/dist/session/provider-cli/provider-usage.js +28 -5
  101. package/dist/session/session-redaction.d.ts +3 -0
  102. package/dist/session/session-redaction.js +38 -0
  103. package/dist/session/session.base.d.ts +6 -1
  104. package/dist/session/session.service.d.ts +8 -2
  105. package/dist/session/session.service.js +522 -41
  106. package/dist/session/session.types.d.ts +70 -0
  107. package/dist/session/session.types.js +76 -4
  108. package/dist/shared/format/format-bytes.d.ts +1 -0
  109. package/dist/shared/format/format-bytes.js +9 -0
  110. package/dist/shared/path/path.js +3 -1
  111. package/dist/shared/process/host-process-recovery.d.ts +12 -0
  112. package/dist/shared/process/host-process-recovery.js +78 -0
  113. package/dist/shared/process/host-process-supervisor.d.ts +58 -0
  114. package/dist/shared/process/host-process-supervisor.js +325 -0
  115. package/dist/shared/process/process.d.ts +1 -0
  116. package/dist/shared/process/process.js +1 -0
  117. package/dist/shared/redaction/redaction.js +12 -2
  118. package/dist/version.d.ts +1 -1
  119. package/dist/version.js +1 -1
  120. package/dist/worktree/artifact-injector.d.ts +3 -2
  121. package/dist/worktree/artifact-injector.js +43 -4
  122. package/dist/worktree/dependency-warmer.d.ts +28 -1
  123. package/dist/worktree/dependency-warmer.js +307 -8
  124. package/dist/worktree/index.d.ts +2 -1
  125. package/dist/worktree/index.js +1 -0
  126. package/dist/worktree/prior-phase-artifact-hydrator.d.ts +2 -0
  127. package/dist/worktree/prior-phase-artifact-hydrator.js +136 -0
  128. package/dist/worktree/worktree-paths.d.ts +4 -0
  129. package/dist/worktree/worktree-paths.js +30 -0
  130. package/dist/worktree/worktree.base.d.ts +3 -0
  131. package/dist/worktree/worktree.service.d.ts +9 -2
  132. package/dist/worktree/worktree.service.js +217 -48
  133. package/dist/worktree/worktree.types.d.ts +5 -1
  134. package/package.json +3 -2
  135. package/runtime/windows-job-supervisor.ps1 +426 -0
  136. package/runtime/windows-listener-owner.ps1 +33 -0
package/README.md CHANGED
@@ -33,6 +33,16 @@ The bridge can also read connection settings from environment variables:
33
33
  - `FORGE_CLI_PROVIDERS`
34
34
  - `FORGE_CODEX_MODELS` / `FORGE_CURSOR_MODELS` (optional comma-separated model ids advertised in runner capabilities)
35
35
 
36
+ Show or change the saved server without editing `bridge.json`:
37
+
38
+ ```bash
39
+ forge-bridge server show
40
+ forge-bridge server set http://localhost:5208
41
+ forge-bridge server set https://srv1493013.tail66073d.ts.net:8443
42
+ ```
43
+
44
+ `FORGE_URL` overrides the saved server. Changing the saved URL retains runner credentials so aliases for the same deployment keep working; pair again with `--server` when switching to a different Forge deployment.
45
+
36
46
  ## Repo-local development
37
47
 
38
48
  For active Forge branch development, run the bridge directly from the checkout instead of publishing a package:
@@ -60,9 +70,29 @@ Protocol-v2 bridges preflight Docker before advertising the `docker` sandbox run
60
70
  ```bash
61
71
  forge sandbox init
62
72
  forge sandbox doctor
73
+ forge sandbox smoke
63
74
  forge-bridge sandbox reap
64
75
  ```
65
76
 
77
+ Configure the local bridge's persistent Docker placement policy with:
78
+
79
+ ```bash
80
+ forge-bridge sandbox on
81
+ forge-bridge sandbox on --allow-open-public
82
+ forge-bridge sandbox status
83
+ forge-bridge sandbox off
84
+ ```
85
+
86
+ `sandbox on` keeps unrestricted public networking denied by default. The developer-only
87
+ `--allow-open-public` option stores an explicit local approval in `bridge.json`; it survives
88
+ bridge restarts and is reported by `sandbox status`. Restart a connected bridge after changing
89
+ the policy. `FORGE_DOCKER_SANDBOX` and `FORGE_ALLOW_OPEN_PUBLIC_SANDBOX` remain higher-priority
90
+ operator overrides when present.
91
+
92
+ `forge sandbox smoke` runs doctor, builds the repository-owned `.forge/Dockerfile`, launches a disposable hardened container on an internal network with a fresh workspace volume, and verifies that its exact attempt-labeled container, network, volume, and image are gone afterward. It writes a redacted JSON report under `FORGE_SANDBOX_STATE_ROOT/smoke-reports`; use `--report <path>` to choose a different destination. Stop the connected bridge before running smoke so the command can exclusively acquire the Docker-context ownership lock.
93
+
94
+ Use `forge sandbox smoke --probe-loopback-port` only when proving Docker host-port allocation. The normal hardened container remains internal with no publication; a separate exact-labeled fixture requests `127.0.0.1::8080/tcp`, records Docker's assigned loopback port, rejects wildcard or ambiguous mappings, and is removed by the same exact-label cleanup verification.
95
+
66
96
  Production shared runners require a Linux rootless Docker daemon. Docker Desktop is developer-only and must be opted in with `FORGE_ALLOW_DOCKER_DESKTOP_SANDBOX=true`. Useful runner settings are:
67
97
 
68
98
  - `FORGE_TRUST_DOMAIN_ID` — must match the project trust domain.
@@ -71,6 +101,10 @@ Production shared runners require a Linux rootless Docker daemon. Docker Desktop
71
101
  - `FORGE_DOCKER_CONTEXT` / `FORGE_DOCKER_EXECUTABLE` — dedicated daemon selection.
72
102
  - `FORGE_SANDBOX_STATE_ROOT` — fsync'd attempt ledgers, restricted diagnostics, and build state.
73
103
  - `FORGE_DISK_HIGH_WATERMARK_PERCENT` / `FORGE_DISK_LOW_WATERMARK_PERCENT` / `FORGE_MINIMUM_WORKSPACE_BYTES` — admission watermarks with high/low hysteresis.
104
+ - Per-attempt workspace reservations are calculated from the repository source footprint, detected Node/.NET/browser toolchains, the execution role, and immutable sandbox app services. The API uses that request for local and Bridge placement; a Bridge rechecks its authoritative checkout and Docker contract before acceptance. Shared Docker images and package caches remain runner-level capacity, while `FORGE_MINIMUM_WORKSPACE_BYTES` remains a separate host safety reserve rather than a per-lane charge.
105
+ - `FORGE_SANDBOX_HOST_MEMORY_RESERVE_BYTES` — explicit host-memory safety-reserve override for sandbox admission. Without an override, Forge derives a bounded reserve from the sampled capacity domain (Linux: 12.5%, 1–4 GiB; Docker Desktop development: 6.25%, 1–2 GiB). The floor, ceiling, and percentage are configurable with `FORGE_SANDBOX_HOST_MEMORY_RESERVE_FLOOR_BYTES`, `FORGE_SANDBOX_HOST_MEMORY_RESERVE_CEILING_BYTES`, and `FORGE_SANDBOX_HOST_MEMORY_RESERVE_PERCENT`.
106
+ - Managed-host admission uses the same bounded 12.5% physical-memory policy through `FORGE_HOST_MEMORY_RESERVE_BYTES` or its `_FLOOR_BYTES`, `_CEILING_BYTES`, and `_PERCENT` controls. Pressure is applied immediately; recovery requires two samples one second apart by default (`FORGE_HOST_MEMORY_RECOVERY_SAMPLES` and `FORGE_HOST_MEMORY_RECOVERY_SAMPLE_INTERVAL_MS`). `FORGE_HOST_DEFAULT_WORKER_MEMORY_LIMIT_BYTES` configures only the conservative cold-start fallback for legacy packets that omit an exact worker request; current packets remain governed by their explicit role request.
107
+ - `FORGE_SANDBOX_MEMORY_SAMPLE_INTERVAL_MS` — interval for sampled Docker peak-memory telemetry (default `1000` ms, clamped to `250`–`30000` ms). Sampling is diagnostic and never changes an attempt outcome.
74
108
  - `FORGE_SANDBOX_DEDICATED_DISK=true` — operator assertion that sandbox storage is on a dedicated, conservatively watermarked disk when the Docker storage driver cannot enforce per-volume quotas. `sandbox_required` fails placement unless either quota support or this assertion is advertised.
75
109
  - `FORGE_SANDBOX_IMAGE_RETENTION_COUNT` / `FORGE_SANDBOX_IMAGE_RETENTION_TTL_MS` — per-project image-cache retention (defaults: 3 images and 7 days).
76
110
  - `FORGE_SANDBOX_AUDIT_RETENTION_COUNT` / `FORGE_SANDBOX_AUDIT_RETENTION_TTL_MS` — restricted failed-build/attestation retention (defaults: 200 keys and 30 days); evidence for active image digests is protected.
@@ -78,7 +112,7 @@ Production shared runners require a Linux rootless Docker daemon. Docker Desktop
78
112
  - `FORGE_SANDBOX_IMAGE_POLICY_ENFORCED`, `FORGE_SANDBOX_SBOM_EXECUTABLE`, `FORGE_SANDBOX_VULNERABILITY_EXECUTABLE`, and `FORGE_SANDBOX_PROVENANCE_SIGNING_KEY` — required generated-image promotion gates. The SBOM command must accept Syft-compatible `<image> -o spdx-json`; the vulnerability command must accept Trivy-compatible image arguments.
79
113
  - `FORGE_SANDBOX_SIGNATURE_EXECUTABLE` / `FORGE_SANDBOX_SIGNATURE_PUBLIC_KEY` — Cosign-compatible verifier and bounded public-key file. `sandbox_required` verifies every digest-pinned external Dockerfile base/`COPY --from` source and Forge tooling base before generated-image promotion, plus every service-catalog and egress-proxy image before runtime use; adoption modes emit a warning when verification is not configured.
80
114
  - `FORGE_SANDBOX_BUILD_EGRESS_ENFORCED` — confirms the dedicated BuildKit builder is behind the approved build-egress control; required for `sandbox_required`.
81
- - `FORGE_SANDBOX_BUILD_MEMORY` / `FORGE_SANDBOX_BUILD_CPU_QUOTA` / `FORGE_SANDBOX_BUILD_NOFILE` — bounded per-build-step memory/swap, CPU CFS quota, and file-descriptor caps (defaults: `4g`, `200000` per `100000` period, and `4096`). `FORGE_SANDBOX_BUILDER_PIDS_LIMIT` caps and verifies aggregate processes on the dedicated BuildKit container (default `512`).
115
+ - `FORGE_SANDBOX_BUILD_NOFILE` — bounded per-build-step file-descriptor cap (default: `4096`). `FORGE_SANDBOX_BUILDER_PIDS_LIMIT` caps and verifies aggregate processes on the dedicated BuildKit container (default `512`). Buildx `--resource` memory/CPU caps are intentionally not emitted because they are not portable across supported Buildx versions; agent runtime containers still receive Docker memory/CPU limits.
82
116
  - `FORGE_SANDBOX_BUILDKIT_CACHE_MAX` / `FORGE_SANDBOX_BUILDKIT_CACHE_RESERVED` — pressure-triggered dedicated-builder cache bounds (defaults: 20 GiB maximum and 2 GiB reserved; minimum free space follows `FORGE_MINIMUM_WORKSPACE_BYTES`).
83
117
  - `FORGE_SANDBOX_SECCOMP_PROFILE` / `FORGE_SANDBOX_LSM_SECURITY_OPT` — absolute hardened seccomp profile and AppArmor/SELinux Docker security option applied to every agent and service; required for `sandbox_required`.
84
118
  - `FORGE_SANDBOX_HARD_WALL_SECONDS` / `FORGE_SANDBOX_IDLE_SECONDS` — monotonic worker deadlines (defaults: 8 hours and 30 minutes; both are capped by the 8-hour hard maximum).
@@ -93,6 +127,8 @@ Temporary host fallback for `sandbox_preferred` requires both sides to opt in: a
93
127
 
94
128
  The bridge reaps exact-labeled orphan resources before connecting and every minute afterward. Connected passes reconcile current-instance ledgers against an authoritative, instance-scoped server attempt snapshot; startup does not adopt old-instance resources and terminates them before advertising capacity. Per-resource removal outcomes are written mode-0600 under `FORGE_SANDBOX_STATE_ROOT/cleanup-reports` before transmission, replayed after reconnect, acknowledged by report ID, and persisted by the API only when attempt, fence, resource runner instance, and current reporting runner match. Fenced dispatch events also persist image/cache status, build/agent-start/import/teardown timestamps, and a validated inventory of created agent/sidecar containers, networks, volumes, and published ports. Selected-session diagnostics expose that lifecycle data and recent cleanup actions while retaining cleanup-pending state after the agent outcome is terminal. Install `forge-bridge sandbox reap` as an independently supervised OS timer with the same `FORGE_RUNNER_ID`, Docker context, and state root so resources are reconciled while the bridge is down; the Docker-context ownership lock makes an overlapping pass fail safely. A non-zero `degradedReservationCount` means teardown has not completed; the affected capacity remains unavailable until a successful reaper pass. Drain a runner from Profile Settings before upgrades or Docker maintenance, wait for active/starting counts to reach zero, then restart the bridge. Profile Settings also exposes a scoped **Reap** action; the API delivers it only to the currently established protocol-v2 runner instance. Image GC runs only while disk pressure is latched, shares the build lock, preserves active image digests, and prunes only expired images beyond the per-project retention count. Lease renewals are HMAC-bound to the attempt and fence and advance an in-container monotonic deadline; lease, hard-wall, and idle expiry produce distinct failure codes.
95
129
 
130
+ Every attempt-owned container (including short-lived initialization helpers), network, and volume carries `dev.forge.resource-lease-id` equal to the dispatch execution lease. Ledger schema v2 persists the same `resourceLeaseId`; teardown compares the complete expected label set, and orphan reaping fails closed unless the managed, resource-lease, execution-lease, attempt, runner, runner-instance, and fencing identities are all present and consistent.
131
+
96
132
  In `bridge_push` mode, the start packet carries only an attempt/fence/branch-bound publication handle. After validating and importing the output bundle, the authenticated current bridge redeems that handle for an in-memory, exact-repository credential; the API rechecks the live lease/fence/grant/branch/result SHA and records redemption before returning it. Git receives the credential through a process environment configuration, never command arguments, files, Git config, or the container. The bridge compares the remote branch with the immutable input commit and pushes only the exact result commit using `--force-with-lease`; cancellation aborts Git, an already-published matching result is an idempotent success, and any other remote value is rejected as stale. The API records the fenced publication acknowledgment before sign-off and does not push the branch a second time while opening the pull request.
97
133
 
98
134
  Failed project, tooling, and agent image stages preserve only a redacted, capped, mode-0600 diagnostic at `FORGE_SANDBOX_STATE_ROOT/build-logs/<image-key>/<stage>.log`. The event stream carries its digest, byte count, and truncation flag, never the log contents. Treat this directory as restricted source-bearing audit data and apply local retention controls.
@@ -1,4 +1,4 @@
1
- import type { BridgeCancelHandler, BridgeDispatchHandler, BridgeLeaseUpdateHandler, BridgeOfferHandler, BridgeReapHandler, BridgeServiceConfig, BridgeStartHandler } from "./bridge.types.js";
1
+ import type { BridgeCancelHandler, BridgeDispatchHandler, BridgeLeaseUpdateHandler, BridgeOfferHandler, BridgeReadinessProbeHandler, BridgeReapHandler, BridgeServiceConfig, BridgeStartHandler } from "./bridge.types.js";
2
2
  export interface BridgeService {
3
3
  connectOnce(): Promise<void>;
4
4
  run(signal?: AbortSignal): Promise<void>;
@@ -8,12 +8,15 @@ export interface BridgeConnection {
8
8
  start(): Promise<void>;
9
9
  stop(): Promise<void>;
10
10
  onClose(handler: (error?: Error) => void): void;
11
+ onReconnecting?(handler: (error?: Error) => void): void;
12
+ onReconnected?(handler: (connectionId?: string) => void | Promise<void>): void;
11
13
  onDispatch(handler: BridgeDispatchHandler): void;
12
14
  onOffer?(handler: BridgeOfferHandler): void;
13
15
  onStart?(handler: BridgeStartHandler): void;
14
16
  onLeaseUpdate?(handler: BridgeLeaseUpdateHandler): void;
15
17
  onCancel(handler: BridgeCancelHandler): void;
16
18
  onReap?(handler: BridgeReapHandler): void;
19
+ onReadinessProbe?(handler: BridgeReadinessProbeHandler): void;
17
20
  invoke<TResponse>(methodName: string, payload: unknown): Promise<TResponse>;
18
21
  }
19
22
  export interface BridgeConnectionFactory {
@@ -1,30 +1,55 @@
1
1
  import type { SessionService } from "../session/session.base.js";
2
- import { type DispatchSandboxResourceRequest } from "../session/session.types.js";
2
+ import { type DispatchSandboxResourceRequest, type RunOnceDispatchPacket, type RunOnceResultPacket } from "../session/session.types.js";
3
3
  import { DockerPreflight } from "../sandbox/preflight.js";
4
+ import type { SandboxPreflightResult } from "../sandbox/sandbox.types.js";
4
5
  import { type SandboxRuntime } from "../sandbox/runtime.js";
5
6
  import type { BridgeConnection, BridgeConnectionFactory, BridgeService } from "./bridge.base.js";
6
7
  import type { BridgeCancelHandler, BridgeDispatchHandler, BridgeLeaseUpdateRequest, BridgeReapRequest, BridgeServiceConfig } from "./bridge.types.js";
8
+ export type SandboxResourceResolver = (dispatch: RunOnceDispatchPacket) => Promise<ResolvedSandboxResourceProfile>;
9
+ export interface ResolvedSandboxResourceProfile {
10
+ readonly resources: DispatchSandboxResourceRequest;
11
+ readonly sandboxConfigCommitSha: string;
12
+ }
13
+ /**
14
+ * Protocol-v2 events are acknowledged one at a time before runOnce returns.
15
+ * Sending the complete transcript again in DispatchResult made long QA and CI
16
+ * sessions exceed SignalR's receive limit, disconnecting the bridge after the
17
+ * provider had already completed. The API combines its acknowledged streamed
18
+ * events with the terminal result, so the callback only needs the outcome and
19
+ * artifacts. Protocol v1 retains the transcript for legacy servers.
20
+ */
21
+ export declare function compactTerminalResult(dispatch: RunOnceDispatchPacket, result: RunOnceResultPacket): RunOnceResultPacket;
7
22
  export declare class ForgeBridgeService implements BridgeService {
8
23
  private readonly config;
9
- private readonly sessions;
10
24
  private readonly connections;
11
25
  private connection;
12
26
  private heartbeatTimer;
27
+ private heartbeatInFlight;
28
+ private consecutiveHeartbeatFailures;
29
+ private reconnectingFromHeartbeatFailure;
13
30
  private leaseWatchdogTimer;
14
31
  private sandboxMaintenanceTimer;
15
32
  private sandboxMaintenanceRunning;
16
33
  private closed;
34
+ private transportRecovery;
35
+ private transportRecoveryGeneration;
17
36
  private stopped;
18
37
  private readonly activeSessions;
19
38
  private readonly reservations;
39
+ private readonly activeReadinessProbes;
20
40
  private readonly preflight;
21
41
  private readonly sandboxRuntime;
22
- constructor(config: BridgeServiceConfig, sessions?: SessionService, connections?: BridgeConnectionFactory, preflight?: DockerPreflight, sandboxRuntime?: SandboxRuntime);
42
+ private readonly sandboxResourceResolver;
43
+ private readonly sessions;
44
+ private sandboxAmbientMemoryCommitmentBytes;
45
+ constructor(config: BridgeServiceConfig, sessions?: SessionService | undefined, connections?: BridgeConnectionFactory, preflight?: DockerPreflight, sandboxRuntime?: SandboxRuntime, sandboxResourceResolver?: SandboxResourceResolver);
23
46
  connectOnce(): Promise<void>;
47
+ private registerConnection;
24
48
  run(signal?: AbortSignal): Promise<void>;
25
49
  stop(): Promise<void>;
26
50
  private handleDispatch;
27
51
  private handleOffer;
52
+ private commitOfferReservation;
28
53
  private handleStart;
29
54
  private redeemSecretGrant;
30
55
  private redeemPublishGrant;
@@ -33,15 +58,19 @@ export declare class ForgeBridgeService implements BridgeService {
33
58
  private parseDispatchOrReport;
34
59
  private handleCancel;
35
60
  private handleReap;
61
+ private handleReadinessProbe;
36
62
  private abortActiveSessions;
63
+ private abortActiveReadinessProbes;
37
64
  private normalizeDispatch;
38
65
  private sendResult;
39
66
  private sendLegacyResult;
40
67
  private sendResultPayload;
41
68
  private startHeartbeat;
69
+ private heartbeatTick;
42
70
  private startLeaseWatchdog;
43
71
  private stopLeaseWatchdog;
44
72
  private expireLeases;
73
+ private expireReservations;
45
74
  private stopHeartbeat;
46
75
  private startSandboxMaintenance;
47
76
  private stopSandboxMaintenance;
@@ -51,8 +80,12 @@ export declare class ForgeBridgeService implements BridgeService {
51
80
  private sendHeartbeat;
52
81
  private capabilities;
53
82
  private usedSandboxResources;
83
+ private activeSandboxResources;
54
84
  private sandboxResourceCapacity;
55
85
  private invokeAck;
86
+ private beginTransportRecovery;
87
+ private completeTransportRecovery;
88
+ private waitForTransportRecovery;
56
89
  private waitForClose;
57
90
  private stopConnection;
58
91
  }
@@ -66,15 +99,28 @@ export declare class SignalRBridgeConnection implements BridgeConnection {
66
99
  start(): Promise<void>;
67
100
  stop(): Promise<void>;
68
101
  onClose(handler: (error?: Error) => void): void;
102
+ onReconnecting(handler: (error?: Error) => void): void;
103
+ onReconnected(handler: (connectionId?: string) => void | Promise<void>): void;
69
104
  onDispatch(handler: BridgeDispatchHandler): void;
70
105
  onOffer(handler: BridgeDispatchHandler): void;
71
106
  onStart(handler: BridgeDispatchHandler): void;
72
107
  onLeaseUpdate(handler: (request: BridgeLeaseUpdateRequest) => Promise<void>): void;
73
108
  onCancel(handler: BridgeCancelHandler): void;
74
109
  onReap(handler: (request: BridgeReapRequest) => Promise<void>): void;
110
+ onReadinessProbe(handler: (request: unknown) => Promise<void>): void;
75
111
  invoke<TResponse>(methodName: string, payload: unknown): Promise<TResponse>;
76
112
  }
77
113
  export declare function defaultBridgeServiceConfig(overrides?: Partial<BridgeServiceConfig>): BridgeServiceConfig;
78
114
  export declare function resolveBridgeRunnerHubUrl(serverUrl: string): URL;
115
+ export declare function delay(ms: number, signal?: AbortSignal): Promise<void>;
116
+ export declare function waitForPromiseOrAbort(promise: Promise<unknown>, signal?: AbortSignal): Promise<void>;
117
+ export declare function canReapManagedSandboxes(preflight: {
118
+ readonly healthy: boolean;
119
+ readonly unavailableCode?: string | null;
120
+ }): boolean;
79
121
  export type SandboxResourceVector = DispatchSandboxResourceRequest;
80
122
  export declare function canReserveSandboxResources(used: SandboxResourceVector, requested: SandboxResourceVector, capacity: SandboxResourceVector): boolean;
123
+ export declare function sandboxMemoryCommitmentCapacity(preflight: Pick<SandboxPreflightResult, "totalMemoryBytes" | "availableMemoryBytes" | "hostReserveBytes">, activeMemoryBytes: number, ambientMemoryCommitmentBytes?: number): number;
124
+ export declare function sandboxCapacityFailureMessage(used: SandboxResourceVector, requested: SandboxResourceVector, capacity: SandboxResourceVector, preflight: SandboxPreflightResult | null, config: BridgeServiceConfig): string;
125
+ export declare function resolveDynamicSandboxResources(requested: DispatchSandboxResourceRequest, serviceCount: number, networkMode: "offline" | "public_allowlist" | "open_public", baseRuntimeOverheadBytes?: number): DispatchSandboxResourceRequest;
126
+ export declare function resolveSandboxResourcesFromRepo(dispatch: RunOnceDispatchPacket, baseRuntimeOverheadBytes?: number): Promise<ResolvedSandboxResourceProfile>;