@oh-my-pi/pi-coding-agent 13.3.2 → 13.3.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/CHANGELOG.md +9 -0
- package/package.json +7 -7
- package/src/cursor.ts +1 -1
- package/src/modes/components/tool-execution.ts +3 -2
- package/src/patch/diff.ts +3 -3
- package/src/prompts/tools/bash.md +14 -1
- package/src/prompts/tools/read.md +8 -1
- package/src/ssh/connection-manager.ts +2 -2
- package/src/ssh/ssh-executor.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [13.3.3] - 2026-02-26
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- Support for `move` parameter in `computeHashlineDiff` to enable file move operations alongside content edits
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Modified no-op detection logic to allow move-only operations when file content remains unchanged
|
|
13
|
+
|
|
5
14
|
## [13.3.1] - 2026-02-26
|
|
6
15
|
|
|
7
16
|
### Added
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "13.3.
|
|
4
|
+
"version": "13.3.4",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/can1357/oh-my-pi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@mozilla/readability": "^0.6",
|
|
44
|
-
"@oh-my-pi/omp-stats": "13.3.
|
|
45
|
-
"@oh-my-pi/pi-agent-core": "13.3.
|
|
46
|
-
"@oh-my-pi/pi-ai": "13.3.
|
|
47
|
-
"@oh-my-pi/pi-natives": "13.3.
|
|
48
|
-
"@oh-my-pi/pi-tui": "13.3.
|
|
49
|
-
"@oh-my-pi/pi-utils": "13.3.
|
|
44
|
+
"@oh-my-pi/omp-stats": "13.3.4",
|
|
45
|
+
"@oh-my-pi/pi-agent-core": "13.3.4",
|
|
46
|
+
"@oh-my-pi/pi-ai": "13.3.4",
|
|
47
|
+
"@oh-my-pi/pi-natives": "13.3.4",
|
|
48
|
+
"@oh-my-pi/pi-tui": "13.3.4",
|
|
49
|
+
"@oh-my-pi/pi-utils": "13.3.4",
|
|
50
50
|
"@sinclair/typebox": "^0.34",
|
|
51
51
|
"@xterm/headless": "^6.0",
|
|
52
52
|
"ajv": "^8.18",
|
package/src/cursor.ts
CHANGED
|
@@ -198,7 +198,7 @@ export class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
198
198
|
const timeoutSeconds = args.timeout && args.timeout > 0 ? args.timeout : undefined;
|
|
199
199
|
const toolResultMessage = await executeTool(this.options, "bash", toolCallId, {
|
|
200
200
|
command: args.command,
|
|
201
|
-
|
|
201
|
+
cwd: args.workingDirectory || undefined,
|
|
202
202
|
timeout: timeoutSeconds,
|
|
203
203
|
});
|
|
204
204
|
return toolResultMessage;
|
|
@@ -204,12 +204,13 @@ export class ToolExecutionComponent extends Container {
|
|
|
204
204
|
return;
|
|
205
205
|
}
|
|
206
206
|
const edits = this.#args?.edits;
|
|
207
|
+
const move = this.#args?.move;
|
|
207
208
|
if (path && Array.isArray(edits)) {
|
|
208
|
-
const argsKey = JSON.stringify({ path, edits });
|
|
209
|
+
const argsKey = JSON.stringify({ path, edits, move });
|
|
209
210
|
if (this.#editDiffArgsKey === argsKey) return;
|
|
210
211
|
this.#editDiffArgsKey = argsKey;
|
|
211
212
|
|
|
212
|
-
computeHashlineDiff({ path, edits }, this.#cwd).then(result => {
|
|
213
|
+
computeHashlineDiff({ path, edits, move }, this.#cwd).then(result => {
|
|
213
214
|
if (this.#editDiffArgsKey === argsKey) {
|
|
214
215
|
this.#editDiffPreview = result;
|
|
215
216
|
this.#updateDisplay();
|
package/src/patch/diff.ts
CHANGED
|
@@ -386,10 +386,10 @@ export async function computePatchDiff(
|
|
|
386
386
|
* Used for preview rendering in the TUI before hashline-mode edits execute.
|
|
387
387
|
*/
|
|
388
388
|
export async function computeHashlineDiff(
|
|
389
|
-
input: { path: string; edits: HashlineEdit[] },
|
|
389
|
+
input: { path: string; edits: HashlineEdit[]; move?: string },
|
|
390
390
|
cwd: string,
|
|
391
391
|
): Promise<DiffResult | DiffError> {
|
|
392
|
-
const { path, edits } = input;
|
|
392
|
+
const { path, edits, move } = input;
|
|
393
393
|
const absolutePath = resolveToCwd(path, cwd);
|
|
394
394
|
|
|
395
395
|
try {
|
|
@@ -414,7 +414,7 @@ export async function computeHashlineDiff(
|
|
|
414
414
|
const normalizedContent = normalizeToLF(content);
|
|
415
415
|
|
|
416
416
|
const result = applyHashlineEdits(normalizedContent, edits);
|
|
417
|
-
if (normalizedContent === result.lines) {
|
|
417
|
+
if (normalizedContent === result.lines && !move) {
|
|
418
418
|
return { error: `No changes would be made to ${path}. The edits produce identical content.` };
|
|
419
419
|
}
|
|
420
420
|
|
|
@@ -22,7 +22,20 @@ Returns the output, and an exit code from command execution.
|
|
|
22
22
|
</output>
|
|
23
23
|
|
|
24
24
|
<critical>
|
|
25
|
+
You **MUST** use specialized tools instead of bash for ALL file operations:
|
|
26
|
+
|
|
27
|
+
|Instead of (WRONG)|Use (CORRECT)|
|
|
28
|
+
|---|---|
|
|
29
|
+
|`cat file`, `head -n N file`|`read(path="file", limit=N)`|
|
|
30
|
+
|`cat -n file \|sed -n '50,150p'`|`read(path="file", offset=50, limit=100)`|
|
|
31
|
+
|`grep -A 20 'pat' file`|`grep(pattern="pat", path="file", post=20)`|
|
|
32
|
+
|`grep -rn 'pat' dir/`|`grep(pattern="pat", path="dir/")`|
|
|
33
|
+
|`rg 'pattern' dir/`|`grep(pattern="pattern", path="dir/")`|
|
|
34
|
+
|`find dir -name '*.ts'`|`find(pattern="dir/**/*.ts")`|
|
|
35
|
+
|`ls dir/`|`read(path="dir/")`|
|
|
36
|
+
|`cat <<'EOF' > file`|`write(path="file", content="...")`|
|
|
37
|
+
|`sed -i 's/old/new/' file`|`edit(path="file", edits=[...])`|
|
|
25
38
|
- You **MUST NOT** use Bash for these operations like read, grep, find, edit, write, where specialized tools exist.
|
|
26
|
-
- You **MUST NOT** use `2>&1` pattern, stdout and stderr are already merged.
|
|
39
|
+
- You **MUST NOT** use `2>&1` | `2>/dev/null` pattern, stdout and stderr are already merged.
|
|
27
40
|
- You **MUST NOT** use `| head -n 50` or `| tail -n 100` pattern, use `head` and `tail` parameters instead.
|
|
28
41
|
</critical>
|
|
@@ -18,4 +18,11 @@ Reads files from local filesystem or internal URLs.
|
|
|
18
18
|
<output>
|
|
19
19
|
- Returns file content as text; images return visual content; PDFs return extracted text
|
|
20
20
|
- Missing files: returns closest filename matches for correction
|
|
21
|
-
</output>
|
|
21
|
+
</output>
|
|
22
|
+
|
|
23
|
+
<critical>
|
|
24
|
+
- You **MUST** use `read` instead of bash for ALL file reading: `cat`, `head`, `tail`, `less`, `more` are FORBIDDEN.
|
|
25
|
+
- You **MUST** use `read(path="dir/")` instead of `ls dir/` for directory listings.
|
|
26
|
+
- You **MUST** always include the `path` parameter — NEVER call `read` with empty arguments `{}`.
|
|
27
|
+
- When reading specific line ranges, use `offset` and `limit`: `read(path="file", offset=50, limit=100)` not `cat -n file | sed`.
|
|
28
|
+
</critical>
|
|
@@ -92,12 +92,12 @@ function buildCommonArgs(host: SSHConnectionTarget): string[] {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
async function runSshSync(args: string[]): Promise<{ exitCode: number | null; stderr: string }> {
|
|
95
|
-
const result = await $`ssh ${args}`.nothrow();
|
|
95
|
+
const result = await $`ssh ${args}`.quiet().nothrow();
|
|
96
96
|
return { exitCode: result.exitCode, stderr: result.stderr.toString().trim() };
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
async function runSshCaptureSync(args: string[]): Promise<{ exitCode: number | null; stdout: string; stderr: string }> {
|
|
100
|
-
const result = await $`ssh ${args}`.nothrow();
|
|
100
|
+
const result = await $`ssh ${args}`.quiet().nothrow();
|
|
101
101
|
return {
|
|
102
102
|
exitCode: result.exitCode,
|
|
103
103
|
stdout: result.stdout.toString().trim(),
|
package/src/ssh/ssh-executor.ts
CHANGED