@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
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { Conflict } from "@shivaedev/platform/errors/taxonomy.ts";
|
|
3
|
+
import { ANSWER_RECORDED } from "#attention.ts";
|
|
4
|
+
import { failureMessage } from "#engine/failureMessage.ts";
|
|
5
|
+
import { makeHuman } from "#engine/makeHuman.ts";
|
|
6
|
+
import type { EngineState } from "#engine/makeState.ts";
|
|
7
|
+
import { readResolution } from "#engine/readResolution.ts";
|
|
8
|
+
import { cleanupSessions } from "#engine/sessionCleanup.ts";
|
|
9
|
+
|
|
10
|
+
export function recordResponseCommand(state: EngineState) {
|
|
11
|
+
return Effect.fn("Fleet.recordResponse")(function* (workId: string, decisionId: string, responseId: string) {
|
|
12
|
+
const stored = yield* state.load(workId);
|
|
13
|
+
const receipts = [...(stored.value.history ?? []).flatMap((cycle) => cycle.responses ?? []), ...(stored.value.responses ?? [])];
|
|
14
|
+
if (receipts.some((receipt) => receipt.decisionId === decisionId && receipt.responseId === responseId)) {
|
|
15
|
+
return stored;
|
|
16
|
+
}
|
|
17
|
+
if (stored.value.stage !== "needs-human" || stored.value.decision?.id !== decisionId) {
|
|
18
|
+
return yield* new Conflict({ message: "Decision changed" });
|
|
19
|
+
}
|
|
20
|
+
yield* readResolution(state.board, stored.value.decision, responseId);
|
|
21
|
+
const recorded = yield* state.save(stored, { ...stored.value, blocker: ANSWER_RECORDED });
|
|
22
|
+
yield* state.load(workId).pipe(
|
|
23
|
+
Effect.flatMap(makeHuman(state)),
|
|
24
|
+
Effect.flatMap(cleanupSessions(state)),
|
|
25
|
+
Effect.catch((error) => recordFailure(state, workId, error)),
|
|
26
|
+
Effect.catchCause(Effect.logError),
|
|
27
|
+
Effect.forkIn(state.launchScope),
|
|
28
|
+
);
|
|
29
|
+
return recorded;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const recordFailure = Effect.fn("Fleet.recordFailure")(function* (state: EngineState, workId: string, error: unknown) {
|
|
34
|
+
const current = yield* state.load(workId);
|
|
35
|
+
return yield* current.value.blocker === ANSWER_RECORDED
|
|
36
|
+
? state.save(current, { ...current.value, blocker: failureMessage(error) })
|
|
37
|
+
: Effect.succeed(current);
|
|
38
|
+
});
|
|
@@ -21,7 +21,7 @@ export const recoverStall = Effect.fn("Fleet.recoverStall")(function* (
|
|
|
21
21
|
if (attempt.status === "interrupted" && recovery?.interruptRequestedAt !== undefined) {
|
|
22
22
|
return yield* resumeStalled(state, stored, attempt);
|
|
23
23
|
}
|
|
24
|
-
if (!stalled(attempt, now, state.
|
|
24
|
+
if (!stalled(attempt, now, (yield* state.current).stallMinutes ?? 30)) {
|
|
25
25
|
return undefined;
|
|
26
26
|
}
|
|
27
27
|
const work = yield* state.board.get(stored.value.workId);
|
package/src/engine/repository.ts
CHANGED
|
@@ -4,33 +4,34 @@ import { defineService } from "@shivaedev/effect-service/define-service.ts";
|
|
|
4
4
|
import { operationRecord } from "#engine/operationRecord.ts";
|
|
5
5
|
import { threadName } from "#engine/threadNames.ts";
|
|
6
6
|
import { type Attempt, allAttempts, backlog, executing, FleetRecord } from "#model.ts";
|
|
7
|
-
import {
|
|
7
|
+
import { checkLaunchAdmission, needsLaunchRecords } from "#scheduling/admission.ts";
|
|
8
|
+
import { requeue } from "#scheduling/areas.ts";
|
|
8
9
|
import { SessionFailure, type SessionReceipt } from "#session/schema.ts";
|
|
9
10
|
import { SessionJournal } from "#session/service.ts";
|
|
11
|
+
import type { FleetStoreOptions } from "#storage/FleetStoreOptions.ts";
|
|
10
12
|
import { makePostgresFleetStore } from "#storage/makePostgresFleetStore.ts";
|
|
11
13
|
|
|
14
|
+
const fleetStoreOptions = {
|
|
15
|
+
admission: checkLaunchAdmission,
|
|
16
|
+
admissionNeedsRecords: needsLaunchRecords,
|
|
17
|
+
backlog,
|
|
18
|
+
executing,
|
|
19
|
+
requeue,
|
|
20
|
+
submissions: (record, since) => allAttempts(record).filter((attempt) => attempt.submittedAt >= since).length,
|
|
21
|
+
} satisfies FleetStoreOptions<FleetRecord>;
|
|
22
|
+
|
|
12
23
|
type Store = Effect.Success<ReturnType<typeof makePostgresFleetStore<typeof FleetRecord>>>;
|
|
13
|
-
export class FleetRepository extends Context.Service<
|
|
14
|
-
FleetRepository,
|
|
15
|
-
|
|
16
|
-
>()("@shivaedev/work-fleet/FleetRepository") {}
|
|
24
|
+
export class FleetRepository extends Context.Service<FleetRepository, Omit<Store, "operationEntries"> & Partial<Pick<Store, "operationEntries">>>()(
|
|
25
|
+
"@shivaedev/work-fleet/FleetRepository",
|
|
26
|
+
) {}
|
|
17
27
|
class RepositoryNamespace extends Context.Service<RepositoryNamespace, string | undefined>()("Fleet/RepositoryNamespace") {}
|
|
18
28
|
const PostgresFleetRepository = defineService({
|
|
19
29
|
id: "Fleet/PostgresFleetRepository",
|
|
20
30
|
initialize: Effect.gen(function* () {
|
|
21
31
|
const namespace = yield* RepositoryNamespace;
|
|
22
|
-
|
|
23
|
-
admission: checkAreas,
|
|
24
|
-
admissionNeedsRecords: needsAreaRecords,
|
|
25
|
-
backlog,
|
|
26
|
-
executing,
|
|
27
|
-
requeue,
|
|
28
|
-
submissions: (record, since) => allAttempts(record).filter((attempt) => attempt.submittedAt >= since).length,
|
|
29
|
-
...(namespace === undefined ? {} : { namespace }),
|
|
30
|
-
});
|
|
31
|
-
return store;
|
|
32
|
+
return yield* makePostgresFleetStore(FleetRecord, { ...fleetStoreOptions, ...(namespace === undefined ? {} : { namespace }) });
|
|
32
33
|
}),
|
|
33
|
-
methods: (
|
|
34
|
+
methods: (store) => store,
|
|
34
35
|
requires: [SqlClient.SqlClient, RepositoryNamespace],
|
|
35
36
|
});
|
|
36
37
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { EngineState, LaunchAdmission } from "#engine/makeState.ts";
|
|
3
|
+
import type { Attempt, FleetRecord } from "#model.ts";
|
|
4
|
+
import type { BoardWork } from "#policy.ts";
|
|
5
|
+
import type { Versioned } from "#storage/model.ts";
|
|
6
|
+
|
|
7
|
+
function launched(record: FleetRecord, attempt: Attempt): FleetRecord {
|
|
8
|
+
return {
|
|
9
|
+
...record,
|
|
10
|
+
admissionReady: true,
|
|
11
|
+
attempts: [...record.attempts, attempt],
|
|
12
|
+
blocker: undefined,
|
|
13
|
+
launchRetry: undefined,
|
|
14
|
+
mergeAreasReleased: undefined,
|
|
15
|
+
mergeReadyAt: undefined,
|
|
16
|
+
mergeReadyHead: undefined,
|
|
17
|
+
pendingAnswers: undefined,
|
|
18
|
+
stage: "executing",
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Urgent work first asks for admission within the limits, so only a launch the limits refused is recorded as over the limit.
|
|
23
|
+
export const saveLaunch = Effect.fn("Fleet.saveLaunch")(function* (
|
|
24
|
+
state: EngineState,
|
|
25
|
+
stored: Versioned<FleetRecord>,
|
|
26
|
+
record: FleetRecord,
|
|
27
|
+
attempt: Attempt,
|
|
28
|
+
launch: Pick<LaunchAdmission, "quota" | "role"> & { readonly priority: BoardWork["priority"] },
|
|
29
|
+
) {
|
|
30
|
+
const implementer = stored.value.stage === "prepared";
|
|
31
|
+
const admission: LaunchAdmission = {
|
|
32
|
+
ignoreAreas: implementer && stored.value.dispatchNow?.ignoreAreas === true,
|
|
33
|
+
implementer,
|
|
34
|
+
quota: launch.quota,
|
|
35
|
+
role: launch.role,
|
|
36
|
+
};
|
|
37
|
+
const urgent = implementer && (launch.priority === "urgent" || stored.value.dispatchNow !== undefined);
|
|
38
|
+
return yield* state
|
|
39
|
+
.save(stored, launched(record, attempt), admission)
|
|
40
|
+
.pipe(
|
|
41
|
+
Effect.catchTag("StorageCapacity", (error) =>
|
|
42
|
+
urgent ? state.save(stored, launched(record, { ...attempt, overLimit: true }), { ...admission, overLimit: true }) : Effect.fail(error),
|
|
43
|
+
),
|
|
44
|
+
);
|
|
45
|
+
});
|
package/src/engine/scheduler.ts
CHANGED
|
@@ -10,9 +10,7 @@ import type { Versioned } from "#storage/model.ts";
|
|
|
10
10
|
|
|
11
11
|
const dispatchRecords = Effect.fn("Fleet.dispatchRecords")(function* (records: readonly Versioned<FleetRecord>[]) {
|
|
12
12
|
const fleet = yield* Fleet;
|
|
13
|
-
const prepared = records
|
|
14
|
-
.filter(({ value }) => value.stage === "prepared")
|
|
15
|
-
.sort((left, right) => (right.value.launchRetry?.retryAt ?? 0) - (left.value.launchRetry?.retryAt ?? 0));
|
|
13
|
+
const prepared = yield* fleet.admissionOrder(records);
|
|
16
14
|
const dispatched: Result.Result<Effect.Success<ReturnType<typeof fleet.dispatch>>, Effect.Error<ReturnType<typeof fleet.dispatch>>>[] = [];
|
|
17
15
|
for (const { value } of prepared) {
|
|
18
16
|
const result = yield* fleet.dispatch(value.workId).pipe(Effect.result);
|
|
@@ -60,8 +58,8 @@ export const cycle = inBoardReadPass(
|
|
|
60
58
|
return result;
|
|
61
59
|
}),
|
|
62
60
|
);
|
|
63
|
-
export const run = Effect.fn("Fleet.run")(function* <R = never>(
|
|
64
|
-
|
|
61
|
+
export const run = Effect.fn("Fleet.run")(function* <R = never, TPause = never>(
|
|
62
|
+
pause: Effect.Effect<void, never, TPause>,
|
|
65
63
|
admit: Effect.Effect<void, never, R> = Effect.void,
|
|
66
64
|
) {
|
|
67
65
|
const fleet = yield* Fleet;
|
|
@@ -82,6 +80,6 @@ export const run = Effect.fn("Fleet.run")(function* <R = never>(
|
|
|
82
80
|
yield* dispatchPrepared;
|
|
83
81
|
yield* schedulerPassed;
|
|
84
82
|
}),
|
|
85
|
-
).pipe(Effect.andThen(
|
|
83
|
+
).pipe(Effect.andThen(pause)),
|
|
86
84
|
);
|
|
87
85
|
});
|
package/src/engine/views.ts
CHANGED
|
@@ -12,6 +12,7 @@ export function views(records: readonly FleetRecord[]): typeof FleetViews.Type {
|
|
|
12
12
|
decision: record.stage === "completed" ? undefined : record.decision,
|
|
13
13
|
links: [...(record.report === undefined ? [] : [record.report.sourcePath]), ...(record.result?.kind === "change" ? [record.result.pr] : [])],
|
|
14
14
|
outcome: record.outcome,
|
|
15
|
+
...(launchedOverLimit(record) ? { overLimit: true } : {}),
|
|
15
16
|
sessions: record.attempts.flatMap(sessionView),
|
|
16
17
|
stage: record.stage,
|
|
17
18
|
workId: record.workId,
|
|
@@ -41,3 +42,7 @@ function sessionView(attempt: Attempt) {
|
|
|
41
42
|
},
|
|
42
43
|
];
|
|
43
44
|
}
|
|
45
|
+
|
|
46
|
+
function launchedOverLimit(record: FleetRecord) {
|
|
47
|
+
return record.attempts.some((attempt) => attempt.overLimit === true && ["submitting", "accepted", "running"].includes(attempt.status));
|
|
48
|
+
}
|
package/src/fleet.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { defineService } from "@shivaedev/effect-service/define-service.ts";
|
|
3
|
+
import { admissionOrder } from "#engine/admissionOrder.ts";
|
|
3
4
|
import { closeDecisions } from "#engine/closeDecisions.ts";
|
|
4
5
|
import { continueCommand } from "#engine/continueCommand.ts";
|
|
5
6
|
import { dispatchCommand } from "#engine/dispatchCommand.ts";
|
|
@@ -11,6 +12,7 @@ import { prepareCommand } from "#engine/prepareCommand.ts";
|
|
|
11
12
|
import { queueAnswerCommand } from "#engine/queueAnswerCommand.ts";
|
|
12
13
|
import { reassignCommand } from "#engine/reassignCommand.ts";
|
|
13
14
|
import { reconcileCommand } from "#engine/reconcileCommand.ts";
|
|
15
|
+
import { recordResponseCommand } from "#engine/recordResponseCommand.ts";
|
|
14
16
|
import { FleetRepository } from "#engine/repository.ts";
|
|
15
17
|
import { resolveCommand } from "#engine/resolveCommand.ts";
|
|
16
18
|
import { cleanupSessions } from "#engine/sessionCleanup.ts";
|
|
@@ -33,6 +35,7 @@ export const Fleet = defineService({
|
|
|
33
35
|
return { ...state, advance: makeAdvance(state, launch), launch };
|
|
34
36
|
}),
|
|
35
37
|
methods: (state) => ({
|
|
38
|
+
admissionOrder: admissionOrder(state),
|
|
36
39
|
continue: continueCommand(state, state.launch),
|
|
37
40
|
dispatch: dispatchCommand(state, state.launch),
|
|
38
41
|
get: (workId: string) => state.load(workId),
|
|
@@ -43,6 +46,7 @@ export const Fleet = defineService({
|
|
|
43
46
|
queueAnswer: queueAnswerCommand(state),
|
|
44
47
|
reassign: reassignCommand(state),
|
|
45
48
|
reconcile: (workId: string) => reconcileCommand(state, state.advance)(workId).pipe(Effect.flatMap(cleanupSessions(state))),
|
|
49
|
+
recordResponse: recordResponseCommand(state),
|
|
46
50
|
resolve: (workId: string, decisionId: string, responseId: string) =>
|
|
47
51
|
resolveCommand(state)(workId, decisionId, responseId).pipe(Effect.flatMap(cleanupSessions(state))),
|
|
48
52
|
}),
|
|
@@ -12,7 +12,11 @@ export const continueCommand = Command.make(
|
|
|
12
12
|
{ args: [Argument.String("id"), Argument.String("message").pipe(Argument.optional)] as const, board, config, port },
|
|
13
13
|
Effect.fn("WorkFleetCli.continue")(function* (input) {
|
|
14
14
|
const message = yield* continuationMessage(Option.getOrUndefined(input.args[1]));
|
|
15
|
-
const value = yield* daemonRequest(
|
|
15
|
+
const value = yield* daemonRequest(
|
|
16
|
+
input.port,
|
|
17
|
+
(client) => client("fleet.continue", { message, workId: input.args[0] }),
|
|
18
|
+
`continue ${input.args[0]}`,
|
|
19
|
+
);
|
|
16
20
|
yield* Console.log(`${value.workId} ${value.stage}${value.blocker === undefined ? "" : `: ${value.blocker}`}`);
|
|
17
21
|
}),
|
|
18
22
|
).pipe(
|
|
@@ -23,7 +27,11 @@ export const releaseCommand = Command.make(
|
|
|
23
27
|
"release",
|
|
24
28
|
{ board, config, port, workIds: Argument.String("id").pipe(Argument.variadic({ min: 1 })) },
|
|
25
29
|
Effect.fn("WorkFleetCli.release")(function* (input) {
|
|
26
|
-
const released = yield* daemonRequest(
|
|
30
|
+
const released = yield* daemonRequest(
|
|
31
|
+
input.port,
|
|
32
|
+
(client) => client("daemon.release", { workIds: input.workIds }),
|
|
33
|
+
`release ${input.workIds.join(", ")}`,
|
|
34
|
+
);
|
|
27
35
|
for (const value of released) {
|
|
28
36
|
yield* Console.log(`${value.workId} ${value.stage}${value.blocker === undefined ? "" : `: ${value.blocker}`}`);
|
|
29
37
|
}
|
|
@@ -41,8 +49,10 @@ export const reassignCommand = Command.make(
|
|
|
41
49
|
to: Argument.Literals("owner", ["maintainer", "orchestrator", "automation"]),
|
|
42
50
|
},
|
|
43
51
|
Effect.fn("WorkFleetCli.reassign")(function* (input) {
|
|
44
|
-
const value = yield* daemonRequest(
|
|
45
|
-
|
|
52
|
+
const value = yield* daemonRequest(
|
|
53
|
+
input.port,
|
|
54
|
+
(client) => client("fleet.reassign", { attentionOwner: input.to, decisionId: input.question, workId: input.id }),
|
|
55
|
+
`reassign ${input.id}`,
|
|
46
56
|
);
|
|
47
57
|
yield* Console.log(`${value.workId} ${value.stage} (waiting on ${value.attentionOwner})`);
|
|
48
58
|
}),
|
|
@@ -52,7 +62,7 @@ export const nameThreadsCommand = Command.make(
|
|
|
52
62
|
"name-threads",
|
|
53
63
|
{ board, config, port },
|
|
54
64
|
Effect.fn("WorkFleetCli.nameThreads")(function* (input) {
|
|
55
|
-
const results = yield* daemonRequest(input.port, (client) => client("daemon.name-threads", {}));
|
|
65
|
+
const results = yield* daemonRequest(input.port, (client) => client("daemon.name-threads", {}), "name-threads");
|
|
56
66
|
for (const result of results) {
|
|
57
67
|
yield* result.error ? Console.error(result.message) : Console.log(result.message);
|
|
58
68
|
}
|
|
@@ -69,8 +79,13 @@ export const answerCommand = Command.make(
|
|
|
69
79
|
release: Flag.Boolean("release").pipe(Flag.withDefault(false)),
|
|
70
80
|
},
|
|
71
81
|
Effect.fn("WorkFleetCli.answer")(function* (input) {
|
|
72
|
-
const
|
|
73
|
-
const
|
|
82
|
+
const supplied = Option.getOrUndefined(input.args[1]);
|
|
83
|
+
const text = input.release && supplied === undefined ? "" : yield* answerText(supplied);
|
|
84
|
+
const value = yield* daemonRequest(
|
|
85
|
+
input.port,
|
|
86
|
+
(client) => client("daemon.answer", { release: input.release, text, workId: input.args[0] }),
|
|
87
|
+
`answer ${input.args[0]}`,
|
|
88
|
+
);
|
|
74
89
|
const detail = (value.pendingAnswers?.length ?? 0) > 0 ? "queued for the next turn" : value.blocker;
|
|
75
90
|
yield* Console.log(`${value.workId} ${value.stage}${detail === undefined ? "" : `: ${detail}`}`);
|
|
76
91
|
}),
|
package/src/host/admission.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { Fleet } from "#fleet.ts";
|
|
|
8
8
|
import type { FleetHost } from "#host/config.ts";
|
|
9
9
|
import { type MainSnapshot, MainSource } from "#host/mainSource.ts";
|
|
10
10
|
import { workerCwd } from "#host/providers.ts";
|
|
11
|
-
import type { FleetRecord } from "#model.ts";
|
|
11
|
+
import type { DispatchNow, FleetRecord } from "#model.ts";
|
|
12
12
|
import { BoardGateway, type BoardWork } from "#policy.ts";
|
|
13
13
|
import type { Preparation } from "#preparation/schema.ts";
|
|
14
14
|
import { workerPrompt } from "#prompt/worker.ts";
|
|
@@ -116,7 +116,7 @@ export const admitApproved = Effect.fn("FleetHost.admitApproved")(function* (hos
|
|
|
116
116
|
return failures;
|
|
117
117
|
}, inBoardReadPass);
|
|
118
118
|
|
|
119
|
-
export const dispatchApproved = Effect.fn("FleetHost.dispatchApproved")(function* (host: FleetHost, workId: string) {
|
|
119
|
+
export const dispatchApproved = Effect.fn("FleetHost.dispatchApproved")(function* (host: FleetHost, workId: string, now?: DispatchNow) {
|
|
120
120
|
const fleet = yield* Fleet;
|
|
121
121
|
const work = yield* (yield* BoardGateway).get(workId);
|
|
122
122
|
if (!work.approved) {
|
|
@@ -127,5 +127,5 @@ export const dispatchApproved = Effect.fn("FleetHost.dispatchApproved")(function
|
|
|
127
127
|
if (existing === undefined || ["completed", "released"].includes(existing.stage) || unlaunched(existing) || !briefChanged(existing, work)) {
|
|
128
128
|
yield* prepareApproved(host, work, existing, "explicit");
|
|
129
129
|
}
|
|
130
|
-
return yield* fleet.dispatch(workId, launchPrompt(host, work));
|
|
130
|
+
return yield* fleet.dispatch(workId, launchPrompt(host, work), now);
|
|
131
131
|
}, inBoardReadPass);
|
package/src/host/answerWork.ts
CHANGED
|
@@ -3,37 +3,38 @@ import { BadRequest, Conflict } from "@shivaedev/platform/errors/taxonomy.ts";
|
|
|
3
3
|
import { Fleet } from "#fleet.ts";
|
|
4
4
|
import type { FleetHost } from "#host/config.ts";
|
|
5
5
|
import { recordDecisionResponse } from "#host/recordDecisionResponse.ts";
|
|
6
|
-
import { withDecisionResponses } from "#host/releaseWork.ts";
|
|
7
6
|
import type { FleetRecord } from "#model.ts";
|
|
8
7
|
import type { Decision } from "#policy.ts";
|
|
9
8
|
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
)
|
|
34
|
-
|
|
9
|
+
export const answerWork = Effect.fn("FleetHost.answerWork")(function* (
|
|
10
|
+
host: FleetHost,
|
|
11
|
+
workId: string,
|
|
12
|
+
text = "",
|
|
13
|
+
release = false,
|
|
14
|
+
background = false,
|
|
15
|
+
) {
|
|
16
|
+
const fleet = yield* Fleet;
|
|
17
|
+
const resolve = background ? fleet.recordResponse : fleet.resolve;
|
|
18
|
+
const original = (yield* fleet.get(workId)).value.decision;
|
|
19
|
+
let recorded: { readonly decisionId: string; readonly responseId: string } | undefined;
|
|
20
|
+
return yield* Effect.gen(function* () {
|
|
21
|
+
const current = (yield* fleet.get(workId)).value;
|
|
22
|
+
if (recorded !== undefined && hasResponse(current, recorded)) {
|
|
23
|
+
return yield* resolve(workId, recorded.decisionId, recorded.responseId);
|
|
24
|
+
}
|
|
25
|
+
if (canQueueAnswer(current, text, release)) {
|
|
26
|
+
return yield* fleet.queueAnswer(workId, text);
|
|
27
|
+
}
|
|
28
|
+
yield* checkDecision(current, original);
|
|
29
|
+
const response = yield* publishAnswer(host, workId, original, text, release);
|
|
30
|
+
recorded = response;
|
|
31
|
+
return yield* resolve(workId, response.decisionId, response.responseId).pipe(
|
|
32
|
+
Effect.catchTag("Conflict", (error) => decisionConflict(fleet, workId, response.decisionId, error)),
|
|
33
|
+
);
|
|
34
|
+
}).pipe(
|
|
35
|
+
Effect.retry({ while: (error) => error._tag === "StorageConflict" || (error._tag === "Conflict" && error.message === "Decision changed") }),
|
|
35
36
|
);
|
|
36
|
-
}
|
|
37
|
+
});
|
|
37
38
|
|
|
38
39
|
function checkDecision(record: FleetRecord, original: Decision | undefined) {
|
|
39
40
|
const current = record.decision;
|
package/src/host/cliOptions.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as Flag from "effect/cli/Flag";
|
|
2
2
|
import * as Option from "effect/Option";
|
|
3
3
|
import { diagnostics as diagnosticsApi } from "@shivaedev/work-board/integration/diagnostics.ts";
|
|
4
|
-
import { loadHost } from "#host/
|
|
4
|
+
import { loadHost } from "#host/configFile.ts";
|
|
5
5
|
|
|
6
6
|
const { DAEMON_PORT } = diagnosticsApi;
|
|
7
7
|
|
package/src/host/commands.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
2
|
-
import { Console, Effect, Layer } from "effect";
|
|
2
|
+
import { Console, Effect, Layer, Stream } from "effect";
|
|
3
3
|
import type { ReportInspection } from "#engine/ReportInspection.ts";
|
|
4
4
|
import { run } from "#engine/scheduler.ts";
|
|
5
5
|
import { Fleet } from "#fleet.ts";
|
|
6
6
|
import { admitApproved, dispatchApproved } from "#host/admission.ts";
|
|
7
7
|
import type { FleetHost } from "#host/config.ts";
|
|
8
|
+
import { GithubApi } from "#host/githubApi.ts";
|
|
8
9
|
import { healthLayer } from "#host/healthLayer.ts";
|
|
10
|
+
import { LiveConfig, staticConfig } from "#host/liveConfig.ts";
|
|
9
11
|
import { gitMainSource, type MainSource } from "#host/mainSource.ts";
|
|
10
12
|
import { hostProvider } from "#host/providers.ts";
|
|
11
13
|
import { fleetHostLayer } from "#host/runtime.ts";
|
|
@@ -14,8 +16,9 @@ import type { BoardGateway, FleetIntegrations, FleetPolicy } from "#policy.ts";
|
|
|
14
16
|
import type { SessionTransport } from "#session/service.ts";
|
|
15
17
|
|
|
16
18
|
export interface HostParts {
|
|
17
|
-
readonly board?: Layer.Layer<BoardGateway | ReportInspection, unknown, MainSource>;
|
|
18
|
-
readonly
|
|
19
|
+
readonly board?: Layer.Layer<BoardGateway | ReportInspection, unknown, MainSource | GithubApi>;
|
|
20
|
+
readonly github?: Layer.Layer<GithubApi>;
|
|
21
|
+
readonly integrations?: Layer.Layer<FleetIntegrations, unknown, MainSource | GithubApi>;
|
|
19
22
|
readonly main: Layer.Layer<MainSource, unknown>;
|
|
20
23
|
readonly policy?: Layer.Layer<FleetPolicy>;
|
|
21
24
|
readonly provider: Layer.Layer<SessionTransport, unknown>;
|
|
@@ -25,13 +28,31 @@ export function productionParts(host: FleetHost): HostParts {
|
|
|
25
28
|
return { main: gitMainSource(host), provider: hostProvider(host) };
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
export function hostLayer(host: FleetHost, parts: HostParts) {
|
|
29
|
-
const runtime = Layer.mergeAll(fleetHostLayer(host, parts), NodeServices.layer).pipe(Layer.provideMerge(healthLayer(host.boardDir)));
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
export function hostLayer(host: FleetHost, parts: HostParts, config: Layer.Layer<LiveConfig, unknown> = staticConfig(host)) {
|
|
32
|
+
const runtime = Layer.mergeAll(fleetHostLayer(host, parts, config), NodeServices.layer).pipe(Layer.provideMerge(healthLayer(host.boardDir)));
|
|
33
|
+
const status = Layer.unwrap(
|
|
34
|
+
Effect.map(LiveConfig, (live) =>
|
|
35
|
+
statusLayer(
|
|
36
|
+
host.boardDir,
|
|
37
|
+
Effect.map(live.current, ({ host: applied }) => ({
|
|
38
|
+
concurrency: applied.concurrency,
|
|
39
|
+
staleAfterMs: Math.max(60_000, applied.interval * 3000),
|
|
40
|
+
})),
|
|
41
|
+
),
|
|
42
|
+
),
|
|
32
43
|
);
|
|
44
|
+
return status.pipe(Layer.provideMerge(runtime), Layer.provideMerge(config));
|
|
33
45
|
}
|
|
34
46
|
|
|
47
|
+
// An applied config edit starts the next pass at once instead of after the interval it replaced, and a low GitHub budget stretches that interval.
|
|
48
|
+
export const schedulerPause = Effect.gen(function* () {
|
|
49
|
+
const live = yield* LiveConfig;
|
|
50
|
+
const github = yield* GithubApi;
|
|
51
|
+
const { host: applied } = yield* live.current;
|
|
52
|
+
const delay = yield* github.pace(applied.interval * 1000);
|
|
53
|
+
yield* Effect.raceFirst(Effect.sleep(delay), live.changes.pipe(Stream.drop(1), Stream.take(1), Stream.runDrain));
|
|
54
|
+
});
|
|
55
|
+
|
|
35
56
|
export function hostScheduler(host: FleetHost) {
|
|
36
57
|
let reported = new Set<string>();
|
|
37
58
|
const admission = admitApproved(host).pipe(
|
|
@@ -45,7 +66,7 @@ export function hostScheduler(host: FleetHost) {
|
|
|
45
66
|
}),
|
|
46
67
|
),
|
|
47
68
|
);
|
|
48
|
-
return run(
|
|
69
|
+
return run(schedulerPause, admission);
|
|
49
70
|
}
|
|
50
71
|
|
|
51
72
|
export function runFleet(host: FleetHost, parts: HostParts = productionParts(host)) {
|
package/src/host/config.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect";
|
|
2
|
-
import * as FileSystem from "effect/FileSystem";
|
|
3
|
-
import * as Path from "effect/Path";
|
|
4
1
|
import * as Schema from "effect/Schema";
|
|
5
|
-
import {
|
|
2
|
+
import { DEFAULT_READ_RETRY_MS } from "#engine/readRetry.ts";
|
|
3
|
+
import { DEFAULT_NAMESPACE, NAMESPACE, SHARED_LOCAL_POSTGRES } from "#host/defaults.ts";
|
|
6
4
|
import { DEFAULT_AREA_MERGE_WAIT_MS } from "#scheduling/areas.ts";
|
|
7
5
|
import { LaunchSettings } from "#session/schema.ts";
|
|
6
|
+
import type { OpenPullRequestCurve } from "#storage/model.ts";
|
|
8
7
|
|
|
9
8
|
const Positive = Schema.Int.check(Schema.isGreaterThan(0));
|
|
9
|
+
const Count = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
|
|
10
10
|
const Text = Schema.String.check(Schema.isMinLength(1));
|
|
11
11
|
const Guidance = Schema.Union([Text, Schema.Struct({ file: Text })]);
|
|
12
12
|
|
|
@@ -21,6 +21,7 @@ export const HostConfig = Schema.Struct({
|
|
|
21
21
|
endpoint: Schema.optional(Text),
|
|
22
22
|
environmentId: Text,
|
|
23
23
|
projectId: Schema.optional(Text),
|
|
24
|
+
recoveryGraceMs: Schema.optional(Positive),
|
|
24
25
|
refreshCommand: Schema.optional(Schema.Struct({ args: Schema.Array(Schema.String), command: Text })),
|
|
25
26
|
requestTimeoutMs: Schema.optional(Positive),
|
|
26
27
|
threadNamePrefix: Schema.optional(Text),
|
|
@@ -33,8 +34,14 @@ export const HostConfig = Schema.Struct({
|
|
|
33
34
|
launch: Schema.optional(LaunchSettings),
|
|
34
35
|
local: Schema.optional(Schema.Struct({ endpoint: Text, requestTimeoutMs: Schema.optional(Positive) })),
|
|
35
36
|
namespace: Schema.optional(Schema.String.check(Schema.isPattern(NAMESPACE))),
|
|
37
|
+
openPullRequests: Schema.optional(
|
|
38
|
+
Schema.Struct({ ease: Count, floor: Schema.optional(Count), max: Positive }).check(
|
|
39
|
+
Schema.makeFilter((curve) => curve.ease <= curve.max || "openPullRequests.ease must not exceed openPullRequests.max"),
|
|
40
|
+
),
|
|
41
|
+
),
|
|
36
42
|
provider: Schema.Literals(["local", "cloud"]),
|
|
37
43
|
quota: Schema.optional(Schema.Literals(["codex", "unlimited"])),
|
|
44
|
+
readRetryMs: Schema.optional(Positive),
|
|
38
45
|
repository: Schema.optional(Schema.Struct({ branch: Text, remote: Text })),
|
|
39
46
|
result: Schema.optional(Schema.Literal("github")),
|
|
40
47
|
stallMinutes: Schema.optional(Positive),
|
|
@@ -51,61 +58,58 @@ export type HostConfig = typeof HostConfig.Type;
|
|
|
51
58
|
|
|
52
59
|
export class HostFailure extends Schema.TaggedError<HostFailure>()("HostFailure", { message: Schema.String }) {}
|
|
53
60
|
|
|
61
|
+
export class HostConfigRejected extends Schema.TaggedError<HostConfigRejected>()("HostConfigRejected", {
|
|
62
|
+
field: Schema.optional(Schema.String),
|
|
63
|
+
file: Schema.String,
|
|
64
|
+
message: Schema.String,
|
|
65
|
+
}) {}
|
|
66
|
+
|
|
54
67
|
export interface FleetHost {
|
|
55
68
|
readonly areaMergeWaitMs: number;
|
|
56
69
|
readonly backlog: number;
|
|
57
70
|
readonly boardDir: string;
|
|
58
71
|
readonly cloud: HostConfig["cloud"];
|
|
59
72
|
readonly concurrency: number;
|
|
73
|
+
readonly config: HostConfig;
|
|
74
|
+
readonly configFile?: string;
|
|
60
75
|
readonly databaseUrl: string;
|
|
61
76
|
readonly interval: number;
|
|
62
77
|
readonly launch: NonNullable<HostConfig["launch"]>;
|
|
63
78
|
readonly local: HostConfig["local"];
|
|
64
79
|
readonly maxConnections: number;
|
|
65
80
|
readonly namespace: string;
|
|
81
|
+
readonly openPullRequests?: OpenPullRequestCurve;
|
|
66
82
|
readonly provider: HostConfig["provider"];
|
|
67
83
|
readonly quota: NonNullable<HostConfig["quota"]>;
|
|
84
|
+
readonly readRetryMs: number;
|
|
68
85
|
readonly repository: NonNullable<HostConfig["repository"]>;
|
|
69
86
|
readonly result?: HostConfig["result"];
|
|
70
87
|
readonly stallMinutes: number;
|
|
71
88
|
readonly worker: HostConfig["worker"];
|
|
72
89
|
}
|
|
73
90
|
|
|
74
|
-
export function resolveHost(boardDir: string, config: HostConfig): FleetHost {
|
|
91
|
+
export function resolveHost(boardDir: string, config: HostConfig, configFile?: string): FleetHost {
|
|
75
92
|
return {
|
|
76
93
|
areaMergeWaitMs: config.areaMergeWaitMs ?? DEFAULT_AREA_MERGE_WAIT_MS,
|
|
77
94
|
backlog: config.backlog ?? 100,
|
|
78
95
|
boardDir,
|
|
79
96
|
cloud: config.cloud,
|
|
80
97
|
concurrency: config.concurrency ?? 100,
|
|
98
|
+
config,
|
|
99
|
+
...(configFile === undefined ? {} : { configFile }),
|
|
81
100
|
databaseUrl: config.database?.url ?? SHARED_LOCAL_POSTGRES,
|
|
82
101
|
interval: config.intervalSeconds ?? 15,
|
|
83
102
|
launch: config.launch ?? {},
|
|
84
103
|
local: config.local,
|
|
85
104
|
maxConnections: config.database?.maxConnections ?? 20,
|
|
86
105
|
namespace: config.namespace ?? DEFAULT_NAMESPACE,
|
|
106
|
+
...(config.openPullRequests === undefined ? {} : { openPullRequests: { ...config.openPullRequests, floor: config.openPullRequests.floor ?? 0 } }),
|
|
87
107
|
provider: config.provider,
|
|
88
108
|
quota: config.quota ?? "codex",
|
|
109
|
+
readRetryMs: config.readRetryMs ?? DEFAULT_READ_RETRY_MS,
|
|
89
110
|
repository: config.repository ?? { branch: "main", remote: "origin" },
|
|
90
111
|
result: config.result,
|
|
91
112
|
stallMinutes: config.stallMinutes ?? 30,
|
|
92
113
|
worker: config.worker,
|
|
93
114
|
};
|
|
94
115
|
}
|
|
95
|
-
|
|
96
|
-
export const loadHost = Effect.fn("FleetHost.loadHost")(function* (board: string, configPath?: string) {
|
|
97
|
-
const fs = yield* FileSystem.FileSystem;
|
|
98
|
-
const path = yield* Path.Path;
|
|
99
|
-
const boardDir = path.resolve(board);
|
|
100
|
-
const file = configPath === undefined ? path.join(boardDir, CONFIG_FILE) : path.resolve(configPath);
|
|
101
|
-
const text = yield* fs
|
|
102
|
-
.readFileString(file)
|
|
103
|
-
.pipe(Effect.mapError(() => new HostFailure({ message: `Fleet host configuration is missing or unreadable: ${file}` })));
|
|
104
|
-
const config = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(HostConfig))(text).pipe(
|
|
105
|
-
Effect.mapError((error) => new HostFailure({ message: `Fleet host configuration ${file} is invalid: ${error.message}` })),
|
|
106
|
-
);
|
|
107
|
-
if (config.provider === "cloud" && (config.cloud === undefined || config.worker === undefined)) {
|
|
108
|
-
return yield* new HostFailure({ message: `Fleet host configuration ${file} selects provider "cloud" without cloud and worker settings` });
|
|
109
|
-
}
|
|
110
|
-
return resolveHost(boardDir, config);
|
|
111
|
-
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as FileSystem from "effect/FileSystem";
|
|
3
|
+
import * as Path from "effect/Path";
|
|
4
|
+
import * as Schema from "effect/Schema";
|
|
5
|
+
import * as SchemaIssue from "effect/SchemaIssue";
|
|
6
|
+
import { HostConfig, HostConfigRejected, HostFailure, resolveHost } from "#host/config.ts";
|
|
7
|
+
import { CONFIG_FILE } from "#host/defaults.ts";
|
|
8
|
+
|
|
9
|
+
export const readHostConfig = Effect.fn("FleetHost.readHostConfig")(function* (file: string) {
|
|
10
|
+
const fs = yield* FileSystem.FileSystem;
|
|
11
|
+
const text = yield* fs
|
|
12
|
+
.readFileString(file)
|
|
13
|
+
.pipe(Effect.mapError(() => new HostConfigRejected({ file, message: `Fleet host configuration is missing or unreadable: ${file}` })));
|
|
14
|
+
const config = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(HostConfig))(text).pipe(
|
|
15
|
+
Effect.mapError((error) => {
|
|
16
|
+
const field = SchemaIssue.makeFormatterStandardSchemaV1()(error.issue).issues[0]?.path?.map(String).join(".");
|
|
17
|
+
return new HostConfigRejected({
|
|
18
|
+
...(field === undefined || field === "" ? {} : { field }),
|
|
19
|
+
file,
|
|
20
|
+
message: `Fleet host configuration ${file} is invalid: ${error.message}`,
|
|
21
|
+
});
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
24
|
+
if (config.provider === "cloud" && (config.cloud === undefined || config.worker === undefined)) {
|
|
25
|
+
return yield* new HostConfigRejected({
|
|
26
|
+
field: config.cloud === undefined ? "cloud" : "worker",
|
|
27
|
+
file,
|
|
28
|
+
message: `Fleet host configuration ${file} selects provider "cloud" without cloud and worker settings`,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return config;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export const loadHost = Effect.fn("FleetHost.loadHost")(function* (board: string, configPath?: string) {
|
|
35
|
+
const path = yield* Path.Path;
|
|
36
|
+
const boardDir = path.resolve(board);
|
|
37
|
+
const file = configPath === undefined ? path.join(boardDir, CONFIG_FILE) : path.resolve(configPath);
|
|
38
|
+
const config = yield* readHostConfig(file).pipe(Effect.mapError((rejected) => new HostFailure({ message: rejected.message })));
|
|
39
|
+
return resolveHost(boardDir, config, file);
|
|
40
|
+
});
|