pi-one-ui 0.3.1 → 0.5.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.
@@ -24,11 +24,7 @@ export type { IconMode } from "../../shared/icons.ts";
24
24
  export type ContextStyle = "text" | "gauge" | "text+gauge";
25
25
  export type SeparatorStyle = "pipe" | "dot" | "chevron" | "none";
26
26
  export type ModelLabelSource = "id" | "name";
27
- export type EditorStyle =
28
- | "opencode"
29
- | "opencode-copy-friendly"
30
- | "accent-rail"
31
- | "minimalist";
27
+ export type EditorStyle = "on" | "off";
32
28
  export type UserMessageStyle =
33
29
  | "framed"
34
30
  | "framed-copy-friendly"
@@ -49,9 +45,7 @@ export type ComponentStyleOwner =
49
45
  | "selectorBorders"
50
46
  | "footer";
51
47
  export type MinimalistPathDisplayMode = "compact" | "project" | "full";
52
- export type MinimalistContextFormat = "percent" | "percent-total";
53
48
  export type EditorBorderColorMode = "static" | "adaptive";
54
- export type CompletionMenuStyle = "native" | "palette";
55
49
  export type CompactFooterMaxLines = 1 | 2 | 3 | "unlimited";
56
50
 
57
51
  export const DEFAULT_COMPACT_FOOTER_FORMAT =
@@ -108,31 +102,12 @@ export type FooterSegmentsConfig = {
108
102
  packageVersion: boolean;
109
103
  };
110
104
 
111
- export type PolishedEditorStyleConfig = {
112
- metadataFormat: string;
113
- completionMenu: CompletionMenuStyle;
114
- };
115
-
116
- export type PolishedCopyFriendlyEditorStyleConfig = {
117
- metadataFormat: string;
118
- completionMenu: CompletionMenuStyle;
119
- };
120
-
121
- export type AccentRailEditorStyleConfig = {
122
- rail: string;
123
- asciiRail: string;
124
- transparent: boolean;
125
- };
126
-
127
105
  export type MinimalistEditorStyleConfig = {
128
106
  pathDisplay: MinimalistPathDisplayMode;
129
- contextFormat: MinimalistContextFormat;
130
- contextGauge: boolean;
131
107
  showSessionName: boolean;
132
108
  showTimer: boolean;
133
109
  showCost: boolean;
134
110
  showGit: boolean;
135
- contextThresholds: ContextThresholds;
136
111
  };
137
112
 
138
113
  /** Temporary name retained for existing settings consumers. */
@@ -143,16 +118,12 @@ export type EditorStylesConfig = {
143
118
  };
144
119
 
145
120
  export type EditorComponentConfig = {
146
- enabled: boolean;
147
121
  style: EditorStyle;
148
122
  colorSource: ColorSource;
149
123
  borderColorMode: EditorBorderColorMode;
150
124
  modelLabel: ModelLabelSource;
151
125
  viewportIndicators: boolean;
152
126
  styles: {
153
- opencode: PolishedEditorStyleConfig;
154
- "opencode-copy-friendly": PolishedCopyFriendlyEditorStyleConfig;
155
- "accent-rail": AccentRailEditorStyleConfig;
156
127
  minimalist: MinimalistEditorStyleConfig;
157
128
  };
158
129
  };
@@ -302,7 +273,7 @@ export type ZentuiConfig = {
302
273
  };
303
274
 
304
275
  export type PolishedTuiColors = {
305
- cwd: ColorSpec;
276
+ cwd?: ColorSpec;
306
277
  sessionName: ColorSpec;
307
278
  gitBranch: ColorSpec;
308
279
  gitStatus: ColorSpec;
@@ -323,8 +294,6 @@ export type PolishedTuiColors = {
323
294
  time: ColorSpec;
324
295
  os: ColorSpec;
325
296
  editorAccent?: ColorSpec;
326
- editorRail?: ColorSpec;
327
- editorPrompt?: ColorSpec;
328
297
  editorBorder?: ColorSpec;
329
298
  editorGitBranch?: ColorSpec;
330
299
  editorModel?: ColorSpec;
@@ -437,23 +406,12 @@ const defaultFooterSegments: FooterSegmentsConfig = {
437
406
  packageVersion: false,
438
407
  };
439
408
 
440
- const DEFAULT_COMPLETION_MENU: CompletionMenuStyle = "palette";
441
-
442
- const defaultAccentRailStyle: AccentRailEditorStyleConfig = {
443
- rail: "▎",
444
- asciiRail: "|",
445
- transparent: false,
446
- };
447
-
448
409
  const defaultMinimalistStyle: MinimalistEditorStyleConfig = {
449
410
  pathDisplay: "compact",
450
- contextFormat: "percent",
451
- contextGauge: false,
452
411
  showSessionName: true,
453
412
  showTimer: true,
454
413
  showCost: true,
455
414
  showGit: true,
456
- contextThresholds: { warning: 70, error: 90 },
457
415
  };
458
416
 
459
417
  const defaultStarshipStyle: StarshipFooterStyleConfig = {
@@ -478,22 +436,12 @@ const defaultStarshipStyle: StarshipFooterStyleConfig = {
478
436
 
479
437
  const defaultComponents: ComponentsConfig = {
480
438
  editor: {
481
- enabled: true,
482
- style: "opencode",
439
+ style: "on",
483
440
  colorSource: "theme",
484
441
  borderColorMode: "static",
485
442
  modelLabel: "id",
486
443
  viewportIndicators: true,
487
444
  styles: {
488
- opencode: {
489
- metadataFormat: DEFAULT_EDITOR_METADATA_FORMAT,
490
- completionMenu: DEFAULT_COMPLETION_MENU,
491
- },
492
- "opencode-copy-friendly": {
493
- metadataFormat: DEFAULT_EDITOR_METADATA_FORMAT,
494
- completionMenu: DEFAULT_COMPLETION_MENU,
495
- },
496
- "accent-rail": defaultAccentRailStyle,
497
445
  minimalist: defaultMinimalistStyle,
498
446
  },
499
447
  },
@@ -533,7 +481,6 @@ export const defaultConfig: PolishedTuiConfig = {
533
481
  projectRefreshIntervalMs: DEFAULT_PROJECT_REFRESH_INTERVAL_MS,
534
482
  icons: { mode: "auto", ...NERD_DEFAULT_ICONS },
535
483
  colors: {
536
- cwd: "bold cyan",
537
484
  sessionName: "bold green",
538
485
  gitBranch: "bold purple",
539
486
  gitStatus: "bold red",
@@ -615,14 +562,9 @@ function parseEditorModelLabel(
615
562
  }
616
563
 
617
564
  function parseEditorStyle(value: unknown): EditorStyle {
618
- if (
619
- value === "opencode" ||
620
- value === "opencode-copy-friendly" ||
621
- value === "accent-rail" ||
622
- value === "minimalist"
623
- ) {
624
- return value;
625
- }
565
+ if (value === "on" || value === "off") return value;
566
+ // 迁移:旧 opencode / minimalist 样式统一收敛为 on(minimalist)。
567
+ if (value === "opencode" || value === "minimalist") return "on";
626
568
  return defaultComponents.editor.style;
627
569
  }
628
570
 
@@ -631,12 +573,6 @@ function parseEditorBorderColorMode(value: unknown): EditorBorderColorMode {
631
573
  return defaultConfig.editorBorderColorMode;
632
574
  }
633
575
 
634
- function parseCompletionMenuStyle(value: unknown): CompletionMenuStyle {
635
- return value === "native" || value === "palette"
636
- ? value
637
- : DEFAULT_COMPLETION_MENU;
638
- }
639
-
640
576
  export function isSeparatorStyle(value: unknown): value is SeparatorStyle {
641
577
  return (
642
578
  value === "pipe" ||
@@ -775,8 +711,6 @@ function normalizeColors(
775
711
  time: colorValue(record, "time"),
776
712
  os: colorValue(record, "os"),
777
713
  editorAccent: colorValue(record, "editorAccent"),
778
- editorRail: colorValue(record, "editorRail"),
779
- editorPrompt: colorValue(record, "editorPrompt"),
780
714
  editorBorder: colorValue(record, "editorBorder"),
781
715
  editorGitBranch: colorValue(record, "editorGitBranch"),
782
716
  editorModel: colorValue(record, "editorModel"),
@@ -1073,11 +1007,6 @@ function resolveComponents(config: ConfigRecord): ComponentsConfig {
1073
1007
  const components = recordValue(config.components);
1074
1008
  const editor = recordValue(components.editor);
1075
1009
  const editorStyles = recordValue(editor.styles);
1076
- const opencode = recordValue(editorStyles.opencode);
1077
- const opencodeCopyFriendly = recordValue(
1078
- editorStyles["opencode-copy-friendly"],
1079
- );
1080
- const accentRail = recordValue(editorStyles["accent-rail"]);
1081
1010
  const minimalist = recordValue(editorStyles.minimalist);
1082
1011
  const userMessages = recordValue(components.userMessages);
1083
1012
  const workingLine = recordValue(components.workingLine);
@@ -1090,8 +1019,12 @@ function resolveComponents(config: ConfigRecord): ComponentsConfig {
1090
1019
 
1091
1020
  return {
1092
1021
  editor: {
1093
- enabled: parseBoolean(editor.enabled, defaultComponents.editor.enabled),
1094
- style: parseEditorStyle(editor.style),
1022
+ // 迁移:旧 enabled:false 收敛为 style:"off"(enabled 字段已移除)。
1023
+ style:
1024
+ hasOwn(editor, "enabled") &&
1025
+ parseBoolean(editor.enabled, true) === false
1026
+ ? "off"
1027
+ : parseEditorStyle(editor.style),
1095
1028
  colorSource: parseColorSource(
1096
1029
  editor.colorSource,
1097
1030
  defaultComponents.editor.colorSource,
@@ -1106,36 +1039,6 @@ function resolveComponents(config: ConfigRecord): ComponentsConfig {
1106
1039
  defaultComponents.editor.viewportIndicators,
1107
1040
  ),
1108
1041
  styles: {
1109
- opencode: {
1110
- metadataFormat: parseNonEmptyString(
1111
- opencode.metadataFormat,
1112
- DEFAULT_EDITOR_METADATA_FORMAT,
1113
- ),
1114
- completionMenu: parseCompletionMenuStyle(opencode.completionMenu),
1115
- },
1116
- "opencode-copy-friendly": {
1117
- metadataFormat: parseNonEmptyString(
1118
- opencodeCopyFriendly.metadataFormat,
1119
- DEFAULT_EDITOR_METADATA_FORMAT,
1120
- ),
1121
- completionMenu: parseCompletionMenuStyle(
1122
- opencodeCopyFriendly.completionMenu,
1123
- ),
1124
- },
1125
- "accent-rail": {
1126
- rail: parseNonEmptyString(
1127
- accentRail.rail,
1128
- defaultAccentRailStyle.rail,
1129
- ),
1130
- asciiRail: parseNonEmptyString(
1131
- accentRail.asciiRail,
1132
- defaultAccentRailStyle.asciiRail,
1133
- ),
1134
- transparent: parseBoolean(
1135
- accentRail.transparent,
1136
- defaultAccentRailStyle.transparent,
1137
- ),
1138
- },
1139
1042
  minimalist: {
1140
1043
  pathDisplay:
1141
1044
  minimalist.pathDisplay === "compact" ||
@@ -1143,15 +1046,6 @@ function resolveComponents(config: ConfigRecord): ComponentsConfig {
1143
1046
  minimalist.pathDisplay === "full"
1144
1047
  ? minimalist.pathDisplay
1145
1048
  : defaultMinimalistStyle.pathDisplay,
1146
- contextFormat:
1147
- minimalist.contextFormat === "percent" ||
1148
- minimalist.contextFormat === "percent-total"
1149
- ? minimalist.contextFormat
1150
- : defaultMinimalistStyle.contextFormat,
1151
- contextGauge: parseBoolean(
1152
- minimalist.contextGauge,
1153
- defaultMinimalistStyle.contextGauge,
1154
- ),
1155
1049
  showSessionName: parseBoolean(
1156
1050
  minimalist.showSessionName,
1157
1051
  defaultMinimalistStyle.showSessionName,
@@ -1168,10 +1062,6 @@ function resolveComponents(config: ConfigRecord): ComponentsConfig {
1168
1062
  minimalist.showGit,
1169
1063
  defaultMinimalistStyle.showGit,
1170
1064
  ),
1171
- contextThresholds: resolveContextThresholds(
1172
- minimalist.contextThresholds,
1173
- defaultMinimalistStyle.contextThresholds,
1174
- ),
1175
1065
  },
1176
1066
  },
1177
1067
  },
@@ -1327,8 +1217,7 @@ function derivedRuntimeView(config: ZentuiConfig): PolishedTuiConfig {
1327
1217
  extensionStatuses: starship.extensionStatuses,
1328
1218
  editorStyle: config.components.editor.style,
1329
1219
  editorStyles: { minimalist },
1330
- editorMetadataFormat:
1331
- config.components.editor.styles.opencode.metadataFormat,
1220
+ editorMetadataFormat: DEFAULT_EDITOR_METADATA_FORMAT,
1332
1221
  editorBorderColorMode: config.components.editor.borderColorMode,
1333
1222
  editorModelLabel: config.components.editor.modelLabel,
1334
1223
  colorSources: {
@@ -1337,7 +1226,7 @@ function derivedRuntimeView(config: ZentuiConfig): PolishedTuiConfig {
1337
1226
  userMessages: config.components.userMessages.colorSource,
1338
1227
  },
1339
1228
  features: {
1340
- editor: config.components.editor.enabled,
1229
+ editor: config.components.editor.style === "on",
1341
1230
  statusLine: config.components.footer.style === "starship",
1342
1231
  viewportIndicators: config.components.editor.viewportIndicators,
1343
1232
  },
@@ -1349,16 +1238,19 @@ const unsupportedComponentStyles = new WeakMap<
1349
1238
  ReadonlySet<ComponentStyleOwner>
1350
1239
  >();
1351
1240
 
1241
+ // Retired selections migrate to the sole "on" (minimalist) style instead of
1242
+ // disabling the custom Editor. opencode itself is retired along with its variants.
1243
+ const retiredEditorStyleIds: ReadonlySet<string> = new Set([
1244
+ "opencode",
1245
+ "opencode-copy-friendly",
1246
+ "accent-rail",
1247
+ ]);
1248
+
1352
1249
  const knownComponentStyleIds: Record<
1353
1250
  ComponentStyleOwner,
1354
1251
  ReadonlySet<string>
1355
1252
  > = {
1356
- editor: new Set([
1357
- "opencode",
1358
- "opencode-copy-friendly",
1359
- "accent-rail",
1360
- "minimalist",
1361
- ]),
1253
+ editor: new Set(["on", "off"]),
1362
1254
  userMessages: new Set([
1363
1255
  "framed",
1364
1256
  "framed-copy-friendly",
@@ -1378,7 +1270,8 @@ function unsupportedSelectedStyleId(
1378
1270
  const style = component.style;
1379
1271
  return typeof style === "string" &&
1380
1272
  style.trim() &&
1381
- !knownComponentStyleIds[owner].has(style)
1273
+ !knownComponentStyleIds[owner].has(style) &&
1274
+ !(owner === "editor" && retiredEditorStyleIds.has(style))
1382
1275
  ? style
1383
1276
  : undefined;
1384
1277
  }
@@ -1525,7 +1418,6 @@ function applyEditorComponentPatch(
1525
1418
  patch: Partial<
1526
1419
  Pick<
1527
1420
  EditorComponentConfig,
1528
- | "enabled"
1529
1421
  | "style"
1530
1422
  | "colorSource"
1531
1423
  | "borderColorMode"
@@ -1534,7 +1426,6 @@ function applyEditorComponentPatch(
1534
1426
  >
1535
1427
  >,
1536
1428
  ): void {
1537
- if (patch.enabled !== undefined) component.enabled = patch.enabled;
1538
1429
  if (patch.style !== undefined) component.style = patch.style;
1539
1430
  if (patch.colorSource !== undefined)
1540
1431
  component.colorSource = patch.colorSource;
@@ -1550,7 +1441,6 @@ export function saveEditorComponentPatch(
1550
1441
  patch: Partial<
1551
1442
  Pick<
1552
1443
  EditorComponentConfig,
1553
- | "enabled"
1554
1444
  | "style"
1555
1445
  | "colorSource"
1556
1446
  | "borderColorMode"
@@ -1567,63 +1457,16 @@ export function saveEditorComponentPatch(
1567
1457
  );
1568
1458
  }
1569
1459
 
1570
- export function savePolishedEditorStylePatch(
1571
- patch: Partial<PolishedEditorStyleConfig>,
1572
- path = configPath,
1573
- ): PolishedTuiConfig {
1574
- return saveComponentsMutation((components) => {
1575
- const style = components.editor.styles.opencode;
1576
- if (patch.metadataFormat !== undefined)
1577
- style.metadataFormat = patch.metadataFormat;
1578
- if (patch.completionMenu !== undefined)
1579
- style.completionMenu = patch.completionMenu;
1580
- }, path);
1581
- }
1582
-
1583
- export function savePolishedCopyFriendlyEditorStylePatch(
1584
- patch: Partial<PolishedCopyFriendlyEditorStyleConfig>,
1585
- path = configPath,
1586
- ): PolishedTuiConfig {
1587
- return saveComponentsMutation((components) => {
1588
- const style = components.editor.styles["opencode-copy-friendly"];
1589
- if (patch.metadataFormat !== undefined)
1590
- style.metadataFormat = patch.metadataFormat;
1591
- if (patch.completionMenu !== undefined)
1592
- style.completionMenu = patch.completionMenu;
1593
- }, path);
1594
- }
1595
-
1596
- export function saveAccentRailEditorStylePatch(
1597
- patch: Partial<AccentRailEditorStyleConfig>,
1598
- path = configPath,
1599
- ): PolishedTuiConfig {
1600
- return saveComponentsMutation((components) => {
1601
- const style = components.editor.styles["accent-rail"];
1602
- if (patch.rail !== undefined) style.rail = patch.rail;
1603
- if (patch.asciiRail !== undefined) style.asciiRail = patch.asciiRail;
1604
- if (patch.transparent !== undefined) style.transparent = patch.transparent;
1605
- }, path);
1606
- }
1607
-
1608
1460
  function applyMinimalistStylePatch(
1609
1461
  style: MinimalistEditorStyleConfig,
1610
1462
  patch: Partial<MinimalistEditorStyleConfig>,
1611
1463
  ): void {
1612
1464
  if (patch.pathDisplay !== undefined) style.pathDisplay = patch.pathDisplay;
1613
- if (patch.contextFormat !== undefined)
1614
- style.contextFormat = patch.contextFormat;
1615
- if (patch.contextGauge !== undefined) style.contextGauge = patch.contextGauge;
1616
1465
  if (patch.showSessionName !== undefined)
1617
1466
  style.showSessionName = patch.showSessionName;
1618
1467
  if (patch.showTimer !== undefined) style.showTimer = patch.showTimer;
1619
1468
  if (patch.showCost !== undefined) style.showCost = patch.showCost;
1620
1469
  if (patch.showGit !== undefined) style.showGit = patch.showGit;
1621
- if (patch.contextThresholds !== undefined) {
1622
- style.contextThresholds = {
1623
- ...style.contextThresholds,
1624
- ...patch.contextThresholds,
1625
- };
1626
- }
1627
1470
  }
1628
1471
 
1629
1472
  export function saveMinimalistEditorStylePatch(
@@ -1813,7 +1656,7 @@ export function saveUiFeaturesPatch(
1813
1656
  return saveComponentsMutation(
1814
1657
  (components) => {
1815
1658
  if (valid.editor !== undefined) {
1816
- components.editor.enabled = valid.editor;
1659
+ components.editor.style = valid.editor ? "on" : "off";
1817
1660
  components.userMessages.enabled = valid.editor;
1818
1661
  components.selectorBorders.enabled = valid.editor;
1819
1662
  }
@@ -1912,10 +1755,6 @@ export function saveContextThresholdsPatch(
1912
1755
  throw new TypeError("Context thresholds must be JSON-serializable numbers");
1913
1756
  }
1914
1757
  return saveComponentsMutation((components) => {
1915
- components.editor.styles.minimalist.contextThresholds = {
1916
- ...components.editor.styles.minimalist.contextThresholds,
1917
- ...thresholds,
1918
- };
1919
1758
  components.footer.styles.starship.contextThresholds = {
1920
1759
  ...components.footer.styles.starship.contextThresholds,
1921
1760
  ...thresholds,
@@ -23,10 +23,11 @@ import {
23
23
  } from "./config/renderer.ts";
24
24
  import {
25
25
  type EditorComponentConfig,
26
- type EditorStyle,
27
26
  type FooterComponentConfig,
28
27
  type FooterStyle,
29
28
  loadConfig as loadShellConfig,
29
+ saveColorSourcesPatch,
30
+ saveEditorBorderColorMode,
30
31
  saveEditorComponentPatch,
31
32
  saveFooterComponentPatch,
32
33
  saveUserMessagesComponentPatch,
@@ -40,12 +41,6 @@ import { overlayManager } from "./overlay/overlay-manager.ts";
40
41
  import { ownerFor } from "./ownership.ts";
41
42
  import { applyPreset, PRESET_VALUES, type Preset } from "./presets.ts";
42
43
 
43
- const EDITOR_STYLES: EditorStyle[] = [
44
- "opencode",
45
- "opencode-copy-friendly",
46
- "accent-rail",
47
- "minimalist",
48
- ];
49
44
  const MESSAGE_STYLES: UserMessageStyle[] = [
50
45
  "framed",
51
46
  "framed-copy-friendly",
@@ -131,18 +126,28 @@ function editorItems(): SettingItem[] {
131
126
  const config = loadShellConfig();
132
127
  return [
133
128
  {
134
- id: "editorEnabled",
129
+ id: "editorStyle",
135
130
  label: "Editor",
136
- description: "Enable the custom input editor.",
137
- currentValue: onOff(config.components.editor.enabled),
131
+ description:
132
+ "on applies the Minimalist decoration; off restores Pi's native editor.",
133
+ currentValue: config.components.editor.style,
138
134
  values: ["on", "off"],
139
135
  },
140
136
  {
141
- id: "editorStyle",
142
- label: "Editor style",
143
- description: "Choose the input editor treatment.",
144
- currentValue: config.components.editor.style,
145
- values: EDITOR_STYLES,
137
+ id: "editorColorSource",
138
+ label: "Color source",
139
+ description:
140
+ "theme resolves colors through the active Pi theme; terminal uses fixed terminal colors.",
141
+ currentValue: config.components.editor.colorSource,
142
+ values: ["theme", "terminal"],
143
+ },
144
+ {
145
+ id: "editorBorderColorMode",
146
+ label: "Border color",
147
+ description:
148
+ "static keeps one border color; adaptive shifts the border with the effort level.",
149
+ currentValue: config.components.editor.borderColorMode,
150
+ values: ["static", "adaptive"],
146
151
  },
147
152
  ];
148
153
  }
@@ -434,18 +439,31 @@ function updateSetting(
434
439
  ctx: any,
435
440
  deps: UnifiedPanelDeps,
436
441
  ): void {
437
- if (id === "editorEnabled") {
438
- if (deps.runtime)
439
- deps.runtime.setEditorComponent({ enabled: isOn(value) }, ctx);
440
- else saveEditorComponentPatch({ enabled: isOn(value) });
442
+ if (id === "editorStyle" && (value === "on" || value === "off")) {
443
+ if (deps.runtime) deps.runtime.setEditorComponent({ style: value }, ctx);
444
+ else saveEditorComponentPatch({ style: value });
441
445
  saveNotice(ctx, "Editor", value);
442
446
  return;
443
447
  }
444
- if (id === "editorStyle" && EDITOR_STYLES.includes(value as EditorStyle)) {
448
+ if (
449
+ id === "editorColorSource" &&
450
+ (value === "theme" || value === "terminal")
451
+ ) {
445
452
  if (deps.runtime)
446
- deps.runtime.setEditorComponent({ style: value as EditorStyle }, ctx);
447
- else saveEditorComponentPatch({ style: value as EditorStyle });
448
- saveNotice(ctx, "Editor style", value);
453
+ deps.runtime.setEditorComponent({ colorSource: value }, ctx);
454
+ else saveColorSourcesPatch({ editor: value });
455
+ saveNotice(ctx, "Color source", value);
456
+ return;
457
+ }
458
+ if (id === "editorBorderColorMode") {
459
+ const valid =
460
+ value === "static" || value === "adaptive" ? value : undefined;
461
+ if (valid) {
462
+ if (deps.runtime)
463
+ deps.runtime.setEditorComponent({ borderColorMode: valid }, ctx);
464
+ else saveEditorBorderColorMode(valid);
465
+ saveNotice(ctx, "Border color", value);
466
+ }
449
467
  return;
450
468
  }
451
469
  if (id === "userMessagesEnabled") {
@@ -620,7 +638,7 @@ export async function showOneUiPanel(
620
638
  createList();
621
639
  list.selectItem(id);
622
640
  } finally {
623
- if (id === "editorEnabled" || id === "editorStyle") {
641
+ if (id === "editorStyle") {
624
642
  panelHandle?.focus();
625
643
  }
626
644
  tui.requestRender();
@@ -17,7 +17,7 @@ export function isPreset(value: string): value is Preset {
17
17
  /** Apply only ownership-related values; detailed options remain user-editable. */
18
18
  export function applyPreset(preset: Preset): void {
19
19
  if (preset === "native") {
20
- saveEditorComponentPatch({ enabled: false });
20
+ saveEditorComponentPatch({ style: "off" });
21
21
  saveUserMessagesComponentPatch({ enabled: false });
22
22
  saveWorkingLineComponentPatch({ enabled: false });
23
23
  saveFooterComponentPatch({ style: "native" });
@@ -25,7 +25,7 @@ export function applyPreset(preset: Preset): void {
25
25
  return;
26
26
  }
27
27
 
28
- saveEditorComponentPatch({ enabled: true });
28
+ saveEditorComponentPatch({ style: "on" });
29
29
  saveUserMessagesComponentPatch({ enabled: true });
30
30
  saveWorkingLineComponentPatch({ enabled: true });
31
31
  saveFooterComponentPatch({ style: "starship" });
@@ -7,7 +7,6 @@ import registerContext, {
7
7
  type ContextExtensionOptions,
8
8
  type ContextRuntimeController,
9
9
  } from "../../layouts/context/index.ts";
10
- import type { AccentRailLayoutPatchDiagnostic } from "../../layouts/editor/accent-rail-layout-patch.ts";
11
10
  import { EditorLayoutController } from "../../layouts/editor/controller.ts";
12
11
  import { FooterLayoutController } from "../../layouts/footer/controller.ts";
13
12
  import registerHeaderLayout from "../../layouts/header/index.ts";
@@ -240,17 +239,6 @@ function createLayoutRuntime(
240
239
  let minimalistProjectRoot: string | undefined;
241
240
  let activeTuiContext: ExtensionContext | undefined;
242
241
 
243
- const recordAccentRailLayoutPatchDiagnostic = (
244
- diagnostic: AccentRailLayoutPatchDiagnostic,
245
- version?: string,
246
- ) => {
247
- if (process.env.ZENTUI_DEBUG === "1") {
248
- console.error(
249
- `[zentui] Accent Rail fullscreen layout patch: ${diagnostic}${version ? ` (Pi TUI ${version})` : ""}`,
250
- );
251
- }
252
- };
253
-
254
242
  /**
255
243
  * Requests redraws from the Editor controller and shared render seam.
256
244
  */
@@ -297,16 +285,6 @@ function createLayoutRuntime(
297
285
  sessionLifecycle,
298
286
  render: { request: () => footerController.requestRender() },
299
287
  getThinkingLevel,
300
- getContextWindow: (ctx) =>
301
- ctx.model?.contextWindow ?? ctx.getContextUsage()?.contextWindow,
302
- getContextPercent: (ctx) => {
303
- const usage = ctx.getContextUsage();
304
- const contextWindow = ctx.model?.contextWindow ?? usage?.contextWindow;
305
- const live = liveContext.get();
306
- return live && contextWindow && contextWindow > 0
307
- ? (live.tokens / contextWindow) * 100
308
- : (usage?.percent ?? undefined);
309
- },
310
288
  getAgentDurationMs: () => workingLineController.duration().elapsedMs() ?? 0,
311
289
  isAgentActive: () => workingLineController.isAgentActive(),
312
290
  isAgentDurationActive: () => workingLineController.duration().isActive(),
@@ -317,7 +295,6 @@ function createLayoutRuntime(
317
295
  if (activeTuiContext) projectRefreshService.reconcile(activeTuiContext);
318
296
  },
319
297
  onModelLabelChanged: (ctx) => syncFooterState(ctx),
320
- recordLayoutDiagnostic: recordAccentRailLayoutPatchDiagnostic,
321
298
  });
322
299
  const syncFooterState = (ctx: ExtensionContext) => sessionState.sync(ctx);
323
300
  const projectRefreshService = new ProjectRefreshService({
@@ -427,10 +404,8 @@ function createLayoutRuntime(
427
404
  * @param coordinator Shared lifecycle event coordinator.
428
405
  */
429
406
  const installEventHandlers = (coordinator: EventCoordinator): void => {
430
- coordinator.on("session_start", async (_event, ctx) => {
407
+ coordinator.on("session_start", (_event, ctx) => {
431
408
  sessionLifecycle.start();
432
- await editorController.startSession(ctx);
433
- if (!sessionLifecycle.isCurrent()) return;
434
409
  liveContext.startSession();
435
410
  sessionState.startSession();
436
411
  minimalistProjectRoot = undefined;