(projectRoot, options = {})
| 283 | } |
| 284 | |
| 285 | function assessStack(projectRoot, options = {}) { |
| 286 | const root = path.resolve(projectRoot || process.cwd()); |
| 287 | const reports = annotateCurrentHeads(root, options.reports || readReadinessReports(root), options); |
| 288 | const ordered = orderReports(root, reports, options); |
| 289 | const blocked = ordered |
| 290 | .map((report) => ({ report, reasons: blockerReasons(report) })) |
| 291 | .filter((entry) => entry.reasons.length > 0); |
| 292 | const status = statusForStack(ordered, blocked); |
| 293 | const stack = { |
| 294 | generatedAt: new Date().toISOString(), |
| 295 | projectRoot: root, |
| 296 | status, |
| 297 | ready: status === 'approval-needed', |
| 298 | reports: ordered, |
| 299 | blocked, |
| 300 | nextAction: buildNextAction(status, ordered), |
| 301 | }; |
| 302 | stack.postApprovalRunbook = buildPostApprovalRunbook(status, ordered); |
| 303 | stack.approvalCapsule = buildStackApprovalCapsule(root, stack); |
| 304 | if (stack.approvalCapsule && options.writeReport !== false && options.writeApprovalCapsule !== false) { |
| 305 | writeApprovalCapsule(root, stack.approvalCapsule); |
| 306 | } |
| 307 | stack.reportPath = options.writeReport === false ? null : writeStackPlan(root, stack); |
| 308 | return stack; |
| 309 | } |
| 310 | |
| 311 | function renderStackPlan(stack) { |
| 312 | const lines = [ |
no test coverage detected