toolroll 0.9.103 → 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 +65 -0
- package/README.md +27 -27
- 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 +117 -103
- 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 +3 -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 +2 -16
- 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 +168 -0
- package/dist/local-owner.js +15 -80
- 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 +2 -17
- package/dist/operate-remote.js +0 -33
- package/dist/operate.js +280 -2304
- 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 +3 -18
- 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 +11 -30
- package/dist/public-check.js +0 -16
- package/dist/publish.js +1 -150
- package/dist/pull-request-flow.js +6 -74
- 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 +26 -103
- 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 +9 -28
- 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 +88 -566
- 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 +29 -564
- 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 +9 -86
- 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 +17 -497
- 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 +8 -133
- 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 +12 -227
- package/dist/server/tasks.js +37 -531
- 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 +8 -73
- 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 +66 -19
- 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 +91 -40
- package/dist/tui.js +54 -54
- 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 +5 -4
- 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 -318
- 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 -1972
- 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 -539
- 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 -41
- 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.d.ts +0 -124
- 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 -52
- 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 -156
- 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 -35
- 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 -1067
- 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 -80
- 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 -59
- 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 -754
- package/dist/server/render-settings.d.ts +0 -93
- package/dist/server/render-tasks.d.ts +0 -774
- 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 -342
- 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 -83
- 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 -30
- 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 -144
- 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/server/settings.js
CHANGED
|
@@ -43,7 +43,6 @@ import { approvalGroup, projectPicker, GROUP_PATHS, groupTitle, modeCeremonyHtml
|
|
|
43
43
|
import { HANDOFF_STYLE, redirect, respond, safeReturn, sayTo, signInSpent, startedHere } from "./http.js";
|
|
44
44
|
import { html, htmlString, joinHtml, postForm, reauth } from "../html.js";
|
|
45
45
|
import { browserCaller, sessionWithinLifetime } from "./session.js";
|
|
46
|
-
/** settings handlers, moved without changing their route bodies. */
|
|
47
46
|
import { DEFAULT_ACCENT, normalHex } from "../accent-colors.js";
|
|
48
47
|
import { resolvePhaseAgent } from "../agentconfig.js";
|
|
49
48
|
import { parseProtectedPaths } from "../approval-policy.js";
|
|
@@ -97,6 +96,8 @@ import { MAX_NETWORK_HOSTS, normalizeHost } from "../egress.js";
|
|
|
97
96
|
import { isWritesMode } from "../writes-mode.js";
|
|
98
97
|
import { isCheckAccess, signInsUnavailableWords, widerThan } from "../check-access.js";
|
|
99
98
|
import { LOCAL_MODE_CONFINES, localModeOn } from "../local-owner.js";
|
|
99
|
+
import { policyInForce, setAdvancedPreference } from "../advanced.js";
|
|
100
|
+
import { advancedShownNow } from "../advanced-view.js";
|
|
100
101
|
import { parseMachLookup, parseReadDeny } from "../project-sandbox.js";
|
|
101
102
|
import { projectDeleteConfirmHtml, projectSettingsHtml } from "../project-delete-ui.js";
|
|
102
103
|
import { endHoldout, setCodeMapSwitch } from "../code-map-acts.js";
|
|
@@ -153,9 +154,6 @@ import { chatReturnWithSaid, goOutside } from "./http.js";
|
|
|
153
154
|
import { leadSettingsHtml, notificationProjects, SETTINGS_AUTOSAVE_SCRIPT, settingsWorkers, telegramDeliveryWords, telegramTrouble } from "./render-settings.js";
|
|
154
155
|
export function createSettingsHandlers(runtime) {
|
|
155
156
|
const { identities, store, providerHome, managedRepos, consoleProjects, sendScreen, chromeFor, connectionCheck, connectionKnown, lastChecks, checkRelease, clock, modelCatalog, modelSeams, toolsViewOf, codexServers, projectViewOf, sessions, restricted, options, integrations, consoleOrigin, evidenceRoot, storagePool, visible, ssoSettings, checkLocalAgents, chatKeyFor, chatCatalog, chatCatalogKnown, leadWords, agentSignInCommand, settingsUpdates, phoneSetup, authenticateApprover, authenticateCredential, deletedRepos, projectOf, providerFor, admissionList, toolHome, connectVisits, mintApprovalNonce, consumeApprovalNonce, googleVisits } = runtime;
|
|
156
|
-
// What agent work cost, by month: API dollars, plan usage and unknown cost apart (spend-report.ts), with this
|
|
157
|
-
// month's limits first. An instance operator's page. A limit opens its form in place (?edit=<scope:key>) and saves
|
|
158
|
-
// to /spend/budget with a step-up.
|
|
159
157
|
async function spendPage(ctx) {
|
|
160
158
|
const { url, who, response, now } = ctx;
|
|
161
159
|
const current = monthOf(now);
|
|
@@ -166,16 +164,14 @@ export function createSettingsHandlers(runtime) {
|
|
|
166
164
|
const rows = spendRows(store.handle, month.from, month.to);
|
|
167
165
|
const subagentNames = subagentNamesOf(store.handle);
|
|
168
166
|
if (url.searchParams.get("format") === "csv") {
|
|
169
|
-
response.writeHead(200, { "content-type": "text/csv; charset=utf-8", "content-disposition": `attachment; filename="
|
|
167
|
+
response.writeHead(200, { "content-type": "text/csv; charset=utf-8", "content-disposition": `attachment; filename="toolroll-spend-${month.name}.csv"`, "cache-control": "no-store", "x-content-type-options": "nosniff" });
|
|
170
168
|
return void response.end(spendReportCsv(rows, subagentNames));
|
|
171
169
|
}
|
|
172
170
|
const shift = (by) => { const at = new Date(`${month.name}-01T00:00:00.000Z`); at.setUTCMonth(at.getUTCMonth() + by); return at.toISOString().slice(0, 7); };
|
|
173
|
-
// Limits read what the budget gate counts today (spend.ts spendItems): always this month's, whichever month is shown.
|
|
174
171
|
const items = spendItems(store.handle, current.from, current.to);
|
|
175
172
|
const saved = store.budgets();
|
|
176
173
|
const budgets = budgetStates(saved, items);
|
|
177
174
|
const has = (scope, key) => saved.some(one => one.scope === scope && one.key === key);
|
|
178
|
-
// Everything and each project with no limit yet, with what it spent this month (counted as a limit would count it).
|
|
179
175
|
const spentFor = (scope, key) => budgetStates([{ id: 0, scope, key, limitMicrousd: 1, hardStop: false, updatedBy: "", updatedAt: "" }], items)[0].spentMicrousd;
|
|
180
176
|
const unlimited = [
|
|
181
177
|
...(has("installation", "*") ? [] : [{ target: "installation:*", label: "Everything", budget: null, spentMicrousd: spentFor("installation", "*") }]),
|
|
@@ -196,9 +192,7 @@ export function createSettingsHandlers(runtime) {
|
|
|
196
192
|
const windows = limitsView(store.providerLimits(), [], { project: projectName, subagent: id => subagentNames.get(id) ?? `Subagent ${id}` }, now);
|
|
197
193
|
const view = { month: month.name, previous: shift(-1), next: month.name === current.name ? null : shift(1), current: current.name, report: spendReport(rows),
|
|
198
194
|
budgets, unlimited, targets, windows, subagentNames, edit, facts: approvalFactsNow(),
|
|
199
|
-
// Suggestions and rules (results-routing slice 4): read-only, for every project this console shows.
|
|
200
195
|
savings: savingsReportOrError(store, consoleProjects(), now) };
|
|
201
|
-
// A refusal for the open form shows in the form; anything else under the limits' heading.
|
|
202
196
|
const said = { said: url.searchParams.get("said"), problem: edit === null ? url.searchParams.get("problem") : null };
|
|
203
197
|
return sendScreen(response, 200, screen("Spend", spendHtml(view, said), { chrome: chromeFor(null, "spend"), functional: { script: spendScript() } }));
|
|
204
198
|
}
|
|
@@ -224,7 +218,6 @@ export function createSettingsHandlers(runtime) {
|
|
|
224
218
|
if (!isProviderId(asked))
|
|
225
219
|
return refuse(response, who, 400, "Choose a known provider.", "/control");
|
|
226
220
|
const task = url.searchParams.get("task") ?? "";
|
|
227
|
-
// The last sign-in check: Check again posts (docs/plans/get-side-effects.md).
|
|
228
221
|
const connection = connectionKnown(asked);
|
|
229
222
|
if (view === "connection") {
|
|
230
223
|
const command = asked === "claude" ? "claude auth login" : asked === "codex" ? "codex login" : asked === "gemini" ? "gemini" : null;
|
|
@@ -234,17 +227,12 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
234
227
|
}
|
|
235
228
|
const setup = store.liveWorktreeSetup(project);
|
|
236
229
|
const preparation = detectPreparation(project);
|
|
237
|
-
// The saved live catalog when it has models for this provider; the
|
|
238
|
-
// built-in short list otherwise.
|
|
239
230
|
const live = asked === "openrouter" ? [] : modelOptions(store, asked, clock(), providerHome).map(({ value, label }) => ({ value, label }));
|
|
240
231
|
const configured = saved?.provider === asked ? saved.model : null;
|
|
241
232
|
const models = live.length === 0 ? modelChoices(asked, configured, providerHome)
|
|
242
233
|
: configured && !live.some(one => one.value === configured) ? [{ value: configured, label: `${configured} — current choice` }, ...live] : live;
|
|
243
234
|
const instructions = previewProjectInstructions(project);
|
|
244
|
-
// The model list as last loaded; Refresh models posts, and the background checks keep it current.
|
|
245
235
|
const catalog = asked === "openrouter" ? modelCatalog.known(readProviderKey("openrouter", providerHome)) ?? { ok: false, problem: "The model list has not loaded yet." } : null;
|
|
246
|
-
// With nothing saved, setup preselects what the installation builds routine tasks with, else "Sized by job"'s
|
|
247
|
-
// routine builder (Sonnet 5.5) for Claude: an exact id, never a floating name.
|
|
248
236
|
const installationBuild = store.phaseConfig(INSTALLATION_SCOPE, "build");
|
|
249
237
|
const routineDefault = PRESETS[DEFAULT_PRESET].rows["build"] ?? "";
|
|
250
238
|
const preselected = installationBuild?.provider === asked && installationBuild.model !== null && models.some(one => one.value === installationBuild.model) ? installationBuild.model
|
|
@@ -253,7 +241,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
253
241
|
return sendScreen(response, 200, screen("Project setup", controlSetupHtml({ repo: project, csrf: who.via === "cookie" ? who.session.csrf : "", provider: asked, inputs, models, connection, catalog, task, preparation,
|
|
254
242
|
instructions: instructions.ok ? { installed: instructions.installed } : { installed: false, message: instructions.message } }), { chrome: chromeFor(project, "settings"), ...(catalog === null ? {} : { functional: { script: openRouterPickerScript() } }) }));
|
|
255
243
|
};
|
|
256
|
-
// Settings → Projects → Pull requests → Check setup: git and GitHub, for one project, by an approver who may turn it on.
|
|
257
244
|
async function pullRequestsCheck(ctx) {
|
|
258
245
|
const { who, response, posted } = ctx;
|
|
259
246
|
const repo = readForm(posted, CONSOLE_FORMS.pullRequestsCheck).get("repo") ?? "";
|
|
@@ -265,7 +252,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
265
252
|
await lastChecks.run(`publishing:${repo}`, () => checkPublishing(repo, options.publishExec === undefined ? {} : { exec: options.publishExec }));
|
|
266
253
|
return redirect(response, `/settings/pull-requests?repo=${encodeURIComponent(repo)}`);
|
|
267
254
|
}
|
|
268
|
-
// Settings → Storage → Check now: measure the checkouts again.
|
|
269
255
|
async function storageCheck(ctx) {
|
|
270
256
|
const databaseFile = store.databaseFile();
|
|
271
257
|
if (databaseFile !== null)
|
|
@@ -273,12 +259,10 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
273
259
|
return redirect(ctx.response, "/settings/storage");
|
|
274
260
|
}
|
|
275
261
|
const measureStorage = (databaseFile) => lastChecks.run("storage", () => checkoutPlan(store, storagePool(databaseFile), clock(), { manual: true }));
|
|
276
|
-
// Settings → Updates → Check now: ask npm once, whether or not automatic checks are on.
|
|
277
262
|
async function updatesCheck(ctx) {
|
|
278
263
|
await checkRelease();
|
|
279
264
|
return redirect(ctx.response, "/settings/updates");
|
|
280
265
|
}
|
|
281
|
-
// Check again (Settings → providers, Project setup): ask this computer's CLI, or test the saved key, now.
|
|
282
266
|
async function connectionCheckNow(ctx) {
|
|
283
267
|
const { response, posted } = ctx;
|
|
284
268
|
const body = readForm(posted, CONSOLE_FORMS.connectionCheck);
|
|
@@ -289,7 +273,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
289
273
|
await connectionCheck(provider, true).catch(() => undefined);
|
|
290
274
|
return redirect(response, back);
|
|
291
275
|
}
|
|
292
|
-
// Refresh models (Project setup, OpenRouter): load the list again, then show the setup page with it.
|
|
293
276
|
async function modelsRefresh(ctx) {
|
|
294
277
|
const { response, posted } = ctx;
|
|
295
278
|
const body = readForm(posted, CONSOLE_FORMS.modelsRefresh);
|
|
@@ -300,10 +283,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
300
283
|
async function modelsPage(ctx) {
|
|
301
284
|
const { url, who, response, project } = ctx;
|
|
302
285
|
const now = clock();
|
|
303
|
-
// The page shows the last check and when it ran (docs/plans/get-side-effects.md): Check now, or the watch loop's
|
|
304
|
-
// automatic checks, fetch the lists and may queue a notice; opening the page never does.
|
|
305
|
-
// Only an instance operator changes models (docs/plans/spend-dashboard.md D4); a preset or a switch is previewed
|
|
306
|
-
// here, read-only, and applied by its own password-checked POST.
|
|
307
286
|
const view = modelsView(who.via === "cookie" && store.isInstanceOperator(who.name), who.via === "cookie" ? who.session.csrf : "", now, url.searchParams.get("said"), url.searchParams.get("problem"), url.searchParams);
|
|
308
287
|
return sendScreen(response, 200, screen("Models", modelsHtml({ ...view, facts: approvalFactsNow() }), { chrome: chromeFor(project, "settings"), functional: { script: modelsScript() } }));
|
|
309
288
|
}
|
|
@@ -333,13 +312,11 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
333
312
|
if (chosen && !projects.includes(chosen))
|
|
334
313
|
return refuse(response, who, 403, "That project is outside your access.", "/projects");
|
|
335
314
|
const kit = kitOf(url.searchParams.get("kit") ?? "")?.id ?? null, wanted = (oneClickOf(url.searchParams.get("connect") ?? "") ?? localConnectOf(url.searchParams.get("connect") ?? ""))?.id ?? null;
|
|
336
|
-
// Choosing a project opens it at once (keeping a kit's Connect), so every form below acts on the project shown.
|
|
337
315
|
const selector = toolsProjectPicker(projects, chosen, { ...(kit === null ? {} : { kit }), ...(wanted === null ? {} : { connect: wanted }) });
|
|
338
316
|
let content = html `<p>Add a project to give its builds tools.</p>`;
|
|
339
317
|
if (chosen) {
|
|
340
318
|
try {
|
|
341
319
|
const approver = who.role === "approver" && who.via === "cookie";
|
|
342
|
-
// What Codex had configured at the last background check (docs/plans/get-side-effects.md): the page starts no codex.
|
|
343
320
|
const view = toolsViewOf(chosen, approver ? lastChecks.known(`codex-tools:${chosen}`)?.value ?? null : null, kit, wanted);
|
|
344
321
|
if (approver)
|
|
345
322
|
view.others = projects.filter(one => one !== chosen).map(one => ({ repo: one, project: projectName(one), open: connectionsOf(store, one).filter(c => c.state === "open").map(c => c.id) }));
|
|
@@ -351,7 +328,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
351
328
|
}
|
|
352
329
|
return sendScreen(response, 200, screen("Tools", settingsSubPage("agents", "Tools", html `${selector}${content}`), { chrome: chromeFor(chosen || project, "settings"), functional: { script: SETTINGS_AUTOSAVE_SCRIPT + TOOLS_PROJECT_SCRIPT } }));
|
|
353
330
|
}
|
|
354
|
-
// Settings → Project: what Toolroll holds for a project; an instance operator deletes it here.
|
|
355
331
|
async function projectPage(ctx) {
|
|
356
332
|
const { url, who, response, project } = ctx;
|
|
357
333
|
const projects = consoleProjects();
|
|
@@ -364,7 +340,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
364
340
|
const content = chosen === "" ? html `${notice.said ? infoLine(notice.said) : ""}${empty({ title: "No projects yet.", action: btn("Add a project", { sm: true, href: "/projects" }) })}` : (projectSettingsHtml({ ...projectViewOf(chosen, who), remoteUrl: store.projectRemote(chosen), codeMap: codeMapView(chosen, who, ctx.now) }, notice));
|
|
365
341
|
return sendScreen(response, 200, screen("Project", settingsSubPage("projects", "Project", html `${selector}${content}`), { chrome: chromeFor(chosen || null, "settings") }));
|
|
366
342
|
}
|
|
367
|
-
/** The project's code map section: the switch, and the holdout while new builds are still being enrolled. */
|
|
368
343
|
function codeMapView(repo, who, now) {
|
|
369
344
|
const row = store.handle.prepare("SELECT code_map, code_map_enroll_until FROM project WHERE path = ?").get(repo);
|
|
370
345
|
const until = typeof row?.["code_map_enroll_until"] === "string" ? row["code_map_enroll_until"] : null;
|
|
@@ -389,9 +364,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
389
364
|
return back("said", kind === "holdout" ? "The holdout has ended. Builds already enrolled keep their arm." : on ? "The code map is on." : "The code map is off.");
|
|
390
365
|
};
|
|
391
366
|
}
|
|
392
|
-
// v102: Settings → Approvals and safety: the defaults for new tasks, a project's separation of duties and release
|
|
393
|
-
// approval, and the way to its operating mode. Anyone who sees the project reads them; each form's own route decides
|
|
394
|
-
// who may change it (an approver for the defaults and releases, an instance operator for the rules).
|
|
395
367
|
async function approvalPage(ctx) {
|
|
396
368
|
const { url, who, response, project, now } = ctx;
|
|
397
369
|
const projects = consoleProjects();
|
|
@@ -402,8 +374,9 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
402
374
|
const release = chosen === "" ? null : releaseApprovalSetting(store, chosen);
|
|
403
375
|
const notice = { said: url.searchParams.get("said"), problem: url.searchParams.get("problem") };
|
|
404
376
|
const csrf = who.via === "cookie" ? who.session.csrf : "";
|
|
405
|
-
const
|
|
406
|
-
|
|
377
|
+
const releases = chosen !== "" && (advancedShownNow() || release.auto);
|
|
378
|
+
const rules = chosen === "" ? html `` : html `${approvalRulesHtml({ repo: chosen, name: projectName(chosen), rules: store.approvalRules(chosen), canChange: who.via === "cookie" && store.isInstanceOperator(who.name), approvers }, notice)}${!releases ? "" :
|
|
379
|
+
releaseApprovalHtml({ repo: chosen, auto: release.auto, setBy: release.setBy, at: release.at, canChange: who.via === "cookie" && who.role === "approver" && !store.isDemo() && store.accountCanAccess(who.name, chosen) })}`;
|
|
407
380
|
const limited = restricted();
|
|
408
381
|
const permission = store.permissionDefault(), quality = store.qualityDefault();
|
|
409
382
|
const changed = (at, by) => at === null ? null : `Changed ${when(at)}${by === null ? "" : ` by ${by}`}`;
|
|
@@ -413,11 +386,16 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
413
386
|
permission: limited ? null : { mode: permission.mode, canManage: who.role === "approver" && csrf !== "", changed: changed(permission.updatedAt, permission.updatedBy) },
|
|
414
387
|
quality: limited ? null : { mode: quality.mode, canManage: who.role === "approver" && csrf !== "", changed: changed(quality.updatedAt, quality.updatedBy) } },
|
|
415
388
|
flags: {}, projects: projects.map(repo => ({ repo, name: projectName(repo) })), chosen, rules,
|
|
389
|
+
advanced: { on: advancedShownNow(), modeActive: projects.some(repo => { try {
|
|
390
|
+
return store.activeMode(repo, now) !== null;
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
return true;
|
|
394
|
+
} }), policy: policyInForce(store) },
|
|
416
395
|
mode: chosen === "" ? "Open a project to sign one" : live === null ? `${projectName(chosen)}: locked, approvals stay with people` : `${projectName(chosen)}: ${live.name} until ${when(live.absoluteExpiry)}`,
|
|
417
396
|
});
|
|
418
397
|
return sendScreen(response, 200, screen("Approvals and safety", page, { chrome: chromeFor(chosen || project, "settings") }));
|
|
419
398
|
}
|
|
420
|
-
// Sprint 8: Settings → Policy, the organisation policy and its history. Anyone signed in reads it; an instance operator changes it.
|
|
421
399
|
async function policyPage(ctx) {
|
|
422
400
|
const { url, who, response, project } = ctx;
|
|
423
401
|
const repos = consoleProjects();
|
|
@@ -425,8 +403,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
425
403
|
const view = { policy: store.orgPolicy(), history: store.policyHistory(50), canChange: who.via === "cookie" && store.isInstanceOperator(who.name), toolNames };
|
|
426
404
|
return sendScreen(response, 200, screen("Policy", settingsSubPage("approval", "Policy", html `${(policyHtml(view, { said: url.searchParams.get("said"), problem: url.searchParams.get("problem") }))}`), { chrome: chromeFor(project, "settings") }));
|
|
427
405
|
}
|
|
428
|
-
// Settings → Flows: the starter flows live under New flow → Starter flows now. This address (and a task's "Do this
|
|
429
|
-
// every time…", ?starter=) lands there with the project, the starter asked about and how a switch went.
|
|
430
406
|
async function flowsPage(ctx) {
|
|
431
407
|
const { url, who, response, project } = ctx;
|
|
432
408
|
const projects = consoleProjects();
|
|
@@ -443,7 +419,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
443
419
|
}
|
|
444
420
|
return redirect(response, `/flows/new?${query.toString()}`);
|
|
445
421
|
}
|
|
446
|
-
// Settings → Integrations: which integrations work. The list is the last checks; a render never waits on one.
|
|
447
422
|
async function integrationsPage(ctx) {
|
|
448
423
|
const { url, response, project } = ctx;
|
|
449
424
|
const who = browserCaller(ctx.who);
|
|
@@ -452,7 +427,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
452
427
|
const list = integrations.list();
|
|
453
428
|
return sendScreen(response, 200, screen("Integrations", settingsSubPage("system", "Integrations", html `${(integrationsHtml(list, who.session.csrf, { said: url.searchParams.get("said"), problem: url.searchParams.get("problem"), checking: integrations.checking, secrets: toolSecretStorage() }))}`), { chrome: chromeFor(project, "settings") }));
|
|
454
429
|
}
|
|
455
|
-
// v104: Settings → Monitoring, where the audit stream and traces go. An instance operator's page.
|
|
456
430
|
async function monitoringPage(ctx) {
|
|
457
431
|
const { url, request, response, project } = ctx;
|
|
458
432
|
const who = browserCaller(ctx.who);
|
|
@@ -461,42 +435,34 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
461
435
|
const view = { settings: readMonitoring(options.configDir), status: store.monitoringStatus(), head: store.ledgerHeadId(), origin: consoleOrigin(request.headers.host) };
|
|
462
436
|
return sendScreen(response, 200, screen("Monitoring", settingsSubPage("system", "Monitoring", html `${(monitoringHtml(view, { said: url.searchParams.get("said"), problem: url.searchParams.get("problem") }))}`), { chrome: chromeFor(project, "settings") }));
|
|
463
437
|
}
|
|
464
|
-
// Settings → Updates: the installed version, three ways to update, the update's steps live, then What's new. An instance operator's page.
|
|
465
438
|
async function updatesPage(ctx) {
|
|
466
439
|
const { url, response, project } = ctx;
|
|
467
440
|
const who = browserCaller(ctx.who);
|
|
468
441
|
const databaseFile = store.databaseFile();
|
|
469
442
|
if (databaseFile === null)
|
|
470
443
|
return refuse(response, who, 403, "An instance operator updates Toolroll.", "/settings");
|
|
471
|
-
// A stalled update is released by the background pass, never by opening this page (docs/plans/get-side-effects.md).
|
|
472
444
|
const status = runtimeUpdateStatus(dirname(databaseFile));
|
|
473
445
|
if (url.searchParams.get("fragment") === "steps")
|
|
474
446
|
return respond(response, 200, "text/html; charset=utf-8", status.journal ? updateStepsHtml(status.journal, status.running) : html `<div id="update-live" data-done="1"></div>`);
|
|
475
447
|
const active = status.journal !== null && !runtimeUpdateTerminal(status.journal.phase);
|
|
476
448
|
const current = options.updates?.current ?? PACKAGE_VERSION;
|
|
477
|
-
// The last answer npm gave (the background checks ask while update checks are on; Check now asks once).
|
|
478
449
|
const checksOff = updateChecksOff(process.env, options.configDir ?? dirname(databaseFile)).off;
|
|
479
450
|
const known = lastChecks.known("release")?.value ?? null;
|
|
480
451
|
const view = { current, latest: active ? { version: current } : known ?? (checksOff ? { off: true } : { pending: true }), method: options.updates?.method ?? installMethod(), journal: status.journal, running: status.running, whatsNew: status.whatsNew, rollbackTo: status.lastUpdate?.to === current ? status.lastUpdate.from : null, csrf: who.session.csrf };
|
|
481
452
|
return sendScreen(response, 200, screen("Updates", settingsSubPage("system", "Updates", html `${(updatesHtml(view, { said: url.searchParams.get("said"), problem: url.searchParams.get("problem") }))}`), { chrome: chromeFor(project, "settings"), ...(active ? { functional: { script: updatesScript(), fetches: true } } : {}) }));
|
|
482
453
|
}
|
|
483
|
-
// v105: Settings → Retention, how long each kind of data is kept. An instance operator's page.
|
|
484
454
|
async function retentionPage(ctx) {
|
|
485
455
|
const { url, response, now, project } = ctx;
|
|
486
456
|
const who = browserCaller(ctx.who);
|
|
487
457
|
const view = { periods: store.retentionPeriods(), chosen: Object.keys(store.retentionChosen()), next: retentionPlan(store, evidenceRoot, now).counts, lastSweep: lastSweepAt(store), csrf: who.session.csrf };
|
|
488
458
|
return sendScreen(response, 200, screen("Retention", settingsSubPage("system", "Retention", html `${(retentionHtml(view, { said: url.searchParams.get("said"), problem: url.searchParams.get("problem") }))}`), { chrome: chromeFor(project, "settings") }));
|
|
489
459
|
}
|
|
490
|
-
// Settings → Storage: what task checkouts use, cleaning up now (the preview behind the password), and when a
|
|
491
|
-
// finished task's clean checkout goes by itself. An instance operator's page.
|
|
492
460
|
async function storagePage(ctx) {
|
|
493
461
|
const { url, response, now, project } = ctx;
|
|
494
462
|
const who = browserCaller(ctx.who);
|
|
495
463
|
const databaseFile = store.databaseFile();
|
|
496
464
|
if (databaseFile === null)
|
|
497
465
|
return refuse(response, who, 403, "An instance operator looks after storage.", "/settings");
|
|
498
|
-
// The last measurement (docs/plans/get-side-effects.md): the background checks measure the checkouts, and so do
|
|
499
|
-
// Check now and every clean-up; opening the page runs no du or git.
|
|
500
466
|
const measured = lastChecks.known("storage");
|
|
501
467
|
const check = postForm("/settings/storage/check", btn("Check now", { sm: true, type: "submit" }));
|
|
502
468
|
if (measured === null) {
|
|
@@ -506,8 +472,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
506
472
|
const sweep = { last: lastSweep(store), off: storageSweepOff(), schedule: sweepSchedule(store, now) };
|
|
507
473
|
return sendScreen(response, 200, screen("Storage", settingsSubPage("system", "Storage", html `${(storageHtml({ plan, csrf: who.session.csrf, sweep, landed: landedSummary(store), measured: html `<div class="k-acts"><span class="k-note">Measured ${new Date(measured.at).toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" })}</span>${check}</div>` }, { said: url.searchParams.get("said"), problem: url.searchParams.get("problem") }))}`), { chrome: chromeFor(project, "settings") }));
|
|
508
474
|
}
|
|
509
|
-
// Settings → Projects → Pull requests: one project's setup. Off, the checks run on open, so the page says
|
|
510
|
-
// exactly what turning on would do, or what to fix first.
|
|
511
475
|
async function pullRequestsPage(ctx) {
|
|
512
476
|
const { url, who, response, project } = ctx;
|
|
513
477
|
const repo = url.searchParams.get("repo") ?? "";
|
|
@@ -516,13 +480,11 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
516
480
|
return refuse(response, who, 404, "No such project.", "/projects");
|
|
517
481
|
const publishing = publishingOf(store, repo);
|
|
518
482
|
const canChange = who.role === "approver" && !store.isDemo();
|
|
519
|
-
// The last setup check for this project (Check setup posts); opening the page asks git and GitHub nothing.
|
|
520
483
|
const check = publishing.on || !canChange ? null : lastChecks.known(`publishing:${repo}`)?.value ?? "unchecked";
|
|
521
484
|
const body = (pullRequestSettingsHtml({ repo, name: projectName(repo), csrf: who.session.csrf, canChange, publishing, check,
|
|
522
485
|
said: url.searchParams.get("said"), problem: url.searchParams.get("problem") }));
|
|
523
486
|
return sendScreen(response, 200, screen("Pull requests", settingsSubPage("projects", "Pull requests", html `${body}`), { chrome: chromeFor(project, "projects") }));
|
|
524
487
|
}
|
|
525
|
-
// Settings → Projects → Checks: how much checks after each build, and the quick command beside the full one.
|
|
526
488
|
async function checksPage(ctx) {
|
|
527
489
|
const { url, who, response, project } = ctx;
|
|
528
490
|
const repo = url.searchParams.get("repo") ?? "";
|
|
@@ -533,10 +495,10 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
533
495
|
const body = (checkSettingsHtml({ repo, name: projectName(repo), csrf: who.session.csrf, canChange: who.role === "approver" && !store.isDemo(),
|
|
534
496
|
level: projectCheckLevel(store, repo).level, full: store.liveVerifyCommand(repo), quick, suggestion: quick === null ? suggestQuickCommand(repo) : null,
|
|
535
497
|
review: (({ on, source }) => ({ on, source }))(store.reviewSwitch(repo, clock())), batch: { on: projectBatchChecks(store, repo).on }, fast: { on: fastStartOn(store, repo) },
|
|
536
|
-
said: url.searchParams.get("said"), problem: url.searchParams.get("problem")
|
|
498
|
+
said: url.searchParams.get("said"), problem: url.searchParams.get("problem"),
|
|
499
|
+
needsPassword: who.authority === "local-owner" && store.accountOf(who.name)?.passwordSet !== true }));
|
|
537
500
|
return sendScreen(response, 200, screen("Checks", settingsSubPage("projects", "Checks", html `${body}`), { chrome: chromeFor(project, "projects") }));
|
|
538
501
|
}
|
|
539
|
-
// Sprint 8: Settings → Backups, how the last backup went and the schedule. An instance operator's page.
|
|
540
502
|
async function backupsPage(ctx) {
|
|
541
503
|
const { url, response, now, project } = ctx;
|
|
542
504
|
const who = browserCaller(ctx.who);
|
|
@@ -549,13 +511,11 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
549
511
|
live: { state: live, folder: liveFolderOf(live.settings, databaseFile), defaultFolder: defaultLiveFolder(databaseFile) } };
|
|
550
512
|
return sendScreen(response, 200, screen("Backups", settingsSubPage("system", "Backups", html `${(backupHtml(view, { said: url.searchParams.get("said"), problem: url.searchParams.get("problem") }))}`), { chrome: chromeFor(project, "settings") }));
|
|
551
513
|
}
|
|
552
|
-
// v105: Settings → Data, where an instance operator downloads everything. The download is a POST with the password.
|
|
553
514
|
async function dataPage(ctx) {
|
|
554
515
|
const { url, response, project } = ctx;
|
|
555
516
|
browserCaller(ctx.who);
|
|
556
517
|
return sendScreen(response, 200, screen("Data", settingsSubPage("system", "Data export", html `${(dataExportHtml({ problem: url.searchParams.get("problem") }))}`), { chrome: chromeFor(project, "settings") }));
|
|
557
518
|
}
|
|
558
|
-
// v100: Settings → Sign-in, the identity provider people sign in with. An instance operator's page.
|
|
559
519
|
async function signInPage(ctx) {
|
|
560
520
|
const { url, request, response, project } = ctx;
|
|
561
521
|
const who = browserCaller(ctx.who);
|
|
@@ -567,7 +527,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
567
527
|
const body = ssoSettingsHtml({ settings, redirect: origin === null ? null : `${origin}${SSO_CALLBACK}`, projects, linked: settings !== null && store.ssoIdentitiesOf(who.name).some(one => one.issuer.replace(/\/+$/, "") === settings.issuer) }, { said: url.searchParams.get("said"), problem: url.searchParams.get("problem") });
|
|
568
528
|
return sendScreen(response, 200, screen("Sign-in", settingsSubPage("access", "Sign-in with a provider", html `${body}`), { chrome: chromeFor(project, "settings") }));
|
|
569
529
|
}
|
|
570
|
-
/** Passwordless (docs/plans/passwordless.md): the switch, and the trade in plain words. */
|
|
571
530
|
async function passwordlessPage(ctx) {
|
|
572
531
|
const { url, response, project } = ctx;
|
|
573
532
|
browserCaller(ctx.who);
|
|
@@ -588,7 +547,6 @@ ${connectionHtml(asked, connection, task)}${command === null ? "" : html `<p>On
|
|
|
588
547
|
}
|
|
589
548
|
if (action !== "on")
|
|
590
549
|
return back("problem", "Choose on or off.");
|
|
591
|
-
// Turning it on is a credential act: a password typed now (or a one-use provider re-check), never a session.
|
|
592
550
|
if (!authenticateCredential(who, body.get("password") ?? "").ok)
|
|
593
551
|
return back("problem", "Enter your Toolroll password to turn Passwordless on.");
|
|
594
552
|
setPasswordless(store, true, who.name, now);
|
|
@@ -655,7 +613,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
655
613
|
}
|
|
656
614
|
return sendScreen(response, 200, screen("Learning", settingsSubPage("agents", "Learning", html `${selector}${content}`), { chrome: chromeFor(chosen || project, "settings") }));
|
|
657
615
|
}
|
|
658
|
-
// Settings → Lead (onboarding): what runs the lead in one line, and the full form under Advanced.
|
|
659
616
|
async function leadPage(ctx) {
|
|
660
617
|
const { url, response, now, project } = ctx;
|
|
661
618
|
const who = browserCaller(ctx.who);
|
|
@@ -681,11 +638,7 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
681
638
|
async function telegramPage(ctx) {
|
|
682
639
|
const { response, now, project } = ctx;
|
|
683
640
|
const who = browserCaller(ctx.who);
|
|
684
|
-
// Any approver pairs their OWN phone here; the bot token stays on /settings.
|
|
685
641
|
const botId = options.telegramTokenFile === undefined ? null : loadBotToken(process.env, options.telegramTokenFile)?.botId ?? null;
|
|
686
|
-
// The settings view holds no secret (a pairing code only appears in
|
|
687
|
-
// the response to Pair, which stays script-free), so it joins the
|
|
688
|
-
// workspace like every other settings page.
|
|
689
642
|
return sendScreen(response, 200, screen("Telegram", telegramSettingsHtml(store, botId, who.name, { now }), { chrome: chromeFor(project, "settings") }));
|
|
690
643
|
}
|
|
691
644
|
async function teamsPage(ctx) {
|
|
@@ -713,14 +666,12 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
713
666
|
const { who, response } = ctx;
|
|
714
667
|
if (!options.configDir)
|
|
715
668
|
return refuse(response, who, 403, "An installation approver can connect Slack.", "/settings");
|
|
716
|
-
response.writeHead(200, { "Content-Type": "application/json; charset=utf-8", "Content-Disposition": 'attachment; filename="
|
|
669
|
+
response.writeHead(200, { "Content-Type": "application/json; charset=utf-8", "Content-Disposition": 'attachment; filename="toolroll-slack.json"', "Cache-Control": "no-store" });
|
|
717
670
|
response.end(JSON.stringify(SLACK_MANIFEST, null, 2));
|
|
718
671
|
return;
|
|
719
672
|
}
|
|
720
673
|
async function settingsHome(ctx) {
|
|
721
674
|
const { url, who, request, response, now, project } = ctx;
|
|
722
|
-
// The overview and its group pages (docs/plans/settings-revamp.md §3): one handler reads the facts once and draws
|
|
723
|
-
// the page asked for; each section's form posts to its own route, which proves the act again.
|
|
724
675
|
const group = GROUP_PATHS[url.pathname] ?? "hub";
|
|
725
676
|
const minimal = options.telegramTokenFile === undefined || restricted();
|
|
726
677
|
const csrf = who.via === "cookie" ? who.session.csrf : "";
|
|
@@ -731,15 +682,12 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
731
682
|
? null
|
|
732
683
|
: effectivePrimary(process.env, options.configDir, options.telegramTokenFile !== undefined && loadBotToken(process.env, options.telegramTokenFile) !== null);
|
|
733
684
|
const push = minimal || csrf === "" ? null : {
|
|
734
|
-
// The section lights only where a secure context exists: the stated
|
|
735
|
-
// public origin, or localhost development (arc 3 finding 2).
|
|
736
685
|
available: options.publicUrl !== undefined || (request.headers.host ?? "").startsWith("localhost") || (request.headers.host ?? "").startsWith("127.0.0.1"),
|
|
737
686
|
devices: store.listPushSubscriptions(who.name).filter(one => one.retiredAt === null || one.retiredReason === "gone")
|
|
738
687
|
.map(one => ({ id: one.id, words: `${one.uaWords} · since ${when(one.createdAt)}`, state: one.retiredAt !== null ? "expired" : one.consecutiveFailures >= 20 ? "failing" : "ok", removable: one.retiredAt === null })),
|
|
739
688
|
};
|
|
740
689
|
const providerKeys = who.role !== "approver" || minimal || csrf === ""
|
|
741
690
|
? null
|
|
742
|
-
// ACP agents sign in their own way; Toolroll keeps no key for them, so the key list holds only the others.
|
|
743
691
|
: await Promise.all(PROVIDER_IDS.filter(isKeyedProvider).map(async (provider) => {
|
|
744
692
|
const key = keyStatus(provider, providerHome), connection = connectionKnown(provider) ?? undefined;
|
|
745
693
|
const mode = readAuthMode(provider, providerHome) === "api-key" ? "api-key" : "subscription";
|
|
@@ -779,7 +727,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
779
727
|
workers: minimal ? null : settingsWorkers(store, now),
|
|
780
728
|
updates,
|
|
781
729
|
firstResult: (() => {
|
|
782
|
-
// The installation fact: when the first Ready result arrived, measured from the first account.
|
|
783
730
|
const at = store.firstSuccessAt(now), since = store.installationStartedAt();
|
|
784
731
|
return at === null || since === null ? null : firstResultWords(since, at);
|
|
785
732
|
})(),
|
|
@@ -788,14 +735,11 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
788
735
|
push,
|
|
789
736
|
digest: digest === null || csrf === "" || chosen?.mode === "quiet" ? null : { every: digest.everyMs === null ? "off" : String(Math.round(digest.everyMs / 60_000)), held: digest.everyMs === null ? null : `${digest.held} routine update${digest.held === 1 ? "" : "s"} held` },
|
|
790
737
|
telegram: {
|
|
791
|
-
// The installation's bot: no part of it (not even its id or last characters) for a project-limited account.
|
|
792
738
|
state: minimal ? "" : hasEnv ? "from the environment" : existing === null ? "not set" : "saved",
|
|
793
739
|
current: minimal ? "" : hasEnv ? `set in the environment (${TOKEN_ENV}), which takes precedence over anything saved here` : existing === null ? "not set" : `saved: ${redactToken(existing.token)} (bot ${existing.botId})`,
|
|
794
740
|
delivery: minimal ? null : telegramDeliveryWords(store, telegramBot), failing: !minimal && telegramTrouble(store, telegramBot),
|
|
795
741
|
},
|
|
796
742
|
email: who.role === "approver" && csrf !== "" && !minimal ? (() => {
|
|
797
|
-
// v87: the mail server flows send email through; the password is never shown back.
|
|
798
|
-
// v89: where Inbox triggers read it, and a connected Google account (its client secret is never shown back either).
|
|
799
743
|
const email = readEmailSettings(options.configDir ?? null), google = (() => { try {
|
|
800
744
|
return readGoogleMail(options.configDir ?? null);
|
|
801
745
|
}
|
|
@@ -824,6 +768,7 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
824
768
|
return null;
|
|
825
769
|
return { owner: who.authority !== "full", passwordSet: store.accountOf(who.name)?.passwordSet === true, canTurnOff: who.authority === "full" && operator };
|
|
826
770
|
})(),
|
|
771
|
+
advanced: { on: requestContext.getStore()?.advanced !== false, canChange: who.via === "cookie" },
|
|
827
772
|
backup: lastBackup === null ? null : lastBackup.ok === false
|
|
828
773
|
? { failed: true, words: `Failed ${when(lastBackup.startedAt)}${lastBackup.error === null ? "" : `: ${lastBackup.error}`}` }
|
|
829
774
|
: { failed: false, words: lastBackup.finishedAt === null ? "Backing up now" : `Backed up ${when(lastBackup.finishedAt)}` },
|
|
@@ -835,8 +780,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
835
780
|
...(script === null ? {} : { functional: { script, ...(group === "alerts" ? { fetches: true } : {}) } }),
|
|
836
781
|
}));
|
|
837
782
|
}
|
|
838
|
-
// A person says a provider's sign-in works again: its sign-in pause
|
|
839
|
-
// lifts, its tasks may start, and one short message says so.
|
|
840
783
|
async function providerResume(ctx) {
|
|
841
784
|
const { url, who, response } = ctx;
|
|
842
785
|
const provider = url.pathname.split("/")[2];
|
|
@@ -847,8 +790,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
847
790
|
liftAuthPause(store, provider, "person", who.name, clock());
|
|
848
791
|
return redirect(response, "/tasks");
|
|
849
792
|
}
|
|
850
|
-
// The update notice is dismissed per browser and per version: a newer release shows it again.
|
|
851
|
-
// Cockpit B2: Forget — nothing verified on this session before now counts as fresh (a CSRF-checked post, like every act).
|
|
852
793
|
async function forgetPassword(ctx) {
|
|
853
794
|
const { who, response, posted } = ctx;
|
|
854
795
|
const body = readForm(posted, CONSOLE_FORMS.forgetPassword);
|
|
@@ -874,7 +815,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
874
815
|
}
|
|
875
816
|
return redirect(response, safeReturn(body.get("return") ?? "/settings/system#updates"));
|
|
876
817
|
}
|
|
877
|
-
// The daily check's switch: an installation setting, so an operator's. (Its own address: POST /settings/updates starts an update.)
|
|
878
818
|
async function updatesChecks(ctx) {
|
|
879
819
|
const { who, response, posted } = ctx;
|
|
880
820
|
const body = readForm(posted, CONSOLE_FORMS.updatesChecks);
|
|
@@ -956,13 +896,10 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
956
896
|
try {
|
|
957
897
|
content = (skillsHtml(skillsView(store, repo, who.name), who.session.csrf, true, { error: message, draft: Object.fromEntries(['method', 'content', 'url', 'sample', 'sha'].map(k => [k, body.get(k) ?? ''])) }));
|
|
958
898
|
}
|
|
959
|
-
catch {
|
|
899
|
+
catch { }
|
|
960
900
|
return sendScreen(response, 409, screen('Skills', settingsSubPage("agents", "Skills", html `${content}`), { chrome: chromeFor(repo, 'settings'), functional: { script: skillsScript() } }));
|
|
961
901
|
}
|
|
962
902
|
};
|
|
963
|
-
// v105: set or remove a monthly budget. An instance operator, with a step-up; the ledger keeps before → after. The
|
|
964
|
-
// amount is checked before the password (nothing is written before the password is proved), so a refused amount
|
|
965
|
-
// shows next to its field with the person's draft kept.
|
|
966
903
|
async function spendBudget(ctx) {
|
|
967
904
|
const { who, response, now, posted } = ctx;
|
|
968
905
|
const body = readForm(posted, CONSOLE_FORMS.spendBudget);
|
|
@@ -996,7 +933,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
996
933
|
const saved = store.setBudget({ scope, key, limitMicrousd: Math.round(dollars) * 1_000_000, hardStop: body.get("stop") === "1" }, who.name, now);
|
|
997
934
|
return done(`${label}: ${spendUsd(saved.limitMicrousd)} a month${saved.hardStop ? ", new API work pauses at the limit" : ", alerts only"}.`);
|
|
998
935
|
}
|
|
999
|
-
// Settings → Project → Builds at once: an approver for the project sets it; the ledger keeps before → after.
|
|
1000
936
|
async function projectConcurrency(ctx) {
|
|
1001
937
|
const { who, response, now, posted } = ctx;
|
|
1002
938
|
const body = readForm(posted, CONSOLE_FORMS.projectConcurrency);
|
|
@@ -1018,8 +954,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1018
954
|
store.bumpWake();
|
|
1019
955
|
return back("said", changed.before === changed.after ? "Nothing changed." : `Saved. Up to ${n} at once.`);
|
|
1020
956
|
}
|
|
1021
|
-
// Settings → Project → Live view (live-detail.ts): an approver for the project shows commands with their password,
|
|
1022
|
-
// or hides them in one step; the ledger keeps each change. It applies from the next run.
|
|
1023
957
|
async function projectLiveView(ctx) {
|
|
1024
958
|
const { who, response, now, posted } = ctx;
|
|
1025
959
|
const body = readForm(posted, CONSOLE_FORMS.projectLiveView);
|
|
@@ -1034,15 +968,12 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1034
968
|
return back("said", setLiveCommands(store, { repo, commands: false, by: who.name, via: "the console" }, now).said);
|
|
1035
969
|
if (act !== "on")
|
|
1036
970
|
return back("problem", "That change isn't available.");
|
|
1037
|
-
// Single use, for this person and exactly this change: a replayed or copied form changes nothing.
|
|
1038
971
|
if (!consumeApprovalNonce(body.get("nonce") ?? "", who.name, LIVE_VIEW_CONSENT, liveViewConsentDigest(repo)))
|
|
1039
972
|
return back("problem", "That form was already used or is out of date. Try again from this page.");
|
|
1040
973
|
if (!authenticateApprover(who, body.get("password") ?? "", repo).ok)
|
|
1041
974
|
return back("problem", "Enter your Toolroll password to show commands.");
|
|
1042
975
|
return back("said", setLiveCommands(store, { repo, commands: true, by: who.name, via: "the console" }, now).said);
|
|
1043
976
|
}
|
|
1044
|
-
// Settings → Project → Network (egress.ts): what the project's builds may reach. An approver for the project changes it
|
|
1045
|
-
// with their password typed now; the ledger keeps before → after. New scopes use it; approved ones keep theirs.
|
|
1046
977
|
async function projectNetwork(ctx) {
|
|
1047
978
|
const { who, response, now, posted } = ctx;
|
|
1048
979
|
const body = readForm(posted, CONSOLE_FORMS.projectNetwork);
|
|
@@ -1063,7 +994,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1063
994
|
const same = JSON.stringify(changed.before) === JSON.stringify(changed.after);
|
|
1064
995
|
return back("said", same ? "Nothing changed." : "Saved. Tasks scoped from now on use it; tasks already approved keep the network they were approved with.");
|
|
1065
996
|
}
|
|
1066
|
-
// Delete a project, in two steps: its name, then what goes and the password. An instance operator; the ledger keeps who and what.
|
|
1067
997
|
async function projectDelete(ctx) {
|
|
1068
998
|
const { response, now, posted } = ctx;
|
|
1069
999
|
const who = browserCaller(ctx.who);
|
|
@@ -1096,7 +1026,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1096
1026
|
}
|
|
1097
1027
|
return back("said", `Deleted ${view.name}: ${holdingsWords(done.removed)}.${done.left.length > 0 ? ` Git kept ${done.left.length === 1 ? "one item" : `${done.left.length} items`}: ${done.left.join("; ")}.` : ""}`, "");
|
|
1098
1028
|
}
|
|
1099
|
-
// Sprint 8: an instance operator saves the organisation policy, with a step-up; the ledger keeps each rule's before → after.
|
|
1100
1029
|
async function policySave(ctx) {
|
|
1101
1030
|
const { who, response, now, posted } = ctx;
|
|
1102
1031
|
const body = readForm(posted, CONSOLE_FORMS.policy);
|
|
@@ -1112,7 +1041,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1112
1041
|
const same = Object.keys(before).every(rule => before[rule] === after[rule]);
|
|
1113
1042
|
return back("said", same ? "Nothing changed." : "Policy saved.");
|
|
1114
1043
|
}
|
|
1115
|
-
// v102: an instance operator changes a project's approval rules, with a step-up; the ledger keeps before → after.
|
|
1116
1044
|
async function approvalSave(ctx) {
|
|
1117
1045
|
const { who, response, now, posted } = ctx;
|
|
1118
1046
|
const body = readForm(posted, CONSOLE_FORMS.approval);
|
|
@@ -1133,8 +1061,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1133
1061
|
store.setApprovalRules(repo, next, who.name, now);
|
|
1134
1062
|
return back("said", `Saved. ${rulesSummary(next)}`);
|
|
1135
1063
|
}
|
|
1136
|
-
// v112: request limits for API tokens (request-budget.ts). An instance operator, in a browser, with their password;
|
|
1137
|
-
// never over /api/cli or /mcp (a token never reaches a console form).
|
|
1138
1064
|
async function requestLimitsSave(ctx) {
|
|
1139
1065
|
const { who, response, now, posted } = ctx;
|
|
1140
1066
|
const body = readForm(posted, CONSOLE_FORMS.requestLimits);
|
|
@@ -1172,7 +1098,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1172
1098
|
const found = await providerFor(before.issuer);
|
|
1173
1099
|
return found.ok ? back("said", `${before.label} answers: it's ready for people to sign in.`) : back("problem", found.said);
|
|
1174
1100
|
}
|
|
1175
|
-
// Sign-in methods and the identity provider are the login itself: a credential act, a password typed now.
|
|
1176
1101
|
if (!authenticateCredential(who, body.get("password") ?? "").ok)
|
|
1177
1102
|
return back("problem", "Enter your Toolroll password to change sign-in.");
|
|
1178
1103
|
if (action === "remove") {
|
|
@@ -1190,13 +1115,11 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1190
1115
|
scopes: body.get("scopes") ?? "", groupsClaim: body.get("groups-claim") ?? "", passwords: body.get("passwords") ?? "", rules }, before);
|
|
1191
1116
|
if (!saved.ok)
|
|
1192
1117
|
return back("problem", saved.said);
|
|
1193
|
-
// The provider has to answer before anyone depends on it.
|
|
1194
1118
|
runtime.ssoProvider = null;
|
|
1195
1119
|
const found = await providerFor(saved.settings.issuer);
|
|
1196
1120
|
store.recordAction({ at: now.toISOString(), actor: who.name, repo: null, taskId: null, runId: null, action: before === null ? "sign-in with a provider turned on" : "sign-in with a provider changed", outcome: "changed", source: "policy", detail: ssoChangeWords(before, saved.settings) });
|
|
1197
1121
|
return found.ok ? back("said", `Saved. People can sign in with ${saved.settings.label}.`) : back("problem", `Saved, but ${saved.settings.label} didn't answer: ${found.said}`);
|
|
1198
1122
|
}
|
|
1199
|
-
// Settings → Updates: start the `toolroll update` job. A step-up; the job writes the ledger entries.
|
|
1200
1123
|
const updatesAct = (op) => async (ctx) => {
|
|
1201
1124
|
const { who, response, posted } = ctx;
|
|
1202
1125
|
const body = readForm(posted, CONSOLE_FORMS.updates);
|
|
@@ -1241,10 +1164,8 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1241
1164
|
abandonRuntimeUpdate(stateDir, prepared.id, `The update could not start: ${error.message}`, clock());
|
|
1242
1165
|
return back("problem", `The update could not start: ${error.message}`);
|
|
1243
1166
|
}
|
|
1244
|
-
// The job records its first step within moments; show it rather than the old page.
|
|
1245
1167
|
return back("said", when === "at" ? `Update to ${version} scheduled for 03:00.` : `Updating to ${version}.`);
|
|
1246
1168
|
};
|
|
1247
|
-
// v105: change how long each kind of data is kept. A step-up; the ledger keeps before → after for each kind.
|
|
1248
1169
|
async function retentionSave(ctx) {
|
|
1249
1170
|
const { who, response, now, posted } = ctx;
|
|
1250
1171
|
const body = readForm(posted, CONSOLE_FORMS.retention);
|
|
@@ -1252,7 +1173,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1252
1173
|
if (!authenticateApprover(who, body.get("password") ?? "").ok)
|
|
1253
1174
|
return back("problem", "Enter your Toolroll password to change retention.");
|
|
1254
1175
|
const before = store.retentionPeriods();
|
|
1255
|
-
// Only what the page offers (or the period already set): a hand-made value doesn't save.
|
|
1256
1176
|
const offered = (kind, days) => days !== undefined && periodChoices(kind, before[kind]).includes(days) ? days : undefined;
|
|
1257
1177
|
const chosen = RETENTION_KINDS.map(({ kind }) => ({ kind, days: body.has(kind) ? offered(kind, parsePeriod(body.get(kind) ?? "")) : before[kind] }));
|
|
1258
1178
|
if (chosen.some(one => one.days === undefined))
|
|
@@ -1262,15 +1182,12 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1262
1182
|
store.setRetentionPeriod(one.kind, one.days ?? null, who.name, now);
|
|
1263
1183
|
return back("said", changed.length === 0 ? "Nothing changed." : "Saved. The next daily sweep uses these periods.");
|
|
1264
1184
|
}
|
|
1265
|
-
// Settings → Storage: when a finished task's clean checkout goes, cleaning up what the preview showed, and throwing
|
|
1266
|
-
// away a checkout kept for its changes. Each takes the password; the ledger keeps every change and removal.
|
|
1267
1185
|
const storageAct = (op) => async (ctx) => {
|
|
1268
1186
|
const { who, response, now, posted } = ctx;
|
|
1269
1187
|
const body = readForm(posted, CONSOLE_FORMS.storage);
|
|
1270
1188
|
const databaseFile = store.databaseFile();
|
|
1271
1189
|
if (databaseFile === null)
|
|
1272
1190
|
return refuse(response, who, 403, "An instance operator looks after storage.", "/settings");
|
|
1273
|
-
// What the page shows next is measured again after the change.
|
|
1274
1191
|
const said = sayTo(response, "/settings/storage");
|
|
1275
1192
|
const back = async (kind, words) => { await measureStorage(databaseFile).catch(() => undefined); return said(kind, words); };
|
|
1276
1193
|
const what = op === "clean" ? "clean up" : op === "discard" ? "discard a task folder" : "change automatic cleanup";
|
|
@@ -1290,7 +1207,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1290
1207
|
}
|
|
1291
1208
|
const pool = storagePool(databaseFile);
|
|
1292
1209
|
if (op === "clean") {
|
|
1293
|
-
// Only what the preview showed goes: when that changed since, the person looks again.
|
|
1294
1210
|
const plan = await checkoutPlan(store, pool, clock(), { manual: true });
|
|
1295
1211
|
if (plan.go.length === 0)
|
|
1296
1212
|
return back("said", "Nothing to clean up.");
|
|
@@ -1303,8 +1219,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1303
1219
|
const done = await discardCheckout(store, pool, body.get("path") ?? "", now, who.name);
|
|
1304
1220
|
return done.ok ? back("said", `Discarded, about ${bytesWords(done.bytes)}. Its branch stays.`) : back("problem", done.message);
|
|
1305
1221
|
};
|
|
1306
|
-
// Pull requests for one project: turn on (the checks run again and must match what the page showed), merge
|
|
1307
|
-
// settings, or turn off. Each takes the password and lands in the ledger.
|
|
1308
1222
|
async function pullRequestsSave(ctx) {
|
|
1309
1223
|
const { who, response, now, posted } = ctx;
|
|
1310
1224
|
const body = readForm(posted, CONSOLE_FORMS.pullRequests);
|
|
@@ -1344,8 +1258,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1344
1258
|
}
|
|
1345
1259
|
return back("problem", "That change isn't available.");
|
|
1346
1260
|
}
|
|
1347
|
-
// Checks for one project: the level, or the quick command (approved like `verify set --quick`). Each takes
|
|
1348
|
-
// the password and lands in the ledger.
|
|
1349
1261
|
async function checksSave(ctx) {
|
|
1350
1262
|
const { who, response, now, posted } = ctx;
|
|
1351
1263
|
const body = readForm(posted, CONSOLE_FORMS.checks);
|
|
@@ -1361,19 +1273,16 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1361
1273
|
if (!authenticateApprover(who, body.get("password") ?? "", repo).ok)
|
|
1362
1274
|
return back("problem", "Enter your Toolroll password to change checks.");
|
|
1363
1275
|
const act = body.get("act");
|
|
1364
|
-
// The automatic review switch: the policy log keeps before → after.
|
|
1365
1276
|
if (act === "review") {
|
|
1366
1277
|
const on = body.get("on") === "1";
|
|
1367
1278
|
store.setReviewSwitch(repo, on, who.name, now);
|
|
1368
1279
|
return back("said", on ? "Automatic review is on." : "Automatic review is off.");
|
|
1369
1280
|
}
|
|
1370
|
-
// Batch checks: off by default; the ledger keeps before → after.
|
|
1371
1281
|
if (act === "batch") {
|
|
1372
1282
|
const on = body.get("on") === "1";
|
|
1373
1283
|
const changed = setProjectBatchChecks(store, repo, on, who.name, now);
|
|
1374
1284
|
return back("said", !changed.changed ? "Saved." : on ? "Batch checks are on." : "Batch checks are off.");
|
|
1375
1285
|
}
|
|
1376
|
-
// Small tasks start right away: a person's own logged settings act, behind this form's password.
|
|
1377
1286
|
if (act === "small-tasks") {
|
|
1378
1287
|
const on = body.get("on") === "1";
|
|
1379
1288
|
store.upsertProject(repo, projectName(repo), now);
|
|
@@ -1409,7 +1318,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1409
1318
|
}
|
|
1410
1319
|
return back("problem", "That change isn't available.");
|
|
1411
1320
|
}
|
|
1412
|
-
// Sprint 8: back up now. An instance operator; the outcome is kept like a scheduled one's.
|
|
1413
1321
|
async function backupStart(ctx) {
|
|
1414
1322
|
const { who, response } = ctx;
|
|
1415
1323
|
const databaseFile = store.databaseFile();
|
|
@@ -1420,7 +1328,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1420
1328
|
return redirect(response, `/settings/backups?problem=${encodeURIComponent(`Backed up. The activity log failed its tamper check, so it was not anchored: ${made.checkpoint.problem}`)}`);
|
|
1421
1329
|
return redirect(response, made.ok ? `/settings/backups?said=${encodeURIComponent("Backed up.")}` : `/settings/backups?problem=${encodeURIComponent(`The backup failed: ${made.error}`)}`);
|
|
1422
1330
|
}
|
|
1423
|
-
// Sprint 8: change the backup schedule. A step-up; the ledger keeps before → after.
|
|
1424
1331
|
async function backupsSave(ctx) {
|
|
1425
1332
|
const { who, response, now, posted } = ctx;
|
|
1426
1333
|
const body = readForm(posted, CONSOLE_FORMS.backups);
|
|
@@ -1444,8 +1351,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1444
1351
|
if (problem !== null)
|
|
1445
1352
|
return back("problem", problem);
|
|
1446
1353
|
}
|
|
1447
|
-
// The continuous copy (live-backup.ts): how often, and a folder that is a plain, private folder of this user's
|
|
1448
|
-
// outside every project and checkout. A form without these fields leaves it as it is.
|
|
1449
1354
|
const liveBefore = liveBackupState(store).settings;
|
|
1450
1355
|
const liveEvery = body.get("live_every") ?? null;
|
|
1451
1356
|
const liveMinutes = Number(liveEvery);
|
|
@@ -1464,7 +1369,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1464
1369
|
keep: liveBefore.keep, folder: liveFolder }, who.name, now);
|
|
1465
1370
|
return back("said", every === "off" ? "Saved. Scheduled backups are off." : "Saved.");
|
|
1466
1371
|
}
|
|
1467
|
-
// v105: download everything as a .zip. An instance operator, with a step-up; the ledger records it.
|
|
1468
1372
|
async function dataExport(ctx) {
|
|
1469
1373
|
const { who, response, now, posted } = ctx;
|
|
1470
1374
|
const body = readForm(posted, CONSOLE_FORMS.data);
|
|
@@ -1478,7 +1382,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1478
1382
|
"cache-control": "no-store", "x-content-type-options": "nosniff" });
|
|
1479
1383
|
return void response.end(zip);
|
|
1480
1384
|
}
|
|
1481
|
-
// Settings → Flows → Switch on: a starter flow's zones and trigger, made together.
|
|
1482
1385
|
async function flowsOn(ctx) {
|
|
1483
1386
|
const { who, response, posted } = ctx;
|
|
1484
1387
|
const body = readForm(posted, CONSOLE_FORMS.flowsOn);
|
|
@@ -1495,7 +1398,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1495
1398
|
const switched = switchOnStarter(store, starter, repo, who.name, clock(), options.configDir ?? null);
|
|
1496
1399
|
return switched.ok ? back("said", switched.said) : back("problem", switched.said);
|
|
1497
1400
|
}
|
|
1498
|
-
// Settings → Integrations → youiyoux → Turn off / Turn on: whether a project's change requests become tasks.
|
|
1499
1401
|
async function integrationsYouiyoux(ctx) {
|
|
1500
1402
|
const { who, response, posted } = ctx;
|
|
1501
1403
|
const body = readForm(posted, CONSOLE_FORMS.integrationsYouiyoux);
|
|
@@ -1510,7 +1412,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1510
1412
|
setYouiyouxIntake(store, repo, on, who.name, clock());
|
|
1511
1413
|
return back("said", on ? `youiyoux requests in ${basename(repo)} become tasks again.` : `youiyoux requests in ${basename(repo)} are off.`);
|
|
1512
1414
|
}
|
|
1513
|
-
// Settings → Integrations → Check connection: one harmless read-only check of one integration, now.
|
|
1514
1415
|
async function integrationsTest(ctx) {
|
|
1515
1416
|
const { who, response, posted } = ctx;
|
|
1516
1417
|
const body = readForm(posted, CONSOLE_FORMS.integrationsTest);
|
|
@@ -1524,7 +1425,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1524
1425
|
return checked.state === "connected" ? back("said", `${checked.name} works${checked.account === null ? "" : ` (${checked.account})`}.`)
|
|
1525
1426
|
: back("problem", `${checked.name}: ${checked.action.kind === "fix" ? checked.action.words : "not set up."}`);
|
|
1526
1427
|
}
|
|
1527
|
-
// v104: change where monitoring goes. A step-up; the ledger keeps before → after (addresses, never secrets).
|
|
1528
1428
|
async function monitoringSave(ctx) {
|
|
1529
1429
|
const { who, request, response, now, posted } = ctx;
|
|
1530
1430
|
const body = readForm(posted, CONSOLE_FORMS.monitoring);
|
|
@@ -1534,13 +1434,11 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1534
1434
|
if (!authenticateApprover(who, body.get("password") ?? "").ok)
|
|
1535
1435
|
return back("problem", "Enter your Toolroll password to change monitoring.");
|
|
1536
1436
|
const before = readMonitoring(options.configDir);
|
|
1537
|
-
// Never into Toolroll's own folder, a project or the build checkouts: an agent could read the stream there.
|
|
1538
1437
|
const saved = saveMonitoring(options.configDir, { webhook: body.get("webhook") ?? "", folder: body.get("folder") ?? "", tracesEndpoint: body.get("traces") ?? "",
|
|
1539
1438
|
headerName: body.get("header-name") ?? "", headerValue: body.get("header-value") ?? "", rotate: body.get("rotate") === "1" }, before, [...new Set([...managedRepos(), ...store.knownRepos(), ...(options.poolRoot === undefined ? [] : [options.poolRoot])])]);
|
|
1540
1439
|
if (!saved.ok)
|
|
1541
1440
|
return back("problem", saved.said);
|
|
1542
1441
|
const after = saved.settings;
|
|
1543
|
-
// A destination that's new or points elsewhere starts over on the monitoring loop's next pass.
|
|
1544
1442
|
const change = monitoringChange(before, after, saved.secret !== null);
|
|
1545
1443
|
if (change !== null) {
|
|
1546
1444
|
store.recordAction({ at: now.toISOString(), actor: who.name, repo: null, taskId: null, runId: null, action: "monitoring changed", outcome: "changed", source: "policy", detail: change });
|
|
@@ -1557,23 +1455,17 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1557
1455
|
const reachable = (one) => visible(one) && consoleProjects().includes(one);
|
|
1558
1456
|
if (!reachable(repo))
|
|
1559
1457
|
return refuse(response, who, 403, "That project is outside your access.", "/projects");
|
|
1560
|
-
// "Also connect to …": a service connected on the shown project, signed in again for another project.
|
|
1561
1458
|
const also = body.get("also");
|
|
1562
1459
|
const split = also === null ? -1 : also.indexOf(":");
|
|
1563
1460
|
const service = oneClickOf(also === null ? body.get("service") ?? "" : split > 0 ? also.slice(0, split) : "");
|
|
1564
|
-
// An app on this computer (Figma's desktop app) connects here, never "also" elsewhere.
|
|
1565
1461
|
const local = service === null && also === null ? localConnectOf(body.get("service") ?? "") : null;
|
|
1566
1462
|
const chosen = service ?? local;
|
|
1567
1463
|
const target = also === null ? repo : split > 0 ? also.slice(split + 1) : "";
|
|
1568
|
-
// From a gallery template that uses this tool: it comes back to that template's page, for this project.
|
|
1569
1464
|
const gallery = also === null && chosen !== null ? galleryTemplateOf(body.get("template") ?? "") : null;
|
|
1570
1465
|
const template = gallery !== null && (gallery.tools ?? []).includes(chosen.id) ? gallery.id : null;
|
|
1571
1466
|
const kit = template === null ? kitOf(body.get("kit") ?? "")?.id ?? null : null;
|
|
1572
|
-
// A Connect that fails comes back to its own button, where the reason is said (no #fragment: one stops the alert's
|
|
1573
|
-
// autofocus); an "Also connect to" refusal goes back to the Connect card.
|
|
1574
1467
|
const back = (words, page = repo) => template !== null ? redirect(response, `/flows/new/${template}?repo=${encodeURIComponent(page)}&problem=${encodeURIComponent(words)}`)
|
|
1575
1468
|
: redirect(response, `/settings/tools?repo=${encodeURIComponent(page)}${kit === null ? "" : `&kit=${kit}`}${chosen === null || also !== null ? "" : `&connect=${chosen.id}`}&problem=${encodeURIComponent(words)}${also === null ? "" : "#connect"}`);
|
|
1576
|
-
// The page posts the project it showed; a post from a page showing another project is stale.
|
|
1577
1469
|
const shown = body.get("shown") ?? "";
|
|
1578
1470
|
if (shown !== repo)
|
|
1579
1471
|
return back("The project changed; connect again.", reachable(shown) ? shown : repo);
|
|
@@ -1589,7 +1481,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1589
1481
|
}
|
|
1590
1482
|
if (!authenticateApprover(who, body.get("password") ?? "").ok)
|
|
1591
1483
|
return back("Enter your Toolroll password to connect a tool.");
|
|
1592
|
-
// An app on this computer: added like a common tool and tested; one that can't be reached isn't kept.
|
|
1593
1484
|
if (local !== null) {
|
|
1594
1485
|
const had = projectToolsOf(store, repo).find(one => one.name === local.id);
|
|
1595
1486
|
if (had !== undefined && localAppOf(had.spec) === null)
|
|
@@ -1614,7 +1505,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1614
1505
|
const origin = consoleOrigin(request.headers.host);
|
|
1615
1506
|
if (origin === null)
|
|
1616
1507
|
return back("Connect tools from this computer (localhost) or from your https address.");
|
|
1617
|
-
// Reconnect read-only (from a connected service's Tools entry): the same sign-in, asking only to read.
|
|
1618
1508
|
const readOnly = also === null && body.get("access") === "read";
|
|
1619
1509
|
const started = await startConnect({ service: service.id, repo: target, by: who.name, origin, kit: also === null ? kit : null, template, readOnly }, options.connectFetch ?? fetch);
|
|
1620
1510
|
if (!started.ok)
|
|
@@ -1622,8 +1512,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1622
1512
|
for (const [key, visit] of connectVisits)
|
|
1623
1513
|
if (visit.expires < Date.now())
|
|
1624
1514
|
connectVisits.delete(key);
|
|
1625
|
-
// The password above proves one thing: this connection, by this account as it is now, and (from a kit whose subagent
|
|
1626
|
-
// is set up) letting that subagent use this tool in this project. The callback holds the visit to exactly that.
|
|
1627
1515
|
const kitSet = kit === null || also !== null ? null : kitOf(kit);
|
|
1628
1516
|
const installed = kitSet === null || !kitSet.tools.some(one => one.tool === service.id) ? null : kitInstalled(store, kitSet, target);
|
|
1629
1517
|
connectVisits.set(started.state, { ...started.visit, generation: store.accountOf(who.name)?.generation ?? -1,
|
|
@@ -1637,7 +1525,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1637
1525
|
if (!visible(repo) || !consoleProjects().includes(repo))
|
|
1638
1526
|
return refuse(response, who, 403, "That project is outside your access.", "/projects");
|
|
1639
1527
|
const back = sayTo(response, `/settings/tools?repo=${encodeURIComponent(repo)}`);
|
|
1640
|
-
// As for Connect: a post from a page that showed another project is refused, never applied here.
|
|
1641
1528
|
const shown = body.get("shown") ?? "";
|
|
1642
1529
|
if (shown !== repo) {
|
|
1643
1530
|
const page = visible(shown) && consoleProjects().includes(shown) ? shown : repo;
|
|
@@ -1645,7 +1532,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1645
1532
|
}
|
|
1646
1533
|
const action = body.get("action") ?? "";
|
|
1647
1534
|
const name = body.get("name") ?? "";
|
|
1648
|
-
// Anything that adds what a build can run or reach, or a secret, needs the password.
|
|
1649
1535
|
if (["add-catalog", "add-custom", "import", "secret"].includes(action) && !authenticateApprover(who, body.get("password") ?? "").ok) {
|
|
1650
1536
|
return back("problem", "Enter your Toolroll password to change this project's tools.");
|
|
1651
1537
|
}
|
|
@@ -1677,7 +1563,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1677
1563
|
const wanted = body.getAll("import");
|
|
1678
1564
|
if (wanted.length === 0)
|
|
1679
1565
|
return back("problem", "Choose at least one tool to add.");
|
|
1680
|
-
// The project's own .mcp.json read now, off the console's thread (folder-look.ts).
|
|
1681
1566
|
let projectConfig;
|
|
1682
1567
|
if (options.identities !== undefined) {
|
|
1683
1568
|
const looked = await lookProjectMcp(repo);
|
|
@@ -1730,8 +1615,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1730
1615
|
async function appearanceSave(ctx) {
|
|
1731
1616
|
const { who, response, posted } = ctx;
|
|
1732
1617
|
const body = readForm(posted, CONSOLE_FORMS.appearance);
|
|
1733
|
-
// A per-browser preference, not a shared setting: it lives in this
|
|
1734
|
-
// person's own cookie and never in the database.
|
|
1735
1618
|
const accentField = body.get("accent");
|
|
1736
1619
|
if (accentField !== null) {
|
|
1737
1620
|
const accent = normalHex(accentField);
|
|
@@ -1740,7 +1623,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1740
1623
|
response.setHeader("Set-Cookie", accent === DEFAULT_ACCENT
|
|
1741
1624
|
? "so-accent=; SameSite=Lax; Path=/; Max-Age=0"
|
|
1742
1625
|
: `so-accent=${accent.slice(1)}; SameSite=Lax; Path=/; Max-Age=31536000`);
|
|
1743
|
-
// The picker saves in the background as the colour settles; a plain form post goes back.
|
|
1744
1626
|
if (body.get("quiet") === "1") {
|
|
1745
1627
|
response.writeHead(204);
|
|
1746
1628
|
response.end();
|
|
@@ -1804,7 +1686,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1804
1686
|
}
|
|
1805
1687
|
return redirect(response, `/settings/knowledge?repo=${encodeURIComponent(repo)}&saved=1`);
|
|
1806
1688
|
}
|
|
1807
|
-
/** A lesson note: a person's own words, accepted as a decision through the one proposal writer, or rejected. */
|
|
1808
1689
|
async function knowledgeNote(ctx) {
|
|
1809
1690
|
const { who, response, now, posted } = ctx;
|
|
1810
1691
|
const body = readForm(posted, CONSOLE_FORMS.knowledgeNote);
|
|
@@ -1824,8 +1705,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1824
1705
|
}
|
|
1825
1706
|
return redirect(response, `/settings/knowledge?repo=${encodeURIComponent(repo)}&saved=1`);
|
|
1826
1707
|
}
|
|
1827
|
-
/** Project memory's clean-up: a person's request, accepting or rejecting one proposal, and restores. Every writer
|
|
1828
|
-
* proves the person inside its own transaction. */
|
|
1829
1708
|
async function knowledgeTidy(ctx) {
|
|
1830
1709
|
const { who, response, now, posted } = ctx;
|
|
1831
1710
|
const body = readForm(posted, CONSOLE_FORMS.knowledgeTidy);
|
|
@@ -1834,7 +1713,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1834
1713
|
return refuse(response, who, 403, 'That project is outside your access.', '/settings/knowledge');
|
|
1835
1714
|
const back = `/settings/knowledge?repo=${encodeURIComponent(repo)}`;
|
|
1836
1715
|
const said = (id) => /^[0-9]{1,12}$/.test(id) ? Number(id) : null;
|
|
1837
|
-
// Only a browser session is a person's proof here; the writers refuse anything else.
|
|
1838
1716
|
const proof = who.via === 'cookie' ? 'session' : 'remote-token';
|
|
1839
1717
|
try {
|
|
1840
1718
|
if (action === 'propose')
|
|
@@ -1911,7 +1789,7 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1911
1789
|
try {
|
|
1912
1790
|
content = (knowledgeHtml(knowledgeView(store, repo, who.name), who.session.csrf, true, draft, error instanceof Error ? error.message : 'Save failed. Your draft is below.'));
|
|
1913
1791
|
}
|
|
1914
|
-
catch {
|
|
1792
|
+
catch { }
|
|
1915
1793
|
return sendScreen(response, 409, screen('Knowledge', settingsSubPage("agents", "Knowledge", html `${content}`), { chrome: chromeFor(repo, 'settings') }));
|
|
1916
1794
|
}
|
|
1917
1795
|
return redirect(response, `/settings/knowledge?repo=${encodeURIComponent(repo)}&saved=1`);
|
|
@@ -1995,7 +1873,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
1995
1873
|
savePrimary(dir, "slack");
|
|
1996
1874
|
return redirect(response, "/settings/slack");
|
|
1997
1875
|
}
|
|
1998
|
-
// Connecting or pairing opens a way to act from Slack: a credential act. Unpairing or disconnecting only closes one.
|
|
1999
1876
|
if (!(action === "connect" || action === "pair" ? authenticateCredential(who, body.get("password") ?? "") : authenticateApprover(who, body.get("password") ?? "")).ok)
|
|
2000
1877
|
return show("Enter your Toolroll password to change Slack access.", 403);
|
|
2001
1878
|
const generation = store.accountOf(who.name).generation;
|
|
@@ -2008,7 +1885,6 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
2008
1885
|
if (credentials || loadSlackCredentials(dir))
|
|
2009
1886
|
return show("Disconnect the current Slack app before connecting another.", 409);
|
|
2010
1887
|
saveSlackCredentials(dir, checked);
|
|
2011
|
-
// A fresh connection asks for the 👀 again at once (an app reinstalled with reactions:write).
|
|
2012
1888
|
state.deleteMeta(checked.installation, ACK_REFUSED_META);
|
|
2013
1889
|
}
|
|
2014
1890
|
catch (error) {
|
|
@@ -2040,13 +1916,9 @@ ${restoreHtml(chosen, retired, undoableMerges(store, chosen), disabledLessons(st
|
|
|
2040
1916
|
};
|
|
2041
1917
|
async function telegramRetry(ctx) {
|
|
2042
1918
|
const { who, response, now } = ctx;
|
|
2043
|
-
// The signed-in person's own unsent replies only: already written and fenced on the pairing; this sends them again now.
|
|
2044
1919
|
store.retryTelegramReplies(who.name, now);
|
|
2045
1920
|
return redirect(response, "/settings/telegram");
|
|
2046
1921
|
}
|
|
2047
|
-
// Approving from chat, as the person's lasting setting (chat-approval.ts): for all their projects or one. Turning it
|
|
2048
|
-
// on or changing its limits is the mode's ceremony (the exact terms, a single-use nonce bound to them, the password
|
|
2049
|
-
// typed again); turning it off is one step, csrf only. Every change is a ledger line.
|
|
2050
1922
|
const chatApprovalAct = (step) => async (ctx) => {
|
|
2051
1923
|
const { request, response, now, posted } = ctx;
|
|
2052
1924
|
const who = browserCaller(ctx.who);
|
|
@@ -2094,16 +1966,12 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2094
1966
|
const { request, response, now, posted } = ctx;
|
|
2095
1967
|
const who = browserCaller(ctx.who);
|
|
2096
1968
|
const body = readForm(posted, CONSOLE_FORMS.telegramPair);
|
|
2097
|
-
// The person's own pairing, under their password: a code minted for
|
|
2098
|
-
// them alone, or their own chats revoked. Teammates' pairings are
|
|
2099
|
-
// never touched from here.
|
|
2100
1969
|
const botId = options.telegramTokenFile === undefined ? null : loadBotToken(process.env, options.telegramTokenFile)?.botId ?? null;
|
|
2101
1970
|
const show = (problem, status = 400) => sendScreen(response, status, screen("Telegram", telegramSettingsHtml(store, botId, who.name, { problem }), { chrome: chromeFor(projectOf(who, request) ?? null, "settings") }));
|
|
2102
1971
|
if (body.getAll("password").length > 1)
|
|
2103
1972
|
return show("Submit one value for each field.");
|
|
2104
1973
|
if (botId === null)
|
|
2105
1974
|
return show("Connect the Telegram bot first.", 409);
|
|
2106
|
-
// Pairing a phone is a credential act (a typed password, always); unpairing only closes a way in.
|
|
2107
1975
|
if (op === "unpair" && authenticateApprover(who, body.get("password") ?? "").ok) {
|
|
2108
1976
|
store.unpairTelegram(botId, who.name, now);
|
|
2109
1977
|
return redirect(response, "/settings/telegram");
|
|
@@ -2242,8 +2110,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2242
2110
|
const body = readForm(posted, CONSOLE_FORMS.messaging);
|
|
2243
2111
|
const wanted = (body.get("primary") ?? "").trim();
|
|
2244
2112
|
const facts = effectivePrimary(process.env, options.configDir, loadBotToken(process.env, options.telegramTokenFile) !== null);
|
|
2245
|
-
// Only a CONFIGURED service may page — choosing silence is not a
|
|
2246
|
-
// selection, and an unconfigured primary would page nobody.
|
|
2247
2113
|
if (!isMessagingChannel(wanted) || !facts.configured.includes(wanted)) {
|
|
2248
2114
|
return refuse(response, who, 400, "primary must be one of the configured services");
|
|
2249
2115
|
}
|
|
@@ -2259,8 +2125,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2259
2125
|
if (wanted !== "auto" && wanted !== "bypassPermissions") {
|
|
2260
2126
|
return refuse(response, who, 400, "permissions must be Auto or Full access", "/settings");
|
|
2261
2127
|
}
|
|
2262
|
-
// Widening every new task to Full access takes a password (chat-management.md §0a.3): an ordinary step-up, so a
|
|
2263
|
-
// signed-in session does under Passwordless. Back to Auto narrows, and needs none.
|
|
2264
2128
|
if (wanted === "bypassPermissions" && store.permissionDefault().mode !== "bypassPermissions" && !authenticateApprover(who, body.get("password") ?? "").ok) {
|
|
2265
2129
|
return redirect(response, `/settings/approval?problem=${encodeURIComponent("Enter your Toolroll password to start new tasks with Full access. Nothing changed.")}#defaults`);
|
|
2266
2130
|
}
|
|
@@ -2286,7 +2150,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2286
2150
|
async function notificationsSave(ctx) {
|
|
2287
2151
|
const { who, response, now, posted } = ctx;
|
|
2288
2152
|
const body = readForm(posted, CONSOLE_FORMS.notifications);
|
|
2289
|
-
// Each person's own choice: a closed list of modes and a 24-hour HH:MM, or off.
|
|
2290
2153
|
const mode = body.get("mode"), time = (body.get("digest") ?? "").trim(), shots = body.get("screenshots");
|
|
2291
2154
|
if (mode !== null && mode !== "quiet" && mode !== "all")
|
|
2292
2155
|
return refuse(response, who, 400, "choose Only when I'm needed or Every step", "/settings");
|
|
@@ -2307,7 +2170,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2307
2170
|
async function notificationsMute(ctx) {
|
|
2308
2171
|
const { who, response, now, posted } = ctx;
|
|
2309
2172
|
const body = readForm(posted, CONSOLE_FORMS.notificationsMute);
|
|
2310
|
-
// Each person's own pings: a muted project stays in Tasks and the evening digest.
|
|
2311
2173
|
const repo = body.get("repo") ?? "";
|
|
2312
2174
|
const project = notificationProjects(store, who.name).find(one => one.repo === repo);
|
|
2313
2175
|
if (project === undefined)
|
|
@@ -2321,8 +2183,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2321
2183
|
if (options.telegramTokenFile === undefined)
|
|
2322
2184
|
return refuse(response, who, 404, "There's no page at this address.", "/chat");
|
|
2323
2185
|
const body = readForm(posted, CONSOLE_FORMS.telegramDigest);
|
|
2324
|
-
// The cadence is a closed list of minutes — never a free number from
|
|
2325
|
-
// a form; "off" clears it. Any approver session may set it.
|
|
2326
2186
|
const wanted = (body.get("every") ?? "").trim();
|
|
2327
2187
|
const allowed = { off: null, "30": 30, "60": 60, "240": 240, "720": 720, "1440": 1440 };
|
|
2328
2188
|
if (!(wanted in allowed))
|
|
@@ -2334,8 +2194,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2334
2194
|
const providerKeyAct = (op) => async (ctx) => {
|
|
2335
2195
|
const { who, response, posted } = ctx;
|
|
2336
2196
|
const body = readForm(posted, CONSOLE_FORMS.providerKey);
|
|
2337
|
-
// The central gate already required an ACTIVE approver; the value is
|
|
2338
|
-
// write-only from here — status pages say set/not-set, never bytes.
|
|
2339
2197
|
const provider = body.get("provider") ?? "";
|
|
2340
2198
|
if (!isProviderId(provider))
|
|
2341
2199
|
return refuse(response, who, 400, "unknown provider", "/settings");
|
|
@@ -2350,10 +2208,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2350
2208
|
? `the ${provider} key is removed — ${provider} uses its own login, so builds are unaffected`
|
|
2351
2209
|
: `the ${provider} key is removed — an environment variable, if one exists, takes over`)}#providers`);
|
|
2352
2210
|
}
|
|
2353
|
-
// Validate EVERYTHING before mutating anything (Codex round 5,
|
|
2354
|
-
// finding 2): an invalid key must never persist a mode change it
|
|
2355
|
-
// then hides, a mode equal to the current one is not a "change",
|
|
2356
|
-
// and an unchanged blank form does nothing.
|
|
2357
2211
|
const wantedMode = body.get("auth-mode");
|
|
2358
2212
|
const value = (body.get("value") ?? "").trim();
|
|
2359
2213
|
const modeSelected = wantedMode === "subscription" || wantedMode === "api-key";
|
|
@@ -2361,16 +2215,12 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2361
2215
|
if (!modeSelected && value === "") {
|
|
2362
2216
|
return refuse(response, who, 400, "nothing to change — paste a key or pick a sign-in", "/settings");
|
|
2363
2217
|
}
|
|
2364
|
-
// A selected-but-inapplicable mode (openrouter subscription) refuses
|
|
2365
|
-
// before any write.
|
|
2366
2218
|
if (modeSelected && wantedMode === "subscription" && !SUBSCRIPTION_CAPABLE[provider]) {
|
|
2367
2219
|
return refuse(response, who, 409, `${provider} has no subscription login — it is API-key only`, "/settings");
|
|
2368
2220
|
}
|
|
2369
|
-
// A present key must be plausible BEFORE the mode is touched.
|
|
2370
2221
|
if (value !== "" && !plausibleKey(value)) {
|
|
2371
2222
|
return refuse(response, who, 400, "that does not look like an API key — check the paste and try again", "/settings");
|
|
2372
2223
|
}
|
|
2373
|
-
// Apply the mode only when it actually differs.
|
|
2374
2224
|
const modeChanged = modeSelected && wantedMode !== currentMode;
|
|
2375
2225
|
if (modeChanged)
|
|
2376
2226
|
setAuthMode(provider, wantedMode, providerHome);
|
|
@@ -2378,10 +2228,7 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2378
2228
|
if (value === "") {
|
|
2379
2229
|
return redirect(response, `/settings/agents?said=${encodeURIComponent(modeChanged ? `${provider} now uses ${wantedMode === "api-key" ? "the API key" : "its own subscription / login"}` : `no change — ${provider} already uses ${currentMode === "api-key" ? "the API key" : "its own subscription / login"}`)}#providers`);
|
|
2380
2230
|
}
|
|
2381
|
-
saveProviderKey(provider, value, providerHome);
|
|
2382
|
-
// Verify right now, so a paste gets an immediate yes/no instead of a
|
|
2383
|
-
// failed build later. A stored-but-unreachable key still says so.
|
|
2384
|
-
// In API-key mode the account check tests the stored key, and remembers the answer until the key changes.
|
|
2231
|
+
saveProviderKey(provider, value, providerHome);
|
|
2385
2232
|
const checked = readAuthMode(provider, providerHome) === "api-key" ? await connectionCheck(provider, true) : null;
|
|
2386
2233
|
const verdict = checked?.verdict ?? await verifyProviderKey(provider, value);
|
|
2387
2234
|
const stored = `the ${provider} key is stored`;
|
|
@@ -2398,7 +2245,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2398
2245
|
return redirect(response, `/settings/alerts?problem=${encodeURIComponent(saved.message)}#telegram-token`);
|
|
2399
2246
|
return redirect(response, `/settings/alerts?said=${encodeURIComponent("Bot token saved. Pair your phone on the Telegram page.")}#telegram-token`);
|
|
2400
2247
|
}
|
|
2401
|
-
// v87: the mail server Send email steps use, and a test email to its own address.
|
|
2402
2248
|
const emailAct = (op) => async (ctx) => {
|
|
2403
2249
|
const { who, response, posted } = ctx;
|
|
2404
2250
|
if (who.role !== "approver" || options.configDir === undefined)
|
|
@@ -2410,7 +2256,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2410
2256
|
return saved.ok ? said(saved.said) : said(saved.message, "problem");
|
|
2411
2257
|
}
|
|
2412
2258
|
if (op === "read-test") {
|
|
2413
|
-
// Sign in and open the inbox read-only, as an Inbox trigger's first check does: nothing is read or changed.
|
|
2414
2259
|
const signed = await mailboxAccess(options.configDir, options.googleFetch ?? fetch);
|
|
2415
2260
|
if (!signed.ok)
|
|
2416
2261
|
return said(signed.said);
|
|
@@ -2424,7 +2269,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2424
2269
|
const sent = await (options.mailSender ?? sendThroughServer)(settings, { from: settings.from, to: [settings.from], subject: "Toolroll: test email", text: "This is a test from Toolroll. Send email steps in your flows will come from this address." });
|
|
2425
2270
|
return said(sent.ok ? `Sent a test email to ${settings.from}.` : sent.said);
|
|
2426
2271
|
};
|
|
2427
|
-
// v89: a Google account for email: save the OAuth client and go to Google's consent screen, or disconnect.
|
|
2428
2272
|
const googleAct = (op) => async (ctx) => {
|
|
2429
2273
|
const { who, request, response, posted } = ctx;
|
|
2430
2274
|
if (who.role !== "approver" || options.configDir === undefined)
|
|
@@ -2467,11 +2311,8 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2467
2311
|
planAuto: body.get("plan-auto") === "1",
|
|
2468
2312
|
reviewAuto: false,
|
|
2469
2313
|
reviewRetryAuto: false,
|
|
2470
|
-
// Repairing failed checks: only the explicit choice grants it, with the limit it signs (check-repair.ts).
|
|
2471
2314
|
repairAuto: body.get("repair-auto") === "1",
|
|
2472
2315
|
repairMaxAttempts: body.get("repair-auto") === "1" ? CHECK_REPAIR_LIMIT : 0,
|
|
2473
|
-
// Approving from the paired chat: only the explicit choice grants it, naming every chat app it covers (a grant
|
|
2474
|
-
// signed before it named them stays Telegram only).
|
|
2475
2316
|
chatApprove: body.get("chat-approve") === "1",
|
|
2476
2317
|
...(body.get("chat-approve") === "1" ? { chatApproveChats: CHAT_APPROVE_ALL } : {}),
|
|
2477
2318
|
publication: body.get("publication") === "automerge" ? "automerge" : "notify",
|
|
@@ -2487,16 +2328,12 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2487
2328
|
}
|
|
2488
2329
|
const digest = modeDigestOf(terms);
|
|
2489
2330
|
if (step === "confirm") {
|
|
2490
|
-
// THE CEREMONY (M1): every resolved term in words, and the password
|
|
2491
|
-
// signs exactly this digest — a drifted form refuses at /mode/sign.
|
|
2492
2331
|
const nonce = mintApprovalNonce(who.name, "mode-sign", `${project}:${digest}`);
|
|
2493
2332
|
const signed = Object.fromEntries(["name", "days", "publication", "auto-approve", "plan-auto", "chat-approve", "repair-auto"]
|
|
2494
2333
|
.map(field => [field, body.get(field) ?? ""]));
|
|
2495
2334
|
const bodyHtml = modeCeremonyHtml({ name, project: projectName(project), words: modeWords(terms), chatApprove: signed["chat-approve"] === "1", repairAuto: signed["repair-auto"] === "1", hidden: { nonce, digest, ...signed, expiry } });
|
|
2496
2335
|
return sendScreen(response, 200, screen("Sign the mode", bodyHtml, { chrome: chromeFor(project, "mode") }));
|
|
2497
2336
|
}
|
|
2498
|
-
// /mode/sign: the fixed expiry rides the form; the digest is
|
|
2499
|
-
// RE-DERIVED from the posted fields — drift is a 409, never a guess.
|
|
2500
2337
|
const fixedExpiry = body.get("expiry") ?? "";
|
|
2501
2338
|
const signedTerms = { ...terms, absoluteExpiry: fixedExpiry };
|
|
2502
2339
|
const rederived = modeDigestOf(signedTerms);
|
|
@@ -2508,7 +2345,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2508
2345
|
return refuse(response, who, 409, "the terms moved while you were reading — read them again", "/mode");
|
|
2509
2346
|
}
|
|
2510
2347
|
const token = body.get("token") ?? "";
|
|
2511
|
-
// A mode that lets a chat app approve, or repairs start by themselves, opens a way to act: a credential act. Any other mode is an ordinary one.
|
|
2512
2348
|
if (!(body.get("chat-approve") === "1" || body.get("repair-auto") === "1" ? authenticateCredential(who, token) : authenticateApprover(who, token)).ok) {
|
|
2513
2349
|
return refuse(response, who, 403, "signing a mode takes your password, typed again", "/mode");
|
|
2514
2350
|
}
|
|
@@ -2530,12 +2366,9 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2530
2366
|
const project = projectOf(who, request);
|
|
2531
2367
|
if (project === null || project === undefined)
|
|
2532
2368
|
return refuse(response, who, 409, "open a project first", "/mode");
|
|
2533
|
-
// LOWERING authority is ONE CLICK for any approver (the v4 ruling):
|
|
2534
|
-
// csrf only, no password — the fastest possible off-switch.
|
|
2535
2369
|
const ended = store.revokeMode(project, who.name, "operator", now);
|
|
2536
2370
|
return redirect(response, ended ? "/mode?said=the%20mode%20is%20ended%20—%20every%20act%20falls%20back%20to%20its%20own%20ceremony" : "/mode");
|
|
2537
2371
|
}
|
|
2538
|
-
// Settings → Lead: the name and persona this person's lead speaks with.
|
|
2539
2372
|
async function leadIdentity(ctx) {
|
|
2540
2373
|
const { who, response, now, posted } = ctx;
|
|
2541
2374
|
const body = readForm(posted, CONSOLE_FORMS.leadIdentity);
|
|
@@ -2545,7 +2378,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2545
2378
|
store.setLeadConfig(who.name, checked.identity.name, checked.identity.persona, now);
|
|
2546
2379
|
return redirect(response, "/settings/lead?saved=1");
|
|
2547
2380
|
}
|
|
2548
|
-
// Settings → Lead: what this person's lead knows about them, one line each.
|
|
2549
2381
|
async function leadAbout(ctx) {
|
|
2550
2382
|
const { who, response, now, posted } = ctx;
|
|
2551
2383
|
const body = readForm(posted, CONSOLE_FORMS.leadAbout);
|
|
@@ -2555,19 +2387,13 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2555
2387
|
saveAboutYou(store, who.name, checked.lines, now);
|
|
2556
2388
|
return redirect(response, "/settings/lead?saved=about");
|
|
2557
2389
|
}
|
|
2558
|
-
// Settings → Lead: stop the lead following up on one of your promises.
|
|
2559
2390
|
async function leadPromiseCancel(ctx) {
|
|
2560
2391
|
const { who, response, now, posted } = ctx;
|
|
2561
2392
|
const body = readForm(posted, CONSOLE_FORMS.leadPromiseCancel);
|
|
2562
2393
|
const id = Number(body.get("promise"));
|
|
2563
2394
|
const done = Number.isSafeInteger(id) && cancelCommitment(store, who.name, id, who.name, "Cancelled in Settings.", now);
|
|
2564
|
-
// The promise leaving the list says it was cancelled; only a refusal needs words.
|
|
2565
2395
|
return redirect(response, done ? "/settings/lead" : chatReturnWithSaid("/settings/lead", "That promise was already closed."));
|
|
2566
2396
|
}
|
|
2567
|
-
// Turn the lead on with the agent signed in on this computer: its membership spends no dollars, so like starting a
|
|
2568
|
-
// conversation it needs no second password; the full form (Advanced) still asks for one.
|
|
2569
|
-
// The welcome's "Use this one" names the agent (`agent`, claude or codex: only one signed in with its account here)
|
|
2570
|
-
// and comes back to the welcome (`return`, that one address only).
|
|
2571
2397
|
async function leadOn(ctx) {
|
|
2572
2398
|
const { who, response, now, posted } = ctx;
|
|
2573
2399
|
const body = readForm(posted, CONSOLE_FORMS.leadOn);
|
|
@@ -2583,10 +2409,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2583
2409
|
const words = asked === null ? `No agent is signed in on this computer yet. Run ${agentSignInCommand()}, then try again.` : `${asked === "claude" ? "Claude Code" : "Codex"} isn't signed in on this computer yet.`;
|
|
2584
2410
|
return redirect(response, back ?? chatReturnWithSaid("/settings/lead", words));
|
|
2585
2411
|
}
|
|
2586
|
-
// Choosing the one already in use changes nothing (its daily turns and the rest stay as set). The local owner's
|
|
2587
|
-
// choice also starts the installation's models on that agent's default preset, in the same write, while nothing
|
|
2588
|
-
// is chosen yet (model-choices.ts fillDefaultRouting): its first task can then be planned and approved without a
|
|
2589
|
-
// password. A full session's choice is as before: its models are Settings → Models'.
|
|
2590
2412
|
store.transact(() => {
|
|
2591
2413
|
if (store.getChatConfig()?.provider !== provider)
|
|
2592
2414
|
store.setChatConfig({ provider, model: "default", dailyTurns: 50, weeklyCeilingMicrousd: 0, priceInMicrousd: 0, priceOutMicrousd: 0 }, who.name, now);
|
|
@@ -2596,8 +2418,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2596
2418
|
});
|
|
2597
2419
|
return redirect(response, back ?? "/chat");
|
|
2598
2420
|
}
|
|
2599
|
-
/** Settings → Models, read from the saved catalog and the role rows at the scope being edited (the installation,
|
|
2600
|
-
* or one project and what it inherits). */
|
|
2601
2421
|
function modelsView(canManage, csrf, now, said, problem, query = new URLSearchParams()) {
|
|
2602
2422
|
const runtimes = runtimeStates(store);
|
|
2603
2423
|
const installed = new Set(runtimes.map(one => one.tool));
|
|
@@ -2629,11 +2449,9 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2629
2449
|
const inUse = presetInUse(store, scope);
|
|
2630
2450
|
const unchosen = repo === null && ALL_SLOTS.every(slot => rowAt(store, INSTALLATION_SCOPE, slot) === null);
|
|
2631
2451
|
const checked = checkScope(store, repo);
|
|
2632
|
-
// A preset or a switch, previewed: the exact rows it moves, with what a change of provider brings along.
|
|
2633
2452
|
const pairWords = (pair, slot) => pair === null ? (repo !== null ? "same as the installation" : slot.phase === "repair" ? "same as the builder" : slot.phase === "review" ? "same as the planner" : slot.tier === "light" ? "routine builder" : slot.tier === "strong" ? "routine one" : "not set") : (pair.model ?? `${pair.provider} default`);
|
|
2634
2453
|
const switchFrom = query.get("switch"), switchTo = query.get("to");
|
|
2635
2454
|
const presetAsked = query.get("preset");
|
|
2636
|
-
// The rows, what they inherit, and both digests come from one snapshot (model-choices.ts previewModelChange).
|
|
2637
2455
|
const previewOf = (title, change, hidden) => {
|
|
2638
2456
|
const snapshot = previewModelChange(store, scope, change);
|
|
2639
2457
|
const rows = snapshot.rows.map(row => {
|
|
@@ -2652,7 +2470,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2652
2470
|
const preview = !canManage ? null
|
|
2653
2471
|
: isPresetName(presetAsked) ? previewOf(`Use ${PRESETS[presetAsked].label}`, presetChange(presetAsked), { preset: presetAsked })
|
|
2654
2472
|
: switchFrom !== null && switchTo !== null && exactModelId(switchFrom) && exactModelId(switchTo) ? previewOf(`Switch to ${switchTo}`, switchChange(store, scope, switchFrom, switchTo), { switch: switchFrom, to: switchTo })
|
|
2655
|
-
// A new installation with nothing chosen yet opens on the default, ready to apply.
|
|
2656
2473
|
: unchosen ? previewOf(`Start with ${PRESETS[DEFAULT_PRESET].label}`, presetChange(DEFAULT_PRESET), { preset: DEFAULT_PRESET })
|
|
2657
2474
|
: null;
|
|
2658
2475
|
const chat = store.getChatConfig();
|
|
@@ -2679,7 +2496,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2679
2496
|
suggested: suggestedView(repo, projects, query.get("suggestion"), now),
|
|
2680
2497
|
};
|
|
2681
2498
|
}
|
|
2682
|
-
/** Google's redirect back: the code becomes a saved refresh token, and a page sends the person back to Settings. */
|
|
2683
2499
|
async function googleCallback(ctx) {
|
|
2684
2500
|
const { request, response, url } = ctx;
|
|
2685
2501
|
const done = (said) => {
|
|
@@ -2714,14 +2530,11 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2714
2530
|
response.end(htmlString(html `<!doctype html><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta http-equiv="refresh" content="0;url=${to}"><title>Toolroll</title>${HANDOFF_STYLE}<p>${words} <a href="${to}">Back to Toolroll</a></p>`));
|
|
2715
2531
|
};
|
|
2716
2532
|
const state = url.searchParams.get("state") ?? "";
|
|
2717
|
-
// Every arrival is logged (never the code or state): a sign-in that never came back is then visible as an absence.
|
|
2718
2533
|
logEvent("info", "connect.callback", { error: url.searchParams.get("error"), known: connectVisits.has(state) });
|
|
2719
2534
|
if (!startedHere(request, state))
|
|
2720
2535
|
return done("/settings/tools", "problem", "That sign-in was started in another browser. Connect again from this one.");
|
|
2721
2536
|
const visit = connectVisits.get(state);
|
|
2722
2537
|
connectVisits.delete(state);
|
|
2723
|
-
// The signer as at Connect: still an approver, not revoked, the same generation, still in the project. Checked here,
|
|
2724
|
-
// before the connection changes, and again at the grant, after every wait.
|
|
2725
2538
|
const standing = () => {
|
|
2726
2539
|
const account = visit === undefined ? null : store.accountOf(visit.by);
|
|
2727
2540
|
return visit !== undefined && account !== null && account.role === "approver" && account.revokedAt === null && visit.generation !== undefined
|
|
@@ -2731,7 +2544,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2731
2544
|
return done("/settings/tools", "problem", "That sign-in expired. Connect again.");
|
|
2732
2545
|
const service = oneClickOf(visit.service);
|
|
2733
2546
|
const kit = visit.kit === null ? null : kitOf(visit.kit);
|
|
2734
|
-
// Started from a gallery template's page: back to it, for the same project.
|
|
2735
2547
|
const template = visit.template === null ? null : galleryTemplateOf(visit.template);
|
|
2736
2548
|
const back = template !== null ? `/flows/new/${template.id}?repo=${encodeURIComponent(visit.repo)}`
|
|
2737
2549
|
: kit === null ? `/settings/tools?repo=${encodeURIComponent(visit.repo)}` : `/kits/${kit.id}?repo=${encodeURIComponent(visit.repo)}`;
|
|
@@ -2747,13 +2559,10 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2747
2559
|
const finished = await finishConnect(store, visit, code, now, { fetcher: options.connectFetch ?? fetch, home: toolHome, omitEnv: ALL_CREDENTIAL_ENV, stillStanding: standing });
|
|
2748
2560
|
if (!finished.ok)
|
|
2749
2561
|
return done(back, "problem", finished.said);
|
|
2750
|
-
// From a kit: its teammate may use the tool now (reading freely, the rest after a person approves each call).
|
|
2751
2562
|
const set = kit === null || !kit.tools.some(one => one.tool === service.id) ? null : kitInstalled(store, kit, visit.repo);
|
|
2752
2563
|
const bound = visit.grant ?? null;
|
|
2753
2564
|
if (set !== null && bound !== null && bound.subagent === set.mate.id && bound.tool === service.id && bound.repo === visit.repo && set.mate.repo === visit.repo
|
|
2754
2565
|
&& store.subagentGrant(set.mate.id, service.id) === null && standing()) {
|
|
2755
|
-
// The password at Connect (toolsConnect) is this grant's proof, for exactly the grant the visit names, while the
|
|
2756
|
-
// signer still stands: re-checked after the tool's listing, in the step that saves the grant.
|
|
2757
2566
|
const granted = await grantTool(store, set.mate, service.id, visit.by, now, { toolHome }, { widening: "proved", stillProved: standing });
|
|
2758
2567
|
if (granted.ok)
|
|
2759
2568
|
return done(back, "said", `${service.label} is connected to ${to}, and ${nameOf(set.mate)} can use it: reading freely, the rest after you approve each call.`);
|
|
@@ -2807,6 +2616,7 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2807
2616
|
"settings.group-projects": settingsHome.bind(null),
|
|
2808
2617
|
"settings.group-access": settingsHome.bind(null),
|
|
2809
2618
|
"settings.group-system": settingsHome.bind(null),
|
|
2619
|
+
"settings.group-advanced": settingsHome.bind(null),
|
|
2810
2620
|
"provider.resume": providerResume,
|
|
2811
2621
|
"settings.updates-dismiss": updatesDismiss,
|
|
2812
2622
|
"session.forget-password": forgetPassword,
|
|
@@ -2916,12 +2726,11 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2916
2726
|
"settings.lead-on": leadOn,
|
|
2917
2727
|
"settings.code-map": codeMapAct("switch"),
|
|
2918
2728
|
"settings.code-map-holdout": codeMapAct("holdout"),
|
|
2729
|
+
"settings.advanced": advancedAct,
|
|
2919
2730
|
}, {
|
|
2920
2731
|
"edge.google-callback": googleCallback,
|
|
2921
2732
|
"edge.connect-callback": connectCallback,
|
|
2922
2733
|
});
|
|
2923
|
-
// Settings → Project → Where builds write (writes-mode.ts). An approver for the project changes it with their password
|
|
2924
|
-
// typed now; the ledger keeps before → after. New scopes use it; approved ones keep theirs.
|
|
2925
2734
|
async function projectWrites(ctx) {
|
|
2926
2735
|
const { who, response, now, posted } = ctx;
|
|
2927
2736
|
const body = readForm(posted, CONSOLE_FORMS.projectWrites);
|
|
@@ -2939,9 +2748,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2939
2748
|
const changed = store.setProjectWrites(repo, wanted, who.name, now);
|
|
2940
2749
|
return back("said", changed.before === changed.after ? "Nothing changed." : "Saved. Tasks scoped from now on use it; tasks already approved keep what they were approved with.");
|
|
2941
2750
|
}
|
|
2942
|
-
// Settings → Project → Check access (check-access.ts). Widening is an instance operator's act with a password typed now
|
|
2943
|
-
// (an identity-provider re-check doesn't count); any approver for the project narrows it. The level is compared again
|
|
2944
|
-
// inside the write, so a change made meanwhile can't turn a narrowing into a widening. The ledger keeps before → after.
|
|
2945
2751
|
async function projectCheckAccess(ctx) {
|
|
2946
2752
|
const { who, response, now, posted } = ctx;
|
|
2947
2753
|
const body = readForm(posted, CONSOLE_FORMS.projectCheckAccess);
|
|
@@ -2954,15 +2760,12 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2954
2760
|
const wanted = body.get("level");
|
|
2955
2761
|
if (!isCheckAccess(wanted))
|
|
2956
2762
|
return back("problem", "Choose how far checks reach. Nothing changed.");
|
|
2957
|
-
// Not available yet (check-access.ts signInsAvailable): refused before the password, whatever the form sent.
|
|
2958
2763
|
const unavailable = wanted === "sign-ins" ? signInsUnavailableWords(options.platform ?? process.platform) : null;
|
|
2959
2764
|
if (unavailable !== null)
|
|
2960
2765
|
return back("problem", `${unavailable} Nothing changed.`);
|
|
2961
2766
|
const widening = widerThan(wanted, store.projectCheckAccess(repo));
|
|
2962
|
-
// Easy-start C5: while local mode is on, this installation always confines; said before the password.
|
|
2963
2767
|
if (wanted === "unsandboxed" && localModeOn(store))
|
|
2964
2768
|
return back("problem", `${LOCAL_MODE_CONFINES} Nothing changed.`);
|
|
2965
|
-
// Sign-ins with an open network: a second, explicit yes, said before the password.
|
|
2966
2769
|
if (wanted === "sign-ins" && widening && store.projectNetwork(repo).mode === "open" && body.get("confirm-open") !== "yes") {
|
|
2967
2770
|
return back("problem", "This project's network is open: confirm that its checks could send your sign-ins to any host. Nothing changed.");
|
|
2968
2771
|
}
|
|
@@ -2977,9 +2780,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
2977
2780
|
return back("problem", "Check access changed meanwhile, and this would now widen it. Nothing changed.");
|
|
2978
2781
|
return back("said", changed.before === changed.after ? "Nothing changed." : "Saved. Tasks scoped from now on use it; tasks already approved keep what they were approved with.");
|
|
2979
2782
|
}
|
|
2980
|
-
// Settings → Project → Home folder (project-sandbox.ts, sandbox parity C9): what the project's builds and checks may not
|
|
2981
|
-
// read, and the macOS services they may also use. An approver for the project changes it with
|
|
2982
|
-
// their password typed now; the ledger keeps before → after. New scopes seal it; approved ones keep theirs.
|
|
2983
2783
|
async function projectSandbox(ctx) {
|
|
2984
2784
|
const { who, response, now, posted } = ctx;
|
|
2985
2785
|
const body = readForm(posted, CONSOLE_FORMS.projectSandbox);
|
|
@@ -3002,8 +2802,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
3002
2802
|
return back("problem", "An approver for this project changes its sandbox. Nothing changed.");
|
|
3003
2803
|
return back("said", JSON.stringify(changed.before) === JSON.stringify(changed.after) ? "Nothing changed." : "Saved. Tasks scoped from now on use it; tasks already approved keep what they were approved with.");
|
|
3004
2804
|
}
|
|
3005
|
-
// Release approval (docs/plans/auto-approve-green.md): an approver of the project. Approving automatically is a
|
|
3006
|
-
// credential act (a password typed now, never a session); asking again is one click and takes back automatic seals.
|
|
3007
2805
|
async function releaseApprovalSave(ctx) {
|
|
3008
2806
|
const { response, now, posted } = ctx;
|
|
3009
2807
|
const who = browserCaller(ctx.who);
|
|
@@ -3026,15 +2824,10 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
3026
2824
|
const changed = setReleaseApproval(store, repo, true, who.name, now);
|
|
3027
2825
|
return back("said", changed.changed ? "Releases approve themselves once CI and the release check pass." : "Saved.");
|
|
3028
2826
|
}
|
|
3029
|
-
// Settings → Spend moved onto the Spend page (/spend), limits first; the old address keeps working.
|
|
3030
2827
|
async function spendSettingsPage(ctx) {
|
|
3031
2828
|
const said = ctx.url.searchParams.get("said"), problem = ctx.url.searchParams.get("problem");
|
|
3032
2829
|
return redirect(ctx.response, `/spend${problem !== null ? `?problem=${encodeURIComponent(problem)}` : said !== null ? `?said=${encodeURIComponent(said)}` : ""}`);
|
|
3033
2830
|
}
|
|
3034
|
-
// Settings → Models (docs/plans/spend-dashboard.md, slice 3): the one editor. Both posts are an instance operator's,
|
|
3035
|
-
// browser-only step-ups: the password (or a Passwordless session, or an identity-provider re-check) is proved here,
|
|
3036
|
-
// and model-choices.ts re-proves the same session, credential generation and operator standing inside the one
|
|
3037
|
-
// transaction that checks the form against what is stored, validates the result and writes and ledgers every row.
|
|
3038
2831
|
function modelsAuthority(who, method) {
|
|
3039
2832
|
const session = who.session;
|
|
3040
2833
|
return { actor: who.name, generation: session.generation, method, live: () => sessions.holds(session) && sessions.savedNow(session) && sessionWithinLifetime(session, Date.now()) };
|
|
@@ -3049,7 +2842,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
3049
2842
|
const done = count === 0 ? "Nothing changed." : `${what}: ${count} change${count === 1 ? "" : "s"} saved for tasks filed from now on.`;
|
|
3050
2843
|
return { key: "said", words: result.unresolved === null ? done : `${done} Some roles have no model yet, so new tasks can't be filed here.` };
|
|
3051
2844
|
}
|
|
3052
|
-
/** One save of the whole editor: every role at the scope, sets and clears, as one change. */
|
|
3053
2845
|
async function modelsSave(ctx) {
|
|
3054
2846
|
const { response, now, posted } = ctx;
|
|
3055
2847
|
const who = browserCaller(ctx.who);
|
|
@@ -3075,7 +2867,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
3075
2867
|
return back("problem", "Choose a model from the list. Nothing changed.");
|
|
3076
2868
|
change.push({ slot, to: { provider: value.slice(0, split), model: value.slice(split + 1) } });
|
|
3077
2869
|
}
|
|
3078
|
-
// Repairs resume the builder's session: a builder moved to another provider takes repair with it.
|
|
3079
2870
|
const builder = change.find(one => one.slot.phase === "build" && one.slot.tier === "routine")?.to ?? null;
|
|
3080
2871
|
const repair = change.findIndex(one => one.slot.phase === "repair");
|
|
3081
2872
|
let follows = false;
|
|
@@ -3087,7 +2878,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
3087
2878
|
const said = modelsSaid(result, scope === INSTALLATION_SCOPE ? "All projects" : projectName(scope));
|
|
3088
2879
|
return back(said.key, follows && result.ok ? `${said.words} Repairs now follow the builder.` : said.words);
|
|
3089
2880
|
}
|
|
3090
|
-
/** A preset or a switch, applied exactly as previewed: the change's own digest rides the form. */
|
|
3091
2881
|
async function modelsApply(ctx) {
|
|
3092
2882
|
const { response, now, posted } = ctx;
|
|
3093
2883
|
const who = browserCaller(ctx.who);
|
|
@@ -3108,9 +2898,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
3108
2898
|
const said = modelsSaid(result, isPresetName(preset) ? PRESETS[preset].label : `Switched to ${to}`);
|
|
3109
2899
|
return back(said.key, said.words);
|
|
3110
2900
|
}
|
|
3111
|
-
// Easy-start C5: turning local mode off (Settings → People and sign-in), from a full session only: an instance
|
|
3112
|
-
// operator's step-up, proved and written in one transaction. It bumps local mode's generation, so every local-owner
|
|
3113
|
-
// session, link and approval bound to the old one stops standing. It is never turned back on here.
|
|
3114
2901
|
async function localModeOff(ctx) {
|
|
3115
2902
|
const { response, now, posted } = ctx;
|
|
3116
2903
|
const who = browserCaller(ctx.who);
|
|
@@ -3131,8 +2918,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
3131
2918
|
return back("problem", turned.reason === "not-on" ? "Local mode is already off." : "Only an instance operator can turn off local mode.");
|
|
3132
2919
|
return back("said", "Local mode is off. This computer's browser signs in with your password now.");
|
|
3133
2920
|
}
|
|
3134
|
-
/** Settings → Models → Suggested: one project's offers, rules and switch; on the installation scope, every
|
|
3135
|
-
* project's offers and rules, each reviewed on its own project's page. */
|
|
3136
2921
|
function suggestedView(repo, projects, asked, now) {
|
|
3137
2922
|
const repos = repo === null ? projects : [repo];
|
|
3138
2923
|
const offers = repos.flatMap(one => suggestionsFor(store, one, now));
|
|
@@ -3156,13 +2941,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
3156
2941
|
title: `Trying ${sizeTitle(one.cohortSize, modelName(store, one.model))}`, words: trialWords(store, one), live: one.state === "trialling" || one.state === "paused" })),
|
|
3157
2942
|
};
|
|
3158
2943
|
}
|
|
3159
|
-
/**
|
|
3160
|
-
* Settings → Models → Suggested (results routing, slice 2): the earned-rule doors (route-rules.ts), re-proved inside
|
|
3161
|
-
* their own transaction. Accepting, keeping a paused rule and switching suggestions on are an instance operator's
|
|
3162
|
-
* step-up (the password, or a Passwordless session); turning a rule off or dropping it, Not now, and switching
|
|
3163
|
-
* suggestions off only take authority away, so a signed-in session does — or this computer's local owner, whose
|
|
3164
|
-
* route row narrows it to exactly that act.
|
|
3165
|
-
*/
|
|
3166
2944
|
function modelsRuleAct(kind) {
|
|
3167
2945
|
return async (ctx) => {
|
|
3168
2946
|
const { response, now, posted } = ctx;
|
|
@@ -3204,8 +2982,6 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
3204
2982
|
: kind === "suggest-on" ? "Suggestions are on for this project." : "Suggestions are off for this project.");
|
|
3205
2983
|
};
|
|
3206
2984
|
}
|
|
3207
|
-
// Settings → Project → Fallback agents (fallback.ts): who takes over when an agent runs out of its plan. An approver for
|
|
3208
|
-
// the project, with their password typed now; the ledger keeps every change. New tasks seal it; approved ones keep theirs.
|
|
3209
2985
|
async function projectFallback(ctx) {
|
|
3210
2986
|
const { who, response, now, posted } = ctx;
|
|
3211
2987
|
const body = readForm(posted, CONSOLE_FORMS.projectFallback);
|
|
@@ -3229,12 +3005,30 @@ ${postForm("/settings/chat-approval/save", html `\
|
|
|
3229
3005
|
});
|
|
3230
3006
|
return done.ok ? back("said", "Saved. Tasks scoped from now on use it; tasks already approved keep the chain they were approved with.") : back("problem", `Nothing changed: ${done.problem}`);
|
|
3231
3007
|
}
|
|
3232
|
-
// Settings → Lead: quick answers on or off (installation-wide; the route admits an instance operator only).
|
|
3233
3008
|
async function leadQuick(ctx) {
|
|
3234
3009
|
const { who, response, now, posted } = ctx;
|
|
3235
3010
|
const body = readForm(posted, CONSOLE_FORMS.leadQuick);
|
|
3236
3011
|
setLeadQuickAnswers(store, body.get("enabled") === "on", who.name, now);
|
|
3237
3012
|
return redirect(response, "/settings/lead?saved=quick");
|
|
3238
3013
|
}
|
|
3014
|
+
async function advancedAct(ctx) {
|
|
3015
|
+
const { who, response, now, posted } = ctx;
|
|
3016
|
+
const body = readForm(posted, CONSOLE_FORMS.advancedView);
|
|
3017
|
+
const back = sayTo(response, "/settings/advanced");
|
|
3018
|
+
if (who.via !== "cookie")
|
|
3019
|
+
return refuse(response, who, 403, "This address needs a browser sign-in.", "/settings");
|
|
3020
|
+
const values = body.getAll("advanced");
|
|
3021
|
+
if (values.length !== 1 || (values[0] !== "on" && values[0] !== "off"))
|
|
3022
|
+
return refuse(response, who, 400, "Choose on or off.", "/settings/advanced");
|
|
3023
|
+
const on = values[0] === "on";
|
|
3024
|
+
const session = who.session;
|
|
3025
|
+
const door = who.authority === "full"
|
|
3026
|
+
? { kind: "person", actor: who.name, generation: session.generation, live: () => sessions.holds(session) && sessions.savedNow(session) && sessionWithinLifetime(session, Date.now()) }
|
|
3027
|
+
: { kind: "local-owner", actor: who.name };
|
|
3028
|
+
const done = setAdvancedPreference(store, door, on, now);
|
|
3029
|
+
if (!done.ok)
|
|
3030
|
+
return refuse(response, who, 403, done.problem, "/settings/advanced");
|
|
3031
|
+
return back("said", on ? "Advanced features show in your menus." : "Advanced features are out of your menus. They still open from here.");
|
|
3032
|
+
}
|
|
3239
3033
|
return { registrations, modelsView };
|
|
3240
3034
|
}
|