@fradser/pi-context 0.6.1 → 0.6.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.
@@ -3,7 +3,7 @@ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
3
  const CONTEXT_GUIDANCE = `
4
4
  ## Isolated research
5
5
 
6
- When the user asks to research, investigate, compare, or understand an external repository, library, codebase, or current technical topic, call \`context_get\`. It starts a separate Pi process with a read/bash allowlist, disabled extension discovery, and prompt-level no-modification guidance; research stays out of the main session. The child may inspect public repositories with a depth-1 temporary clone under /tmp.
6
+ For questions about an external repository, library, codebase, or current technical topic, call \`context_get\` instead of researching inline. Research then stays out of the main session.
7
7
  `;
8
8
 
9
9
  export function registerContextGuidance(pi: ExtensionAPI): void {
@@ -1,8 +1,9 @@
1
- import { getMarkdownTheme, keyHint, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- import { type Component, Markdown, Text, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
1
+ import { keyHint, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ import { type Component, Text, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
3
3
  import {
4
+ bindLifecycleRenderers,
5
+ contentDetailLines,
4
6
  createLiveActivityWidget,
5
- createStaticToolLifecycleResultRenderer,
6
7
  eventToolLifecycle,
7
8
  runPiWorker,
8
9
  type PiLiveWidgetContext,
@@ -12,6 +13,14 @@ import { Type } from "typebox";
12
13
  import { buildContextResearchPrompt } from "./context-prompt.ts";
13
14
 
14
15
  const RESEARCH_TOOLS = ["read", "bash"];
16
+
17
+ /** Geometry bound once: the research row shares hint and wrapping. */
18
+ const contextRows = bindLifecycleRenderers({
19
+ fit: truncateToWidth,
20
+ visibleWidth,
21
+ wrapDetail: (line, width) => wrapTextWithAnsi(line, Math.max(1, width)),
22
+ expandHint: () => keyHint("app.tools.expand", "to expand"),
23
+ });
15
24
  const FINAL_ANSWER_RETRY_INSTRUCTION = `
16
25
 
17
26
  Completion requirement: the previous attempt produced no textual final answer. Complete the original research request now without relying on hidden reasoning, transient tool output, or state from the prior attempt; repeat any inspection needed to support the answer. Your final assistant message must be a self-contained plain-text answer with the conclusion and concrete evidence. Do not finish immediately after a tool call.`;
@@ -64,10 +73,6 @@ function renderContextCall(
64
73
  };
65
74
  }
66
75
 
67
- function resultText(result: ToolTextResult): string {
68
- return result.content.find((part) => part.type === "text")?.text ?? "";
69
- }
70
-
71
76
  export function buildResearchPrompt(query: string, finalAnswerRetry = false): string {
72
77
  const prompt = buildContextResearchPrompt({
73
78
  userResearchRequest: query,
@@ -87,14 +92,14 @@ interface ActiveResearch {
87
92
 
88
93
  let researchToken = 0;
89
94
  let activeResearch: ActiveResearch | undefined;
95
+ // Identity, marker, and activity rendering all come from pi-kit, so this
96
+ // widget uses the same row language as every other package's status row; the
97
+ // activity format is the only per-package choice.
90
98
  const researchWidget = createLiveActivityWidget({
91
99
  key: "context-research",
92
100
  placement: "aboveEditor",
93
101
  fit: truncateToWidth,
94
- formatIdentity: (identity, theme) => theme.fg("success", theme.bold(identity)),
95
- formatActivity: (activity, theme) => new Markdown(
96
- activity, 0, 0, getMarkdownTheme(), { color: (text) => theme.fg("accent", text) },
97
- ).render(Math.max(1, visibleWidth(activity))).map((line) => line.trim()).filter(Boolean).join(" "),
102
+ activityFormat: "markdown",
98
103
  });
99
104
 
100
105
  /** Show the running-research status above the editor; returns a token for updates/clear. */
@@ -186,20 +191,12 @@ export function registerContextTools(pi: ExtensionAPI): void {
186
191
  }
187
192
  const query = (context.args as { query?: string })?.query;
188
193
  const subject = formatResearchSubject(query);
189
- const text = resultText(result as ToolTextResult);
190
- const details = text.split("\n").map((line) => line.trim()).filter(Boolean);
191
194
  const spec = eventToolLifecycle("context", subject, {
192
195
  label: "researched",
193
- details,
196
+ details: contentDetailLines(result),
194
197
  detailLimit: "all",
195
198
  });
196
- return createStaticToolLifecycleResultRenderer({
197
- createSpec: () => spec,
198
- expandHint: keyHint("app.tools.expand", "to expand"),
199
- fit: truncateToWidth,
200
- visibleWidth,
201
- wrapDetail: (line, width) => wrapTextWithAnsi(line, Math.max(1, width)),
202
- })(result as ToolTextResult, options, theme, context);
199
+ return contextRows.result(() => spec)(result as ToolTextResult, options, theme, context);
203
200
  },
204
201
  async execute(_toolCallId, params, signal, onUpdate, ctx) {
205
202
  const widget = startResearchWidget(ctx as ResearchWidgetContext | undefined);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fradser/pi-context",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Retrieve context for repositories, libraries, and technical questions with one native tool that launches an isolated prompt-constrained Pi research child.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -36,6 +36,6 @@
36
36
  "typebox": "*"
37
37
  },
38
38
  "dependencies": {
39
- "@fradser/pi-kit": "0.4.2"
39
+ "@fradser/pi-kit": "0.5.0"
40
40
  }
41
41
  }