@flanksource/clicky-ui 0.3.59 → 0.3.60
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.
- package/NOTICE.md +58 -0
- package/dist/data/Clicky.cjs +2 -1
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.d.ts +2 -0
- package/dist/data/Clicky.d.ts.map +1 -1
- package/dist/data/Clicky.js +2 -1
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/PromptBanner.model.cjs +10 -0
- package/dist/data/PromptBanner.model.cjs.map +1 -1
- package/dist/data/PromptBanner.model.d.ts +2 -0
- package/dist/data/PromptBanner.model.d.ts.map +1 -1
- package/dist/data/PromptBanner.model.js +10 -1
- package/dist/data/PromptBanner.model.js.map +1 -1
- package/dist/data/PromptDialog.cjs +16 -49
- package/dist/data/PromptDialog.cjs.map +1 -1
- package/dist/data/PromptDialog.d.ts +7 -1
- package/dist/data/PromptDialog.d.ts.map +1 -1
- package/dist/data/PromptDialog.js +17 -50
- package/dist/data/PromptDialog.js.map +1 -1
- package/dist/data/PromptForm.cjs +79 -0
- package/dist/data/PromptForm.cjs.map +1 -0
- package/dist/data/PromptForm.d.ts +26 -0
- package/dist/data/PromptForm.d.ts.map +1 -0
- package/dist/data/PromptForm.js +79 -0
- package/dist/data/PromptForm.js.map +1 -0
- package/dist/data/PromptIndicator.cjs +82 -0
- package/dist/data/PromptIndicator.cjs.map +1 -0
- package/dist/data/PromptIndicator.d.ts +19 -0
- package/dist/data/PromptIndicator.d.ts.map +1 -0
- package/dist/data/PromptIndicator.js +82 -0
- package/dist/data/PromptIndicator.js.map +1 -0
- package/dist/data/PromptList.cjs +67 -0
- package/dist/data/PromptList.cjs.map +1 -0
- package/dist/data/PromptList.d.ts +13 -0
- package/dist/data/PromptList.d.ts.map +1 -0
- package/dist/data/PromptList.js +67 -0
- package/dist/data/PromptList.js.map +1 -0
- package/dist/data/git/GitChangeList.cjs +11 -4
- package/dist/data/git/GitChangeList.cjs.map +1 -1
- package/dist/data/git/GitChangeList.d.ts +2 -35
- package/dist/data/git/GitChangeList.d.ts.map +1 -1
- package/dist/data/git/GitChangeList.js +11 -4
- package/dist/data/git/GitChangeList.js.map +1 -1
- package/dist/data/git/GitLink.cjs +13 -0
- package/dist/data/git/GitLink.cjs.map +1 -0
- package/dist/data/git/GitLink.d.ts +8 -0
- package/dist/data/git/GitLink.d.ts.map +1 -0
- package/dist/data/git/GitLink.js +13 -0
- package/dist/data/git/GitLink.js.map +1 -0
- package/dist/data/git/git-links.cjs +54 -0
- package/dist/data/git/git-links.cjs.map +1 -0
- package/dist/data/git/git-links.d.ts +4 -0
- package/dist/data/git/git-links.d.ts.map +1 -0
- package/dist/data/git/git-links.js +53 -0
- package/dist/data/git/git-links.js.map +1 -0
- package/dist/data/git/index.d.ts +3 -0
- package/dist/data/git/index.d.ts.map +1 -1
- package/dist/data/git/types.d.ts +54 -0
- package/dist/data/git/types.d.ts.map +1 -0
- package/dist/data/test-runner/MatrixMarks.cjs +4 -3
- package/dist/data/test-runner/MatrixMarks.cjs.map +1 -1
- package/dist/data/test-runner/MatrixMarks.d.ts +7 -4
- package/dist/data/test-runner/MatrixMarks.d.ts.map +1 -1
- package/dist/data/test-runner/MatrixMarks.js +4 -3
- package/dist/data/test-runner/MatrixMarks.js.map +1 -1
- package/dist/data/test-runner/TestRunSummary.cjs +1 -1
- package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
- package/dist/data/test-runner/TestRunSummary.js +1 -1
- package/dist/data/test-runner/TestRunSummary.js.map +1 -1
- package/dist/data/test-runner/TestTree.cjs +1 -1
- package/dist/data/test-runner/TestTree.cjs.map +1 -1
- package/dist/data/test-runner/TestTree.js +1 -1
- package/dist/data/test-runner/TestTree.js.map +1 -1
- package/dist/data/test-runner/TestTreeNode.cjs +2 -2
- package/dist/data/test-runner/TestTreeNode.cjs.map +1 -1
- package/dist/data/test-runner/TestTreeNode.js +2 -2
- package/dist/data/test-runner/TestTreeNode.js.map +1 -1
- package/dist/data/test-runner/adapter.cjs +7 -0
- package/dist/data/test-runner/adapter.cjs.map +1 -1
- package/dist/data/test-runner/adapter.d.ts +7 -0
- package/dist/data/test-runner/adapter.d.ts.map +1 -1
- package/dist/data/test-runner/adapter.js +7 -0
- package/dist/data/test-runner/adapter.js.map +1 -1
- package/dist/data/test-runner/index.d.ts +1 -1
- package/dist/data/test-runner/index.d.ts.map +1 -1
- package/dist/data/test-runner/marks.cjs +3 -3
- package/dist/data/test-runner/marks.cjs.map +1 -1
- package/dist/data/test-runner/marks.js +3 -3
- package/dist/data/test-runner/marks.js.map +1 -1
- package/dist/data/test-runner/matrix-marks.cjs +12 -3
- package/dist/data/test-runner/matrix-marks.cjs.map +1 -1
- package/dist/data/test-runner/matrix-marks.d.ts +13 -0
- package/dist/data/test-runner/matrix-marks.d.ts.map +1 -1
- package/dist/data/test-runner/matrix-marks.js +12 -3
- package/dist/data/test-runner/matrix-marks.js.map +1 -1
- package/dist/data/test-runner/status.cjs +1 -1
- package/dist/data/test-runner/status.cjs.map +1 -1
- package/dist/data/test-runner/status.js +1 -1
- package/dist/data/test-runner/status.js.map +1 -1
- package/dist/data/test-runner/types.d.ts +2 -0
- package/dist/data/test-runner/types.d.ts.map +1 -1
- package/dist/data/verification/adapterViews.cjs +3 -1
- package/dist/data/verification/adapterViews.cjs.map +1 -1
- package/dist/data/verification/adapterViews.d.ts +5 -2
- package/dist/data/verification/adapterViews.d.ts.map +1 -1
- package/dist/data/verification/adapterViews.js +4 -2
- package/dist/data/verification/adapterViews.js.map +1 -1
- package/dist/data/verification/adapters.cjs +28 -7
- package/dist/data/verification/adapters.cjs.map +1 -1
- package/dist/data/verification/adapters.d.ts +7 -1
- package/dist/data/verification/adapters.d.ts.map +1 -1
- package/dist/data/verification/adapters.js +28 -7
- package/dist/data/verification/adapters.js.map +1 -1
- package/dist/data/verification/stepKind.cjs +1 -0
- package/dist/data/verification/stepKind.cjs.map +1 -1
- package/dist/data/verification/stepKind.d.ts.map +1 -1
- package/dist/data/verification/stepKind.js +1 -0
- package/dist/data/verification/stepKind.js.map +1 -1
- package/dist/data/verification/stepKindViews.cjs +17 -0
- package/dist/data/verification/stepKindViews.cjs.map +1 -1
- package/dist/data/verification/stepKindViews.d.ts +4 -0
- package/dist/data/verification/stepKindViews.d.ts.map +1 -1
- package/dist/data/verification/stepKindViews.js +17 -1
- package/dist/data/verification/stepKindViews.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +114 -0
- package/dist/data.d.ts +3 -0
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +51 -1
- package/dist/git.cjs +6 -0
- package/dist/git.d.ts +4 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +3 -0
- package/dist/hooks/use-prompts.cjs +18 -11
- package/dist/hooks/use-prompts.cjs.map +1 -1
- package/dist/hooks/use-prompts.d.ts.map +1 -1
- package/dist/hooks/use-prompts.js +18 -11
- package/dist/hooks/use-prompts.js.map +1 -1
- package/dist/icons/components/UiApi.cjs +37 -0
- package/dist/icons/components/UiApi.cjs.map +1 -0
- package/dist/icons/components/UiApi.d.ts +9 -0
- package/dist/icons/components/UiApi.d.ts.map +1 -0
- package/dist/icons/components/UiApi.js +35 -0
- package/dist/icons/components/UiApi.js.map +1 -0
- package/dist/icons/components/UiApiBridge.cjs +38 -0
- package/dist/icons/components/UiApiBridge.cjs.map +1 -0
- package/dist/icons/components/UiApiBridge.d.ts +9 -0
- package/dist/icons/components/UiApiBridge.d.ts.map +1 -0
- package/dist/icons/components/UiApiBridge.js +36 -0
- package/dist/icons/components/UiApiBridge.js.map +1 -0
- package/dist/icons/components/UiApiGateway.cjs +33 -0
- package/dist/icons/components/UiApiGateway.cjs.map +1 -0
- package/dist/icons/components/UiApiGateway.d.ts +9 -0
- package/dist/icons/components/UiApiGateway.d.ts.map +1 -0
- package/dist/icons/components/UiApiGateway.js +31 -0
- package/dist/icons/components/UiApiGateway.js.map +1 -0
- package/dist/icons/components/UiApiRequest.cjs +37 -0
- package/dist/icons/components/UiApiRequest.cjs.map +1 -0
- package/dist/icons/components/UiApiRequest.d.ts +9 -0
- package/dist/icons/components/UiApiRequest.d.ts.map +1 -0
- package/dist/icons/components/UiApiRequest.js +35 -0
- package/dist/icons/components/UiApiRequest.js.map +1 -0
- package/dist/icons/components/UiArrowDecision.cjs +51 -0
- package/dist/icons/components/UiArrowDecision.cjs.map +1 -0
- package/dist/icons/components/UiArrowDecision.d.ts +15 -0
- package/dist/icons/components/UiArrowDecision.d.ts.map +1 -0
- package/dist/icons/components/UiArrowDecision.js +48 -0
- package/dist/icons/components/UiArrowDecision.js.map +1 -0
- package/dist/icons/components/UiArrowSquareIn.cjs +51 -0
- package/dist/icons/components/UiArrowSquareIn.cjs.map +1 -0
- package/dist/icons/components/UiArrowSquareIn.d.ts +15 -0
- package/dist/icons/components/UiArrowSquareIn.d.ts.map +1 -0
- package/dist/icons/components/UiArrowSquareIn.js +48 -0
- package/dist/icons/components/UiArrowSquareIn.js.map +1 -0
- package/dist/icons/components/UiBatchCheck.cjs +55 -0
- package/dist/icons/components/UiBatchCheck.cjs.map +1 -0
- package/dist/icons/components/UiBatchCheck.d.ts +15 -0
- package/dist/icons/components/UiBatchCheck.d.ts.map +1 -0
- package/dist/icons/components/UiBatchCheck.js +52 -0
- package/dist/icons/components/UiBatchCheck.js.map +1 -0
- package/dist/icons/components/UiBatchJob.cjs +39 -0
- package/dist/icons/components/UiBatchJob.cjs.map +1 -0
- package/dist/icons/components/UiBatchJob.d.ts +9 -0
- package/dist/icons/components/UiBatchJob.d.ts.map +1 -0
- package/dist/icons/components/UiBatchJob.js +37 -0
- package/dist/icons/components/UiBatchJob.js.map +1 -0
- package/dist/icons/components/UiBatchRequest.cjs +39 -0
- package/dist/icons/components/UiBatchRequest.cjs.map +1 -0
- package/dist/icons/components/UiBatchRequest.d.ts +9 -0
- package/dist/icons/components/UiBatchRequest.d.ts.map +1 -0
- package/dist/icons/components/UiBatchRequest.js +37 -0
- package/dist/icons/components/UiBatchRequest.js.map +1 -0
- package/dist/icons/components/UiBpmnConditional.cjs +29 -0
- package/dist/icons/components/UiBpmnConditional.cjs.map +1 -0
- package/dist/icons/components/UiBpmnConditional.d.ts +9 -0
- package/dist/icons/components/UiBpmnConditional.d.ts.map +1 -0
- package/dist/icons/components/UiBpmnConditional.js +27 -0
- package/dist/icons/components/UiBpmnConditional.js.map +1 -0
- package/dist/icons/components/UiBranchFlow.cjs +33 -0
- package/dist/icons/components/UiBranchFlow.cjs.map +1 -0
- package/dist/icons/components/UiBranchFlow.d.ts +9 -0
- package/dist/icons/components/UiBranchFlow.d.ts.map +1 -0
- package/dist/icons/components/UiBranchFlow.js +31 -0
- package/dist/icons/components/UiBranchFlow.js.map +1 -0
- package/dist/icons/components/UiClassicBatch.cjs +29 -0
- package/dist/icons/components/UiClassicBatch.cjs.map +1 -0
- package/dist/icons/components/UiClassicBatch.d.ts +9 -0
- package/dist/icons/components/UiClassicBatch.d.ts.map +1 -0
- package/dist/icons/components/UiClassicBatch.js +27 -0
- package/dist/icons/components/UiClassicBatch.js.map +1 -0
- package/dist/icons/components/UiCodeFile.cjs +29 -0
- package/dist/icons/components/UiCodeFile.cjs.map +1 -0
- package/dist/icons/components/UiCodeFile.d.ts +9 -0
- package/dist/icons/components/UiCodeFile.d.ts.map +1 -0
- package/dist/icons/components/UiCodeFile.js +27 -0
- package/dist/icons/components/UiCodeFile.js.map +1 -0
- package/dist/icons/components/UiColumnsLayout.cjs +29 -0
- package/dist/icons/components/UiColumnsLayout.cjs.map +1 -0
- package/dist/icons/components/UiColumnsLayout.d.ts +9 -0
- package/dist/icons/components/UiColumnsLayout.d.ts.map +1 -0
- package/dist/icons/components/UiColumnsLayout.js +27 -0
- package/dist/icons/components/UiColumnsLayout.js.map +1 -0
- package/dist/icons/components/UiCondition.cjs +37 -0
- package/dist/icons/components/UiCondition.cjs.map +1 -0
- package/dist/icons/components/UiCondition.d.ts +9 -0
- package/dist/icons/components/UiCondition.d.ts.map +1 -0
- package/dist/icons/components/UiCondition.js +35 -0
- package/dist/icons/components/UiCondition.js.map +1 -0
- package/dist/icons/components/UiConditions.cjs +29 -0
- package/dist/icons/components/UiConditions.cjs.map +1 -0
- package/dist/icons/components/UiConditions.d.ts +9 -0
- package/dist/icons/components/UiConditions.d.ts.map +1 -0
- package/dist/icons/components/UiConditions.js +27 -0
- package/dist/icons/components/UiConditions.js.map +1 -0
- package/dist/icons/components/UiDelayQueue.cjs +40 -0
- package/dist/icons/components/UiDelayQueue.cjs.map +1 -0
- package/dist/icons/components/UiDelayQueue.d.ts +9 -0
- package/dist/icons/components/UiDelayQueue.d.ts.map +1 -0
- package/dist/icons/components/UiDelayQueue.js +38 -0
- package/dist/icons/components/UiDelayQueue.js.map +1 -0
- package/dist/icons/components/UiDynamicForm.cjs +51 -0
- package/dist/icons/components/UiDynamicForm.cjs.map +1 -0
- package/dist/icons/components/UiDynamicForm.d.ts +15 -0
- package/dist/icons/components/UiDynamicForm.d.ts.map +1 -0
- package/dist/icons/components/UiDynamicForm.js +48 -0
- package/dist/icons/components/UiDynamicForm.js.map +1 -0
- package/dist/icons/components/UiFlowArrow.cjs +51 -0
- package/dist/icons/components/UiFlowArrow.cjs.map +1 -0
- package/dist/icons/components/UiFlowArrow.d.ts +15 -0
- package/dist/icons/components/UiFlowArrow.d.ts.map +1 -0
- package/dist/icons/components/UiFlowArrow.js +48 -0
- package/dist/icons/components/UiFlowArrow.js.map +1 -0
- package/dist/icons/components/UiFormFields.cjs +33 -0
- package/dist/icons/components/UiFormFields.cjs.map +1 -0
- package/dist/icons/components/UiFormFields.d.ts +9 -0
- package/dist/icons/components/UiFormFields.d.ts.map +1 -0
- package/dist/icons/components/UiFormFields.js +31 -0
- package/dist/icons/components/UiFormFields.js.map +1 -0
- package/dist/icons/components/UiFormStep.cjs +38 -0
- package/dist/icons/components/UiFormStep.cjs.map +1 -0
- package/dist/icons/components/UiFormStep.d.ts +9 -0
- package/dist/icons/components/UiFormStep.d.ts.map +1 -0
- package/dist/icons/components/UiFormStep.js +36 -0
- package/dist/icons/components/UiFormStep.js.map +1 -0
- package/dist/icons/components/UiGatewayApi.cjs +32 -0
- package/dist/icons/components/UiGatewayApi.cjs.map +1 -0
- package/dist/icons/components/UiGatewayApi.d.ts +9 -0
- package/dist/icons/components/UiGatewayApi.d.ts.map +1 -0
- package/dist/icons/components/UiGatewayApi.js +30 -0
- package/dist/icons/components/UiGatewayApi.js.map +1 -0
- package/dist/icons/components/UiImportArrow.cjs +29 -0
- package/dist/icons/components/UiImportArrow.cjs.map +1 -0
- package/dist/icons/components/UiImportArrow.d.ts +9 -0
- package/dist/icons/components/UiImportArrow.d.ts.map +1 -0
- package/dist/icons/components/UiImportArrow.js +27 -0
- package/dist/icons/components/UiImportArrow.js.map +1 -0
- package/dist/icons/components/UiInputField.cjs +33 -0
- package/dist/icons/components/UiInputField.cjs.map +1 -0
- package/dist/icons/components/UiInputField.d.ts +9 -0
- package/dist/icons/components/UiInputField.d.ts.map +1 -0
- package/dist/icons/components/UiInputField.js +31 -0
- package/dist/icons/components/UiInputField.js.map +1 -0
- package/dist/icons/components/UiInsertTable.cjs +29 -0
- package/dist/icons/components/UiInsertTable.cjs.map +1 -0
- package/dist/icons/components/UiInsertTable.d.ts +9 -0
- package/dist/icons/components/UiInsertTable.d.ts.map +1 -0
- package/dist/icons/components/UiInsertTable.js +27 -0
- package/dist/icons/components/UiInsertTable.js.map +1 -0
- package/dist/icons/components/UiLayoutTemplate.cjs +32 -0
- package/dist/icons/components/UiLayoutTemplate.cjs.map +1 -0
- package/dist/icons/components/UiLayoutTemplate.d.ts +9 -0
- package/dist/icons/components/UiLayoutTemplate.d.ts.map +1 -0
- package/dist/icons/components/UiLayoutTemplate.js +30 -0
- package/dist/icons/components/UiLayoutTemplate.js.map +1 -0
- package/dist/icons/components/UiLayoutWindow.cjs +56 -0
- package/dist/icons/components/UiLayoutWindow.cjs.map +1 -0
- package/dist/icons/components/UiLayoutWindow.d.ts +15 -0
- package/dist/icons/components/UiLayoutWindow.d.ts.map +1 -0
- package/dist/icons/components/UiLayoutWindow.js +53 -0
- package/dist/icons/components/UiLayoutWindow.js.map +1 -0
- package/dist/icons/components/UiListEnd.cjs +33 -0
- package/dist/icons/components/UiListEnd.cjs.map +1 -0
- package/dist/icons/components/UiListEnd.d.ts +9 -0
- package/dist/icons/components/UiListEnd.d.ts.map +1 -0
- package/dist/icons/components/UiListEnd.js +31 -0
- package/dist/icons/components/UiListEnd.js.map +1 -0
- package/dist/icons/components/UiListEndLine.cjs +51 -0
- package/dist/icons/components/UiListEndLine.cjs.map +1 -0
- package/dist/icons/components/UiListEndLine.d.ts +15 -0
- package/dist/icons/components/UiListEndLine.d.ts.map +1 -0
- package/dist/icons/components/UiListEndLine.js +48 -0
- package/dist/icons/components/UiListEndLine.js.map +1 -0
- package/dist/icons/components/UiListNumbers.cjs +51 -0
- package/dist/icons/components/UiListNumbers.cjs.map +1 -0
- package/dist/icons/components/UiListNumbers.d.ts +15 -0
- package/dist/icons/components/UiListNumbers.d.ts.map +1 -0
- package/dist/icons/components/UiListNumbers.js +48 -0
- package/dist/icons/components/UiListNumbers.js.map +1 -0
- package/dist/icons/components/UiLowPriority.cjs +29 -0
- package/dist/icons/components/UiLowPriority.cjs.map +1 -0
- package/dist/icons/components/UiLowPriority.d.ts +9 -0
- package/dist/icons/components/UiLowPriority.d.ts.map +1 -0
- package/dist/icons/components/UiLowPriority.js +27 -0
- package/dist/icons/components/UiLowPriority.js.map +1 -0
- package/dist/icons/components/UiMergeQueue.cjs +38 -0
- package/dist/icons/components/UiMergeQueue.cjs.map +1 -0
- package/dist/icons/components/UiMergeQueue.d.ts +9 -0
- package/dist/icons/components/UiMergeQueue.d.ts.map +1 -0
- package/dist/icons/components/UiMergeQueue.js +36 -0
- package/dist/icons/components/UiMergeQueue.js.map +1 -0
- package/dist/icons/components/UiPipelineStage.cjs +33 -0
- package/dist/icons/components/UiPipelineStage.cjs.map +1 -0
- package/dist/icons/components/UiPipelineStage.d.ts +9 -0
- package/dist/icons/components/UiPipelineStage.d.ts.map +1 -0
- package/dist/icons/components/UiPipelineStage.js +31 -0
- package/dist/icons/components/UiPipelineStage.js.map +1 -0
- package/dist/icons/components/UiPlaylistRemove.cjs +29 -0
- package/dist/icons/components/UiPlaylistRemove.cjs.map +1 -0
- package/dist/icons/components/UiPlaylistRemove.d.ts +9 -0
- package/dist/icons/components/UiPlaylistRemove.d.ts.map +1 -0
- package/dist/icons/components/UiPlaylistRemove.js +27 -0
- package/dist/icons/components/UiPlaylistRemove.js.map +1 -0
- package/dist/icons/components/UiReportForms.cjs +51 -0
- package/dist/icons/components/UiReportForms.cjs.map +1 -0
- package/dist/icons/components/UiReportForms.d.ts +15 -0
- package/dist/icons/components/UiReportForms.d.ts.map +1 -0
- package/dist/icons/components/UiReportForms.js +48 -0
- package/dist/icons/components/UiReportForms.js.map +1 -0
- package/dist/icons/components/UiScreenTemplate.cjs +29 -0
- package/dist/icons/components/UiScreenTemplate.cjs.map +1 -0
- package/dist/icons/components/UiScreenTemplate.d.ts +9 -0
- package/dist/icons/components/UiScreenTemplate.d.ts.map +1 -0
- package/dist/icons/components/UiScreenTemplate.js +27 -0
- package/dist/icons/components/UiScreenTemplate.js.map +1 -0
- package/dist/icons/components/UiServices.cjs +29 -0
- package/dist/icons/components/UiServices.cjs.map +1 -0
- package/dist/icons/components/UiServices.d.ts +9 -0
- package/dist/icons/components/UiServices.d.ts.map +1 -0
- package/dist/icons/components/UiServices.js +27 -0
- package/dist/icons/components/UiServices.js.map +1 -0
- package/dist/icons/components/UiSkipCircle.cjs +51 -0
- package/dist/icons/components/UiSkipCircle.cjs.map +1 -0
- package/dist/icons/components/UiSkipCircle.d.ts +15 -0
- package/dist/icons/components/UiSkipCircle.d.ts.map +1 -0
- package/dist/icons/components/UiSkipCircle.js +48 -0
- package/dist/icons/components/UiSkipCircle.js.map +1 -0
- package/dist/icons/components/UiTaskBatch.cjs +33 -0
- package/dist/icons/components/UiTaskBatch.cjs.map +1 -0
- package/dist/icons/components/UiTaskBatch.d.ts +9 -0
- package/dist/icons/components/UiTaskBatch.d.ts.map +1 -0
- package/dist/icons/components/UiTaskBatch.js +31 -0
- package/dist/icons/components/UiTaskBatch.js.map +1 -0
- package/dist/icons/components/UiTodoList.cjs +29 -0
- package/dist/icons/components/UiTodoList.cjs.map +1 -0
- package/dist/icons/components/UiTodoList.d.ts +9 -0
- package/dist/icons/components/UiTodoList.d.ts.map +1 -0
- package/dist/icons/components/UiTodoList.js +27 -0
- package/dist/icons/components/UiTodoList.js.map +1 -0
- package/dist/icons/components/UiTrayArrowDown.cjs +51 -0
- package/dist/icons/components/UiTrayArrowDown.cjs.map +1 -0
- package/dist/icons/components/UiTrayArrowDown.d.ts +15 -0
- package/dist/icons/components/UiTrayArrowDown.d.ts.map +1 -0
- package/dist/icons/components/UiTrayArrowDown.js +48 -0
- package/dist/icons/components/UiTrayArrowDown.js.map +1 -0
- package/dist/icons/components/UiVault.cjs +51 -0
- package/dist/icons/components/UiVault.cjs.map +1 -0
- package/dist/icons/components/UiVault.d.ts +15 -0
- package/dist/icons/components/UiVault.d.ts.map +1 -0
- package/dist/icons/components/UiVault.js +48 -0
- package/dist/icons/components/UiVault.js.map +1 -0
- package/dist/icons/components/UiWebServiceDefinition.cjs +39 -0
- package/dist/icons/components/UiWebServiceDefinition.cjs.map +1 -0
- package/dist/icons/components/UiWebServiceDefinition.d.ts +9 -0
- package/dist/icons/components/UiWebServiceDefinition.d.ts.map +1 -0
- package/dist/icons/components/UiWebServiceDefinition.js +37 -0
- package/dist/icons/components/UiWebServiceDefinition.js.map +1 -0
- package/dist/icons/components/UiWebhook.cjs +29 -0
- package/dist/icons/components/UiWebhook.cjs.map +1 -0
- package/dist/icons/components/UiWebhook.d.ts +9 -0
- package/dist/icons/components/UiWebhook.d.ts.map +1 -0
- package/dist/icons/components/UiWebhook.js +27 -0
- package/dist/icons/components/UiWebhook.js.map +1 -0
- package/dist/icons/components/UiWebhookLine.cjs +51 -0
- package/dist/icons/components/UiWebhookLine.cjs.map +1 -0
- package/dist/icons/components/UiWebhookLine.d.ts +15 -0
- package/dist/icons/components/UiWebhookLine.d.ts.map +1 -0
- package/dist/icons/components/UiWebhookLine.js +48 -0
- package/dist/icons/components/UiWebhookLine.js.map +1 -0
- package/dist/icons/index.d.ts +58 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/registry.cjs +90 -0
- package/dist/icons/registry.cjs.map +1 -1
- package/dist/icons/registry.d.ts.map +1 -1
- package/dist/icons/registry.js +90 -0
- package/dist/icons/registry.js.map +1 -1
- package/dist/icons.cjs +103 -0
- package/dist/icons.js +46 -1
- package/dist/index.cjs +114 -0
- package/dist/index.js +51 -1
- package/dist/overlay/DropdownMenu.cjs +17 -14
- package/dist/overlay/DropdownMenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenu.d.ts +1 -0
- package/dist/overlay/DropdownMenu.d.ts.map +1 -1
- package/dist/overlay/DropdownMenu.js +18 -15
- package/dist/overlay/DropdownMenu.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapters.cjs","names":["ChecklistDetail","hasStepDetail","outcomeFor","readStepDetail","readStepSource","stepSourceCopy","stepKindCopy","UiTerminal","createTestRunnerRegistry","FixtureDetail","verifyNodeTest","StepOutputs"],"sources":["../../../src/data/verification/adapters.tsx"],"sourcesContent":["// Domain node adapters for VerificationResults: a checklist adapter for the\n// synthesized \"Acceptance criteria\" node and its items, and a fixture/CEL\n// adapter for the failing-step detail. Rendering lives in adapterViews.tsx —\n// split out so this file's only exports are the registry (react/only-export-\n// components forbids mixing component declarations with plain exports).\n\nimport type { ReactNode } from \"react\";\nimport { ChecklistDetail, FixtureDetail } from \"./adapterViews\";\nimport { StepOutputs } from \"./stepKindViews\";\nimport { verifyNodeTest } from \"./verifyReportTests\";\nimport { UiTerminal } from \"../../icons\";\nimport { hasStepDetail, readStepDetail, stepKindCopy, type WaitDetail } from \"./stepKind\";\nimport { readStepSource, stepSourceCopy } from \"./stepSource\";\nimport {\n createTestRunnerRegistry,\n outcomeFor,\n type BriefSection,\n type CopySections,\n type FixtureContext,\n type Test,\n type TestNodeAdapter,\n type TestNodeAdapterRegistry,\n type TestOutcome,\n type TestSummary,\n} from \"../test-runner\";\n\nfunction isChecklistNode(node: Test): boolean {\n return node.framework === \"checklist\";\n}\n\nfunction checklistMark(item: Test): string {\n if (item.failed) return \"[ ]\";\n if (item.passed) return \"[x]\";\n return \"[?]\";\n}\n\n/** `- [x]/[ ]/[?] criterion — reason` for each item, or the leaf itself. */\nfunction checklistCopy(node: Test): CopySections {\n const items = node.children && node.children.length > 0 ? node.children : [node];\n const lines = items.map(\n (item) => `- ${checklistMark(item)} ${item.name}${item.message ? ` — ${item.message}` : \"\"}`,\n );\n return { brief: [{ title: \"Criteria\", body: lines.join(\"\\n\") }] };\n}\n\nconst checklistAdapter: TestNodeAdapter = {\n id: \"verification-checklist\",\n match: isChecklistNode,\n renderDetail: ({ node }) => <ChecklistDetail node={node} />,\n copy: ({ node }) => checklistCopy(node),\n};\n\n// A typed step kind (services, todo, …) may report no command or CEL context at\n// all, so `detail.step` claims the node as well. A \"fixture\" leaf is a step whose\n// result has not arrived yet (a live or background step): it carries only the\n// execution node, which FixtureDetail renders as a header. Fixture parents\n// (markdown tables, runner steps) have children and stay with the default body.\nfunction isFixtureNode(node: Test): boolean {\n if (node.context !== undefined || hasStepDetail(node.detail)) return true;\n return node.framework === \"fixture\" && (node.children?.length ?? 0) === 0;\n}\n\n// ── Copy sections for fixture steps (exec / query / table / test / lint) ───\n\nfunction readCelTrace(detail: unknown): string | undefined {\n if (detail && typeof detail === \"object\" && !Array.isArray(detail)) {\n const value = (detail as Record<string, unknown>).cel_trace;\n if (typeof value === \"string\" && value.length > 0) return value;\n }\n return undefined;\n}\n\n// Mirrors CelDetails: without a CEL gate, a command step's `actual` is the whole\n// command result object, already covered by the Command section and output.\nfunction comparisonValue(hasCelGate: boolean, value: unknown): unknown {\n if (value === undefined) return undefined;\n if (hasCelGate) return value;\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) return undefined;\n return value;\n}\n\nfunction formatValue(value: unknown): string {\n return typeof value === \"string\" ? value : JSON.stringify(value, null, 2);\n}\n\nfunction commandSection(node: Test, context: FixtureContext | undefined): BriefSection[] {\n const command = context?.command ?? node.command;\n if (!command) return [];\n const cwd = context?.cwd ?? node.work_dir;\n const exit = context?.exit_code;\n const lines = [`$ ${command}`, cwd && `cwd: ${cwd}`, exit !== undefined && `exit: ${exit}`];\n return [{ title: \"Command\", lang: \"sh\", body: lines.filter(Boolean).join(\"\\n\") }];\n}\n\nfunction assertionSection(node: Test, context: FixtureContext | undefined): BriefSection[] {\n const expression = context?.cel_expression;\n const trace = readCelTrace(node.detail);\n const hasCelGate = !!(expression || trace);\n const vars = context?.cel_vars ?? {};\n const expected = comparisonValue(hasCelGate, context?.expected);\n const actual = comparisonValue(hasCelGate, context?.actual);\n const lines = [\n expression && `expression: ${expression}`,\n trace && `trace:\\n${trace}`,\n Object.keys(vars).length > 0 && `vars: ${formatValue(vars)}`,\n expected !== undefined && `expected: ${formatValue(expected)}`,\n actual !== undefined && `actual: ${formatValue(actual)}`,\n ].filter(Boolean);\n return lines.length > 0 ? [{ title: \"Assertion\", body: lines.join(\"\\n\") }] : [];\n}\n\nconst OUTCOME_GLYPH: Record<TestOutcome, string> = {\n passed: \"✓\",\n failed: \"✗\",\n errored: \"✗\",\n timedout: \"⏱\",\n warned: \"!\",\n aborted: \"■\",\n skipped: \"-\",\n pending: \"○\",\n running: \"…\",\n};\n\nfunction childLine(child: Test): string {\n const outcome = outcomeFor(child);\n const exit = (child.context as FixtureContext | undefined)?.exit_code;\n const reason = child.message ?? (exit ? `exit ${exit}` : undefined);\n return `${outcome ? OUTCOME_GLYPH[outcome] : \"·\"} ${child.name}${reason ? ` — ${reason}` : \"\"}`;\n}\n\nfunction summaryLine(summary: TestSummary): string {\n const counts: [number | undefined, string][] = [\n [summary.Passed, \"passed\"],\n [summary.Failed, \"failed\"],\n [summary.Warned, \"warned\"],\n [summary.Timedout, \"timed out\"],\n [summary.Skipped, \"skipped\"],\n [summary.Pending, \"pending\"],\n [summary.Running, \"running\"],\n ];\n const parts = counts.filter(([n]) => !!n).map(([n, label]) => `${n} ${label}`);\n return [`${summary.Total} total`, ...parts].join(\" · \");\n}\n\nfunction resultsSection(node: Test): BriefSection[] {\n const lines = [\n ...(node.summary ? [summaryLine(node.summary)] : []),\n ...(node.children ?? []).map(childLine),\n ];\n return lines.length > 0 ? [{ title: \"Results\", body: lines.join(\"\\n\") }] : [];\n}\n\n/** Command, CEL assertion and per-child verdicts for a fixture step or its parent. */\nfunction fixtureCopy(node: Test): CopySections {\n const context = node.context as FixtureContext | undefined;\n const command = context?.command ?? node.command;\n const stepDetail = readStepDetail(node.detail);\n const source = readStepSource(node.detail);\n return {\n brief: [\n ...commandSection(node, context),\n ...assertionSection(node, context),\n ...(source.kind === \"source\" ? stepSourceCopy(source.source) : []),\n ...(stepDetail.kind === \"step\" ? stepKindCopy(stepDetail.step) : []),\n ...resultsSection(node),\n ],\n items: command ? [{ label: \"Copy command\", icon: UiTerminal, value: command }] : [],\n };\n}\n\n// gavel's FixtureResult.Type values plus \"fixture\" (a markdown table of rows)\n// and the typed step kinds. Table and runner-step parents carry no `context`,\n// so the fixture adapter never claims them; this copy-only adapter gives them\n// the same sections. \"playwright\" is also a test framework, so it counts as a\n// step only when the node carries `detail.step`.\nconst FIXTURE_STEP_FRAMEWORKS = new Set([\n \"exec\",\n \"query\",\n \"fixture\",\n \"test\",\n \"lint\",\n \"verify\",\n \"services\",\n \"todo\",\n \"todo_prompt\",\n \"ai\",\n \"browser\",\n \"playwright\",\n \"agent-browser\",\n]);\n\nfunction isFixtureStepNode(node: Test): boolean {\n const framework = node.framework ?? \"\";\n if (framework === \"playwright\") return hasStepDetail(node.detail);\n return FIXTURE_STEP_FRAMEWORKS.has(framework);\n}\n\nconst fixtureStepCopyAdapter: TestNodeAdapter = {\n id: \"verification-step-copy\",\n match: isFixtureStepNode,\n copy: ({ node }) => fixtureCopy(node),\n};\n\n/** Default node adapters for VerificationResults: checklist items and\n * fixture/CEL steps. Registration order matters only when a node could match\n * both — a checklist node never carries a `context`, so the two never race. */\nexport type VerificationAdapterOptions = {\n /** Override the wait section while retaining the fixture's other detail sections. */\n renderWait?: (wait: WaitDetail) => ReactNode;\n};\n\nexport function verificationAdapters(options: VerificationAdapterOptions = {}): TestNodeAdapterRegistry {\n const fixtureAdapter: TestNodeAdapter = {\n id: \"verification-fixture\",\n match: isFixtureNode,\n renderDetail: ({ node }) => <FixtureDetail node={node} {...options} />,\n detailAttempts: ({ node }) => {\n const detail = readStepDetail(node.detail);\n if (detail.kind !== \"step\") return [];\n return detail.step.attempts.map((attempt) => ({\n id: attempt.attempt, status: attempt.status,\n ...(attempt.durationMs !== undefined ? { durationMs: attempt.durationMs } : {}),\n node: attempt.result ? verifyNodeTest(attempt.result) : {\n name: node.name, message: `Attempt ${attempt.attempt}: execution evidence was not stored in this report.`,\n detail: { step: detail.step.step },\n },\n }));\n },\n detailTabs: ({ node }) => {\n const detail = readStepDetail(node.detail);\n if (detail.kind !== \"step\" || detail.step.outputs === undefined) return [];\n return [{ id: \"outputs\", label: \"Outputs\", render: () => <StepOutputs outputs={detail.step.outputs} /> }];\n },\n copy: ({ node }) => fixtureCopy(node),\n };\n return createTestRunnerRegistry([checklistAdapter, fixtureAdapter, fixtureStepCopyAdapter]);\n}\n"],"mappings":";;;;;;;;;;AA0BA,SAAS,gBAAgB,MAAqB;CAC5C,OAAO,KAAK,cAAc;AAC5B;AAEA,SAAS,cAAc,MAAoB;CACzC,IAAI,KAAK,QAAQ,OAAO;CACxB,IAAI,KAAK,QAAQ,OAAO;CACxB,OAAO;AACT;;AAGA,SAAS,cAAc,MAA0B;CAK/C,OAAO,EAAE,OAAO,CAAC;EAAE,OAAO;EAAY,OAJxB,KAAK,YAAY,KAAK,SAAS,SAAS,IAAI,KAAK,WAAW,CAAC,IAAI,EAAA,CAC3D,KACjB,SAAS,KAAK,cAAc,IAAI,EAAE,GAAG,KAAK,OAAO,KAAK,UAAU,MAAM,KAAK,YAAY,IAE9C,CAAA,CAAM,KAAK,IAAI;CAAE,CAAC,EAAE;AAClE;AAEA,IAAM,mBAAoC;CACxC,IAAI;CACJ,OAAO;CACP,eAAe,EAAE,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAACA,qBAAAA,iBAAD,EAAuB,KAAO,CAAA;CAC1D,OAAO,EAAE,WAAW,cAAc,IAAI;AACxC;AAOA,SAAS,cAAc,MAAqB;CAC1C,IAAI,KAAK,YAAY,KAAA,KAAaC,iBAAAA,cAAc,KAAK,MAAM,GAAG,OAAO;CACrE,OAAO,KAAK,cAAc,cAAc,KAAK,UAAU,UAAU,OAAO;AAC1E;AAIA,SAAS,aAAa,QAAqC;CACzD,IAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,GAAG;EAClE,MAAM,QAAS,OAAmC;EAClD,IAAI,OAAO,UAAU,YAAY,MAAM,SAAS,GAAG,OAAO;CAC5D;AAEF;AAIA,SAAS,gBAAgB,YAAqB,OAAyB;CACrE,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,IAAI,YAAY,OAAO;CACvB,IAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAA;CACjF,OAAO;AACT;AAEA,SAAS,YAAY,OAAwB;CAC3C,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,OAAO,MAAM,CAAC;AAC1E;AAEA,SAAS,eAAe,MAAY,SAAqD;CACvF,MAAM,UAAU,SAAS,WAAW,KAAK;CACzC,IAAI,CAAC,SAAS,OAAO,CAAC;CACtB,MAAM,MAAM,SAAS,OAAO,KAAK;CACjC,MAAM,OAAO,SAAS;CAEtB,OAAO,CAAC;EAAE,OAAO;EAAW,MAAM;EAAM,MAAM;GAD/B,KAAK;GAAW,OAAO,QAAQ;GAAO,SAAS,KAAA,KAAa,SAAS;EACtC,CAAA,CAAM,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI;CAAE,CAAC;AAClF;AAEA,SAAS,iBAAiB,MAAY,SAAqD;CACzF,MAAM,aAAa,SAAS;CAC5B,MAAM,QAAQ,aAAa,KAAK,MAAM;CACtC,MAAM,aAAa,CAAC,EAAE,cAAc;CACpC,MAAM,OAAO,SAAS,YAAY,CAAC;CACnC,MAAM,WAAW,gBAAgB,YAAY,SAAS,QAAQ;CAC9D,MAAM,SAAS,gBAAgB,YAAY,SAAS,MAAM;CAC1D,MAAM,QAAQ;EACZ,cAAc,eAAe;EAC7B,SAAS,WAAW;EACpB,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,YAAY,IAAI;EACzD,aAAa,KAAA,KAAa,aAAa,YAAY,QAAQ;EAC3D,WAAW,KAAA,KAAa,WAAW,YAAY,MAAM;CACvD,CAAC,CAAC,OAAO,OAAO;CAChB,OAAO,MAAM,SAAS,IAAI,CAAC;EAAE,OAAO;EAAa,MAAM,MAAM,KAAK,IAAI;CAAE,CAAC,IAAI,CAAC;AAChF;AAEA,IAAM,gBAA6C;CACjD,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,UAAU;CACV,QAAQ;CACR,SAAS;CACT,SAAS;CACT,SAAS;CACT,SAAS;AACX;AAEA,SAAS,UAAU,OAAqB;CACtC,MAAM,UAAUC,eAAAA,WAAW,KAAK;CAChC,MAAM,OAAQ,MAAM,SAAwC;CAC5D,MAAM,SAAS,MAAM,YAAY,OAAO,QAAQ,SAAS,KAAA;CACzD,OAAO,GAAG,UAAU,cAAc,WAAW,IAAI,GAAG,MAAM,OAAO,SAAS,MAAM,WAAW;AAC7F;AAEA,SAAS,YAAY,SAA8B;CAUjD,MAAM,QAAQ;EARZ,CAAC,QAAQ,QAAQ,QAAQ;EACzB,CAAC,QAAQ,QAAQ,QAAQ;EACzB,CAAC,QAAQ,QAAQ,QAAQ;EACzB,CAAC,QAAQ,UAAU,WAAW;EAC9B,CAAC,QAAQ,SAAS,SAAS;EAC3B,CAAC,QAAQ,SAAS,SAAS;EAC3B,CAAC,QAAQ,SAAS,SAAS;CAEf,CAAA,CAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,WAAW,GAAG,EAAE,GAAG,OAAO;CAC7E,OAAO,CAAC,GAAG,QAAQ,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,KAAK,KAAK;AACxD;AAEA,SAAS,eAAe,MAA4B;CAClD,MAAM,QAAQ,CACZ,GAAI,KAAK,UAAU,CAAC,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAClD,IAAI,KAAK,YAAY,CAAC,EAAA,CAAG,IAAI,SAAS,CACxC;CACA,OAAO,MAAM,SAAS,IAAI,CAAC;EAAE,OAAO;EAAW,MAAM,MAAM,KAAK,IAAI;CAAE,CAAC,IAAI,CAAC;AAC9E;;AAGA,SAAS,YAAY,MAA0B;CAC7C,MAAM,UAAU,KAAK;CACrB,MAAM,UAAU,SAAS,WAAW,KAAK;CACzC,MAAM,aAAaC,iBAAAA,eAAe,KAAK,MAAM;CAC7C,MAAM,SAASC,mBAAAA,eAAe,KAAK,MAAM;CACzC,OAAO;EACL,OAAO;GACL,GAAG,eAAe,MAAM,OAAO;GAC/B,GAAG,iBAAiB,MAAM,OAAO;GACjC,GAAI,OAAO,SAAS,WAAWC,mBAAAA,eAAe,OAAO,MAAM,IAAI,CAAC;GAChE,GAAI,WAAW,SAAS,SAASC,iBAAAA,aAAa,WAAW,IAAI,IAAI,CAAC;GAClE,GAAG,eAAe,IAAI;EACxB;EACA,OAAO,UAAU,CAAC;GAAE,OAAO;GAAgB,MAAMC,mBAAAA;GAAY,OAAO;EAAQ,CAAC,IAAI,CAAC;CACpF;AACF;AAOA,IAAM,0CAA0B,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,kBAAkB,MAAqB;CAC9C,MAAM,YAAY,KAAK,aAAa;CACpC,IAAI,cAAc,cAAc,OAAON,iBAAAA,cAAc,KAAK,MAAM;CAChE,OAAO,wBAAwB,IAAI,SAAS;AAC9C;AAEA,IAAM,yBAA0C;CAC9C,IAAI;CACJ,OAAO;CACP,OAAO,EAAE,WAAW,YAAY,IAAI;AACtC;AAUA,SAAgB,qBAAqB,UAAsC,CAAC,GAA4B;CAwBtG,OAAOO,gBAAAA,yBAAyB;EAAC;EAAkB;GAtBjD,IAAI;GACJ,OAAO;GACP,eAAe,EAAE,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAACC,qBAAAA,eAAD;IAAqB;IAAM,GAAI;GAAU,CAAA;GACrE,iBAAiB,EAAE,WAAW;IAC5B,MAAM,SAASN,iBAAAA,eAAe,KAAK,MAAM;IACzC,IAAI,OAAO,SAAS,QAAQ,OAAO,CAAC;IACpC,OAAO,OAAO,KAAK,SAAS,KAAK,aAAa;KAC5C,IAAI,QAAQ;KAAS,QAAQ,QAAQ;KACrC,GAAI,QAAQ,eAAe,KAAA,IAAY,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;KAC7E,MAAM,QAAQ,SAASO,0BAAAA,eAAe,QAAQ,MAAM,IAAI;MACtD,MAAM,KAAK;MAAM,SAAS,WAAW,QAAQ,QAAQ;MACrD,QAAQ,EAAE,MAAM,OAAO,KAAK,KAAK;KACnC;IACF,EAAE;GACJ;GACA,aAAa,EAAE,WAAW;IACxB,MAAM,SAASP,iBAAAA,eAAe,KAAK,MAAM;IACzC,IAAI,OAAO,SAAS,UAAU,OAAO,KAAK,YAAY,KAAA,GAAW,OAAO,CAAC;IACzE,OAAO,CAAC;KAAE,IAAI;KAAW,OAAO;KAAW,cAAc,iBAAA,GAAA,kBAAA,IAAA,CAACQ,sBAAAA,aAAD,EAAa,SAAS,OAAO,KAAK,QAAU,CAAA;IAAE,CAAC;GAC1G;GACA,OAAO,EAAE,WAAW,YAAY,IAAI;EAEa;EAAgB;CAAsB,CAAC;AAC5F"}
|
|
1
|
+
{"version":3,"file":"adapters.cjs","names":["ChecklistDetail","hasStepDetail","outcomeFor","readStepDetail","readStepSource","stepSourceCopy","stepKindCopy","UiTerminal","createTestRunnerRegistry","FixtureDetail","verifyNodeTest","StepOutputs"],"sources":["../../../src/data/verification/adapters.tsx"],"sourcesContent":["// Domain node adapters for VerificationResults: a checklist adapter for the\n// synthesized \"Acceptance criteria\" node and its items, and a fixture/CEL\n// adapter for the failing-step detail. Rendering lives in adapterViews.tsx —\n// split out so this file's only exports are the registry (react/only-export-\n// components forbids mixing component declarations with plain exports).\n\nimport type { ReactNode } from \"react\";\nimport { ChecklistDetail, FixtureDetail } from \"./adapterViews\";\nimport { StepOutputs } from \"./stepKindViews\";\nimport { verifyNodeTest } from \"./verifyReportTests\";\nimport { UiTerminal } from \"../../icons\";\nimport { hasStepDetail, readStepDetail, stepKindCopy, type WaitDetail } from \"./stepKind\";\nimport { readStepSource, stepSourceCopy } from \"./stepSource\";\nimport {\n createTestRunnerRegistry,\n outcomeFor,\n type BriefSection,\n type CopySections,\n type FixtureContext,\n type Test,\n type TestNodeAdapter,\n type TestNodeAdapterRegistry,\n type TestOutcome,\n type TestSummary,\n} from \"../test-runner\";\n\nfunction isChecklistNode(node: Test): boolean {\n return node.framework === \"checklist\";\n}\n\nfunction checklistMark(item: Test): string {\n if (item.failed) return \"[ ]\";\n if (item.passed) return \"[x]\";\n return \"[?]\";\n}\n\n/** `- [x]/[ ]/[?] criterion — reason` for each item, or the leaf itself. */\nfunction checklistCopy(node: Test): CopySections {\n const items = node.children && node.children.length > 0 ? node.children : [node];\n const lines = items.map(\n (item) => `- ${checklistMark(item)} ${item.name}${item.message ? ` — ${item.message}` : \"\"}`,\n );\n return { brief: [{ title: \"Criteria\", body: lines.join(\"\\n\") }] };\n}\n\nconst checklistAdapter: TestNodeAdapter = {\n id: \"verification-checklist\",\n match: isChecklistNode,\n renderDetail: ({ node }) => <ChecklistDetail node={node} />,\n copy: ({ node }) => checklistCopy(node),\n};\n\n// A typed step kind (services, todo, …) may report no command or CEL context at\n// all, so `detail.step` claims the node as well. A \"fixture\" leaf is a step whose\n// result has not arrived yet (a live or background step): it carries only the\n// execution node, which FixtureDetail renders as a header. Fixture parents\n// (markdown tables, runner steps) have children and stay with the default body.\nfunction isFixtureNode(node: Test): boolean {\n if (node.context !== undefined || hasStepDetail(node.detail)) return true;\n return node.framework === \"fixture\" && (node.children?.length ?? 0) === 0;\n}\n\n// ── Copy sections for fixture steps (exec / query / table / test / lint) ───\n\nfunction readCelTrace(detail: unknown): string | undefined {\n if (detail && typeof detail === \"object\" && !Array.isArray(detail)) {\n const value = (detail as Record<string, unknown>).cel_trace;\n if (typeof value === \"string\" && value.length > 0) return value;\n }\n return undefined;\n}\n\n// Mirrors CelDetails: without a CEL gate, a command step's `actual` is the whole\n// command result object, already covered by the Command section and output.\nfunction comparisonValue(hasCelGate: boolean, value: unknown): unknown {\n if (value === undefined) return undefined;\n if (hasCelGate) return value;\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) return undefined;\n return value;\n}\n\nfunction formatValue(value: unknown): string {\n return typeof value === \"string\" ? value : JSON.stringify(value, null, 2);\n}\n\nfunction commandSection(node: Test, context: FixtureContext | undefined): BriefSection[] {\n const command = context?.command ?? node.command;\n if (!command) return [];\n const cwd = context?.cwd ?? node.work_dir;\n const exit = context?.exit_code;\n const lines = [`$ ${command}`, cwd && `cwd: ${cwd}`, exit !== undefined && `exit: ${exit}`];\n return [{ title: \"Command\", lang: \"sh\", body: lines.filter(Boolean).join(\"\\n\") }];\n}\n\nfunction assertionSection(node: Test, context: FixtureContext | undefined): BriefSection[] {\n const expression = context?.cel_expression;\n const trace = readCelTrace(node.detail);\n const hasCelGate = !!(expression || trace);\n const vars = context?.cel_vars ?? {};\n const expected = comparisonValue(hasCelGate, context?.expected);\n const actual = comparisonValue(hasCelGate, context?.actual);\n const lines = [\n expression && `expression: ${expression}`,\n trace && `trace:\\n${trace}`,\n Object.keys(vars).length > 0 && `vars: ${formatValue(vars)}`,\n expected !== undefined && `expected: ${formatValue(expected)}`,\n actual !== undefined && `actual: ${formatValue(actual)}`,\n ].filter(Boolean);\n return lines.length > 0 ? [{ title: \"Assertion\", body: lines.join(\"\\n\") }] : [];\n}\n\nconst OUTCOME_GLYPH: Record<TestOutcome, string> = {\n passed: \"✓\",\n failed: \"✗\",\n errored: \"✗\",\n timedout: \"⏱\",\n warned: \"!\",\n aborted: \"■\",\n skipped: \"-\",\n pending: \"○\",\n running: \"…\",\n};\n\nfunction childLine(child: Test): string {\n const outcome = outcomeFor(child);\n const exit = (child.context as FixtureContext | undefined)?.exit_code;\n const reason = child.message ?? (exit ? `exit ${exit}` : undefined);\n return `${outcome ? OUTCOME_GLYPH[outcome] : \"·\"} ${child.name}${reason ? ` — ${reason}` : \"\"}`;\n}\n\nfunction summaryLine(summary: TestSummary): string {\n const counts: [number | undefined, string][] = [\n [summary.Passed, \"passed\"],\n [summary.Failed, \"failed\"],\n [summary.Warned, \"warned\"],\n [summary.Timedout, \"timed out\"],\n [summary.Skipped, \"skipped\"],\n [summary.Pending, \"pending\"],\n [summary.Running, \"running\"],\n ];\n const parts = counts.filter(([n]) => !!n).map(([n, label]) => `${n} ${label}`);\n return [`${summary.Total} total`, ...parts].join(\" · \");\n}\n\nfunction resultsSection(node: Test): BriefSection[] {\n const lines = [\n ...(node.summary ? [summaryLine(node.summary)] : []),\n ...(node.children ?? []).map(childLine),\n ];\n return lines.length > 0 ? [{ title: \"Results\", body: lines.join(\"\\n\") }] : [];\n}\n\n/** Command, CEL assertion and per-child verdicts for a fixture step or its parent. */\nfunction fixtureCopy(node: Test): CopySections {\n const context = node.context as FixtureContext | undefined;\n const command = context?.command ?? node.command;\n const stepDetail = readStepDetail(node.detail);\n const source = readStepSource(node.detail);\n return {\n brief: [\n ...commandSection(node, context),\n ...assertionSection(node, context),\n ...(source.kind === \"source\" ? stepSourceCopy(source.source) : []),\n ...(stepDetail.kind === \"step\" ? stepKindCopy(stepDetail.step) : []),\n ...resultsSection(node),\n ],\n items: command ? [{ label: \"Copy command\", icon: UiTerminal, value: command }] : [],\n };\n}\n\n// gavel's FixtureResult.Type values plus \"fixture\" (a markdown table of rows)\n// and the typed step kinds. Table and runner-step parents carry no `context`,\n// so the fixture adapter never claims them; this copy-only adapter gives them\n// the same sections. \"playwright\" is also a test framework, so it counts as a\n// step only when the node carries `detail.step`.\nconst FIXTURE_STEP_FRAMEWORKS = new Set([\n \"exec\",\n \"query\",\n \"fixture\",\n \"test\",\n \"lint\",\n \"verify\",\n \"services\",\n \"todo\",\n \"todo_prompt\",\n \"ai\",\n \"browser\",\n \"playwright\",\n \"agent-browser\",\n]);\n\nfunction isFixtureStepNode(node: Test): boolean {\n const framework = node.framework ?? \"\";\n if (framework === \"playwright\") return hasStepDetail(node.detail);\n return FIXTURE_STEP_FRAMEWORKS.has(framework);\n}\n\nconst fixtureStepCopyAdapter: TestNodeAdapter = {\n id: \"verification-step-copy\",\n match: isFixtureStepNode,\n copy: ({ node }) => fixtureCopy(node),\n};\n\n/** Default node adapters for VerificationResults: checklist items and\n * fixture/CEL steps. Registration order matters only when a node could match\n * both — a checklist node never carries a `context`, so the two never race. */\nexport type VerificationAdapterOptions = {\n /** Override the wait section while retaining the fixture's other detail sections. */\n renderWait?: (wait: WaitDetail) => ReactNode;\n /**\n * The answerable form of a step waiting on a person (`node.waiting`), shown in\n * its own section at the top of the step's detail. The host resolves which\n * pending prompt belongs to the node and answers it (e.g. with PromptForm).\n */\n renderPendingPrompt?: (node: Test) => ReactNode;\n};\n\n// The attempt a step is waiting in: it carries the step's name and task id (the\n// host finds the step's prompt by them) and `waiting`, and, when its result has\n// nothing marking it a fixture step, the step reference, so the fixture detail\n// (and its pending form) still renders it.\nfunction liveAttemptNode(step: Test, attempt: Test, ref: { id: string; kind: string }): Test {\n const live: Test = { ...attempt, name: step.name, ...(step.task_id !== undefined ? { task_id: step.task_id } : {}), waiting: true };\n if (isFixtureNode(live)) return live;\n // readStepDetail has already checked that an attempt result's detail is an object.\n return { ...live, detail: { ...(attempt.detail as Record<string, unknown> | undefined), step: ref } };\n}\n\nexport function verificationAdapters(options: VerificationAdapterOptions = {}): TestNodeAdapterRegistry {\n const fixtureAdapter: TestNodeAdapter = {\n id: \"verification-fixture\",\n match: isFixtureNode,\n renderDetail: ({ node }) => <FixtureDetail node={node} {...options} />,\n detailAttempts: ({ node }) => {\n const detail = readStepDetail(node.detail);\n if (detail.kind !== \"step\") return [];\n const live = detail.step.attempts.length - 1;\n return detail.step.attempts.map((attempt, index) => {\n const attemptNode: Test = attempt.result ? verifyNodeTest(attempt.result) : {\n name: node.name, message: `Attempt ${attempt.attempt}: execution evidence was not stored in this report.`,\n detail: { step: detail.step.step },\n };\n // The step waits in its last attempt; that one keeps the step's identity so the host finds its prompt.\n const waiting = node.waiting === true && index === live;\n return {\n id: attempt.attempt, status: attempt.status,\n ...(attempt.durationMs !== undefined ? { durationMs: attempt.durationMs } : {}),\n node: waiting ? liveAttemptNode(node, attemptNode, detail.step.step) : attemptNode,\n };\n });\n },\n detailTabs: ({ node }) => {\n const detail = readStepDetail(node.detail);\n if (detail.kind !== \"step\" || detail.step.outputs === undefined) return [];\n return [{ id: \"outputs\", label: \"Outputs\", render: () => <StepOutputs outputs={detail.step.outputs} /> }];\n },\n copy: ({ node }) => fixtureCopy(node),\n };\n return createTestRunnerRegistry([checklistAdapter, fixtureAdapter, fixtureStepCopyAdapter]);\n}\n"],"mappings":"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"}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { WaitDetail } from './stepKind.js';
|
|
3
|
-
import { TestNodeAdapterRegistry } from '../test-runner/index.js';
|
|
3
|
+
import { Test, TestNodeAdapterRegistry } from '../test-runner/index.js';
|
|
4
4
|
/** Default node adapters for VerificationResults: checklist items and
|
|
5
5
|
* fixture/CEL steps. Registration order matters only when a node could match
|
|
6
6
|
* both — a checklist node never carries a `context`, so the two never race. */
|
|
7
7
|
export type VerificationAdapterOptions = {
|
|
8
8
|
/** Override the wait section while retaining the fixture's other detail sections. */
|
|
9
9
|
renderWait?: (wait: WaitDetail) => ReactNode;
|
|
10
|
+
/**
|
|
11
|
+
* The answerable form of a step waiting on a person (`node.waiting`), shown in
|
|
12
|
+
* its own section at the top of the step's detail. The host resolves which
|
|
13
|
+
* pending prompt belongs to the node and answers it (e.g. with PromptForm).
|
|
14
|
+
*/
|
|
15
|
+
renderPendingPrompt?: (node: Test) => ReactNode;
|
|
10
16
|
};
|
|
11
17
|
export declare function verificationAdapters(options?: VerificationAdapterOptions): TestNodeAdapterRegistry;
|
|
12
18
|
//# sourceMappingURL=adapters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../../src/data/verification/adapters.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,OAAO,EAA+C,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE1F,OAAO,
|
|
1
|
+
{"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../../src/data/verification/adapters.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,OAAO,EAA+C,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE1F,OAAO,EAML,KAAK,IAAI,EAET,KAAK,uBAAuB,EAG7B,MAAM,gBAAgB,CAAC;AAmLxB;;gFAEgF;AAChF,MAAM,MAAM,0BAA0B,GAAG;IACvC,qFAAqF;IACrF,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS,CAAC;IAC7C;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC;CACjD,CAAC;AAaF,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,0BAA+B,GAAG,uBAAuB,CA+BtG"}
|
|
@@ -164,6 +164,22 @@ var fixtureStepCopyAdapter = {
|
|
|
164
164
|
match: isFixtureStepNode,
|
|
165
165
|
copy: ({ node }) => fixtureCopy(node)
|
|
166
166
|
};
|
|
167
|
+
function liveAttemptNode(step, attempt, ref) {
|
|
168
|
+
const live = {
|
|
169
|
+
...attempt,
|
|
170
|
+
name: step.name,
|
|
171
|
+
...step.task_id !== void 0 ? { task_id: step.task_id } : {},
|
|
172
|
+
waiting: true
|
|
173
|
+
};
|
|
174
|
+
if (isFixtureNode(live)) return live;
|
|
175
|
+
return {
|
|
176
|
+
...live,
|
|
177
|
+
detail: {
|
|
178
|
+
...attempt.detail,
|
|
179
|
+
step: ref
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
167
183
|
function verificationAdapters(options = {}) {
|
|
168
184
|
return createTestRunnerRegistry([
|
|
169
185
|
checklistAdapter,
|
|
@@ -177,16 +193,21 @@ function verificationAdapters(options = {}) {
|
|
|
177
193
|
detailAttempts: ({ node }) => {
|
|
178
194
|
const detail = readStepDetail(node.detail);
|
|
179
195
|
if (detail.kind !== "step") return [];
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
...attempt.durationMs !== void 0 ? { durationMs: attempt.durationMs } : {},
|
|
184
|
-
node: attempt.result ? verifyNodeTest(attempt.result) : {
|
|
196
|
+
const live = detail.step.attempts.length - 1;
|
|
197
|
+
return detail.step.attempts.map((attempt, index) => {
|
|
198
|
+
const attemptNode = attempt.result ? verifyNodeTest(attempt.result) : {
|
|
185
199
|
name: node.name,
|
|
186
200
|
message: `Attempt ${attempt.attempt}: execution evidence was not stored in this report.`,
|
|
187
201
|
detail: { step: detail.step.step }
|
|
188
|
-
}
|
|
189
|
-
|
|
202
|
+
};
|
|
203
|
+
const waiting = node.waiting === true && index === live;
|
|
204
|
+
return {
|
|
205
|
+
id: attempt.attempt,
|
|
206
|
+
status: attempt.status,
|
|
207
|
+
...attempt.durationMs !== void 0 ? { durationMs: attempt.durationMs } : {},
|
|
208
|
+
node: waiting ? liveAttemptNode(node, attemptNode, detail.step.step) : attemptNode
|
|
209
|
+
};
|
|
210
|
+
});
|
|
190
211
|
},
|
|
191
212
|
detailTabs: ({ node }) => {
|
|
192
213
|
const detail = readStepDetail(node.detail);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapters.js","names":[],"sources":["../../../src/data/verification/adapters.tsx"],"sourcesContent":["// Domain node adapters for VerificationResults: a checklist adapter for the\n// synthesized \"Acceptance criteria\" node and its items, and a fixture/CEL\n// adapter for the failing-step detail. Rendering lives in adapterViews.tsx —\n// split out so this file's only exports are the registry (react/only-export-\n// components forbids mixing component declarations with plain exports).\n\nimport type { ReactNode } from \"react\";\nimport { ChecklistDetail, FixtureDetail } from \"./adapterViews\";\nimport { StepOutputs } from \"./stepKindViews\";\nimport { verifyNodeTest } from \"./verifyReportTests\";\nimport { UiTerminal } from \"../../icons\";\nimport { hasStepDetail, readStepDetail, stepKindCopy, type WaitDetail } from \"./stepKind\";\nimport { readStepSource, stepSourceCopy } from \"./stepSource\";\nimport {\n createTestRunnerRegistry,\n outcomeFor,\n type BriefSection,\n type CopySections,\n type FixtureContext,\n type Test,\n type TestNodeAdapter,\n type TestNodeAdapterRegistry,\n type TestOutcome,\n type TestSummary,\n} from \"../test-runner\";\n\nfunction isChecklistNode(node: Test): boolean {\n return node.framework === \"checklist\";\n}\n\nfunction checklistMark(item: Test): string {\n if (item.failed) return \"[ ]\";\n if (item.passed) return \"[x]\";\n return \"[?]\";\n}\n\n/** `- [x]/[ ]/[?] criterion — reason` for each item, or the leaf itself. */\nfunction checklistCopy(node: Test): CopySections {\n const items = node.children && node.children.length > 0 ? node.children : [node];\n const lines = items.map(\n (item) => `- ${checklistMark(item)} ${item.name}${item.message ? ` — ${item.message}` : \"\"}`,\n );\n return { brief: [{ title: \"Criteria\", body: lines.join(\"\\n\") }] };\n}\n\nconst checklistAdapter: TestNodeAdapter = {\n id: \"verification-checklist\",\n match: isChecklistNode,\n renderDetail: ({ node }) => <ChecklistDetail node={node} />,\n copy: ({ node }) => checklistCopy(node),\n};\n\n// A typed step kind (services, todo, …) may report no command or CEL context at\n// all, so `detail.step` claims the node as well. A \"fixture\" leaf is a step whose\n// result has not arrived yet (a live or background step): it carries only the\n// execution node, which FixtureDetail renders as a header. Fixture parents\n// (markdown tables, runner steps) have children and stay with the default body.\nfunction isFixtureNode(node: Test): boolean {\n if (node.context !== undefined || hasStepDetail(node.detail)) return true;\n return node.framework === \"fixture\" && (node.children?.length ?? 0) === 0;\n}\n\n// ── Copy sections for fixture steps (exec / query / table / test / lint) ───\n\nfunction readCelTrace(detail: unknown): string | undefined {\n if (detail && typeof detail === \"object\" && !Array.isArray(detail)) {\n const value = (detail as Record<string, unknown>).cel_trace;\n if (typeof value === \"string\" && value.length > 0) return value;\n }\n return undefined;\n}\n\n// Mirrors CelDetails: without a CEL gate, a command step's `actual` is the whole\n// command result object, already covered by the Command section and output.\nfunction comparisonValue(hasCelGate: boolean, value: unknown): unknown {\n if (value === undefined) return undefined;\n if (hasCelGate) return value;\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) return undefined;\n return value;\n}\n\nfunction formatValue(value: unknown): string {\n return typeof value === \"string\" ? value : JSON.stringify(value, null, 2);\n}\n\nfunction commandSection(node: Test, context: FixtureContext | undefined): BriefSection[] {\n const command = context?.command ?? node.command;\n if (!command) return [];\n const cwd = context?.cwd ?? node.work_dir;\n const exit = context?.exit_code;\n const lines = [`$ ${command}`, cwd && `cwd: ${cwd}`, exit !== undefined && `exit: ${exit}`];\n return [{ title: \"Command\", lang: \"sh\", body: lines.filter(Boolean).join(\"\\n\") }];\n}\n\nfunction assertionSection(node: Test, context: FixtureContext | undefined): BriefSection[] {\n const expression = context?.cel_expression;\n const trace = readCelTrace(node.detail);\n const hasCelGate = !!(expression || trace);\n const vars = context?.cel_vars ?? {};\n const expected = comparisonValue(hasCelGate, context?.expected);\n const actual = comparisonValue(hasCelGate, context?.actual);\n const lines = [\n expression && `expression: ${expression}`,\n trace && `trace:\\n${trace}`,\n Object.keys(vars).length > 0 && `vars: ${formatValue(vars)}`,\n expected !== undefined && `expected: ${formatValue(expected)}`,\n actual !== undefined && `actual: ${formatValue(actual)}`,\n ].filter(Boolean);\n return lines.length > 0 ? [{ title: \"Assertion\", body: lines.join(\"\\n\") }] : [];\n}\n\nconst OUTCOME_GLYPH: Record<TestOutcome, string> = {\n passed: \"✓\",\n failed: \"✗\",\n errored: \"✗\",\n timedout: \"⏱\",\n warned: \"!\",\n aborted: \"■\",\n skipped: \"-\",\n pending: \"○\",\n running: \"…\",\n};\n\nfunction childLine(child: Test): string {\n const outcome = outcomeFor(child);\n const exit = (child.context as FixtureContext | undefined)?.exit_code;\n const reason = child.message ?? (exit ? `exit ${exit}` : undefined);\n return `${outcome ? OUTCOME_GLYPH[outcome] : \"·\"} ${child.name}${reason ? ` — ${reason}` : \"\"}`;\n}\n\nfunction summaryLine(summary: TestSummary): string {\n const counts: [number | undefined, string][] = [\n [summary.Passed, \"passed\"],\n [summary.Failed, \"failed\"],\n [summary.Warned, \"warned\"],\n [summary.Timedout, \"timed out\"],\n [summary.Skipped, \"skipped\"],\n [summary.Pending, \"pending\"],\n [summary.Running, \"running\"],\n ];\n const parts = counts.filter(([n]) => !!n).map(([n, label]) => `${n} ${label}`);\n return [`${summary.Total} total`, ...parts].join(\" · \");\n}\n\nfunction resultsSection(node: Test): BriefSection[] {\n const lines = [\n ...(node.summary ? [summaryLine(node.summary)] : []),\n ...(node.children ?? []).map(childLine),\n ];\n return lines.length > 0 ? [{ title: \"Results\", body: lines.join(\"\\n\") }] : [];\n}\n\n/** Command, CEL assertion and per-child verdicts for a fixture step or its parent. */\nfunction fixtureCopy(node: Test): CopySections {\n const context = node.context as FixtureContext | undefined;\n const command = context?.command ?? node.command;\n const stepDetail = readStepDetail(node.detail);\n const source = readStepSource(node.detail);\n return {\n brief: [\n ...commandSection(node, context),\n ...assertionSection(node, context),\n ...(source.kind === \"source\" ? stepSourceCopy(source.source) : []),\n ...(stepDetail.kind === \"step\" ? stepKindCopy(stepDetail.step) : []),\n ...resultsSection(node),\n ],\n items: command ? [{ label: \"Copy command\", icon: UiTerminal, value: command }] : [],\n };\n}\n\n// gavel's FixtureResult.Type values plus \"fixture\" (a markdown table of rows)\n// and the typed step kinds. Table and runner-step parents carry no `context`,\n// so the fixture adapter never claims them; this copy-only adapter gives them\n// the same sections. \"playwright\" is also a test framework, so it counts as a\n// step only when the node carries `detail.step`.\nconst FIXTURE_STEP_FRAMEWORKS = new Set([\n \"exec\",\n \"query\",\n \"fixture\",\n \"test\",\n \"lint\",\n \"verify\",\n \"services\",\n \"todo\",\n \"todo_prompt\",\n \"ai\",\n \"browser\",\n \"playwright\",\n \"agent-browser\",\n]);\n\nfunction isFixtureStepNode(node: Test): boolean {\n const framework = node.framework ?? \"\";\n if (framework === \"playwright\") return hasStepDetail(node.detail);\n return FIXTURE_STEP_FRAMEWORKS.has(framework);\n}\n\nconst fixtureStepCopyAdapter: TestNodeAdapter = {\n id: \"verification-step-copy\",\n match: isFixtureStepNode,\n copy: ({ node }) => fixtureCopy(node),\n};\n\n/** Default node adapters for VerificationResults: checklist items and\n * fixture/CEL steps. Registration order matters only when a node could match\n * both — a checklist node never carries a `context`, so the two never race. */\nexport type VerificationAdapterOptions = {\n /** Override the wait section while retaining the fixture's other detail sections. */\n renderWait?: (wait: WaitDetail) => ReactNode;\n};\n\nexport function verificationAdapters(options: VerificationAdapterOptions = {}): TestNodeAdapterRegistry {\n const fixtureAdapter: TestNodeAdapter = {\n id: \"verification-fixture\",\n match: isFixtureNode,\n renderDetail: ({ node }) => <FixtureDetail node={node} {...options} />,\n detailAttempts: ({ node }) => {\n const detail = readStepDetail(node.detail);\n if (detail.kind !== \"step\") return [];\n return detail.step.attempts.map((attempt) => ({\n id: attempt.attempt, status: attempt.status,\n ...(attempt.durationMs !== undefined ? { durationMs: attempt.durationMs } : {}),\n node: attempt.result ? verifyNodeTest(attempt.result) : {\n name: node.name, message: `Attempt ${attempt.attempt}: execution evidence was not stored in this report.`,\n detail: { step: detail.step.step },\n },\n }));\n },\n detailTabs: ({ node }) => {\n const detail = readStepDetail(node.detail);\n if (detail.kind !== \"step\" || detail.step.outputs === undefined) return [];\n return [{ id: \"outputs\", label: \"Outputs\", render: () => <StepOutputs outputs={detail.step.outputs} /> }];\n },\n copy: ({ node }) => fixtureCopy(node),\n };\n return createTestRunnerRegistry([checklistAdapter, fixtureAdapter, fixtureStepCopyAdapter]);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"adapters.js","names":[],"sources":["../../../src/data/verification/adapters.tsx"],"sourcesContent":["// Domain node adapters for VerificationResults: a checklist adapter for the\n// synthesized \"Acceptance criteria\" node and its items, and a fixture/CEL\n// adapter for the failing-step detail. Rendering lives in adapterViews.tsx —\n// split out so this file's only exports are the registry (react/only-export-\n// components forbids mixing component declarations with plain exports).\n\nimport type { ReactNode } from \"react\";\nimport { ChecklistDetail, FixtureDetail } from \"./adapterViews\";\nimport { StepOutputs } from \"./stepKindViews\";\nimport { verifyNodeTest } from \"./verifyReportTests\";\nimport { UiTerminal } from \"../../icons\";\nimport { hasStepDetail, readStepDetail, stepKindCopy, type WaitDetail } from \"./stepKind\";\nimport { readStepSource, stepSourceCopy } from \"./stepSource\";\nimport {\n createTestRunnerRegistry,\n outcomeFor,\n type BriefSection,\n type CopySections,\n type FixtureContext,\n type Test,\n type TestNodeAdapter,\n type TestNodeAdapterRegistry,\n type TestOutcome,\n type TestSummary,\n} from \"../test-runner\";\n\nfunction isChecklistNode(node: Test): boolean {\n return node.framework === \"checklist\";\n}\n\nfunction checklistMark(item: Test): string {\n if (item.failed) return \"[ ]\";\n if (item.passed) return \"[x]\";\n return \"[?]\";\n}\n\n/** `- [x]/[ ]/[?] criterion — reason` for each item, or the leaf itself. */\nfunction checklistCopy(node: Test): CopySections {\n const items = node.children && node.children.length > 0 ? node.children : [node];\n const lines = items.map(\n (item) => `- ${checklistMark(item)} ${item.name}${item.message ? ` — ${item.message}` : \"\"}`,\n );\n return { brief: [{ title: \"Criteria\", body: lines.join(\"\\n\") }] };\n}\n\nconst checklistAdapter: TestNodeAdapter = {\n id: \"verification-checklist\",\n match: isChecklistNode,\n renderDetail: ({ node }) => <ChecklistDetail node={node} />,\n copy: ({ node }) => checklistCopy(node),\n};\n\n// A typed step kind (services, todo, …) may report no command or CEL context at\n// all, so `detail.step` claims the node as well. A \"fixture\" leaf is a step whose\n// result has not arrived yet (a live or background step): it carries only the\n// execution node, which FixtureDetail renders as a header. Fixture parents\n// (markdown tables, runner steps) have children and stay with the default body.\nfunction isFixtureNode(node: Test): boolean {\n if (node.context !== undefined || hasStepDetail(node.detail)) return true;\n return node.framework === \"fixture\" && (node.children?.length ?? 0) === 0;\n}\n\n// ── Copy sections for fixture steps (exec / query / table / test / lint) ───\n\nfunction readCelTrace(detail: unknown): string | undefined {\n if (detail && typeof detail === \"object\" && !Array.isArray(detail)) {\n const value = (detail as Record<string, unknown>).cel_trace;\n if (typeof value === \"string\" && value.length > 0) return value;\n }\n return undefined;\n}\n\n// Mirrors CelDetails: without a CEL gate, a command step's `actual` is the whole\n// command result object, already covered by the Command section and output.\nfunction comparisonValue(hasCelGate: boolean, value: unknown): unknown {\n if (value === undefined) return undefined;\n if (hasCelGate) return value;\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) return undefined;\n return value;\n}\n\nfunction formatValue(value: unknown): string {\n return typeof value === \"string\" ? value : JSON.stringify(value, null, 2);\n}\n\nfunction commandSection(node: Test, context: FixtureContext | undefined): BriefSection[] {\n const command = context?.command ?? node.command;\n if (!command) return [];\n const cwd = context?.cwd ?? node.work_dir;\n const exit = context?.exit_code;\n const lines = [`$ ${command}`, cwd && `cwd: ${cwd}`, exit !== undefined && `exit: ${exit}`];\n return [{ title: \"Command\", lang: \"sh\", body: lines.filter(Boolean).join(\"\\n\") }];\n}\n\nfunction assertionSection(node: Test, context: FixtureContext | undefined): BriefSection[] {\n const expression = context?.cel_expression;\n const trace = readCelTrace(node.detail);\n const hasCelGate = !!(expression || trace);\n const vars = context?.cel_vars ?? {};\n const expected = comparisonValue(hasCelGate, context?.expected);\n const actual = comparisonValue(hasCelGate, context?.actual);\n const lines = [\n expression && `expression: ${expression}`,\n trace && `trace:\\n${trace}`,\n Object.keys(vars).length > 0 && `vars: ${formatValue(vars)}`,\n expected !== undefined && `expected: ${formatValue(expected)}`,\n actual !== undefined && `actual: ${formatValue(actual)}`,\n ].filter(Boolean);\n return lines.length > 0 ? [{ title: \"Assertion\", body: lines.join(\"\\n\") }] : [];\n}\n\nconst OUTCOME_GLYPH: Record<TestOutcome, string> = {\n passed: \"✓\",\n failed: \"✗\",\n errored: \"✗\",\n timedout: \"⏱\",\n warned: \"!\",\n aborted: \"■\",\n skipped: \"-\",\n pending: \"○\",\n running: \"…\",\n};\n\nfunction childLine(child: Test): string {\n const outcome = outcomeFor(child);\n const exit = (child.context as FixtureContext | undefined)?.exit_code;\n const reason = child.message ?? (exit ? `exit ${exit}` : undefined);\n return `${outcome ? OUTCOME_GLYPH[outcome] : \"·\"} ${child.name}${reason ? ` — ${reason}` : \"\"}`;\n}\n\nfunction summaryLine(summary: TestSummary): string {\n const counts: [number | undefined, string][] = [\n [summary.Passed, \"passed\"],\n [summary.Failed, \"failed\"],\n [summary.Warned, \"warned\"],\n [summary.Timedout, \"timed out\"],\n [summary.Skipped, \"skipped\"],\n [summary.Pending, \"pending\"],\n [summary.Running, \"running\"],\n ];\n const parts = counts.filter(([n]) => !!n).map(([n, label]) => `${n} ${label}`);\n return [`${summary.Total} total`, ...parts].join(\" · \");\n}\n\nfunction resultsSection(node: Test): BriefSection[] {\n const lines = [\n ...(node.summary ? [summaryLine(node.summary)] : []),\n ...(node.children ?? []).map(childLine),\n ];\n return lines.length > 0 ? [{ title: \"Results\", body: lines.join(\"\\n\") }] : [];\n}\n\n/** Command, CEL assertion and per-child verdicts for a fixture step or its parent. */\nfunction fixtureCopy(node: Test): CopySections {\n const context = node.context as FixtureContext | undefined;\n const command = context?.command ?? node.command;\n const stepDetail = readStepDetail(node.detail);\n const source = readStepSource(node.detail);\n return {\n brief: [\n ...commandSection(node, context),\n ...assertionSection(node, context),\n ...(source.kind === \"source\" ? stepSourceCopy(source.source) : []),\n ...(stepDetail.kind === \"step\" ? stepKindCopy(stepDetail.step) : []),\n ...resultsSection(node),\n ],\n items: command ? [{ label: \"Copy command\", icon: UiTerminal, value: command }] : [],\n };\n}\n\n// gavel's FixtureResult.Type values plus \"fixture\" (a markdown table of rows)\n// and the typed step kinds. Table and runner-step parents carry no `context`,\n// so the fixture adapter never claims them; this copy-only adapter gives them\n// the same sections. \"playwright\" is also a test framework, so it counts as a\n// step only when the node carries `detail.step`.\nconst FIXTURE_STEP_FRAMEWORKS = new Set([\n \"exec\",\n \"query\",\n \"fixture\",\n \"test\",\n \"lint\",\n \"verify\",\n \"services\",\n \"todo\",\n \"todo_prompt\",\n \"ai\",\n \"browser\",\n \"playwright\",\n \"agent-browser\",\n]);\n\nfunction isFixtureStepNode(node: Test): boolean {\n const framework = node.framework ?? \"\";\n if (framework === \"playwright\") return hasStepDetail(node.detail);\n return FIXTURE_STEP_FRAMEWORKS.has(framework);\n}\n\nconst fixtureStepCopyAdapter: TestNodeAdapter = {\n id: \"verification-step-copy\",\n match: isFixtureStepNode,\n copy: ({ node }) => fixtureCopy(node),\n};\n\n/** Default node adapters for VerificationResults: checklist items and\n * fixture/CEL steps. Registration order matters only when a node could match\n * both — a checklist node never carries a `context`, so the two never race. */\nexport type VerificationAdapterOptions = {\n /** Override the wait section while retaining the fixture's other detail sections. */\n renderWait?: (wait: WaitDetail) => ReactNode;\n /**\n * The answerable form of a step waiting on a person (`node.waiting`), shown in\n * its own section at the top of the step's detail. The host resolves which\n * pending prompt belongs to the node and answers it (e.g. with PromptForm).\n */\n renderPendingPrompt?: (node: Test) => ReactNode;\n};\n\n// The attempt a step is waiting in: it carries the step's name and task id (the\n// host finds the step's prompt by them) and `waiting`, and, when its result has\n// nothing marking it a fixture step, the step reference, so the fixture detail\n// (and its pending form) still renders it.\nfunction liveAttemptNode(step: Test, attempt: Test, ref: { id: string; kind: string }): Test {\n const live: Test = { ...attempt, name: step.name, ...(step.task_id !== undefined ? { task_id: step.task_id } : {}), waiting: true };\n if (isFixtureNode(live)) return live;\n // readStepDetail has already checked that an attempt result's detail is an object.\n return { ...live, detail: { ...(attempt.detail as Record<string, unknown> | undefined), step: ref } };\n}\n\nexport function verificationAdapters(options: VerificationAdapterOptions = {}): TestNodeAdapterRegistry {\n const fixtureAdapter: TestNodeAdapter = {\n id: \"verification-fixture\",\n match: isFixtureNode,\n renderDetail: ({ node }) => <FixtureDetail node={node} {...options} />,\n detailAttempts: ({ node }) => {\n const detail = readStepDetail(node.detail);\n if (detail.kind !== \"step\") return [];\n const live = detail.step.attempts.length - 1;\n return detail.step.attempts.map((attempt, index) => {\n const attemptNode: Test = attempt.result ? verifyNodeTest(attempt.result) : {\n name: node.name, message: `Attempt ${attempt.attempt}: execution evidence was not stored in this report.`,\n detail: { step: detail.step.step },\n };\n // The step waits in its last attempt; that one keeps the step's identity so the host finds its prompt.\n const waiting = node.waiting === true && index === live;\n return {\n id: attempt.attempt, status: attempt.status,\n ...(attempt.durationMs !== undefined ? { durationMs: attempt.durationMs } : {}),\n node: waiting ? liveAttemptNode(node, attemptNode, detail.step.step) : attemptNode,\n };\n });\n },\n detailTabs: ({ node }) => {\n const detail = readStepDetail(node.detail);\n if (detail.kind !== \"step\" || detail.step.outputs === undefined) return [];\n return [{ id: \"outputs\", label: \"Outputs\", render: () => <StepOutputs outputs={detail.step.outputs} /> }];\n },\n copy: ({ node }) => fixtureCopy(node),\n };\n return createTestRunnerRegistry([checklistAdapter, fixtureAdapter, fixtureStepCopyAdapter]);\n}\n"],"mappings":"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"}
|
|
@@ -115,6 +115,7 @@ function readAttemptResult(value, path) {
|
|
|
115
115
|
"running"
|
|
116
116
|
]) if (node[key] !== void 0) bool(node[key], `${path}.${key}`);
|
|
117
117
|
if (node.duration !== void 0) nonnegative(node.duration, `${path}.duration`);
|
|
118
|
+
if (node.detail !== void 0) record(node.detail, `${path}.detail`);
|
|
118
119
|
if (node.children !== void 0) list(node.children, `${path}.children`).forEach((child, i) => readAttemptResult(child, `${path}.children[${i}]`));
|
|
119
120
|
return {
|
|
120
121
|
...node,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stepKind.cjs","names":["formatTestDuration"],"sources":["../../../src/data/verification/stepKind.ts"],"sourcesContent":["// The typed step-kind detail gavel's fixture verifier attaches to a node\n// (fixtures/verifier/report.go): `detail.step` names the kind and id, beside\n// the structured `wait`, `attempts`, `exports`, `outputs` and (for a\n// background Playwright watcher) `events`. Parsed here, once, so the detail\n// view and the copy brief read the same typed shape. A present-but-malformed\n// field is reported by path instead of being guessed at.\n\nimport type { BriefSection } from \"../test-runner\";\nimport { formatTestDuration } from \"../test-runner\";\nimport type { VerifyNode } from \"./verify-report\";\n\nexport type StepRef = { id: string; kind: string };\n\nexport type WaitPolicy = {\n until?: string;\n failWhen?: string;\n interval?: string;\n backoff?: { factor?: number; max?: string };\n jitter?: string;\n timeout?: string;\n};\n\nexport const WAIT_OUTCOMES = [\"satisfied\", \"failed\", \"timeout\"] as const;\nexport type WaitOutcome = (typeof WAIT_OUTCOMES)[number];\n\nexport type WaitDetail = {\n policy: WaitPolicy;\n outcome: WaitOutcome;\n durationMs: number;\n /** The CEL expression that decided the outcome: policy.failWhen when it fired, else policy.until. */\n expression?: string;\n /** Domain reason the wait ended unsatisfied; may span several lines. */\n cause?: string;\n outputs?: unknown;\n error?: string;\n trace?: string;\n};\n\nexport type StepAttempt = { attempt: number; status: string; error?: string; durationMs?: number; result?: VerifyNode };\n\nexport type StepExport = { name: string; value: unknown; step: string };\n\nexport const WATCHER_EVENT_TYPES = [\"alert\", \"console\", \"pageerror\", \"response\"] as const;\nexport type WatcherEventType = (typeof WATCHER_EVENT_TYPES)[number];\n\nexport type WatcherEvent = {\n type: WatcherEventType;\n text?: string;\n url?: string;\n status?: number;\n detail?: string;\n};\n\nexport type StepDetail = {\n step: StepRef;\n outputs?: unknown;\n exports: StepExport[];\n wait?: WaitDetail;\n attempts: StepAttempt[];\n events: WatcherEvent[];\n /** Whether the step runs in the background until teardown (a watcher). */\n background: boolean;\n /** Everything else in `node.detail` (cel_trace, run, recordings, …). */\n rest: Record<string, unknown>;\n};\n\nexport type StepDetailResult =\n | { kind: \"none\" }\n | { kind: \"step\"; step: StepDetail }\n | { kind: \"invalid\"; error: string };\n\nconst STEP_KEYS = new Set([\"step\", \"outputs\", \"exports\", \"wait\", \"attempts\", \"events\", \"background\"]);\n\nclass StepDetailError extends Error {}\n\nfunction fail(path: string, expectation: string): never {\n throw new StepDetailError(`${path} must be ${expectation}`);\n}\n\ntype Rec = Record<string, unknown>;\n\nconst isRecord = (value: unknown): value is Rec =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nfunction record(value: unknown, path: string): Rec {\n return isRecord(value) ? value : fail(path, \"an object\");\n}\n\nfunction list(value: unknown, path: string): unknown[] {\n return Array.isArray(value) ? value : fail(path, \"an array\");\n}\n\nfunction str(value: unknown, path: string): string {\n return typeof value === \"string\" ? value : fail(path, \"a string\");\n}\n\nfunction num(value: unknown, path: string): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fail(path, \"a number\");\n}\n\nfunction bool(value: unknown, path: string): boolean {\n return typeof value === \"boolean\" ? value : fail(path, \"a boolean\");\n}\n\nfunction oneOf<T extends string>(value: unknown, allowed: readonly T[], path: string): T {\n return allowed.includes(value as T)\n ? (value as T)\n : fail(path, `one of ${allowed.join(\", \")} (got ${JSON.stringify(value)})`);\n}\n\n/** `{ [key]: read(value) }` when the optional field is present, else `{}` — absent stays an absent key. */\nfunction optional<K extends string, T>(source: Rec, key: K, read: (value: unknown) => T): { [P in K]?: T } {\n return source[key] === undefined || source[key] === null ? {} : ({ [key]: read(source[key]) } as { [P in K]?: T });\n}\n\n/** Durations arrive as Go-style strings (\"15s\"); a bare number is nanoseconds like every other duration on the wire. */\nfunction durationText(value: unknown, path: string): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return formatTestDuration(value);\n return fail(path, \"a duration string or nanosecond number\");\n}\n\nfunction scalarText(value: unknown, path: string): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return String(value);\n return fail(path, \"a string or number\");\n}\n\nfunction readPolicy(value: unknown): WaitPolicy {\n const path = \"detail.wait.policy\";\n const policy = record(value, path);\n const backoff = (raw: unknown) => {\n const b = record(raw, `${path}.backoff`);\n return {\n ...optional(b, \"factor\", (v) => num(v, `${path}.backoff.factor`)),\n ...optional(b, \"max\", (v) => durationText(v, `${path}.backoff.max`)),\n };\n };\n return {\n ...optional(policy, \"until\", (v) => str(v, `${path}.until`)),\n ...optional(policy, \"failWhen\", (v) => str(v, `${path}.failWhen`)),\n ...optional(policy, \"interval\", (v) => durationText(v, `${path}.interval`)),\n ...optional(policy, \"backoff\", backoff),\n ...optional(policy, \"jitter\", (v) => scalarText(v, `${path}.jitter`)),\n ...optional(policy, \"timeout\", (v) => durationText(v, `${path}.timeout`)),\n };\n}\n\nfunction readWait(value: unknown): WaitDetail {\n const wait = record(value, \"detail.wait\");\n return {\n policy: readPolicy(wait.policy ?? {}),\n outcome: oneOf(wait.outcome, WAIT_OUTCOMES, \"detail.wait.outcome\"),\n durationMs: nonnegative(wait.durationMs, \"detail.wait.durationMs\"),\n ...(wait.outputs === undefined ? {} : { outputs: wait.outputs }),\n ...optional(wait, \"expression\", (v) => str(v, \"detail.wait.expression\")),\n ...optional(wait, \"cause\", (v) => str(v, \"detail.wait.cause\")),\n ...optional(wait, \"error\", (v) => str(v, \"detail.wait.error\")),\n ...optional(wait, \"trace\", (v) => str(v, \"detail.wait.trace\")),\n };\n}\n\nfunction nonnegative(value: unknown, path: string): number {\n const result = num(value, path);\n return result >= 0 ? result : fail(path, \"non-negative\");\n}\n\nfunction readAttemptResult(value: unknown, path: string): VerifyNode {\n const node = record(value, path);\n str(node.name, `${path}.name`);\n for (const key of [\"framework\", \"message\", \"command\", \"work_dir\", \"stdout\", \"stderr\"]) {\n if (node[key] !== undefined) str(node[key], `${path}.${key}`);\n }\n for (const key of [\"passed\", \"failed\", \"timed_out\", \"warned\", \"skipped\", \"pending\", \"running\"]) {\n if (node[key] !== undefined) bool(node[key], `${path}.${key}`);\n }\n if (node.duration !== undefined) nonnegative(node.duration, `${path}.duration`);\n if (node.children !== undefined) list(node.children, `${path}.children`).forEach((child, i) => readAttemptResult(child, `${path}.children[${i}]`));\n return { ...node, name: str(node.name, `${path}.name`) } as VerifyNode;\n}\n\nfunction readAttempt(value: unknown, index: number): StepAttempt {\n const path = `detail.attempts[${index}]`;\n const a = record(value, path);\n return {\n attempt: num(a.attempt, `${path}.attempt`),\n status: str(a.status, `${path}.status`),\n ...optional(a, \"error\", (v) => str(v, `${path}.error`)),\n ...optional(a, \"durationMs\", (v) => nonnegative(v, `${path}.durationMs`)),\n ...optional(a, \"result\", (v) => readAttemptResult(v, `${path}.result`)),\n };\n}\n\nfunction readAttempts(value: unknown): StepAttempt[] {\n const attempts = list(value, \"detail.attempts\").map(readAttempt);\n attempts.forEach((attempt, index) => {\n if (attempt.attempt !== index + 1) fail(`detail.attempts[${index}].attempt`, `the sequence number ${index + 1}`);\n });\n return attempts;\n}\n\nfunction readExports(value: unknown): StepExport[] {\n return Object.entries(record(value, \"detail.exports\")).map(([name, raw]) => {\n const path = `detail.exports.${name}`;\n const entry = record(raw, path);\n return { name, value: entry.value, step: str(entry.step, `${path}.step`) };\n });\n}\n\nfunction readEvent(value: unknown, index: number): WatcherEvent {\n const path = `detail.events[${index}]`;\n const e = record(value, path);\n return {\n type: oneOf(e.type, WATCHER_EVENT_TYPES, `${path}.type`),\n ...optional(e, \"text\", (v) => str(v, `${path}.text`)),\n ...optional(e, \"url\", (v) => str(v, `${path}.url`)),\n ...optional(e, \"status\", (v) => num(v, `${path}.status`)),\n ...optional(e, \"detail\", (v) => str(v, `${path}.detail`)),\n };\n}\n\nfunction readStep(detail: Rec): StepDetail {\n const ref = record(detail.step, \"detail.step\");\n const rest = Object.fromEntries(Object.entries(detail).filter(([key]) => !STEP_KEYS.has(key)));\n return {\n step: { id: str(ref.id, \"detail.step.id\"), kind: str(ref.kind, \"detail.step.kind\") },\n ...(detail.outputs === undefined ? {} : { outputs: detail.outputs }),\n exports: detail.exports == null ? [] : readExports(detail.exports),\n ...optional(detail, \"wait\", readWait),\n attempts: readAttempts(detail.attempts ?? []),\n events: list(detail.events ?? [], \"detail.events\").map(readEvent),\n background: bool(detail.background ?? false, \"detail.background\"),\n rest,\n };\n}\n\n/**\n * Whether `node.detail` carries a typed step (`detail.step`), and if so its\n * parsed contents. A node without `detail.step` is \"none\" whatever else its\n * detail holds; a `step` whose fields violate the contract is \"invalid\" with\n * the offending path, so the view can say so rather than render a guess.\n */\nexport function readStepDetail(detail: unknown): StepDetailResult {\n if (!isRecord(detail) || detail.step === undefined) return { kind: \"none\" };\n try {\n return { kind: \"step\", step: readStep(detail) };\n } catch (error) {\n if (error instanceof StepDetailError) return { kind: \"invalid\", error: error.message };\n throw error;\n }\n}\n\n/** The step detail when there is one, for matchers that only need to know. */\nexport function hasStepDetail(detail: unknown): boolean {\n return readStepDetail(detail).kind !== \"none\";\n}\n\n/** The fixtures.ExecutionNode fields gavel puts at the top of `node.detail`, shown as a header instead of raw JSON. */\nexport type ExecutionHeader = {\n kind?: string;\n state?: string;\n file?: string;\n sectionPath?: string;\n /** Zero-based row of the step within its section. */\n rowIndex?: number;\n line?: number;\n startedAt?: string;\n finishedAt?: string;\n /** Nanoseconds. */\n durationNs?: number;\n error?: string;\n};\n\nconst isString = (value: unknown): value is string => typeof value === \"string\";\nconst isNumber = (value: unknown): value is number => typeof value === \"number\" && Number.isFinite(value);\n\n/**\n * Splits the ExecutionNode fields (name, kind, state, origin, started_at,\n * finished_at, duration, error) off `detail` into a header, dropping the\n * internal `key`. A field of an unexpected type is not consumed — it stays in\n * `rest`, so it is visible in the raw block rather than silently hidden.\n */\nexport function splitExecutionDetail(detail: unknown): { header: ExecutionHeader; rest: unknown } {\n if (!isRecord(detail)) return { header: {}, rest: detail };\n const rest: Rec = { ...detail };\n delete rest.key;\n const take = <T>(key: string, guard: (value: unknown) => value is T): T | undefined => {\n const value = rest[key];\n if (!guard(value)) return undefined;\n delete rest[key];\n return value;\n };\n const header: ExecutionHeader = {};\n const assign = <K extends keyof ExecutionHeader>(field: K, value: ExecutionHeader[K] | undefined) => {\n if (value !== undefined) header[field] = value;\n };\n take(\"name\", isString);\n assign(\"kind\", take(\"kind\", isString));\n assign(\"state\", take(\"state\", isString));\n assign(\"startedAt\", take(\"started_at\", isString));\n assign(\"finishedAt\", take(\"finished_at\", isString));\n assign(\"durationNs\", take(\"duration\", isNumber));\n assign(\"error\", take(\"error\", isString));\n const origin = take(\"origin\", isRecord);\n if (origin) {\n assign(\"file\", isString(origin.file) ? origin.file : undefined);\n assign(\"sectionPath\", isString(origin.section_path) ? origin.section_path : undefined);\n assign(\"rowIndex\", isNumber(origin.row_index) ? origin.row_index : undefined);\n assign(\"line\", isNumber(origin.line) ? origin.line : undefined);\n }\n return { header, rest: Object.keys(rest).length > 0 ? rest : undefined };\n}\n\nexport type WaitCondition = \"until\" | \"failWhen\";\n\n/** Which of the wait's two conditions decided its outcome. `expression` is authoritative; older payloads without it are inferred from the outcome. */\nexport function waitDecidedBy(wait: WaitDetail): WaitCondition {\n if (wait.expression !== undefined) return wait.expression === wait.policy.failWhen ? \"failWhen\" : \"until\";\n return wait.outcome === \"failed\" && wait.policy.failWhen ? \"failWhen\" : \"until\";\n}\n\n/** `09:00:04` from an RFC 3339 timestamp, as written (no timezone conversion); anything else verbatim. */\nexport function clockTime(at: string): string {\n return /T(\\d{2}:\\d{2}:\\d{2})/.exec(at)?.[1] ?? at;\n}\n\nexport function formatDelay(ms: number): string {\n return ms <= 0 ? \"0ms\" : formatTestDuration(ms * 1e6);\n}\n\n/** `every 1s · backoff ×1.5 up to 10s · jitter ±20% · timeout 3m`, skipping what the policy leaves unset. */\nexport function policySummary(policy: WaitPolicy): string {\n const backoff = [\n policy.backoff?.factor !== undefined && `×${policy.backoff.factor}`,\n policy.backoff?.max && `up to ${policy.backoff.max}`,\n ].filter(Boolean);\n return [\n policy.interval && `every ${policy.interval}`,\n backoff.length > 0 && `backoff ${backoff.join(\" \")}`,\n policy.jitter && `jitter ±${policy.jitter}`,\n policy.timeout && `timeout ${policy.timeout}`,\n ]\n .filter(Boolean)\n .join(\" · \");\n}\n\nexport function formatExportValue(value: unknown): string {\n if (value === undefined) return \"\";\n return typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\nfunction waitCopy(wait: WaitDetail): BriefSection {\n const { policy } = wait;\n const lines = [\n `outcome: ${wait.outcome}`,\n `elapsed: ${formatDelay(wait.durationMs)}`,\n `policy: ${policySummary(policy)}`,\n policy.until && `until: ${policy.until}`,\n policy.failWhen && `failWhen: ${policy.failWhen}`,\n wait.expression && `decided by: ${wait.expression}`,\n wait.cause && `cause: ${wait.cause}`,\n wait.error && `error: ${wait.error}`,\n wait.trace && `trace: ${wait.trace}`,\n wait.outputs !== undefined && `outputs: ${JSON.stringify(wait.outputs)}`,\n ];\n return { title: \"Wait\", body: lines.filter(Boolean).join(\"\\n\") };\n}\n\nfunction attemptLine(a: StepAttempt): string {\n const head = [`#${a.attempt}`, a.status, a.durationMs !== undefined && formatDelay(a.durationMs)];\n return `${head.filter(Boolean).join(\" \")}${a.error ? ` — ${a.error}` : \"\"}`;\n}\n\nfunction eventLine(e: WatcherEvent): string {\n const body = [e.status, e.text, e.url].filter((part) => part !== undefined).join(\" \");\n return `[${e.type}]${body ? ` ${body}` : \"\"}${e.detail ? ` — ${e.detail}` : \"\"}`;\n}\n\n/** Brief sections for the \"Copy details\" button: wait trace, retry attempts, exports and watcher events. */\nexport function stepKindCopy(step: StepDetail): BriefSection[] {\n return [\n ...(step.outputs !== undefined ? [{ title: \"Outputs\", body: JSON.stringify(step.outputs, null, 2), lang: \"json\" }] : []),\n ...(step.wait ? [waitCopy(step.wait)] : []),\n ...(step.attempts.length > 0 ? [{ title: \"Attempts\", body: step.attempts.map(attemptLine).join(\"\\n\") }] : []),\n ...(step.exports.length > 0\n ? [{ title: \"Exports\", body: step.exports.map((e) => `${e.name}=${formatExportValue(e.value)} (from ${e.step})`).join(\"\\n\") }]\n : []),\n ...(step.events.length > 0 ? [{ title: \"Events\", body: step.events.map(eventLine).join(\"\\n\") }] : []),\n ];\n}\n"],"mappings":";;AAsBA,IAAa,gBAAgB;CAAC;CAAa;CAAU;AAAS;AAoB9D,IAAa,sBAAsB;CAAC;CAAS;CAAW;CAAa;AAAU;AA6B/E,IAAM,4BAAY,IAAI,IAAI;CAAC;CAAQ;CAAW;CAAW;CAAQ;CAAY;CAAU;AAAY,CAAC;AAEpG,IAAM,kBAAN,cAA8B,MAAM,CAAC;AAErC,SAAS,KAAK,MAAc,aAA4B;CACtD,MAAM,IAAI,gBAAgB,GAAG,KAAK,WAAW,aAAa;AAC5D;AAIA,IAAM,YAAY,UAChB,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAErE,SAAS,OAAO,OAAgB,MAAmB;CACjD,OAAO,SAAS,KAAK,IAAI,QAAQ,KAAK,MAAM,WAAW;AACzD;AAEA,SAAS,KAAK,OAAgB,MAAyB;CACrD,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,KAAK,MAAM,UAAU;AAC7D;AAEA,SAAS,IAAI,OAAgB,MAAsB;CACjD,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAK,MAAM,UAAU;AAClE;AAEA,SAAS,IAAI,OAAgB,MAAsB;CACjD,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ,KAAK,MAAM,UAAU;AAC5F;AAEA,SAAS,KAAK,OAAgB,MAAuB;CACnD,OAAO,OAAO,UAAU,YAAY,QAAQ,KAAK,MAAM,WAAW;AACpE;AAEA,SAAS,MAAwB,OAAgB,SAAuB,MAAiB;CACvF,OAAO,QAAQ,SAAS,KAAU,IAC7B,QACD,KAAK,MAAM,UAAU,QAAQ,KAAK,IAAI,EAAE,QAAQ,KAAK,UAAU,KAAK,EAAE,EAAE;AAC9E;;AAGA,SAAS,SAA8B,QAAa,KAAQ,MAA+C;CACzG,OAAO,OAAO,SAAS,KAAA,KAAa,OAAO,SAAS,OAAO,CAAC,IAAK,GAAG,MAAM,KAAK,OAAO,IAAI,EAAE;AAC9F;;AAGA,SAAS,aAAa,OAAgB,MAAsB;CAC1D,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,OAAO,UAAU,UAAU,OAAOA,eAAAA,mBAAmB,KAAK;CAC9D,OAAO,KAAK,MAAM,wCAAwC;AAC5D;AAEA,SAAS,WAAW,OAAgB,MAAsB;CACxD,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,OAAO,UAAU,UAAU,OAAO,OAAO,KAAK;CAClD,OAAO,KAAK,MAAM,oBAAoB;AACxC;AAEA,SAAS,WAAW,OAA4B;CAC9C,MAAM,OAAO;CACb,MAAM,SAAS,OAAO,OAAO,IAAI;CACjC,MAAM,WAAW,QAAiB;EAChC,MAAM,IAAI,OAAO,KAAK,GAAG,KAAK,SAAS;EACvC,OAAO;GACL,GAAG,SAAS,GAAG,WAAW,MAAM,IAAI,GAAG,GAAG,KAAK,gBAAgB,CAAC;GAChE,GAAG,SAAS,GAAG,QAAQ,MAAM,aAAa,GAAG,GAAG,KAAK,aAAa,CAAC;EACrE;CACF;CACA,OAAO;EACL,GAAG,SAAS,QAAQ,UAAU,MAAM,IAAI,GAAG,GAAG,KAAK,OAAO,CAAC;EAC3D,GAAG,SAAS,QAAQ,aAAa,MAAM,IAAI,GAAG,GAAG,KAAK,UAAU,CAAC;EACjE,GAAG,SAAS,QAAQ,aAAa,MAAM,aAAa,GAAG,GAAG,KAAK,UAAU,CAAC;EAC1E,GAAG,SAAS,QAAQ,WAAW,OAAO;EACtC,GAAG,SAAS,QAAQ,WAAW,MAAM,WAAW,GAAG,GAAG,KAAK,QAAQ,CAAC;EACpE,GAAG,SAAS,QAAQ,YAAY,MAAM,aAAa,GAAG,GAAG,KAAK,SAAS,CAAC;CAC1E;AACF;AAEA,SAAS,SAAS,OAA4B;CAC5C,MAAM,OAAO,OAAO,OAAO,aAAa;CACxC,OAAO;EACL,QAAQ,WAAW,KAAK,UAAU,CAAC,CAAC;EACpC,SAAS,MAAM,KAAK,SAAS,eAAe,qBAAqB;EACjE,YAAY,YAAY,KAAK,YAAY,wBAAwB;EACjE,GAAI,KAAK,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,KAAK,QAAQ;EAC9D,GAAG,SAAS,MAAM,eAAe,MAAM,IAAI,GAAG,wBAAwB,CAAC;EACvE,GAAG,SAAS,MAAM,UAAU,MAAM,IAAI,GAAG,mBAAmB,CAAC;EAC7D,GAAG,SAAS,MAAM,UAAU,MAAM,IAAI,GAAG,mBAAmB,CAAC;EAC7D,GAAG,SAAS,MAAM,UAAU,MAAM,IAAI,GAAG,mBAAmB,CAAC;CAC/D;AACF;AAEA,SAAS,YAAY,OAAgB,MAAsB;CACzD,MAAM,SAAS,IAAI,OAAO,IAAI;CAC9B,OAAO,UAAU,IAAI,SAAS,KAAK,MAAM,cAAc;AACzD;AAEA,SAAS,kBAAkB,OAAgB,MAA0B;CACnE,MAAM,OAAO,OAAO,OAAO,IAAI;CAC/B,IAAI,KAAK,MAAM,GAAG,KAAK,MAAM;CAC7B,KAAK,MAAM,OAAO;EAAC;EAAa;EAAW;EAAW;EAAY;EAAU;CAAQ,GAClF,IAAI,KAAK,SAAS,KAAA,GAAW,IAAI,KAAK,MAAM,GAAG,KAAK,GAAG,KAAK;CAE9D,KAAK,MAAM,OAAO;EAAC;EAAU;EAAU;EAAa;EAAU;EAAW;EAAW;CAAS,GAC3F,IAAI,KAAK,SAAS,KAAA,GAAW,KAAK,KAAK,MAAM,GAAG,KAAK,GAAG,KAAK;CAE/D,IAAI,KAAK,aAAa,KAAA,GAAW,YAAY,KAAK,UAAU,GAAG,KAAK,UAAU;CAC9E,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,KAAK,UAAU,GAAG,KAAK,UAAU,CAAC,CAAC,SAAS,OAAO,MAAM,kBAAkB,OAAO,GAAG,KAAK,YAAY,EAAE,EAAE,CAAC;CACjJ,OAAO;EAAE,GAAG;EAAM,MAAM,IAAI,KAAK,MAAM,GAAG,KAAK,MAAM;CAAE;AACzD;AAEA,SAAS,YAAY,OAAgB,OAA4B;CAC/D,MAAM,OAAO,mBAAmB,MAAM;CACtC,MAAM,IAAI,OAAO,OAAO,IAAI;CAC5B,OAAO;EACL,SAAS,IAAI,EAAE,SAAS,GAAG,KAAK,SAAS;EACzC,QAAQ,IAAI,EAAE,QAAQ,GAAG,KAAK,QAAQ;EACtC,GAAG,SAAS,GAAG,UAAU,MAAM,IAAI,GAAG,GAAG,KAAK,OAAO,CAAC;EACtD,GAAG,SAAS,GAAG,eAAe,MAAM,YAAY,GAAG,GAAG,KAAK,YAAY,CAAC;EACxE,GAAG,SAAS,GAAG,WAAW,MAAM,kBAAkB,GAAG,GAAG,KAAK,QAAQ,CAAC;CACxE;AACF;AAEA,SAAS,aAAa,OAA+B;CACnD,MAAM,WAAW,KAAK,OAAO,iBAAiB,CAAC,CAAC,IAAI,WAAW;CAC/D,SAAS,SAAS,SAAS,UAAU;EACnC,IAAI,QAAQ,YAAY,QAAQ,GAAG,KAAK,mBAAmB,MAAM,YAAY,uBAAuB,QAAQ,GAAG;CACjH,CAAC;CACD,OAAO;AACT;AAEA,SAAS,YAAY,OAA8B;CACjD,OAAO,OAAO,QAAQ,OAAO,OAAO,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,SAAS;EAC1E,MAAM,OAAO,kBAAkB;EAC/B,MAAM,QAAQ,OAAO,KAAK,IAAI;EAC9B,OAAO;GAAE;GAAM,OAAO,MAAM;GAAO,MAAM,IAAI,MAAM,MAAM,GAAG,KAAK,MAAM;EAAE;CAC3E,CAAC;AACH;AAEA,SAAS,UAAU,OAAgB,OAA6B;CAC9D,MAAM,OAAO,iBAAiB,MAAM;CACpC,MAAM,IAAI,OAAO,OAAO,IAAI;CAC5B,OAAO;EACL,MAAM,MAAM,EAAE,MAAM,qBAAqB,GAAG,KAAK,MAAM;EACvD,GAAG,SAAS,GAAG,SAAS,MAAM,IAAI,GAAG,GAAG,KAAK,MAAM,CAAC;EACpD,GAAG,SAAS,GAAG,QAAQ,MAAM,IAAI,GAAG,GAAG,KAAK,KAAK,CAAC;EAClD,GAAG,SAAS,GAAG,WAAW,MAAM,IAAI,GAAG,GAAG,KAAK,QAAQ,CAAC;EACxD,GAAG,SAAS,GAAG,WAAW,MAAM,IAAI,GAAG,GAAG,KAAK,QAAQ,CAAC;CAC1D;AACF;AAEA,SAAS,SAAS,QAAyB;CACzC,MAAM,MAAM,OAAO,OAAO,MAAM,aAAa;CAC7C,MAAM,OAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;CAC7F,OAAO;EACL,MAAM;GAAE,IAAI,IAAI,IAAI,IAAI,gBAAgB;GAAG,MAAM,IAAI,IAAI,MAAM,kBAAkB;EAAE;EACnF,GAAI,OAAO,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,OAAO,QAAQ;EAClE,SAAS,OAAO,WAAW,OAAO,CAAC,IAAI,YAAY,OAAO,OAAO;EACjE,GAAG,SAAS,QAAQ,QAAQ,QAAQ;EACpC,UAAU,aAAa,OAAO,YAAY,CAAC,CAAC;EAC5C,QAAQ,KAAK,OAAO,UAAU,CAAC,GAAG,eAAe,CAAC,CAAC,IAAI,SAAS;EAChE,YAAY,KAAK,OAAO,cAAc,OAAO,mBAAmB;EAChE;CACF;AACF;;;;;;;AAQA,SAAgB,eAAe,QAAmC;CAChE,IAAI,CAAC,SAAS,MAAM,KAAK,OAAO,SAAS,KAAA,GAAW,OAAO,EAAE,MAAM,OAAO;CAC1E,IAAI;EACF,OAAO;GAAE,MAAM;GAAQ,MAAM,SAAS,MAAM;EAAE;CAChD,SAAS,OAAO;EACd,IAAI,iBAAiB,iBAAiB,OAAO;GAAE,MAAM;GAAW,OAAO,MAAM;EAAQ;EACrF,MAAM;CACR;AACF;;AAGA,SAAgB,cAAc,QAA0B;CACtD,OAAO,eAAe,MAAM,CAAC,CAAC,SAAS;AACzC;AAkBA,IAAM,YAAY,UAAoC,OAAO,UAAU;AACvE,IAAM,YAAY,UAAoC,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;;;;;;;AAQxG,SAAgB,qBAAqB,QAA6D;CAChG,IAAI,CAAC,SAAS,MAAM,GAAG,OAAO;EAAE,QAAQ,CAAC;EAAG,MAAM;CAAO;CACzD,MAAM,OAAY,EAAE,GAAG,OAAO;CAC9B,OAAO,KAAK;CACZ,MAAM,QAAW,KAAa,UAAyD;EACrF,MAAM,QAAQ,KAAK;EACnB,IAAI,CAAC,MAAM,KAAK,GAAG,OAAO,KAAA;EAC1B,OAAO,KAAK;EACZ,OAAO;CACT;CACA,MAAM,SAA0B,CAAC;CACjC,MAAM,UAA2C,OAAU,UAA0C;EACnG,IAAI,UAAU,KAAA,GAAW,OAAO,SAAS;CAC3C;CACA,KAAK,QAAQ,QAAQ;CACrB,OAAO,QAAQ,KAAK,QAAQ,QAAQ,CAAC;CACrC,OAAO,SAAS,KAAK,SAAS,QAAQ,CAAC;CACvC,OAAO,aAAa,KAAK,cAAc,QAAQ,CAAC;CAChD,OAAO,cAAc,KAAK,eAAe,QAAQ,CAAC;CAClD,OAAO,cAAc,KAAK,YAAY,QAAQ,CAAC;CAC/C,OAAO,SAAS,KAAK,SAAS,QAAQ,CAAC;CACvC,MAAM,SAAS,KAAK,UAAU,QAAQ;CACtC,IAAI,QAAQ;EACV,OAAO,QAAQ,SAAS,OAAO,IAAI,IAAI,OAAO,OAAO,KAAA,CAAS;EAC9D,OAAO,eAAe,SAAS,OAAO,YAAY,IAAI,OAAO,eAAe,KAAA,CAAS;EACrF,OAAO,YAAY,SAAS,OAAO,SAAS,IAAI,OAAO,YAAY,KAAA,CAAS;EAC5E,OAAO,QAAQ,SAAS,OAAO,IAAI,IAAI,OAAO,OAAO,KAAA,CAAS;CAChE;CACA,OAAO;EAAE;EAAQ,MAAM,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,OAAO,KAAA;CAAU;AACzE;;AAKA,SAAgB,cAAc,MAAiC;CAC7D,IAAI,KAAK,eAAe,KAAA,GAAW,OAAO,KAAK,eAAe,KAAK,OAAO,WAAW,aAAa;CAClG,OAAO,KAAK,YAAY,YAAY,KAAK,OAAO,WAAW,aAAa;AAC1E;;AAGA,SAAgB,UAAU,IAAoB;CAC5C,OAAO,uBAAuB,KAAK,EAAE,CAAC,GAAG,MAAM;AACjD;AAEA,SAAgB,YAAY,IAAoB;CAC9C,OAAO,MAAM,IAAI,QAAQA,eAAAA,mBAAmB,KAAK,GAAG;AACtD;;AAGA,SAAgB,cAAc,QAA4B;CACxD,MAAM,UAAU,CACd,OAAO,SAAS,WAAW,KAAA,KAAa,IAAI,OAAO,QAAQ,UAC3D,OAAO,SAAS,OAAO,SAAS,OAAO,QAAQ,KACjD,CAAC,CAAC,OAAO,OAAO;CAChB,OAAO;EACL,OAAO,YAAY,SAAS,OAAO;EACnC,QAAQ,SAAS,KAAK,WAAW,QAAQ,KAAK,GAAG;EACjD,OAAO,UAAU,WAAW,OAAO;EACnC,OAAO,WAAW,WAAW,OAAO;CACtC,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,KAAK;AACf;AAEA,SAAgB,kBAAkB,OAAwB;CACxD,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK;AACjE;AAEA,SAAS,SAAS,MAAgC;CAChD,MAAM,EAAE,WAAW;CAanB,OAAO;EAAE,OAAO;EAAQ,MAAM;GAX5B,YAAY,KAAK;GACjB,YAAY,YAAY,KAAK,UAAU;GACvC,WAAW,cAAc,MAAM;GAC/B,OAAO,SAAS,UAAU,OAAO;GACjC,OAAO,YAAY,aAAa,OAAO;GACvC,KAAK,cAAc,eAAe,KAAK;GACvC,KAAK,SAAS,UAAU,KAAK;GAC7B,KAAK,SAAS,UAAU,KAAK;GAC7B,KAAK,SAAS,UAAU,KAAK;GAC7B,KAAK,YAAY,KAAA,KAAa,YAAY,KAAK,UAAU,KAAK,OAAO;EAEzC,CAAA,CAAM,OAAO,OAAO,CAAC,CAAC,KAAK,IAAI;CAAE;AACjE;AAEA,SAAS,YAAY,GAAwB;CAE3C,OAAO,GAAG;EADI,IAAI,EAAE;EAAW,EAAE;EAAQ,EAAE,eAAe,KAAA,KAAa,YAAY,EAAE,UAAU;CACrF,CAAA,CAAK,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,QAAQ,MAAM,EAAE,UAAU;AACzE;AAEA,SAAS,UAAU,GAAyB;CAC1C,MAAM,OAAO;EAAC,EAAE;EAAQ,EAAE;EAAM,EAAE;CAAG,CAAC,CAAC,QAAQ,SAAS,SAAS,KAAA,CAAS,CAAC,CAAC,KAAK,GAAG;CACpF,OAAO,IAAI,EAAE,KAAK,GAAG,OAAO,IAAI,SAAS,KAAK,EAAE,SAAS,MAAM,EAAE,WAAW;AAC9E;;AAGA,SAAgB,aAAa,MAAkC;CAC7D,OAAO;EACL,GAAI,KAAK,YAAY,KAAA,IAAY,CAAC;GAAE,OAAO;GAAW,MAAM,KAAK,UAAU,KAAK,SAAS,MAAM,CAAC;GAAG,MAAM;EAAO,CAAC,IAAI,CAAC;EACtH,GAAI,KAAK,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,IAAI,CAAC;EACzC,GAAI,KAAK,SAAS,SAAS,IAAI,CAAC;GAAE,OAAO;GAAY,MAAM,KAAK,SAAS,IAAI,WAAW,CAAC,CAAC,KAAK,IAAI;EAAE,CAAC,IAAI,CAAC;EAC3G,GAAI,KAAK,QAAQ,SAAS,IACtB,CAAC;GAAE,OAAO;GAAW,MAAM,KAAK,QAAQ,KAAK,MAAM,GAAG,EAAE,KAAK,GAAG,kBAAkB,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI;EAAE,CAAC,IAC3H,CAAC;EACL,GAAI,KAAK,OAAO,SAAS,IAAI,CAAC;GAAE,OAAO;GAAU,MAAM,KAAK,OAAO,IAAI,SAAS,CAAC,CAAC,KAAK,IAAI;EAAE,CAAC,IAAI,CAAC;CACrG;AACF"}
|
|
1
|
+
{"version":3,"file":"stepKind.cjs","names":["formatTestDuration"],"sources":["../../../src/data/verification/stepKind.ts"],"sourcesContent":["// The typed step-kind detail gavel's fixture verifier attaches to a node\n// (fixtures/verifier/report.go): `detail.step` names the kind and id, beside\n// the structured `wait`, `attempts`, `exports`, `outputs` and (for a\n// background Playwright watcher) `events`. Parsed here, once, so the detail\n// view and the copy brief read the same typed shape. A present-but-malformed\n// field is reported by path instead of being guessed at.\n\nimport type { BriefSection } from \"../test-runner\";\nimport { formatTestDuration } from \"../test-runner\";\nimport type { VerifyNode } from \"./verify-report\";\n\nexport type StepRef = { id: string; kind: string };\n\nexport type WaitPolicy = {\n until?: string;\n failWhen?: string;\n interval?: string;\n backoff?: { factor?: number; max?: string };\n jitter?: string;\n timeout?: string;\n};\n\nexport const WAIT_OUTCOMES = [\"satisfied\", \"failed\", \"timeout\"] as const;\nexport type WaitOutcome = (typeof WAIT_OUTCOMES)[number];\n\nexport type WaitDetail = {\n policy: WaitPolicy;\n outcome: WaitOutcome;\n durationMs: number;\n /** The CEL expression that decided the outcome: policy.failWhen when it fired, else policy.until. */\n expression?: string;\n /** Domain reason the wait ended unsatisfied; may span several lines. */\n cause?: string;\n outputs?: unknown;\n error?: string;\n trace?: string;\n};\n\nexport type StepAttempt = { attempt: number; status: string; error?: string; durationMs?: number; result?: VerifyNode };\n\nexport type StepExport = { name: string; value: unknown; step: string };\n\nexport const WATCHER_EVENT_TYPES = [\"alert\", \"console\", \"pageerror\", \"response\"] as const;\nexport type WatcherEventType = (typeof WATCHER_EVENT_TYPES)[number];\n\nexport type WatcherEvent = {\n type: WatcherEventType;\n text?: string;\n url?: string;\n status?: number;\n detail?: string;\n};\n\nexport type StepDetail = {\n step: StepRef;\n outputs?: unknown;\n exports: StepExport[];\n wait?: WaitDetail;\n attempts: StepAttempt[];\n events: WatcherEvent[];\n /** Whether the step runs in the background until teardown (a watcher). */\n background: boolean;\n /** Everything else in `node.detail` (cel_trace, run, recordings, …). */\n rest: Record<string, unknown>;\n};\n\nexport type StepDetailResult =\n | { kind: \"none\" }\n | { kind: \"step\"; step: StepDetail }\n | { kind: \"invalid\"; error: string };\n\nconst STEP_KEYS = new Set([\"step\", \"outputs\", \"exports\", \"wait\", \"attempts\", \"events\", \"background\"]);\n\nclass StepDetailError extends Error {}\n\nfunction fail(path: string, expectation: string): never {\n throw new StepDetailError(`${path} must be ${expectation}`);\n}\n\ntype Rec = Record<string, unknown>;\n\nconst isRecord = (value: unknown): value is Rec =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nfunction record(value: unknown, path: string): Rec {\n return isRecord(value) ? value : fail(path, \"an object\");\n}\n\nfunction list(value: unknown, path: string): unknown[] {\n return Array.isArray(value) ? value : fail(path, \"an array\");\n}\n\nfunction str(value: unknown, path: string): string {\n return typeof value === \"string\" ? value : fail(path, \"a string\");\n}\n\nfunction num(value: unknown, path: string): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fail(path, \"a number\");\n}\n\nfunction bool(value: unknown, path: string): boolean {\n return typeof value === \"boolean\" ? value : fail(path, \"a boolean\");\n}\n\nfunction oneOf<T extends string>(value: unknown, allowed: readonly T[], path: string): T {\n return allowed.includes(value as T)\n ? (value as T)\n : fail(path, `one of ${allowed.join(\", \")} (got ${JSON.stringify(value)})`);\n}\n\n/** `{ [key]: read(value) }` when the optional field is present, else `{}` — absent stays an absent key. */\nfunction optional<K extends string, T>(source: Rec, key: K, read: (value: unknown) => T): { [P in K]?: T } {\n return source[key] === undefined || source[key] === null ? {} : ({ [key]: read(source[key]) } as { [P in K]?: T });\n}\n\n/** Durations arrive as Go-style strings (\"15s\"); a bare number is nanoseconds like every other duration on the wire. */\nfunction durationText(value: unknown, path: string): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return formatTestDuration(value);\n return fail(path, \"a duration string or nanosecond number\");\n}\n\nfunction scalarText(value: unknown, path: string): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return String(value);\n return fail(path, \"a string or number\");\n}\n\nfunction readPolicy(value: unknown): WaitPolicy {\n const path = \"detail.wait.policy\";\n const policy = record(value, path);\n const backoff = (raw: unknown) => {\n const b = record(raw, `${path}.backoff`);\n return {\n ...optional(b, \"factor\", (v) => num(v, `${path}.backoff.factor`)),\n ...optional(b, \"max\", (v) => durationText(v, `${path}.backoff.max`)),\n };\n };\n return {\n ...optional(policy, \"until\", (v) => str(v, `${path}.until`)),\n ...optional(policy, \"failWhen\", (v) => str(v, `${path}.failWhen`)),\n ...optional(policy, \"interval\", (v) => durationText(v, `${path}.interval`)),\n ...optional(policy, \"backoff\", backoff),\n ...optional(policy, \"jitter\", (v) => scalarText(v, `${path}.jitter`)),\n ...optional(policy, \"timeout\", (v) => durationText(v, `${path}.timeout`)),\n };\n}\n\nfunction readWait(value: unknown): WaitDetail {\n const wait = record(value, \"detail.wait\");\n return {\n policy: readPolicy(wait.policy ?? {}),\n outcome: oneOf(wait.outcome, WAIT_OUTCOMES, \"detail.wait.outcome\"),\n durationMs: nonnegative(wait.durationMs, \"detail.wait.durationMs\"),\n ...(wait.outputs === undefined ? {} : { outputs: wait.outputs }),\n ...optional(wait, \"expression\", (v) => str(v, \"detail.wait.expression\")),\n ...optional(wait, \"cause\", (v) => str(v, \"detail.wait.cause\")),\n ...optional(wait, \"error\", (v) => str(v, \"detail.wait.error\")),\n ...optional(wait, \"trace\", (v) => str(v, \"detail.wait.trace\")),\n };\n}\n\nfunction nonnegative(value: unknown, path: string): number {\n const result = num(value, path);\n return result >= 0 ? result : fail(path, \"non-negative\");\n}\n\nfunction readAttemptResult(value: unknown, path: string): VerifyNode {\n const node = record(value, path);\n str(node.name, `${path}.name`);\n for (const key of [\"framework\", \"message\", \"command\", \"work_dir\", \"stdout\", \"stderr\"]) {\n if (node[key] !== undefined) str(node[key], `${path}.${key}`);\n }\n for (const key of [\"passed\", \"failed\", \"timed_out\", \"warned\", \"skipped\", \"pending\", \"running\"]) {\n if (node[key] !== undefined) bool(node[key], `${path}.${key}`);\n }\n if (node.duration !== undefined) nonnegative(node.duration, `${path}.duration`);\n if (node.detail !== undefined) record(node.detail, `${path}.detail`);\n if (node.children !== undefined) list(node.children, `${path}.children`).forEach((child, i) => readAttemptResult(child, `${path}.children[${i}]`));\n return { ...node, name: str(node.name, `${path}.name`) } as VerifyNode;\n}\n\nfunction readAttempt(value: unknown, index: number): StepAttempt {\n const path = `detail.attempts[${index}]`;\n const a = record(value, path);\n return {\n attempt: num(a.attempt, `${path}.attempt`),\n status: str(a.status, `${path}.status`),\n ...optional(a, \"error\", (v) => str(v, `${path}.error`)),\n ...optional(a, \"durationMs\", (v) => nonnegative(v, `${path}.durationMs`)),\n ...optional(a, \"result\", (v) => readAttemptResult(v, `${path}.result`)),\n };\n}\n\nfunction readAttempts(value: unknown): StepAttempt[] {\n const attempts = list(value, \"detail.attempts\").map(readAttempt);\n attempts.forEach((attempt, index) => {\n if (attempt.attempt !== index + 1) fail(`detail.attempts[${index}].attempt`, `the sequence number ${index + 1}`);\n });\n return attempts;\n}\n\nfunction readExports(value: unknown): StepExport[] {\n return Object.entries(record(value, \"detail.exports\")).map(([name, raw]) => {\n const path = `detail.exports.${name}`;\n const entry = record(raw, path);\n return { name, value: entry.value, step: str(entry.step, `${path}.step`) };\n });\n}\n\nfunction readEvent(value: unknown, index: number): WatcherEvent {\n const path = `detail.events[${index}]`;\n const e = record(value, path);\n return {\n type: oneOf(e.type, WATCHER_EVENT_TYPES, `${path}.type`),\n ...optional(e, \"text\", (v) => str(v, `${path}.text`)),\n ...optional(e, \"url\", (v) => str(v, `${path}.url`)),\n ...optional(e, \"status\", (v) => num(v, `${path}.status`)),\n ...optional(e, \"detail\", (v) => str(v, `${path}.detail`)),\n };\n}\n\nfunction readStep(detail: Rec): StepDetail {\n const ref = record(detail.step, \"detail.step\");\n const rest = Object.fromEntries(Object.entries(detail).filter(([key]) => !STEP_KEYS.has(key)));\n return {\n step: { id: str(ref.id, \"detail.step.id\"), kind: str(ref.kind, \"detail.step.kind\") },\n ...(detail.outputs === undefined ? {} : { outputs: detail.outputs }),\n exports: detail.exports == null ? [] : readExports(detail.exports),\n ...optional(detail, \"wait\", readWait),\n attempts: readAttempts(detail.attempts ?? []),\n events: list(detail.events ?? [], \"detail.events\").map(readEvent),\n background: bool(detail.background ?? false, \"detail.background\"),\n rest,\n };\n}\n\n/**\n * Whether `node.detail` carries a typed step (`detail.step`), and if so its\n * parsed contents. A node without `detail.step` is \"none\" whatever else its\n * detail holds; a `step` whose fields violate the contract is \"invalid\" with\n * the offending path, so the view can say so rather than render a guess.\n */\nexport function readStepDetail(detail: unknown): StepDetailResult {\n if (!isRecord(detail) || detail.step === undefined) return { kind: \"none\" };\n try {\n return { kind: \"step\", step: readStep(detail) };\n } catch (error) {\n if (error instanceof StepDetailError) return { kind: \"invalid\", error: error.message };\n throw error;\n }\n}\n\n/** The step detail when there is one, for matchers that only need to know. */\nexport function hasStepDetail(detail: unknown): boolean {\n return readStepDetail(detail).kind !== \"none\";\n}\n\n/** The fixtures.ExecutionNode fields gavel puts at the top of `node.detail`, shown as a header instead of raw JSON. */\nexport type ExecutionHeader = {\n kind?: string;\n state?: string;\n file?: string;\n sectionPath?: string;\n /** Zero-based row of the step within its section. */\n rowIndex?: number;\n line?: number;\n startedAt?: string;\n finishedAt?: string;\n /** Nanoseconds. */\n durationNs?: number;\n error?: string;\n};\n\nconst isString = (value: unknown): value is string => typeof value === \"string\";\nconst isNumber = (value: unknown): value is number => typeof value === \"number\" && Number.isFinite(value);\n\n/**\n * Splits the ExecutionNode fields (name, kind, state, origin, started_at,\n * finished_at, duration, error) off `detail` into a header, dropping the\n * internal `key`. A field of an unexpected type is not consumed — it stays in\n * `rest`, so it is visible in the raw block rather than silently hidden.\n */\nexport function splitExecutionDetail(detail: unknown): { header: ExecutionHeader; rest: unknown } {\n if (!isRecord(detail)) return { header: {}, rest: detail };\n const rest: Rec = { ...detail };\n delete rest.key;\n const take = <T>(key: string, guard: (value: unknown) => value is T): T | undefined => {\n const value = rest[key];\n if (!guard(value)) return undefined;\n delete rest[key];\n return value;\n };\n const header: ExecutionHeader = {};\n const assign = <K extends keyof ExecutionHeader>(field: K, value: ExecutionHeader[K] | undefined) => {\n if (value !== undefined) header[field] = value;\n };\n take(\"name\", isString);\n assign(\"kind\", take(\"kind\", isString));\n assign(\"state\", take(\"state\", isString));\n assign(\"startedAt\", take(\"started_at\", isString));\n assign(\"finishedAt\", take(\"finished_at\", isString));\n assign(\"durationNs\", take(\"duration\", isNumber));\n assign(\"error\", take(\"error\", isString));\n const origin = take(\"origin\", isRecord);\n if (origin) {\n assign(\"file\", isString(origin.file) ? origin.file : undefined);\n assign(\"sectionPath\", isString(origin.section_path) ? origin.section_path : undefined);\n assign(\"rowIndex\", isNumber(origin.row_index) ? origin.row_index : undefined);\n assign(\"line\", isNumber(origin.line) ? origin.line : undefined);\n }\n return { header, rest: Object.keys(rest).length > 0 ? rest : undefined };\n}\n\nexport type WaitCondition = \"until\" | \"failWhen\";\n\n/** Which of the wait's two conditions decided its outcome. `expression` is authoritative; older payloads without it are inferred from the outcome. */\nexport function waitDecidedBy(wait: WaitDetail): WaitCondition {\n if (wait.expression !== undefined) return wait.expression === wait.policy.failWhen ? \"failWhen\" : \"until\";\n return wait.outcome === \"failed\" && wait.policy.failWhen ? \"failWhen\" : \"until\";\n}\n\n/** `09:00:04` from an RFC 3339 timestamp, as written (no timezone conversion); anything else verbatim. */\nexport function clockTime(at: string): string {\n return /T(\\d{2}:\\d{2}:\\d{2})/.exec(at)?.[1] ?? at;\n}\n\nexport function formatDelay(ms: number): string {\n return ms <= 0 ? \"0ms\" : formatTestDuration(ms * 1e6);\n}\n\n/** `every 1s · backoff ×1.5 up to 10s · jitter ±20% · timeout 3m`, skipping what the policy leaves unset. */\nexport function policySummary(policy: WaitPolicy): string {\n const backoff = [\n policy.backoff?.factor !== undefined && `×${policy.backoff.factor}`,\n policy.backoff?.max && `up to ${policy.backoff.max}`,\n ].filter(Boolean);\n return [\n policy.interval && `every ${policy.interval}`,\n backoff.length > 0 && `backoff ${backoff.join(\" \")}`,\n policy.jitter && `jitter ±${policy.jitter}`,\n policy.timeout && `timeout ${policy.timeout}`,\n ]\n .filter(Boolean)\n .join(\" · \");\n}\n\nexport function formatExportValue(value: unknown): string {\n if (value === undefined) return \"\";\n return typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\nfunction waitCopy(wait: WaitDetail): BriefSection {\n const { policy } = wait;\n const lines = [\n `outcome: ${wait.outcome}`,\n `elapsed: ${formatDelay(wait.durationMs)}`,\n `policy: ${policySummary(policy)}`,\n policy.until && `until: ${policy.until}`,\n policy.failWhen && `failWhen: ${policy.failWhen}`,\n wait.expression && `decided by: ${wait.expression}`,\n wait.cause && `cause: ${wait.cause}`,\n wait.error && `error: ${wait.error}`,\n wait.trace && `trace: ${wait.trace}`,\n wait.outputs !== undefined && `outputs: ${JSON.stringify(wait.outputs)}`,\n ];\n return { title: \"Wait\", body: lines.filter(Boolean).join(\"\\n\") };\n}\n\nfunction attemptLine(a: StepAttempt): string {\n const head = [`#${a.attempt}`, a.status, a.durationMs !== undefined && formatDelay(a.durationMs)];\n return `${head.filter(Boolean).join(\" \")}${a.error ? ` — ${a.error}` : \"\"}`;\n}\n\nfunction eventLine(e: WatcherEvent): string {\n const body = [e.status, e.text, e.url].filter((part) => part !== undefined).join(\" \");\n return `[${e.type}]${body ? ` ${body}` : \"\"}${e.detail ? ` — ${e.detail}` : \"\"}`;\n}\n\n/** Brief sections for the \"Copy details\" button: wait trace, retry attempts, exports and watcher events. */\nexport function stepKindCopy(step: StepDetail): BriefSection[] {\n return [\n ...(step.outputs !== undefined ? [{ title: \"Outputs\", body: JSON.stringify(step.outputs, null, 2), lang: \"json\" }] : []),\n ...(step.wait ? [waitCopy(step.wait)] : []),\n ...(step.attempts.length > 0 ? [{ title: \"Attempts\", body: step.attempts.map(attemptLine).join(\"\\n\") }] : []),\n ...(step.exports.length > 0\n ? [{ title: \"Exports\", body: step.exports.map((e) => `${e.name}=${formatExportValue(e.value)} (from ${e.step})`).join(\"\\n\") }]\n : []),\n ...(step.events.length > 0 ? [{ title: \"Events\", body: step.events.map(eventLine).join(\"\\n\") }] : []),\n ];\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stepKind.d.ts","sourceRoot":"","sources":["../../../src/data/verification/stepKind.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,MAAM,OAAO,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,aAAa,6CAA8C,CAAC;AACzE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,qGAAqG;IACrG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAAE,CAAC;AAExH,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAExE,eAAO,MAAM,mBAAmB,wDAAyD,CAAC;AAC1F,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,0EAA0E;IAC1E,UAAU,EAAE,OAAO,CAAC;IACpB,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"stepKind.d.ts","sourceRoot":"","sources":["../../../src/data/verification/stepKind.ts"],"names":[],"mappings":"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"}
|
|
@@ -115,6 +115,7 @@ function readAttemptResult(value, path) {
|
|
|
115
115
|
"running"
|
|
116
116
|
]) if (node[key] !== void 0) bool(node[key], `${path}.${key}`);
|
|
117
117
|
if (node.duration !== void 0) nonnegative(node.duration, `${path}.duration`);
|
|
118
|
+
if (node.detail !== void 0) record(node.detail, `${path}.detail`);
|
|
118
119
|
if (node.children !== void 0) list(node.children, `${path}.children`).forEach((child, i) => readAttemptResult(child, `${path}.children[${i}]`));
|
|
119
120
|
return {
|
|
120
121
|
...node,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stepKind.js","names":[],"sources":["../../../src/data/verification/stepKind.ts"],"sourcesContent":["// The typed step-kind detail gavel's fixture verifier attaches to a node\n// (fixtures/verifier/report.go): `detail.step` names the kind and id, beside\n// the structured `wait`, `attempts`, `exports`, `outputs` and (for a\n// background Playwright watcher) `events`. Parsed here, once, so the detail\n// view and the copy brief read the same typed shape. A present-but-malformed\n// field is reported by path instead of being guessed at.\n\nimport type { BriefSection } from \"../test-runner\";\nimport { formatTestDuration } from \"../test-runner\";\nimport type { VerifyNode } from \"./verify-report\";\n\nexport type StepRef = { id: string; kind: string };\n\nexport type WaitPolicy = {\n until?: string;\n failWhen?: string;\n interval?: string;\n backoff?: { factor?: number; max?: string };\n jitter?: string;\n timeout?: string;\n};\n\nexport const WAIT_OUTCOMES = [\"satisfied\", \"failed\", \"timeout\"] as const;\nexport type WaitOutcome = (typeof WAIT_OUTCOMES)[number];\n\nexport type WaitDetail = {\n policy: WaitPolicy;\n outcome: WaitOutcome;\n durationMs: number;\n /** The CEL expression that decided the outcome: policy.failWhen when it fired, else policy.until. */\n expression?: string;\n /** Domain reason the wait ended unsatisfied; may span several lines. */\n cause?: string;\n outputs?: unknown;\n error?: string;\n trace?: string;\n};\n\nexport type StepAttempt = { attempt: number; status: string; error?: string; durationMs?: number; result?: VerifyNode };\n\nexport type StepExport = { name: string; value: unknown; step: string };\n\nexport const WATCHER_EVENT_TYPES = [\"alert\", \"console\", \"pageerror\", \"response\"] as const;\nexport type WatcherEventType = (typeof WATCHER_EVENT_TYPES)[number];\n\nexport type WatcherEvent = {\n type: WatcherEventType;\n text?: string;\n url?: string;\n status?: number;\n detail?: string;\n};\n\nexport type StepDetail = {\n step: StepRef;\n outputs?: unknown;\n exports: StepExport[];\n wait?: WaitDetail;\n attempts: StepAttempt[];\n events: WatcherEvent[];\n /** Whether the step runs in the background until teardown (a watcher). */\n background: boolean;\n /** Everything else in `node.detail` (cel_trace, run, recordings, …). */\n rest: Record<string, unknown>;\n};\n\nexport type StepDetailResult =\n | { kind: \"none\" }\n | { kind: \"step\"; step: StepDetail }\n | { kind: \"invalid\"; error: string };\n\nconst STEP_KEYS = new Set([\"step\", \"outputs\", \"exports\", \"wait\", \"attempts\", \"events\", \"background\"]);\n\nclass StepDetailError extends Error {}\n\nfunction fail(path: string, expectation: string): never {\n throw new StepDetailError(`${path} must be ${expectation}`);\n}\n\ntype Rec = Record<string, unknown>;\n\nconst isRecord = (value: unknown): value is Rec =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nfunction record(value: unknown, path: string): Rec {\n return isRecord(value) ? value : fail(path, \"an object\");\n}\n\nfunction list(value: unknown, path: string): unknown[] {\n return Array.isArray(value) ? value : fail(path, \"an array\");\n}\n\nfunction str(value: unknown, path: string): string {\n return typeof value === \"string\" ? value : fail(path, \"a string\");\n}\n\nfunction num(value: unknown, path: string): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fail(path, \"a number\");\n}\n\nfunction bool(value: unknown, path: string): boolean {\n return typeof value === \"boolean\" ? value : fail(path, \"a boolean\");\n}\n\nfunction oneOf<T extends string>(value: unknown, allowed: readonly T[], path: string): T {\n return allowed.includes(value as T)\n ? (value as T)\n : fail(path, `one of ${allowed.join(\", \")} (got ${JSON.stringify(value)})`);\n}\n\n/** `{ [key]: read(value) }` when the optional field is present, else `{}` — absent stays an absent key. */\nfunction optional<K extends string, T>(source: Rec, key: K, read: (value: unknown) => T): { [P in K]?: T } {\n return source[key] === undefined || source[key] === null ? {} : ({ [key]: read(source[key]) } as { [P in K]?: T });\n}\n\n/** Durations arrive as Go-style strings (\"15s\"); a bare number is nanoseconds like every other duration on the wire. */\nfunction durationText(value: unknown, path: string): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return formatTestDuration(value);\n return fail(path, \"a duration string or nanosecond number\");\n}\n\nfunction scalarText(value: unknown, path: string): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return String(value);\n return fail(path, \"a string or number\");\n}\n\nfunction readPolicy(value: unknown): WaitPolicy {\n const path = \"detail.wait.policy\";\n const policy = record(value, path);\n const backoff = (raw: unknown) => {\n const b = record(raw, `${path}.backoff`);\n return {\n ...optional(b, \"factor\", (v) => num(v, `${path}.backoff.factor`)),\n ...optional(b, \"max\", (v) => durationText(v, `${path}.backoff.max`)),\n };\n };\n return {\n ...optional(policy, \"until\", (v) => str(v, `${path}.until`)),\n ...optional(policy, \"failWhen\", (v) => str(v, `${path}.failWhen`)),\n ...optional(policy, \"interval\", (v) => durationText(v, `${path}.interval`)),\n ...optional(policy, \"backoff\", backoff),\n ...optional(policy, \"jitter\", (v) => scalarText(v, `${path}.jitter`)),\n ...optional(policy, \"timeout\", (v) => durationText(v, `${path}.timeout`)),\n };\n}\n\nfunction readWait(value: unknown): WaitDetail {\n const wait = record(value, \"detail.wait\");\n return {\n policy: readPolicy(wait.policy ?? {}),\n outcome: oneOf(wait.outcome, WAIT_OUTCOMES, \"detail.wait.outcome\"),\n durationMs: nonnegative(wait.durationMs, \"detail.wait.durationMs\"),\n ...(wait.outputs === undefined ? {} : { outputs: wait.outputs }),\n ...optional(wait, \"expression\", (v) => str(v, \"detail.wait.expression\")),\n ...optional(wait, \"cause\", (v) => str(v, \"detail.wait.cause\")),\n ...optional(wait, \"error\", (v) => str(v, \"detail.wait.error\")),\n ...optional(wait, \"trace\", (v) => str(v, \"detail.wait.trace\")),\n };\n}\n\nfunction nonnegative(value: unknown, path: string): number {\n const result = num(value, path);\n return result >= 0 ? result : fail(path, \"non-negative\");\n}\n\nfunction readAttemptResult(value: unknown, path: string): VerifyNode {\n const node = record(value, path);\n str(node.name, `${path}.name`);\n for (const key of [\"framework\", \"message\", \"command\", \"work_dir\", \"stdout\", \"stderr\"]) {\n if (node[key] !== undefined) str(node[key], `${path}.${key}`);\n }\n for (const key of [\"passed\", \"failed\", \"timed_out\", \"warned\", \"skipped\", \"pending\", \"running\"]) {\n if (node[key] !== undefined) bool(node[key], `${path}.${key}`);\n }\n if (node.duration !== undefined) nonnegative(node.duration, `${path}.duration`);\n if (node.children !== undefined) list(node.children, `${path}.children`).forEach((child, i) => readAttemptResult(child, `${path}.children[${i}]`));\n return { ...node, name: str(node.name, `${path}.name`) } as VerifyNode;\n}\n\nfunction readAttempt(value: unknown, index: number): StepAttempt {\n const path = `detail.attempts[${index}]`;\n const a = record(value, path);\n return {\n attempt: num(a.attempt, `${path}.attempt`),\n status: str(a.status, `${path}.status`),\n ...optional(a, \"error\", (v) => str(v, `${path}.error`)),\n ...optional(a, \"durationMs\", (v) => nonnegative(v, `${path}.durationMs`)),\n ...optional(a, \"result\", (v) => readAttemptResult(v, `${path}.result`)),\n };\n}\n\nfunction readAttempts(value: unknown): StepAttempt[] {\n const attempts = list(value, \"detail.attempts\").map(readAttempt);\n attempts.forEach((attempt, index) => {\n if (attempt.attempt !== index + 1) fail(`detail.attempts[${index}].attempt`, `the sequence number ${index + 1}`);\n });\n return attempts;\n}\n\nfunction readExports(value: unknown): StepExport[] {\n return Object.entries(record(value, \"detail.exports\")).map(([name, raw]) => {\n const path = `detail.exports.${name}`;\n const entry = record(raw, path);\n return { name, value: entry.value, step: str(entry.step, `${path}.step`) };\n });\n}\n\nfunction readEvent(value: unknown, index: number): WatcherEvent {\n const path = `detail.events[${index}]`;\n const e = record(value, path);\n return {\n type: oneOf(e.type, WATCHER_EVENT_TYPES, `${path}.type`),\n ...optional(e, \"text\", (v) => str(v, `${path}.text`)),\n ...optional(e, \"url\", (v) => str(v, `${path}.url`)),\n ...optional(e, \"status\", (v) => num(v, `${path}.status`)),\n ...optional(e, \"detail\", (v) => str(v, `${path}.detail`)),\n };\n}\n\nfunction readStep(detail: Rec): StepDetail {\n const ref = record(detail.step, \"detail.step\");\n const rest = Object.fromEntries(Object.entries(detail).filter(([key]) => !STEP_KEYS.has(key)));\n return {\n step: { id: str(ref.id, \"detail.step.id\"), kind: str(ref.kind, \"detail.step.kind\") },\n ...(detail.outputs === undefined ? {} : { outputs: detail.outputs }),\n exports: detail.exports == null ? [] : readExports(detail.exports),\n ...optional(detail, \"wait\", readWait),\n attempts: readAttempts(detail.attempts ?? []),\n events: list(detail.events ?? [], \"detail.events\").map(readEvent),\n background: bool(detail.background ?? false, \"detail.background\"),\n rest,\n };\n}\n\n/**\n * Whether `node.detail` carries a typed step (`detail.step`), and if so its\n * parsed contents. A node without `detail.step` is \"none\" whatever else its\n * detail holds; a `step` whose fields violate the contract is \"invalid\" with\n * the offending path, so the view can say so rather than render a guess.\n */\nexport function readStepDetail(detail: unknown): StepDetailResult {\n if (!isRecord(detail) || detail.step === undefined) return { kind: \"none\" };\n try {\n return { kind: \"step\", step: readStep(detail) };\n } catch (error) {\n if (error instanceof StepDetailError) return { kind: \"invalid\", error: error.message };\n throw error;\n }\n}\n\n/** The step detail when there is one, for matchers that only need to know. */\nexport function hasStepDetail(detail: unknown): boolean {\n return readStepDetail(detail).kind !== \"none\";\n}\n\n/** The fixtures.ExecutionNode fields gavel puts at the top of `node.detail`, shown as a header instead of raw JSON. */\nexport type ExecutionHeader = {\n kind?: string;\n state?: string;\n file?: string;\n sectionPath?: string;\n /** Zero-based row of the step within its section. */\n rowIndex?: number;\n line?: number;\n startedAt?: string;\n finishedAt?: string;\n /** Nanoseconds. */\n durationNs?: number;\n error?: string;\n};\n\nconst isString = (value: unknown): value is string => typeof value === \"string\";\nconst isNumber = (value: unknown): value is number => typeof value === \"number\" && Number.isFinite(value);\n\n/**\n * Splits the ExecutionNode fields (name, kind, state, origin, started_at,\n * finished_at, duration, error) off `detail` into a header, dropping the\n * internal `key`. A field of an unexpected type is not consumed — it stays in\n * `rest`, so it is visible in the raw block rather than silently hidden.\n */\nexport function splitExecutionDetail(detail: unknown): { header: ExecutionHeader; rest: unknown } {\n if (!isRecord(detail)) return { header: {}, rest: detail };\n const rest: Rec = { ...detail };\n delete rest.key;\n const take = <T>(key: string, guard: (value: unknown) => value is T): T | undefined => {\n const value = rest[key];\n if (!guard(value)) return undefined;\n delete rest[key];\n return value;\n };\n const header: ExecutionHeader = {};\n const assign = <K extends keyof ExecutionHeader>(field: K, value: ExecutionHeader[K] | undefined) => {\n if (value !== undefined) header[field] = value;\n };\n take(\"name\", isString);\n assign(\"kind\", take(\"kind\", isString));\n assign(\"state\", take(\"state\", isString));\n assign(\"startedAt\", take(\"started_at\", isString));\n assign(\"finishedAt\", take(\"finished_at\", isString));\n assign(\"durationNs\", take(\"duration\", isNumber));\n assign(\"error\", take(\"error\", isString));\n const origin = take(\"origin\", isRecord);\n if (origin) {\n assign(\"file\", isString(origin.file) ? origin.file : undefined);\n assign(\"sectionPath\", isString(origin.section_path) ? origin.section_path : undefined);\n assign(\"rowIndex\", isNumber(origin.row_index) ? origin.row_index : undefined);\n assign(\"line\", isNumber(origin.line) ? origin.line : undefined);\n }\n return { header, rest: Object.keys(rest).length > 0 ? rest : undefined };\n}\n\nexport type WaitCondition = \"until\" | \"failWhen\";\n\n/** Which of the wait's two conditions decided its outcome. `expression` is authoritative; older payloads without it are inferred from the outcome. */\nexport function waitDecidedBy(wait: WaitDetail): WaitCondition {\n if (wait.expression !== undefined) return wait.expression === wait.policy.failWhen ? \"failWhen\" : \"until\";\n return wait.outcome === \"failed\" && wait.policy.failWhen ? \"failWhen\" : \"until\";\n}\n\n/** `09:00:04` from an RFC 3339 timestamp, as written (no timezone conversion); anything else verbatim. */\nexport function clockTime(at: string): string {\n return /T(\\d{2}:\\d{2}:\\d{2})/.exec(at)?.[1] ?? at;\n}\n\nexport function formatDelay(ms: number): string {\n return ms <= 0 ? \"0ms\" : formatTestDuration(ms * 1e6);\n}\n\n/** `every 1s · backoff ×1.5 up to 10s · jitter ±20% · timeout 3m`, skipping what the policy leaves unset. */\nexport function policySummary(policy: WaitPolicy): string {\n const backoff = [\n policy.backoff?.factor !== undefined && `×${policy.backoff.factor}`,\n policy.backoff?.max && `up to ${policy.backoff.max}`,\n ].filter(Boolean);\n return [\n policy.interval && `every ${policy.interval}`,\n backoff.length > 0 && `backoff ${backoff.join(\" \")}`,\n policy.jitter && `jitter ±${policy.jitter}`,\n policy.timeout && `timeout ${policy.timeout}`,\n ]\n .filter(Boolean)\n .join(\" · \");\n}\n\nexport function formatExportValue(value: unknown): string {\n if (value === undefined) return \"\";\n return typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\nfunction waitCopy(wait: WaitDetail): BriefSection {\n const { policy } = wait;\n const lines = [\n `outcome: ${wait.outcome}`,\n `elapsed: ${formatDelay(wait.durationMs)}`,\n `policy: ${policySummary(policy)}`,\n policy.until && `until: ${policy.until}`,\n policy.failWhen && `failWhen: ${policy.failWhen}`,\n wait.expression && `decided by: ${wait.expression}`,\n wait.cause && `cause: ${wait.cause}`,\n wait.error && `error: ${wait.error}`,\n wait.trace && `trace: ${wait.trace}`,\n wait.outputs !== undefined && `outputs: ${JSON.stringify(wait.outputs)}`,\n ];\n return { title: \"Wait\", body: lines.filter(Boolean).join(\"\\n\") };\n}\n\nfunction attemptLine(a: StepAttempt): string {\n const head = [`#${a.attempt}`, a.status, a.durationMs !== undefined && formatDelay(a.durationMs)];\n return `${head.filter(Boolean).join(\" \")}${a.error ? ` — ${a.error}` : \"\"}`;\n}\n\nfunction eventLine(e: WatcherEvent): string {\n const body = [e.status, e.text, e.url].filter((part) => part !== undefined).join(\" \");\n return `[${e.type}]${body ? ` ${body}` : \"\"}${e.detail ? ` — ${e.detail}` : \"\"}`;\n}\n\n/** Brief sections for the \"Copy details\" button: wait trace, retry attempts, exports and watcher events. */\nexport function stepKindCopy(step: StepDetail): BriefSection[] {\n return [\n ...(step.outputs !== undefined ? [{ title: \"Outputs\", body: JSON.stringify(step.outputs, null, 2), lang: \"json\" }] : []),\n ...(step.wait ? [waitCopy(step.wait)] : []),\n ...(step.attempts.length > 0 ? [{ title: \"Attempts\", body: step.attempts.map(attemptLine).join(\"\\n\") }] : []),\n ...(step.exports.length > 0\n ? [{ title: \"Exports\", body: step.exports.map((e) => `${e.name}=${formatExportValue(e.value)} (from ${e.step})`).join(\"\\n\") }]\n : []),\n ...(step.events.length > 0 ? [{ title: \"Events\", body: step.events.map(eventLine).join(\"\\n\") }] : []),\n ];\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stepKind.js","names":[],"sources":["../../../src/data/verification/stepKind.ts"],"sourcesContent":["// The typed step-kind detail gavel's fixture verifier attaches to a node\n// (fixtures/verifier/report.go): `detail.step` names the kind and id, beside\n// the structured `wait`, `attempts`, `exports`, `outputs` and (for a\n// background Playwright watcher) `events`. Parsed here, once, so the detail\n// view and the copy brief read the same typed shape. A present-but-malformed\n// field is reported by path instead of being guessed at.\n\nimport type { BriefSection } from \"../test-runner\";\nimport { formatTestDuration } from \"../test-runner\";\nimport type { VerifyNode } from \"./verify-report\";\n\nexport type StepRef = { id: string; kind: string };\n\nexport type WaitPolicy = {\n until?: string;\n failWhen?: string;\n interval?: string;\n backoff?: { factor?: number; max?: string };\n jitter?: string;\n timeout?: string;\n};\n\nexport const WAIT_OUTCOMES = [\"satisfied\", \"failed\", \"timeout\"] as const;\nexport type WaitOutcome = (typeof WAIT_OUTCOMES)[number];\n\nexport type WaitDetail = {\n policy: WaitPolicy;\n outcome: WaitOutcome;\n durationMs: number;\n /** The CEL expression that decided the outcome: policy.failWhen when it fired, else policy.until. */\n expression?: string;\n /** Domain reason the wait ended unsatisfied; may span several lines. */\n cause?: string;\n outputs?: unknown;\n error?: string;\n trace?: string;\n};\n\nexport type StepAttempt = { attempt: number; status: string; error?: string; durationMs?: number; result?: VerifyNode };\n\nexport type StepExport = { name: string; value: unknown; step: string };\n\nexport const WATCHER_EVENT_TYPES = [\"alert\", \"console\", \"pageerror\", \"response\"] as const;\nexport type WatcherEventType = (typeof WATCHER_EVENT_TYPES)[number];\n\nexport type WatcherEvent = {\n type: WatcherEventType;\n text?: string;\n url?: string;\n status?: number;\n detail?: string;\n};\n\nexport type StepDetail = {\n step: StepRef;\n outputs?: unknown;\n exports: StepExport[];\n wait?: WaitDetail;\n attempts: StepAttempt[];\n events: WatcherEvent[];\n /** Whether the step runs in the background until teardown (a watcher). */\n background: boolean;\n /** Everything else in `node.detail` (cel_trace, run, recordings, …). */\n rest: Record<string, unknown>;\n};\n\nexport type StepDetailResult =\n | { kind: \"none\" }\n | { kind: \"step\"; step: StepDetail }\n | { kind: \"invalid\"; error: string };\n\nconst STEP_KEYS = new Set([\"step\", \"outputs\", \"exports\", \"wait\", \"attempts\", \"events\", \"background\"]);\n\nclass StepDetailError extends Error {}\n\nfunction fail(path: string, expectation: string): never {\n throw new StepDetailError(`${path} must be ${expectation}`);\n}\n\ntype Rec = Record<string, unknown>;\n\nconst isRecord = (value: unknown): value is Rec =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nfunction record(value: unknown, path: string): Rec {\n return isRecord(value) ? value : fail(path, \"an object\");\n}\n\nfunction list(value: unknown, path: string): unknown[] {\n return Array.isArray(value) ? value : fail(path, \"an array\");\n}\n\nfunction str(value: unknown, path: string): string {\n return typeof value === \"string\" ? value : fail(path, \"a string\");\n}\n\nfunction num(value: unknown, path: string): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fail(path, \"a number\");\n}\n\nfunction bool(value: unknown, path: string): boolean {\n return typeof value === \"boolean\" ? value : fail(path, \"a boolean\");\n}\n\nfunction oneOf<T extends string>(value: unknown, allowed: readonly T[], path: string): T {\n return allowed.includes(value as T)\n ? (value as T)\n : fail(path, `one of ${allowed.join(\", \")} (got ${JSON.stringify(value)})`);\n}\n\n/** `{ [key]: read(value) }` when the optional field is present, else `{}` — absent stays an absent key. */\nfunction optional<K extends string, T>(source: Rec, key: K, read: (value: unknown) => T): { [P in K]?: T } {\n return source[key] === undefined || source[key] === null ? {} : ({ [key]: read(source[key]) } as { [P in K]?: T });\n}\n\n/** Durations arrive as Go-style strings (\"15s\"); a bare number is nanoseconds like every other duration on the wire. */\nfunction durationText(value: unknown, path: string): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return formatTestDuration(value);\n return fail(path, \"a duration string or nanosecond number\");\n}\n\nfunction scalarText(value: unknown, path: string): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return String(value);\n return fail(path, \"a string or number\");\n}\n\nfunction readPolicy(value: unknown): WaitPolicy {\n const path = \"detail.wait.policy\";\n const policy = record(value, path);\n const backoff = (raw: unknown) => {\n const b = record(raw, `${path}.backoff`);\n return {\n ...optional(b, \"factor\", (v) => num(v, `${path}.backoff.factor`)),\n ...optional(b, \"max\", (v) => durationText(v, `${path}.backoff.max`)),\n };\n };\n return {\n ...optional(policy, \"until\", (v) => str(v, `${path}.until`)),\n ...optional(policy, \"failWhen\", (v) => str(v, `${path}.failWhen`)),\n ...optional(policy, \"interval\", (v) => durationText(v, `${path}.interval`)),\n ...optional(policy, \"backoff\", backoff),\n ...optional(policy, \"jitter\", (v) => scalarText(v, `${path}.jitter`)),\n ...optional(policy, \"timeout\", (v) => durationText(v, `${path}.timeout`)),\n };\n}\n\nfunction readWait(value: unknown): WaitDetail {\n const wait = record(value, \"detail.wait\");\n return {\n policy: readPolicy(wait.policy ?? {}),\n outcome: oneOf(wait.outcome, WAIT_OUTCOMES, \"detail.wait.outcome\"),\n durationMs: nonnegative(wait.durationMs, \"detail.wait.durationMs\"),\n ...(wait.outputs === undefined ? {} : { outputs: wait.outputs }),\n ...optional(wait, \"expression\", (v) => str(v, \"detail.wait.expression\")),\n ...optional(wait, \"cause\", (v) => str(v, \"detail.wait.cause\")),\n ...optional(wait, \"error\", (v) => str(v, \"detail.wait.error\")),\n ...optional(wait, \"trace\", (v) => str(v, \"detail.wait.trace\")),\n };\n}\n\nfunction nonnegative(value: unknown, path: string): number {\n const result = num(value, path);\n return result >= 0 ? result : fail(path, \"non-negative\");\n}\n\nfunction readAttemptResult(value: unknown, path: string): VerifyNode {\n const node = record(value, path);\n str(node.name, `${path}.name`);\n for (const key of [\"framework\", \"message\", \"command\", \"work_dir\", \"stdout\", \"stderr\"]) {\n if (node[key] !== undefined) str(node[key], `${path}.${key}`);\n }\n for (const key of [\"passed\", \"failed\", \"timed_out\", \"warned\", \"skipped\", \"pending\", \"running\"]) {\n if (node[key] !== undefined) bool(node[key], `${path}.${key}`);\n }\n if (node.duration !== undefined) nonnegative(node.duration, `${path}.duration`);\n if (node.detail !== undefined) record(node.detail, `${path}.detail`);\n if (node.children !== undefined) list(node.children, `${path}.children`).forEach((child, i) => readAttemptResult(child, `${path}.children[${i}]`));\n return { ...node, name: str(node.name, `${path}.name`) } as VerifyNode;\n}\n\nfunction readAttempt(value: unknown, index: number): StepAttempt {\n const path = `detail.attempts[${index}]`;\n const a = record(value, path);\n return {\n attempt: num(a.attempt, `${path}.attempt`),\n status: str(a.status, `${path}.status`),\n ...optional(a, \"error\", (v) => str(v, `${path}.error`)),\n ...optional(a, \"durationMs\", (v) => nonnegative(v, `${path}.durationMs`)),\n ...optional(a, \"result\", (v) => readAttemptResult(v, `${path}.result`)),\n };\n}\n\nfunction readAttempts(value: unknown): StepAttempt[] {\n const attempts = list(value, \"detail.attempts\").map(readAttempt);\n attempts.forEach((attempt, index) => {\n if (attempt.attempt !== index + 1) fail(`detail.attempts[${index}].attempt`, `the sequence number ${index + 1}`);\n });\n return attempts;\n}\n\nfunction readExports(value: unknown): StepExport[] {\n return Object.entries(record(value, \"detail.exports\")).map(([name, raw]) => {\n const path = `detail.exports.${name}`;\n const entry = record(raw, path);\n return { name, value: entry.value, step: str(entry.step, `${path}.step`) };\n });\n}\n\nfunction readEvent(value: unknown, index: number): WatcherEvent {\n const path = `detail.events[${index}]`;\n const e = record(value, path);\n return {\n type: oneOf(e.type, WATCHER_EVENT_TYPES, `${path}.type`),\n ...optional(e, \"text\", (v) => str(v, `${path}.text`)),\n ...optional(e, \"url\", (v) => str(v, `${path}.url`)),\n ...optional(e, \"status\", (v) => num(v, `${path}.status`)),\n ...optional(e, \"detail\", (v) => str(v, `${path}.detail`)),\n };\n}\n\nfunction readStep(detail: Rec): StepDetail {\n const ref = record(detail.step, \"detail.step\");\n const rest = Object.fromEntries(Object.entries(detail).filter(([key]) => !STEP_KEYS.has(key)));\n return {\n step: { id: str(ref.id, \"detail.step.id\"), kind: str(ref.kind, \"detail.step.kind\") },\n ...(detail.outputs === undefined ? {} : { outputs: detail.outputs }),\n exports: detail.exports == null ? [] : readExports(detail.exports),\n ...optional(detail, \"wait\", readWait),\n attempts: readAttempts(detail.attempts ?? []),\n events: list(detail.events ?? [], \"detail.events\").map(readEvent),\n background: bool(detail.background ?? false, \"detail.background\"),\n rest,\n };\n}\n\n/**\n * Whether `node.detail` carries a typed step (`detail.step`), and if so its\n * parsed contents. A node without `detail.step` is \"none\" whatever else its\n * detail holds; a `step` whose fields violate the contract is \"invalid\" with\n * the offending path, so the view can say so rather than render a guess.\n */\nexport function readStepDetail(detail: unknown): StepDetailResult {\n if (!isRecord(detail) || detail.step === undefined) return { kind: \"none\" };\n try {\n return { kind: \"step\", step: readStep(detail) };\n } catch (error) {\n if (error instanceof StepDetailError) return { kind: \"invalid\", error: error.message };\n throw error;\n }\n}\n\n/** The step detail when there is one, for matchers that only need to know. */\nexport function hasStepDetail(detail: unknown): boolean {\n return readStepDetail(detail).kind !== \"none\";\n}\n\n/** The fixtures.ExecutionNode fields gavel puts at the top of `node.detail`, shown as a header instead of raw JSON. */\nexport type ExecutionHeader = {\n kind?: string;\n state?: string;\n file?: string;\n sectionPath?: string;\n /** Zero-based row of the step within its section. */\n rowIndex?: number;\n line?: number;\n startedAt?: string;\n finishedAt?: string;\n /** Nanoseconds. */\n durationNs?: number;\n error?: string;\n};\n\nconst isString = (value: unknown): value is string => typeof value === \"string\";\nconst isNumber = (value: unknown): value is number => typeof value === \"number\" && Number.isFinite(value);\n\n/**\n * Splits the ExecutionNode fields (name, kind, state, origin, started_at,\n * finished_at, duration, error) off `detail` into a header, dropping the\n * internal `key`. A field of an unexpected type is not consumed — it stays in\n * `rest`, so it is visible in the raw block rather than silently hidden.\n */\nexport function splitExecutionDetail(detail: unknown): { header: ExecutionHeader; rest: unknown } {\n if (!isRecord(detail)) return { header: {}, rest: detail };\n const rest: Rec = { ...detail };\n delete rest.key;\n const take = <T>(key: string, guard: (value: unknown) => value is T): T | undefined => {\n const value = rest[key];\n if (!guard(value)) return undefined;\n delete rest[key];\n return value;\n };\n const header: ExecutionHeader = {};\n const assign = <K extends keyof ExecutionHeader>(field: K, value: ExecutionHeader[K] | undefined) => {\n if (value !== undefined) header[field] = value;\n };\n take(\"name\", isString);\n assign(\"kind\", take(\"kind\", isString));\n assign(\"state\", take(\"state\", isString));\n assign(\"startedAt\", take(\"started_at\", isString));\n assign(\"finishedAt\", take(\"finished_at\", isString));\n assign(\"durationNs\", take(\"duration\", isNumber));\n assign(\"error\", take(\"error\", isString));\n const origin = take(\"origin\", isRecord);\n if (origin) {\n assign(\"file\", isString(origin.file) ? origin.file : undefined);\n assign(\"sectionPath\", isString(origin.section_path) ? origin.section_path : undefined);\n assign(\"rowIndex\", isNumber(origin.row_index) ? origin.row_index : undefined);\n assign(\"line\", isNumber(origin.line) ? origin.line : undefined);\n }\n return { header, rest: Object.keys(rest).length > 0 ? rest : undefined };\n}\n\nexport type WaitCondition = \"until\" | \"failWhen\";\n\n/** Which of the wait's two conditions decided its outcome. `expression` is authoritative; older payloads without it are inferred from the outcome. */\nexport function waitDecidedBy(wait: WaitDetail): WaitCondition {\n if (wait.expression !== undefined) return wait.expression === wait.policy.failWhen ? \"failWhen\" : \"until\";\n return wait.outcome === \"failed\" && wait.policy.failWhen ? \"failWhen\" : \"until\";\n}\n\n/** `09:00:04` from an RFC 3339 timestamp, as written (no timezone conversion); anything else verbatim. */\nexport function clockTime(at: string): string {\n return /T(\\d{2}:\\d{2}:\\d{2})/.exec(at)?.[1] ?? at;\n}\n\nexport function formatDelay(ms: number): string {\n return ms <= 0 ? \"0ms\" : formatTestDuration(ms * 1e6);\n}\n\n/** `every 1s · backoff ×1.5 up to 10s · jitter ±20% · timeout 3m`, skipping what the policy leaves unset. */\nexport function policySummary(policy: WaitPolicy): string {\n const backoff = [\n policy.backoff?.factor !== undefined && `×${policy.backoff.factor}`,\n policy.backoff?.max && `up to ${policy.backoff.max}`,\n ].filter(Boolean);\n return [\n policy.interval && `every ${policy.interval}`,\n backoff.length > 0 && `backoff ${backoff.join(\" \")}`,\n policy.jitter && `jitter ±${policy.jitter}`,\n policy.timeout && `timeout ${policy.timeout}`,\n ]\n .filter(Boolean)\n .join(\" · \");\n}\n\nexport function formatExportValue(value: unknown): string {\n if (value === undefined) return \"\";\n return typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\nfunction waitCopy(wait: WaitDetail): BriefSection {\n const { policy } = wait;\n const lines = [\n `outcome: ${wait.outcome}`,\n `elapsed: ${formatDelay(wait.durationMs)}`,\n `policy: ${policySummary(policy)}`,\n policy.until && `until: ${policy.until}`,\n policy.failWhen && `failWhen: ${policy.failWhen}`,\n wait.expression && `decided by: ${wait.expression}`,\n wait.cause && `cause: ${wait.cause}`,\n wait.error && `error: ${wait.error}`,\n wait.trace && `trace: ${wait.trace}`,\n wait.outputs !== undefined && `outputs: ${JSON.stringify(wait.outputs)}`,\n ];\n return { title: \"Wait\", body: lines.filter(Boolean).join(\"\\n\") };\n}\n\nfunction attemptLine(a: StepAttempt): string {\n const head = [`#${a.attempt}`, a.status, a.durationMs !== undefined && formatDelay(a.durationMs)];\n return `${head.filter(Boolean).join(\" \")}${a.error ? ` — ${a.error}` : \"\"}`;\n}\n\nfunction eventLine(e: WatcherEvent): string {\n const body = [e.status, e.text, e.url].filter((part) => part !== undefined).join(\" \");\n return `[${e.type}]${body ? ` ${body}` : \"\"}${e.detail ? ` — ${e.detail}` : \"\"}`;\n}\n\n/** Brief sections for the \"Copy details\" button: wait trace, retry attempts, exports and watcher events. */\nexport function stepKindCopy(step: StepDetail): BriefSection[] {\n return [\n ...(step.outputs !== undefined ? [{ title: \"Outputs\", body: JSON.stringify(step.outputs, null, 2), lang: \"json\" }] : []),\n ...(step.wait ? [waitCopy(step.wait)] : []),\n ...(step.attempts.length > 0 ? [{ title: \"Attempts\", body: step.attempts.map(attemptLine).join(\"\\n\") }] : []),\n ...(step.exports.length > 0\n ? [{ title: \"Exports\", body: step.exports.map((e) => `${e.name}=${formatExportValue(e.value)} (from ${e.step})`).join(\"\\n\") }]\n : []),\n ...(step.events.length > 0 ? [{ title: \"Events\", body: step.events.map(eventLine).join(\"\\n\") }] : []),\n ];\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_utils = require("../../lib/utils.cjs");
|
|
2
|
+
const require_UiHourglass = require("../../icons/components/UiHourglass.cjs");
|
|
2
3
|
const require_button = require("../../components/button.cjs");
|
|
3
4
|
const require_Badge = require("../Badge.cjs");
|
|
4
5
|
const require_JsonView = require("../JsonView.cjs");
|
|
@@ -22,6 +23,21 @@ function Section({ name, title, aside, children }) {
|
|
|
22
23
|
}), children]
|
|
23
24
|
});
|
|
24
25
|
}
|
|
26
|
+
/** The host's answerable form for a step waiting on a person. */
|
|
27
|
+
function StepPendingFormSection({ children }) {
|
|
28
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Section, {
|
|
29
|
+
name: "pending-form",
|
|
30
|
+
title: "Form",
|
|
31
|
+
aside: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Badge.Badge, {
|
|
32
|
+
tone: "warning",
|
|
33
|
+
size: "xs",
|
|
34
|
+
icon: require_UiHourglass.UiHourglass,
|
|
35
|
+
clickToCopy: false,
|
|
36
|
+
children: "Awaiting answer"
|
|
37
|
+
}),
|
|
38
|
+
children
|
|
39
|
+
});
|
|
40
|
+
}
|
|
25
41
|
var OUTCOME_BADGE = {
|
|
26
42
|
satisfied: {
|
|
27
43
|
label: "Satisfied",
|
|
@@ -405,6 +421,7 @@ exports.FailureCallout = FailureCallout;
|
|
|
405
421
|
exports.MalformedStepDetail = MalformedStepDetail;
|
|
406
422
|
exports.StepKindSections = StepKindSections;
|
|
407
423
|
exports.StepOutputs = StepOutputs;
|
|
424
|
+
exports.StepPendingFormSection = StepPendingFormSection;
|
|
408
425
|
exports.StepSourceSection = StepSourceSection;
|
|
409
426
|
exports.StepWait = StepWait;
|
|
410
427
|
|