cloving 1.1.0 → 1.3.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/README.md +584 -144
- package/assets/watch-fonts/fira-code-OFL.md +93 -0
- package/assets/watch-fonts/fira-code-latin-400-normal.woff2 +0 -0
- package/assets/watch-fonts/fira-code-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-OFL.md +93 -0
- package/assets/watch-fonts/heebo-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-latin-700-normal.woff2 +0 -0
- package/assets/watch-fonts/heebo-latin-800-normal.woff2 +0 -0
- package/assets/watch-fonts/manifest.json +112 -0
- package/assets/watch-fonts/space-grotesk-OFL.md +93 -0
- package/assets/watch-fonts/space-grotesk-latin-400-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-500-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-600-normal.woff2 +0 -0
- package/assets/watch-fonts/space-grotesk-latin-700-normal.woff2 +0 -0
- package/dist/src/agent-harness-shell.d.ts +12 -0
- package/dist/src/agent-harness-shell.js +90 -0
- package/dist/src/agent-harness-versions.d.ts +8 -0
- package/dist/src/agent-harness-versions.js +49 -0
- package/dist/src/agent-harnesses.d.ts +4 -0
- package/dist/src/agent-harnesses.js +13 -0
- package/dist/src/authority/commands.d.ts +2 -0
- package/dist/src/authority/commands.js +49 -8
- package/dist/src/authority/dispatch-decision.d.ts +1 -0
- package/dist/src/authority/dispatch-decision.js +7 -4
- package/dist/src/authority/events.js +2 -2
- package/dist/src/authority/gate-reduction.d.ts +1 -0
- package/dist/src/authority/gate-reduction.js +18 -3
- package/dist/src/authority/gates.d.ts +2 -1
- package/dist/src/authority/gates.js +5 -1
- package/dist/src/authority/handoff-chain.d.ts +24 -0
- package/dist/src/authority/handoff-chain.js +46 -0
- package/dist/src/authority/operations.js +1 -1
- package/dist/src/authority/reconciliation.d.ts +1 -0
- package/dist/src/authority/reconciliation.js +18 -11
- package/dist/src/authority/reduction.d.ts +1 -1
- package/dist/src/authority/reduction.js +6 -1
- package/dist/src/authority/status-input.d.ts +1 -1
- package/dist/src/authority/status.d.ts +1 -0
- package/dist/src/authority/status.js +27 -3
- package/dist/src/authority/transitions.d.ts +5 -5
- package/dist/src/authority/transitions.js +9 -0
- package/dist/src/broker/actor/authority-delivery.js +1 -0
- package/dist/src/broker/actor/authority-queries.d.ts +11 -1
- package/dist/src/broker/actor/authority-queries.js +67 -3
- package/dist/src/broker/actor/authority-receipts.js +11 -1
- package/dist/src/broker/actor/authority-session.js +2 -2
- package/dist/src/broker/actor/authority-settings.js +4 -0
- package/dist/src/broker/actor/delivery-intents.d.ts +3 -1
- package/dist/src/broker/actor/delivery-intents.js +4 -4
- package/dist/src/broker/actor/effect-delivery.js +13 -1
- package/dist/src/broker/actor/effect-queries.d.ts +1 -0
- package/dist/src/broker/actor/effect-queries.js +7 -0
- package/dist/src/broker/actor/pin-check.js +1 -1
- package/dist/src/broker/actor/stop-plan.js +1 -1
- package/dist/src/broker/actor/turn-state.js +1 -1
- package/dist/src/broker/authority-admission.js +26 -5
- package/dist/src/broker/authority-restore.js +1 -0
- package/dist/src/broker/decision-restore.js +4 -4
- package/dist/src/broker/socket-address.d.ts +3 -1
- package/dist/src/broker/socket-address.js +2 -2
- package/dist/src/cli/arguments.d.ts +11 -13
- package/dist/src/cli/arguments.js +37 -107
- package/dist/src/cli/command-effects.d.ts +7 -0
- package/dist/src/cli/command-effects.js +39 -0
- package/dist/src/cli/commands.js +11 -4
- package/dist/src/cli/config-arguments.d.ts +11 -0
- package/dist/src/cli/config-arguments.js +59 -0
- package/dist/src/cli/config-command.d.ts +2 -0
- package/dist/src/cli/config-command.js +105 -0
- package/dist/src/cli/config-file.d.ts +3 -0
- package/dist/src/cli/config-file.js +50 -0
- package/dist/src/cli/config-lock.d.ts +7 -0
- package/dist/src/cli/config-lock.js +61 -0
- package/dist/src/cli/config-notice.d.ts +5 -0
- package/dist/src/cli/config-notice.js +46 -0
- package/dist/src/cli/doctor-github.d.ts +9 -0
- package/dist/src/cli/doctor-github.js +138 -0
- package/dist/src/cli/doctor-harness.d.ts +13 -0
- package/dist/src/cli/doctor-harness.js +242 -0
- package/dist/src/cli/doctor-local.d.ts +18 -0
- package/dist/src/cli/doctor-local.js +77 -0
- package/dist/src/cli/doctor-runtime.d.ts +15 -0
- package/dist/src/cli/doctor-runtime.js +176 -0
- package/dist/src/cli/doctor-service.d.ts +1 -0
- package/dist/src/cli/doctor-service.js +11 -0
- package/dist/src/cli/doctor-workflows.d.ts +3 -0
- package/dist/src/cli/doctor-workflows.js +45 -0
- package/dist/src/cli/doctor.d.ts +15 -0
- package/dist/src/cli/doctor.js +190 -0
- package/dist/src/cli/github-ci-progress.d.ts +8 -0
- package/dist/src/cli/github-ci-progress.js +83 -0
- package/dist/src/cli/github-retry.d.ts +6 -0
- package/dist/src/cli/github-retry.js +47 -0
- package/dist/src/cli/harness-probes.d.ts +22 -0
- package/dist/src/cli/harness-probes.js +183 -0
- package/dist/src/cli/main.d.ts +7 -1
- package/dist/src/cli/main.js +39 -61
- package/dist/src/cli/phone-arguments.d.ts +14 -0
- package/dist/src/cli/phone-arguments.js +37 -0
- package/dist/src/cli/phone-client.d.ts +2 -0
- package/dist/src/cli/phone-client.js +32 -0
- package/dist/src/cli/phone-command.d.ts +13 -0
- package/dist/src/cli/phone-command.js +101 -0
- package/dist/src/cli/probe-command.d.ts +36 -0
- package/dist/src/cli/probe-command.js +59 -0
- package/dist/src/cli/project-settings.d.ts +4 -0
- package/dist/src/cli/project-settings.js +33 -0
- package/dist/src/cli/render.d.ts +3 -1
- package/dist/src/cli/render.js +102 -39
- package/dist/src/cli/report-github.d.ts +18 -0
- package/dist/src/cli/report-github.js +200 -0
- package/dist/src/cli/report.d.ts +17 -0
- package/dist/src/cli/report.js +192 -0
- package/dist/src/cli/repository-arguments.d.ts +5 -0
- package/dist/src/cli/repository-arguments.js +34 -0
- package/dist/src/cli/runtime-arguments.d.ts +4 -0
- package/dist/src/cli/runtime-arguments.js +15 -0
- package/dist/src/cli/runtime-directory.d.ts +6 -2
- package/dist/src/cli/runtime-directory.js +72 -14
- package/dist/src/cli/toolchain.d.ts +2 -0
- package/dist/src/cli/toolchain.js +22 -2
- package/dist/src/cli/usage-render.d.ts +5 -0
- package/dist/src/cli/usage-render.js +40 -1
- package/dist/src/cli/usage.d.ts +3 -3
- package/dist/src/cli/usage.js +74 -45
- package/dist/src/cli/watch-actions.d.ts +2 -0
- package/dist/src/cli/watch-actions.js +4 -4
- package/dist/src/cli/watch-board-view.d.ts +12 -1
- package/dist/src/cli/watch-board-view.js +64 -12
- package/dist/src/cli/watch-board.d.ts +7 -1
- package/dist/src/cli/watch-board.js +61 -16
- package/dist/src/cli/watch-card-forms.js +2 -2
- package/dist/src/cli/watch-client.d.ts +1 -1
- package/dist/src/cli/watch-client.js +12 -3
- package/dist/src/cli/watch-header-view.d.ts +27 -0
- package/dist/src/cli/watch-header-view.js +116 -0
- package/dist/src/cli/watch-model.d.ts +10 -4
- package/dist/src/cli/watch-model.js +49 -59
- package/dist/src/cli/watch-page.js +67 -14
- package/dist/src/cli/watch-phases.js +3 -3
- package/dist/src/cli/watch-phone-client.d.ts +1 -0
- package/dist/src/cli/watch-phone-client.js +84 -0
- package/dist/src/cli/watch-phone-view.d.ts +56 -0
- package/dist/src/cli/watch-phone-view.js +113 -0
- package/dist/src/cli/watch-phone.d.ts +5 -0
- package/dist/src/cli/watch-phone.js +53 -0
- package/dist/src/cli/watch-pr-command.d.ts +5 -2
- package/dist/src/cli/watch-pr-command.js +41 -4
- package/dist/src/cli/watch-pr-identity.d.ts +14 -2
- package/dist/src/cli/watch-pr-identity.js +25 -0
- package/dist/src/cli/watch-pr-observer.d.ts +1 -0
- package/dist/src/cli/watch-pr-observer.js +48 -6
- package/dist/src/cli/watch-pull-request.d.ts +12 -0
- package/dist/src/cli/watch-pull-request.js +134 -0
- package/dist/src/cli/watch-reads.d.ts +7 -1
- package/dist/src/cli/watch-reads.js +42 -20
- package/dist/src/cli/watch-render.d.ts +23 -2
- package/dist/src/cli/watch-render.js +2 -1
- package/dist/src/cli/watch-server.js +56 -7
- package/dist/src/cli/watch-turn.d.ts +4 -1
- package/dist/src/cli/watch-turn.js +38 -2
- package/dist/src/cli/watch-usage.js +5 -1
- package/dist/src/cli/watch-view.d.ts +10 -17
- package/dist/src/cli/watch-view.js +33 -77
- package/dist/src/cli.js +106 -23
- package/dist/src/command-settings.d.ts +16 -0
- package/dist/src/command-settings.js +42 -0
- package/dist/src/configuration-change.d.ts +11 -0
- package/dist/src/configuration-change.js +62 -0
- package/dist/src/configuration-display.d.ts +21 -0
- package/dist/src/configuration-display.js +69 -0
- package/dist/src/configuration-schema.d.ts +49 -0
- package/dist/src/configuration-schema.js +159 -0
- package/dist/src/daemon/claude-turn.d.ts +20 -5
- package/dist/src/daemon/claude-turn.js +116 -53
- package/dist/src/daemon/claude-worker.d.ts +3 -5
- package/dist/src/daemon/claude-worker.js +64 -80
- package/dist/src/daemon/command-journal.d.ts +5 -0
- package/dist/src/daemon/command-journal.js +50 -0
- package/dist/src/daemon/command-process.d.ts +28 -0
- package/dist/src/daemon/command-process.js +164 -0
- package/dist/src/daemon/command-worker.d.ts +19 -0
- package/dist/src/daemon/command-worker.js +182 -0
- package/dist/src/daemon/cursor-stream.d.ts +4 -0
- package/dist/src/daemon/cursor-stream.js +154 -0
- package/dist/src/daemon/daemon-adapters.d.ts +58 -0
- package/dist/src/daemon/daemon-adapters.js +102 -0
- package/dist/src/daemon/daemon-loops.d.ts +14 -0
- package/dist/src/daemon/daemon-loops.js +39 -0
- package/dist/src/daemon/daemon.d.ts +3 -30
- package/dist/src/daemon/daemon.js +132 -110
- package/dist/src/daemon/declared-input.d.ts +3 -0
- package/dist/src/daemon/declared-input.js +9 -0
- package/dist/src/daemon/delivery-router.js +7 -1
- package/dist/src/daemon/gemini-stream.d.ts +4 -0
- package/dist/src/daemon/gemini-stream.js +129 -0
- package/dist/src/daemon/github-calls.d.ts +4 -0
- package/dist/src/daemon/github-calls.js +16 -7
- package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
- package/dist/src/daemon/github-ci-rerun.js +92 -0
- package/dist/src/daemon/github-ci.d.ts +6 -0
- package/dist/src/daemon/github-ci.js +251 -0
- package/dist/src/daemon/github-merge-call.d.ts +16 -0
- package/dist/src/daemon/github-merge-call.js +73 -0
- package/dist/src/daemon/github-merge.d.ts +3 -5
- package/dist/src/daemon/github-merge.js +59 -98
- package/dist/src/daemon/github-methods.d.ts +28 -0
- package/dist/src/daemon/github-methods.js +90 -16
- package/dist/src/daemon/github-operation.d.ts +3 -0
- package/dist/src/daemon/github-retry.d.ts +6 -0
- package/dist/src/daemon/github-retry.js +13 -0
- package/dist/src/daemon/github-ticket-status.js +27 -1
- package/dist/src/daemon/github-worker.js +2 -1
- package/dist/src/daemon/handoff-worker.d.ts +10 -0
- package/dist/src/daemon/handoff-worker.js +232 -0
- package/dist/src/daemon/issue-queue.d.ts +2 -0
- package/dist/src/daemon/issue-queue.js +92 -63
- package/dist/src/daemon/notify-journal.d.ts +18 -0
- package/dist/src/daemon/notify-journal.js +108 -0
- package/dist/src/daemon/notify-message.js +2 -1
- package/dist/src/daemon/notify.js +177 -37
- package/dist/src/daemon/opencode-stream.d.ts +5 -0
- package/dist/src/daemon/opencode-stream.js +87 -0
- package/dist/src/daemon/queue-status.d.ts +4 -0
- package/dist/src/daemon/queue-status.js +38 -0
- package/dist/src/daemon/retry-worktree.d.ts +18 -0
- package/dist/src/daemon/retry-worktree.js +139 -0
- package/dist/src/daemon/retrying-turn.d.ts +5 -0
- package/dist/src/daemon/retrying-turn.js +145 -21
- package/dist/src/daemon/schedule-journal.d.ts +19 -0
- package/dist/src/daemon/schedule-journal.js +57 -0
- package/dist/src/daemon/text-output.d.ts +18 -0
- package/dist/src/daemon/text-output.js +44 -0
- package/dist/src/daemon/ticket-dependency-waits.d.ts +18 -0
- package/dist/src/daemon/ticket-dependency-waits.js +60 -0
- package/dist/src/daemon/ticket-registration.d.ts +10 -8
- package/dist/src/daemon/ticket-registration.js +146 -47
- package/dist/src/daemon/ticket-source.d.ts +4 -1
- package/dist/src/daemon/ticket-source.js +8 -2
- package/dist/src/daemon/turn-command.d.ts +10 -0
- package/dist/src/daemon/turn-command.js +33 -0
- package/dist/src/daemon/turn-report.d.ts +18 -0
- package/dist/src/daemon/turn-report.js +79 -0
- package/dist/src/daemon/work-tree.d.ts +2 -1
- package/dist/src/daemon/work-tree.js +15 -12
- package/dist/src/daemon/workflow-generations.d.ts +32 -0
- package/dist/src/daemon/workflow-generations.js +57 -0
- package/dist/src/daemon/workflow-replay.d.ts +16 -0
- package/dist/src/daemon/workflow-replay.js +58 -0
- package/dist/src/daemon/workflow-schedules.d.ts +27 -0
- package/dist/src/daemon/workflow-schedules.js +185 -0
- package/dist/src/decision-visibility.d.ts +2 -0
- package/dist/src/decision-visibility.js +10 -0
- package/dist/src/decision-wait.d.ts +1 -0
- package/dist/src/decision-wait.js +3 -0
- package/dist/src/delivery-backoff.d.ts +1 -0
- package/dist/src/delivery-backoff.js +3 -0
- package/dist/src/doctor-report.d.ts +24 -0
- package/dist/src/doctor-report.js +70 -0
- package/dist/src/execution-pin.d.ts +9 -0
- package/dist/src/execution-pin.js +86 -2
- package/dist/src/grok-result.d.ts +12 -0
- package/dist/src/grok-result.js +61 -0
- package/dist/src/harness-defaults.d.ts +35 -0
- package/dist/src/harness-defaults.js +121 -0
- package/dist/src/host/decision-resume.d.ts +35 -0
- package/dist/src/host/decision-resume.js +86 -0
- package/dist/src/host/gate-bridge.d.ts +48 -0
- package/dist/src/host/gate-bridge.js +124 -0
- package/dist/src/host/run-wait.d.ts +26 -0
- package/dist/src/host/run-wait.js +37 -0
- package/dist/src/host/start-delivery.d.ts +3 -2
- package/dist/src/host/start-delivery.js +11 -4
- package/dist/src/host/step-bridge-host.d.ts +6 -19
- package/dist/src/host/step-bridge-host.js +57 -55
- package/dist/src/host/world-reconciliation.d.ts +1 -0
- package/dist/src/host/world-reconciliation.js +3 -0
- package/dist/src/host/world-runs.js +5 -0
- package/dist/src/issue-identity.d.ts +6 -0
- package/dist/src/issue-identity.js +23 -0
- package/dist/src/merge-request.d.ts +19 -0
- package/dist/src/merge-request.js +32 -0
- package/dist/src/phone/canonical-json.d.ts +1 -0
- package/dist/src/phone/canonical-json.js +16 -0
- package/dist/src/phone/phone-link.d.ts +7 -0
- package/dist/src/phone/phone-link.js +21 -0
- package/dist/src/phone/qr-data.d.ts +8 -0
- package/dist/src/phone/qr-data.js +133 -0
- package/dist/src/phone/qr-matrix.d.ts +6 -0
- package/dist/src/phone/qr-matrix.js +175 -0
- package/dist/src/phone/qr-penalty.d.ts +3 -0
- package/dist/src/phone/qr-penalty.js +67 -0
- package/dist/src/phone/qr-picture.d.ts +5 -0
- package/dist/src/phone/qr-picture.js +24 -0
- package/dist/src/private-config.schema.json +263 -0
- package/dist/src/project-config.schema.json +65 -0
- package/dist/src/project-settings.d.ts +19 -0
- package/dist/src/project-settings.js +131 -0
- package/dist/src/relay/answer-check.d.ts +24 -0
- package/dist/src/relay/answer-check.js +145 -0
- package/dist/src/relay/answer-inbox.d.ts +15 -0
- package/dist/src/relay/answer-inbox.js +173 -0
- package/dist/src/relay/daemon-keys.d.ts +16 -0
- package/dist/src/relay/daemon-keys.js +75 -0
- package/dist/src/relay/decision-check.d.ts +3 -0
- package/dist/src/relay/decision-check.js +77 -0
- package/dist/src/relay/decision-close.d.ts +6 -0
- package/dist/src/relay/decision-close.js +72 -0
- package/dist/src/relay/decision-envelopes.d.ts +29 -0
- package/dist/src/relay/decision-envelopes.js +93 -0
- package/dist/src/relay/decision-watch.d.ts +14 -0
- package/dist/src/relay/decision-watch.js +68 -0
- package/dist/src/relay/envelope-post.d.ts +8 -0
- package/dist/src/relay/envelope-post.js +71 -0
- package/dist/src/relay/envelope.d.ts +28 -0
- package/dist/src/relay/envelope.js +53 -0
- package/dist/src/relay/hpke.d.ts +25 -0
- package/dist/src/relay/hpke.js +108 -0
- package/dist/src/relay/pairing-checks.d.ts +42 -0
- package/dist/src/relay/pairing-checks.js +172 -0
- package/dist/src/relay/pairing-follow.d.ts +8 -0
- package/dist/src/relay/pairing-follow.js +95 -0
- package/dist/src/relay/pairing-session.d.ts +29 -0
- package/dist/src/relay/pairing-session.js +87 -0
- package/dist/src/relay/phone-delivery.d.ts +51 -0
- package/dist/src/relay/phone-delivery.js +139 -0
- package/dist/src/relay/phone-devices.d.ts +36 -0
- package/dist/src/relay/phone-devices.js +46 -0
- package/dist/src/relay/phone-inbox.d.ts +18 -0
- package/dist/src/relay/phone-inbox.js +17 -0
- package/dist/src/relay/phone-operations.d.ts +18 -0
- package/dist/src/relay/phone-operations.js +121 -0
- package/dist/src/relay/phone-outbox.d.ts +21 -0
- package/dist/src/relay/phone-outbox.js +25 -0
- package/dist/src/relay/phone-socket.d.ts +6 -0
- package/dist/src/relay/phone-socket.js +63 -0
- package/dist/src/relay/relay-control.d.ts +7 -0
- package/dist/src/relay/relay-control.js +24 -0
- package/dist/src/relay/relay-files.d.ts +2 -0
- package/dist/src/relay/relay-files.js +23 -0
- package/dist/src/relay/relay-heartbeat.d.ts +17 -0
- package/dist/src/relay/relay-heartbeat.js +81 -0
- package/dist/src/relay/relay-http.d.ts +14 -0
- package/dist/src/relay/relay-http.js +63 -0
- package/dist/src/relay/relay-registration.d.ts +15 -0
- package/dist/src/relay/relay-registration.js +63 -0
- package/dist/src/relay/relay-service.d.ts +25 -0
- package/dist/src/relay/relay-service.js +216 -0
- package/dist/src/relay/relay-store.d.ts +48 -0
- package/dist/src/relay/relay-store.js +131 -0
- package/dist/src/relay/sealed-post.d.ts +25 -0
- package/dist/src/relay/sealed-post.js +52 -0
- package/dist/src/relay.d.ts +1 -0
- package/dist/src/relay.js +8 -0
- package/dist/src/report-statistics.d.ts +50 -0
- package/dist/src/report-statistics.js +70 -0
- package/dist/src/report.d.ts +171 -0
- package/dist/src/report.js +119 -0
- package/dist/src/repository-identity.d.ts +4 -0
- package/dist/src/repository-identity.js +4 -0
- package/dist/src/review-subject.d.ts +41 -0
- package/dist/src/review-subject.js +91 -0
- package/dist/src/run-wait.d.ts +23 -0
- package/dist/src/run-wait.js +20 -0
- package/dist/src/service/active-tickets.d.ts +4 -0
- package/dist/src/service/active-tickets.js +49 -0
- package/dist/src/service/command-effects.d.ts +4 -0
- package/dist/src/service/command-effects.js +16 -0
- package/dist/src/service/decision-handler.d.ts +4 -0
- package/dist/src/service/decision-handler.js +39 -4
- package/dist/src/service/gateway.js +18 -3
- package/dist/src/service/queue-runs.d.ts +3 -0
- package/dist/src/service/queue-runs.js +39 -0
- package/dist/src/service/registry.d.ts +22 -3
- package/dist/src/service/registry.js +51 -8
- package/dist/src/service/replies.d.ts +10 -0
- package/dist/src/service/replies.js +12 -0
- package/dist/src/service/run-handlers.js +45 -54
- package/dist/src/service/run-metadata.d.ts +8 -0
- package/dist/src/service/run-metadata.js +53 -0
- package/dist/src/service/run-waits.d.ts +3 -0
- package/dist/src/service/run-waits.js +41 -0
- package/dist/src/service/service.d.ts +21 -2
- package/dist/src/service/service.js +23 -5
- package/dist/src/service/submission-handler.js +70 -19
- package/dist/src/service/worker-port.d.ts +1 -0
- package/dist/src/service/worker-totals.js +10 -1
- package/dist/src/step-bridge.d.ts +32 -0
- package/dist/src/steps/decision-gate.d.ts +2 -1
- package/dist/src/steps/decision-gate.js +7 -0
- package/dist/src/steps/handoff.d.ts +2 -0
- package/dist/src/steps/handoff.js +13 -0
- package/dist/src/steps/merge-by-person.d.ts +2 -0
- package/dist/src/steps/merge-by-person.js +18 -0
- package/dist/src/steps/merge-when-green.d.ts +2 -0
- package/dist/src/steps/merge-when-green.js +62 -0
- package/dist/src/steps/review-by-agent.d.ts +5 -0
- package/dist/src/steps/review-by-agent.js +124 -0
- package/dist/src/steps/review-by-person.d.ts +4 -0
- package/dist/src/steps/review-by-person.js +16 -0
- package/dist/src/steps/review-subject.d.ts +2 -0
- package/dist/src/steps/review-subject.js +11 -0
- package/dist/src/steps/run-command.d.ts +2 -0
- package/dist/src/steps/run-command.js +15 -0
- package/dist/src/steps/sleep.d.ts +3 -0
- package/dist/src/steps/sleep.js +19 -0
- package/dist/src/steps/wait-for-decision.d.ts +2 -0
- package/dist/src/steps/wait-for-decision.js +71 -0
- package/dist/src/steps/wait-for-run.d.ts +5 -0
- package/dist/src/steps/wait-for-run.js +9 -0
- package/dist/src/storage/decision-snapshots.d.ts +1 -0
- package/dist/src/storage/decision-snapshots.js +7 -1
- package/dist/src/submission.d.ts +4 -0
- package/dist/src/submission.js +6 -2
- package/dist/src/testing.d.ts +29 -0
- package/dist/src/testing.js +264 -0
- package/dist/src/ticket-dependencies.d.ts +1 -0
- package/dist/src/ticket-dependencies.js +15 -0
- package/dist/src/ticket-status-stream.d.ts +9 -0
- package/dist/src/ticket-status-stream.js +94 -0
- package/dist/src/ticket-status.js +7 -4
- package/dist/src/token-prices.d.ts +14 -4
- package/dist/src/token-prices.js +56 -11
- package/dist/src/turn-profile.d.ts +1 -0
- package/dist/src/turn-profile.js +8 -1
- package/dist/src/worker-usage.d.ts +25 -0
- package/dist/src/worker-usage.js +58 -1
- package/dist/src/workflow-admission.d.ts +6 -0
- package/dist/src/workflow-candidate.d.ts +7 -2
- package/dist/src/workflow-candidate.js +48 -5
- package/dist/src/workflow-contracts.d.ts +2 -0
- package/dist/src/workflow-contracts.js +8 -3
- package/dist/src/workflow-declaration.d.ts +31 -2
- package/dist/src/workflow-declaration.js +140 -16
- package/dist/src/workflow-discovery.d.ts +19 -0
- package/dist/src/workflow-discovery.js +36 -0
- package/dist/src/workflow-refusals.d.ts +6 -0
- package/dist/src/workflow-refusals.js +42 -0
- package/dist/src/workflow-schedule.d.ts +22 -0
- package/dist/src/workflow-schedule.js +53 -0
- package/dist/src/workflows.d.ts +12 -1
- package/dist/src/workflows.js +9 -0
- package/dist/tools/admit-workflow.d.ts +14 -0
- package/dist/tools/admit-workflow.js +107 -0
- package/dist/tools/doctor-adoption.d.ts +1 -0
- package/dist/tools/doctor-adoption.js +11 -0
- package/dist/tools/project-configuration.d.ts +4 -0
- package/dist/tools/project-configuration.js +47 -0
- package/dist/tools/self-host-processes.d.ts +1 -0
- package/dist/tools/self-host-processes.js +33 -22
- package/dist/tools/self-host-project.d.ts +21 -0
- package/dist/tools/self-host-project.js +224 -0
- package/dist/tools/self-host-runtime.d.ts +16 -0
- package/dist/tools/self-host-runtime.js +60 -0
- package/dist/tools/self-host-workflows.d.ts +1 -0
- package/dist/tools/self-host-workflows.js +36 -1
- package/dist/tools/self-host.js +106 -135
- package/dist/tools/workflow-bundle-dependencies.d.ts +5 -0
- package/dist/tools/workflow-bundle-dependencies.js +93 -0
- package/dist/tools/workflow-bundles.d.ts +20 -0
- package/dist/tools/workflow-bundles.js +173 -0
- package/dist/tools/workflow-candidate-counts.d.ts +12 -0
- package/dist/tools/workflow-candidate-counts.js +266 -0
- package/dist/tools/workflow-candidate-fields.d.ts +5 -0
- package/dist/tools/workflow-candidate-fields.js +24 -0
- package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
- package/dist/tools/workflow-candidate-helper-counts.js +129 -0
- package/dist/tools/workflow-candidate-program.d.ts +13 -0
- package/dist/tools/workflow-candidate-program.js +106 -0
- package/dist/tools/workflow-candidate-source.d.ts +6 -0
- package/dist/tools/workflow-candidate-source.js +169 -0
- package/dist/tools/workflow-candidate-syntax.d.ts +21 -0
- package/dist/tools/workflow-candidate-syntax.js +263 -0
- package/dist/tools/workflow-command.d.ts +1 -0
- package/dist/tools/workflow-command.js +143 -0
- package/dist/tools/workflow-folder-capture.d.ts +18 -0
- package/dist/tools/workflow-folder-capture.js +261 -0
- package/dist/tools/workflow-folders.d.ts +49 -0
- package/dist/tools/workflow-folders.js +203 -0
- package/dist/tools/workflow-source-effects.d.ts +10 -0
- package/dist/tools/workflow-source-effects.js +213 -0
- package/dist/tools/workflow-test-hook.d.ts +7 -0
- package/dist/tools/workflow-test-hook.js +16 -0
- package/dist/tools/workflow-test-loader.d.ts +1 -0
- package/dist/tools/workflow-test-loader.js +10 -0
- package/dist/workflows/develop-prd.js +71 -3
- package/dist/workflows/develop-ticket.js +6 -1
- package/dist/workflows/ticket-prompts.js +17 -3
- package/package.json +66 -6
- package/templates/develop/README.md +78 -0
- package/templates/develop/develop/accept.ts +11 -0
- package/templates/develop/develop/flow-tests.ts +357 -0
- package/templates/develop/develop/local.ts +40 -0
- package/templates/develop/develop/option-tests.ts +174 -0
- package/templates/develop/develop/partial-choice.ts +29 -0
- package/templates/develop/develop/partial.ts +28 -0
- package/templates/develop/develop/pull.ts +152 -0
- package/templates/develop/develop/queue-partial.ts +39 -0
- package/templates/develop/develop/refusal-tests.ts +174 -0
- package/templates/develop/develop/report.ts +156 -0
- package/templates/develop/develop/round.ts +40 -0
- package/templates/develop/develop/scenarios.ts +87 -0
- package/templates/develop/develop/turn.ts +67 -0
- package/templates/develop/develop.declaration.json +24 -0
- package/templates/develop/develop.test.ts +287 -0
- package/templates/develop/develop.ts +30 -0
- package/templates/develop/template.json +153 -0
- package/dist/src/chats/analysis-batches.d.ts +0 -24
- package/dist/src/chats/analysis-batches.js +0 -83
- package/dist/src/chats/analysis-contract.d.ts +0 -80
- package/dist/src/chats/analysis-contract.js +0 -16
- package/dist/src/chats/analysis-data.d.ts +0 -3
- package/dist/src/chats/analysis-data.js +0 -85
- package/dist/src/chats/analysis-input.d.ts +0 -12
- package/dist/src/chats/analysis-input.js +0 -83
- package/dist/src/chats/analysis-links.d.ts +0 -2
- package/dist/src/chats/analysis-links.js +0 -25
- package/dist/src/chats/analysis-prompt.d.ts +0 -10
- package/dist/src/chats/analysis-prompt.js +0 -16
- package/dist/src/chats/analysis-proposal.d.ts +0 -2
- package/dist/src/chats/analysis-proposal.js +0 -32
- package/dist/src/chats/analysis-provenance.d.ts +0 -4
- package/dist/src/chats/analysis-provenance.js +0 -99
- package/dist/src/chats/analysis-shape.d.ts +0 -3
- package/dist/src/chats/analysis-shape.js +0 -228
- package/dist/src/chats/analysis.d.ts +0 -3
- package/dist/src/chats/analysis.js +0 -42
- package/dist/src/chats/corpus-input.d.ts +0 -5
- package/dist/src/chats/corpus-input.js +0 -288
- package/dist/src/chats/destination.d.ts +0 -4
- package/dist/src/chats/destination.js +0 -96
- package/dist/src/chats/import.d.ts +0 -15
- package/dist/src/chats/import.js +0 -243
- package/dist/src/chats/input-file.d.ts +0 -3
- package/dist/src/chats/input-file.js +0 -32
- package/dist/src/chats/normalize.d.ts +0 -29
- package/dist/src/chats/normalize.js +0 -155
- package/dist/src/chats/previous-import.d.ts +0 -5
- package/dist/src/chats/previous-import.js +0 -34
- package/dist/src/chats/reader.d.ts +0 -21
- package/dist/src/chats/reader.js +0 -118
- package/dist/src/chats/redact-import.d.ts +0 -14
- package/dist/src/chats/redact-import.js +0 -141
- package/dist/src/chats/redaction.d.ts +0 -41
- package/dist/src/chats/redaction.js +0 -161
- package/dist/src/chats/revision-input.d.ts +0 -3
- package/dist/src/chats/revision-input.js +0 -180
- package/dist/src/chats/revision.d.ts +0 -48
- package/dist/src/chats/revision.js +0 -94
- package/dist/src/chats/selection.d.ts +0 -25
- package/dist/src/chats/selection.js +0 -109
- package/dist/src/chats/source.d.ts +0 -23
- package/dist/src/chats/source.js +0 -135
- package/dist/src/chats/structure.d.ts +0 -57
- package/dist/src/chats/structure.js +0 -216
- package/dist/src/daemon/analysis-launch.d.ts +0 -5
- package/dist/src/daemon/analysis-launch.js +0 -81
- package/dist/src/daemon/analysis-token.d.ts +0 -6
- package/dist/src/daemon/analysis-token.js +0 -88
- package/dist/src/daemon/analysis-worker.d.ts +0 -22
- package/dist/src/daemon/analysis-worker.js +0 -219
- package/dist/src/daemon/chats-files.d.ts +0 -15
- package/dist/src/daemon/chats-files.js +0 -113
- package/dist/src/daemon/chats-worker.d.ts +0 -12
- package/dist/src/daemon/chats-worker.js +0 -200
- package/dist/workflows/analyze-chats.d.ts +0 -10
- package/dist/workflows/analyze-chats.declaration.json +0 -9
- package/dist/workflows/analyze-chats.js +0 -73
|
@@ -55,21 +55,45 @@ export function CardReview(props) {
|
|
|
55
55
|
]),
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
|
-
export function
|
|
58
|
+
export function staleObservation(card, now) {
|
|
59
|
+
const observation = card.pullRequestObservation;
|
|
60
|
+
const lastSuccess = observation?.lastSuccess;
|
|
61
|
+
if (observation?.status === "merged" ||
|
|
62
|
+
lastSuccess?.status !== "unmerged" ||
|
|
63
|
+
!(Date.parse(now) - lastSuccess.readAt > 120000))
|
|
64
|
+
return null;
|
|
65
|
+
return [
|
|
66
|
+
" ",
|
|
67
|
+
element("span", { class: "completion-stale", children: "Stale" }),
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
export function observationText(card, fallback) {
|
|
71
|
+
if (fallback !== "Needs attention")
|
|
72
|
+
return fallback;
|
|
73
|
+
const status = card.pullRequestObservation?.status;
|
|
74
|
+
if (status === "merged")
|
|
75
|
+
return `PR merged · #${String(card.pullRequestNumber)}`;
|
|
76
|
+
if (status === "pending")
|
|
77
|
+
return "Checking PR";
|
|
78
|
+
if (status === "unavailable")
|
|
79
|
+
return "PR status unavailable";
|
|
80
|
+
return fallback;
|
|
81
|
+
}
|
|
82
|
+
export function completionMark(card, context) {
|
|
59
83
|
const mark = card.completionMark;
|
|
60
84
|
if (mark === null)
|
|
61
85
|
return null;
|
|
62
|
-
|
|
63
|
-
const status = card.pullRequestObservation?.status;
|
|
64
|
-
if (text === "Needs attention" && status === "merged")
|
|
65
|
-
text = `PR merged #${String(card.pullRequestNumber)}`;
|
|
66
|
-
if (text === "Needs attention" && status === "unavailable")
|
|
67
|
-
text = "PR status unavailable";
|
|
86
|
+
const text = observationText(card, mark.text);
|
|
68
87
|
if (mark.laterRunId === null)
|
|
69
|
-
return
|
|
88
|
+
return [
|
|
89
|
+
element("span", { class: "completion-mark", children: text }),
|
|
90
|
+
mark.text === "Needs attention"
|
|
91
|
+
? staleObservation(card, context.now)
|
|
92
|
+
: null,
|
|
93
|
+
];
|
|
70
94
|
return element("a", {
|
|
71
95
|
class: "completion-mark",
|
|
72
|
-
href: watchHash({ workflowId, runId: mark.laterRunId }),
|
|
96
|
+
href: watchHash({ workflowId: context.workflowId, runId: mark.laterRunId }),
|
|
73
97
|
children: mark.text,
|
|
74
98
|
});
|
|
75
99
|
}
|
|
@@ -106,10 +130,28 @@ export function Card(props) {
|
|
|
106
130
|
element("small", { children: card.runId.slice(0, 12) }),
|
|
107
131
|
],
|
|
108
132
|
}),
|
|
109
|
-
completionMark(card, workflowId),
|
|
133
|
+
completionMark(card, { workflowId, now: props.observationNow ?? now }),
|
|
134
|
+
component(HandoffLinks, { run: card }),
|
|
110
135
|
],
|
|
111
136
|
});
|
|
112
137
|
}
|
|
138
|
+
export function HandoffLinks(props) {
|
|
139
|
+
const { parentRunId, childRunIds, awaitedRunId } = props.run;
|
|
140
|
+
const links = [
|
|
141
|
+
...(awaitedRunId == null
|
|
142
|
+
? []
|
|
143
|
+
: [{ label: "Waiting for run", runId: awaitedRunId }]),
|
|
144
|
+
...(parentRunId == null
|
|
145
|
+
? []
|
|
146
|
+
: [{ label: "Parent run", runId: parentRunId }]),
|
|
147
|
+
...(childRunIds ?? []).map((runId) => ({ label: "Child run", runId })),
|
|
148
|
+
];
|
|
149
|
+
return links.map(({ label, runId }) => element("a", {
|
|
150
|
+
class: "meta",
|
|
151
|
+
href: watchHash({ workflowId: null, runId }),
|
|
152
|
+
children: `${label}: ${runId}`,
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
113
155
|
export function WorkflowList(props) {
|
|
114
156
|
return element("nav", {
|
|
115
157
|
class: "workflows",
|
|
@@ -167,7 +209,13 @@ export function Column(props) {
|
|
|
167
209
|
: element("div", {
|
|
168
210
|
class: "column-cards",
|
|
169
211
|
children: [
|
|
170
|
-
column.cards.map((card) => component(Card, {
|
|
212
|
+
column.cards.map((card) => component(Card, {
|
|
213
|
+
key: card.runId,
|
|
214
|
+
card,
|
|
215
|
+
workflowId,
|
|
216
|
+
now,
|
|
217
|
+
observationNow: props.observationNow,
|
|
218
|
+
})),
|
|
171
219
|
props.addCard,
|
|
172
220
|
],
|
|
173
221
|
}),
|
|
@@ -179,7 +227,10 @@ export function Board(props) {
|
|
|
179
227
|
return element("main", {
|
|
180
228
|
class: "board",
|
|
181
229
|
children: [
|
|
182
|
-
element("h2", {
|
|
230
|
+
element("h2", {
|
|
231
|
+
class: "visually-hidden",
|
|
232
|
+
children: workflow.workflowId,
|
|
233
|
+
}),
|
|
183
234
|
element("div", {
|
|
184
235
|
class: "columns",
|
|
185
236
|
children: workflow.columns.map((column, index) => component(Column, {
|
|
@@ -187,6 +238,7 @@ export function Board(props) {
|
|
|
187
238
|
column,
|
|
188
239
|
workflowId: workflow.workflowId,
|
|
189
240
|
now,
|
|
241
|
+
observationNow: props.observationNow,
|
|
190
242
|
controls: props.controls,
|
|
191
243
|
addCard: index === 0
|
|
192
244
|
? component(AddCard, {
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
+
import type { WorkflowStage, WorkflowStages } from "../workflow-declaration.ts";
|
|
1
2
|
import type { WatchCompletionMark, WatchRun, WatchStep, WatchWorkflow } from "./watch-render.ts";
|
|
2
3
|
export declare function completionMarkOf(run: WatchRun, candidates: readonly WatchRun[]): WatchCompletionMark | null;
|
|
3
4
|
export declare function activeRun(state: string): boolean;
|
|
4
5
|
export declare function recentRun(latestAt: string | null, now: string): boolean;
|
|
5
|
-
export declare function
|
|
6
|
+
export declare function stagesFor(metadata: WorkflowStages | undefined, workflowId: string): readonly WorkflowStage[] | undefined;
|
|
7
|
+
export declare function currentStepOf(events: readonly unknown[], workflow: {
|
|
8
|
+
readonly workflowId: string;
|
|
9
|
+
readonly stages: readonly WorkflowStage[] | undefined;
|
|
10
|
+
}): WatchStep;
|
|
6
11
|
export declare function roundOf(events: readonly unknown[]): number;
|
|
7
12
|
interface BoardInputs {
|
|
8
13
|
readonly workflows: readonly string[];
|
|
14
|
+
readonly workflowStages?: WorkflowStages;
|
|
9
15
|
readonly updatedAt: string;
|
|
10
16
|
readonly summaries?: readonly unknown[];
|
|
11
17
|
readonly completionCandidates?: readonly WatchRun[];
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { linksOf } from "../authority/handoff-chain.js";
|
|
1
2
|
import { record } from "../protocol.js";
|
|
2
3
|
import { isInstant } from "../authority/instants.js";
|
|
3
4
|
import { issueSteps } from "./watch-phases.js";
|
|
5
|
+
import { sameIssue } from "./watch-pr-identity.js";
|
|
4
6
|
const weekMilliseconds = 7 * 24 * 60 * 60 * 1000;
|
|
5
7
|
const terminalStates = ["completed", "failed", "cancelled"];
|
|
6
8
|
function eventTime(run, type) {
|
|
@@ -12,11 +14,15 @@ export function completionMarkOf(run, candidates) {
|
|
|
12
14
|
run.state !== "completed" ||
|
|
13
15
|
run.outcome !== "blocked")
|
|
14
16
|
return null;
|
|
17
|
+
if (run.mergeProof != null)
|
|
18
|
+
return {
|
|
19
|
+
text: `PR merged · #${String(run.mergeProof.number)}`,
|
|
20
|
+
laterRunId: null,
|
|
21
|
+
};
|
|
15
22
|
const completedAt = eventTime(run, "run.completed");
|
|
16
23
|
const later = candidates
|
|
17
|
-
.filter((candidate) =>
|
|
18
|
-
|
|
19
|
-
candidate.ticketId === run.ticketId &&
|
|
24
|
+
.filter((candidate) => sameIssue(run.issueIdentity, candidate.issueIdentity) &&
|
|
25
|
+
candidate.mergeProof != null &&
|
|
20
26
|
candidate.runId !== run.runId &&
|
|
21
27
|
candidate.workflowId === "develop-issue" &&
|
|
22
28
|
candidate.state === "completed" &&
|
|
@@ -32,7 +38,7 @@ export function completionMarkOf(run, candidates) {
|
|
|
32
38
|
(first.runId < second.runId ? -1 : 1))[0];
|
|
33
39
|
return later === undefined
|
|
34
40
|
? { text: "Needs attention", laterRunId: null }
|
|
35
|
-
: { text: "
|
|
41
|
+
: { text: "Ticket completed by later run", laterRunId: later.runId };
|
|
36
42
|
}
|
|
37
43
|
export function activeRun(state) {
|
|
38
44
|
return !terminalStates.includes(state);
|
|
@@ -41,10 +47,17 @@ export function recentRun(latestAt, now) {
|
|
|
41
47
|
const age = Date.parse(now) - Date.parse(latestAt ?? "");
|
|
42
48
|
return age >= 0 && age <= weekMilliseconds;
|
|
43
49
|
}
|
|
44
|
-
function
|
|
50
|
+
export function stagesFor(metadata, workflowId) {
|
|
51
|
+
return metadata !== undefined && Object.hasOwn(metadata, workflowId)
|
|
52
|
+
? metadata[workflowId]
|
|
53
|
+
: undefined;
|
|
54
|
+
}
|
|
55
|
+
function stepNames(workflowId, stages) {
|
|
56
|
+
if (workflowId !== "develop-issue" && stages !== undefined)
|
|
57
|
+
return [...stages.map((stage) => stage.label), "Other"];
|
|
45
58
|
return workflowId === "develop-issue"
|
|
46
59
|
? issueSteps.map((step) => step.name)
|
|
47
|
-
: ["
|
|
60
|
+
: ["Agent turn", "Your review"];
|
|
48
61
|
}
|
|
49
62
|
function operationOf(event) {
|
|
50
63
|
const payload = record(record(event)?.["payload"]);
|
|
@@ -63,7 +76,7 @@ function stepName(event, workflowId) {
|
|
|
63
76
|
if (type !== "effect.requested")
|
|
64
77
|
return undefined;
|
|
65
78
|
if (workflowId !== "develop-issue")
|
|
66
|
-
return "
|
|
79
|
+
return "Agent turn";
|
|
67
80
|
return issueSteps.find((step) => step.operation === operationOf(event)[4])
|
|
68
81
|
?.name;
|
|
69
82
|
}
|
|
@@ -74,10 +87,30 @@ function startedAt(event) {
|
|
|
74
87
|
function chronological(events) {
|
|
75
88
|
return events.toSorted((first, second) => Date.parse(startedAt(first) ?? "") - Date.parse(startedAt(second) ?? ""));
|
|
76
89
|
}
|
|
77
|
-
|
|
90
|
+
function declaredStage(event, stages) {
|
|
91
|
+
if (record(event)?.["type"] === "effect.requested") {
|
|
92
|
+
const operation = operationOf(event)[4];
|
|
93
|
+
return stages.find((stage) => stage.operations?.some((name) => name === operation));
|
|
94
|
+
}
|
|
95
|
+
const payload = record(record(event)?.["payload"]);
|
|
96
|
+
return (stages.find((stage) => stage.gateIds?.some((name) => name === payload?.["gateId"])) ??
|
|
97
|
+
stages.find((stage) => stage.gateKinds?.some((name) => name === payload?.["gateKind"])));
|
|
98
|
+
}
|
|
99
|
+
function declaredStep(events, stages) {
|
|
100
|
+
const event = events
|
|
101
|
+
.filter((item) => ["effect.requested", "gate.opened"].includes(String(record(item)?.["type"])))
|
|
102
|
+
.toSorted((first, second) => Number(record(second)?.["sequence"]) -
|
|
103
|
+
Number(record(first)?.["sequence"]))[0];
|
|
104
|
+
const stage = declaredStage(event, stages);
|
|
105
|
+
return { name: stage?.label ?? "Other", startedAt: startedAt(event) };
|
|
106
|
+
}
|
|
107
|
+
export function currentStepOf(events, workflow) {
|
|
108
|
+
const { workflowId, stages } = workflow;
|
|
109
|
+
if (workflowId !== "develop-issue" && stages !== undefined)
|
|
110
|
+
return declaredStep(events, stages);
|
|
78
111
|
const event = chronological(events).findLast((item) => stepName(item, workflowId) !== undefined);
|
|
79
112
|
return {
|
|
80
|
-
name: stepName(event, workflowId) ?? stepNames(workflowId)[0] ?? "
|
|
113
|
+
name: stepName(event, workflowId) ?? stepNames(workflowId)[0] ?? "Agent turn",
|
|
81
114
|
startedAt: startedAt(event),
|
|
82
115
|
};
|
|
83
116
|
}
|
|
@@ -96,11 +129,20 @@ function columnOf(run, now) {
|
|
|
96
129
|
return "Stopped";
|
|
97
130
|
return run.outcome === "handoff_requested" ? "Done" : null;
|
|
98
131
|
}
|
|
99
|
-
function
|
|
132
|
+
function issueCardDetails(run) {
|
|
100
133
|
const issue = run.workflowId === "develop-issue";
|
|
134
|
+
return {
|
|
135
|
+
round: issue ? run.round : null,
|
|
136
|
+
greptileScore: issue ? (run.reviews.at(-1)?.score ?? null) : null,
|
|
137
|
+
pullRequestNumber: issue ? (run.pullRequest?.number ?? null) : null,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function cardOf(run, runs) {
|
|
101
141
|
return {
|
|
102
142
|
runId: run.runId,
|
|
103
143
|
title: run.title,
|
|
144
|
+
...linksOf(run),
|
|
145
|
+
...(run.awaitedRunId == null ? {} : { awaitedRunId: run.awaitedRunId }),
|
|
104
146
|
completionMark: completionMarkOf(run, runs),
|
|
105
147
|
pullRequestObservation: null,
|
|
106
148
|
claudeCostUsd: run.claudeCostUsd,
|
|
@@ -109,9 +151,7 @@ function cardOf(run, runs) {
|
|
|
109
151
|
currentStep: activeRun(run.state) ? run.currentStep : null,
|
|
110
152
|
endedAt: activeRun(run.state) ? null : run.latestAt,
|
|
111
153
|
decisionWaiting: run.decisions.length > 0,
|
|
112
|
-
|
|
113
|
-
greptileScore: issue ? (run.reviews.at(-1)?.score ?? null) : null,
|
|
114
|
-
pullRequestNumber: issue ? (run.pullRequest?.number ?? null) : null,
|
|
154
|
+
...issueCardDetails(run),
|
|
115
155
|
};
|
|
116
156
|
}
|
|
117
157
|
function stepOrder(first, second) {
|
|
@@ -133,7 +173,8 @@ function summaryOf(value) {
|
|
|
133
173
|
const latest = fields?.["latestAt"];
|
|
134
174
|
return {
|
|
135
175
|
state: String(fields?.["state"]),
|
|
136
|
-
waiting: Array.isArray(pending) && pending.length > 0
|
|
176
|
+
waiting: (Array.isArray(pending) && pending.length > 0) ||
|
|
177
|
+
typeof fields?.["awaitedRunId"] === "string",
|
|
137
178
|
latestAt: typeof latest === "string" ? latest : null,
|
|
138
179
|
};
|
|
139
180
|
}
|
|
@@ -143,13 +184,17 @@ export function boardsOf(inputs, runs) {
|
|
|
143
184
|
const summaries = inputs.summaries === undefined
|
|
144
185
|
? own.map((run) => ({
|
|
145
186
|
state: run.state,
|
|
146
|
-
waiting: run.decisions.length > 0,
|
|
187
|
+
waiting: run.decisions.length > 0 || run.awaitedRunId != null,
|
|
147
188
|
latestAt: run.latestAt,
|
|
148
189
|
}))
|
|
149
190
|
: inputs.summaries
|
|
150
191
|
.filter((value) => record(value)?.["workflowId"] === workflowId)
|
|
151
192
|
.map(summaryOf);
|
|
152
|
-
const columns = [
|
|
193
|
+
const columns = [
|
|
194
|
+
...stepNames(workflowId, stagesFor(inputs.workflowStages, workflowId)),
|
|
195
|
+
"Done",
|
|
196
|
+
"Stopped",
|
|
197
|
+
].map((name) => {
|
|
153
198
|
const cards = own
|
|
154
199
|
.filter((run) => columnOf(run, inputs.updatedAt) === name)
|
|
155
200
|
.map((run) => cardOf(run, inputs.completionCandidates ?? runs));
|
|
@@ -14,7 +14,7 @@ export async function watchCardForms(directory) {
|
|
|
14
14
|
if (!isWorkflowDeclaration(value))
|
|
15
15
|
continue;
|
|
16
16
|
const entries = Object.entries(value.input.fields);
|
|
17
|
-
if (!entries.every(([, rule]) => rule === "string" || rule.type === "string"))
|
|
17
|
+
if (!entries.every(([, rule]) => rule === "string" || rule.type === "string" || rule.type === "ticket"))
|
|
18
18
|
continue;
|
|
19
19
|
if (forms.some((form) => form.workflowId === value.workflowId))
|
|
20
20
|
continue;
|
|
@@ -23,7 +23,7 @@ export async function watchCardForms(directory) {
|
|
|
23
23
|
source: "input",
|
|
24
24
|
fields: entries.map(([name, rule]) => ({
|
|
25
25
|
name,
|
|
26
|
-
label: name,
|
|
26
|
+
label: rule !== "string" && rule.type === "ticket" ? "Ticket ID" : name,
|
|
27
27
|
multiline: false,
|
|
28
28
|
optional: rule !== "string" && rule.optional === true,
|
|
29
29
|
})),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const watchClient = "\nconst state = { model: null, stale: false, copied: \"\", label: \"\", run: \"\", loading: false, again: false, columns: {}, cards: {}, start: null, hovered: null, focused: null };\nfunction readPreference(key) {\n try { return JSON.parse(localStorage.getItem(key)); }\n catch { return null; }\n}\nfunction readColumnChoices(key) {\n const value = readPreference(key);\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return null;\n return Object.fromEntries(Object.entries(value).filter(([, choice]) => typeof choice === \"boolean\"));\n}\nfunction savePreference(key, value) {\n try { localStorage.setItem(key, JSON.stringify(value)); }\n catch {}\n}\nfunction startControls() {\n if (state.start === null) state.start = readPreference(\"cloving.watch.start\") === true;\n return { shown: state.start, onToggle() {\n state.start = !state.start;\n savePreference(\"cloving.watch.start\", state.start);\n draw();\n } };\n}\nfunction columnControls(model, selected) {\n const workflowId = model === null ? null : boardWorkflow(model, watchLocation(selected).workflowId);\n if (workflowId === null) return undefined;\n const key = \"cloving.watch.columns:\" + workflowId;\n if (!Object.hasOwn(state.columns, workflowId))\n state.columns = { ...state.columns, [workflowId]: readColumnChoices(key) };\n const choices = state.columns[workflowId];\n return { choices, onHover(name) { state.hovered = name; }, onFocus(name) { state.focused = name; }, onToggle(name) {\n const changed = { ...choices, [name]: !columnCollapsed(choices, name) };\n state.columns = { ...state.columns, [workflowId]: changed };\n savePreference(key, changed);\n draw();\n } };\n}\nfunction moved(next, followed) {\n const arrived = next === \"waiting_gate\" && next !== state.run;\n state.run = next;\n if (arrived) scrollTo(0, 0);\n else if (followed && next === \"running\") scrollTo(0, document.body.scrollHeight);\n}\nfunction copy(command) {\n const shown = (label) => {\n state.copied = command;\n state.label = label;\n draw();\n };\n navigator.clipboard.writeText(command).then(\n () => { shown(\"Copied\"); },\n () => { shown(\"Copy failed\"); },\n );\n}\nfunction draw() {\n const { model, stale } = state;\n const selected = location.hash.slice(1);\n const followed = innerHeight + scrollY >= document.body.scrollHeight - 80;\n const copying = { command: state.copied, label: state.label, onCopy: copy };\n const now = new Date().toISOString();\n const columns = columnControls(model, selected);\n const start = model === null ? undefined : startControls();\n const cards = cardControls(model, model === null ? null : boardWorkflow(model, watchLocation(selected).workflowId));\n const page = component(Page, { model, selected, now, stale, copying, columns, start, cards });\n render(page, document.getElementById(\"app\"));\n if (model === null) return;\n document.title = watchTitle(model, selected);\n const { runId } = watchLocation(selected);\n moved(model.runs.find((run) => run.runId === runId)?.state ?? \"\", followed);\n}\nasync function withSelectedRun(model) {\n const { runId } = watchLocation(location.hash);\n if (runId === null || model.runs.some((run) => run.runId === runId)) return model;\n const detail = await fetch(\"data.json?runId=\" + encodeURIComponent(runId), { cache: \"no-store\" });\n if (detail.status === 404) return model;\n if (!detail.ok) throw new Error(\"watch-run-not-available\");\n const { run } = await detail.json();\n if (run?.runId !== runId) throw new Error(\"watch-run-mismatch\");\n return { ...model, runs: [...model.runs, run] };\n}\nasync function load() {\n state.again = state.loading;\n if (state.loading) return;\n state.loading = true;\n try {\n const reply = await fetch(\"data.json\", { cache: \"no-store\" });\n if (!reply.ok) throw new Error(\"watch-not-available\");\n
|
|
1
|
+
export declare const watchClient = "\nconst state = { model: null, receivedAt: 0, stale: false, copied: \"\", label: \"\", run: \"\", loading: false, again: false, columns: {}, cards: {}, start: null, hovered: null, focused: null, phonePairing: null, phoneBusy: false, phoneMessage: \"\", phone: null, phoneLoadedAt: 0, phoneAccepted: null, phoneSequence: 0, phoneApplied: 0 };\nfunction readPreference(key) {\n try { return JSON.parse(localStorage.getItem(key)); }\n catch { return null; }\n}\nfunction readColumnChoices(key) {\n const value = readPreference(key);\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return null;\n return Object.fromEntries(Object.entries(value).filter(([, choice]) => typeof choice === \"boolean\"));\n}\nfunction savePreference(key, value) {\n try { localStorage.setItem(key, JSON.stringify(value)); }\n catch {}\n}\nfunction startControls() {\n if (state.start === null) state.start = readPreference(\"cloving.watch.start\") === true;\n return { shown: state.start, onToggle() {\n state.start = !state.start;\n savePreference(\"cloving.watch.start\", state.start);\n draw();\n } };\n}\nfunction columnControls(model, selected) {\n const workflowId = model === null ? null : boardWorkflow(model, watchLocation(selected).workflowId);\n if (workflowId === null) return undefined;\n const key = \"cloving.watch.columns:\" + workflowId;\n if (!Object.hasOwn(state.columns, workflowId))\n state.columns = { ...state.columns, [workflowId]: readColumnChoices(key) };\n const choices = state.columns[workflowId];\n return { choices, onHover(name) { state.hovered = name; }, onFocus(name) { state.focused = name; }, onToggle(name) {\n const changed = { ...choices, [name]: !columnCollapsed(choices, name) };\n state.columns = { ...state.columns, [workflowId]: changed };\n savePreference(key, changed);\n draw();\n } };\n}\nfunction moved(next, followed) {\n const arrived = next === \"waiting_gate\" && next !== state.run;\n state.run = next;\n if (arrived) scrollTo(0, 0);\n else if (followed && next === \"running\") scrollTo(0, document.body.scrollHeight);\n}\nfunction copy(command) {\n const shown = (label) => {\n state.copied = command;\n state.label = label;\n draw();\n };\n navigator.clipboard.writeText(command).then(\n () => { shown(\"Copied\"); },\n () => { shown(\"Copy failed\"); },\n );\n}\nfunction draw() {\n const { model, stale } = state;\n const selected = location.hash.slice(1);\n const followed = innerHeight + scrollY >= document.body.scrollHeight - 80;\n const copying = { command: state.copied, label: state.label, onCopy: copy };\n const now = new Date().toISOString();\n const observationNow = model === null ? now : new Date(Date.parse(model.updatedAt) + performance.now() - state.receivedAt).toISOString();\n const columns = columnControls(model, selected);\n const start = model === null ? undefined : startControls();\n const cards = cardControls(model, model === null ? null : boardWorkflow(model, watchLocation(selected).workflowId));\n const phone = model === null ? undefined : phoneControls(now);\n const page = component(Page, { model, selected, now, observationNow, stale, copying, columns, start, cards, phone });\n render(page, document.getElementById(\"app\"));\n if (model === null) return;\n document.title = watchTitle(model, selected);\n const { runId } = watchLocation(selected);\n moved(model.runs.find((run) => run.runId === runId)?.state ?? \"\", followed);\n}\nasync function withSelectedRun(model) {\n const { runId } = watchLocation(location.hash);\n if (runId === null || model.runs.some((run) => run.runId === runId)) return model;\n const detail = await fetch(\"data.json?runId=\" + encodeURIComponent(runId), { cache: \"no-store\" });\n if (detail.status === 404) return model;\n if (!detail.ok) throw new Error(\"watch-run-not-available\");\n const { run } = await detail.json();\n if (run?.runId !== runId) throw new Error(\"watch-run-mismatch\");\n return { ...model, runs: [...model.runs, run] };\n}\nasync function load() {\n state.again = state.loading;\n if (state.loading) return;\n state.loading = true;\n try {\n const reply = await fetch(\"data.json\", { cache: \"no-store\" });\n if (!reply.ok) throw new Error(\"watch-not-available\");\n const model = await reply.json();\n const receivedAt = performance.now();\n state.model = await withSelectedRun(model);\n state.receivedAt = receivedAt;\n state.stale = false;\n } catch {\n state.stale = true;\n }\n state.loading = false;\n draw();\n if (state.again) load();\n}\nfunction listen() {\n const source = new EventSource(\"events\");\n source.onmessage = () => { load(); };\n source.onerror = () => { state.stale = true; draw(); };\n}\naddEventListener(\"keydown\", (event) => {\n if (event.key !== String.fromCharCode(92) || event.defaultPrevented || event.repeat || event.isComposing) return;\n if (event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) return;\n if (event.target?.closest?.(\"input, textarea, select, [contenteditable]\")) return;\n const target = state.hovered ?? state.focused;\n if (target === null || watchLocation(location.hash).runId !== null) return;\n const controls = columnControls(state.model, location.hash);\n if (controls === undefined) return;\n event.preventDefault();\n controls.onToggle(target);\n});\naddEventListener(\"hashchange\", () => { state.run = \"\"; state.hovered = null; state.focused = null; draw(); load(); });\ndraw();\nlisten();\nsetInterval(draw, 1000);\nsetInterval(load, 15000);\nif (actionToken !== null) {\n phoneLoad();\n setInterval(phoneLoad, 2000);\n}\n";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const watchClient = `
|
|
2
|
-
const state = { model: null, stale: false, copied: "", label: "", run: "", loading: false, again: false, columns: {}, cards: {}, start: null, hovered: null, focused: null };
|
|
2
|
+
const state = { model: null, receivedAt: 0, stale: false, copied: "", label: "", run: "", loading: false, again: false, columns: {}, cards: {}, start: null, hovered: null, focused: null, phonePairing: null, phoneBusy: false, phoneMessage: "", phone: null, phoneLoadedAt: 0, phoneAccepted: null, phoneSequence: 0, phoneApplied: 0 };
|
|
3
3
|
function readPreference(key) {
|
|
4
4
|
try { return JSON.parse(localStorage.getItem(key)); }
|
|
5
5
|
catch { return null; }
|
|
@@ -58,10 +58,12 @@ function draw() {
|
|
|
58
58
|
const followed = innerHeight + scrollY >= document.body.scrollHeight - 80;
|
|
59
59
|
const copying = { command: state.copied, label: state.label, onCopy: copy };
|
|
60
60
|
const now = new Date().toISOString();
|
|
61
|
+
const observationNow = model === null ? now : new Date(Date.parse(model.updatedAt) + performance.now() - state.receivedAt).toISOString();
|
|
61
62
|
const columns = columnControls(model, selected);
|
|
62
63
|
const start = model === null ? undefined : startControls();
|
|
63
64
|
const cards = cardControls(model, model === null ? null : boardWorkflow(model, watchLocation(selected).workflowId));
|
|
64
|
-
const
|
|
65
|
+
const phone = model === null ? undefined : phoneControls(now);
|
|
66
|
+
const page = component(Page, { model, selected, now, observationNow, stale, copying, columns, start, cards, phone });
|
|
65
67
|
render(page, document.getElementById("app"));
|
|
66
68
|
if (model === null) return;
|
|
67
69
|
document.title = watchTitle(model, selected);
|
|
@@ -85,7 +87,10 @@ async function load() {
|
|
|
85
87
|
try {
|
|
86
88
|
const reply = await fetch("data.json", { cache: "no-store" });
|
|
87
89
|
if (!reply.ok) throw new Error("watch-not-available");
|
|
88
|
-
|
|
90
|
+
const model = await reply.json();
|
|
91
|
+
const receivedAt = performance.now();
|
|
92
|
+
state.model = await withSelectedRun(model);
|
|
93
|
+
state.receivedAt = receivedAt;
|
|
89
94
|
state.stale = false;
|
|
90
95
|
} catch {
|
|
91
96
|
state.stale = true;
|
|
@@ -115,4 +120,8 @@ draw();
|
|
|
115
120
|
listen();
|
|
116
121
|
setInterval(draw, 1000);
|
|
117
122
|
setInterval(load, 15000);
|
|
123
|
+
if (actionToken !== null) {
|
|
124
|
+
phoneLoad();
|
|
125
|
+
setInterval(phoneLoad, 2000);
|
|
126
|
+
}
|
|
118
127
|
`;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type PhoneControls } from "./watch-phone-view.ts";
|
|
2
|
+
import { type Shown } from "./watch-element.ts";
|
|
3
|
+
import { type WatchModel } from "./watch-render.ts";
|
|
4
|
+
export interface StartControls {
|
|
5
|
+
readonly shown: boolean;
|
|
6
|
+
readonly onToggle: () => void;
|
|
7
|
+
}
|
|
8
|
+
export interface HeaderProps {
|
|
9
|
+
readonly model: WatchModel | null;
|
|
10
|
+
readonly stale: boolean;
|
|
11
|
+
readonly start?: StartControls;
|
|
12
|
+
readonly phone?: PhoneControls | undefined;
|
|
13
|
+
readonly now?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const clove: {
|
|
16
|
+
viewBox: string;
|
|
17
|
+
paths: string[];
|
|
18
|
+
};
|
|
19
|
+
export declare function queueLanes(model: WatchModel): string | null;
|
|
20
|
+
export declare function skippedText(value: unknown): string;
|
|
21
|
+
export declare function Queue(props: {
|
|
22
|
+
readonly model: WatchModel;
|
|
23
|
+
}): Shown;
|
|
24
|
+
export declare function Brand(): Shown;
|
|
25
|
+
export declare function HeaderStatus(props: HeaderProps): Shown;
|
|
26
|
+
export declare function HeaderActions(props: HeaderProps): Shown;
|
|
27
|
+
export declare function Header(props: HeaderProps): Shown;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { record } from "../protocol.js";
|
|
2
|
+
import { PhonePanel } from "./watch-phone-view.js";
|
|
3
|
+
import { component, element } from "./watch-element.js";
|
|
4
|
+
import { clockTime, counted } from "./watch-render.js";
|
|
5
|
+
export const clove = {
|
|
6
|
+
viewBox: "0.6625858545303345 0.6630800366401672 46.674827575683594 46.673831939697266",
|
|
7
|
+
paths: [
|
|
8
|
+
"M41.47315,11.48535c-1.20117-0.12305-2.16211-1.08398-2.28418-2.28516c-0.17676-1.7334-1.01758-3.29492-2.36865-4.39648s-3.05078-1.61719-4.7832-1.43359c-3.34277,0.34082-5.86377,3.13086-5.86377,6.49121v14.13867c0,0.27637,0.22363,0.5,0.5,0.5H40.8125c3.59766,0,6.52441-2.92676,6.52441-6.52441C47.33692,14.61523,44.81592,11.82422,41.47315,11.48535z M35.56543,15.81543l-5.85791,5.85742c-0.09766,0.09766-0.22559,0.14648-0.35352,0.14648s-0.25586-0.04883-0.35352-0.14648c-0.19531-0.19531-0.19531-0.51172,0-0.70703l5.85791-5.85742c0.19531-0.19531,0.51172-0.19531,0.70703,0C35.76073,15.30372,35.76074,15.62011,35.56543,15.81543z",
|
|
9
|
+
"M15.30225,0.66308c-3.36035,0-6.15088,2.52051-6.49121,5.86328C8.68897,7.72852,7.72852,8.68945,6.52686,8.81152c-1.7334,0.17578-3.29492,1.01758-4.396,2.36816s-1.61035,3.0498-1.43408,4.7832c0.34033,3.34277,3.13086,5.86328,6.49121,5.86328h14.13867c0.27637,0,0.5-0.22363,0.5-0.5V7.18751C21.82666,3.58984,18.8999,0.66308,15.30225,0.66308z M18.99951,19.00001c-0.09766,0.09766-0.22559,0.14648-0.35352,0.14648s-0.25586-0.04883-0.35352-0.14648l-5.85742-5.8584c-0.19531-0.19531-0.19531-0.51172,0-0.70703c0.19531-0.19531,0.51172-0.19531,0.70703,0l5.85742,5.8584C19.19482,18.48829,19.19482,18.80469,18.99951,19.00001z",
|
|
10
|
+
"M24,26.17383H9.86133c-3.59766,0-6.52441,2.92676-6.52441,6.52441c0,3.35938,2.52051,6.14941,5.86377,6.49023c1.20117,0.12207,2.16211,1.08301,2.28418,2.28418c0.17676,1.7334,1.01758,3.29492,2.36865,4.39648c1.17529,0.95801,2.61377,1.46777,4.11035,1.46777c0.22314,0,0.44775-0.01074,0.67285-0.03418C21.97949,46.96189,24.5,44.17186,24.5,40.81248V26.67383C24.5,26.39746,24.27637,26.17383,24,26.17383z M21.67334,29.70704l-5.85791,5.8584c-0.09766,0.09766-0.22559,0.14648-0.35352,0.14648s-0.25586-0.04883-0.35352-0.14648c-0.19531-0.19531-0.19531-0.51172,0-0.70703L20.9663,29c0.19531-0.19531,0.51172-0.19531,0.70703,0S21.86865,29.51172,21.67334,29.70704z",
|
|
11
|
+
"M47.30322,32.03711c-0.34033-3.34277-3.13086-5.86328-6.49072-5.86328H26.67334c-0.27637,0-0.5,0.22363-0.5,0.5V40.8125c0,3.59766,2.92676,6.52441,6.52442,6.52441c3.36035,0,6.15088-2.52148,6.49121-5.86426c0.12207-1.20117,1.08301-2.16211,2.28418-2.28418c1.7334-0.17578,3.29492-1.01758,4.396-2.36816S47.47949,33.7705,47.30322,32.03711z M35.56543,35.56543c-0.09766,0.09766-0.22559,0.14648-0.35352,0.14648s-0.25586-0.04883-0.35352-0.14648l-5.85791-5.8584c-0.19531-0.19531-0.19531-0.51172,0-0.70703s0.51172-0.19531,0.70703,0l5.85791,5.8584C35.76074,35.05371,35.76074,35.37011,35.56543,35.56543z",
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
export function queueLanes(model) {
|
|
15
|
+
const queue = model.queue;
|
|
16
|
+
if (queue === undefined)
|
|
17
|
+
return null;
|
|
18
|
+
return `Queue: ${String(queue["busy"])} of ${String(queue["lanes"])} lanes busy`;
|
|
19
|
+
}
|
|
20
|
+
export function skippedText(value) {
|
|
21
|
+
const ticket = record(value) ?? {};
|
|
22
|
+
const name = `#${String(ticket["ticketId"])}`;
|
|
23
|
+
const dependencies = ticket["dependencies"];
|
|
24
|
+
if (ticket["reason"] === "ticket-dependency-open" &&
|
|
25
|
+
Array.isArray(dependencies))
|
|
26
|
+
return `${name} waits for ${dependencies.map((item) => `#${String(item)}`).join(", ")}`;
|
|
27
|
+
if (ticket["reason"] === "ticket-active")
|
|
28
|
+
return `${name} is in work`;
|
|
29
|
+
return `${name}: ${String(ticket["reason"])}`;
|
|
30
|
+
}
|
|
31
|
+
export function Queue(props) {
|
|
32
|
+
const skipped = props.model.queue?.["skipped"];
|
|
33
|
+
if (!Array.isArray(skipped) || skipped.length === 0)
|
|
34
|
+
return null;
|
|
35
|
+
return element("details", {
|
|
36
|
+
class: "queue-waiting",
|
|
37
|
+
children: [
|
|
38
|
+
element("summary", {
|
|
39
|
+
children: `${counted(skipped.length, "ticket")} skipped`,
|
|
40
|
+
}),
|
|
41
|
+
element("ul", {
|
|
42
|
+
children: skipped.map((value) => element("li", { children: skippedText(value) })),
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function Brand() {
|
|
48
|
+
return element("strong", {
|
|
49
|
+
class: "brand",
|
|
50
|
+
children: [
|
|
51
|
+
element("svg", {
|
|
52
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
53
|
+
"aria-hidden": "true",
|
|
54
|
+
focusable: "false",
|
|
55
|
+
viewBox: clove.viewBox,
|
|
56
|
+
children: clove.paths.map((d) => element("path", { fill: "currentColor", d })),
|
|
57
|
+
}),
|
|
58
|
+
"cloving",
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
export function HeaderStatus(props) {
|
|
63
|
+
const { model, stale } = props;
|
|
64
|
+
const updated = model === null ? "" : `updated ${clockTime(model.updatedAt)}`;
|
|
65
|
+
const stamp = stale
|
|
66
|
+
? element("span", {
|
|
67
|
+
class: "bad",
|
|
68
|
+
children: "The watch tool does not answer.",
|
|
69
|
+
})
|
|
70
|
+
: element("span", { children: updated });
|
|
71
|
+
const lanes = model === null ? null : queueLanes(model);
|
|
72
|
+
return element("div", {
|
|
73
|
+
class: "header-status",
|
|
74
|
+
children: [
|
|
75
|
+
stamp,
|
|
76
|
+
lanes === null
|
|
77
|
+
? null
|
|
78
|
+
: element("span", { class: "queue-lanes", children: lanes }),
|
|
79
|
+
],
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export function HeaderActions(props) {
|
|
83
|
+
const { start, phone } = props;
|
|
84
|
+
if (start === undefined && phone === undefined)
|
|
85
|
+
return null;
|
|
86
|
+
return element("div", {
|
|
87
|
+
class: "header-actions",
|
|
88
|
+
children: [
|
|
89
|
+
start === undefined
|
|
90
|
+
? null
|
|
91
|
+
: element("button", {
|
|
92
|
+
type: "button",
|
|
93
|
+
class: "start-toggle",
|
|
94
|
+
"aria-controls": "start-run",
|
|
95
|
+
"aria-expanded": String(start.shown),
|
|
96
|
+
onClick: start.onToggle,
|
|
97
|
+
children: "Start a run",
|
|
98
|
+
}),
|
|
99
|
+
phone === undefined
|
|
100
|
+
? null
|
|
101
|
+
: component(PhonePanel, {
|
|
102
|
+
phone,
|
|
103
|
+
now: props.now ?? props.model?.updatedAt ?? "",
|
|
104
|
+
}),
|
|
105
|
+
],
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
export function Header(props) {
|
|
109
|
+
return element("header", {
|
|
110
|
+
children: [
|
|
111
|
+
component(Brand, {}),
|
|
112
|
+
component(HeaderStatus, props),
|
|
113
|
+
component(HeaderActions, props),
|
|
114
|
+
],
|
|
115
|
+
});
|
|
116
|
+
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import type { WorkflowStages } from "../workflow-declaration.ts";
|
|
2
|
+
import { type WorkflowRefusal } from "../workflow-refusals.ts";
|
|
1
3
|
import type { WatchDecision, WatchItem, WatchModel, WatchTurn } from "./watch-render.ts";
|
|
4
|
+
import { type GithubRecords } from "./watch-pull-request.ts";
|
|
5
|
+
export type { GithubRecords } from "./watch-pull-request.ts";
|
|
6
|
+
import { type PrRepository } from "./watch-pr-identity.ts";
|
|
7
|
+
type Fields = Readonly<Record<string, unknown>>;
|
|
2
8
|
export declare function activityOf(line: string): WatchItem[];
|
|
3
9
|
export interface TurnRecords {
|
|
4
10
|
readonly key: string;
|
|
@@ -10,7 +16,11 @@ export interface TurnRecords {
|
|
|
10
16
|
export declare function turnOf(records: TurnRecords): WatchTurn;
|
|
11
17
|
export declare function decisionCommands(decision: unknown, client: string): WatchDecision;
|
|
12
18
|
export interface WatchInputs {
|
|
19
|
+
readonly queue?: Fields;
|
|
20
|
+
readonly repository?: PrRepository | null;
|
|
13
21
|
readonly workflows: readonly string[];
|
|
22
|
+
readonly workflowRefusals?: readonly WorkflowRefusal[];
|
|
23
|
+
readonly workflowStages?: WorkflowStages;
|
|
14
24
|
readonly summaries?: readonly unknown[];
|
|
15
25
|
readonly home: string;
|
|
16
26
|
readonly client: string;
|
|
@@ -22,8 +32,4 @@ export interface WatchInputs {
|
|
|
22
32
|
readonly turns: readonly WatchTurn[];
|
|
23
33
|
readonly githubRecords: readonly GithubRecords[];
|
|
24
34
|
}
|
|
25
|
-
export interface GithubRecords {
|
|
26
|
-
readonly started: unknown;
|
|
27
|
-
readonly result: unknown;
|
|
28
|
-
}
|
|
29
35
|
export declare function watchModel(inputs: WatchInputs): WatchModel;
|