pi-one-ui 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -1
- package/README.en.md +5 -4
- package/README.md +7 -5
- package/extensions/app/commands/settings-previews.ts +23 -44
- package/extensions/app/config/shell.ts +19 -58
- package/extensions/app/panel.ts +42 -19
- package/extensions/app/presets.ts +2 -2
- package/extensions/layouts/context/renderer/index.ts +15 -0
- package/extensions/layouts/context/renderer/tool/toggle-render-cache.ts +333 -0
- package/extensions/layouts/editor/controller.ts +16 -8
- package/extensions/layouts/editor/minimalist-editor.ts +10 -5
- package/extensions/layouts/editor/ui.ts +52 -365
- package/extensions/layouts/footer/footer.ts +7 -3
- package/extensions/shared/style.ts +48 -0
- package/extensions/tools/patch-keys.ts +5 -0
- package/package.json +1 -1
- package/themes/cc-dark.json +7 -4
- package/themes/cc-light.json +4 -1
- package/extensions/layouts/editor/completion-menu.ts +0 -183
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 工具卡 updateDisplay 跨 toggle 重建缓存(on/compact 共用,off 关闭)。
|
|
3
|
+
*
|
|
4
|
+
* 原生 ToolExecutionComponent.updateDisplay 每次调用都会 clear 后重新调用
|
|
5
|
+
* call/result renderer 生成全新组件,新组件内部行缓存为空,导致折叠/展开
|
|
6
|
+
* 切换(Ctrl+O、group.setExpanded、鼠标点击)每次都要重新 wrap 输出全文,
|
|
7
|
+
* 大输出下可达数百毫秒同步阻塞。
|
|
8
|
+
*
|
|
9
|
+
* 这里按工具实例缓存(collapsed/expanded 两槽)的渲染指纹:内容指纹
|
|
10
|
+
* (args/result/isPartial/executionStarted/argsComplete/showImages/mode/theme)
|
|
11
|
+
* 未变化时跳过原生全量重建;容器内当前槽位与目标槽位不同时,把目标槽构建
|
|
12
|
+
* 时缓存的 call/result 组件重新装入对应壳容器(selfRenderContainer /
|
|
13
|
+
* contentBox / contentText)并恢复派生字段,实现零重建的来回切换。
|
|
14
|
+
*
|
|
15
|
+
* 失效面:result/args 等输入变化(指纹比较)、模式切换(mode 入指纹)、
|
|
16
|
+
* 主题或配置变化(setTheme / clear 由装配层在既有回调中驱动)。
|
|
17
|
+
* fallback 分支(contentText,无 renderer 定义的工具)不做组件级切换,
|
|
18
|
+
* 切槽时退化为原生重建,与现状一致。
|
|
19
|
+
*/
|
|
20
|
+
import { ToolExecutionComponent } from "@earendil-works/pi-coding-agent";
|
|
21
|
+
import { config } from "../../../../app/config/renderer.ts";
|
|
22
|
+
import {
|
|
23
|
+
patchRegistry,
|
|
24
|
+
TOGGLE_RENDER_CACHE_PATCH,
|
|
25
|
+
} from "../../../../tools/patch-keys.ts";
|
|
26
|
+
import { scheduleAnimation } from "./result.ts";
|
|
27
|
+
|
|
28
|
+
type RenderSlot = {
|
|
29
|
+
/** 输入指纹(args/result/isPartial 等,不含 expanded)。 */
|
|
30
|
+
inputFingerprint: unknown[];
|
|
31
|
+
/** 构建时的派生组件引用(call/result),用于同槽外部污染检测。 */
|
|
32
|
+
components: [unknown, unknown];
|
|
33
|
+
hideComponent: boolean;
|
|
34
|
+
/** 构建时实际挂载的壳载体:box / self / text / null(未挂候选容器)。 */
|
|
35
|
+
shell: "box" | "self" | "text" | null;
|
|
36
|
+
callComponent: unknown;
|
|
37
|
+
resultComponent: unknown;
|
|
38
|
+
/** rendererState 中 ccstyle 渲染层的指针快照(切槽重装时恢复)。 */
|
|
39
|
+
stateSnapshot: [unknown, unknown, unknown];
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
type ComponentCache = {
|
|
43
|
+
expanded?: RenderSlot;
|
|
44
|
+
collapsed?: RenderSlot;
|
|
45
|
+
/** 容器当前装着的槽位(重建/装载后更新)。 */
|
|
46
|
+
current?: "expanded" | "collapsed";
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
let componentCaches = new WeakMap<object, ComponentCache>();
|
|
50
|
+
|
|
51
|
+
type ToggleRenderCachePatch = {
|
|
52
|
+
active: boolean;
|
|
53
|
+
prototype: any;
|
|
54
|
+
installed: () => void;
|
|
55
|
+
original: () => void;
|
|
56
|
+
theme: unknown;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type ToggleRenderCacheHooks = {
|
|
60
|
+
setTheme(theme: unknown): void;
|
|
61
|
+
/** 配置/主题等外部状态变化后丢弃全部缓存(下次 updateDisplay 重建)。 */
|
|
62
|
+
clear(): void;
|
|
63
|
+
shutdown(): void;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/** 渲染输入指纹:不含 expanded(由槽位区分),不含组件引用。 */
|
|
67
|
+
function fingerprintOf(
|
|
68
|
+
component: any,
|
|
69
|
+
patch: ToggleRenderCachePatch,
|
|
70
|
+
): unknown[] {
|
|
71
|
+
return [
|
|
72
|
+
component.args,
|
|
73
|
+
component.result,
|
|
74
|
+
component.isPartial === true,
|
|
75
|
+
component.executionStarted === true,
|
|
76
|
+
component.argsComplete === true,
|
|
77
|
+
component.showImages === true,
|
|
78
|
+
config.mode,
|
|
79
|
+
patch.theme,
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function componentsOf(component: any): [unknown, unknown] {
|
|
84
|
+
return [component.callRendererComponent, component.resultRendererComponent];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function sameComponents(
|
|
88
|
+
left: [unknown, unknown],
|
|
89
|
+
right: [unknown, unknown],
|
|
90
|
+
): boolean {
|
|
91
|
+
return left[0] === right[0] && left[1] === right[1];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function sameFingerprint(left: unknown[], right: unknown[]): boolean {
|
|
95
|
+
if (left.length !== right.length) return false;
|
|
96
|
+
for (let i = 0; i < left.length; i++) {
|
|
97
|
+
if (left[i] !== right[i]) return false;
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** 从 children 中识别当前挂载的候选壳(无副作用,不调用 getRenderShell)。 */
|
|
103
|
+
function mountedShell(component: any): "box" | "self" | "text" | null {
|
|
104
|
+
const children = Array.isArray(component?.children) ? component.children : [];
|
|
105
|
+
for (const child of children) {
|
|
106
|
+
if (child === component.contentBox) return "box";
|
|
107
|
+
if (child === component.selfRenderContainer) return "self";
|
|
108
|
+
if (child === component.contentText) return "text";
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function shellContainer(
|
|
114
|
+
component: any,
|
|
115
|
+
shell: "box" | "self" | "text" | null,
|
|
116
|
+
): any {
|
|
117
|
+
if (shell === "box") return component.contentBox;
|
|
118
|
+
if (shell === "self") return component.selfRenderContainer;
|
|
119
|
+
if (shell === "text") return component.contentText;
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** 与 default-mode 的 syncToolShell 同款:把目标壳换入 children,排除其余候选。 */
|
|
124
|
+
function syncShell(component: any, shell: "box" | "self" | "text"): void {
|
|
125
|
+
const target = shellContainer(component, shell);
|
|
126
|
+
if (!target || !Array.isArray(component.children)) return;
|
|
127
|
+
const candidates = new Set(
|
|
128
|
+
[
|
|
129
|
+
component.contentText,
|
|
130
|
+
component.contentBox,
|
|
131
|
+
component.selfRenderContainer,
|
|
132
|
+
].filter(Boolean),
|
|
133
|
+
);
|
|
134
|
+
const indexes = component.children
|
|
135
|
+
.map((child: any, index: number) => (candidates.has(child) ? index : -1))
|
|
136
|
+
.filter((index: number) => index >= 0);
|
|
137
|
+
const targetIndex = indexes[0];
|
|
138
|
+
if (targetIndex === undefined) return;
|
|
139
|
+
component.children[targetIndex] = target;
|
|
140
|
+
for (const index of indexes.sort(
|
|
141
|
+
(left: number, right: number) => right - left,
|
|
142
|
+
)) {
|
|
143
|
+
if (index !== targetIndex) component.children.splice(index, 1);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function stateSnapshotOf(component: any): [unknown, unknown, unknown] {
|
|
148
|
+
const state = component?.rendererState;
|
|
149
|
+
return [
|
|
150
|
+
state?.ccstyleIoView,
|
|
151
|
+
state?.ccstyleExpandedIoView,
|
|
152
|
+
state?.ccstyleToolVisualState,
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function restoreStateSnapshot(
|
|
157
|
+
component: any,
|
|
158
|
+
slotKey: "expanded" | "collapsed",
|
|
159
|
+
snapshot: [unknown, unknown, unknown],
|
|
160
|
+
): void {
|
|
161
|
+
if (
|
|
162
|
+
component?.rendererState === undefined &&
|
|
163
|
+
snapshot.every((v) => v === undefined)
|
|
164
|
+
) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const state = (component.rendererState ??= {});
|
|
168
|
+
// ioView/visualState 每槽构建时都会写入,按槽恢复;
|
|
169
|
+
// expandedIoView 是跨槽保留指针(折叠 renderer 不清),只在展开槽恢复。
|
|
170
|
+
state.ccstyleIoView = snapshot[0];
|
|
171
|
+
state.ccstyleToolVisualState = snapshot[1];
|
|
172
|
+
if (slotKey === "expanded") state.ccstyleExpandedIoView = snapshot[2];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* 把缓存槽的 call/result 组件装回目标壳容器并恢复派生字段。
|
|
177
|
+
* 同时恢复 ccstyle 渲染层的 rendererState 指针快照(ioView / expandedIoView /
|
|
178
|
+
* visualState),补齐切槽跳过 renderer 调用导致的状态缺失;pending 展开时
|
|
179
|
+
* 重新调度加载动画。text fallback 槽(无容器装载语义)返回 false,调用方
|
|
180
|
+
* 退化为重建。
|
|
181
|
+
*/
|
|
182
|
+
function mountSlot(
|
|
183
|
+
component: any,
|
|
184
|
+
slotKey: "expanded" | "collapsed",
|
|
185
|
+
slot: RenderSlot,
|
|
186
|
+
): boolean {
|
|
187
|
+
if (!slot.shell || slot.shell === "text") return false;
|
|
188
|
+
const container = shellContainer(component, slot.shell);
|
|
189
|
+
if (!container || typeof container.clear !== "function") return false;
|
|
190
|
+
syncShell(component, slot.shell);
|
|
191
|
+
container.clear();
|
|
192
|
+
if (slot.callComponent !== undefined)
|
|
193
|
+
container.addChild(slot.callComponent as any);
|
|
194
|
+
if (slot.resultComponent !== undefined)
|
|
195
|
+
container.addChild(slot.resultComponent as any);
|
|
196
|
+
component.callRendererComponent = slot.callComponent;
|
|
197
|
+
component.resultRendererComponent = slot.resultComponent;
|
|
198
|
+
component.hideComponent = slot.hideComponent;
|
|
199
|
+
restoreStateSnapshot(component, slotKey, slot.stateSnapshot);
|
|
200
|
+
if (slot.resultComponent !== undefined) {
|
|
201
|
+
// pending(流式)且已展开:恢复加载动画调度(默认 renderResult 的副作用)。
|
|
202
|
+
if (component.isPartial === true || component.executionStarted === true) {
|
|
203
|
+
try {
|
|
204
|
+
scheduleAnimation(component);
|
|
205
|
+
} catch {
|
|
206
|
+
// 动画调度失败不影响装载结果。
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function installToggleRenderCache(): ToggleRenderCacheHooks {
|
|
214
|
+
const previous = patchRegistry.get<ToggleRenderCachePatch>(
|
|
215
|
+
TOGGLE_RENDER_CACHE_PATCH,
|
|
216
|
+
);
|
|
217
|
+
// /reload 残留的旧补丁先停用,链上以本次安装为准。
|
|
218
|
+
if (previous) previous.active = false;
|
|
219
|
+
const prototype = ToolExecutionComponent.prototype as any;
|
|
220
|
+
const original = prototype.updateDisplay;
|
|
221
|
+
const patch: ToggleRenderCachePatch = {
|
|
222
|
+
active: true,
|
|
223
|
+
prototype,
|
|
224
|
+
installed: undefined as any,
|
|
225
|
+
original,
|
|
226
|
+
theme: undefined,
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
patch.installed = function (this: any) {
|
|
230
|
+
if (!patch.active || config.mode === "off") {
|
|
231
|
+
return patch.original.call(this);
|
|
232
|
+
}
|
|
233
|
+
const self = this;
|
|
234
|
+
if (
|
|
235
|
+
!self ||
|
|
236
|
+
typeof self.expanded !== "boolean" ||
|
|
237
|
+
typeof self.hideComponent !== "boolean"
|
|
238
|
+
) {
|
|
239
|
+
return patch.original.call(this);
|
|
240
|
+
}
|
|
241
|
+
const slotKey: "expanded" | "collapsed" = self.expanded
|
|
242
|
+
? "expanded"
|
|
243
|
+
: "collapsed";
|
|
244
|
+
const fingerprint = fingerprintOf(self, patch);
|
|
245
|
+
const componentsNow = componentsOf(self);
|
|
246
|
+
let entry = componentCaches.get(self);
|
|
247
|
+
const slot = entry?.[slotKey];
|
|
248
|
+
|
|
249
|
+
const rebuild = () => {
|
|
250
|
+
entry ??= {};
|
|
251
|
+
componentCaches.set(self, entry);
|
|
252
|
+
// 防止 renderer 复用另一槽的组件实例:pi 的 renderResult 通过
|
|
253
|
+
// context.lastComponent(= resultRendererComponent 字段)复用组件,
|
|
254
|
+
// 跨槽复用会把另一槽缓存的内容覆盖污染(如 bash 的 rebuildln 重建
|
|
255
|
+
// children)。重置字段强制新建,保证两槽各自持有独立实例。
|
|
256
|
+
const otherKey: "expanded" | "collapsed" =
|
|
257
|
+
slotKey === "expanded" ? "collapsed" : "expanded";
|
|
258
|
+
const other = entry[otherKey];
|
|
259
|
+
if (other && other.shell !== "text") {
|
|
260
|
+
if (self.callRendererComponent === other.callComponent) {
|
|
261
|
+
self.callRendererComponent = undefined;
|
|
262
|
+
}
|
|
263
|
+
if (self.resultRendererComponent === other.resultComponent) {
|
|
264
|
+
self.resultRendererComponent = undefined;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
patch.original.call(this);
|
|
268
|
+
// 输入指纹取重建后的状态快照;组件引用由重建产物决定。
|
|
269
|
+
const shell = mountedShell(self);
|
|
270
|
+
const built: RenderSlot = {
|
|
271
|
+
inputFingerprint: fingerprintOf(self, patch),
|
|
272
|
+
components: componentsOf(self),
|
|
273
|
+
hideComponent: self.hideComponent === true,
|
|
274
|
+
shell,
|
|
275
|
+
callComponent:
|
|
276
|
+
shell === "text"
|
|
277
|
+
? undefined
|
|
278
|
+
: (self.callRendererComponent ?? undefined),
|
|
279
|
+
resultComponent:
|
|
280
|
+
shell === "text"
|
|
281
|
+
? undefined
|
|
282
|
+
: (self.resultRendererComponent ?? undefined),
|
|
283
|
+
stateSnapshot: stateSnapshotOf(self),
|
|
284
|
+
};
|
|
285
|
+
entry[slotKey] = built;
|
|
286
|
+
entry.current = slotKey;
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const inputsMatch =
|
|
290
|
+
slot && sameFingerprint(slot.inputFingerprint, fingerprint);
|
|
291
|
+
if (inputsMatch && entry) {
|
|
292
|
+
if (entry.current === slotKey) {
|
|
293
|
+
if (sameComponents(slot.components, componentsNow)) {
|
|
294
|
+
// 容器内容仍是该槽,无重建必要;仅恢复可能被外部改写的派生字段。
|
|
295
|
+
self.hideComponent = slot.hideComponent;
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
// 外部(第三方 renderer、测试)替换了派生组件:走重建刷新。
|
|
299
|
+
rebuild();
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
if (!mountSlot(self, slotKey, slot)) {
|
|
303
|
+
// text fallback 或防御性失败:退化为原生重建。
|
|
304
|
+
rebuild();
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
entry.current = slotKey;
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
rebuild();
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
prototype.updateDisplay = patch.installed;
|
|
314
|
+
patchRegistry.install(TOGGLE_RENDER_CACHE_PATCH, patch);
|
|
315
|
+
|
|
316
|
+
return {
|
|
317
|
+
setTheme(theme: unknown) {
|
|
318
|
+
patch.theme = theme;
|
|
319
|
+
},
|
|
320
|
+
clear() {
|
|
321
|
+
componentCaches = new WeakMap();
|
|
322
|
+
},
|
|
323
|
+
shutdown() {
|
|
324
|
+
if (!patch.active) return;
|
|
325
|
+
patch.active = false;
|
|
326
|
+
if (prototype.updateDisplay === patch.installed) {
|
|
327
|
+
prototype.updateDisplay = patch.original;
|
|
328
|
+
}
|
|
329
|
+
patchRegistry.dispose(TOGGLE_RENDER_CACHE_PATCH, patch);
|
|
330
|
+
componentCaches = new WeakMap();
|
|
331
|
+
},
|
|
332
|
+
};
|
|
333
|
+
}
|
|
@@ -143,10 +143,15 @@ export class EditorLayoutController {
|
|
|
143
143
|
): { applied: boolean; reason?: string } {
|
|
144
144
|
this.context.saveComponent(patch);
|
|
145
145
|
let result: EditorChangeResult | undefined;
|
|
146
|
-
if (patch.
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
if (patch.style === "off") {
|
|
147
|
+
// off 透传原生渲染:不替换工厂,既有编辑器实例与 overlay preFocus
|
|
148
|
+
// 保持有效(面板关闭后仍能聚焦输入框)。
|
|
149
149
|
this.setMinimalistDecorationActive(false);
|
|
150
|
+
} else if (patch.style === "on" && this.isTuiContext(ctx)) {
|
|
151
|
+
// on 收敛所有权:未安装或第三方接管时安装回来;
|
|
152
|
+
// 已有自身工厂时 installEditor 短路,不产生替换。
|
|
153
|
+
result = this.reconcile(ctx);
|
|
154
|
+
}
|
|
150
155
|
if (patch.modelLabel !== undefined) this.context.onModelLabelChanged(ctx);
|
|
151
156
|
this.context.onProjectRequirementChanged();
|
|
152
157
|
this.requestRender();
|
|
@@ -196,7 +201,7 @@ export class EditorLayoutController {
|
|
|
196
201
|
Boolean(
|
|
197
202
|
this.activeTuiContext && this.ownsActiveFactory(this.activeTuiContext),
|
|
198
203
|
) &&
|
|
199
|
-
editor.style === "
|
|
204
|
+
editor.style === "on" &&
|
|
200
205
|
(minimalist.showGit || minimalist.pathDisplay === "project")
|
|
201
206
|
);
|
|
202
207
|
}
|
|
@@ -328,7 +333,7 @@ export class EditorLayoutController {
|
|
|
328
333
|
this.minimalistDecorationActive &&
|
|
329
334
|
this.isEditorEnabled() &&
|
|
330
335
|
this.ownsActiveFactory(ctx) &&
|
|
331
|
-
config.style === "
|
|
336
|
+
config.style === "on" &&
|
|
332
337
|
config.styles.minimalist.showTimer,
|
|
333
338
|
);
|
|
334
339
|
if (!needed) {
|
|
@@ -365,14 +370,17 @@ export class EditorLayoutController {
|
|
|
365
370
|
}
|
|
366
371
|
|
|
367
372
|
/**
|
|
368
|
-
* Returns whether the configured Editor
|
|
373
|
+
* Returns whether the configured Editor factory can be installed.
|
|
374
|
+
*
|
|
375
|
+
* style "off" restores Pi's native editor: the factory is not installed and
|
|
376
|
+
* any third-party or native editor keeps ownership.
|
|
369
377
|
*
|
|
370
|
-
* @returns Whether the Editor is
|
|
378
|
+
* @returns Whether the Editor is on and supported.
|
|
371
379
|
*/
|
|
372
380
|
private isEditorEnabled(): boolean {
|
|
373
381
|
const editor = this.context.getConfig().components.editor;
|
|
374
382
|
return (
|
|
375
|
-
editor.
|
|
383
|
+
editor.style === "on" &&
|
|
376
384
|
!hasUnsupportedComponentStyle(this.context.getConfig(), "editor")
|
|
377
385
|
);
|
|
378
386
|
}
|
|
@@ -10,6 +10,7 @@ export { formatElapsedDuration } from "../../shared/format.ts";
|
|
|
10
10
|
import {
|
|
11
11
|
EDITOR_ACCENT_FALLBACK,
|
|
12
12
|
EDITOR_BORDER_FALLBACK,
|
|
13
|
+
renderSourceColor,
|
|
13
14
|
renderStyleForSource,
|
|
14
15
|
renderStyleForSourceOrFallback,
|
|
15
16
|
safeThemeFg,
|
|
@@ -213,11 +214,12 @@ function renderTopRight(
|
|
|
213
214
|
const model = sanitizeEditorMetadataText(metadata.modelLabel ?? "");
|
|
214
215
|
if (model) {
|
|
215
216
|
parts.push(
|
|
216
|
-
|
|
217
|
+
renderSourceColor(
|
|
217
218
|
uiTheme,
|
|
218
219
|
source,
|
|
219
220
|
config.colors.editorModel,
|
|
220
|
-
|
|
221
|
+
"editorModel",
|
|
222
|
+
MINIMALIST_MODEL_FALLBACK.theme,
|
|
221
223
|
model,
|
|
222
224
|
),
|
|
223
225
|
);
|
|
@@ -293,10 +295,12 @@ function renderBottomRight(
|
|
|
293
295
|
): string {
|
|
294
296
|
const cwd = sanitizeEditorMetadataText(minimalistCwdLabel(metadata, config));
|
|
295
297
|
return cwd
|
|
296
|
-
?
|
|
298
|
+
? renderSourceColor(
|
|
297
299
|
uiTheme,
|
|
298
300
|
config.components.editor.colorSource,
|
|
299
301
|
config.colors.cwd,
|
|
302
|
+
"cwd",
|
|
303
|
+
"bold cyan",
|
|
300
304
|
cwd,
|
|
301
305
|
)
|
|
302
306
|
: "";
|
|
@@ -386,11 +390,12 @@ export function renderMinimalistFrame({
|
|
|
386
390
|
const activeThinking =
|
|
387
391
|
thinking && thinking.toLowerCase() !== "off" ? thinking : "";
|
|
388
392
|
const renderStaticBorder = (text: string) =>
|
|
389
|
-
|
|
393
|
+
renderSourceColor(
|
|
390
394
|
uiTheme,
|
|
391
395
|
source,
|
|
392
396
|
config.colors.editorBorder,
|
|
393
|
-
|
|
397
|
+
"editorBorder",
|
|
398
|
+
EDITOR_BORDER_FALLBACK.theme,
|
|
394
399
|
text,
|
|
395
400
|
);
|
|
396
401
|
const terminalAdaptiveThinkingStyle = activeThinking
|