toolroll 0.9.104 → 0.9.105
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 +62 -5
- package/README.md +18 -20
- package/dist/accent-colors.js +0 -29
- package/dist/acp-agents.js +0 -3
- package/dist/acp-attest.js +0 -30
- package/dist/acp-check.js +3 -70
- package/dist/acp-client.js +3 -94
- package/dist/acp-inspect.js +1 -20
- package/dist/action-ledger.js +0 -8
- package/dist/activity-line.js +0 -14
- package/dist/actor.js +0 -15
- package/dist/advanced-schema.js +12 -0
- package/dist/advanced-view.js +26 -0
- package/dist/advanced.js +61 -0
- package/dist/agent-board.js +0 -117
- package/dist/agent-fence.js +11 -367
- package/dist/agent-onboard.js +12 -50
- package/dist/agent-pulse.js +5 -38
- package/dist/agent-state-words.js +0 -8
- package/dist/agent-state.js +1 -45
- package/dist/agent-turns.js +3 -17
- package/dist/agentconfig.js +1 -99
- package/dist/agents-board.js +0 -60
- package/dist/agents-live.js +1 -8
- package/dist/api-tokens.js +0 -27
- package/dist/approval-authority.js +0 -59
- package/dist/approval-password.js +0 -10
- package/dist/approval-policy.js +0 -29
- package/dist/approval-rules-ui.js +0 -9
- package/dist/assignment-adapters.js +0 -14
- package/dist/assignment-brief.js +1 -17
- package/dist/assignment-delivery.js +0 -22
- package/dist/assignment-presentation.js +0 -14
- package/dist/assignment-status.js +1 -30
- package/dist/assignment-ui.js +0 -12
- package/dist/assignment.js +17 -139
- package/dist/attest.js +0 -38
- package/dist/audit-cli.js +0 -9
- package/dist/backend.js +0 -59
- package/dist/backup-ui.js +0 -12
- package/dist/backup.js +8 -61
- package/dist/batch-checks.js +0 -20
- package/dist/batch-policy.js +0 -4
- package/dist/beads.js +0 -48
- package/dist/bin.js +0 -8
- package/dist/board.js +1 -36
- package/dist/boot-identity.js +0 -42
- package/dist/bounded-spawn.js +4 -28
- package/dist/brand-mark.js +0 -21
- package/dist/brief-fence.js +0 -16
- package/dist/browser/terminal.css +1 -1
- package/dist/browser/terminal.js +16 -16
- package/dist/browser/workspace.css +2 -2
- package/dist/browser/workspace.js +26 -26
- package/dist/browser-crew.js +0 -8
- package/dist/browser-shell.js +2 -15
- package/dist/browser-workspace.js +6 -30
- package/dist/budget-alerts.js +1 -4
- package/dist/build-review.js +2 -50
- package/dist/builder-restart.js +0 -13
- package/dist/builder.js +21 -1035
- package/dist/canonical-json.js +0 -12
- package/dist/capscan.js +1 -32
- package/dist/card-catalog.js +0 -12
- package/dist/card-cli.js +0 -1
- package/dist/card-render.js +0 -25
- package/dist/card-sources.js +0 -10
- package/dist/chat-acceptance.js +0 -7
- package/dist/chat-actions.js +5 -190
- package/dist/chat-admission.js +0 -7
- package/dist/chat-approval.js +0 -25
- package/dist/chat-ask.js +0 -17
- package/dist/chat-card-part.js +0 -3
- package/dist/chat-card.js +0 -6
- package/dist/chat-channel.js +2 -83
- package/dist/chat-continuity.js +0 -31
- package/dist/chat-controls.js +0 -7
- package/dist/chat-core.js +0 -55
- package/dist/chat-decide.js +2 -153
- package/dist/chat-delivery-state.js +0 -49
- package/dist/chat-delivery.js +2 -143
- package/dist/chat-display.js +0 -2
- package/dist/chat-evidence.js +0 -65
- package/dist/chat-flow.js +0 -72
- package/dist/chat-follow.js +0 -13
- package/dist/chat-inbox.js +0 -34
- package/dist/chat-live-schema.js +0 -14
- package/dist/chat-live.js +2 -87
- package/dist/chat-message-states.js +13 -40
- package/dist/chat-messages.js +0 -153
- package/dist/chat-migration.js +0 -57
- package/dist/chat-polish.js +0 -7
- package/dist/chat-quiet.js +0 -37
- package/dist/chat-review.js +0 -4
- package/dist/chat-rooms.js +0 -22
- package/dist/chat-settings-page.js +0 -4
- package/dist/chat-task-actions.js +0 -7
- package/dist/chat-terms.js +0 -21
- package/dist/chat-voice.js +0 -38
- package/dist/chat-warmth.js +1 -3
- package/dist/check-access.js +0 -30
- package/dist/check-facts.js +2 -62
- package/dist/check-failure.js +0 -98
- package/dist/check-levels-ui.js +4 -10
- package/dist/check-levels.js +3 -35
- package/dist/check-load.js +1 -49
- package/dist/check-only-standing.js +0 -6
- package/dist/check-only.js +0 -22
- package/dist/check-progress.js +0 -32
- package/dist/check-repair.js +2 -35
- package/dist/check-report.js +1 -108
- package/dist/check-stamp.js +0 -20
- package/dist/checkout-cleanup.js +0 -84
- package/dist/checkout-proof.js +1 -13
- package/dist/child-database.js +0 -3
- package/dist/claim.js +4 -508
- package/dist/claude-print.js +0 -10
- package/dist/cli-fast.js +0 -8
- package/dist/cli-help.js +90 -78
- package/dist/cli-http.js +0 -10
- package/dist/cli.js +26 -241
- package/dist/code-extract.js +0 -6
- package/dist/code-map-acts.js +0 -7
- package/dist/code-map-admission.js +2 -26
- package/dist/code-map-build.js +3 -24
- package/dist/code-map-cli.js +0 -4
- package/dist/code-map-main.js +0 -6
- package/dist/code-map-read.js +0 -12
- package/dist/code-map-report.js +0 -9
- package/dist/code-map-shape.js +0 -19
- package/dist/code-map-store.js +0 -26
- package/dist/codex-limits.js +1 -17
- package/dist/coding-context.js +0 -10
- package/dist/coding-handoff.js +0 -14
- package/dist/coding-provider.js +0 -39
- package/dist/coding-shipping-ui.js +0 -1
- package/dist/coding-ui.js +0 -1
- package/dist/coding-update.js +1 -18
- package/dist/coding-workspace.js +0 -27
- package/dist/commit-extract.js +0 -83
- package/dist/connect-cli.js +0 -19
- package/dist/console-chrome.js +1 -34
- package/dist/console-instance.js +2 -91
- package/dist/container-state.js +0 -4
- package/dist/containment.js +2 -105
- package/dist/contract-changes.js +0 -6
- package/dist/contracts/acceptance-terms.js +0 -7
- package/dist/contracts/chat-actions.js +0 -46
- package/dist/contracts/chat-callback-rows.js +0 -8
- package/dist/contracts/chat-card.js +0 -14
- package/dist/contracts/chat-content.js +0 -55
- package/dist/contracts/chat-tables.js +0 -7
- package/dist/contracts/cli.js +0 -59
- package/dist/contracts/coding-activity.js +0 -15
- package/dist/contracts/coding-context.js +0 -15
- package/dist/contracts/coding-handoff.js +0 -11
- package/dist/contracts/coding-workspace.js +0 -14
- package/dist/contracts/console-api.js +1 -54
- package/dist/contracts/contract-test.js +0 -14
- package/dist/contracts/contract.js +0 -48
- package/dist/contracts/decision.js +0 -20
- package/dist/contracts/diff-stat.js +0 -16
- package/dist/contracts/discord-callback.js +0 -9
- package/dist/contracts/flow-card.js +0 -18
- package/dist/contracts/flow-propose.js +0 -8
- package/dist/contracts/flow-send.js +0 -31
- package/dist/contracts/flow.js +0 -112
- package/dist/contracts/gateway-tools.js +0 -22
- package/dist/contracts/handoff.js +0 -22
- package/dist/contracts/integration-metadata.js +0 -39
- package/dist/contracts/lead-context.js +0 -14
- package/dist/contracts/lead-tools.js +0 -49
- package/dist/contracts/mcp-oauth.js +0 -12
- package/dist/contracts/memory-pass.js +0 -21
- package/dist/contracts/model-catalog.js +0 -9
- package/dist/contracts/observation-request.js +0 -11
- package/dist/contracts/plan.js +0 -16
- package/dist/contracts/project-knowledge.js +0 -26
- package/dist/contracts/project-memory.js +0 -16
- package/dist/contracts/project-skills.js +0 -31
- package/dist/contracts/proof.js +0 -23
- package/dist/contracts/provider.js +0 -9
- package/dist/contracts/recipes.js +0 -16
- package/dist/contracts/release-check.js +0 -61
- package/dist/contracts/release-terms.js +0 -27
- package/dist/contracts/retention.js +0 -12
- package/dist/contracts/review-findings.js +0 -13
- package/dist/contracts/route-results.js +0 -15
- package/dist/contracts/route.js +0 -33
- package/dist/contracts/scope.js +0 -29
- package/dist/contracts/scout-report.js +0 -34
- package/dist/contracts/slack-callback.js +0 -11
- package/dist/contracts/sort-answer.js +0 -24
- package/dist/contracts/stage-output.js +0 -46
- package/dist/contracts/storage.js +0 -8
- package/dist/contracts/store-json.js +0 -41
- package/dist/contracts/subagent-turn.js +0 -23
- package/dist/contracts/task-sizing.js +0 -10
- package/dist/contracts/teams-callback.js +0 -7
- package/dist/contracts/telegram-callback.js +0 -27
- package/dist/contracts/trigger-payloads.js +0 -41
- package/dist/contracts/update-journal.js +0 -47
- package/dist/contracts/verification-receipt.js +0 -36
- package/dist/contracts/verification-view.js +0 -15
- package/dist/contracts/youiyoux-request.js +0 -26
- package/dist/control-setup.js +0 -7
- package/dist/control-ui.js +0 -3
- package/dist/controller-service.js +0 -4
- package/dist/controller-supervisor.js +0 -15
- package/dist/converse.js +3 -129
- package/dist/coordinator-proposals.js +1 -6
- package/dist/coordinator.js +0 -65
- package/dist/credentials-ui.js +0 -6
- package/dist/daemon.js +0 -137
- package/dist/database-reclaim.js +0 -3
- package/dist/decision.js +0 -78
- package/dist/demo-chat.js +4 -15
- package/dist/demo-sign-in.js +77 -0
- package/dist/demo.js +5 -194
- package/dist/deploy-gate.js +0 -20
- package/dist/deploy-lock.js +0 -4
- package/dist/deploy-phase.js +0 -22
- package/dist/deploy-rescue.js +0 -21
- package/dist/deprecations.js +0 -12
- package/dist/design/kit.css +9 -6
- package/dist/design/kit.js +2 -33
- package/dist/desktop-access.js +0 -9
- package/dist/desktop-bundle.js +1 -3
- package/dist/desktop-host.js +0 -34
- package/dist/desktop-update-gate.js +0 -8
- package/dist/desktop-update-recovery.js +1 -18
- package/dist/desktop-update.js +2 -48
- package/dist/digest-times.js +0 -2
- package/dist/disclosure.js +0 -5
- package/dist/discord-api.js +0 -6
- package/dist/discord-chat.js +0 -31
- package/dist/discord.js +0 -7
- package/dist/discover.js +0 -50
- package/dist/dispatch.js +61 -60
- package/dist/dispose.js +0 -208
- package/dist/doctor.js +0 -48
- package/dist/easy-start-args.js +7 -7
- package/dist/easy-start.js +32 -45
- package/dist/egress.js +1 -63
- package/dist/email-settings.js +0 -8
- package/dist/envelope.js +50 -86
- package/dist/eval-gate.js +1 -37
- package/dist/eval-hooks.js +0 -120
- package/dist/eval-oracle-main.js +0 -7
- package/dist/eval-oracle.js +3 -42
- package/dist/eval-world.js +1 -23
- package/dist/evals.js +6 -134
- package/dist/evidence-pack.js +0 -29
- package/dist/evidence-pair.js +0 -17
- package/dist/evidence.js +4 -280
- package/dist/exec.js +19 -404
- package/dist/exhaustion.js +0 -30
- package/dist/export-ui.js +0 -7
- package/dist/export.js +1 -38
- package/dist/failing-first.js +0 -6
- package/dist/fallback-schema.js +0 -5
- package/dist/fallback.js +0 -81
- package/dist/fast-start.js +0 -97
- package/dist/fast-terms.js +0 -3
- package/dist/fenced-check-coverage.js +0 -11
- package/dist/findings.js +1 -63
- package/dist/first-run.js +4 -57
- package/dist/first-tasks-child.js +0 -5
- package/dist/flaky-ci.js +1 -24
- package/dist/flaky-cli.js +0 -4
- package/dist/flaky.js +0 -43
- package/dist/fleet-schema.js +0 -11
- package/dist/flow-actions.js +0 -31
- package/dist/flow-browser.js +0 -42
- package/dist/flow-cadence.js +1 -24
- package/dist/flow-card-task.js +0 -11
- package/dist/flow-changed.js +0 -16
- package/dist/flow-code.js +1 -45
- package/dist/flow-draft.js +0 -17
- package/dist/flow-engine.js +2 -76
- package/dist/flow-gallery-ui.js +0 -28
- package/dist/flow-gallery.js +0 -54
- package/dist/flow-insights.js +0 -12
- package/dist/flow-items.js +0 -27
- package/dist/flow-live.js +0 -31
- package/dist/flow-people.js +0 -14
- package/dist/flow-pull-request.js +0 -32
- package/dist/flow-replies.js +0 -9
- package/dist/flow-result-card.js +0 -8
- package/dist/flow-schedule.js +0 -74
- package/dist/flow-scripts.js +0 -13
- package/dist/flow-secrets.js +0 -10
- package/dist/flow-send.js +0 -45
- package/dist/flow-share.js +0 -60
- package/dist/flow-sort.js +1 -24
- package/dist/flow-starters-ui.js +0 -2
- package/dist/flow-starters.js +0 -13
- package/dist/flow-steps.js +0 -80
- package/dist/flow-triggers.js +2 -256
- package/dist/flow-unattended-words.js +0 -13
- package/dist/flow-unattended.js +2 -115
- package/dist/flows-cli.js +2 -36
- package/dist/flows-ui.js +0 -51
- package/dist/flows.js +0 -158
- package/dist/folder-gate.js +0 -21
- package/dist/folder-look.js +0 -42
- package/dist/follow-through-brief.js +0 -6
- package/dist/follow-through-cli.js +0 -5
- package/dist/fonts.js +0 -13
- package/dist/gaps.js +0 -20
- package/dist/gate-failure.js +0 -7
- package/dist/git-floor.js +0 -12
- package/dist/git-incident.js +2 -38
- package/dist/git-views.js +0 -24
- package/dist/git.js +0 -31
- package/dist/github-import.js +0 -22
- package/dist/github-jobs.js +0 -12
- package/dist/google-mail.js +2 -27
- package/dist/grant.js +0 -110
- package/dist/graph.js +0 -108
- package/dist/guides.js +4 -15
- package/dist/handover-note.js +0 -12
- package/dist/health-cli.js +0 -2
- package/dist/home-groups.js +0 -15
- package/dist/html.js +0 -54
- package/dist/install-method.js +0 -12
- package/dist/integrations-ui.js +0 -15
- package/dist/integrations.js +7 -50
- package/dist/invoke.js +1 -381
- package/dist/is-record.js +0 -1
- package/dist/issues.js +0 -48
- package/dist/jsonl-discriminants.js +0 -6
- package/dist/keymap.js +0 -17
- package/dist/keys.js +0 -56
- package/dist/kits-ui.js +0 -3
- package/dist/kits.js +1 -24
- package/dist/knowledge-cli.js +0 -4
- package/dist/knowledge-ui.js +0 -8
- package/dist/landed-cleanup.js +0 -119
- package/dist/laptop-background.js +0 -85
- package/dist/laptop-service.js +0 -67
- package/dist/latency-timeline.js +2 -23
- package/dist/lead-about.js +0 -7
- package/dist/lead-answer-eval.js +0 -39
- package/dist/lead-capabilities.js +0 -19
- package/dist/lead-cli-live.js +0 -22
- package/dist/lead-cli.js +0 -27
- package/dist/lead-commitments.js +1 -27
- package/dist/lead-context.js +2 -42
- package/dist/lead-contract.js +0 -8
- package/dist/lead-doors.js +0 -105
- package/dist/lead-follow.js +0 -41
- package/dist/lead-identity.js +1 -4
- package/dist/lead-latency-schema.js +0 -13
- package/dist/lead-people.js +3 -18
- package/dist/lead-progress.js +0 -12
- package/dist/lead-queue-runtime.js +0 -26
- package/dist/lead-queue.js +0 -35
- package/dist/lead-route.js +0 -33
- package/dist/lead-status.js +0 -37
- package/dist/lead-sweep.js +0 -18
- package/dist/lead-tools.js +0 -160
- package/dist/lead-voice.js +0 -54
- package/dist/lead.js +2 -105
- package/dist/learning-child.js +0 -6
- package/dist/learning-look.js +0 -14
- package/dist/ledger-chain.js +0 -34
- package/dist/ledger-csv.js +0 -2
- package/dist/ledger-view.js +0 -3
- package/dist/lesson-notes.js +0 -56
- package/dist/limits-ui.js +0 -14
- package/dist/link.js +0 -79
- package/dist/live-backup.js +3 -33
- package/dist/live-bus.js +7 -81
- package/dist/live-children-read.js +4 -47
- package/dist/live-children.js +4 -44
- package/dist/live-detail.js +0 -17
- package/dist/live-input.js +5 -68
- package/dist/live-main-read.js +1 -14
- package/dist/live-notes.js +0 -12
- package/dist/live-open.js +1 -23
- package/dist/live-records.js +4 -151
- package/dist/live-reply.js +1 -51
- package/dist/live-terminal.js +12 -111
- package/dist/live.js +4 -130
- package/dist/local-owner-acts.js +0 -53
- package/dist/local-owner.js +2 -93
- package/dist/log.js +0 -8
- package/dist/login-secrets.js +2 -38
- package/dist/machine-check.js +0 -2
- package/dist/machine-identity.js +1 -46
- package/dist/mailbox.js +0 -30
- package/dist/maintenance.js +1 -3
- package/dist/mcp-connect.js +0 -88
- package/dist/mcp-core.js +0 -45
- package/dist/mcp-http.js +0 -13
- package/dist/mcp-oauth.js +0 -37
- package/dist/mcp-person.js +0 -11
- package/dist/mcp.js +3 -73
- package/dist/memory-cli.js +0 -3
- package/dist/memory-pass.js +0 -53
- package/dist/memory-tidy.js +0 -55
- package/dist/memory-use.js +2 -24
- package/dist/merge-checklist.js +21 -29
- package/dist/metrics.js +0 -10
- package/dist/mobile-viewport.js +0 -6
- package/dist/model-catalog.js +1 -33
- package/dist/model-choices.js +9 -84
- package/dist/model-names.js +0 -9
- package/dist/models-cli.js +0 -13
- package/dist/models-ui.js +0 -17
- package/dist/modes.js +0 -35
- package/dist/monitoring-settings.js +2 -27
- package/dist/monitoring-ui.js +2 -14
- package/dist/monitoring.js +2 -38
- package/dist/names.js +0 -39
- package/dist/needs-you.js +7 -70
- package/dist/never-index.js +0 -9
- package/dist/nightly-check.js +0 -74
- package/dist/nightly-github.js +0 -168
- package/dist/notification-delivery.js +0 -3
- package/dist/notification-rows.js +0 -17
- package/dist/oauth-run-token.js +1 -37
- package/dist/observations.js +0 -16
- package/dist/oidc.js +1 -20
- package/dist/onboard.js +4 -57
- package/dist/one-step-chat-schema.js +0 -15
- package/dist/openrouter-models.js +0 -6
- package/dist/operate-remote-arguments.js +0 -17
- package/dist/operate-remote.js +0 -33
- package/dist/operate.js +227 -2326
- package/dist/orphan-sweep.js +3 -37
- package/dist/page-work-contract.js +0 -3
- package/dist/password-bearer.js +1 -11
- package/dist/passwordless.js +0 -3
- package/dist/peek-cli.js +0 -46
- package/dist/peek.js +2 -61
- package/dist/people-audit-ui.js +0 -6
- package/dist/person-proof.js +0 -6
- package/dist/phase-routing.js +8 -183
- package/dist/plain-schema.js +0 -14
- package/dist/plain-words.js +18 -12
- package/dist/plan-auto.js +0 -20
- package/dist/plan-login.js +0 -16
- package/dist/plan.js +0 -68
- package/dist/plane-review.js +0 -56
- package/dist/planner-source.js +0 -96
- package/dist/planner.js +0 -117
- package/dist/policy-ui.js +0 -8
- package/dist/policy.js +0 -47
- package/dist/prepared-evidence.js +0 -5
- package/dist/principal.js +0 -29
- package/dist/probe.js +0 -30
- package/dist/process-custody.js +0 -15
- package/dist/process-liveness.js +0 -32
- package/dist/process-tree.js +3 -29
- package/dist/project-access.js +0 -10
- package/dist/project-admission.js +1 -41
- package/dist/project-cli.js +0 -6
- package/dist/project-concurrency.js +0 -35
- package/dist/project-delete-ui.js +4 -29
- package/dist/project-delete.js +1 -73
- package/dist/project-demo.js +0 -13
- package/dist/project-file.js +0 -2
- package/dist/project-identity.js +0 -41
- package/dist/project-knowledge.js +0 -39
- package/dist/project-learning.js +3 -55
- package/dist/project-memory.js +2 -45
- package/dist/project-outcomes.js +0 -6
- package/dist/project-sandbox.js +0 -23
- package/dist/project-skills.js +0 -12
- package/dist/project-tools.js +6 -184
- package/dist/project.js +0 -48
- package/dist/prompt.js +0 -31
- package/dist/proof.js +0 -220
- package/dist/proposal.js +0 -50
- package/dist/protected-storage-look.js +0 -6
- package/dist/protected-storage.js +1 -84
- package/dist/provider-auth.js +3 -69
- package/dist/provider-capture.js +1 -15
- package/dist/provider-connection.js +0 -8
- package/dist/provider-home.js +0 -25
- package/dist/provider-limits.js +0 -14
- package/dist/provider.js +0 -324
- package/dist/public-access.js +0 -34
- package/dist/public-check.js +0 -16
- package/dist/publish.js +1 -150
- package/dist/pull-request-flow.js +0 -77
- package/dist/pull-request-schema.js +0 -4
- package/dist/pull-request-ui.js +0 -5
- package/dist/pulls.js +0 -80
- package/dist/push.js +5 -89
- package/dist/quick-start.js +1 -23
- package/dist/read-executor-worker.js +0 -1
- package/dist/read-executor.js +0 -10
- package/dist/read-only-request.js +0 -7
- package/dist/recipe-ui.js +0 -6
- package/dist/recipes.js +0 -13
- package/dist/release-adapters.js +6 -214
- package/dist/release-approval.js +0 -74
- package/dist/release-authority.js +0 -42
- package/dist/release-auto.js +0 -142
- package/dist/release-card.js +0 -100
- package/dist/release-carry.js +0 -132
- package/dist/release-ci-hold.js +0 -20
- package/dist/release-cli.js +0 -46
- package/dist/release-coverage.js +0 -16
- package/dist/release-gate.js +0 -30
- package/dist/release-git.js +0 -24
- package/dist/release-links.js +0 -17
- package/dist/release-net.js +0 -42
- package/dist/release-next.js +0 -25
- package/dist/release-recheck.js +0 -89
- package/dist/release-refusal.js +0 -18
- package/dist/release-view.js +0 -5
- package/dist/release.js +7 -341
- package/dist/releases.js +0 -49
- package/dist/remote-audit.js +0 -25
- package/dist/remote-command.js +0 -16
- package/dist/remote-destination.js +5 -26
- package/dist/remote-exec.js +1 -27
- package/dist/remote-main.js +1 -53
- package/dist/remote-run.js +0 -5
- package/dist/remote.js +0 -49
- package/dist/render.js +0 -133
- package/dist/reply-shape.js +0 -85
- package/dist/reply-voice.js +0 -7
- package/dist/report-summary.js +0 -5
- package/dist/reported-usage.js +0 -30
- package/dist/repos.js +9 -62
- package/dist/repository-context.js +1 -24
- package/dist/request-budget-ui.js +0 -4
- package/dist/request-budget.js +0 -23
- package/dist/restart-certification.js +0 -37
- package/dist/result-actions.js +0 -62
- package/dist/result-acts.js +0 -34
- package/dist/result-completion.js +0 -25
- package/dist/result-evidence-readers.js +0 -3
- package/dist/result-follow-ups.js +1 -39
- package/dist/result-review.js +0 -86
- package/dist/result-shots.js +0 -39
- package/dist/retention-ui.js +0 -7
- package/dist/retention.js +2 -46
- package/dist/review-context.js +0 -129
- package/dist/review-evidence.js +0 -4
- package/dist/review-switch.js +1 -7
- package/dist/reviewer.js +0 -35
- package/dist/route-change-check.js +0 -2
- package/dist/route-change.js +0 -16
- package/dist/route-hooks.js +0 -27
- package/dist/route-results.js +2 -58
- package/dist/route-rules.js +1 -106
- package/dist/route-savings.js +0 -36
- package/dist/route-store.js +1 -133
- package/dist/run-closeout.js +2 -50
- package/dist/run-efficiency.js +2 -44
- package/dist/run-ending.js +0 -13
- package/dist/runner-process.js +0 -33
- package/dist/runner.js +17 -189
- package/dist/sample-project.js +2 -27
- package/dist/sandbox-launch.js +4 -25
- package/dist/sandbox-runtime.js +1 -88
- package/dist/scan.js +0 -27
- package/dist/scope.js +4 -567
- package/dist/scout-browser-lock.js +0 -6
- package/dist/scout-browser.js +2 -68
- package/dist/scout-net.js +1 -32
- package/dist/scout-report.js +0 -22
- package/dist/scout.js +1 -116
- package/dist/secret-mint.js +0 -6
- package/dist/serve.js +21 -555
- package/dist/server/agents-computers.js +0 -10
- package/dist/server/agents-live-filed.js +0 -13
- package/dist/server/agents-live-lead.js +0 -19
- package/dist/server/agents-live-room.js +0 -19
- package/dist/server/chat.js +2 -194
- package/dist/server/chrome.js +17 -263
- package/dist/server/console.css +4 -4
- package/dist/server/edge-refusal.js +0 -3
- package/dist/server/flows.js +5 -74
- package/dist/server/guards.js +1 -88
- package/dist/server/handler-registry.js +0 -2
- package/dist/server/home-asks.js +1 -22
- package/dist/server/home.js +1 -30
- package/dist/server/http.js +0 -82
- package/dist/server/in-place.js +0 -15
- package/dist/server/kit-standalone.js +0 -20
- package/dist/server/kit.js +2 -114
- package/dist/server/last-checks.js +0 -2
- package/dist/server/live.js +1 -36
- package/dist/server/merge-ready-view.js +0 -6
- package/dist/server/mutation-key.js +3 -40
- package/dist/server/pages-assets.js +0 -16
- package/dist/server/pages.js +7 -195
- package/dist/server/people-tokens.js +3 -101
- package/dist/server/remote-hooks.js +0 -13
- package/dist/server/remote.js +0 -28
- package/dist/server/render-chat.js +8 -144
- package/dist/server/render-code-map.js +0 -5
- package/dist/server/render-flaky.js +0 -8
- package/dist/server/render-follow-through.js +2 -5
- package/dist/server/render-history.js +2 -34
- package/dist/server/render-new-task.js +2 -29
- package/dist/server/render-pages.js +1 -111
- package/dist/server/render-people.js +2 -46
- package/dist/server/render-projects.js +15 -32
- package/dist/server/render-release.js +1 -14
- package/dist/server/render-results.js +4 -355
- package/dist/server/render-settings.js +0 -15
- package/dist/server/render-tasks.js +13 -493
- package/dist/server/request-context.js +2 -9
- package/dist/server/retired-routes.js +0 -11
- package/dist/server/route-policy.js +0 -3
- package/dist/server/route-table.js +6 -135
- package/dist/server/runtime.js +0 -1
- package/dist/server/session.js +0 -28
- package/dist/server/settings.js +40 -246
- package/dist/server/signup-gate.js +0 -11
- package/dist/server/sweeps.js +0 -6
- package/dist/server/task-views.js +9 -227
- package/dist/server/tasks.js +5 -539
- package/dist/server/terminals.js +2 -46
- package/dist/server/welcome.js +2 -22
- package/dist/server-telemetry.js +0 -9
- package/dist/settings-groups-ui.js +50 -63
- package/dist/settings-kit-script.js +0 -19
- package/dist/settings-kit.js +0 -63
- package/dist/settings-proofs.js +0 -23
- package/dist/setup-guide.js +1 -9
- package/dist/shared-deps.js +9 -84
- package/dist/sign-in-guard.js +0 -27
- package/dist/skills-ui.js +0 -2
- package/dist/skills.js +2 -54
- package/dist/slack-api.js +0 -3
- package/dist/slack-chat.js +0 -25
- package/dist/slack-settings.js +0 -1
- package/dist/slack-socket.js +0 -5
- package/dist/slack.js +0 -4
- package/dist/sleep.js +0 -1
- package/dist/source-key.js +0 -10
- package/dist/spend-report.js +0 -29
- package/dist/spend-ui.js +0 -26
- package/dist/spend.js +0 -40
- package/dist/sqlite-runtime.js +0 -2
- package/dist/sqlite-telemetry.js +0 -9
- package/dist/sso-settings.js +0 -13
- package/dist/sso-ui.js +0 -2
- package/dist/staged-runtimes.js +5 -39
- package/dist/steer-capabilities.js +1 -7
- package/dist/steer-controls.js +0 -10
- package/dist/steer-live.js +0 -31
- package/dist/steer-mailbox.js +4 -65
- package/dist/steer-status.js +0 -7
- package/dist/stop-proof.js +5 -62
- package/dist/storage-sweep-child.js +1 -5
- package/dist/storage-sweep-process.js +2 -20
- package/dist/storage-sweep-schedule.js +0 -32
- package/dist/storage-sweep.js +2 -51
- package/dist/storage-ui.js +0 -18
- package/dist/storage.js +0 -31
- package/dist/store-baseline.js +0 -14
- package/dist/store.js +109 -4763
- package/dist/stream-scope.js +0 -16
- package/dist/structured-output.js +0 -39
- package/dist/style-asset.js +0 -2
- package/dist/subagent-admin.js +0 -9
- package/dist/subagent-desk.js +0 -29
- package/dist/subagent-memory.js +0 -38
- package/dist/subagent-question.js +0 -29
- package/dist/subagent-tools.js +1 -60
- package/dist/subagent-week.js +0 -28
- package/dist/subagent-work.js +1 -39
- package/dist/subagents-ui.js +1 -13
- package/dist/subagents.js +0 -40
- package/dist/subscription-chat.js +1 -42
- package/dist/summary.js +0 -19
- package/dist/surface.js +0 -75
- package/dist/sweep-gate.js +0 -2
- package/dist/sweep-quarantine.js +2 -13
- package/dist/sync.js +0 -47
- package/dist/tailnet.js +0 -9
- package/dist/tamper-scan.js +0 -15
- package/dist/task-activity.js +1 -16
- package/dist/task-aliases.js +0 -3
- package/dist/task-archive.js +0 -7
- package/dist/task-base.js +0 -18
- package/dist/task-composer.js +0 -2
- package/dist/task-control.js +0 -74
- package/dist/task-live.js +0 -23
- package/dist/task-moves.js +0 -28
- package/dist/task-outcome-cli.js +17 -28
- package/dist/task-review-brief.js +0 -7
- package/dist/task-sizing.js +0 -47
- package/dist/task-source.js +0 -23
- package/dist/task-status.js +0 -106
- package/dist/task-text.js +0 -12
- package/dist/team-chat-authorization.js +0 -3
- package/dist/team-contract.js +0 -2
- package/dist/team-http.js +0 -4
- package/dist/team-leads.js +1 -16
- package/dist/team-runtime.js +0 -13
- package/dist/team-ui.js +0 -1
- package/dist/team-updates.js +0 -4
- package/dist/teams-api.js +0 -12
- package/dist/teams-chat.js +0 -28
- package/dist/teams.js +0 -12
- package/dist/teardown-git.js +6 -294
- package/dist/telegram-flow.js +0 -51
- package/dist/telegram-lead.js +2 -203
- package/dist/telegram-live.js +1 -42
- package/dist/telegram-progress.js +0 -18
- package/dist/telegram-settings.js +0 -7
- package/dist/telegram-status.js +0 -46
- package/dist/telegram-team.js +1 -33
- package/dist/telegram.js +6 -454
- package/dist/templates.js +0 -24
- package/dist/terminal-catalog.js +2 -20
- package/dist/terminal-text.js +0 -12
- package/dist/test-infra.js +0 -50
- package/dist/test-temp.js +3 -26
- package/dist/text-limits.js +0 -92
- package/dist/tidy.js +0 -76
- package/dist/tier-report.js +0 -2
- package/dist/token-notices.js +1 -9
- package/dist/tokens-cli.js +0 -13
- package/dist/tool-broker.js +2 -53
- package/dist/tool-launcher.js +0 -14
- package/dist/tool-secret-store.js +3 -125
- package/dist/toolroll-update-cli.js +0 -9
- package/dist/toolroll-update-ui.js +0 -14
- package/dist/toolroll-update.js +13 -252
- package/dist/tools-ui.js +0 -17
- package/dist/transitions-recipes.js +0 -2
- package/dist/tree-proof.js +0 -23
- package/dist/tui-contract.js +0 -8
- package/dist/tui-source.js +16 -36
- package/dist/tui.js +1 -1
- package/dist/typed-start.js +0 -27
- package/dist/unfenced-test-support.js +0 -5
- package/dist/up-processes.js +1 -40
- package/dist/up-role-child.js +1 -13
- package/dist/update-notice.js +0 -1
- package/dist/vanished-retry.js +0 -40
- package/dist/verification-evidence.js +0 -39
- package/dist/version.js +0 -1
- package/dist/wake-hub.js +0 -28
- package/dist/webhook-limits.js +0 -7
- package/dist/webhook-readers.js +0 -30
- package/dist/webhook-signing.js +0 -14
- package/dist/webhooks.js +0 -54
- package/dist/welcome-facts.js +2 -14
- package/dist/when-html.js +0 -27
- package/dist/work-index.js +26 -98
- package/dist/work-summary.js +2 -17
- package/dist/workspace-motion.js +0 -2
- package/dist/workspace-revision.js +1 -21
- package/dist/workspace-ui.js +15 -135
- package/dist/worktree-notices.js +0 -3
- package/dist/worktree.js +0 -308
- package/dist/writes-mode.js +0 -1
- package/dist/youiyoux-intake.js +4 -159
- package/package.json +4 -3
- package/dist/accent-colors.d.ts +0 -51
- package/dist/acp-agents.d.ts +0 -43
- package/dist/acp-attest.d.ts +0 -44
- package/dist/acp-check.d.ts +0 -37
- package/dist/acp-client.d.ts +0 -163
- package/dist/acp-inspect.d.ts +0 -23
- package/dist/action-ledger.d.ts +0 -27
- package/dist/activity-line.d.ts +0 -29
- package/dist/actor.d.ts +0 -11
- package/dist/agent-board.d.ts +0 -229
- package/dist/agent-fence.d.ts +0 -479
- package/dist/agent-onboard.d.ts +0 -158
- package/dist/agent-pulse.d.ts +0 -43
- package/dist/agent-state-words.d.ts +0 -19
- package/dist/agent-state.d.ts +0 -65
- package/dist/agent-turns.d.ts +0 -52
- package/dist/agentconfig.d.ts +0 -191
- package/dist/agents-board.d.ts +0 -145
- package/dist/agents-live.d.ts +0 -31
- package/dist/api-tokens.d.ts +0 -80
- package/dist/approval-authority.d.ts +0 -51
- package/dist/approval-password.d.ts +0 -31
- package/dist/approval-policy.d.ts +0 -69
- package/dist/approval-rules-ui.d.ts +0 -40
- package/dist/assignment-adapters.d.ts +0 -152
- package/dist/assignment-brief.d.ts +0 -83
- package/dist/assignment-delivery.d.ts +0 -86
- package/dist/assignment-presentation.d.ts +0 -37
- package/dist/assignment-status.d.ts +0 -71
- package/dist/assignment-ui.d.ts +0 -68
- package/dist/assignment.d.ts +0 -350
- package/dist/attest.d.ts +0 -59
- package/dist/audit-cli.d.ts +0 -17
- package/dist/backend.d.ts +0 -97
- package/dist/backup-ui.d.ts +0 -32
- package/dist/backup.d.ts +0 -92
- package/dist/batch-checks.d.ts +0 -15
- package/dist/batch-policy.d.ts +0 -23
- package/dist/beads.d.ts +0 -34
- package/dist/bin.d.ts +0 -2
- package/dist/board.d.ts +0 -134
- package/dist/boot-identity.d.ts +0 -64
- package/dist/bounded-spawn.d.ts +0 -57
- package/dist/brand-icons.d.ts +0 -168
- package/dist/brand-mark.d.ts +0 -28
- package/dist/brief-fence.d.ts +0 -9
- package/dist/browser-crew.d.ts +0 -12
- package/dist/browser-shell.d.ts +0 -9
- package/dist/browser-workspace.d.ts +0 -1985
- package/dist/budget-alerts.d.ts +0 -19
- package/dist/build-review.d.ts +0 -38
- package/dist/builder-restart.d.ts +0 -21
- package/dist/builder.d.ts +0 -409
- package/dist/canonical-json.d.ts +0 -14
- package/dist/capscan.d.ts +0 -35
- package/dist/card-catalog.d.ts +0 -209
- package/dist/card-cli.d.ts +0 -43
- package/dist/card-render.d.ts +0 -43
- package/dist/card-sources.d.ts +0 -68
- package/dist/chat-acceptance.d.ts +0 -74
- package/dist/chat-actions.d.ts +0 -460
- package/dist/chat-admission.d.ts +0 -19
- package/dist/chat-approval.d.ts +0 -58
- package/dist/chat-ask.d.ts +0 -32
- package/dist/chat-card-part.d.ts +0 -11
- package/dist/chat-card.d.ts +0 -46
- package/dist/chat-channel.d.ts +0 -126
- package/dist/chat-continuity.d.ts +0 -32
- package/dist/chat-controls.d.ts +0 -117
- package/dist/chat-core.d.ts +0 -177
- package/dist/chat-decide.d.ts +0 -269
- package/dist/chat-delivery-state.d.ts +0 -132
- package/dist/chat-delivery.d.ts +0 -71
- package/dist/chat-display.d.ts +0 -1
- package/dist/chat-evidence.d.ts +0 -123
- package/dist/chat-flow.d.ts +0 -70
- package/dist/chat-follow.d.ts +0 -20
- package/dist/chat-inbox.d.ts +0 -57
- package/dist/chat-live-schema.d.ts +0 -17
- package/dist/chat-live.d.ts +0 -161
- package/dist/chat-message-states.d.ts +0 -75
- package/dist/chat-messages.d.ts +0 -338
- package/dist/chat-migration.d.ts +0 -30
- package/dist/chat-polish.d.ts +0 -17
- package/dist/chat-quiet.d.ts +0 -40
- package/dist/chat-review.d.ts +0 -51
- package/dist/chat-rooms.d.ts +0 -123
- package/dist/chat-settings-page.d.ts +0 -43
- package/dist/chat-task-actions.d.ts +0 -59
- package/dist/chat-terms.d.ts +0 -29
- package/dist/chat-voice.d.ts +0 -69
- package/dist/chat-warmth.d.ts +0 -21
- package/dist/check-access.d.ts +0 -54
- package/dist/check-facts.d.ts +0 -126
- package/dist/check-failure.d.ts +0 -113
- package/dist/check-levels-ui.d.ts +0 -36
- package/dist/check-levels.d.ts +0 -70
- package/dist/check-load.d.ts +0 -85
- package/dist/check-only-standing.d.ts +0 -36
- package/dist/check-only.d.ts +0 -15
- package/dist/check-progress.d.ts +0 -78
- package/dist/check-repair.d.ts +0 -47
- package/dist/check-report.d.ts +0 -177
- package/dist/check-stamp.d.ts +0 -46
- package/dist/checkout-cleanup.d.ts +0 -157
- package/dist/checkout-proof.d.ts +0 -28
- package/dist/child-database.d.ts +0 -12
- package/dist/claim.d.ts +0 -627
- package/dist/claude-print.d.ts +0 -12
- package/dist/cli-fast.d.ts +0 -8
- package/dist/cli-help.d.ts +0 -8
- package/dist/cli-http.d.ts +0 -58
- package/dist/cli.d.ts +0 -149
- package/dist/code-extract.d.ts +0 -44
- package/dist/code-map-acts.d.ts +0 -24
- package/dist/code-map-admission.d.ts +0 -52
- package/dist/code-map-build.d.ts +0 -63
- package/dist/code-map-cli.d.ts +0 -153
- package/dist/code-map-main.d.ts +0 -1
- package/dist/code-map-read.d.ts +0 -106
- package/dist/code-map-report.d.ts +0 -37
- package/dist/code-map-shape.d.ts +0 -172
- package/dist/code-map-store.d.ts +0 -136
- package/dist/codex-limits.d.ts +0 -15
- package/dist/coding-context.d.ts +0 -18
- package/dist/coding-handoff.d.ts +0 -39
- package/dist/coding-provider.d.ts +0 -88
- package/dist/coding-shipping-ui.d.ts +0 -5
- package/dist/coding-types.d.ts +0 -16
- package/dist/coding-ui.d.ts +0 -19
- package/dist/coding-update.d.ts +0 -28
- package/dist/coding-workspace.d.ts +0 -141
- package/dist/commit-extract.d.ts +0 -135
- package/dist/connect-cli.d.ts +0 -34
- package/dist/console-chrome.d.ts +0 -41
- package/dist/console-instance.d.ts +0 -157
- package/dist/container-state.d.ts +0 -5
- package/dist/containment.d.ts +0 -205
- package/dist/contract-changes.d.ts +0 -52
- package/dist/contracts/acceptance-terms.d.ts +0 -14
- package/dist/contracts/chat-actions.d.ts +0 -465
- package/dist/contracts/chat-callback-rows.d.ts +0 -59
- package/dist/contracts/chat-card.d.ts +0 -91
- package/dist/contracts/chat-content.d.ts +0 -551
- package/dist/contracts/chat-tables.d.ts +0 -12
- package/dist/contracts/cli.d.ts +0 -987
- package/dist/contracts/coding-activity.d.ts +0 -64
- package/dist/contracts/coding-context.d.ts +0 -97
- package/dist/contracts/coding-handoff.d.ts +0 -44
- package/dist/contracts/coding-workspace.d.ts +0 -165
- package/dist/contracts/console-api.d.ts +0 -540
- package/dist/contracts/contract-test.d.ts +0 -45
- package/dist/contracts/contract.d.ts +0 -92
- package/dist/contracts/decision.d.ts +0 -45
- package/dist/contracts/diff-stat.d.ts +0 -58
- package/dist/contracts/discord-callback.d.ts +0 -45
- package/dist/contracts/flow-card.d.ts +0 -53
- package/dist/contracts/flow-propose.d.ts +0 -334
- package/dist/contracts/flow-send.d.ts +0 -245
- package/dist/contracts/flow.d.ts +0 -19565
- package/dist/contracts/gateway-tools.d.ts +0 -472
- package/dist/contracts/handoff.d.ts +0 -91
- package/dist/contracts/health.d.ts +0 -82
- package/dist/contracts/integration-metadata.d.ts +0 -100
- package/dist/contracts/lead-context.d.ts +0 -165
- package/dist/contracts/lead-tools.d.ts +0 -2312
- package/dist/contracts/mcp-oauth.d.ts +0 -53
- package/dist/contracts/memory-pass.d.ts +0 -157
- package/dist/contracts/model-catalog.d.ts +0 -21
- package/dist/contracts/observation-request.d.ts +0 -37
- package/dist/contracts/plan.d.ts +0 -58
- package/dist/contracts/project-knowledge.d.ts +0 -159
- package/dist/contracts/project-memory.d.ts +0 -119
- package/dist/contracts/project-skills.d.ts +0 -120
- package/dist/contracts/proof.d.ts +0 -136
- package/dist/contracts/provider.d.ts +0 -40
- package/dist/contracts/recipes.d.ts +0 -166
- package/dist/contracts/release-check.d.ts +0 -371
- package/dist/contracts/release-terms.d.ts +0 -107
- package/dist/contracts/retention.d.ts +0 -42
- package/dist/contracts/review-findings.d.ts +0 -46
- package/dist/contracts/route-results.d.ts +0 -121
- package/dist/contracts/route.d.ts +0 -897
- package/dist/contracts/scope.d.ts +0 -105
- package/dist/contracts/scout-report.d.ts +0 -234
- package/dist/contracts/slack-callback.d.ts +0 -43
- package/dist/contracts/sort-answer.d.ts +0 -83
- package/dist/contracts/stage-output.d.ts +0 -127
- package/dist/contracts/storage.d.ts +0 -37
- package/dist/contracts/store-json.d.ts +0 -313
- package/dist/contracts/subagent-turn.d.ts +0 -43
- package/dist/contracts/task-sizing.d.ts +0 -24
- package/dist/contracts/teams-callback.d.ts +0 -13
- package/dist/contracts/telegram-callback.d.ts +0 -120
- package/dist/contracts/trigger-payloads.d.ts +0 -389
- package/dist/contracts/update-journal.d.ts +0 -254
- package/dist/contracts/verification-receipt.d.ts +0 -200
- package/dist/contracts/verification-view.d.ts +0 -102
- package/dist/contracts/youiyoux-request.d.ts +0 -248
- package/dist/control-setup.d.ts +0 -44
- package/dist/control-ui.d.ts +0 -37
- package/dist/controller-service.d.ts +0 -1
- package/dist/controller-supervisor.d.ts +0 -38
- package/dist/converse.d.ts +0 -316
- package/dist/coordinator-proposals.d.ts +0 -29
- package/dist/coordinator.d.ts +0 -186
- package/dist/credentials-ui.d.ts +0 -33
- package/dist/daemon.d.ts +0 -226
- package/dist/database-reclaim.d.ts +0 -4
- package/dist/decision.d.ts +0 -119
- package/dist/demo-chat.d.ts +0 -32
- package/dist/demo.d.ts +0 -153
- package/dist/deploy-gate.d.ts +0 -20
- package/dist/deploy-lock.d.ts +0 -8
- package/dist/deploy-phase.d.ts +0 -37
- package/dist/deploy-rescue.d.ts +0 -42
- package/dist/deprecations.d.ts +0 -20
- package/dist/design/kit.d.ts +0 -216
- package/dist/desktop-access.d.ts +0 -28
- package/dist/desktop-bundle.d.ts +0 -16
- package/dist/desktop-host.d.ts +0 -54
- package/dist/desktop-update-gate.d.ts +0 -12
- package/dist/desktop-update-recovery.d.ts +0 -14
- package/dist/desktop-update.d.ts +0 -147
- package/dist/digest-times.d.ts +0 -3
- package/dist/disclosure.d.ts +0 -6
- package/dist/discord-api.d.ts +0 -24
- package/dist/discord-chat.d.ts +0 -27
- package/dist/discord-settings.d.ts +0 -4
- package/dist/discord.d.ts +0 -10
- package/dist/discover.d.ts +0 -75
- package/dist/dispatch.d.ts +0 -123
- package/dist/dispose.d.ts +0 -194
- package/dist/doctor.d.ts +0 -67
- package/dist/easy-start-args.d.ts +0 -13
- package/dist/easy-start.d.ts +0 -77
- package/dist/egress.d.ts +0 -121
- package/dist/email-settings.d.ts +0 -34
- package/dist/envelope.d.ts +0 -47
- package/dist/eval-gate.d.ts +0 -51
- package/dist/eval-hooks.d.ts +0 -94
- package/dist/eval-oracle-main.d.ts +0 -1
- package/dist/eval-oracle.d.ts +0 -60
- package/dist/eval-world.d.ts +0 -17
- package/dist/evals.d.ts +0 -299
- package/dist/evidence-pack.d.ts +0 -186
- package/dist/evidence-pair.d.ts +0 -53
- package/dist/evidence.d.ts +0 -371
- package/dist/exec.d.ts +0 -355
- package/dist/exhaustion.d.ts +0 -58
- package/dist/export-ui.d.ts +0 -11
- package/dist/export.d.ts +0 -48
- package/dist/failing-first.d.ts +0 -31
- package/dist/fallback-schema.d.ts +0 -8
- package/dist/fallback.d.ts +0 -138
- package/dist/fast-start.d.ts +0 -213
- package/dist/fast-terms.d.ts +0 -9
- package/dist/fenced-check-coverage.d.ts +0 -62
- package/dist/findings.d.ts +0 -224
- package/dist/first-run.d.ts +0 -197
- package/dist/first-tasks-child.d.ts +0 -1
- package/dist/flaky-ci.d.ts +0 -31
- package/dist/flaky-cli.d.ts +0 -60
- package/dist/flaky.d.ts +0 -83
- package/dist/fleet-schema.d.ts +0 -17
- package/dist/flow-actions.d.ts +0 -79
- package/dist/flow-browser.d.ts +0 -103
- package/dist/flow-cadence.d.ts +0 -48
- package/dist/flow-card-task.d.ts +0 -11
- package/dist/flow-changed.d.ts +0 -14
- package/dist/flow-code.d.ts +0 -84
- package/dist/flow-draft.d.ts +0 -42
- package/dist/flow-engine.d.ts +0 -82
- package/dist/flow-gallery-ui.d.ts +0 -73
- package/dist/flow-gallery.d.ts +0 -147
- package/dist/flow-insights.d.ts +0 -104
- package/dist/flow-items.d.ts +0 -37
- package/dist/flow-live.d.ts +0 -16
- package/dist/flow-people.d.ts +0 -23
- package/dist/flow-pull-request.d.ts +0 -14
- package/dist/flow-replies.d.ts +0 -48
- package/dist/flow-result-card.d.ts +0 -22
- package/dist/flow-schedule.d.ts +0 -154
- package/dist/flow-scripts.d.ts +0 -31
- package/dist/flow-secrets.d.ts +0 -13
- package/dist/flow-send.d.ts +0 -54
- package/dist/flow-share.d.ts +0 -78
- package/dist/flow-sort.d.ts +0 -63
- package/dist/flow-starters-ui.d.ts +0 -15
- package/dist/flow-starters.d.ts +0 -63
- package/dist/flow-steps.d.ts +0 -52
- package/dist/flow-triggers.d.ts +0 -303
- package/dist/flow-unattended-words.d.ts +0 -48
- package/dist/flow-unattended.d.ts +0 -259
- package/dist/flows-cli.d.ts +0 -358
- package/dist/flows-ui.d.ts +0 -70
- package/dist/flows.d.ts +0 -136
- package/dist/folder-gate.d.ts +0 -32
- package/dist/folder-look.d.ts +0 -110
- package/dist/follow-through-brief.d.ts +0 -12
- package/dist/follow-through-cli.d.ts +0 -23
- package/dist/fonts.d.ts +0 -19
- package/dist/gaps.d.ts +0 -35
- package/dist/gate-failure.d.ts +0 -40
- package/dist/git-floor.d.ts +0 -16
- package/dist/git-incident.d.ts +0 -65
- package/dist/git-views.d.ts +0 -20
- package/dist/git.d.ts +0 -54
- package/dist/github-import.d.ts +0 -62
- package/dist/github-jobs.d.ts +0 -25
- package/dist/google-mail.d.ts +0 -59
- package/dist/grant.d.ts +0 -136
- package/dist/graph.d.ts +0 -164
- package/dist/guides.d.ts +0 -22
- package/dist/handover-note.d.ts +0 -33
- package/dist/health-cli.d.ts +0 -3
- package/dist/home-groups.d.ts +0 -39
- package/dist/html.d.ts +0 -85
- package/dist/install-method.d.ts +0 -17
- package/dist/integrations-ui.d.ts +0 -17
- package/dist/integrations.d.ts +0 -138
- package/dist/invoke.d.ts +0 -228
- package/dist/is-record.d.ts +0 -2
- package/dist/issues.d.ts +0 -41
- package/dist/jsonl-discriminants.d.ts +0 -11
- package/dist/keymap.d.ts +0 -43
- package/dist/keys.d.ts +0 -108
- package/dist/kits-ui.d.ts +0 -16
- package/dist/kits.d.ts +0 -88
- package/dist/knowledge-cli.d.ts +0 -132
- package/dist/knowledge-ui.d.ts +0 -45
- package/dist/landed-cleanup.d.ts +0 -175
- package/dist/laptop-background.d.ts +0 -187
- package/dist/laptop-service.d.ts +0 -111
- package/dist/latency-timeline.d.ts +0 -46
- package/dist/lead-about.d.ts +0 -35
- package/dist/lead-answer-eval.d.ts +0 -93
- package/dist/lead-capabilities.d.ts +0 -57
- package/dist/lead-cli-live.d.ts +0 -56
- package/dist/lead-cli.d.ts +0 -58
- package/dist/lead-commitments.d.ts +0 -84
- package/dist/lead-context.d.ts +0 -45
- package/dist/lead-contract.d.ts +0 -10
- package/dist/lead-doors.d.ts +0 -122
- package/dist/lead-follow.d.ts +0 -26
- package/dist/lead-identity.d.ts +0 -23
- package/dist/lead-latency-schema.d.ts +0 -24
- package/dist/lead-people.d.ts +0 -55
- package/dist/lead-progress.d.ts +0 -67
- package/dist/lead-queue-runtime.d.ts +0 -46
- package/dist/lead-queue.d.ts +0 -104
- package/dist/lead-route.d.ts +0 -56
- package/dist/lead-status.d.ts +0 -116
- package/dist/lead-sweep.d.ts +0 -67
- package/dist/lead-tools.d.ts +0 -167
- package/dist/lead-voice.d.ts +0 -85
- package/dist/lead.d.ts +0 -142
- package/dist/learning-child.d.ts +0 -1
- package/dist/learning-look.d.ts +0 -25
- package/dist/ledger-chain.d.ts +0 -46
- package/dist/ledger-csv.d.ts +0 -4
- package/dist/ledger-view.d.ts +0 -27
- package/dist/lesson-notes.d.ts +0 -81
- package/dist/limits-ui.d.ts +0 -34
- package/dist/link.d.ts +0 -72
- package/dist/live-backup.d.ts +0 -39
- package/dist/live-bus.d.ts +0 -141
- package/dist/live-children-read.d.ts +0 -52
- package/dist/live-children.d.ts +0 -73
- package/dist/live-detail.d.ts +0 -27
- package/dist/live-input.d.ts +0 -68
- package/dist/live-main-read.d.ts +0 -19
- package/dist/live-notes.d.ts +0 -20
- package/dist/live-open.d.ts +0 -28
- package/dist/live-records.d.ts +0 -149
- package/dist/live-reply.d.ts +0 -83
- package/dist/live-terminal.d.ts +0 -273
- package/dist/live.d.ts +0 -152
- package/dist/local-owner-acts.d.ts +0 -83
- package/dist/local-owner.d.ts +0 -135
- package/dist/log.d.ts +0 -7
- package/dist/login-secrets.d.ts +0 -60
- package/dist/machine-check.d.ts +0 -16
- package/dist/machine-identity.d.ts +0 -75
- package/dist/mailbox.d.ts +0 -57
- package/dist/maintenance.d.ts +0 -13
- package/dist/mcp-connect.d.ts +0 -181
- package/dist/mcp-core.d.ts +0 -110
- package/dist/mcp-http.d.ts +0 -32
- package/dist/mcp-oauth.d.ts +0 -92
- package/dist/mcp-person.d.ts +0 -22
- package/dist/mcp.d.ts +0 -20
- package/dist/memory-cli.d.ts +0 -768
- package/dist/memory-pass.d.ts +0 -151
- package/dist/memory-tidy.d.ts +0 -181
- package/dist/memory-use.d.ts +0 -35
- package/dist/merge-checklist.d.ts +0 -55
- package/dist/metrics.d.ts +0 -6
- package/dist/mobile-viewport.d.ts +0 -7
- package/dist/model-catalog.d.ts +0 -123
- package/dist/model-choices.d.ts +0 -235
- package/dist/model-names.d.ts +0 -6
- package/dist/models-cli.d.ts +0 -307
- package/dist/models-ui.d.ts +0 -161
- package/dist/modes.d.ts +0 -99
- package/dist/monitoring-settings.d.ts +0 -44
- package/dist/monitoring-ui.d.ts +0 -23
- package/dist/monitoring.d.ts +0 -34
- package/dist/names.d.ts +0 -67
- package/dist/needs-you.d.ts +0 -164
- package/dist/never-index.d.ts +0 -3
- package/dist/nightly-check.d.ts +0 -107
- package/dist/nightly-github.d.ts +0 -318
- package/dist/notification-delivery.d.ts +0 -19
- package/dist/notification-rows.d.ts +0 -30
- package/dist/oauth-run-token.d.ts +0 -51
- package/dist/observations.d.ts +0 -36
- package/dist/oidc.d.ts +0 -71
- package/dist/onboard.d.ts +0 -108
- package/dist/one-step-chat-schema.d.ts +0 -22
- package/dist/openrouter-models.d.ts +0 -34
- package/dist/operate-remote-arguments.d.ts +0 -36
- package/dist/operate-remote.d.ts +0 -98
- package/dist/operate.d.ts +0 -401
- package/dist/orphan-sweep.d.ts +0 -65
- package/dist/page-work-contract.d.ts +0 -21
- package/dist/password-bearer.d.ts +0 -25
- package/dist/passwordless.d.ts +0 -23
- package/dist/peek-cli.d.ts +0 -112
- package/dist/peek.d.ts +0 -110
- package/dist/people-audit-ui.d.ts +0 -16
- package/dist/person-proof.d.ts +0 -2
- package/dist/phase-routing.d.ts +0 -401
- package/dist/plain-schema.d.ts +0 -23
- package/dist/plain-words.d.ts +0 -20
- package/dist/plan-auto.d.ts +0 -25
- package/dist/plan-login.d.ts +0 -14
- package/dist/plan.d.ts +0 -188
- package/dist/plane-review.d.ts +0 -54
- package/dist/planner-source.d.ts +0 -225
- package/dist/planner.d.ts +0 -76
- package/dist/policy-ui.d.ts +0 -22
- package/dist/policy.d.ts +0 -92
- package/dist/prepared-evidence.d.ts +0 -17
- package/dist/principal.d.ts +0 -42
- package/dist/probe.d.ts +0 -46
- package/dist/process-custody.d.ts +0 -17
- package/dist/process-liveness.d.ts +0 -13
- package/dist/process-tree.d.ts +0 -39
- package/dist/project-access.d.ts +0 -17
- package/dist/project-activity.d.ts +0 -20
- package/dist/project-admission.d.ts +0 -105
- package/dist/project-cli.d.ts +0 -19
- package/dist/project-concurrency.d.ts +0 -62
- package/dist/project-delete-ui.d.ts +0 -96
- package/dist/project-delete.d.ts +0 -59
- package/dist/project-demo.d.ts +0 -12
- package/dist/project-file.d.ts +0 -3
- package/dist/project-identity.d.ts +0 -52
- package/dist/project-knowledge.d.ts +0 -124
- package/dist/project-learning.d.ts +0 -120
- package/dist/project-memory.d.ts +0 -70
- package/dist/project-outcomes.d.ts +0 -119
- package/dist/project-sandbox.d.ts +0 -59
- package/dist/project-skills.d.ts +0 -139
- package/dist/project-tools.d.ts +0 -318
- package/dist/project.d.ts +0 -65
- package/dist/prompt.d.ts +0 -33
- package/dist/proof.d.ts +0 -457
- package/dist/proposal.d.ts +0 -70
- package/dist/protected-storage-look.d.ts +0 -1
- package/dist/protected-storage.d.ts +0 -98
- package/dist/provider-auth.d.ts +0 -143
- package/dist/provider-capture.d.ts +0 -34
- package/dist/provider-connection.d.ts +0 -23
- package/dist/provider-home.d.ts +0 -22
- package/dist/provider-limits.d.ts +0 -37
- package/dist/provider.d.ts +0 -369
- package/dist/public-access.d.ts +0 -61
- package/dist/public-check.d.ts +0 -37
- package/dist/publish.d.ts +0 -146
- package/dist/pull-request-flow.d.ts +0 -189
- package/dist/pull-request-schema.d.ts +0 -5
- package/dist/pull-request-ui.d.ts +0 -25
- package/dist/pulls.d.ts +0 -121
- package/dist/push.d.ts +0 -120
- package/dist/quality.d.ts +0 -8
- package/dist/quick-start.d.ts +0 -26
- package/dist/read-executor-worker.d.ts +0 -1
- package/dist/read-executor.d.ts +0 -66
- package/dist/read-only-request.d.ts +0 -4
- package/dist/recipe-ui.d.ts +0 -21
- package/dist/recipes.d.ts +0 -56
- package/dist/release-adapters.d.ts +0 -205
- package/dist/release-approval.d.ts +0 -180
- package/dist/release-authority.d.ts +0 -173
- package/dist/release-auto.d.ts +0 -184
- package/dist/release-card.d.ts +0 -170
- package/dist/release-carry.d.ts +0 -261
- package/dist/release-ci-hold.d.ts +0 -41
- package/dist/release-cli.d.ts +0 -34
- package/dist/release-coverage.d.ts +0 -16
- package/dist/release-gate.d.ts +0 -84
- package/dist/release-git.d.ts +0 -43
- package/dist/release-links.d.ts +0 -29
- package/dist/release-net.d.ts +0 -90
- package/dist/release-next.d.ts +0 -48
- package/dist/release-recheck.d.ts +0 -146
- package/dist/release-refusal.d.ts +0 -32
- package/dist/release-view.d.ts +0 -37
- package/dist/release.d.ts +0 -806
- package/dist/releases.d.ts +0 -94
- package/dist/remote-audit.d.ts +0 -79
- package/dist/remote-command.d.ts +0 -45
- package/dist/remote-destination.d.ts +0 -36
- package/dist/remote-exec.d.ts +0 -38
- package/dist/remote-main.d.ts +0 -111
- package/dist/remote-run.d.ts +0 -20
- package/dist/remote.d.ts +0 -67
- package/dist/render.d.ts +0 -64
- package/dist/reply-shape.d.ts +0 -106
- package/dist/reply-voice.d.ts +0 -23
- package/dist/report-summary.d.ts +0 -22
- package/dist/reported-usage.d.ts +0 -69
- package/dist/repos.d.ts +0 -67
- package/dist/repository-context-ui.d.ts +0 -3
- package/dist/repository-context.d.ts +0 -66
- package/dist/request-budget-ui.d.ts +0 -14
- package/dist/request-budget.d.ts +0 -127
- package/dist/restart-certification.d.ts +0 -133
- package/dist/result-actions.d.ts +0 -36
- package/dist/result-acts.d.ts +0 -112
- package/dist/result-completion.d.ts +0 -39
- package/dist/result-evidence-readers.d.ts +0 -42
- package/dist/result-follow-ups.d.ts +0 -118
- package/dist/result-review.d.ts +0 -220
- package/dist/result-shots.d.ts +0 -59
- package/dist/retention-ui.d.ts +0 -21
- package/dist/retention.d.ts +0 -77
- package/dist/review-context.d.ts +0 -245
- package/dist/review-evidence.d.ts +0 -33
- package/dist/review-switch.d.ts +0 -36
- package/dist/reviewer.d.ts +0 -99
- package/dist/route-change-check.d.ts +0 -4
- package/dist/route-change.d.ts +0 -22
- package/dist/route-hooks.d.ts +0 -54
- package/dist/route-results.d.ts +0 -75
- package/dist/route-rules.d.ts +0 -324
- package/dist/route-savings.d.ts +0 -136
- package/dist/route-store.d.ts +0 -300
- package/dist/run-closeout.d.ts +0 -89
- package/dist/run-efficiency.d.ts +0 -74
- package/dist/run-ending.d.ts +0 -21
- package/dist/runner-process.d.ts +0 -76
- package/dist/runner.d.ts +0 -324
- package/dist/sample-project.d.ts +0 -31
- package/dist/sandbox-launch.d.ts +0 -1
- package/dist/sandbox-runtime.d.ts +0 -128
- package/dist/scan.d.ts +0 -32
- package/dist/scope.d.ts +0 -1098
- package/dist/scout-browser-lock.d.ts +0 -69
- package/dist/scout-browser.d.ts +0 -107
- package/dist/scout-net.d.ts +0 -25
- package/dist/scout-report.d.ts +0 -23
- package/dist/scout.d.ts +0 -142
- package/dist/secret-mint.d.ts +0 -1
- package/dist/serve.d.ts +0 -11
- package/dist/server/agents-computers.d.ts +0 -9
- package/dist/server/agents-live-filed.d.ts +0 -17
- package/dist/server/agents-live-lead.d.ts +0 -47
- package/dist/server/agents-live-room.d.ts +0 -23
- package/dist/server/chat.d.ts +0 -39
- package/dist/server/chrome.d.ts +0 -328
- package/dist/server/edge-refusal.d.ts +0 -7
- package/dist/server/flows.d.ts +0 -8
- package/dist/server/guards.d.ts +0 -81
- package/dist/server/handler-context.d.ts +0 -22
- package/dist/server/handler-registry.d.ts +0 -23
- package/dist/server/home-asks.d.ts +0 -45
- package/dist/server/home.d.ts +0 -65
- package/dist/server/http.d.ts +0 -337
- package/dist/server/in-place.d.ts +0 -15
- package/dist/server/kit-standalone.d.ts +0 -22
- package/dist/server/kit.d.ts +0 -452
- package/dist/server/last-checks.d.ts +0 -17
- package/dist/server/live.d.ts +0 -74
- package/dist/server/merge-ready-view.d.ts +0 -10
- package/dist/server/mutation-key.d.ts +0 -70
- package/dist/server/pages-assets.d.ts +0 -11
- package/dist/server/pages.d.ts +0 -8
- package/dist/server/people-tokens.d.ts +0 -18
- package/dist/server/remote-hooks.d.ts +0 -29
- package/dist/server/remote.d.ts +0 -60
- package/dist/server/render-chat.d.ts +0 -439
- package/dist/server/render-code-map.d.ts +0 -30
- package/dist/server/render-flaky.d.ts +0 -20
- package/dist/server/render-follow-through.d.ts +0 -11
- package/dist/server/render-history.d.ts +0 -51
- package/dist/server/render-new-task.d.ts +0 -54
- package/dist/server/render-pages.d.ts +0 -236
- package/dist/server/render-people.d.ts +0 -102
- package/dist/server/render-projects.d.ts +0 -104
- package/dist/server/render-release.d.ts +0 -19
- package/dist/server/render-results.d.ts +0 -758
- package/dist/server/render-settings.d.ts +0 -93
- package/dist/server/render-tasks.d.ts +0 -783
- package/dist/server/request-context.d.ts +0 -78
- package/dist/server/retired-routes.d.ts +0 -17
- package/dist/server/route-policy.d.ts +0 -18
- package/dist/server/route-table.d.ts +0 -114
- package/dist/server/runtime.d.ts +0 -343
- package/dist/server/session.d.ts +0 -192
- package/dist/server/settings.d.ts +0 -76
- package/dist/server/signup-gate.d.ts +0 -9
- package/dist/server/sweeps.d.ts +0 -4
- package/dist/server/task-views.d.ts +0 -98
- package/dist/server/tasks.d.ts +0 -108
- package/dist/server/terminals.d.ts +0 -31
- package/dist/server/welcome.d.ts +0 -28
- package/dist/server-telemetry.d.ts +0 -87
- package/dist/settings-groups-ui.d.ts +0 -286
- package/dist/settings-kit-script.d.ts +0 -21
- package/dist/settings-kit.d.ts +0 -173
- package/dist/settings-proofs.d.ts +0 -64
- package/dist/setup-guide.d.ts +0 -39
- package/dist/shared-deps.d.ts +0 -115
- package/dist/sign-in-guard.d.ts +0 -70
- package/dist/skills-ui.d.ts +0 -12
- package/dist/skills.d.ts +0 -99
- package/dist/slack-api.d.ts +0 -59
- package/dist/slack-chat.d.ts +0 -37
- package/dist/slack-settings.d.ts +0 -4
- package/dist/slack-socket.d.ts +0 -12
- package/dist/slack.d.ts +0 -6
- package/dist/sleep.d.ts +0 -2
- package/dist/source-key.d.ts +0 -2
- package/dist/spend-report.d.ts +0 -87
- package/dist/spend-ui.d.ts +0 -80
- package/dist/spend.d.ts +0 -142
- package/dist/sqlite-runtime.d.ts +0 -3
- package/dist/sqlite-telemetry.d.ts +0 -9
- package/dist/sso-settings.d.ts +0 -33
- package/dist/sso-ui.d.ts +0 -26
- package/dist/staged-runtimes.d.ts +0 -54
- package/dist/steer-capabilities.d.ts +0 -32
- package/dist/steer-controls.d.ts +0 -14
- package/dist/steer-live.d.ts +0 -19
- package/dist/steer-mailbox.d.ts +0 -46
- package/dist/steer-status.d.ts +0 -25
- package/dist/stop-proof.d.ts +0 -67
- package/dist/storage-sweep-child.d.ts +0 -1
- package/dist/storage-sweep-process.d.ts +0 -55
- package/dist/storage-sweep-schedule.d.ts +0 -30
- package/dist/storage-sweep.d.ts +0 -77
- package/dist/storage-ui.d.ts +0 -23
- package/dist/storage.d.ts +0 -68
- package/dist/store-baseline.d.ts +0 -19
- package/dist/store.d.ts +0 -8613
- package/dist/stream-scope.d.ts +0 -18
- package/dist/structured-output.d.ts +0 -57
- package/dist/style-asset.d.ts +0 -7
- package/dist/subagent-admin.d.ts +0 -53
- package/dist/subagent-desk.d.ts +0 -59
- package/dist/subagent-memory.d.ts +0 -65
- package/dist/subagent-question.d.ts +0 -59
- package/dist/subagent-tools.d.ts +0 -125
- package/dist/subagent-week.d.ts +0 -68
- package/dist/subagent-work.d.ts +0 -76
- package/dist/subagents-ui.d.ts +0 -22
- package/dist/subagents.d.ts +0 -146
- package/dist/subscription-chat.d.ts +0 -54
- package/dist/summary.d.ts +0 -33
- package/dist/surface.d.ts +0 -49
- package/dist/sweep-gate.d.ts +0 -10
- package/dist/sweep-quarantine.d.ts +0 -29
- package/dist/sync.d.ts +0 -94
- package/dist/tailnet.d.ts +0 -11
- package/dist/tamper-scan.d.ts +0 -4
- package/dist/task-activity.d.ts +0 -27
- package/dist/task-aliases.d.ts +0 -5
- package/dist/task-archive.d.ts +0 -13
- package/dist/task-base.d.ts +0 -39
- package/dist/task-composer.d.ts +0 -14
- package/dist/task-control.d.ts +0 -159
- package/dist/task-live.d.ts +0 -8
- package/dist/task-moves.d.ts +0 -90
- package/dist/task-outcome-cli.d.ts +0 -48
- package/dist/task-review-brief.d.ts +0 -69
- package/dist/task-sizing.d.ts +0 -58
- package/dist/task-source.d.ts +0 -77
- package/dist/task-status.d.ts +0 -324
- package/dist/task-text.d.ts +0 -31
- package/dist/team-chat-authorization.d.ts +0 -11
- package/dist/team-contract.d.ts +0 -103
- package/dist/team-http.d.ts +0 -25
- package/dist/team-leads.d.ts +0 -85
- package/dist/team-runtime.d.ts +0 -25
- package/dist/team-ui.d.ts +0 -4
- package/dist/team-updates.d.ts +0 -8
- package/dist/teams-api.d.ts +0 -33
- package/dist/teams-chat.d.ts +0 -36
- package/dist/teams-settings.d.ts +0 -14
- package/dist/teams.d.ts +0 -24
- package/dist/teardown-git.d.ts +0 -164
- package/dist/telegram-flow.d.ts +0 -112
- package/dist/telegram-lead.d.ts +0 -151
- package/dist/telegram-live.d.ts +0 -116
- package/dist/telegram-progress.d.ts +0 -20
- package/dist/telegram-settings.d.ts +0 -9
- package/dist/telegram-status.d.ts +0 -83
- package/dist/telegram-team.d.ts +0 -68
- package/dist/telegram.d.ts +0 -271
- package/dist/templates.d.ts +0 -69
- package/dist/terminal-catalog.d.ts +0 -11
- package/dist/terminal-text.d.ts +0 -11
- package/dist/test-infra.d.ts +0 -34
- package/dist/test-temp.d.ts +0 -40
- package/dist/text-limits.d.ts +0 -297
- package/dist/tidy.d.ts +0 -130
- package/dist/tier-report.d.ts +0 -44
- package/dist/token-notices.d.ts +0 -11
- package/dist/tokens-cli.d.ts +0 -21
- package/dist/tool-broker.d.ts +0 -52
- package/dist/tool-launcher.d.ts +0 -1
- package/dist/tool-secret-store.d.ts +0 -167
- package/dist/toolroll-update-cli.d.ts +0 -15
- package/dist/toolroll-update-ui.d.ts +0 -47
- package/dist/toolroll-update.d.ts +0 -265
- package/dist/tools-ui.d.ts +0 -51
- package/dist/transitions-recipes.d.ts +0 -1
- package/dist/tree-proof.d.ts +0 -34
- package/dist/tui-contract.d.ts +0 -202
- package/dist/tui-source.d.ts +0 -14
- package/dist/typed-start.d.ts +0 -51
- package/dist/unfenced-test-support.d.ts +0 -2
- package/dist/up-processes.d.ts +0 -162
- package/dist/up-role-child.d.ts +0 -1
- package/dist/update-notice.d.ts +0 -5
- package/dist/vanished-retry.d.ts +0 -30
- package/dist/verification-evidence.d.ts +0 -68
- package/dist/version.d.ts +0 -2
- package/dist/wake-hub.d.ts +0 -72
- package/dist/webhook-limits.d.ts +0 -23
- package/dist/webhook-readers.d.ts +0 -56
- package/dist/webhook-signing.d.ts +0 -27
- package/dist/webhooks.d.ts +0 -84
- package/dist/welcome-facts.d.ts +0 -18
- package/dist/when-html.d.ts +0 -40
- package/dist/work-index.d.ts +0 -175
- package/dist/work-summary.d.ts +0 -61
- package/dist/workspace-motion.d.ts +0 -4
- package/dist/workspace-revision.d.ts +0 -48
- package/dist/workspace-ui.d.ts +0 -385
- package/dist/worktree-notices.d.ts +0 -13
- package/dist/worktree.d.ts +0 -365
- package/dist/writes-mode.d.ts +0 -9
- package/dist/youiyoux-intake.d.ts +0 -234
package/dist/flow-triggers.js
CHANGED
|
@@ -1,35 +1,5 @@
|
|
|
1
1
|
import { adapterPolicy } from "./server/route-policy.js";
|
|
2
2
|
import { html, htmlString, postForm, styleElement } from "./html.js";
|
|
3
|
-
/**
|
|
4
|
-
* Flow triggers (v82): what starts cards in a flow without someone adding
|
|
5
|
-
* them by hand.
|
|
6
|
-
*
|
|
7
|
-
* - button — a named button with questions; pressing it makes a card from the answers.
|
|
8
|
-
* - schedule — a card on a schedule (every N minutes, daily, weekdays, weekly), or a standing order's task;
|
|
9
|
-
* v90: or a project script run on the schedule, each item it prints a card.
|
|
10
|
-
* - github — new issues (optionally with a label), new pull requests, or failed checks on a branch.
|
|
11
|
-
* - linear — Linear issues in a team, moving into a state, and/or with a label.
|
|
12
|
-
* - flow — another flow's cards reaching one of its zones.
|
|
13
|
-
* - webhook — anything that can post JSON to the trigger's secret address.
|
|
14
|
-
* - email — mail arriving in a folder of the account set up in Settings → Email (v89),
|
|
15
|
-
* read-only over IMAP; optionally only from some senders or with words in the subject.
|
|
16
|
-
* - chat — messages in a Slack, Discord or Teams channel (v89), connected from the
|
|
17
|
-
* channel itself (chat-inbox.ts), never from here.
|
|
18
|
-
* - plane-review — every day at a set time (07:30 in the computer's time zone unless it says),
|
|
19
|
-
* the plane's last 24 hours read straight from the store (plane-review.ts): one card
|
|
20
|
-
* per distinct problem worth fixing, and the same problem on a later day joins its
|
|
21
|
-
* card while that card is still open. A clean day makes nothing. Waits only a person
|
|
22
|
-
* can end make no card; ones over three days are mentioned once in its summary line,
|
|
23
|
-
* linked to Needs you. Its row is kept as a
|
|
24
|
-
* 'schedule' (the table's kinds are fixed); its settings say what it is.
|
|
25
|
-
*
|
|
26
|
-
* GitHub and Linear are checked by the worker's pass — `gh` and one HTTPS
|
|
27
|
-
* request, never a model — or pushed to a secret webhook address when the
|
|
28
|
-
* console has a public one. Either way one outside thing makes at most one
|
|
29
|
-
* card; outside text is checked for keys before it becomes a card; GitHub
|
|
30
|
-
* text from outside the team is left out unless the trigger says anyone;
|
|
31
|
-
* and a card's work is an ordinary task under the usual approvals.
|
|
32
|
-
*/
|
|
33
3
|
import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
34
4
|
import { readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
35
5
|
import { SecretStoreError, readHeldSecret, writeHeldSecret } from "./tool-secret-store.js";
|
|
@@ -55,25 +25,15 @@ import { isRecord } from "./is-record.js";
|
|
|
55
25
|
import { folderAnswers } from "./folder-gate.js";
|
|
56
26
|
export { FLOW_TRIGGER_KINDS };
|
|
57
27
|
export const CHAT_APP_NAMES = { slack: "Slack", discord: "Discord", teams: "Teams", telegram: "Telegram" };
|
|
58
|
-
/** What each kind is called on the canvas. */
|
|
59
28
|
export const FLOW_TRIGGER_WORDS = {
|
|
60
29
|
button: "Button", schedule: "Schedule", github: "GitHub", linear: "Linear", flow: "Another flow", webhook: "Webhook", email: "Email inbox", chat: "Chat channel", "plane-review": "Plane review",
|
|
61
30
|
};
|
|
62
|
-
/** How often the worker checks GitHub and Linear, and how it backs off when they don't answer. */
|
|
63
31
|
export const POLL_EVERY_MS = 2 * 60_000;
|
|
64
32
|
const BACKOFF_MS = [5 * 60_000, 15 * 60_000, 60 * 60_000];
|
|
65
|
-
/** At most this many cards from one check or one delivery; the rest wait for the next. */
|
|
66
33
|
export const CARDS_PER_CHECK = 10;
|
|
67
34
|
const HOOK_BYTES = 1_000_000;
|
|
68
|
-
/** Authors GitHub says have write access to the repository. */
|
|
69
35
|
const TEAM = new Set(["OWNER", "MEMBER", "COLLABORATOR"]);
|
|
70
|
-
// ------------------------------------------------------------ the terms
|
|
71
36
|
const HIDDEN = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f\u200b-\u200f\u202a-\u202e\u2066-\u2069]/;
|
|
72
|
-
/**
|
|
73
|
-
* A trigger's settings read by their one schema (`label: required`, `unknown key 'flows'`). A setting given as null is
|
|
74
|
-
* left out, and a button's blank question lines are dropped, as every release has read them. Then what the schema can't
|
|
75
|
-
* say, named by its path: no hidden characters and nothing that looks like a key, anywhere in the settings.
|
|
76
|
-
*/
|
|
77
37
|
export function readTriggerSettings(raw) {
|
|
78
38
|
const body = isRecord(raw) ? Object.fromEntries(Object.entries(raw).filter(([, value]) => value !== null).map(([key, value]) => [key, key === "questions" && Array.isArray(value) ? value.filter(one => typeof one !== "string" || one.trim() !== "") : value])) : raw;
|
|
79
39
|
const read = parseContract(triggerInputSchema, body, FLOW_ALIASES);
|
|
@@ -92,7 +52,6 @@ export function readTriggerSettings(raw) {
|
|
|
92
52
|
}
|
|
93
53
|
return read;
|
|
94
54
|
}
|
|
95
|
-
/** A schedule said in words ("every 2 hours", "daily 09:00 Europe/London", "monday 09:00") or in its stored form ("daily:09:00"). */
|
|
96
55
|
export function scheduleFromWords(text) {
|
|
97
56
|
const raw = text.trim().replace(/\s+/g, " ");
|
|
98
57
|
if (parseSchedule(raw) !== null)
|
|
@@ -123,9 +82,7 @@ export function scheduleFromWords(text) {
|
|
|
123
82
|
}
|
|
124
83
|
return null;
|
|
125
84
|
}
|
|
126
|
-
/** A GitHub repository as owner/name, read from a project's origin remote when it is on GitHub. */
|
|
127
85
|
export function githubRepoOf(path) {
|
|
128
|
-
// In the console, a folder that hasn't answered a look lately is not read on its thread (folder-gate.ts).
|
|
129
86
|
if (!folderAnswers(path))
|
|
130
87
|
return null;
|
|
131
88
|
try {
|
|
@@ -139,10 +96,7 @@ export function githubRepoOf(path) {
|
|
|
139
96
|
return null;
|
|
140
97
|
}
|
|
141
98
|
}
|
|
142
|
-
/** A trigger's settings, checked whole against the flow it starts cards in (readTriggerSettings, then the flow, its zones,
|
|
143
|
-
* the project's scripts and the schedule). Throws FlowContractError, each line naming its setting. */
|
|
144
99
|
export function validateTriggerConfig(raw, context) {
|
|
145
|
-
// Connecting a channel proves it's one the person is in: it happens in the channel, not here.
|
|
146
100
|
if (isRecord(raw) && raw["kind"] === "chat")
|
|
147
101
|
throw new FlowContractError([`kind: connect a chat channel from the channel itself: where Toolroll is in Slack, Discord, Teams or a Telegram group, send “flow ${context.flow.id}”`]);
|
|
148
102
|
const read = readTriggerSettings(raw);
|
|
@@ -150,7 +104,6 @@ export function validateTriggerConfig(raw, context) {
|
|
|
150
104
|
throw new FlowContractError(read.issues.map(one => one.line));
|
|
151
105
|
const input = read.value;
|
|
152
106
|
const refuse = (path, what) => { throw new FlowContractError([`${path}: ${what}`]); };
|
|
153
|
-
/** A setting's words, trimmed; blank is left out. */
|
|
154
107
|
const said = (value) => value === undefined || value.trim() === "" ? null : value.trim();
|
|
155
108
|
const named = said(input.zone);
|
|
156
109
|
const zoneStage = named === null ? null : context.definition.stages.find(one => one.id === named || one.title.toLowerCase() === named.toLowerCase());
|
|
@@ -170,7 +123,6 @@ export function validateTriggerConfig(raw, context) {
|
|
|
170
123
|
case "schedule": {
|
|
171
124
|
const said_ = said(input.schedule) ?? refuse("schedule", "required");
|
|
172
125
|
const schedule = scheduleFromWords(said_) ?? refuse("schedule", "say it like “every 2 hours”, “daily 09:00 Europe/London”, “weekdays 09:00” or “monday 09:00”");
|
|
173
|
-
// A script on a schedule (v90): each item it prints becomes a card.
|
|
174
126
|
const script = said(input.script);
|
|
175
127
|
if (script !== null) {
|
|
176
128
|
if (context.store.flowScript(context.flow.repo, script) === null)
|
|
@@ -216,8 +168,6 @@ export function validateTriggerConfig(raw, context) {
|
|
|
216
168
|
}
|
|
217
169
|
case "webhook":
|
|
218
170
|
{
|
|
219
|
-
// v126: Sentry and Vercel deliveries are read by their own readers, scoped by project (and Vercel's by team); the
|
|
220
|
-
// others pick their fields from the JSON by dot-paths. A setting that the sender doesn't read is refused, not kept.
|
|
221
171
|
const sender = input.sender ?? "none";
|
|
222
172
|
const provider = sender === "sentry" || sender === "vercel";
|
|
223
173
|
const project = said(input.project), team = said(input.team), idField = said(input.idField), urlField = said(input.urlField);
|
|
@@ -256,7 +206,6 @@ export function validateTriggerConfig(raw, context) {
|
|
|
256
206
|
}
|
|
257
207
|
}
|
|
258
208
|
}
|
|
259
|
-
/** The computer's time zone, as a schedule names one. */
|
|
260
209
|
function localTimeZone() {
|
|
261
210
|
try {
|
|
262
211
|
return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
@@ -265,11 +214,9 @@ function localTimeZone() {
|
|
|
265
214
|
return "UTC";
|
|
266
215
|
}
|
|
267
216
|
}
|
|
268
|
-
/** Addresses and domains from "priya@example.com, @shop.com, example.org". */
|
|
269
217
|
function sendersOf(text) {
|
|
270
218
|
return [...new Set(text.split(/[\s,;]+/).map(one => one.trim().toLowerCase().replace(/^@/, "")).filter(one => /^([a-z0-9._%+-]+@)?[a-z0-9-]+(\.[a-z0-9-]+)*\.[a-z]{2,}$/.test(one)))].slice(0, 20);
|
|
271
219
|
}
|
|
272
|
-
/** Whether an email is one this trigger takes: from a named sender (or domain), with the words in its subject. */
|
|
273
220
|
export function mailMatches(config, mail) {
|
|
274
221
|
const from = mail.from.toLowerCase();
|
|
275
222
|
const senders = config.sender === null ? [] : sendersOf(config.sender);
|
|
@@ -277,7 +224,6 @@ export function mailMatches(config, mail) {
|
|
|
277
224
|
return false;
|
|
278
225
|
return config.subject === null || mail.subject.toLowerCase().includes(config.subject.toLowerCase());
|
|
279
226
|
}
|
|
280
|
-
/** The trigger in the words the canvas and its cards use. */
|
|
281
227
|
export function describeTrigger(config, store) {
|
|
282
228
|
const from = (value) => value === "team" ? ", from people with write access" : ", from anyone";
|
|
283
229
|
const way = (delivery) => delivery === "poll" ? " (checked every 2 minutes)" : " (sent to its webhook address)";
|
|
@@ -286,7 +232,6 @@ export function describeTrigger(config, store) {
|
|
|
286
232
|
case "schedule": {
|
|
287
233
|
const schedule = parseSchedule(config.schedule);
|
|
288
234
|
const when = schedule === null ? config.schedule : describeSchedule(schedule);
|
|
289
|
-
// Its limits and terms are said once, in "What each run files" (describeStandingOrder).
|
|
290
235
|
if (config.order !== undefined)
|
|
291
236
|
return `${when.charAt(0).toUpperCase()}${when.slice(1)}: files the task “${config.title}”`;
|
|
292
237
|
return config.script !== undefined ? `${when.charAt(0).toUpperCase()}${when.slice(1)}: runs the ${config.script} script, and each item it prints becomes a card` : `${when.charAt(0).toUpperCase()}${when.slice(1)}: “${config.title}”`;
|
|
@@ -310,7 +255,6 @@ export function describeTrigger(config, store) {
|
|
|
310
255
|
case "email": return `Email arriving in ${config.folder === "INBOX" ? "the inbox" : config.folder}${config.sender === null ? "" : ` from ${config.sender}`}${config.subject === null ? "" : ` with “${config.subject}” in the subject`} (checked every 2 minutes)`;
|
|
311
256
|
}
|
|
312
257
|
}
|
|
313
|
-
/** The trigger in two short lines for the canvas: what it is, and the one detail that tells it apart. */
|
|
314
258
|
export function triggerHeadline(config, store) {
|
|
315
259
|
switch (config.kind) {
|
|
316
260
|
case "button": return { name: config.label, detail: `Asks ${config.questions.length} question${config.questions.length === 1 ? "" : "s"}` };
|
|
@@ -345,40 +289,31 @@ export function triggerConfigOf(trigger) {
|
|
|
345
289
|
const read = readTriggerConfig(raw);
|
|
346
290
|
return read.ok ? read.value : null;
|
|
347
291
|
}
|
|
348
|
-
/** What a saved trigger leaves out, it had as these (every release has saved them whole; a hand-made row may not). */
|
|
349
292
|
const SAVED_DEFAULTS = {
|
|
350
293
|
button: { questions: ["What needs doing?", "Details"] }, schedule: { description: null }, github: { label: null, branch: null, from: "team", delivery: "poll" },
|
|
351
294
|
linear: { team: null, state: null, label: null, delivery: "poll" }, webhook: { title: "Webhook", titleField: null, bodyField: null, sender: "none", project: null, team: null, idField: null, urlField: null }, email: { folder: "INBOX", sender: null, subject: null },
|
|
352
295
|
};
|
|
353
|
-
/** A saved trigger's config (`configJson`, which carries no version) read by its one schema, what it leaves out filled. */
|
|
354
296
|
export function readTriggerConfig(raw) {
|
|
355
297
|
const kind = isRecord(raw) ? raw["kind"] : undefined;
|
|
356
298
|
const body = isRecord(raw) ? { zone: null, ...SAVED_DEFAULTS[kind], ...raw } : raw;
|
|
357
299
|
return parseContract(triggerConfigSchema, body);
|
|
358
300
|
}
|
|
359
|
-
/** v126: what a webhook trigger takes, in words: what its sender sends it, or anything posted when it's unsigned. */
|
|
360
301
|
function webhookWords(config) {
|
|
361
302
|
const sender = senderOf(config);
|
|
362
303
|
const scope = config.project == null ? "" : ` from ${config.project}`;
|
|
363
304
|
return sender === "sentry" ? `Sentry issue alerts and new issues${scope}` : sender === "vercel" ? `Failed Vercel deployments${scope}`
|
|
364
305
|
: sender === "none" ? "Anything posted to its webhook address" : `Requests signed ${sender === "standard" ? "the Standard Webhooks way" : "GitHub-style"} to its webhook address`;
|
|
365
306
|
}
|
|
366
|
-
/** v126: who signs a webhook trigger's deliveries; one saved before senders were chosen is unsigned. */
|
|
367
307
|
export const senderOf = (config) => config.sender ?? "none";
|
|
368
|
-
/** Whether this trigger takes deliveries at a secret address rather than being checked. */
|
|
369
|
-
/** Whether a raw trigger the caller is about to add would take deliveries (an address): read leniently, before validation. */
|
|
370
308
|
export function rawTakesDeliveries(raw) {
|
|
371
309
|
if (raw === null || typeof raw !== "object")
|
|
372
310
|
return false;
|
|
373
311
|
const one = raw;
|
|
374
312
|
return one["kind"] === "webhook" || ((one["kind"] === "github" || one["kind"] === "linear") && one["delivery"] === "webhook");
|
|
375
313
|
}
|
|
376
|
-
/** Whether a trigger brings in items from anyone (chat-management.md §0a.3): GitHub issues or pull requests from anyone,
|
|
377
|
-
* or mail from any sender. A widening: it takes a person's password, on every road that adds one. */
|
|
378
314
|
export function admitsAnyone(config) {
|
|
379
315
|
return (config.kind === "github" && config.from === "anyone") || (config.kind === "email" && config.sender === null);
|
|
380
316
|
}
|
|
381
|
-
/** The same, read leniently from a raw trigger before validation (so the form can ask for the password first). */
|
|
382
317
|
export function rawAdmitsAnyone(raw) {
|
|
383
318
|
if (raw === null || typeof raw !== "object")
|
|
384
319
|
return false;
|
|
@@ -388,26 +323,16 @@ export function rawAdmitsAnyone(raw) {
|
|
|
388
323
|
export function takesDeliveries(config) {
|
|
389
324
|
return config.kind === "webhook" || ((config.kind === "github" || config.kind === "linear") && config.delivery === "webhook");
|
|
390
325
|
}
|
|
391
|
-
// ------------------------------------------------------ secrets on disk
|
|
392
326
|
const hookHash = (token) => createHash("sha256").update(token).digest("hex");
|
|
393
|
-
/**
|
|
394
|
-
* A webhook's signing secret: kept by Toolroll (tool-secret-store.ts) as `flow-hook.<trigger>`, in a file of that name
|
|
395
|
-
* before. v126: each secret has its own address, named by an id made for the one change that writes it, so no two
|
|
396
|
-
* changes ever write the same place; the trigger points at it (flow_trigger.hook_credential) only once it is whole.
|
|
397
|
-
* "legacy" is the address every secret saved before v126 has, so those keep authenticating with nothing moved; ""
|
|
398
|
-
* (or an id that isn't one) has no address at all.
|
|
399
|
-
*/
|
|
400
327
|
const hookSecret = (trigger, credential) => credential === "legacy"
|
|
401
328
|
? { name: `flow-hook.${trigger}`, file: ["flow-hooks", `${trigger}.json`] }
|
|
402
329
|
: /^[0-9a-f]{32}$/.test(credential) ? { name: `flow-hook.${trigger}.${credential}`, file: ["flow-hooks", `${trigger}.${credential}.json`] } : null;
|
|
403
|
-
/** A webhook's signing secret (made here, or pasted from its sender). In the keychain (or an owner-only file where there's none), never a column. */
|
|
404
330
|
export function saveHookSecret(dir, trigger, secret, credential = "legacy") {
|
|
405
331
|
const held = hookSecret(trigger, credential);
|
|
406
332
|
if (held === null)
|
|
407
333
|
throw new Error("not a credential id");
|
|
408
334
|
writeHeldSecret(dir, held.name, held.file, `${JSON.stringify({ secret })}\n`);
|
|
409
335
|
}
|
|
410
|
-
/** Exactly this credential's secret, or null: never another's. */
|
|
411
336
|
export function readHookSecret(dir, trigger, credential = "legacy") {
|
|
412
337
|
const held = hookSecret(trigger, credential);
|
|
413
338
|
if (held === null)
|
|
@@ -420,7 +345,6 @@ export function readHookSecret(dir, trigger, credential = "legacy") {
|
|
|
420
345
|
return null;
|
|
421
346
|
}
|
|
422
347
|
}
|
|
423
|
-
/** Cleanup only: a secret no trigger points at is never read, whether or not its file is gone. */
|
|
424
348
|
function dropHookSecret(dir, trigger, credential) {
|
|
425
349
|
const held = hookSecret(trigger, credential);
|
|
426
350
|
if (held === null)
|
|
@@ -428,10 +352,9 @@ function dropHookSecret(dir, trigger, credential) {
|
|
|
428
352
|
try {
|
|
429
353
|
writeHeldSecret(dir, held.name, held.file, null);
|
|
430
354
|
}
|
|
431
|
-
catch {
|
|
355
|
+
catch { }
|
|
432
356
|
}
|
|
433
357
|
const LINEAR = { name: "linear-key", file: ["linear-key"] };
|
|
434
|
-
/** The Linear API key the worker checks Linear with: the environment, or kept by Toolroll (the keychain, or an owner-only file beside the database). */
|
|
435
358
|
export function readLinearKey(dir) {
|
|
436
359
|
const env = envValue(process.env, "LINEAR_KEY")?.trim();
|
|
437
360
|
if (env)
|
|
@@ -460,7 +383,6 @@ export function saveLinearKey(dir, key) {
|
|
|
460
383
|
}
|
|
461
384
|
export function removeLinearKey(dir) { writeHeldSecret(dir, LINEAR.name, LINEAR.file, null); }
|
|
462
385
|
const HOOKS_FILE = "hooks-url";
|
|
463
|
-
/** The public address webhooks reach this console at (a reverse proxy such as Caddy, exposing /hooks/ only). */
|
|
464
386
|
export function readHooksBase(dir) {
|
|
465
387
|
if (dir === null)
|
|
466
388
|
return null;
|
|
@@ -491,12 +413,6 @@ export function saveHooksBase(dir, value) {
|
|
|
491
413
|
return { ok: true, base: readHooksBase(dir) };
|
|
492
414
|
}
|
|
493
415
|
export const HOOK_PATH = "/hooks/flow/";
|
|
494
|
-
/** Add a trigger to a flow. A webhook trigger's address (and GitHub's signing secret) is returned once and never stored readable. */
|
|
495
|
-
/**
|
|
496
|
-
* `ingress: "proved"`: the caller proved a password typed now (a credential act, docs/plans/passwordless.md) — only then
|
|
497
|
-
* may a trigger that takes deliveries be made with an address. Without it a webhook is made with none (its panel's
|
|
498
|
-
* set-up, which asks for the password, makes one), and GitHub/Linear webhook delivery is refused.
|
|
499
|
-
*/
|
|
500
416
|
export function addFlowTriggerTo(store, flow, raw, actor, now, dir, options = {}) {
|
|
501
417
|
const definition = flowDefinitionOf(flow);
|
|
502
418
|
if (definition === null || flow.state !== "active")
|
|
@@ -512,19 +428,13 @@ export function addFlowTriggerTo(store, flow, raw, actor, now, dir, options = {}
|
|
|
512
428
|
return { ok: false, message: "Webhook addresses are set up on the console." };
|
|
513
429
|
if (takesDeliveries(config) && config.kind !== "webhook" && options.ingress !== "proved")
|
|
514
430
|
return { ok: false, message: "Webhook delivery is set up on the flow's trigger panel, with your password." };
|
|
515
|
-
// Items from anyone come in only on a person's proof (chat-management.md §0a.3): never from a card, an import or a template alone.
|
|
516
431
|
if (admitsAnyone(config) && options.ingress !== "proved" && options.widening !== "proved")
|
|
517
432
|
return { ok: false, message: "A trigger that brings in items from anyone takes your password. Add it on the flow's Triggers panel." };
|
|
518
|
-
// v126: a webhook made where no one is shown its address (the gallery, an import) is made with none: its first
|
|
519
|
-
// set-up or New address makes one and shows it. A webhook made on its panel is shown its address now.
|
|
520
433
|
const token = takesDeliveries(config) && options.ingress === "proved" && (options.shown !== false || config.kind !== "webhook") ? randomBytes(24).toString("base64url") : null;
|
|
521
434
|
const schedule = config.kind === "schedule" || config.kind === "plane-review" ? parseSchedule(config.schedule) : null;
|
|
522
435
|
const id = store.addFlowTrigger({
|
|
523
|
-
// The table's kinds were fixed before plane reviews: one is kept as the daily schedule it is.
|
|
524
436
|
flow: flow.id, kind: config.kind === "plane-review" ? "schedule" : config.kind, configJson: JSON.stringify(config), hookHash: token === null ? null : hookHash(token),
|
|
525
|
-
// Only what happens from now on: never the backlog of issues, runs or finished cards.
|
|
526
437
|
cursor: config.kind === "flow" ? String(store.latestFlowEvent()) : config.kind === "github" || config.kind === "linear" ? now.toISOString() : null,
|
|
527
|
-
// Email: the first check notes where the mailbox stands (no cursor yet), so only mail after this becomes cards.
|
|
528
438
|
nextAt: schedule !== null ? firstFireAt(schedule, now) : polled(config) ? now.toISOString() : null,
|
|
529
439
|
by: actor,
|
|
530
440
|
}, now);
|
|
@@ -533,22 +443,17 @@ export function addFlowTriggerTo(store, flow, raw, actor, now, dir, options = {}
|
|
|
533
443
|
secret = randomBytes(24).toString("hex");
|
|
534
444
|
saveHookSecret(dir, id, secret);
|
|
535
445
|
}
|
|
536
|
-
// v126: a webhook starts with no secret at all (not the legacy address): it is set up on its panel, never here.
|
|
537
446
|
if (config.kind === "webhook")
|
|
538
447
|
store.swapFlowHookCredential(id, { credential: "legacy", configJson: JSON.stringify(config), hookHash: token === null ? null : hookHash(token) }, { credential: "" }, null, now);
|
|
539
448
|
const reveal = token === null ? null : { path: `${HOOK_PATH}${token}`, address: dir === null || readHooksBase(dir) === null ? null : `${readHooksBase(dir)}${HOOK_PATH}${token}`, secret };
|
|
540
449
|
return { ok: true, id, said: token === null ? "Trigger added." : "Trigger added. Copy its address now; it isn't shown again.", reveal };
|
|
541
450
|
}
|
|
542
|
-
/** A new secret address for a webhook trigger (the old one stops working at once). */
|
|
543
451
|
export function renewFlowHook(store, trigger, now, dir) {
|
|
544
452
|
const config = triggerConfigOf(trigger);
|
|
545
453
|
if (config === null || !takesDeliveries(config) || trigger.state === "removed")
|
|
546
454
|
return { ok: false, message: "That trigger has no webhook address." };
|
|
547
455
|
const token = randomBytes(24).toString("base64url");
|
|
548
456
|
let secret = null;
|
|
549
|
-
// GitHub's own trigger gets a new secret with its new address (as it always has); a webhook keeps its secret. Either
|
|
550
|
-
// way the address moves in one conditional write with the secret it is proven by, from the pair read here: a renewal
|
|
551
|
-
// that fails (or loses to another) leaves the working address and its secret exactly as they were.
|
|
552
457
|
if (config.kind === "github") {
|
|
553
458
|
secret = randomBytes(24).toString("hex");
|
|
554
459
|
const saved = nextHookCredential(store, trigger, secret, null, now, dir, hookHash(token));
|
|
@@ -561,10 +466,6 @@ export function renewFlowHook(store, trigger, now, dir) {
|
|
|
561
466
|
const base = readHooksBase(dir);
|
|
562
467
|
return { ok: true, id: trigger.id, said: "New address made; the old one no longer works. Copy it now; it isn't shown again.", reveal: { path: `${HOOK_PATH}${token}`, address: base === null ? null : `${base}${HOOK_PATH}${token}`, secret } };
|
|
563
468
|
}
|
|
564
|
-
/**
|
|
565
|
-
* Pause a trigger, or turn it on again. A schedule that never had a time (a routine moved to a flow while it waited
|
|
566
|
-
* for approval, v115) starts counting from now, as a new schedule does; one that was due while it was off fires once.
|
|
567
|
-
*/
|
|
568
469
|
export function setFlowTriggerOn(store, trigger, on, now, by) {
|
|
569
470
|
const config = on && trigger.nextAt === null ? triggerConfigOf(trigger) : null;
|
|
570
471
|
const schedule = config !== null && (config.kind === "schedule" || config.kind === "plane-review") ? parseSchedule(config.schedule) : null;
|
|
@@ -575,20 +476,17 @@ export function removeFlowTrigger(store, trigger, now, dir, by) {
|
|
|
575
476
|
if (dir !== null)
|
|
576
477
|
dropHookSecret(dir, trigger.id, trigger.hookCredential);
|
|
577
478
|
}
|
|
578
|
-
/** Checked by the worker's pass (rather than pushed, fired on a schedule or followed). */
|
|
579
479
|
function polled(config) {
|
|
580
480
|
return config.kind === "email" || ((config.kind === "github" || config.kind === "linear") && config.delivery === "poll");
|
|
581
481
|
}
|
|
582
482
|
function startZone(config, definition) {
|
|
583
483
|
return config.zone !== null && definition.stages.some(one => one.id === config.zone) ? config.zone : definition.start;
|
|
584
484
|
}
|
|
585
|
-
/** The active flow that already made a card for this failing commit in a project, if any. */
|
|
586
485
|
function checksCardOf(store, repo, key) {
|
|
587
486
|
const row = store.handle.prepare(`SELECT f.name FROM flow_trigger_event e JOIN flow_trigger t ON t.id = e.trigger JOIN flow f ON f.id = t.flow
|
|
588
487
|
WHERE f.repo = ? AND f.state = 'active' AND e.key = ? AND e.card IS NOT NULL LIMIT 1`).get(repo, key);
|
|
589
488
|
return row === undefined ? null : `“${String(row["name"])}”`;
|
|
590
489
|
}
|
|
591
|
-
/** One outside thing into one card, at most once per trigger (a failing run, once per project). Keys and control characters never reach a card. */
|
|
592
490
|
function makeCard(store, trigger, config, item, by, now, byKind = "automation") {
|
|
593
491
|
const flow = store.getFlow(trigger.flow);
|
|
594
492
|
const definition = flow === null ? null : flowDefinitionOf(flow);
|
|
@@ -602,11 +500,9 @@ function makeCard(store, trigger, config, item, by, now, byKind = "automation")
|
|
|
602
500
|
store.recordFlowTriggerEvent(trigger.id, item.key, null, note, now);
|
|
603
501
|
return { made: "skipped", note: `${item.source.label}: ${note}`, card: null };
|
|
604
502
|
}
|
|
605
|
-
// Claimed inside the write lock: a worker and a console (or an old and a new worker) checking at once make one card.
|
|
606
503
|
return store.transact(() => {
|
|
607
504
|
if (store.flowTriggerSaw(trigger.id, item.key))
|
|
608
505
|
return { made: "seen", note: null, card: null };
|
|
609
|
-
// One failing run is one fix: a second trigger watching the same checks in this project leaves it to the first.
|
|
610
506
|
const filed = item.key.startsWith("checks:") ? checksCardOf(store, flow.repo, item.key) : null;
|
|
611
507
|
if (filed !== null) {
|
|
612
508
|
const note = `already a card in ${filed}`;
|
|
@@ -618,11 +514,6 @@ function makeCard(store, trigger, config, item, by, now, byKind = "automation")
|
|
|
618
514
|
return { made: "added", note: null, card };
|
|
619
515
|
});
|
|
620
516
|
}
|
|
621
|
-
/**
|
|
622
|
-
* v115: a schedule with a standing order (what a routine was) files its task and the card that follows it, together or
|
|
623
|
-
* not at all; a slot it skips says why on the trigger. The card starts in the schedule's build step, which follows the
|
|
624
|
-
* task it was filed with.
|
|
625
|
-
*/
|
|
626
517
|
function fileOrderCard(store, trigger, config, order, item, slot, now) {
|
|
627
518
|
const flow = store.getFlow(trigger.flow);
|
|
628
519
|
const definition = flow === null ? null : flowDefinitionOf(flow);
|
|
@@ -647,7 +538,6 @@ function fileOrderCard(store, trigger, config, order, item, slot, now) {
|
|
|
647
538
|
}
|
|
648
539
|
const card = store.addFlowCard({ flow: flow.id, title: text.title, description: text.description, stage: zone, by: "Schedule", byKind: "automation", source: item.source }, now);
|
|
649
540
|
store.updateFlowCard(card, { task: fired.taskId, primaryTask: fired.taskId, waiting: "Filed as a task" }, now);
|
|
650
|
-
// The firing keeps its task: one-at-a-time and the weekly limit count it however the card moves later.
|
|
651
541
|
store.recordFlowTriggerEvent(trigger.id, item.key, card, null, now, fired.taskId);
|
|
652
542
|
return { made: "added", note: fired.note ?? (fired.approved ? `Filed ${fired.taskId}, approved.` : `Filed ${fired.taskId}; it waits for approval.`), card };
|
|
653
543
|
});
|
|
@@ -669,15 +559,12 @@ function outcomeWords(results, more) {
|
|
|
669
559
|
parts.push("More on the next check.");
|
|
670
560
|
return parts.join(" ");
|
|
671
561
|
}
|
|
672
|
-
/** One outside thing into one card through a trigger (a chat channel's message, v89): at most once per key. */
|
|
673
562
|
export function addTriggerCard(store, trigger, item, by, now) {
|
|
674
563
|
const config = triggerConfigOf(trigger);
|
|
675
564
|
if (config === null || trigger.state !== "active")
|
|
676
565
|
return { made: "skipped", note: "the trigger isn't active", card: null };
|
|
677
|
-
// A channel's message is the app's word for who sent it, not a signed-in account: automation (v126).
|
|
678
566
|
return makeCard(store, trigger, config, item, by, now, "automation");
|
|
679
567
|
}
|
|
680
|
-
/** Press a button trigger: the first answer is the card's title, the rest its details. */
|
|
681
568
|
export function pressFlowButton(store, trigger, answers, actor, now) {
|
|
682
569
|
const config = triggerConfigOf(trigger);
|
|
683
570
|
if (config?.kind !== "button" || trigger.state !== "active")
|
|
@@ -693,7 +580,6 @@ export function pressFlowButton(store, trigger, answers, actor, now) {
|
|
|
693
580
|
store.updateFlowTrigger(trigger.id, { lastAt: now.toISOString(), lastOutcome: `Pressed by ${actor}.` }, now);
|
|
694
581
|
return { ok: true, said: "Card added.", card: result.card };
|
|
695
582
|
}
|
|
696
|
-
/** Every trigger in one project that is due: schedules and other flows here, GitHub, Linear and email by asking them. */
|
|
697
583
|
export async function runFlowTriggers(store, repo, now, io) {
|
|
698
584
|
const pass = { added: 0, checked: 0, problems: [] };
|
|
699
585
|
const triggers = store.activeFlowTriggers(repo);
|
|
@@ -704,7 +590,6 @@ export async function runFlowTriggers(store, repo, now, io) {
|
|
|
704
590
|
if (config === null)
|
|
705
591
|
continue;
|
|
706
592
|
try {
|
|
707
|
-
// v126: deliveries held over the hourly limit become their cards as the hour makes room.
|
|
708
593
|
if (takesDeliveries(config))
|
|
709
594
|
pass.added += drainHeldDeliveries(store, trigger, now);
|
|
710
595
|
if (config.kind === "schedule" && config.script !== undefined && trigger.nextAt !== null && Date.parse(trigger.nextAt) <= now.getTime()) {
|
|
@@ -733,10 +618,8 @@ export async function runFlowTriggers(store, repo, now, io) {
|
|
|
733
618
|
}
|
|
734
619
|
return pass;
|
|
735
620
|
}
|
|
736
|
-
/** "Check now" on the canvas: one trigger, right away, in words. */
|
|
737
621
|
export async function checkFlowTriggerNow(store, trigger, now, io) {
|
|
738
622
|
const config = triggerConfigOf(trigger);
|
|
739
|
-
// A schedule's script runs now, once; its schedule stays as it is.
|
|
740
623
|
if (config?.kind === "schedule" && config.script !== undefined) {
|
|
741
624
|
const fired = await fireScript(store, trigger, config, now, io, false);
|
|
742
625
|
return { ok: fired.ok, said: fired.said };
|
|
@@ -756,12 +639,10 @@ function fireSchedule(store, trigger, config, now) {
|
|
|
756
639
|
return 0;
|
|
757
640
|
const slot = trigger.nextAt;
|
|
758
641
|
const next = nextFireAt(schedule, slot, now);
|
|
759
|
-
// One card at a time: while the last one still waits where it started, the slot is skipped, not piled up.
|
|
760
642
|
const last = config.order === undefined ? store.lastFlowTriggerCard(trigger.id) : null;
|
|
761
643
|
const card = last === null ? null : store.getFlowCard(last);
|
|
762
644
|
const flow = store.getFlow(trigger.flow);
|
|
763
645
|
const definition = flow === null ? null : flowDefinitionOf(flow);
|
|
764
|
-
// A standing order says itself when it waits (its last task unfinished); other schedules wait on their last card.
|
|
765
646
|
if (card !== null && definition !== null && card.state === "active" && card.stage === startZone(config, definition) && card.entry === 1) {
|
|
766
647
|
store.recordFlowTriggerEvent(trigger.id, `slot:${slot}`, null, "the last one hadn't been picked up", now);
|
|
767
648
|
store.updateFlowTrigger(trigger.id, { nextAt: next, lastAt: now.toISOString(), lastOutcome: "Skipped: the last card hasn't been picked up yet." }, now);
|
|
@@ -775,20 +656,12 @@ function fireSchedule(store, trigger, config, now) {
|
|
|
775
656
|
store.updateFlowTrigger(trigger.id, { nextAt: next, lastAt: now.toISOString(), lastOutcome: made.made === "added" ? made.note ?? "Added a card." : made.note ?? "Nothing new." }, now);
|
|
776
657
|
return made.made === "added" ? 1 : 0;
|
|
777
658
|
}
|
|
778
|
-
/** The problem a plane review's event key names, and the day: `plane:<problem>:<YYYY-MM-DD>`. */
|
|
779
659
|
const planeKey = (problem, day) => `plane:${problem}:${day}`;
|
|
780
|
-
/** The card a plane review last made or joined for one problem, if any. */
|
|
781
660
|
function planeCardOf(store, trigger, problem) {
|
|
782
661
|
const prefix = `plane:${problem}:`;
|
|
783
662
|
const row = store.handle.prepare("SELECT card FROM flow_trigger_event WHERE trigger = ? AND substr(key, 1, ?) = ? AND card IS NOT NULL ORDER BY rowid DESC LIMIT 1").get(trigger, prefix.length, prefix);
|
|
784
663
|
return row === undefined ? null : Number(row["card"]);
|
|
785
664
|
}
|
|
786
|
-
/**
|
|
787
|
-
* A plane review: the last 24 hours, one card per problem worth fixing. Each problem is noted once a day; a problem
|
|
788
|
-
* whose card is still open joins it (a note with the day's counts and evidence) instead of making another, and one
|
|
789
|
-
* whose card is finished starts a new card, since it came back. A clean day adds nothing and tells nobody.
|
|
790
|
-
* `scheduled` moves the trigger to its next morning; "Run now" leaves its times alone.
|
|
791
|
-
*/
|
|
792
665
|
export async function firePlaneReview(store, trigger, config, now, scheduled) {
|
|
793
666
|
const schedule = parseSchedule(config.schedule);
|
|
794
667
|
const next = scheduled && schedule !== null && trigger.nextAt !== null ? nextFireAt(schedule, trigger.nextAt, now) : trigger.nextAt;
|
|
@@ -799,13 +672,10 @@ export async function firePlaneReview(store, trigger, config, now, scheduled) {
|
|
|
799
672
|
};
|
|
800
673
|
if (flow === null || flow.state !== "active")
|
|
801
674
|
return done("The flow isn't active.");
|
|
802
|
-
// Loaded when a review first runs: the reader reaches the integrations and task status, which reach back to these triggers.
|
|
803
675
|
const { longPersonWaits, longWaitWords, problemCard, problemText, reviewPlane } = await import("./plane-review.js");
|
|
804
|
-
// Only the projects the flow's owner may see: a flow's cards are read by everyone on its project.
|
|
805
676
|
const owner = store.accountOf(flow.owner);
|
|
806
677
|
const canSee = (repo) => owner === null || (repo !== null && store.accountCanAccess(flow.owner, repo)) || (repo === null && owner.projects === null);
|
|
807
678
|
const problems = reviewPlane(store, now, canSee);
|
|
808
|
-
// Long waits on a person are said here once, linked to Needs you (planeStatusLink), and file nothing.
|
|
809
679
|
const waited = longWaitWords(longPersonWaits(store, now, canSee));
|
|
810
680
|
const said = (words) => waited === null ? words : `${words} ${waited}`;
|
|
811
681
|
const timeZone = schedule !== null && schedule.kind !== "every" ? schedule.timezone ?? "UTC" : "UTC";
|
|
@@ -840,13 +710,10 @@ export async function firePlaneReview(store, trigger, config, now, scheduled) {
|
|
|
840
710
|
skipped.length > 0 ? `Left out ${plural(skipped.length, "problem")}: ${skipped[0]}.` : null].filter(one => one !== null);
|
|
841
711
|
return done(said(parts.length === 0 ? "Nothing new since this morning's review." : parts.join(" ")), added, joined);
|
|
842
712
|
}
|
|
843
|
-
/** Where a person sees everything that waits on them. */
|
|
844
713
|
export const NEEDS_YOU_HREF = "/tasks?view=needs-you";
|
|
845
|
-
/** A plane review whose summary mentions long waits on a person links to Needs you. */
|
|
846
714
|
export function planeStatusLink(config, status) {
|
|
847
715
|
return config?.kind === "plane-review" && status !== null && /waited over \d+ days for you\.$/.test(status) ? { label: "Needs you", href: NEEDS_YOU_HREF } : null;
|
|
848
716
|
}
|
|
849
|
-
/** v96: a schedule (a subagent's routine) makes its card now, once per press, and keeps its own times. */
|
|
850
717
|
export function runScheduleNow(store, trigger, actor, now) {
|
|
851
718
|
const config = triggerConfigOf(trigger);
|
|
852
719
|
if (config?.kind !== "schedule" || config.script !== undefined)
|
|
@@ -860,7 +727,6 @@ export function runScheduleNow(store, trigger, actor, now) {
|
|
|
860
727
|
store.updateFlowTrigger(trigger.id, { lastAt: now.toISOString(), lastOutcome: `${made.note ?? "Added a card."} (run now)` }, now);
|
|
861
728
|
return { ok: true, card: made.card };
|
|
862
729
|
}
|
|
863
|
-
/** A schedule's script (v90): it runs in a clean folder inside the agents' fence; each item it prints is a card, once. */
|
|
864
730
|
async function fireScript(store, trigger, config, now, io, scheduled) {
|
|
865
731
|
const schedule = parseSchedule(config.schedule);
|
|
866
732
|
const next = scheduled && schedule !== null && trigger.nextAt !== null ? nextFireAt(schedule, trigger.nextAt, now) : trigger.nextAt;
|
|
@@ -878,15 +744,12 @@ async function fireScript(store, trigger, config, now, io, scheduled) {
|
|
|
878
744
|
const missing = (config.secrets ?? []).filter(name => saved[name] === undefined);
|
|
879
745
|
if (missing.length > 0)
|
|
880
746
|
return done(false, `${script.name} needs the secret${missing.length === 1 ? "" : "s"} ${missing.join(", ")}. Save ${missing.length === 1 ? "it" : "them"} on the flow first.`);
|
|
881
|
-
// Loaded when a script first runs: the runner reaches the builder's modules, which reach back to these triggers.
|
|
882
747
|
const { cardsFromOutput, cleanFolder, flowLaunch, runCode } = await import("./flow-code.js");
|
|
883
748
|
const scratch = io.scratch ?? join(io.dir ?? tmpdir(), "flow-scratch");
|
|
884
749
|
const folder = cleanFolder(scratch, `flow-trigger-${trigger.id}`);
|
|
885
|
-
// Its cards run on their own only if it ran the very code a grant signed: pinned just before and just after the run.
|
|
886
750
|
const pin = scheduled && grantSignsScriptOf(store, flow.id, trigger.id, now) ? () => scriptProvenanceOf(store, flow.repo, script.name) : null;
|
|
887
751
|
const before = pin === null ? null : await pin();
|
|
888
752
|
let ran;
|
|
889
|
-
// A full boundary around its clean folder, though it has no checkout (flow-code.ts flowLaunch).
|
|
890
753
|
const launch = await flowLaunch(store, { repo: flow.repo, folder, scratch, copy: false, policy: store.flowFencePolicy(flow.id), ...(io.fenceAvailable === undefined ? {} : { available: io.fenceAvailable }), ...(io.home === undefined ? {} : { home: io.home }) });
|
|
891
754
|
try {
|
|
892
755
|
if (launch !== null && "problem" in launch)
|
|
@@ -930,26 +793,20 @@ async function checkTrigger(store, trigger, config, now, io) {
|
|
|
930
793
|
store.updateFlowTrigger(trigger.id, { failures, lastAt: now.toISOString(), lastOutcome: fetched.problem, nextAt: new Date(now.getTime() + BACKOFF_MS[Math.min(failures, BACKOFF_MS.length) - 1]).toISOString() }, now);
|
|
931
794
|
return { ok: false, said: fetched.problem, added: 0 };
|
|
932
795
|
}
|
|
933
|
-
// Tidy's CI evidence (task-tidy.md): the watched branch's completed runs, green and red, beside the failures it carded.
|
|
934
796
|
if (config.kind === "github" && config.watch === "checks")
|
|
935
797
|
await observeBranchRuns(store, trigger, config, io.gh, now);
|
|
936
798
|
const by = config.kind === "github" ? "GitHub" : config.kind === "linear" ? "Linear" : "Email";
|
|
937
|
-
// Known items are left out before the batch is taken (v126): a page of things already received can't keep the unseen
|
|
938
|
-
// ones behind it waiting.
|
|
939
799
|
const fresh = fetched.items.filter(item => !store.flowTriggerSaw(trigger.id, item.key));
|
|
940
800
|
const due = fresh.slice(0, CARDS_PER_CHECK);
|
|
941
801
|
const results = due.map(item => "skip" in item
|
|
942
802
|
? (store.recordFlowTriggerEvent(trigger.id, item.key, null, item.skip, now) ? { made: "skipped", note: `${item.label}: ${item.skip}`, card: null } : { made: "seen", note: null, card: null })
|
|
943
803
|
: makeCard(store, trigger, config, item, by, now));
|
|
944
|
-
// A mailbox says itself whether more is waiting; its cursor is already just past what it read.
|
|
945
804
|
const more = fetched.more ?? fresh.length > CARDS_PER_CHECK;
|
|
946
|
-
// The cursor moves past what was handled, never past what is still waiting.
|
|
947
805
|
const cursor = fetched.more !== undefined ? fetched.cursor ?? trigger.cursor : more ? due.at(-1)?.at ?? trigger.cursor : fetched.cursor ?? trigger.cursor;
|
|
948
806
|
const said = results.length === 0 && fetched.said !== undefined ? fetched.said : outcomeWords(results, more);
|
|
949
807
|
store.updateFlowTrigger(trigger.id, { failures: 0, cursor, lastAt: now.toISOString(), lastOutcome: said, nextAt: new Date(now.getTime() + POLL_EVERY_MS).toISOString() }, now);
|
|
950
808
|
return { ok: true, said, added: results.filter(one => one.made === "added").length };
|
|
951
809
|
}
|
|
952
|
-
/** New mail in the folder since the last check, each message a card (or why it was left out). */
|
|
953
810
|
async function fetchMail(store, config, trigger, io, now) {
|
|
954
811
|
const signed = await mailboxAccess(io.dir, io.fetch);
|
|
955
812
|
if (!signed.ok)
|
|
@@ -962,14 +819,12 @@ async function fetchMail(store, config, trigger, io, now) {
|
|
|
962
819
|
const items = read.mails.map(readInboundMail).filter(mail => mailMatches(config, mail)).map(mail => {
|
|
963
820
|
const key = `mail:${read.at.validity}:${mail.uid}`, at = mailCursorText({ validity: read.at.validity, uid: mail.uid });
|
|
964
821
|
const label = `Email from ${mail.from || "an unknown sender"}`.slice(0, 120);
|
|
965
|
-
// Machines and this account itself never start cards: a flow that answers mail mustn't answer them.
|
|
966
822
|
if (mail.automatic)
|
|
967
823
|
return { key, skip: "an automatic reply", label, at };
|
|
968
824
|
if (mail.from === own)
|
|
969
825
|
return { key, skip: "sent from this account", label, at };
|
|
970
826
|
if (mail.from === "")
|
|
971
827
|
return { key, skip: "it had no sender", label, at };
|
|
972
|
-
// A reply to a card's email (v91) joins that card instead of starting another.
|
|
973
828
|
const reply = takeReply(store, mail, own, now);
|
|
974
829
|
if (reply !== null)
|
|
975
830
|
return { key, skip: `a reply to “${reply.card.title}”`, label, at };
|
|
@@ -981,7 +836,6 @@ async function fetchMail(store, config, trigger, io, now) {
|
|
|
981
836
|
: read.renumbered ? "The mail server renumbered this folder; watching it from now." : undefined;
|
|
982
837
|
return { ok: true, items, cursor: mailCursorText(read.at), more: read.more, ...(said === undefined ? {} : { said }) };
|
|
983
838
|
}
|
|
984
|
-
/** A GitHub issue or pull request as a card, or why it is left out; null when it doesn't match. */
|
|
985
839
|
export function githubItem(config, raw, what) {
|
|
986
840
|
const item = readGithubIssue(raw);
|
|
987
841
|
const number = Number(item.number);
|
|
@@ -1004,7 +858,6 @@ export function githubItem(config, raw, what) {
|
|
|
1004
858
|
description: `From ${what === "issue" ? "GitHub issue" : "pull request"} #${number} by @${login}${branches}:\n\n${item.body ?? ""}`.trim().slice(0, 4000),
|
|
1005
859
|
source: { kind: "github", label, url: item.html_url || null } };
|
|
1006
860
|
}
|
|
1007
|
-
/** A failed workflow run as a card: one card per failing commit on the watched branch. */
|
|
1008
861
|
export function githubRunItem(config, raw) {
|
|
1009
862
|
const run = readGithubRun(raw);
|
|
1010
863
|
if (run.conclusion !== "failure" || (config.branch !== null && (run.head_branch ?? "") !== config.branch))
|
|
@@ -1020,7 +873,6 @@ export function githubRunItem(config, raw) {
|
|
|
1020
873
|
}
|
|
1021
874
|
async function fetchGitHub(config, trigger, gh) {
|
|
1022
875
|
const since = trigger.cursor ?? trigger.createdAt;
|
|
1023
|
-
// A label trigger follows the moment the label is added (issue events), so an old labeled issue that merely gets a comment makes no card.
|
|
1024
876
|
const labelEvents = config.watch === "issues" && config.label !== null;
|
|
1025
877
|
const path = labelEvents ? `repos/${config.repo}/issues/events?per_page=50`
|
|
1026
878
|
: config.watch === "issues" ? `repos/${config.repo}/issues?state=open&sort=created&direction=desc&per_page=30`
|
|
@@ -1057,7 +909,6 @@ async function fetchGitHub(config, trigger, gh) {
|
|
|
1057
909
|
const items = labeled.map(one => { const item = githubItem(config, one.issue, "issue"); return item === null ? null : { ...item, at: one.created_at || null }; }).filter((one) => one !== null);
|
|
1058
910
|
return { ok: true, items: unique(items), cursor: labeled.map(one => one.created_at ?? "").at(-1) ?? trigger.cursor };
|
|
1059
911
|
}
|
|
1060
|
-
// New issues and pull requests: opened after the trigger was added, oldest first; the key keeps each to one card.
|
|
1061
912
|
const what = config.watch === "pulls" ? "pull" : "issue";
|
|
1062
913
|
const items = readGithubIssueList(body).filter(one => Date.parse(one.created_at ?? "") > created).reverse().map(one => githubItem(config, one, what)).filter((one) => one !== null);
|
|
1063
914
|
return { ok: true, items, cursor: trigger.cursor };
|
|
@@ -1065,7 +916,6 @@ async function fetchGitHub(config, trigger, gh) {
|
|
|
1065
916
|
const unique = (items) => items.filter((item, index) => items.findIndex(one => one.key === item.key) === index);
|
|
1066
917
|
export const LINEAR_URL = "https://api.linear.app/graphql";
|
|
1067
918
|
export const LINEAR_QUERY = "query FlowTrigger($filter: IssueFilter) { issues(filter: $filter, first: 50, orderBy: updatedAt) { nodes { identifier title description url updatedAt state { name } team { key } labels { nodes { name } } } } }";
|
|
1068
|
-
/** A Linear issue as a card; null when it doesn't match the trigger. */
|
|
1069
919
|
export function linearItem(config, raw) {
|
|
1070
920
|
const issue = readLinearIssue(raw);
|
|
1071
921
|
const identifier = issue.identifier ?? "";
|
|
@@ -1118,14 +968,11 @@ async function fetchLinear(config, trigger, io) {
|
|
|
1118
968
|
const items = issues.map(one => linearItem(config, one)).filter((one) => one !== null);
|
|
1119
969
|
return { ok: true, items, cursor: issues.map(one => one.updatedAt ?? "").filter(one => one !== "").at(-1) ?? trigger.cursor };
|
|
1120
970
|
}
|
|
1121
|
-
/** A header that only describes the delivery (not a security header): its first value. */
|
|
1122
971
|
const header = (delivery, name) => delivery.headers[name]?.[0] ?? "";
|
|
1123
972
|
function sameHex(expected, given) {
|
|
1124
973
|
const a = Buffer.from(expected, "utf8"), b = Buffer.from(given, "utf8");
|
|
1125
974
|
return a.length === b.length && timingSafeEqual(a, b);
|
|
1126
975
|
}
|
|
1127
|
-
/** How a webhook trigger's deliveries are proven, before anything in them is read: its sender's signature over the raw
|
|
1128
|
-
* bytes with the current generation's secret. Null when proven (or unsigned); otherwise the refusal, which writes nothing. */
|
|
1129
976
|
function proveHook(trigger, config, delivery, dir, now) {
|
|
1130
977
|
if (config.kind === "github") {
|
|
1131
978
|
const secret = readHookSecret(dir, trigger.id, trigger.hookCredential);
|
|
@@ -1152,10 +999,7 @@ function proveHook(trigger, config, delivery, dir, now) {
|
|
|
1152
999
|
const proof = proveDelivery(sender, secret, delivery.headers, delivery.body, now);
|
|
1153
1000
|
return proof.ok ? { signedId: proof.signedId } : { status: 401, said: proof.said };
|
|
1154
1001
|
}
|
|
1155
|
-
/** A webhook delivery at a trigger's secret address: prove it, read it, make at most the cards it names. Nothing runs here. */
|
|
1156
1002
|
export function receiveFlowHook(store, token, delivery, dir, now) {
|
|
1157
|
-
// v126 floods (webhook-limits.ts): what doesn't prove itself is counted per address, and past the minute's limit is
|
|
1158
|
-
// answered 429 and does nothing. A delivery that proves itself is never refused by this count.
|
|
1159
1003
|
const unproven = (address, answer) => {
|
|
1160
1004
|
const count = countUnproven(store, address, now);
|
|
1161
1005
|
return count.over ? { status: 429, said: "Too many. Try again later.", retryAfter: count.retryAfterSeconds } : answer;
|
|
@@ -1169,7 +1013,6 @@ export function receiveFlowHook(store, token, delivery, dir, now) {
|
|
|
1169
1013
|
if (!adapterPolicy({ caller: "service", capability: "none" }, undefined, source => source === "flow" && store.getFlow(trigger.flow) !== null).ok)
|
|
1170
1014
|
return { status: 403, said: "No access to this flow." };
|
|
1171
1015
|
const address = trigger.hookHash ?? UNKNOWN_ADDRESS;
|
|
1172
|
-
// An unsigned webhook has nothing to prove: every delivery to it counts (and it is lossy under a flood, by design).
|
|
1173
1016
|
const unsigned = config.kind === "webhook" && senderOf(config) === "none";
|
|
1174
1017
|
if (unsigned) {
|
|
1175
1018
|
const counted = unproven(address, { status: 0, said: "" });
|
|
@@ -1178,14 +1021,10 @@ export function receiveFlowHook(store, token, delivery, dir, now) {
|
|
|
1178
1021
|
}
|
|
1179
1022
|
if (delivery.body.length > HOOK_BYTES)
|
|
1180
1023
|
return unsigned ? { status: 413, said: "Too large." } : unproven(address, { status: 413, said: "Too large." });
|
|
1181
|
-
// Proven over the raw bytes before anything in them is read; a refusal writes nothing, not even the last outcome.
|
|
1182
1024
|
const proven = proveHook(trigger, config, delivery, dir, now);
|
|
1183
1025
|
if ("status" in proven)
|
|
1184
1026
|
return unsigned ? proven : unproven(address, proven);
|
|
1185
1027
|
const note = (said) => { store.updateFlowTrigger(trigger.id, { lastAt: now.toISOString(), lastOutcome: said }, now); };
|
|
1186
|
-
// Every write a delivery makes is bound to the trigger as it was proven against (v126): its secret, settings, address
|
|
1187
|
-
// and state, read again in the same transaction. A change that landed meanwhile (a new secret, another sender, a new
|
|
1188
|
-
// address, a pause) means this delivery writes nothing at all.
|
|
1189
1028
|
const written = (write) => store.transact(() => {
|
|
1190
1029
|
const current = store.getFlowTrigger(trigger.id);
|
|
1191
1030
|
if (current === null || current.state !== "active" || current.hookCredential !== trigger.hookCredential || current.configJson !== trigger.configJson || current.hookHash !== trigger.hookHash) {
|
|
@@ -1208,14 +1047,11 @@ export function receiveFlowHook(store, token, delivery, dir, now) {
|
|
|
1208
1047
|
return written(() => { note("GitHub connected."); return { status: 200, said: "Connected." }; });
|
|
1209
1048
|
if (repository.toLowerCase() !== config.repo.toLowerCase())
|
|
1210
1049
|
return { status: 202, said: "Not this repository." };
|
|
1211
|
-
// A label trigger takes the moment its label is added (or an issue opened with it); a plain one takes new issues.
|
|
1212
1050
|
const labeledNow = action === "labeled" && config.label !== null && (body.label?.name ?? "").toLowerCase() === config.label.toLowerCase();
|
|
1213
1051
|
const found = config.watch === "issues" && event === "issues" && (action === "opened" || labeledNow) ? githubItem(config, body.issue, "issue")
|
|
1214
1052
|
: config.watch === "pulls" && event === "pull_request" && ["opened", "ready_for_review", "labeled", "reopened"].includes(action) ? githubItem(config, body.pull_request, "pull")
|
|
1215
1053
|
: config.watch === "checks" && event === "workflow_run" && action === "completed" ? githubRunItem(config, body.workflow_run) : null;
|
|
1216
1054
|
items = found === null ? [] : [found];
|
|
1217
|
-
// A signed workflow run on the watched branch is tidy's CI evidence too (task-tidy.md), green or red: recorded only
|
|
1218
|
-
// inside `written`, which re-proves the trigger is still active with the same config, credential and address.
|
|
1219
1055
|
if (config.watch === "checks" && config.branch !== null && event === "workflow_run" && action === "completed") {
|
|
1220
1056
|
const branch = config.branch;
|
|
1221
1057
|
const recorded = written(() => { recordBranchCheckRun(store, { repo: config.repo, branch }, readGithubRun(body.workflow_run), now); return { status: 200, said: "Recorded." }; });
|
|
@@ -1225,31 +1061,20 @@ export function receiveFlowHook(store, token, delivery, dir, now) {
|
|
|
1225
1061
|
}
|
|
1226
1062
|
else if (config.kind === "linear") {
|
|
1227
1063
|
const body = readLinearEvent(payload), sent = Number(body.webhookTimestamp);
|
|
1228
|
-
// Signed but stale: as unproven as no signature at all, so it counts toward the address's minute.
|
|
1229
1064
|
if (!Number.isFinite(sent) || Math.abs(now.getTime() - sent) > 5 * 60_000)
|
|
1230
1065
|
return unproven(address, { status: 401, said: "Too old." });
|
|
1231
1066
|
if (body.type !== "Issue" || !["create", "update"].includes(body.action ?? ""))
|
|
1232
1067
|
return { status: 202, said: "Ignored." };
|
|
1233
|
-
// A state trigger fires when the issue arrives in that state, not on every later edit there.
|
|
1234
1068
|
const moved = body.action === "create" || body.updatedFrom?.stateId !== undefined || config.state === null;
|
|
1235
1069
|
const found = moved ? linearItem(config, body.data) : null;
|
|
1236
1070
|
items = found === null ? [] : [found];
|
|
1237
1071
|
}
|
|
1238
1072
|
else if (config.kind === "webhook") {
|
|
1239
|
-
// v126: read by its sender's reader (webhook-readers.ts): Sentry's and Vercel's check shape, action and scope before
|
|
1240
|
-
// an identity is claimed; the others pick their fields by dot-paths.
|
|
1241
1073
|
const body = readWebhookPayload(payload);
|
|
1242
1074
|
const sender = senderOf(config);
|
|
1243
1075
|
const read = readDelivery(body, { sender, title: config.title, titleField: config.titleField, bodyField: config.bodyField, idField: config.idField ?? null, urlField: config.urlField ?? null, project: config.project ?? null, team: config.team ?? null });
|
|
1244
|
-
// A delivery's own key: an unsigned webhook's is what the sender says (as before); a signed one's only what its
|
|
1245
|
-
// signature covers — Standard Webhooks' signed id, or the raw bytes. Keys carry the sender, so nothing unsigned
|
|
1246
|
-
// stands for anything signed.
|
|
1247
1076
|
const bodyHash = createHash("sha256").update(delivery.body).digest("hex");
|
|
1248
|
-
// A signed delivery id is outside words too: one that isn't a usable identity (padded, hidden characters, too long,
|
|
1249
|
-
// or looking like a key) is never a key; the delivery is received under its bytes, and made into nothing.
|
|
1250
1077
|
const signedId = proven.signedId === null ? null : identityOf(proven.signedId);
|
|
1251
|
-
// An unsigned sender's own id is outside words too: judged as sent, and when it isn't a usable identity (padded,
|
|
1252
|
-
// hidden characters, too long, looking like a key) the delivery keys on its bytes instead, as when there is none.
|
|
1253
1078
|
const saidId = header(delivery, "x-request-id") || header(delivery, "x-delivery-id") || header(delivery, "idempotency-key");
|
|
1254
1079
|
const headerId = saidId === "" ? null : identityOf(saidId);
|
|
1255
1080
|
const deliveryKey = sender === "none"
|
|
@@ -1257,7 +1082,6 @@ export function receiveFlowHook(store, token, delivery, dir, now) {
|
|
|
1257
1082
|
: signedId?.ok === true ? `v3:${sender}:wid:${signedId.id}` : `v3:${sender}:body:${bodyHash}`;
|
|
1258
1083
|
if (signedId?.ok === false)
|
|
1259
1084
|
items = [{ key: deliveryKey, skip: `its delivery id: ${signedId.why}`, label: "Webhook", at: null }];
|
|
1260
|
-
// Not for this flow: received under the delivery's own key, so it never uses up the identity of what it names.
|
|
1261
1085
|
else if (read.kind === "ignored")
|
|
1262
1086
|
return written(() => {
|
|
1263
1087
|
const before = store.flowReceipt(trigger.id, deliveryKey);
|
|
@@ -1269,7 +1093,6 @@ export function receiveFlowHook(store, token, delivery, dir, now) {
|
|
|
1269
1093
|
else if (read.kind === "skip")
|
|
1270
1094
|
items = [{ key: deliveryKey, skip: read.why, label: "Webhook", at: null }];
|
|
1271
1095
|
else {
|
|
1272
|
-
// The outside thing's identity, when it has one, groups its deliveries: one card per issue or deployment.
|
|
1273
1096
|
const key = read.identity === null ? deliveryKey : `v3:${sender}:id:${read.identity}`;
|
|
1274
1097
|
items = [{ key, at: null, title: read.title, description: read.description,
|
|
1275
1098
|
source: { kind: sender === "sentry" || sender === "vercel" ? sender : "webhook", label: read.label, url: read.url,
|
|
@@ -1278,47 +1101,33 @@ export function receiveFlowHook(store, token, delivery, dir, now) {
|
|
|
1278
1101
|
}
|
|
1279
1102
|
if (items.length === 0)
|
|
1280
1103
|
return { status: 202, said: "Nothing for this flow." };
|
|
1281
|
-
// Every key is outside words until judged (v126): a GitHub or Linear identifier, like any identity, that is too long,
|
|
1282
|
-
// carries hidden characters or looks like a key is never a key — the delivery is received under its bytes instead,
|
|
1283
|
-
// and made into nothing.
|
|
1284
|
-
// (A webhook's identities were judged by its reader, raw, before its key was made: only GitHub's and Linear's here.)
|
|
1285
1104
|
const deliveryBytes = createHash("sha256").update(delivery.body).digest("hex");
|
|
1286
1105
|
if (config.kind !== "webhook")
|
|
1287
1106
|
items = items.map(item => {
|
|
1288
1107
|
const identity = item.key.slice(item.key.indexOf(":") + 1);
|
|
1289
1108
|
const judged = identityOf(identity);
|
|
1290
|
-
// A fixed label: nothing of the refused identity is kept, not even in the words the panel shows.
|
|
1291
1109
|
if (!judged.ok)
|
|
1292
1110
|
return { key: `v3:${config.kind}:body:${deliveryBytes}`, skip: judged.why, label: "A delivery", at: null };
|
|
1293
1111
|
if ("skip" in item)
|
|
1294
1112
|
return item;
|
|
1295
|
-
// A signed GitHub or Linear delivery says, at its receipt, who proved it and what it names (v126) — a polled item
|
|
1296
|
-
// never does, so the two stay apart; nothing is inferred later from today's settings.
|
|
1297
1113
|
const url = safeLink(item.source.url, config.kind === "github" ? [{ host: "github.com", subdomains: false }] : [{ host: "linear.app", subdomains: false }]);
|
|
1298
1114
|
return { ...item, source: { ...item.source, url, verified: config.kind, external: { id: judged.id, url }, receipt: item.key } };
|
|
1299
1115
|
});
|
|
1300
1116
|
const by = config.kind === "github" ? "GitHub" : config.kind === "linear" ? "Linear" : "Webhook";
|
|
1301
1117
|
return written(() => {
|
|
1302
|
-
// Received before (v126): said for what it was, never as a card that isn't there.
|
|
1303
1118
|
const first = items[0];
|
|
1304
1119
|
const before = items.length === 1 ? store.flowReceipt(trigger.id, first.key) : null;
|
|
1305
1120
|
if (before !== null)
|
|
1306
1121
|
return repeatAnswer(before);
|
|
1307
|
-
// The hourly card limit (v126), decided in this same transaction, counted when each card was made: a signed delivery
|
|
1308
|
-
// over it is held whole and made into its card when there's room; an unsigned one is turned away.
|
|
1309
1122
|
const making = items.filter((item) => !("skip" in item));
|
|
1310
1123
|
if (making.length > 0 && store.flowCardsAcceptedSince(trigger.id, new Date(now.getTime() - 3_600_000)) >= CARDS_PER_HOUR) {
|
|
1311
|
-
// Rejections are decided before anything is written: an unsigned one writes nothing at all.
|
|
1312
1124
|
if (unsigned)
|
|
1313
1125
|
return { status: 429, said: "Too many in the last hour. Try again later.", retryAfter: 3600 };
|
|
1314
1126
|
if (store.heldFlowReceiptCount(trigger.id) >= HELD_AT_MOST) {
|
|
1315
|
-
// Turned away, written nowhere but the trigger's lasting count.
|
|
1316
1127
|
store.noteFlowDeliveryDropped(trigger.id, now);
|
|
1317
1128
|
return { status: 503, said: "Too many waiting already. Resend it later from the sender's delivery log." };
|
|
1318
1129
|
}
|
|
1319
1130
|
const item = making[0];
|
|
1320
|
-
// Screened and bounded whole before it is kept — its words as a card's are, and where it came from (label, link,
|
|
1321
|
-
// identity) as a delivery's are: a held item is never something a card couldn't hold.
|
|
1322
1131
|
const words = flowCardText(item.title, item.description);
|
|
1323
1132
|
const source = heldSourceOf(item.source, item.key);
|
|
1324
1133
|
const problem = "problem" in words ? (words.problem.startsWith("That looks like a key") ? "it looked like it held a key or password" : words.problem) : source === null ? "where it came from couldn't be kept safely" : null;
|
|
@@ -1341,16 +1150,10 @@ export function receiveFlowHook(store, token, delivery, dir, now) {
|
|
|
1341
1150
|
: makeCard(store, trigger, config, item, by, now));
|
|
1342
1151
|
const said = outcomeWords(results, false);
|
|
1343
1152
|
note(said);
|
|
1344
|
-
// The sender's answer is made from public reasons, not edited out of the panel's words.
|
|
1345
1153
|
return { status: 202, said: outcomeWords(results.map(one => ({ ...one, note: publicReason(one.note) })), false) };
|
|
1346
1154
|
});
|
|
1347
1155
|
}
|
|
1348
|
-
/** A held item's whole size, at most, as saved: room for the largest card-sized item there can be (a 200-character
|
|
1349
|
-
* title and 4,000-character details, a label and two 2,000-character links) with every character escaped six-fold in
|
|
1350
|
-
* JSON, so no item a card could hold is ever refused for its size. */
|
|
1351
1156
|
const HELD_ITEM_BYTES = 6 * (200 + 4_000 + 120 + 2 * 2_000 + 400) + 2_000;
|
|
1352
|
-
/** Where a held delivery came from, made safe to keep: a bounded label and kind with nothing that looks like a key, a
|
|
1353
|
-
* link made safe (https, no user information, query or fragment), a screened identity. Null when it can't be. */
|
|
1354
1157
|
function heldSourceOf(source, key) {
|
|
1355
1158
|
const label = source.label.slice(0, 120), kind = source.kind.slice(0, 40);
|
|
1356
1159
|
if (looksSecret(label) || looksSecret(kind))
|
|
@@ -1376,13 +1179,6 @@ function readHeldItem(json) {
|
|
|
1376
1179
|
return null;
|
|
1377
1180
|
}
|
|
1378
1181
|
}
|
|
1379
|
-
/**
|
|
1380
|
-
* v126: make a trigger's held deliveries into their cards while the last hour has room, oldest first. Each card in its
|
|
1381
|
-
* own write transaction, which reads everything it acts on under the write lock: the trigger (still active, still
|
|
1382
|
-
* taking deliveries), the hour's room, the oldest held receipt, the flow; then the same guards intake has (a failing
|
|
1383
|
-
* run already owned by another card in the project is left out). The card and the receipt's move to accepted land
|
|
1384
|
-
* together, or neither does.
|
|
1385
|
-
*/
|
|
1386
1182
|
export function drainHeldDeliveries(store, trigger, now) {
|
|
1387
1183
|
let added = 0;
|
|
1388
1184
|
for (;;) {
|
|
@@ -1406,7 +1202,6 @@ export function drainHeldDeliveries(store, trigger, now) {
|
|
|
1406
1202
|
store.skipHeldReceipt(current.id, next.key, "problem" in words ? words.problem : "it couldn't be read back");
|
|
1407
1203
|
return "left";
|
|
1408
1204
|
}
|
|
1409
|
-
// One failing run is one fix, held or not: a card another trigger in this project already made for it wins.
|
|
1410
1205
|
const filed = next.key.startsWith("checks:") ? checksCardOf(store, flow.repo, next.key) : null;
|
|
1411
1206
|
if (filed !== null) {
|
|
1412
1207
|
store.skipHeldReceipt(current.id, next.key, `already a card in ${filed}`);
|
|
@@ -1423,35 +1218,21 @@ export function drainHeldDeliveries(store, trigger, now) {
|
|
|
1423
1218
|
added++;
|
|
1424
1219
|
}
|
|
1425
1220
|
}
|
|
1426
|
-
/**
|
|
1427
|
-
* v126: a delivery refused before it could be read (too large, a body that wouldn't read): it proves nothing, so it
|
|
1428
|
-
* counts toward its address's minute like any unproven delivery. The answer to give instead when that count is over.
|
|
1429
|
-
*/
|
|
1430
1221
|
export function hookRefusedUnread(store, token, now) {
|
|
1431
1222
|
const trigger = /^[A-Za-z0-9_-]{20,64}$/.test(token) ? store.flowTriggerByHook(hookHash(token)) : null;
|
|
1432
1223
|
const count = countUnproven(store, trigger?.hookHash ?? UNKNOWN_ADDRESS, now);
|
|
1433
1224
|
return count.over ? { status: 429, said: "Too many. Try again later.", retryAfter: count.retryAfterSeconds } : null;
|
|
1434
1225
|
}
|
|
1435
|
-
/** v126: a delivery received before, answered for what it was — never as a card that isn't there. */
|
|
1436
1226
|
function repeatAnswer(before) {
|
|
1437
1227
|
return { status: 202, said: before.state === "accepted" ? "Already received." : before.state === "held" ? "Already received; waiting for room."
|
|
1438
1228
|
: before.state === "skipped" ? `Already received; it wasn't added${before.note === null ? "" : `: ${publicReason(before.note)}`}.` : "Already received." };
|
|
1439
1229
|
}
|
|
1440
|
-
/** Why an item was left out, as its sender is told (v126): reasons about what it sent, but never this installation's
|
|
1441
|
-
* flows or cards — a reason that names one is said without it. The full words stay on the signed-in panel. */
|
|
1442
1230
|
function publicReason(note) {
|
|
1443
1231
|
if (note === null)
|
|
1444
1232
|
return null;
|
|
1445
1233
|
const at = note.indexOf("already a card in");
|
|
1446
1234
|
return at === -1 ? note : `${note.slice(0, at)}already on a card`;
|
|
1447
1235
|
}
|
|
1448
|
-
/**
|
|
1449
|
-
* v126: a webhook's credentials change. A new secret is written whole at an address of its own (an id made for this
|
|
1450
|
-
* change alone, so a change racing it never writes there), and only then does the trigger point at it — only from the
|
|
1451
|
-
* secret and settings read here, so of two changes at once exactly one lands. No secret means "": nothing is ever
|
|
1452
|
-
* adopted from a place an unfinished change may have left something. The loser removes only what it wrote; the winner
|
|
1453
|
-
* removes the secret it replaced, as cleanup only (nothing points at it any more).
|
|
1454
|
-
*/
|
|
1455
1236
|
function nextHookCredential(store, trigger, secret, configJson, now, dir, hookHash) {
|
|
1456
1237
|
const credential = secret === null ? "" : randomBytes(16).toString("hex");
|
|
1457
1238
|
if (secret !== null) {
|
|
@@ -1469,8 +1250,6 @@ function nextHookCredential(store, trigger, secret, configJson, now, dir, hookHa
|
|
|
1469
1250
|
dropHookSecret(dir, trigger.id, trigger.hookCredential);
|
|
1470
1251
|
return { ok: true };
|
|
1471
1252
|
}
|
|
1472
|
-
/** A signing secret pasted on the secure panel behind the password, never in chat: Linear's, or a signed webhook's
|
|
1473
|
-
* sender's (Sentry's or Vercel's own, or a Standard or GitHub-style one made elsewhere). */
|
|
1474
1253
|
export function saveSigningSecret(store, trigger, secret, now, dir) {
|
|
1475
1254
|
const config = triggerConfigOf(trigger);
|
|
1476
1255
|
const clean = secret.trim();
|
|
@@ -1494,11 +1273,6 @@ const SECRET_SHAPE_WORDS = {
|
|
|
1494
1273
|
standard: "Paste the secret exactly as the sender shows it: whsec_ followed by its key.",
|
|
1495
1274
|
"github-style": "Paste the secret exactly as the sender shows it (16 to 200 characters, no spaces).",
|
|
1496
1275
|
};
|
|
1497
|
-
/**
|
|
1498
|
-
* v126: a new secret for a webhook whose sender Toolroll makes secrets for (Standard Webhooks, GitHub-style), shown once.
|
|
1499
|
-
* Its address stays as it is (New address is its own action). Sentry's and Vercel's secrets are theirs, pasted instead.
|
|
1500
|
-
* The only place such a secret is made: creating a trigger (from the panel, the gallery or an import) never does.
|
|
1501
|
-
*/
|
|
1502
1276
|
export function setUpFlowHook(store, trigger, now, dir) {
|
|
1503
1277
|
const config = triggerConfigOf(trigger);
|
|
1504
1278
|
if (config?.kind !== "webhook" || trigger.state === "removed")
|
|
@@ -1507,9 +1281,6 @@ export function setUpFlowHook(store, trigger, now, dir) {
|
|
|
1507
1281
|
if (sender === "none" || !makesSecret(sender))
|
|
1508
1282
|
return { ok: false, message: sender === "none" ? "An unsigned webhook has no secret. Choose who signs its deliveries first." : `${SENDER_WORDS[sender]} makes its own secret: paste it here instead.` };
|
|
1509
1283
|
const secret = makeSecret(sender);
|
|
1510
|
-
// A webhook with no address yet (made by the gallery or an import, where no one was shown one) gets its address with
|
|
1511
|
-
// its secret, both shown together once. One that has an address keeps it — a replaced secret, a set-up after its
|
|
1512
|
-
// sender changed — because the sender already has it.
|
|
1513
1284
|
const first = trigger.hookHash === null;
|
|
1514
1285
|
const token = first ? randomBytes(24).toString("base64url") : null;
|
|
1515
1286
|
const saved = nextHookCredential(store, trigger, secret, null, now, dir, token === null ? undefined : hookHash(token));
|
|
@@ -1522,11 +1293,6 @@ export function setUpFlowHook(store, trigger, now, dir) {
|
|
|
1522
1293
|
: { ok: true, id: trigger.id, said: `New secret made; any earlier one no longer works. Copy it now; it isn't shown again. The address stays as it is.`,
|
|
1523
1294
|
reveal: { path: "", address: null, secret } };
|
|
1524
1295
|
}
|
|
1525
|
-
/**
|
|
1526
|
-
* v126: change who signs a webhook's deliveries, in place: the trigger keeps its id, address and what it has received
|
|
1527
|
-
* (keys carry the sender, so nothing received unsigned stands for anything signed). Its credentials move to the next
|
|
1528
|
-
* generation with no secret: it isn't ready until it is set up again. Settings the new sender doesn't read are left out.
|
|
1529
|
-
*/
|
|
1530
1296
|
export function changeFlowHookSender(store, trigger, sender, actor, now, dir) {
|
|
1531
1297
|
const config = triggerConfigOf(trigger);
|
|
1532
1298
|
const flow = store.getFlow(trigger.flow);
|
|
@@ -1556,11 +1322,6 @@ export function changeFlowHookSender(store, trigger, sender, actor, now, dir) {
|
|
|
1556
1322
|
: makesSecret(next) ? `Now signed by ${SENDER_WORDS[next]}. Set it up (its address and secret are shown together) before deliveries are taken: until then they are refused.`
|
|
1557
1323
|
: `Now signed by ${SENDER_WORDS[next]}. Paste ${SENDER_WORDS[next]}'s secret before deliveries are taken: until then they are refused.` };
|
|
1558
1324
|
}
|
|
1559
|
-
/**
|
|
1560
|
-
* v126: which project (and, for Vercel, team) a Sentry or Vercel webhook takes deliveries from, set in place: the
|
|
1561
|
-
* trigger keeps its id, address, secret and history; blank takes any project the secret covers. Only from the settings
|
|
1562
|
-
* read here, so a change racing it doesn't land on top of it.
|
|
1563
|
-
*/
|
|
1564
1325
|
export function setFlowHookScope(store, trigger, scope, actor, now) {
|
|
1565
1326
|
const config = triggerConfigOf(trigger);
|
|
1566
1327
|
const flow = store.getFlow(trigger.flow);
|
|
@@ -1584,8 +1345,6 @@ export function setFlowHookScope(store, trigger, scope, actor, now) {
|
|
|
1584
1345
|
const project = changed.kind === "webhook" ? changed.project ?? null : null;
|
|
1585
1346
|
return { ok: true, said: project === null ? `Any ${SENDER_WORDS[sender]} project this secret covers can add cards.` : `Only deliveries from ${project} add cards now.` };
|
|
1586
1347
|
}
|
|
1587
|
-
/** Whether a webhook trigger can prove its deliveries: an unsigned webhook always (its address is all it has), the others
|
|
1588
|
-
* once the current generation's secret is saved. */
|
|
1589
1348
|
export function hookReady(trigger, dir) {
|
|
1590
1349
|
const config = triggerConfigOf(trigger);
|
|
1591
1350
|
if (config === null || !takesDeliveries(config))
|
|
@@ -1594,11 +1353,8 @@ export function hookReady(trigger, dir) {
|
|
|
1594
1353
|
return true;
|
|
1595
1354
|
return dir !== null && readHookSecret(dir, trigger.id, trigger.hookCredential) !== null;
|
|
1596
1355
|
}
|
|
1597
|
-
// ------------------------------------------------------ public forms (v84)
|
|
1598
1356
|
export const FORM_PATH = "/hooks/form/";
|
|
1599
|
-
/** At most this many cards an hour from one shared form. */
|
|
1600
1357
|
const FORM_CARDS_PER_HOUR = 30;
|
|
1601
|
-
/** Share a button as a secret link anyone can fill in, without signing in. The link is shown once; only its hash is kept. */
|
|
1602
1358
|
export function shareFlowButton(store, trigger, now, dir) {
|
|
1603
1359
|
if (triggerConfigOf(trigger)?.kind !== "button" || trigger.state === "removed")
|
|
1604
1360
|
return { ok: false, message: "Only a button can be shared as a form." };
|
|
@@ -1619,12 +1375,10 @@ label{display:grid;gap:6px;margin:0 0 16px;font-weight:600}input,textarea{font:i
|
|
|
1619
1375
|
textarea{min-height:96px;resize:vertical}button{font:inherit;font-weight:600;border:0;border-radius:10px;padding:12px 18px;min-height:44px;background:var(--accent);color:var(--bg);cursor:pointer}
|
|
1620
1376
|
p{color:var(--muted)}.trap{position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden}a{color:var(--accent)}
|
|
1621
1377
|
`;
|
|
1622
|
-
/** The public page: the button's name and its questions, nothing about the flow, the project or anyone in it. */
|
|
1623
1378
|
function formHtml(label, body) {
|
|
1624
1379
|
return htmlString(html `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="robots" content="noindex">
|
|
1625
1380
|
<title>${label}</title>${styleElement(FORM_CSS)}</head><body><main><h1>${label}</h1><div class="card">${body}</div></main></body></html>`);
|
|
1626
1381
|
}
|
|
1627
|
-
/** GET a shared form: its questions. */
|
|
1628
1382
|
export function flowFormPage(store, token, now) {
|
|
1629
1383
|
const trigger = /^[A-Za-z0-9_-]{20,64}$/.test(token) ? store.flowTriggerByHook(hookHash(token)) : null;
|
|
1630
1384
|
const config = trigger === null ? null : triggerConfigOf(trigger);
|
|
@@ -1633,10 +1387,8 @@ export function flowFormPage(store, token, now) {
|
|
|
1633
1387
|
if (!adapterPolicy({ caller: "anonymous", capability: "none" }, undefined, source => source === "flow" && store.getFlow(trigger.flow) !== null).ok)
|
|
1634
1388
|
return { status: 403, html: "" };
|
|
1635
1389
|
const fields = config.questions.map((question, index) => html `<label>${question}${index === 0 ? html `<input name="a${index}" required maxlength="200" autocomplete="off">` : html `<textarea name="a${index}" maxlength="3000"></textarea>`}</label>`);
|
|
1636
|
-
// Signed out by nature: no session, so no CSRF; the trap, the shown time and the hourly limit guard it. It posts back to its own address.
|
|
1637
1390
|
return { status: 200, html: formHtml(config.label, postForm("", html `${fields}<div class="trap" aria-hidden="true"><label>Leave this empty<input name="website" tabindex="-1" autocomplete="off"></label></div><input type="hidden" name="t" value="${now.getTime()}"><button>Send</button>`, { signedOut: true })) };
|
|
1638
1391
|
}
|
|
1639
|
-
/** POST a shared form: at most one card per submission, keys refused, a limit per hour, and quiet about what a bot did wrong. */
|
|
1640
1392
|
export function receiveFlowForm(store, token, fields, now) {
|
|
1641
1393
|
const trigger = /^[A-Za-z0-9_-]{20,64}$/.test(token) ? store.flowTriggerByHook(hookHash(token)) : null;
|
|
1642
1394
|
const config = trigger === null ? null : triggerConfigOf(trigger);
|
|
@@ -1646,7 +1398,6 @@ export function receiveFlowForm(store, token, fields, now) {
|
|
|
1646
1398
|
return { status: 403, html: "" };
|
|
1647
1399
|
const again = html `<p><a href="${FORM_PATH + token}">Send another</a></p>`;
|
|
1648
1400
|
const thanks = formHtml(config.label, html `<p>Thanks — it's been sent.</p>${again}`);
|
|
1649
|
-
// A filled trap, or a page posted faster than a person could, gets thanks and makes nothing.
|
|
1650
1401
|
const form = readFormSubmission(fields, config.questions.length);
|
|
1651
1402
|
const shown = Number(form.t);
|
|
1652
1403
|
if ((form.website ?? "") !== "" || !Number.isFinite(shown) || now.getTime() - shown < 2000 || now.getTime() - shown > 86_400_000)
|
|
@@ -1664,9 +1415,6 @@ export function receiveFlowForm(store, token, fields, now) {
|
|
|
1664
1415
|
store.updateFlowTrigger(trigger.id, { lastAt: now.toISOString(), lastOutcome: "Someone sent the form." }, now);
|
|
1665
1416
|
return { status: 200, html: thanks };
|
|
1666
1417
|
}
|
|
1667
|
-
/** Tidy's CI evidence (docs/plans/task-tidy.md): the watched branch's recent completed workflow runs, read through the
|
|
1668
|
-
* person's own gh login. Recorded only while the trigger still watches exactly that repository and branch once GitHub
|
|
1669
|
-
* answered; any failure records nothing (tidy then keeps the notices). */
|
|
1670
1418
|
async function observeBranchRuns(store, trigger, config, gh, now) {
|
|
1671
1419
|
if (config.branch === null)
|
|
1672
1420
|
return;
|
|
@@ -1688,16 +1436,14 @@ async function observeBranchRuns(store, trigger, config, gh, now) {
|
|
|
1688
1436
|
return;
|
|
1689
1437
|
}
|
|
1690
1438
|
const runs = [...readGithubRunList(body).workflow_runs ?? []];
|
|
1691
|
-
// A few older failure cards' own runs, so tidy can tell whether each was a push to this branch (task-tidy.md).
|
|
1692
1439
|
for (const id of unprovenNoticeRuns(store, trigger.id, config.repo)) {
|
|
1693
1440
|
try {
|
|
1694
1441
|
const one = await gh("gh", ["api", "-H", "Accept: application/vnd.github+json", `repos/${config.repo}/actions/runs/${id}`], { timeoutMs: 20_000 });
|
|
1695
1442
|
if (one.code === 0)
|
|
1696
1443
|
runs.push(readGithubRun(JSON.parse(one.stdout)));
|
|
1697
1444
|
}
|
|
1698
|
-
catch {
|
|
1445
|
+
catch { }
|
|
1699
1446
|
}
|
|
1700
|
-
// Re-proved and recorded in one transaction: a trigger paused or changed meanwhile records nothing.
|
|
1701
1447
|
store.transact(() => {
|
|
1702
1448
|
const current = store.getFlowTrigger(trigger.id);
|
|
1703
1449
|
const still = current === null ? null : triggerConfigOf(current);
|