@loucompanion/forge-bridge 0.1.3-dev.f66395c3ac21 → 0.1.3-dev.fbe15023cdfe

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 (150) hide show
  1. package/README.md +78 -0
  2. package/dist/bridge/bridge.base.d.ts +6 -1
  3. package/dist/bridge/bridge.service.d.ts +60 -3
  4. package/dist/bridge/bridge.service.js +970 -24
  5. package/dist/bridge/bridge.types.d.ts +172 -1
  6. package/dist/cleanup/cleanup.service.d.ts +13 -2
  7. package/dist/cleanup/cleanup.service.js +435 -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.d.ts +2 -0
  14. package/dist/cli/cli.help.js +217 -0
  15. package/dist/cli/cli.service.d.ts +42 -2
  16. package/dist/cli/cli.service.js +356 -205
  17. package/dist/cli/local-config.d.ts +6 -0
  18. package/dist/cli/local-config.js +47 -3
  19. package/dist/runtime/attempt-node-runtime-launcher.d.ts +17 -0
  20. package/dist/runtime/attempt-node-runtime-launcher.js +101 -0
  21. package/dist/runtime/attempt-process-supervisor-registry.d.ts +20 -0
  22. package/dist/runtime/attempt-process-supervisor-registry.js +64 -0
  23. package/dist/runtime/attempt-process-supervisor.d.ts +86 -0
  24. package/dist/runtime/attempt-process-supervisor.js +350 -0
  25. package/dist/runtime/generated-output-reset.d.ts +10 -0
  26. package/dist/runtime/generated-output-reset.js +103 -0
  27. package/dist/runtime/host-listener-inspector.d.ts +44 -0
  28. package/dist/runtime/host-listener-inspector.js +324 -0
  29. package/dist/runtime/host-port-broker.d.ts +76 -0
  30. package/dist/runtime/host-port-broker.js +333 -0
  31. package/dist/runtime/host-runtime-contract.d.ts +47 -0
  32. package/dist/runtime/host-runtime-contract.js +700 -0
  33. package/dist/runtime/host-runtime-lease.d.ts +133 -0
  34. package/dist/runtime/host-runtime-lease.js +1460 -0
  35. package/dist/runtime/host-runtime-promotion.d.ts +23 -0
  36. package/dist/runtime/host-runtime-promotion.js +159 -0
  37. package/dist/runtime/node-host-runtime-adapter.d.ts +51 -0
  38. package/dist/runtime/node-host-runtime-adapter.js +268 -0
  39. package/dist/runtime/playwright-host-runtime-adapter.d.ts +20 -0
  40. package/dist/runtime/playwright-host-runtime-adapter.js +220 -0
  41. package/dist/runtime/runtime-isolation-lease.d.ts +67 -0
  42. package/dist/runtime/runtime-isolation-lease.js +158 -0
  43. package/dist/sandbox/command-runner.d.ts +4 -0
  44. package/dist/sandbox/command-runner.js +47 -0
  45. package/dist/sandbox/contract.d.ts +5 -0
  46. package/dist/sandbox/contract.js +276 -0
  47. package/dist/sandbox/event-budget.d.ts +11 -0
  48. package/dist/sandbox/event-budget.js +27 -0
  49. package/dist/sandbox/image-policy.d.ts +35 -0
  50. package/dist/sandbox/image-policy.js +247 -0
  51. package/dist/sandbox/index.d.ts +5 -0
  52. package/dist/sandbox/index.js +5 -0
  53. package/dist/sandbox/lease-watchdog.d.ts +18 -0
  54. package/dist/sandbox/lease-watchdog.js +67 -0
  55. package/dist/sandbox/preflight.d.ts +54 -0
  56. package/dist/sandbox/preflight.js +335 -0
  57. package/dist/sandbox/process.d.ts +20 -0
  58. package/dist/sandbox/process.js +209 -0
  59. package/dist/sandbox/provider-auth/codex.d.ts +26 -0
  60. package/dist/sandbox/provider-auth/codex.js +212 -0
  61. package/dist/sandbox/repository-lock.d.ts +5 -0
  62. package/dist/sandbox/repository-lock.js +119 -0
  63. package/dist/sandbox/runtime.d.ts +297 -0
  64. package/dist/sandbox/runtime.js +2338 -0
  65. package/dist/sandbox/sandbox.types.d.ts +86 -0
  66. package/dist/sandbox/sandbox.types.js +1 -0
  67. package/dist/sandbox/smoke.d.ts +76 -0
  68. package/dist/sandbox/smoke.js +380 -0
  69. package/dist/sandbox/worker-supervisor.d.ts +13 -0
  70. package/dist/sandbox/worker-supervisor.js +36 -0
  71. package/dist/sandbox/worker.d.ts +1 -0
  72. package/dist/sandbox/worker.js +225 -0
  73. package/dist/sandbox/workspace.service.d.ts +13 -0
  74. package/dist/sandbox/workspace.service.js +72 -0
  75. package/dist/session/managed-attempt-tools.d.ts +12 -0
  76. package/dist/session/managed-attempt-tools.js +561 -0
  77. package/dist/session/phase-completion.artifacts.d.ts +10 -0
  78. package/dist/session/phase-completion.artifacts.js +627 -0
  79. package/dist/session/phase-completion.d.ts +43 -42
  80. package/dist/session/phase-completion.helpers.d.ts +112 -0
  81. package/dist/session/phase-completion.helpers.js +684 -0
  82. package/dist/session/phase-completion.js +114 -3007
  83. package/dist/session/phase-completion.prompts.d.ts +14 -0
  84. package/dist/session/phase-completion.prompts.js +234 -0
  85. package/dist/session/phase-completion.runtime.d.ts +47 -0
  86. package/dist/session/phase-completion.runtime.js +731 -0
  87. package/dist/session/phase-completion.schemas.d.ts +3 -0
  88. package/dist/session/phase-completion.schemas.js +812 -0
  89. package/dist/session/phase-completion.validation.d.ts +37 -0
  90. package/dist/session/phase-completion.validation.js +828 -0
  91. package/dist/session/provider-cli/ci-repair-readiness.d.ts +8 -0
  92. package/dist/session/provider-cli/ci-repair-readiness.js +90 -0
  93. package/dist/session/provider-cli/provider-cli.artifacts.d.ts +93 -0
  94. package/dist/session/provider-cli/provider-cli.artifacts.js +778 -0
  95. package/dist/session/provider-cli/provider-cli.base.d.ts +1 -0
  96. package/dist/session/provider-cli/provider-cli.deterministic-payloads.d.ts +12 -0
  97. package/dist/session/provider-cli/provider-cli.deterministic-payloads.js +279 -0
  98. package/dist/session/provider-cli/provider-cli.deterministic.d.ts +14 -0
  99. package/dist/session/provider-cli/provider-cli.deterministic.js +375 -0
  100. package/dist/session/provider-cli/provider-cli.process.d.ts +48 -0
  101. package/dist/session/provider-cli/provider-cli.process.js +474 -0
  102. package/dist/session/provider-cli/provider-cli.prompts.d.ts +47 -0
  103. package/dist/session/provider-cli/provider-cli.prompts.js +595 -0
  104. package/dist/session/provider-cli/provider-cli.qa-sidecars.d.ts +11 -0
  105. package/dist/session/provider-cli/provider-cli.qa-sidecars.js +66 -0
  106. package/dist/session/provider-cli/provider-cli.runtime.d.ts +9 -0
  107. package/dist/session/provider-cli/provider-cli.runtime.js +41 -0
  108. package/dist/session/provider-cli/provider-cli.service.d.ts +22 -53
  109. package/dist/session/provider-cli/provider-cli.service.js +587 -2530
  110. package/dist/session/provider-cli/provider-cli.types.d.ts +6 -0
  111. package/dist/session/provider-cli/provider-output-state.d.ts +22 -0
  112. package/dist/session/provider-cli/provider-output-state.js +473 -0
  113. package/dist/session/session-redaction.d.ts +3 -0
  114. package/dist/session/session-redaction.js +23 -0
  115. package/dist/session/session.base.d.ts +6 -1
  116. package/dist/session/session.service.d.ts +8 -2
  117. package/dist/session/session.service.js +463 -58
  118. package/dist/session/session.types.d.ts +177 -1
  119. package/dist/session/session.types.js +352 -3
  120. package/dist/shared/path/path.js +3 -1
  121. package/dist/shared/process/host-process-recovery.d.ts +12 -0
  122. package/dist/shared/process/host-process-recovery.js +78 -0
  123. package/dist/shared/process/host-process-supervisor.d.ts +57 -0
  124. package/dist/shared/process/host-process-supervisor.js +282 -0
  125. package/dist/shared/process/process.d.ts +1 -0
  126. package/dist/shared/process/process.js +1 -0
  127. package/dist/shared/process/windows-launch.d.ts +8 -0
  128. package/dist/shared/process/windows-launch.js +41 -0
  129. package/dist/shared/provider-capabilities.d.ts +1 -0
  130. package/dist/shared/provider-capabilities.js +3 -0
  131. package/dist/shared/redaction/redaction.js +10 -3
  132. package/dist/version.d.ts +1 -1
  133. package/dist/version.js +1 -1
  134. package/dist/worktree/artifact-injector.d.ts +3 -2
  135. package/dist/worktree/artifact-injector.js +82 -10
  136. package/dist/worktree/dependency-warmer.d.ts +21 -1
  137. package/dist/worktree/dependency-warmer.js +138 -5
  138. package/dist/worktree/index.d.ts +1 -0
  139. package/dist/worktree/index.js +1 -0
  140. package/dist/worktree/prior-phase-artifact-hydrator.d.ts +2 -0
  141. package/dist/worktree/prior-phase-artifact-hydrator.js +136 -0
  142. package/dist/worktree/worktree-paths.d.ts +4 -0
  143. package/dist/worktree/worktree-paths.js +30 -0
  144. package/dist/worktree/worktree.base.d.ts +3 -0
  145. package/dist/worktree/worktree.service.d.ts +9 -3
  146. package/dist/worktree/worktree.service.js +100 -52
  147. package/dist/worktree/worktree.types.d.ts +3 -1
  148. package/package.json +6 -3
  149. package/runtime/windows-job-supervisor.ps1 +356 -0
  150. package/runtime/windows-listener-owner.ps1 +33 -0
@@ -0,0 +1,14 @@
1
+ import { type CompletionPhase, type DebugCompletionPhase, type DecomposeCompletionGate, type DevelopCompletionPhase, type DraftCompletionGate, type QaCompletionGate } from "./phase-completion.js";
2
+ export declare function completionPromptForPhase(phase: CompletionPhase, artifactRoot?: string): string;
3
+ export declare function completionPromptForDevelopCycle(phase: CompletionPhase): string;
4
+ export declare function completionPromptForQaCycle(currentGate?: QaCompletionGate, artifactRoot?: string): string;
5
+ export declare function completionPromptForDraftCycle(currentGate?: DraftCompletionGate): string;
6
+ export declare function completionPromptForDecomposeCycle(currentGate?: DecomposeCompletionGate): string;
7
+ export declare function completionPromptForDebugCycle(currentGate?: DebugCompletionPhase): string;
8
+ export declare function nextPhaseAfter(phase: CompletionPhase): DevelopCompletionPhase | null;
9
+ export declare function nextDebugPhaseAfter(phase: DebugCompletionPhase): DebugCompletionPhase | null;
10
+ export declare function completionToolNextInstruction(completedPhase: CompletionPhase, status: string, nextPhase: CompletionPhase | "dev_test_ready" | "qa_ready" | "sign_off_ready" | "provider_checks_ready"): string;
11
+ export declare function completionToolNextInstructionForDraftGate(completedGate: DraftCompletionGate, status: string, nextGate: DraftCompletionGate | null): string;
12
+ export declare function completionToolNextInstructionForQaGate(completedGate: QaCompletionGate, status: string, nextGate: QaCompletionGate | null): string;
13
+ export declare function completionToolNextInstructionForDecomposeGate(completedGate: DecomposeCompletionGate, status: string, nextGate: DecomposeCompletionGate | null): string;
14
+ export declare function completionToolNextInstructionForDebugGate(completedGate: DebugCompletionPhase, status: string, nextGate: DebugCompletionPhase | null): string;
@@ -0,0 +1,234 @@
1
+ import { completionPhaseOrder, completionToolNamesForPhase, debugCompletionPhaseOrder, expectedCompletionToolName, expectedDebugCompletionToolName, expectedDecomposeCompletionToolName, phaseFiles, toolServerName } from "./phase-completion.js";
2
+ import { isDebugCompletionPhase, isDevelopCompletionPhase } from "./phase-completion.validation.js";
3
+ export function completionPromptForPhase(phase, artifactRoot = ".forge/work-items/{workItemId}/artifacts") {
4
+ const toolName = expectedCompletionToolName(phase);
5
+ const alias = completionToolNamesForPhase(phase).find((name) => name !== toolName);
6
+ const artifactName = phaseFiles[phase].jsonFileName;
7
+ if (phase === "qa") {
8
+ return `Forge completion tools are available through the MCP server named \`${toolServerName}\`.
9
+ Do not write QA artifacts by hand. When QA is complete, call \`${toolName}(...)\`${alias ? ` (or \`${alias}\` if your client shows unqualified MCP tool names)` : ""} with the required structured QA payload.
10
+ That tool writes the durable QA bundle under \`${artifactRoot}/\`: \`qa.plan.json\`, \`qa.evidence.json\`, \`qa.findings.json\`, \`${artifactName}\`, and \`qa.report.md\`.
11
+ Use \`status: "pass"\` only when the validated changes satisfy acceptance criteria with concrete evidence. Use \`status: "needs_rework"\` with actionable in-scope findings, or \`status: "blocked"\` with a concrete blocker_reason.
12
+ Include \`policy_warnings\` for non-blocking Forge policy or scope mismatches that should remain visible after QA.
13
+ Forge will mirror only the tool-written QA artifacts; reporting QA completion in prose is not enough.`;
14
+ }
15
+ if (phase === "architect") {
16
+ return `Forge completion tools are available through the MCP server named \`${toolServerName}\`.
17
+ Do not write Architect artifacts by hand. When the plan is complete, call \`${toolName}(...)\`${alias ? ` (or \`${alias}\` if your client shows unqualified MCP tool names)` : ""} with the full structured Architect planning payload.
18
+ That tool writes \`.forge/work-items/{workItemId}/artifacts/implementation.plan.json\`, \`qa.plan.json\`, \`${artifactName}\`, and \`architect.report.md\`.
19
+ The payload must put \`phases\`, \`tasks\`, \`dependencies\`, and \`phase_gates\` as top-level fields inside \`implementation_plan\`, for example:
20
+ \`{ "status": "pass", "summary": "...", "implementation_plan": { "schema_version": 1, "plan_id": "plan-...", "phases": [{ "id": "phase-1", "tasks": ["task-1"], "gate": "gate-1" }], "tasks": [{ "id": "task-1", "verification_scope": { "schema_version": 1, "surface": ["domain_contract"], "required_evidence": ["unit_tests"], "not_applicable": ["browser_manual", "api_http"], "browser_required": false, "api_required": false, "rationale": "Backend-only child task." }, "tests": [{ "command": "npm test" }] }], "dependencies": [], "phase_gates": [{ "id": "gate-1", "phase": "phase-1" }] }, "qa_plan": { "schema_version": 1, "final_qa": [{ "id": "qa-1", "coverage": "..." }] }, "report_markdown": "# Architect Report" }\`.
21
+ \`implementation_plan.tasks\` are Develop child tasks only: each task should include \`verification_scope\` describing task-level QA evidence, and must require a focused repo/product implementation change. Put parent-story QA, sign-off, child-count/materialization inventory, parent plan artifact checks, and final integrated acceptance proof in \`qa_plan.final_qa\`, not as child Develop tasks.
22
+ Dependency entries use canonical \`before\` and \`after\` task ids, for example \`{ "before": "task-1", "after": "task-2" }\`. Forge accepts \`from\`/\`to\` only as aliases and normalizes them before writing artifacts.
23
+ Use \`status: "pass"\` for a valid pending-approval plan, \`needs_revision\` when story/design input must change, or \`blocked\` with a concrete blocker.
24
+ Forge will mirror only the tool-written Architect artifacts; reporting the plan in prose is not enough.`;
25
+ }
26
+ if (phase === "ci_repair") {
27
+ return `Forge completion tools are available through the MCP server named \`${toolServerName}\`.
28
+ Read the generated \`.forge/work-items/{workItemId}/ci-repair.readiness.json\` before running validation.
29
+ Do not write the CI-repair handoff by hand. After the repair and locally equivalent validation are complete, call \`${toolName}(...)\`${alias ? ` (or \`${alias}\` if your client shows unqualified MCP tool names)` : ""}.
30
+ That tool validates failed-check inspection, root cause, scoped changes, narrow proof, every failed-job guard/test/drift step, provider-only classifications, broader validation, remaining risk, provider state, and push readiness.
31
+ It writes \`.forge/work-items/{workItemId}/artifacts/${artifactName}\`. Forge Bridge will not commit, push, or report CI repair success until this gate passes.
32
+ For a step classified \`provider_only\`, include the exact reason and provider check that will supply the missing proof. Do not weaken or delete the provider check.`;
33
+ }
34
+ return `Forge completion tools are available through the MCP server named \`${toolServerName}\`.
35
+ Do not write phase artifacts by hand. When the phase is complete, call \`${toolName}(...)\`${alias ? ` (or \`${alias}\` if your client shows unqualified MCP tool names)` : ""} with the required evidence payload.
36
+ That tool writes \`.forge/work-items/{workItemId}/artifacts/${artifactName}\` and returns the artifact reference that Forge will mirror through the existing phase-artifact pipeline.
37
+ If the work cannot pass, call the same tool with a non-pass status and explicit blockers instead of reporting completion in prose only.`;
38
+ }
39
+ export function completionPromptForDevelopCycle(phase) {
40
+ return `Forge completion tools are available through the MCP server named \`${toolServerName}\`.
41
+ Do not write phase artifacts by hand. The tool server enforces phase order and starts this run in \`${phase}\`.
42
+ Complete the dev cycle in order inside this same provider session:
43
+ 1. Call \`forge.complete_implementation(...)\` when implementation evidence is ready.
44
+ 2. Follow the returned self-review instruction, then call \`forge.complete_self_review(...)\`.
45
+ 3. Follow the returned validation instruction, then call \`forge.complete_validation(...)\`.
46
+ Each tool writes the canonical artifact under \`.forge/work-items/{workItemId}/artifacts/\` and returns the next-phase instruction Forge expects you to follow.
47
+ If the current phase cannot pass, call the current phase tool with a non-pass status and explicit blockers instead of reporting completion in prose only.`;
48
+ }
49
+ export function completionPromptForQaCycle(currentGate = "qa_plan", artifactRoot = ".forge/work-items/{workItemId}/artifacts") {
50
+ return `Forge completion tools are available through the MCP server named \`${toolServerName}\`.
51
+ Do not write QA artifacts by hand. The tool server enforces QA gate order and starts this run at \`${currentGate}\`.
52
+ Complete the QA cycle in order inside this same provider session. Start long, independent regression verification as early as practical, continue API/source/manual review while it runs, and wait for its receipt only when those independent checks are complete:
53
+ 1. Call \`forge.complete_qa_plan(...)\` after the QA test plan/checklist is ready.
54
+ 2. Follow the returned regression instruction, then call \`forge.complete_qa_regression(...)\`.
55
+ 3. Follow the returned API/backend instruction, then call \`forge.complete_qa_api(...)\`.
56
+ 4. Follow the returned manual web instruction, then call \`forge.complete_qa_manual_web(...)\`.
57
+ 5. Follow the returned bug reproduction instruction, then call \`forge.complete_qa_bug_repro(...)\`.
58
+ 6. Follow the returned findings instruction, then call \`forge.complete_qa_findings(...)\`.
59
+ 7. Follow the returned verdict instruction, then call \`forge.complete_qa_verdict(...)\`.
60
+ Use \`status: "skipped"\` with a reason for gates that are not applicable. If a gate is blocked, keep moving through later gates as skipped due to the blocker and finish with a blocked verdict.
61
+ On a managed host, start solution-wide \`dotnet test Forge.sln\` evidence through \`forge.start_managed_command\` with at least a 45-minute timeout. Do not poll it. Continue independent QA work, then call \`forge.wait_managed_command\` once; Forge keeps the session healthy and streams durable progress while that call waits. Include the returned \`managed_command_id\` in command evidence. The regression gate rejects generic-shell timeouts and non-terminal receipts for that command.
62
+ The final verdict tool writes the canonical QA bundle under \`${artifactRoot}/\`: \`qa.plan.json\`, \`qa.evidence.json\`, \`qa.findings.json\`, \`qa.verdict.json\`, and \`qa.report.md\`.
63
+ Include \`policy_warnings\` in the final verdict for non-blocking Forge policy or scope mismatches that should remain visible after QA.
64
+ The legacy \`forge.complete_qa\` one-shot tool is not available in normal QA-cycle mode. Reporting QA completion in prose is not enough.`;
65
+ }
66
+ export function completionPromptForDraftCycle(currentGate = "draft_intent") {
67
+ return `Forge completion tools are available through the MCP server named \`${toolServerName}\`.
68
+ Do not finish Draft by prose or raw JSON. The tool server enforces Draft gate order and starts at \`${currentGate}\`.
69
+ Complete the Draft cycle in order inside this same provider session:
70
+ 1. Call \`forge.complete_draft_intent(...)\` after interpreting user intent and non-goals.
71
+ 2. Follow the returned repo-context instruction, inspect selected project/repo assumptions, then call \`forge.complete_draft_repo_context(...)\`.
72
+ 3. Follow the returned graph-context instruction, account for DAG/dependency placement, then call \`forge.complete_draft_graph_context(...)\`.
73
+ 4. Follow the returned product-scope instruction, choose product scope for the selected project, then call \`forge.complete_draft_product_scope(...)\`.
74
+ 5. Follow the returned draft-plan instruction, draft the requested final JSON shape for the current Draft kind, then call \`forge.complete_draft_work_order_plan(...)\`.
75
+ 6. Follow the returned critic instruction, critique literalism, wrong-project scope, and decomposition quality, then call \`forge.complete_draft_critic(...)\`.
76
+ 7. Follow the returned proposal instruction, then call \`forge.complete_draft_proposal(...)\` with the final Draft JSON payload in \`draft_json\`.
77
+ The final proposal tool writes \`draft.proposal.json\` under \`.forge/work-items/{workItemId}/artifacts/\`. Reporting Draft completion in prose is not enough.`;
78
+ }
79
+ export function completionPromptForDecomposeCycle(currentGate = "decompose_subject_intake") {
80
+ return `# Forge Decompose completion cycle
81
+ You must complete the Decompose gates in order using the Forge MCP tools. Reporting progress in prose is not enough.
82
+
83
+ Current gate: ${currentGate}
84
+
85
+ Required order:
86
+ 1. Call \`forge.complete_decompose_subject_intake(...)\` after identifying the Work Order/Feature subject, scope, and non-goals.
87
+ 2. Follow the returned context-review instruction, inspect injected project/repo/dependency context, then call \`forge.complete_decompose_context_review(...)\`.
88
+ 3. Follow the returned breakdown-strategy instruction, choose safe Feature/Story boundaries, then call \`forge.complete_decompose_breakdown_strategy(...)\`.
89
+ 4. Follow the returned child-items instruction, draft candidate child items, then call \`forge.complete_decompose_child_items(...)\`.
90
+ 5. Follow the returned dependency-graph instruction, validate keys/dependencies/order, then call \`forge.complete_decompose_dependency_graph(...)\`.
91
+ 6. Follow the returned critic instruction, critique scope, DAG safety, manual reconciliation risk, and missing acceptance detail, then call \`forge.complete_decompose_critic(...)\`.
92
+ 7. Follow the returned proposal instruction, then call \`forge.complete_decompose_proposal(...)\` with final JSON in \`proposal_json\`.
93
+ The final proposal tool writes \`decompose.proposal.json\` under \`.forge/work-items/{workItemId}/artifacts/\`. The proposal_json object must contain summary, optional blockedReason, and candidates. Work Order-to-Feature candidates may include \`estimated_qa_scope\`; Feature-to-Story candidates should include \`qa_scope\` with schema_version 1 plus scheduleIndex, waveIndex, expectedOutput, handoffSummary, and dependencyReason for dependency handoff.`;
94
+ }
95
+ export function completionPromptForDebugCycle(currentGate = "debug_repro") {
96
+ return `Forge completion tools are available through the MCP server named \`${toolServerName}\`.
97
+ Do not write Debug artifacts by hand. The tool server enforces Debug gate order and starts this run at \`${currentGate}\`.
98
+ Complete the Debug cycle in order inside this same provider session:
99
+ 1. Reproduce or tightly characterize the bug, then call \`forge.complete_debug_repro(...)\`.
100
+ 2. Follow the returned root-cause instruction, isolate evidence, then call \`forge.complete_debug_root_cause(...)\`.
101
+ 3. Follow the returned fix instruction, apply the smallest safe fix with regression coverage when practical, then call \`forge.complete_debug_fix(...)\`.
102
+ 4. Follow the returned regression instruction, prove the original repro is negative and the fix is QA-ready, then call \`forge.complete_debug_regression(...)\`.
103
+ Each tool writes a canonical Debug artifact under \`.forge/work-items/{workItemId}/artifacts/\`: \`debug.repro.json\`, \`debug.root-cause.json\`, \`debug.fix.json\`, and \`debug.regression.json\` plus \`debug.report.md\` when report text is provided or generated.
104
+ Use a non-pass status with explicit blockers when the current Debug gate cannot pass. Reporting Debug completion in prose is not enough; the relevant MCP completion tool is the transition request.`;
105
+ }
106
+ export function nextPhaseAfter(phase) {
107
+ if (!isDevelopCompletionPhase(phase)) {
108
+ return null;
109
+ }
110
+ const index = completionPhaseOrder.indexOf(phase);
111
+ return index >= 0 ? completionPhaseOrder[index + 1] ?? null : null;
112
+ }
113
+ export function nextDebugPhaseAfter(phase) {
114
+ const index = debugCompletionPhaseOrder.indexOf(phase);
115
+ return index >= 0 ? debugCompletionPhaseOrder[index + 1] ?? null : null;
116
+ }
117
+ export function completionToolNextInstruction(completedPhase, status, nextPhase) {
118
+ if (completedPhase === "qa") {
119
+ if (status === "blocked") {
120
+ return "QA blocked. Forge recorded the blocker reason and will surface the run for human attention.";
121
+ }
122
+ if (status === "needs_rework") {
123
+ return "QA findings recorded. Forge has the structured evidence needed to route this work back for implementation rework.";
124
+ }
125
+ return "QA accepted. Forge has the structured evidence needed to move this work item to Sign-Off.";
126
+ }
127
+ if (completedPhase === "ci_repair") {
128
+ return status === "pass"
129
+ ? "CI repair handoff accepted. Forge Bridge may now commit, push, and return the PR to provider checks."
130
+ : "Stay in CI repair, address the exact missing evidence returned by this gate, then call forge.complete_ci_repair again.";
131
+ }
132
+ if (status !== "pass") {
133
+ return `Stay in ${completedPhase}, address the recorded blockers, then call ${expectedCompletionToolName(completedPhase)} again.`;
134
+ }
135
+ if (isDebugCompletionPhase(completedPhase)) {
136
+ const debugNext = isDebugCompletionPhase(nextPhase) ? nextPhase : null;
137
+ return completionToolNextInstructionForDebugGate(completedPhase, status, debugNext);
138
+ }
139
+ if (nextPhase === "self_review") {
140
+ return "Implementation accepted. Begin self-review: inspect the diff, apply safe fixes, and call forge.complete_self_review with review evidence.";
141
+ }
142
+ if (nextPhase === "validation") {
143
+ return "Self-review accepted. Begin validation: run deterministic checks, prove acceptance criteria, and call forge.complete_validation with command evidence.";
144
+ }
145
+ return "Validation accepted. Forge has the structured evidence needed to move this work item to QA.";
146
+ }
147
+ export function completionToolNextInstructionForDraftGate(completedGate, status, nextGate) {
148
+ if (status === "blocked") {
149
+ return `Stay in ${completedGate}; record the blocker and retry the same Draft gate when unblocked.`;
150
+ }
151
+ if (!nextGate) {
152
+ return "Draft proposal accepted. Forge has the structured Work Order draft JSON needed to populate the form.";
153
+ }
154
+ const instructions = {
155
+ draft_intent: "Capture intent/non-goals, then call forge.complete_draft_intent.",
156
+ draft_repo_context: "Inspect selected repo/project assumptions, then call forge.complete_draft_repo_context.",
157
+ draft_graph_context: "Account for DAG dependencies and placement, then call forge.complete_draft_graph_context.",
158
+ draft_product_scope: "Choose product scope for the selected project, then call forge.complete_draft_product_scope.",
159
+ draft_work_order_plan: "Draft the current Draft kind's plan fields, then call forge.complete_draft_work_order_plan.",
160
+ draft_critic: "Critique literalism/wrong-project scope/decomposition risk, then call forge.complete_draft_critic.",
161
+ draft_proposal: "Submit final draft_json through forge.complete_draft_proposal."
162
+ };
163
+ return `${completedGate} accepted. Continue to ${nextGate}. ${instructions[nextGate]}`;
164
+ }
165
+ export function completionToolNextInstructionForQaGate(completedGate, status, nextGate) {
166
+ if (!nextGate) {
167
+ if (status === "blocked") {
168
+ return "QA blocked. Forge recorded the blocker reason and will surface the run for human attention.";
169
+ }
170
+ if (status === "needs_rework") {
171
+ return "QA findings recorded. Forge has the structured evidence needed to route this work back for implementation rework.";
172
+ }
173
+ return "QA accepted. Forge has the structured evidence needed to move this work item to Sign-Off.";
174
+ }
175
+ const skipped = status === "skipped";
176
+ const blocked = status === "blocked";
177
+ const prefix = blocked
178
+ ? `${completedGate} recorded a blocker. Continue through ${nextGate} and mark downstream gates skipped if the blocker prevents evidence collection.`
179
+ : skipped
180
+ ? `${completedGate} skipped. Continue to ${nextGate}.`
181
+ : `${completedGate} accepted. Continue to ${nextGate}.`;
182
+ return `${prefix} ${qaGateInstruction(nextGate)}`;
183
+ }
184
+ export function completionToolNextInstructionForDecomposeGate(completedGate, status, nextGate) {
185
+ if (status !== "pass") {
186
+ return `Stay in ${completedGate}, address the recorded blockers/rework, then call ${expectedDecomposeCompletionToolName(completedGate)} again.`;
187
+ }
188
+ if (!nextGate) {
189
+ return "Decompose proposal accepted. Forge has the structured child-item proposal JSON needed to populate the proposal row.";
190
+ }
191
+ const nextInstructions = {
192
+ decompose_subject_intake: "Capture subject/scope, then call forge.complete_decompose_subject_intake.",
193
+ decompose_context_review: "Review project/repo/dependency context, then call forge.complete_decompose_context_review.",
194
+ decompose_breakdown_strategy: "Choose safe child boundaries, then call forge.complete_decompose_breakdown_strategy.",
195
+ decompose_child_items: "Draft child candidates, then call forge.complete_decompose_child_items.",
196
+ decompose_dependency_graph: "Validate dependency DAG, then call forge.complete_decompose_dependency_graph.",
197
+ decompose_critic: "Critique the decomposition, then call forge.complete_decompose_critic.",
198
+ decompose_proposal: "Submit final proposal_json through forge.complete_decompose_proposal."
199
+ };
200
+ return `${completedGate} accepted. ${nextInstructions[nextGate]}`;
201
+ }
202
+ export function completionToolNextInstructionForDebugGate(completedGate, status, nextGate) {
203
+ if (status !== "pass") {
204
+ return `Stay in ${completedGate}, address the recorded blockers, then call ${expectedDebugCompletionToolName(completedGate)} again.`;
205
+ }
206
+ if (nextGate === "debug_root_cause") {
207
+ return "Debug repro accepted. Begin root-cause analysis: connect the observed failure to code evidence and call forge.complete_debug_root_cause.";
208
+ }
209
+ if (nextGate === "debug_fix") {
210
+ return "Debug root cause accepted. Apply the smallest safe fix with regression coverage where practical, then call forge.complete_debug_fix.";
211
+ }
212
+ if (nextGate === "debug_regression") {
213
+ return "Debug fix accepted. Prove the original repro is negative, run targeted regression checks, and call forge.complete_debug_regression.";
214
+ }
215
+ return "Debug regression accepted. Forge has the structured evidence needed to move this bug fix to QA.";
216
+ }
217
+ function qaGateInstruction(gate) {
218
+ switch (gate) {
219
+ case "qa_regression":
220
+ return "Run or explicitly skip applicable regression/build/lint/typecheck/e2e checks, then call forge.complete_qa_regression. On a managed host, start solution-wide dotnet test Forge.sln early with forge.start_managed_command using at least a 45-minute timeout. Do not poll it: continue independent QA checks, then call forge.wait_managed_command once and include its terminal managed_command_id in command evidence. Forge keeps the session healthy and streams durable progress while that wait call is active. A reproduced failure outside the current diff and acceptance criteria may remain non-blocking only when the current item has independent passing evidence: preserve it as an out_of_scope_failure with candidate_bug_id, scope_evidence, acceptance_criteria_independent: true, and a failing focused repro command/exit code. Never classify an unexplained, in-scope, or infrastructure failure this way.";
221
+ case "qa_api":
222
+ return "Run or explicitly skip applicable API/backend contract checks, then call forge.complete_qa_api.";
223
+ case "qa_manual_web":
224
+ return "Run or explicitly skip applicable browser/manual web checks, then call forge.complete_qa_manual_web.";
225
+ case "qa_bug_repro":
226
+ return "Reproduce or explicitly skip relevant defects/candidate bugs, then call forge.complete_qa_bug_repro.";
227
+ case "qa_findings":
228
+ return "Normalize observations into findings and candidate bugs, then call forge.complete_qa_findings.";
229
+ case "qa_verdict":
230
+ return "Assemble the final QA verdict from all prior gate evidence, then call forge.complete_qa_verdict.";
231
+ case "qa_plan":
232
+ return "Prepare the QA checklist, then call forge.complete_qa_plan.";
233
+ }
234
+ }
@@ -0,0 +1,47 @@
1
+ import { type CompletionToolCallResult, type CompletionToolRuntime, type CompletionToolRuntimeOptions, type CompletionToolServerConfig } from "./phase-completion.js";
2
+ import { type ManagedAttemptToolResult } from "./managed-attempt-tools.js";
3
+ export declare function prepareCompletionToolRuntime(options: CompletionToolRuntimeOptions): Promise<CompletionToolRuntime>;
4
+ export declare function buildCompletionToolServerArgs(config: CompletionToolServerConfig): readonly string[];
5
+ export declare function codexMcpConfigArgs(runtime: CompletionToolRuntime): readonly string[];
6
+ export declare function cursorMcpServerConfig(runtime: CompletionToolRuntime): unknown;
7
+ export declare function completionToolNamesForServer(config: CompletionToolServerConfig): readonly string[];
8
+ export declare class CompletionToolServerSession {
9
+ private readonly config;
10
+ private currentPhase;
11
+ private currentQaGate;
12
+ private currentDraftGate;
13
+ private currentDecomposeGate;
14
+ private readonly managedCommandReceipts;
15
+ private completed;
16
+ constructor(config: CompletionToolServerConfig);
17
+ get instructions(): string;
18
+ toolDefinitions(): readonly unknown[];
19
+ callTool(toolName: string, input: unknown): Promise<CompletionToolCallResult | ManagedAttemptToolResult>;
20
+ private callDecomposeGateTool;
21
+ private callDraftGateTool;
22
+ private callDebugGateTool;
23
+ private callQaGateTool;
24
+ private advanceAfterPass;
25
+ private advanceAfterDecomposeGate;
26
+ private advanceAfterDraftGate;
27
+ private advanceAfterQaGate;
28
+ private advanceAfterDebugGate;
29
+ }
30
+ export declare function completionToolRuntimeEnvironment(runtimeEnvironment?: Readonly<Record<string, string>>): Readonly<Record<string, string>>;
31
+ /**
32
+ * A solution-wide Forge test is long enough that a generic provider shell can
33
+ * expire while VSTest is still healthy. On managed host attempts, only the
34
+ * attempt-owned command runner can prove the exact process outcome and clean
35
+ * up its process tree. Keep this check at the completion gate so prompt drift
36
+ * cannot turn an arbitrary shell timeout into a QA blocker.
37
+ */
38
+ export declare function assertManagedQaRegressionEvidence(input: unknown, receipts: readonly Readonly<Record<string, unknown>>[]): void;
39
+ export declare function runCompletionMcpServer(config: CompletionToolServerConfig): Promise<void>;
40
+ export declare function parseCompletionMcpArgs(argv: readonly string[]): {
41
+ readonly ok: true;
42
+ readonly config: CompletionToolServerConfig;
43
+ } | {
44
+ readonly ok: false;
45
+ readonly error: string;
46
+ };
47
+ export declare function completionRedactionEnv(secrets: readonly string[]): Readonly<Record<string, string>>;