(args: {
workspaceId: string;
entry: { projectPath: string; workspace: WorkspaceConfigEntry };
proposePlanResult: { planPath: string };
})
| 8719 | } |
| 8720 | |
| 8721 | private async handleSuccessfulWorkflowProposePlan(args: { |
| 8722 | workspaceId: string; |
| 8723 | entry: { projectPath: string; workspace: WorkspaceConfigEntry }; |
| 8724 | proposePlanResult: { planPath: string }; |
| 8725 | }): Promise<void> { |
| 8726 | assert( |
| 8727 | args.workspaceId.length > 0, |
| 8728 | "handleSuccessfulWorkflowProposePlan: workspaceId must be non-empty" |
| 8729 | ); |
| 8730 | assert( |
| 8731 | args.proposePlanResult.planPath.length > 0, |
| 8732 | "handleSuccessfulWorkflowProposePlan: planPath must be non-empty" |
| 8733 | ); |
| 8734 | |
| 8735 | if (args.entry.workspace.workflowTask?.outputSchema !== undefined) { |
| 8736 | const error = new Error( |
| 8737 | "Workflow plan agents return { reportMarkdown, planFilePath }; do not provide schema/outputSchema." |
| 8738 | ); |
| 8739 | await this.editWorkspaceEntry( |
| 8740 | args.workspaceId, |
| 8741 | (workspace) => { |
| 8742 | workspace.taskStatus = "interrupted"; |
| 8743 | workspace.taskLaunchError = error.message; |
| 8744 | }, |
| 8745 | { allowMissing: true } |
| 8746 | ); |
| 8747 | this.rejectWaiters(args.workspaceId, error); |
| 8748 | await this.emitWorkspaceMetadata(args.workspaceId); |
| 8749 | return; |
| 8750 | } |
| 8751 | |
| 8752 | let planSummary: { content: string; path: string } | null = null; |
| 8753 | try { |
| 8754 | const info = await this.workspaceService.getInfo(args.workspaceId); |
| 8755 | if (!info) { |
| 8756 | log.error("Workflow plan completion could not read workspace metadata", { |
| 8757 | workspaceId: args.workspaceId, |
| 8758 | }); |
| 8759 | } else { |
| 8760 | const runtime = createRuntimeForWorkspace(info); |
| 8761 | const planResult = await readPlanFile( |
| 8762 | runtime, |
| 8763 | info.name, |
| 8764 | info.projectName, |
| 8765 | args.workspaceId |
| 8766 | ); |
| 8767 | if (planResult.exists && planResult.content.trim().length > 0) { |
| 8768 | if (planResult.path !== args.proposePlanResult.planPath) { |
| 8769 | log.debug("Workflow plan completion using canonical plan file path", { |
| 8770 | workspaceId: args.workspaceId, |
| 8771 | proposedPlanPath: args.proposePlanResult.planPath, |
| 8772 | canonicalPlanPath: planResult.path, |
| 8773 | }); |
| 8774 | } |
| 8775 | planSummary = { content: planResult.content, path: planResult.path }; |
| 8776 | } else { |
| 8777 | log.error("Workflow plan completion did not find non-empty plan file content", { |
| 8778 | workspaceId: args.workspaceId, |
no test coverage detected