@promptctl/cc-candybar 1.37.0 → 1.38.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.
- package/dist/index.mjs +96 -93
- package/package.json +5 -5
- package/schema/cc-candybar.schema.json +124 -0
- package/src/click/wire.ts +10 -1
- package/src/config/action.ts +110 -1
- package/src/config/default-dsl-config.ts +64 -243
- package/src/config/loader/actions.ts +138 -61
- package/src/config/loader/cross-ref.ts +48 -10
- package/src/config/loader/globals.ts +40 -0
- package/src/config/settings-menu.ts +338 -16
- package/src/daemon/verbs/config-validators.ts +14 -11
- package/src/daemon/verbs/index.ts +39 -3
- package/src/daemon/verbs/state-validators.ts +26 -8
- package/src/help-text.ts +6 -3
- package/src/install/index.ts +2 -2
- package/src/render/action.ts +199 -45
- package/src/render/picker.ts +34 -32
- package/src/themes/policy.ts +21 -4
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
|
|
29
29
|
import type { DslConfig, LayoutNode, SegmentDecl } from "./dsl-types.js";
|
|
30
30
|
import { parseDslConfig } from "./dsl-loader.js";
|
|
31
|
-
import { BOOLEAN_MEMBERS, PADDING_RANGE } from "../themes/policy.js";
|
|
32
31
|
import { mergeWithDefault } from "./loader/merge.js";
|
|
33
32
|
|
|
34
33
|
// ─── Shared template fragments ───────────────────────────────────────────────
|
|
@@ -247,17 +246,22 @@ function etaHeatFg(etaRef: string, warnRef: string): string {
|
|
|
247
246
|
// hand-authored JSON5, so a malformed group is still caught loudly at import
|
|
248
247
|
// time — the type safety net just moves from tsc to that parse, never lost.
|
|
249
248
|
//
|
|
250
|
-
// One collapsed-by-default drawer holding
|
|
251
|
-
//
|
|
252
|
-
//
|
|
253
|
-
//
|
|
254
|
-
//
|
|
255
|
-
//
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
//
|
|
259
|
-
//
|
|
260
|
-
//
|
|
249
|
+
// One collapsed-by-default drawer holding what the SESSION-scoped settings
|
|
250
|
+
// menu deliberately does not: `charset` and `colorCompatibility` — terminal
|
|
251
|
+
// capability facts (glyph coverage, colour depth) rather than tastes that
|
|
252
|
+
// vary session to session, so they have no session half to choose between —
|
|
253
|
+
// and one segment-scoped persist control (directoryPaletteControl, a
|
|
254
|
+
// per-segment palette pin rather than a whole-bar default).
|
|
255
|
+
//
|
|
256
|
+
// [LAW:one-source-of-truth] candybar-settings-ui-aok.3 moved every setting
|
|
257
|
+
// with BOTH halves — theme/style/look/preset/autoWrap/padding — out of this
|
|
258
|
+
// drawer and into the synthesized settings menu, where each is ONE control
|
|
259
|
+
// whose destination the `persist?` selector chooses. They used to be spelled
|
|
260
|
+
// twice here (`{{ menu "applyTheme" }}` beside `📌{{ menu
|
|
261
|
+
// "applyThemeForever" }}`), which is exactly the second representation that
|
|
262
|
+
// collapse removed. What is left in this drawer is durable-only by nature,
|
|
263
|
+
// not by omission — there is nothing for a persist? selector to choose.
|
|
264
|
+
//
|
|
261
265
|
// Placed as a sibling in row 1's horizontal container, toggled from beside the
|
|
262
266
|
// quick-action tray — see `root` below.
|
|
263
267
|
//
|
|
@@ -267,26 +271,16 @@ function etaHeatFg(etaRef: string, warnRef: string): string {
|
|
|
267
271
|
// root too), so a second `settingsDrawer` reference embedded in a preset's
|
|
268
272
|
// own root would be a SECOND declaration of "settings" and collide with
|
|
269
273
|
// itself, not a reuse of the first. It stays only in the default `root`
|
|
270
|
-
// below; the library presets under `presets:` reach
|
|
271
|
-
//
|
|
272
|
-
//
|
|
273
|
-
//
|
|
274
|
+
// below; the library presets under `presets:` reach it by switching back to
|
|
275
|
+
// the "default" preset from the GLOBAL settings menu, which
|
|
276
|
+
// synthesizeSettingsMenu splices into every preset root
|
|
277
|
+
// (src/config/settings-menu.ts) — never by re-embedding this group.
|
|
274
278
|
const settingsDrawer = {
|
|
275
279
|
kind: "group",
|
|
276
280
|
name: "settings",
|
|
277
|
-
label: "⚙
|
|
281
|
+
label: "⚙ terminal",
|
|
278
282
|
direction: "horizontal",
|
|
279
|
-
children: [
|
|
280
|
-
"themeControl",
|
|
281
|
-
"lookControl",
|
|
282
|
-
"presetControl",
|
|
283
|
-
"styleControl",
|
|
284
|
-
"charsetControl",
|
|
285
|
-
"colorCompatControl",
|
|
286
|
-
"wrapToggleControl",
|
|
287
|
-
"paddingControl",
|
|
288
|
-
"directoryPaletteControl",
|
|
289
|
-
],
|
|
283
|
+
children: ["charsetControl", "colorCompatControl", "directoryPaletteControl"],
|
|
290
284
|
} as unknown as LayoutNode;
|
|
291
285
|
|
|
292
286
|
// ─── The default config ──────────────────────────────────────────────────────
|
|
@@ -309,8 +303,8 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
309
303
|
// catppuccin-latte — a light palette that landed as a drive-by in an
|
|
310
304
|
// unrelated formatting-cleanup commit and read poorly on the dark
|
|
311
305
|
// terminals most users run — after live-clicking every registry theme
|
|
312
|
-
// through the
|
|
313
|
-
// per-row hue-step
|
|
306
|
+
// through the settings menu's theme picker: it stays legible as the
|
|
307
|
+
// per-row hue-step shifts each
|
|
314
308
|
// row's hue, where warmer bases (gruvbox, dracula) drifted toward mud
|
|
315
309
|
// and the pastel ones (rose-pine, atom-one) washed out at this
|
|
316
310
|
// contrast.
|
|
@@ -780,14 +774,7 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
780
774
|
default: 0,
|
|
781
775
|
},
|
|
782
776
|
|
|
783
|
-
//
|
|
784
|
-
// [LAW:one-source-of-truth] `activeStyle` reads the SAME "style" SessionState
|
|
785
|
-
// key the daemon resolves into the strip joiner per render (see
|
|
786
|
-
// effectiveStripStyle wiring in src/daemon/server.ts) — the picker's write
|
|
787
|
-
// and the render's read are one value. Empty default ⇒ the daemon's
|
|
788
|
-
// "powerline" floor is in effect and styleControl shows "(default)".
|
|
789
|
-
activeStyle: { kind: "state", key: "style", default: "" },
|
|
790
|
-
// No page-cursor var: the styleControl {{ menu }} synthesizes its own page
|
|
777
|
+
// No page-cursor var: a {{ menu }} synthesizes its own page
|
|
791
778
|
// cursor (state var + int action, named by menuPageKey) under the reserved
|
|
792
779
|
// menus.* namespace, alongside its open-state.
|
|
793
780
|
},
|
|
@@ -1133,107 +1120,16 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
1133
1120
|
" .metrics.sessionDuration .metrics.messageCount" +
|
|
1134
1121
|
" .metrics.linesAdded .metrics.linesRemoved }}",
|
|
1135
1122
|
},
|
|
1136
|
-
//
|
|
1137
|
-
//
|
|
1138
|
-
//
|
|
1139
|
-
//
|
|
1140
|
-
//
|
|
1141
|
-
//
|
|
1142
|
-
//
|
|
1143
|
-
//
|
|
1144
|
-
//
|
|
1145
|
-
//
|
|
1146
|
-
// render) and stay-open, so shapes can be tried in a row; ▾/✕ collapse.
|
|
1147
|
-
// [LAW:dataflow-not-control-flow] No display state from the provider — the
|
|
1148
|
-
// label is the one "style" value the click writes and the render reads.
|
|
1149
|
-
// Lives inside the settingsDrawer group (candybar-config-engine-71o.4) — not
|
|
1150
|
-
// on `root` directly — so it renders only while the drawer is open.
|
|
1151
|
-
// The 📌 "make default" menu + ↺ reset, one per control below, is
|
|
1152
|
-
// styleControl/themeControl/lookControl's PERSIST twin (candybar-config-
|
|
1153
|
-
// engine-71o.5) — the exact pairing charsetControl/colorCompatControl/
|
|
1154
|
-
// wrapToggleControl/paddingControl already use, since theme/style/look
|
|
1155
|
-
// are the only three of the drawer's seven knobs with a session `set`
|
|
1156
|
-
// half at all. Its own "pickersForever" accordion key keeps the
|
|
1157
|
-
// persist tier visually distinct from the existing "pickers" try tier
|
|
1158
|
-
// (opening a session preview and opening a "pin as default" picker are
|
|
1159
|
-
// different intents; auto-closing one when the other opens would
|
|
1160
|
-
// conflate them) without touching the already-shipped/tested "pickers"
|
|
1161
|
-
// accordion's membership.
|
|
1162
|
-
styleControl: {
|
|
1163
|
-
template:
|
|
1164
|
-
"✦ {{ if .activeStyle }}{{ .activeStyle }}{{ else }}(default){{ end }} " +
|
|
1165
|
-
'{{ menu "applyStyle" }} ' +
|
|
1166
|
-
'📌{{ menu "applyStyleForever" (dict "key" "pickersForever") }} ' +
|
|
1167
|
-
'{{ action "resetStyle" "↺" }}',
|
|
1168
|
-
bg: "surface",
|
|
1169
|
-
fg: "foreground",
|
|
1170
|
-
},
|
|
1171
|
-
// Theme control — the palette switcher, wired into the DEFAULT bar
|
|
1172
|
-
// (brandon-theming-8uj.1) so theme selection is discoverable without
|
|
1173
|
-
// reading docs/interaction-authoring.md or hand-authoring a config.
|
|
1174
|
-
// [LAW:one-source-of-truth] The trigger reads `.theme.effective` — the
|
|
1175
|
-
// SAME daemon-resolved name (effectiveThemeName) the rendered basePalette
|
|
1176
|
-
// is built from — so the label and the colors can never drift; unlike
|
|
1177
|
-
// styleControl (no "effective style" input exists), no extra `state`
|
|
1178
|
-
// variable is needed here. Shares the "pickers" accordion key with
|
|
1179
|
-
// lookControl so opening one closes the other, the docs' canonical
|
|
1180
|
-
// two-menu pairing. Moved inside the settingsDrawer group
|
|
1181
|
-
// (candybar-config-engine-71o.4) alongside style/look/charset/
|
|
1182
|
-
// colorCompatibility/autoWrap/padding — one collapsed home for every
|
|
1183
|
-
// bar-mutable display default, instead of its own always-on row.
|
|
1184
|
-
themeControl: {
|
|
1185
|
-
template:
|
|
1186
|
-
"🎨 {{ .theme.effective }} " +
|
|
1187
|
-
'{{ menu "applyTheme" (dict "key" "pickers") }} ' +
|
|
1188
|
-
'📌{{ menu "applyThemeForever" (dict "key" "pickersForever") }} ' +
|
|
1189
|
-
'{{ action "resetTheme" "↺" }}',
|
|
1190
|
-
bg: "surface",
|
|
1191
|
-
fg: "foreground",
|
|
1192
|
-
},
|
|
1193
|
-
// Look control — the theme-ADAPTATION switcher (see the `looks` block
|
|
1194
|
-
// below), the exact twin of themeControl one dimension over:
|
|
1195
|
-
// `.look.effective` is the daemon-resolved name (effectiveLookName) the
|
|
1196
|
-
// rendered ThemeKey composes from. closeOnPick collapses the drop after a
|
|
1197
|
-
// pick — looks are tried one at a time against the chosen theme, not
|
|
1198
|
-
// stacked open.
|
|
1199
|
-
lookControl: {
|
|
1200
|
-
template:
|
|
1201
|
-
"◐ {{ .look.effective }} " +
|
|
1202
|
-
'{{ menu "applyLook" (dict "key" "pickers" "closeOnPick" true) }} ' +
|
|
1203
|
-
'📌{{ menu "applyLookForever" (dict "key" "pickersForever" "closeOnPick" true) }} ' +
|
|
1204
|
-
'{{ action "resetLook" "↺" }}',
|
|
1205
|
-
bg: "surface",
|
|
1206
|
-
fg: "foreground",
|
|
1207
|
-
},
|
|
1208
|
-
// Preset control — the whole-arrangement switcher (brandon-presets-0yk.3),
|
|
1209
|
-
// the exact twin of themeControl/lookControl one level up: `.preset.
|
|
1210
|
-
// effective` is the daemon-resolved name (effectivePresetName) that chose
|
|
1211
|
-
// BOTH the compiled root this render walked and the globals it rendered
|
|
1212
|
-
// with, so the label can never name an arrangement the bar is not in.
|
|
1213
|
-
// closeOnPick on both menus, like lookControl: a preset swap is a
|
|
1214
|
-
// decisive whole-bar change tried one at a time, not a stackable tweak.
|
|
1215
|
-
// Lives inside settingsDrawer (never inside a preset's own staged root —
|
|
1216
|
-
// see settingsDrawer's comment), so every bundled preset — including the
|
|
1217
|
-
// narrow `compact` one — keeps the one control that switches back.
|
|
1218
|
-
presetControl: {
|
|
1219
|
-
template:
|
|
1220
|
-
"▦ {{ .preset.effective }} " +
|
|
1221
|
-
'{{ menu "applyPreset" (dict "key" "pickers" "closeOnPick" true) }} ' +
|
|
1222
|
-
'📌{{ menu "applyPresetForever" (dict "key" "pickersForever" "closeOnPick" true) }} ' +
|
|
1223
|
-
'{{ action "resetPreset" "↺" }}',
|
|
1224
|
-
bg: "surface",
|
|
1225
|
-
fg: "foreground",
|
|
1226
|
-
},
|
|
1227
|
-
// ── The four .3 globals steppers, folded into the settingsDrawer group
|
|
1228
|
-
// (candybar-config-engine-71o.4) alongside theme/style/look above. Each
|
|
1229
|
-
// pairs a `persist` control with a `↺` reset (docs' persist/reset
|
|
1230
|
-
// convention) — `charset`/`colorCompatibility` have no SessionState half
|
|
1231
|
-
// at all, so persist is genuinely their only seam, while
|
|
1232
|
-
// `autoWrap`/`padding` do have one and are simply spelled durable here
|
|
1233
|
-
// (candybar-settings-ui-aok.3 owns whether the panel offers the choice).
|
|
1234
|
-
// Labels
|
|
1235
|
-
// read `.field.effective` (the daemon-resolved value BuildLineOptions
|
|
1236
|
-
// actually rendered with), never a restated literal.
|
|
1123
|
+
// ── The TWO globals steppers left in this drawer. `charset` and
|
|
1124
|
+
// `colorCompatibility` have no SessionState half at all — they describe
|
|
1125
|
+
// the terminal, not a taste that varies per session — so `persist` is
|
|
1126
|
+
// genuinely their only seam and there is no destination for a `persist?`
|
|
1127
|
+
// selector to choose between. Everything with both halves
|
|
1128
|
+
// (theme/style/look/preset/autoWrap/padding) moved to the synthesized
|
|
1129
|
+
// settings menu as ONE dual control each (candybar-settings-ui-aok.3).
|
|
1130
|
+
// Each pairs a `persist` control with a `↺` reset (docs' persist/reset
|
|
1131
|
+
// convention); labels read `.field.effective` (the daemon-resolved value
|
|
1132
|
+
// BuildLineOptions actually rendered with), never a restated literal.
|
|
1237
1133
|
charsetControl: {
|
|
1238
1134
|
template:
|
|
1239
1135
|
"{{ .charset.effective }} " +
|
|
@@ -1248,20 +1144,6 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
1248
1144
|
bg: "surface",
|
|
1249
1145
|
fg: "foreground",
|
|
1250
1146
|
},
|
|
1251
|
-
wrapToggleControl: {
|
|
1252
|
-
template:
|
|
1253
|
-
'{{ action "toggleWrapForever" "wrap: on" "wrap: off" }} ' +
|
|
1254
|
-
'{{ action "resetAutoWrap" "↺" }}',
|
|
1255
|
-
bg: "surface",
|
|
1256
|
-
fg: "foreground",
|
|
1257
|
-
},
|
|
1258
|
-
paddingControl: {
|
|
1259
|
-
template:
|
|
1260
|
-
'{{ action "paddingDownForever" "◀" }} padding {{ .padding.effective }} ' +
|
|
1261
|
-
'{{ action "paddingUpForever" "▶" }} {{ action "resetPadding" "↺" }}',
|
|
1262
|
-
bg: "surface",
|
|
1263
|
-
fg: "foreground",
|
|
1264
|
-
},
|
|
1265
1147
|
// [LAW:verifiable-goals] candybar-config-engine-71o.6's own acceptance
|
|
1266
1148
|
// bar, mirrored from .3/.5: at least ONE segment-scoped field must be
|
|
1267
1149
|
// menu-able from the BUNDLED default with no hand-authored actions.
|
|
@@ -1273,7 +1155,7 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
1273
1155
|
// (loader/persist-target.ts) — the SAME `from: "themes"` domain
|
|
1274
1156
|
// applyThemeForever already uses.
|
|
1275
1157
|
// [LAW:one-source-of-truth] exception: unlike charsetControl/
|
|
1276
|
-
//
|
|
1158
|
+
// the other controls' `.field.effective` labels, there is no
|
|
1277
1159
|
// `segments.directory.palette.effective` payload projection — adding one
|
|
1278
1160
|
// would require threading the full DslConfig through
|
|
1279
1161
|
// buildRenderPayload's signature (today built from EffectiveGlobals
|
|
@@ -1375,70 +1257,19 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
1375
1257
|
openProject: { open: "{{ .project_dir }}" },
|
|
1376
1258
|
openTranscript: { open: "{{ .transcript_path }}" },
|
|
1377
1259
|
|
|
1378
|
-
// [LAW:locality-or-seam] The
|
|
1379
|
-
// styleControl {{ menu }} above. The disclosure's open-state toggle, its
|
|
1380
|
-
// backing state var, AND the picker body's page cursor (state var + int
|
|
1381
|
-
// action) are all SYNTHESIZED by the menu pass (under the reserved menus.*
|
|
1382
|
-
// namespace) — no hand-authored open/close or page plumbing. This one action
|
|
1383
|
-
// is the picker body's apply effect, gated by derivation
|
|
1384
|
-
// (deriveActionValidators): it writes the chosen shape, gated to the
|
|
1385
|
-
// STRIP_STYLES allow-list because its value source is `from: "styles"`. The
|
|
1386
|
-
// rendered click and the wire gate share that one source — a template cannot
|
|
1387
|
-
// smuggle an un-gated style write.
|
|
1388
|
-
applyStyle: { set: "style", from: "styles" },
|
|
1389
|
-
|
|
1390
|
-
// [LAW:locality-or-seam] The theme/look pickers' behaviors, decoupled by
|
|
1391
|
-
// NAME from themeControl/lookControl {{ menu }}s above — same seam as
|
|
1392
|
-
// applyStyle. "theme" is the baseline permanent state key (validateTheme,
|
|
1393
|
-
// registered in state-validators.ts); dropBaselineAllowLists reuses that
|
|
1394
|
-
// gate for an allow-list contribution instead of re-registering it, so
|
|
1395
|
-
// this action derives nothing new. "look" has no baseline entry, so this
|
|
1396
|
-
// action derives a fresh allow-list validator ranging the merged `looks`
|
|
1397
|
-
// block's names — the same derivation test/dsl-looks.test.ts exercises.
|
|
1398
|
-
applyTheme: { set: "theme", from: "themes" },
|
|
1399
|
-
applyLook: { set: "look", from: "looks" },
|
|
1400
|
-
// [LAW:one-type-per-behavior] The preset picker's session-preview
|
|
1401
|
-
// behavior (brandon-presets-0yk.3), the exact twin of applyLook one level
|
|
1402
|
-
// up: "preset" has no baseline SessionState entry, so this derives a
|
|
1403
|
-
// fresh allow-list validator ranging the merged `presets` block's names
|
|
1404
|
-
// (the floor included — presetNames always seeds it) via the same
|
|
1405
|
-
// `from`-sourced derivation every picker above uses.
|
|
1406
|
-
applyPreset: { set: "preset", from: "presets" },
|
|
1407
|
-
|
|
1408
|
-
// [LAW:one-source-of-truth] The persist-forever twins of applyTheme/
|
|
1409
|
-
// applyStyle/applyLook/applyPreset above (candybar-config-engine-71o.5,
|
|
1410
|
-
// brandon-presets-0yk.3) — same domain sources (`from`), same picker
|
|
1411
|
-
// mechanism, but the target is the Globals field the config DEFAULT
|
|
1412
|
-
// reads (`palette`/`style`/`look`/`preset`, isGlobalsField-checked at
|
|
1413
|
-
// load), not the SessionState key the session preview writes.
|
|
1414
|
-
// Precedence is unchanged: a session's own `set` pick still wins over a
|
|
1415
|
-
// persisted default for that session — effectiveThemeName/
|
|
1416
|
-
// effectiveStripStyle/effectiveLookName/effectivePresetName all read
|
|
1417
|
-
// SessionState before globals. Paired with a `reset` each, per the docs'
|
|
1418
|
-
// persist/reset convention.
|
|
1419
|
-
applyThemeForever: { persist: "palette", from: "themes" },
|
|
1420
|
-
resetTheme: { reset: "palette" },
|
|
1421
|
-
applyStyleForever: { persist: "style", from: "styles" },
|
|
1422
|
-
resetStyle: { reset: "style" },
|
|
1423
|
-
applyLookForever: { persist: "look", from: "looks" },
|
|
1424
|
-
resetLook: { reset: "look" },
|
|
1425
|
-
applyPresetForever: { persist: "preset", from: "presets" },
|
|
1426
|
-
resetPreset: { reset: "preset" },
|
|
1427
|
-
|
|
1428
|
-
// [LAW:locality-or-seam] The settings-drawer steppers' behaviors
|
|
1260
|
+
// [LAW:locality-or-seam] The settings-drawer controls' behaviors
|
|
1429
1261
|
// (candybar-config-engine-71o.4), decoupled by NAME from
|
|
1430
|
-
// charsetControl/colorCompatControl
|
|
1431
|
-
//
|
|
1432
|
-
//
|
|
1433
|
-
// SessionState half
|
|
1434
|
-
//
|
|
1435
|
-
//
|
|
1436
|
-
//
|
|
1437
|
-
// config
|
|
1438
|
-
// hand-authored file itself), gated by the SAME
|
|
1439
|
-
// pass
|
|
1440
|
-
//
|
|
1441
|
-
// undoable from the bar, per the docs' persist/reset convention.
|
|
1262
|
+
// charsetControl/colorCompatControl below. These are durable-only by
|
|
1263
|
+
// NATURE, not by omission: `charset` and `colorCompatibility` describe the
|
|
1264
|
+
// terminal (glyph coverage, colour depth) rather than a taste that varies
|
|
1265
|
+
// between sessions, so they have no SessionState half for a `persist?`
|
|
1266
|
+
// selector to choose between — which is exactly why
|
|
1267
|
+
// candybar-settings-ui-aok.3 left them here while moving every
|
|
1268
|
+
// both-halves setting into the settings menu as one dual control. Each
|
|
1269
|
+
// writes the config DEFAULT through the daemon-owned overrides layer
|
|
1270
|
+
// (never the hand-authored file itself), gated by the SAME
|
|
1271
|
+
// deriveConfigActionValidators pass, and is paired with a `reset` so a
|
|
1272
|
+
// drawer choice is always undoable from the bar.
|
|
1442
1273
|
applyCharsetForever: { persist: "charset", from: "charsets" },
|
|
1443
1274
|
resetCharset: { reset: "charset" },
|
|
1444
1275
|
applyColorCompatForever: {
|
|
@@ -1446,15 +1277,6 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
1446
1277
|
from: "colorCompatibilities",
|
|
1447
1278
|
},
|
|
1448
1279
|
resetColorCompat: { reset: "colorCompatibility" },
|
|
1449
|
-
// [LAW:one-source-of-truth] The toggle's members and the stepper's bounds
|
|
1450
|
-
// are the SAME literals the resolvers parse a session pick with
|
|
1451
|
-
// (BOOLEAN_MEMBERS / PADDING_RANGE in themes/policy.ts) — a click cannot
|
|
1452
|
-
// write a value the render's own resolution would then refuse.
|
|
1453
|
-
toggleWrapForever: { persist: "autoWrap", cycle: [...BOOLEAN_MEMBERS] },
|
|
1454
|
-
resetAutoWrap: { reset: "autoWrap" },
|
|
1455
|
-
paddingDownForever: { persist: "padding", ...PADDING_RANGE, by: -1 },
|
|
1456
|
-
paddingUpForever: { persist: "padding", ...PADDING_RANGE, by: 1 },
|
|
1457
|
-
resetPadding: { reset: "padding" },
|
|
1458
1280
|
|
|
1459
1281
|
// [LAW:locality-or-seam] The segment-palette control's behavior
|
|
1460
1282
|
// (candybar-config-engine-71o.6), decoupled by NAME from
|
|
@@ -1462,7 +1284,7 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
1462
1284
|
// palette` — NOT a Globals field — so it rides the SAME generic
|
|
1463
1285
|
// `from`/`reset` machinery every other persist pair here uses, over a
|
|
1464
1286
|
// key namespace loader/persist-target.ts opened alongside the pre-
|
|
1465
|
-
// existing Globals-field one. Like
|
|
1287
|
+
// existing Globals-field one. Like charset/colorCompatibility, this field has
|
|
1466
1288
|
// no SessionState half at all: a per-segment `palette:` is a static pin
|
|
1467
1289
|
// that ignores the session theme by design (src/dsl/render.ts), so
|
|
1468
1290
|
// `persist` is its only seam.
|
|
@@ -1531,10 +1353,10 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
1531
1353
|
// Named config FRAGMENTS — each an alternative `root` + display `globals`,
|
|
1532
1354
|
// i.e. a whole arrangement of the bar rather than one knob. A preset is to
|
|
1533
1355
|
// configuration what a look is to a theme, and rides the identical seam:
|
|
1534
|
-
// selected per session via the `preset` SessionState key
|
|
1535
|
-
//
|
|
1536
|
-
//
|
|
1537
|
-
// globals.preset over this floor.
|
|
1356
|
+
// selected per session via the `preset` SessionState key — or pinned as the
|
|
1357
|
+
// durable default via `globals.preset` — through the settings menu's ONE
|
|
1358
|
+
// dual preset control (src/config/settings-menu.ts), resolved as session
|
|
1359
|
+
// pick over globals.preset over this floor.
|
|
1538
1360
|
// [LAW:one-source-of-truth] Merges by name (user wins per name), so this
|
|
1539
1361
|
// stdlib is present in every merged config by construction, exactly as
|
|
1540
1362
|
// looks' "none"/"vivid"/"muted"/… is — a user redefining "compact" or
|
|
@@ -1573,11 +1395,13 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
1573
1395
|
// `gitaculous`, and `padding: 0` to buy back the chrome a narrow column
|
|
1574
1396
|
// can't spare.
|
|
1575
1397
|
//
|
|
1576
|
-
// [LAW:no-silent-failure]
|
|
1577
|
-
//
|
|
1578
|
-
//
|
|
1579
|
-
//
|
|
1580
|
-
//
|
|
1398
|
+
// [LAW:no-silent-failure] A session that switches TO compact is never
|
|
1399
|
+
// stranded: synthesizeSettingsMenu splices the global settings menu — and
|
|
1400
|
+
// with it the preset switcher — into EVERY preset root, so one click back
|
|
1401
|
+
// to "default" restores everything compact traded away for width. That is
|
|
1402
|
+
// why this root carries no preset control of its own: one guaranteed door
|
|
1403
|
+
// per root, minted once and referenced, not a segment each preset must
|
|
1404
|
+
// remember to carry [LAW:one-source-of-truth].
|
|
1581
1405
|
compact: {
|
|
1582
1406
|
root: {
|
|
1583
1407
|
kind: "container",
|
|
@@ -1586,7 +1410,6 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
1586
1410
|
{ kind: "segment", name: "directory" },
|
|
1587
1411
|
{ kind: "segment", name: "git" },
|
|
1588
1412
|
{ kind: "segment", name: "context" },
|
|
1589
|
-
{ kind: "segment", name: "presetControl" },
|
|
1590
1413
|
],
|
|
1591
1414
|
},
|
|
1592
1415
|
globals: { padding: 0 },
|
|
@@ -1599,10 +1422,9 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
1599
1422
|
// picture rather than the quiet default. A third row carries the two
|
|
1600
1423
|
// per-turn throughput segments, which read "—" between turns
|
|
1601
1424
|
// ([LAW:no-silent-failure] on speed/tokenSparkline) rather than an empty
|
|
1602
|
-
// or stale row.
|
|
1603
|
-
//
|
|
1604
|
-
//
|
|
1605
|
-
// the drawer and every other bar-mutable default from there.
|
|
1425
|
+
// or stale row. Like `compact`, it carries no preset control of its own —
|
|
1426
|
+
// the global settings menu is spliced into every preset root and is the
|
|
1427
|
+
// one door back.
|
|
1606
1428
|
verbose: {
|
|
1607
1429
|
root: {
|
|
1608
1430
|
kind: "container",
|
|
@@ -1616,7 +1438,6 @@ export const RAW_DEFAULT_DSL_CONFIG = {
|
|
|
1616
1438
|
{ kind: "segment", name: "gitaculous" },
|
|
1617
1439
|
{ kind: "segment", name: "gitPr" },
|
|
1618
1440
|
{ kind: "segment", name: "toolbar" },
|
|
1619
|
-
{ kind: "segment", name: "presetControl" },
|
|
1620
1441
|
],
|
|
1621
1442
|
},
|
|
1622
1443
|
{
|
|
@@ -1779,7 +1600,7 @@ const AUTHORED_PALETTE_NAMES = new Set(
|
|
|
1779
1600
|
// the zero-config daemon path (loadConfig: no config file found ⇒ raw={},
|
|
1780
1601
|
// merged directly against this constant — see src/config/dsl-loader.ts and
|
|
1781
1602
|
// src/config/loader/merge.ts) would ship an UNSYNTHESIZED default: a
|
|
1782
|
-
// `{{ menu (dict "key" …) }}` accordion pairing (
|
|
1603
|
+
// `{{ menu (dict "key" …) }}` accordion pairing (the settings menu's pickers,
|
|
1783
1604
|
// brandon-theming-8uj.1) would render its glyph, but clicking it would reject
|
|
1784
1605
|
// with "unknown state key" — the synthesis that derives a menu's `menus.*`
|
|
1785
1606
|
// state var + cycle action only ever ran over TEXT a user typed, never over
|