@aragon-agent/cli 0.6.2 → 0.6.4
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 +321 -0
- package/README.md +297 -2
- package/dist/agent/controller.d.ts +193 -1
- package/dist/agent/controller.js +475 -2
- package/dist/agent/headless.d.ts +8 -0
- package/dist/agent/headless.js +47 -0
- package/dist/agent/reducer.d.ts +189 -0
- package/dist/agent/reducer.js +301 -2
- package/dist/agent/system-prompt.d.ts +14 -0
- package/dist/agent/system-prompt.js +2 -0
- package/dist/cli.js +297 -16
- package/dist/commands/builtins.js +165 -24
- package/dist/commands/registry.d.ts +27 -0
- package/dist/compaction/archive.d.ts +175 -0
- package/dist/compaction/archive.js +267 -0
- package/dist/compaction/child.d.ts +97 -0
- package/dist/compaction/child.js +118 -0
- package/dist/compaction/command.d.ts +41 -0
- package/dist/compaction/command.js +355 -0
- package/dist/compaction/compactor.d.ts +302 -0
- package/dist/compaction/compactor.js +810 -0
- package/dist/compaction/digest.d.ts +62 -0
- package/dist/compaction/digest.js +164 -0
- package/dist/compaction/limits.d.ts +165 -0
- package/dist/compaction/limits.js +172 -0
- package/dist/compaction/pressure.d.ts +135 -0
- package/dist/compaction/pressure.js +167 -0
- package/dist/compaction/summarize-call.d.ts +70 -0
- package/dist/compaction/summarize-call.js +86 -0
- package/dist/compaction/summary-prompt.d.ts +85 -0
- package/dist/compaction/summary-prompt.js +197 -0
- package/dist/compaction/tail-budget.d.ts +52 -0
- package/dist/compaction/tail-budget.js +67 -0
- package/dist/compaction/types.d.ts +215 -0
- package/dist/compaction/types.js +22 -0
- package/dist/compaction/wiring.d.ts +264 -0
- package/dist/compaction/wiring.js +577 -0
- package/dist/config/app-paths.d.ts +14 -0
- package/dist/config/app-paths.js +16 -0
- package/dist/config/cli-commands.d.ts +41 -0
- package/dist/config/cli-commands.js +77 -1
- package/dist/config/env.d.ts +5 -2
- package/dist/config/env.js +140 -3
- package/dist/config/load.d.ts +42 -0
- package/dist/config/load.js +101 -1
- package/dist/config/schema.d.ts +244 -0
- package/dist/config/schema.js +170 -0
- package/dist/config/store.js +37 -1
- package/dist/config/ui-state.d.ts +28 -1
- package/dist/config/ui-state.js +9 -0
- package/dist/exec/events.d.ts +50 -1
- package/dist/exec/runner.js +42 -0
- package/dist/input/limits.d.ts +72 -0
- package/dist/input/limits.js +63 -0
- package/dist/input/mouse-events.d.ts +31 -5
- package/dist/input/mouse-events.js +86 -27
- package/dist/input/paste-parse.d.ts +71 -0
- package/dist/input/paste-parse.js +95 -0
- package/dist/input/stdin-filter.d.ts +81 -0
- package/dist/input/stdin-filter.js +379 -0
- package/dist/logging/install.d.ts +53 -1
- package/dist/logging/install.js +81 -1
- package/dist/logging/logger.d.ts +1 -1
- package/dist/proc/classify.d.ts +52 -0
- package/dist/proc/classify.js +143 -0
- package/dist/proc/kill-tree.d.ts +42 -0
- package/dist/proc/kill-tree.js +119 -0
- package/dist/proc/limits.d.ts +84 -0
- package/dist/proc/limits.js +84 -0
- package/dist/proc/log-ring.d.ts +68 -0
- package/dist/proc/log-ring.js +102 -0
- package/dist/proc/prompt.d.ts +24 -0
- package/dist/proc/prompt.js +49 -0
- package/dist/proc/readiness.d.ts +102 -0
- package/dist/proc/readiness.js +219 -0
- package/dist/proc/supervisor.d.ts +103 -0
- package/dist/proc/supervisor.js +465 -0
- package/dist/proc/types.d.ts +175 -0
- package/dist/proc/types.js +15 -0
- package/dist/session/persist.js +55 -1
- package/dist/team/report.js +7 -1
- package/dist/team/runtime.d.ts +10 -0
- package/dist/team/runtime.js +7 -0
- package/dist/team/subagent.d.ts +31 -1
- package/dist/team/subagent.js +42 -15
- package/dist/team/types.d.ts +8 -0
- package/dist/tools/bash-tool.d.ts +51 -2
- package/dist/tools/bash-tool.js +321 -51
- package/dist/tools/fs-tools.d.ts +17 -0
- package/dist/tools/index.d.ts +55 -2
- package/dist/tools/index.js +39 -1
- package/dist/tools/proc-tools.d.ts +25 -0
- package/dist/tools/proc-tools.js +102 -0
- package/dist/ui/ActivityLine.d.ts +19 -1
- package/dist/ui/ActivityLine.js +10 -2
- package/dist/ui/App.d.ts +62 -2
- package/dist/ui/App.js +546 -16
- package/dist/ui/Composer.d.ts +66 -1
- package/dist/ui/Composer.js +50 -6
- package/dist/ui/PromptInput.d.ts +82 -3
- package/dist/ui/PromptInput.js +232 -49
- package/dist/ui/StatusBar.d.ts +59 -0
- package/dist/ui/StatusBar.js +16 -4
- package/dist/ui/TeamPanel.js +7 -1
- package/dist/ui/Transcript.d.ts +21 -1
- package/dist/ui/Transcript.js +61 -3
- package/dist/ui/clipboard.d.ts +52 -0
- package/dist/ui/clipboard.js +91 -0
- package/dist/ui/composer-limits.d.ts +31 -0
- package/dist/ui/composer-limits.js +50 -0
- package/dist/ui/composer-rows.d.ts +73 -0
- package/dist/ui/composer-rows.js +201 -0
- package/dist/ui/editor-reducer.d.ts +37 -0
- package/dist/ui/editor-reducer.js +88 -12
- package/dist/ui/entries/CompactionCard.d.ts +75 -0
- package/dist/ui/entries/CompactionCard.js +158 -0
- package/dist/ui/entries/ServiceCard.d.ts +66 -0
- package/dist/ui/entries/ServiceCard.js +116 -0
- package/dist/ui/entries/UserEntry.d.ts +17 -3
- package/dist/ui/entries/UserEntry.js +34 -5
- package/dist/ui/frame-differ.d.ts +46 -0
- package/dist/ui/frame-differ.js +94 -10
- package/dist/ui/gauge.d.ts +16 -1
- package/dist/ui/gauge.js +25 -6
- package/dist/ui/glyphs.d.ts +11 -0
- package/dist/ui/glyphs.js +2 -0
- package/dist/ui/layout/ScrollViewport.d.ts +43 -6
- package/dist/ui/layout/ScrollViewport.js +128 -21
- package/dist/ui/layout/budget.d.ts +44 -9
- package/dist/ui/layout/budget.js +42 -10
- package/dist/ui/layout/follow-state.d.ts +137 -0
- package/dist/ui/layout/follow-state.js +150 -0
- package/dist/ui/layout/virtual-window.d.ts +11 -0
- package/dist/ui/layout/virtual-window.js +85 -1
- package/dist/ui/overlays/HelpOverlay.js +9 -1
- package/dist/ui/overlays/PlanReviewOverlay.js +10 -2
- package/dist/ui/overlays/QuestionOverlay.js +5 -1
- package/dist/ui/overlays/SettingsScreen.d.ts +47 -1
- package/dist/ui/overlays/SettingsScreen.js +74 -2
- package/dist/ui/palettes.d.ts +16 -0
- package/dist/ui/palettes.js +6 -0
- package/dist/ui/paste-frames.d.ts +87 -0
- package/dist/ui/paste-frames.js +112 -0
- package/dist/ui/paste-tokens.d.ts +90 -0
- package/dist/ui/paste-tokens.js +147 -0
- package/dist/ui/screen.d.ts +38 -0
- package/dist/ui/screen.js +113 -8
- package/dist/ui/selection/highlight.d.ts +39 -0
- package/dist/ui/selection/highlight.js +64 -0
- package/dist/ui/selection/screen-mirror.d.ts +24 -0
- package/dist/ui/selection/screen-mirror.js +35 -0
- package/dist/ui/selection/selection-controller.d.ts +88 -0
- package/dist/ui/selection/selection-controller.js +282 -0
- package/dist/ui/selection/selection.d.ts +90 -0
- package/dist/ui/selection/selection.js +223 -0
- package/dist/ui/stdout-frame-writer.d.ts +33 -0
- package/dist/ui/stdout-frame-writer.js +15 -0
- package/dist/ui/theme.d.ts +11 -0
- package/dist/ui/theme.js +2 -0
- package/dist/ui/transcript-text.js +72 -0
- package/dist/ui/use-startup-notices.d.ts +27 -1
- package/dist/ui/use-startup-notices.js +43 -11
- package/dist/ui/use-wheel-routing.d.ts +1 -1
- package/dist/ui/use-wheel-routing.js +8 -0
- package/package.json +4 -2
- package/dist/input/stdin-mouse-filter.d.ts +0 -42
- package/dist/input/stdin-mouse-filter.js +0 -153
package/dist/config/schema.d.ts
CHANGED
|
@@ -115,6 +115,36 @@ export declare const DEFAULT_DIFF_RENDER = true;
|
|
|
115
115
|
* because the frame differ already removes the flicker on its own.
|
|
116
116
|
*/
|
|
117
117
|
export declare const DEFAULT_SYNC_OUTPUT = true;
|
|
118
|
+
/**
|
|
119
|
+
* Drag-select + copy, and — because §4.4.1 gates `\x1b[?1002h` on exactly this
|
|
120
|
+
* value — whether motion reporting is requested from the terminal at all.
|
|
121
|
+
*
|
|
122
|
+
* That gating is what makes `false` BYTE-IDENTICAL to a pre-feature session
|
|
123
|
+
* rather than merely equivalent (AC-8 / D-15). Ignored when `mouse` is false,
|
|
124
|
+
* since there is no capture to select with.
|
|
125
|
+
*/
|
|
126
|
+
export declare const DEFAULT_MOUSE_SELECT = true;
|
|
127
|
+
/**
|
|
128
|
+
* Idle delay before a paused viewport returns to the newest line, in ms.
|
|
129
|
+
*
|
|
130
|
+
* Five seconds is chosen to be LONGER than a glance and SHORTER than a read.
|
|
131
|
+
* `0` disables auto-resume entirely, and it is a real value rather than a
|
|
132
|
+
* sentinel-shaped default: `shouldArmResume` refuses on it before any timer is
|
|
133
|
+
* created (AC-9), so the revert for Rule B is one config key.
|
|
134
|
+
*
|
|
135
|
+
* NO CLI FLAG (§6.1). It is a comfort preference, set once
|
|
136
|
+
* (`aragon config set scrollResumeMs 8000`) and then forgotten — the same
|
|
137
|
+
* argument this file already makes for `historyEnabled`. Adding a flag for every
|
|
138
|
+
* scalar is how a CLI ends up with sixty of them.
|
|
139
|
+
*/
|
|
140
|
+
export declare const DEFAULT_SCROLL_RESUME_MS = 5000;
|
|
141
|
+
/**
|
|
142
|
+
* `clampIntAllowingZero`, and the choice is load-bearing: `clampInt` delegates to
|
|
143
|
+
* `coercePositiveInt`, which returns the FALLBACK for `n <= 0` — so `0` would
|
|
144
|
+
* silently become 5000 and the documented off switch would not be an off switch.
|
|
145
|
+
* Exactly the trap `retry.maxRetries` needed this helper for.
|
|
146
|
+
*/
|
|
147
|
+
export declare function clampScrollResumeMs(v: unknown, fallback: number): number;
|
|
118
148
|
/** `ask_user` calls allowed per user turn. */
|
|
119
149
|
export declare const DEFAULT_PLAN_MAX_ASK_ROUNDS = 4;
|
|
120
150
|
/**
|
|
@@ -489,6 +519,136 @@ export declare const DEFAULT_UPDATE_CONFIG: UpdateConfig;
|
|
|
489
519
|
* cannot see it reading.
|
|
490
520
|
*/
|
|
491
521
|
export declare function clampUpdateConfig(raw: unknown): UpdateConfig;
|
|
522
|
+
export type CompactionFailureMode = 'truncate' | 'stop';
|
|
523
|
+
export interface CompactionConfig {
|
|
524
|
+
/**
|
|
525
|
+
* Whether a `ContextManager` is constructed at all. Default TRUE.
|
|
526
|
+
*
|
|
527
|
+
* THE ONLY KEY IN THIS SECTION THAT DEFAULTS ON, AND THE ONLY ONE READ ONCE AT
|
|
528
|
+
* CONSTRUCTION — the `team.enabled` / `todo.enabled` / `fast.enabled` rule.
|
|
529
|
+
*
|
|
530
|
+
* IT DEFAULTS TO `true` UNLIKE EVERY OTHER OPTIONAL SUBSYSTEM HERE, and that is
|
|
531
|
+
* deliberate (D-16): `fast.enabled` and `team.enabled` default off because they
|
|
532
|
+
* ADD behaviour the user did not ask for. This one REMOVES a failure the user
|
|
533
|
+
* did not ask for — without it, the answer to a full context window is a dead
|
|
534
|
+
* run. Byte-identity is still honoured: `--no-compaction` constructs no
|
|
535
|
+
* manager, subscribes nothing, allocates no registry, and leaves the engine
|
|
536
|
+
* loop with `ctx.contextManager === undefined`.
|
|
537
|
+
*/
|
|
538
|
+
enabled: boolean;
|
|
539
|
+
/** Occupancy ratio that triggers compaction. Read LIVE. */
|
|
540
|
+
threshold: number;
|
|
541
|
+
/**
|
|
542
|
+
* Where the status-bar gauge turns amber.
|
|
543
|
+
*
|
|
544
|
+
* CLAMPED JOINTLY WITH `threshold`, AND THE ORDER IS FIXED — see
|
|
545
|
+
* `clampCompactionConfig`. "Jointly" is not an instruction.
|
|
546
|
+
*/
|
|
547
|
+
warnThreshold: number;
|
|
548
|
+
/** Complete turns kept verbatim in the tail. Read LIVE. */
|
|
549
|
+
keepRecentTurns: number;
|
|
550
|
+
/**
|
|
551
|
+
* Summarize with the fast tier when it resolves. Default TRUE.
|
|
552
|
+
*
|
|
553
|
+
* A PREFERENCE, NOT THE COMMON PATH (P2-8). `resolveFastTier` returns
|
|
554
|
+
* `{ok:false, reason:'disabled'}` on `fast.enabled !== true` alone, and
|
|
555
|
+
* `fast.enabled` defaults to `false` — so out of the box the summarizer is the
|
|
556
|
+
* SESSION'S OWN MODEL, and the first compaction is a ~30 k-token call on it.
|
|
557
|
+
*/
|
|
558
|
+
useFastTier: boolean;
|
|
559
|
+
/** What happens when summarization fails outright. See §3.7 rungs 3 / 4. */
|
|
560
|
+
onFailure: CompactionFailureMode;
|
|
561
|
+
/**
|
|
562
|
+
* Give `task` children their own compaction
|
|
563
|
+
* (context-auto-compaction-hardening §3.4 / W3). Default TRUE.
|
|
564
|
+
*
|
|
565
|
+
* IT REVERSES D-15, WHOSE PREMISE IS MEASURABLY FALSE at the configured bounds:
|
|
566
|
+
* `team.maxTurnsPerSubagent` is 24 and `team.dispatchTimeoutMs` is 900 000, and
|
|
567
|
+
* 24 turns over fifteen minutes is the same profile as the lead run this
|
|
568
|
+
* feature exists for. When a child overflows today its history is discarded and
|
|
569
|
+
* the lead receives one partial sentence for the whole dispatch.
|
|
570
|
+
*
|
|
571
|
+
* `false` REPRODUCES ROUND 1 EXACTLY: `subagent.ts` spreads no `contextManager`
|
|
572
|
+
* key at all, so the child's loop gate tests an absent field.
|
|
573
|
+
*/
|
|
574
|
+
subagents: boolean;
|
|
575
|
+
/**
|
|
576
|
+
* Write the dropped messages to `<home>/compaction/` before adopting a splice
|
|
577
|
+
* (context-auto-compaction-hardening §3.5 / W4). Default TRUE.
|
|
578
|
+
*
|
|
579
|
+
* NOT UNDO (§12): restoring an over-full history restores the condition that
|
|
580
|
+
* triggered the compaction. This is fidelity on disk, so "the summary is wrong
|
|
581
|
+
* and the agent proceeded on a false record" becomes something a human can
|
|
582
|
+
* check rather than something they must accept.
|
|
583
|
+
*/
|
|
584
|
+
archive: boolean;
|
|
585
|
+
}
|
|
586
|
+
export declare const DEFAULT_COMPACTION_CONFIG: CompactionConfig;
|
|
587
|
+
/**
|
|
588
|
+
* THE single gate for every compaction-config read AND write, mirroring the six
|
|
589
|
+
* clamps above for the reason all of them record: hardening only the read path
|
|
590
|
+
* leaves a bad value on disk that reverts to the default on every launch, which
|
|
591
|
+
* presents to the user as "my setting won't stick".
|
|
592
|
+
*
|
|
593
|
+
* THE ORDER IS FIXED AND IT MATTERS (§4.2 / P2-5). `threshold` is clamped to
|
|
594
|
+
* `[0.5, 0.95]` FIRST, then `warnThreshold` to
|
|
595
|
+
* `[0.4, clampedThreshold - 0.05]`. The other order lets a file holding
|
|
596
|
+
* `{threshold: 0.6, warnThreshold: 0.9}` produce a warn mark ABOVE the trigger —
|
|
597
|
+
* a gauge that turns amber after it has already gone red. Both bounds of the
|
|
598
|
+
* second range stay reachable at the extremes: `threshold` floored at `0.5`
|
|
599
|
+
* gives `warnThreshold` a range of `[0.4, 0.45]`.
|
|
600
|
+
*/
|
|
601
|
+
export declare function clampCompactionConfig(raw: unknown): CompactionConfig;
|
|
602
|
+
export interface BashConfig {
|
|
603
|
+
/**
|
|
604
|
+
* Register `bash_output` / `bash_kill`, honour `background`, splice the prompt
|
|
605
|
+
* block, render the chip. Default TRUE.
|
|
606
|
+
*
|
|
607
|
+
* READ ONCE AT CONSTRUCTION, the `team.enabled` / `todo.enabled` /
|
|
608
|
+
* `fast.enabled` rule.
|
|
609
|
+
*
|
|
610
|
+
* IT GOVERNS *SERVICES*, NEVER *INTERRUPTIBILITY* (I-2 / D-9). `Esc`/`Esc`,
|
|
611
|
+
* the foreground child registry and `forceStop()` are unconditional, because
|
|
612
|
+
* "bash always settles" and "Esc twice always works" are promised
|
|
613
|
+
* unconditionally — a user who turned background services off has not asked
|
|
614
|
+
* for a less interruptible agent.
|
|
615
|
+
*/
|
|
616
|
+
background: boolean;
|
|
617
|
+
/**
|
|
618
|
+
* Let the classifier decide when the model did not say. Default TRUE.
|
|
619
|
+
*
|
|
620
|
+
* RESOLVES TO `false` WITHOUT AN INTERACTIVE VIEW (D-15 / P1-8), and that is
|
|
621
|
+
* decided at the tool layer rather than here: the value on disk is the user's
|
|
622
|
+
* preference, and headless has no card, no `/bg` and no user to keep a service
|
|
623
|
+
* alive, so the rescue would be a surprise instead. An explicit
|
|
624
|
+
* `background: true` is still honoured there — that one the model asked for.
|
|
625
|
+
*/
|
|
626
|
+
autoBackground: boolean;
|
|
627
|
+
/** How long a background launch may block the turn before returning. */
|
|
628
|
+
startupSettleMs: number;
|
|
629
|
+
/** How long a service may stay `starting` before it is called `running`. */
|
|
630
|
+
readyTimeoutMs: number;
|
|
631
|
+
}
|
|
632
|
+
export declare const DEFAULT_BASH_CONFIG: BashConfig;
|
|
633
|
+
/**
|
|
634
|
+
* THE single gate for every bash-config read AND write, mirroring
|
|
635
|
+
* `clampSkillsConfig` / `clampLogConfig` / `clampTeamConfig` / `clampTodoConfig`
|
|
636
|
+
* for the reason those record: hardening only the read path leaves a bad value
|
|
637
|
+
* on disk that reverts to the default on every launch, which presents to the
|
|
638
|
+
* user as "my setting won't stick".
|
|
639
|
+
*
|
|
640
|
+
* CLAMPED, NEVER REJECTED — the discipline every other key in this file follows.
|
|
641
|
+
* A garbage `startupSettleMs` resolves to 4000 and throws nothing.
|
|
642
|
+
*/
|
|
643
|
+
export declare function clampBashConfig(raw: unknown): BashConfig;
|
|
644
|
+
/**
|
|
645
|
+
* Parse `0.9`, `90%` or `90` into a ratio, or `null` when it is neither.
|
|
646
|
+
*
|
|
647
|
+
* `null` RATHER THAN A CLAMPED DEFAULT, because this is a COMMAND argument and
|
|
648
|
+
* not a config value: `/compact threshold banana` must say so rather than
|
|
649
|
+
* silently setting 0.9 and reporting success.
|
|
650
|
+
*/
|
|
651
|
+
export declare function parseThresholdInput(raw: string): number | null;
|
|
492
652
|
export interface PersistedConfig {
|
|
493
653
|
version: number;
|
|
494
654
|
provider: string;
|
|
@@ -578,6 +738,24 @@ export interface PersistedConfig {
|
|
|
578
738
|
* heuristics for an explicit `true` to override (D-10).
|
|
579
739
|
*/
|
|
580
740
|
mouse: boolean;
|
|
741
|
+
/**
|
|
742
|
+
* Drag-select + copy in full-screen mode (tui-selection-and-scroll-follow
|
|
743
|
+
* §6.1). Ignored when `mouse` is false; also decides whether `?1002h` is
|
|
744
|
+
* written at all, so `false` is byte-identical to a pre-feature session.
|
|
745
|
+
*/
|
|
746
|
+
mouseSelect: boolean;
|
|
747
|
+
/**
|
|
748
|
+
* Recognise pasted text and collapse a large paste into a placeholder
|
|
749
|
+
* (tui-paste-handling D-10 / section 7.3).
|
|
750
|
+
*
|
|
751
|
+
* A PLAIN BOOLEAN and the ONLY user-facing key this feature adds: the collapse
|
|
752
|
+
* threshold and every size bound are structural and live in `input/limits.ts`
|
|
753
|
+
* / `ui/composer-limits.ts`. A tunable threshold is a preference nobody has
|
|
754
|
+
* asked for; a kill switch is what a bug report needs.
|
|
755
|
+
*/
|
|
756
|
+
paste: boolean;
|
|
757
|
+
/** Idle ms before a paused viewport returns to the newest line; `0` disables. */
|
|
758
|
+
scrollResumeMs: number;
|
|
581
759
|
/** Start every session in PLAN mode (plan-mode §4.4). */
|
|
582
760
|
planModeDefault: boolean;
|
|
583
761
|
/** `ask_user` rounds allowed per user turn; clamped to [1, 10]. */
|
|
@@ -598,6 +776,10 @@ export interface PersistedConfig {
|
|
|
598
776
|
fast: FastConfig;
|
|
599
777
|
/** Auto-update. The EIGHTH nested object; scalars only (see UpdateConfig). */
|
|
600
778
|
update: UpdateConfig;
|
|
779
|
+
/** Context compaction. The NINTH nested object; scalars only (see CompactionConfig). */
|
|
780
|
+
compaction: CompactionConfig;
|
|
781
|
+
/** Background services. The TENTH nested object; scalars only (see BashConfig). */
|
|
782
|
+
bash: BashConfig;
|
|
601
783
|
}
|
|
602
784
|
export declare const DEFAULT_CONFIG: PersistedConfig;
|
|
603
785
|
/**
|
|
@@ -727,6 +909,30 @@ export interface CliConfig {
|
|
|
727
909
|
* only). Resolved by `resolveMouse` in `load.ts`.
|
|
728
910
|
*/
|
|
729
911
|
mouse: boolean;
|
|
912
|
+
/**
|
|
913
|
+
* Whether this session may drag-select and copy.
|
|
914
|
+
*
|
|
915
|
+
* IT MUST EXIST HERE AND NOT ONLY IN `PersistedConfig`, for the reason
|
|
916
|
+
* `diffRender` above records at length: `runInteractive` reads
|
|
917
|
+
* `config.mouseSelect` — where `config` is a `CliConfig` — to decide the
|
|
918
|
+
* `?1002h` write, the controller and the `decorate` hook. A key added to the
|
|
919
|
+
* persisted shape alone would round-trip through `config set`, appear in
|
|
920
|
+
* `config list`, and never reach a single one of them.
|
|
921
|
+
*/
|
|
922
|
+
mouseSelect: boolean;
|
|
923
|
+
/**
|
|
924
|
+
* Whether this session recognises pastes at all.
|
|
925
|
+
*
|
|
926
|
+
* IT MUST EXIST HERE AND NOT ONLY IN `PersistedConfig`, for the reason
|
|
927
|
+
* `mouseSelect` above records: `runInteractive` reads `config.paste` -- where
|
|
928
|
+
* `config` is a `CliConfig` -- to decide the filter's `paste` feature, the
|
|
929
|
+
* `?2004h` write and the `PasteBridge`. A key added to the persisted shape
|
|
930
|
+
* alone would round-trip through `config set`, appear in `config list`, and
|
|
931
|
+
* reach none of them.
|
|
932
|
+
*/
|
|
933
|
+
paste: boolean;
|
|
934
|
+
/** Idle ms before a paused viewport returns to the newest line; `0` disables. */
|
|
935
|
+
scrollResumeMs: number;
|
|
730
936
|
/**
|
|
731
937
|
* Whether this session opens in PLAN mode.
|
|
732
938
|
*
|
|
@@ -800,6 +1006,44 @@ export interface CliConfig {
|
|
|
800
1006
|
* and be discarded, with no compile error and no runtime error.
|
|
801
1007
|
*/
|
|
802
1008
|
update: UpdateConfig;
|
|
1009
|
+
/**
|
|
1010
|
+
* Resolved context-compaction settings (context-auto-compaction §4.2).
|
|
1011
|
+
*
|
|
1012
|
+
* `enabled` here decides whether `AgentController` CONSTRUCTS a
|
|
1013
|
+
* `CompactionWiring` at all, which is what makes `false` byte-identical to a
|
|
1014
|
+
* pre-feature build: no manager is passed to `new Agent({...})`, nothing is
|
|
1015
|
+
* subscribed, no registry is allocated, and the loop's checkpoint is one `if`
|
|
1016
|
+
* against an absent field. The other five keys are read LIVE on every use, so
|
|
1017
|
+
* `/compact threshold 0.8` takes effect in the running session.
|
|
1018
|
+
*
|
|
1019
|
+
* IT MUST EXIST HERE AND NOT ONLY IN `PersistedConfig`, for the reason
|
|
1020
|
+
* `showThinking`, `liveToolOutput`, `diffRender`, `mouseSelect` and `update`
|
|
1021
|
+
* each record above: the controller and the compactor read `config.compaction`,
|
|
1022
|
+
* where `config` is a `CliConfig`, so a key added to the persisted shape alone
|
|
1023
|
+
* would round-trip through `config set`, appear in `config list` — and never
|
|
1024
|
+
* reach either of them.
|
|
1025
|
+
*/
|
|
1026
|
+
compaction: CompactionConfig;
|
|
1027
|
+
/**
|
|
1028
|
+
* Resolved background-service settings (background-service-supervision §5.4).
|
|
1029
|
+
*
|
|
1030
|
+
* `background` here decides whether `bash`'s schema carries a `background`
|
|
1031
|
+
* property, whether `bash_output` / `bash_kill` are REGISTERED and whether
|
|
1032
|
+
* `<background_services>` is spliced — all three at construction, and none of
|
|
1033
|
+
* them undoable, the `team.enabled` / `todo.enabled` / `fast.enabled` rule.
|
|
1034
|
+
* The other three keys are read LIVE.
|
|
1035
|
+
*
|
|
1036
|
+
* IT DOES NOT GATE THE INTERRUPT LADDER (I-2 / D-9). `ProcSupervisor` is
|
|
1037
|
+
* constructed unconditionally, because `Esc`/`Esc` and the foreground registry
|
|
1038
|
+
* are what make G2 and G3 true and those are promised whatever this says.
|
|
1039
|
+
*
|
|
1040
|
+
* IT MUST EXIST HERE AND NOT ONLY IN `PersistedConfig`, for the reason every
|
|
1041
|
+
* section above records: the controller and `bash` read `config.bash`, where
|
|
1042
|
+
* `config` is a `CliConfig`, so a key added to the persisted shape alone would
|
|
1043
|
+
* round-trip through `config set`, appear in `config list` — and never reach
|
|
1044
|
+
* either of them.
|
|
1045
|
+
*/
|
|
1046
|
+
bash: BashConfig;
|
|
803
1047
|
/**
|
|
804
1048
|
* Lifetime submit count driving the composer hint fade (`HINT_FADE_AFTER`).
|
|
805
1049
|
*
|
package/dist/config/schema.js
CHANGED
|
@@ -169,6 +169,42 @@ export const DEFAULT_DIFF_RENDER = true;
|
|
|
169
169
|
*/
|
|
170
170
|
export const DEFAULT_SYNC_OUTPUT = true;
|
|
171
171
|
// ---------------------------------------------------------------------------
|
|
172
|
+
// Selection + scroll follow (tui-selection-and-scroll-follow §6.1)
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
/**
|
|
175
|
+
* Drag-select + copy, and — because §4.4.1 gates `\x1b[?1002h` on exactly this
|
|
176
|
+
* value — whether motion reporting is requested from the terminal at all.
|
|
177
|
+
*
|
|
178
|
+
* That gating is what makes `false` BYTE-IDENTICAL to a pre-feature session
|
|
179
|
+
* rather than merely equivalent (AC-8 / D-15). Ignored when `mouse` is false,
|
|
180
|
+
* since there is no capture to select with.
|
|
181
|
+
*/
|
|
182
|
+
export const DEFAULT_MOUSE_SELECT = true;
|
|
183
|
+
/**
|
|
184
|
+
* Idle delay before a paused viewport returns to the newest line, in ms.
|
|
185
|
+
*
|
|
186
|
+
* Five seconds is chosen to be LONGER than a glance and SHORTER than a read.
|
|
187
|
+
* `0` disables auto-resume entirely, and it is a real value rather than a
|
|
188
|
+
* sentinel-shaped default: `shouldArmResume` refuses on it before any timer is
|
|
189
|
+
* created (AC-9), so the revert for Rule B is one config key.
|
|
190
|
+
*
|
|
191
|
+
* NO CLI FLAG (§6.1). It is a comfort preference, set once
|
|
192
|
+
* (`aragon config set scrollResumeMs 8000`) and then forgotten — the same
|
|
193
|
+
* argument this file already makes for `historyEnabled`. Adding a flag for every
|
|
194
|
+
* scalar is how a CLI ends up with sixty of them.
|
|
195
|
+
*/
|
|
196
|
+
export const DEFAULT_SCROLL_RESUME_MS = 5000;
|
|
197
|
+
const SCROLL_RESUME_RANGE = { min: 0, max: 120_000 };
|
|
198
|
+
/**
|
|
199
|
+
* `clampIntAllowingZero`, and the choice is load-bearing: `clampInt` delegates to
|
|
200
|
+
* `coercePositiveInt`, which returns the FALLBACK for `n <= 0` — so `0` would
|
|
201
|
+
* silently become 5000 and the documented off switch would not be an off switch.
|
|
202
|
+
* Exactly the trap `retry.maxRetries` needed this helper for.
|
|
203
|
+
*/
|
|
204
|
+
export function clampScrollResumeMs(v, fallback) {
|
|
205
|
+
return clampIntAllowingZero(v, fallback, SCROLL_RESUME_RANGE);
|
|
206
|
+
}
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
172
208
|
// Plan mode (plan-mode §4.4)
|
|
173
209
|
//
|
|
174
210
|
// THREE FLAT KEYS, not a nested `planMode` object. `store.ts` documents that its
|
|
@@ -669,6 +705,126 @@ function isRegistryUrl(raw) {
|
|
|
669
705
|
return false;
|
|
670
706
|
}
|
|
671
707
|
}
|
|
708
|
+
export const DEFAULT_COMPACTION_CONFIG = {
|
|
709
|
+
enabled: true,
|
|
710
|
+
threshold: 0.9,
|
|
711
|
+
warnThreshold: 0.75,
|
|
712
|
+
keepRecentTurns: 4,
|
|
713
|
+
useFastTier: true,
|
|
714
|
+
onFailure: 'truncate',
|
|
715
|
+
subagents: true,
|
|
716
|
+
archive: true,
|
|
717
|
+
};
|
|
718
|
+
const THRESHOLD_RANGE = { min: 0.5, max: 0.95 };
|
|
719
|
+
const WARN_THRESHOLD_FLOOR = 0.4;
|
|
720
|
+
/** The gap the warn mark must stay below the trigger by. */
|
|
721
|
+
const WARN_THRESHOLD_GAP = 0.05;
|
|
722
|
+
const KEEP_RECENT_TURNS_RANGE = { min: 1, max: 20 };
|
|
723
|
+
const COMPACTION_FAILURE_MODES = ['truncate', 'stop'];
|
|
724
|
+
/**
|
|
725
|
+
* Round a ratio to two decimals — the precision a percentage actually has.
|
|
726
|
+
*
|
|
727
|
+
* BINARY FLOATING POINT MAKES `0.95 - 0.05` EQUAL `0.8999999999999999`, and both
|
|
728
|
+
* numbers here are produced by subtraction (`threshold - WARN_THRESHOLD_GAP`) and
|
|
729
|
+
* by division (`parseThresholdInput` turning `90` into `90/100`). Without this,
|
|
730
|
+
* `aragon config list` shows a seventeen-digit value for a setting the user typed
|
|
731
|
+
* as `90%`, and `config.json` records one — which looks like corruption and
|
|
732
|
+
* invites a hand-edit that the clamp then has to defend against.
|
|
733
|
+
*
|
|
734
|
+
* Two decimals is exact for every value the range can hold: the clamp is
|
|
735
|
+
* `[0.5, 0.95]` and the UI reads it as a whole percentage.
|
|
736
|
+
*/
|
|
737
|
+
function ratio(value) {
|
|
738
|
+
return Math.round(value * 100) / 100;
|
|
739
|
+
}
|
|
740
|
+
function failureMode(value, fallback) {
|
|
741
|
+
return typeof value === 'string' && COMPACTION_FAILURE_MODES.includes(value)
|
|
742
|
+
? value
|
|
743
|
+
: fallback;
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* THE single gate for every compaction-config read AND write, mirroring the six
|
|
747
|
+
* clamps above for the reason all of them record: hardening only the read path
|
|
748
|
+
* leaves a bad value on disk that reverts to the default on every launch, which
|
|
749
|
+
* presents to the user as "my setting won't stick".
|
|
750
|
+
*
|
|
751
|
+
* THE ORDER IS FIXED AND IT MATTERS (§4.2 / P2-5). `threshold` is clamped to
|
|
752
|
+
* `[0.5, 0.95]` FIRST, then `warnThreshold` to
|
|
753
|
+
* `[0.4, clampedThreshold - 0.05]`. The other order lets a file holding
|
|
754
|
+
* `{threshold: 0.6, warnThreshold: 0.9}` produce a warn mark ABOVE the trigger —
|
|
755
|
+
* a gauge that turns amber after it has already gone red. Both bounds of the
|
|
756
|
+
* second range stay reachable at the extremes: `threshold` floored at `0.5`
|
|
757
|
+
* gives `warnThreshold` a range of `[0.4, 0.45]`.
|
|
758
|
+
*/
|
|
759
|
+
export function clampCompactionConfig(raw) {
|
|
760
|
+
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
761
|
+
const threshold = ratio(clampNumber(src.threshold, DEFAULT_COMPACTION_CONFIG.threshold, THRESHOLD_RANGE));
|
|
762
|
+
const warnCeiling = ratio(threshold - WARN_THRESHOLD_GAP);
|
|
763
|
+
return {
|
|
764
|
+
enabled: bool(src.enabled, DEFAULT_COMPACTION_CONFIG.enabled),
|
|
765
|
+
threshold,
|
|
766
|
+
warnThreshold: ratio(clampNumber(src.warnThreshold, DEFAULT_COMPACTION_CONFIG.warnThreshold, {
|
|
767
|
+
min: Math.min(WARN_THRESHOLD_FLOOR, warnCeiling),
|
|
768
|
+
max: warnCeiling,
|
|
769
|
+
})),
|
|
770
|
+
keepRecentTurns: clampInt(src.keepRecentTurns, DEFAULT_COMPACTION_CONFIG.keepRecentTurns, KEEP_RECENT_TURNS_RANGE),
|
|
771
|
+
useFastTier: bool(src.useFastTier, DEFAULT_COMPACTION_CONFIG.useFastTier),
|
|
772
|
+
// CLAMPED TO THE DEFAULT, NEVER REJECTED — the discipline every other key in
|
|
773
|
+
// this file follows. `ARAGON_COMPACTION_ON_FAILURE=garbage` resolves to
|
|
774
|
+
// `truncate` and throws nothing.
|
|
775
|
+
onFailure: failureMode(src.onFailure, DEFAULT_COMPACTION_CONFIG.onFailure),
|
|
776
|
+
subagents: bool(src.subagents, DEFAULT_COMPACTION_CONFIG.subagents),
|
|
777
|
+
archive: bool(src.archive, DEFAULT_COMPACTION_CONFIG.archive),
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
export const DEFAULT_BASH_CONFIG = {
|
|
781
|
+
background: true,
|
|
782
|
+
autoBackground: true,
|
|
783
|
+
startupSettleMs: 4000,
|
|
784
|
+
readyTimeoutMs: 60_000,
|
|
785
|
+
};
|
|
786
|
+
const STARTUP_SETTLE_RANGE = { min: 500, max: 30_000 };
|
|
787
|
+
const READY_TIMEOUT_RANGE = { min: 5_000, max: 600_000 };
|
|
788
|
+
/**
|
|
789
|
+
* THE single gate for every bash-config read AND write, mirroring
|
|
790
|
+
* `clampSkillsConfig` / `clampLogConfig` / `clampTeamConfig` / `clampTodoConfig`
|
|
791
|
+
* for the reason those record: hardening only the read path leaves a bad value
|
|
792
|
+
* on disk that reverts to the default on every launch, which presents to the
|
|
793
|
+
* user as "my setting won't stick".
|
|
794
|
+
*
|
|
795
|
+
* CLAMPED, NEVER REJECTED — the discipline every other key in this file follows.
|
|
796
|
+
* A garbage `startupSettleMs` resolves to 4000 and throws nothing.
|
|
797
|
+
*/
|
|
798
|
+
export function clampBashConfig(raw) {
|
|
799
|
+
const src = (raw && typeof raw === 'object' ? raw : {});
|
|
800
|
+
return {
|
|
801
|
+
background: bool(src.background, DEFAULT_BASH_CONFIG.background),
|
|
802
|
+
autoBackground: bool(src.autoBackground, DEFAULT_BASH_CONFIG.autoBackground),
|
|
803
|
+
startupSettleMs: clampInt(src.startupSettleMs, DEFAULT_BASH_CONFIG.startupSettleMs, STARTUP_SETTLE_RANGE),
|
|
804
|
+
readyTimeoutMs: clampInt(src.readyTimeoutMs, DEFAULT_BASH_CONFIG.readyTimeoutMs, READY_TIMEOUT_RANGE),
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Parse `0.9`, `90%` or `90` into a ratio, or `null` when it is neither.
|
|
809
|
+
*
|
|
810
|
+
* `null` RATHER THAN A CLAMPED DEFAULT, because this is a COMMAND argument and
|
|
811
|
+
* not a config value: `/compact threshold banana` must say so rather than
|
|
812
|
+
* silently setting 0.9 and reporting success.
|
|
813
|
+
*/
|
|
814
|
+
export function parseThresholdInput(raw) {
|
|
815
|
+
const trimmed = raw.trim().replace(/%$/, '');
|
|
816
|
+
if (trimmed.length === 0)
|
|
817
|
+
return null;
|
|
818
|
+
const n = Number.parseFloat(trimmed);
|
|
819
|
+
if (!Number.isFinite(n))
|
|
820
|
+
return null;
|
|
821
|
+
// `90` means 90 %, `0.9` means 0.9. The ambiguity is only at `1`, which is
|
|
822
|
+
// above the clamp ceiling either way.
|
|
823
|
+
const ratio = n > 1 ? n / 100 : n;
|
|
824
|
+
if (ratio <= 0 || ratio > 1)
|
|
825
|
+
return null;
|
|
826
|
+
return ratio;
|
|
827
|
+
}
|
|
672
828
|
export const DEFAULT_CONFIG = {
|
|
673
829
|
version: CONFIG_VERSION,
|
|
674
830
|
provider: 'anthropic',
|
|
@@ -703,6 +859,9 @@ export const DEFAULT_CONFIG = {
|
|
|
703
859
|
density: 'comfortable',
|
|
704
860
|
hints: true,
|
|
705
861
|
mouse: true,
|
|
862
|
+
mouseSelect: DEFAULT_MOUSE_SELECT,
|
|
863
|
+
paste: true,
|
|
864
|
+
scrollResumeMs: DEFAULT_SCROLL_RESUME_MS,
|
|
706
865
|
planModeDefault: false,
|
|
707
866
|
planModeMaxAskRounds: DEFAULT_PLAN_MAX_ASK_ROUNDS,
|
|
708
867
|
planModeHumanTimeoutMs: DEFAULT_PLAN_HUMAN_TIMEOUT_MS,
|
|
@@ -728,6 +887,17 @@ export const DEFAULT_CONFIG = {
|
|
|
728
887
|
// (`cfg.update.mode !== 'off'`) would read TRUE and the feature would be on
|
|
729
888
|
// for a reason nobody could point at.
|
|
730
889
|
update: DEFAULT_UPDATE_CONFIG,
|
|
890
|
+
// And one section later again, for the fourth time. Without this line a user
|
|
891
|
+
// whose `config.json` predates compaction resolves `config.compaction.enabled`
|
|
892
|
+
// to `undefined`, which is FALSY — so a feature that is `true` by default would
|
|
893
|
+
// arrive OFF for every existing user, which is the one direction this
|
|
894
|
+
// particular default must never fail in.
|
|
895
|
+
compaction: DEFAULT_COMPACTION_CONFIG,
|
|
896
|
+
// And one section later again, for the fifth time. `bash.background` is `true`
|
|
897
|
+
// by default, so a `config.json` predating this feature resolving it to
|
|
898
|
+
// `undefined` would arrive with background services OFF for every existing
|
|
899
|
+
// user — the same direction the compaction line above must never fail in.
|
|
900
|
+
bash: DEFAULT_BASH_CONFIG,
|
|
731
901
|
};
|
|
732
902
|
/**
|
|
733
903
|
* Runtime state that used to be stored in `config.json` by mistake
|
package/dist/config/store.js
CHANGED
|
@@ -14,7 +14,7 @@ import { dirname } from 'node:path';
|
|
|
14
14
|
import process from 'node:process';
|
|
15
15
|
import { getConfigPath, getSessionsDir } from './app-paths.js';
|
|
16
16
|
import { registerSecretsFrom } from '../logging/secret-registry.js';
|
|
17
|
-
import { CONFIG_VERSION, DEFAULT_CONFIG, clampFastConfig, clampLogConfig, clampMaxTokens, clampRetryConfig, clampSkillsConfig, clampTeamConfig, clampTodoConfig, clampUpdateConfig, isAutoToken, stripLegacyStateKeys, } from './schema.js';
|
|
17
|
+
import { clampBashConfig, CONFIG_VERSION, DEFAULT_CONFIG, clampCompactionConfig, clampFastConfig, clampLogConfig, clampMaxTokens, clampRetryConfig, clampSkillsConfig, clampTeamConfig, clampTodoConfig, clampUpdateConfig, isAutoToken, stripLegacyStateKeys, } from './schema.js';
|
|
18
18
|
/**
|
|
19
19
|
* Normalize `maxTokens` for both directions of the config file.
|
|
20
20
|
*
|
|
@@ -139,6 +139,29 @@ export function loadPersistedConfig() {
|
|
|
139
139
|
// predates auto-update, which is all of them. Without it `config.update.mode`
|
|
140
140
|
// reads `undefined`, and the §3.8 gate tests `!== 'off'`.
|
|
141
141
|
update: clampUpdateConfig({ ...DEFAULT_CONFIG.update, ...(partial.update ?? {}) }),
|
|
142
|
+
// `compaction` is the ninth. Same one-level rule, same merge — and the READ
|
|
143
|
+
// half supplies a whole section to every user whose `config.json` predates
|
|
144
|
+
// this feature, which is all of them. Without it `config.compaction.enabled`
|
|
145
|
+
// reads `undefined`, which is FALSY, so a feature that is `true` by default
|
|
146
|
+
// would arrive off for every existing user.
|
|
147
|
+
compaction: clampCompactionConfig({
|
|
148
|
+
...DEFAULT_CONFIG.compaction,
|
|
149
|
+
...(partial.compaction ?? {}),
|
|
150
|
+
}),
|
|
151
|
+
// `bash` is the tenth. Same one-level rule, same merge — and the READ half
|
|
152
|
+
// supplies a whole section to every user whose `config.json` predates
|
|
153
|
+
// background services, which is all of them. Without it
|
|
154
|
+
// `config.bash.background` reads `undefined`, which is FALSY, so a feature
|
|
155
|
+
// that is `true` by default would arrive off for every existing user.
|
|
156
|
+
//
|
|
157
|
+
// A SIBLING OF `compaction`, NOT A KEY INSIDE ITS ARGUMENT. Nesting it one
|
|
158
|
+
// level too deep type-checks — `...DEFAULT_CONFIG` above already supplies a
|
|
159
|
+
// `bash`, so nothing is missing from the return type — and hands
|
|
160
|
+
// `clampCompactionConfig` a key it drops on the floor. The section then
|
|
161
|
+
// reaches callers straight off the shallow `...partial` spread: unclamped,
|
|
162
|
+
// and NOT merged over the defaults, which is verbatim the failure the
|
|
163
|
+
// paragraph above says this line prevents.
|
|
164
|
+
bash: clampBashConfig({ ...DEFAULT_CONFIG.bash, ...(partial.bash ?? {}) }),
|
|
142
165
|
};
|
|
143
166
|
}
|
|
144
167
|
/**
|
|
@@ -208,6 +231,19 @@ export function updatePersistedConfig(patch) {
|
|
|
208
231
|
// enterprise mirror the user configured last month is gone with no error
|
|
209
232
|
// anywhere. AC-20 is the assertion that proves both halves exist.
|
|
210
233
|
update: clampUpdateConfig({ ...current.update, ...(patch.update ?? {}) }),
|
|
234
|
+
// The ninth section, and the fourth time this file records the same trap.
|
|
235
|
+
// `/compact threshold 0.8` sends `{ compaction: { threshold: 0.8 } }`;
|
|
236
|
+
// without this line the shallow top-level spread REPLACES the section,
|
|
237
|
+
// `enabled` is written absent, and a user who deliberately turned compaction
|
|
238
|
+
// OFF finds it back on tomorrow — a feature that spends money on their behalf
|
|
239
|
+
// re-enabling itself because they nudged a threshold.
|
|
240
|
+
compaction: clampCompactionConfig({ ...current.compaction, ...(patch.compaction ?? {}) }),
|
|
241
|
+
// The tenth section, and the fifth time this file records the same trap.
|
|
242
|
+
// A patch carrying only `{ bash: { autoBackground: false } }` — turning the
|
|
243
|
+
// CLASSIFIER off — would, without this line, be spread shallowly over the
|
|
244
|
+
// top level and write `background` absent, silently unregistering
|
|
245
|
+
// `bash_output` / `bash_kill` from the next launch onward.
|
|
246
|
+
bash: clampBashConfig({ ...current.bash, ...(patch.bash ?? {}) }),
|
|
211
247
|
};
|
|
212
248
|
writeConfigFile(merged);
|
|
213
249
|
return merged;
|
|
@@ -32,8 +32,32 @@ export interface UiState {
|
|
|
32
32
|
schema: number;
|
|
33
33
|
/** Lifetime submit count; drives the composer hint fade (`HINT_FADE_AFTER`). */
|
|
34
34
|
submitCount: number;
|
|
35
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Whether the one-shot "hold Shift to select text" notice has been shown.
|
|
37
|
+
*
|
|
38
|
+
* DELIBERATELY NOT READ BY THE LIVE GATE ANY MORE (tui-selection-and-scroll-
|
|
39
|
+
* follow P1-8). It is kept in the shape so `importLegacyUiState` still has
|
|
40
|
+
* somewhere to put a migrated value and so a file written by 0.6.2 round-trips
|
|
41
|
+
* unchanged; `mouseNoticeVersion` below is what the notice now consults.
|
|
42
|
+
*/
|
|
36
43
|
mouseNoticeSeen: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Which revision of the mouse notice this user has already been shown
|
|
46
|
+
* (`0` = none).
|
|
47
|
+
*
|
|
48
|
+
* A VERSION BESIDE THE BOOLEAN, NOT A BUMPED SCHEMA, and this is the second
|
|
49
|
+
* time this file has had to say so. The audience for the CORRECTED text — "drag
|
|
50
|
+
* to select, releasing copies" — is exactly the set of users who already have
|
|
51
|
+
* `mouseNoticeSeen: true` on disk from the old "hold Shift" text, so a boolean
|
|
52
|
+
* can only say "shown", never "shown WHAT". And bumping `UI_STATE_SCHEMA`, the
|
|
53
|
+
* nearest thing to "bump the key", makes `readFromDisk` discard the WHOLE
|
|
54
|
+
* object: every user's `submitCount` resets and the composer hint un-fades for
|
|
55
|
+
* all of them, to re-show one notice.
|
|
56
|
+
*
|
|
57
|
+
* `vtInputNoticeVersion` below is the precedent, written about this exact
|
|
58
|
+
* situation one feature earlier.
|
|
59
|
+
*/
|
|
60
|
+
mouseNoticeVersion: number;
|
|
37
61
|
/**
|
|
38
62
|
* Which revision of the "this Windows console cannot deliver Shift+Tab or the
|
|
39
63
|
* wheel" notice this user has already been shown (`0` = none).
|
|
@@ -69,6 +93,9 @@ export declare function bumpSubmitCount(): number;
|
|
|
69
93
|
export declare function getMouseNoticeSeen(): boolean;
|
|
70
94
|
export declare function setMouseNoticeSeen(seen: boolean): void;
|
|
71
95
|
/** `0` on a file written before the field existed — see the field's comment. */
|
|
96
|
+
export declare function getMouseNoticeVersion(): number;
|
|
97
|
+
export declare function setMouseNoticeVersion(version: number): void;
|
|
98
|
+
/** `0` on a file written before the field existed — see the field's comment. */
|
|
72
99
|
export declare function getVtInputNoticeVersion(): number;
|
|
73
100
|
export declare function setVtInputNoticeVersion(version: number): void;
|
|
74
101
|
/**
|
package/dist/config/ui-state.js
CHANGED
|
@@ -35,6 +35,7 @@ const DEFAULT_UI_STATE = {
|
|
|
35
35
|
schema: UI_STATE_SCHEMA,
|
|
36
36
|
submitCount: 0,
|
|
37
37
|
mouseNoticeSeen: false,
|
|
38
|
+
mouseNoticeVersion: 0,
|
|
38
39
|
vtInputNoticeVersion: 0,
|
|
39
40
|
};
|
|
40
41
|
let memory = null;
|
|
@@ -66,6 +67,7 @@ function readFromDisk() {
|
|
|
66
67
|
mouseNoticeSeen: typeof parsed.mouseNoticeSeen === 'boolean'
|
|
67
68
|
? parsed.mouseNoticeSeen
|
|
68
69
|
: DEFAULT_UI_STATE.mouseNoticeSeen,
|
|
70
|
+
mouseNoticeVersion: coerceCount(parsed.mouseNoticeVersion, DEFAULT_UI_STATE.mouseNoticeVersion),
|
|
69
71
|
vtInputNoticeVersion: coerceCount(parsed.vtInputNoticeVersion, DEFAULT_UI_STATE.vtInputNoticeVersion),
|
|
70
72
|
};
|
|
71
73
|
}
|
|
@@ -127,6 +129,13 @@ export function setMouseNoticeSeen(seen) {
|
|
|
127
129
|
update({ mouseNoticeSeen: seen });
|
|
128
130
|
}
|
|
129
131
|
/** `0` on a file written before the field existed — see the field's comment. */
|
|
132
|
+
export function getMouseNoticeVersion() {
|
|
133
|
+
return loadUiState().mouseNoticeVersion;
|
|
134
|
+
}
|
|
135
|
+
export function setMouseNoticeVersion(version) {
|
|
136
|
+
update({ mouseNoticeVersion: version });
|
|
137
|
+
}
|
|
138
|
+
/** `0` on a file written before the field existed — see the field's comment. */
|
|
130
139
|
export function getVtInputNoticeVersion() {
|
|
131
140
|
return loadUiState().vtInputNoticeVersion;
|
|
132
141
|
}
|