@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.
|
|
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.
|
|
43
|
-
"@oh-my-pi/pi-ai": "3.20.
|
|
44
|
-
"@oh-my-pi/pi-git-tool": "3.20.
|
|
45
|
-
"@oh-my-pi/pi-tui": "3.20.
|
|
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",
|
package/src/core/tools/find.ts
CHANGED
|
@@ -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(
|
|
136
|
+
args.push(effectivePattern, searchPath);
|
|
131
137
|
|
|
132
138
|
// Run fd
|
|
133
139
|
const result = Bun.spawnSync([fdPath, ...args], {
|
package/src/core/tools/ls.ts
CHANGED
|
@@ -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)
|
|
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
|
-
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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();
|