@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
package/dist/config/schema.js
DELETED
|
@@ -1,1383 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Config schema — the persisted config-file shape, the in-memory effective
|
|
3
|
-
* config, sane defaults, and small validation/masking helpers.
|
|
4
|
-
*
|
|
5
|
-
* See spec §3.5 (resolution pipeline), §6.1 (config file), and §3.8 (timeout
|
|
6
|
-
* invariant).
|
|
7
|
-
*/
|
|
8
|
-
import { isAbsolute } from 'node:path';
|
|
9
|
-
import { ABSOLUTE_MAX_OUTPUT_TOKENS, DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_RETRY_POLICY, MIN_MAX_OUTPUT_TOKENS, RETRY_LIMITS, } from '@aragon-agent/core';
|
|
10
|
-
import { clampLogLevel } from '../logging/levels.js';
|
|
11
|
-
import { PROC_LIMITS } from '../proc/limits.js';
|
|
12
|
-
import { TEAM_LIMITS } from '../team/limits.js';
|
|
13
|
-
import { DEFAULT_GOVERNANCE_CONFIG } from './governance-config.js';
|
|
14
|
-
// Governance mode (governance-mode 11.1): defined in its own file so this one does not grow.
|
|
15
|
-
export { clampGovernanceConfig, DEFAULT_GOVERNANCE_CONFIG, } from './governance-config.js';
|
|
16
|
-
// ---------------------------------------------------------------------------
|
|
17
|
-
// Provider set — only the adapter-backed providers are usable at run time (R5).
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
/**
|
|
20
|
-
* `ModelRegistry` seeds builtin lists for five providers, but `initProviders()`
|
|
21
|
-
* registers only three adapters. Running a model whose provider has no adapter
|
|
22
|
-
* throws `Unknown LLM provider`, so the CLI only ever offers these three.
|
|
23
|
-
*/
|
|
24
|
-
export const ADAPTER_PROVIDERS = ['anthropic', 'openai', 'google'];
|
|
25
|
-
export function isAdapterProvider(id) {
|
|
26
|
-
return ADAPTER_PROVIDERS.includes(id);
|
|
27
|
-
}
|
|
28
|
-
// ---------------------------------------------------------------------------
|
|
29
|
-
// Thinking levels
|
|
30
|
-
// ---------------------------------------------------------------------------
|
|
31
|
-
export const THINKING_LEVELS = [
|
|
32
|
-
'off',
|
|
33
|
-
'minimal',
|
|
34
|
-
'low',
|
|
35
|
-
'medium',
|
|
36
|
-
'high',
|
|
37
|
-
'xhigh',
|
|
38
|
-
];
|
|
39
|
-
export function isThinkingLevel(v) {
|
|
40
|
-
return typeof v === 'string' && THINKING_LEVELS.includes(v);
|
|
41
|
-
}
|
|
42
|
-
export function clampThinkingLevel(v, fallback) {
|
|
43
|
-
return isThinkingLevel(v) ? v : fallback;
|
|
44
|
-
}
|
|
45
|
-
// ---------------------------------------------------------------------------
|
|
46
|
-
// Theme
|
|
47
|
-
// ---------------------------------------------------------------------------
|
|
48
|
-
export const THEME_NAMES = ['auto', 'warm', 'cool', 'light'];
|
|
49
|
-
/** The v0.3.0 name for what is now `cool`. Accepted forever as an alias. */
|
|
50
|
-
export const LEGACY_DARK_THEME = 'dark';
|
|
51
|
-
export function isThemeName(v) {
|
|
52
|
-
return typeof v === 'string' && THEME_NAMES.includes(v);
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* THE single gate for every theme write (spec §4.5 / R-4).
|
|
56
|
-
*
|
|
57
|
-
* All three write paths funnel through here — config resolution (`load.ts`),
|
|
58
|
-
* `aragon config set theme`, and the `/theme` slash command — which is why the
|
|
59
|
-
* `dark -> cool` migration lives here and nowhere else. Putting it in a
|
|
60
|
-
* `load.ts` normalization step instead would migrate what users *read* but not
|
|
61
|
-
* what they *write*, producing the worst kind of bug: "the flag works but the
|
|
62
|
-
* setting won't stick."
|
|
63
|
-
*
|
|
64
|
-
* An unrecognized value still falls back silently (plus a warn toast at the call
|
|
65
|
-
* site). Turning that into a hard exit would be an unannounced breaking change
|
|
66
|
-
* and would not match `clampThinkingLevel` / `clampTranscriptWindow`.
|
|
67
|
-
*/
|
|
68
|
-
export function clampTheme(v, fallback) {
|
|
69
|
-
if (v === LEGACY_DARK_THEME)
|
|
70
|
-
return 'cool';
|
|
71
|
-
return isThemeName(v) ? v : fallback;
|
|
72
|
-
}
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
// Density / hints (v0.4.0)
|
|
75
|
-
// ---------------------------------------------------------------------------
|
|
76
|
-
export const SCROLL_MODES = ['native', 'app'];
|
|
77
|
-
export const DEFAULT_SCROLL_MODE = 'native';
|
|
78
|
-
export function clampScrollMode(v, fallback) {
|
|
79
|
-
if (typeof v !== 'string')
|
|
80
|
-
return fallback;
|
|
81
|
-
const normalized = v.trim().toLowerCase();
|
|
82
|
-
return normalized === 'native' || normalized === 'app' ? normalized : fallback;
|
|
83
|
-
}
|
|
84
|
-
export const DENSITY_MODES = ['comfortable', 'compact'];
|
|
85
|
-
export function clampDensity(v, fallback) {
|
|
86
|
-
return v === 'comfortable' || v === 'compact' ? v : fallback;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Submissions after which the composer hint collapses to `? help` (§4.6).
|
|
90
|
-
* Only the IDLE hint fades; the running hint carries the abort key and is
|
|
91
|
-
* always shown in full.
|
|
92
|
-
*/
|
|
93
|
-
export const HINT_FADE_AFTER = 8;
|
|
94
|
-
// ---------------------------------------------------------------------------
|
|
95
|
-
// Defaults
|
|
96
|
-
// ---------------------------------------------------------------------------
|
|
97
|
-
export const CONFIG_VERSION = 1;
|
|
98
|
-
export const DEFAULT_MODEL = 'claude-sonnet-4-5-20250929';
|
|
99
|
-
/** Per-tool executor ceiling (§3.8). Headroom for typical installs/builds. */
|
|
100
|
-
export const DEFAULT_TOOL_TIMEOUT_MS = 180_000;
|
|
101
|
-
/** Extra margin so idle timeout is strictly greater than the tool ceiling. */
|
|
102
|
-
export const IDLE_TIMEOUT_MARGIN_MS = 30_000;
|
|
103
|
-
/** Watchdog idle timeout (§3.8) — must stay ≥ toolTimeout so long tools survive. */
|
|
104
|
-
export const DEFAULT_IDLE_TIMEOUT_MS = DEFAULT_TOOL_TIMEOUT_MS + IDLE_TIMEOUT_MARGIN_MS;
|
|
105
|
-
/**
|
|
106
|
-
* Cap on the recall list.
|
|
107
|
-
*
|
|
108
|
-
* The list itself now lives in `<home>/prompt-history.jsonl`; this constant is
|
|
109
|
-
* consumed by `config/prompt-history.ts`, not by the UI.
|
|
110
|
-
*/
|
|
111
|
-
export const PROMPT_HISTORY_CAP = 100;
|
|
112
|
-
/**
|
|
113
|
-
* The SCROLL HORIZON: entries older than this are not reachable inside the app
|
|
114
|
-
* and render as the "N earlier entries collapsed" line instead (invariant I-3).
|
|
115
|
-
*
|
|
116
|
-
* It used to be a rendering budget as well, because yoga laid out every child
|
|
117
|
-
* even when `overflow: hidden` clipped it. The viewport is virtualised now
|
|
118
|
-
* (tui-render-performance L3) — off-screen entries are not mounted at all — so
|
|
119
|
-
* the horizon costs O(entries) of arithmetic rather than O(characters) of layout
|
|
120
|
-
* and the default rises 300 -> 1000 with a 20000 ceiling. An existing persisted
|
|
121
|
-
* `300` is still valid and still clamps; no config migration is required.
|
|
122
|
-
*/
|
|
123
|
-
export const DEFAULT_TRANSCRIPT_WINDOW = 1000;
|
|
124
|
-
export const MIN_TRANSCRIPT_WINDOW = 50;
|
|
125
|
-
export const MAX_TRANSCRIPT_WINDOW = 20_000;
|
|
126
|
-
export function clampTranscriptWindow(v, fallback) {
|
|
127
|
-
const n = coercePositiveInt(v, fallback);
|
|
128
|
-
return Math.min(MAX_TRANSCRIPT_WINDOW, Math.max(MIN_TRANSCRIPT_WINDOW, n));
|
|
129
|
-
}
|
|
130
|
-
// ---------------------------------------------------------------------------
|
|
131
|
-
// Context window override (context-usage-gauge-accuracy §3.6 / W5)
|
|
132
|
-
// ---------------------------------------------------------------------------
|
|
133
|
-
/**
|
|
134
|
-
* Bounds for a hand-supplied context window.
|
|
135
|
-
*
|
|
136
|
-
* The floor is roughly the smallest window any current model ships with; the
|
|
137
|
-
* ceiling is well above the largest, and both exist to keep a typo (a missing
|
|
138
|
-
* or an extra zero) from producing a gauge that is permanently red or
|
|
139
|
-
* permanently flat.
|
|
140
|
-
*/
|
|
141
|
-
export const MIN_CONTEXT_WINDOW = 8_000;
|
|
142
|
-
export const MAX_CONTEXT_WINDOW = 5_000_000;
|
|
143
|
-
/**
|
|
144
|
-
* THE single gate for every `contextWindow` read AND write.
|
|
145
|
-
*
|
|
146
|
-
* TRI-STATE, AND `null` MUST PASS STRAIGHT THROUGH (RV-12). `null` means AUTO -
|
|
147
|
-
* take the model table's number, or the 128k placeholder. Clamping it into
|
|
148
|
-
* `[8000, ...]` yields 8000, which removes "auto" from the config permanently
|
|
149
|
-
* and presents to the user as an 8k denominator with a permanently red bar and
|
|
150
|
-
* no visible source. `maxTokens` above is the existing tri-state precedent and
|
|
151
|
-
* this deliberately copies its shape rather than inventing a second convention.
|
|
152
|
-
*/
|
|
153
|
-
export function clampContextWindow(v, fallback) {
|
|
154
|
-
if (v === null)
|
|
155
|
-
return null;
|
|
156
|
-
if (v === undefined || v === '')
|
|
157
|
-
return fallback;
|
|
158
|
-
const n = typeof v === 'number' ? v : Number.parseInt(String(v), 10);
|
|
159
|
-
if (!Number.isFinite(n) || n <= 0)
|
|
160
|
-
return fallback;
|
|
161
|
-
return Math.min(MAX_CONTEXT_WINDOW, Math.max(MIN_CONTEXT_WINDOW, Math.floor(n)));
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Parse text typed into the settings screen or the profile editor for a
|
|
165
|
-
* context window (profile-context-window §5.3).
|
|
166
|
-
*
|
|
167
|
-
* THE MIRROR OF `parseMaxTokensInput` BELOW, down to the tri-state shape: it
|
|
168
|
-
* distinguishes AUTO from "the user typed nonsense", which `clampContextWindow`
|
|
169
|
-
* cannot - a typo must change NOTHING rather than silently discard the number
|
|
170
|
-
* the user meant to set. `''` / `'auto'` / `'0'` are AUTO (`isAutoToken`);
|
|
171
|
-
* a digit run is clamped through THE single gate; anything else is invalid.
|
|
172
|
-
*/
|
|
173
|
-
export function parseContextWindowInput(raw) {
|
|
174
|
-
const trimmed = String(raw ?? '').trim();
|
|
175
|
-
if (isAutoToken(trimmed))
|
|
176
|
-
return { kind: 'auto' };
|
|
177
|
-
if (!/^\d+$/.test(trimmed))
|
|
178
|
-
return { kind: 'invalid' };
|
|
179
|
-
const value = clampContextWindow(trimmed, null);
|
|
180
|
-
if (value === null)
|
|
181
|
-
return { kind: 'invalid' };
|
|
182
|
-
return { kind: 'value', value, clamped: value !== Number.parseInt(trimmed, 10) };
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Entries kept in `ViewState` at all (tui-render-performance L1 / R5).
|
|
186
|
-
*
|
|
187
|
-
* A DIFFERENT BOUND FROM `transcriptWindow`, and the two must not be merged:
|
|
188
|
-
* the window is what the user can scroll to, this is what the process keeps in
|
|
189
|
-
* memory and what `/save` can export. Dropped entries are COUNTED and reported
|
|
190
|
-
* (`/perf`, and a leading line in the exported transcript) — never silent.
|
|
191
|
-
*/
|
|
192
|
-
export const DEFAULT_TRANSCRIPT_RETAIN = 1000;
|
|
193
|
-
export const MIN_TRANSCRIPT_RETAIN = 200;
|
|
194
|
-
export const MAX_TRANSCRIPT_RETAIN = 20_000;
|
|
195
|
-
export function clampTranscriptRetain(v, fallback) {
|
|
196
|
-
const n = coercePositiveInt(v, fallback);
|
|
197
|
-
return Math.min(MAX_TRANSCRIPT_RETAIN, Math.max(MIN_TRANSCRIPT_RETAIN, n));
|
|
198
|
-
}
|
|
199
|
-
// ---------------------------------------------------------------------------
|
|
200
|
-
// Adaptive render governor (tui-render-performance L4 / R7)
|
|
201
|
-
// ---------------------------------------------------------------------------
|
|
202
|
-
/** Adaptive coalescing under load. On by default; `--no-render-governor` kills it. */
|
|
203
|
-
export const DEFAULT_RENDER_GOVERNOR = true;
|
|
204
|
-
/**
|
|
205
|
-
* Ceiling of the governor ladder, in ms. `33` flattens the ladder to a single
|
|
206
|
-
* rung, which is the pre-feature behaviour without needing the kill switch.
|
|
207
|
-
*/
|
|
208
|
-
export const DEFAULT_MAX_RENDER_INTERVAL_MS = 320;
|
|
209
|
-
const RENDER_INTERVAL_RANGE = { min: 33, max: 1000 };
|
|
210
|
-
export function clampMaxRenderInterval(v, fallback) {
|
|
211
|
-
return clampInt(v, fallback, RENDER_INTERVAL_RANGE);
|
|
212
|
-
}
|
|
213
|
-
// ---------------------------------------------------------------------------
|
|
214
|
-
// Frame diffing (tui-input-flicker-fix §5.1)
|
|
215
|
-
//
|
|
216
|
-
// TWO TROUBLESHOOTING SWITCHES, in the same class as `historyEnabled`: neither
|
|
217
|
-
// appears on the settings overlay, because a user who needs them is debugging a
|
|
218
|
-
// terminal, not adjusting a preference.
|
|
219
|
-
// ---------------------------------------------------------------------------
|
|
220
|
-
/**
|
|
221
|
-
* Repaint only the frame lines that changed (full-screen only).
|
|
222
|
-
*
|
|
223
|
-
* ON by default, and `--no-diff-render` restores today's byte stream EXACTLY —
|
|
224
|
-
* the interposer is not constructed at all, so a regression on an exotic
|
|
225
|
-
* terminal is one flag away from being neutralised (§3.5 rung 2).
|
|
226
|
-
*/
|
|
227
|
-
export const DEFAULT_DIFF_RENDER = true;
|
|
228
|
-
/**
|
|
229
|
-
* Wrap each repaint batch in DEC 2026 begin/end synchronized update.
|
|
230
|
-
*
|
|
231
|
-
* ON by default with NO capability probe (§3.3): terminals that do not implement
|
|
232
|
-
* mode 2026 parse the CSI sequence, find an unknown private mode and discard it,
|
|
233
|
-
* so a false positive costs nothing — and a false negative costs nothing either,
|
|
234
|
-
* because the frame differ already removes the flicker on its own.
|
|
235
|
-
*/
|
|
236
|
-
export const DEFAULT_SYNC_OUTPUT = true;
|
|
237
|
-
// ---------------------------------------------------------------------------
|
|
238
|
-
// Selection + scroll follow (tui-selection-and-scroll-follow §6.1)
|
|
239
|
-
// ---------------------------------------------------------------------------
|
|
240
|
-
/**
|
|
241
|
-
* Drag-select + copy, and — because §4.4.1 gates `\x1b[?1002h` on exactly this
|
|
242
|
-
* value — whether motion reporting is requested from the terminal at all.
|
|
243
|
-
*
|
|
244
|
-
* That gating is what makes `false` BYTE-IDENTICAL to a pre-feature session
|
|
245
|
-
* rather than merely equivalent (AC-8 / D-15). Ignored when `mouse` is false,
|
|
246
|
-
* since there is no capture to select with.
|
|
247
|
-
*/
|
|
248
|
-
export const DEFAULT_MOUSE_SELECT = true;
|
|
249
|
-
/**
|
|
250
|
-
* Idle delay before a paused viewport returns to the newest line, in ms.
|
|
251
|
-
*
|
|
252
|
-
* Five seconds is chosen to be LONGER than a glance and SHORTER than a read.
|
|
253
|
-
* `0` disables auto-resume entirely, and it is a real value rather than a
|
|
254
|
-
* sentinel-shaped default: `shouldArmResume` refuses on it before any timer is
|
|
255
|
-
* created (AC-9), so the revert for Rule B is one config key.
|
|
256
|
-
*
|
|
257
|
-
* NO CLI FLAG (§6.1). It is a comfort preference, set once
|
|
258
|
-
* (`aragon config set scrollResumeMs 8000`) and then forgotten — the same
|
|
259
|
-
* argument this file already makes for `historyEnabled`. Adding a flag for every
|
|
260
|
-
* scalar is how a CLI ends up with sixty of them.
|
|
261
|
-
*/
|
|
262
|
-
export const DEFAULT_SCROLL_RESUME_MS = 5000;
|
|
263
|
-
const SCROLL_RESUME_RANGE = { min: 0, max: 120_000 };
|
|
264
|
-
/**
|
|
265
|
-
* `clampIntAllowingZero`, and the choice is load-bearing: `clampInt` delegates to
|
|
266
|
-
* `coercePositiveInt`, which returns the FALLBACK for `n <= 0` — so `0` would
|
|
267
|
-
* silently become 5000 and the documented off switch would not be an off switch.
|
|
268
|
-
* Exactly the trap `retry.maxRetries` needed this helper for.
|
|
269
|
-
*/
|
|
270
|
-
export function clampScrollResumeMs(v, fallback) {
|
|
271
|
-
return clampIntAllowingZero(v, fallback, SCROLL_RESUME_RANGE);
|
|
272
|
-
}
|
|
273
|
-
// ---------------------------------------------------------------------------
|
|
274
|
-
// Plan mode (plan-mode §4.4)
|
|
275
|
-
//
|
|
276
|
-
// THREE FLAT KEYS, not a nested `planMode` object. `store.ts` documents that its
|
|
277
|
-
// nested-object merge is hand-written and capped at one level; three scalars do
|
|
278
|
-
// not justify a second `clampXConfig` gate plus two more merge sites, and flat
|
|
279
|
-
// keys mean `store.ts` needs ZERO changes.
|
|
280
|
-
//
|
|
281
|
-
// ONE OF THOSE KEYS IS GONE: `planModeMaxAskRounds` capped `ask_user` at four
|
|
282
|
-
// rounds per turn. There is no cap any more, so there is no number to store, no
|
|
283
|
-
// range to clamp and nothing to configure. It is retired through
|
|
284
|
-
// `RETIRED_CONFIG_KEYS` below rather than defaulted to a large number — a
|
|
285
|
-
// ninety-nine in the config file is the same second source of truth as a four.
|
|
286
|
-
// ---------------------------------------------------------------------------
|
|
287
|
-
/**
|
|
288
|
-
* Ceiling on ONE human wait, in ms. Thirty minutes is far outside "the user
|
|
289
|
-
* went to get coffee", but a ceiling has to exist: an unattended terminal must
|
|
290
|
-
* not wedge a CI job or a stale ssh session forever.
|
|
291
|
-
*
|
|
292
|
-
* THIS IS NOT A ROUND LIMIT and the distinction matters. It bounds a single wait
|
|
293
|
-
* (liveness); it says nothing about how many times the model may ask.
|
|
294
|
-
*/
|
|
295
|
-
export const DEFAULT_PLAN_HUMAN_TIMEOUT_MS = 1_800_000;
|
|
296
|
-
const HUMAN_TIMEOUT_RANGE = { min: 60_000, max: 7_200_000 };
|
|
297
|
-
export function clampHumanTimeout(v, fallback) {
|
|
298
|
-
return clampInt(v, fallback, HUMAN_TIMEOUT_RANGE);
|
|
299
|
-
}
|
|
300
|
-
export const SKILLS_INTEGRITY_MODES = ['off', 'warn', 'strict'];
|
|
301
|
-
export function clampSkillsIntegrity(v, fallback) {
|
|
302
|
-
return typeof v === 'string' && SKILLS_INTEGRITY_MODES.includes(v)
|
|
303
|
-
? v
|
|
304
|
-
: fallback;
|
|
305
|
-
}
|
|
306
|
-
export const SKILLS_TOOL_POLICY_MODES = ['off', 'warn', 'enforce'];
|
|
307
|
-
export function isSkillsToolPolicyMode(v) {
|
|
308
|
-
return typeof v === 'string' && SKILLS_TOOL_POLICY_MODES.includes(v);
|
|
309
|
-
}
|
|
310
|
-
export function clampSkillsToolPolicy(v, fallback) {
|
|
311
|
-
return isSkillsToolPolicyMode(v) ? v : fallback;
|
|
312
|
-
}
|
|
313
|
-
export const DEFAULT_ALLOWED_SKILL_HOSTS = [
|
|
314
|
-
'github.com',
|
|
315
|
-
'raw.githubusercontent.com',
|
|
316
|
-
'codeload.github.com',
|
|
317
|
-
'gitlab.com',
|
|
318
|
-
'objects.githubusercontent.com',
|
|
319
|
-
];
|
|
320
|
-
export const DEFAULT_SKILLS_CONFIG = {
|
|
321
|
-
enabled: true,
|
|
322
|
-
disabled: [],
|
|
323
|
-
requireApproval: true,
|
|
324
|
-
allowedHosts: DEFAULT_ALLOWED_SKILL_HOSTS,
|
|
325
|
-
projectDirs: ['.aragon/skills', '.claude/skills'],
|
|
326
|
-
trustedProjectDirs: [],
|
|
327
|
-
catalogMaxBytes: 6000,
|
|
328
|
-
bodyMaxBytes: 30_000,
|
|
329
|
-
integrity: 'warn',
|
|
330
|
-
usageTracking: true,
|
|
331
|
-
toolPolicy: 'enforce',
|
|
332
|
-
// ON by default: the capability this key controls is the feature's whole point,
|
|
333
|
-
// and it costs zero model calls (local matching over in-memory records).
|
|
334
|
-
triage: true,
|
|
335
|
-
};
|
|
336
|
-
const CATALOG_BYTES_RANGE = { min: 500, max: 40_000 };
|
|
337
|
-
/**
|
|
338
|
-
* Upper bound is 50 000, NOT the 90 000 an earlier draft used.
|
|
339
|
-
* `SKILL_RESULT_MAX_BYTES` is 60 000 and must also fit the file list and the
|
|
340
|
-
* head/tail guidance; 50 000 leaves that margin. A 90 000-CHARACTER body is
|
|
341
|
-
* 270 000 bytes of CJK, which `ToolExecutor` would chop mid-tag (D19).
|
|
342
|
-
*/
|
|
343
|
-
const BODY_BYTES_RANGE = { min: 1000, max: 50_000 };
|
|
344
|
-
function clampInt(v, fallback, range) {
|
|
345
|
-
const n = coercePositiveInt(v, fallback);
|
|
346
|
-
return Math.min(range.max, Math.max(range.min, n));
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* `clampInt` for a key whose range legitimately includes ZERO.
|
|
350
|
-
*
|
|
351
|
-
* `clampInt` delegates to `coercePositiveInt`, which returns the FALLBACK for
|
|
352
|
-
* `n <= 0` — so a range whose floor is `0` cannot express `0` through it, and the
|
|
353
|
-
* value silently becomes the default. That trap is invisible at the call site and
|
|
354
|
-
* is what `retry.maxRetries` needs this helper for: `0` is that key's documented
|
|
355
|
-
* floor and its kill switch, and four documented controls send it
|
|
356
|
-
* (`/retry max 0`, `--retry-max 0`, `ARAGON_RETRY_MAX=0`,
|
|
357
|
-
* `aragon config set retry.maxRetries 0`). Through `clampInt` all four would set
|
|
358
|
-
* the MAXIMUM instead of the minimum, with no error anywhere.
|
|
359
|
-
*
|
|
360
|
-
* Own coercion: `Number.parseInt`, reject only non-finite and negative, then
|
|
361
|
-
* floor and clamp.
|
|
362
|
-
*/
|
|
363
|
-
function clampIntAllowingZero(v, fallback, range) {
|
|
364
|
-
if (v === null || v === undefined || v === '')
|
|
365
|
-
return clampToRange(fallback, range);
|
|
366
|
-
const n = typeof v === 'number' ? v : Number.parseInt(String(v), 10);
|
|
367
|
-
if (!Number.isFinite(n) || n < 0)
|
|
368
|
-
return clampToRange(fallback, range);
|
|
369
|
-
return clampToRange(Math.floor(n), range);
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
|
-
* `clampInt` for a key that is legitimately a FLOAT.
|
|
373
|
-
*
|
|
374
|
-
* `coercePositiveInt` floors, and `2.5` is a legitimate backoff factor — the same
|
|
375
|
-
* coercion trap `clampIntAllowingZero` above closes for `0`, one type over.
|
|
376
|
-
*/
|
|
377
|
-
function clampNumber(v, fallback, range) {
|
|
378
|
-
if (v === null || v === undefined || v === '')
|
|
379
|
-
return clampToRange(fallback, range);
|
|
380
|
-
const n = typeof v === 'number' ? v : Number.parseFloat(String(v));
|
|
381
|
-
if (!Number.isFinite(n))
|
|
382
|
-
return clampToRange(fallback, range);
|
|
383
|
-
return clampToRange(n, range);
|
|
384
|
-
}
|
|
385
|
-
function clampToRange(n, range) {
|
|
386
|
-
return Math.min(range.max, Math.max(range.min, n));
|
|
387
|
-
}
|
|
388
|
-
function stringArray(v, fallback) {
|
|
389
|
-
if (!Array.isArray(v))
|
|
390
|
-
return fallback;
|
|
391
|
-
const out = v.filter((item) => typeof item === 'string' && item.trim().length > 0);
|
|
392
|
-
return out.map((s) => s.trim());
|
|
393
|
-
}
|
|
394
|
-
function bool(v, fallback) {
|
|
395
|
-
return typeof v === 'boolean' ? v : fallback;
|
|
396
|
-
}
|
|
397
|
-
/**
|
|
398
|
-
* THE single gate for every skills-config read AND write (§10.3.1).
|
|
399
|
-
*
|
|
400
|
-
* Shared by `loadConfig()`, `loadPersistedConfig()` and `updatePersistedConfig()`
|
|
401
|
-
* on purpose: hardening only the read path would leave a corrupt value on disk
|
|
402
|
-
* that silently reverts to a default on every launch — the failure looks like
|
|
403
|
-
* "my setting won't stick" with no error anywhere.
|
|
404
|
-
*/
|
|
405
|
-
export function clampSkillsConfig(raw) {
|
|
406
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
407
|
-
return {
|
|
408
|
-
enabled: bool(src.enabled, DEFAULT_SKILLS_CONFIG.enabled),
|
|
409
|
-
disabled: stringArray(src.disabled, DEFAULT_SKILLS_CONFIG.disabled),
|
|
410
|
-
requireApproval: bool(src.requireApproval, DEFAULT_SKILLS_CONFIG.requireApproval),
|
|
411
|
-
allowedHosts: stringArray(src.allowedHosts, DEFAULT_SKILLS_CONFIG.allowedHosts),
|
|
412
|
-
projectDirs: stringArray(src.projectDirs, DEFAULT_SKILLS_CONFIG.projectDirs),
|
|
413
|
-
trustedProjectDirs: stringArray(src.trustedProjectDirs, DEFAULT_SKILLS_CONFIG.trustedProjectDirs),
|
|
414
|
-
catalogMaxBytes: clampInt(src.catalogMaxBytes, DEFAULT_SKILLS_CONFIG.catalogMaxBytes, CATALOG_BYTES_RANGE),
|
|
415
|
-
bodyMaxBytes: clampInt(src.bodyMaxBytes, DEFAULT_SKILLS_CONFIG.bodyMaxBytes, BODY_BYTES_RANGE),
|
|
416
|
-
integrity: clampSkillsIntegrity(src.integrity, DEFAULT_SKILLS_CONFIG.integrity),
|
|
417
|
-
usageTracking: bool(src.usageTracking, DEFAULT_SKILLS_CONFIG.usageTracking),
|
|
418
|
-
toolPolicy: clampSkillsToolPolicy(src.toolPolicy, DEFAULT_SKILLS_CONFIG.toolPolicy),
|
|
419
|
-
triage: bool(src.triage, DEFAULT_SKILLS_CONFIG.triage),
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
export const DEFAULT_SKILLS_RUNTIME = { forcedSkills: [], approveAll: false };
|
|
423
|
-
const DEFAULT_MAX_LOG_FILE_BYTES = 5 * 1024 * 1024;
|
|
424
|
-
const LOG_FILE_BYTES_RANGE = { min: 64 * 1024, max: 256 * 1024 * 1024 };
|
|
425
|
-
const LOG_MAX_FILES_RANGE = { min: 1, max: 200 };
|
|
426
|
-
const LOG_PREVIEW_CHARS_RANGE = { min: 0, max: 8192 };
|
|
427
|
-
export const DEFAULT_LOG_CONFIG = {
|
|
428
|
-
level: 'info',
|
|
429
|
-
toFile: true,
|
|
430
|
-
dir: '',
|
|
431
|
-
maxFileBytes: DEFAULT_MAX_LOG_FILE_BYTES,
|
|
432
|
-
maxFiles: 10,
|
|
433
|
-
redactSecrets: true,
|
|
434
|
-
previewChars: 512,
|
|
435
|
-
};
|
|
436
|
-
/**
|
|
437
|
-
* Coerce a log directory. Anything relative is discarded (falling back to
|
|
438
|
-
* `<home>/logs`) rather than resolved: a relative path would silently mean a
|
|
439
|
-
* different directory for every working directory the CLI is launched from, and
|
|
440
|
-
* `debug`-level files carry prompt text (R-13).
|
|
441
|
-
*/
|
|
442
|
-
function logDir(v, fallback) {
|
|
443
|
-
if (typeof v !== 'string')
|
|
444
|
-
return fallback;
|
|
445
|
-
const trimmed = v.trim();
|
|
446
|
-
if (trimmed.length === 0)
|
|
447
|
-
return '';
|
|
448
|
-
return isAbsolute(trimmed) ? trimmed : fallback;
|
|
449
|
-
}
|
|
450
|
-
/**
|
|
451
|
-
* THE single gate for every log-config read AND write, exactly like
|
|
452
|
-
* `clampSkillsConfig`: hardening only the read path leaves a bad value on disk
|
|
453
|
-
* that reverts on every launch, which presents as "my setting won't stick".
|
|
454
|
-
*
|
|
455
|
-
* `previewChars` uses its own coercion because `coercePositiveInt` rejects `0`,
|
|
456
|
-
* and `0` is a legitimate value here — it means "record that content existed,
|
|
457
|
-
* but none of it".
|
|
458
|
-
*/
|
|
459
|
-
export function clampLogConfig(raw) {
|
|
460
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
461
|
-
const preview = typeof src.previewChars === 'number' || typeof src.previewChars === 'string'
|
|
462
|
-
? Number.parseInt(String(src.previewChars), 10)
|
|
463
|
-
: Number.NaN;
|
|
464
|
-
return {
|
|
465
|
-
level: clampLogLevel(src.level, DEFAULT_LOG_CONFIG.level),
|
|
466
|
-
toFile: bool(src.toFile, DEFAULT_LOG_CONFIG.toFile),
|
|
467
|
-
dir: logDir(src.dir, DEFAULT_LOG_CONFIG.dir),
|
|
468
|
-
maxFileBytes: clampInt(src.maxFileBytes, DEFAULT_LOG_CONFIG.maxFileBytes, LOG_FILE_BYTES_RANGE),
|
|
469
|
-
maxFiles: clampInt(src.maxFiles, DEFAULT_LOG_CONFIG.maxFiles, LOG_MAX_FILES_RANGE),
|
|
470
|
-
redactSecrets: bool(src.redactSecrets, DEFAULT_LOG_CONFIG.redactSecrets),
|
|
471
|
-
previewChars: Number.isFinite(preview)
|
|
472
|
-
? Math.min(LOG_PREVIEW_CHARS_RANGE.max, Math.max(LOG_PREVIEW_CHARS_RANGE.min, preview))
|
|
473
|
-
: DEFAULT_LOG_CONFIG.previewChars,
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
/**
|
|
477
|
-
* The requirement's ceiling on the fan-out (R-g).
|
|
478
|
-
*
|
|
479
|
-
* Re-exported from `TEAM_LIMITS` rather than re-spelled, because it is enforced
|
|
480
|
-
* in TWO places — here on the config value, and again in
|
|
481
|
-
* `normalizeSubagentSpecs` on what the model asked for — and two copies of the
|
|
482
|
-
* same 10 is exactly how a hand-edited `config.json` ends up being able to raise
|
|
483
|
-
* a ceiling the requirement fixed.
|
|
484
|
-
*/
|
|
485
|
-
export const HARD_MAX_SUBAGENTS = TEAM_LIMITS.hardMaxSubagents;
|
|
486
|
-
export const DEFAULT_TEAM_CONFIG = {
|
|
487
|
-
enabled: true,
|
|
488
|
-
// 8 IS THE DEFAULT, 10 IS THE CEILING, and they are not the same number
|
|
489
|
-
// (subagent-fanout D-1 / D-2). `maxConcurrent` moves WITH `maxSubagents`
|
|
490
|
-
// because a wider population behind a 3-wide pool shows the user nothing:
|
|
491
|
-
// children 4..8 simply queue (`team-bus.test.ts` records the queued phase).
|
|
492
|
-
maxSubagents: 8,
|
|
493
|
-
maxConcurrent: 8,
|
|
494
|
-
// 0 = NO LIMIT. Subagents run under the same regime as the lead: no
|
|
495
|
-
// wall clock, no turn cap; only the idle watchdog and the user's Esc.
|
|
496
|
-
subagentTimeoutMs: 0,
|
|
497
|
-
dispatchTimeoutMs: 0,
|
|
498
|
-
maxTurnsPerSubagent: 0,
|
|
499
|
-
// The dispatch supervisor, default ON (team-overseer): ceilings become
|
|
500
|
-
// inspections; the fast-tier supervisor decides what to do.
|
|
501
|
-
overseer: true,
|
|
502
|
-
// 0 = the structural cadence default (300 s). See the field docstring.
|
|
503
|
-
overseerIntervalMs: 0,
|
|
504
|
-
// The parity default: children run the lead's own model until the user
|
|
505
|
-
// says otherwise (AC-1 - an upgraded config behaves exactly as before).
|
|
506
|
-
model: 'main',
|
|
507
|
-
modelProfileId: null,
|
|
508
|
-
};
|
|
509
|
-
const SUBAGENTS_RANGE = { min: 1, max: HARD_MAX_SUBAGENTS };
|
|
510
|
-
const CONCURRENT_RANGE = { min: 1, max: HARD_MAX_SUBAGENTS };
|
|
511
|
-
// `min: 0` is the documented OFF SWITCH for each bound, so these MUST use
|
|
512
|
-
// `clampIntAllowingZero`: plain `clampInt` folds `0` back to the fallback
|
|
513
|
-
// ("my setting won't stick"), the exact trap `scrollResumeMs` records above.
|
|
514
|
-
const SUBAGENT_TIMEOUT_RANGE = { min: 0, max: 1_800_000 };
|
|
515
|
-
const DISPATCH_TIMEOUT_RANGE = { min: 0, max: 3_600_000 };
|
|
516
|
-
const OVERSEER_INTERVAL_RANGE = { min: 0, max: 3_600_000 };
|
|
517
|
-
const TURNS_RANGE = { min: 0, max: 100 };
|
|
518
|
-
/**
|
|
519
|
-
* THE single gate for every team-config read AND write, mirroring
|
|
520
|
-
* `clampSkillsConfig` / `clampLogConfig` for the reason those two record:
|
|
521
|
-
* hardening only the read path leaves a bad value on disk that reverts to the
|
|
522
|
-
* default on every launch, which presents to the user as "my setting won't
|
|
523
|
-
* stick".
|
|
524
|
-
*
|
|
525
|
-
* `maxConcurrent` is additionally capped at `maxSubagents`: a pool wider than
|
|
526
|
-
* the population it draws from is not wrong so much as meaningless, and letting
|
|
527
|
-
* the two disagree would make the panel's `n/m` readout confusing for no gain.
|
|
528
|
-
*/
|
|
529
|
-
export function clampTeamConfig(raw) {
|
|
530
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
531
|
-
const maxSubagents = clampInt(src.maxSubagents, DEFAULT_TEAM_CONFIG.maxSubagents, SUBAGENTS_RANGE);
|
|
532
|
-
return {
|
|
533
|
-
enabled: bool(src.enabled, DEFAULT_TEAM_CONFIG.enabled),
|
|
534
|
-
maxSubagents,
|
|
535
|
-
maxConcurrent: Math.min(maxSubagents, clampInt(src.maxConcurrent, DEFAULT_TEAM_CONFIG.maxConcurrent, CONCURRENT_RANGE)),
|
|
536
|
-
subagentTimeoutMs: clampIntAllowingZero(src.subagentTimeoutMs, DEFAULT_TEAM_CONFIG.subagentTimeoutMs, SUBAGENT_TIMEOUT_RANGE),
|
|
537
|
-
dispatchTimeoutMs: clampIntAllowingZero(src.dispatchTimeoutMs, DEFAULT_TEAM_CONFIG.dispatchTimeoutMs, DISPATCH_TIMEOUT_RANGE),
|
|
538
|
-
maxTurnsPerSubagent: clampIntAllowingZero(src.maxTurnsPerSubagent, DEFAULT_TEAM_CONFIG.maxTurnsPerSubagent, TURNS_RANGE),
|
|
539
|
-
overseer: bool(src.overseer, DEFAULT_TEAM_CONFIG.overseer),
|
|
540
|
-
overseerIntervalMs: clampIntAllowingZero(src.overseerIntervalMs, DEFAULT_TEAM_CONFIG.overseerIntervalMs, OVERSEER_INTERVAL_RANGE),
|
|
541
|
-
// typo-changes-nothing, the discipline every enum clamp here follows: a
|
|
542
|
-
// hand-edited `model: 'fats'` resolves to 'main' (the parity default)
|
|
543
|
-
// rather than invalidating the file or refusing to launch. A bad
|
|
544
|
-
// `modelProfileId` (wrong type, or over the 128-codepoint budget
|
|
545
|
-
// `model-profiles.ts::validText` defines) is nulled the same way;
|
|
546
|
-
// reference EXISTENCE stays a resolution-time concern (D-4).
|
|
547
|
-
model: src.model === 'fast' || src.model === 'profile' ? src.model : 'main',
|
|
548
|
-
modelProfileId: typeof src.modelProfileId === 'string' && src.modelProfileId.length > 0
|
|
549
|
-
&& [...src.modelProfileId].length <= 128
|
|
550
|
-
? src.modelProfileId
|
|
551
|
-
: null,
|
|
552
|
-
// TRANSPARENT, and only ever `true` (subagent-fanout D-3 / R-6). The flag is
|
|
553
|
-
// not a setting: it is the one-shot marker the migration leaves behind, so a
|
|
554
|
-
// clamp that dropped it would re-migrate the user on every launch. Written
|
|
555
|
-
// as a spread rather than `=== true ? true : undefined` so the key stays
|
|
556
|
-
// ABSENT (not `undefined`) in the clamped result - `toEqual(DEFAULT_TEAM_CONFIG)`
|
|
557
|
-
// and the on-disk shape both depend on that.
|
|
558
|
-
...(src.fanoutMigrated === true ? { fanoutMigrated: true } : {}),
|
|
559
|
-
};
|
|
560
|
-
}
|
|
561
|
-
/**
|
|
562
|
-
* The team ceilings cli <= 0.6.16 (7a6bf5630) persisted as its OWN defaults:
|
|
563
|
-
* every user who touched team mode back then still carries this exact triple
|
|
564
|
-
* in config.json, because `resolveTeamConfig` merges file values verbatim and
|
|
565
|
-
* no migration ever rewrote them. They are the kill ceilings behind F-8's
|
|
566
|
-
* "first block all failed" dispatches, so loading rewrites them to 0 (= no
|
|
567
|
-
* ceiling, the shipped default since 2ff15a9c3).
|
|
568
|
-
*
|
|
569
|
-
* EXACT-EQUALITY ONLY: a value that differs was a deliberate user choice and
|
|
570
|
-
* survives untouched. The price of that test is that a user who hand-types
|
|
571
|
-
* 300000 today is migrated to 0 too - the accepted trade, and the safe
|
|
572
|
-
* direction (no ceiling, not a cliff).
|
|
573
|
-
*/
|
|
574
|
-
export const LEGACY_TEAM_CEILING_DEFAULTS = {
|
|
575
|
-
subagentTimeoutMs: 300_000,
|
|
576
|
-
dispatchTimeoutMs: 900_000,
|
|
577
|
-
maxTurnsPerSubagent: 24,
|
|
578
|
-
};
|
|
579
|
-
/**
|
|
580
|
-
* The `{ key: 0 }` patch for legacy-default-equal ceilings, or `null` when
|
|
581
|
-
* nothing matches. Pure on purpose: `loadConfig` decides WHERE the patch is
|
|
582
|
-
* applied and persisted; this function only answers WHICH keys match, so the
|
|
583
|
-
* equality test lives beside the constants it reads.
|
|
584
|
-
*/
|
|
585
|
-
export function legacyTeamCeilingPatch(raw) {
|
|
586
|
-
if (!raw || typeof raw !== 'object')
|
|
587
|
-
return null;
|
|
588
|
-
const src = raw;
|
|
589
|
-
const patch = {};
|
|
590
|
-
let matched = false;
|
|
591
|
-
for (const key of Object.keys(LEGACY_TEAM_CEILING_DEFAULTS)) {
|
|
592
|
-
if (src[key] === LEGACY_TEAM_CEILING_DEFAULTS[key]) {
|
|
593
|
-
patch[key] = 0;
|
|
594
|
-
matched = true;
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
return matched ? patch : null;
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* The fan-out defaults cli <= 0.6.x persisted as its OWN defaults
|
|
601
|
-
* (subagent-fanout F-2 / R-1).
|
|
602
|
-
*
|
|
603
|
-
* THE SAME TRAP AS THE CEILINGS ABOVE, ONE SECTION OVER. `mergePersistedConfig`
|
|
604
|
-
* writes the WHOLE `team` section on every save, so a user who has ever touched
|
|
605
|
-
* any setting carries this exact pair in `config.json` - changing
|
|
606
|
-
* `DEFAULT_TEAM_CONFIG` alone would never reach them, and they would keep
|
|
607
|
-
* seeing "only 3 subagents at once" for ever.
|
|
608
|
-
*/
|
|
609
|
-
export const LEGACY_TEAM_FANOUT_DEFAULTS = {
|
|
610
|
-
maxSubagents: 5,
|
|
611
|
-
maxConcurrent: 3,
|
|
612
|
-
};
|
|
613
|
-
/**
|
|
614
|
-
* The `{ maxSubagents, maxConcurrent, fanoutMigrated }` patch for the legacy
|
|
615
|
-
* default pair, or `null` when nothing matches (subagent-fanout D-3).
|
|
616
|
-
*
|
|
617
|
-
* EXACT-EQUALITY ONLY, the rule `legacyTeamCeilingPatch` records: a value that
|
|
618
|
-
* differs was a deliberate user choice and survives untouched. Two differences
|
|
619
|
-
* from that function, both deliberate:
|
|
620
|
-
*
|
|
621
|
-
* - `fanoutMigrated: true` short-circuits to `null`. That is what makes "the
|
|
622
|
-
* user changed their mind and went back to 5/3" stick: without it the next
|
|
623
|
-
* launch would migrate them again, every launch, for ever.
|
|
624
|
-
* - `maxConcurrent` is allowed to be ABSENT as well as 3, because a
|
|
625
|
-
* hand-written section may name only one key and a half-written pair is
|
|
626
|
-
* still the legacy intent, not a user decision.
|
|
627
|
-
*
|
|
628
|
-
* Pure on purpose: `loadConfig` decides WHERE the patch is applied and
|
|
629
|
-
* persisted; this function only answers WHICH keys match, so the equality test
|
|
630
|
-
* lives beside the constants it reads.
|
|
631
|
-
*/
|
|
632
|
-
export function legacyTeamFanoutPatch(raw) {
|
|
633
|
-
if (!raw || typeof raw !== 'object' || Array.isArray(raw))
|
|
634
|
-
return null;
|
|
635
|
-
const src = raw;
|
|
636
|
-
if (src.fanoutMigrated === true)
|
|
637
|
-
return null;
|
|
638
|
-
if (src.maxSubagents !== LEGACY_TEAM_FANOUT_DEFAULTS.maxSubagents)
|
|
639
|
-
return null;
|
|
640
|
-
if (src.maxConcurrent !== undefined
|
|
641
|
-
&& src.maxConcurrent !== LEGACY_TEAM_FANOUT_DEFAULTS.maxConcurrent)
|
|
642
|
-
return null;
|
|
643
|
-
return {
|
|
644
|
-
maxSubagents: DEFAULT_TEAM_CONFIG.maxSubagents,
|
|
645
|
-
maxConcurrent: DEFAULT_TEAM_CONFIG.maxConcurrent,
|
|
646
|
-
fanoutMigrated: true,
|
|
647
|
-
};
|
|
648
|
-
}
|
|
649
|
-
export const DEFAULT_TODO_CONFIG = {
|
|
650
|
-
enabled: true,
|
|
651
|
-
panel: true,
|
|
652
|
-
followThrough: 'notify',
|
|
653
|
-
acceptance: true,
|
|
654
|
-
};
|
|
655
|
-
/**
|
|
656
|
-
* There is no enum helper in this file, so this follows the `isThinkingLevel`
|
|
657
|
-
* shape already here rather than inventing a second idiom.
|
|
658
|
-
*/
|
|
659
|
-
const FOLLOW_THROUGH_MODES = ['notify', 'auto', 'off'];
|
|
660
|
-
function followMode(value, fallback) {
|
|
661
|
-
return typeof value === 'string' && FOLLOW_THROUGH_MODES.includes(value)
|
|
662
|
-
? value
|
|
663
|
-
: fallback;
|
|
664
|
-
}
|
|
665
|
-
/**
|
|
666
|
-
* THE single gate for every todo-config read AND write, mirroring
|
|
667
|
-
* `clampSkillsConfig` / `clampLogConfig` / `clampTeamConfig` for the reason
|
|
668
|
-
* those record: hardening only the read path leaves a bad value on disk that
|
|
669
|
-
* reverts to the default on every launch, which presents to the user as "my
|
|
670
|
-
* setting won't stick".
|
|
671
|
-
*/
|
|
672
|
-
export function clampTodoConfig(raw) {
|
|
673
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
674
|
-
return {
|
|
675
|
-
enabled: bool(src.enabled, DEFAULT_TODO_CONFIG.enabled),
|
|
676
|
-
panel: bool(src.panel, DEFAULT_TODO_CONFIG.panel),
|
|
677
|
-
// CLAMPED TO THE DEFAULT, NEVER REJECTED — the discipline every other key in
|
|
678
|
-
// this file follows, and the trade round 1 already made for `--thinking`.
|
|
679
|
-
// `ARAGON_TODO_FOLLOW=garbage` therefore resolves to `'notify'` and throws
|
|
680
|
-
// nothing (AC-5).
|
|
681
|
-
followThrough: followMode(src.followThrough, DEFAULT_TODO_CONFIG.followThrough),
|
|
682
|
-
// The fourth key needs nothing beyond this line: no migration, because
|
|
683
|
-
// `CONFIG_VERSION` is only stamped and never branched, and an old file reaches
|
|
684
|
-
// the new default through `{ ...DEFAULT, ...partial } + clamp`.
|
|
685
|
-
acceptance: bool(src.acceptance, DEFAULT_TODO_CONFIG.acceptance),
|
|
686
|
-
};
|
|
687
|
-
}
|
|
688
|
-
export const DEFAULT_RETRY_CONFIG = {
|
|
689
|
-
enabled: true,
|
|
690
|
-
maxRetries: DEFAULT_RETRY_POLICY.maxRetries,
|
|
691
|
-
initialDelayMs: DEFAULT_RETRY_POLICY.initialDelayMs,
|
|
692
|
-
maxDelayMs: DEFAULT_RETRY_POLICY.maxDelayMs,
|
|
693
|
-
multiplier: DEFAULT_RETRY_POLICY.multiplier,
|
|
694
|
-
jitter: DEFAULT_RETRY_POLICY.jitter,
|
|
695
|
-
respectRetryAfter: DEFAULT_RETRY_POLICY.respectRetryAfter,
|
|
696
|
-
maxElapsedMs: DEFAULT_RETRY_POLICY.maxElapsedMs,
|
|
697
|
-
onPartialStream: DEFAULT_RETRY_POLICY.onPartialStream,
|
|
698
|
-
};
|
|
699
|
-
/**
|
|
700
|
-
* `hardMaxRetries` re-exported rather than re-spelled, for the reason
|
|
701
|
-
* `HARD_MAX_SUBAGENTS` records: the ceiling is enforced in TWO places — here on
|
|
702
|
-
* the config value, and again by `normalizePolicy` inside the engine — and two
|
|
703
|
-
* copies of the same 20 is exactly how a hand-edited `config.json` ends up able
|
|
704
|
-
* to raise a ceiling the mechanism fixed.
|
|
705
|
-
*/
|
|
706
|
-
export const HARD_MAX_RETRIES = RETRY_LIMITS.hardMaxRetries;
|
|
707
|
-
/** FLOOR 0 — and `clampIntAllowingZero` is what makes that reachable. */
|
|
708
|
-
const RETRY_MAX_RANGE = { min: 0, max: HARD_MAX_RETRIES };
|
|
709
|
-
const RETRY_INITIAL_DELAY_RANGE = { min: 100, max: 30_000 };
|
|
710
|
-
const RETRY_MAX_DELAY_RANGE = { min: 1000, max: RETRY_LIMITS.absoluteMaxDelayMs };
|
|
711
|
-
const RETRY_MULTIPLIER_RANGE = { min: 1, max: 5 };
|
|
712
|
-
const RETRY_ELAPSED_RANGE = { min: 10_000, max: 1_800_000 };
|
|
713
|
-
/**
|
|
714
|
-
* THE single gate for every retry-config read AND write, mirroring
|
|
715
|
-
* `clampSkillsConfig` / `clampLogConfig` / `clampTeamConfig` / `clampTodoConfig`
|
|
716
|
-
* for the reason those record: hardening only the read path leaves a bad value on
|
|
717
|
-
* disk that reverts to the default on every launch, which presents to the user as
|
|
718
|
-
* "my setting won't stick".
|
|
719
|
-
*
|
|
720
|
-
* Three invariants live inside the gate:
|
|
721
|
-
*
|
|
722
|
-
* - `maxDelayMs = max(maxDelayMs, initialDelayMs)` — a ceiling under the floor
|
|
723
|
-
* makes the ladder a flat line and the countdown a lie.
|
|
724
|
-
* - `multiplier` goes through `clampNumber`, not `clampInt`: `2.5` is a
|
|
725
|
-
* legitimate factor and `coercePositiveInt` would floor it to 2.
|
|
726
|
-
* - `maxRetries` goes through `clampIntAllowingZero`. THIS IS THE ONE THAT SHIPS
|
|
727
|
-
* BROKEN WITHOUT IT (R-16): `clampInt` returns the fallback for `n <= 0`, so
|
|
728
|
-
* `clampRetryConfig({ maxRetries: 0 })` would yield 10 — the maximum instead
|
|
729
|
-
* of the minimum, silently, for the key that gates the whole feature.
|
|
730
|
-
*
|
|
731
|
-
* `maxElapsedMs` intentionally keeps plain `clampInt`: its floor is 10 000, so it
|
|
732
|
-
* has no `0` to express.
|
|
733
|
-
*/
|
|
734
|
-
export function clampRetryConfig(raw) {
|
|
735
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
736
|
-
const initialDelayMs = clampInt(src.initialDelayMs, DEFAULT_RETRY_CONFIG.initialDelayMs, RETRY_INITIAL_DELAY_RANGE);
|
|
737
|
-
const maxDelayMs = Math.max(initialDelayMs, clampInt(src.maxDelayMs, DEFAULT_RETRY_CONFIG.maxDelayMs, RETRY_MAX_DELAY_RANGE));
|
|
738
|
-
return {
|
|
739
|
-
enabled: bool(src.enabled, DEFAULT_RETRY_CONFIG.enabled),
|
|
740
|
-
maxRetries: clampIntAllowingZero(src.maxRetries, DEFAULT_RETRY_CONFIG.maxRetries, RETRY_MAX_RANGE),
|
|
741
|
-
initialDelayMs,
|
|
742
|
-
maxDelayMs,
|
|
743
|
-
multiplier: clampNumber(src.multiplier, DEFAULT_RETRY_CONFIG.multiplier, RETRY_MULTIPLIER_RANGE),
|
|
744
|
-
jitter: bool(src.jitter, DEFAULT_RETRY_CONFIG.jitter),
|
|
745
|
-
respectRetryAfter: bool(src.respectRetryAfter, DEFAULT_RETRY_CONFIG.respectRetryAfter),
|
|
746
|
-
maxElapsedMs: clampInt(src.maxElapsedMs, DEFAULT_RETRY_CONFIG.maxElapsedMs, RETRY_ELAPSED_RANGE),
|
|
747
|
-
onPartialStream: bool(src.onPartialStream, DEFAULT_RETRY_CONFIG.onPartialStream),
|
|
748
|
-
};
|
|
749
|
-
}
|
|
750
|
-
/**
|
|
751
|
-
* `RetryConfig` (user intent) -> `RetryPolicy` (engine policy), or `null` for
|
|
752
|
-
* "the user said no".
|
|
753
|
-
*
|
|
754
|
-
* `null` rather than a policy with `maxRetries: 0` because `ProviderRegistry`
|
|
755
|
-
* short-circuits on a null policy and returns the adapter's iterator DIRECTLY —
|
|
756
|
-
* an opted-out session is then allocation-identical to a pre-feature build.
|
|
757
|
-
*
|
|
758
|
-
* TOTAL, AND IT ACCEPTS A MISSING SECTION. `loadConfig` always supplies one, but
|
|
759
|
-
* a `CliConfig` built by hand — every controller test in this package does exactly
|
|
760
|
-
* that, and so would an embedder — legitimately omits it, and a `TypeError` from a
|
|
761
|
-
* pure translation function is the wrong way to find out. Routing through
|
|
762
|
-
* `clampRetryConfig` also means an out-of-range hand-built value can never reach
|
|
763
|
-
* the engine, which is the same "one gate, both directions" rule every other
|
|
764
|
-
* section in this file follows.
|
|
765
|
-
*/
|
|
766
|
-
export function toRetryPolicy(cfg) {
|
|
767
|
-
const safe = clampRetryConfig(cfg);
|
|
768
|
-
if (!safe.enabled || safe.maxRetries <= 0)
|
|
769
|
-
return null;
|
|
770
|
-
return {
|
|
771
|
-
maxRetries: safe.maxRetries,
|
|
772
|
-
initialDelayMs: safe.initialDelayMs,
|
|
773
|
-
maxDelayMs: safe.maxDelayMs,
|
|
774
|
-
multiplier: safe.multiplier,
|
|
775
|
-
jitter: safe.jitter,
|
|
776
|
-
respectRetryAfter: safe.respectRetryAfter,
|
|
777
|
-
maxElapsedMs: safe.maxElapsedMs,
|
|
778
|
-
onPartialStream: safe.onPartialStream,
|
|
779
|
-
};
|
|
780
|
-
}
|
|
781
|
-
export const DEFAULT_FAST_CONFIG = {
|
|
782
|
-
// R-d, and the one default in this file that is a REQUIREMENT rather than a
|
|
783
|
-
// judgement: a feature that silently spends money on a second provider is not
|
|
784
|
-
// a default (D-3).
|
|
785
|
-
enabled: false,
|
|
786
|
-
provider: '',
|
|
787
|
-
model: '',
|
|
788
|
-
baseUrl: '',
|
|
789
|
-
thinkingLevel: 'off',
|
|
790
|
-
review: true,
|
|
791
|
-
reviewEveryTurns: 5,
|
|
792
|
-
reviewContextTurns: 3,
|
|
793
|
-
reviewMaxChars: 280,
|
|
794
|
-
// 40 is roughly 200 reviewed turns at the default cadence: comfortably past a
|
|
795
|
-
// full working session, short of a runaway (D-H2).
|
|
796
|
-
reviewMaxPerSession: 40,
|
|
797
|
-
};
|
|
798
|
-
const REVIEW_EVERY_RANGE = { min: 1, max: 50 };
|
|
799
|
-
const REVIEW_CONTEXT_RANGE = { min: 1, max: 10 };
|
|
800
|
-
const REVIEW_CHARS_RANGE = { min: 80, max: 600 };
|
|
801
|
-
/** No "unlimited" sentinel: a magic `0` reads as "disabled" to the next person
|
|
802
|
-
* who meets it, and 500 is already past any session a human sits through. */
|
|
803
|
-
const REVIEW_SESSION_RANGE = { min: 1, max: 500 };
|
|
804
|
-
/** Trim a string field, falling back when the value is not a string at all. */
|
|
805
|
-
function text(v, fallback) {
|
|
806
|
-
return typeof v === 'string' ? v.trim() : fallback;
|
|
807
|
-
}
|
|
808
|
-
/**
|
|
809
|
-
* THE single gate for every fast-config read AND write, mirroring
|
|
810
|
-
* `clampSkillsConfig` / `clampLogConfig` / `clampTeamConfig` / `clampTodoConfig`
|
|
811
|
-
* for the reason those four record: hardening only the read path leaves a bad
|
|
812
|
-
* value on disk that reverts to the default on every launch, which presents to
|
|
813
|
-
* the user as "my setting won't stick".
|
|
814
|
-
*
|
|
815
|
-
* `provider` is CLAMPED TO `''` rather than rejected when it names something
|
|
816
|
-
* with no adapter. `''` means "inherit the main provider", which is the safe
|
|
817
|
-
* reading of a typo — and `resolveFastTier` reports `no_adapter` for the case a
|
|
818
|
-
* user really did configure a dead vendor as the MAIN one.
|
|
819
|
-
*/
|
|
820
|
-
export function clampFastConfig(raw) {
|
|
821
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
822
|
-
const provider = text(src.provider, DEFAULT_FAST_CONFIG.provider);
|
|
823
|
-
return {
|
|
824
|
-
enabled: bool(src.enabled, DEFAULT_FAST_CONFIG.enabled),
|
|
825
|
-
provider: provider.length === 0 || isAdapterProvider(provider) ? provider : '',
|
|
826
|
-
model: text(src.model, DEFAULT_FAST_CONFIG.model),
|
|
827
|
-
baseUrl: text(src.baseUrl, DEFAULT_FAST_CONFIG.baseUrl),
|
|
828
|
-
thinkingLevel: clampThinkingLevel(src.thinkingLevel, DEFAULT_FAST_CONFIG.thinkingLevel),
|
|
829
|
-
review: bool(src.review, DEFAULT_FAST_CONFIG.review),
|
|
830
|
-
reviewEveryTurns: clampInt(src.reviewEveryTurns, DEFAULT_FAST_CONFIG.reviewEveryTurns, REVIEW_EVERY_RANGE),
|
|
831
|
-
reviewContextTurns: clampInt(src.reviewContextTurns, DEFAULT_FAST_CONFIG.reviewContextTurns, REVIEW_CONTEXT_RANGE),
|
|
832
|
-
reviewMaxChars: clampInt(src.reviewMaxChars, DEFAULT_FAST_CONFIG.reviewMaxChars, REVIEW_CHARS_RANGE),
|
|
833
|
-
reviewMaxPerSession: clampInt(src.reviewMaxPerSession, DEFAULT_FAST_CONFIG.reviewMaxPerSession, REVIEW_SESSION_RANGE),
|
|
834
|
-
};
|
|
835
|
-
}
|
|
836
|
-
// ---------------------------------------------------------------------------
|
|
837
|
-
// Auto-update (cli-auto-update §4.1)
|
|
838
|
-
//
|
|
839
|
-
// The EIGHTH nested section in the persisted config, after `apiKeys`, `skills`,
|
|
840
|
-
// `log`, `team`, `todo`, `retry` and `fast` — and, like all of them, SCALARS
|
|
841
|
-
// ONLY, exactly one level deep. `store.ts` merges these sections BY HAND and
|
|
842
|
-
// that merge is only correct while nesting stays flat (C-5).
|
|
843
|
-
//
|
|
844
|
-
// BOTH OF `store.ts`'s MERGES MUST LEARN ABOUT THIS SECTION, AND THE OMISSION IS
|
|
845
|
-
// SILENT (C-4 / R-10). `config set update.mode notify` sends
|
|
846
|
-
// `{ update: { mode: 'notify' } }`; without the write merge the shallow
|
|
847
|
-
// top-level spread REPLACES the whole section and `checkIntervalMs`, `registry`
|
|
848
|
-
// and `distTag` silently revert on disk. This package has paid for that twice
|
|
849
|
-
// already — `todo` P0-1 and `fast` R-10 — which is why it is written down a
|
|
850
|
-
// third time rather than assumed to be common knowledge.
|
|
851
|
-
//
|
|
852
|
-
// FOUR KEYS AND NO MORE (D-16). `mode` covers on / notify / off; a fifth key
|
|
853
|
-
// (`autoInstall`) would be a second way to say the same thing, and two ways to
|
|
854
|
-
// express one setting is how they end up disagreeing.
|
|
855
|
-
// ---------------------------------------------------------------------------
|
|
856
|
-
/** `auto` installs; `notify` only reports; `off` disables the subsystem. */
|
|
857
|
-
export const UPDATE_MODES = ['auto', 'notify', 'off'];
|
|
858
|
-
export function isUpdateMode(v) {
|
|
859
|
-
return typeof v === 'string' && UPDATE_MODES.includes(v);
|
|
860
|
-
}
|
|
861
|
-
export const DEFAULT_UPDATE_CONFIG = {
|
|
862
|
-
mode: 'auto',
|
|
863
|
-
// FOUR HOURS, in ms. `checkIntervalMs` and not `checkIntervalHours` (D-17):
|
|
864
|
-
// every other duration in this config is in ms (`toolTimeoutMs`,
|
|
865
|
-
// `idleTimeoutMs`, `team.dispatchTimeoutMs`, `retry.initialDelayMs`), and one
|
|
866
|
-
// unit per file is worth more than one shorter number.
|
|
867
|
-
checkIntervalMs: 14_400_000,
|
|
868
|
-
registry: '',
|
|
869
|
-
distTag: 'latest',
|
|
870
|
-
};
|
|
871
|
-
/** 15 minutes to 7 days. The floor is a politeness bound on the registry. */
|
|
872
|
-
const UPDATE_INTERVAL_RANGE = { min: 900_000, max: 604_800_000 };
|
|
873
|
-
/** npm's own dist-tag grammar, loosely: no slashes, no spaces, no `@`. */
|
|
874
|
-
const DIST_TAG_RE = /^[a-z0-9][a-z0-9._-]{0,63}$/i;
|
|
875
|
-
/**
|
|
876
|
-
* THE single gate for every update-config read AND write, mirroring
|
|
877
|
-
* `clampSkillsConfig` / `clampLogConfig` / `clampTeamConfig` / `clampTodoConfig`
|
|
878
|
-
* / `clampRetryConfig` / `clampFastConfig` for the reason all six record:
|
|
879
|
-
* hardening only the read path leaves a bad value on disk that reverts to the
|
|
880
|
-
* default on every launch, which presents to the user as "my setting won't
|
|
881
|
-
* stick".
|
|
882
|
-
*
|
|
883
|
-
* `registry` is CLAMPED TO `''` rather than rejected when it is not an
|
|
884
|
-
* `http(s):` URL. `''` means "derive it" (§3.3), which is the safe reading of a
|
|
885
|
-
* typo — the alternative is a background timer that throws on a value the user
|
|
886
|
-
* cannot see it reading.
|
|
887
|
-
*/
|
|
888
|
-
export function clampUpdateConfig(raw) {
|
|
889
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
890
|
-
const registry = text(src.registry, DEFAULT_UPDATE_CONFIG.registry);
|
|
891
|
-
const distTag = text(src.distTag, DEFAULT_UPDATE_CONFIG.distTag);
|
|
892
|
-
return {
|
|
893
|
-
mode: isUpdateMode(src.mode) ? src.mode : DEFAULT_UPDATE_CONFIG.mode,
|
|
894
|
-
checkIntervalMs: clampInt(src.checkIntervalMs, DEFAULT_UPDATE_CONFIG.checkIntervalMs, UPDATE_INTERVAL_RANGE),
|
|
895
|
-
registry: isRegistryUrl(registry) ? registry : DEFAULT_UPDATE_CONFIG.registry,
|
|
896
|
-
distTag: DIST_TAG_RE.test(distTag) ? distTag : DEFAULT_UPDATE_CONFIG.distTag,
|
|
897
|
-
};
|
|
898
|
-
}
|
|
899
|
-
function isRegistryUrl(raw) {
|
|
900
|
-
if (raw.length === 0)
|
|
901
|
-
return false;
|
|
902
|
-
try {
|
|
903
|
-
const url = new URL(raw);
|
|
904
|
-
// `http:` is accepted for a LAN mirror; nothing else is a registry.
|
|
905
|
-
return url.protocol === 'https:' || url.protocol === 'http:';
|
|
906
|
-
}
|
|
907
|
-
catch {
|
|
908
|
-
return false;
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
export const DEFAULT_COMPACTION_CONFIG = {
|
|
912
|
-
enabled: true,
|
|
913
|
-
threshold: 0.9,
|
|
914
|
-
warnThreshold: 0.75,
|
|
915
|
-
keepRecentTurns: 4,
|
|
916
|
-
useFastTier: true,
|
|
917
|
-
onFailure: 'stop',
|
|
918
|
-
subagents: true,
|
|
919
|
-
archive: true,
|
|
920
|
-
};
|
|
921
|
-
const THRESHOLD_RANGE = { min: 0.5, max: 0.95 };
|
|
922
|
-
const WARN_THRESHOLD_FLOOR = 0.4;
|
|
923
|
-
/** The gap the warn mark must stay below the trigger by. */
|
|
924
|
-
const WARN_THRESHOLD_GAP = 0.05;
|
|
925
|
-
const KEEP_RECENT_TURNS_RANGE = { min: 1, max: 20 };
|
|
926
|
-
const COMPACTION_FAILURE_MODES = ['truncate', 'stop'];
|
|
927
|
-
/**
|
|
928
|
-
* Round a ratio to two decimals — the precision a percentage actually has.
|
|
929
|
-
*
|
|
930
|
-
* BINARY FLOATING POINT MAKES `0.95 - 0.05` EQUAL `0.8999999999999999`, and both
|
|
931
|
-
* numbers here are produced by subtraction (`threshold - WARN_THRESHOLD_GAP`) and
|
|
932
|
-
* by division (`parseThresholdInput` turning `90` into `90/100`). Without this,
|
|
933
|
-
* `aragon config list` shows a seventeen-digit value for a setting the user typed
|
|
934
|
-
* as `90%`, and `config.json` records one — which looks like corruption and
|
|
935
|
-
* invites a hand-edit that the clamp then has to defend against.
|
|
936
|
-
*
|
|
937
|
-
* Two decimals is exact for every value the range can hold: the clamp is
|
|
938
|
-
* `[0.5, 0.95]` and the UI reads it as a whole percentage.
|
|
939
|
-
*/
|
|
940
|
-
function ratio(value) {
|
|
941
|
-
return Math.round(value * 100) / 100;
|
|
942
|
-
}
|
|
943
|
-
function failureMode(value, fallback) {
|
|
944
|
-
return typeof value === 'string' && COMPACTION_FAILURE_MODES.includes(value)
|
|
945
|
-
? value
|
|
946
|
-
: fallback;
|
|
947
|
-
}
|
|
948
|
-
/**
|
|
949
|
-
* THE single gate for every compaction-config read AND write, mirroring the six
|
|
950
|
-
* clamps above for the reason all of them record: hardening only the read path
|
|
951
|
-
* leaves a bad value on disk that reverts to the default on every launch, which
|
|
952
|
-
* presents to the user as "my setting won't stick".
|
|
953
|
-
*
|
|
954
|
-
* THE ORDER IS FIXED AND IT MATTERS (§4.2 / P2-5). `threshold` is clamped to
|
|
955
|
-
* `[0.5, 0.95]` FIRST, then `warnThreshold` to
|
|
956
|
-
* `[0.4, clampedThreshold - 0.05]`. The other order lets a file holding
|
|
957
|
-
* `{threshold: 0.6, warnThreshold: 0.9}` produce a warn mark ABOVE the trigger —
|
|
958
|
-
* a gauge that turns amber after it has already gone red. Both bounds of the
|
|
959
|
-
* second range stay reachable at the extremes: `threshold` floored at `0.5`
|
|
960
|
-
* gives `warnThreshold` a range of `[0.4, 0.45]`.
|
|
961
|
-
*/
|
|
962
|
-
export function clampCompactionConfig(raw) {
|
|
963
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
964
|
-
const threshold = ratio(clampNumber(src.threshold, DEFAULT_COMPACTION_CONFIG.threshold, THRESHOLD_RANGE));
|
|
965
|
-
const warnCeiling = ratio(threshold - WARN_THRESHOLD_GAP);
|
|
966
|
-
return {
|
|
967
|
-
enabled: bool(src.enabled, DEFAULT_COMPACTION_CONFIG.enabled),
|
|
968
|
-
threshold,
|
|
969
|
-
warnThreshold: ratio(clampNumber(src.warnThreshold, DEFAULT_COMPACTION_CONFIG.warnThreshold, {
|
|
970
|
-
min: Math.min(WARN_THRESHOLD_FLOOR, warnCeiling),
|
|
971
|
-
max: warnCeiling,
|
|
972
|
-
})),
|
|
973
|
-
keepRecentTurns: clampInt(src.keepRecentTurns, DEFAULT_COMPACTION_CONFIG.keepRecentTurns, KEEP_RECENT_TURNS_RANGE),
|
|
974
|
-
useFastTier: bool(src.useFastTier, DEFAULT_COMPACTION_CONFIG.useFastTier),
|
|
975
|
-
// CLAMPED TO THE DEFAULT, NEVER REJECTED — the discipline every other key in
|
|
976
|
-
// this file follows. `ARAGON_COMPACTION_ON_FAILURE=garbage` resolves to
|
|
977
|
-
// `truncate` and throws nothing.
|
|
978
|
-
onFailure: failureMode(src.onFailure, DEFAULT_COMPACTION_CONFIG.onFailure),
|
|
979
|
-
subagents: bool(src.subagents, DEFAULT_COMPACTION_CONFIG.subagents),
|
|
980
|
-
archive: bool(src.archive, DEFAULT_COMPACTION_CONFIG.archive),
|
|
981
|
-
};
|
|
982
|
-
}
|
|
983
|
-
export const DEFAULT_BASH_CONFIG = {
|
|
984
|
-
background: true,
|
|
985
|
-
autoBackground: true,
|
|
986
|
-
startupSettleMs: 4000,
|
|
987
|
-
readyTimeoutMs: 60_000,
|
|
988
|
-
};
|
|
989
|
-
const STARTUP_SETTLE_RANGE = { min: 500, max: 30_000 };
|
|
990
|
-
const READY_TIMEOUT_RANGE = { min: 5_000, max: 600_000 };
|
|
991
|
-
/**
|
|
992
|
-
* THE single gate for every bash-config read AND write, mirroring
|
|
993
|
-
* `clampSkillsConfig` / `clampLogConfig` / `clampTeamConfig` / `clampTodoConfig`
|
|
994
|
-
* for the reason those record: hardening only the read path leaves a bad value
|
|
995
|
-
* on disk that reverts to the default on every launch, which presents to the
|
|
996
|
-
* user as "my setting won't stick".
|
|
997
|
-
*
|
|
998
|
-
* CLAMPED, NEVER REJECTED — the discipline every other key in this file follows.
|
|
999
|
-
* A garbage `startupSettleMs` resolves to 4000 and throws nothing.
|
|
1000
|
-
*/
|
|
1001
|
-
export function clampBashConfig(raw) {
|
|
1002
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
1003
|
-
return {
|
|
1004
|
-
background: bool(src.background, DEFAULT_BASH_CONFIG.background),
|
|
1005
|
-
autoBackground: bool(src.autoBackground, DEFAULT_BASH_CONFIG.autoBackground),
|
|
1006
|
-
startupSettleMs: clampInt(src.startupSettleMs, DEFAULT_BASH_CONFIG.startupSettleMs, STARTUP_SETTLE_RANGE),
|
|
1007
|
-
readyTimeoutMs: clampInt(src.readyTimeoutMs, DEFAULT_BASH_CONFIG.readyTimeoutMs, READY_TIMEOUT_RANGE),
|
|
1008
|
-
};
|
|
1009
|
-
}
|
|
1010
|
-
export const DEFAULT_JOBS_CONFIG = {
|
|
1011
|
-
enabled: true,
|
|
1012
|
-
waitSeconds: 30,
|
|
1013
|
-
stallSeconds: 300,
|
|
1014
|
-
persistLog: true,
|
|
1015
|
-
noticeSteer: true,
|
|
1016
|
-
};
|
|
1017
|
-
// DERIVED, NOT RESTATED (extended-job-wait I-2): a second copy of the ceiling is
|
|
1018
|
-
// how the config layer and the tool layer end up disagreeing without an error.
|
|
1019
|
-
const WAIT_SECONDS_RANGE = {
|
|
1020
|
-
min: PROC_LIMITS.waitMinSeconds,
|
|
1021
|
-
max: PROC_LIMITS.waitMaxSeconds,
|
|
1022
|
-
};
|
|
1023
|
-
const STALL_SECONDS_RANGE = { min: 30, max: 3600 };
|
|
1024
|
-
/**
|
|
1025
|
-
* THE single gate for every `jobs` read AND write, mirroring `clampBashConfig`
|
|
1026
|
-
* and the four sections before it.
|
|
1027
|
-
*
|
|
1028
|
-
* THE ELEVENTH SECTION, AND THE FIRST ONE THAT `config set` CAN REACH BY
|
|
1029
|
-
* NESTED KEY (§6.5). Every key is a SCALAR and the section is ONE level deep,
|
|
1030
|
-
* because `runConfigGet` splits on a single dot - a `jobs.mirror.enabled` would
|
|
1031
|
-
* resolve to `undefined` and the setting would silently never apply.
|
|
1032
|
-
*/
|
|
1033
|
-
export function clampJobsConfig(raw) {
|
|
1034
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
1035
|
-
return {
|
|
1036
|
-
enabled: bool(src.enabled, DEFAULT_JOBS_CONFIG.enabled),
|
|
1037
|
-
waitSeconds: clampInt(src.waitSeconds, DEFAULT_JOBS_CONFIG.waitSeconds, WAIT_SECONDS_RANGE),
|
|
1038
|
-
stallSeconds: clampInt(src.stallSeconds, DEFAULT_JOBS_CONFIG.stallSeconds, STALL_SECONDS_RANGE),
|
|
1039
|
-
persistLog: bool(src.persistLog, DEFAULT_JOBS_CONFIG.persistLog),
|
|
1040
|
-
noticeSteer: bool(src.noticeSteer, DEFAULT_JOBS_CONFIG.noticeSteer),
|
|
1041
|
-
};
|
|
1042
|
-
}
|
|
1043
|
-
export const DEFAULT_PROMPTS_CONFIG = {
|
|
1044
|
-
enabled: true,
|
|
1045
|
-
insertMode: 'insert',
|
|
1046
|
-
};
|
|
1047
|
-
const PROMPT_INSERT_MODES = ['insert', 'replace'];
|
|
1048
|
-
/**
|
|
1049
|
-
* THE single gate for every `prompts` read AND write, like the eleven sections
|
|
1050
|
-
* above it.
|
|
1051
|
-
*
|
|
1052
|
-
* An unrecognized `insertMode` falls back to `insert` rather than to `replace`,
|
|
1053
|
-
* and that direction is deliberate: a typo must never silently start DISCARDING
|
|
1054
|
-
* what the user has already typed into the composer.
|
|
1055
|
-
*/
|
|
1056
|
-
export function clampPromptsConfig(raw) {
|
|
1057
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
1058
|
-
const mode = typeof src.insertMode === 'string' ? src.insertMode.trim().toLowerCase() : '';
|
|
1059
|
-
return {
|
|
1060
|
-
enabled: bool(src.enabled, DEFAULT_PROMPTS_CONFIG.enabled),
|
|
1061
|
-
insertMode: PROMPT_INSERT_MODES.includes(mode)
|
|
1062
|
-
? mode
|
|
1063
|
-
: DEFAULT_PROMPTS_CONFIG.insertMode,
|
|
1064
|
-
};
|
|
1065
|
-
}
|
|
1066
|
-
export const DEFAULT_TASK_SUMMARY_CONFIG = {
|
|
1067
|
-
enabled: true,
|
|
1068
|
-
fallback: true,
|
|
1069
|
-
};
|
|
1070
|
-
/**
|
|
1071
|
-
* THE single gate for every `taskSummary` read AND write, like the twelve sections
|
|
1072
|
-
* above it.
|
|
1073
|
-
*
|
|
1074
|
-
* BOTH DEFAULTS ARE `true`, AND THE DIRECTION MATTERS: a corrupt or hand-edited
|
|
1075
|
-
* section must not silently switch off a feature the user asked for, and - more
|
|
1076
|
-
* importantly - it must not switch off the FLOOR, which is the only thing standing
|
|
1077
|
-
* between a failed call and an empty header cell.
|
|
1078
|
-
*/
|
|
1079
|
-
export function clampTaskSummaryConfig(raw) {
|
|
1080
|
-
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
1081
|
-
return {
|
|
1082
|
-
enabled: bool(src.enabled, DEFAULT_TASK_SUMMARY_CONFIG.enabled),
|
|
1083
|
-
fallback: bool(src.fallback, DEFAULT_TASK_SUMMARY_CONFIG.fallback),
|
|
1084
|
-
};
|
|
1085
|
-
}
|
|
1086
|
-
/**
|
|
1087
|
-
* Parse `0.9`, `90%` or `90` into a ratio, or `null` when it is neither.
|
|
1088
|
-
*
|
|
1089
|
-
* `null` RATHER THAN A CLAMPED DEFAULT, because this is a COMMAND argument and
|
|
1090
|
-
* not a config value: `/compact threshold banana` must say so rather than
|
|
1091
|
-
* silently setting 0.9 and reporting success.
|
|
1092
|
-
*/
|
|
1093
|
-
export function parseThresholdInput(raw) {
|
|
1094
|
-
const trimmed = raw.trim().replace(/%$/, '');
|
|
1095
|
-
if (trimmed.length === 0)
|
|
1096
|
-
return null;
|
|
1097
|
-
const n = Number.parseFloat(trimmed);
|
|
1098
|
-
if (!Number.isFinite(n))
|
|
1099
|
-
return null;
|
|
1100
|
-
// `90` means 90 %, `0.9` means 0.9. The ambiguity is only at `1`, which is
|
|
1101
|
-
// above the clamp ceiling either way.
|
|
1102
|
-
const ratio = n > 1 ? n / 100 : n;
|
|
1103
|
-
if (ratio <= 0 || ratio > 1)
|
|
1104
|
-
return null;
|
|
1105
|
-
return ratio;
|
|
1106
|
-
}
|
|
1107
|
-
export const DEFAULT_CONFIG = {
|
|
1108
|
-
version: CONFIG_VERSION,
|
|
1109
|
-
provider: 'anthropic',
|
|
1110
|
-
model: DEFAULT_MODEL,
|
|
1111
|
-
baseUrl: null,
|
|
1112
|
-
thinkingLevel: 'off',
|
|
1113
|
-
// Off by default — the product default this whole round exists to establish
|
|
1114
|
-
// (D-1). One config key restores the old behaviour permanently.
|
|
1115
|
-
showThinking: false,
|
|
1116
|
-
// ON by default (D-28), and the OPPOSITE of the key above it on purpose: this
|
|
1117
|
-
// one shows work that is otherwise invisible for the whole duration of the
|
|
1118
|
-
// most expensive thing the agent does.
|
|
1119
|
-
liveToolOutput: true,
|
|
1120
|
-
// The engine owns this number; spelling it here again is how the CLI and the
|
|
1121
|
-
// provider adapters end up disagreeing about what "the default" is.
|
|
1122
|
-
maxTokens: DEFAULT_MAX_OUTPUT_TOKENS,
|
|
1123
|
-
// AUTO. The model table is right for every listed model, and a default number
|
|
1124
|
-
// here would be the same fabricated denominator this key exists to correct.
|
|
1125
|
-
contextWindow: null,
|
|
1126
|
-
theme: 'auto',
|
|
1127
|
-
reducedMotion: false,
|
|
1128
|
-
exitTranscript: true,
|
|
1129
|
-
transcriptWindow: DEFAULT_TRANSCRIPT_WINDOW,
|
|
1130
|
-
transcriptRetain: DEFAULT_TRANSCRIPT_RETAIN,
|
|
1131
|
-
renderGovernor: DEFAULT_RENDER_GOVERNOR,
|
|
1132
|
-
maxRenderIntervalMs: DEFAULT_MAX_RENDER_INTERVAL_MS,
|
|
1133
|
-
diffRender: DEFAULT_DIFF_RENDER,
|
|
1134
|
-
scrollMode: DEFAULT_SCROLL_MODE,
|
|
1135
|
-
syncOutput: DEFAULT_SYNC_OUTPUT,
|
|
1136
|
-
confirmTools: false,
|
|
1137
|
-
toolTimeoutMs: DEFAULT_TOOL_TIMEOUT_MS,
|
|
1138
|
-
idleTimeoutMs: DEFAULT_IDLE_TIMEOUT_MS,
|
|
1139
|
-
apiKeys: {},
|
|
1140
|
-
historyEnabled: true,
|
|
1141
|
-
density: 'comfortable',
|
|
1142
|
-
hints: true,
|
|
1143
|
-
mouse: true,
|
|
1144
|
-
mouseSelect: DEFAULT_MOUSE_SELECT,
|
|
1145
|
-
paste: true,
|
|
1146
|
-
keyboardEnhancement: true,
|
|
1147
|
-
scrollResumeMs: DEFAULT_SCROLL_RESUME_MS,
|
|
1148
|
-
planModeDefault: false,
|
|
1149
|
-
planModeHumanTimeoutMs: DEFAULT_PLAN_HUMAN_TIMEOUT_MS,
|
|
1150
|
-
skills: DEFAULT_SKILLS_CONFIG,
|
|
1151
|
-
log: DEFAULT_LOG_CONFIG,
|
|
1152
|
-
team: DEFAULT_TEAM_CONFIG,
|
|
1153
|
-
// The load path's first spread is what supplies the section to a user with no
|
|
1154
|
-
// `todo` key at all, so this line is as required as the two merges in
|
|
1155
|
-
// `store.ts` (P0-1).
|
|
1156
|
-
todo: DEFAULT_TODO_CONFIG,
|
|
1157
|
-
// Same requirement one section later: without this line a user with no `retry`
|
|
1158
|
-
// key resolves `config.retry` to `undefined` and `toRetryPolicy` throws.
|
|
1159
|
-
retry: DEFAULT_RETRY_CONFIG,
|
|
1160
|
-
// And one section later again: the load path's first spread is what supplies
|
|
1161
|
-
// `fast` to a user whose `config.json` predates this feature, which is every
|
|
1162
|
-
// existing user. Without it `config.fast.enabled` reads `undefined`, which is
|
|
1163
|
-
// falsy and so LOOKS correct — right up until `/fast on` writes a section that
|
|
1164
|
-
// has no other keys in it (P0-1's shape, one feature later).
|
|
1165
|
-
fast: DEFAULT_FAST_CONFIG,
|
|
1166
|
-
// And one section later again, for the third time. Without this line a user
|
|
1167
|
-
// whose `config.json` predates auto-update resolves `config.update.mode` to
|
|
1168
|
-
// `undefined`, which is neither `'auto'` nor `'off'` — so the §3.8 gate
|
|
1169
|
-
// (`cfg.update.mode !== 'off'`) would read TRUE and the feature would be on
|
|
1170
|
-
// for a reason nobody could point at.
|
|
1171
|
-
update: DEFAULT_UPDATE_CONFIG,
|
|
1172
|
-
// And one section later again, for the fourth time. Without this line a user
|
|
1173
|
-
// whose `config.json` predates compaction resolves `config.compaction.enabled`
|
|
1174
|
-
// to `undefined`, which is FALSY — so a feature that is `true` by default would
|
|
1175
|
-
// arrive OFF for every existing user, which is the one direction this
|
|
1176
|
-
// particular default must never fail in.
|
|
1177
|
-
compaction: DEFAULT_COMPACTION_CONFIG,
|
|
1178
|
-
// And one section later again, for the fifth time. `bash.background` is `true`
|
|
1179
|
-
// by default, so a `config.json` predating this feature resolving it to
|
|
1180
|
-
// `undefined` would arrive with background services OFF for every existing
|
|
1181
|
-
// user — the same direction the compaction line above must never fail in.
|
|
1182
|
-
bash: DEFAULT_BASH_CONFIG,
|
|
1183
|
-
// And one section later again, for the sixth time, and this one would fail
|
|
1184
|
-
// in the WORSE direction: every key in `jobs` is `true` or positive by
|
|
1185
|
-
// default, so a `config.json` predating this feature resolving `config.jobs`
|
|
1186
|
-
// to `undefined` would throw on `config.jobs.waitSeconds` at construction
|
|
1187
|
-
// rather than quietly disabling something.
|
|
1188
|
-
jobs: DEFAULT_JOBS_CONFIG,
|
|
1189
|
-
// And one section later again, for the seventh time, and this one has BOTH
|
|
1190
|
-
// failure directions at once: `prompts.enabled` is `true` by default, so a
|
|
1191
|
-
// `config.json` predating this feature would resolve it to `undefined` (falsy)
|
|
1192
|
-
// and arrive with the key silently off - while
|
|
1193
|
-
// `prompts.insertMode` would be `undefined`, which is neither `'insert'` nor
|
|
1194
|
-
// `'replace'` and would make `planPromptFill` fall through to its `replace`
|
|
1195
|
-
// branch. That branch discards the user's own words, so the miss would be a data
|
|
1196
|
-
// loss rather than a missing hint.
|
|
1197
|
-
prompts: DEFAULT_PROMPTS_CONFIG,
|
|
1198
|
-
// And one section later again, for the eighth time - and this one has a silent
|
|
1199
|
-
// DATA-LOSS-shaped miss: `taskSummary.enabled` and `.fallback` are both `true` by
|
|
1200
|
-
// default, and `App` reads `cfg.taskSummary?.fallback !== false` at call time. A
|
|
1201
|
-
// `config.json` predating this feature would resolve them to `undefined`, which
|
|
1202
|
-
// happens to behave like the defaults in those two readers but NOT in
|
|
1203
|
-
// `config list`, so the file would report a section it never wrote. One line
|
|
1204
|
-
// here, like the seven above it.
|
|
1205
|
-
taskSummary: DEFAULT_TASK_SUMMARY_CONFIG,
|
|
1206
|
-
// And one section later again. Without this line a `config.json` predating governance
|
|
1207
|
-
// resolves `governance` to `undefined`; every reader would then disagree with `config list`.
|
|
1208
|
-
governance: DEFAULT_GOVERNANCE_CONFIG,
|
|
1209
|
-
};
|
|
1210
|
-
/**
|
|
1211
|
-
* Runtime state that used to be stored in `config.json` by mistake
|
|
1212
|
-
* (config-state-separation §4.5). Each one now lives in its own file:
|
|
1213
|
-
* `promptHistory` → `prompt-history.jsonl`, `submitCount` / `mouseNoticeSeen`
|
|
1214
|
-
* → `state.json`, and `recentModels` was dead — nothing ever wrote it.
|
|
1215
|
-
*/
|
|
1216
|
-
export const LEGACY_STATE_KEYS = [
|
|
1217
|
-
'promptHistory',
|
|
1218
|
-
'submitCount',
|
|
1219
|
-
'mouseNoticeSeen',
|
|
1220
|
-
'recentModels',
|
|
1221
|
-
];
|
|
1222
|
-
/**
|
|
1223
|
-
* THE single gate that keeps those keys out of `config.json`, and the one thing
|
|
1224
|
-
* in this change that cannot be skipped.
|
|
1225
|
-
*
|
|
1226
|
-
* `loadPersistedConfig()` merges `{ ...DEFAULT_CONFIG, ...partial }` where
|
|
1227
|
-
* `partial` is the raw parse of whatever is on disk. Removing the fields from
|
|
1228
|
-
* the interface therefore removes NOTHING from the file: the keys ride through
|
|
1229
|
-
* the spread and `updatePersistedConfig` writes them straight back. The user
|
|
1230
|
-
* deletes `promptHistory` by hand and watches it grow back.
|
|
1231
|
-
*
|
|
1232
|
-
* Applied on the READ side on purpose, which is what makes it self-healing:
|
|
1233
|
-
* every write goes read-strip-merge-write, so a hand-edited file, a downgrade
|
|
1234
|
-
* to 0.5.x and back, or a half-finished migration all converge on a clean file
|
|
1235
|
-
* at the next write. Same shape as `clampSkillsConfig` / `clampLogConfig` —
|
|
1236
|
-
* one door for both directions.
|
|
1237
|
-
*/
|
|
1238
|
-
export function stripLegacyStateKeys(raw) {
|
|
1239
|
-
const out = { ...raw };
|
|
1240
|
-
for (const key of LEGACY_STATE_KEYS)
|
|
1241
|
-
delete out[key];
|
|
1242
|
-
return out;
|
|
1243
|
-
}
|
|
1244
|
-
/**
|
|
1245
|
-
* Config keys whose MEANING was removed, mapped to the explanation a user gets if
|
|
1246
|
-
* they still try to set one.
|
|
1247
|
-
*
|
|
1248
|
-
* SEPARATE FROM `LEGACY_STATE_KEYS`, because the disposition differs: those keys'
|
|
1249
|
-
* values were MOVED somewhere else, while these have nowhere to go — the feature
|
|
1250
|
-
* they configured no longer exists. Merging the two lists would erase that
|
|
1251
|
-
* difference at exactly the moment someone is reading the file to find out what
|
|
1252
|
-
* happened to their setting.
|
|
1253
|
-
*
|
|
1254
|
-
* Stripped on the READ side for the same reason `stripLegacyStateKeys` is:
|
|
1255
|
-
* `loadPersistedConfig()` merges `{ ...DEFAULT_CONFIG, ...partial }`, so a key
|
|
1256
|
-
* left on disk rides that spread into memory and `updatePersistedConfig` writes it
|
|
1257
|
-
* straight back. The user deletes the line, launches once, and watches it return.
|
|
1258
|
-
*/
|
|
1259
|
-
export const RETIRED_CONFIG_KEYS = {
|
|
1260
|
-
planModeMaxAskRounds: 'ask_user has no round limit any more, so this key is gone. Nothing to set; ' +
|
|
1261
|
-
'the next config write removes it from config.json.',
|
|
1262
|
-
};
|
|
1263
|
-
/**
|
|
1264
|
-
* THE single gate that keeps retired keys out of `config.json`. Applied on the
|
|
1265
|
-
* read side, so it is self-healing: every write is read-strip-merge-write, and a
|
|
1266
|
-
* hand-edited file, a downgrade to an older CLI and back, or a half-finished
|
|
1267
|
-
* migration all converge on a clean file at the next write.
|
|
1268
|
-
*/
|
|
1269
|
-
export function stripRetiredConfigKeys(raw) {
|
|
1270
|
-
const out = { ...raw };
|
|
1271
|
-
for (const key of Object.keys(RETIRED_CONFIG_KEYS))
|
|
1272
|
-
delete out[key];
|
|
1273
|
-
return out;
|
|
1274
|
-
}
|
|
1275
|
-
// ---------------------------------------------------------------------------
|
|
1276
|
-
// Coercion / validation helpers
|
|
1277
|
-
// ---------------------------------------------------------------------------
|
|
1278
|
-
/** Coerce an arbitrary value into a positive integer, or `undefined`. */
|
|
1279
|
-
function coerceTokenCount(v) {
|
|
1280
|
-
if (v === null || v === undefined || v === '')
|
|
1281
|
-
return undefined;
|
|
1282
|
-
const n = typeof v === 'number' ? v : Number.parseInt(String(v), 10);
|
|
1283
|
-
if (!Number.isFinite(n) || n <= 0)
|
|
1284
|
-
return undefined;
|
|
1285
|
-
return Math.floor(n);
|
|
1286
|
-
}
|
|
1287
|
-
/**
|
|
1288
|
-
* Coerce an arbitrary value into a positive integer, or `undefined`.
|
|
1289
|
-
*
|
|
1290
|
-
* Kept because callers outside this feature still use it, and deliberately
|
|
1291
|
-
* WITHOUT the range clamp so its behaviour for in-range values is byte-identical
|
|
1292
|
-
* to what it always was. New code wants `clampMaxTokens`.
|
|
1293
|
-
*/
|
|
1294
|
-
export function coerceMaxTokens(v) {
|
|
1295
|
-
return coerceTokenCount(v);
|
|
1296
|
-
}
|
|
1297
|
-
/**
|
|
1298
|
-
* The accepted range for an explicit output cap.
|
|
1299
|
-
*
|
|
1300
|
-
* The floor is the engine's: below it a turn cannot produce a usable tool call.
|
|
1301
|
-
* The ceiling is a sanity bound on a hand-edited file, not a model limit — the
|
|
1302
|
-
* real per-model ceiling is applied later, by `resolveOutputTokens`.
|
|
1303
|
-
*/
|
|
1304
|
-
export const MAX_TOKENS_RANGE = {
|
|
1305
|
-
min: MIN_MAX_OUTPUT_TOKENS,
|
|
1306
|
-
max: ABSOLUTE_MAX_OUTPUT_TOKENS,
|
|
1307
|
-
};
|
|
1308
|
-
/** `auto`, an empty string and `0` all mean AUTO — "let the model decide". */
|
|
1309
|
-
export function isAutoToken(v) {
|
|
1310
|
-
if (v === 0)
|
|
1311
|
-
return true;
|
|
1312
|
-
if (typeof v !== 'string')
|
|
1313
|
-
return false;
|
|
1314
|
-
const trimmed = v.trim().toLowerCase();
|
|
1315
|
-
return trimmed === '' || trimmed === 'auto' || trimmed === '0';
|
|
1316
|
-
}
|
|
1317
|
-
/**
|
|
1318
|
-
* THE single gate for every `maxTokens` read AND write, in the shape
|
|
1319
|
-
* `clampSkillsConfig` / `clampLogConfig` / `clampTeamConfig` already use.
|
|
1320
|
-
*
|
|
1321
|
-
* Both directions on purpose: hardening only the read path leaves a bad value on
|
|
1322
|
-
* disk that reverts to a default on every launch, which presents to the user as
|
|
1323
|
-
* "my setting won't stick".
|
|
1324
|
-
*
|
|
1325
|
-
* Returns `undefined` for AUTO and for anything unusable — the caller decides
|
|
1326
|
-
* which of the two it was, because they mean different things.
|
|
1327
|
-
*/
|
|
1328
|
-
export function clampMaxTokens(v) {
|
|
1329
|
-
const n = coerceTokenCount(v);
|
|
1330
|
-
if (n === undefined)
|
|
1331
|
-
return undefined;
|
|
1332
|
-
return Math.min(MAX_TOKENS_RANGE.max, Math.max(MAX_TOKENS_RANGE.min, n));
|
|
1333
|
-
}
|
|
1334
|
-
/**
|
|
1335
|
-
* Parse text typed into the settings screen, a slash command, or `config set`.
|
|
1336
|
-
*
|
|
1337
|
-
* Distinguishes AUTO from "the user typed nonsense", which `clampMaxTokens`
|
|
1338
|
-
* cannot: both come back as `undefined` there, and treating a typo as AUTO would
|
|
1339
|
-
* silently discard the number the user meant to set.
|
|
1340
|
-
*/
|
|
1341
|
-
export function parseMaxTokensInput(raw) {
|
|
1342
|
-
const trimmed = String(raw ?? '').trim();
|
|
1343
|
-
if (isAutoToken(trimmed))
|
|
1344
|
-
return { kind: 'auto' };
|
|
1345
|
-
if (!/^\d+$/.test(trimmed))
|
|
1346
|
-
return { kind: 'invalid' };
|
|
1347
|
-
const parsed = Number.parseInt(trimmed, 10);
|
|
1348
|
-
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
1349
|
-
return { kind: 'invalid' };
|
|
1350
|
-
const value = Math.min(MAX_TOKENS_RANGE.max, Math.max(MAX_TOKENS_RANGE.min, parsed));
|
|
1351
|
-
return { kind: 'value', value, clamped: value !== parsed };
|
|
1352
|
-
}
|
|
1353
|
-
/** The product default, re-exported so the CLI never spells the number itself. */
|
|
1354
|
-
export const DEFAULT_MAX_TOKENS = DEFAULT_MAX_OUTPUT_TOKENS;
|
|
1355
|
-
/** Coerce a value into a positive integer with a fallback (for timeouts). */
|
|
1356
|
-
export function coercePositiveInt(v, fallback) {
|
|
1357
|
-
if (v === null || v === undefined || v === '')
|
|
1358
|
-
return fallback;
|
|
1359
|
-
const n = typeof v === 'number' ? v : Number.parseInt(String(v), 10);
|
|
1360
|
-
if (!Number.isFinite(n) || n <= 0)
|
|
1361
|
-
return fallback;
|
|
1362
|
-
return Math.floor(n);
|
|
1363
|
-
}
|
|
1364
|
-
/**
|
|
1365
|
-
* Mask a secret for display: keep a short prefix + suffix, redact the middle.
|
|
1366
|
-
* A short/empty key is fully redacted so the length is not leaked.
|
|
1367
|
-
*
|
|
1368
|
-
* The glyphs are parameters with ASCII defaults (spec §4.1 tier B). This module
|
|
1369
|
-
* has no terminal capabilities to consult, and the result is rendered in the
|
|
1370
|
-
* settings screen — which on a legacy `cmd.exe` used to show two question-mark
|
|
1371
|
-
* boxes where the redaction dots belonged. The UI passes its resolved glyphs;
|
|
1372
|
-
* every other caller gets output that is safe anywhere.
|
|
1373
|
-
*/
|
|
1374
|
-
export function maskSecret(key, opts = {}) {
|
|
1375
|
-
const maskChar = opts.maskChar ?? '*';
|
|
1376
|
-
const ellipsis = opts.ellipsis ?? '...';
|
|
1377
|
-
if (!key)
|
|
1378
|
-
return '(not set)';
|
|
1379
|
-
const trimmed = key.trim();
|
|
1380
|
-
if (trimmed.length <= 8)
|
|
1381
|
-
return maskChar.repeat(4);
|
|
1382
|
-
return `${trimmed.slice(0, 3)}${ellipsis}${trimmed.slice(-4)}`;
|
|
1383
|
-
}
|