@maplezzk/pi-interactive-subagents 3.14.1 → 3.16.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": "@maplezzk/pi-interactive-subagents",
3
- "version": "3.14.1",
3
+ "version": "3.16.0",
4
4
  "description": "Interactive async subagents for pi — spawn, orchestrate, and manage sub-agent sessions in multiplexer panes. Fork of HazAT/pi-interactive-subagents.",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -62,8 +62,8 @@
62
62
  ],
63
63
  "dependencies": {
64
64
  "ajv": "^8.20.0",
65
- "pi-extensions-i18n": "^0.4.1",
66
- "pi-terminal-mux": "^0.6.1"
65
+ "pi-extensions-i18n": "^0.6.0",
66
+ "pi-terminal-mux": "^0.6.3"
67
67
  },
68
68
  "peerDependencies": {
69
69
  "@earendil-works/pi-coding-agent": ">=0.80.0",
@@ -4,7 +4,7 @@ import { Type, type Static } from "@sinclair/typebox";
4
4
  import { Box, Text, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
5
5
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
- import { createTranslator, loadCatalog } from "pi-extensions-i18n";
7
+ import { createTranslator, installNoticeRenderer, loadCatalog, notifyWithSource, type NoticeColor, type NoticeSource } from "pi-extensions-i18n";
8
8
  import {
9
9
  readdirSync,
10
10
  readFileSync,
@@ -87,6 +87,21 @@ import {
87
87
 
88
88
  const i18n = createTranslator(loadCatalog(new URL("../../locales/index.json", import.meta.url)));
89
89
 
90
+ /** 本扩展的提示标签;短且唯一,便于在会话里定位来源。 */
91
+ const NOTICE_TAG = "subagents";
92
+ /** 提示标签颜色;与其它扩展错开,避免看起来像同一条消息。 */
93
+ const NOTICE_COLOR: NoticeColor = "toolTitle";
94
+ /** 本扩展的提示来源。 */
95
+ const NOTICE_SOURCE: NoticeSource = { tag: NOTICE_TAG, color: NOTICE_COLOR };
96
+
97
+ /**
98
+ * 统一的用户可见提示出口:加来源标签后交给 Pi 的 notify。
99
+ * 包内所有 notify 都走这里,避免遗漏标签或颜色。
100
+ */
101
+ function notify(ctx: ExtensionContext, message: string, level: "info" | "warning" | "error"): void {
102
+ notifyWithSource({ ctx, source: NOTICE_SOURCE, level, message });
103
+ }
104
+
90
105
  /** Absolute path to `pi-extension/subagents`. https://github.com/nodejs/node/issues/37845 */
91
106
  const SUBAGENTS_DIR = dirname(fileURLToPath(import.meta.url));
92
107
 
@@ -1280,7 +1295,7 @@ async function editSubagentExtensionsManually(
1280
1295
  initial: readonly string[],
1281
1296
  ): Promise<string[] | undefined> {
1282
1297
  if (!ctx.hasUI) {
1283
- ctx.ui.notify(i18n.t("extensionInteractiveOnly"), "warning");
1298
+ notify(ctx, i18n.t("extensionInteractiveOnly"), "warning");
1284
1299
  return undefined;
1285
1300
  }
1286
1301
 
@@ -1295,7 +1310,7 @@ async function editSubagentExtensionsManually(
1295
1310
  /** Save a selected extension list and report the effective configuration. */
1296
1311
  function saveSelectedSubagentExtensions(ctx: ExtensionContext, extensions: readonly string[]): void {
1297
1312
  const saved = saveSubagentExtensions(extensions);
1298
- ctx.ui.notify(
1313
+ notify(ctx,
1299
1314
  i18n.t("extensionSaved", { value: formatSubagentExtensions(saved.extensions) }),
1300
1315
  "info",
1301
1316
  );
@@ -1304,7 +1319,7 @@ function saveSelectedSubagentExtensions(ctx: ExtensionContext, extensions: reado
1304
1319
  /** Let the user toggle discovered extensions while keeping the built-in done hook fixed. */
1305
1320
  async function chooseSubagentExtensions(ctx: ExtensionContext): Promise<void> {
1306
1321
  if (!ctx.hasUI) {
1307
- ctx.ui.notify(i18n.t("extensionInteractiveOnly"), "warning");
1322
+ notify(ctx, i18n.t("extensionInteractiveOnly"), "warning");
1308
1323
  return;
1309
1324
  }
1310
1325
 
@@ -1388,7 +1403,7 @@ async function handleSubagentExtensionsCommand(
1388
1403
 
1389
1404
  if (extensionArgs.toLowerCase() === SUBAGENT_EXTENSIONS_CLEAR) {
1390
1405
  const saved = saveSubagentExtensions([]);
1391
- ctx.ui.notify(
1406
+ notify(ctx,
1392
1407
  i18n.t("extensionSaved", { value: formatSubagentExtensions(saved.extensions) }),
1393
1408
  "info",
1394
1409
  );
@@ -1397,12 +1412,12 @@ async function handleSubagentExtensionsCommand(
1397
1412
 
1398
1413
  const extensions = parseSubagentExtensionPaths(extensionArgs);
1399
1414
  if (!extensions) {
1400
- ctx.ui.notify(i18n.t("extensionInvalid", { value: requested }), "warning");
1415
+ notify(ctx, i18n.t("extensionInvalid", { value: requested }), "warning");
1401
1416
  return true;
1402
1417
  }
1403
1418
 
1404
1419
  const saved = saveSubagentExtensions(extensions);
1405
- ctx.ui.notify(
1420
+ notify(ctx,
1406
1421
  i18n.t("extensionSaved", { value: formatSubagentExtensions(saved.extensions) }),
1407
1422
  "info",
1408
1423
  );
@@ -1427,7 +1442,7 @@ function registerMuxConfigCommand(pi: ExtensionAPI): void {
1427
1442
  if (requested) {
1428
1443
  const selection = parseMuxConfigRequest(requested);
1429
1444
  if (!selection) {
1430
- ctx.ui.notify(i18n.t("muxInvalid", { value: requested }), "warning");
1445
+ notify(ctx, i18n.t("muxInvalid", { value: requested }), "warning");
1431
1446
  return;
1432
1447
  }
1433
1448
  try {
@@ -1435,18 +1450,18 @@ function registerMuxConfigCommand(pi: ExtensionAPI): void {
1435
1450
  const herdrMode = saved.preference === HERDR_MUX_BACKEND
1436
1451
  ? saved.herdrMode ?? loadHerdrModeConfig().herdrMode
1437
1452
  : undefined;
1438
- ctx.ui.notify(
1453
+ notify(ctx,
1439
1454
  i18n.t("muxSaved", { value: muxPreferenceLabel(saved.preference, herdrMode) }),
1440
1455
  "info",
1441
1456
  );
1442
1457
  } catch (error) {
1443
- ctx.ui.notify(String(error), "error");
1458
+ notify(ctx, String(error), "error");
1444
1459
  }
1445
1460
  return;
1446
1461
  }
1447
1462
 
1448
1463
  if (!ctx.hasUI) {
1449
- ctx.ui.notify(i18n.t("muxInteractiveOnly"), "warning");
1464
+ notify(ctx, i18n.t("muxInteractiveOnly"), "warning");
1450
1465
  return;
1451
1466
  }
1452
1467
 
@@ -1491,14 +1506,14 @@ function registerMuxConfigCommand(pi: ExtensionAPI): void {
1491
1506
  if (!selected) return;
1492
1507
  try {
1493
1508
  const saved = saveMuxConfigSelection(selected);
1494
- ctx.ui.notify(
1509
+ notify(ctx,
1495
1510
  i18n.t("muxSaved", {
1496
1511
  value: muxPreferenceLabel(saved.preference, saved.herdrMode),
1497
1512
  }),
1498
1513
  "info",
1499
1514
  );
1500
1515
  } catch (error) {
1501
- ctx.ui.notify(String(error), "error");
1516
+ notify(ctx, String(error), "error");
1502
1517
  }
1503
1518
  },
1504
1519
  };
@@ -1525,6 +1540,8 @@ function buildTerminalRenameEnvironment(surface: string, backend = getMuxBackend
1525
1540
  }
1526
1541
 
1527
1542
  export const __test__ = {
1543
+ notify,
1544
+ NOTICE_SOURCE,
1528
1545
  buildTerminalRenameEnvironment,
1529
1546
  borderLine,
1530
1547
  parseMuxConfigRequest,
@@ -2004,6 +2021,8 @@ async function watchSubagent(
2004
2021
  }
2005
2022
 
2006
2023
  export default function subagentsExtension(pi: ExtensionAPI) {
2024
+ // 提示画成会话区里的带底色消息块;渲染器在本包这个模块实例里注册一次。
2025
+ installNoticeRenderer(pi);
2007
2026
  applyPersistedMuxPreference();
2008
2027
 
2009
2028
  // Expose launchSubagent / watchSubagent for programmatic use by other extensions
@@ -2614,7 +2633,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
2614
2633
  handler: async (args, ctx) => {
2615
2634
  const trimmed = args.trim();
2616
2635
  if (!trimmed) {
2617
- ctx.ui.notify("Usage: /subagent <agent> [task]", "warning");
2636
+ notify(ctx, "Usage: /subagent <agent> [task]", "warning");
2618
2637
  return;
2619
2638
  }
2620
2639
 
@@ -2624,7 +2643,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
2624
2643
 
2625
2644
  const defs = loadAgentDefaults(agentName);
2626
2645
  if (!defs) {
2627
- ctx.ui.notify(
2646
+ notify(ctx,
2628
2647
  `Agent "${agentName}" not found in ~/.pi/agent/agents/ or .pi/agents/`,
2629
2648
  "error",
2630
2649
  );
@@ -2782,7 +2801,7 @@ export default function subagentsExtension(pi: ExtensionAPI) {
2782
2801
  handler: async (args, ctx) => {
2783
2802
  const task = args.trim();
2784
2803
  if (!task) {
2785
- ctx.ui.notify("Usage: /plan <what to build>", "warning");
2804
+ notify(ctx, "Usage: /plan <what to build>", "warning");
2786
2805
  return;
2787
2806
  }
2788
2807