@promptctl/cc-candybar 1.41.3 → 1.42.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptctl/cc-candybar",
3
- "version": "1.41.3",
3
+ "version": "1.42.0",
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,9 +91,9 @@
91
91
  "mobx": "^6.15.0"
92
92
  },
93
93
  "optionalDependencies": {
94
- "@promptctl/cc-candybar-darwin-arm64": "1.41.3",
95
- "@promptctl/cc-candybar-darwin-x64": "1.41.3",
96
- "@promptctl/cc-candybar-linux-x64": "1.41.3",
97
- "@promptctl/cc-candybar-linux-arm64": "1.41.3"
94
+ "@promptctl/cc-candybar-darwin-arm64": "1.42.0",
95
+ "@promptctl/cc-candybar-darwin-x64": "1.42.0",
96
+ "@promptctl/cc-candybar-linux-x64": "1.42.0",
97
+ "@promptctl/cc-candybar-linux-arm64": "1.42.0"
98
98
  }
99
99
  }
@@ -0,0 +1,8 @@
1
+ // [LAW:one-source-of-truth] The bare flags Node answers itself. The dispatch in
2
+ // index.ts reads it, `--help` renders its own lines from it, and the Rust client
3
+ // routes exactly these to Node (its NODE_FLAGS; check-protocol diffs the two),
4
+ // so a spelling added here without its mirror fails the build, not the user.
5
+ export const NODE_FLAGS = {
6
+ help: ["-h", "--help"],
7
+ version: ["-V", "--version"],
8
+ } as const;
@@ -64,6 +64,7 @@ export function formatStats(s: StatsSnapshot): string {
64
64
  lines.push(`process`);
65
65
  lines.push(` pid ${s.pid}`);
66
66
  lines.push(` version ${s.version}`);
67
+ lines.push(` protocol ${s.protocolVersion}`);
67
68
  lines.push(` startedAt ${s.startedAt}`);
68
69
  lines.push(` uptime ${fmtUptime(s.uptimeSec)}`);
69
70
  lines.push(` rss ${fmtBytes(s.rssBytes)}`);
@@ -5,6 +5,7 @@
5
5
  import type { LaunchCategory } from "../proc/launch";
6
6
  import type { LaunchStatsHandle } from "../proc/stats-handle";
7
7
  import { PROTOCOL_VERSION } from "./protocol";
8
+ import { PACKAGE_VERSION } from "../version";
8
9
 
9
10
  // Rolling window for "last minute" counts. Keep timestamps for each launch in
10
11
  // a ring buffer; eviction happens lazily on read.
@@ -28,7 +29,11 @@ const HISTOGRAM_CAP = 16;
28
29
 
29
30
  export interface StatsSnapshot {
30
31
  pid: number;
31
- version: number;
32
+ // [LAW:one-source-of-truth] The daemon's own baked package stamp — set
33
+ // against `cc-candybar --version` to diagnose client-vs-daemon skew in one
34
+ // step. The wire contract number is a different fact under its own name.
35
+ version: string;
36
+ protocolVersion: number;
32
37
  startedAt: string;
33
38
  uptimeSec: number;
34
39
  rssBytes: number;
@@ -199,7 +204,8 @@ export class RuntimeStats {
199
204
  const mem = process.memoryUsage();
200
205
  return {
201
206
  pid: process.pid,
202
- version: PROTOCOL_VERSION,
207
+ version: PACKAGE_VERSION,
208
+ protocolVersion: PROTOCOL_VERSION,
203
209
  startedAt: this.startedAt.toISOString(),
204
210
  uptimeSec: Math.floor((Date.now() - this.startedAt.getTime()) / 1000),
205
211
  rssBytes: mem.rss,
package/src/help-text.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { DISCLOSURE_GLYPH_CLOSED } from "./config/disclosure";
2
2
  import { HELP_GLYPH_CLOSED } from "./config/help";
3
+ import { NODE_FLAGS } from "./cli-flags";
3
4
 
4
5
  // [LAW:effects-at-boundaries] Pure data, no I/O — index.ts owns the console.log
5
6
  // effect. Kept as its own module so the text is importable (and testable) without
@@ -36,7 +37,8 @@ cc-candybar - Beautiful powerline statusline for Claude Code
36
37
  Usage: cc-candybar [options]
37
38
 
38
39
  Standalone Commands:
39
- -h, --help Show this help
40
+ ${NODE_FLAGS.help.join(", ").padEnd(25)}Show this help
41
+ ${NODE_FLAGS.version.join(", ").padEnd(25)}Print the version of this runtime (cc-candybar <version>)
40
42
 
41
43
  Debugging:
42
44
  CC_CANDYBAR_DEBUG=1 Enable debug logging for troubleshooting
package/src/index.ts CHANGED
@@ -16,6 +16,8 @@ import { runCheck } from "./check";
16
16
  import { obtainDaemonKick } from "./daemon/acquire";
17
17
  import { planOutcome } from "./render/outcome-plan";
18
18
  import { HELP_TEXT } from "./help-text";
19
+ import { NODE_FLAGS } from "./cli-flags";
20
+ import { PACKAGE_VERSION } from "./version";
19
21
 
20
22
  // Read terminal width from the live shell context (no subprocess). Returns
21
23
  // undefined when nothing reliable is available; the daemon falls back to its
@@ -52,6 +54,9 @@ function detectTermCols(): number | undefined {
52
54
  // widen recall of a fact that is otherwise reported as a plain `false`.
53
55
  const SSH_ENV_VARS = ["SSH_CONNECTION", "SSH_CLIENT", "SSH_TTY"] as const;
54
56
 
57
+ const hasFlag = (flags: readonly string[]): boolean =>
58
+ flags.some((f) => process.argv.includes(f));
59
+
55
60
  // [LAW:dataflow-not-control-flow] A fold over the vocabulary, not a chain of
56
61
  // ifs — adding a name is a data edit.
57
62
  //
@@ -69,13 +74,18 @@ function showHelpText(): void {
69
74
 
70
75
  async function main(): Promise<void> {
71
76
  try {
72
- const showHelp =
73
- process.argv.includes("--help") || process.argv.includes("-h");
74
-
75
- if (showHelp) {
77
+ if (hasFlag(NODE_FLAGS.help)) {
76
78
  showHelpText();
77
79
  process.exit(0);
78
80
  }
81
+ // [LAW:one-type-per-behavior] Answers "what is THIS binary" from the baked
82
+ // stamp alone — never a daemon probe, which would fail exactly when the
83
+ // flag is most needed (no working daemon). Daemon skew is the stats
84
+ // snapshot's `version` field.
85
+ if (hasFlag(NODE_FLAGS.version)) {
86
+ console.log(`cc-candybar ${PACKAGE_VERSION}`);
87
+ process.exit(0);
88
+ }
79
89
 
80
90
  // [LAW:dataflow-not-control-flow] Subcommand dispatch is data: argv[2]
81
91
  // selects the handler. Each handler short-circuits via process.exit().
@@ -8,12 +8,7 @@ import type { PermanentOutcome } from "../daemon/client-transport";
8
8
  import { obtainDaemonKick } from "../daemon/acquire";
9
9
  import { URL_SCHEME, VERB_COPY } from "../click/wire";
10
10
  import { DISCLOSURE_GLYPH_CLOSED } from "../config/disclosure";
11
-
12
- // [LAW:one-source-of-truth] Replaced at build time by tsdown's `define` option
13
- // from package.json — the single version stamp install output reports.
14
- declare const __PACKAGE_VERSION__: string;
15
- const PACKAGE_VERSION =
16
- typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : "dev";
11
+ import { PACKAGE_VERSION } from "../version";
17
12
 
18
13
  const PACKAGE_NAME = "@promptctl/cc-candybar";
19
14
  const BUNDLE_ID = "com.cccandybar.url-handler";
package/src/version.ts ADDED
@@ -0,0 +1,17 @@
1
+ // [LAW:one-source-of-truth] THE version stamp of this runtime. package.json is
2
+ // the sole authority: tsdown's `define` bakes it into the bundle, and
3
+ // scripts/version-stamp.cjs preloads it for untranspiled source. Every consumer
4
+ // — `--version`, the install banner, the daemon's stats snapshot — reads this
5
+ // one export.
6
+ declare const __PACKAGE_VERSION__: string;
7
+
8
+ // [LAW:no-silent-failure] A runtime that cannot say what it is must say THAT.
9
+ // The old `"dev"` fallback was an answer-shaped void in a flag whose whole job
10
+ // is answering this question; an unsubstituted build now fails at module load.
11
+ if (typeof __PACKAGE_VERSION__ === "undefined") {
12
+ throw new Error(
13
+ "__PACKAGE_VERSION__ was not substituted: build via tsdown (define), or preload scripts/version-stamp.cjs when running source",
14
+ );
15
+ }
16
+
17
+ export const PACKAGE_VERSION: string = __PACKAGE_VERSION__;