@promptctl/cc-candybar 1.39.0 → 1.41.0

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.
@@ -52,14 +52,30 @@ export function resolvePaletteName(name: string): string {
52
52
  // default rather than throw or render something the label disagrees with
53
53
  // [LAW:no-silent-failure] — the caller publishes what this returns as
54
54
  // `<field>.effective`, so bar and label always trace to one value.
55
+ //
56
+ // [LAW:one-source-of-truth] `staged` is the RIGHTMOST rung of the precedence
57
+ // chain documented in src/config/presets.ts — a fragment some transient MODE of
58
+ // the bar puts on top while it is on (today: edit mode's `editGlobals`). It
59
+ // outranks even the session pick because it is decided LATER: a user picks a
60
+ // style, then afterwards enters edit mode. That is the same lifetime rule that
61
+ // forced the preset's own position, applied one rung further along, which is
62
+ // why it is a parameter of THIS function rather than a check at any call site —
63
+ // a chain with a rung missing from one field is exactly the drift a single
64
+ // resolver exists to prevent.
65
+ //
66
+ // [LAW:dataflow-not-control-flow] Absent ⇒ `undefined`, which the `??` chain
67
+ // skips by the same code path a session that never clicked skips its own rung.
68
+ // There is no "is edit mode on" branch anywhere below this line; the mode is
69
+ // carried entirely by whether this argument has a value.
55
70
  export function effectiveGlobal<T>(
71
+ staged: T | null | undefined,
56
72
  sessionPick: string | null,
57
73
  configDefault: T | null | undefined,
58
74
  floor: T,
59
75
  parseSession: (raw: string) => T | null,
60
76
  ): T {
61
77
  const picked = sessionPick === null ? null : parseSession(sessionPick);
62
- return picked ?? configDefault ?? floor;
78
+ return staged ?? picked ?? configDefault ?? floor;
63
79
  }
64
80
 
65
81
  // The theme name a render should use, as data.
@@ -70,10 +86,12 @@ export function effectiveGlobal<T>(
70
86
  // parse is identity: there is no membership to check here, and pretending
71
87
  // otherwise would collapse names `paletteForThemeName` handles fine.
72
88
  export function effectiveThemeName(
89
+ stagedPalette: string | undefined,
73
90
  sessionTheme: string | null,
74
91
  globalsPalette: string | undefined,
75
92
  ): string {
76
93
  return effectiveGlobal(
94
+ stagedPalette,
77
95
  sessionTheme,
78
96
  globalsPalette,
79
97
  "textual-dark",
@@ -110,7 +128,12 @@ export function listResolvablePaletteNames(): readonly string[] {
110
128
  //
111
129
  // The floor's membership is a load-time guarantee, not a runtime hope: the
112
130
  // bundled stdlib ships it and merge-by-name cannot remove it.
131
+ //
132
+ // The staged rung runs through the SAME membership parse the other two do: a
133
+ // fragment naming a member the config does not declare is no more a pick than a
134
+ // stale session entry is, and collapses one rung onward rather than throwing.
113
135
  export function effectiveMemberName(
136
+ stagedName: string | undefined,
114
137
  sessionPick: string | null,
115
138
  configDefault: string | undefined,
116
139
  floor: string,
@@ -119,6 +142,7 @@ export function effectiveMemberName(
119
142
  const member = (raw: string): string | null =>
120
143
  Object.prototype.hasOwnProperty.call(declared, raw) ? raw : null;
121
144
  return effectiveGlobal(
145
+ stagedName === undefined ? null : member(stagedName),
122
146
  sessionPick,
123
147
  member(configDefault ?? floor),
124
148
  floor,
@@ -133,11 +157,18 @@ export function effectiveMemberName(
133
157
  // carries. A named wrapper (not a bare call at each site) so the floor is
134
158
  // spelled once and the three call sites cannot disagree about it.
135
159
  export function effectiveLookName(
160
+ stagedLook: string | undefined,
136
161
  sessionLook: string | null,
137
162
  globalsLook: string | undefined,
138
163
  declaredLooks: Readonly<Record<string, ThemeKey>>,
139
164
  ): string {
140
- return effectiveMemberName(sessionLook, globalsLook, "none", declaredLooks);
165
+ return effectiveMemberName(
166
+ stagedLook,
167
+ sessionLook,
168
+ globalsLook,
169
+ "none",
170
+ declaredLooks,
171
+ );
141
172
  }
142
173
 
143
174
  // [LAW:single-enforcer] The one place an effective look NAME becomes the
@@ -196,11 +227,16 @@ export function isStripStyle(value: string): value is StripStyle {
196
227
  // [LAW:one-source-of-truth]; test/session-globals.test.ts pins it with a stale
197
228
  // pick over a valid non-floor default, the case the old tests never exercised.
198
229
  export function effectiveStripStyle(
230
+ stagedStyle: StripStyle | undefined,
199
231
  sessionStyle: string | null,
200
232
  globalsStyle: StripStyle | undefined,
201
233
  ): StripStyle {
202
- return effectiveGlobal(sessionStyle, globalsStyle, "powerline", (raw) =>
203
- isStripStyle(raw) ? raw : null,
234
+ return effectiveGlobal(
235
+ stagedStyle,
236
+ sessionStyle,
237
+ globalsStyle,
238
+ "powerline",
239
+ (raw) => (isStripStyle(raw) ? raw : null),
204
240
  );
205
241
  }
206
242
 
@@ -323,10 +359,12 @@ function parsePadding(raw: string): number | null {
323
359
  // Whether a render wraps over-wide rows, as data. The session's pick over the
324
360
  // config default over the on floor — `effectiveGlobal` with a boolean domain.
325
361
  export function effectiveAutoWrap(
362
+ stagedAutoWrap: boolean | undefined,
326
363
  sessionAutoWrap: string | null,
327
364
  globalsAutoWrap: boolean | undefined,
328
365
  ): boolean {
329
366
  return effectiveGlobal(
367
+ stagedAutoWrap,
330
368
  sessionAutoWrap,
331
369
  globalsAutoWrap,
332
370
  DEFAULT_WRAP,
@@ -341,10 +379,12 @@ export function effectiveAutoWrap(
341
379
  // own default is the honest answer rather than a render at a width nobody
342
380
  // chose.
343
381
  export function effectivePadding(
382
+ stagedPadding: number | undefined,
344
383
  sessionPadding: string | null,
345
384
  globalsPadding: number | undefined,
346
385
  ): number {
347
386
  return effectiveGlobal(
387
+ stagedPadding,
348
388
  sessionPadding,
349
389
  globalsPadding,
350
390
  DEFAULT_PADDING,