@promptctl/cc-candybar 1.7.0 → 1.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptctl/cc-candybar",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
4
4
  "description": "Statusline renderer for Claude Code — a JSON5-configurable DSL with daemon-cached data sources, byte-clean palette-aware composition, and OSC8 click verbs.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.mjs",
@@ -91,10 +91,10 @@
91
91
  "mobx": "^6.15.0"
92
92
  },
93
93
  "optionalDependencies": {
94
- "@promptctl/cc-candybar-darwin-arm64": "1.7.0",
95
- "@promptctl/cc-candybar-darwin-x64": "1.7.0",
96
- "@promptctl/cc-candybar-linux-x64": "1.7.0",
97
- "@promptctl/cc-candybar-linux-arm64": "1.7.0"
94
+ "@promptctl/cc-candybar-darwin-arm64": "1.7.2",
95
+ "@promptctl/cc-candybar-darwin-x64": "1.7.2",
96
+ "@promptctl/cc-candybar-linux-x64": "1.7.2",
97
+ "@promptctl/cc-candybar-linux-arm64": "1.7.2"
98
98
  },
99
99
  "pnpm": {
100
100
  "supportedArchitectures": {
@@ -30,7 +30,7 @@ import type { DslConfig } from "./dsl-types.js";
30
30
  //
31
31
  // Factored out of the segments' `template` fields so:
32
32
  // (1) the git working-tree counts and status icon can be shared by the two
33
- // git-style segments (git, gitTaculous) without duplication, and
33
+ // git-style segments (git, gitaculous) without duplication, and
34
34
  // (2) the block/weekly threshold cascade can be parameterized on the
35
35
  // variable name without resorting to runtime string surgery.
36
36
 
@@ -543,7 +543,7 @@ export const DEFAULT_DSL_CONFIG = {
543
543
  fg: "foreground",
544
544
  when: '{{ ne .git.branch "" }}',
545
545
  },
546
- gitTaculous: {
546
+ gitaculous: {
547
547
  template:
548
548
  " (git)" +
549
549
  '{{ if ne .git.repoName "" }} {{ .git.repoName }}{{ end }}' +
@@ -750,11 +750,12 @@ export const DEFAULT_DSL_CONFIG = {
750
750
  fg: "foreground",
751
751
  },
752
752
  // The expanded style picker: one full-width page (paged=false) over the
753
- // `applyStyle` option domain — the 3 powerline shapes. closeOnPick folds a
754
- // page-reset into the apply, so a pick reshapes the bar and closes the row
755
- // in one click. The active shape is marked by the picker helper.
753
+ // `applyStyle` option domain — the 3 powerline shapes. closeOnPick defaults
754
+ // false (omitted here), so a pick reshapes the bar live and LEAVES THE ROW
755
+ // OPEN shapes can be tried in a row; the affordance closes. The active
756
+ // shape is marked by the picker helper.
756
757
  stylePicker: {
757
- template: '{{ picker "applyStyle" "stylePage" true false }}',
758
+ template: '{{ picker "applyStyle" "stylePage" }}',
758
759
  bg: "surface",
759
760
  fg: "foreground",
760
761
  },
@@ -22,6 +22,16 @@ import {
22
22
  refResolves,
23
23
  } from "./refs.js";
24
24
 
25
+ // [LAW:one-source-of-truth] The renamed built-in segments: old name → current
26
+ // name. A user config (which merges on top of the bundled default) that names a
27
+ // renamed segment in `root` finds no matching declaration and would otherwise
28
+ // get the generic "does not match any declared segment" error. This map turns
29
+ // that into a migration pointer [LAW:no-silent-failure] — data, not a per-name
30
+ // branch, so a future rename is one row here, not new control flow.
31
+ export const RENAMED_SEGMENTS: Readonly<Record<string, string>> = {
32
+ gitTaculous: "gitaculous",
33
+ };
34
+
25
35
  export function validateCrossReferences(
26
36
  ctx: ValidateCtx,
27
37
  cfg: DslConfig,
@@ -69,9 +79,14 @@ export function validateCrossReferences(
69
79
  }
70
80
  if (node.kind !== "segment") continue;
71
81
  if (!Object.prototype.hasOwnProperty.call(cfg.segments, node.name)) {
82
+ const renamed = RENAMED_SEGMENTS[node.name];
83
+ const hint =
84
+ renamed !== undefined
85
+ ? ` (the built-in segment "${node.name}" was renamed to "${renamed}" — update this reference)`
86
+ : "";
72
87
  ctx.issues.push({
73
88
  path: layoutKey,
74
- message: `${layoutKey} entry "${node.name}" does not match any declared segment`,
89
+ message: `${layoutKey} entry "${node.name}" does not match any declared segment${hint}`,
75
90
  line: layoutLine,
76
91
  });
77
92
  }
@@ -208,6 +208,17 @@ function renderPicker(
208
208
  // (closeOnPick, paged). Returns T (RichText), the single fragment go-template-js
209
209
  // emits for `{{ picker … }}`.
210
210
  //
211
+ // [LAW:no-mode-explosion] Both bools are OPTIONAL trailing values with a
212
+ // documented default of `false`: `closeOnPick=false` is stay-open (a pick
213
+ // recolors live and LEAVES THE MENU OPEN so themes can be tried in a row — the
214
+ // baseline UX; the ✕ affordance closes), `closeOnPick=true` is the opt-in where a
215
+ // pick ALSO writes the page key closed; `paged=false` is one wrapping page,
216
+ // `paged=true` slices into ←/→ pages at the live width. `enforceArgTypes`
217
+ // validates only the values actually passed (it loops over arity), so an omitted
218
+ // trailing bool arrives `undefined` and resolves to the default here — no arity
219
+ // error, and order is preserved so existing callers (which pass both) are
220
+ // untouched. Authoring stay-open + paged is `{{ picker "a" "p" false true }}`.
221
+ //
211
222
  // [LAW:one-way-deps] The caller injects this FuncMap into createCcCandybarEngine
212
223
  // (capabilities-over-context) so the generic engine never imports the picker.
213
224
  export function pickerFuncs(runtime: ActionRuntime): FuncMap {
@@ -216,9 +227,16 @@ export function pickerFuncs(runtime: ActionRuntime): FuncMap {
216
227
  fn: (
217
228
  applyName: string,
218
229
  pageName: string,
219
- closeOnPick: boolean,
220
- paged: boolean,
221
- ) => renderPicker(applyName, pageName, closeOnPick, paged, runtime),
230
+ closeOnPick?: boolean,
231
+ paged?: boolean,
232
+ ) =>
233
+ renderPicker(
234
+ applyName,
235
+ pageName,
236
+ closeOnPick === true,
237
+ paged === true,
238
+ runtime,
239
+ ),
222
240
  argTypes: ["string", "string", "bool", "bool"],
223
241
  returnType: "T",
224
242
  },
@@ -11,13 +11,21 @@
11
11
  // Variability lives in the inputs (hint set or not, env set or not, stderr a
12
12
  // TTY or not), never in whether work runs.
13
13
 
14
- // @info Reserves characters for Claude Code's right-side UI messages
15
- // (e.g., "Current: 2.1.78 · latest: 2.1.78", "Thinking off")
16
- const RESERVED_CHARS = 45;
14
+ // @info Reserves columns for Claude Code's statusline left gutter. Claude Code
15
+ // prints each statusline row inset by a fixed left margin, so a row rendered at
16
+ // the full raw column count would be shifted right past the terminal edge and
17
+ // soft-wrap its trailing cells. The reserve is exactly that left margin — NOT a
18
+ // right-side overlay budget. The version/autoupdate/"Remote Control" hints render
19
+ // on their own right-aligned lines below the bar and never overlap a statusline
20
+ // row, so they cost zero usable width here. Verified empirically against a live
21
+ // Claude Code statusline (the older value of 45 was a guess for a right-side
22
+ // overlay that does not sit on the statusline row); re-measure if Claude Code's
23
+ // statusline gutter changes.
24
+ const RESERVED_CHARS = 2;
17
25
 
18
26
  // [LAW:single-enforcer] The canonical raw-cols → usable-cols transform.
19
- // Every consumer that needs to honor Claude Code's overlay routes through
20
- // here; there is no parallel `cols - 45` math anywhere. Exposed so callers
27
+ // Every consumer that needs to honor Claude Code's statusline gutter routes
28
+ // through here; there is no parallel `cols - N` math anywhere. Exposed so callers
21
29
  // that already have a raw width (e.g. the daemon's wire-fallback path,
22
30
  // the demo reading process.stdout.columns) can apply the reserve without
23
31
  // re-entering the env/stderr resolution chain in getTerminalWidth.