detached 4d937f1

chore: ignore reviewers and superpowers docs

commit
4d937f1f49026cc9d27d29b7754381d944d7a174
author
brice · · 2026-08-04 09:32 UTC
parent
ae5a835
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
4 files · +2 -389
M .gitignore +2 -0
@@ -73,4 +73,6 @@ logs/
7373 .tmp/
7474 tmp/
7575 .agent-reviews/
76+.codereview/
77+docs/superpowers/
7678 npm/
@@ -73,4 +73,6 @@ logs/
73 .tmp/73 .tmp/
74 tmp/74 tmp/
75 .agent-reviews/75 .agent-reviews/
76+.codereview/
77+docs/superpowers/
76 npm/78 npm/
D docs/superpowers/plans/2026-07-28-configurable-auto-compact-threshold.md +0 -239
@@ -1,239 +0,0 @@
1-# Configurable Auto-Compact Threshold Implementation Plan
2-
3-> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4-
5-**Goal:** Add persisted auto-compaction threshold presets to the interactive TUI settings.
6-
7-**Architecture:** Keep automatic triggering in `packages/agent/modes`. Thread an optional integer percentage from persisted `agent.Config` into `modes.InteractiveConfig`, normalize missing or invalid values to 85%, and let zero disable only percentage-based triggers. Reuse the settings dialog's existing fixed-option picker and settings-store persistence path.
8-
9-**Tech Stack:** Go, standard library, Zot's existing TUI settings dialog, JSON configuration.
10-
11-## Global Constraints
12-
13-- Supported values are `0` (off), `70`, `80`, `85`, and `90`.
14-- Missing or invalid persisted values resolve to `85`.
15-- Disabling the threshold does not disable manual compaction or HTTP 413 recovery.
16-- Do not add dependencies or change non-interactive compaction behavior.
17-- Preserve unrelated working-tree changes and stage only this feature.
18-
19----
20-
21-### Task 1: Configuration and threshold decision
22-
23-**Files:**
24-- Modify: `packages/agent/config.go`
25-- Modify: `packages/agent/modes/interactive.go`
26-- Create: `packages/agent/modes/auto_compact_test.go`
27-- Modify: `packages/agent/cli.go`
28-
29-**Interfaces:**
30-- Produces: `Config.AutoCompactThreshold *int`
31-- Produces: `InteractiveConfig.AutoCompactThreshold *int`
32-- Produces: `normalizeAutoCompactThreshold(*int) int`
33-- Produces: `shouldAutoCompact(inputTokens, contextWindow, thresholdPercent int) bool`
34-
35-- [ ] **Step 1: Write failing normalization and decision tests**
36-
37-Add table-driven tests proving nil and invalid values resolve to 85, supported presets survive unchanged, zero disables percentage checks, and 70/80/85/90 trigger exactly at their boundaries.
38-
39-```go
40-func TestNormalizeAutoCompactThreshold(t *testing.T) {
41- tests := []struct {
42- name string
43- value *int
44- want int
45- }{
46- {name: "missing", value: nil, want: 85},
47- {name: "off", value: intPtr(0), want: 0},
48- {name: "seventy", value: intPtr(70), want: 70},
49- {name: "invalid", value: intPtr(42), want: 85},
50- }
51- // Assert normalizeAutoCompactThreshold(test.value) == test.want.
52-}
53-
54-func TestShouldAutoCompactUsesConfiguredThreshold(t *testing.T) {
55- if shouldAutoCompact(84, 100, 85) {
56- t.Fatal("84% must remain below an 85% threshold")
57- }
58- if !shouldAutoCompact(85, 100, 85) {
59- t.Fatal("85% must trigger an 85% threshold")
60- }
61- if shouldAutoCompact(100, 100, 0) {
62- t.Fatal("off must disable percentage-triggered compaction")
63- }
64-}
65-```
66-
67-- [ ] **Step 2: Run tests and verify RED**
68-
69-Run:
70-
71-```sh
72-go test ./packages/agent/modes -run 'TestNormalizeAutoCompactThreshold|TestShouldAutoCompactUsesConfiguredThreshold' -count=1
73-```
74-
75-Expected: compilation failure because the normalization and decision helpers do not exist.
76-
77-- [ ] **Step 3: Add optional configuration and minimal helpers**
78-
79-Add `AutoCompactThreshold *int` with JSON name `auto_compact_threshold` to both configuration structs. Implement normalization for exactly `0`, `70`, `80`, `85`, and `90`, defaulting all other values to `85`. Replace the hard-coded fraction check with the normalized percentage helper and pass the config field through `cli.go`.
80-
81-- [ ] **Step 4: Run focused tests and verify GREEN**
82-
83-Run:
84-
85-```sh
86-go test ./packages/agent/modes -run 'TestNormalizeAutoCompactThreshold|TestShouldAutoCompactUsesConfiguredThreshold' -count=1
87-```
88-
89-Expected: PASS.
90-
91-### Task 2: Persistence and TUI preset picker
92-
93-**Files:**
94-- Modify: `packages/agent/settings_store.go`
95-- Modify: `packages/agent/settings_store_test.go`
96-- Modify: `packages/agent/modes/interactive.go`
97-- Modify: `packages/agent/modes/auto_compact_test.go`
98-
99-**Interfaces:**
100-- Extends: `SettingsStore.SetAutoCompactThreshold(percent int) error`
101-- Consumes: `normalizeAutoCompactThreshold(*int) int`
102-
103-- [ ] **Step 1: Write failing persistence and settings-item tests**
104-
105-Add a settings-store test that writes `70` into an isolated `$ZOT_HOME` and verifies `auto_compact_threshold` plus an unrelated config field. Add a modes test that opens settings with missing configuration and verifies the option values are `0`, `70`, `80`, `85`, `90` with `85` selected.
106-
107-```go
108-func TestConfigSettingsStorePersistsAutoCompactThreshold(t *testing.T) {
109- t.Setenv("ZOT_HOME", t.TempDir())
110- if err := SaveConfig(Config{Theme: "dark"}); err != nil {
111- t.Fatal(err)
112- }
113- if err := (configSettingsStore{}).SetAutoCompactThreshold(70); err != nil {
114- t.Fatal(err)
115- }
116- cfg, err := LoadConfig()
117- if err != nil {
118- t.Fatal(err)
119- }
120- if cfg.AutoCompactThreshold == nil || *cfg.AutoCompactThreshold != 70 {
121- t.Fatalf("auto_compact_threshold = %v, want 70", cfg.AutoCompactThreshold)
122- }
123- if cfg.Theme != "dark" {
124- t.Fatalf("unrelated config changed: theme = %q, want dark", cfg.Theme)
125- }
126-}
127-```
128-
129-- [ ] **Step 2: Run tests and verify RED**
130-
131-Run:
132-
133-```sh
134-go test ./packages/agent ./packages/agent/modes -run 'AutoCompactThreshold|SettingsDialog.*AutoCompact' -count=1
135-```
136-
137-Expected: compilation or assertion failure because persistence and the picker row do not exist.
138-
139-- [ ] **Step 3: Implement persistence and live setting application**
140-
141-Add the settings-store method, fixed picker options, choice resolution, action routing, integer parsing, live `InteractiveConfig` update, and status message. Persist only values exposed by the picker; normalize the live value defensively before use.
142-
143-- [ ] **Step 4: Run focused tests and verify GREEN**
144-
145-Run:
146-
147-```sh
148-go test ./packages/agent ./packages/agent/modes -run 'AutoCompactThreshold|SettingsDialog.*AutoCompact' -count=1
149-```
150-
151-Expected: PASS.
152-
153-### Task 3: Documentation and full verification
154-
155-**Files:**
156-- Modify: `README.md`
157-- Review: `docs/superpowers/specs/2026-07-28-configurable-auto-compact-threshold-design.md`
158-- Review: `docs/superpowers/plans/2026-07-28-configurable-auto-compact-threshold.md`
159-
160-**Interfaces:**
161-- Documents: `auto_compact_threshold`
162-- Documents: `/settings` presets and `off` semantics
163-
164-- [ ] **Step 1: Update user documentation**
165-
166-Document `off`, `70%`, `80%`, `85%` default, and `90%` in the `/settings` section. Update `/compact` to state that threshold-based auto-compaction is configurable and that payload-too-large recovery remains active when the percentage trigger is off.
167-
168-- [ ] **Step 2: Format changed Go files**
169-
170-Run:
171-
172-```sh
173-gofmt -w packages/agent/config.go packages/agent/settings_store.go packages/agent/settings_store_test.go packages/agent/cli.go packages/agent/modes/interactive.go packages/agent/modes/auto_compact_test.go
174-```
175-
176-- [ ] **Step 3: Run the complete test suite**
177-
178-Run:
179-
180-```sh
181-go test ./...
182-```
183-
184-Expected: PASS.
185-
186-- [ ] **Step 4: Run static analysis**
187-
188-Run:
189-
190-```sh
191-go vet ./...
192-```
193-
194-Expected: PASS.
195-
196-- [ ] **Step 5: Inspect the final change**
197-
198-Run:
199-
200-```sh
201-git diff --check
202-git status --short
203-git diff
204-```
205-
206-Confirm only the configuration, TUI, tests, README, design, and plan belong to the feature.
207-
208-### Task 4: Publish the pull request
209-
210-**Files:**
211-- Stage only the files listed in Tasks 1-3.
212-
213-**Interfaces:**
214-- Produces: branch `codex/configurable-auto-compact-threshold`
215-- Produces: one feature commit and a ready GitHub pull request
216-
217-- [ ] **Step 1: Create the feature branch**
218-
219-```sh
220-git switch -c codex/configurable-auto-compact-threshold
221-```
222-
223-- [ ] **Step 2: Stage explicit feature paths and review**
224-
225-Stage only the implementation, tests, README, design, and plan. Review `git diff --cached --check` and `git diff --cached`.
226-
227-- [ ] **Step 3: Commit**
228-
229-```sh
230-git commit -m "Make auto-compact threshold configurable"
231-```
232-
233-- [ ] **Step 4: Push the branch**
234-
235-Push to the appropriate writable GitHub remote with upstream tracking.
236-
237-- [ ] **Step 5: Open a ready pull request**
238-
239-Target the upstream default branch. Include the behavior, compatibility, user impact, and exact validation commands in the PR body.
@@ -1,239 +0,0 @@
1-# Configurable Auto-Compact Threshold Implementation Plan
2-
3-> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4-
5-**Goal:** Add persisted auto-compaction threshold presets to the interactive TUI settings.
6-
7-**Architecture:** Keep automatic triggering in `packages/agent/modes`. Thread an optional integer percentage from persisted `agent.Config` into `modes.InteractiveConfig`, normalize missing or invalid values to 85%, and let zero disable only percentage-based triggers. Reuse the settings dialog's existing fixed-option picker and settings-store persistence path.
8-
9-**Tech Stack:** Go, standard library, Zot's existing TUI settings dialog, JSON configuration.
10-
11-## Global Constraints
12-
13-- Supported values are `0` (off), `70`, `80`, `85`, and `90`.
14-- Missing or invalid persisted values resolve to `85`.
15-- Disabling the threshold does not disable manual compaction or HTTP 413 recovery.
16-- Do not add dependencies or change non-interactive compaction behavior.
17-- Preserve unrelated working-tree changes and stage only this feature.
18-
19----
20-
21-### Task 1: Configuration and threshold decision
22-
23-**Files:**
24-- Modify: `packages/agent/config.go`
25-- Modify: `packages/agent/modes/interactive.go`
26-- Create: `packages/agent/modes/auto_compact_test.go`
27-- Modify: `packages/agent/cli.go`
28-
29-**Interfaces:**
30-- Produces: `Config.AutoCompactThreshold *int`
31-- Produces: `InteractiveConfig.AutoCompactThreshold *int`
32-- Produces: `normalizeAutoCompactThreshold(*int) int`
33-- Produces: `shouldAutoCompact(inputTokens, contextWindow, thresholdPercent int) bool`
34-
35-- [ ] **Step 1: Write failing normalization and decision tests**
36-
37-Add table-driven tests proving nil and invalid values resolve to 85, supported presets survive unchanged, zero disables percentage checks, and 70/80/85/90 trigger exactly at their boundaries.
38-
39-```go
40-func TestNormalizeAutoCompactThreshold(t *testing.T) {
41- tests := []struct {
42- name string
43- value *int
44- want int
45- }{
46- {name: "missing", value: nil, want: 85},
47- {name: "off", value: intPtr(0), want: 0},
48- {name: "seventy", value: intPtr(70), want: 70},
49- {name: "invalid", value: intPtr(42), want: 85},
50- }
51- // Assert normalizeAutoCompactThreshold(test.value) == test.want.
52-}
53-
54-func TestShouldAutoCompactUsesConfiguredThreshold(t *testing.T) {
55- if shouldAutoCompact(84, 100, 85) {
56- t.Fatal("84% must remain below an 85% threshold")
57- }
58- if !shouldAutoCompact(85, 100, 85) {
59- t.Fatal("85% must trigger an 85% threshold")
60- }
61- if shouldAutoCompact(100, 100, 0) {
62- t.Fatal("off must disable percentage-triggered compaction")
63- }
64-}
65-```
66-
67-- [ ] **Step 2: Run tests and verify RED**
68-
69-Run:
70-
71-```sh
72-go test ./packages/agent/modes -run 'TestNormalizeAutoCompactThreshold|TestShouldAutoCompactUsesConfiguredThreshold' -count=1
73-```
74-
75-Expected: compilation failure because the normalization and decision helpers do not exist.
76-
77-- [ ] **Step 3: Add optional configuration and minimal helpers**
78-
79-Add `AutoCompactThreshold *int` with JSON name `auto_compact_threshold` to both configuration structs. Implement normalization for exactly `0`, `70`, `80`, `85`, and `90`, defaulting all other values to `85`. Replace the hard-coded fraction check with the normalized percentage helper and pass the config field through `cli.go`.
80-
81-- [ ] **Step 4: Run focused tests and verify GREEN**
82-
83-Run:
84-
85-```sh
86-go test ./packages/agent/modes -run 'TestNormalizeAutoCompactThreshold|TestShouldAutoCompactUsesConfiguredThreshold' -count=1
87-```
88-
89-Expected: PASS.
90-
91-### Task 2: Persistence and TUI preset picker
92-
93-**Files:**
94-- Modify: `packages/agent/settings_store.go`
95-- Modify: `packages/agent/settings_store_test.go`
96-- Modify: `packages/agent/modes/interactive.go`
97-- Modify: `packages/agent/modes/auto_compact_test.go`
98-
99-**Interfaces:**
100-- Extends: `SettingsStore.SetAutoCompactThreshold(percent int) error`
101-- Consumes: `normalizeAutoCompactThreshold(*int) int`
102-
103-- [ ] **Step 1: Write failing persistence and settings-item tests**
104-
105-Add a settings-store test that writes `70` into an isolated `$ZOT_HOME` and verifies `auto_compact_threshold` plus an unrelated config field. Add a modes test that opens settings with missing configuration and verifies the option values are `0`, `70`, `80`, `85`, `90` with `85` selected.
106-
107-```go
108-func TestConfigSettingsStorePersistsAutoCompactThreshold(t *testing.T) {
109- t.Setenv("ZOT_HOME", t.TempDir())
110- if err := SaveConfig(Config{Theme: "dark"}); err != nil {
111- t.Fatal(err)
112- }
113- if err := (configSettingsStore{}).SetAutoCompactThreshold(70); err != nil {
114- t.Fatal(err)
115- }
116- cfg, err := LoadConfig()
117- if err != nil {
118- t.Fatal(err)
119- }
120- if cfg.AutoCompactThreshold == nil || *cfg.AutoCompactThreshold != 70 {
121- t.Fatalf("auto_compact_threshold = %v, want 70", cfg.AutoCompactThreshold)
122- }
123- if cfg.Theme != "dark" {
124- t.Fatalf("unrelated config changed: theme = %q, want dark", cfg.Theme)
125- }
126-}
127-```
128-
129-- [ ] **Step 2: Run tests and verify RED**
130-
131-Run:
132-
133-```sh
134-go test ./packages/agent ./packages/agent/modes -run 'AutoCompactThreshold|SettingsDialog.*AutoCompact' -count=1
135-```
136-
137-Expected: compilation or assertion failure because persistence and the picker row do not exist.
138-
139-- [ ] **Step 3: Implement persistence and live setting application**
140-
141-Add the settings-store method, fixed picker options, choice resolution, action routing, integer parsing, live `InteractiveConfig` update, and status message. Persist only values exposed by the picker; normalize the live value defensively before use.
142-
143-- [ ] **Step 4: Run focused tests and verify GREEN**
144-
145-Run:
146-
147-```sh
148-go test ./packages/agent ./packages/agent/modes -run 'AutoCompactThreshold|SettingsDialog.*AutoCompact' -count=1
149-```
150-
151-Expected: PASS.
152-
153-### Task 3: Documentation and full verification
154-
155-**Files:**
156-- Modify: `README.md`
157-- Review: `docs/superpowers/specs/2026-07-28-configurable-auto-compact-threshold-design.md`
158-- Review: `docs/superpowers/plans/2026-07-28-configurable-auto-compact-threshold.md`
159-
160-**Interfaces:**
161-- Documents: `auto_compact_threshold`
162-- Documents: `/settings` presets and `off` semantics
163-
164-- [ ] **Step 1: Update user documentation**
165-
166-Document `off`, `70%`, `80%`, `85%` default, and `90%` in the `/settings` section. Update `/compact` to state that threshold-based auto-compaction is configurable and that payload-too-large recovery remains active when the percentage trigger is off.
167-
168-- [ ] **Step 2: Format changed Go files**
169-
170-Run:
171-
172-```sh
173-gofmt -w packages/agent/config.go packages/agent/settings_store.go packages/agent/settings_store_test.go packages/agent/cli.go packages/agent/modes/interactive.go packages/agent/modes/auto_compact_test.go
174-```
175-
176-- [ ] **Step 3: Run the complete test suite**
177-
178-Run:
179-
180-```sh
181-go test ./...
182-```
183-
184-Expected: PASS.
185-
186-- [ ] **Step 4: Run static analysis**
187-
188-Run:
189-
190-```sh
191-go vet ./...
192-```
193-
194-Expected: PASS.
195-
196-- [ ] **Step 5: Inspect the final change**
197-
198-Run:
199-
200-```sh
201-git diff --check
202-git status --short
203-git diff
204-```
205-
206-Confirm only the configuration, TUI, tests, README, design, and plan belong to the feature.
207-
208-### Task 4: Publish the pull request
209-
210-**Files:**
211-- Stage only the files listed in Tasks 1-3.
212-
213-**Interfaces:**
214-- Produces: branch `codex/configurable-auto-compact-threshold`
215-- Produces: one feature commit and a ready GitHub pull request
216-
217-- [ ] **Step 1: Create the feature branch**
218-
219-```sh
220-git switch -c codex/configurable-auto-compact-threshold
221-```
222-
223-- [ ] **Step 2: Stage explicit feature paths and review**
224-
225-Stage only the implementation, tests, README, design, and plan. Review `git diff --cached --check` and `git diff --cached`.
226-
227-- [ ] **Step 3: Commit**
228-
229-```sh
230-git commit -m "Make auto-compact threshold configurable"
231-```
232-
233-- [ ] **Step 4: Push the branch**
234-
235-Push to the appropriate writable GitHub remote with upstream tracking.
236-
237-- [ ] **Step 5: Open a ready pull request**
238-
239-Target the upstream default branch. Include the behavior, compatibility, user impact, and exact validation commands in the PR body.
D docs/superpowers/specs/2026-07-28-configurable-auto-compact-threshold-design.md +0 -73
@@ -1,73 +0,0 @@
1-# Configurable Auto-Compact Threshold
2-
3-## Goal
4-
5-Let users choose when Zot automatically compacts an interactive transcript from the existing `/settings` dialog, while preserving the current 85% behavior by default.
6-
7-## User Experience
8-
9-Add a top-level `/settings` option named **auto-compact threshold** with these choices:
10-
11-- `off`
12-- `70%`
13-- `80%`
14-- `85%` (default)
15-- `90%`
16-
17-Changing the option takes effect for the next turn without restarting Zot.
18-
19-The `off` choice disables context-percentage triggers before and after turns. It does not disable:
20-
21-- manual `/compact`
22-- explicit RPC or SDK compaction
23-- automatic compaction and retry after an HTTP 413 or equivalent payload-too-large response
24-
25-## Configuration
26-
27-Persist the selected percentage in `$ZOT_HOME/config.json` as:
28-
29-```json
30-{
31- "auto_compact_threshold": 85
32-}
33-```
34-
35-The field is an optional integer percentage:
36-
37-- A missing field resolves to `85` for backward compatibility.
38-- `0` represents `off`.
39-- Valid non-zero values are `70`, `80`, `85`, and `90`.
40-- Any other persisted value resolves to `85` at runtime.
41-- When a user selects a setting in the TUI, Zot writes only one of the supported values.
42-
43-## Implementation Boundaries
44-
45-The interactive host continues to own automatic triggering. `core.Agent.Compact`, RPC, SDK, bot, print, and JSON mode behavior remain unchanged.
46-
47-Replace the hard-coded `0.85` comparison with a helper that resolves the configured integer percentage and compares the most recent context usage against the model's advertised context window. A resolved value of `0` returns false for percentage-based checks.
48-
49-The payload-too-large recovery path continues to invoke automatic compaction independently of the configured percentage.
50-
51-The settings dialog uses its existing fixed-option picker. No free-form numeric input or new dialog control is introduced.
52-
53-## Error Handling
54-
55-Configuration writes use the existing settings-store error path and show failures in the TUI status area. An invalid value already present in `config.json` does not prevent startup; Zot falls back to 85%.
56-
57-## Tests
58-
59-Add focused tests covering:
60-
61-- missing configuration resolves to 85%
62-- every supported preset resolves correctly
63-- invalid persisted values resolve to 85%
64-- `off` suppresses percentage-triggered compaction
65-- threshold comparison uses the selected percentage
66-- the settings store persists the selected integer
67-- the settings dialog exposes all presets with 85% selected by default
68-
69-Run the focused package tests during development, then `gofmt`, `go test ./...`, `go vet ./...`, `git diff --check`, and final status/diff inspection.
70-
71-## Documentation
72-
73-Update the README sections for `/settings` and `/compact` to list the presets, default, immediate application, and the fact that `off` does not disable payload-too-large recovery.
@@ -1,73 +0,0 @@
1-# Configurable Auto-Compact Threshold
2-
3-## Goal
4-
5-Let users choose when Zot automatically compacts an interactive transcript from the existing `/settings` dialog, while preserving the current 85% behavior by default.
6-
7-## User Experience
8-
9-Add a top-level `/settings` option named **auto-compact threshold** with these choices:
10-
11-- `off`
12-- `70%`
13-- `80%`
14-- `85%` (default)
15-- `90%`
16-
17-Changing the option takes effect for the next turn without restarting Zot.
18-
19-The `off` choice disables context-percentage triggers before and after turns. It does not disable:
20-
21-- manual `/compact`
22-- explicit RPC or SDK compaction
23-- automatic compaction and retry after an HTTP 413 or equivalent payload-too-large response
24-
25-## Configuration
26-
27-Persist the selected percentage in `$ZOT_HOME/config.json` as:
28-
29-```json
30-{
31- "auto_compact_threshold": 85
32-}
33-```
34-
35-The field is an optional integer percentage:
36-
37-- A missing field resolves to `85` for backward compatibility.
38-- `0` represents `off`.
39-- Valid non-zero values are `70`, `80`, `85`, and `90`.
40-- Any other persisted value resolves to `85` at runtime.
41-- When a user selects a setting in the TUI, Zot writes only one of the supported values.
42-
43-## Implementation Boundaries
44-
45-The interactive host continues to own automatic triggering. `core.Agent.Compact`, RPC, SDK, bot, print, and JSON mode behavior remain unchanged.
46-
47-Replace the hard-coded `0.85` comparison with a helper that resolves the configured integer percentage and compares the most recent context usage against the model's advertised context window. A resolved value of `0` returns false for percentage-based checks.
48-
49-The payload-too-large recovery path continues to invoke automatic compaction independently of the configured percentage.
50-
51-The settings dialog uses its existing fixed-option picker. No free-form numeric input or new dialog control is introduced.
52-
53-## Error Handling
54-
55-Configuration writes use the existing settings-store error path and show failures in the TUI status area. An invalid value already present in `config.json` does not prevent startup; Zot falls back to 85%.
56-
57-## Tests
58-
59-Add focused tests covering:
60-
61-- missing configuration resolves to 85%
62-- every supported preset resolves correctly
63-- invalid persisted values resolve to 85%
64-- `off` suppresses percentage-triggered compaction
65-- threshold comparison uses the selected percentage
66-- the settings store persists the selected integer
67-- the settings dialog exposes all presets with 85% selected by default
68-
69-Run the focused package tests during development, then `gofmt`, `go test ./...`, `go vet ./...`, `git diff --check`, and final status/diff inspection.
70-
71-## Documentation
72-
73-Update the README sections for `/settings` and `/compact` to list the presets, default, immediate application, and the fact that `off` does not disable payload-too-large recovery.
D docs/superpowers/specs/2026-08-04-terminal-alerts-design.md +0 -77
@@ -1,77 +0,0 @@
1-# Terminal Alerts and Extension Bells
2-
3-## Goal
4-
5-Provide a reusable host alert boundary for the interactive terminal. The first alert kind is a terminal bell, emitted as `\a` only by the interactive host.
6-
7-The same alert policy serves the main agent session and trusted, user-installed extensions that need to draw attention to an interactive question or panel.
8-
9-## User Experience
10-
11-The main interactive session emits one bell after a submitted main-agent run becomes idle and the paced final response has finished rendering when the outcome needs attention:
12-
13-- normal final answer
14-- output-limit/truncated response
15-- non-recoverable provider error
16-- rescue dialog opened after a recoverable provider error
17-
18-The bell is suppressed for explicit cancellation, automatic compaction/retry, and work immediately followed by another queued turn. `/btw`, Telegram, SDK, JSON, print, stream, RPC, and swarm-agent modes do not write raw terminal bell bytes.
19-
20-Users can disable both main-agent and extension terminal alerts from `/settings`. Alerts are enabled by default when the configuration field is missing.
21-
22-## Public Extension Surface
23-
24-Extensions send a fire-and-forget structured alert frame:
25-
26-```json
27-{"type":"alert","kind":"bell","reason":"question_ready"}
28-```
29-
30-The Go extension SDK exposes the equivalent `Extension.Alert(AlertRequest)` method. The host-side alert hook is optional so existing `HostHooks` embedders remain compatible. `kind` is initially `bell`; `reason` is semantic metadata and is not rendered as terminal text. Extensions never provide raw terminal bytes, ANSI sequences, counts, or sound patterns.
31-
32-The host owns the output policy. Interactive mode writes a standalone BEL byte through its injected `tui.Terminal`; non-interactive hosts remain byte-clean and may ignore or translate the request.
33-
34-## Configuration
35-
36-Persist the shared policy in `$ZOT_HOME/config.json`:
37-
38-```json
39-{"terminal_alerts_enabled": true}
40-```
41-
42-The optional boolean resolves as follows:
43-
44-- missing or `null`: enabled
45-- `true`: enabled
46-- `false`: disabled
47-
48-The setting applies immediately to the current interactive session and persists for future sessions.
49-
50-## Lifecycle Boundary
51-
52-The main-agent alert is scheduled from the interactive `startTurnRequest` completion path, not from `core.Agent` events. `EvTurnEnd` is one model step and `EvDone` is not emitted on every error path. The final outcome is tracked from both the last turn event and the returned `Prompt`/`Continue` error.
53-
54-A pending main-agent alert waits for the streaming pacer to drain `streamPending`. If a new queued/recovery turn begins before the drain completes, the pending alert is discarded. The bell is emitted only after the host is truly idle.
55-
56-## Extension Routing
57-
58-`packages/agent/extproto` defines the alert wire frame. `packages/agent/extensions` routes it through the optional `AlertHostHooks` extension to `HostHooks`. Interactive mode applies the shared setting and terminal output. RPC mode translates extension alerts into an `ext_alert` JSON event; print, stream, JSON, Telegram, and other non-interactive hosts do not write BEL to their data streams.
59-
60-Unknown alert kinds are ignored by the interactive renderer. The wire shape is additive and permits future host alert kinds without exposing terminal implementation details.
61-
62-## Tests
63-
64-Cover:
65-
66-- BEL writes as a standalone byte through an injected writer
67-- extension SDK emits the structured alert frame
68-- extension manager routes alert frames to host hooks
69-- disabled terminal alerts suppress both main and extension alerts
70-- missing configuration enables alerts
71-- main completion alerts wait for paced output to drain
72-- cancellation, recovery, queue, and side-chat paths do not produce an unwanted main bell
73-- RPC alert translation does not emit raw BEL
74-
75-## Documentation
76-
77-Document the `/settings` terminal-alert toggle and the extension alert frame/SDK method in `README.md` and `docs/extensions.md`. State that terminal bells depend on terminal emulator settings and may be audible, visual, or suppressed by the host terminal.
@@ -1,77 +0,0 @@
1-# Terminal Alerts and Extension Bells
2-
3-## Goal
4-
5-Provide a reusable host alert boundary for the interactive terminal. The first alert kind is a terminal bell, emitted as `\a` only by the interactive host.
6-
7-The same alert policy serves the main agent session and trusted, user-installed extensions that need to draw attention to an interactive question or panel.
8-
9-## User Experience
10-
11-The main interactive session emits one bell after a submitted main-agent run becomes idle and the paced final response has finished rendering when the outcome needs attention:
12-
13-- normal final answer
14-- output-limit/truncated response
15-- non-recoverable provider error
16-- rescue dialog opened after a recoverable provider error
17-
18-The bell is suppressed for explicit cancellation, automatic compaction/retry, and work immediately followed by another queued turn. `/btw`, Telegram, SDK, JSON, print, stream, RPC, and swarm-agent modes do not write raw terminal bell bytes.
19-
20-Users can disable both main-agent and extension terminal alerts from `/settings`. Alerts are enabled by default when the configuration field is missing.
21-
22-## Public Extension Surface
23-
24-Extensions send a fire-and-forget structured alert frame:
25-
26-```json
27-{"type":"alert","kind":"bell","reason":"question_ready"}
28-```
29-
30-The Go extension SDK exposes the equivalent `Extension.Alert(AlertRequest)` method. The host-side alert hook is optional so existing `HostHooks` embedders remain compatible. `kind` is initially `bell`; `reason` is semantic metadata and is not rendered as terminal text. Extensions never provide raw terminal bytes, ANSI sequences, counts, or sound patterns.
31-
32-The host owns the output policy. Interactive mode writes a standalone BEL byte through its injected `tui.Terminal`; non-interactive hosts remain byte-clean and may ignore or translate the request.
33-
34-## Configuration
35-
36-Persist the shared policy in `$ZOT_HOME/config.json`:
37-
38-```json
39-{"terminal_alerts_enabled": true}
40-```
41-
42-The optional boolean resolves as follows:
43-
44-- missing or `null`: enabled
45-- `true`: enabled
46-- `false`: disabled
47-
48-The setting applies immediately to the current interactive session and persists for future sessions.
49-
50-## Lifecycle Boundary
51-
52-The main-agent alert is scheduled from the interactive `startTurnRequest` completion path, not from `core.Agent` events. `EvTurnEnd` is one model step and `EvDone` is not emitted on every error path. The final outcome is tracked from both the last turn event and the returned `Prompt`/`Continue` error.
53-
54-A pending main-agent alert waits for the streaming pacer to drain `streamPending`. If a new queued/recovery turn begins before the drain completes, the pending alert is discarded. The bell is emitted only after the host is truly idle.
55-
56-## Extension Routing
57-
58-`packages/agent/extproto` defines the alert wire frame. `packages/agent/extensions` routes it through the optional `AlertHostHooks` extension to `HostHooks`. Interactive mode applies the shared setting and terminal output. RPC mode translates extension alerts into an `ext_alert` JSON event; print, stream, JSON, Telegram, and other non-interactive hosts do not write BEL to their data streams.
59-
60-Unknown alert kinds are ignored by the interactive renderer. The wire shape is additive and permits future host alert kinds without exposing terminal implementation details.
61-
62-## Tests
63-
64-Cover:
65-
66-- BEL writes as a standalone byte through an injected writer
67-- extension SDK emits the structured alert frame
68-- extension manager routes alert frames to host hooks
69-- disabled terminal alerts suppress both main and extension alerts
70-- missing configuration enables alerts
71-- main completion alerts wait for paced output to drain
72-- cancellation, recovery, queue, and side-chat paths do not produce an unwanted main bell
73-- RPC alert translation does not emit raw BEL
74-
75-## Documentation
76-
77-Document the `/settings` terminal-alert toggle and the extension alert frame/SDK method in `README.md` and `docs/extensions.md`. State that terminal bells depend on terminal emulator settings and may be audible, visual, or suppressed by the host terminal.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 476

↑↓ moveenter openesc close