@loucompanion/forge-bridge 0.1.3-dev.fbe15023cdfe → 0.1.4-dev.bfa11ebe98c6

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 (160) hide show
  1. package/README.md +88 -2
  2. package/dist/bridge/bridge-chat.types.d.ts +111 -0
  3. package/dist/bridge/bridge-chat.types.js +401 -0
  4. package/dist/bridge/bridge.base.d.ts +4 -1
  5. package/dist/bridge/bridge.service.d.ts +72 -3
  6. package/dist/bridge/bridge.service.js +1562 -152
  7. package/dist/bridge/bridge.types.d.ts +46 -1
  8. package/dist/bridge/dispatch-result-outbox.d.ts +25 -0
  9. package/dist/bridge/dispatch-result-outbox.js +62 -0
  10. package/dist/bridge/dispatch-result-worker.d.ts +2 -0
  11. package/dist/bridge/dispatch-result-worker.js +122 -0
  12. package/dist/bridge/internals.d.ts +2 -0
  13. package/dist/bridge/internals.js +1 -0
  14. package/dist/bridge/readiness-result-outbox.d.ts +21 -0
  15. package/dist/bridge/readiness-result-outbox.js +54 -0
  16. package/dist/bridge/readiness-result-worker.d.ts +2 -0
  17. package/dist/bridge/readiness-result-worker.js +121 -0
  18. package/dist/bridge/runner-host-capabilities.d.ts +15 -0
  19. package/dist/bridge/runner-host-capabilities.js +93 -0
  20. package/dist/cleanup/cleanup.service.d.ts +1 -0
  21. package/dist/cleanup/cleanup.service.js +70 -9
  22. package/dist/cli/cli.help.js +2 -2
  23. package/dist/cli/cli.service.d.ts +14 -6
  24. package/dist/cli/cli.service.js +75 -16
  25. package/dist/cli/local-config.d.ts +1 -0
  26. package/dist/cli/local-config.js +4 -0
  27. package/dist/runtime/aspnet-runtime-prebuild.d.ts +36 -0
  28. package/dist/runtime/aspnet-runtime-prebuild.js +341 -0
  29. package/dist/runtime/attempt-node-runtime-launcher.d.ts +2 -1
  30. package/dist/runtime/attempt-node-runtime-launcher.js +57 -18
  31. package/dist/runtime/attempt-path-operation.d.ts +21 -0
  32. package/dist/runtime/attempt-path-operation.js +94 -0
  33. package/dist/runtime/attempt-private-directory.d.ts +6 -0
  34. package/dist/runtime/attempt-private-directory.js +54 -0
  35. package/dist/runtime/attempt-process-supervisor.d.ts +11 -0
  36. package/dist/runtime/attempt-process-supervisor.js +67 -20
  37. package/dist/runtime/canonical-source-file.d.ts +3 -0
  38. package/dist/runtime/canonical-source-file.js +54 -0
  39. package/dist/runtime/docker-engine-probe.d.ts +90 -0
  40. package/dist/runtime/docker-engine-probe.js +333 -0
  41. package/dist/runtime/generated-output-reset.d.ts +10 -0
  42. package/dist/runtime/generated-output-reset.js +62 -8
  43. package/dist/runtime/host-database-capability-boundary.d.ts +16 -0
  44. package/dist/runtime/host-database-capability-boundary.js +62 -0
  45. package/dist/runtime/host-diagnostics.d.ts +11 -0
  46. package/dist/runtime/host-diagnostics.js +191 -0
  47. package/dist/runtime/host-execution-root.d.ts +4 -0
  48. package/dist/runtime/host-execution-root.js +39 -0
  49. package/dist/runtime/host-listener-inspector.d.ts +8 -1
  50. package/dist/runtime/host-listener-inspector.js +121 -60
  51. package/dist/runtime/host-runtime-contract.d.ts +12 -1
  52. package/dist/runtime/host-runtime-contract.js +107 -53
  53. package/dist/runtime/host-runtime-lease.d.ts +90 -8
  54. package/dist/runtime/host-runtime-lease.js +1097 -108
  55. package/dist/runtime/host-runtime-promotion.d.ts +12 -3
  56. package/dist/runtime/host-runtime-promotion.js +59 -12
  57. package/dist/runtime/memory-capacity.d.ts +70 -0
  58. package/dist/runtime/memory-capacity.js +123 -0
  59. package/dist/runtime/native-test-postgres-fallback.d.ts +25 -0
  60. package/dist/runtime/native-test-postgres-fallback.js +91 -0
  61. package/dist/runtime/node-host-runtime-adapter.d.ts +3 -0
  62. package/dist/runtime/node-host-runtime-adapter.js +28 -11
  63. package/dist/runtime/pinned-directory-process.d.ts +9 -0
  64. package/dist/runtime/pinned-directory-process.js +61 -0
  65. package/dist/runtime/pinned-source-directory.d.ts +17 -0
  66. package/dist/runtime/pinned-source-directory.js +94 -0
  67. package/dist/runtime/playwright-host-runtime-adapter.d.ts +1 -0
  68. package/dist/runtime/playwright-host-runtime-adapter.js +53 -5
  69. package/dist/runtime/prepared-runtime-identity.d.ts +6 -0
  70. package/dist/runtime/prepared-runtime-identity.js +218 -0
  71. package/dist/runtime/prepared-runtime-readiness.d.ts +30 -0
  72. package/dist/runtime/prepared-runtime-readiness.js +285 -0
  73. package/dist/runtime/runtime-isolation-lease.js +4 -1
  74. package/dist/runtime/workspace-resource-estimator.d.ts +17 -0
  75. package/dist/runtime/workspace-resource-estimator.js +174 -0
  76. package/dist/sandbox/preflight.d.ts +31 -1
  77. package/dist/sandbox/preflight.js +237 -51
  78. package/dist/sandbox/repository-lock.d.ts +2 -1
  79. package/dist/sandbox/repository-lock.js +17 -8
  80. package/dist/sandbox/runtime.d.ts +6 -1
  81. package/dist/sandbox/runtime.js +132 -103
  82. package/dist/sandbox/sandbox.types.d.ts +7 -0
  83. package/dist/sandbox/workspace.service.js +2 -0
  84. package/dist/session/managed-attempt-tools.d.ts +17 -1
  85. package/dist/session/managed-attempt-tools.js +481 -31
  86. package/dist/session/managed-build-coordinator.d.ts +5 -0
  87. package/dist/session/managed-build-coordinator.js +105 -0
  88. package/dist/session/managed-build-receipt.d.ts +21 -0
  89. package/dist/session/managed-build-receipt.js +337 -0
  90. package/dist/session/managed-verification-timeouts.d.ts +8 -0
  91. package/dist/session/managed-verification-timeouts.js +17 -0
  92. package/dist/session/phase-completion.artifacts.d.ts +17 -0
  93. package/dist/session/phase-completion.artifacts.js +224 -22
  94. package/dist/session/phase-completion.d.ts +11 -1
  95. package/dist/session/phase-completion.helpers.d.ts +5 -0
  96. package/dist/session/phase-completion.helpers.js +30 -7
  97. package/dist/session/phase-completion.js +14 -3
  98. package/dist/session/phase-completion.prompts.js +17 -18
  99. package/dist/session/phase-completion.runtime.d.ts +3 -1
  100. package/dist/session/phase-completion.runtime.js +118 -16
  101. package/dist/session/phase-completion.schemas.js +49 -2
  102. package/dist/session/phase-completion.validation.d.ts +1 -0
  103. package/dist/session/phase-completion.validation.js +111 -21
  104. package/dist/session/pre-publication-validation.d.ts +75 -0
  105. package/dist/session/pre-publication-validation.js +657 -0
  106. package/dist/session/provider-cli/bridge-cli.conformance-fixtures.d.ts +72 -0
  107. package/dist/session/provider-cli/bridge-cli.conformance-fixtures.js +462 -0
  108. package/dist/session/provider-cli/ci-repair-readiness.d.ts +8 -0
  109. package/dist/session/provider-cli/ci-repair-readiness.js +23 -3
  110. package/dist/session/provider-cli/provider-cli.artifacts.d.ts +4 -2
  111. package/dist/session/provider-cli/provider-cli.artifacts.js +47 -13
  112. package/dist/session/provider-cli/provider-cli.deterministic.js +34 -2
  113. package/dist/session/provider-cli/provider-cli.process.d.ts +51 -0
  114. package/dist/session/provider-cli/provider-cli.process.js +422 -22
  115. package/dist/session/provider-cli/provider-cli.prompts.d.ts +5 -0
  116. package/dist/session/provider-cli/provider-cli.prompts.js +136 -16
  117. package/dist/session/provider-cli/provider-cli.repair-epoch.d.ts +6 -0
  118. package/dist/session/provider-cli/provider-cli.repair-epoch.js +11 -0
  119. package/dist/session/provider-cli/provider-cli.runtime.d.ts +8 -1
  120. package/dist/session/provider-cli/provider-cli.runtime.js +40 -3
  121. package/dist/session/provider-cli/provider-cli.service.d.ts +30 -5
  122. package/dist/session/provider-cli/provider-cli.service.js +771 -68
  123. package/dist/session/provider-cli/provider-cli.types.d.ts +2 -0
  124. package/dist/session/provider-cli/provider-output-state.d.ts +10 -0
  125. package/dist/session/provider-cli/provider-output-state.js +361 -17
  126. package/dist/session/provider-cli/provider-usage.d.ts +7 -0
  127. package/dist/session/provider-cli/provider-usage.js +28 -5
  128. package/dist/session/session-redaction.js +434 -9
  129. package/dist/session/session.service.js +145 -23
  130. package/dist/session/session.types.d.ts +147 -2
  131. package/dist/session/session.types.js +587 -7
  132. package/dist/session/unreferenced-exports.d.ts +12 -0
  133. package/dist/session/unreferenced-exports.js +59 -0
  134. package/dist/shared/format/format-bytes.d.ts +1 -0
  135. package/dist/shared/format/format-bytes.js +9 -0
  136. package/dist/shared/git/git.js +2 -1
  137. package/dist/shared/path/path.d.ts +1 -0
  138. package/dist/shared/path/path.js +18 -0
  139. package/dist/shared/process/dotnet-toolchain.d.ts +17 -0
  140. package/dist/shared/process/dotnet-toolchain.js +307 -0
  141. package/dist/shared/process/host-process-supervisor.d.ts +2 -0
  142. package/dist/shared/process/host-process-supervisor.js +57 -9
  143. package/dist/shared/process/process.d.ts +2 -0
  144. package/dist/shared/process/process.js +12 -7
  145. package/dist/shared/provider-capabilities.d.ts +3 -0
  146. package/dist/shared/provider-capabilities.js +85 -0
  147. package/dist/shared/redaction/redaction.d.ts +1 -0
  148. package/dist/shared/redaction/redaction.js +39 -3
  149. package/dist/version.d.ts +1 -1
  150. package/dist/version.js +1 -1
  151. package/dist/worktree/dependency-warmer.d.ts +41 -9
  152. package/dist/worktree/dependency-warmer.js +497 -22
  153. package/dist/worktree/index.d.ts +1 -1
  154. package/dist/worktree/story-qa-reference-hydrator.d.ts +4 -0
  155. package/dist/worktree/story-qa-reference-hydrator.js +253 -0
  156. package/dist/worktree/worktree.service.d.ts +7 -0
  157. package/dist/worktree/worktree.service.js +253 -21
  158. package/dist/worktree/worktree.types.d.ts +7 -1
  159. package/package.json +7 -5
  160. package/runtime/windows-job-supervisor.ps1 +380 -14
@@ -4,6 +4,8 @@ import { artifactRootFor, artifactRootForOwner, debugCompletionPhaseOrder, draft
4
4
  import { ensureNoSymbolicLinkPathSegments, isPathUnderRoot, sha256File } from "../qa-sidecar-validation.js";
5
5
  import { hasLaunchTarget } from "./provider-cli.qa-sidecars.js";
6
6
  import { clip, isNodeError, messageFromError, normalizedString, parseJsonLine, stringField } from "./provider-output-state.js";
7
+ const maxTransportedQaSidecarBytes = 8 * 1024 * 1024;
8
+ const maxTransportedQaSidecarsTotalBytes = 16 * 1024 * 1024;
7
9
  const developCyclePhaseOrder = ["implementation", "self_review", "validation"];
8
10
  const nonPublishableWorktreePaths = [".forge", ".local"];
9
11
  export async function emitDraftGateArtifacts(emit, worktreePath, workItemId) {
@@ -146,23 +148,23 @@ export async function cleanupCompletionTools(completionTools, emit) {
146
148
  }).catch(() => undefined);
147
149
  }
148
150
  }
149
- export async function commitWorktreeChanges(git, worktreePath, workItemId) {
151
+ export async function commitWorktreeChanges(git, worktreePath, workItemId, alreadyStagedChangedFiles) {
152
+ const changedFiles = alreadyStagedChangedFiles ?? await stagePublishableWorktreeChanges(git, worktreePath);
153
+ if (changedFiles.length > 0) {
154
+ await git.run(worktreePath, ["commit", "-m", `provider cli changeset for ${workItemId.slice(0, 8)}`]);
155
+ }
156
+ const commitSha = (await git.run(worktreePath, ["rev-parse", "HEAD"])).trim();
157
+ return { commitSha, changedFiles };
158
+ }
159
+ export async function stagePublishableWorktreeChanges(git, worktreePath) {
150
160
  await git.run(worktreePath, ["add", "-A"]);
151
161
  for (const reservedPath of nonPublishableWorktreePaths) {
152
162
  await git.run(worktreePath, ["reset", "--", reservedPath]).catch(() => "");
153
163
  }
154
- const changedFiles = (await git.run(worktreePath, ["diff", "--cached", "--name-only"]))
164
+ return (await git.run(worktreePath, ["diff", "--cached", "--name-only"]))
155
165
  .split(/\r?\n/)
156
166
  .map((line) => line.trim())
157
167
  .filter(Boolean);
158
- if (changedFiles.length > 0) {
159
- await git.run(worktreePath, ["commit", "-m", `provider cli changeset for ${workItemId.slice(0, 8)}`]);
160
- }
161
- else {
162
- await git.run(worktreePath, ["commit", "--allow-empty", "-m", `provider cli completed for ${workItemId.slice(0, 8)}`]);
163
- }
164
- const commitSha = (await git.run(worktreePath, ["rev-parse", "HEAD"])).trim();
165
- return { commitSha, changedFiles };
166
168
  }
167
169
  export function phaseCompleteEventType(phase) {
168
170
  return phase === "implementation" ? "implementation_complete" : `${phase}_complete`;
@@ -212,12 +214,13 @@ export async function readQaCompletionArtifactBundle(worktreePath, workItemId, o
212
214
  const planJson = await fs.readFile(path.join(artifactRoot, qaArtifactFileNames.plan), "utf8");
213
215
  const evidenceJson = await fs.readFile(path.join(artifactRoot, qaArtifactFileNames.evidence), "utf8");
214
216
  const findingsJson = await fs.readFile(path.join(artifactRoot, qaArtifactFileNames.findings), "utf8");
215
- await validateQaBundleSidecarReferences(worktreePath, workItemId, ownerType, ownerId);
217
+ const sidecars = await readQaBundleSidecars(worktreePath, workItemId, ownerType, ownerId);
216
218
  return {
217
219
  ...artifact,
218
220
  planJson,
219
221
  evidenceJson,
220
- findingsJson
222
+ findingsJson,
223
+ sidecars
221
224
  };
222
225
  }
223
226
  export async function hasCompleteQaArtifactBundle(worktreePath, workItemId, ownerType, ownerId) {
@@ -274,15 +277,21 @@ function hasPassingRepositoryPlaywrightEvidence(evidence) {
274
277
  });
275
278
  }
276
279
  export async function validateQaBundleSidecarReferences(worktreePath, workItemId, ownerType, ownerId) {
280
+ await readQaBundleSidecars(worktreePath, workItemId, ownerType, ownerId);
281
+ }
282
+ export async function readQaBundleSidecars(worktreePath, workItemId, ownerType, ownerId) {
277
283
  const artifactRoot = ownerType && ownerId
278
284
  ? artifactRootForOwner(worktreePath, ownerType, ownerId)
279
285
  : artifactRootFor(worktreePath, workItemId);
280
286
  const evidence = await readJsonObjectFile(path.join(artifactRoot, qaArtifactFileNames.evidence));
281
287
  const sidecars = arrayField(evidence, "sidecars");
282
288
  if (sidecars.length === 0) {
283
- return;
289
+ return [];
284
290
  }
285
291
  const qaSidecarRoot = path.resolve(artifactRoot, "qa");
292
+ const transported = [];
293
+ const transportedByPath = new Map();
294
+ let totalBytes = 0;
286
295
  for (const [index, sidecar] of sidecars.entries()) {
287
296
  const sidecarPath = stringField(sidecar, "path");
288
297
  const expectedHash = stringField(sidecar, "content_hash");
@@ -312,11 +321,36 @@ export async function validateQaBundleSidecarReferences(worktreePath, workItemId
312
321
  if (stat.size !== expectedBytes) {
313
322
  throw new Error(`QA sidecar ${index} bytes do not match the referenced file.`);
314
323
  }
324
+ if (stat.size > maxTransportedQaSidecarBytes) {
325
+ throw new Error(`QA sidecar ${index} exceeds the ${maxTransportedQaSidecarBytes}-byte transport limit.`);
326
+ }
315
327
  const actualHash = await sha256File(fullPath);
316
328
  if (actualHash !== expectedHash.trim().toLowerCase()) {
317
329
  throw new Error(`QA sidecar ${index} content_hash does not match the referenced file.`);
318
330
  }
331
+ const canonicalPath = path.relative(worktreePath, fullPath).split(path.sep).join("/");
332
+ const duplicateKey = canonicalPath.toLowerCase();
333
+ const existing = transportedByPath.get(duplicateKey);
334
+ if (existing) {
335
+ if (existing.contentHash !== actualHash || existing.bytes !== stat.size) {
336
+ throw new Error(`QA sidecar ${index} conflicts with another payload for ${canonicalPath}.`);
337
+ }
338
+ continue;
339
+ }
340
+ totalBytes += stat.size;
341
+ if (totalBytes > maxTransportedQaSidecarsTotalBytes) {
342
+ throw new Error(`QA sidecars exceed the ${maxTransportedQaSidecarsTotalBytes}-byte total transport limit.`);
343
+ }
344
+ const content = await fs.readFile(fullPath);
345
+ transportedByPath.set(duplicateKey, { contentHash: actualHash, bytes: stat.size });
346
+ transported.push({
347
+ path: canonicalPath,
348
+ contentBase64: content.toString("base64"),
349
+ contentHash: actualHash,
350
+ bytes: stat.size
351
+ });
319
352
  }
353
+ return transported;
320
354
  }
321
355
  export async function emitQaStructuredEvents(emit, artifact) {
322
356
  const artifactRoot = path.dirname(artifact.path);
@@ -3,12 +3,13 @@ import path from "node:path";
3
3
  import { GitClient } from "../../shared/git/git.js";
4
4
  import { buildSpecBody, selectLaneCommand } from "../../worktree/artifact-injector.js";
5
5
  import { completionPhaseFromDispatch, debugCompletionPhaseOrder, expectedCompletionToolName, expectedDebugCompletionToolName, expectedQaCompletionToolName, qaCompletionGateOrder, readCompletionArtifact, usesDebugCycleCompletion, usesDevelopCycleCompletion, writeCompletionArtifact } from "../phase-completion.js";
6
- import { emitArchitectStructuredEvents, emitCompletionArtifactRecorded, emitQaArtifactRecorded, emitQaGateAccepted, emitQaStructuredEvents, isDebugCompletionPhaseForProvider, nextQaGate, phaseCompleteEventType, qaArtifactRootForDispatch, readQaCompletionArtifactBundle, readQaGateArtifact } from "./provider-cli.artifacts.js";
6
+ import { commitWorktreeChanges, emitArchitectStructuredEvents, emitCompletionArtifactRecorded, emitQaArtifactRecorded, emitQaGateAccepted, emitQaStructuredEvents, isDebugCompletionPhaseForProvider, nextQaGate, phaseCompleteEventType, qaArtifactRootForDispatch, readQaCompletionArtifactBundle, readQaGateArtifact } from "./provider-cli.artifacts.js";
7
7
  import { deterministicBrowserCheck, deterministicBrowserSidecar, hasLaunchTarget, writeQaSidecarFiles } from "./provider-cli.qa-sidecars.js";
8
8
  import { buildProviderCliCommand, formatProviderCliCommand, isPullRequestCheckRepairDispatch, isPullRequestCommentsDispatch, singleLine } from "./provider-cli.prompts.js";
9
9
  import { estimatedDeterministicUsage, exactRedactionSecrets } from "./provider-cli.runtime.js";
10
10
  import { buildProviderUsageEvent } from "./provider-usage.js";
11
11
  import { writeCiRepairReadinessManifest } from "./ci-repair-readiness.js";
12
+ import { assertRepairHeadEpoch } from "./provider-cli.repair-epoch.js";
12
13
  import { deterministicArchitectPayload, deterministicCompletionPayload, deterministicQaGatePayload } from "./provider-cli.deterministic-payloads.js";
13
14
  export class DeterministicProviderCliService {
14
15
  git;
@@ -211,6 +212,7 @@ export class DeterministicProviderCliService {
211
212
  }
212
213
  async runPullRequestRepair(context, route) {
213
214
  const { dispatch, worktree } = context;
215
+ await assertRepairHeadEpoch(context, this.git);
214
216
  const repairChecks = route === "ci_repair" || isPullRequestCheckRepairDispatch(dispatch);
215
217
  const addressComments = isPullRequestCommentsDispatch(dispatch);
216
218
  let repairArtifact = null;
@@ -238,7 +240,37 @@ export class DeterministicProviderCliService {
238
240
  throw new Error(`Deterministic CI repair did not produce ${reference.path}.`);
239
241
  await emitCompletionArtifactRecorded(context.emit, worktree.worktreePath, repairArtifact);
240
242
  }
241
- await this.git.run(worktree.worktreePath, ["commit", "--allow-empty", "-m", `forge bridge ${repairChecks ? "ci repair" : addressComments ? "pr comments" : "conflict resolve"} for ${dispatch.workItem.id.slice(0, 8)}`]);
243
+ if (addressComments) {
244
+ const actionable = dispatch.pullRequest?.reviewFindings.filter(finding => finding.actionable) ?? [];
245
+ if (actionable.length === 0 || !dispatch.pullRequest?.reviewIssueKey || !dispatch.pullRequest.headSha) {
246
+ throw new Error("Deterministic comment repair requires a durable actionable finding snapshot.");
247
+ }
248
+ await writeCompletionArtifact({
249
+ worktreePath: worktree.worktreePath,
250
+ workItemId: dispatch.workItem.id,
251
+ phase: "comment_repair",
252
+ producedBy: "forge-deterministic-provider",
253
+ }, expectedCompletionToolName("comment_repair"), {
254
+ status: "pass",
255
+ summary: "Recorded deterministic decision-required outcomes without changing source.",
256
+ repair_head_sha: dispatch.pullRequest.headSha,
257
+ repair_issue_key: dispatch.pullRequest.reviewIssueKey,
258
+ dispositions: actionable.map(finding => ({
259
+ claim_id: finding.claimId,
260
+ kind: finding.kind,
261
+ body_sha256: finding.bodySha256,
262
+ disposition: "needs_decision",
263
+ evidence: "The deterministic provider cannot evaluate semantic review feedback."
264
+ })),
265
+ changed_files: [],
266
+ validation: []
267
+ });
268
+ repairArtifact = await readCompletionArtifact(worktree.worktreePath, dispatch.workItem.id, "comment_repair");
269
+ if (!repairArtifact)
270
+ throw new Error("Deterministic comment repair did not produce its completion artifact.");
271
+ await emitCompletionArtifactRecorded(context.emit, worktree.worktreePath, repairArtifact);
272
+ }
273
+ await commitWorktreeChanges(this.git, worktree.worktreePath, dispatch.workItem.id);
242
274
  await context.emit(buildProviderUsageEvent(dispatch, estimatedDeterministicUsage()));
243
275
  await context.emit({
244
276
  role: "assistant",
@@ -1,4 +1,5 @@
1
1
  import { type LaunchCommand } from "../../shared/process/windows-launch.js";
2
+ export declare const PROVIDER_OUTPUT_CAPTURE_LIMIT_CHARS: number;
2
3
  export type ProviderCliCommand = LaunchCommand;
3
4
  export interface ProviderProcessRunRequest {
4
5
  readonly command: string;
@@ -7,11 +8,21 @@ export interface ProviderProcessRunRequest {
7
8
  readonly env?: Readonly<Record<string, string>>;
8
9
  readonly stdin?: string;
9
10
  readonly captureOutput?: boolean;
11
+ /**
12
+ * Exact process-local values that must be removed from rejected errors and
13
+ * supervisor persistence. This metadata is consumed by the attempt
14
+ * supervisor and is never forwarded to the child process.
15
+ */
16
+ readonly failureRedactionValues?: readonly string[];
10
17
  }
11
18
  export interface ProviderProcessRunResult {
12
19
  readonly exitCode: number;
13
20
  readonly stdout: string;
14
21
  readonly stderr: string;
22
+ readonly peakMemoryBytes?: number;
23
+ readonly memorySampleCount?: number;
24
+ readonly memorySource?: string;
25
+ readonly memoryObservedAt?: string;
15
26
  }
16
27
  export interface ProviderProcessRunner {
17
28
  run(request: ProviderProcessRunRequest, handlers?: ProviderProcessHandlers, signal?: AbortSignal): Promise<ProviderProcessRunResult>;
@@ -21,6 +32,36 @@ export interface ProviderProcessHandlers {
21
32
  onStdoutLine?(line: string): Promise<void> | void;
22
33
  onStderrLine?(line: string): Promise<void> | void;
23
34
  }
35
+ /** Recovery must wrap the attempt coordinator, never its raw OS runner. Each
36
+ * relaunch needs a new fenced child generation and exclusive launch files. */
37
+ export declare function recoveringProviderProcessRunner(inner: ProviderProcessRunner): ProviderProcessRunner;
38
+ /**
39
+ * Codex Desktop and an independently installed Codex CLI can briefly disagree
40
+ * about the shared models-cache schema during a rolling upgrade. Recover only
41
+ * that exact failure by quarantining the bounded cache file and retrying once;
42
+ * auth, config, sessions, and every other CODEX_HOME entry remain untouched.
43
+ */
44
+ export declare class CodexModelsCacheRecoveringProcessRunner implements ProviderProcessRunner {
45
+ private readonly inner;
46
+ constructor(inner: ProviderProcessRunner);
47
+ run(request: ProviderProcessRunRequest, handlers?: ProviderProcessHandlers, signal?: AbortSignal): Promise<ProviderProcessRunResult>;
48
+ }
49
+ /**
50
+ * Some Codex CLI builds can start new turns but cannot resume an older thread
51
+ * because the backing app does not implement the paginated thread lookup RPC.
52
+ * Preserve the prepared worktree and prompt, then retry once as a fresh turn.
53
+ */
54
+ export declare class CodexResumeRecoveringProcessRunner implements ProviderProcessRunner {
55
+ private readonly inner;
56
+ constructor(inner: ProviderProcessRunner);
57
+ run(request: ProviderProcessRunRequest, handlers?: ProviderProcessHandlers, signal?: AbortSignal): Promise<ProviderProcessRunResult>;
58
+ }
59
+ /**
60
+ * Recognizes the exact nonzero Codex service response at the provider-process
61
+ * boundary. Provider stdout is deliberately excluded because it can contain
62
+ * arbitrary tool/command output and therefore cannot mint retry authority.
63
+ */
64
+ export declare function isTransientCodexProviderNotFoundFailure(command: string, result: ProviderProcessRunResult): boolean;
24
65
  interface ProviderChildEnvironmentOptions {
25
66
  readonly parentEnv?: NodeJS.ProcessEnv;
26
67
  readonly platform?: NodeJS.Platform;
@@ -28,9 +69,19 @@ interface ProviderChildEnvironmentOptions {
28
69
  }
29
70
  export declare function buildProviderChildEnvironment(requestEnv?: Readonly<Record<string, string>>, options?: ProviderChildEnvironmentOptions): NodeJS.ProcessEnv;
30
71
  export declare class StreamingProviderProcessRunner implements ProviderProcessRunner {
72
+ private readonly terminalExitGraceMs;
73
+ constructor(terminalExitGraceMs?: number);
31
74
  run(request: ProviderProcessRunRequest, handlers?: ProviderProcessHandlers, signal?: AbortSignal): Promise<ProviderProcessRunResult>;
32
75
  }
76
+ /** Returns aggregate resident bytes for the exact supervised Unix process group. */
77
+ export declare function processGroupResidentMemoryBytes(processGroupId: number, platform?: NodeJS.Platform, procRoot?: string): number | null;
33
78
  export declare function resolveCodexNpmDirectLaunch(commandPath: string, args: readonly string[]): LaunchCommand | null;
79
+ /**
80
+ * npm installs of Claude Code (`npm i -g @anthropic-ai/claude-code`) put a `claude.cmd` shim on
81
+ * PATH; launch its cli.js directly for the same Job Object reasons as Codex. The native installer
82
+ * ships `claude.exe`, which is preferred by PATH resolution and needs no rewrite.
83
+ */
84
+ export declare function resolveClaudeNpmDirectLaunch(commandPath: string, args: readonly string[]): LaunchCommand | null;
34
85
  /**
35
86
  * Avoids cmd.exe's nested-quote handling for package-manager shims. That
36
87
  * quoting loses executable paths containing spaces after the command is