pi-extensions-tool-display 1.1.0 → 1.1.2

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/README.md CHANGED
@@ -14,6 +14,8 @@ It is also a standalone Pi extension. Install or include this package in Pi's pa
14
14
 
15
15
  This package owns the display protocol and generic component composition only. Each feature extension continues to own its domain-specific audit extraction, copy, status, and layout.
16
16
 
17
+ Built-in overrides only replace tools that Pi has already activated; `registerToolOverrides` does not enable inactive built-in tools.
18
+
17
19
  ## Upstream attribution
18
20
 
19
21
  The display integration is designed to work with the MIT-licensed [`MasuRii/pi-tool-display`](https://github.com/MasuRii/pi-tool-display), the original full-featured Pi tool-display project. We thank MasuRii for that work.
package/README.zh-CN.md CHANGED
@@ -14,6 +14,8 @@
14
14
 
15
15
  这个包负责实际工具展示、展示协议和通用组件组合。具体业务的审计数据提取、文案、状态和布局仍由调用方维护,避免把不同扩展耦合在一起。
16
16
 
17
+ 内建工具覆盖只替换 Pi 当前已经激活的工具;`registerToolOverrides` 不会启用原本未激活的内建工具。
18
+
17
19
  ## 上游引用
18
20
 
19
21
  本包的展示集成设计用于兼容 MIT 许可的 [`MasuRii/pi-tool-display`](https://github.com/MasuRii/pi-tool-display),这是 Pi 生态中原始的完整工具展示项目。感谢 MasuRii 的工作。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-extensions-tool-display",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Pi tool display host and shared result-rendering protocol for extensions",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -48,8 +48,8 @@
48
48
  "tool-display"
49
49
  ],
50
50
  "peerDependencies": {
51
- "@earendil-works/pi-coding-agent": ">=0.80.0 <0.81.0",
52
- "@earendil-works/pi-tui": ">=0.80.0 <0.81.0"
51
+ "@earendil-works/pi-coding-agent": ">=0.80.0",
52
+ "@earendil-works/pi-tui": ">=0.80.0"
53
53
  },
54
54
  "pi": {
55
55
  "extensions": [
@@ -60,8 +60,8 @@
60
60
  ]
61
61
  },
62
62
  "devDependencies": {
63
- "@earendil-works/pi-coding-agent": "0.80.10",
64
- "@earendil-works/pi-tui": "0.80.10",
63
+ "@earendil-works/pi-coding-agent": "0.85.1",
64
+ "@earendil-works/pi-tui": "0.85.1",
65
65
  "@types/node": "24.12.4",
66
66
  "tsx": "4.23.1",
67
67
  "typescript": "5.9.3"
package/src/index.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  type ToolDisplayCapabilities,
14
14
  } from "./capabilities.js";
15
15
  import { registerToolDisplayOverrides } from "./tool-overrides.js";
16
+ import { logToolDisplayDebug } from "./debug-logger.js";
16
17
  import { disposeAll, resetDisposed } from "./disposable.js";
17
18
  import { registerThinkingLabeling } from "./thinking-label.js";
18
19
  import registerNativeUserMessageBox from "./user-message-box-native.js";
@@ -24,6 +25,12 @@ import {
24
25
 
25
26
  export * from "./result-render-middleware.js";
26
27
 
28
+ const TOOL_DISPLAY_RELOAD_ACTIVE_TOOLS_KEY = Symbol.for("pi-tool-display.reloadActiveTools.v1");
29
+ const BUILT_IN_TOOL_OVERRIDE_NAME_SET = new Set<string>(BUILT_IN_TOOL_OVERRIDE_NAMES);
30
+ type GlobalWithToolDisplayReloadState = typeof globalThis & {
31
+ [TOOL_DISPLAY_RELOAD_ACTIVE_TOOLS_KEY]?: string[];
32
+ };
33
+
27
34
  function ownershipChanged(
28
35
  previous: ToolDisplayConfig,
29
36
  next: ToolDisplayConfig,
@@ -65,10 +72,21 @@ export function ensureToolDisplayHost(
65
72
  if (initializedHosts.has(pi)) return;
66
73
  initializedHosts.add(pi);
67
74
 
75
+ const globalReloadState = globalThis as GlobalWithToolDisplayReloadState;
76
+ const activeBuiltInToolNamesBeforeReload = globalReloadState[TOOL_DISPLAY_RELOAD_ACTIVE_TOOLS_KEY];
77
+ delete globalReloadState[TOOL_DISPLAY_RELOAD_ACTIVE_TOOLS_KEY];
78
+
68
79
  resetDisposed();
69
80
 
70
81
  pi.on("session_shutdown", (event: { reason: string }) => {
71
82
  if (event.reason === "reload") {
83
+ try {
84
+ globalReloadState[TOOL_DISPLAY_RELOAD_ACTIVE_TOOLS_KEY] = pi
85
+ .getActiveTools()
86
+ .filter((toolName) => BUILT_IN_TOOL_OVERRIDE_NAME_SET.has(toolName));
87
+ } catch (error) {
88
+ logToolDisplayDebug("Failed to preserve active built-in tools for reload.", error);
89
+ }
72
90
  disposeAll();
73
91
  initializedHosts.delete(pi);
74
92
  }
@@ -112,7 +130,7 @@ export function ensureToolDisplayHost(
112
130
  };
113
131
 
114
132
  if (initial.config.enabled) {
115
- registerToolDisplayOverrides(pi, getEffectiveConfig);
133
+ registerToolDisplayOverrides(pi, getEffectiveConfig, activeBuiltInToolNamesBeforeReload);
116
134
  registerNativeUserMessageBox(pi, getConfig);
117
135
  registerThinkingLabeling(pi);
118
136
  }
@@ -1668,9 +1668,20 @@ function tryGetAllTools(pi: ExtensionAPI, debugMessage: string): unknown[] | und
1668
1668
  }
1669
1669
  }
1670
1670
 
1671
+ // Return undefined until Pi binds the extension action methods.
1672
+ function tryGetActiveToolNames(pi: ExtensionAPI, debugMessage: string): string[] | undefined {
1673
+ try {
1674
+ return pi.getActiveTools();
1675
+ } catch (error) {
1676
+ logToolDisplayDebug(debugMessage, error);
1677
+ return undefined;
1678
+ }
1679
+ }
1680
+
1671
1681
  export function registerToolDisplayOverrides(
1672
1682
  pi: ExtensionAPI,
1673
1683
  getConfig: ConfigGetter,
1684
+ activeToolNamesDuringLoad?: readonly string[],
1674
1685
  ): void {
1675
1686
  clearBuiltInToolCache();
1676
1687
  const toolDisplayApi = installToolDisplayApi(getConfig);
@@ -1688,7 +1699,7 @@ export function registerToolDisplayOverrides(
1688
1699
  const registeredBuiltInToolOverrides = new Set<BuiltInToolOverrideName>();
1689
1700
 
1690
1701
  const isExternallyOwnedBuiltInTool = (toolName: BuiltInToolOverrideName): boolean => {
1691
- const allTools = tryGetAllTools(pi, "Built-in tool override ownership discovery unavailable during extension load; registering renderer for pre-bind history rendering.");
1702
+ const allTools = tryGetAllTools(pi, "Built-in tool override ownership discovery unavailable; skipping conflicting owners.");
1692
1703
  if (!allTools) {
1693
1704
  return false;
1694
1705
  }
@@ -1780,7 +1791,37 @@ export function registerToolDisplayOverrides(
1780
1791
  return { scope: getSearchScope(args), limitSuffix: args.limit !== undefined ? ` (limit ${args.limit})` : "" };
1781
1792
  };
1782
1793
 
1783
- registerIfOwned("read", () => {
1794
+ const builtInToolRegistrations = new Map<BuiltInToolOverrideName, () => void>();
1795
+
1796
+ // Record each built-in replacement until Pi exposes its active tool selection.
1797
+ const recordBuiltInToolRegistration = (
1798
+ toolName: BuiltInToolOverrideName,
1799
+ register: () => void,
1800
+ ): void => {
1801
+ builtInToolRegistrations.set(toolName, register);
1802
+ };
1803
+
1804
+ // Retry deferred replacements against Pi's current active tool selection.
1805
+ const registerActiveBuiltInToolOverrides = (
1806
+ knownActiveToolNames?: readonly string[],
1807
+ ): void => {
1808
+ const activeToolNames = knownActiveToolNames ?? tryGetActiveToolNames(
1809
+ pi,
1810
+ "Built-in tool activation discovery unavailable; skipping display overrides.",
1811
+ );
1812
+ if (!activeToolNames) {
1813
+ return;
1814
+ }
1815
+
1816
+ const activeTools = new Set(activeToolNames);
1817
+ for (const [toolName, register] of builtInToolRegistrations) {
1818
+ if (activeTools.has(toolName)) {
1819
+ registerIfOwned(toolName, register);
1820
+ }
1821
+ }
1822
+ };
1823
+
1824
+ recordBuiltInToolRegistration("read", () => {
1784
1825
  registerRuntimeTool(pi, {
1785
1826
  name: "read",
1786
1827
  label: "read",
@@ -1795,7 +1836,7 @@ export function registerToolDisplayOverrides(
1795
1836
  });
1796
1837
  });
1797
1838
 
1798
- registerIfOwned("grep", () => {
1839
+ recordBuiltInToolRegistration("grep", () => {
1799
1840
  registerRuntimeTool(pi, {
1800
1841
  name: "grep",
1801
1842
  label: "grep",
@@ -1816,7 +1857,7 @@ export function registerToolDisplayOverrides(
1816
1857
  });
1817
1858
  });
1818
1859
 
1819
- registerIfOwned("find", () => {
1860
+ recordBuiltInToolRegistration("find", () => {
1820
1861
  registerRuntimeTool(pi, {
1821
1862
  name: "find",
1822
1863
  label: "find",
@@ -1834,7 +1875,7 @@ export function registerToolDisplayOverrides(
1834
1875
  });
1835
1876
  });
1836
1877
 
1837
- registerIfOwned("ls", () => {
1878
+ recordBuiltInToolRegistration("ls", () => {
1838
1879
  registerRuntimeTool(pi, {
1839
1880
  name: "ls",
1840
1881
  label: "ls",
@@ -1850,7 +1891,7 @@ export function registerToolDisplayOverrides(
1850
1891
  });
1851
1892
  });
1852
1893
 
1853
- registerIfOwned("edit", () => {
1894
+ recordBuiltInToolRegistration("edit", () => {
1854
1895
  registerRuntimeTool(pi, {
1855
1896
  name: "edit",
1856
1897
  label: "edit",
@@ -1872,7 +1913,7 @@ export function registerToolDisplayOverrides(
1872
1913
  });
1873
1914
  });
1874
1915
 
1875
- registerIfOwned("write", () => {
1916
+ recordBuiltInToolRegistration("write", () => {
1876
1917
  registerRuntimeTool(pi, {
1877
1918
  name: "write",
1878
1919
  label: "write",
@@ -1945,7 +1986,7 @@ export function registerToolDisplayOverrides(
1945
1986
  });
1946
1987
  });
1947
1988
 
1948
- registerIfOwned("bash", () => {
1989
+ recordBuiltInToolRegistration("bash", () => {
1949
1990
  registerRuntimeTool(pi, {
1950
1991
  name: "bash",
1951
1992
  label: "bash",
@@ -2024,6 +2065,8 @@ export function registerToolDisplayOverrides(
2024
2065
  });
2025
2066
  });
2026
2067
 
2068
+ registerActiveBuiltInToolOverrides(activeToolNamesDuringLoad);
2069
+
2027
2070
  const wrappedCustomToolNames = new Set<string>();
2028
2071
  registerCleanup(() => wrappedCustomToolNames.clear());
2029
2072
 
@@ -2229,11 +2272,13 @@ export function registerToolDisplayOverrides(
2229
2272
 
2230
2273
  pi.on("session_start", async () => {
2231
2274
  clearWriteExecutionMeta(writeExecutionMetaByToolCallId);
2275
+ registerActiveBuiltInToolOverrides();
2232
2276
  registerMcpToolOverrides();
2233
2277
  scheduleMcpToolOverrideDiscovery();
2234
2278
  });
2235
2279
  pi.on("before_agent_start", async () => {
2236
2280
  clearWriteExecutionMeta(writeExecutionMetaByToolCallId);
2281
+ registerActiveBuiltInToolOverrides();
2237
2282
  registerMcpToolOverrides();
2238
2283
  scheduleMcpToolOverrideDiscovery();
2239
2284
  });