@sushant-kum/ccstatus 0.1.1 → 0.2.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.
@@ -1,9 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  COLORS,
4
+ LINKABLE,
4
5
  configPath,
5
6
  importCcstatusline,
6
7
  isValidWhen,
8
+ linkedSurfaces,
7
9
  loadConfigFile,
8
10
  readSnapshot,
9
11
  registry,
@@ -11,8 +13,9 @@ import {
11
13
  rendererBg,
12
14
  rendererColor,
13
15
  saveConfigFile,
14
- snapshotPath
15
- } from "./chunk-ZD5C4L7U.js";
16
+ snapshotPath,
17
+ writeLinkedLines
18
+ } from "./chunk-EUAY5IC6.js";
16
19
 
17
20
  // src/app.tsx
18
21
  import { Box as Box12, Text as Text12, useApp, useInput as useInput10 } from "ink";
@@ -307,58 +310,35 @@ function Import({
307
310
  // src/screens/items.tsx
308
311
  import { Box as Box5, Text as Text5, useInput as useInput3 } from "ink";
309
312
  import { useState as useState3 } from "react";
310
-
311
- // src/named-colors.ts
312
- var all = [...COLORS];
313
- var NAMED_COLORS = [
314
- "(none)",
315
- ...all.filter((c) => !c.startsWith("bg")),
316
- ...all.filter((c) => c.startsWith("bg"))
317
- ];
318
-
319
- // src/screens/items.tsx
320
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
321
- var SURFACES = ["band", "statusline", "pane"];
322
- var FIELDS2 = ["fg", "bg", "raw", "merge", "align"];
313
+ import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
314
+ var SURFACES = LINKABLE;
315
+ var FIELDS2 = ["raw", "merge", "align"];
323
316
  var ALIGNS = ["left", "center", "right"];
324
- var FG = NAMED_COLORS.filter((c) => !c.startsWith("bg"));
325
- var BG = ["(none)", ...NAMED_COLORS.filter((c) => c.startsWith("bg"))];
326
317
  var WIDGETS = Object.values(registry);
327
318
  var wrap = (i, n) => (i + n) % n;
319
+ var makeId = (type) => `${type}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
328
320
  var isStylable = (item) => item.type !== "flex-separator";
329
321
  function Chip({ item, selected }) {
330
- const fg = isStylable(item) ? item.fg : void 0;
331
- const bg = isStylable(item) ? item.bg : void 0;
332
- return /* @__PURE__ */ jsxs4(Text5, { inverse: selected, color: inkColor(fg), backgroundColor: inkBg(bg), children: [
322
+ return /* @__PURE__ */ jsxs4(Text5, { inverse: selected, children: [
333
323
  "[ ",
334
324
  item.type,
335
325
  " ]"
336
326
  ] });
337
327
  }
338
- function Swatch({ name, bg }) {
339
- if (!name) {
340
- return /* @__PURE__ */ jsx4(Text5, { dimColor: true, children: "(none)" });
341
- }
342
- return /* @__PURE__ */ jsxs4(Text5, { color: bg ? void 0 : inkColor(name), backgroundColor: bg ? inkBg(name) : void 0, children: [
343
- " ",
344
- name,
345
- " "
346
- ] });
347
- }
348
328
  function Items({ config, setConfig, goHome }) {
349
329
  const [surface, setSurface] = useState3("band");
350
330
  const [sel, setSel] = useState3(0);
351
331
  const [mode, setMode] = useState3("strip");
332
+ const [linkPick, setLinkPick] = useState3(0);
333
+ const [confirm, setConfirm] = useState3(null);
352
334
  const [field, setField] = useState3(0);
353
335
  const [pick, setPick] = useState3(0);
354
336
  const items = config.surfaces[surface].lines[0] ?? [];
355
337
  const cur = items[Math.min(sel, items.length - 1)];
356
338
  const idx = cur ? items.indexOf(cur) : -1;
357
339
  const commit = (next) => {
358
- const s = config.surfaces[surface];
359
- const lines = [next, ...s.lines.slice(1)];
360
- const c = { ...config, surfaces: { ...config.surfaces, [surface]: { ...s, lines } } };
361
- setConfig(c);
340
+ const lines = [next, ...config.surfaces[surface].lines.slice(1)];
341
+ setConfig({ ...config, surfaces: writeLinkedLines(config.surfaces, surface, lines) });
362
342
  };
363
343
  const patch = (p) => {
364
344
  const base = items[idx];
@@ -373,20 +353,12 @@ function Items({ config, setConfig, goHome }) {
373
353
  }
374
354
  commit(items.map((it, i) => i === idx ? item : it));
375
355
  };
376
- const cycleColor = (list, cur2, dir) => {
377
- const n = list[wrap(Math.max(0, list.indexOf(cur2 ?? "(none)")) + dir + list.length, list.length)] ?? "(none)";
378
- return n === "(none)" ? void 0 : n;
379
- };
380
356
  const change = (dir) => {
381
357
  if (!cur || !isStylable(cur)) {
382
358
  return;
383
359
  }
384
360
  const f = FIELDS2[field];
385
- if (f === "fg") {
386
- patch({ fg: cycleColor(FG, cur.fg, dir) });
387
- } else if (f === "bg") {
388
- patch({ bg: cycleColor(BG, cur.bg, dir) });
389
- } else if (f === "raw") {
361
+ if (f === "raw") {
390
362
  patch({ rawValue: !cur.rawValue });
391
363
  } else if (f === "merge") {
392
364
  patch({ merge: !cur.merge });
@@ -410,6 +382,45 @@ function Items({ config, setConfig, goHome }) {
410
382
  commit(next);
411
383
  setSel(j);
412
384
  };
385
+ const others = SURFACES.filter((s) => s !== surface);
386
+ const linkOptions = [
387
+ ...others.map((s) => ({ label: s, targets: [s] })),
388
+ { label: "all others", targets: others }
389
+ ];
390
+ const linkReplacements = (targets) => SURFACES.filter((s) => s !== surface && (targets.includes(s) || config.surfaces[s].linked));
391
+ const applyLink = (targets) => {
392
+ const marked = { ...config.surfaces };
393
+ marked[surface] = { ...config.surfaces[surface], linked: true };
394
+ for (const t of targets) {
395
+ marked[t] = { ...config.surfaces[t], linked: true };
396
+ }
397
+ const surfaces = writeLinkedLines(marked, surface, config.surfaces[surface].lines);
398
+ setConfig({ ...config, surfaces });
399
+ };
400
+ const applyUnlink = () => {
401
+ const layout = config.surfaces[surface];
402
+ if (!layout.linked) {
403
+ return;
404
+ }
405
+ const surfaces = {
406
+ ...config.surfaces,
407
+ [surface]: {
408
+ ...layout,
409
+ linked: false,
410
+ lines: layout.lines.map(
411
+ (line) => line.map((it) => ({ ...it, id: makeId(it.type) }))
412
+ )
413
+ }
414
+ };
415
+ const remaining = linkedSurfaces(surfaces);
416
+ if (remaining.length === 1) {
417
+ const lone = remaining[0];
418
+ if (lone) {
419
+ surfaces[lone] = { ...surfaces[lone], linked: false };
420
+ }
421
+ }
422
+ setConfig({ ...config, surfaces });
423
+ };
413
424
  useInput3((input, key) => {
414
425
  if (mode === "picker") {
415
426
  if (key.escape) {
@@ -422,7 +433,7 @@ function Items({ config, setConfig, goHome }) {
422
433
  const picked = WIDGETS[pick];
423
434
  if (picked) {
424
435
  const type = picked.type;
425
- const id = `${type}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
436
+ const id = makeId(type);
426
437
  const newItem = type === "custom-text" ? { id, type, text: "" } : type === "custom-command" ? { id, type, command: "" } : type === "flex-separator" ? { id, type } : { id, type };
427
438
  commit([...items, newItem]);
428
439
  setSel(items.length);
@@ -441,6 +452,35 @@ function Items({ config, setConfig, goHome }) {
441
452
  } else if (key.rightArrow) {
442
453
  change(1);
443
454
  }
455
+ } else if (mode === "link") {
456
+ if (confirm) {
457
+ if (input === "y") {
458
+ applyLink(confirm);
459
+ setConfirm(null);
460
+ setMode("strip");
461
+ } else if (input === "n" || key.escape) {
462
+ setConfirm(null);
463
+ setMode("strip");
464
+ }
465
+ } else if (key.escape) {
466
+ setMode("strip");
467
+ } else if (key.upArrow) {
468
+ setLinkPick((p) => wrap(p - 1 + linkOptions.length, linkOptions.length));
469
+ } else if (key.downArrow) {
470
+ setLinkPick((p) => wrap(p + 1, linkOptions.length));
471
+ } else if (key.return) {
472
+ const chosen = linkOptions[linkPick];
473
+ if (chosen) {
474
+ const affected = linkReplacements(chosen.targets);
475
+ const nonEmpty = affected.some((t) => config.surfaces[t].lines.some((l) => l.length > 0));
476
+ if (nonEmpty) {
477
+ setConfirm(affected);
478
+ } else {
479
+ applyLink(chosen.targets);
480
+ setMode("strip");
481
+ }
482
+ }
483
+ }
444
484
  } else {
445
485
  if (key.escape) {
446
486
  goHome();
@@ -464,6 +504,12 @@ function Items({ config, setConfig, goHome }) {
464
504
  } else if (input === "e" && idx >= 0) {
465
505
  setField(0);
466
506
  setMode("editor");
507
+ } else if (input === "l") {
508
+ setLinkPick(0);
509
+ setConfirm(null);
510
+ setMode("link");
511
+ } else if (input === "u") {
512
+ applyUnlink();
467
513
  }
468
514
  }
469
515
  });
@@ -482,8 +528,35 @@ function Items({ config, setConfig, goHome }) {
482
528
  s === surface ? `[${s}]` : s,
483
529
  " "
484
530
  ] }, s)) }),
485
- /* @__PURE__ */ jsx4(Box5, { children: items.length === 0 ? /* @__PURE__ */ jsx4(Text5, { dimColor: true, children: "(no items \u2014 press a)" }) : items.map((it, i) => /* @__PURE__ */ jsx4(Chip, { item: it, selected: i === idx }, it.id)) }),
486
- mode === "picker" ? /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", marginTop: 1, children: [
531
+ config.surfaces[surface].linked && /* @__PURE__ */ jsxs4(Text5, { color: "magenta", children: [
532
+ "\u{1F517} linked: ",
533
+ SURFACES.filter((s) => config.surfaces[s].linked).join(", "),
534
+ " \u2014 edits apply to all"
535
+ ] }),
536
+ /* @__PURE__ */ jsx4(Box5, { children: items.length === 0 ? /* @__PURE__ */ jsx4(Text5, { dimColor: true, children: "(no items \u2014 press a)" }) : (
537
+ // Item ids are unique within a surface. Linked surfaces share ids across
538
+ // surfaces (DEC-0018), but only one surface's items render here at a time,
539
+ // so these keys never collide. (The live Preview renders a RenderModel of
540
+ // positional segments — paint.tsx keys by index, not item id.)
541
+ items.map((it, i) => /* @__PURE__ */ jsx4(Chip, { item: it, selected: i === idx }, it.id))
542
+ ) }),
543
+ mode === "link" ? /* @__PURE__ */ jsx4(Box5, { flexDirection: "column", marginTop: 1, children: confirm ? /* @__PURE__ */ jsxs4(Text5, { children: [
544
+ "Replace ",
545
+ confirm.join(", "),
546
+ " layout with ",
547
+ surface,
548
+ "'s? (y/n)"
549
+ ] }) : /* @__PURE__ */ jsxs4(Fragment, { children: [
550
+ /* @__PURE__ */ jsxs4(Text5, { bold: true, children: [
551
+ "Link ",
552
+ surface,
553
+ " layout to:"
554
+ ] }),
555
+ linkOptions.map((o, i) => /* @__PURE__ */ jsxs4(Text5, { color: i === linkPick ? "cyan" : void 0, children: [
556
+ i === linkPick ? "\u25B8 " : " ",
557
+ o.label
558
+ ] }, o.label))
559
+ ] }) }) : mode === "picker" ? /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", marginTop: 1, children: [
487
560
  /* @__PURE__ */ jsx4(Text5, { bold: true, children: "Add widget" }),
488
561
  WIDGETS.map((w, i) => /* @__PURE__ */ jsxs4(Text5, { color: i === pick ? "cyan" : void 0, children: [
489
562
  i === pick ? "\u25B8 " : " ",
@@ -496,11 +569,9 @@ function Items({ config, setConfig, goHome }) {
496
569
  "type: ",
497
570
  cur.type
498
571
  ] }),
499
- row(0, "fg", /* @__PURE__ */ jsx4(Swatch, { name: cur.fg })),
500
- row(1, "bg", /* @__PURE__ */ jsx4(Swatch, { name: cur.bg, bg: true })),
501
- row(2, "raw", /* @__PURE__ */ jsx4(Text5, { children: cur.rawValue ? "on" : "off" })),
502
- row(3, "merge", /* @__PURE__ */ jsx4(Text5, { children: cur.merge ? "on" : "off" })),
503
- row(4, "align", /* @__PURE__ */ jsx4(Text5, { children: cur.align ?? "left" }))
572
+ row(0, "raw", /* @__PURE__ */ jsx4(Text5, { children: cur.rawValue ? "on" : "off" })),
573
+ row(1, "merge", /* @__PURE__ */ jsx4(Text5, { children: cur.merge ? "on" : "off" })),
574
+ row(2, "align", /* @__PURE__ */ jsx4(Text5, { children: cur.align ?? "left" }))
504
575
  ] }) : /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", marginTop: 1, borderStyle: "round", paddingX: 1, children: [
505
576
  /* @__PURE__ */ jsxs4(Text5, { children: [
506
577
  "type: ",
@@ -508,7 +579,7 @@ function Items({ config, setConfig, goHome }) {
508
579
  ] }),
509
580
  /* @__PURE__ */ jsx4(Text5, { dimColor: true, children: "(flex separator \u2014 no style options)" })
510
581
  ] })),
511
- /* @__PURE__ */ jsx4(Text5, { dimColor: true, children: mode === "strip" ? "\u2190/\u2192 select \xB7 [/] move \xB7 a add \xB7 x remove \xB7 e edit \xB7 tab surface \xB7 esc back" : mode === "editor" ? "\u2191/\u2193 field \xB7 \u2190/\u2192 change \xB7 esc done" : "\u2191/\u2193 choose \xB7 enter add \xB7 esc cancel" })
582
+ /* @__PURE__ */ jsx4(Text5, { dimColor: true, children: mode === "strip" ? "\u2190/\u2192 select \xB7 [/] move \xB7 a add \xB7 x remove \xB7 e edit \xB7 l link \xB7 u unlink \xB7 tab surface \xB7 esc back" : mode === "editor" ? "\u2191/\u2193 field \xB7 \u2190/\u2192 change \xB7 esc done" : mode === "link" ? confirm ? "y confirm \xB7 n cancel" : "\u2191/\u2193 choose \xB7 enter link \xB7 esc cancel" : "\u2191/\u2193 choose \xB7 enter add \xB7 esc cancel" })
512
583
  ] });
513
584
  }
514
585
 
@@ -1064,9 +1135,19 @@ function Surfaces({ config, setConfig, goHome }) {
1064
1135
  // src/screens/themes.tsx
1065
1136
  import { Box as Box11, Text as Text11, useInput as useInput9 } from "ink";
1066
1137
  import { useState as useState9 } from "react";
1138
+
1139
+ // src/named-colors.ts
1140
+ var all = [...COLORS];
1141
+ var NAMED_COLORS = [
1142
+ "(none)",
1143
+ ...all.filter((c) => !c.startsWith("bg")),
1144
+ ...all.filter((c) => c.startsWith("bg"))
1145
+ ];
1146
+
1147
+ // src/screens/themes.tsx
1067
1148
  import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1068
- var FG2 = NAMED_COLORS.filter((c) => !c.startsWith("bg"));
1069
- var BG2 = NAMED_COLORS.filter((c) => c.startsWith("bg"));
1149
+ var FG = NAMED_COLORS.filter((c) => !c.startsWith("bg"));
1150
+ var BG = ["(none)", ...NAMED_COLORS.filter((c) => c.startsWith("bg"))];
1070
1151
  var FIELDS3 = ["fg", "bg"];
1071
1152
  function uniqueName(base, themes) {
1072
1153
  if (!(base in themes)) {
@@ -1082,15 +1163,20 @@ function Themes({ config, setConfig, goHome }) {
1082
1163
  const names = Object.keys(config.themes);
1083
1164
  const [sel, setSel] = useState9(Math.max(0, names.indexOf(config.theme)));
1084
1165
  const [mode, setMode] = useState9("list");
1085
- const [w, setW] = useState9(0);
1166
+ const [slot, setSlot] = useState9(0);
1086
1167
  const [field, setField] = useState9(0);
1087
1168
  const [pick, setPick] = useState9(0);
1088
1169
  const name = names[Math.min(sel, names.length - 1)];
1089
- const theme = name && config.themes[name] || {};
1090
- const widgets = Object.keys(theme);
1091
- const widget = widgets[Math.min(w, widgets.length - 1)];
1092
- const list = FIELDS3[field] === "fg" ? FG2 : BG2;
1170
+ const theme = name && config.themes[name] || [];
1171
+ const count = theme.length;
1172
+ const slotIdx = Math.min(slot, count - 1);
1173
+ const list = FIELDS3[field] === "fg" ? FG : BG;
1093
1174
  const setThemes = (themes, active = config.theme) => setConfig({ ...config, theme: active, themes });
1175
+ const writeSlot = (index, entry) => {
1176
+ if (name) {
1177
+ setThemes({ ...config.themes, [name]: theme.map((s, i) => i === index ? entry : s) });
1178
+ }
1179
+ };
1094
1180
  useInput9((input, key) => {
1095
1181
  if (mode === "list") {
1096
1182
  if (key.escape) {
@@ -1104,49 +1190,65 @@ function Themes({ config, setConfig, goHome }) {
1104
1190
  setConfig({ ...config, theme: name });
1105
1191
  }
1106
1192
  } else if (key.rightArrow) {
1107
- if (widgets.length) {
1108
- setW(0);
1109
- setMode("colors");
1193
+ if (count) {
1194
+ setSlot(0);
1195
+ setMode("slots");
1110
1196
  }
1111
1197
  } else if (input === "n") {
1112
1198
  const n = uniqueName("custom", config.themes);
1113
- setThemes({ ...config.themes, [n]: {} });
1199
+ setThemes({ ...config.themes, [n]: [] });
1114
1200
  setSel(names.length);
1115
1201
  } else if (input === "d" && name) {
1116
1202
  const n = uniqueName(`${name}-copy`, config.themes);
1117
1203
  setThemes({ ...config.themes, [n]: structuredClone(theme) });
1118
1204
  setSel(names.length);
1119
1205
  }
1120
- } else if (mode === "colors") {
1206
+ } else if (mode === "slots") {
1121
1207
  if (key.escape || key.leftArrow && field === 0) {
1122
1208
  setMode("list");
1123
1209
  } else if (key.upArrow) {
1124
- setW((i) => Math.max(0, i - 1));
1210
+ setSlot(Math.max(0, slotIdx - 1));
1125
1211
  } else if (key.downArrow) {
1126
- setW((i) => Math.min(widgets.length - 1, i + 1));
1212
+ setSlot(Math.min(count - 1, slotIdx + 1));
1127
1213
  } else if (key.leftArrow) {
1128
1214
  setField(0);
1129
1215
  } else if (key.rightArrow) {
1130
1216
  setField(1);
1131
- } else if (key.return && widget) {
1132
- const cur = theme[widget]?.[FIELDS3[field] ?? "fg"];
1133
- setPick(Math.max(0, list.indexOf(cur ?? "")));
1217
+ } else if (key.return && slotIdx >= 0) {
1218
+ const cur = theme[slotIdx]?.[FIELDS3[field] ?? "fg"];
1219
+ setPick(Math.max(0, list.indexOf(cur ?? "(none)")));
1134
1220
  setMode("picker");
1221
+ } else if (input === "a" && name) {
1222
+ setThemes({ ...config.themes, [name]: [...theme, {}] });
1223
+ setSlot(count);
1224
+ } else if (input === "x" && name && slotIdx >= 0) {
1225
+ const next = theme.filter((_, i) => i !== slotIdx);
1226
+ setThemes({ ...config.themes, [name]: next });
1227
+ if (next.length === 0) {
1228
+ setMode("list");
1229
+ } else {
1230
+ setSlot(Math.min(slotIdx, next.length - 1));
1231
+ }
1135
1232
  }
1136
1233
  } else {
1137
1234
  if (key.escape) {
1138
- setMode("colors");
1235
+ setMode("slots");
1139
1236
  } else if (key.upArrow) {
1140
1237
  setPick((p) => Math.max(0, p - 1));
1141
1238
  } else if (key.downArrow) {
1142
1239
  setPick((p) => Math.min(list.length - 1, p + 1));
1143
- } else if (key.return && name && widget) {
1240
+ } else if (key.return && slotIdx >= 0) {
1144
1241
  const f = FIELDS3[field] ?? "fg";
1145
1242
  const chosen = list[pick];
1146
1243
  if (chosen) {
1147
- const entry = { ...theme[widget], [f]: chosen };
1148
- setThemes({ ...config.themes, [name]: { ...theme, [widget]: entry } });
1149
- setMode("colors");
1244
+ const entry = { ...theme[slotIdx] };
1245
+ if (chosen === "(none)") {
1246
+ delete entry[f];
1247
+ } else {
1248
+ entry[f] = chosen;
1249
+ }
1250
+ writeSlot(slotIdx, entry);
1251
+ setMode("slots");
1150
1252
  }
1151
1253
  }
1152
1254
  }
@@ -1160,14 +1262,14 @@ function Themes({ config, setConfig, goHome }) {
1160
1262
  ] }, n)),
1161
1263
  /* @__PURE__ */ jsxs10(Text11, { dimColor: true, children: [
1162
1264
  name,
1163
- " colors:"
1265
+ " palette slots:"
1164
1266
  ] }),
1165
- widgets.map((wt, i) => {
1166
- const c = theme[wt] ?? {};
1167
- const on = mode !== "list" && i === w;
1267
+ count === 0 && /* @__PURE__ */ jsx10(Text11, { dimColor: true, children: "(empty palette)" }),
1268
+ theme.map((c, i) => {
1269
+ const on = mode !== "list" && i === slotIdx;
1168
1270
  return /* @__PURE__ */ jsxs10(Text11, { children: [
1169
1271
  on ? "\u25B8 " : " ",
1170
- wt.padEnd(20),
1272
+ String(i).padEnd(4),
1171
1273
  /* @__PURE__ */ jsxs10(Text11, { color: inkColor(c.fg), inverse: on && field === 0, children: [
1172
1274
  " ",
1173
1275
  c.fg ?? "(none)",
@@ -1178,14 +1280,14 @@ function Themes({ config, setConfig, goHome }) {
1178
1280
  c.bg ?? "(none)",
1179
1281
  " "
1180
1282
  ] })
1181
- ] }, wt);
1283
+ ] }, i);
1182
1284
  }),
1183
1285
  mode === "picker" && /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", children: [
1184
1286
  /* @__PURE__ */ jsxs10(Text11, { bold: true, children: [
1185
1287
  "Pick ",
1186
1288
  FIELDS3[field],
1187
- " for ",
1188
- widget
1289
+ " for slot ",
1290
+ slotIdx
1189
1291
  ] }),
1190
1292
  list.map((c, i) => /* @__PURE__ */ jsxs10(Text11, { color: i === pick ? "cyan" : void 0, children: [
1191
1293
  i === pick ? "\u25B8 " : " ",
@@ -1203,7 +1305,7 @@ function Themes({ config, setConfig, goHome }) {
1203
1305
  )
1204
1306
  ] }, c))
1205
1307
  ] }),
1206
- /* @__PURE__ */ jsx10(Text11, { dimColor: true, children: mode === "list" ? "\u2191/\u2193 select \xB7 \u23CE activate \xB7 \u2192 colors \xB7 n new \xB7 d duplicate \xB7 esc back" : mode === "colors" ? "\u2191/\u2193 widget \xB7 \u2190/\u2192 fg/bg \xB7 \u23CE pick \xB7 esc back" : "\u2191/\u2193 choose \xB7 \u23CE set \xB7 esc cancel" })
1308
+ /* @__PURE__ */ jsx10(Text11, { dimColor: true, children: mode === "list" ? "\u2191/\u2193 select \xB7 \u23CE activate \xB7 \u2192 slots \xB7 n new \xB7 d duplicate \xB7 esc back" : mode === "slots" ? "\u2191/\u2193 slot \xB7 \u2190/\u2192 fg/bg \xB7 \u23CE pick \xB7 a add \xB7 x remove \xB7 esc back" : "\u2191/\u2193 choose \xB7 \u23CE set \xB7 esc cancel" })
1207
1309
  ] });
1208
1310
  }
1209
1311
 
@@ -5,128 +5,6 @@ var __export = (target, all) => {
5
5
  __defProp(target, name, { get: all[name], enumerable: true });
6
6
  };
7
7
 
8
- // ../core/src/theme/themes.ts
9
- function resolveColors(item, config) {
10
- const themeEntry = config.themes[config.theme]?.[item.type];
11
- const fg2 = item.type === "flex-separator" ? void 0 : item.fg;
12
- const bg2 = item.type === "flex-separator" ? void 0 : item.bg;
13
- return {
14
- fg: fg2 ?? themeEntry?.fg,
15
- bg: bg2 ?? themeEntry?.bg
16
- };
17
- }
18
- var WIDGETS = [
19
- "model",
20
- "version",
21
- "context-percentage",
22
- "git-branch",
23
- "git-changes",
24
- "tokens-input",
25
- "tokens-output",
26
- "tokens-total"
27
- ];
28
- var mk = (rows) => {
29
- const t = {};
30
- WIDGETS.forEach((w, i) => {
31
- const row = rows[i];
32
- if (!row) {
33
- throw new Error(`theme definition is missing a color row for widget "${w}"`);
34
- }
35
- const [fg2, bg2] = row;
36
- t[w] = { fg: fg2, bg: bg2 };
37
- });
38
- return t;
39
- };
40
- var builtinThemes = {
41
- default: {
42
- model: { fg: "black", bg: "bgCyan" },
43
- version: { fg: "white", bg: "bgBlue" },
44
- "context-percentage": { fg: "black", bg: "bgBrightYellow" },
45
- "git-branch": { fg: "black", bg: "bgCyan" },
46
- "git-changes": { fg: "white", bg: "bgBrightBlack" }
47
- },
48
- classic: mk([
49
- ["black", "bgYellow"],
50
- ["black", "bgWhite"],
51
- ["black", "bgGreen"],
52
- ["white", "bgBlue"],
53
- ["black", "bgMagenta"],
54
- ["black", "bgCyan"],
55
- ["black", "bgBrightYellow"],
56
- ["white", "bgRed"]
57
- ]),
58
- nord: mk([
59
- ["black", "bgBrightCyan"],
60
- ["black", "bgCyan"],
61
- ["black", "bgBlue"],
62
- ["white", "bgBrightBlack"],
63
- ["black", "bgBrightBlue"],
64
- ["black", "bgGreen"],
65
- ["black", "bgYellow"],
66
- ["white", "bgBlack"]
67
- ]),
68
- dracula: mk([
69
- ["black", "bgMagenta"],
70
- ["black", "bgBrightMagenta"],
71
- ["black", "bgBrightGreen"],
72
- ["black", "bgBrightCyan"],
73
- ["black", "bgBrightYellow"],
74
- ["black", "bgBrightRed"],
75
- ["white", "bgBrightBlack"],
76
- ["white", "bgMagenta"]
77
- ]),
78
- gruvbox: mk([
79
- ["black", "bgYellow"],
80
- ["black", "bgBrightYellow"],
81
- ["black", "bgGreen"],
82
- ["black", "bgCyan"],
83
- ["black", "bgRed"],
84
- ["black", "bgMagenta"],
85
- ["white", "bgBrightBlack"],
86
- ["white", "bgBlack"]
87
- ]),
88
- monokai: mk([
89
- ["black", "bgBrightGreen"],
90
- ["black", "bgBrightYellow"],
91
- ["black", "bgBrightMagenta"],
92
- ["black", "bgBrightCyan"],
93
- ["black", "bgBrightRed"],
94
- ["white", "bgBrightBlack"],
95
- ["black", "bgYellow"],
96
- ["white", "bgBlack"]
97
- ]),
98
- "one-dark": mk([
99
- ["black", "bgBlue"],
100
- ["black", "bgBrightBlue"],
101
- ["black", "bgGreen"],
102
- ["black", "bgMagenta"],
103
- ["black", "bgYellow"],
104
- ["black", "bgCyan"],
105
- ["white", "bgBrightBlack"],
106
- ["white", "bgBlack"]
107
- ]),
108
- solarized: mk([
109
- ["white", "bgBlue"],
110
- ["black", "bgCyan"],
111
- ["black", "bgYellow"],
112
- ["white", "bgGreen"],
113
- ["white", "bgMagenta"],
114
- ["white", "bgRed"],
115
- ["white", "bgBrightBlack"],
116
- ["white", "bgBlack"]
117
- ]),
118
- "tokyo-night": mk([
119
- ["black", "bgBrightBlue"],
120
- ["black", "bgBlue"],
121
- ["black", "bgBrightGreen"],
122
- ["black", "bgBrightMagenta"],
123
- ["black", "bgBrightYellow"],
124
- ["black", "bgBrightCyan"],
125
- ["white", "bgBrightBlack"],
126
- ["white", "bgBlack"]
127
- ])
128
- };
129
-
130
8
  // ../core/src/widgets/registry.ts
131
9
  var registry = {};
132
10
  function register(def) {
@@ -145,9 +23,8 @@ function itemToCell(item, config, snapshot, commandOutputs) {
145
23
  }
146
24
  const flex = item.type === "flex-separator";
147
25
  const pad = flex ? "" : " ".repeat(Math.max(0, Math.floor(config.defaults.padding)));
148
- const { fg: fg2, bg: bg2 } = resolveColors(item, config);
149
26
  const merge = item.type === "flex-separator" ? false : item.merge ?? false;
150
- return { text: flex ? "" : `${pad}${value}${pad}`, fg: fg2, bg: bg2, merge, flex };
27
+ return { text: flex ? "" : `${pad}${value}${pad}`, merge, flex };
151
28
  }
152
29
  function lineToCells(items, config, snapshot, commandOutputs) {
153
30
  return items.map((it) => itemToCell(it, config, snapshot, commandOutputs)).filter((c) => c !== null);
@@ -250,6 +127,55 @@ function composeLine(cells, mode, width, glyph = "\u2592") {
250
127
  return truncate(segs, width);
251
128
  }
252
129
 
130
+ // ../core/src/theme/contrast.ts
131
+ var LIGHT_BG = /* @__PURE__ */ new Set([
132
+ "green",
133
+ "yellow",
134
+ "cyan",
135
+ "white",
136
+ "brightGreen",
137
+ "brightYellow",
138
+ "brightCyan",
139
+ "brightWhite"
140
+ ]);
141
+ var baseColor = (bg2) => {
142
+ if (!bg2.startsWith("bg")) {
143
+ return bg2;
144
+ }
145
+ const rest = bg2.slice(2);
146
+ return rest.charAt(0).toLowerCase() + rest.slice(1);
147
+ };
148
+ function contrastFg(bg2) {
149
+ return LIGHT_BG.has(baseColor(bg2)) ? "black" : "white";
150
+ }
151
+
152
+ // ../core/src/layout/palette.ts
153
+ function assignPaletteColors(cells, theme) {
154
+ if (theme.length === 0) {
155
+ return cells.map((c) => ({ ...c }));
156
+ }
157
+ const out = [];
158
+ let slot = -1;
159
+ let prev;
160
+ for (const c of cells) {
161
+ if (c.flex) {
162
+ out.push({ ...c });
163
+ prev = c;
164
+ continue;
165
+ }
166
+ const continuation = c.merge === true && prev !== void 0 && !prev.flex;
167
+ if (!continuation) {
168
+ slot += 1;
169
+ }
170
+ const pal = theme[slot % theme.length];
171
+ const bg2 = pal?.bg;
172
+ const fg2 = pal?.fg ?? (bg2 !== void 0 ? contrastFg(bg2) : void 0);
173
+ out.push({ ...c, fg: fg2, bg: bg2 });
174
+ prev = c;
175
+ }
176
+ return out;
177
+ }
178
+
253
179
  // ../core/src/format.ts
254
180
  function fmtNum(n) {
255
181
  const trim = (v, suffix) => `${v.toFixed(1).replace(/\.0$/, "")}${suffix}`;
@@ -525,7 +451,8 @@ function render(config, snapshot, opts) {
525
451
  return { lines: [] };
526
452
  }
527
453
  const outputs = opts.commandOutputs ?? {};
528
- const lines = surface.lines.map((items) => lineToCells(items, config, snapshot, outputs)).filter((cells) => cells.length > 0).map((cells) => ({
454
+ const theme = Object.hasOwn(config.themes, config.theme) ? config.themes[config.theme] ?? [] : [];
455
+ const lines = surface.lines.map((items) => lineToCells(items, config, snapshot, outputs)).filter((cells) => cells.length > 0).map((cells) => assignPaletteColors(cells, theme)).map((cells) => ({
529
456
  segments: composeLine(cells, config.defaults.separator, opts.width, config.defaults.glyph)
530
457
  }));
531
458
  return { lines };
@@ -609,6 +536,98 @@ function isColor(x) {
609
536
  return typeof x === "string" && COLORS.has(x);
610
537
  }
611
538
 
539
+ // ../core/src/theme/themes.ts
540
+ var mk = (rows) => rows.map(([fg2, bg2]) => ({ fg: fg2, bg: bg2 }));
541
+ var builtinThemes = {
542
+ default: [
543
+ { fg: "black", bg: "bgCyan" },
544
+ { fg: "white", bg: "bgBlue" },
545
+ { fg: "black", bg: "bgBrightYellow" },
546
+ { fg: "white", bg: "bgBrightBlack" },
547
+ { fg: "black", bg: "bgGreen" }
548
+ ],
549
+ classic: mk([
550
+ ["black", "bgYellow"],
551
+ ["black", "bgWhite"],
552
+ ["black", "bgGreen"],
553
+ ["white", "bgBlue"],
554
+ ["black", "bgMagenta"],
555
+ ["black", "bgCyan"],
556
+ ["black", "bgBrightYellow"],
557
+ ["white", "bgRed"]
558
+ ]),
559
+ nord: mk([
560
+ ["black", "bgBrightCyan"],
561
+ ["black", "bgCyan"],
562
+ ["black", "bgBlue"],
563
+ ["white", "bgBrightBlack"],
564
+ ["black", "bgBrightBlue"],
565
+ ["black", "bgGreen"],
566
+ ["black", "bgYellow"],
567
+ ["white", "bgBlack"]
568
+ ]),
569
+ dracula: mk([
570
+ ["black", "bgMagenta"],
571
+ ["black", "bgBrightMagenta"],
572
+ ["black", "bgBrightGreen"],
573
+ ["black", "bgBrightCyan"],
574
+ ["black", "bgBrightYellow"],
575
+ ["black", "bgBrightRed"],
576
+ ["white", "bgBrightBlack"],
577
+ ["white", "bgMagenta"]
578
+ ]),
579
+ gruvbox: mk([
580
+ ["black", "bgYellow"],
581
+ ["black", "bgBrightYellow"],
582
+ ["black", "bgGreen"],
583
+ ["black", "bgCyan"],
584
+ ["black", "bgRed"],
585
+ ["black", "bgMagenta"],
586
+ ["white", "bgBrightBlack"],
587
+ ["white", "bgBlack"]
588
+ ]),
589
+ monokai: mk([
590
+ ["black", "bgBrightGreen"],
591
+ ["black", "bgBrightYellow"],
592
+ ["black", "bgBrightMagenta"],
593
+ ["black", "bgBrightCyan"],
594
+ ["black", "bgBrightRed"],
595
+ ["white", "bgBrightBlack"],
596
+ ["black", "bgYellow"],
597
+ ["white", "bgBlack"]
598
+ ]),
599
+ "one-dark": mk([
600
+ ["black", "bgBlue"],
601
+ ["black", "bgBrightBlue"],
602
+ ["black", "bgGreen"],
603
+ ["black", "bgMagenta"],
604
+ ["black", "bgYellow"],
605
+ ["black", "bgCyan"],
606
+ ["white", "bgBrightBlack"],
607
+ ["white", "bgBlack"]
608
+ ]),
609
+ solarized: mk([
610
+ ["white", "bgBlue"],
611
+ ["black", "bgCyan"],
612
+ ["black", "bgYellow"],
613
+ ["white", "bgGreen"],
614
+ ["white", "bgMagenta"],
615
+ ["white", "bgRed"],
616
+ ["white", "bgBrightBlack"],
617
+ ["white", "bgBlack"]
618
+ ]),
619
+ "tokyo-night": mk([
620
+ ["black", "bgBrightBlue"],
621
+ ["black", "bgBlue"],
622
+ ["black", "bgBrightGreen"],
623
+ ["black", "bgBrightMagenta"],
624
+ ["black", "bgBrightYellow"],
625
+ ["black", "bgBrightCyan"],
626
+ ["white", "bgBrightBlack"],
627
+ ["white", "bgBlack"]
628
+ ])
629
+ };
630
+
612
631
  // ../core/src/toast.ts
613
632
  var TOAST_FIELDS = {
614
633
  ctxPct: (s) => s.ctxPct,
@@ -655,6 +674,53 @@ var defaultConfig = {
655
674
  }
656
675
  };
657
676
 
677
+ // ../core/src/config/links.ts
678
+ var LINKABLE = ["band", "statusline", "pane"];
679
+ var clone = (v) => JSON.parse(JSON.stringify(v));
680
+ function linkedSurfaces(surfaces) {
681
+ return LINKABLE.filter((name) => surfaces[name].linked);
682
+ }
683
+ function writeLinkedLines(surfaces, surface, lines) {
684
+ const next = { ...surfaces };
685
+ next[surface] = { ...surfaces[surface], lines: clone(lines) };
686
+ if (surfaces[surface].linked) {
687
+ for (const member of LINKABLE) {
688
+ if (member !== surface && surfaces[member].linked) {
689
+ next[member] = { ...surfaces[member], lines: clone(lines) };
690
+ }
691
+ }
692
+ }
693
+ return next;
694
+ }
695
+ function normalizeLinks(surfaces, warn) {
696
+ const linked = linkedSurfaces(surfaces);
697
+ if (linked.length < 2) {
698
+ for (const name of linked) {
699
+ delete surfaces[name].linked;
700
+ warn(`dropped lone surface link on "${name}"`);
701
+ }
702
+ return;
703
+ }
704
+ const canonical = linked[0];
705
+ if (!canonical) {
706
+ return;
707
+ }
708
+ const source = JSON.stringify(surfaces[canonical].lines);
709
+ let diverged = false;
710
+ for (const name of linked) {
711
+ if (name === canonical) {
712
+ continue;
713
+ }
714
+ if (JSON.stringify(surfaces[name].lines) !== source) {
715
+ surfaces[name].lines = clone(surfaces[canonical].lines);
716
+ diverged = true;
717
+ }
718
+ }
719
+ if (diverged) {
720
+ warn(`linked surfaces diverged; synced to "${canonical}"`);
721
+ }
722
+ }
723
+
658
724
  // ../../node_modules/zod/v3/external.js
659
725
  var external_exports = {};
660
726
  __export(external_exports, {
@@ -4713,7 +4779,8 @@ var itemSchema = external_exports.object({
4713
4779
  });
4714
4780
  var surfaceLayoutSchema = external_exports.object({
4715
4781
  enabled: external_exports.boolean(),
4716
- lines: external_exports.array(external_exports.array(itemSchema))
4782
+ lines: external_exports.array(external_exports.array(itemSchema)),
4783
+ linked: external_exports.boolean().optional()
4717
4784
  });
4718
4785
  var toastRuleSchema = external_exports.object({
4719
4786
  when: external_exports.string(),
@@ -4723,7 +4790,7 @@ var toastRuleSchema = external_exports.object({
4723
4790
  var configSchema = external_exports.object({
4724
4791
  version: external_exports.literal(1).catch(1),
4725
4792
  theme: external_exports.string().default("default"),
4726
- themes: external_exports.record(external_exports.record(external_exports.object({ fg: external_exports.string().optional(), bg: external_exports.string().optional() }))).default({}),
4793
+ themes: external_exports.record(external_exports.unknown()).default({}),
4727
4794
  defaults: external_exports.object({
4728
4795
  separator: sep,
4729
4796
  padding: external_exports.number().int().min(0).catch(1),
@@ -4780,7 +4847,7 @@ var WIDGET_TYPES = [
4780
4847
  ];
4781
4848
 
4782
4849
  // ../core/src/config/validate.ts
4783
- var clone = (v) => JSON.parse(JSON.stringify(v));
4850
+ var clone2 = (v) => JSON.parse(JSON.stringify(v));
4784
4851
  var WIDGET_TYPE_SET = new Set(WIDGET_TYPES);
4785
4852
  function cleanStyle(raw, type, warn) {
4786
4853
  const style = {};
@@ -4793,16 +4860,8 @@ function cleanStyle(raw, type, warn) {
4793
4860
  if (raw.rawValue !== void 0) {
4794
4861
  style.rawValue = raw.rawValue;
4795
4862
  }
4796
- for (const key of ["fg", "bg"]) {
4797
- const v = raw[key];
4798
- if (v === void 0) {
4799
- continue;
4800
- }
4801
- if (isColor(v)) {
4802
- style[key] = v;
4803
- } else {
4804
- warn(`stripped unknown color "${v}" on a ${type} item`);
4805
- }
4863
+ if (raw.fg !== void 0 || raw.bg !== void 0) {
4864
+ warn(`dropped per-item color on a ${type} item; colors now come from the theme palette`);
4806
4865
  }
4807
4866
  return style;
4808
4867
  }
@@ -4835,28 +4894,42 @@ function cleanItem(raw, warn) {
4835
4894
  return { id, type, ...style };
4836
4895
  }
4837
4896
  function cleanThemes(themes, warn) {
4838
- const cleaned = {};
4839
- for (const [themeName, themeEntries] of Object.entries(themes)) {
4840
- const cleanedEntries = {};
4841
- for (const [widgetName, entry] of Object.entries(themeEntries)) {
4842
- const cleanedEntry = { ...entry };
4897
+ const cleaned = /* @__PURE__ */ Object.create(null);
4898
+ for (const [name, value] of Object.entries(themes)) {
4899
+ if (!Array.isArray(value)) {
4900
+ const message = value !== null && typeof value === "object" ? `theme "${name}" uses the old per-widget format and was dropped; colors are now a positional palette` : `theme "${name}" is not a palette array and was dropped; colors are now a positional palette`;
4901
+ warn(message);
4902
+ continue;
4903
+ }
4904
+ const slots = [];
4905
+ value.forEach((rawSlot, i) => {
4906
+ if (!rawSlot || typeof rawSlot !== "object") {
4907
+ warn(`replaced invalid slot ${i} in theme "${name}" with an empty slot`);
4908
+ slots.push({});
4909
+ return;
4910
+ }
4911
+ const entry = rawSlot;
4912
+ const slot = {};
4843
4913
  for (const key of ["fg", "bg"]) {
4844
- if (cleanedEntry[key] !== void 0 && !isColor(cleanedEntry[key])) {
4845
- warn(
4846
- `stripped unknown color "${cleanedEntry[key]}" in theme "${themeName}" (${widgetName})`
4847
- );
4848
- cleanedEntry[key] = void 0;
4914
+ const v = entry[key];
4915
+ if (v === void 0) {
4916
+ continue;
4917
+ }
4918
+ if (typeof v === "string" && isColor(v)) {
4919
+ slot[key] = v;
4920
+ } else {
4921
+ warn(`stripped unknown color "${String(v)}" in theme "${name}" (slot ${i})`);
4849
4922
  }
4850
4923
  }
4851
- cleanedEntries[widgetName] = cleanedEntry;
4852
- }
4853
- cleaned[themeName] = cleanedEntries;
4924
+ slots.push(slot);
4925
+ });
4926
+ cleaned[name] = slots;
4854
4927
  }
4855
4928
  return cleaned;
4856
4929
  }
4857
4930
  function cleanToasts(raw, warn) {
4858
4931
  if (!raw) {
4859
- return clone(defaultConfig.surfaces.toasts);
4932
+ return clone2(defaultConfig.surfaces.toasts);
4860
4933
  }
4861
4934
  const rules = raw.rules.filter((r) => {
4862
4935
  if (isValidWhen(r.when)) {
@@ -4881,26 +4954,39 @@ function loadConfig(raw) {
4881
4954
  if (raw !== void 0) {
4882
4955
  warn(`config invalid (${parsed.error.issues[0]?.message ?? "unknown"}); using defaults`);
4883
4956
  }
4884
- return { config: clone(defaultConfig), warnings };
4957
+ return { config: clone2(defaultConfig), warnings };
4885
4958
  }
4886
4959
  const p = parsed.data;
4887
4960
  const surf = (name) => {
4888
4961
  const s = p.surfaces[name];
4889
4962
  if (!s) {
4890
- return clone(defaultConfig.surfaces[name]);
4963
+ return clone2(defaultConfig.surfaces[name]);
4891
4964
  }
4892
- return {
4965
+ const layout = {
4893
4966
  enabled: s.enabled,
4894
4967
  lines: s.lines.map(
4895
4968
  (line) => line.map((it) => cleanItem(it, warn)).filter((x) => x !== null)
4896
4969
  )
4897
4970
  };
4971
+ if (s.linked) {
4972
+ layout.linked = true;
4973
+ }
4974
+ return layout;
4898
4975
  };
4899
- const themesToUse = Object.keys(p.themes).length ? p.themes : clone(defaultConfig.themes);
4976
+ const cleaned = cleanThemes(p.themes, warn);
4977
+ const themes = Object.keys(cleaned).length ? cleaned : clone2(builtinThemes);
4978
+ if (!Object.hasOwn(themes, "default")) {
4979
+ themes["default"] = clone2(builtinThemes["default"] ?? []);
4980
+ }
4981
+ let theme = p.theme;
4982
+ if (!Object.hasOwn(themes, theme)) {
4983
+ warn(`theme "${theme}" not found; using "default"`);
4984
+ theme = "default";
4985
+ }
4900
4986
  const config = {
4901
4987
  version: 1,
4902
- theme: p.theme,
4903
- themes: cleanThemes(themesToUse, warn),
4988
+ theme,
4989
+ themes,
4904
4990
  defaults: { ...defaultConfig.defaults, ...p.defaults },
4905
4991
  surfaces: {
4906
4992
  band: surf("band"),
@@ -4909,11 +4995,12 @@ function loadConfig(raw) {
4909
4995
  toasts: cleanToasts(p.surfaces.toasts, warn)
4910
4996
  }
4911
4997
  };
4998
+ normalizeLinks(config.surfaces, warn);
4912
4999
  return { config, warnings };
4913
5000
  }
4914
5001
 
4915
5002
  // ../core/src/config/import-ccstatusline.ts
4916
- var clone2 = (v) => JSON.parse(JSON.stringify(v));
5003
+ var clone3 = (v) => JSON.parse(JSON.stringify(v));
4917
5004
  var TYPE_MAP = {
4918
5005
  model: "model",
4919
5006
  version: "version",
@@ -5004,7 +5091,6 @@ var UNSUPPORTED = {
5004
5091
  function baseStyle(raw, idFallback) {
5005
5092
  return {
5006
5093
  id: String(raw["id"] ?? `${idFallback}-${Math.random().toString(36).slice(2)}`),
5007
- bg: typeof raw["backgroundColor"] === "string" ? raw["backgroundColor"] : void 0,
5008
5094
  rawValue: raw["rawValue"] === true || void 0,
5009
5095
  merge: raw["merge"] === true || void 0
5010
5096
  };
@@ -5013,7 +5099,7 @@ function importCcstatusline(raw) {
5013
5099
  const warnings = [];
5014
5100
  if (!raw || typeof raw !== "object" || !Array.isArray(raw.lines)) {
5015
5101
  warnings.push("input is not a ccstatusline config; using defaults");
5016
- return { config: clone2(defaultConfig), warnings };
5102
+ return { config: clone3(defaultConfig), warnings };
5017
5103
  }
5018
5104
  const lines = raw.lines.map(
5019
5105
  (line) => (Array.isArray(line) ? line : []).flatMap((item) => {
@@ -5252,6 +5338,9 @@ export {
5252
5338
  toAnsi,
5253
5339
  COLORS,
5254
5340
  isValidWhen,
5341
+ LINKABLE,
5342
+ linkedSurfaces,
5343
+ writeLinkedLines,
5255
5344
  importCcstatusline,
5256
5345
  rendererColor,
5257
5346
  rendererBg,
package/dist/index.js CHANGED
@@ -4,10 +4,10 @@
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  var sub = process.argv[2];
6
6
  if (sub === "statusline") {
7
- const { runStatusline } = await import("./statusline-cmd-XIBNUV3A.js");
7
+ const { runStatusline } = await import("./statusline-cmd-5XRA4JYE.js");
8
8
  await runStatusline();
9
9
  } else {
10
10
  const { render } = await import("ink");
11
- const { App } = await import("./app-YVZJ6IYT.js");
11
+ const { App } = await import("./app-DVVWJH7H.js");
12
12
  render(/* @__PURE__ */ jsx(App, {}));
13
13
  }
@@ -6,7 +6,7 @@ import {
6
6
  render,
7
7
  snapshotPath,
8
8
  toAnsi
9
- } from "./chunk-ZD5C4L7U.js";
9
+ } from "./chunk-EUAY5IC6.js";
10
10
 
11
11
  // src/statusline-cmd.ts
12
12
  function renderStatuslineAnsi(config, snapshot) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sushant-kum/ccstatus",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Interactive configurator (npx @sushant-kum/ccstatus) for the ccstatus Claude Code status bar — band, status line, pane, and threshold toasts from one config.",
5
5
  "license": "MIT",
6
6
  "author": "Sushant Kumar",