@fitchmultz/pi-subagents 0.52.12 → 0.52.14

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/CHANGELOG.md CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## 0.52.14 - 2026-11-02
6
+
7
+ <!-- npm-release:unreleased:start -->
8
+ <!-- npm-release:unreleased:end -->
9
+
10
+ - perf: parallelize independent hot-path awaits in intercom and observer (#331) ([af45187](https://github.com/fitchmultz/pi-subagents/commit/af4518766064dc55969ca331d655611b2690f687))
11
+
12
+ ### What's Changed
13
+
14
+ - perf: parallelize independent hot-path awaits in intercom and observer by @fitchmultz in https://github.com/fitchmultz/pi-subagents/pull/331
15
+
16
+ **Full Changelog**: https://github.com/fitchmultz/pi-subagents/compare/v0.52.13...v0.52.14
17
+
18
+ ## 0.52.13 - 2026-11-02
19
+
20
+ <!-- npm-release:unreleased:start -->
21
+ <!-- npm-release:unreleased:end -->
22
+
23
+ - Raise the Pi floor to 1.5.0 (#329) ([fdc15e0](https://github.com/fitchmultz/pi-subagents/commit/fdc15e09fff7bedb74901b09374779b1e8fe4449))
24
+
25
+ ### What's Changed
26
+
27
+ - Raise the Pi floor to 1.5.0 by @fitchmultz in https://github.com/fitchmultz/pi-subagents/pull/329
28
+
29
+ **Full Changelog**: https://github.com/fitchmultz/pi-subagents/compare/v0.52.12...v0.52.13
30
+
5
31
  ## 0.52.12 - 2026-11-02
6
32
 
7
33
  <!-- npm-release:unreleased:start -->
package/README.md CHANGED
@@ -127,9 +127,9 @@ It never runs during startup/install, deletes data, or reclaims disk space.
127
127
  - [Development and qualification](docs/development.md)
128
128
  - [Diagnosis, baseline, and measurable rebuild gates](docs/single-agent-rebuild.md)
129
129
 
130
- Supports official Pi and the maintained `fitchmultz/pi` fork; the two hosts are
131
- qualified separately, including native Android/Termux. Node.js is required; see
132
- [development prerequisites](docs/development.md). Source installs on Android also
133
- need an Android-native `tsgo` on PATH; the prebuilt npm package does not need a
134
- compiler. See [native Android/Termux](docs/development.md#native-androidtermux).
135
- MIT licensed.
130
+ Supports official Pi and the maintained `fitchmultz/pi` fork at 1.5.0 or later;
131
+ the two hosts are qualified separately, including native Android/Termux. Node.js
132
+ is required; see [development prerequisites](docs/development.md). Source
133
+ installs on Android also need an Android-native `tsgo` on PATH; the prebuilt npm
134
+ package does not need a compiler. See
135
+ [native Android/Termux](docs/development.md#native-androidtermux). MIT licensed.
@@ -20,12 +20,17 @@ if (manifest === undefined) {
20
20
  }
21
21
  const root = pathToFileURL(path.join(path.dirname(manifest), "dist/index.js"));
22
22
  // oxlint-disable-next-line typescript/no-unsafe-assignment
23
- const tui = await import(__rewriteRelativeImportExtension(root.href));
23
+ const tuiPromise = import(__rewriteRelativeImportExtension(root.href));
24
24
  // oxlint-disable-next-line typescript/no-unsafe-assignment
25
- const layout = await import(__rewriteRelativeImportExtension(new URL("./layout.js", root).href));
25
+ const layoutPromise = import(__rewriteRelativeImportExtension(new URL("./layout.js", root).href));
26
26
  // oxlint-disable-next-line typescript/no-unsafe-assignment
27
- const dispatch = await import(__rewriteRelativeImportExtension(new URL("./tui.js", root).href));
28
- const sdk = await loadSDK(sdkRoot);
27
+ const dispatchPromise = import(__rewriteRelativeImportExtension(new URL("./tui.js", root).href));
28
+ const [tui, layout, dispatch, sdk] = await Promise.all([
29
+ tuiPromise,
30
+ layoutPromise,
31
+ dispatchPromise,
32
+ loadSDK(sdkRoot),
33
+ ]);
29
34
  export const { Container, HStack, ScrollView, Text, TruncatedText, VStack } = tui;
30
35
  export const { AssistantMessageComponent, ToolExecutionComponent, createBashToolDefinition, createEditToolDefinition, createFindToolDefinition, createGrepToolDefinition, createLsToolDefinition, createPowerShellToolDefinition, createReadToolDefinition, createWriteToolDefinition, rawKeyHint, } = sdk;
31
36
  export const { renderLayoutFrame, getLayoutBoxesAt, getScrollViewsAt } = layout;
@@ -170,13 +170,16 @@ export class ObserverTranscript extends Container {
170
170
  }
171
171
  const { entry, card, request, controller } = job;
172
172
  const options = { signal: controller.signal, hideThinking: this.display.hideThinking };
173
- let page = await this.journal.page(entry, Math.max(0, request.requested), options);
174
- if (request.requested < 0 && page.pages > 1) {
175
- page = await this.journal.page(entry, page.pages - 1, options);
176
- }
177
- const call = typeof page.message.toolCallId === "string" && !card.tool
178
- ? await this.journal.call(page.message.toolCallId, card.id, controller.signal)
179
- : undefined;
173
+ const toolCallId = recordAt(entry.value, "message")?.toolCallId;
174
+ const [firstPage, call] = await Promise.all([
175
+ this.journal.page(entry, Math.max(0, request.requested), options),
176
+ typeof toolCallId === "string" && !card.tool
177
+ ? this.journal.call(toolCallId, card.id, controller.signal)
178
+ : undefined,
179
+ ]);
180
+ const page = request.requested < 0 && firstPage.pages > 1
181
+ ? await this.journal.page(entry, firstPage.pages - 1, options)
182
+ : firstPage;
180
183
  if (!this.current(job)) {
181
184
  return;
182
185
  }
@@ -14,12 +14,13 @@ import { isChild, packageRoot } from "./host.js";
14
14
  // Only the detached runner needs absolute imports from the selected host package.
15
15
  const require = isChild() ? createRequire(path.join(packageRoot(), "dist/index.js")) : undefined;
16
16
  // oxlint-disable-next-line typescript/no-unsafe-assignment
17
- const typebox = require === undefined
18
- ? await import("typebox")
19
- : await import(__rewriteRelativeImportExtension(pathToFileURL(require.resolve("typebox")).href));
17
+ const typeboxPromise = require === undefined
18
+ ? import("typebox")
19
+ : import(__rewriteRelativeImportExtension(pathToFileURL(require.resolve("typebox")).href));
20
20
  // oxlint-disable-next-line typescript/no-unsafe-assignment
21
- const value = require === undefined
22
- ? await import("typebox/value")
23
- : await import(__rewriteRelativeImportExtension(pathToFileURL(require.resolve("typebox/value")).href));
21
+ const valuePromise = require === undefined
22
+ ? import("typebox/value")
23
+ : import(__rewriteRelativeImportExtension(pathToFileURL(require.resolve("typebox/value")).href));
24
+ const [typebox, value] = await Promise.all([typeboxPromise, valuePromise]);
24
25
  export const { Type } = typebox;
25
26
  export const Assert = value.Assert;
@@ -1 +1 @@
1
- export const EXTENSION_BUILD = Object.freeze({"version":"0.52.12","sha256":"afeb6d4b7e13dfe796c199d39eddf3836e8f7ee7185f302254f4182659a0388c"});
1
+ export const EXTENSION_BUILD = Object.freeze({"version":"0.52.14","sha256":"ec0886af93d91687cfae1ed692e1e2e31127d3fbf98abadf192034a044e44d51"});
@@ -250,15 +250,18 @@ export class IntercomConnection {
250
250
  async connect(ctx, generation, sessionId) {
251
251
  const next = this.createClient();
252
252
  try {
253
- await spawnBrokerIfNeeded(this.config.brokerCommand, this.config.brokerArgs, (message) => {
254
- if (message === undefined) {
255
- this.reporter.recover("older-broker");
256
- }
257
- else {
258
- this.reporter.report("older-broker", message, "warning");
259
- }
260
- });
261
- await next.connect(await this.lifecycle.registration(this.hooks.pendingAsks()), nativePeerId(sessionId));
253
+ const [, registration] = await Promise.all([
254
+ spawnBrokerIfNeeded(this.config.brokerCommand, this.config.brokerArgs, (message) => {
255
+ if (message === undefined) {
256
+ this.reporter.recover("older-broker");
257
+ }
258
+ else {
259
+ this.reporter.report("older-broker", message, "warning");
260
+ }
261
+ }),
262
+ this.lifecycle.registration(this.hooks.pendingAsks()),
263
+ ]);
264
+ await next.connect(registration, nativePeerId(sessionId));
262
265
  if (!this.lifecycle.live(ctx, generation)) {
263
266
  await next.disconnect();
264
267
  throw new Error("Intercom runtime no longer active");
@@ -1,7 +1,7 @@
1
- import { getMarkdownTheme, keyHint, truncateToVisualLines, } from "@earendil-works/pi-coding-agent";
1
+ import { getMarkdownTheme, truncateToVisualLines, } from "@earendil-works/pi-coding-agent";
2
2
  import { Box, Container, Markdown, Spacer, Text, truncateToWidth, } from "@earendil-works/pi-tui";
3
3
  import { actionText } from "./tui-action.js";
4
- function preview(content, expanded, theme, showHint = true) {
4
+ function preview(content, expanded, theme, expandHint) {
5
5
  if (expanded) {
6
6
  return content;
7
7
  }
@@ -10,7 +10,7 @@ function preview(content, expanded, theme, showHint = true) {
10
10
  render(width) {
11
11
  if (cache?.width !== width) {
12
12
  const { visualLines, skippedCount } = truncateToVisualLines(content.render(width).join("\n"), 4, width, 0, "start");
13
- const hint = theme.fg("dim", `… ${skippedCount} more lines${showHint ? ` · ${keyHint("app.tools.expand", "to expand")}` : ""}`);
13
+ const hint = theme.fg("dim", `… ${skippedCount} more lines${expandHint === undefined ? "" : ` · ${expandHint}`}`);
14
14
  cache = {
15
15
  width,
16
16
  lines: skippedCount > 0 ? [...visualLines, truncateToWidth(hint, width)] : visualLines,
@@ -24,10 +24,12 @@ function preview(content, expanded, theme, showHint = true) {
24
24
  },
25
25
  };
26
26
  }
27
- export const renderCompactResult = (result, { expanded }, theme) => preview(new Text(theme.fg("toolOutput", result.content
27
+ export const renderCompactResult = (result, { expanded }, theme, context) => preview(new Text(theme.fg("toolOutput", result.content
28
28
  .filter((block) => block.type === "text")
29
29
  .map((block) => block.text)
30
- .join("\n")), 0, 0), expanded, theme);
30
+ .join("\n")), 0, 0), expanded, theme,
31
+ // Pi injects keyHint so the hint shows the user's configured keys.
32
+ context.keyHint("app.tools.expand", "to expand"));
31
33
  export function registerCompactMessages(pi, types) {
32
34
  let ui;
33
35
  pi.on("session_start", (_event, ctx) => {
@@ -37,7 +39,8 @@ export function registerCompactMessages(pi, types) {
37
39
  ui = undefined;
38
40
  });
39
41
  for (const type of types) {
40
- pi.registerMessageRenderer(type, (message, { expanded, outputPad }, theme) => {
42
+ pi.registerMessageRenderer(type, (message, options, theme) => {
43
+ const { expanded, outputPad } = options;
41
44
  const text = typeof message.content === "string"
42
45
  ? message.content
43
46
  : message.content
@@ -53,13 +56,13 @@ export function registerCompactMessages(pi, types) {
53
56
  this.clear();
54
57
  const label = theme.fg("customMessageLabel", theme.bold(`[${type}]`));
55
58
  this.addChild(markdown.render(width).length > 4
56
- ? actionText(`${label} · ${keyHint("app.tools.expand", expanded ? "to collapse" : "to expand")}`, () => ui?.setToolsExpanded(!expanded))
59
+ ? actionText(`${label} · ${options.keyHint("app.tools.expand", expanded ? "to collapse" : "to expand")}`, () => ui?.setToolsExpanded(!expanded))
57
60
  : new Text(label, 0, 0));
58
61
  return super.render(width);
59
62
  }
60
63
  })());
61
64
  box.addChild(new Spacer(1));
62
- box.addChild(preview(markdown, expanded, theme, false));
65
+ box.addChild(preview(markdown, expanded, theme));
63
66
  return box;
64
67
  });
65
68
  }
@@ -53,12 +53,6 @@ hosted CI; do not substitute a weakened checker or incompatible Linux executable
53
53
 
54
54
  ## Runtime qualification
55
55
 
56
- The official development SDK 1.4.0 pins Undici 8.10.2 exactly. A parent-scoped
57
- override selects 8.12.3 for that development graph to fix GHSA-4qv8-2p9j-2685,
58
- GHSA-f72v-6w45-q472 and GHSA-xjj6-f33q-929c. Remove the override when an official
59
- SDK release supplies a fixed version. It does not replace a consumer's host SDK
60
- or Node's built-in fetch.
61
-
62
56
  Qualify the latest stable official Pi and the intended fork revision separately.
63
57
  Record the exact package root, revision/build, Node binary, and executed test
64
58
  commands. Matching versions do not establish matching runtime behavior.
package/docs/reference.md CHANGED
@@ -29,7 +29,7 @@ unknown IDs and invalid suffixes fail without fuzzy matching or another provider
29
29
  Native resolution follows Pi's case-insensitive ID matching. Pi still applies the
30
30
  selected model's native thinking capabilities.
31
31
 
32
- Official Pi 1.3.0 and 1.4.0 do not export that resolver. Older fork runtimes also
32
+ Official Pi, including 1.5.0, does not export that resolver. Older fork runtimes also
33
33
  lack the export. Those hosts retain
34
34
  case-sensitive literal-ID overrides and inherited thinking; suffix requests fail with an upgrade
35
35
  message rather than being parsed by an extension-side replacement. This requires
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fitchmultz/pi-subagents",
3
- "version": "0.52.12",
3
+ "version": "0.52.14",
4
4
  "description": "Pi extension for subagent orchestration and local session coordination",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -104,10 +104,10 @@
104
104
  }
105
105
  },
106
106
  "devDependencies": {
107
- "@earendil-works/pi-agent-core": "1.4.0",
108
- "@earendil-works/pi-ai": "1.4.0",
109
- "@earendil-works/pi-coding-agent": "1.4.0",
110
- "@earendil-works/pi-tui": "1.4.0",
107
+ "@earendil-works/pi-agent-core": "1.5.0",
108
+ "@earendil-works/pi-ai": "1.5.0",
109
+ "@earendil-works/pi-coding-agent": "1.5.0",
110
+ "@earendil-works/pi-tui": "1.5.0",
111
111
  "@types/node": "24.19.2",
112
112
  "@types/sinon": "22.0.2",
113
113
  "oxfmt": "0.75.0",
@@ -123,10 +123,5 @@
123
123
  },
124
124
  "engines": {
125
125
  "node": ">=24.21.0"
126
- },
127
- "overrides": {
128
- "@earendil-works/pi-coding-agent": {
129
- "undici": "8.12.3"
130
- }
131
126
  }
132
127
  }
@@ -4,7 +4,7 @@ set -euo pipefail
4
4
  if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
5
5
  printf '%s\n' 'Usage: bash scripts/linux-smoke.sh
6
6
 
7
- Validate committed HEAD in Docker against a credential-free, prebuilt Pi 1.0
7
+ Validate committed HEAD in Docker against a credential-free, prebuilt Pi 1.5.0+
8
8
  Linux archive with a single top-level pi/ directory and built SDK/CLI output.
9
9
 
10
10
  Example:
@@ -21,7 +21,7 @@ if [[ $# -ne 0 ]]; then
21
21
  printf '%s\n' 'No arguments accepted; use --help.' >&2
22
22
  exit 2
23
23
  fi
24
- : "${PI_LINUX_PI_ARCHIVE:?Set PI_LINUX_PI_ARCHIVE to an absolute path to a credential-free prebuilt Linux Pi 1.0 .tar.gz (top-level pi/) with its Linux dependencies and built SDK/CLI.}"
24
+ : "${PI_LINUX_PI_ARCHIVE:?Set PI_LINUX_PI_ARCHIVE to an absolute path to a credential-free prebuilt Linux Pi 1.5.0+ .tar.gz (top-level pi/) with its Linux dependencies and built SDK/CLI.}"
25
25
 
26
26
  # Validate committed HEAD without passing host credentials or mounting the checkout.
27
27
  git -C "$(dirname "$0")/.." archive HEAD | docker run --rm --init -i \
@@ -16,12 +16,17 @@ if (manifest === undefined) {
16
16
  }
17
17
  const root = pathToFileURL(path.join(path.dirname(manifest), "dist/index.js"));
18
18
  // oxlint-disable-next-line typescript/no-unsafe-assignment
19
- const tui: typeof Tui = await import(root.href);
19
+ const tuiPromise: Promise<typeof Tui> = import(root.href);
20
20
  // oxlint-disable-next-line typescript/no-unsafe-assignment
21
- const layout: typeof Layout = await import(new URL("./layout.js", root).href);
21
+ const layoutPromise: Promise<typeof Layout> = import(new URL("./layout.js", root).href);
22
22
  // oxlint-disable-next-line typescript/no-unsafe-assignment
23
- const dispatch: typeof Dispatch = await import(new URL("./tui.js", root).href);
24
- const sdk = await loadSDK(sdkRoot);
23
+ const dispatchPromise: Promise<typeof Dispatch> = import(new URL("./tui.js", root).href);
24
+ const [tui, layout, dispatch, sdk] = await Promise.all([
25
+ tuiPromise,
26
+ layoutPromise,
27
+ dispatchPromise,
28
+ loadSDK(sdkRoot),
29
+ ]);
25
30
  export const { Container, HStack, ScrollView, Text, TruncatedText, VStack } = tui;
26
31
  export const {
27
32
  AssistantMessageComponent,
@@ -211,14 +211,17 @@ export class ObserverTranscript extends Container {
211
211
  }
212
212
  const { entry, card, request, controller } = job;
213
213
  const options = { signal: controller.signal, hideThinking: this.display.hideThinking };
214
- let page = await this.journal.page(entry, Math.max(0, request.requested), options);
215
- if (request.requested < 0 && page.pages > 1) {
216
- page = await this.journal.page(entry, page.pages - 1, options);
217
- }
218
- const call =
219
- typeof page.message.toolCallId === "string" && !card.tool
220
- ? await this.journal.call(page.message.toolCallId, card.id, controller.signal)
221
- : undefined;
214
+ const toolCallId = recordAt(entry.value, "message")?.toolCallId;
215
+ const [firstPage, call] = await Promise.all([
216
+ this.journal.page(entry, Math.max(0, request.requested), options),
217
+ typeof toolCallId === "string" && !card.tool
218
+ ? this.journal.call(toolCallId, card.id, controller.signal)
219
+ : undefined,
220
+ ]);
221
+ const page =
222
+ request.requested < 0 && firstPage.pages > 1
223
+ ? await this.journal.page(entry, firstPage.pages - 1, options)
224
+ : firstPage;
222
225
  if (!this.current(job)) {
223
226
  return;
224
227
  }
@@ -9,14 +9,15 @@ import { isChild, packageRoot } from "./host.ts";
9
9
  // Only the detached runner needs absolute imports from the selected host package.
10
10
  const require = isChild() ? createRequire(path.join(packageRoot(), "dist/index.js")) : undefined;
11
11
  // oxlint-disable-next-line typescript/no-unsafe-assignment
12
- const typebox: typeof NativeTypebox =
12
+ const typeboxPromise: Promise<typeof NativeTypebox> =
13
13
  require === undefined
14
- ? await import("typebox")
15
- : await import(pathToFileURL(require.resolve("typebox")).href);
14
+ ? import("typebox")
15
+ : import(pathToFileURL(require.resolve("typebox")).href);
16
16
  // oxlint-disable-next-line typescript/no-unsafe-assignment
17
- const value: typeof NativeValue =
17
+ const valuePromise: Promise<typeof NativeValue> =
18
18
  require === undefined
19
- ? await import("typebox/value")
20
- : await import(pathToFileURL(require.resolve("typebox/value")).href);
19
+ ? import("typebox/value")
20
+ : import(pathToFileURL(require.resolve("typebox/value")).href);
21
+ const [typebox, value] = await Promise.all([typeboxPromise, valuePromise]);
21
22
  export const { Type } = typebox;
22
23
  export const Assert: typeof NativeValue.Assert = value.Assert;
@@ -307,17 +307,17 @@ export class IntercomConnection {
307
307
  ): Promise<IntercomTransport> {
308
308
  const next = this.createClient();
309
309
  try {
310
- await spawnBrokerIfNeeded(this.config.brokerCommand, this.config.brokerArgs, (message) => {
311
- if (message === undefined) {
312
- this.reporter.recover("older-broker");
313
- } else {
314
- this.reporter.report("older-broker", message, "warning");
315
- }
316
- });
317
- await next.connect(
318
- await this.lifecycle.registration(this.hooks.pendingAsks()),
319
- nativePeerId(sessionId),
320
- );
310
+ const [, registration] = await Promise.all([
311
+ spawnBrokerIfNeeded(this.config.brokerCommand, this.config.brokerArgs, (message) => {
312
+ if (message === undefined) {
313
+ this.reporter.recover("older-broker");
314
+ } else {
315
+ this.reporter.report("older-broker", message, "warning");
316
+ }
317
+ }),
318
+ this.lifecycle.registration(this.hooks.pendingAsks()),
319
+ ]);
320
+ await next.connect(registration, nativePeerId(sessionId));
321
321
  if (!this.lifecycle.live(ctx, generation)) {
322
322
  await next.disconnect();
323
323
  throw new Error("Intercom runtime no longer active");
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  getMarkdownTheme,
3
- keyHint,
4
3
  truncateToVisualLines,
5
4
  type ExtensionAPI,
6
5
  type ExtensionContext,
@@ -18,7 +17,12 @@ import {
18
17
  } from "@earendil-works/pi-tui";
19
18
  import { actionText } from "./tui-action.ts";
20
19
 
21
- function preview(content: Component, expanded: boolean, theme: Theme, showHint = true): Component {
20
+ function preview(
21
+ content: Component,
22
+ expanded: boolean,
23
+ theme: Theme,
24
+ expandHint?: string,
25
+ ): Component {
22
26
  if (expanded) {
23
27
  return content;
24
28
  }
@@ -35,7 +39,7 @@ function preview(content: Component, expanded: boolean, theme: Theme, showHint =
35
39
  );
36
40
  const hint = theme.fg(
37
41
  "dim",
38
- `… ${skippedCount} more lines${showHint ? ` · ${keyHint("app.tools.expand", "to expand")}` : ""}`,
42
+ `… ${skippedCount} more lines${expandHint === undefined ? "" : ` · ${expandHint}`}`,
39
43
  );
40
44
  cache = {
41
45
  width,
@@ -55,6 +59,7 @@ export const renderCompactResult: NonNullable<ToolDefinition["renderResult"]> =
55
59
  result,
56
60
  { expanded },
57
61
  theme,
62
+ context,
58
63
  ) =>
59
64
  preview(
60
65
  new Text(
@@ -70,6 +75,8 @@ export const renderCompactResult: NonNullable<ToolDefinition["renderResult"]> =
70
75
  ),
71
76
  expanded,
72
77
  theme,
78
+ // Pi injects keyHint so the hint shows the user's configured keys.
79
+ context.keyHint("app.tools.expand", "to expand"),
73
80
  );
74
81
 
75
82
  export function registerCompactMessages(pi: ExtensionAPI, types: readonly string[]): void {
@@ -81,7 +88,8 @@ export function registerCompactMessages(pi: ExtensionAPI, types: readonly string
81
88
  ui = undefined;
82
89
  });
83
90
  for (const type of types) {
84
- pi.registerMessageRenderer(type, (message, { expanded, outputPad }, theme) => {
91
+ pi.registerMessageRenderer(type, (message, options, theme) => {
92
+ const { expanded, outputPad } = options;
85
93
  const text =
86
94
  typeof message.content === "string"
87
95
  ? message.content
@@ -101,7 +109,7 @@ export function registerCompactMessages(pi: ExtensionAPI, types: readonly string
101
109
  this.addChild(
102
110
  markdown.render(width).length > 4
103
111
  ? actionText(
104
- `${label} · ${keyHint("app.tools.expand", expanded ? "to collapse" : "to expand")}`,
112
+ `${label} · ${options.keyHint("app.tools.expand", expanded ? "to collapse" : "to expand")}`,
105
113
  () => ui?.setToolsExpanded(!expanded),
106
114
  )
107
115
  : new Text(label, 0, 0),
@@ -111,7 +119,7 @@ export function registerCompactMessages(pi: ExtensionAPI, types: readonly string
111
119
  })(),
112
120
  );
113
121
  box.addChild(new Spacer(1));
114
- box.addChild(preview(markdown, expanded, theme, false));
122
+ box.addChild(preview(markdown, expanded, theme));
115
123
  return box;
116
124
  });
117
125
  }
package/tsconfig.json CHANGED
@@ -23,7 +23,12 @@
23
23
  "exactOptionalPropertyTypes": true,
24
24
  "noUncheckedSideEffectImports": true,
25
25
  "forceConsistentCasingInFileNames": true,
26
- "noCheck": false
26
+ "noCheck": false,
27
+ "paths": {
28
+ "@earendil-works/pi-ai": [
29
+ "./node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/pi-ai-extension-view.d.ts"
30
+ ]
31
+ }
27
32
  },
28
33
  "include": [
29
34
  "**/*.ts",