@fradser/pi-context 0.6.2 → 0.6.4

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Frad LEE
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -27,10 +27,10 @@ Pi recognizes these requests and invokes `context_get` automatically. Users do n
27
27
  The child runs as:
28
28
 
29
29
  ```text
30
- pi --print --mode json --no-session -ne -ns -np -nc --no-themes --tools read,bash
30
+ pi --print --mode json --no-session -ne -ns -np -nc --no-themes --tools read,bash,grep,find
31
31
  ```
32
32
 
33
- The child runs in the caller's working directory through pi-kit's minimal `runPiWorker` mode: `-ne -ns -np -nc --no-themes` disables extension, skill, prompt-template, context-file, and theme discovery, while `--tools read,bash` exposes only the two required tools. It has no sandbox, timeout, or display truncation; `bash` remains technically able to write because there is no OS sandbox, so the bundled worker prompt requires no modifications. If line-level evidence from a public repository is necessary, it may use `git clone --depth=1` under `/tmp` with removal after inspection. It must not run package-management, deployment, or interactive commands. The shared worker fails closed if its bounded stdout, stderr, or JSONL line limits are exceeded.
33
+ The child runs in the caller's working directory through pi-kit's minimal `runPiWorker` mode: `-ne -ns -np -nc --no-themes` disables extension, skill, prompt-template, context-file, and theme discovery, while the shared `MINIMAL_PI_WORKER_TOOLS` grant (`read,bash,grep,find`) exposes only those four built-in tools; the `grep` and `find` entries are Pi's own built-in search tools, not an installed search extension, and the set is defined once in pi-kit so this package carries no local tool literal. It has no sandbox, timeout, or display truncation; `bash` remains technically able to write because there is no OS sandbox, so the bundled worker prompt requires no modifications. If line-level evidence from a public repository is necessary, it may use `git clone --depth=1` under `/tmp` with removal after inspection. It must not run package-management, deployment, or interactive commands. The shared worker fails closed if its bounded stdout, stderr, or JSONL line limits are exceeded.
34
34
 
35
35
  A package-local typed builder reads the bundled Markdown as a reference protocol and builds a task-specific context-review prompt containing the caller working directory, complete research request, reference protocol, and completion contract. The Markdown file itself is never used as an execution identity. Startup renders `[context] research started · <research query>`, using the normalized concrete query that produced the prompt; the row remains width-bounded and does not expose the resource path. While the async child runs, the transcript keeps only that started row with no duplicate progress row; live progress shows in the researcher widget above the editor. The widget shows neutral live research activity. The child always runs with `--no-session`, so separate invocations retain no memory or agent-teams state. A successful empty answer is retried exactly once with a stronger completion requirement that does not rely on hidden reasoning or prior tool output. Results enter the main session untruncated and render as a compact, expandable `[context] researched` lifecycle row.
36
36
 
@@ -7,9 +7,15 @@ For questions about an external repository, library, codebase, or current techni
7
7
  `;
8
8
 
9
9
  export function registerContextGuidance(pi: ExtensionAPI): void {
10
- pi.on("before_agent_start", async (event) => ({
11
- systemPrompt: event.systemPrompt + CONTEXT_GUIDANCE,
12
- }));
10
+ pi.on("before_agent_start", async (event) => {
11
+ const options = event.systemPromptOptions;
12
+ if (!("sections" in options) || !options.sections || typeof options.sections !== "object" || Array.isArray(options.sections)) {
13
+ throw new Error("This extension requires Pi structured prompt sections.");
14
+ }
15
+ const sections = options.sections;
16
+ Reflect.deleteProperty(sections, "context_research");
17
+ Object.assign(sections, { context_research: CONTEXT_GUIDANCE });
18
+ });
13
19
  }
14
20
 
15
21
  export default registerContextGuidance;
@@ -5,15 +5,16 @@ import {
5
5
  contentDetailLines,
6
6
  createLiveActivityWidget,
7
7
  eventToolLifecycle,
8
+ hiddenThinkingEnabled,
9
+ MINIMAL_PI_WORKER_TOOLS,
8
10
  runPiWorker,
11
+ visibleWorkerActivity,
9
12
  type PiLiveWidgetContext,
10
13
  type PiWorkerProgressUpdate,
11
14
  } from "@fradser/pi-kit";
12
15
  import { Type } from "typebox";
13
16
  import { buildContextResearchPrompt } from "./context-prompt.ts";
14
17
 
15
- const RESEARCH_TOOLS = ["read", "bash"];
16
-
17
18
  /** Geometry bound once: the research row shares hint and wrapping. */
18
19
  const contextRows = bindLifecycleRenderers({
19
20
  fit: truncateToWidth,
@@ -92,6 +93,9 @@ interface ActiveResearch {
92
93
 
93
94
  let researchToken = 0;
94
95
  let activeResearch: ActiveResearch | undefined;
96
+ /** Bound by registerContextTools, which alone owns the ExtensionAPI. Read per
97
+ * update so a mid-session settings change reaches the next researcher row. */
98
+ let hiddenThinking: () => boolean = () => false;
95
99
  // Identity, marker, and activity rendering all come from pi-kit, so this
96
100
  // widget uses the same row language as every other package's status row; the
97
101
  // activity format is the only per-package choice.
@@ -140,7 +144,10 @@ export function runResearchChild(
140
144
  return runPiWorker({
141
145
  prompt: buildResearchPrompt(query, finalAnswerRetry),
142
146
  cwd: process.cwd(),
143
- tools: RESEARCH_TOOLS,
147
+ // The grant is pi-kit's canonical minimal worker set (read, bash, grep, and
148
+ // find): inspection access plus Pi's own built-in discovery tools, so one
149
+ // research question costs fewer model turns and no search extension is added.
150
+ tools: MINIMAL_PI_WORKER_TOOLS,
144
151
  minimal: true,
145
152
  signal,
146
153
  onUpdate,
@@ -167,13 +174,14 @@ const ResearchParams = Type.Object({
167
174
  });
168
175
 
169
176
  export function registerContextTools(pi: ExtensionAPI): void {
177
+ hiddenThinking = () => hiddenThinkingEnabled(pi);
170
178
  pi.registerTool({
171
179
  name: "context_get",
172
180
  label: "Isolated Pi research",
173
- description: "Research a repository, library, codebase, or technical topic in an independent prompt-constrained Pi child process. The child has read and bash available and can inspect or temporarily clone public repositories under /tmp.",
181
+ description: "Research a repository, library, codebase, or technical topic in an independent prompt-constrained Pi child process. The child has read, bash, grep, and find available and can inspect or temporarily clone public repositories under /tmp.",
174
182
  promptSnippet: "Research independently in a prompt-constrained Pi child process",
175
183
  promptGuidelines: [
176
- "Use context_get when the user needs external context for a repository, library, codebase, or current technical topic. It retrieves that context in an isolated Pi process with a read/bash allowlist and prompt-level no-modification guidance.",
184
+ "Use context_get when the user needs external context for a repository, library, codebase, or current technical topic. It retrieves that context in an isolated Pi process with a read/bash/grep/find allowlist and prompt-level no-modification guidance.",
177
185
  ],
178
186
  parameters: ResearchParams,
179
187
  executionMode: "sequential",
@@ -194,7 +202,6 @@ export function registerContextTools(pi: ExtensionAPI): void {
194
202
  const spec = eventToolLifecycle("context", subject, {
195
203
  label: "researched",
196
204
  details: contentDetailLines(result),
197
- detailLimit: "all",
198
205
  });
199
206
  return contextRows.result(() => spec)(result as ToolTextResult, options, theme, context);
200
207
  },
@@ -202,8 +209,12 @@ export function registerContextTools(pi: ExtensionAPI): void {
202
209
  const widget = startResearchWidget(ctx as ResearchWidgetContext | undefined);
203
210
  try {
204
211
  const child = await runResearchWithFinalAnswerRetry(params.query, signal, (progress) => {
205
- updateResearchWidget(widget, progress.activity);
206
- onUpdate?.(textResult(progress.activity ?? "Working...", {
212
+ // The above-editor row is the reader's surface, so reasoning becomes
213
+ // Pi's label when thinking blocks are hidden. Tool and answer activity
214
+ // keep their own text and the order in which they arrived.
215
+ const activity = visibleWorkerActivity(progress, hiddenThinking());
216
+ updateResearchWidget(widget, activity);
217
+ onUpdate?.(textResult(activity ?? "Working...", {
207
218
  operation: "context-review",
208
219
  }));
209
220
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fradser/pi-context",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
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.5.0"
39
+ "@fradser/pi-kit": "0.6.0"
40
40
  }
41
- }
41
+ }
@@ -1,6 +1,6 @@
1
1
  You are the stateless one-shot research worker bundled with @fradser/pi-context and invoked by its context_get tool.
2
2
 
3
- Research the supplied request independently and return a concise, evidence-based answer. You have read and bash available. Treat the caller's working directory as read-only: never edit or write files. Bash can technically write, so this boundary is enforced by your instructions rather than an OS sandbox.
3
+ Research the supplied request independently and return a concise, evidence-based answer. You have read, bash, grep, and find available. Prefer grep and find for locating files and matching lines, and reserve bash for commands they cannot express, so the evidence is reached in as few steps as possible. Treat the caller's working directory as read-only: never edit or write files. Bash can technically write, so this boundary is enforced by your instructions rather than an OS sandbox.
4
4
 
5
5
  For public repository line-level evidence, you may run git clone --depth=1 into a unique /tmp directory, inspect it, and remove it before answering. Never modify the caller's working directory. Do not use package managers, deployment commands, or interactive commands.
6
6
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  Use `context_get` for a repository, library, codebase, or technical research request. It launches a stateless one-shot Pi worker so exploratory work and its tool calls do not enter the main session.
4
4
 
5
- A package-local typed builder reads the bundled Markdown as a reference protocol and constructs a task-specific context-review prompt from the current request and working directory, then adds an explicit completion contract. The transcript identifies that execution with the normalized concrete request (`[context] research started · <research query>`), never with the Markdown path; while the async child runs, no duplicate progress row is rendered and live progress shows only in the researcher widget. The child has a `read,bash` allowlist and no extension discovery. The prompt requires read-only behavior and forbids edits, writes, package-manager commands, deployment, and interactive commands; `bash` can technically write because the child has no OS sandbox. For public repository evidence it may run `git clone --depth=1` into a unique directory under `/tmp`, inspect only the relevant files, cite the evidence in its answer, and remove the clone before it exits.
5
+ A package-local typed builder reads the bundled Markdown as a reference protocol and constructs a task-specific context-review prompt from the current request and working directory, then adds an explicit completion contract. The transcript identifies that execution with the normalized concrete request (`[context] research started · <research query>`), never with the Markdown path; while the async child runs, no duplicate progress row is rendered and live progress shows only in the researcher widget. The child has pi-kit's canonical minimal worker grant (`MINIMAL_PI_WORKER_TOOLS`: `read,bash,grep,find`, all built-in tools; no search extension, no package-local list) and no extension discovery. The prompt requires read-only behavior and forbids edits, writes, package-manager commands, deployment, and interactive commands; `bash` can technically write because the child has no OS sandbox. For public repository evidence it may run `git clone --depth=1` into a unique directory under `/tmp`, inspect only the relevant files, cite the evidence in its answer, and remove the clone before it exits.
6
6
 
7
7
  The returned answer should synthesize findings, distinguish facts from uncertainty, and cite useful source URLs or repository paths. It must not modify the caller's working directory.