@shivaedev/work-fleet 0.2.1 → 0.4.0
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/CHANGELOG.md +55 -0
- package/README.md +61 -19
- package/dist/DispatchRequest.d.ts +13 -0
- package/dist/DispatchRequest.d.ts.map +1 -0
- package/dist/DispatchRequest.js +12 -0
- package/dist/DispatchRequest.js.map +1 -0
- package/dist/admit.d.ts +11 -0
- package/dist/admit.d.ts.map +1 -1
- package/dist/attention.d.ts +1 -0
- package/dist/attention.d.ts.map +1 -1
- package/dist/attention.js +4 -0
- package/dist/attention.js.map +1 -1
- package/dist/board/fleetField.d.ts +1 -0
- package/dist/board/fleetField.d.ts.map +1 -1
- package/dist/board/fleetField.js +4 -0
- package/dist/board/fleetField.js.map +1 -1
- package/dist/board/markdown.d.ts.map +1 -1
- package/dist/board/markdown.js +7 -2
- package/dist/board/markdown.js.map +1 -1
- package/dist/board/publish.d.ts +2 -0
- package/dist/board/publish.d.ts.map +1 -1
- package/dist/board/publishReport.d.ts +1 -0
- package/dist/board/publishReport.d.ts.map +1 -1
- package/dist/board/readPass.d.ts +1 -0
- package/dist/board/readPass.d.ts.map +1 -1
- package/dist/cli.js +13 -6
- package/dist/cli.js.map +1 -1
- package/dist/engine/abandonStalled.d.ts +1171 -1004
- package/dist/engine/abandonStalled.d.ts.map +1 -1
- package/dist/engine/admissionOrder.d.ts +1091 -0
- package/dist/engine/admissionOrder.d.ts.map +1 -0
- package/dist/engine/admissionOrder.js +15 -0
- package/dist/engine/admissionOrder.js.map +1 -0
- package/dist/engine/applyResolution.d.ts +20 -0
- package/dist/engine/applyResolution.d.ts.map +1 -1
- package/dist/engine/approveBrief.d.ts +31 -0
- package/dist/engine/approveBrief.d.ts.map +1 -1
- package/dist/engine/authorizeResolution.d.ts +1160 -1003
- package/dist/engine/authorizeResolution.d.ts.map +1 -1
- package/dist/engine/boardBrief.d.ts +32 -0
- package/dist/engine/boardBrief.d.ts.map +1 -1
- package/dist/engine/capacityRetry.d.ts +3488 -3007
- package/dist/engine/capacityRetry.d.ts.map +1 -1
- package/dist/engine/closeDecisions.d.ts +20 -0
- package/dist/engine/closeDecisions.d.ts.map +1 -1
- package/dist/engine/completeBoardWork.d.ts +20 -0
- package/dist/engine/completeBoardWork.d.ts.map +1 -1
- package/dist/engine/completeReport.d.ts +21 -0
- package/dist/engine/completeReport.d.ts.map +1 -1
- package/dist/engine/continueCommand.d.ts +10 -0
- package/dist/engine/continueCommand.d.ts.map +1 -1
- package/dist/engine/continueWorker.d.ts +20 -0
- package/dist/engine/continueWorker.d.ts.map +1 -1
- package/dist/engine/deliverPendingAnswers.d.ts +1085 -898
- package/dist/engine/deliverPendingAnswers.d.ts.map +1 -1
- package/dist/engine/dispatchCommand.d.ts +14 -1
- package/dist/engine/dispatchCommand.d.ts.map +1 -1
- package/dist/engine/dispatchCommand.js +25 -5
- package/dist/engine/dispatchCommand.js.map +1 -1
- package/dist/engine/ensureDecisionOwner.d.ts +20 -0
- package/dist/engine/ensureDecisionOwner.d.ts.map +1 -1
- package/dist/engine/ensurePublication.d.ts +20 -0
- package/dist/engine/ensurePublication.d.ts.map +1 -1
- package/dist/engine/failureContext.d.ts +1 -0
- package/dist/engine/failureContext.d.ts.map +1 -1
- package/dist/engine/failureContext.js.map +1 -1
- package/dist/engine/failureMessage.js +11 -1
- package/dist/engine/failureMessage.js.map +1 -1
- package/dist/engine/health.d.ts +10 -0
- package/dist/engine/health.d.ts.map +1 -1
- package/dist/engine/inspectRenewal.d.ts +21 -0
- package/dist/engine/inspectRenewal.d.ts.map +1 -1
- package/dist/engine/launchInput.d.ts +10 -0
- package/dist/engine/launchInput.d.ts.map +1 -1
- package/dist/engine/launchReceipt.d.ts +10 -0
- package/dist/engine/launchReceipt.d.ts.map +1 -1
- package/dist/engine/localOnlyCriteria.d.ts +1 -0
- package/dist/engine/localOnlyCriteria.d.ts.map +1 -1
- package/dist/engine/localOnlyCriteria.js +5 -1
- package/dist/engine/localOnlyCriteria.js.map +1 -1
- package/dist/engine/makeAdopt.d.ts +21 -0
- package/dist/engine/makeAdopt.d.ts.map +1 -1
- package/dist/engine/makeAdvance.d.ts +10 -0
- package/dist/engine/makeAdvance.d.ts.map +1 -1
- package/dist/engine/makeDeliver.d.ts +20 -0
- package/dist/engine/makeDeliver.d.ts.map +1 -1
- package/dist/engine/makeHuman.d.ts +20 -0
- package/dist/engine/makeHuman.d.ts.map +1 -1
- package/dist/engine/makeLaunch.d.ts +20 -0
- package/dist/engine/makeLaunch.d.ts.map +1 -1
- package/dist/engine/makeLaunch.js +4 -13
- package/dist/engine/makeLaunch.js.map +1 -1
- package/dist/engine/makeObserve.d.ts +20 -0
- package/dist/engine/makeObserve.d.ts.map +1 -1
- package/dist/engine/makeReview.d.ts +21 -0
- package/dist/engine/makeReview.d.ts.map +1 -1
- package/dist/engine/makeState.d.ts +1164 -1010
- package/dist/engine/makeState.d.ts.map +1 -1
- package/dist/engine/makeState.js +19 -11
- package/dist/engine/makeState.js.map +1 -1
- package/dist/engine/makeValidate.d.ts +21 -0
- package/dist/engine/makeValidate.d.ts.map +1 -1
- package/dist/engine/mergeReadiness.d.ts +1425 -1764
- package/dist/engine/mergeReadiness.d.ts.map +1 -1
- package/dist/engine/mergeReadiness.js +3 -4
- package/dist/engine/mergeReadiness.js.map +1 -1
- package/dist/engine/observeDeliveryFailure.d.ts +1170 -1003
- package/dist/engine/observeDeliveryFailure.d.ts.map +1 -1
- package/dist/engine/observeRenewal.d.ts +33 -0
- package/dist/engine/observeRenewal.d.ts.map +1 -1
- package/dist/engine/obtainReview.d.ts +11 -0
- package/dist/engine/obtainReview.d.ts.map +1 -1
- package/dist/engine/obtainReview.js +2 -1
- package/dist/engine/obtainReview.js.map +1 -1
- package/dist/engine/operationRecord.d.ts +1898 -1779
- package/dist/engine/operationRecord.d.ts.map +1 -1
- package/dist/engine/persistTerminalReceipts.d.ts +20 -0
- package/dist/engine/persistTerminalReceipts.d.ts.map +1 -1
- package/dist/engine/prepareCommand.d.ts +10 -0
- package/dist/engine/prepareCommand.d.ts.map +1 -1
- package/dist/engine/prepareCommand.js +1 -1
- package/dist/engine/prepareCommand.js.map +1 -1
- package/dist/engine/queueAnswerCommand.d.ts +10 -0
- package/dist/engine/queueAnswerCommand.d.ts.map +1 -1
- package/dist/engine/readOrContinueReview.d.ts +11 -0
- package/dist/engine/readOrContinueReview.d.ts.map +1 -1
- package/dist/engine/readOrContinueReview.js +2 -1
- package/dist/engine/readOrContinueReview.js.map +1 -1
- package/dist/engine/readResolution.d.ts +1 -0
- package/dist/engine/readResolution.d.ts.map +1 -1
- package/dist/engine/readRetry.d.ts +2345 -2010
- package/dist/engine/readRetry.d.ts.map +1 -1
- package/dist/engine/readRetry.js +22 -2
- package/dist/engine/readRetry.js.map +1 -1
- package/dist/engine/reassignCommand.d.ts +10 -0
- package/dist/engine/reassignCommand.d.ts.map +1 -1
- package/dist/engine/reconcileAttempt.d.ts +12 -1
- package/dist/engine/reconcileAttempt.d.ts.map +1 -1
- package/dist/engine/reconcileAttempt.js +2 -1
- package/dist/engine/reconcileAttempt.js.map +1 -1
- package/dist/engine/reconcileCommand.d.ts +10 -0
- package/dist/engine/reconcileCommand.d.ts.map +1 -1
- package/dist/engine/recordResponseCommand.d.ts +551 -0
- package/dist/engine/recordResponseCommand.d.ts.map +1 -0
- package/dist/engine/recordResponseCommand.js +30 -0
- package/dist/engine/recordResponseCommand.js.map +1 -0
- package/dist/engine/recoverStall.d.ts +1172 -1004
- package/dist/engine/recoverStall.d.ts.map +1 -1
- package/dist/engine/recoverStall.js +1 -1
- package/dist/engine/recoverStall.js.map +1 -1
- package/dist/engine/recoverUnobservable.d.ts +1172 -1004
- package/dist/engine/recoverUnobservable.d.ts.map +1 -1
- package/dist/engine/refreshBrief.d.ts +2344 -2009
- package/dist/engine/refreshBrief.d.ts.map +1 -1
- package/dist/engine/refreshReviewResult.d.ts +21 -0
- package/dist/engine/refreshReviewResult.d.ts.map +1 -1
- package/dist/engine/releaseClosedPreparation.d.ts +1171 -1003
- package/dist/engine/releaseClosedPreparation.d.ts.map +1 -1
- package/dist/engine/releaseExecution.d.ts +1170 -1003
- package/dist/engine/releaseExecution.d.ts.map +1 -1
- package/dist/engine/releaseFinishedWork.d.ts +10 -0
- package/dist/engine/releaseFinishedWork.d.ts.map +1 -1
- package/dist/engine/repository.d.ts +1115 -1003
- package/dist/engine/repository.d.ts.map +1 -1
- package/dist/engine/repository.js +12 -12
- package/dist/engine/repository.js.map +1 -1
- package/dist/engine/requestConflictRepair.d.ts +1170 -1003
- package/dist/engine/requestConflictRepair.d.ts.map +1 -1
- package/dist/engine/requestRework.d.ts +20 -0
- package/dist/engine/requestRework.d.ts.map +1 -1
- package/dist/engine/resolveCommand.d.ts +10 -0
- package/dist/engine/resolveCommand.d.ts.map +1 -1
- package/dist/engine/resolveExecution.d.ts +1170 -1003
- package/dist/engine/resolveExecution.d.ts.map +1 -1
- package/dist/engine/resumeAttempt.d.ts +1171 -1003
- package/dist/engine/resumeAttempt.d.ts.map +1 -1
- package/dist/engine/retireUnacknowledged.d.ts +20 -0
- package/dist/engine/retireUnacknowledged.d.ts.map +1 -1
- package/dist/engine/retryTerminal.d.ts +1160 -1003
- package/dist/engine/retryTerminal.d.ts.map +1 -1
- package/dist/engine/saveLaunch.d.ts +10598 -0
- package/dist/engine/saveLaunch.d.ts.map +1 -0
- package/dist/engine/saveLaunch.js +30 -0
- package/dist/engine/saveLaunch.js.map +1 -0
- package/dist/engine/scheduler.d.ts +21 -1
- package/dist/engine/scheduler.d.ts.map +1 -1
- package/dist/engine/scheduler.js +3 -5
- package/dist/engine/scheduler.js.map +1 -1
- package/dist/engine/sessionCleanup.d.ts +20 -0
- package/dist/engine/sessionCleanup.d.ts.map +1 -1
- package/dist/engine/settleMergedDelivery.d.ts +1170 -1003
- package/dist/engine/settleMergedDelivery.d.ts.map +1 -1
- package/dist/engine/steerBrief.d.ts +1075 -898
- package/dist/engine/steerBrief.d.ts.map +1 -1
- package/dist/engine/submissionFailure.d.ts +1150 -1003
- package/dist/engine/submissionFailure.d.ts.map +1 -1
- package/dist/engine/submitLaunch.d.ts +1160 -1003
- package/dist/engine/submitLaunch.d.ts.map +1 -1
- package/dist/engine/views.d.ts.map +1 -1
- package/dist/engine/views.js +4 -0
- package/dist/engine/views.js.map +1 -1
- package/dist/engine/workerReport.d.ts +30 -0
- package/dist/engine/workerReport.d.ts.map +1 -1
- package/dist/fleet.d.ts +2716 -983
- package/dist/fleet.d.ts.map +1 -1
- package/dist/fleet.js +4 -0
- package/dist/fleet.js.map +1 -1
- package/dist/host/actionCommands.d.ts.map +1 -1
- package/dist/host/actionCommands.js +7 -6
- package/dist/host/actionCommands.js.map +1 -1
- package/dist/host/admission.d.ts +24 -1
- package/dist/host/admission.d.ts.map +1 -1
- package/dist/host/admission.js +2 -2
- package/dist/host/admission.js.map +1 -1
- package/dist/host/answerWork.d.ts +12 -2
- package/dist/host/answerWork.d.ts.map +1 -1
- package/dist/host/answerWork.js +19 -23
- package/dist/host/answerWork.js.map +1 -1
- package/dist/host/cliOptions.d.ts +1 -1
- package/dist/host/cliOptions.d.ts.map +1 -1
- package/dist/host/cliOptions.js +1 -1
- package/dist/host/cliOptions.js.map +1 -1
- package/dist/host/commands.d.ts +28 -4
- package/dist/host/commands.d.ts.map +1 -1
- package/dist/host/commands.js +19 -5
- package/dist/host/commands.js.map +1 -1
- package/dist/host/config.d.ts +20 -5
- package/dist/host/config.d.ts.map +1 -1
- package/dist/host/config.js +17 -19
- package/dist/host/config.js.map +1 -1
- package/dist/host/configFile.d.ts +66 -0
- package/dist/host/configFile.d.ts.map +1 -0
- package/dist/host/configFile.js +37 -0
- package/dist/host/configFile.js.map +1 -0
- package/dist/host/configSettings.d.ts +488 -0
- package/dist/host/configSettings.d.ts.map +1 -0
- package/dist/host/configSettings.js +115 -0
- package/dist/host/configSettings.js.map +1 -0
- package/dist/host/daemon.d.ts +881 -1185
- package/dist/host/daemon.d.ts.map +1 -1
- package/dist/host/daemon.js +2 -1
- package/dist/host/daemon.js.map +1 -1
- package/dist/host/daemonClient.d.ts +301 -605
- package/dist/host/daemonClient.d.ts.map +1 -1
- package/dist/host/daemonClient.js +28 -7
- package/dist/host/daemonClient.js.map +1 -1
- package/dist/host/daemonContract.d.ts +1973 -3075
- package/dist/host/daemonContract.d.ts.map +1 -1
- package/dist/host/daemonContract.js +12 -4
- package/dist/host/daemonContract.js.map +1 -1
- package/dist/host/daemonDiagnostics.d.ts.map +1 -1
- package/dist/host/daemonDiagnostics.js +9 -3
- package/dist/host/daemonDiagnostics.js.map +1 -1
- package/dist/host/daemonHandlers.d.ts +2 -1
- package/dist/host/daemonHandlers.d.ts.map +1 -1
- package/dist/host/daemonHandlers.js +20 -7
- package/dist/host/daemonHandlers.js.map +1 -1
- package/dist/host/daemonSnapshots.d.ts.map +1 -1
- package/dist/host/daemonSnapshots.js +21 -1
- package/dist/host/daemonSnapshots.js.map +1 -1
- package/dist/host/dispatchRequests.d.ts +30 -0
- package/dist/host/dispatchRequests.d.ts.map +1 -0
- package/dist/host/dispatchRequests.js +40 -0
- package/dist/host/dispatchRequests.js.map +1 -0
- package/dist/host/follow.js +1 -1
- package/dist/host/follow.js.map +1 -1
- package/dist/host/followState.d.ts.map +1 -1
- package/dist/host/followState.js +5 -4
- package/dist/host/followState.js.map +1 -1
- package/dist/host/github.d.ts +5 -6
- package/dist/host/github.d.ts.map +1 -1
- package/dist/host/github.js +3 -4
- package/dist/host/github.js.map +1 -1
- package/dist/host/githubApi.d.ts +15 -0
- package/dist/host/githubApi.d.ts.map +1 -0
- package/dist/host/githubApi.js +117 -0
- package/dist/host/githubApi.js.map +1 -0
- package/dist/host/githubChecks.d.ts +13 -3
- package/dist/host/githubChecks.d.ts.map +1 -1
- package/dist/host/githubChecks.js +5 -5
- package/dist/host/githubChecks.js.map +1 -1
- package/dist/host/githubDelivery.d.ts +13 -1
- package/dist/host/githubDelivery.d.ts.map +1 -1
- package/dist/host/githubDelivery.js +39 -6
- package/dist/host/githubDelivery.js.map +1 -1
- package/dist/host/githubRateLimit.d.ts +23 -0
- package/dist/host/githubRateLimit.d.ts.map +1 -0
- package/dist/host/githubRateLimit.js +70 -0
- package/dist/host/githubRateLimit.js.map +1 -0
- package/dist/host/githubRequiredChecks.d.ts +1 -2
- package/dist/host/githubRequiredChecks.d.ts.map +1 -1
- package/dist/host/githubRequiredChecks.js +2 -2
- package/dist/host/githubRequiredChecks.js.map +1 -1
- package/dist/host/githubResponse.d.ts +10 -0
- package/dist/host/githubResponse.d.ts.map +1 -0
- package/dist/host/githubResponse.js +29 -0
- package/dist/host/githubResponse.js.map +1 -0
- package/dist/host/githubResult.d.ts +3 -2
- package/dist/host/githubResult.d.ts.map +1 -1
- package/dist/host/githubResult.js +9 -12
- package/dist/host/githubResult.js.map +1 -1
- package/dist/host/githubTransport.d.ts +13 -0
- package/dist/host/githubTransport.d.ts.map +1 -0
- package/dist/host/{githubRead.js → githubTransport.js} +9 -10
- package/dist/host/githubTransport.js.map +1 -0
- package/dist/host/integrations.d.ts +6 -0
- package/dist/host/integrations.d.ts.map +1 -0
- package/dist/host/integrations.js +34 -0
- package/dist/host/integrations.js.map +1 -0
- package/dist/host/liveConfig.d.ts +21 -0
- package/dist/host/liveConfig.d.ts.map +1 -0
- package/dist/host/liveConfig.js +75 -0
- package/dist/host/liveConfig.js.map +1 -0
- package/dist/host/providers.d.ts.map +1 -1
- package/dist/host/providers.js +2 -2
- package/dist/host/providers.js.map +1 -1
- package/dist/host/readWaitStates.d.ts.map +1 -1
- package/dist/host/readWaitStates.js +8 -18
- package/dist/host/readWaitStates.js.map +1 -1
- package/dist/host/reassignWork.d.ts +10 -0
- package/dist/host/reassignWork.d.ts.map +1 -1
- package/dist/host/recordDecisionResponse.d.ts +1 -0
- package/dist/host/recordDecisionResponse.d.ts.map +1 -1
- package/dist/host/releaseWork.d.ts +24 -3
- package/dist/host/releaseWork.d.ts.map +1 -1
- package/dist/host/releaseWork.js +11 -7
- package/dist/host/releaseWork.js.map +1 -1
- package/dist/host/renderStatus.d.ts +2 -2
- package/dist/host/renderStatus.d.ts.map +1 -1
- package/dist/host/renderStatus.js +8 -2
- package/dist/host/renderStatus.js.map +1 -1
- package/dist/host/reportBoard.d.ts +1 -1
- package/dist/host/reportBoard.d.ts.map +1 -1
- package/dist/host/reportBoard.js +6 -3
- package/dist/host/reportBoard.js.map +1 -1
- package/dist/host/reportPublication.d.ts +2 -1
- package/dist/host/reportPublication.d.ts.map +1 -1
- package/dist/host/reportPublication.js +5 -2
- package/dist/host/reportPublication.js.map +1 -1
- package/dist/host/runtime.d.ts +8 -6
- package/dist/host/runtime.d.ts.map +1 -1
- package/dist/host/runtime.js +38 -46
- package/dist/host/runtime.js.map +1 -1
- package/dist/host/snapshotStream.d.ts.map +1 -1
- package/dist/host/snapshotStream.js +4 -1
- package/dist/host/snapshotStream.js.map +1 -1
- package/dist/host/status.d.ts +22 -2
- package/dist/host/status.d.ts.map +1 -1
- package/dist/host/status.js +19 -5
- package/dist/host/status.js.map +1 -1
- package/dist/host/statusLayer.d.ts +3 -3
- package/dist/host/statusLayer.d.ts.map +1 -1
- package/dist/host/statusLayer.js +13 -3
- package/dist/host/statusLayer.js.map +1 -1
- package/dist/host/waitOutcome.d.ts.map +1 -1
- package/dist/host/waitOutcome.js +5 -2
- package/dist/host/waitOutcome.js.map +1 -1
- package/dist/model.d.ts +39 -0
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +5 -0
- package/dist/model.js.map +1 -1
- package/dist/operations.d.ts +270 -0
- package/dist/operations.d.ts.map +1 -1
- package/dist/packageInfo.d.ts +1 -1
- package/dist/packageInfo.js +1 -1
- package/dist/policy.d.ts +8 -0
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +2 -0
- package/dist/policy.js.map +1 -1
- package/dist/providers/codexCloud.d.ts +2 -0
- package/dist/providers/codexCloud.d.ts.map +1 -1
- package/dist/providers/codexCloud.js +2 -1
- package/dist/providers/codexCloud.js.map +1 -1
- package/dist/qualifyDependencies.d.ts +10 -0
- package/dist/qualifyDependencies.d.ts.map +1 -1
- package/dist/scheduling/admission.d.ts +1635 -0
- package/dist/scheduling/admission.d.ts.map +1 -0
- package/dist/scheduling/admission.js +11 -0
- package/dist/scheduling/admission.js.map +1 -0
- package/dist/scheduling/areas.d.ts +30 -0
- package/dist/scheduling/areas.d.ts.map +1 -1
- package/dist/scheduling/areas.js +1 -0
- package/dist/scheduling/areas.js.map +1 -1
- package/dist/scheduling/backPressure.d.ts +1637 -0
- package/dist/scheduling/backPressure.d.ts.map +1 -0
- package/dist/scheduling/backPressure.js +44 -0
- package/dist/scheduling/backPressure.js.map +1 -0
- package/dist/storage/FleetStoreOptions.d.ts +2 -2
- package/dist/storage/FleetStoreOptions.d.ts.map +1 -1
- package/dist/storage/addShapeColumns.d.ts +5 -0
- package/dist/storage/addShapeColumns.d.ts.map +1 -0
- package/dist/storage/addShapeColumns.js +24 -0
- package/dist/storage/addShapeColumns.js.map +1 -0
- package/dist/storage/dispatchStore.d.ts +47 -0
- package/dist/storage/dispatchStore.d.ts.map +1 -0
- package/dist/storage/dispatchStore.js +89 -0
- package/dist/storage/dispatchStore.js.map +1 -0
- package/dist/storage/errors.d.ts +2 -1
- package/dist/storage/errors.d.ts.map +1 -1
- package/dist/storage/errors.js +2 -1
- package/dist/storage/errors.js.map +1 -1
- package/dist/storage/fleetMigrations.d.ts +1 -1
- package/dist/storage/fleetMigrations.d.ts.map +1 -1
- package/dist/storage/fleetMigrations.js +24 -17
- package/dist/storage/fleetMigrations.js.map +1 -1
- package/dist/storage/listedRecords.d.ts +9 -0
- package/dist/storage/listedRecords.d.ts.map +1 -0
- package/dist/storage/listedRecords.js +40 -0
- package/dist/storage/listedRecords.js.map +1 -0
- package/dist/storage/makePostgresFleetStore.d.ts +2 -6
- package/dist/storage/makePostgresFleetStore.d.ts.map +1 -1
- package/dist/storage/makePostgresFleetStore.js +4 -10
- package/dist/storage/makePostgresFleetStore.js.map +1 -1
- package/dist/storage/model.d.ts +9 -0
- package/dist/storage/model.d.ts.map +1 -1
- package/dist/storage/model.js.map +1 -1
- package/dist/storage/shapeV14.d.ts +808 -0
- package/dist/storage/shapeV14.d.ts.map +1 -0
- package/dist/storage/shapeV14.js +18 -0
- package/dist/storage/shapeV14.js.map +1 -0
- package/package.json +6 -6
- package/src/DispatchRequest.ts +13 -0
- package/src/attention.ts +5 -0
- package/src/board/fleetField.ts +5 -0
- package/src/board/markdown.ts +7 -2
- package/src/cli.ts +24 -10
- package/src/engine/admissionOrder.ts +25 -0
- package/src/engine/dispatchCommand.ts +29 -5
- package/src/engine/failureContext.ts +1 -0
- package/src/engine/failureMessage.ts +12 -1
- package/src/engine/localOnlyCriteria.ts +6 -1
- package/src/engine/makeLaunch.ts +4 -17
- package/src/engine/makeState.ts +30 -26
- package/src/engine/mergeReadiness.ts +6 -5
- package/src/engine/obtainReview.ts +2 -1
- package/src/engine/prepareCommand.ts +1 -1
- package/src/engine/readOrContinueReview.ts +2 -1
- package/src/engine/readRetry.ts +26 -2
- package/src/engine/reconcileAttempt.ts +2 -1
- package/src/engine/recordResponseCommand.ts +38 -0
- package/src/engine/recoverStall.ts +1 -1
- package/src/engine/repository.ts +17 -16
- package/src/engine/saveLaunch.ts +45 -0
- package/src/engine/scheduler.ts +4 -6
- package/src/engine/views.ts +5 -0
- package/src/fleet.ts +4 -0
- package/src/host/actionCommands.ts +22 -7
- package/src/host/admission.ts +3 -3
- package/src/host/answerWork.ts +28 -27
- package/src/host/cliOptions.ts +1 -1
- package/src/host/commands.ts +29 -8
- package/src/host/config.ts +26 -22
- package/src/host/configFile.ts +40 -0
- package/src/host/configSettings.ts +126 -0
- package/src/host/daemon.ts +2 -1
- package/src/host/daemonClient.ts +42 -7
- package/src/host/daemonContract.ts +12 -4
- package/src/host/daemonDiagnostics.ts +11 -3
- package/src/host/daemonHandlers.ts +24 -7
- package/src/host/daemonSnapshots.ts +24 -1
- package/src/host/dispatchRequests.ts +53 -0
- package/src/host/follow.ts +1 -1
- package/src/host/followState.ts +6 -6
- package/src/host/github.ts +8 -6
- package/src/host/githubApi.ts +142 -0
- package/src/host/githubChecks.ts +6 -5
- package/src/host/githubDelivery.ts +47 -10
- package/src/host/githubRateLimit.ts +91 -0
- package/src/host/githubRequiredChecks.ts +2 -2
- package/src/host/githubResponse.ts +37 -0
- package/src/host/githubResult.ts +15 -17
- package/src/host/githubTransport.ts +31 -0
- package/src/host/integrations.ts +40 -0
- package/src/host/liveConfig.ts +135 -0
- package/src/host/providers.ts +4 -2
- package/src/host/readWaitStates.ts +8 -20
- package/src/host/releaseWork.ts +12 -9
- package/src/host/renderStatus.ts +10 -3
- package/src/host/reportBoard.ts +6 -3
- package/src/host/reportPublication.ts +6 -4
- package/src/host/runtime.ts +49 -56
- package/src/host/snapshotStream.ts +6 -1
- package/src/host/status.ts +24 -7
- package/src/host/statusLayer.ts +21 -5
- package/src/host/waitOutcome.ts +5 -2
- package/src/model.ts +6 -0
- package/src/packageInfo.ts +1 -1
- package/src/policy.ts +8 -0
- package/src/providers/codexCloud.ts +2 -1
- package/src/scheduling/admission.ts +19 -0
- package/src/scheduling/areas.ts +1 -0
- package/src/scheduling/backPressure.ts +55 -0
- package/src/storage/FleetStoreOptions.ts +7 -2
- package/src/storage/addShapeColumns.ts +24 -0
- package/src/storage/dispatchStore.ts +104 -0
- package/src/storage/errors.ts +2 -1
- package/src/storage/fleetMigrations.ts +24 -17
- package/src/storage/listedRecords.ts +53 -0
- package/src/storage/makePostgresFleetStore.ts +4 -10
- package/src/storage/model.ts +7 -0
- package/src/storage/shapeV14.ts +19 -0
- package/dist/host/githubRead.d.ts +0 -5
- package/dist/host/githubRead.d.ts.map +0 -1
- package/dist/host/githubRead.js.map +0 -1
- package/dist/host/recordPayloads.d.ts +0 -4
- package/dist/host/recordPayloads.d.ts.map +0 -1
- package/dist/host/recordPayloads.js +0 -21
- package/dist/host/recordPayloads.js.map +0 -1
- package/dist/storage/migrateFleet.d.ts +0 -3
- package/dist/storage/migrateFleet.d.ts.map +0 -1
- package/dist/storage/migrateFleet.js +0 -11
- package/dist/storage/migrateFleet.js.map +0 -1
- package/src/host/githubRead.ts +0 -20
- package/src/host/recordPayloads.ts +0 -24
- package/src/storage/migrateFleet.ts +0 -11
package/src/host/renderStatus.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { diagnostics as diagnosticsApi } from "@shivaedev/work-board/integration/diagnostics.ts";
|
|
2
2
|
import { sessionStatus } from "#engine/sessionStatus.ts";
|
|
3
|
+
import { type DaemonStatus, renderConfig } from "#host/configSettings.ts";
|
|
3
4
|
import type { FleetViews } from "#model.ts";
|
|
4
5
|
|
|
5
6
|
const { DAEMON_PORT } = diagnosticsApi;
|
|
@@ -7,14 +8,14 @@ const { DAEMON_PORT } = diagnosticsApi;
|
|
|
7
8
|
type View = (typeof FleetViews.Type)["active"][number];
|
|
8
9
|
|
|
9
10
|
function line(view: View, waiting: boolean, port: number) {
|
|
10
|
-
const reason = view.decision?.reason ?? view.
|
|
11
|
+
const reason = view.blocker ?? view.decision?.reason ?? (view.overLimit ? "launched over the limit" : undefined);
|
|
11
12
|
const detail = reason === undefined ? "" : ` ${reason}`;
|
|
12
13
|
const links = [...view.links, ...view.sessions.map(sessionStatus)];
|
|
13
14
|
const answer = waiting ? `\n work-fleet answer ${view.workId}${port === DAEMON_PORT ? "" : ` --port ${port}`}` : "";
|
|
14
15
|
return ` ${view.workId} ${view.stage}${detail}${links.length === 0 ? "" : ` (${links.join(", ")})`}${answer}`;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
export function renderStatus(current: typeof
|
|
18
|
+
export function renderStatus(current: typeof DaemonStatus.Type, port: number = DAEMON_PORT): string {
|
|
18
19
|
const sections: readonly [string, readonly View[]][] = [
|
|
19
20
|
["Active", current.active],
|
|
20
21
|
["Waiting on maintainer", current.waiting.maintainer],
|
|
@@ -22,7 +23,7 @@ export function renderStatus(current: typeof FleetViews.Type, port: number = DAE
|
|
|
22
23
|
["Waiting on automation", current.waiting.automation],
|
|
23
24
|
["Completed", current.completed],
|
|
24
25
|
];
|
|
25
|
-
|
|
26
|
+
const rendered = sections
|
|
26
27
|
.map(([title, items]) =>
|
|
27
28
|
[
|
|
28
29
|
`${title} (${items.length})`,
|
|
@@ -30,4 +31,10 @@ export function renderStatus(current: typeof FleetViews.Type, port: number = DAE
|
|
|
30
31
|
].join("\n"),
|
|
31
32
|
)
|
|
32
33
|
.join("\n");
|
|
34
|
+
const dispatches = current.dispatches ?? [];
|
|
35
|
+
const views =
|
|
36
|
+
dispatches.length === 0
|
|
37
|
+
? rendered
|
|
38
|
+
: `${rendered}\nDispatches (${dispatches.length})\n${dispatches.map((request) => ` ${request.workId} dispatch ${request.status}${request.error === undefined ? "" : `: ${request.error}`}`).join("\n")}`;
|
|
39
|
+
return current.config === undefined ? views : `${views}\n${renderConfig(current.config)}`;
|
|
33
40
|
}
|
package/src/host/reportBoard.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
2
2
|
import { Context, Effect, Layer } from "effect";
|
|
3
3
|
import { defineService } from "@shivaedev/effect-service/define-service.ts";
|
|
4
|
-
import { BadRequest
|
|
4
|
+
import { BadRequest } from "@shivaedev/platform/errors/taxonomy.ts";
|
|
5
5
|
import { markdownBoard } from "#board/markdown.ts";
|
|
6
6
|
import { reportContent } from "#board/reportContent.ts";
|
|
7
7
|
import { reportFiles } from "#board/reportFiles.ts";
|
|
@@ -12,6 +12,8 @@ import { withFailureContext } from "#engine/failureContext.ts";
|
|
|
12
12
|
import { ReportInspection } from "#engine/ReportInspection.ts";
|
|
13
13
|
import { isFleetError } from "#errors.ts";
|
|
14
14
|
import type { FleetHost } from "#host/config.ts";
|
|
15
|
+
import { GithubApi } from "#host/githubApi.ts";
|
|
16
|
+
import { githubFailure } from "#host/githubRateLimit.ts";
|
|
15
17
|
import { MainSource } from "#host/mainSource.ts";
|
|
16
18
|
import { reportPublication, reportRepository } from "#host/reportPublication.ts";
|
|
17
19
|
import { BoardFailure, BoardGateway, type BoardWork } from "#policy.ts";
|
|
@@ -57,7 +59,7 @@ const ReportBoard = defineService({
|
|
|
57
59
|
const { root, check, files } = yield* ReportInputs;
|
|
58
60
|
function inspect(work: BoardWork) {
|
|
59
61
|
return check(work).pipe(
|
|
60
|
-
Effect.mapError((
|
|
62
|
+
Effect.mapError(githubFailure("Report publication could not be checked on GitHub")),
|
|
61
63
|
Effect.flatMap((published) =>
|
|
62
64
|
published ? Effect.fail(withFailureContext(new BadRequest({ message: PUBLISHED_REPORT }), { code: "report-published" })) : Effect.void,
|
|
63
65
|
),
|
|
@@ -121,12 +123,13 @@ export function hostReportBoard(host: FleetHost) {
|
|
|
121
123
|
return Layer.unwrap(
|
|
122
124
|
Effect.gen(function* () {
|
|
123
125
|
const main = yield* MainSource;
|
|
126
|
+
const github = yield* GithubApi;
|
|
124
127
|
function check(work: BoardWork) {
|
|
125
128
|
return Effect.gen(function* () {
|
|
126
129
|
if (host.worker === undefined) {
|
|
127
130
|
return yield* Effect.fail(new BoardFailure({ message: "Report publication checks need worker.branchPrefix" }));
|
|
128
131
|
}
|
|
129
|
-
return yield* reportPublication(
|
|
132
|
+
return yield* reportPublication(github)(
|
|
130
133
|
yield* reportRepository(main.repositoryRoot, host.repository.remote),
|
|
131
134
|
`${host.worker.branchPrefix}${work.workId}`,
|
|
132
135
|
);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Effect, Schema } from "effect";
|
|
2
2
|
import { ServiceUnavailable } from "@shivaedev/platform/errors/taxonomy.ts";
|
|
3
3
|
import type { FleetError } from "#errors.ts";
|
|
4
|
+
import type { GithubRead } from "#host/github.ts";
|
|
5
|
+
import { githubFailure } from "#host/githubRateLimit.ts";
|
|
4
6
|
import { readCommand } from "#host/readCommand.ts";
|
|
5
7
|
|
|
6
8
|
const References = Schema.Array(Schema.Array(Schema.Struct({ ref: Schema.String })));
|
|
@@ -17,13 +19,13 @@ export function makeReportPublication<R>(read: (endpoint: string) => Effect.Effe
|
|
|
17
19
|
).pipe(Effect.flatMap(Schema.decodeUnknownEffect(Schema.fromJsonString(PullRequests))));
|
|
18
20
|
return refs.flat().some((ref) => ref.ref === `refs/heads/${branch}`) || prs.flat().length > 0;
|
|
19
21
|
},
|
|
20
|
-
Effect.mapError((
|
|
22
|
+
Effect.mapError(githubFailure("Report publication could not be checked on GitHub")),
|
|
21
23
|
);
|
|
22
24
|
}
|
|
23
25
|
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
export function reportPublication(read: GithubRead) {
|
|
27
|
+
return makeReportPublication(read.pages);
|
|
28
|
+
}
|
|
27
29
|
|
|
28
30
|
export const reportRepository = Effect.fn("Fleet.reportRepository")(function* (cwd: string, remote: string) {
|
|
29
31
|
const url = (yield* readCommand("git", ["remote", "get-url", remote], cwd)).trim();
|
package/src/host/runtime.ts
CHANGED
|
@@ -1,81 +1,63 @@
|
|
|
1
1
|
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
2
2
|
import { Clock, Effect, Layer, Redacted } from "effect";
|
|
3
|
-
import { defineService } from "@shivaedev/effect-service/define-service.ts";
|
|
4
3
|
import { appDatabase } from "@shivaedev/platform/appHost.ts";
|
|
5
4
|
import { ServiceUnavailable } from "@shivaedev/platform/errors/taxonomy.ts";
|
|
6
|
-
import type { DecisionCode } from "#DecisionCode.ts";
|
|
7
|
-
import { withFailureContext } from "#engine/failureContext.ts";
|
|
8
5
|
import type { ReportInspection } from "#engine/ReportInspection.ts";
|
|
9
6
|
import { fleetSessionJournal, postgresFleetRepository } from "#engine/repository.ts";
|
|
10
7
|
import { Fleet } from "#fleet.ts";
|
|
11
8
|
import { type FleetHost, HostFailure } from "#host/config.ts";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { hostGuidance } from "#host/guidance.ts";
|
|
9
|
+
import { type GithubApi, githubApiLayer } from "#host/githubApi.ts";
|
|
10
|
+
import { hostIntegrations } from "#host/integrations.ts";
|
|
11
|
+
import { type AppliedConfig, LiveConfig, staticConfig } from "#host/liveConfig.ts";
|
|
16
12
|
import { localOnlyBoardPath } from "#host/localOnlyBoardPath.ts";
|
|
17
13
|
import { MainSource } from "#host/mainSource.ts";
|
|
18
14
|
import { providerHealth } from "#host/providerHealth.ts";
|
|
19
15
|
import { hostQuota } from "#host/quota.ts";
|
|
20
16
|
import { hostReportBoard } from "#host/reportBoard.ts";
|
|
21
|
-
import { type BoardGateway, FleetIntegrations, FleetPolicy } from "#policy.ts";
|
|
17
|
+
import { type BoardGateway, type FleetConfiguration, type FleetIntegrations, FleetPolicy } from "#policy.ts";
|
|
22
18
|
import { SessionService, type SessionTransport } from "#session/service.ts";
|
|
23
19
|
import { fleetMigrations } from "#storage/fleetMigrations.ts";
|
|
24
20
|
|
|
25
|
-
function unconfigured(message: string, code: DecisionCode = "fleet-integration") {
|
|
26
|
-
return Effect.fail(withFailureContext(new ServiceUnavailable({ message }), { attentionOwner: "automation", code, retryable: false }));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function hostIntegrations(host: FleetHost) {
|
|
30
|
-
const HostIntegrations = defineService({
|
|
31
|
-
id: "Fleet/HostIntegrations",
|
|
32
|
-
initialize: MainSource,
|
|
33
|
-
methods: (main) =>
|
|
34
|
-
FleetIntegrations.of({
|
|
35
|
-
checks: (_work, result) =>
|
|
36
|
-
result.kind === "no-change"
|
|
37
|
-
? unconfigured("No-change validation is not configured in this Fleet host; inspect the worker session", "no-change-checks-unconfigured")
|
|
38
|
-
: githubChecks(result, host.repository.branch).pipe(Effect.provide(NodeServices.layer)),
|
|
39
|
-
delivery: githubDelivery(main.repositoryRoot),
|
|
40
|
-
main: main.observe,
|
|
41
|
-
result:
|
|
42
|
-
host.result === "github"
|
|
43
|
-
? githubResult(host, main)
|
|
44
|
-
: () => unconfigured("Worker result adoption is not configured in this Fleet host; inspect the worker session"),
|
|
45
|
-
}),
|
|
46
|
-
requires: [MainSource],
|
|
47
|
-
});
|
|
48
|
-
return Layer.effect(FleetIntegrations)(HostIntegrations).pipe(Layer.provide(HostIntegrations.layer));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
21
|
export function hostPolicy(host: FleetHost) {
|
|
52
22
|
return Layer.effect(FleetPolicy)(
|
|
53
23
|
Effect.gen(function* () {
|
|
54
24
|
const clock = yield* Clock.Clock;
|
|
55
25
|
const main = yield* MainSource;
|
|
26
|
+
const live = yield* LiveConfig;
|
|
56
27
|
const localPath = host.provider === "cloud" ? yield* localOnlyBoardPath(host.boardDir, main.repositoryRoot) : undefined;
|
|
57
|
-
const reviewerGuidance = yield* hostGuidance(host, "reviewer");
|
|
58
|
-
const workerGuidance = yield* hostGuidance(host, "worker");
|
|
59
28
|
function now() {
|
|
60
29
|
return clock.currentTimeMillisUnsafe();
|
|
61
30
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
quota
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
31
|
+
// Each quota source caches its observation, so a reload reuses the source for an unchanged quota setting.
|
|
32
|
+
const quotas = new Map<FleetHost["quota"], ReturnType<typeof hostQuota>>();
|
|
33
|
+
function refreshQuota(applied: FleetHost) {
|
|
34
|
+
const known = quotas.get(applied.quota);
|
|
35
|
+
if (known !== undefined) {
|
|
36
|
+
return known;
|
|
37
|
+
}
|
|
38
|
+
const created = hostQuota(applied, now);
|
|
39
|
+
quotas.set(applied.quota, created);
|
|
40
|
+
return created;
|
|
41
|
+
}
|
|
42
|
+
function configuration({ guidance, host: applied }: AppliedConfig): FleetConfiguration {
|
|
43
|
+
return {
|
|
44
|
+
areaMergeWaitMs: applied.areaMergeWaitMs,
|
|
45
|
+
deliveryBacklog: applied.backlog,
|
|
46
|
+
executionConcurrency: applied.concurrency,
|
|
47
|
+
launch: applied.launch,
|
|
48
|
+
...(localPath === undefined ? {} : { localOnlyBoardPath: localPath }),
|
|
49
|
+
now,
|
|
50
|
+
...(applied.openPullRequests === undefined ? {} : { openPullRequests: applied.openPullRequests }),
|
|
51
|
+
operationId: () => crypto.randomUUID(),
|
|
52
|
+
quota: { expiresAt: 0, observedAt: 0 },
|
|
53
|
+
readGuidance: (role) => guidance[role].pipe(Effect.mapError((error) => new ServiceUnavailable({ message: error.message }))),
|
|
54
|
+
readRetryMs: applied.readRetryMs,
|
|
55
|
+
refreshQuota: refreshQuota(applied),
|
|
56
|
+
stallMinutes: applied.stallMinutes,
|
|
57
|
+
...(applied.worker === undefined ? {} : { sharedEnvironment: applied.worker.sharedEnvironment }),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return FleetPolicy.of({ ...configuration(yield* live.current), current: Effect.map(live.current, configuration) });
|
|
79
61
|
}),
|
|
80
62
|
);
|
|
81
63
|
}
|
|
@@ -107,23 +89,34 @@ export function hostSql(host: FleetHost) {
|
|
|
107
89
|
export function fleetHostLayer<TProvider, TMain>(
|
|
108
90
|
host: FleetHost,
|
|
109
91
|
parts: {
|
|
110
|
-
readonly board?: Layer.Layer<BoardGateway | ReportInspection, unknown, MainSource>;
|
|
111
|
-
readonly
|
|
92
|
+
readonly board?: Layer.Layer<BoardGateway | ReportInspection, unknown, MainSource | GithubApi>;
|
|
93
|
+
readonly github?: Layer.Layer<GithubApi>;
|
|
94
|
+
readonly integrations?: Layer.Layer<FleetIntegrations, unknown, MainSource | GithubApi>;
|
|
112
95
|
readonly main: Layer.Layer<MainSource, TMain>;
|
|
113
96
|
readonly policy?: Layer.Layer<FleetPolicy>;
|
|
114
97
|
readonly provider: Layer.Layer<SessionTransport, TProvider>;
|
|
115
98
|
},
|
|
99
|
+
config: Layer.Layer<LiveConfig, unknown> = staticConfig(host),
|
|
116
100
|
) {
|
|
117
101
|
const repository = postgresFleetRepository(host.namespace);
|
|
118
102
|
const sessions = SessionService.layer.pipe(
|
|
119
103
|
Layer.provideMerge([fleetSessionJournal.pipe(Layer.provide(repository)), providerHealth.pipe(Layer.provide(parts.provider))]),
|
|
120
104
|
);
|
|
105
|
+
const github = parts.github ?? githubApiLayer.pipe(Layer.provide(NodeServices.layer));
|
|
121
106
|
const board = (parts.board ?? hostReportBoard(host)).pipe(Layer.provide(parts.main), Layer.provide(NodeServices.layer));
|
|
122
107
|
const integrations = (parts.integrations ?? hostIntegrations(host)).pipe(Layer.provide(parts.main));
|
|
123
108
|
return Fleet.layer.pipe(
|
|
124
109
|
Layer.provideMerge(
|
|
125
|
-
Layer.mergeAll(
|
|
110
|
+
Layer.mergeAll(
|
|
111
|
+
repository,
|
|
112
|
+
sessions,
|
|
113
|
+
board,
|
|
114
|
+
parts.policy ?? hostPolicy(host).pipe(Layer.provide([parts.main, config])),
|
|
115
|
+
integrations,
|
|
116
|
+
parts.main,
|
|
117
|
+
),
|
|
126
118
|
),
|
|
119
|
+
Layer.provideMerge(github),
|
|
127
120
|
Layer.provideMerge(hostSql(host)),
|
|
128
121
|
);
|
|
129
122
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Stream } from "effect";
|
|
2
|
+
import { ANSWER_RECORDED } from "#attention.ts";
|
|
2
3
|
import type { FleetError } from "#errors.ts";
|
|
3
4
|
import type { State } from "#host/waitOutcome.ts";
|
|
4
5
|
|
|
@@ -12,7 +13,11 @@ export function snapshotStream(snapshots: Stream.Stream<States, FleetError>, ids
|
|
|
12
13
|
if (continuous && selected === undefined) {
|
|
13
14
|
return states;
|
|
14
15
|
}
|
|
15
|
-
selected ??= new Set(
|
|
16
|
+
selected ??= new Set(
|
|
17
|
+
states
|
|
18
|
+
.filter((state) => state.blocker === ANSWER_RECORDED || !["completed", "needs-human", "released"].includes(state.stage))
|
|
19
|
+
.map((state) => state.workId),
|
|
20
|
+
);
|
|
16
21
|
const selection = selected;
|
|
17
22
|
return states.filter((state) => selection.has(state.workId));
|
|
18
23
|
}),
|
package/src/host/status.ts
CHANGED
|
@@ -1,16 +1,33 @@
|
|
|
1
1
|
import { Effect, Schema } from "effect";
|
|
2
|
+
import { makeRepository } from "@shivaedev/effect-sql/repository.ts";
|
|
2
3
|
import { views } from "#engine/views.ts";
|
|
3
4
|
import type { FleetHost } from "#host/config.ts";
|
|
4
|
-
import {
|
|
5
|
-
import { FleetRecord
|
|
6
|
-
import {
|
|
5
|
+
import { renderStatus as render } from "#host/renderStatus.ts";
|
|
6
|
+
import { FleetRecord } from "#model.ts";
|
|
7
|
+
import { dispatchStore } from "#storage/dispatchStore.ts";
|
|
8
|
+
import { recordModel } from "#storage/model.ts";
|
|
9
|
+
import { readRecords } from "#storage/readRecords.ts";
|
|
10
|
+
import { recordShape } from "#storage/recordShape.ts";
|
|
11
|
+
import { recordValues } from "#storage/recordValue.ts";
|
|
7
12
|
|
|
8
|
-
export function renderStatus(current: typeof
|
|
13
|
+
export function renderStatus(current: Parameters<typeof render>[0]) {
|
|
9
14
|
return render(current);
|
|
10
15
|
}
|
|
11
16
|
|
|
12
17
|
export const fleetStatus = Effect.fn("FleetHost.fleetStatus")(function* (host: FleetHost, workId?: string) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
const repository = yield* makeRepository(recordModel(), {
|
|
19
|
+
idColumn: "work_id",
|
|
20
|
+
spanPrefix: "FleetReader",
|
|
21
|
+
tableName: `${host.namespace}_records`,
|
|
22
|
+
});
|
|
23
|
+
const records = yield* readRecords(
|
|
24
|
+
host.namespace,
|
|
25
|
+
Effect.gen(function* () {
|
|
26
|
+
const rows = yield* repository.findMany({ orderBy: { direction: "asc", field: "work_id" }, where: { "work_id": workId } });
|
|
27
|
+
return yield* Schema.decodeUnknownEffect(Schema.Array(FleetRecord))(yield* recordValues(rows, recordShape(), host.namespace));
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
const requests = yield* (yield* dispatchStore(host.namespace)).list(workId);
|
|
31
|
+
const dispatches = requests.filter((request) => request.status !== "completed");
|
|
32
|
+
return dispatches.length === 0 ? views(records) : { ...views(records), dispatches };
|
|
16
33
|
});
|
package/src/host/statusLayer.ts
CHANGED
|
@@ -8,18 +8,22 @@ import { writeStatus } from "#board/writeStatus.ts";
|
|
|
8
8
|
import { Health, HealthPublication, HealthSnapshot } from "#engine/health.ts";
|
|
9
9
|
import { views } from "#engine/views.ts";
|
|
10
10
|
import { Fleet } from "#fleet.ts";
|
|
11
|
+
import { GithubApi } from "#host/githubApi.ts";
|
|
12
|
+
import type { GithubObservation } from "#host/githubRateLimit.ts";
|
|
11
13
|
import { executing } from "#model.ts";
|
|
12
14
|
|
|
13
15
|
const { SourceFailure } = diagnosticsApi;
|
|
14
16
|
|
|
15
17
|
class StatusHealth extends Context.Service<StatusHealth, Option.Option<Health["Service"]>>()("Fleet/StatusHealth") {}
|
|
18
|
+
class StatusGithub extends Context.Service<StatusGithub, Effect.Effect<readonly GithubObservation[]>>()("Fleet/StatusGithub") {}
|
|
16
19
|
|
|
17
|
-
export function statusLayer(root: string, healthConfig?: { readonly concurrency: number; readonly staleAfterMs: number }) {
|
|
20
|
+
export function statusLayer(root: string, healthConfig?: Effect.Effect<{ readonly concurrency: number; readonly staleAfterMs: number }>) {
|
|
18
21
|
const StatusPublication = defineService({
|
|
19
22
|
id: "Fleet/StatusPublication",
|
|
20
23
|
initialize: Effect.gen(function* () {
|
|
21
24
|
const fleet = yield* Fleet;
|
|
22
25
|
const health = yield* StatusHealth;
|
|
26
|
+
const github = yield* StatusGithub;
|
|
23
27
|
const fs = yield* FileSystem.FileSystem;
|
|
24
28
|
const realRoot = yield* fs.realPath(root);
|
|
25
29
|
const lock = yield* Semaphore.make(1);
|
|
@@ -37,10 +41,12 @@ export function statusLayer(root: string, healthConfig?: { readonly concurrency:
|
|
|
37
41
|
).pipe(Effect.catch((error) => Console.error(`work-fleet: status publication failed: ${error.message}`)));
|
|
38
42
|
if (healthConfig !== undefined) {
|
|
39
43
|
const state = health._tag === "Some" ? yield* Ref.get(health.value) : { lastCapacityRejection: null, lastSchedulerPass: null };
|
|
44
|
+
const observations = yield* github;
|
|
40
45
|
const nextHealth: FleetHealth = {
|
|
46
|
+
...(observations.length === 0 ? {} : { github: observations }),
|
|
41
47
|
observedAt: yield* Clock.currentTimeMillis,
|
|
42
48
|
version: 2,
|
|
43
|
-
...healthConfig,
|
|
49
|
+
...(yield* healthConfig),
|
|
44
50
|
...state,
|
|
45
51
|
queued: records.filter(({ value }) => value.stage === "prepared").length,
|
|
46
52
|
running: records.filter(({ value }) => executing(value)).length,
|
|
@@ -71,18 +77,28 @@ export function statusLayer(root: string, healthConfig?: { readonly concurrency:
|
|
|
71
77
|
readHealth: () => readSnapshot(snapshot),
|
|
72
78
|
reassign: (...args: Parameters<typeof fleet.reassign>) => after(fleet.reassign(...args)),
|
|
73
79
|
reconcile: (workId: string) => after(fleet.reconcile(workId)),
|
|
80
|
+
recordResponse: (...args: Parameters<typeof fleet.recordResponse>) => after(fleet.recordResponse(...args)),
|
|
74
81
|
resolve: (...args: Parameters<typeof fleet.resolve>) => after(fleet.resolve(...args)),
|
|
75
82
|
};
|
|
76
83
|
},
|
|
77
|
-
requires: [Fleet, FileSystem.FileSystem, StatusHealth],
|
|
84
|
+
requires: [Fleet, FileSystem.FileSystem, StatusHealth, StatusGithub],
|
|
78
85
|
});
|
|
79
86
|
return Layer.unwrap(
|
|
80
|
-
Effect.map(Effect.serviceOption(Health), (health) =>
|
|
87
|
+
Effect.map(Effect.all([Effect.serviceOption(Health), Effect.serviceOption(GithubApi)]), ([health, github]) =>
|
|
81
88
|
Layer.unwrap(
|
|
82
89
|
Effect.map(StatusPublication, ({ readHealth, publishHealth, ...fleet }) =>
|
|
83
90
|
Layer.mergeAll(Layer.succeed(HealthSnapshot, readHealth()), Layer.succeed(HealthPublication, publishHealth()), Layer.succeed(Fleet, fleet)),
|
|
84
91
|
),
|
|
85
|
-
).pipe(
|
|
92
|
+
).pipe(
|
|
93
|
+
Layer.provide(
|
|
94
|
+
StatusPublication.layer.pipe(
|
|
95
|
+
Layer.provide([
|
|
96
|
+
Layer.succeed(StatusHealth, health),
|
|
97
|
+
Layer.succeed(StatusGithub, github._tag === "Some" ? github.value.observations() : Effect.succeed([])),
|
|
98
|
+
]),
|
|
99
|
+
),
|
|
100
|
+
),
|
|
101
|
+
),
|
|
86
102
|
),
|
|
87
103
|
);
|
|
88
104
|
}
|
package/src/host/waitOutcome.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Schema from "effect/Schema";
|
|
2
|
-
import { AttentionOwner, waitingOwner } from "#attention.ts";
|
|
2
|
+
import { ANSWER_RECORDED, AttentionOwner, waitingOwner } from "#attention.ts";
|
|
3
3
|
|
|
4
4
|
export const WAIT_EXIT = { completed: 0, error: 1, released: 3, timeout: 4, waitingDecision: 2 } as const;
|
|
5
5
|
|
|
@@ -28,6 +28,9 @@ export type WaitState = typeof WaitState.Type;
|
|
|
28
28
|
export const State = Schema.Struct({ ...WaitState.fields, workId: Schema.String });
|
|
29
29
|
|
|
30
30
|
export function settled(workId: string, state: WaitState): WaitOutcome | undefined {
|
|
31
|
+
if (state.blocker === ANSWER_RECORDED) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
31
34
|
const owner = waitingOwner(state);
|
|
32
35
|
const attention = owner === undefined ? "" : ` (waiting on ${owner})`;
|
|
33
36
|
if (state.stage === "completed") {
|
|
@@ -37,7 +40,7 @@ export function settled(workId: string, state: WaitState): WaitOutcome | undefin
|
|
|
37
40
|
if (state.stage === "needs-human") {
|
|
38
41
|
return {
|
|
39
42
|
code: WAIT_EXIT.waitingDecision,
|
|
40
|
-
summary: `${workId} needs-human${attention}: ${state.
|
|
43
|
+
summary: `${workId} needs-human${attention}: ${state.blocker ?? state.decision?.reason ?? "a Board decision is pending"}`,
|
|
41
44
|
};
|
|
42
45
|
}
|
|
43
46
|
if (state.stage === "released") {
|
package/src/model.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Schema } from "effect";
|
|
|
2
2
|
import { diagnostics } from "@shivaedev/work-board/integration/diagnostics.ts";
|
|
3
3
|
import { AttentionOwner } from "#attention.ts";
|
|
4
4
|
import { BoardReport } from "#board/schema.ts";
|
|
5
|
+
import { DispatchRequest } from "#DispatchRequest.ts";
|
|
5
6
|
import { Checks, Decision, DecisionResponse, Delivery, Review, SupersededDecision, WorkResult } from "#policy.ts";
|
|
6
7
|
import { Preparation } from "#preparation/schema.ts";
|
|
7
8
|
import { LaunchSettings, SessionObservation, SessionReceipt } from "#session/schema.ts";
|
|
@@ -29,6 +30,7 @@ export const Attempt = Schema.Struct({
|
|
|
29
30
|
observationRetries: Schema.optional(Schema.Number),
|
|
30
31
|
operationId: Schema.String,
|
|
31
32
|
output: Schema.optional(Schema.String),
|
|
33
|
+
overLimit: Schema.optional(Schema.Boolean),
|
|
32
34
|
progress: Schema.optional(Schema.Struct({ at: Schema.Number, signature: Schema.String })),
|
|
33
35
|
prompt: Schema.optional(Schema.String),
|
|
34
36
|
providerFailures: Schema.optional(Schema.Number),
|
|
@@ -74,6 +76,7 @@ const cycleFields = {
|
|
|
74
76
|
decisionAcknowledged: Schema.optional(Schema.Boolean),
|
|
75
77
|
decisionPublished: Schema.optional(Schema.Boolean),
|
|
76
78
|
deliverable: Schema.optional(Schema.Literal("report")),
|
|
79
|
+
dispatchNow: Schema.optional(Schema.Struct({ ignoreAreas: Schema.Boolean })),
|
|
77
80
|
integrationRetry: Schema.optional(Schema.Struct({ error: Schema.String, failures: Schema.Number, retryAt: Schema.Number })),
|
|
78
81
|
launch: Schema.optional(LaunchSettings),
|
|
79
82
|
launchRetry: Schema.optional(
|
|
@@ -101,6 +104,7 @@ export const FleetCycleSnapshot = Schema.Struct({ ...cycleFields, archivedAt: Sc
|
|
|
101
104
|
export type FleetCycleSnapshot = typeof FleetCycleSnapshot.Type;
|
|
102
105
|
export const FleetRecord = Schema.Struct({ ...cycleFields, history: Schema.optional(Schema.Array(FleetCycleSnapshot)), workId: Schema.String });
|
|
103
106
|
export type FleetRecord = typeof FleetRecord.Type;
|
|
107
|
+
export type DispatchNow = NonNullable<FleetRecord["dispatchNow"]>;
|
|
104
108
|
export function executing(record: FleetRecord): boolean {
|
|
105
109
|
return record.attempts.some((attempt) => ["submitting", "accepted", "running"].includes(attempt.status));
|
|
106
110
|
}
|
|
@@ -114,6 +118,7 @@ export const FleetView = Schema.Struct({
|
|
|
114
118
|
decisionAcknowledged: Schema.optional(Schema.Boolean),
|
|
115
119
|
links: Schema.Array(Schema.String),
|
|
116
120
|
outcome: FleetRecord.fields.outcome,
|
|
121
|
+
overLimit: Schema.optional(Schema.Boolean),
|
|
117
122
|
sessions: Schema.Array(
|
|
118
123
|
Schema.Struct({
|
|
119
124
|
...SessionReceipt.fields,
|
|
@@ -130,6 +135,7 @@ export const FleetView = Schema.Struct({
|
|
|
130
135
|
export const FleetViews = Schema.Struct({
|
|
131
136
|
active: Schema.Array(FleetView),
|
|
132
137
|
completed: Schema.Array(FleetView),
|
|
138
|
+
dispatches: Schema.optional(Schema.Array(DispatchRequest)),
|
|
133
139
|
waiting: Schema.Struct({
|
|
134
140
|
automation: Schema.Array(FleetView),
|
|
135
141
|
maintainer: Schema.Array(FleetView),
|
package/src/packageInfo.ts
CHANGED
package/src/policy.ts
CHANGED
|
@@ -12,13 +12,17 @@ import type { FleetError } from "#errors.ts";
|
|
|
12
12
|
import type { MainObservation, Preparation } from "#preparation/schema.ts";
|
|
13
13
|
import type { SessionObservation } from "#session/schema.ts";
|
|
14
14
|
import { type LaunchSettings, SessionReceipt } from "#session/schema.ts";
|
|
15
|
+
import type { OpenPullRequestCurve } from "#storage/model.ts";
|
|
15
16
|
|
|
17
|
+
export const Priority = Schema.Literals(["urgent", "high", "normal"]);
|
|
18
|
+
export type Priority = typeof Priority.Type;
|
|
16
19
|
export const BoardWork = Schema.Struct({
|
|
17
20
|
approved: Schema.Boolean,
|
|
18
21
|
areas: Schema.optional(Schema.Array(Schema.String)),
|
|
19
22
|
context: Schema.String,
|
|
20
23
|
deliverable: Schema.optional(Schema.Literal("report")),
|
|
21
24
|
dependsOn: Schema.Array(Schema.String),
|
|
25
|
+
priority: Schema.optional(Priority),
|
|
22
26
|
revision: Schema.String,
|
|
23
27
|
sourcePath: Schema.String,
|
|
24
28
|
status: Schema.optional(Schema.String),
|
|
@@ -105,14 +109,18 @@ export const Delivery = Schema.Struct({ head: Schema.String, revision: Schema.St
|
|
|
105
109
|
export type Delivery = typeof Delivery.Type;
|
|
106
110
|
export interface FleetConfiguration {
|
|
107
111
|
readonly areaMergeWaitMs?: number;
|
|
112
|
+
// A host that reloads its settings serves the configuration each scheduler pass and launch should apply.
|
|
113
|
+
readonly current?: Effect.Effect<FleetConfiguration>;
|
|
108
114
|
readonly deliveryBacklog?: number;
|
|
109
115
|
readonly executionConcurrency?: number;
|
|
110
116
|
readonly launch?: LaunchSettings;
|
|
111
117
|
readonly localOnlyBoardPath?: string;
|
|
112
118
|
readonly now: () => number;
|
|
119
|
+
readonly openPullRequests?: OpenPullRequestCurve;
|
|
113
120
|
readonly operationId: () => string;
|
|
114
121
|
readonly quota: { readonly available?: number; readonly observedAt: number; readonly expiresAt: number };
|
|
115
122
|
readonly readGuidance?: (role: "worker" | "reviewer") => Effect.Effect<string | undefined, FleetError>;
|
|
123
|
+
readonly readRetryMs?: number;
|
|
116
124
|
readonly refreshQuota?: () => Effect.Effect<FleetConfiguration["quota"], FleetError>;
|
|
117
125
|
readonly reviewerGuidance?: string;
|
|
118
126
|
readonly sharedEnvironment?: string;
|
|
@@ -15,6 +15,7 @@ export const CodexCloudConfiguration = Schema.Struct({
|
|
|
15
15
|
endpoint: Schema.optional(Schema.String),
|
|
16
16
|
environmentId: Schema.String.check(Schema.isNonEmpty()),
|
|
17
17
|
projectId: Schema.optional(Schema.String.check(Schema.isNonEmpty())),
|
|
18
|
+
recoveryGraceMs: Schema.Finite.check(Schema.isGreaterThan(0)),
|
|
18
19
|
refreshCommand: Schema.optional(Schema.Struct({ args: Schema.Array(Schema.String), command: Schema.String })),
|
|
19
20
|
requestTimeoutMs: Schema.Finite.check(Schema.isGreaterThan(0)),
|
|
20
21
|
threadNamePrefix: Schema.optional(Schema.String.check(Schema.isNonEmpty())),
|
|
@@ -86,7 +87,7 @@ const CodexCloud = defineService({
|
|
|
86
87
|
const adapter = codexAdapter(rpc, {
|
|
87
88
|
beforeTurn: verifyEnvironment,
|
|
88
89
|
provisioning: "unknown",
|
|
89
|
-
recoveryGraceMs:
|
|
90
|
+
recoveryGraceMs: config.recoveryGraceMs,
|
|
90
91
|
threadStart: (input) => threadStart(config, input),
|
|
91
92
|
});
|
|
92
93
|
return {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { FleetRecord } from "#model.ts";
|
|
3
|
+
import { checkAreas, needsAreaRecords } from "#scheduling/areas.ts";
|
|
4
|
+
import { acquiresExecution, checkBackPressure } from "#scheduling/backPressure.ts";
|
|
5
|
+
import type { AdmissionLimits } from "#storage/model.ts";
|
|
6
|
+
|
|
7
|
+
export const checkLaunchAdmission = Effect.fn("Fleet.checkLaunchAdmission")(function* (
|
|
8
|
+
record: FleetRecord,
|
|
9
|
+
previous: FleetRecord | undefined,
|
|
10
|
+
records: readonly FleetRecord[],
|
|
11
|
+
limits: AdmissionLimits,
|
|
12
|
+
) {
|
|
13
|
+
yield* checkAreas(record, previous, records, limits);
|
|
14
|
+
yield* checkBackPressure(record, previous, records, limits);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export function needsLaunchRecords(record: FleetRecord, previous: FleetRecord | undefined, limits: AdmissionLimits): boolean {
|
|
18
|
+
return needsAreaRecords(record, previous, limits) || (limits.implementers !== undefined && acquiresExecution(record, previous));
|
|
19
|
+
}
|
package/src/scheduling/areas.ts
CHANGED
|
@@ -27,6 +27,7 @@ function holdsAreas(record: FleetRecord, now: number, mergeWaitMs: number): bool
|
|
|
27
27
|
return (
|
|
28
28
|
!["completed", "released"].includes(record.stage)
|
|
29
29
|
&& record.attempts.length > 0
|
|
30
|
+
&& (record.stage !== "prepared" || executing(record))
|
|
30
31
|
&& record.mergeAreasReleased !== true
|
|
31
32
|
&& !mergeWaitExpired(record, now, mergeWaitMs)
|
|
32
33
|
);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { backlog, executing, type FleetRecord } from "#model.ts";
|
|
3
|
+
import { StorageCapacity } from "#storage/errors.ts";
|
|
4
|
+
import type { AdmissionLimits, OpenPullRequestCurve } from "#storage/model.ts";
|
|
5
|
+
|
|
6
|
+
export function implementerLimit(concurrency: number, curve: OpenPullRequestCurve | undefined, open: number): number {
|
|
7
|
+
if (curve === undefined || (open <= curve.ease && open < curve.max)) {
|
|
8
|
+
return concurrency;
|
|
9
|
+
}
|
|
10
|
+
const floor = Math.min(curve.floor, concurrency);
|
|
11
|
+
if (open >= curve.max) {
|
|
12
|
+
return floor;
|
|
13
|
+
}
|
|
14
|
+
return floor + Math.floor(((concurrency - floor) * (curve.max - open)) / (curve.max - curve.ease));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Reviews, repairs and answers for work that already has a session hold a slot ahead of new implementers while they wait to launch.
|
|
18
|
+
function awaitsMergeWork(record: FleetRecord): boolean {
|
|
19
|
+
return (
|
|
20
|
+
!executing(record)
|
|
21
|
+
&& (["reviewing", "repairing"].includes(record.stage)
|
|
22
|
+
|| (!["prepared", "completed", "released"].includes(record.stage) && (record.pendingAnswers?.length ?? 0) > 0))
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function acquiresExecution(record: FleetRecord, previous: FleetRecord | undefined): boolean {
|
|
27
|
+
return executing(record) && (previous === undefined || !executing(previous));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const checkBackPressure = Effect.fn("Fleet.checkBackPressure")(function* (
|
|
31
|
+
record: FleetRecord,
|
|
32
|
+
previous: FleetRecord | undefined,
|
|
33
|
+
records: readonly FleetRecord[],
|
|
34
|
+
limits: AdmissionLimits,
|
|
35
|
+
) {
|
|
36
|
+
const implementers = limits.implementers;
|
|
37
|
+
if (implementers === undefined || !acquiresExecution(record, previous)) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const others = records.filter((entry) => entry.workId !== record.workId);
|
|
41
|
+
const running = others.filter(executing).length;
|
|
42
|
+
const waiting = others.filter(awaitsMergeWork).length;
|
|
43
|
+
const open = others.filter(backlog).length;
|
|
44
|
+
const curve = implementers.openPullRequests;
|
|
45
|
+
const limit = implementerLimit(implementers.concurrency, curve, open);
|
|
46
|
+
if (running + waiting < limit) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (curve !== undefined && limit < implementers.concurrency) {
|
|
50
|
+
return yield* Effect.fail(new StorageCapacity({ kind: "open-pull-requests", limit: curve.max, occupied: open }));
|
|
51
|
+
}
|
|
52
|
+
if (running < implementers.concurrency) {
|
|
53
|
+
return yield* Effect.fail(new StorageCapacity({ kind: "merge-work", limit: implementers.concurrency, occupied: waiting }));
|
|
54
|
+
}
|
|
55
|
+
});
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { Effect } from "effect";
|
|
2
|
-
import type { StorageAdmission } from "#storage/errors.ts";
|
|
2
|
+
import type { StorageAdmission, StorageCapacity } from "#storage/errors.ts";
|
|
3
3
|
import type { AdmissionLimits } from "#storage/model.ts";
|
|
4
4
|
|
|
5
5
|
export interface FleetStoreOptions<A> {
|
|
6
|
-
readonly admission?: (
|
|
6
|
+
readonly admission?: (
|
|
7
|
+
record: A,
|
|
8
|
+
previous: A | undefined,
|
|
9
|
+
records: readonly A[],
|
|
10
|
+
limits: AdmissionLimits,
|
|
11
|
+
) => Effect.Effect<void, StorageAdmission | StorageCapacity>;
|
|
7
12
|
readonly admissionNeedsRecords?: (record: A, previous: A | undefined, limits: AdmissionLimits) => boolean;
|
|
8
13
|
readonly backlog?: (record: A) => boolean;
|
|
9
14
|
readonly executing?: (record: A) => boolean;
|