@oh-my-pi/pi-coding-agent 12.7.2 → 12.7.3

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,11 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [12.7.3] - 2026-02-16
6
+
7
+ ### Fixed
8
+ - Suppressed hashline output for subagents without the edit tool (e.g. explore agents)
9
+
5
10
  ## [12.7.1] - 2026-02-16
6
11
  ### Changed
7
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-coding-agent",
3
- "version": "12.7.2",
3
+ "version": "12.7.3",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "bin": {
@@ -84,12 +84,12 @@
84
84
  },
85
85
  "dependencies": {
86
86
  "@mozilla/readability": "0.6.0",
87
- "@oh-my-pi/omp-stats": "12.7.2",
88
- "@oh-my-pi/pi-agent-core": "12.7.2",
89
- "@oh-my-pi/pi-ai": "12.7.2",
90
- "@oh-my-pi/pi-natives": "12.7.2",
91
- "@oh-my-pi/pi-tui": "12.7.2",
92
- "@oh-my-pi/pi-utils": "12.7.2",
87
+ "@oh-my-pi/omp-stats": "12.7.3",
88
+ "@oh-my-pi/pi-agent-core": "12.7.3",
89
+ "@oh-my-pi/pi-ai": "12.7.3",
90
+ "@oh-my-pi/pi-natives": "12.7.3",
91
+ "@oh-my-pi/pi-tui": "12.7.3",
92
+ "@oh-my-pi/pi-utils": "12.7.3",
93
93
  "@sinclair/typebox": "^0.34.48",
94
94
  "@xterm/headless": "^6.0.0",
95
95
  "ajv": "^8.18.0",
package/src/sdk.ts CHANGED
@@ -701,6 +701,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
701
701
  cwd,
702
702
  hasUI: options.hasUI ?? false,
703
703
  enableLsp,
704
+ get hasEditTool() {
705
+ return !options.toolNames || options.toolNames.includes("edit");
706
+ },
704
707
  skipPythonPreflight: options.skipPythonPreflight,
705
708
  contextFiles,
706
709
  skills,
@@ -1072,6 +1072,11 @@ export class AgentSession {
1072
1072
  return this.agent.state.tools.map(t => t.name);
1073
1073
  }
1074
1074
 
1075
+ /** Whether the edit tool is registered in this session. */
1076
+ get hasEditTool(): boolean {
1077
+ return this.#toolRegistry.has("edit");
1078
+ }
1079
+
1075
1080
  /**
1076
1081
  * Get a tool by name from the registry.
1077
1082
  */
@@ -1518,7 +1523,7 @@ export class AgentSession {
1518
1523
  if (fileMentions.length > 0) {
1519
1524
  const fileMentionMessages = await generateFileMentionMessages(fileMentions, this.sessionManager.getCwd(), {
1520
1525
  autoResizeImages: this.settings.get("images.autoResize"),
1521
- useHashLines: resolveFileDisplayMode(this.settings).hashLines,
1526
+ useHashLines: resolveFileDisplayMode(this).hashLines,
1522
1527
  });
1523
1528
  messages.push(...fileMentionMessages);
1524
1529
  }
package/src/tools/grep.ts CHANGED
@@ -62,7 +62,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails> {
62
62
  readonly parameters = grepSchema;
63
63
 
64
64
  constructor(private readonly session: ToolSession) {
65
- const displayMode = resolveFileDisplayMode(session.settings);
65
+ const displayMode = resolveFileDisplayMode(session);
66
66
  this.description = renderPromptTemplate(grepDescription, {
67
67
  IS_HASHLINE_MODE: displayMode.hashLines,
68
68
  IS_LINE_NUMBER_MODE: !displayMode.hashLines && displayMode.lineNumbers,
@@ -103,7 +103,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails> {
103
103
  const patternHasNewline = normalizedPattern.includes("\n") || normalizedPattern.includes("\\n");
104
104
  const effectiveMultiline = multiline ?? patternHasNewline;
105
105
 
106
- const useHashLines = resolveFileDisplayMode(this.session.settings).hashLines;
106
+ const useHashLines = resolveFileDisplayMode(this.session).hashLines;
107
107
  const searchPath = resolveToCwd(searchDir || ".", this.session.cwd);
108
108
  const scopePath = (() => {
109
109
  const relative = path.relative(this.session.cwd, searchPath).replace(/\\/g, "/");
@@ -119,6 +119,8 @@ export interface ToolSession {
119
119
  promptTemplates?: PromptTemplate[];
120
120
  /** Whether LSP integrations are enabled */
121
121
  enableLsp?: boolean;
122
+ /** Whether the edit tool is available in this session (controls hashline output) */
123
+ hasEditTool?: boolean;
122
124
  /** Event bus for tool/extension communication */
123
125
  eventBus?: EventBus;
124
126
  /** Output schema for structured completion (subagents) */
package/src/tools/read.ts CHANGED
@@ -544,7 +544,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
544
544
  readonly #autoResizeImages: boolean;
545
545
 
546
546
  constructor(private readonly session: ToolSession) {
547
- const displayMode = resolveFileDisplayMode(session.settings);
547
+ const displayMode = resolveFileDisplayMode(session);
548
548
  this.#autoResizeImages = session.settings.get("images.autoResize");
549
549
  this.description = renderPromptTemplate(readDescription, {
550
550
  DEFAULT_MAX_LINES: String(DEFAULT_MAX_LINES),
@@ -562,7 +562,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
562
562
  ): Promise<AgentToolResult<ReadToolDetails>> {
563
563
  const { path: readPath, offset, limit } = params;
564
564
 
565
- const displayMode = resolveFileDisplayMode(this.session.settings);
565
+ const displayMode = resolveFileDisplayMode(this.session);
566
566
 
567
567
  // Handle internal URLs (agent://, skill://)
568
568
  const internalRouter = this.session.internalRouter;
@@ -848,7 +848,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
848
848
  async #handleInternalUrl(url: string, offset?: number, limit?: number): Promise<AgentToolResult<ReadToolDetails>> {
849
849
  const internalRouter = this.session.internalRouter!;
850
850
 
851
- const displayMode = resolveFileDisplayMode(this.session.settings);
851
+ const displayMode = resolveFileDisplayMode(this.session);
852
852
 
853
853
  // Check if URL has query extraction (agent:// only)
854
854
  let parsed: URL;
@@ -1,25 +1,34 @@
1
1
  /**
2
2
  * Resolve line-display mode for file-like outputs (read, grep, @file mentions).
3
3
  */
4
- export interface FileDisplayModeSettings {
5
- get(key: "readLineNumbers" | "readHashLines" | "edit.mode"): unknown;
6
- }
7
4
 
8
5
  export interface FileDisplayMode {
9
6
  lineNumbers: boolean;
10
7
  hashLines: boolean;
11
8
  }
12
9
 
10
+ /** Session-like object providing settings and tool availability for display mode resolution. */
11
+ export interface FileDisplayModeSession {
12
+ /** Whether the edit tool is available. Hashlines are suppressed without it. */
13
+ hasEditTool?: boolean;
14
+ settings: {
15
+ get(key: "readLineNumbers" | "readHashLines" | "edit.mode"): unknown;
16
+ };
17
+ }
18
+
13
19
  /**
14
- * Computes effective line display mode from settings/env.
20
+ * Computes effective line display mode from session settings/env.
15
21
  * Hashline mode takes precedence and implies line-addressed output everywhere.
22
+ * Hashlines are suppressed when the edit tool is not available (e.g. explore agents).
16
23
  */
17
- export function resolveFileDisplayMode(settings: FileDisplayModeSettings): FileDisplayMode {
24
+ export function resolveFileDisplayMode(session: FileDisplayModeSession): FileDisplayMode {
25
+ const { settings } = session;
26
+ const hasEditTool = session.hasEditTool ?? true;
18
27
  const hashLines =
19
- settings.get("readHashLines") === true ||
20
- settings.get("edit.mode") === "hashline" ||
21
- Bun.env.PI_EDIT_VARIANT === "hashline";
22
-
28
+ hasEditTool &&
29
+ (settings.get("readHashLines") === true ||
30
+ settings.get("edit.mode") === "hashline" ||
31
+ Bun.env.PI_EDIT_VARIANT === "hashline");
23
32
  return {
24
33
  hashLines,
25
34
  lineNumbers: hashLines || settings.get("readLineNumbers") === true,