pi-one-ui 0.7.2 → 0.9.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +52 -1
  2. package/README.en.md +5 -8
  3. package/README.md +6 -7
  4. package/extensions/app/config/footer.ts +21 -5
  5. package/extensions/app/config/renderer.ts +1 -12
  6. package/extensions/app/config/shell.ts +62 -60
  7. package/extensions/app/runtime/prototype-patch-registry.ts +13 -9
  8. package/extensions/app/runtime/tui-runtime.ts +19 -12
  9. package/extensions/app/settings/controller.ts +2 -2
  10. package/extensions/layouts/context/index.ts +2 -2
  11. package/extensions/layouts/context/message/user-message-osc.ts +1 -1
  12. package/extensions/layouts/context/message/user-message-styles.ts +9 -6
  13. package/extensions/layouts/context/message/user-message.ts +5 -5
  14. package/extensions/layouts/context/renderer/compact-mode.ts +2 -2
  15. package/extensions/layouts/context/renderer/default-mode.ts +10 -10
  16. package/extensions/layouts/context/renderer/index.ts +0 -1
  17. package/extensions/layouts/context/renderer/mouse/hover.ts +0 -4
  18. package/extensions/layouts/context/renderer/mouse/interaction.ts +106 -95
  19. package/extensions/layouts/context/renderer/mouse/layout.ts +0 -4
  20. package/extensions/layouts/context/renderer/mouse/scroll.ts +2 -183
  21. package/extensions/layouts/context/renderer/tool/diff/diff-edit-render.ts +1 -1
  22. package/extensions/layouts/context/renderer/tool/diff/index.ts +1 -1
  23. package/extensions/layouts/context/renderer/tool/grouping.ts +3 -3
  24. package/extensions/layouts/context/renderer/tool/message-display.ts +7 -7
  25. package/extensions/layouts/context/renderer/tool/result.ts +16 -16
  26. package/extensions/layouts/context/renderer/tool/toggle-render-cache.ts +9 -9
  27. package/extensions/layouts/editor/controller.ts +17 -17
  28. package/extensions/layouts/editor/editor-metadata-format.ts +5 -5
  29. package/extensions/layouts/editor/factory.ts +5 -5
  30. package/extensions/layouts/editor/minimalist-editor.ts +8 -8
  31. package/extensions/layouts/editor/ownership.ts +24 -20
  32. package/extensions/layouts/editor/ui.ts +10 -15
  33. package/extensions/layouts/footer/controller.ts +4 -4
  34. package/extensions/layouts/footer/data.ts +2 -2
  35. package/extensions/layouts/footer/extension-status.ts +4 -4
  36. package/extensions/layouts/footer/footer.ts +5 -2
  37. package/extensions/layouts/overlay/selector-border.ts +4 -4
  38. package/extensions/layouts/overlay/selector-controller.ts +1 -1
  39. package/extensions/layouts/overlay/settings-previews.ts +2 -2
  40. package/extensions/layouts/working-line/interaction-summary.ts +3 -1
  41. package/extensions/layouts/working-line/working-line.ts +4 -4
  42. package/extensions/services/package-data.ts +1 -1
  43. package/extensions/shared/style.ts +66 -56
  44. package/extensions/tools/patch-keys.ts +22 -25
  45. package/package.json +7 -7
@@ -13,7 +13,7 @@ import {
13
13
  import { showMoreHintText } from "./show-more-hint.ts";
14
14
 
15
15
  /**
16
- * 接管三个消息组件(`<skill>` 块、压缩摘要、分支摘要),ccstyle on 时渲染为
16
+ * 接管三个消息组件(`<skill>` 块、压缩摘要、分支摘要),pi-one-ui on 时渲染为
17
17
  * 与工具调用一致的单行风格(● Title · hint),off 时回退原生。
18
18
  *
19
19
  * 三者结构同构:Box + markdownTheme + updateDisplay,构造/setExpanded/invalidate
@@ -68,12 +68,12 @@ function ensureHintHover(component: any): void {
68
68
  };
69
69
  }
70
70
 
71
- function renderCcstyle(component: any, kind: DisplayKind): void {
71
+ function renderPolishedMessage(component: any, kind: DisplayKind): void {
72
72
  const theme = displayTheme;
73
73
  if (!theme) return; // 主题未就绪时保留原生渲染
74
74
  if (component.bgFn) component.setBgFn?.(undefined); // 与工具调用一致,去掉灰底
75
75
  if (component.paddingY !== 0) {
76
- component._ccstyleOriginalPaddingY = component.paddingY;
76
+ component._oneuiOriginalPaddingY = component.paddingY;
77
77
  component.paddingY = 0; // 工具组件 paddingY=0;原生 Box 默认 1,会上下各留一个空行
78
78
  }
79
79
  component.clear();
@@ -128,16 +128,16 @@ export function installMessageDisplayRendering(): () => void {
128
128
  const installed = function (this: any) {
129
129
  if (patch.active && config.mode !== "off") {
130
130
  try {
131
- renderCcstyle(this, kind);
131
+ renderPolishedMessage(this, kind);
132
132
  return;
133
133
  } catch {
134
134
  // 渲染失败回退原生
135
135
  }
136
136
  }
137
137
  // 回退原生前恢复 paddingY,避免原生渲染丢失上下内边距
138
- if (this._ccstyleOriginalPaddingY !== undefined) {
139
- this.paddingY = this._ccstyleOriginalPaddingY;
140
- delete this._ccstyleOriginalPaddingY;
138
+ if (this._oneuiOriginalPaddingY !== undefined) {
139
+ this.paddingY = this._oneuiOriginalPaddingY;
140
+ delete this._oneuiOriginalPaddingY;
141
141
  }
142
142
  original.call(this);
143
143
  };
@@ -247,8 +247,8 @@ const activeAnimationContexts = new Set<any>();
247
247
  let sharedAnimationTimer: ReturnType<typeof setTimeout> | null = null;
248
248
 
249
249
  function clearAnimation(context: any) {
250
- if (!context?.state?.ccstyleAnimationScheduled) return;
251
- context.state.ccstyleAnimationScheduled = false;
250
+ if (!context?.state?.oneuiAnimationScheduled) return;
251
+ context.state.oneuiAnimationScheduled = false;
252
252
  activeAnimationContexts.delete(context);
253
253
  if (activeAnimationContexts.size === 0 && sharedAnimationTimer) {
254
254
  clearTimeout(sharedAnimationTimer);
@@ -258,7 +258,7 @@ function clearAnimation(context: any) {
258
258
 
259
259
  export function clearAllAnimations() {
260
260
  for (const ctx of activeAnimationContexts) {
261
- ctx.state.ccstyleAnimationScheduled = false;
261
+ ctx.state.oneuiAnimationScheduled = false;
262
262
  }
263
263
  activeAnimationContexts.clear();
264
264
  if (sharedAnimationTimer) {
@@ -272,8 +272,8 @@ export function scheduleAnimation(
272
272
  intervalMs = TOOL_LOADING_INTERVAL_MS,
273
273
  ) {
274
274
  const state = (context.state ??= {});
275
- if (state.ccstyleAnimationScheduled) return;
276
- state.ccstyleAnimationScheduled = true;
275
+ if (state.oneuiAnimationScheduled) return;
276
+ state.oneuiAnimationScheduled = true;
277
277
  activeAnimationContexts.add(context);
278
278
  if (!sharedAnimationTimer) {
279
279
  sharedAnimationTimer = setTimeout(() => {
@@ -281,7 +281,7 @@ export function scheduleAnimation(
281
281
  const contexts = Array.from(activeAnimationContexts);
282
282
  activeAnimationContexts.clear();
283
283
  for (const ctx of contexts) {
284
- ctx.state.ccstyleAnimationScheduled = false;
284
+ ctx.state.oneuiAnimationScheduled = false;
285
285
  ctx.invalidate?.();
286
286
  }
287
287
  }, intervalMs);
@@ -307,8 +307,8 @@ export function settledIcon(
307
307
  export function setToolVisualState(context: any, visualState: ToolVisualState) {
308
308
  const state = (context.state ??= {});
309
309
  if (visualState !== "pending") clearAnimation(context);
310
- if (state.ccstyleToolVisualState === visualState) return;
311
- state.ccstyleToolVisualState = visualState;
310
+ if (state.oneuiToolVisualState === visualState) return;
311
+ state.oneuiToolVisualState = visualState;
312
312
  // Do not invalidate synchronously from renderResult. Pi is already rendering
313
313
  // this tool row; recursively scheduling another render here can retain both
314
314
  // the finalized result component and its previous secondary/partial component,
@@ -317,7 +317,7 @@ export function setToolVisualState(context: any, visualState: ToolVisualState) {
317
317
  }
318
318
 
319
319
  function getToolVisualState(context: any): ToolVisualState | undefined {
320
- return context?.state?.ccstyleToolVisualState as ToolVisualState | undefined;
320
+ return context?.state?.oneuiToolVisualState as ToolVisualState | undefined;
321
321
  }
322
322
 
323
323
  export function resolveToolVisualState(
@@ -346,7 +346,7 @@ export function toolIconColor(
346
346
  }
347
347
 
348
348
  export function isToolExpanded(options: any, context: any): boolean {
349
- const local = context?.state?.ccstyleToolExpanded;
349
+ const local = context?.state?.oneuiToolExpanded;
350
350
  return typeof local === "boolean"
351
351
  ? local
352
352
  : Boolean(options?.expanded ?? context?.expanded);
@@ -407,7 +407,7 @@ export type ToolIoSection = "input" | "output";
407
407
  // Module-local token: /reload creates a fresh token, so stale view instances are
408
408
  // replaced instead of retaining their old render implementation.
409
409
  const EXPANDED_TOOL_IO_VIEW_GENERATION = Symbol(
410
- "ccstyle-expanded-tool-io-view",
410
+ "pi-one-ui.expanded-tool-io-view",
411
411
  );
412
412
 
413
413
  /**
@@ -931,7 +931,7 @@ export function renderExpandedToolResult(
931
931
 
932
932
  // Prefer structured Input/Output when we have args or non-empty output.
933
933
  if (inputBody.trim() || outputBody.trim()) {
934
- const cached = context?.state?.ccstyleExpandedIoView;
934
+ const cached = context?.state?.oneuiExpandedIoView;
935
935
  let view: ExpandedToolIoView;
936
936
  if (isExpandedToolIoView(lastComponent)) {
937
937
  view = lastComponent;
@@ -962,8 +962,8 @@ export function renderExpandedToolResult(
962
962
  }
963
963
 
964
964
  if (context?.state) {
965
- context.state.ccstyleIoView = undefined;
966
- context.state.ccstyleExpandedIoView = undefined;
965
+ context.state.oneuiIoView = undefined;
966
+ context.state.oneuiExpandedIoView = undefined;
967
967
  }
968
968
  const color = isError ? "error" : "muted";
969
969
  return new Text(theme.fg(color, renderCollapsedToolResult("Done")), 0, 0);
@@ -1079,8 +1079,8 @@ function rememberIoView(context: any, view: ExpandedToolIoView): void {
1079
1079
  ioViewInvalidators.set(view, () => context.invalidate());
1080
1080
  }
1081
1081
  if (!context.state || typeof context.state !== "object") context.state = {};
1082
- context.state.ccstyleIoView = view;
1083
- context.state.ccstyleExpandedIoView = view;
1082
+ context.state.oneuiIoView = view;
1083
+ context.state.oneuiExpandedIoView = view;
1084
1084
  }
1085
1085
 
1086
1086
  /** hover 状态变更后刷新上一个/下一个视图(context.invalidate 缓存于 ioViewInvalidators)。 */
@@ -35,7 +35,7 @@ type RenderSlot = {
35
35
  shell: "box" | "self" | "text" | null;
36
36
  callComponent: unknown;
37
37
  resultComponent: unknown;
38
- /** rendererState 中 ccstyle 渲染层的指针快照(切槽重装时恢复)。 */
38
+ /** rendererState 中 pi-one-ui 渲染层的指针快照(切槽重装时恢复)。 */
39
39
  stateSnapshot: [unknown, unknown, unknown];
40
40
  };
41
41
 
@@ -89,7 +89,7 @@ function fingerprintOf(
89
89
  * 不再排期,长命令期间 loading 图标就会冻结在当前帧。
90
90
  */
91
91
  function schedulesPendingAnimation(component: any): boolean {
92
- const visualState = component?.rendererState?.ccstyleToolVisualState as
92
+ const visualState = component?.rendererState?.oneuiToolVisualState as
93
93
  | string
94
94
  | undefined;
95
95
  const pending =
@@ -166,9 +166,9 @@ function syncShell(component: any, shell: "box" | "self" | "text"): void {
166
166
  function stateSnapshotOf(component: any): [unknown, unknown, unknown] {
167
167
  const state = component?.rendererState;
168
168
  return [
169
- state?.ccstyleIoView,
170
- state?.ccstyleExpandedIoView,
171
- state?.ccstyleToolVisualState,
169
+ state?.oneuiIoView,
170
+ state?.oneuiExpandedIoView,
171
+ state?.oneuiToolVisualState,
172
172
  ];
173
173
  }
174
174
 
@@ -186,14 +186,14 @@ function restoreStateSnapshot(
186
186
  const state = (component.rendererState ??= {});
187
187
  // ioView/visualState 每槽构建时都会写入,按槽恢复;
188
188
  // expandedIoView 是跨槽保留指针(折叠 renderer 不清),只在展开槽恢复。
189
- state.ccstyleIoView = snapshot[0];
190
- state.ccstyleToolVisualState = snapshot[1];
191
- if (slotKey === "expanded") state.ccstyleExpandedIoView = snapshot[2];
189
+ state.oneuiIoView = snapshot[0];
190
+ state.oneuiToolVisualState = snapshot[1];
191
+ if (slotKey === "expanded") state.oneuiExpandedIoView = snapshot[2];
192
192
  }
193
193
 
194
194
  /**
195
195
  * 把缓存槽的 call/result 组件装回目标壳容器并恢复派生字段。
196
- * 同时恢复 ccstyle 渲染层的 rendererState 指针快照(ioView / expandedIoView /
196
+ * 同时恢复 pi-one-ui 渲染层的 rendererState 指针快照(ioView / expandedIoView /
197
197
  * visualState),补齐切槽跳过 renderer 调用导致的状态缺失;pending 展开时
198
198
  * 重新调度加载动画。text fallback 槽(无容器装载语义)返回 false,调用方
199
199
  * 退化为重建。
@@ -20,9 +20,9 @@ import {
20
20
  } from "./factory.ts";
21
21
  import {
22
22
  type EditorFactory,
23
- getZentuiEditorBaseFactory,
23
+ getPolishedEditorBaseFactory,
24
24
  isOwnedEditorFactory,
25
- isZentuiEditorFactory,
25
+ isPolishedEditorFactory,
26
26
  } from "./ownership.ts";
27
27
 
28
28
  export type EditorChangeResult = { ok: true } | { ok: false; reason: string };
@@ -72,18 +72,18 @@ export class EditorLayoutController {
72
72
  * Installs or reconciles the configured Editor for an active session.
73
73
  *
74
74
  * @param ctx Active Pi extension context.
75
- * @param allowStaleZentui Whether a stale predecessor may be replaced.
75
+ * @param allowStalePolished Whether a stale predecessor may be replaced.
76
76
  * @returns The replacement result when a host factory changed.
77
77
  */
78
78
  install(
79
79
  ctx: ExtensionContext,
80
- allowStaleZentui = true,
80
+ allowStalePolished = true,
81
81
  ): EditorChangeResult | undefined {
82
82
  if (!this.isTuiContext(ctx)) return;
83
83
  this.activeTuiContext = ctx;
84
84
  if (this.isEditorEnabled()) this.clearEditorOwnership();
85
- else this.uninstall(ctx, { allowStaleZentui });
86
- const result = this.reconcile(ctx, { allowStaleZentui });
85
+ else this.uninstall(ctx, { allowStalePolished });
86
+ const result = this.reconcile(ctx, { allowStalePolished });
87
87
  this.scheduleReconciliation(ctx);
88
88
  return result;
89
89
  }
@@ -97,15 +97,15 @@ export class EditorLayoutController {
97
97
  */
98
98
  reconcile(
99
99
  ctx: ExtensionContext,
100
- options: { allowStaleZentui?: boolean } = {},
100
+ options: { allowStalePolished?: boolean } = {},
101
101
  ): EditorChangeResult | undefined {
102
102
  try {
103
103
  if (this.isEditorEnabled()) {
104
104
  const currentFactory = ctx.ui.getEditorComponent();
105
105
  if (
106
- isZentuiEditorFactory(currentFactory) &&
106
+ isPolishedEditorFactory(currentFactory) &&
107
107
  !this.ownsFactory(currentFactory) &&
108
- !options.allowStaleZentui
108
+ !options.allowStalePolished
109
109
  ) {
110
110
  this.clearEditorOwnership();
111
111
  return;
@@ -254,7 +254,7 @@ export class EditorLayoutController {
254
254
  */
255
255
  uninstall(
256
256
  ctx: ExtensionContext,
257
- options: { allowStaleZentui?: boolean } = {},
257
+ options: { allowStalePolished?: boolean } = {},
258
258
  ): EditorChangeResult {
259
259
  let currentFactory: EditorFactory | undefined;
260
260
  try {
@@ -266,17 +266,17 @@ export class EditorLayoutController {
266
266
  "the current editor factory could not be observed safely; reload Pi to apply this change",
267
267
  };
268
268
  }
269
- if (!currentFactory || !isZentuiEditorFactory(currentFactory)) {
269
+ if (!currentFactory || !isPolishedEditorFactory(currentFactory)) {
270
270
  this.clearEditorOwnership();
271
271
  return { ok: true };
272
272
  }
273
- if (!this.ownsFactory(currentFactory) && !options.allowStaleZentui) {
273
+ if (!this.ownsFactory(currentFactory) && !options.allowStalePolished) {
274
274
  this.clearEditorOwnership();
275
275
  return { ok: true };
276
276
  }
277
277
  const result = this.replace(
278
278
  ctx,
279
- getZentuiEditorBaseFactory(currentFactory) ??
279
+ getPolishedEditorBaseFactory(currentFactory) ??
280
280
  (this.editorInstallMode === "wrapper"
281
281
  ? this.wrappedEditorFactory
282
282
  : undefined),
@@ -299,7 +299,7 @@ export class EditorLayoutController {
299
299
  if (currentFactory && this.ownsFactory(currentFactory)) {
300
300
  this.replace(
301
301
  ctx,
302
- getZentuiEditorBaseFactory(currentFactory) ??
302
+ getPolishedEditorBaseFactory(currentFactory) ??
303
303
  (this.editorInstallMode === "wrapper"
304
304
  ? this.wrappedEditorFactory
305
305
  : undefined),
@@ -395,7 +395,7 @@ export class EditorLayoutController {
395
395
  * @param factory Factory created by this controller.
396
396
  */
397
397
  private trackFactory(factory: EditorFactory): void {
398
- const baseFactory = getZentuiEditorBaseFactory(factory);
398
+ const baseFactory = getPolishedEditorBaseFactory(factory);
399
399
  this.wrappedEditorFactory = baseFactory;
400
400
  this.installedEditorFactory = factory;
401
401
  this.editorInstallMode = baseFactory ? "wrapper" : "standalone";
@@ -444,8 +444,8 @@ export class EditorLayoutController {
444
444
  return { ok: true };
445
445
  }
446
446
  const baseFactory =
447
- getZentuiEditorBaseFactory(currentFactory) ??
448
- (currentFactory && !isZentuiEditorFactory(currentFactory)
447
+ getPolishedEditorBaseFactory(currentFactory) ??
448
+ (currentFactory && !isPolishedEditorFactory(currentFactory)
449
449
  ? currentFactory
450
450
  : undefined);
451
451
  const runtime = this.factoryRuntime(ctx);
@@ -1,5 +1,5 @@
1
1
  import type { Theme } from "@earendil-works/pi-coding-agent";
2
- import type { ZentuiConfig } from "../../app/config/shell.ts";
2
+ import type { PolishedTuiConfig } from "../../app/config/shell.ts";
3
3
  import {
4
4
  EDITOR_ACCENT_FALLBACK,
5
5
  renderThemeStyleOrFallback,
@@ -140,7 +140,7 @@ export function sanitizeEditorMetadataText(value: string): string {
140
140
  }
141
141
 
142
142
  function editorThinkingStyle(
143
- config: ZentuiConfig,
143
+ config: PolishedTuiConfig,
144
144
  level: string,
145
145
  ): string | undefined {
146
146
  switch (level.toLowerCase()) {
@@ -171,7 +171,7 @@ function renderVariable(
171
171
  name: string,
172
172
  values: EditorMetadataValues,
173
173
  uiTheme: Theme,
174
- config: ZentuiConfig,
174
+ config: PolishedTuiConfig,
175
175
  ): { plain: string; styled: string } {
176
176
  const thinking =
177
177
  values.thinking.toLowerCase() === "off" ? "" : values.thinking;
@@ -235,7 +235,7 @@ function renderTokens(
235
235
  tokens: FormatToken[],
236
236
  values: EditorMetadataValues,
237
237
  uiTheme: Theme,
238
- config: ZentuiConfig,
238
+ config: PolishedTuiConfig,
239
239
  ): RenderedTokens {
240
240
  let styled = "";
241
241
  let hasDynamic = false;
@@ -275,7 +275,7 @@ export function renderEditorMetadataFormat(
275
275
  format: string,
276
276
  values: EditorMetadataValues,
277
277
  uiTheme: Theme,
278
- config: ZentuiConfig,
278
+ config: PolishedTuiConfig,
279
279
  ): string {
280
280
  return renderTokens(
281
281
  parseFooterFormat(sanitizeEditorMetadataText(format)),
@@ -11,7 +11,7 @@ import {
11
11
  type EditorFactory,
12
12
  markEditorFactory,
13
13
  markWrappedEditorFactory,
14
- type ZentuiEditorFactory,
14
+ type PolishedEditorFactory,
15
15
  } from "./ownership.ts";
16
16
  import { PolishedEditor, WrappedPolishedEditor } from "./ui.ts";
17
17
 
@@ -38,7 +38,7 @@ export type EditorFactoryRuntime = {
38
38
  export function createEditorFactory(
39
39
  ctx: ExtensionContext,
40
40
  runtime: EditorFactoryRuntime,
41
- ): ZentuiEditorFactory {
41
+ ): PolishedEditorFactory {
42
42
  const factory = ((
43
43
  tui: TUI,
44
44
  theme: EditorTheme,
@@ -56,7 +56,7 @@ export function createEditorFactory(
56
56
  () => editorDecoration(ctx, runtime),
57
57
  runtime.onDecorationActive,
58
58
  );
59
- }) as ZentuiEditorFactory;
59
+ }) as PolishedEditorFactory;
60
60
  return markEditorFactory(factory, runtime.ownerToken);
61
61
  }
62
62
 
@@ -72,7 +72,7 @@ export function createWrappedEditorFactory(
72
72
  ctx: ExtensionContext,
73
73
  baseFactory: EditorFactory,
74
74
  runtime: EditorFactoryRuntime,
75
- ): ZentuiEditorFactory {
75
+ ): PolishedEditorFactory {
76
76
  const factory = ((
77
77
  tui: TUI,
78
78
  theme: EditorTheme,
@@ -88,7 +88,7 @@ export function createWrappedEditorFactory(
88
88
  () => editorDecoration(ctx, runtime),
89
89
  runtime.onDecorationActive,
90
90
  );
91
- }) as ZentuiEditorFactory;
91
+ }) as PolishedEditorFactory;
92
92
  return markWrappedEditorFactory(factory, baseFactory, runtime.ownerToken);
93
93
  }
94
94
 
@@ -1,7 +1,7 @@
1
1
  import { basename, isAbsolute, relative, sep } from "node:path";
2
2
  import type { Theme } from "@earendil-works/pi-coding-agent";
3
3
  import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
4
- import type { ColorSpec, ZentuiConfig } from "../../app/config/shell.ts";
4
+ import type { ColorSpec, PolishedTuiConfig } from "../../app/config/shell.ts";
5
5
  import { formatCwdLabel, formatElapsedDuration } from "../../shared/format.ts";
6
6
  import { sanitizeEditorMetadataText } from "./editor-metadata-format.ts";
7
7
 
@@ -46,7 +46,7 @@ export type MinimalistFrameOptions = {
46
46
  inputText: string;
47
47
  metadata: MinimalistEditorMetadata;
48
48
  uiTheme: Theme;
49
- config: ZentuiConfig;
49
+ config: PolishedTuiConfig;
50
50
  borderColor?: (text: string) => string;
51
51
  };
52
52
 
@@ -103,7 +103,7 @@ function joinStyled(parts: string[], separator: string): string {
103
103
  }
104
104
 
105
105
  function thinkingStyle(
106
- config: ZentuiConfig,
106
+ config: PolishedTuiConfig,
107
107
  level: string,
108
108
  ): string | undefined {
109
109
  switch (level.toLowerCase()) {
@@ -134,7 +134,7 @@ function renderTopLeft(
134
134
  inputText: string,
135
135
  metadata: MinimalistEditorMetadata,
136
136
  uiTheme: Theme,
137
- config: ZentuiConfig,
137
+ config: PolishedTuiConfig,
138
138
  includeSessionName = true,
139
139
  ): string {
140
140
  const trimmed = inputText.trimStart();
@@ -184,7 +184,7 @@ function renderTopLeft(
184
184
  function renderTopRight(
185
185
  metadata: MinimalistEditorMetadata,
186
186
  uiTheme: Theme,
187
- config: ZentuiConfig,
187
+ config: PolishedTuiConfig,
188
188
  renderBorder: (text: string) => string,
189
189
  renderThinking: (text: string) => string,
190
190
  ): string {
@@ -223,7 +223,7 @@ function renderTopRight(
223
223
  function renderBottomLeft(
224
224
  metadata: MinimalistEditorMetadata,
225
225
  uiTheme: Theme,
226
- config: ZentuiConfig,
226
+ config: PolishedTuiConfig,
227
227
  ): string {
228
228
  if (!config.components.editor.styles.minimalist.showGit) return "";
229
229
  const branch = sanitizeEditorMetadataText(metadata.branch ?? "");
@@ -251,7 +251,7 @@ function renderBottomLeft(
251
251
 
252
252
  function minimalistCwdLabel(
253
253
  metadata: MinimalistEditorMetadata,
254
- config: ZentuiConfig,
254
+ config: PolishedTuiConfig,
255
255
  ): string {
256
256
  const full = () =>
257
257
  formatCwdLabel(metadata.cwd, "", { mode: "full", depth: 0 });
@@ -276,7 +276,7 @@ function minimalistCwdLabel(
276
276
  function renderBottomRight(
277
277
  metadata: MinimalistEditorMetadata,
278
278
  uiTheme: Theme,
279
- config: ZentuiConfig,
279
+ config: PolishedTuiConfig,
280
280
  ): string {
281
281
  if (config.components.editor.styles.minimalist.showCwd === false) {
282
282
  return "";
@@ -1,24 +1,28 @@
1
1
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
2
 
3
- /** Symbol used to identify factories created by the Editor layout. */
4
- export const ZENTUI_EDITOR_FACTORY = Symbol.for("pi-zentui.editor-factory");
3
+ /**
4
+ * Symbol used to identify factories created by the Editor layout. All wrappers
5
+ * and marks live in one process, so the key only has to be stable across
6
+ * `/reload` within that process.
7
+ */
8
+ export const POLISHED_EDITOR_FACTORY = Symbol.for("pi-one-ui.editor-factory");
5
9
 
6
10
  /** Symbol used to retain the wrapped third-party editor factory. */
7
- export const ZENTUI_EDITOR_BASE_FACTORY = Symbol.for(
8
- "pi-zentui.editor-base-factory",
11
+ export const POLISHED_EDITOR_BASE_FACTORY = Symbol.for(
12
+ "pi-one-ui.editor-base-factory",
9
13
  );
10
14
 
11
15
  /** Symbol used to identify the active Editor layout owner. */
12
- export const ZENTUI_EDITOR_OWNER = Symbol.for("pi-zentui.editor-owner");
16
+ export const POLISHED_EDITOR_OWNER = Symbol.for("pi-one-ui.editor-owner");
13
17
 
14
18
  export type EditorFactory = NonNullable<
15
19
  Parameters<ExtensionContext["ui"]["setEditorComponent"]>[0]
16
20
  >;
17
21
 
18
- export type ZentuiEditorFactory = EditorFactory & {
19
- [ZENTUI_EDITOR_FACTORY]?: true;
20
- [ZENTUI_EDITOR_BASE_FACTORY]?: EditorFactory;
21
- [ZENTUI_EDITOR_OWNER]?: symbol;
22
+ export type PolishedEditorFactory = EditorFactory & {
23
+ [POLISHED_EDITOR_FACTORY]?: true;
24
+ [POLISHED_EDITOR_BASE_FACTORY]?: EditorFactory;
25
+ [POLISHED_EDITOR_OWNER]?: symbol;
22
26
  };
23
27
 
24
28
  /**
@@ -27,11 +31,11 @@ export type ZentuiEditorFactory = EditorFactory & {
27
31
  * @param factory Candidate host editor factory.
28
32
  * @returns Whether the factory carries the Editor layout marker.
29
33
  */
30
- export function isZentuiEditorFactory(
34
+ export function isPolishedEditorFactory(
31
35
  factory: EditorFactory | undefined,
32
36
  ): boolean {
33
37
  return Boolean(
34
- (factory as ZentuiEditorFactory | undefined)?.[ZENTUI_EDITOR_FACTORY],
38
+ (factory as PolishedEditorFactory | undefined)?.[POLISHED_EDITOR_FACTORY],
35
39
  );
36
40
  }
37
41
 
@@ -41,11 +45,11 @@ export function isZentuiEditorFactory(
41
45
  * @param factory Candidate host editor factory.
42
46
  * @returns The retained base factory, when present.
43
47
  */
44
- export function getZentuiEditorBaseFactory(
48
+ export function getPolishedEditorBaseFactory(
45
49
  factory: EditorFactory | undefined,
46
50
  ): EditorFactory | undefined {
47
- return (factory as ZentuiEditorFactory | undefined)?.[
48
- ZENTUI_EDITOR_BASE_FACTORY
51
+ return (factory as PolishedEditorFactory | undefined)?.[
52
+ POLISHED_EDITOR_BASE_FACTORY
49
53
  ];
50
54
  }
51
55
 
@@ -61,7 +65,7 @@ export function isOwnedEditorFactory(
61
65
  ownerToken: symbol,
62
66
  ): boolean {
63
67
  return (
64
- (factory as ZentuiEditorFactory | undefined)?.[ZENTUI_EDITOR_OWNER] ===
68
+ (factory as PolishedEditorFactory | undefined)?.[POLISHED_EDITOR_OWNER] ===
65
69
  ownerToken
66
70
  );
67
71
  }
@@ -77,9 +81,9 @@ export function markEditorFactory<T extends EditorFactory>(
77
81
  factory: T,
78
82
  ownerToken: symbol,
79
83
  ): T {
80
- const marked = factory as T & ZentuiEditorFactory;
81
- marked[ZENTUI_EDITOR_FACTORY] = true;
82
- marked[ZENTUI_EDITOR_OWNER] = ownerToken;
84
+ const marked = factory as T & PolishedEditorFactory;
85
+ marked[POLISHED_EDITOR_FACTORY] = true;
86
+ marked[POLISHED_EDITOR_OWNER] = ownerToken;
83
87
  return factory;
84
88
  }
85
89
 
@@ -97,7 +101,7 @@ export function markWrappedEditorFactory<T extends EditorFactory>(
97
101
  ownerToken: symbol,
98
102
  ): T {
99
103
  const marked = markEditorFactory(factory, ownerToken) as T &
100
- ZentuiEditorFactory;
101
- marked[ZENTUI_EDITOR_BASE_FACTORY] = baseFactory;
104
+ PolishedEditorFactory;
105
+ marked[POLISHED_EDITOR_BASE_FACTORY] = baseFactory;
102
106
  return factory;
103
107
  }
@@ -12,7 +12,7 @@ import {
12
12
  truncateToWidth,
13
13
  visibleWidth,
14
14
  } from "@earendil-works/pi-tui";
15
- import type { ZentuiConfig } from "../../app/config/shell.ts";
15
+ import type { PolishedTuiConfig } from "../../app/config/shell.ts";
16
16
  import {
17
17
  EDITOR_ACCENT_FALLBACK,
18
18
  EDITOR_BORDER_FALLBACK,
@@ -25,8 +25,6 @@ import {
25
25
  renderMinimalistFrame,
26
26
  } from "./minimalist-editor.ts";
27
27
 
28
- const LEGACY_SPLIT_POLISHED_FRAME = Symbol.for("pi-zentui.polished-frame");
29
-
30
28
  export type ViewportCounts = {
31
29
  above?: string;
32
30
  below?: string;
@@ -101,7 +99,7 @@ type MinimalistFrameAdapterOptions = {
101
99
  autocompleteSource: AutocompleteEditorInternals;
102
100
  autocompleteCapture?: AutocompleteCapture;
103
101
  uiTheme: Theme;
104
- config: ZentuiConfig;
102
+ config: PolishedTuiConfig;
105
103
  inputText: string;
106
104
  metadata: MinimalistEditorMetadata;
107
105
  ownedFrame?: PolishedFrameSplit;
@@ -293,7 +291,7 @@ export function renderWithAutocompleteCapture<T>(
293
291
  * (保持 Pi 原生 effort/主题变色不动)。
294
292
  */
295
293
  export function offEditorBorderColor(
296
- config: ZentuiConfig,
294
+ config: PolishedTuiConfig,
297
295
  uiTheme: Theme,
298
296
  ): ((text: string) => string) | undefined {
299
297
  const editor = config.components.editor;
@@ -316,7 +314,7 @@ function fillLine(content: string, width: number): string {
316
314
  }
317
315
 
318
316
  function getEditorChromeWidths(
319
- config: ZentuiConfig,
317
+ config: PolishedTuiConfig,
320
318
  uiTheme: Theme,
321
319
  reset: string,
322
320
  ) {
@@ -353,7 +351,7 @@ function parseEditorBorder(
353
351
 
354
352
  function unwrapPolishedFrameOnly(
355
353
  lines: string[],
356
- config: ZentuiConfig,
354
+ config: PolishedTuiConfig,
357
355
  uiTheme: Theme,
358
356
  ): { editorLines: string[]; viewport: ViewportCounts } | undefined {
359
357
  if (lines.length < 5) return undefined;
@@ -379,7 +377,7 @@ function unwrapPolishedFrameOnly(
379
377
 
380
378
  function splitPolishedFrame(
381
379
  lines: string[],
382
- config: ZentuiConfig,
380
+ config: PolishedTuiConfig,
383
381
  uiTheme: Theme,
384
382
  ): PolishedFrameSplit | undefined {
385
383
  if (!parseEditorBorder(lines[0] ?? "", "above")) return undefined;
@@ -397,9 +395,8 @@ function splitPolishedFrame(
397
395
  }
398
396
 
399
397
  function inspectPolishedFrameProvenance(
400
- base: WrappedEditor,
401
398
  rendered: string[],
402
- config: ZentuiConfig,
399
+ config: PolishedTuiConfig,
403
400
  uiTheme: Theme,
404
401
  ): { safe: boolean; ownedFrame?: PolishedFrameSplit } {
405
402
  const provenance = POLISHED_FRAME_SPLITS.get(rendered);
@@ -411,7 +408,6 @@ function inspectPolishedFrameProvenance(
411
408
  const ownedFrame = provenanceMatches ? provenance?.split : undefined;
412
409
  const unsafe =
413
410
  Boolean(provenance && !provenanceMatches) ||
414
- LEGACY_SPLIT_POLISHED_FRAME in base ||
415
411
  (!ownedFrame && Boolean(splitPolishedFrame(rendered, config, uiTheme)));
416
412
  return { safe: !unsafe, ownedFrame };
417
413
  }
@@ -485,7 +481,7 @@ export class PolishedEditor extends CustomEditor {
485
481
  private readonly getThinkingLevel: () => string | undefined;
486
482
  private readonly getMinimalistMetadata: () => MinimalistEditorMetadata;
487
483
  private readonly onMinimalistDecorationChange: (active: boolean) => void;
488
- private readonly getConfig: () => ZentuiConfig;
484
+ private readonly getConfig: () => PolishedTuiConfig;
489
485
  private readonly uiTheme: Theme;
490
486
 
491
487
  constructor(
@@ -493,7 +489,7 @@ export class PolishedEditor extends CustomEditor {
493
489
  theme: EditorTheme,
494
490
  keybindings: KeybindingsManager,
495
491
  uiTheme: Theme,
496
- getConfig: () => ZentuiConfig,
492
+ getConfig: () => PolishedTuiConfig,
497
493
  getModelMeta: () => EditorMeta,
498
494
  getThinkingLevel: () => string | undefined,
499
495
  getMinimalistMetadata: () => MinimalistEditorMetadata = () => ({ cwd: "" }),
@@ -569,7 +565,7 @@ export class WrappedPolishedEditor implements EditorComponent {
569
565
  constructor(
570
566
  private readonly base: WrappedEditor,
571
567
  private readonly uiTheme: Theme,
572
- private readonly getConfig: () => ZentuiConfig,
568
+ private readonly getConfig: () => PolishedTuiConfig,
573
569
  private readonly getModelMeta: () => EditorMeta,
574
570
  private readonly getThinkingLevel: () => string | undefined,
575
571
  private readonly getMinimalistMetadata: () => MinimalistEditorMetadata = () => ({
@@ -702,7 +698,6 @@ export class WrappedPolishedEditor implements EditorComponent {
702
698
  }
703
699
  try {
704
700
  const provenance = inspectPolishedFrameProvenance(
705
- this.base,
706
701
  captured.value,
707
702
  config,
708
703
  this.uiTheme,