pi-extensions-tool-display 1.1.2 → 1.3.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-extensions-tool-display",
3
- "version": "1.1.2",
3
+ "version": "1.3.0",
4
4
  "description": "Pi tool display host and shared result-rendering protocol for extensions",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -47,13 +47,17 @@
47
47
  "coding-agent",
48
48
  "tool-display"
49
49
  ],
50
+ "dependencies": {
51
+ "pi-extensions-i18n": "^0.6.0"
52
+ },
50
53
  "peerDependencies": {
51
54
  "@earendil-works/pi-coding-agent": ">=0.80.0",
52
55
  "@earendil-works/pi-tui": ">=0.80.0"
53
56
  },
54
57
  "pi": {
55
58
  "extensions": [
56
- "./index.ts"
59
+ "./index.ts",
60
+ "../pi-extensions-i18n/index.ts"
57
61
  ],
58
62
  "skills": [
59
63
  "./SKILL.md"
@@ -11,6 +11,19 @@ import {
11
11
  import { shortenPath } from "./render-utils.js";
12
12
  import type { InspectorSettingItem } from "./settings-inspector-modal.js";
13
13
  import { type ToolDisplayConfig } from "./types.js";
14
+ import {
15
+ notifyWithSource,
16
+ type NoticeColor,
17
+ type NoticeLevel,
18
+ type NoticeSource,
19
+ } from "pi-extensions-i18n";
20
+
21
+ /** 本扩展的提示标签;短且唯一,便于在会话里定位来源。 */
22
+ const NOTICE_TAG = "display";
23
+ /** 提示标签颜色;与其它扩展错开,避免看起来像同一条消息。 */
24
+ const NOTICE_COLOR: NoticeColor = "muted";
25
+ /** 本扩展的提示来源。 */
26
+ const NOTICE_SOURCE: NoticeSource = { tag: NOTICE_TAG, color: NOTICE_COLOR };
14
27
 
15
28
  interface ToolDisplayConfigController {
16
29
  getConfig(): ToolDisplayConfig;
@@ -18,6 +31,11 @@ interface ToolDisplayConfigController {
18
31
  getCapabilities(): ToolDisplayCapabilities;
19
32
  }
20
33
 
34
+ /** 带来源标签的用户提示;集中走统一出口,调用点不再直接碰 ctx.ui.notify。 */
35
+ function notify(ctx: ExtensionCommandContext, message: string, level: NoticeLevel): void {
36
+ notifyWithSource({ ctx, source: NOTICE_SOURCE, level, message });
37
+ }
38
+
21
39
  interface ModalOverlayOptions {
22
40
  anchor: "center";
23
41
  width: number;
@@ -483,7 +501,8 @@ export function handleToolDisplayArgs(args: string, ctx: ExtensionCommandContext
483
501
  const normalized = raw.toLowerCase();
484
502
 
485
503
  if (normalized === "show") {
486
- ctx.ui.notify(
504
+ notify(
505
+ ctx,
487
506
  `tool-display: ${summarizeConfig(controller.getConfig(), controller.getCapabilities())}`,
488
507
  "info",
489
508
  );
@@ -492,7 +511,7 @@ export function handleToolDisplayArgs(args: string, ctx: ExtensionCommandContext
492
511
 
493
512
  if (normalized === "reset") {
494
513
  controller.setConfig(applyPreset("opencode", controller.getConfig().enabled), ctx);
495
- ctx.ui.notify("Tool display preset reset to opencode.", "info");
514
+ notify(ctx, "Tool display preset reset to opencode.", "info");
496
515
  return true;
497
516
  }
498
517
 
@@ -500,16 +519,16 @@ export function handleToolDisplayArgs(args: string, ctx: ExtensionCommandContext
500
519
  const candidate = normalized.slice("preset ".length).trim();
501
520
  const preset = parseToolDisplayPreset(candidate);
502
521
  if (!preset) {
503
- ctx.ui.notify(`Unknown preset. Use: /config:tool-display preset ${PRESET_COMMAND_HINT}`, "warning");
522
+ notify(ctx, `Unknown preset. Use: /config:tool-display preset ${PRESET_COMMAND_HINT}`, "warning");
504
523
  return true;
505
524
  }
506
525
 
507
526
  controller.setConfig(applyPreset(preset, controller.getConfig().enabled), ctx);
508
- ctx.ui.notify(`Tool display preset set to ${preset}.`, "info");
527
+ notify(ctx, `Tool display preset set to ${preset}.`, "info");
509
528
  return true;
510
529
  }
511
530
 
512
- ctx.ui.notify(`Usage: /config:tool-display [show|reset|preset ${PRESET_COMMAND_HINT}]`, "warning");
531
+ notify(ctx, `Usage: /config:tool-display [show|reset|preset ${PRESET_COMMAND_HINT}]`, "warning");
513
532
  return true;
514
533
  }
515
534
 
@@ -523,7 +542,7 @@ export async function runToolDisplayCommandHandler(
523
542
  }
524
543
 
525
544
  if (!ctx.hasUI) {
526
- ctx.ui.notify("/config:tool-display requires interactive TUI mode.", "warning");
545
+ notify(ctx, "/config:tool-display requires interactive TUI mode.", "warning");
527
546
  return;
528
547
  }
529
548
 
package/src/index.ts CHANGED
@@ -22,6 +22,19 @@ import {
22
22
  type ConfigLoadResult,
23
23
  type ToolDisplayConfig,
24
24
  } from "./types.js";
25
+ import {
26
+ installNoticeRenderer,
27
+ notifyWithSource,
28
+ type NoticeColor,
29
+ type NoticeSource,
30
+ } from "pi-extensions-i18n";
31
+
32
+ /** 本扩展的提示标签;短且唯一,便于在会话里定位来源。 */
33
+ const NOTICE_TAG = "display";
34
+ /** 提示标签颜色;与其它扩展错开,避免看起来像同一条消息。 */
35
+ const NOTICE_COLOR: NoticeColor = "muted";
36
+ /** 本扩展的提示来源。 */
37
+ const NOTICE_SOURCE: NoticeSource = { tag: NOTICE_TAG, color: NOTICE_COLOR };
25
38
 
26
39
  export * from "./result-render-middleware.js";
27
40
 
@@ -118,14 +131,16 @@ export function ensureToolDisplayHost(
118
131
 
119
132
  const saved = saveToolDisplayConfig(normalized);
120
133
  if (!saved.success && saved.error) {
121
- ctx.ui.notify(saved.error, "error");
134
+ notifyWithSource({ ctx, source: NOTICE_SOURCE, level: "error", message: saved.error });
122
135
  }
123
136
 
124
137
  if (requiresReload) {
125
- ctx.ui.notify(
126
- "Global switch or tool ownership updates apply after /reload.",
127
- "warning",
128
- );
138
+ notifyWithSource({
139
+ ctx,
140
+ source: NOTICE_SOURCE,
141
+ level: "warning",
142
+ message: "Global switch or tool ownership updates apply after /reload.",
143
+ });
129
144
  }
130
145
  };
131
146
 
@@ -152,7 +167,7 @@ export function ensureToolDisplayHost(
152
167
  pi.on("session_start", async (_event, ctx) => {
153
168
  refreshCapabilities();
154
169
  if (pendingLoadError) {
155
- ctx.ui.notify(pendingLoadError, "warning");
170
+ notifyWithSource({ ctx, source: NOTICE_SOURCE, level: "warning", message: pendingLoadError });
156
171
  pendingLoadError = undefined;
157
172
  }
158
173
  });
@@ -166,5 +181,7 @@ export default function toolDisplayExtension(
166
181
  pi: ExtensionAPI,
167
182
  initial: ConfigLoadResult = loadToolDisplayConfig(),
168
183
  ): void {
184
+ // 提示画成会话区里的带底色消息块;渲染器在本包这个模块实例里注册一次。
185
+ installNoticeRenderer(pi);
169
186
  ensureToolDisplayHost(pi, initial);
170
187
  }
@@ -1,6 +1,18 @@
1
1
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
2
  import { isRecord } from "./tool-metadata.js";
3
3
  import { onReloadShutdown } from "./extension-lifecycle.js";
4
+ import {
5
+ notifyWithSource,
6
+ type NoticeColor,
7
+ type NoticeSource,
8
+ } from "pi-extensions-i18n";
9
+
10
+ /** 本扩展的提示标签;短且唯一,便于在会话里定位来源。 */
11
+ const NOTICE_TAG = "display";
12
+ /** 提示标签颜色;与其它扩展错开,避免看起来像同一条消息。 */
13
+ const NOTICE_COLOR: NoticeColor = "muted";
14
+ /** 本扩展的提示来源。 */
15
+ const NOTICE_SOURCE: NoticeSource = { tag: NOTICE_TAG, color: NOTICE_COLOR };
4
16
 
5
17
  interface ThemeLike {
6
18
  fg(color: string, text: string): string;
@@ -286,7 +298,7 @@ function processThinkingEvent(
286
298
  prefixThinkingBlocksForDisplay(message, ctx?.ui?.theme);
287
299
  } catch (error) {
288
300
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
289
- ctx?.ui?.notify(`${notifyPrefix}: ${errorMessage}`, "warning");
301
+ if (ctx) notifyWithSource({ ctx, source: NOTICE_SOURCE, level: "warning", message: `${notifyPrefix}: ${errorMessage}` });
290
302
  }
291
303
  }
292
304
 
@@ -315,7 +327,7 @@ function handleThinkingContextEvent(event: unknown, ctx: ExtensionContext | unde
315
327
  }
316
328
  } catch (error) {
317
329
  const message = error instanceof Error ? error.message : "Unknown error";
318
- ctx?.ui?.notify(`Thinking context sanitization failed: ${message}`, "warning");
330
+ if (ctx) notifyWithSource({ ctx, source: NOTICE_SOURCE, level: "warning", message: `Thinking context sanitization failed: ${message}` });
319
331
  }
320
332
  }
321
333