@aragon-agent/cli 0.6.47 → 0.6.48
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 +13 -0
- package/README.md +27 -6
- package/dist/agent/coalesce.d.ts +1 -1
- package/dist/agent/controller.d.ts +21 -21
- package/dist/agent/controller.js +13 -13
- package/dist/agent/conversation-reset.d.ts +1 -1
- package/dist/agent/governance-wiring.d.ts +6 -6
- package/dist/agent/governance-wiring.js +4 -4
- package/dist/agent/headless.d.ts +5 -5
- package/dist/agent/headless.js +4 -4
- package/dist/agent/job-notices.d.ts +1 -1
- package/dist/agent/job-notices.js +1 -1
- package/dist/agent/kit-apply.d.ts +3 -3
- package/dist/agent/kit-apply.js +3 -3
- package/dist/agent/model-profile-settings.d.ts +2 -2
- package/dist/agent/model-profile-settings.js +6 -6
- package/dist/agent/prompt-options.d.ts +1 -1
- package/dist/agent/system-prompt.d.ts +1 -1
- package/dist/{ui → app}/App.d.ts +9 -9
- package/dist/{ui → app}/App.js +79 -79
- package/dist/{ui → app}/use-startup-notices.d.ts +1 -1
- package/dist/{ui → app}/use-startup-notices.js +2 -2
- package/dist/cli.js +29 -29
- package/dist/commands/agents-command.js +1 -1
- package/dist/commands/builtins.js +9 -9
- package/dist/commands/governance-command.js +2 -2
- package/dist/commands/governance-runs-table.js +1 -1
- package/dist/commands/kit-command.js +1 -1
- package/dist/commands/perf.d.ts +3 -3
- package/dist/commands/perf.js +1 -1
- package/dist/commands/registry.d.ts +8 -8
- package/dist/commands/skills.js +2 -2
- package/dist/commands/team-command.js +1 -1
- package/dist/compaction/archive.d.ts +1 -1
- package/dist/compaction/archive.js +1 -1
- package/dist/compaction/child.d.ts +3 -3
- package/dist/compaction/child.js +4 -4
- package/dist/compaction/command.js +5 -5
- package/dist/compaction/compactor.d.ts +6 -6
- package/dist/compaction/compactor.js +6 -6
- package/dist/compaction/context-command.js +1 -1
- package/dist/compaction/digest.js +1 -1
- package/dist/compaction/memory-input.js +1 -1
- package/dist/compaction/memory-validation.js +1 -1
- package/dist/compaction/memory.js +1 -1
- package/dist/compaction/summarize-call.js +1 -1
- package/dist/compaction/summary-prompt.js +1 -1
- package/dist/compaction/tail-budget.js +2 -2
- package/dist/compaction/wiring.d.ts +5 -5
- package/dist/compaction/wiring.js +2 -2
- package/dist/config/cli-commands.d.ts +1 -1
- package/dist/config/cli-commands.js +3 -3
- package/dist/config/env.d.ts +1 -1
- package/dist/config/env.js +4 -4
- package/dist/config/load.d.ts +2 -2
- package/dist/config/load.js +6 -6
- package/dist/config/migrate-state-out-of-config.js +1 -1
- package/dist/config/model-profile-store.d.ts +4 -54
- package/dist/config/model-profile-store.js +3 -3
- package/dist/config/prompt-history.js +1 -1
- package/dist/config/store.d.ts +2 -2
- package/dist/config/store.js +3 -3
- package/dist/diagnostics/doctor.js +4 -4
- package/dist/exec/bridge/decisions.d.ts +1 -1
- package/dist/exec/bridge/human-answers.d.ts +1 -1
- package/dist/exec/bridge/human-answers.js +1 -1
- package/dist/exec/bridge/protocol.d.ts +1 -1
- package/dist/exec/bridge/server.js +1 -1
- package/dist/exec/events.d.ts +2 -2
- package/dist/exec/index.d.ts +1 -1
- package/dist/exec/index.js +1 -1
- package/dist/exec/permission.js +1 -1
- package/dist/exec/runner.d.ts +3 -3
- package/dist/exec/runner.js +2 -2
- package/dist/exec/threads/runtime.js +1 -1
- package/dist/fast/digest.d.ts +1 -1
- package/dist/fast/digest.js +1 -1
- package/dist/fast/frames.d.ts +1 -1
- package/dist/fast/frames.js +1 -1
- package/dist/fast/prompt.d.ts +1 -1
- package/dist/fast/prompt.js +1 -1
- package/dist/fast/review-call.js +1 -1
- package/dist/fast/reviewer.d.ts +3 -3
- package/dist/fast/reviewer.js +1 -1
- package/dist/fast/summary-call.d.ts +3 -3
- package/dist/fast/summary-call.js +2 -2
- package/dist/fast/summary-prompt.d.ts +1 -1
- package/dist/fast/summary-prompt.js +1 -1
- package/dist/fast/wiring.d.ts +4 -4
- package/dist/fast/wiring.js +1 -1
- package/dist/governance/card-normalize.d.ts +1 -1
- package/dist/governance/copy.d.ts +1 -1
- package/dist/governance/copy.js +2 -2
- package/dist/governance/engine/artifact-persist.d.ts +1 -1
- package/dist/governance/engine/budget.d.ts +1 -1
- package/dist/governance/engine/budget.js +1 -1
- package/dist/governance/engine/cards.d.ts +1 -1
- package/dist/governance/engine/digest.js +1 -1
- package/dist/governance/engine/engine-core.d.ts +5 -5
- package/dist/governance/engine/engine-core.js +1 -1
- package/dist/governance/engine/engine.d.ts +1 -1
- package/dist/governance/engine/engine.js +1 -1
- package/dist/governance/engine/estimate.d.ts +1 -1
- package/dist/governance/engine/estimate.js +1 -1
- package/dist/governance/engine/inspector.js +2 -2
- package/dist/governance/engine/integration.d.ts +1 -1
- package/dist/governance/engine/lifecycle.d.ts +1 -1
- package/dist/governance/engine/lifecycle.js +1 -1
- package/dist/governance/engine/phase-members.d.ts +1 -1
- package/dist/governance/engine/phase-planner.d.ts +1 -1
- package/dist/governance/engine/phase-planner.js +1 -1
- package/dist/governance/engine/rebuild.d.ts +1 -1
- package/dist/governance/engine/report.d.ts +1 -1
- package/dist/governance/engine/report.js +1 -1
- package/dist/governance/engine/run-digest.d.ts +1 -1
- package/dist/governance/engine/spec-builder.d.ts +2 -2
- package/dist/governance/engine/spec-builder.js +2 -2
- package/dist/governance/engine/stage-runner.js +2 -2
- package/dist/governance/engine/start-input.d.ts +1 -1
- package/dist/governance/engine/start-input.js +1 -1
- package/dist/governance/engine/state-machine.d.ts +1 -1
- package/dist/governance/engine/state-machine.js +3 -3
- package/dist/governance/engine/submission-queries.d.ts +1 -1
- package/dist/governance/engine/submission-render.d.ts +1 -1
- package/dist/governance/engine/submissions.d.ts +1 -1
- package/dist/governance/engine/submissions.js +1 -1
- package/dist/governance/engine/visibility.d.ts +1 -1
- package/dist/governance/engine/visibility.js +1 -1
- package/dist/governance/posture-transition.d.ts +2 -2
- package/dist/governance/posture-transition.js +1 -1
- package/dist/governance/profiles.d.ts +1 -1
- package/dist/governance/prompts/orchestrator-block.d.ts +2 -2
- package/dist/governance/prompts/orchestrator-block.js +2 -2
- package/dist/governance/prompts/plan-addendum.d.ts +1 -1
- package/dist/governance/prompts/plan-addendum.js +1 -1
- package/dist/governance/prompts/role-blocks.d.ts +2 -2
- package/dist/governance/prompts/role-blocks.js +1 -1
- package/dist/governance/report-reader.js +1 -1
- package/dist/governance/roles.d.ts +1 -1
- package/dist/governance/rules/claims.d.ts +1 -1
- package/dist/governance/rules/claims.js +1 -1
- package/dist/governance/rules/elimination.d.ts +1 -1
- package/dist/governance/rules/elimination.js +1 -1
- package/dist/governance/rules/failure-analysis.d.ts +2 -2
- package/dist/governance/rules/failure-analysis.js +1 -1
- package/dist/governance/rules/ledger-replay.d.ts +1 -1
- package/dist/governance/rules/ledger-state.d.ts +1 -1
- package/dist/governance/rules/ledger-state.js +1 -1
- package/dist/governance/rules/ledger.d.ts +2 -2
- package/dist/governance/rules/ledger.js +2 -2
- package/dist/governance/rules/rca.d.ts +1 -1
- package/dist/governance/rules/rca.js +1 -1
- package/dist/governance/rules/settlement.d.ts +2 -2
- package/dist/governance/rules/settlement.js +2 -2
- package/dist/governance/rules/suspicion.d.ts +1 -1
- package/dist/governance/store/artifacts.d.ts +1 -1
- package/dist/governance/store/artifacts.js +1 -1
- package/dist/governance/store/events-log.d.ts +1 -1
- package/dist/governance/store/run-store.d.ts +1 -1
- package/dist/governance/store/run-store.js +1 -1
- package/dist/governance/store/scoreboard-export.d.ts +1 -1
- package/dist/governance/tools/child-tools.d.ts +1 -1
- package/dist/governance/tools/guard.d.ts +1 -1
- package/dist/governance/tools/guard.js +1 -1
- package/dist/governance/tools/inspector-tools.d.ts +2 -2
- package/dist/governance/tools/inspector-tools.js +2 -2
- package/dist/governance/tools/lead-tools.d.ts +1 -1
- package/dist/governance/tools/lead-tools.js +1 -1
- package/dist/governance/tools/normalize-util.js +1 -1
- package/dist/governance/tools/scan-incomplete.js +1 -1
- package/dist/governance/tools/shared-tools.d.ts +1 -1
- package/dist/governance/tools/shared-tools.js +1 -1
- package/dist/governance/tools/submit-normalizers.d.ts +1 -1
- package/dist/governance/tools/submit-normalizers.js +1 -1
- package/dist/governance/tools/submit-tools.d.ts +1 -1
- package/dist/logging/cli-commands.js +1 -1
- package/dist/logging/install.d.ts +1 -1
- package/dist/logging/install.js +3 -3
- package/dist/logging/logger.d.ts +2 -2
- package/dist/logging/logger.js +31 -2
- package/dist/proc/kill-tree.js +1 -1
- package/dist/proc/log-mirror.js +1 -1
- package/dist/proc/log-ring.js +2 -2
- package/dist/proc/notices.d.ts +1 -1
- package/dist/proc/notices.js +2 -2
- package/dist/proc/prompt.d.ts +1 -1
- package/dist/proc/prompt.js +1 -1
- package/dist/proc/readiness.js +1 -1
- package/dist/proc/supervisor.d.ts +1 -1
- package/dist/proc/supervisor.js +3 -3
- package/dist/proc/wait.d.ts +1 -1
- package/dist/proc/wait.js +1 -1
- package/dist/prompts/command.d.ts +1 -1
- package/dist/prompts/command.js +1 -1
- package/dist/prompts/normalize.d.ts +1 -1
- package/dist/prompts/normalize.js +1 -1
- package/dist/prompts/resolve.d.ts +1 -1
- package/dist/prompts/store.d.ts +2 -12
- package/dist/prompts/store.js +6 -60
- package/dist/session/checkpoint.d.ts +2 -2
- package/dist/session/clear-archive.d.ts +2 -2
- package/dist/session/persist.d.ts +2 -2
- package/dist/session/persist.js +1 -1
- package/dist/session/startup-session.d.ts +2 -2
- package/dist/session/validate-session.js +3 -3
- package/dist/skills/service.d.ts +2 -2
- package/dist/team/bus.d.ts +1 -1
- package/dist/team/bus.js +1 -1
- package/dist/team/child-reviewer.d.ts +2 -2
- package/dist/team/child-reviewer.js +1 -1
- package/dist/team/comm-tools.js +1 -1
- package/dist/team/dispatch-gate.js +1 -1
- package/dist/team/forced-dispatch.js +1 -1
- package/dist/team/forced-mode.d.ts +1 -1
- package/dist/team/forced-prompt.d.ts +1 -1
- package/dist/team/forced-prompt.js +1 -1
- package/dist/team/normalize.d.ts +1 -1
- package/dist/team/normalize.js +1 -1
- package/dist/team/overseer.d.ts +3 -3
- package/dist/team/overseer.js +3 -3
- package/dist/team/prompt.d.ts +1 -1
- package/dist/team/prompt.js +1 -1
- package/dist/team/report.d.ts +2 -2
- package/dist/team/report.js +2 -2
- package/dist/team/retry.d.ts +1 -1
- package/dist/team/retry.js +1 -1
- package/dist/team/runtime.d.ts +4 -4
- package/dist/team/runtime.js +2 -2
- package/dist/team/settled.d.ts +2 -2
- package/dist/team/subagent.d.ts +4 -4
- package/dist/team/subagent.js +5 -5
- package/dist/team/task-tool.d.ts +1 -1
- package/dist/team/task-tool.js +1 -1
- package/dist/todo/normalize.d.ts +1 -1
- package/dist/todo/normalize.js +1 -1
- package/dist/todo/prompt.d.ts +1 -1
- package/dist/todo/prompt.js +1 -1
- package/dist/todo/store.d.ts +1 -1
- package/dist/todo/store.js +2 -2
- package/dist/todo/todo-tool.d.ts +1 -1
- package/dist/todo/todo-tool.js +2 -2
- package/dist/tools/bash-tool.d.ts +1 -1
- package/dist/tools/bash-tool.js +2 -2
- package/dist/tools/diff.d.ts +1 -1
- package/dist/tools/diff.js +1 -1
- package/dist/tools/file-change-store.d.ts +1 -1
- package/dist/tools/fs-tools.d.ts +2 -2
- package/dist/tools/fs-tools.js +1 -1
- package/dist/tools/index.d.ts +3 -3
- package/dist/tools/index.js +1 -1
- package/dist/tools/job-tools.d.ts +2 -2
- package/dist/tools/job-tools.js +4 -4
- package/dist/tools/plan-tools.d.ts +1 -1
- package/dist/tools/plan-tools.js +1 -1
- package/dist/tools/proc-tools.d.ts +1 -1
- package/dist/tools/proc-tools.js +2 -2
- package/dist/update/classify-failure.d.ts +1 -1
- package/dist/update/install-lock.js +1 -1
- package/dist/update/install-source.d.ts +1 -1
- package/dist/update/installer.js +2 -2
- package/dist/update/npm-view.d.ts +1 -1
- package/dist/update/npm-view.js +1 -1
- package/dist/update/registry.d.ts +1 -1
- package/dist/update/registry.js +1 -1
- package/dist/update/service.d.ts +2 -2
- package/dist/update/service.js +2 -2
- package/package.json +7 -7
- package/dist/agent/agent-mode.d.ts +0 -108
- package/dist/agent/agent-mode.js +0 -121
- package/dist/agent/entry-limits.d.ts +0 -65
- package/dist/agent/entry-limits.js +0 -133
- package/dist/agent/governance-view.d.ts +0 -40
- package/dist/agent/governance-view.js +0 -40
- package/dist/agent/invocation-card.d.ts +0 -77
- package/dist/agent/invocation-card.js +0 -169
- package/dist/agent/model-probe-limits.d.ts +0 -39
- package/dist/agent/model-probe-limits.js +0 -25
- package/dist/agent/model-probe.d.ts +0 -104
- package/dist/agent/model-probe.js +0 -391
- package/dist/agent/queued-messages.d.ts +0 -23
- package/dist/agent/queued-messages.js +0 -49
- package/dist/agent/reducer.d.ts +0 -857
- package/dist/agent/reducer.js +0 -1646
- package/dist/agent/retry-view.d.ts +0 -68
- package/dist/agent/retry-view.js +0 -95
- package/dist/agent/usage.d.ts +0 -47
- package/dist/agent/usage.js +0 -84
- package/dist/compaction/limits.d.ts +0 -61
- package/dist/compaction/limits.js +0 -64
- package/dist/compaction/meter.d.ts +0 -276
- package/dist/compaction/meter.js +0 -512
- package/dist/compaction/pressure.d.ts +0 -163
- package/dist/compaction/pressure.js +0 -199
- package/dist/compaction/reason-text.d.ts +0 -36
- package/dist/compaction/reason-text.js +0 -78
- package/dist/compaction/types.d.ts +0 -360
- package/dist/compaction/types.js +0 -22
- package/dist/config/governance-config.d.ts +0 -125
- package/dist/config/governance-config.js +0 -164
- package/dist/config/kit-resolution.d.ts +0 -93
- package/dist/config/kit-resolution.js +0 -226
- package/dist/config/model-kits.d.ts +0 -225
- package/dist/config/model-kits.js +0 -302
- package/dist/config/model-profile-resolution.d.ts +0 -28
- package/dist/config/model-profile-resolution.js +0 -88
- package/dist/config/model-profiles.d.ts +0 -103
- package/dist/config/model-profiles.js +0 -188
- package/dist/config/schema.d.ts +0 -1645
- package/dist/config/schema.js +0 -1383
- package/dist/fast/limits.d.ts +0 -152
- package/dist/fast/limits.js +0 -152
- package/dist/fast/resolve.d.ts +0 -44
- package/dist/fast/resolve.js +0 -107
- package/dist/fast/task-summary-types.d.ts +0 -66
- package/dist/fast/task-summary-types.js +0 -17
- package/dist/fast/types.d.ts +0 -141
- package/dist/fast/types.js +0 -14
- package/dist/governance/governed-dispatch.d.ts +0 -19
- package/dist/governance/governed-dispatch.js +0 -17
- package/dist/governance/limits.d.ts +0 -107
- package/dist/governance/limits.js +0 -131
- package/dist/governance/posture.d.ts +0 -35
- package/dist/governance/posture.js +0 -59
- package/dist/governance/rules/events-table.d.ts +0 -46
- package/dist/governance/rules/events-table.js +0 -94
- package/dist/governance/types.d.ts +0 -661
- package/dist/governance/types.js +0 -27
- package/dist/input/control-sequences.d.ts +0 -71
- package/dist/input/control-sequences.js +0 -222
- package/dist/input/csiu-keys.d.ts +0 -66
- package/dist/input/csiu-keys.js +0 -181
- package/dist/input/cursor-report.d.ts +0 -61
- package/dist/input/cursor-report.js +0 -97
- package/dist/input/enter-sequences.d.ts +0 -64
- package/dist/input/enter-sequences.js +0 -153
- package/dist/input/interrupt-gesture.d.ts +0 -18
- package/dist/input/interrupt-gesture.js +0 -19
- package/dist/input/keyboard-enhancement.d.ts +0 -42
- package/dist/input/keyboard-enhancement.js +0 -65
- package/dist/input/keymap.d.ts +0 -20
- package/dist/input/keymap.js +0 -99
- package/dist/input/limits.d.ts +0 -118
- package/dist/input/limits.js +0 -109
- package/dist/input/mouse-events.d.ts +0 -87
- package/dist/input/mouse-events.js +0 -212
- package/dist/input/paste-parse.d.ts +0 -83
- package/dist/input/paste-parse.js +0 -107
- package/dist/input/pointer-router.d.ts +0 -11
- package/dist/input/pointer-router.js +0 -14
- package/dist/input/stdin-filter.d.ts +0 -112
- package/dist/input/stdin-filter.js +0 -657
- package/dist/input/win32-input-mode.d.ts +0 -61
- package/dist/input/win32-input-mode.js +0 -269
- package/dist/logging/levels.d.ts +0 -40
- package/dist/logging/levels.js +0 -59
- package/dist/logging/secret-registry.d.ts +0 -32
- package/dist/logging/secret-registry.js +0 -73
- package/dist/proc/limits.d.ts +0 -214
- package/dist/proc/limits.js +0 -221
- package/dist/proc/progress.d.ts +0 -47
- package/dist/proc/progress.js +0 -163
- package/dist/proc/types.d.ts +0 -269
- package/dist/proc/types.js +0 -15
- package/dist/proc/wait-view.d.ts +0 -65
- package/dist/proc/wait-view.js +0 -66
- package/dist/prompts/copy.d.ts +0 -89
- package/dist/prompts/copy.js +0 -131
- package/dist/prompts/fill.d.ts +0 -51
- package/dist/prompts/fill.js +0 -46
- package/dist/prompts/limits.d.ts +0 -53
- package/dist/prompts/limits.js +0 -53
- package/dist/prompts/search.d.ts +0 -58
- package/dist/prompts/search.js +0 -146
- package/dist/prompts/types.d.ts +0 -204
- package/dist/prompts/types.js +0 -13
- package/dist/team/activity.d.ts +0 -67
- package/dist/team/activity.js +0 -130
- package/dist/team/limits.d.ts +0 -308
- package/dist/team/limits.js +0 -330
- package/dist/team/model.d.ts +0 -104
- package/dist/team/model.js +0 -150
- package/dist/team/panel-rows.d.ts +0 -48
- package/dist/team/panel-rows.js +0 -75
- package/dist/team/timeline.d.ts +0 -74
- package/dist/team/timeline.js +0 -101
- package/dist/team/types.d.ts +0 -354
- package/dist/team/types.js +0 -13
- package/dist/todo/acceptance.d.ts +0 -120
- package/dist/todo/acceptance.js +0 -399
- package/dist/todo/follow-through.d.ts +0 -138
- package/dist/todo/follow-through.js +0 -248
- package/dist/todo/limits.d.ts +0 -152
- package/dist/todo/limits.js +0 -152
- package/dist/todo/panel-rows.d.ts +0 -45
- package/dist/todo/panel-rows.js +0 -70
- package/dist/todo/plan-sections.d.ts +0 -60
- package/dist/todo/plan-sections.js +0 -108
- package/dist/todo/row-window.d.ts +0 -51
- package/dist/todo/row-window.js +0 -107
- package/dist/todo/types.d.ts +0 -124
- package/dist/todo/types.js +0 -12
- package/dist/tools/human-input.d.ts +0 -212
- package/dist/tools/human-input.js +0 -265
- package/dist/tools/patch.d.ts +0 -115
- package/dist/tools/patch.js +0 -453
- package/dist/tools/terminal-output.d.ts +0 -115
- package/dist/tools/terminal-output.js +0 -201
- package/dist/tools/tool-output-store.d.ts +0 -68
- package/dist/tools/tool-output-store.js +0 -102
- package/dist/ui/ActivityLine.d.ts +0 -26
- package/dist/ui/ActivityLine.js +0 -51
- package/dist/ui/AutocompletePopup.d.ts +0 -23
- package/dist/ui/AutocompletePopup.js +0 -17
- package/dist/ui/BottomStatusRow.d.ts +0 -10
- package/dist/ui/BottomStatusRow.js +0 -9
- package/dist/ui/Composer.d.ts +0 -115
- package/dist/ui/Composer.js +0 -64
- package/dist/ui/GovernancePanel.d.ts +0 -50
- package/dist/ui/GovernancePanel.js +0 -77
- package/dist/ui/GovernanceRun.d.ts +0 -18
- package/dist/ui/GovernanceRun.js +0 -11
- package/dist/ui/Header.d.ts +0 -48
- package/dist/ui/Header.js +0 -27
- package/dist/ui/Logo.d.ts +0 -32
- package/dist/ui/Logo.js +0 -65
- package/dist/ui/Markdown.d.ts +0 -29
- package/dist/ui/Markdown.js +0 -116
- package/dist/ui/PromptCaret.d.ts +0 -11
- package/dist/ui/PromptCaret.js +0 -31
- package/dist/ui/PromptInput.d.ts +0 -192
- package/dist/ui/PromptInput.js +0 -689
- package/dist/ui/QueuePanel.d.ts +0 -8
- package/dist/ui/QueuePanel.js +0 -9
- package/dist/ui/QueueStatusRow.d.ts +0 -24
- package/dist/ui/QueueStatusRow.js +0 -51
- package/dist/ui/ScrollbackShell.d.ts +0 -132
- package/dist/ui/ScrollbackShell.js +0 -26
- package/dist/ui/SessionOpener.d.ts +0 -30
- package/dist/ui/SessionOpener.js +0 -12
- package/dist/ui/StatusBar.d.ts +0 -130
- package/dist/ui/StatusBar.js +0 -61
- package/dist/ui/TeamPanel.d.ts +0 -76
- package/dist/ui/TeamPanel.js +0 -103
- package/dist/ui/ToastStack.d.ts +0 -8
- package/dist/ui/ToastStack.js +0 -31
- package/dist/ui/TodoPanel.d.ts +0 -52
- package/dist/ui/TodoPanel.js +0 -214
- package/dist/ui/Transcript.d.ts +0 -105
- package/dist/ui/Transcript.js +0 -258
- package/dist/ui/UpdateLine.d.ts +0 -44
- package/dist/ui/UpdateLine.js +0 -129
- package/dist/ui/activity-phrases.d.ts +0 -33
- package/dist/ui/activity-phrases.js +0 -50
- package/dist/ui/capabilities.d.ts +0 -27
- package/dist/ui/capabilities.js +0 -65
- package/dist/ui/clipboard-task.d.ts +0 -29
- package/dist/ui/clipboard-task.js +0 -66
- package/dist/ui/clipboard.d.ts +0 -31
- package/dist/ui/clipboard.js +0 -157
- package/dist/ui/color-runtime.d.ts +0 -5
- package/dist/ui/color-runtime.js +0 -29
- package/dist/ui/composer-input.d.ts +0 -38
- package/dist/ui/composer-input.js +0 -79
- package/dist/ui/composer-limits.d.ts +0 -30
- package/dist/ui/composer-limits.js +0 -45
- package/dist/ui/composer-rows.d.ts +0 -73
- package/dist/ui/composer-rows.js +0 -129
- package/dist/ui/console-bridge.d.ts +0 -19
- package/dist/ui/console-bridge.js +0 -52
- package/dist/ui/density.d.ts +0 -26
- package/dist/ui/density.js +0 -34
- package/dist/ui/display-tab.d.ts +0 -51
- package/dist/ui/display-tab.js +0 -82
- package/dist/ui/editor-navigation.d.ts +0 -55
- package/dist/ui/editor-navigation.js +0 -96
- package/dist/ui/editor-reducer.d.ts +0 -108
- package/dist/ui/editor-reducer.js +0 -187
- package/dist/ui/enter-frames.d.ts +0 -47
- package/dist/ui/enter-frames.js +0 -117
- package/dist/ui/entries/AssistantEntry.d.ts +0 -37
- package/dist/ui/entries/AssistantEntry.js +0 -43
- package/dist/ui/entries/CompactionCard.d.ts +0 -88
- package/dist/ui/entries/CompactionCard.js +0 -222
- package/dist/ui/entries/DiffView.d.ts +0 -61
- package/dist/ui/entries/DiffView.js +0 -103
- package/dist/ui/entries/EntryFrame.d.ts +0 -23
- package/dist/ui/entries/EntryFrame.js +0 -6
- package/dist/ui/entries/FastCard.d.ts +0 -53
- package/dist/ui/entries/FastCard.js +0 -105
- package/dist/ui/entries/GovernanceCard.d.ts +0 -30
- package/dist/ui/entries/GovernanceCard.js +0 -32
- package/dist/ui/entries/InvocationCard.d.ts +0 -20
- package/dist/ui/entries/InvocationCard.js +0 -32
- package/dist/ui/entries/QueuedEntry.d.ts +0 -27
- package/dist/ui/entries/QueuedEntry.js +0 -33
- package/dist/ui/entries/RetryCard.d.ts +0 -56
- package/dist/ui/entries/RetryCard.js +0 -60
- package/dist/ui/entries/ServiceCard.d.ts +0 -82
- package/dist/ui/entries/ServiceCard.js +0 -151
- package/dist/ui/entries/TeamCard.d.ts +0 -55
- package/dist/ui/entries/TeamCard.js +0 -94
- package/dist/ui/entries/TodoCard.d.ts +0 -54
- package/dist/ui/entries/TodoCard.js +0 -98
- package/dist/ui/entries/ToolCard.d.ts +0 -81
- package/dist/ui/entries/ToolCard.js +0 -169
- package/dist/ui/entries/ToolPreview.d.ts +0 -59
- package/dist/ui/entries/ToolPreview.js +0 -208
- package/dist/ui/entries/UserEntry.d.ts +0 -36
- package/dist/ui/entries/UserEntry.js +0 -57
- package/dist/ui/entries/WaitCard.d.ts +0 -37
- package/dist/ui/entries/WaitCard.js +0 -92
- package/dist/ui/exit-snapshot.d.ts +0 -43
- package/dist/ui/exit-snapshot.js +0 -26
- package/dist/ui/frame-differ.d.ts +0 -166
- package/dist/ui/frame-differ.js +0 -354
- package/dist/ui/frame-observer.d.ts +0 -17
- package/dist/ui/frame-observer.js +0 -94
- package/dist/ui/frame-parser.d.ts +0 -7
- package/dist/ui/frame-parser.js +0 -18
- package/dist/ui/gauge.d.ts +0 -39
- package/dist/ui/gauge.js +0 -55
- package/dist/ui/glyphs.d.ts +0 -178
- package/dist/ui/glyphs.js +0 -165
- package/dist/ui/governance-copy.d.ts +0 -69
- package/dist/ui/governance-copy.js +0 -104
- package/dist/ui/governance-status.d.ts +0 -145
- package/dist/ui/governance-status.js +0 -326
- package/dist/ui/gradient.d.ts +0 -11
- package/dist/ui/gradient.js +0 -50
- package/dist/ui/ink-runtime.d.ts +0 -4
- package/dist/ui/ink-runtime.js +0 -51
- package/dist/ui/interaction-copy.d.ts +0 -84
- package/dist/ui/interaction-copy.js +0 -41
- package/dist/ui/interaction-hints.d.ts +0 -44
- package/dist/ui/interaction-hints.js +0 -97
- package/dist/ui/layout/AppShell.d.ts +0 -17
- package/dist/ui/layout/AppShell.js +0 -6
- package/dist/ui/layout/Gutter.d.ts +0 -67
- package/dist/ui/layout/Gutter.js +0 -42
- package/dist/ui/layout/MeasuredEntry.d.ts +0 -21
- package/dist/ui/layout/MeasuredEntry.js +0 -30
- package/dist/ui/layout/OverlayFrame.d.ts +0 -73
- package/dist/ui/layout/OverlayFrame.js +0 -110
- package/dist/ui/layout/ScrollIndicator.d.ts +0 -32
- package/dist/ui/layout/ScrollIndicator.js +0 -22
- package/dist/ui/layout/ScrollViewport.d.ts +0 -40
- package/dist/ui/layout/ScrollViewport.js +0 -222
- package/dist/ui/layout/agents-board.d.ts +0 -102
- package/dist/ui/layout/agents-board.js +0 -389
- package/dist/ui/layout/autocomplete.d.ts +0 -18
- package/dist/ui/layout/autocomplete.js +0 -26
- package/dist/ui/layout/budget.d.ts +0 -43
- package/dist/ui/layout/budget.js +0 -52
- package/dist/ui/layout/cells.d.ts +0 -61
- package/dist/ui/layout/cells.js +0 -156
- package/dist/ui/layout/document-layout.d.ts +0 -13
- package/dist/ui/layout/document-layout.js +0 -10
- package/dist/ui/layout/follow-state.d.ts +0 -138
- package/dist/ui/layout/follow-state.js +0 -148
- package/dist/ui/layout/frame.d.ts +0 -36
- package/dist/ui/layout/frame.js +0 -39
- package/dist/ui/layout/governance-board.d.ts +0 -121
- package/dist/ui/layout/governance-board.js +0 -382
- package/dist/ui/layout/governance-card.d.ts +0 -53
- package/dist/ui/layout/governance-card.js +0 -134
- package/dist/ui/layout/governance-chip.d.ts +0 -38
- package/dist/ui/layout/governance-chip.js +0 -64
- package/dist/ui/layout/governance-panel.d.ts +0 -85
- package/dist/ui/layout/governance-panel.js +0 -358
- package/dist/ui/layout/governance-roster.d.ts +0 -65
- package/dist/ui/layout/governance-roster.js +0 -275
- package/dist/ui/layout/header-hints.d.ts +0 -90
- package/dist/ui/layout/header-hints.js +0 -110
- package/dist/ui/layout/header-left.d.ts +0 -115
- package/dist/ui/layout/header-left.js +0 -206
- package/dist/ui/layout/invocation-card.d.ts +0 -41
- package/dist/ui/layout/invocation-card.js +0 -91
- package/dist/ui/layout/kit-chip.d.ts +0 -50
- package/dist/ui/layout/kit-chip.js +0 -81
- package/dist/ui/layout/overlay-window.d.ts +0 -43
- package/dist/ui/layout/overlay-window.js +0 -51
- package/dist/ui/layout/queue-layout.d.ts +0 -19
- package/dist/ui/layout/queue-layout.js +0 -26
- package/dist/ui/layout/rail.d.ts +0 -7
- package/dist/ui/layout/rail.js +0 -16
- package/dist/ui/layout/scroll-indicator.d.ts +0 -27
- package/dist/ui/layout/scroll-indicator.js +0 -36
- package/dist/ui/layout/scroll.d.ts +0 -37
- package/dist/ui/layout/scroll.js +0 -99
- package/dist/ui/layout/scrollbar-geometry.d.ts +0 -17
- package/dist/ui/layout/scrollbar-geometry.js +0 -13
- package/dist/ui/layout/session-chip.d.ts +0 -52
- package/dist/ui/layout/session-chip.js +0 -64
- package/dist/ui/layout/shortcut-panel-layout.d.ts +0 -191
- package/dist/ui/layout/shortcut-panel-layout.js +0 -321
- package/dist/ui/layout/status-detail-layout.d.ts +0 -9
- package/dist/ui/layout/status-detail-layout.js +0 -79
- package/dist/ui/layout/status-layout.d.ts +0 -140
- package/dist/ui/layout/status-layout.js +0 -262
- package/dist/ui/layout/task-summary-cell.d.ts +0 -61
- package/dist/ui/layout/task-summary-cell.js +0 -65
- package/dist/ui/layout/team-panel.d.ts +0 -18
- package/dist/ui/layout/team-panel.js +0 -25
- package/dist/ui/layout/team-row.d.ts +0 -139
- package/dist/ui/layout/team-row.js +0 -246
- package/dist/ui/layout/todo-layout.d.ts +0 -62
- package/dist/ui/layout/todo-layout.js +0 -102
- package/dist/ui/layout/useTerminalSize.d.ts +0 -13
- package/dist/ui/layout/useTerminalSize.js +0 -50
- package/dist/ui/layout/viewport-geometry.d.ts +0 -29
- package/dist/ui/layout/viewport-geometry.js +0 -28
- package/dist/ui/layout/virtual-window.d.ts +0 -112
- package/dist/ui/layout/virtual-window.js +0 -494
- package/dist/ui/layout/wait-bar.d.ts +0 -34
- package/dist/ui/layout/wait-bar.js +0 -48
- package/dist/ui/layout/wrap-rows.d.ts +0 -26
- package/dist/ui/layout/wrap-rows.js +0 -88
- package/dist/ui/live-clamp.d.ts +0 -14
- package/dist/ui/live-clamp.js +0 -46
- package/dist/ui/markdown-blocks.d.ts +0 -107
- package/dist/ui/markdown-blocks.js +0 -240
- package/dist/ui/overlays/AgentsBoardOverlay.d.ts +0 -57
- package/dist/ui/overlays/AgentsBoardOverlay.js +0 -183
- package/dist/ui/overlays/ConfirmDialog.d.ts +0 -31
- package/dist/ui/overlays/ConfirmDialog.js +0 -44
- package/dist/ui/overlays/GovernanceBoardOverlay.d.ts +0 -41
- package/dist/ui/overlays/GovernanceBoardOverlay.js +0 -76
- package/dist/ui/overlays/GovernanceSettingsPage.d.ts +0 -48
- package/dist/ui/overlays/GovernanceSettingsPage.js +0 -93
- package/dist/ui/overlays/HelpOverlay.d.ts +0 -29
- package/dist/ui/overlays/HelpOverlay.js +0 -232
- package/dist/ui/overlays/KitEditor.d.ts +0 -23
- package/dist/ui/overlays/KitEditor.js +0 -101
- package/dist/ui/overlays/KitManager.d.ts +0 -23
- package/dist/ui/overlays/KitManager.js +0 -104
- package/dist/ui/overlays/KitPicker.d.ts +0 -49
- package/dist/ui/overlays/KitPicker.js +0 -58
- package/dist/ui/overlays/ModelDiscoveryList.d.ts +0 -23
- package/dist/ui/overlays/ModelDiscoveryList.js +0 -161
- package/dist/ui/overlays/ModelPicker.d.ts +0 -26
- package/dist/ui/overlays/ModelPicker.js +0 -63
- package/dist/ui/overlays/ModelProfileEditor.d.ts +0 -29
- package/dist/ui/overlays/ModelProfileEditor.js +0 -168
- package/dist/ui/overlays/ModelProfilePicker.d.ts +0 -48
- package/dist/ui/overlays/ModelProfilePicker.js +0 -231
- package/dist/ui/overlays/PlanReviewOverlay.d.ts +0 -51
- package/dist/ui/overlays/PlanReviewOverlay.js +0 -132
- package/dist/ui/overlays/PromptEditorPage.d.ts +0 -48
- package/dist/ui/overlays/PromptEditorPage.js +0 -227
- package/dist/ui/overlays/PromptLibraryOverlay.d.ts +0 -37
- package/dist/ui/overlays/PromptLibraryOverlay.js +0 -191
- package/dist/ui/overlays/PromptPicker.d.ts +0 -36
- package/dist/ui/overlays/PromptPicker.js +0 -129
- package/dist/ui/overlays/PromptTextArea.d.ts +0 -86
- package/dist/ui/overlays/PromptTextArea.js +0 -141
- package/dist/ui/overlays/QuestionOverlay.d.ts +0 -39
- package/dist/ui/overlays/QuestionOverlay.js +0 -258
- package/dist/ui/overlays/QueueOverlay.d.ts +0 -22
- package/dist/ui/overlays/QueueOverlay.js +0 -79
- package/dist/ui/overlays/SettingsScreen.d.ts +0 -228
- package/dist/ui/overlays/SettingsScreen.js +0 -1037
- package/dist/ui/overlays/ShortcutPanel.d.ts +0 -39
- package/dist/ui/overlays/ShortcutPanel.js +0 -106
- package/dist/ui/overlays/TeamFanoutPage.d.ts +0 -51
- package/dist/ui/overlays/TeamFanoutPage.js +0 -90
- package/dist/ui/overlays/governance-settings.d.ts +0 -79
- package/dist/ui/overlays/governance-settings.js +0 -140
- package/dist/ui/overlays/kit-picker-state.d.ts +0 -87
- package/dist/ui/overlays/kit-picker-state.js +0 -136
- package/dist/ui/overlays/kit-settings-state.d.ts +0 -129
- package/dist/ui/overlays/kit-settings-state.js +0 -268
- package/dist/ui/overlays/model-probe-view.d.ts +0 -128
- package/dist/ui/overlays/model-probe-view.js +0 -225
- package/dist/ui/overlays/model-profile-state.d.ts +0 -177
- package/dist/ui/overlays/model-profile-state.js +0 -301
- package/dist/ui/overlays/prompt-library-state.d.ts +0 -162
- package/dist/ui/overlays/prompt-library-state.js +0 -335
- package/dist/ui/overlays/prompt-picker-state.d.ts +0 -71
- package/dist/ui/overlays/prompt-picker-state.js +0 -98
- package/dist/ui/overlays/team-fanout-state.d.ts +0 -106
- package/dist/ui/overlays/team-fanout-state.js +0 -155
- package/dist/ui/overlays/use-model-probe.d.ts +0 -30
- package/dist/ui/overlays/use-model-probe.js +0 -109
- package/dist/ui/palettes.d.ts +0 -112
- package/dist/ui/palettes.js +0 -130
- package/dist/ui/paste-frames.d.ts +0 -91
- package/dist/ui/paste-frames.js +0 -117
- package/dist/ui/paste-tokens.d.ts +0 -90
- package/dist/ui/paste-tokens.js +0 -147
- package/dist/ui/render-cache.d.ts +0 -81
- package/dist/ui/render-cache.js +0 -196
- package/dist/ui/render-governor.d.ts +0 -54
- package/dist/ui/render-governor.js +0 -78
- package/dist/ui/run-metrics.d.ts +0 -23
- package/dist/ui/run-metrics.js +0 -27
- package/dist/ui/run-status-row.d.ts +0 -63
- package/dist/ui/run-status-row.js +0 -54
- package/dist/ui/screen.d.ts +0 -107
- package/dist/ui/screen.js +0 -234
- package/dist/ui/scrollback/LiveTail.d.ts +0 -115
- package/dist/ui/scrollback/LiveTail.js +0 -48
- package/dist/ui/scrollback/band.d.ts +0 -114
- package/dist/ui/scrollback/band.js +0 -143
- package/dist/ui/scrollback/budget.d.ts +0 -90
- package/dist/ui/scrollback/budget.js +0 -100
- package/dist/ui/scrollback/canvas.d.ts +0 -100
- package/dist/ui/scrollback/canvas.js +0 -114
- package/dist/ui/scrollback/cursor-probe.d.ts +0 -71
- package/dist/ui/scrollback/cursor-probe.js +0 -133
- package/dist/ui/scrollback/drain.d.ts +0 -32
- package/dist/ui/scrollback/drain.js +0 -64
- package/dist/ui/scrollback/exit-summary.d.ts +0 -23
- package/dist/ui/scrollback/exit-summary.js +0 -25
- package/dist/ui/scrollback/limits.d.ts +0 -98
- package/dist/ui/scrollback/limits.js +0 -98
- package/dist/ui/scrollback/live-preview.d.ts +0 -34
- package/dist/ui/scrollback/live-preview.js +0 -130
- package/dist/ui/scrollback/overflow-print.d.ts +0 -108
- package/dist/ui/scrollback/overflow-print.js +0 -120
- package/dist/ui/scrollback/renderer.d.ts +0 -48
- package/dist/ui/scrollback/renderer.js +0 -186
- package/dist/ui/scrollback/scrollback-writer.d.ts +0 -174
- package/dist/ui/scrollback/scrollback-writer.js +0 -648
- package/dist/ui/scrollback/settled-boundary.d.ts +0 -42
- package/dist/ui/scrollback/settled-boundary.js +0 -109
- package/dist/ui/scrollback/tail-anchor.d.ts +0 -71
- package/dist/ui/scrollback/tail-anchor.js +0 -79
- package/dist/ui/scrollback/tail-window.d.ts +0 -73
- package/dist/ui/scrollback/tail-window.js +0 -89
- package/dist/ui/scrollback/use-scrollback-view.d.ts +0 -139
- package/dist/ui/scrollback/use-scrollback-view.js +0 -601
- package/dist/ui/scrollback/writer-shapes.d.ts +0 -127
- package/dist/ui/scrollback/writer-shapes.js +0 -159
- package/dist/ui/scrollbar-controller.d.ts +0 -30
- package/dist/ui/scrollbar-controller.js +0 -124
- package/dist/ui/selection/highlight.d.ts +0 -39
- package/dist/ui/selection/highlight.js +0 -64
- package/dist/ui/selection/screen-mirror.d.ts +0 -24
- package/dist/ui/selection/screen-mirror.js +0 -35
- package/dist/ui/selection/selection-controller.d.ts +0 -104
- package/dist/ui/selection/selection-controller.js +0 -372
- package/dist/ui/selection/selection.d.ts +0 -90
- package/dist/ui/selection/selection.js +0 -223
- package/dist/ui/shortcuts.d.ts +0 -81
- package/dist/ui/shortcuts.js +0 -221
- package/dist/ui/status-feedback.d.ts +0 -35
- package/dist/ui/status-feedback.js +0 -38
- package/dist/ui/stdout-frame-writer.d.ts +0 -74
- package/dist/ui/stdout-frame-writer.js +0 -155
- package/dist/ui/team-status.d.ts +0 -166
- package/dist/ui/team-status.js +0 -252
- package/dist/ui/terminal-plan.d.ts +0 -52
- package/dist/ui/terminal-plan.js +0 -49
- package/dist/ui/theme.d.ts +0 -96
- package/dist/ui/theme.js +0 -130
- package/dist/ui/transcript-text.d.ts +0 -41
- package/dist/ui/transcript-text.js +0 -282
- package/dist/ui/use-height-store.d.ts +0 -31
- package/dist/ui/use-height-store.js +0 -76
- package/dist/ui/use-render-governor.d.ts +0 -39
- package/dist/ui/use-render-governor.js +0 -57
- package/dist/ui/use-wheel-routing.d.ts +0 -57
- package/dist/ui/use-wheel-routing.js +0 -152
- package/dist/ui/win-vt-force.d.ts +0 -136
- package/dist/ui/win-vt-force.js +0 -237
- package/dist/ui/win-vt-input.d.ts +0 -57
- package/dist/ui/win-vt-input.js +0 -62
- package/dist/update/limits.d.ts +0 -111
- package/dist/update/limits.js +0 -111
- package/dist/update/semver.d.ts +0 -89
- package/dist/update/semver.js +0 -295
- package/dist/update/types.d.ts +0 -169
- package/dist/update/types.js +0 -68
- /package/dist/{ui → app}/session-bridge.d.ts +0 -0
- /package/dist/{ui → app}/session-bridge.js +0 -0
|
@@ -1,1037 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* Settings screen — edit provider / model / base URL / thinking / max tokens /
|
|
4
|
-
* API key for the active provider (spec §3.5 / §5.2). Up/Down move between
|
|
5
|
-
* fields; Left/Right cycle enum fields; typing edits text/secret fields;
|
|
6
|
-
* Enter saves; Esc (handled by the App) closes without saving.
|
|
7
|
-
*
|
|
8
|
-
* The API key is never printed: it renders as dots while editing and masked
|
|
9
|
-
* otherwise.
|
|
10
|
-
*/
|
|
11
|
-
import { useEffect, useReducer, useRef, useState } from 'react';
|
|
12
|
-
import { Text, useInput } from 'ink';
|
|
13
|
-
import { DEFAULT_MAX_OUTPUT_TOKENS, resolveOutputTokens, } from '@aragon-agent/core';
|
|
14
|
-
import { ADAPTER_PROVIDERS, THINKING_LEVELS, maskSecret, parseContextWindowInput, parseMaxTokensInput, parseThresholdInput, } from '../../config/schema.js';
|
|
15
|
-
import { LOG_LEVEL_NAMES } from '../../logging/levels.js';
|
|
16
|
-
import { pickGlyphs } from '../glyphs.js';
|
|
17
|
-
import { OverlayFrame } from '../layout/OverlayFrame.js';
|
|
18
|
-
import { stripPasteFrames } from '../paste-frames.js';
|
|
19
|
-
import { stripEnterFrames } from '../enter-frames.js';
|
|
20
|
-
import { emptyModelProfiles } from '../../config/model-profiles.js';
|
|
21
|
-
import { registerSecret } from '../../logging/secret-registry.js';
|
|
22
|
-
import { ModelProfilePicker, useProfileScroll } from './ModelProfilePicker.js';
|
|
23
|
-
import { ModelProfileEditor } from './ModelProfileEditor.js';
|
|
24
|
-
import { ModelDiscoveryList } from './ModelDiscoveryList.js';
|
|
25
|
-
import { useModelProbe } from './use-model-probe.js';
|
|
26
|
-
import { canProbe, editorProbeTarget, visibleProbeViews } from './model-probe-view.js';
|
|
27
|
-
import { createModelProfileState, createCustomProfile, modelProfileReducer, profileUsers, draftTeam, draftSubagentProfileId, subagentModelSummary, subagentSelectedId, SUBAGENT_FAST_ROW_ID } from './model-profile-state.js';
|
|
28
|
-
import { KitEditor } from './KitEditor.js';
|
|
29
|
-
import { KitManager } from './KitManager.js';
|
|
30
|
-
import { TeamFanoutPage } from './TeamFanoutPage.js';
|
|
31
|
-
import { fanoutRows, teamFanoutValues, teamSummary } from './team-fanout-state.js';
|
|
32
|
-
import { GovernanceSettingsPage } from './GovernanceSettingsPage.js';
|
|
33
|
-
import { draftGovernance, governanceRestartNote, governanceSettingRows, governanceSummary, } from './governance-settings.js';
|
|
34
|
-
import { heldSlots, kitManagerRows, kitPackRow, kitReducer } from './kit-settings-state.js';
|
|
35
|
-
/**
|
|
36
|
-
* THE ROOT PAGE'S ROW INDEXES, AS NAMES (subagent-model V-5).
|
|
37
|
-
*
|
|
38
|
-
* Five offset sites used to agree by accident on the number 3; the Subagent
|
|
39
|
-
* model row moves every one of them. Each site below now cites its constant,
|
|
40
|
-
* so adding a row later is a one-line change instead of a silent regression
|
|
41
|
-
* that focuses an error message on the wrong field.
|
|
42
|
-
*
|
|
43
|
-
* DERIVED FROM ONE LIST (agent-model-kits §4.5), because the kit row is the
|
|
44
|
-
* fifth of these and the "five offsets agreed by accident" defect does not need
|
|
45
|
-
* a sequel. Order here IS the render order.
|
|
46
|
-
*/
|
|
47
|
-
const ROOT_ROWS = ['main', 'fast', 'subagent', 'team', 'governance', 'kit', 'manage'];
|
|
48
|
-
const ROOT_MAIN = ROOT_ROWS.indexOf('main');
|
|
49
|
-
const ROOT_FAST = ROOT_ROWS.indexOf('fast');
|
|
50
|
-
const ROOT_SUBAGENT = ROOT_ROWS.indexOf('subagent');
|
|
51
|
-
// The fan-out page (subagent-fanout D-5). It is FOURTH, directly under the model
|
|
52
|
-
// row it complements: "which model children run on" and "how many children" are
|
|
53
|
-
// one decision, and splitting them across the page would make the pair harder to
|
|
54
|
-
// keep consistent than the pair of numbers inside it.
|
|
55
|
-
const ROOT_TEAM = ROOT_ROWS.indexOf('team');
|
|
56
|
-
// Governance (governance-mode-v1-1 5.2) sits right under Team: both decide the SHAPE of the
|
|
57
|
-
// team, and the row is an index into this list like every other, never a typed number.
|
|
58
|
-
const ROOT_GOVERNANCE = ROOT_ROWS.indexOf('governance');
|
|
59
|
-
const ROOT_KIT = ROOT_ROWS.indexOf('kit');
|
|
60
|
-
const ROOT_MANAGE = ROOT_ROWS.indexOf('manage');
|
|
61
|
-
const ROOT_FIRST_FIELD = ROOT_ROWS.length;
|
|
62
|
-
/** Stand-in target while no editor exists; no probe row is rendered then. */
|
|
63
|
-
const NO_PROFILE_TARGET = { provider: '', model: '', baseUrl: null,
|
|
64
|
-
apiKey: null };
|
|
65
|
-
const SHOW_THINKING_OPTIONS = ['off', 'on'];
|
|
66
|
-
const LIVE_OUTPUT_OPTIONS = ['off', 'on'];
|
|
67
|
-
const FAST_ENABLED_OPTIONS = ['off', 'on'];
|
|
68
|
-
const COMPACTION_ENABLED_OPTIONS = ['off', 'on'];
|
|
69
|
-
/**
|
|
70
|
-
* `(inherit)` IS THE EMPTY STRING, rendered as a word.
|
|
71
|
-
*
|
|
72
|
-
* An empty enum cell would read as "unset and therefore broken"; the truth is
|
|
73
|
-
* that an empty `fast.provider` INHERITS the main provider, which is the setting
|
|
74
|
-
* most users want and the one they should not have to type (§3.2 rule 2).
|
|
75
|
-
*/
|
|
76
|
-
const FAST_INHERIT_PROVIDER = '(inherit)';
|
|
77
|
-
const FAST_PROVIDER_OPTIONS = [FAST_INHERIT_PROVIDER, ...ADAPTER_PROVIDERS];
|
|
78
|
-
/**
|
|
79
|
-
* The derived, non-editable line under the five fast rows — the sibling of
|
|
80
|
-
* `effectiveCapLine`, and it exists for the same reason (§4.5).
|
|
81
|
-
*
|
|
82
|
-
* A SETTINGS SCREEN THAT LETS A USER SWITCH A TIER ON AND GIVES NO SIGNAL THAT
|
|
83
|
-
* IT CANNOT RESOLVE is the failure `effectiveCapLine` was added to fix for
|
|
84
|
-
* `maxTokens`, one screen later. `keyFor` is the same resolver the controller
|
|
85
|
-
* uses, so this line and the runtime cannot disagree.
|
|
86
|
-
*
|
|
87
|
-
* IT DOES NOT TAKE `fastReviewBudget` AND MUST NOT (§4.4 part 5): this line
|
|
88
|
-
* describes what the tier IS, not what it is allowed to spend.
|
|
89
|
-
*/
|
|
90
|
-
export function fastTierLine(values, hasKey) {
|
|
91
|
-
if (values.fastEnabled !== 'on')
|
|
92
|
-
return 'Fast tier: off';
|
|
93
|
-
const model = values.fastModel.trim();
|
|
94
|
-
if (model.length === 0)
|
|
95
|
-
return 'Fast tier: off (fast.model is not set)';
|
|
96
|
-
const provider = values.fastProvider === FAST_INHERIT_PROVIDER || values.fastProvider.trim().length === 0
|
|
97
|
-
? values.provider
|
|
98
|
-
: values.fastProvider;
|
|
99
|
-
if (!hasKey(provider)) {
|
|
100
|
-
return `Fast tier: ${provider}:${model} (no API key for ${provider} - the tier will stay off)`;
|
|
101
|
-
}
|
|
102
|
-
const review = values.fastReview.trim().toLowerCase();
|
|
103
|
-
const cadence = review === 'off'
|
|
104
|
-
? 'review off'
|
|
105
|
-
: /^\d+$/.test(review)
|
|
106
|
-
? `review every ${review} turns`
|
|
107
|
-
: 'review every 5 turns';
|
|
108
|
-
return `Fast tier: ${provider}:${model} (key set) ${cadence}`;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* The five editable fast rows, as a config patch (§4.5 / hardening §4.4).
|
|
112
|
-
*
|
|
113
|
-
* PURE AND EXPORTED so `App`'s save handler holds no parsing of its own, and so
|
|
114
|
-
* the round trip `fastSettingsFrom(config)` -> edit -> `readFastSettings` can be
|
|
115
|
-
* tested without a terminal.
|
|
116
|
-
*
|
|
117
|
-
* A TYPO IN `fastReview` CHANGES NOTHING — the `review` / `reviewEveryTurns`
|
|
118
|
-
* keys are simply omitted from the patch, so `clampFastConfig`'s merge keeps
|
|
119
|
-
* whatever was there. That is the `Max tokens` discipline this screen already
|
|
120
|
-
* follows, and the alternative (resolving a typo to the default) silently
|
|
121
|
-
* discards the cadence the user actually set. `fastReviewBudget` follows the
|
|
122
|
-
* same rule; an out-of-range NUMBER is passed through to `clampFastConfig`'s
|
|
123
|
-
* `REVIEW_SESSION_RANGE` rather than being validated a second time here, so a
|
|
124
|
-
* row edit and a hand-edited `config.json` land on the same value.
|
|
125
|
-
*/
|
|
126
|
-
export function readFastSettings(values) {
|
|
127
|
-
const review = values.fastReview.trim().toLowerCase();
|
|
128
|
-
const parsed = /^\d+$/.test(review) ? Number.parseInt(review, 10) : Number.NaN;
|
|
129
|
-
const budget = values.fastReviewBudget.trim();
|
|
130
|
-
const parsedBudget = /^\d+$/.test(budget) ? Number.parseInt(budget, 10) : Number.NaN;
|
|
131
|
-
return {
|
|
132
|
-
enabled: values.fastEnabled === 'on',
|
|
133
|
-
model: values.fastModel.trim(),
|
|
134
|
-
provider: values.fastProvider === FAST_INHERIT_PROVIDER ? '' : values.fastProvider.trim(),
|
|
135
|
-
...(review === 'off' ? { review: false } : {}),
|
|
136
|
-
...(Number.isFinite(parsed) && parsed > 0
|
|
137
|
-
? { review: true, reviewEveryTurns: parsed }
|
|
138
|
-
: {}),
|
|
139
|
-
...(Number.isFinite(parsedBudget) ? { reviewMaxPerSession: parsedBudget } : {}),
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* The inverse: seed the five rows from a resolved config.
|
|
144
|
-
*
|
|
145
|
-
* OMITTING A KEY HERE IS THE SILENT HALF OF ADDING A ROW (§4.4 part 4): the row
|
|
146
|
-
* renders empty, `readFastSettings` sees an unparseable value, and an untouched
|
|
147
|
-
* save writes the clamp's default over whatever the user had.
|
|
148
|
-
*/
|
|
149
|
-
export function fastSettingsFrom(fast) {
|
|
150
|
-
return {
|
|
151
|
-
fastEnabled: fast.enabled ? 'on' : 'off',
|
|
152
|
-
fastModel: fast.model,
|
|
153
|
-
fastProvider: fast.provider.trim().length > 0 ? fast.provider : FAST_INHERIT_PROVIDER,
|
|
154
|
-
fastReview: fast.review ? String(fast.reviewEveryTurns) : 'off',
|
|
155
|
-
fastReviewBudget: String(fast.reviewMaxPerSession),
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Read the three compaction rows back into a config patch.
|
|
160
|
-
*
|
|
161
|
-
* A TYPO CHANGES NOTHING — the discipline `readFastSettings` states one function
|
|
162
|
-
* up, and the reason is the same: a threshold that silently resolved to the
|
|
163
|
-
* default on a mistyped keystroke would be a setting the user believes they
|
|
164
|
-
* changed and did not. `parseThresholdInput` returns `null` for anything that is
|
|
165
|
-
* not a ratio or a percentage, and the key is then simply absent from the patch.
|
|
166
|
-
*/
|
|
167
|
-
export function readCompactionSettings(values) {
|
|
168
|
-
const threshold = parseThresholdInput(values.compactionThreshold);
|
|
169
|
-
const keep = values.compactionKeepTurns.trim();
|
|
170
|
-
const parsedKeep = /^\d+$/.test(keep) ? Number.parseInt(keep, 10) : Number.NaN;
|
|
171
|
-
return {
|
|
172
|
-
enabled: values.compactionEnabled === 'on',
|
|
173
|
-
...(threshold !== null ? { threshold } : {}),
|
|
174
|
-
...(Number.isFinite(parsedKeep) && parsedKeep > 0 ? { keepRecentTurns: parsedKeep } : {}),
|
|
175
|
-
// AN ENUM ROW CANNOT BE MISTYPED, so unlike the two text rows above these are
|
|
176
|
-
// written unconditionally.
|
|
177
|
-
subagents: values.compactionSubagents === 'on',
|
|
178
|
-
archive: values.compactionArchive === 'on',
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* The inverse: seed the three rows from a resolved config.
|
|
183
|
-
*
|
|
184
|
-
* OMITTING A KEY HERE IS THE SILENT HALF OF ADDING A ROW, exactly as it is for
|
|
185
|
-
* the fast rows above: the row renders empty, `readCompactionSettings` sees an
|
|
186
|
-
* unparseable value, and an untouched save writes the clamp's default over
|
|
187
|
-
* whatever the user had.
|
|
188
|
-
*/
|
|
189
|
-
export function compactionSettingsFrom(compaction) {
|
|
190
|
-
return {
|
|
191
|
-
compactionEnabled: compaction.enabled ? 'on' : 'off',
|
|
192
|
-
// A PERCENTAGE, because that is the unit the status bar shows and the unit a
|
|
193
|
-
// user thinks in. `parseThresholdInput` accepts it back.
|
|
194
|
-
compactionThreshold: String(Math.round(compaction.threshold * 100)),
|
|
195
|
-
compactionKeepTurns: String(compaction.keepRecentTurns),
|
|
196
|
-
compactionSubagents: compaction.subagents ? 'on' : 'off',
|
|
197
|
-
compactionArchive: compaction.archive ? 'on' : 'off',
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
const FIELDS = [
|
|
201
|
-
{ key: 'provider', label: 'Provider', kind: 'enum', options: ADAPTER_PROVIDERS },
|
|
202
|
-
{ key: 'model', label: 'Model', kind: 'text' },
|
|
203
|
-
{ key: 'baseUrl', label: 'Base URL', kind: 'text' },
|
|
204
|
-
{ key: 'thinkingLevel', label: 'Thinking', kind: 'enum', options: THINKING_LEVELS },
|
|
205
|
-
// Directly under `Thinking`, so the effort setting and the display setting are
|
|
206
|
-
// read together. `Show thinking` is 13 characters, inside the 18-column label
|
|
207
|
-
// budget `.padEnd(18)` enforces below and that IF-H7 records as silently
|
|
208
|
-
// overflowing.
|
|
209
|
-
{ key: 'showThinking', label: 'Show thinking', kind: 'enum', options: SHOW_THINKING_OPTIONS },
|
|
210
|
-
// Beside `Show thinking`, because the two are the transcript's only display
|
|
211
|
-
// switches. `Live output` is 11 characters, inside the 18-column label budget
|
|
212
|
-
// `.padEnd(18)` enforces below and that IF-H7 records as silently overflowing.
|
|
213
|
-
{ key: 'liveToolOutput', label: 'Live output', kind: 'enum', options: LIVE_OUTPUT_OPTIONS },
|
|
214
|
-
{ key: 'maxTokens', label: 'Max tokens', kind: 'text' },
|
|
215
|
-
// DIRECTLY UNDER `Max tokens`: the two token rows read together. `Context
|
|
216
|
-
// window` is 14 characters, inside the 18-column label budget `.padEnd(18)`
|
|
217
|
-
// enforces below (IF-H7). Only ever RENDERED while Main is unbound - see
|
|
218
|
-
// `SettingsValues.contextWindow` and the unbound-group filter below.
|
|
219
|
-
{ key: 'contextWindow', label: 'Context window', kind: 'text' },
|
|
220
|
-
// The fast tier sits AFTER `Max tokens` and BEFORE `API key`, because the key
|
|
221
|
-
// row is the one a user scrolls to deliberately and putting five rows past it
|
|
222
|
-
// would bury it (fast-model-tier §4.5). The rationale survives a fifth row;
|
|
223
|
-
// the count in it did not.
|
|
224
|
-
//
|
|
225
|
-
// `Fast review budget` is a `'text'` row, NOT a new numeric kind (D-H12):
|
|
226
|
-
// `SettingsRow.kind` is `'enum' | 'text' | 'secret'`, and `Max tokens` and
|
|
227
|
-
// `Fast review` are both bounded numbers already living as text plus an
|
|
228
|
-
// adapter parse. A fourth kind for one row would be a new interaction pattern
|
|
229
|
-
// in a screen whose whole design is that it edits text.
|
|
230
|
-
//
|
|
231
|
-
// ITS LABEL IS SHORT BECAUSE THE LABEL COLUMN IS A BUDGET, NOT A HINT SLOT.
|
|
232
|
-
// Labels render `.padEnd(18)` below, so one that reaches 18 does not truncate
|
|
233
|
-
// and does not wrap - it pushes ITS OWN value right (or butts against it at
|
|
234
|
-
// exactly 18) while every other row's value stays put, and the column stops
|
|
235
|
-
// being a column. So no `(1-500)` here: no other bounded row carries its range
|
|
236
|
-
// either (`Max tokens`, `Fast review`), `clampFastConfig` is the enforcement,
|
|
237
|
-
// and `/fast budget` states the range in the one place a user meets it - when
|
|
238
|
-
// it refuses a bad one. The name matches that command for the same reason.
|
|
239
|
-
{ key: 'fastEnabled', label: 'Fast tier', kind: 'enum', options: FAST_ENABLED_OPTIONS },
|
|
240
|
-
{ key: 'fastModel', label: 'Fast model', kind: 'text' },
|
|
241
|
-
{ key: 'fastProvider', label: 'Fast provider', kind: 'enum', options: FAST_PROVIDER_OPTIONS },
|
|
242
|
-
{ key: 'fastReview', label: 'Fast review', kind: 'text' },
|
|
243
|
-
{ key: 'fastReviewBudget', label: 'Fast budget', kind: 'text' },
|
|
244
|
-
// Context compaction sits after the fast rows and still BEFORE `API key`, for
|
|
245
|
-
// the reason recorded above that row: the key is the one a user scrolls to
|
|
246
|
-
// deliberately, and burying it further would be worse than the ordering is
|
|
247
|
-
// better. Three rows, and every label is inside the 18-column budget
|
|
248
|
-
// `.padEnd(18)` enforces below.
|
|
249
|
-
//
|
|
250
|
-
// `Compact at` is a PERCENTAGE and carries no `(50-95)` hint, for the reason
|
|
251
|
-
// `Fast budget` records: no other bounded row carries its range either,
|
|
252
|
-
// `clampCompactionConfig` is the enforcement, and `/compact threshold` states
|
|
253
|
-
// the range in the one place a user meets it — when it refuses a bad one.
|
|
254
|
-
{ key: 'compactionEnabled', label: 'Auto-compaction', kind: 'enum', options: COMPACTION_ENABLED_OPTIONS },
|
|
255
|
-
{ key: 'compactionThreshold', label: 'Compact at %', kind: 'text' },
|
|
256
|
-
{ key: 'compactionKeepTurns', label: 'Keep turns', kind: 'text' },
|
|
257
|
-
// Both labels are inside the 18-column budget `.padEnd(18)` enforces below.
|
|
258
|
-
{ key: 'compactionSubagents', label: 'Compact children', kind: 'enum', options: COMPACTION_ENABLED_OPTIONS },
|
|
259
|
-
{ key: 'compactionArchive', label: 'Archive dropped', kind: 'enum', options: COMPACTION_ENABLED_OPTIONS },
|
|
260
|
-
{ key: 'apiKey', label: 'API key', kind: 'secret' },
|
|
261
|
-
{ key: 'logLevel', label: 'Log level', kind: 'enum', options: LOG_LEVEL_NAMES },
|
|
262
|
-
];
|
|
263
|
-
/**
|
|
264
|
-
* The cap this setting will ACTUALLY produce against the selected model.
|
|
265
|
-
*
|
|
266
|
-
* Exported for the tests, and computed on every render rather than in an effect:
|
|
267
|
-
* `resolveOutputTokens` is pure, allocation-light and does no I/O — the ceiling
|
|
268
|
-
* lookup is a `Map.get` plus at most seven regex tests.
|
|
269
|
-
*
|
|
270
|
-
* Without this row the settings screen can only show what the user typed, and
|
|
271
|
-
* "I set 64000 but answers still stop early" has no answer anywhere in the UI.
|
|
272
|
-
*/
|
|
273
|
-
export function effectiveCapLine(values) {
|
|
274
|
-
const parsed = parseMaxTokensInput(values.maxTokens);
|
|
275
|
-
if (parsed.kind === 'invalid')
|
|
276
|
-
return 'Effective: - (not a number; use a value or "auto")';
|
|
277
|
-
const requested = parsed.kind === 'value' ? parsed.value : undefined;
|
|
278
|
-
const resolution = resolveOutputTokens({
|
|
279
|
-
providerId: values.provider,
|
|
280
|
-
modelId: values.model,
|
|
281
|
-
...(requested !== undefined ? { requested } : {}),
|
|
282
|
-
});
|
|
283
|
-
if (resolution.clampedBy === 'ceiling') {
|
|
284
|
-
const ambition = requested ?? DEFAULT_MAX_OUTPUT_TOKENS;
|
|
285
|
-
return `Effective: ${resolution.value} (clamped from ${ambition} by the ${values.model} ceiling)`;
|
|
286
|
-
}
|
|
287
|
-
if (requested === undefined)
|
|
288
|
-
return `Effective: ${resolution.value} (auto)`;
|
|
289
|
-
return `Effective: ${resolution.value}`;
|
|
290
|
-
}
|
|
291
|
-
export function SettingsScreen(props) {
|
|
292
|
-
return props.draft ? _jsx(ProfileSettingsScreen, { ...props, draft: props.draft })
|
|
293
|
-
: _jsx(LegacySettingsScreen, { ...props });
|
|
294
|
-
}
|
|
295
|
-
function LegacySettingsScreen({ isActive = true, initial, apiKeys, maxRows, cols, scrollOffset, onScrollClamp, theme, caps, onSave, retrySummary, }) {
|
|
296
|
-
const [values, setValues] = useState(initial);
|
|
297
|
-
const [index, setIndex] = useState(0);
|
|
298
|
-
const glyphs = pickGlyphs(caps);
|
|
299
|
-
const field = FIELDS[index];
|
|
300
|
-
const focusedOffset = useProfileScroll({ maxRows, cols, scrollOffset, onScrollClamp, theme, caps }, index);
|
|
301
|
-
const cycle = (dir) => {
|
|
302
|
-
if (field.kind !== 'enum' || !field.options)
|
|
303
|
-
return;
|
|
304
|
-
const opts = field.options;
|
|
305
|
-
const cur = opts.indexOf(String(values[field.key]));
|
|
306
|
-
const next = (cur + dir + opts.length) % opts.length;
|
|
307
|
-
const nextVal = opts[next];
|
|
308
|
-
setValues((prev) => {
|
|
309
|
-
const updated = { ...prev, [field.key]: nextVal };
|
|
310
|
-
// Clear the key editor on provider switch. Never round-trip a resolved
|
|
311
|
-
// (possibly env-only) key into the editor — saving would then persist a
|
|
312
|
-
// secret the user never typed into the 0600 config file.
|
|
313
|
-
if (field.key === 'provider') {
|
|
314
|
-
updated.apiKey = '';
|
|
315
|
-
}
|
|
316
|
-
return updated;
|
|
317
|
-
});
|
|
318
|
-
};
|
|
319
|
-
useInput((input, key) => {
|
|
320
|
-
if (!isActive)
|
|
321
|
-
return;
|
|
322
|
-
if (key.escape)
|
|
323
|
-
return; // App closes the overlay.
|
|
324
|
-
if (key.upArrow) {
|
|
325
|
-
setIndex((i) => (i - 1 + FIELDS.length) % FIELDS.length);
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
// `&& !key.shift` is a real key collision, not a style choice: Shift+Tab is
|
|
329
|
-
// the global mode toggle, and without the guard it would also advance the
|
|
330
|
-
// field cursor here — the user changes mode and their selection jumps
|
|
331
|
-
// (AC-P4). The mode toggle itself is a no-op while an overlay is open, so
|
|
332
|
-
// this branch simply has to stay out of the way.
|
|
333
|
-
if (key.downArrow || (key.tab && !key.shift)) {
|
|
334
|
-
setIndex((i) => (i + 1) % FIELDS.length);
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
if (key.return) {
|
|
338
|
-
onSave?.(values);
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
if (field.kind === 'enum') {
|
|
342
|
-
if (key.leftArrow)
|
|
343
|
-
cycle(-1);
|
|
344
|
-
if (key.rightArrow)
|
|
345
|
-
cycle(1);
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
// text / secret editing
|
|
349
|
-
if (key.backspace || key.delete) {
|
|
350
|
-
setValues((prev) => ({ ...prev, [field.key]: String(prev[field.key]).slice(0, -1) }));
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
if (input && !key.ctrl && !key.meta) {
|
|
354
|
-
// `stripPasteFrames`, NOT `input` (I-12 / P0-2). `useInput` is a BROADCAST,
|
|
355
|
-
// so this handler sees the NUL-framed paste the composer was sent. An API
|
|
356
|
-
// key is ~100 characters with no line break, which trips the filter's Tier
|
|
357
|
-
// 2 burst rule and gets framed -- and nothing downstream would remove the
|
|
358
|
-
// NULs: `trim()` does not treat U+0000 as whitespace, `maskDot` hides the
|
|
359
|
-
// damage, and the value is handed to `registerSecret()` and
|
|
360
|
-
// `controller.setApiKey()`. The user is told the settings were saved and
|
|
361
|
-
// every request afterwards fails to authenticate with nothing on screen to
|
|
362
|
-
// explain it. Pasting IS how a key enters this process.
|
|
363
|
-
// `stripEnterFrames` INSIDE (tui-shift-enter-copy-queue 3.5): the same
|
|
364
|
-
// broadcast carries the newline frame a Shift+Enter produced, and this
|
|
365
|
-
// composition order is the one that leaves no NUL in the field -- the
|
|
366
|
-
// outer paste strip removes the frame's newline for a single-line field
|
|
367
|
-
// exactly as it removes a bare Ctrl+J today, while the reverse order
|
|
368
|
-
// would leak the frame's letter as visible text.
|
|
369
|
-
const text = stripPasteFrames(stripEnterFrames(input));
|
|
370
|
-
if (text.length === 0)
|
|
371
|
-
return;
|
|
372
|
-
setValues((prev) => ({ ...prev, [field.key]: String(prev[field.key]) + text }));
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
const displayValue = (f, selected) => {
|
|
376
|
-
const raw = String(values[f.key] ?? '');
|
|
377
|
-
if (f.kind === 'secret') {
|
|
378
|
-
// Indicate an already-configured key (env or file) without revealing it or
|
|
379
|
-
// its length — the editor stays empty until the user types a replacement.
|
|
380
|
-
const configured = (apiKeys[values.provider] ?? '').length > 0;
|
|
381
|
-
if (raw.length > 0) {
|
|
382
|
-
return selected
|
|
383
|
-
? glyphs.maskDot.repeat(Math.min(raw.length, 24))
|
|
384
|
-
: maskSecret(raw, { maskChar: glyphs.maskDot, ellipsis: glyphs.ellipsis });
|
|
385
|
-
}
|
|
386
|
-
if (configured)
|
|
387
|
-
return selected ? '(configured - type to replace)' : '(configured)';
|
|
388
|
-
return selected ? '(type to set)' : '(none)';
|
|
389
|
-
}
|
|
390
|
-
if (f.kind === 'enum')
|
|
391
|
-
return raw;
|
|
392
|
-
// An empty cap field is AUTO, not "unset". `(none)` would read as a missing
|
|
393
|
-
// setting, which is the one thing this field can never be.
|
|
394
|
-
if (f.key === 'maxTokens' && raw.length === 0)
|
|
395
|
-
return 'auto';
|
|
396
|
-
// An empty window field is AUTO, not "unset" - the same reading, and the
|
|
397
|
-
// second of the TWO render points that must agree (P2-1: the profile
|
|
398
|
-
// screen's row fallback below is the other).
|
|
399
|
-
if (f.key === 'contextWindow' && raw.length === 0)
|
|
400
|
-
return 'auto';
|
|
401
|
-
// `(not set)` and NOT `(same as main)`, which is the honest reading of §3.2
|
|
402
|
-
// rule 3: an empty `fast.model` does not inherit, it means the tier is
|
|
403
|
-
// unconfigured. `(same as main)` is a fact the derived line below states
|
|
404
|
-
// when the value literally equals the main model — never a placeholder.
|
|
405
|
-
if (f.key === 'fastModel' && raw.length === 0) {
|
|
406
|
-
return selected ? '(type a model id)' : '(not set)';
|
|
407
|
-
}
|
|
408
|
-
if (f.key === 'fastReview' && raw.length === 0)
|
|
409
|
-
return 'every 5 turns';
|
|
410
|
-
return raw.length > 0 ? raw : selected ? '(type to set)' : '(none)';
|
|
411
|
-
};
|
|
412
|
-
// One element per row, each `wrap="truncate"` — the contract for OverlayFrame's
|
|
413
|
-
// controlled mode. The old title alone was 68 characters and wrapped below 70
|
|
414
|
-
// columns, adding a row the frame could not account for (P2-9 / R-8).
|
|
415
|
-
const rows = FIELDS.map((f, i) => {
|
|
416
|
-
const selected = i === index;
|
|
417
|
-
return (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: selected ? theme.accent : theme.muted, children: selected ? `${glyphs.caret} ` : ' ' }), _jsx(Text, { color: selected ? theme.assistant : theme.muted, children: (f.key === 'apiKey' ? `API key (${values.provider})` : f.label).padEnd(18) }), _jsx(Text, { color: selected ? theme.primary : theme.muted, children: displayValue(f, selected) }), f.kind === 'enum' && selected && (_jsxs(Text, { color: theme.muted, children: [' (', glyphs.arrowLeft, "/", glyphs.arrowRight, ')'] }))] }, f.key));
|
|
418
|
-
});
|
|
419
|
-
// One element, `wrap="truncate"`, pushed like every other row — OverlayFrame's
|
|
420
|
-
// controlled mode slices by ELEMENT, so a row that wraps desynchronises the
|
|
421
|
-
// position indicator.
|
|
422
|
-
rows.push(_jsx(Text, { wrap: "truncate", color: theme.muted, children: effectiveCapLine(values) }, "__effective"));
|
|
423
|
-
rows.push(_jsx(Text, { wrap: "truncate", color: theme.muted, children: fastTierLine(values, (id) => (apiKeys[id] ?? '').length > 0) }, "__fast"));
|
|
424
|
-
/**
|
|
425
|
-
* ONE ROW, NOT NINE (llm-api-retry-backoff §6.9).
|
|
426
|
-
*
|
|
427
|
-
* READ-ONLY, and deliberately so: the nine `retry.*` keys belong to `config set`
|
|
428
|
-
* and `config.json`, and a settings screen that exposed a jitter checkbox is a
|
|
429
|
-
* settings screen nobody reads. What a user needs HERE is the answer to "is it
|
|
430
|
-
* on, and how many" — the discoverable control is `/retry`, which this row names.
|
|
431
|
-
*/
|
|
432
|
-
if (retrySummary) {
|
|
433
|
-
rows.push(_jsxs(Text, { wrap: "truncate", color: theme.muted, children: [' ', 'API retries'.padEnd(18), retrySummary] }, "__retry"));
|
|
434
|
-
}
|
|
435
|
-
rows.push(_jsx(Text, { wrap: "truncate", color: theme.muted, children: "Enter saves. Keys persist to the config file (0600)." }, "__save"));
|
|
436
|
-
return (_jsx(OverlayFrame, { title: "Settings", hint: `${glyphs.arrowUp}${glyphs.arrowDown} field ${glyphs.midDot} ${glyphs.arrowLeft}${glyphs.arrowRight} change ${glyphs.midDot} Enter save ${glyphs.midDot} Esc close`, maxRows: maxRows, cols: cols, rows: rows, scrollOffset: focusedOffset, onScrollClamp: onScrollClamp, theme: theme, caps: caps }));
|
|
437
|
-
}
|
|
438
|
-
// `contextWindow` joins the exclusion list so a bound Main can never leak a
|
|
439
|
-
// SECOND copy of the row through PROFILE_FIELDS - the root row belongs to the
|
|
440
|
-
// unbound group below, exclusively (AC-11).
|
|
441
|
-
const PROFILE_FIELDS = FIELDS.filter((field) => ![
|
|
442
|
-
'provider', 'model', 'baseUrl', 'apiKey', 'fastProvider', 'fastModel', 'fastEnabled',
|
|
443
|
-
'contextWindow',
|
|
444
|
-
].includes(field.key));
|
|
445
|
-
function profileSettingsValues(initial, draft) {
|
|
446
|
-
const file = draft.baseline;
|
|
447
|
-
return { ...initial, provider: file.provider ?? initial.provider,
|
|
448
|
-
model: file.model ?? initial.model,
|
|
449
|
-
baseUrl: file.baseUrl ?? '', apiKey: '', fastModel: file.fast?.model ?? '',
|
|
450
|
-
fastProvider: file.fast?.provider || FAST_INHERIT_PROVIDER,
|
|
451
|
-
// SEEDED FROM THE FILE VALUE, like its provider/model/baseUrl siblings
|
|
452
|
-
// (AC-11 / P2-3): when env holds an override the file value is not the
|
|
453
|
-
// effective one, and this screen edits the FILE.
|
|
454
|
-
contextWindow: file.contextWindow == null ? 'auto' : String(file.contextWindow) };
|
|
455
|
-
}
|
|
456
|
-
/** Only fields changed by the user belong in a settings transaction. */
|
|
457
|
-
export function readDirtySettings(initial, values) {
|
|
458
|
-
const patch = {};
|
|
459
|
-
const dirty = (key) => initial[key] !== values[key];
|
|
460
|
-
if (dirty('provider'))
|
|
461
|
-
patch.provider = values.provider;
|
|
462
|
-
if (dirty('model'))
|
|
463
|
-
patch.model = values.model.trim();
|
|
464
|
-
if (dirty('baseUrl'))
|
|
465
|
-
patch.baseUrl = values.baseUrl.trim();
|
|
466
|
-
if (dirty('apiKey') && values.apiKey.trim()) {
|
|
467
|
-
patch.apiKeys = { [values.provider]: values.apiKey.trim() };
|
|
468
|
-
}
|
|
469
|
-
if (dirty('thinkingLevel'))
|
|
470
|
-
patch.thinkingLevel = values.thinkingLevel;
|
|
471
|
-
if (dirty('showThinking'))
|
|
472
|
-
patch.showThinking = values.showThinking === 'on';
|
|
473
|
-
if (dirty('liveToolOutput'))
|
|
474
|
-
patch.liveToolOutput = values.liveToolOutput === 'on';
|
|
475
|
-
if (dirty('logLevel'))
|
|
476
|
-
patch.log = { level: values.logLevel };
|
|
477
|
-
if (dirty('maxTokens')) {
|
|
478
|
-
const parsed = parseMaxTokensInput(values.maxTokens);
|
|
479
|
-
if (parsed.kind === 'invalid')
|
|
480
|
-
throw new Error('Max tokens: use a number or auto.');
|
|
481
|
-
patch.maxTokens = parsed.kind === 'auto' ? null : parsed.value;
|
|
482
|
-
}
|
|
483
|
-
if (dirty('contextWindow')) {
|
|
484
|
-
// TYPO CHANGES NOTHING: the message's `Context window:` prefix is what
|
|
485
|
-
// `saveProfileSettings`'s focus logic matches to jump to this row. The
|
|
486
|
-
// silent clamp on a value mirrors `config set contextWindow`.
|
|
487
|
-
const parsed = parseContextWindowInput(values.contextWindow);
|
|
488
|
-
if (parsed.kind === 'invalid')
|
|
489
|
-
throw new Error('Context window: use a number or auto.');
|
|
490
|
-
patch.contextWindow = parsed.kind === 'auto' ? null : parsed.value;
|
|
491
|
-
}
|
|
492
|
-
const fast = {};
|
|
493
|
-
const parsedFast = readFastSettings(values);
|
|
494
|
-
if (dirty('fastModel'))
|
|
495
|
-
fast.model = parsedFast.model;
|
|
496
|
-
if (dirty('fastProvider'))
|
|
497
|
-
fast.provider = parsedFast.provider;
|
|
498
|
-
if (dirty('fastEnabled'))
|
|
499
|
-
fast.enabled = parsedFast.enabled;
|
|
500
|
-
if (dirty('fastReview')) {
|
|
501
|
-
if (parsedFast.review === undefined)
|
|
502
|
-
throw new Error('Fast review: use a turn count or off.');
|
|
503
|
-
fast.review = parsedFast.review;
|
|
504
|
-
if (parsedFast.reviewEveryTurns !== undefined) {
|
|
505
|
-
fast.reviewEveryTurns = parsedFast.reviewEveryTurns;
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
if (dirty('fastReviewBudget')) {
|
|
509
|
-
if (parsedFast.reviewMaxPerSession === undefined) {
|
|
510
|
-
throw new Error('Fast budget: use a number.');
|
|
511
|
-
}
|
|
512
|
-
fast.reviewMaxPerSession = parsedFast.reviewMaxPerSession;
|
|
513
|
-
}
|
|
514
|
-
if (Object.keys(fast).length)
|
|
515
|
-
patch.fast = fast;
|
|
516
|
-
const compaction = {};
|
|
517
|
-
const parsedCompaction = readCompactionSettings(values);
|
|
518
|
-
const mapping = { compactionEnabled: 'enabled', compactionThreshold: 'threshold',
|
|
519
|
-
compactionKeepTurns: 'keepRecentTurns', compactionSubagents: 'subagents',
|
|
520
|
-
compactionArchive: 'archive' };
|
|
521
|
-
for (const [field, key] of Object.entries(mapping)) {
|
|
522
|
-
if (!dirty(field))
|
|
523
|
-
continue;
|
|
524
|
-
const value = parsedCompaction[key];
|
|
525
|
-
if (value === undefined) {
|
|
526
|
-
const label = FIELDS.find((item) => item.key === field).label;
|
|
527
|
-
throw new Error(`${label}: use a number.`);
|
|
528
|
-
}
|
|
529
|
-
Object.assign(compaction, { [key]: value });
|
|
530
|
-
}
|
|
531
|
-
if (Object.keys(compaction).length)
|
|
532
|
-
patch.compaction = compaction;
|
|
533
|
-
return patch;
|
|
534
|
-
}
|
|
535
|
-
function saveError(result) {
|
|
536
|
-
if (result.persisted)
|
|
537
|
-
return 'Saved; not fully applied. Close and restart. Save disabled.';
|
|
538
|
-
const errors = {
|
|
539
|
-
busy: 'Busy. Wait for running work to finish, then save again.',
|
|
540
|
-
conflict: 'Config changed elsewhere. Reload before saving.',
|
|
541
|
-
read_failed: 'Cannot read config. Repair with aragon config edit, then reload.',
|
|
542
|
-
write_failed: 'Could not save. Your changes are still here; retry Save.',
|
|
543
|
-
invalid: 'Invalid settings. Review the highlighted field and retry.',
|
|
544
|
-
};
|
|
545
|
-
return errors[result.code ?? ''] ?? 'Could not save. Review settings and retry.';
|
|
546
|
-
}
|
|
547
|
-
function isKitAction(action) {
|
|
548
|
-
return action.type.startsWith('kit-');
|
|
549
|
-
}
|
|
550
|
-
/**
|
|
551
|
-
* ONE REDUCER FOR THE WHOLE SCREEN, TWO OWNERS INSIDE IT (agent-model-kits §4.5).
|
|
552
|
-
*
|
|
553
|
-
* The kit pages need their own data mutations (create, duplicate, delete, apply)
|
|
554
|
-
* but must not introduce a second state object: `Save`, `Esc` and the dirty
|
|
555
|
-
* badge are shared, and a second store is how a settings screen starts
|
|
556
|
-
* disagreeing with itself. `kitReducer` returns the SAME state shape, so the
|
|
557
|
-
* split is invisible from the outside.
|
|
558
|
-
*/
|
|
559
|
-
function settingsReducer(state, action) {
|
|
560
|
-
return isKitAction(action) ? kitReducer(state, action) : modelProfileReducer(state, action);
|
|
561
|
-
}
|
|
562
|
-
function useProfileSettingsState(props) {
|
|
563
|
-
const [state, dispatch] = useReducer(settingsReducer, props.draft, createModelProfileState);
|
|
564
|
-
const [initial, setInitial] = useState(() => profileSettingsValues(props.initial, props.draft));
|
|
565
|
-
const [values, setValues] = useState(initial);
|
|
566
|
-
const [index, setIndex] = useState(0);
|
|
567
|
-
const [error, setError] = useState();
|
|
568
|
-
const [persisted, setPersisted] = useState(false);
|
|
569
|
-
const [confirmIndex, setConfirmIndex] = useState(0);
|
|
570
|
-
const [reloadPending, setReloadPending] = useState(false);
|
|
571
|
-
const offset = useProfileScroll(props, index);
|
|
572
|
-
// THE PROBE LIVES HERE, NOT IN THE EDITOR (RV-P0-1): this component survives a
|
|
573
|
-
// page switch, the editor does not, and a hook inside the editor would abort its
|
|
574
|
-
// own discovery the moment `Discover models` opens the list page.
|
|
575
|
-
const probe = useModelProbe(props.probe);
|
|
576
|
-
const probeTarget = state.editor
|
|
577
|
-
? editorProbeTarget(state.editor, props.apiKeys) : undefined;
|
|
578
|
-
// TWO SLOTS: a verdict and a discovered list answer different questions, and
|
|
579
|
-
// opening the list must not erase a verdict the user still wants to read.
|
|
580
|
-
const probeViews = visibleProbeViews(probe.test, probe.discovery, probeTarget ?? NO_PROFILE_TARGET, props.probe);
|
|
581
|
-
const previousPage = useRef(state.page);
|
|
582
|
-
useEffect(() => {
|
|
583
|
-
const previous = previousPage.current;
|
|
584
|
-
previousPage.current = state.page;
|
|
585
|
-
if (state.page !== 'root' || previous === 'discard-confirm')
|
|
586
|
-
return;
|
|
587
|
-
setIndex(0);
|
|
588
|
-
props.onScrollClamp?.(0);
|
|
589
|
-
}, [state.page]);
|
|
590
|
-
const library = state.draft.profiles ?? emptyModelProfiles();
|
|
591
|
-
const glyphs = pickGlyphs(props.caps);
|
|
592
|
-
const dirty = state.dirty || Object.keys(values).some((key) => values[key] !== initial[key]);
|
|
593
|
-
const fields = [FIELDS.find((item) => item.key === 'fastEnabled'),
|
|
594
|
-
...FIELDS.filter((item) => library.mainId === null
|
|
595
|
-
&& ['provider', 'model', 'baseUrl', 'contextWindow', 'apiKey'].includes(item.key)),
|
|
596
|
-
...FIELDS.filter((item) => library.fastId === null
|
|
597
|
-
&& ['fastModel', 'fastProvider'].includes(item.key)), ...PROFILE_FIELDS];
|
|
598
|
-
// EIGHT FIXED ROWS now (Main, Fast, Subagent model, Subagent fan-out, Kit pack,
|
|
599
|
-
// Manage, Save, Reload) around the `fields` block - derived from ROOT_ROWS so
|
|
600
|
-
// the count and the offsets cannot drift apart (see those constants).
|
|
601
|
-
const count = fields.length + ROOT_ROWS.length + 2;
|
|
602
|
-
const field = fields[index - ROOT_FIRST_FIELD];
|
|
603
|
-
const readError = state.draft.readError;
|
|
604
|
-
// THREE CONFIRMATIONS SHARE ONE PAGE, which is why the page name - not a
|
|
605
|
-
// boolean - is what the renderer and the input hook both branch on.
|
|
606
|
-
const confirming = state.page === 'delete-confirm' || state.page === 'discard-confirm'
|
|
607
|
-
|| state.page === 'kit-delete';
|
|
608
|
-
return { state, dispatch, initial, setInitial, values, setValues, index, setIndex,
|
|
609
|
-
error, setError, persisted, setPersisted, confirmIndex, setConfirmIndex,
|
|
610
|
-
reloadPending, setReloadPending, offset, library, glyphs, dirty, fields, count,
|
|
611
|
-
field, readError, confirming, probe, probeTarget, probeViews };
|
|
612
|
-
}
|
|
613
|
-
function saveProfileSettings(props, view) {
|
|
614
|
-
const { persisted, readError, initial, values, fields, state, setError, setIndex, setPersisted } = view;
|
|
615
|
-
if (persisted || readError || !props.onProfileSave)
|
|
616
|
-
return;
|
|
617
|
-
let patch;
|
|
618
|
-
try {
|
|
619
|
-
patch = readDirtySettings(initial, values);
|
|
620
|
-
}
|
|
621
|
-
catch (failure) {
|
|
622
|
-
const message = failure.message;
|
|
623
|
-
setError(message);
|
|
624
|
-
const at = fields.findIndex((item) => message.startsWith(`${item.label}:`));
|
|
625
|
-
if (at >= 0)
|
|
626
|
-
setIndex(at + ROOT_FIRST_FIELD);
|
|
627
|
-
return;
|
|
628
|
-
}
|
|
629
|
-
const result = props.onProfileSave({
|
|
630
|
-
...state.draft, patch: { ...state.draft.patch, ...patch },
|
|
631
|
-
});
|
|
632
|
-
if (!result.ok) {
|
|
633
|
-
setError(saveError(result));
|
|
634
|
-
setPersisted(result.persisted);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
function reloadProfileSettings(props, view) {
|
|
638
|
-
const { dispatch, setInitial, setValues, setError, setIndex, setReloadPending } = view;
|
|
639
|
-
if (!props.onReload)
|
|
640
|
-
return;
|
|
641
|
-
const next = props.onReload();
|
|
642
|
-
dispatch({ type: 'reload', draft: next });
|
|
643
|
-
const live = next.liveBaseline;
|
|
644
|
-
const refreshed = { ...props.initial, provider: live.provider, model: live.model,
|
|
645
|
-
baseUrl: live.baseUrl ?? '', thinkingLevel: live.thinkingLevel,
|
|
646
|
-
showThinking: live.showThinking ? 'on' : 'off',
|
|
647
|
-
liveToolOutput: live.liveToolOutput ? 'on' : 'off',
|
|
648
|
-
maxTokens: live.maxTokens === undefined ? '' : String(live.maxTokens),
|
|
649
|
-
contextWindow: live.contextWindow == null ? 'auto' : String(live.contextWindow),
|
|
650
|
-
logLevel: live.log?.level ?? props.initial.logLevel,
|
|
651
|
-
...(live.fast ? fastSettingsFrom(live.fast) : {}),
|
|
652
|
-
...(live.compaction ? compactionSettingsFrom(live.compaction) : {}),
|
|
653
|
-
};
|
|
654
|
-
const nextValues = profileSettingsValues(refreshed, next);
|
|
655
|
-
setInitial(nextValues);
|
|
656
|
-
setValues(nextValues);
|
|
657
|
-
setError(undefined);
|
|
658
|
-
setIndex(0);
|
|
659
|
-
setReloadPending(false);
|
|
660
|
-
}
|
|
661
|
-
function cancelProfileSettings(props, view, reloading = false) {
|
|
662
|
-
const { persisted, dirty, setReloadPending, setConfirmIndex, dispatch } = view;
|
|
663
|
-
if (persisted) {
|
|
664
|
-
props.onClose?.();
|
|
665
|
-
return;
|
|
666
|
-
}
|
|
667
|
-
if (!dirty) {
|
|
668
|
-
if (reloading)
|
|
669
|
-
reloadProfileSettings(props, view);
|
|
670
|
-
else
|
|
671
|
-
props.onClose?.();
|
|
672
|
-
return;
|
|
673
|
-
}
|
|
674
|
-
setReloadPending(reloading);
|
|
675
|
-
setConfirmIndex(0);
|
|
676
|
-
dispatch({ type: 'page', page: 'discard-confirm' });
|
|
677
|
-
}
|
|
678
|
-
function activateRootSetting(props, view) {
|
|
679
|
-
const { index, count, readError, persisted, dispatch } = view;
|
|
680
|
-
if (index === count - 1) {
|
|
681
|
-
cancelProfileSettings(props, view, true);
|
|
682
|
-
return;
|
|
683
|
-
}
|
|
684
|
-
if (readError || persisted)
|
|
685
|
-
return;
|
|
686
|
-
if (index === ROOT_MAIN || index === ROOT_FAST) {
|
|
687
|
-
dispatch({ type: 'page', page: 'picker', role: index === ROOT_MAIN ? 'main' : 'fast' });
|
|
688
|
-
}
|
|
689
|
-
else if (index === ROOT_SUBAGENT) {
|
|
690
|
-
// The user-owned cost switch (D-5): its own picker mode, writing
|
|
691
|
-
// `draft.patch.team` rather than a `${role}Id` library key.
|
|
692
|
-
dispatch({ type: 'page', page: 'picker', role: 'subagent' });
|
|
693
|
-
}
|
|
694
|
-
else if (index === ROOT_TEAM) {
|
|
695
|
-
// MUST STAY ABOVE THE FALLBACK `else` BELOW, WHICH IS `saveProfileSettings`
|
|
696
|
-
// (R-P1-8). A missing or mis-derived constant here does not fail to compile:
|
|
697
|
-
// pressing Enter on this row would silently COMMIT the whole draft, so
|
|
698
|
-
// `team-fanout-page.test.tsx` asserts that Enter on this row saves nothing.
|
|
699
|
-
dispatch({ type: 'page', page: 'team' });
|
|
700
|
-
}
|
|
701
|
-
else if (index === ROOT_GOVERNANCE) {
|
|
702
|
-
// SAME RULE AS THE TEAM BRANCH ABOVE, and the same cost of getting it wrong: this MUST
|
|
703
|
-
// stay above the fallback `else`, which is `saveProfileSettings`. A misplaced branch
|
|
704
|
-
// compiles and silently commits the whole draft when Enter opens the page.
|
|
705
|
-
dispatch({ type: 'page', page: 'governance' });
|
|
706
|
-
}
|
|
707
|
-
else if (index === ROOT_KIT) {
|
|
708
|
-
// The fifth root row opens the manager, not a picker: kits are data the user
|
|
709
|
-
// owns here, and `ctrl+K` is where they are CONSUMED (agent-model-kits §4.5).
|
|
710
|
-
dispatch({ type: 'page', page: 'kits' });
|
|
711
|
-
}
|
|
712
|
-
else if (index === ROOT_MANAGE)
|
|
713
|
-
dispatch({ type: 'page', page: 'manager' });
|
|
714
|
-
else
|
|
715
|
-
saveProfileSettings(props, view);
|
|
716
|
-
}
|
|
717
|
-
function useRootSettingsInput(props, view) {
|
|
718
|
-
const { index, count, field, readError, persisted, values, state, setIndex, setValues } = view;
|
|
719
|
-
useInput((input, key) => {
|
|
720
|
-
if (props.isActive === false)
|
|
721
|
-
return;
|
|
722
|
-
if (key.escape) {
|
|
723
|
-
cancelProfileSettings(props, view);
|
|
724
|
-
return;
|
|
725
|
-
}
|
|
726
|
-
if (key.ctrl && input === 's') {
|
|
727
|
-
saveProfileSettings(props, view);
|
|
728
|
-
return;
|
|
729
|
-
}
|
|
730
|
-
if (key.upArrow || (key.tab && key.shift)) {
|
|
731
|
-
setIndex((index - 1 + count) % count);
|
|
732
|
-
return;
|
|
733
|
-
}
|
|
734
|
-
if (key.downArrow || key.tab) {
|
|
735
|
-
setIndex((index + 1) % count);
|
|
736
|
-
return;
|
|
737
|
-
}
|
|
738
|
-
if (key.return) {
|
|
739
|
-
activateRootSetting(props, view);
|
|
740
|
-
return;
|
|
741
|
-
}
|
|
742
|
-
if (!field || readError || persisted || key.ctrl || key.meta)
|
|
743
|
-
return;
|
|
744
|
-
if (field.kind === 'enum') {
|
|
745
|
-
if (!key.leftArrow && !key.rightArrow)
|
|
746
|
-
return;
|
|
747
|
-
const options = field.options;
|
|
748
|
-
const at = options.indexOf(String(values[field.key]));
|
|
749
|
-
setValues({ ...values, ...(field.key === 'provider' ? { apiKey: '' } : {}),
|
|
750
|
-
[field.key]: options[(at + (key.leftArrow ? -1 : 1) + options.length) % options.length] });
|
|
751
|
-
return;
|
|
752
|
-
}
|
|
753
|
-
const text = stripPasteFrames(stripEnterFrames(input));
|
|
754
|
-
const value = key.backspace || key.delete
|
|
755
|
-
? [...String(values[field.key])].slice(0, -1).join('') : String(values[field.key]) + text;
|
|
756
|
-
if (field.key === 'apiKey')
|
|
757
|
-
registerSecret(value);
|
|
758
|
-
if (key.backspace || key.delete || text)
|
|
759
|
-
setValues({ ...values, [field.key]: value });
|
|
760
|
-
}, { isActive: state.page === 'root' });
|
|
761
|
-
}
|
|
762
|
-
function useSettingsConfirmationInput(props, view) {
|
|
763
|
-
const { state, dispatch, confirmIndex, setConfirmIndex, reloadPending, confirming } = view;
|
|
764
|
-
useInput((_input, key) => {
|
|
765
|
-
if (props.isActive === false)
|
|
766
|
-
return;
|
|
767
|
-
if (key.escape) {
|
|
768
|
-
dispatch({ type: 'page', page: state.page === 'delete-confirm'
|
|
769
|
-
? 'manager' : 'root' });
|
|
770
|
-
return;
|
|
771
|
-
}
|
|
772
|
-
if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow || key.tab) {
|
|
773
|
-
setConfirmIndex((confirmIndex + 1) % 2);
|
|
774
|
-
return;
|
|
775
|
-
}
|
|
776
|
-
if (!key.return)
|
|
777
|
-
return;
|
|
778
|
-
if (state.page === 'kit-delete') {
|
|
779
|
-
dispatch(confirmIndex === 1 ? { type: 'kit-confirm-delete' }
|
|
780
|
-
: { type: 'page', page: 'kits' });
|
|
781
|
-
return;
|
|
782
|
-
}
|
|
783
|
-
if (state.page === 'delete-confirm') {
|
|
784
|
-
dispatch(confirmIndex === 1 ? { type: 'confirm-delete' }
|
|
785
|
-
: { type: 'page', page: 'manager' });
|
|
786
|
-
}
|
|
787
|
-
else if (confirmIndex === 0)
|
|
788
|
-
dispatch({ type: 'page', page: 'root' });
|
|
789
|
-
else if (reloadPending)
|
|
790
|
-
reloadProfileSettings(props, view);
|
|
791
|
-
else
|
|
792
|
-
props.onClose?.();
|
|
793
|
-
}, { isActive: confirming });
|
|
794
|
-
}
|
|
795
|
-
/**
|
|
796
|
-
* The kit deletion confirmation (agent-model-kits D-9 / AC-30).
|
|
797
|
-
*
|
|
798
|
-
* `Cancel` IS THE DEFAULT FOCUS, like the profile confirmation next door: the
|
|
799
|
-
* `Enter` key that opened this page must not be the one that deletes. The second
|
|
800
|
-
* line names what the user loses - a kit, and with it the default pointer and any
|
|
801
|
-
* session binding that named it.
|
|
802
|
-
*/
|
|
803
|
-
function renderKitDeleteConfirmation(props, view) {
|
|
804
|
-
const { state, confirmIndex, glyphs } = view;
|
|
805
|
-
const kit = (state.draft.profiles?.kits ?? []).find((item) => item.id === state.kitDraft?.id);
|
|
806
|
-
const rows = ['Cancel', 'Delete'].map((label, at) => (_jsxs(Text, { wrap: "truncate", color: props.theme.primary, children: [confirmIndex === at ? `${glyphs.caret} ` : ' ', label] }, label)));
|
|
807
|
-
rows.push(_jsx(Text, { wrap: "truncate", color: props.theme.muted, children: `Deletes kit "${kit?.name ?? ''}". Its three slots stay as they are; only the preset goes.` }, "consequence"));
|
|
808
|
-
return _jsx(OverlayFrame, { ...props, title: `Delete kit ${kit?.name ?? ''}?`, hint: "Enter choose | Esc continue", rows: rows, scrollOffset: confirmIndex });
|
|
809
|
-
}
|
|
810
|
-
function renderSettingsConfirmation(props, view) {
|
|
811
|
-
const { state, library, confirmIndex, glyphs } = view;
|
|
812
|
-
const deletingKit = state.page === 'kit-delete';
|
|
813
|
-
if (deletingKit)
|
|
814
|
-
return renderKitDeleteConfirmation(props, view);
|
|
815
|
-
const deleting = state.page === 'delete-confirm';
|
|
816
|
-
const name = library.entries.find((entry) => entry.id === state.deleteId)?.name ?? '';
|
|
817
|
-
// UNBIND-AND-DELETE (D-6): a referenced entry stays deletable in ONE flow,
|
|
818
|
-
// and the button names what will happen.
|
|
819
|
-
const labels = deleting
|
|
820
|
-
? ['Cancel', state.deleteUsers ? 'Unbind and delete' : 'Delete']
|
|
821
|
-
: ['Continue', 'Discard'];
|
|
822
|
-
const rows = labels
|
|
823
|
-
.map((label, at) => _jsxs(Text, { wrap: "truncate", color: props.theme.primary, children: [confirmIndex === at ? `${glyphs.caret} ` : ' ', label] }, label));
|
|
824
|
-
// V-8: A RENDER-ONLY ROW, pushed AFTER the buttons. `confirmIndex` stays a
|
|
825
|
-
// 0..1 index over the two buttons and `scrollOffset` follows it, so this
|
|
826
|
-
// line must never sit between them or take an array slot of its own.
|
|
827
|
-
if (deleting && state.deleteUsers) {
|
|
828
|
-
rows.push(_jsxs(Text, { wrap: "truncate", color: props.theme.muted, children: ["Used by ", state.deleteUsers, ". The binding(s) will be cleared."] }, "users"));
|
|
829
|
-
}
|
|
830
|
-
return _jsx(OverlayFrame, { ...props, title: deleting ? `Delete ${name}?` : 'Discard unsaved changes?', hint: "Enter choose | Esc continue", rows: rows, scrollOffset: confirmIndex });
|
|
831
|
-
}
|
|
832
|
-
/** Zero-network guard: no key (or no probe port) means no request at all. */
|
|
833
|
-
function startTest(view) {
|
|
834
|
-
if (view.probeTarget && canProbe(view.probeViews.test)) {
|
|
835
|
-
view.probe.startTest(view.probeTarget);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
/** Discover from the draft, then show the list page: the state stays here. */
|
|
839
|
-
function startDiscovery(view, dispatch) {
|
|
840
|
-
if (!view.probeTarget || !canProbe(view.probeViews.test))
|
|
841
|
-
return;
|
|
842
|
-
view.probe.startDiscovery(view.probeTarget);
|
|
843
|
-
dispatch({ type: 'page', page: 'models' });
|
|
844
|
-
}
|
|
845
|
-
/**
|
|
846
|
-
* Whether the fast tier resolves FOR DISPLAY while the subagent picker is
|
|
847
|
-
* open (D-5): the built-in `Fast tier model` row then annotates itself with
|
|
848
|
-
* `(fast tier off)`, so choosing it is never a surprise fallback. The same
|
|
849
|
-
* enabled + model + config-file-key approximation `fastTierLine` uses - and
|
|
850
|
-
* the same env-key blindness (V-10), accepted for consistency with it.
|
|
851
|
-
*/
|
|
852
|
-
function fastTierUnavailable(props, view) {
|
|
853
|
-
const { values } = view;
|
|
854
|
-
if (values.fastEnabled !== 'on')
|
|
855
|
-
return true;
|
|
856
|
-
if (values.fastModel.trim().length === 0)
|
|
857
|
-
return true;
|
|
858
|
-
const provider = values.fastProvider === FAST_INHERIT_PROVIDER
|
|
859
|
-
|| values.fastProvider.trim().length === 0 ? values.provider : values.fastProvider;
|
|
860
|
-
return (props.apiKeys[provider] ?? '').length === 0;
|
|
861
|
-
}
|
|
862
|
-
function renderProfileSubpage(props, view) {
|
|
863
|
-
const { state, library, dispatch, setConfirmIndex } = view;
|
|
864
|
-
// THE FAN-OUT PAGE (subagent-fanout 3.4.4). Placed before the picker branch
|
|
865
|
-
// because that branch is the unconditional fallback; the page name is unique,
|
|
866
|
-
// so its position among the others is arbitrary.
|
|
867
|
-
if (state.page === 'team')
|
|
868
|
-
return _jsx(TeamFanoutPage, { ...props, view: {
|
|
869
|
-
rows: fanoutRows(teamFanoutValues(state.draft), props.teamRegistered),
|
|
870
|
-
error: state.error,
|
|
871
|
-
}, dispatch: dispatch, onBack: () => dispatch({ type: 'page', page: 'root' }) });
|
|
872
|
-
if (state.page === 'governance') {
|
|
873
|
-
const config = draftGovernance(state.draft);
|
|
874
|
-
return _jsx(GovernanceSettingsPage, { ...props, view: {
|
|
875
|
-
rows: governanceSettingRows(config),
|
|
876
|
-
error: state.error,
|
|
877
|
-
restartNote: governanceRestartNote(config.enabled, props.governanceRegistered),
|
|
878
|
-
}, dispatch: dispatch, onBack: () => dispatch({ type: 'page', page: 'root' }) });
|
|
879
|
-
}
|
|
880
|
-
// THE KIT PAGES (agent-model-kits §4.5). They are dispatched BEFORE the profile
|
|
881
|
-
// pages because `'kit-slot'` RENDERS a profile picker while belonging to the
|
|
882
|
-
// kit editor - the page name, not the component, decides where the user is.
|
|
883
|
-
if (state.page === 'kits')
|
|
884
|
-
return _jsx(KitManager, { ...props, rows: kitManagerRows(state), error: state.error, dispatch: dispatch, onBack: () => dispatch({ type: 'page', page: 'root' }) });
|
|
885
|
-
if (state.page === 'kit-edit' && state.kitDraft)
|
|
886
|
-
return _jsx(KitEditor, { ...props, draft: state.kitDraft, state: state, dispatch: dispatch });
|
|
887
|
-
if (state.page === 'kit-slot' && state.kitDraft) {
|
|
888
|
-
return renderKitSlotPicker(props, view, state.kitDraft);
|
|
889
|
-
}
|
|
890
|
-
if (state.page === 'editor' && state.editor)
|
|
891
|
-
return _jsx(ModelProfileEditor, { ...props, editor: state.editor, users: profileUsers(library, state.editor.original.id, draftSubagentProfileId(state.draft)), error: state.error, dispatch: dispatch, probeView: view.probeViews.test, probeBusy: view.probe.busy, probeTarget: view.probeTarget, onTest: () => startTest(view), onDiscover: () => startDiscovery(view, dispatch), onCancelProbe: view.probe.cancel });
|
|
892
|
-
// A DISCOVERY IS A PAGE, NOT A POPUP: the list is where the answer belongs, and
|
|
893
|
-
// the probe state it renders keeps running because it lives one level up.
|
|
894
|
-
if (state.page === 'models' && state.editor)
|
|
895
|
-
return _jsx(ModelDiscoveryList, { ...props, provider: state.editor.provider, currentModel: state.editor.model, view: view.probeViews.discovery, busy: view.probe.discovery.phase === 'discovering', onChoose: (model) => dispatch({ type: 'choose-model', model }), onRetry: () => startDiscovery(view, dispatch), onBack: () => dispatch({ type: 'page', page: 'editor' }), onCancelProbe: view.probe.cancel });
|
|
896
|
-
// A NEW PROFILE SEEDED FROM THE MAIN CONNECTION while the subagent picker is
|
|
897
|
-
// open: 'subagent' is picker-only (6.2), so the seed role falls back to
|
|
898
|
-
// 'main' while `state.role` keeps driving the select that binds it. 'binding'
|
|
899
|
-
// is the kit slot's chooser and seeds the same way.
|
|
900
|
-
const createRole = state.role === 'subagent' || state.role === 'binding'
|
|
901
|
-
? 'main' : state.role;
|
|
902
|
-
if (state.page === 'picker' || state.page === 'manager')
|
|
903
|
-
return _jsx(ModelProfilePicker, { ...props, profiles: library, savedProfiles: state.draft.baseline.modelProfiles, role: state.role, customProfile: createCustomProfile(state.draft, createRole), manager: state.page === 'manager', error: state.error, selectedIdOverride: state.role === 'subagent' ? subagentSelectedId(state.draft) : undefined, subagentProfileId: draftSubagentProfileId(state.draft), fastTierOff: state.role === 'subagent' && fastTierUnavailable(props, view), onSelect: (id) => dispatch({ type: 'select', role: state.role, id }), onCreate: () => dispatch({ type: 'edit', profile: createCustomProfile(state.draft, createRole),
|
|
904
|
-
bindNew: state.page === 'picker' }), onEdit: (profile) => dispatch({ type: 'edit', profile }), onDuplicate: (id) => dispatch({ type: 'duplicate', id }), onDelete: (id) => { setConfirmIndex(0); dispatch({ type: 'delete', id }); }, onCancel: () => dispatch({ type: 'page', page: 'root' }) });
|
|
905
|
-
return null;
|
|
906
|
-
}
|
|
907
|
-
/** Which slot value the kit picker should mark `[Selected]`. */
|
|
908
|
-
function kitSlotSelection(kitDraft) {
|
|
909
|
-
if (kitDraft.slot === 'main')
|
|
910
|
-
return kitDraft.mainProfileId || null;
|
|
911
|
-
if (kitDraft.slot === 'fast')
|
|
912
|
-
return kitDraft.fastProfileId;
|
|
913
|
-
if (kitDraft.subagent.model === 'profile')
|
|
914
|
-
return kitDraft.subagent.modelProfileId;
|
|
915
|
-
return kitDraft.subagent.model === 'fast' ? SUBAGENT_FAST_ROW_ID : null;
|
|
916
|
-
}
|
|
917
|
-
/**
|
|
918
|
-
* The slot chooser: the SAME profile picker, in its `binding` role.
|
|
919
|
-
*
|
|
920
|
-
* A kit slot can only name a profile, so there is no `Current custom` row and no
|
|
921
|
-
* `Same as main` (those are the subagent slot's own three-state vocabulary). The
|
|
922
|
-
* subagent slot keeps the `subagent` role, which is why `Fast tier (off - falls
|
|
923
|
-
* back to main)` needs no new wording anywhere (RV-P2-6).
|
|
924
|
-
*/
|
|
925
|
-
function renderKitSlotPicker(props, view, kitDraft) {
|
|
926
|
-
const { state, library, dispatch } = view;
|
|
927
|
-
const role = kitDraft.slot === 'subagent' ? 'subagent' : 'binding';
|
|
928
|
-
return _jsx(ModelProfilePicker, { ...props, profiles: library, savedProfiles: state.draft.baseline.modelProfiles, role: role, customProfile: createCustomProfile(state.draft, 'main'), error: state.error, selectedIdOverride: kitSlotSelection(kitDraft), subagentProfileId: draftSubagentProfileId(state.draft), fastTierOff: kitDraft.slot === 'subagent' && fastTierUnavailable(props, view), onSelect: (id) => {
|
|
929
|
-
if (kitDraft.slot === 'main') {
|
|
930
|
-
dispatch({ type: 'kit-main', id });
|
|
931
|
-
return;
|
|
932
|
-
}
|
|
933
|
-
if (kitDraft.slot === 'fast') {
|
|
934
|
-
dispatch({ type: 'kit-fast', id });
|
|
935
|
-
return;
|
|
936
|
-
}
|
|
937
|
-
dispatch({ type: 'kit-subagent',
|
|
938
|
-
model: id === null ? 'main' : id === SUBAGENT_FAST_ROW_ID ? 'fast' : 'profile',
|
|
939
|
-
modelProfileId: id === null || id === SUBAGENT_FAST_ROW_ID ? null : id });
|
|
940
|
-
}, onCreate: () => dispatch({ type: 'edit', profile: createCustomProfile(state.draft, 'main') }), onEdit: (profile) => dispatch({ type: 'edit', profile }), onDuplicate: (id) => dispatch({ type: 'duplicate', id }), onDelete: (id) => dispatch({ type: 'delete', id }), onCancel: () => dispatch({ type: 'kit-cancel' }) });
|
|
941
|
-
}
|
|
942
|
-
function buildRootSettingsRows(props, view) {
|
|
943
|
-
const { library, fields, values, persisted, readError, index, glyphs, state } = view;
|
|
944
|
-
const name = (id) => {
|
|
945
|
-
const entry = library.entries.find((candidate) => candidate.id === id);
|
|
946
|
-
if (!entry)
|
|
947
|
-
return 'Current custom';
|
|
948
|
-
const missing = !entry.apiKey && !props.apiKeys[entry.provider];
|
|
949
|
-
return `${entry.name} ${entry.provider}:${entry.model}${missing ? ' [Missing API key]' : ''}`;
|
|
950
|
-
};
|
|
951
|
-
// THE SUBAGENT MODEL ROW (D-5), third on the page, summarized from the
|
|
952
|
-
// same draft/baseline sources every other derived row here reads. The fast
|
|
953
|
-
// tier check mirrors `fastTierLine`'s approximation (enabled + model + a
|
|
954
|
-
// config-file key) so the two derived lines can never disagree.
|
|
955
|
-
const team = draftTeam(state.draft);
|
|
956
|
-
const mainBound = library.entries.find((entry) => entry.id === library.mainId);
|
|
957
|
-
const mainConnection = mainBound
|
|
958
|
-
? `${mainBound.provider}:${mainBound.model}`
|
|
959
|
-
: `${values.provider}:${values.model}`;
|
|
960
|
-
const fastModel = values.fastModel.trim();
|
|
961
|
-
const fastProvider = values.fastProvider === FAST_INHERIT_PROVIDER
|
|
962
|
-
|| values.fastProvider.trim().length === 0 ? values.provider : values.fastProvider;
|
|
963
|
-
const fastConnection = values.fastEnabled === 'on' && fastModel.length > 0
|
|
964
|
-
&& (props.apiKeys[fastProvider] ?? '').length > 0
|
|
965
|
-
? `${fastProvider}:${fastModel}` : null;
|
|
966
|
-
const subagentLine = subagentModelSummary({ mode: team.model,
|
|
967
|
-
modelProfileId: team.modelProfileId, mainConnection, fastConnection,
|
|
968
|
-
profiles: state.draft.profiles,
|
|
969
|
-
hasKey: (id) => (props.apiKeys[id] ?? '').length > 0 });
|
|
970
|
-
// HELD SLOTS SHOW THE KIT'S EFFECTIVE VALUES (RV-P0-2 / AC-38). Three rows on
|
|
971
|
-
// this page read the FILE's bindings while the header reads the live ones, so
|
|
972
|
-
// without this the screen says `Main profile Opus` over a header that says
|
|
973
|
-
// `haiku` - and the only available conclusion is that the app is broken.
|
|
974
|
-
// `Enter` on any of these rows writes an explicit choice, which releases that
|
|
975
|
-
// slot (§4.3), so what the user sees is what they are about to change.
|
|
976
|
-
const held = heldSlots(state);
|
|
977
|
-
const kitTag = held.kitName ? ` (kit ${held.kitName})` : '';
|
|
978
|
-
const mainValue = `${name(held.mainId ?? library.mainId)}${held.held.includes('main')
|
|
979
|
-
? kitTag : ''}`;
|
|
980
|
-
const fastValue = held.held.includes('fast')
|
|
981
|
-
? `${held.fastId ? name(held.fastId) : 'Off (this kit turns the tier off)'}${kitTag}`
|
|
982
|
-
: name(library.fastId);
|
|
983
|
-
const subagentValue = held.subagent
|
|
984
|
-
? `${subagentModelSummary({ mode: held.subagent.model,
|
|
985
|
-
modelProfileId: held.subagent.modelProfileId, mainConnection, fastConnection,
|
|
986
|
-
profiles: state.draft.profiles,
|
|
987
|
-
hasKey: (id) => (props.apiKeys[id] ?? '').length > 0 })}${kitTag}`
|
|
988
|
-
: subagentLine;
|
|
989
|
-
// THE TEAM SUMMARY (subagent-fanout 3.4.4, renamed by
|
|
990
|
-
// team-command-forced-dispatch §3.9): a DERIVED row, like the three above it,
|
|
991
|
-
// and deliberately not a control - the values are adjusted on the page Enter
|
|
992
|
-
// opens, so the root row cannot change one by accident. It now summarises the
|
|
993
|
-
// WHOLE section, switch included, because `Team mode` is one of those values
|
|
994
|
-
// and a summary that always printed numbers would describe a capability the
|
|
995
|
-
// user may have just switched off.
|
|
996
|
-
const summary = teamSummary(teamFanoutValues(state.draft));
|
|
997
|
-
const lines = [`Main profile ${mainValue}`,
|
|
998
|
-
`Fast profile ${fastValue}`,
|
|
999
|
-
`Subagent model ${subagentValue}`,
|
|
1000
|
-
// `Team`, not `Subagent fan-out`: the row heads a page that now owns
|
|
1001
|
-
// four values, only two of which are about fan-out width. `padEnd(18)` is
|
|
1002
|
-
// unchanged, so the value column still lines up with `Subagent model`.
|
|
1003
|
-
`Team ${summary}`,
|
|
1004
|
-
`Governance ${governanceSummary(draftGovernance(state.draft))}`,
|
|
1005
|
-
`Kit pack ${kitPackRow(state)}`,
|
|
1006
|
-
`Manage profiles ${library.entries.length} saved`,
|
|
1007
|
-
...fields.map((item) => `${item.label.padEnd(18)}${item.key === 'apiKey'
|
|
1008
|
-
? values.apiKey ? 'Configured (replacement)' : props.apiKeys[values.provider]
|
|
1009
|
-
? 'Configured (type to replace)' : '(type to set)'
|
|
1010
|
-
: values[item.key] || (item.key === 'maxTokens' || item.key === 'contextWindow'
|
|
1011
|
-
? 'auto' : '(not set)')}`),
|
|
1012
|
-
persisted || readError ? 'Save (disabled)' : 'Save settings', 'Reload settings'];
|
|
1013
|
-
const rows = lines.map((line, at) => _jsxs(Text, { wrap: "truncate", color: at === index ? props.theme.accent : props.theme.muted, children: [at === index ? `${glyphs.caret} ` : ' ', line] }, at));
|
|
1014
|
-
rows.push(_jsx(Text, { wrap: "truncate", color: props.theme.muted, children: effectiveCapLine(values) }, "effective"));
|
|
1015
|
-
const overrides = state.draft.liveBaseline.modelProfileState;
|
|
1016
|
-
if (overrides?.main.overriddenFields.length || overrides?.fast.overriddenFields.length) {
|
|
1017
|
-
rows.push(_jsx(Text, { wrap: "truncate", color: props.theme.muted, children: "Startup overrides active; explicit selection applies now. Restart uses startup overrides." }, "overrides"));
|
|
1018
|
-
}
|
|
1019
|
-
if (props.retrySummary)
|
|
1020
|
-
rows.push(_jsxs(Text, { wrap: "truncate", color: props.theme.muted, children: ["API retries: ", props.retrySummary] }, "retry"));
|
|
1021
|
-
return rows;
|
|
1022
|
-
}
|
|
1023
|
-
function ProfileSettingsScreen(props) {
|
|
1024
|
-
const view = useProfileSettingsState(props);
|
|
1025
|
-
useRootSettingsInput(props, view);
|
|
1026
|
-
useSettingsConfirmationInput(props, view);
|
|
1027
|
-
if (view.confirming)
|
|
1028
|
-
return renderSettingsConfirmation(props, view);
|
|
1029
|
-
const subpage = renderProfileSubpage(props, view);
|
|
1030
|
-
if (subpage)
|
|
1031
|
-
return subpage;
|
|
1032
|
-
const { error, readError, dirty, persisted, index, offset } = view;
|
|
1033
|
-
return _jsx(OverlayFrame, { ...props, rows: buildRootSettingsRows(props, view), scrollOffset: offset, title: error ?? (readError ? 'Cannot read config. Repair with aragon config edit; Reload.'
|
|
1034
|
-
: dirty ? 'Settings | Unsaved changes' : 'Settings'), hint: persisted ? 'Esc close; restart to apply' : index < ROOT_FIRST_FIELD
|
|
1035
|
-
? 'Enter select/edit | Ctrl+S save | Esc cancel'
|
|
1036
|
-
: 'Enter save/action | Ctrl+S save | Esc cancel' });
|
|
1037
|
-
}
|