pi-one-ui 0.3.0 → 0.3.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.en.md +14 -14
  3. package/README.md +14 -14
  4. package/extensions/app/commands/settings-previews.ts +3 -3
  5. package/extensions/app/config/renderer.ts +7 -6
  6. package/extensions/app/config/shell.ts +4 -4
  7. package/extensions/app/overlay/selector-border.ts +5 -5
  8. package/extensions/app/ownership.ts +1 -1
  9. package/extensions/app/panel.ts +18 -19
  10. package/extensions/app/runtime/tui-runtime.ts +31 -31
  11. package/extensions/features/context-inspector/index.ts +3 -3
  12. package/extensions/features/session-reference/index.ts +5 -5
  13. package/extensions/features/subagent-autocomplete.ts +1 -1
  14. package/extensions/layouts/context/index.ts +9 -12
  15. package/extensions/layouts/context/renderer/compact-mode.ts +24 -24
  16. package/extensions/layouts/context/renderer/default-mode.ts +21 -16
  17. package/extensions/layouts/context/renderer/index.ts +24 -24
  18. package/extensions/layouts/context/renderer/mouse/hover.ts +6 -6
  19. package/extensions/layouts/context/renderer/mouse/interaction.ts +35 -35
  20. package/extensions/layouts/context/renderer/mouse/packets.ts +3 -2
  21. package/extensions/layouts/context/renderer/mouse/scroll.ts +2 -2
  22. package/extensions/layouts/context/renderer/tool/diff/diff-component.ts +2 -1
  23. package/extensions/layouts/context/renderer/tool/diff/diff-edit-render.ts +21 -21
  24. package/extensions/layouts/context/renderer/tool/diff/diff-header.ts +4 -4
  25. package/extensions/layouts/context/renderer/tool/diff/diff-highlight.ts +6 -6
  26. package/extensions/layouts/context/renderer/tool/diff/diff-inline.ts +1 -1
  27. package/extensions/layouts/context/renderer/tool/diff/diff-layout.ts +18 -18
  28. package/extensions/layouts/context/renderer/tool/diff/diff-limits.ts +5 -5
  29. package/extensions/layouts/context/renderer/tool/diff/diff-palette.ts +3 -3
  30. package/extensions/layouts/context/renderer/tool/diff/diff-presentation.ts +1 -1
  31. package/extensions/layouts/context/renderer/tool/diff/diff-renderer.ts +2 -1
  32. package/extensions/layouts/context/renderer/tool/diff/diff-write-render.ts +31 -31
  33. package/extensions/layouts/context/renderer/tool/diff/index.ts +4 -4
  34. package/extensions/layouts/context/renderer/tool/diff/line-width-safety.ts +1 -1
  35. package/extensions/layouts/context/renderer/tool/diff/write-execution.ts +1 -1
  36. package/extensions/layouts/context/renderer/tool/grouping.ts +12 -12
  37. package/extensions/layouts/context/renderer/tool/message-display.ts +2 -2
  38. package/extensions/layouts/context/renderer/tool/result.ts +199 -19
  39. package/extensions/layouts/context/summary/core.ts +1 -0
  40. package/extensions/layouts/context/summary/index.ts +3 -3
  41. package/extensions/layouts/context/thinking/compact-thinking.ts +12 -13
  42. package/extensions/layouts/editor/accent-rail-editor.ts +5 -5
  43. package/extensions/layouts/editor/controller.ts +4 -4
  44. package/extensions/layouts/editor/editor-metadata-format.ts +4 -4
  45. package/extensions/layouts/editor/factory.ts +3 -3
  46. package/extensions/layouts/editor/index.ts +7 -7
  47. package/extensions/layouts/editor/minimalist-editor.ts +1 -1
  48. package/extensions/layouts/editor/ui.ts +7 -7
  49. package/extensions/layouts/footer/controller.ts +3 -3
  50. package/extensions/layouts/footer/footer.ts +21 -21
  51. package/extensions/layouts/footer/index.ts +8 -8
  52. package/extensions/layouts/header/index.ts +1 -1
  53. package/extensions/layouts/header/startup-header.ts +3 -2
  54. package/extensions/layouts/working-line/controller.ts +6 -6
  55. package/extensions/services/project-refresh.ts +2 -2
  56. package/extensions/services/session-state.ts +1 -1
  57. package/extensions/shared/format.ts +2 -2
  58. package/package.json +8 -10
  59. package/extensions/features/legacy/working-message.ts +0 -226
@@ -1,69 +1,69 @@
1
1
  import {
2
+ type Component,
2
3
  Text,
3
4
  truncateToWidth,
4
5
  visibleWidth,
5
- type Component,
6
6
  } from "@earendil-works/pi-tui";
7
7
  import { sanitizeToolResultText } from "../../../../../tools/tool-result-sanitize.ts";
8
8
  import { showMoreHintText } from "../show-more-hint.ts";
9
- import { splitWriteContentLines } from "./diff-text.ts";
10
9
  import {
11
- collectDiffStats,
12
- getLineNumberWidth,
13
- type DiffLineEntry,
14
- type DiffStats,
15
- type ParsedDiffEntry,
16
- } from "./diff-parse.ts";
10
+ createDiffRenderCache,
11
+ type DiffRenderOptions,
12
+ type DisplayConfigInput,
13
+ displayConfigCacheKey,
14
+ RICH_DIFF_COMPONENT,
15
+ resolveDiffIndicatorMode,
16
+ resolveLiveDisplayConfig,
17
+ } from "./diff-component.ts";
18
+ import {
19
+ renderDiffFrameLine,
20
+ renderSingleDiffRow,
21
+ renderWriteHeader,
22
+ } from "./diff-header.ts";
23
+ import {
24
+ type CodeLineHighlighter,
25
+ createCodeLineHighlighter,
26
+ resolveLanguageFromPath,
27
+ } from "./diff-highlight.ts";
17
28
  import {
18
29
  buildInlineHighlightMap,
19
30
  buildSplitRows,
20
31
  type DiffSpan,
21
32
  type SplitDiffRow,
22
33
  } from "./diff-inline.ts";
23
- import { resolveDiffPalette, type DiffTheme } from "./diff-palette.ts";
24
- import {
25
- createCodeLineHighlighter,
26
- resolveLanguageFromPath,
27
- type CodeLineHighlighter,
28
- } from "./diff-highlight.ts";
29
34
  import {
30
35
  canRenderSplitLayout,
36
+ type DiffRenderContext,
37
+ type RenderedRow,
31
38
  renderCompact,
32
39
  renderSplit,
33
40
  renderUnified,
34
- type DiffRenderContext,
35
- type RenderedRow,
36
41
  } from "./diff-layout.ts";
37
- import {
38
- renderDiffFrameLine,
39
- renderSingleDiffRow,
40
- renderWriteHeader,
41
- } from "./diff-header.ts";
42
42
  import {
43
43
  applyLineLimit,
44
- clampDiffLineToWidth,
45
44
  clampDiffLinesToWidth,
45
+ clampDiffLineToWidth,
46
46
  resolveDiffDisplayLimit,
47
47
  resolveDiffProcessBudget,
48
48
  resolveWriteCollapsedLimit,
49
49
  takeEntriesForLineBudget,
50
50
  takeSplitRowsForBudget,
51
51
  } from "./diff-limits.ts";
52
+ import { type DiffTheme, resolveDiffPalette } from "./diff-palette.ts";
52
53
  import {
53
- RICH_DIFF_COMPONENT,
54
- createDiffRenderCache,
55
- displayConfigCacheKey,
56
- resolveDiffIndicatorMode,
57
- resolveLiveDisplayConfig,
58
- type DiffRenderOptions,
59
- type DisplayConfigInput,
60
- } from "./diff-component.ts";
54
+ collectDiffStats,
55
+ type DiffLineEntry,
56
+ type DiffStats,
57
+ getLineNumberWidth,
58
+ type ParsedDiffEntry,
59
+ } from "./diff-parse.ts";
61
60
  import {
62
61
  buildDiffSummaryText,
62
+ type DiffPresentationMode,
63
63
  normalizeDiffRenderWidth,
64
64
  resolveDiffPresentationMode,
65
- type DiffPresentationMode,
66
65
  } from "./diff-presentation.ts";
66
+ import { splitWriteContentLines } from "./diff-text.ts";
67
67
 
68
68
  type WriteDiffOperationKind = "context" | "remove" | "add";
69
69
 
@@ -3,12 +3,12 @@ import {
3
3
  type ExtensionAPI,
4
4
  } from "@earendil-works/pi-coding-agent";
5
5
  import { truncateToWidth } from "@earendil-works/pi-tui";
6
+ import { DEFAULT_TOOL_DISPLAY_CONFIG } from "../../../../../app/config/renderer.ts";
6
7
  import {
8
+ type DisplayConfigInput,
7
9
  renderEditDiffResult,
8
10
  renderWriteDiffResult,
9
- type DisplayConfigInput,
10
11
  } from "./diff-renderer.ts";
11
- import { DEFAULT_TOOL_DISPLAY_CONFIG } from "../../../../../app/config/renderer.ts";
12
12
  import {
13
13
  executeWriteWithMetadata,
14
14
  WriteExecutionMetadataStore,
@@ -139,9 +139,9 @@ export function installWriteOverride(
139
139
 
140
140
  export {
141
141
  DEFAULT_TOOL_DISPLAY_CONFIG,
142
- type ToolDisplayConfig,
143
- type DiffViewMode,
144
142
  type DiffIndicatorMode,
143
+ type DiffViewMode,
144
+ type ToolDisplayConfig,
145
145
  } from "../../../../../app/config/renderer.ts";
146
146
  export type { DisplayConfigInput } from "./diff-renderer.ts";
147
147
  export { WriteExecutionMetadataStore } from "./write-execution.ts";
@@ -1,6 +1,6 @@
1
+ import { showMoreHintText } from "../show-more-hint.ts";
1
2
  import { normalizeDiffRenderWidth } from "./diff-presentation.ts";
2
3
  import { pluralize } from "./diff-text.ts";
3
- import { showMoreHintText } from "../show-more-hint.ts";
4
4
 
5
5
  export interface WidthMeasurementOps {
6
6
  measure(text: string): number;
@@ -1,6 +1,6 @@
1
- import { withFileMutationQueue } from "@earendil-works/pi-coding-agent";
2
1
  import { lstat, mkdir, readFile, writeFile } from "node:fs/promises";
3
2
  import { dirname, isAbsolute, resolve } from "node:path";
3
+ import { withFileMutationQueue } from "@earendil-works/pi-coding-agent";
4
4
 
5
5
  export const MAX_COMPARABLE_WRITE_BYTES = 512_000;
6
6
  export const MAX_WRITE_METADATA_ENTRIES = 100;
@@ -3,38 +3,38 @@ import {
3
3
  ToolExecutionComponent,
4
4
  } from "@earendil-works/pi-coding-agent";
5
5
  import {
6
+ type Component,
6
7
  Container,
7
8
  Spacer,
8
9
  truncateToWidth,
9
10
  visibleWidth,
10
- type Component,
11
11
  } from "@earendil-works/pi-tui";
12
- import { toolLoadingIcon } from "../../../../tools/tool-loading-icon.ts";
13
- import { isToolTuiFullscreen, showMoreHintText } from "./show-more-hint.ts";
14
12
  import {
15
13
  stripAnsi,
16
14
  stripBackgroundAnsi,
17
15
  stripLeadingStatusIcon,
18
16
  } from "../../../../tools/ansi-text.ts";
19
17
  import { walkComponentTree } from "../../../../tools/component-tree.ts";
18
+ import {
19
+ TOOL_GROUPING_GENERATION_KEY as GENERATION_KEY,
20
+ TOOL_GROUPING_PARENT_KEY as PARENT_KEY,
21
+ TOOL_GROUPING_PATCH_KEY as PATCH_KEY,
22
+ patchRegistry,
23
+ } from "../../../../tools/patch-keys.ts";
24
+ import { toolLoadingIcon } from "../../../../tools/tool-loading-icon.ts";
20
25
  import { humanizeToolLabel, toolCallSummary } from "./names.ts";
21
26
  import {
27
+ type CapturedIoViewMarker,
22
28
  captureIoViewMarkers,
29
+ type ExpandedToolIoView,
23
30
  getActiveIoViewFrame,
24
31
  isExpandedToolIoView,
25
32
  replayIoViewMarkers,
26
- type CapturedIoViewMarker,
27
- type ExpandedToolIoView,
28
33
  type ToolIoSection,
29
34
  } from "./result.ts";
30
- import {
31
- patchRegistry,
32
- TOOL_GROUPING_GENERATION_KEY as GENERATION_KEY,
33
- TOOL_GROUPING_PARENT_KEY as PARENT_KEY,
34
- TOOL_GROUPING_PATCH_KEY as PATCH_KEY,
35
- } from "../../../../tools/patch-keys.ts";
35
+ import { isToolTuiFullscreen, showMoreHintText } from "./show-more-hint.ts";
36
36
 
37
- const NON_GROUPABLE = new Set(["edit", "write", "apply_patch"]);
37
+ const NON_GROUPABLE = new Set(["edit", "write", "apply_patch", "subagent"]);
38
38
 
39
39
  type Patch = {
40
40
  owner: object;
@@ -4,13 +4,13 @@ import {
4
4
  SkillInvocationMessageComponent,
5
5
  } from "@earendil-works/pi-coding-agent";
6
6
  import { Markdown, Spacer, Text } from "@earendil-works/pi-tui";
7
+ import { config } from "../../../../app/config/renderer.ts";
8
+ import { walkComponentTree } from "../../../../tools/component-tree.ts";
7
9
  import {
8
10
  MESSAGE_DISPLAY_PATCH,
9
11
  patchRegistry,
10
12
  } from "../../../../tools/patch-keys.ts";
11
- import { config } from "../../../../app/config/renderer.ts";
12
13
  import { showMoreHintText } from "./show-more-hint.ts";
13
- import { walkComponentTree } from "../../../../tools/component-tree.ts";
14
14
 
15
15
  /**
16
16
  * 接管三个消息组件(`<skill>` 块、压缩摘要、分支摘要),ccstyle on 时渲染为
@@ -1,17 +1,17 @@
1
+ import { inspect } from "node:util";
1
2
  import {
2
3
  Text,
3
4
  truncateToWidth,
4
5
  visibleWidth,
5
6
  wrapTextWithAnsi,
6
7
  } from "@earendil-works/pi-tui";
7
- import { inspect } from "node:util";
8
8
  import { config } from "../../../../app/config/renderer.ts";
9
- import { showMoreHintText } from "./show-more-hint.ts";
10
9
  import {
11
10
  TOOL_LOADING_INTERVAL_MS,
12
11
  toolLoadingIcon,
13
12
  } from "../../../../tools/tool-loading-icon.ts";
14
13
  import { sanitizeToolResultText } from "../../../../tools/tool-result-sanitize.ts";
14
+ import { showMoreHintText } from "./show-more-hint.ts";
15
15
 
16
16
  const TOOL_VIEWPORT_WIDTH_RATIO = 0.8;
17
17
 
@@ -43,21 +43,185 @@ function rawTextFromResult(result: any): string {
43
43
  : "";
44
44
  }
45
45
 
46
+ const MAX_TOOL_DETAILS_DEPTH = 8;
47
+ const MAX_TOOL_DETAILS_ENTRIES = 64;
48
+ const MAX_TOOL_DETAILS_NODES = 512;
49
+ const MAX_TOOL_DETAILS_STRING_LENGTH = 4096;
50
+ const TOOL_DETAILS_TRUNCATED = "[truncated]";
51
+
52
+ type ToolDetailsProjectionState = {
53
+ remainingNodes: number;
54
+ readonly seen: WeakSet<object>;
55
+ };
56
+
57
+ function projectToolDetailsDescriptor(
58
+ descriptor: PropertyDescriptor | undefined,
59
+ state: ToolDetailsProjectionState,
60
+ depth: number,
61
+ ): unknown {
62
+ if (!descriptor) return "[empty]";
63
+ if ("value" in descriptor)
64
+ return projectToolDetailsValue(descriptor.value, state, depth);
65
+ if (descriptor.get && descriptor.set) return "[Getter/Setter]";
66
+ if (descriptor.get) return "[Getter]";
67
+ return "[Setter]";
68
+ }
69
+
70
+ function projectToolDetailsValue(
71
+ value: unknown,
72
+ state: ToolDetailsProjectionState,
73
+ depth = 0,
74
+ ): unknown {
75
+ if (typeof value === "string")
76
+ return value.length > MAX_TOOL_DETAILS_STRING_LENGTH
77
+ ? `${value.slice(0, MAX_TOOL_DETAILS_STRING_LENGTH)}…`
78
+ : value;
79
+ if (
80
+ value === null ||
81
+ (typeof value !== "object" && typeof value !== "function")
82
+ )
83
+ return value;
84
+ if (typeof value === "function")
85
+ return `[Function${value.name ? `: ${value.name}` : ""}]`;
86
+ if (state.seen.has(value)) return "[Circular]";
87
+ if (state.remainingNodes <= 0) return "[node budget exhausted]";
88
+ if (depth >= MAX_TOOL_DETAILS_DEPTH) return "[depth limit]";
89
+
90
+ state.remainingNodes--;
91
+ state.seen.add(value);
92
+ try {
93
+ if (Array.isArray(value)) {
94
+ const output: unknown[] = [];
95
+ const limit = Math.min(value.length, MAX_TOOL_DETAILS_ENTRIES);
96
+ let index = 0;
97
+ for (; index < limit && state.remainingNodes > 0; index++) {
98
+ output.push(
99
+ projectToolDetailsDescriptor(
100
+ Object.getOwnPropertyDescriptor(value, String(index)),
101
+ state,
102
+ depth + 1,
103
+ ),
104
+ );
105
+ }
106
+ if (index < value.length)
107
+ output.push(`... ${value.length - index} more items`);
108
+ return output;
109
+ }
110
+
111
+ if (value instanceof Map) {
112
+ const output: unknown[] = [];
113
+ let processed = 0;
114
+ for (const [key, entry] of value) {
115
+ if (processed === MAX_TOOL_DETAILS_ENTRIES || state.remainingNodes <= 0)
116
+ break;
117
+ output.push([
118
+ projectToolDetailsValue(key, state, depth + 1),
119
+ projectToolDetailsValue(entry, state, depth + 1),
120
+ ]);
121
+ processed++;
122
+ }
123
+ if (processed < value.size)
124
+ output.push(`... ${value.size - processed} more entries`);
125
+ return { Map: output };
126
+ }
127
+
128
+ if (value instanceof Set) {
129
+ const output: unknown[] = [];
130
+ let processed = 0;
131
+ for (const entry of value) {
132
+ if (processed === MAX_TOOL_DETAILS_ENTRIES || state.remainingNodes <= 0)
133
+ break;
134
+ output.push(projectToolDetailsValue(entry, state, depth + 1));
135
+ processed++;
136
+ }
137
+ if (processed < value.size)
138
+ output.push(`... ${value.size - processed} more entries`);
139
+ return { Set: output };
140
+ }
141
+
142
+ if (ArrayBuffer.isView(value)) {
143
+ const length =
144
+ "length" in value && typeof value.length === "number"
145
+ ? value.length
146
+ : 0;
147
+ const output: unknown[] = [];
148
+ const limit = Math.min(length, MAX_TOOL_DETAILS_ENTRIES);
149
+ for (let index = 0; index < limit; index++)
150
+ output.push(Reflect.get(value, index));
151
+ if (limit < length) output.push(`... ${length - limit} more items`);
152
+ return output;
153
+ }
154
+
155
+ if (value instanceof Date || value instanceof RegExp) return value;
156
+ if (value instanceof Error) {
157
+ return {
158
+ name: value.name,
159
+ message: projectToolDetailsValue(value.message, state, depth + 1),
160
+ };
161
+ }
162
+
163
+ const output: Record<string, unknown> = {};
164
+ let processed = 0;
165
+ for (const key in value) {
166
+ if (!Object.hasOwn(value, key)) continue;
167
+ if (processed === MAX_TOOL_DETAILS_ENTRIES || state.remainingNodes <= 0) {
168
+ Object.defineProperty(output, "... more properties", {
169
+ value: TOOL_DETAILS_TRUNCATED,
170
+ enumerable: true,
171
+ });
172
+ break;
173
+ }
174
+ Object.defineProperty(output, key, {
175
+ value: projectToolDetailsDescriptor(
176
+ Object.getOwnPropertyDescriptor(value, key),
177
+ state,
178
+ depth + 1,
179
+ ),
180
+ enumerable: true,
181
+ });
182
+ processed++;
183
+ }
184
+ return output;
185
+ } catch (error) {
186
+ return `[uninspectable: ${error instanceof Error ? error.message : String(error)}]`;
187
+ }
188
+ }
189
+
46
190
  function detailsFromResult(result: any): string {
47
- if (result?.details === undefined) return "";
48
- const details =
49
- typeof result.details === "string"
50
- ? result.details
51
- : inspect(result.details, { depth: 8, breakLength: 100, compact: false });
191
+ const rawDetails = result?.details;
192
+ if (rawDetails === undefined) return "";
193
+ if (typeof rawDetails === "string")
194
+ return sanitizeToolResultText(rawDetails, 16_384);
195
+ const projected = projectToolDetailsValue(rawDetails, {
196
+ remainingNodes: MAX_TOOL_DETAILS_NODES,
197
+ seen: new WeakSet(),
198
+ });
199
+ const details = inspect(projected, {
200
+ depth: MAX_TOOL_DETAILS_DEPTH,
201
+ breakLength: 100,
202
+ compact: false,
203
+ customInspect: false,
204
+ getters: false,
205
+ maxArrayLength: MAX_TOOL_DETAILS_ENTRIES + 1,
206
+ maxStringLength: MAX_TOOL_DETAILS_STRING_LENGTH,
207
+ });
52
208
  return sanitizeToolResultText(details, 16_384);
53
209
  }
54
210
 
55
211
  export function textFromResult(result: any, expanded = false): string {
56
- // Compact previews only need short text; bound sanitize work.
212
+ // Compact previews only need visible text; avoid traversing large custom details.
57
213
  const content = sanitizeToolResultText(rawTextFromResult(result), 16_384);
214
+ if (content && !expanded) {
215
+ return content;
216
+ }
217
+
58
218
  const details = detailsFromResult(result);
59
- if (!content) return details;
60
- if (!expanded || !details || details === content) return content;
219
+ if (!content) {
220
+ return details;
221
+ }
222
+ if (!details || details === content) {
223
+ return content;
224
+ }
61
225
  return `${content}\nDetails:\n${details}`;
62
226
  }
63
227
 
@@ -301,6 +465,14 @@ export class ExpandedToolIoView {
301
465
  this.flushLeft = flushLeft;
302
466
  }
303
467
 
468
+ setTheme(theme: any): void {
469
+ if (this.theme === theme) {
470
+ return;
471
+ }
472
+ this.theme = theme;
473
+ this.invalidate();
474
+ }
475
+
304
476
  setContent(
305
477
  inputBody: string,
306
478
  outputBody: string,
@@ -759,17 +931,12 @@ export function renderExpandedToolResult(
759
931
 
760
932
  // Prefer structured Input/Output when we have args or non-empty output.
761
933
  if (inputBody.trim() || outputBody.trim()) {
934
+ const cached = context?.state?.ccstyleExpandedIoView;
762
935
  let view: ExpandedToolIoView;
763
936
  if (isExpandedToolIoView(lastComponent)) {
764
- lastComponent.setContent(
765
- inputBody,
766
- outputBody,
767
- isError,
768
- maxLines,
769
- maxLines,
770
- flushLeft,
771
- );
772
937
  view = lastComponent;
938
+ } else if (isExpandedToolIoView(cached)) {
939
+ view = cached;
773
940
  } else {
774
941
  view = new ExpandedToolIoView(
775
942
  theme,
@@ -781,11 +948,23 @@ export function renderExpandedToolResult(
781
948
  flushLeft,
782
949
  );
783
950
  }
951
+ view.setTheme(theme);
952
+ view.setContent(
953
+ inputBody,
954
+ outputBody,
955
+ isError,
956
+ maxLines,
957
+ maxLines,
958
+ flushLeft,
959
+ );
784
960
  if (context) rememberIoView(context, view);
785
961
  return view;
786
962
  }
787
963
 
788
- if (context?.state) context.state.ccstyleIoView = undefined;
964
+ if (context?.state) {
965
+ context.state.ccstyleIoView = undefined;
966
+ context.state.ccstyleExpandedIoView = undefined;
967
+ }
789
968
  const color = isError ? "error" : "muted";
790
969
  return new Text(theme.fg(color, renderCollapsedToolResult("Done")), 0, 0);
791
970
  }
@@ -901,6 +1080,7 @@ function rememberIoView(context: any, view: ExpandedToolIoView): void {
901
1080
  }
902
1081
  if (!context.state || typeof context.state !== "object") context.state = {};
903
1082
  context.state.ccstyleIoView = view;
1083
+ context.state.ccstyleExpandedIoView = view;
904
1084
  }
905
1085
 
906
1086
  /** hover 状态变更后刷新上一个/下一个视图(context.invalidate 缓存于 ioViewInvalidators)。 */
@@ -10,6 +10,7 @@
10
10
 
11
11
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
12
12
  import { formatDuration } from "../../../tools/format.ts";
13
+
13
14
  export { formatDuration };
14
15
 
15
16
  /** 工具分类。 */
@@ -7,13 +7,13 @@
7
7
  * 引用块文字色取主题 mdQuote(cc 主题下为 muted 灰),内容用 *斜体* 语法。
8
8
  */
9
9
 
10
- import { Markdown } from "@earendil-works/pi-tui";
11
- import { getMarkdownTheme } from "@earendil-works/pi-coding-agent";
12
10
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
11
+ import { getMarkdownTheme } from "@earendil-works/pi-coding-agent";
12
+ import { Markdown } from "@earendil-works/pi-tui";
13
13
  import {
14
+ type AgentSummaryData,
14
15
  bindAgentSummary,
15
16
  summaryMarkdown,
16
- type AgentSummaryData,
17
17
  } from "./core.ts";
18
18
 
19
19
  export const AGENT_SUMMARY_ENTRY_TYPE = "agent-summary";
@@ -12,31 +12,30 @@ import {
12
12
  type Theme,
13
13
  } from "@earendil-works/pi-coding-agent";
14
14
  import {
15
+ Box,
16
+ type Component,
15
17
  getKeybindings,
18
+ Markdown,
19
+ Spacer,
20
+ Text,
16
21
  truncateToWidth,
17
22
  visibleWidth,
18
23
  wrapTextWithAnsi,
19
24
  } from "@earendil-works/pi-tui";
20
25
  import {
21
- Box,
22
- Markdown,
23
- Spacer,
24
- Text,
25
- type Component,
26
- } from "@earendil-works/pi-tui";
27
- import { isToolTuiFullscreen } from "../renderer/tool/show-more-hint.ts";
26
+ COMPACT_THINKING_OWNER,
27
+ COMPACT_THINKING_PATCH_KEY,
28
+ PROTOTYPE_ORIGINAL_KEY,
29
+ patchRegistry,
30
+ } from "../../../tools/patch-keys.ts";
28
31
  import {
29
32
  animateCompactThinkingText,
30
33
  formatThoughtDuration,
31
34
  styleCompactThinkingText,
32
35
  } from "../renderer/compact-mode.ts";
33
36
  import { refreshMountedContext } from "../renderer/context-refresh.ts";
34
- import {
35
- COMPACT_THINKING_OWNER,
36
- COMPACT_THINKING_PATCH_KEY,
37
- patchRegistry,
38
- PROTOTYPE_ORIGINAL_KEY,
39
- } from "../../../tools/patch-keys.ts";
37
+ import { isToolTuiFullscreen } from "../renderer/tool/show-more-hint.ts";
38
+
40
39
  // 保持导出兼容:渲染函数已并入 renderer/compact-mode.ts,这里 re-export。
41
40
  export {
42
41
  animateCompactThinkingText,
@@ -1,16 +1,16 @@
1
1
  import type { Theme } from "@earendil-works/pi-coding-agent";
2
2
  import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
3
+ import type { ZentuiConfig } from "../../app/config/shell.ts";
4
+ import {
5
+ renderStyleForSourceOrFallback,
6
+ type SourceStyleFallback,
7
+ } from "../../shared/style.ts";
3
8
  import {
4
9
  applyOwnedLayoutBackground,
5
10
  fillTerminalLine,
6
11
  renderCompletionRows,
7
12
  } from "./completion-menu.ts";
8
- import type { ZentuiConfig } from "../../app/config/shell.ts";
9
13
  import { sanitizeEditorMetadataText } from "./editor-metadata-format.ts";
10
- import {
11
- renderStyleForSourceOrFallback,
12
- type SourceStyleFallback,
13
- } from "../../shared/style.ts";
14
14
 
15
15
  export const ACCENT_RAIL_CHROME_WIDTH = 2;
16
16
 
@@ -6,17 +6,17 @@ import {
6
6
  hasUnsupportedComponentStyle,
7
7
  type PolishedTuiConfig,
8
8
  } from "../../app/config/shell.ts";
9
- import { SessionLifecycle } from "../../app/runtime/session-lifecycle.ts";
10
9
  import type { RenderScheduler } from "../../app/runtime/render-scheduler.ts";
10
+ import type { SessionLifecycle } from "../../app/runtime/session-lifecycle.ts";
11
11
  import type { FooterState } from "../footer/index.ts";
12
12
  import {
13
+ type AccentRailLayoutPatchDiagnostic,
13
14
  installHostAccentRailLayoutPatch,
14
15
  retainAccentRailLayoutPatchInstallation,
15
- type AccentRailLayoutPatchDiagnostic,
16
16
  } from "./accent-rail-layout-patch.ts";
17
17
  import {
18
- replaceEditorComponentWithExpandedText,
19
18
  type EditorTransferFailureReason,
19
+ replaceEditorComponentWithExpandedText,
20
20
  } from "./editor-transfer.ts";
21
21
  import {
22
22
  createEditorFactory,
@@ -24,10 +24,10 @@ import {
24
24
  type EditorFactoryRuntime,
25
25
  } from "./factory.ts";
26
26
  import {
27
+ type EditorFactory,
27
28
  getZentuiEditorBaseFactory,
28
29
  isOwnedEditorFactory,
29
30
  isZentuiEditorFactory,
30
- type EditorFactory,
31
31
  } from "./ownership.ts";
32
32
 
33
33
  export type EditorChangeResult = { ok: true } | { ok: false; reason: string };
@@ -1,14 +1,14 @@
1
1
  import type { Theme } from "@earendil-works/pi-coding-agent";
2
2
  import type { ZentuiConfig } from "../../app/config/shell.ts";
3
- import {
4
- type FormatToken,
5
- parseFooterFormat,
6
- } from "../footer/footer-format.ts";
7
3
  import {
8
4
  EDITOR_ACCENT_FALLBACK,
9
5
  renderStyleForSourceOrFallback,
10
6
  safeThemeFg,
11
7
  } from "../../shared/style.ts";
8
+ import {
9
+ type FormatToken,
10
+ parseFooterFormat,
11
+ } from "../footer/footer-format.ts";
12
12
 
13
13
  export type EditorMetadataValues = {
14
14
  model: string;
@@ -6,15 +6,15 @@ import type {
6
6
  } from "@earendil-works/pi-coding-agent";
7
7
  import type { EditorTheme, TUI } from "@earendil-works/pi-tui";
8
8
  import type { PolishedTuiConfig } from "../../app/config/shell.ts";
9
- import { modelLabelFor, type FooterState } from "../footer/index.ts";
9
+ import { type FooterState, modelLabelFor } from "../footer/index.ts";
10
10
  import { markAccentRailLayoutEditor } from "./accent-rail-layout-patch.ts";
11
- import { PolishedEditor, WrappedPolishedEditor } from "./ui.ts";
12
11
  import {
12
+ type EditorFactory,
13
13
  markEditorFactory,
14
14
  markWrappedEditorFactory,
15
- type EditorFactory,
16
15
  type ZentuiEditorFactory,
17
16
  } from "./ownership.ts";
17
+ import { PolishedEditor, WrappedPolishedEditor } from "./ui.ts";
18
18
 
19
19
  export type EditorFactoryRuntime = {
20
20
  readonly ownerToken: symbol;
@@ -1,16 +1,16 @@
1
1
  export {
2
- EditorLayoutController,
3
- type EditorChangeResult,
4
- type EditorLayoutControllerContext,
5
- } from "./controller.ts";
6
- export {
2
+ type AccentRailLayoutPatchDiagnostic,
7
3
  installHostAccentRailLayoutPatch,
8
4
  markAccentRailLayoutEditor,
9
5
  retainAccentRailLayoutPatchInstallation,
10
- type AccentRailLayoutPatchDiagnostic,
11
6
  } from "./accent-rail-layout-patch.ts";
12
7
  export {
13
- replaceEditorComponentWithExpandedText,
8
+ type EditorChangeResult,
9
+ EditorLayoutController,
10
+ type EditorLayoutControllerContext,
11
+ } from "./controller.ts";
12
+ export {
14
13
  type EditorTransferFailureReason,
14
+ replaceEditorComponentWithExpandedText,
15
15
  } from "./editor-transfer.ts";
16
16
  export { PolishedEditor, WrappedPolishedEditor } from "./ui.ts";