pi-one-ui 0.3.0 → 0.4.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 (63) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/README.en.md +39 -35
  3. package/README.md +20 -16
  4. package/extensions/app/commands/settings-previews.ts +4 -16
  5. package/extensions/app/config/renderer.ts +7 -6
  6. package/extensions/app/config/shell.ts +15 -137
  7. package/extensions/app/overlay/selector-border.ts +5 -5
  8. package/extensions/app/ownership.ts +1 -1
  9. package/extensions/app/panel.ts +19 -25
  10. package/extensions/app/runtime/tui-runtime.ts +31 -56
  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/controller.ts +3 -57
  43. package/extensions/layouts/editor/editor-metadata-format.ts +4 -4
  44. package/extensions/layouts/editor/factory.ts +5 -23
  45. package/extensions/layouts/editor/index.ts +2 -8
  46. package/extensions/layouts/editor/minimalist-editor.ts +1 -52
  47. package/extensions/layouts/editor/ui.ts +23 -255
  48. package/extensions/layouts/footer/controller.ts +3 -3
  49. package/extensions/layouts/footer/footer.ts +21 -21
  50. package/extensions/layouts/footer/index.ts +8 -8
  51. package/extensions/layouts/header/index.ts +1 -1
  52. package/extensions/layouts/header/startup-header.ts +3 -2
  53. package/extensions/layouts/working-line/controller.ts +6 -6
  54. package/extensions/layouts/working-line/interaction-summary.ts +47 -7
  55. package/extensions/layouts/working-line/working-line.ts +24 -3
  56. package/extensions/services/project-refresh.ts +2 -2
  57. package/extensions/services/session-state.ts +1 -1
  58. package/extensions/shared/format.ts +2 -2
  59. package/extensions/shared/icons.ts +0 -4
  60. package/package.json +9 -12
  61. package/extensions/features/legacy/working-message.ts +0 -226
  62. package/extensions/layouts/editor/accent-rail-editor.ts +0 -112
  63. package/extensions/layouts/editor/accent-rail-layout-patch.ts +0 -530
@@ -40,12 +40,7 @@ import { overlayManager } from "./overlay/overlay-manager.ts";
40
40
  import { ownerFor } from "./ownership.ts";
41
41
  import { applyPreset, PRESET_VALUES, type Preset } from "./presets.ts";
42
42
 
43
- const EDITOR_STYLES: EditorStyle[] = [
44
- "opencode",
45
- "opencode-copy-friendly",
46
- "accent-rail",
47
- "minimalist",
48
- ];
43
+ const EDITOR_STYLES: EditorStyle[] = ["opencode", "minimalist"];
49
44
  const MESSAGE_STYLES: UserMessageStyle[] = [
50
45
  "framed",
51
46
  "framed-copy-friendly",
@@ -413,6 +408,13 @@ function saveNotice(ctx: any, label: string, value: string): void {
413
408
  );
414
409
  }
415
410
 
411
+ function notifyUpdateError(ctx: any, error: unknown): void {
412
+ ctx.ui?.notify?.(
413
+ `Could not update /oneui setting: ${error instanceof Error ? error.message : String(error)}`,
414
+ "error",
415
+ );
416
+ }
417
+
416
418
  /**
417
419
  * Persists one panel setting and reconciles its owning runtime layout.
418
420
  *
@@ -605,27 +607,19 @@ export async function showOneUiPanel(
605
607
  10,
606
608
  getSettingsListTheme(),
607
609
  (id, value) => {
608
- // Replacing Pi's editor synchronously moves focus away from
609
- // this overlay. Restore the overlay handle after the editor
610
- // has been reconciled so the panel remains interactive.
611
- if (id === "editorEnabled") {
612
- try {
613
- updateSetting(id, value, ctx, deps);
614
- list.updateValue(id, value);
615
- } catch (error) {
616
- ctx.ui?.notify?.(
617
- `Could not update Editor setting: ${error instanceof Error ? error.message : String(error)}`,
618
- "error",
619
- );
620
- } finally {
610
+ try {
611
+ updateSetting(id, value, ctx, deps);
612
+ list.updateValue(id, value);
613
+ } catch (error) {
614
+ notifyUpdateError(ctx, error);
615
+ createList();
616
+ list.selectItem(id);
617
+ } finally {
618
+ if (id === "editorEnabled" || id === "editorStyle") {
621
619
  panelHandle?.focus();
622
- tui.requestRender();
623
620
  }
624
- return;
621
+ tui.requestRender();
625
622
  }
626
- updateSetting(id, value, ctx, deps);
627
- list.updateValue(id, value);
628
- tui.requestRender();
629
623
  },
630
624
  () => done(undefined),
631
625
  );
@@ -687,7 +681,7 @@ export async function showOneUiPanel(
687
681
  width: "85%",
688
682
  maxHeight: "90%",
689
683
  margin: {
690
- top: 10,
684
+ top: 6,
691
685
  right: 1,
692
686
  bottom: 1,
693
687
  left: 1,
@@ -3,56 +3,55 @@ import type {
3
3
  ExtensionContext,
4
4
  Theme,
5
5
  } from "@earendil-works/pi-coding-agent";
6
- import { showOneUiPanel, type TuiPanelRuntime } from "../panel.ts";
7
- import {
8
- createPiExtensionPort,
9
- type PiExtensionPort,
10
- } from "../host/pi-extension-port.ts";
11
- import { createPiUiPort, type PiUiPort } from "../host/pi-ui-port.ts";
12
- import { LayoutRegistry } from "../ownership/layout-registry.ts";
13
- import registerHeaderLayout from "../../layouts/header/index.ts";
14
- import { EventCoordinator } from "./event-coordinator.ts";
15
- import { RenderScheduler } from "./render-scheduler.ts";
16
- import { RuntimeStateStore } from "./runtime-state.ts";
6
+ import registerContext, {
7
+ type ContextExtensionOptions,
8
+ type ContextRuntimeController,
9
+ } from "../../layouts/context/index.ts";
17
10
  import { EditorLayoutController } from "../../layouts/editor/controller.ts";
18
11
  import { FooterLayoutController } from "../../layouts/footer/controller.ts";
12
+ import registerHeaderLayout from "../../layouts/header/index.ts";
19
13
  import {
20
14
  WorkingLineLayoutController,
21
15
  type WorkingLineMessage,
22
16
  type WorkingLineMessageEnd,
23
17
  } from "../../layouts/working-line/controller.ts";
24
- import registerContext, {
25
- type ContextExtensionOptions,
26
- type ContextRuntimeController,
27
- } from "../../layouts/context/index.ts";
28
- import type { AccentRailLayoutPatchDiagnostic } from "../../layouts/editor/accent-rail-layout-patch.ts";
18
+ import {
19
+ renderTurnSummaryEntry,
20
+ TURN_SUMMARY_ENTRY_TYPE,
21
+ } from "../../layouts/working-line/interaction-summary.ts";
22
+ import { LiveContextController } from "../../services/live-context.ts";
23
+ import {
24
+ ProjectRefreshService,
25
+ type ScheduleProjectRefreshOptions,
26
+ } from "../../services/project-refresh.ts";
27
+ import {
28
+ SessionStateService,
29
+ syncState,
30
+ } from "../../services/session-state.ts";
31
+ import { resolveFooterTelemetry } from "../../services/telemetry.ts";
29
32
  import {
30
33
  ensureConfigExists,
31
34
  hasUnsupportedComponentStyle,
32
35
  loadConfig,
33
36
  mergeConfig,
37
+ type PolishedTuiConfig,
34
38
  saveEditorComponentPatch,
35
39
  saveFooterComponentPatch,
36
40
  saveWorkingLineComponentPatch,
37
- type PolishedTuiConfig,
38
41
  } from "../config/shell.ts";
39
- import { configStore, type ConfigRecord } from "../config/store.ts";
40
- import {
41
- SessionStateService,
42
- syncState,
43
- } from "../../services/session-state.ts";
42
+ import { type ConfigRecord, configStore } from "../config/store.ts";
44
43
  import {
45
- renderTurnSummaryEntry,
46
- TURN_SUMMARY_ENTRY_TYPE,
47
- } from "../../layouts/working-line/interaction-summary.ts";
48
- import { LiveContextController } from "../../services/live-context.ts";
49
- import {
50
- ProjectRefreshService,
51
- type ScheduleProjectRefreshOptions,
52
- } from "../../services/project-refresh.ts";
44
+ createPiExtensionPort,
45
+ type PiExtensionPort,
46
+ } from "../host/pi-extension-port.ts";
47
+ import { createPiUiPort, type PiUiPort } from "../host/pi-ui-port.ts";
53
48
  import { SelectorController } from "../overlay/selector-controller.ts";
49
+ import { LayoutRegistry } from "../ownership/layout-registry.ts";
50
+ import { showOneUiPanel, type TuiPanelRuntime } from "../panel.ts";
51
+ import { EventCoordinator } from "./event-coordinator.ts";
52
+ import { RenderScheduler } from "./render-scheduler.ts";
53
+ import { RuntimeStateStore } from "./runtime-state.ts";
54
54
  import { SessionLifecycle } from "./session-lifecycle.ts";
55
- import { resolveFooterTelemetry } from "../../services/telemetry.ts";
56
55
 
57
56
  export type TuiRuntimeContext = {
58
57
  readonly extensions: PiExtensionPort;
@@ -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;
@@ -2,10 +2,10 @@ import {
2
2
  type BuildSystemPromptOptions,
3
3
  type ExtensionAPI,
4
4
  type ExtensionCommandContext,
5
- type ToolInfo,
6
5
  estimateTokens,
7
6
  formatSkillsForPrompt,
8
7
  getMarkdownTheme,
8
+ type ToolInfo,
9
9
  } from "@earendil-works/pi-coding-agent";
10
10
  import {
11
11
  Key,
@@ -13,9 +13,9 @@ import {
13
13
  matchesKey,
14
14
  visibleWidth,
15
15
  } from "@earendil-works/pi-tui";
16
- import { mouseBaseButton, parseSgrMousePacket } from "../../tools/sgr-mouse.ts";
17
- import { padLine } from "../../tools/format.ts";
18
16
  import { overlayManager } from "../../app/overlay/overlay-manager.ts";
17
+ import { padLine } from "../../tools/format.ts";
18
+ import { mouseBaseButton, parseSgrMousePacket } from "../../tools/sgr-mouse.ts";
19
19
 
20
20
  export type ContextPart = {
21
21
  label: string;
@@ -1,25 +1,25 @@
1
1
  import { resolve } from "node:path";
2
2
  import {
3
- SessionManager,
4
3
  type ExtensionAPI,
5
4
  type SessionInfo,
5
+ SessionManager,
6
6
  } from "@earendil-works/pi-coding-agent";
7
7
  import {
8
- Text,
9
8
  type AutocompleteItem,
10
9
  type AutocompleteProvider,
11
10
  type AutocompleteSuggestions,
12
11
  fuzzyFilter,
12
+ Text,
13
13
  } from "@earendil-works/pi-tui";
14
14
  import {
15
- SESSION_REFERENCE_CUSTOM_TYPE,
16
- SESSION_REFERENCE_PREFIX,
17
15
  buildReferenceContentFromSections,
18
16
  extractSessionReferenceIds,
19
17
  formatReferenceSession,
20
- sessionTitle,
21
18
  type ReferenceSessionInfo,
22
19
  type ReferenceSource,
20
+ SESSION_REFERENCE_CUSTOM_TYPE,
21
+ SESSION_REFERENCE_PREFIX,
22
+ sessionTitle,
23
23
  } from "./session.ts";
24
24
 
25
25
  const MAX_SESSION_SUGGESTIONS = 3;
@@ -1,6 +1,6 @@
1
1
  import { existsSync, readdirSync, readFileSync } from "node:fs";
2
- import { join } from "node:path";
3
2
  import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
4
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
5
5
  import {
6
6
  type AutocompleteItem,
@@ -4,7 +4,6 @@ import type {
4
4
  Theme,
5
5
  } from "@earendil-works/pi-coding-agent";
6
6
  import { config } from "../../app/config/renderer.ts";
7
- import { configStore, type ConfigRecord } from "../../app/config/store.ts";
8
7
  import {
9
8
  hasUnsupportedComponentStyle,
10
9
  loadConfig,
@@ -13,27 +12,25 @@ import {
13
12
  type UserMessagesComponentConfig,
14
13
  type ZentuiConfig,
15
14
  } from "../../app/config/shell.ts";
16
- import {
17
- installUserMessageStyle,
18
- removeUserMessageStyle,
19
- } from "./message/user-message.ts";
20
-
15
+ import { type ConfigRecord, configStore } from "../../app/config/store.ts";
21
16
  // shell
22
17
  import piAliases from "../../features/aliases.ts";
18
+ import context from "../../features/context-inspector/index.ts";
23
19
  import { installFlushDockedBash } from "../../features/flush-docked-bash.ts";
24
-
20
+ import sessionReference from "../../features/session-reference/index.ts";
25
21
  // feature
26
22
  import agentAutocomplete from "../../features/subagent-autocomplete.ts";
27
- import agentSummary from "./summary/index.ts";
28
- import context from "../../features/context-inspector/index.ts";
29
- import sessionReference from "../../features/session-reference/index.ts";
30
- import { installCompactThinking } from "./thinking/compact-thinking.ts";
31
-
23
+ import {
24
+ installUserMessageStyle,
25
+ removeUserMessageStyle,
26
+ } from "./message/user-message.ts";
32
27
  // renderer
33
28
  import registerContextRenderer, {
34
29
  getCompactThinkingConfig,
35
30
  } from "./renderer/index.ts";
36
31
  import markdownEnhance from "./renderer/markdown-enhance.ts";
32
+ import agentSummary from "./summary/index.ts";
33
+ import { installCompactThinking } from "./thinking/compact-thinking.ts";
37
34
 
38
35
  export type ContextRuntimeController = {
39
36
  setMode: (mode: "on" | "compact" | "off", ctx: ExtensionContext) => void;
@@ -17,41 +17,22 @@
17
17
  */
18
18
  import {
19
19
  AssistantMessageComponent,
20
- ToolExecutionComponent,
21
20
  type Theme,
21
+ ToolExecutionComponent,
22
22
  } from "@earendil-works/pi-coding-agent";
23
23
  import {
24
- truncateToWidth,
25
- visibleWidth,
26
24
  Box,
27
25
  Spacer,
26
+ truncateToWidth,
27
+ visibleWidth,
28
28
  } from "@earendil-works/pi-tui";
29
29
  import { config, getToolDisplayConfig } from "../../../app/config/renderer.ts";
30
- import { toolLoadingIcon } from "../../../tools/tool-loading-icon.ts";
31
- import { sanitizeToolResultText } from "../../../tools/tool-result-sanitize.ts";
32
- import { refreshContextComponent } from "./context-refresh.ts";
33
- import { getMessageDisplayTheme } from "./tool/message-display.ts";
34
- import { showMoreHintText } from "./tool/show-more-hint.ts";
35
- import {
36
- countEditDiffStats,
37
- countWriteDiffStats,
38
- isRichDiffComponent,
39
- } from "./tool/diff/diff-renderer.ts";
40
- import { renderRichToolResult } from "./tool/diff/index.ts";
41
- import type { WriteExecutionMetadataStore } from "./tool/diff/write-execution.ts";
42
- import { isToolCallHovered } from "./mouse/hover.ts";
43
- import {
44
- insetComponent,
45
- renderExpandedToolResult,
46
- scheduleAnimation,
47
- } from "./tool/result.ts";
48
- import { oneLine } from "../../../tools/format.ts";
49
- import { paddedBackgroundRow } from "./tool/grouping.ts";
50
30
  import {
51
31
  hasVisibleText,
52
32
  stripBackgroundAnsi,
53
33
  } from "../../../tools/ansi-text.ts";
54
34
  import { walkComponentTree } from "../../../tools/component-tree.ts";
35
+ import { oneLine } from "../../../tools/format.ts";
55
36
  import {
56
37
  ASSISTANT_REENTRY_DESCRIPTION,
57
38
  ASSISTANT_REENTRY_KEY,
@@ -61,9 +42,28 @@ import {
61
42
  ASSISTANT_TOGGLE_ROUND_KEY,
62
43
  COMPACT_MODE_PATCH_KEY,
63
44
  COMPACT_THINKING_PATCH_KEY,
64
- patchRegistry,
65
45
  PROTOTYPE_ORIGINAL_KEY,
46
+ patchRegistry,
66
47
  } from "../../../tools/patch-keys.ts";
48
+ import { toolLoadingIcon } from "../../../tools/tool-loading-icon.ts";
49
+ import { sanitizeToolResultText } from "../../../tools/tool-result-sanitize.ts";
50
+ import { refreshContextComponent } from "./context-refresh.ts";
51
+ import { isToolCallHovered } from "./mouse/hover.ts";
52
+ import {
53
+ countEditDiffStats,
54
+ countWriteDiffStats,
55
+ isRichDiffComponent,
56
+ } from "./tool/diff/diff-renderer.ts";
57
+ import { renderRichToolResult } from "./tool/diff/index.ts";
58
+ import type { WriteExecutionMetadataStore } from "./tool/diff/write-execution.ts";
59
+ import { paddedBackgroundRow } from "./tool/grouping.ts";
60
+ import { getMessageDisplayTheme } from "./tool/message-display.ts";
61
+ import {
62
+ insetComponent,
63
+ renderExpandedToolResult,
64
+ scheduleAnimation,
65
+ } from "./tool/result.ts";
66
+ import { showMoreHintText } from "./tool/show-more-hint.ts";
67
67
 
68
68
  /** compact 渲染层对 compact-thinking 的只读查询面(不建第二套计时器)。 */
69
69
  export type CompactThinkingQuery = {
@@ -7,10 +7,11 @@
7
7
  import { ToolExecutionComponent } from "@earendil-works/pi-coding-agent";
8
8
  import { Text, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
9
9
  import {
10
+ type CompactStyleMode,
10
11
  config,
11
12
  getToolDisplayConfig,
12
- type CompactStyleMode,
13
13
  } from "../../../app/config/renderer.ts";
14
+ import { oneLine } from "../../../tools/format.ts";
14
15
  import {
15
16
  COMPONENT_TOOL_RENDER_MODE,
16
17
  GLOBAL_TOOL_RENDER_PATCH,
@@ -18,6 +19,13 @@ import {
18
19
  TOOL_EXPANDED_BACKGROUND_PATCH,
19
20
  } from "../../../tools/patch-keys.ts";
20
21
  import { isToolCallHovered } from "./mouse/hover.ts";
22
+ import { countWriteDiffStats } from "./tool/diff/diff-renderer.ts";
23
+ import {
24
+ renderRichToolResult,
25
+ type WriteExecutionMetadataStore,
26
+ } from "./tool/diff/index.ts";
27
+ import { getMessageDisplayTheme } from "./tool/message-display.ts";
28
+ import { humanizeToolLabel, toolCallSummary } from "./tool/names.ts";
21
29
  import {
22
30
  countLines,
23
31
  hasExpandableDetail,
@@ -30,28 +38,20 @@ import {
30
38
  renderExpandedToolResult,
31
39
  resolveToolVisualState,
32
40
  scheduleAnimation,
33
- settledIcon,
34
41
  setToolVisualState,
42
+ settledIcon,
35
43
  textFromResult,
36
44
  toolIconColor,
37
45
  toolViewportWidth,
38
46
  } from "./tool/result.ts";
39
- import { oneLine } from "../../../tools/format.ts";
40
47
  import { showMoreHintText } from "./tool/show-more-hint.ts";
41
- import { countWriteDiffStats } from "./tool/diff/diff-renderer.ts";
42
- import {
43
- renderRichToolResult,
44
- type WriteExecutionMetadataStore,
45
- } from "./tool/diff/index.ts";
46
- import { getMessageDisplayTheme } from "./tool/message-display.ts";
47
- import { humanizeToolLabel, toolCallSummary } from "./tool/names.ts";
48
48
 
49
49
  // 成功勾:亮绿 truecolor(与 message-display 一致)
50
50
  const BRIGHT_GREEN = "\x1b[38;2;80;220;100m";
51
51
  const ANSI_FG_RESET = "\x1b[39m";
52
52
 
53
- // pi-subagents 等扩展为 Agent 提供专用渲染器,ccstyle 必须保留。
54
- const DEDICATED_RENDERER_TOOLS = new Set(["Agent"]);
53
+ // Preserve rich renderers owned by legacy Agent tools and modern pi-subagents.
54
+ const DEDICATED_RENDERER_TOOLS = new Set(["Agent", "subagent"]);
55
55
 
56
56
  export type DefaultModeHooks = {
57
57
  /** 本安装是否仍持有全局工具渲染补丁。 */
@@ -148,14 +148,14 @@ function renderDefault(
148
148
  tool: any,
149
149
  slot: "renderCall" | "renderResult",
150
150
  args: any[],
151
- fallback = "",
151
+ fallback: string | (() => string) = "",
152
152
  ) {
153
153
  try {
154
154
  if (typeof tool?.[slot] === "function") return tool[slot](...args);
155
155
  } catch {
156
156
  // Fall through to raw fallback.
157
157
  }
158
- return new Text(fallback, 0, 0);
158
+ return new Text(typeof fallback === "function" ? fallback() : fallback, 0, 0);
159
159
  }
160
160
 
161
161
  type ParsedTask = { id: string; status: string; subject: string };
@@ -320,7 +320,7 @@ function createCcstyleTool(
320
320
  originalTool,
321
321
  "renderResult",
322
322
  [result, options, theme, context],
323
- textFromResult(result),
323
+ () => textFromResult(result),
324
324
  );
325
325
  }
326
326
 
@@ -421,7 +421,12 @@ function createCcstyleTool(
421
421
  isToolCallHovered(toolCallId) ? cachedHoveredLine! : cachedLine,
422
422
  ];
423
423
  },
424
- invalidate() {},
424
+ invalidate() {
425
+ cachedWidth = undefined;
426
+ cachedLine = undefined;
427
+ cachedHoveredLine = undefined;
428
+ context?.state?.ccstyleExpandedIoView?.invalidate?.();
429
+ },
425
430
  };
426
431
  },
427
432
  };
@@ -1,52 +1,52 @@
1
1
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- import type { CompactThinkingController } from "../thinking/compact-thinking.ts";
3
2
  import {
4
- installToolGrouping,
5
- type ToolGroupingHooks,
6
- } from "./tool/grouping.ts";
3
+ type CompactStyleMode,
4
+ type Config,
5
+ config,
6
+ normalizeConfig,
7
+ setConfig,
8
+ updateConfig,
9
+ } from "../../../app/config/renderer.ts";
10
+ import { isLazyProxyTui } from "../../../tools/fullscreen-detect.ts";
11
+ import {
12
+ GLOBAL_COMPACTION_RENDER_PATCH,
13
+ patchRegistry,
14
+ } from "../../../tools/patch-keys.ts";
15
+ import type { CompactThinkingController } from "../thinking/compact-thinking.ts";
7
16
  import {
8
- installCompactMode,
9
- refreshCompactModeComponents,
10
17
  type CompactModeHooks,
11
18
  type CompactThinkingQuery,
19
+ installCompactMode,
20
+ refreshCompactModeComponents,
12
21
  } from "./compact-mode.ts";
13
22
  import {
23
+ type DefaultModeHooks,
14
24
  installDefaultMode,
15
25
  installToolExpandedBackground,
16
- type DefaultModeHooks,
17
26
  } from "./default-mode.ts";
18
- import { isLazyProxyTui } from "../../../tools/fullscreen-detect.ts";
19
- import {
20
- GLOBAL_COMPACTION_RENDER_PATCH,
21
- patchRegistry,
22
- } from "../../../tools/patch-keys.ts";
23
- import {
24
- config,
25
- normalizeConfig,
26
- setConfig,
27
- updateConfig,
28
- type CompactStyleMode,
29
- type Config,
30
- } from "../../../app/config/renderer.ts";
27
+ import { setHoveredToolGroup, setHoveredToolIo } from "./mouse/hover.ts";
31
28
  import {
32
29
  installToolMouseInteraction,
33
30
  resetToolHoverState,
34
31
  scheduleSessionRender,
35
- teardownToolMouseInteraction,
36
32
  TOOL_MOUSE_DISABLE,
33
+ teardownToolMouseInteraction,
37
34
  } from "./mouse/interaction.ts";
38
35
  import { getToolMouseTui } from "./mouse/scroll.ts";
39
- import { setHoveredToolGroup, setHoveredToolIo } from "./mouse/hover.ts";
40
- import { clearAllAnimations } from "./tool/result.ts";
41
36
  import {
42
37
  installWriteOverride,
43
38
  WriteExecutionMetadataStore,
44
39
  } from "./tool/diff/index.ts";
40
+ import {
41
+ installToolGrouping,
42
+ type ToolGroupingHooks,
43
+ } from "./tool/grouping.ts";
45
44
  import {
46
45
  installMessageDisplayRendering,
47
46
  refreshMessageDisplays,
48
47
  setMessageDisplayTheme,
49
48
  } from "./tool/message-display.ts";
49
+ import { clearAllAnimations } from "./tool/result.ts";
50
50
 
51
51
  /**
52
52
  * Claude Code Style for pi — 装配入口。
@@ -277,10 +277,10 @@ export {
277
277
  preservesOriginalRenderer,
278
278
  shouldRenderRichDiff,
279
279
  } from "./default-mode.ts";
280
+ export { installToolMouseInteraction } from "./mouse/interaction.ts";
280
281
  export {
281
282
  ExpandedToolIoView,
282
283
  ExpandedToolResultText,
283
284
  formatToolInputArgs,
284
285
  SHOW_MORE_LABEL,
285
286
  } from "./tool/result.ts";
286
- export { installToolMouseInteraction } from "./mouse/interaction.ts";
@@ -1,17 +1,17 @@
1
- import { ThinkingPreviewBlock } from "../../thinking/compact-thinking.ts";
2
- import { setHoveredCompactAssistant } from "../compact-mode.ts";
3
1
  import {
4
2
  patchRegistry,
5
3
  TOOL_HOVER_STATE_KEY,
6
4
  } from "../../../../tools/patch-keys.ts";
5
+ import type { ThinkingPreviewBlock } from "../../thinking/compact-thinking.ts";
6
+ import { setHoveredCompactAssistant } from "../compact-mode.ts";
7
+ import type { ToolGroupComponent } from "../tool/grouping.ts";
7
8
  import {
8
- isExpandedToolIoView,
9
- invalidateIoView,
10
9
  type ExpandedToolIoView,
10
+ invalidateIoView,
11
+ isExpandedToolIoView,
11
12
  type ToolIoSection,
12
13
  } from "../tool/result.ts";
13
- import type { ToolGroupComponent } from "../tool/grouping.ts";
14
- import { componentAtLocalRow, type ComponentRowHit } from "./layout.ts";
14
+ import { type ComponentRowHit, componentAtLocalRow } from "./layout.ts";
15
15
  import { setScrollButtonHovered } from "./scroll.ts";
16
16
 
17
17
  type SharedToolHoverState = { toolCallId: string | null };