@hank-warren/pi-statusline 0.4.1 → 0.4.2
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 +6 -0
- package/README.md +20 -0
- package/package.json +1 -1
- package/settings.ts +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @hank-warren/pi-statusline
|
|
2
2
|
|
|
3
|
+
## 0.4.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1e25d6b: Guard against a setting being added without being registered for persistence. `SETTING_KEYS` feeds the per-key diff behind every save, so a key missing from it applied live and then silently failed to persist. Omitting one is now a `tsc` error naming the key, plus a test asserting the list matches `defaultSettings()`. Adds an "Adding a setting" checklist and the cross-version compatibility rules to the README.
|
|
8
|
+
|
|
3
9
|
## 0.4.1
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -30,6 +30,26 @@ Settings live in a single global file, `~/.pi/agent/statusline-settings.json`, w
|
|
|
30
30
|
|
|
31
31
|
Saves are per-key rather than whole-file: a change writes only the fields it actually touched over whatever is on disk at that moment. Sessions load settings once at startup, so a whole-file write would let a session that started hours ago revert edits it never saw — including hand edits and changes made in another session. Opening `/statusline` also re-reads the file first, so the menu always edits current state. Two sessions changing the *same* field are still last-writer-wins; everything else merges.
|
|
32
32
|
|
|
33
|
+
### Adding a setting
|
|
34
|
+
|
|
35
|
+
A setting is persisted, validated, diffed, and rendered in separate places, so add it to all of them:
|
|
36
|
+
|
|
37
|
+
1. `StatuslineSettings` in `settings.ts` — plus `BOOLEAN_SETTING_KEYS` if it is a toggle.
|
|
38
|
+
2. `defaultSettings()`.
|
|
39
|
+
3. `normalizeSettings()` — the `known` key set, and a parse branch that falls back to the default for an invalid value rather than discarding the whole file.
|
|
40
|
+
4. `serializeSettings()` — write it only when it differs from its default, keeping the file sparse.
|
|
41
|
+
5. `SETTING_KEYS`.
|
|
42
|
+
6. A row in `buildSettingItems()` and a branch in `applySettingChange()` in `settings-menu.ts`, placed in the order the element renders.
|
|
43
|
+
7. Live-apply handling in `applySettings()` in `index.ts`, if the change needs more than a repaint (disposing a poller, forcing a full redraw on a row-count change).
|
|
44
|
+
|
|
45
|
+
Steps 1 and 5 are enforced: omitting the key from `SETTING_KEYS` fails `npm run typecheck` by name, and a test asserts it matches the keys of `defaultSettings()`. Nothing enforces steps 3, 4, 6 or 7 — a setting missing from `serializeSettings` applies live and never persists.
|
|
46
|
+
|
|
47
|
+
Compatibility rules, because old and new versions share one file:
|
|
48
|
+
|
|
49
|
+
- **Never change a key's type or meaning — add a sibling key.** This is why `showCacheCelebration` stayed a boolean when it gained animation styles: an older version reading a repurposed key falls back to its default and can write that fallback back.
|
|
50
|
+
- **Unknown keys survive an older version; unknown *values* do not.** A theme name a reader does not recognise falls back to `default`, and a whole-file write from that reader drops the choice. Extending a cosmetic enum is fine; encoding behaviour in one is riskier than adding a key.
|
|
51
|
+
- **Keep settings independent.** Per-key saves mean two fields can be written by different sessions at different times, so resolve any relationship between settings at render time, not on disk.
|
|
52
|
+
|
|
33
53
|
## Themes
|
|
34
54
|
|
|
35
55
|
| Name | Notes |
|
package/package.json
CHANGED
package/settings.ts
CHANGED
|
@@ -176,6 +176,17 @@ export const SETTING_KEYS = [
|
|
|
176
176
|
|
|
177
177
|
export type SettingKey = (typeof SETTING_KEYS)[number];
|
|
178
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Compile-time completeness guard.
|
|
181
|
+
*
|
|
182
|
+
* `satisfies readonly (keyof StatuslineSettings)[]` above only proves the listed
|
|
183
|
+
* keys are real; it does not prove every key is listed. That gap is silent and
|
|
184
|
+
* expensive: SETTING_KEYS feeds changedSettingKeys, which feeds every save, so a
|
|
185
|
+
* setting missing from it works all session and then vanishes on restart.
|
|
186
|
+
*/
|
|
187
|
+
type Unlisted<Key extends never> = Key;
|
|
188
|
+
type _EverySettingKeyIsListed = Unlisted<Exclude<keyof StatuslineSettings, SettingKey>>;
|
|
189
|
+
|
|
179
190
|
/** The keys one edit actually touched; the unit of a merging save. */
|
|
180
191
|
export function changedSettingKeys(
|
|
181
192
|
previous: StatuslineSettings,
|