@oh-my-pi/pi-coding-agent 3.20.0 → 3.20.1

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,16 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [3.20.1] - 2026-01-06
6
+ ### Fixed
7
+
8
+ - Fixed find tool failing to match patterns with path separators (e.g., `reports/**`) by enabling full-path matching in fd
9
+
10
+ ### Changed
11
+
12
+ - Changed multi-task display to show task descriptions instead of agent names when available
13
+ - Changed ls tool to show relative modification times (e.g., "2d ago", "just now") for each entry
14
+
5
15
  ## [3.20.0] - 2026-01-06
6
16
  ### Added
7
17
 
@@ -1686,4 +1696,4 @@ Initial public release.
1686
1696
  - Git branch display in footer
1687
1697
  - Message queueing during streaming responses
1688
1698
  - OAuth integration for Gmail and Google Calendar access
1689
- - HTML export with syntax highlighting and collapsible sections
1699
+ - HTML export with syntax highlighting and collapsible sections
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-coding-agent",
3
- "version": "3.20.0",
3
+ "version": "3.20.1",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "ompConfig": {
@@ -39,10 +39,10 @@
39
39
  "prepublishOnly": "bun run generate-template && bun run clean && bun run build"
40
40
  },
41
41
  "dependencies": {
42
- "@oh-my-pi/pi-agent-core": "3.20.0",
43
- "@oh-my-pi/pi-ai": "3.20.0",
44
- "@oh-my-pi/pi-git-tool": "3.20.0",
45
- "@oh-my-pi/pi-tui": "3.20.0",
42
+ "@oh-my-pi/pi-agent-core": "3.20.1",
43
+ "@oh-my-pi/pi-ai": "3.20.1",
44
+ "@oh-my-pi/pi-git-tool": "3.20.1",
45
+ "@oh-my-pi/pi-tui": "3.20.1",
46
46
  "@openai/agents": "^0.3.7",
47
47
  "@sinclair/typebox": "^0.34.46",
48
48
  "ajv": "^8.17.1",
@@ -83,8 +83,14 @@ export function createFindTool(cwd: string): AgentTool<typeof findSchema> {
83
83
  const shouldSortByMtime = sortByMtime ?? false;
84
84
 
85
85
  // Build fd arguments
86
+ // When pattern contains path separators (e.g. "reports/**"), use --full-path
87
+ // so fd matches against the full path, not just the filename.
88
+ // Also prepend **/ to anchor the pattern at any depth in the search path.
89
+ const hasPathSeparator = pattern.includes("/") || pattern.includes("\\");
90
+ const effectivePattern = hasPathSeparator && !pattern.startsWith("**/") ? `**/${pattern}` : pattern;
86
91
  const args: string[] = [
87
92
  "--glob", // Use glob pattern
93
+ ...(hasPathSeparator ? ["--full-path"] : []),
88
94
  "--color=never", // No ANSI colors
89
95
  "--max-results",
90
96
  String(effectiveLimit),
@@ -127,7 +133,7 @@ export function createFindTool(cwd: string): AgentTool<typeof findSchema> {
127
133
  }
128
134
 
129
135
  // Pattern and path
130
- args.push(pattern, searchPath);
136
+ args.push(effectivePattern, searchPath);
131
137
 
132
138
  // Run fd
133
139
  const result = Bun.spawnSync([fdPath, ...args], {
@@ -4,6 +4,7 @@ import type { AgentTool } from "@oh-my-pi/pi-agent-core";
4
4
  import { Type } from "@sinclair/typebox";
5
5
  import { untilAborted } from "../utils";
6
6
  import { resolveToCwd } from "./path-utils";
7
+ import { formatAge } from "./render-utils";
7
8
  import { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from "./truncate";
8
9
 
9
10
  const lsSchema = Type.Object({
@@ -26,7 +27,7 @@ export function createLsTool(cwd: string): AgentTool<typeof lsSchema> {
26
27
  return {
27
28
  name: "ls",
28
29
  label: "Ls",
29
- description: `List directory contents. Returns entries sorted alphabetically, with '/' suffix for directories. Includes dotfiles. Output is truncated to 500 entries or 50KB (whichever is hit first). List structure helps with directory navigation and finding target files.`,
30
+ description: `List directory contents with modification times. Returns entries sorted alphabetically, with '/' suffix for directories and relative age (e.g., "2d ago", "just now"). Includes dotfiles. Output is truncated to 500 entries or 50KB (whichever is hit first).`,
30
31
  parameters: lsSchema,
31
32
  execute: async (
32
33
  _toolCallId: string,
@@ -73,6 +74,7 @@ export function createLsTool(cwd: string): AgentTool<typeof lsSchema> {
73
74
 
74
75
  const fullPath = nodePath.join(dirPath, entry);
75
76
  let suffix = "";
77
+ let age = "";
76
78
 
77
79
  try {
78
80
  const entryStat = statSync(fullPath);
@@ -82,12 +84,17 @@ export function createLsTool(cwd: string): AgentTool<typeof lsSchema> {
82
84
  } else {
83
85
  fileCount += 1;
84
86
  }
87
+ // Calculate age from mtime
88
+ const ageSeconds = Math.floor((Date.now() - entryStat.mtimeMs) / 1000);
89
+ age = formatAge(ageSeconds);
85
90
  } catch {
86
91
  // Skip entries we can't stat
87
92
  continue;
88
93
  }
89
94
 
90
- results.push(entry + suffix);
95
+ // Format: "name/ (2d ago)" or "name (just now)"
96
+ const line = age ? `${entry}${suffix} (${age})` : entry + suffix;
97
+ results.push(line);
91
98
  }
92
99
 
93
100
  if (results.length === 0) {
@@ -111,8 +111,8 @@ export function renderCall(args: TaskParams, theme: Theme): Component {
111
111
  return new Text(`${label} ${theme.fg("accent", task.agent)}: ${theme.fg("muted", taskPreview)}`, 0, 0);
112
112
  }
113
113
 
114
- // Multiple tasks - show count and agent names
115
- const agents = args.tasks.map((t) => t.agent).join(", ");
114
+ // Multiple tasks - show count and descriptions (or agent names as fallback)
115
+ const agents = args.tasks.map((t) => t.description?.trim() || t.agent).join(", ");
116
116
  return new Text(
117
117
  `${label} ${theme.fg("muted", `${args.tasks.length} agents: ${truncate(agents, 50, theme.format.ellipsis)}`)}`,
118
118
  0,
@@ -3,12 +3,12 @@ import * as os from "node:os";
3
3
  import * as path from "node:path";
4
4
 
5
5
  function getWorktreeBase(): string {
6
- try {
7
- accessSync("/work", constants.W_OK);
8
- return "/work/.tree";
9
- } catch {
10
- return path.join(os.tmpdir(), ".tree");
11
- }
6
+ try {
7
+ accessSync("/work", constants.W_OK);
8
+ return "/work/.tree";
9
+ } catch {
10
+ return path.join(os.tmpdir(), ".tree");
11
+ }
12
12
  }
13
13
 
14
14
  export const WORKTREE_BASE = getWorktreeBase();