@tmustier/pi-files-widget 0.2.0 → 0.2.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 +6 -0
- package/file-viewer.ts +4 -1
- package/index.ts +2 -5
- package/package.json +3 -3
- package/utils.ts +37 -9
- package/viewer.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this extension will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.2.1] - 2026-09-22
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- Reduce Pi startup work by checking required commands directly on `PATH` instead of spawning `which`/`where`, and load the file-browser implementation only when `/readfiles` is invoked.
|
|
9
|
+
- Update session lifecycle, key handling, notifications, and file viewer results for Pi 0.87.
|
|
10
|
+
|
|
5
11
|
## [0.2.0] - 2026-07-04
|
|
6
12
|
|
|
7
13
|
### Added
|
package/file-viewer.ts
CHANGED
|
@@ -171,7 +171,10 @@ export function loadFileContent(
|
|
|
171
171
|
try {
|
|
172
172
|
try {
|
|
173
173
|
if (statSync(filePath).isDirectory()) {
|
|
174
|
-
return
|
|
174
|
+
return {
|
|
175
|
+
lines: ["Directory selected - expand it in the file tree instead of opening it."],
|
|
176
|
+
renderedMarkdown: false,
|
|
177
|
+
};
|
|
175
178
|
}
|
|
176
179
|
} catch {
|
|
177
180
|
// Ignore stat errors and fall through to normal handling
|
package/index.ts
CHANGED
|
@@ -10,7 +10,6 @@ import { statSync } from "node:fs";
|
|
|
10
10
|
import { homedir } from "node:os";
|
|
11
11
|
import { isAbsolute, join, resolve } from "node:path";
|
|
12
12
|
|
|
13
|
-
import { createFileBrowser } from "./browser";
|
|
14
13
|
import { POLL_INTERVAL_MS } from "./constants";
|
|
15
14
|
import { formatCommentMessage } from "./comment";
|
|
16
15
|
import { hasCommand } from "./utils";
|
|
@@ -57,6 +56,7 @@ export default function editorExtension(pi: ExtensionAPI): void {
|
|
|
57
56
|
return;
|
|
58
57
|
}
|
|
59
58
|
const initialPath = resolved.path;
|
|
59
|
+
const { createFileBrowser } = await import("./browser");
|
|
60
60
|
|
|
61
61
|
await ctx.ui.custom<void>((tui, theme, _kb, done) => {
|
|
62
62
|
let pollInterval: ReturnType<typeof setInterval> | null = null;
|
|
@@ -73,7 +73,7 @@ export default function editorExtension(pi: ExtensionAPI): void {
|
|
|
73
73
|
const message = formatCommentMessage(payload, comment);
|
|
74
74
|
if (ctx.isIdle()) {
|
|
75
75
|
pi.sendUserMessage(message);
|
|
76
|
-
ctx.ui.notify(`Comment sent to agent for ${payload.relPath} (${payload.lineRange})`, "
|
|
76
|
+
ctx.ui.notify(`Comment sent to agent for ${payload.relPath} (${payload.lineRange})`, "info");
|
|
77
77
|
} else {
|
|
78
78
|
pi.sendUserMessage(message, { deliverAs: "followUp" });
|
|
79
79
|
ctx.ui.notify(`Comment queued for agent for ${payload.relPath} (${payload.lineRange})`, "info");
|
|
@@ -125,7 +125,4 @@ export default function editorExtension(pi: ExtensionAPI): void {
|
|
|
125
125
|
agentModifiedFiles.clear();
|
|
126
126
|
});
|
|
127
127
|
|
|
128
|
-
pi.on("session_switch", async () => {
|
|
129
|
-
agentModifiedFiles.clear();
|
|
130
|
-
});
|
|
131
128
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tmustier/pi-files-widget",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "In-terminal file browser and viewer for Pi.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Thomas Mustier",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"video": "https://raw.githubusercontent.com/tmustier/pi-extensions/main/files-widget/demo.mp4"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@earendil-works/pi-coding-agent": "
|
|
32
|
-
"@earendil-works/pi-tui": "
|
|
31
|
+
"@earendil-works/pi-coding-agent": "0.87.0",
|
|
32
|
+
"@earendil-works/pi-tui": "0.87.0"
|
|
33
33
|
}
|
|
34
34
|
}
|
package/utils.ts
CHANGED
|
@@ -1,13 +1,41 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { accessSync, constants, statSync } from "node:fs";
|
|
2
|
+
import { extname, join } from "node:path";
|
|
3
|
+
|
|
4
|
+
export interface CommandLookupOptions {
|
|
5
|
+
platform?: NodeJS.Platform;
|
|
6
|
+
path?: string;
|
|
7
|
+
pathExt?: string;
|
|
8
|
+
cwd?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function hasCommand(cmd: string, options: CommandLookupOptions = {}): boolean {
|
|
12
|
+
const platform = options.platform ?? process.platform;
|
|
13
|
+
const pathValue = options.path ?? process.env.PATH ?? "";
|
|
14
|
+
const pathEntries = pathValue.split(platform === "win32" ? ";" : ":");
|
|
15
|
+
const searchDirectories = platform === "win32"
|
|
16
|
+
? [options.cwd ?? process.cwd(), ...pathEntries]
|
|
17
|
+
: pathEntries;
|
|
18
|
+
const extensions = platform === "win32" && !extname(cmd)
|
|
19
|
+
? (options.pathExt ?? process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean)
|
|
20
|
+
: [""];
|
|
21
|
+
const accessMode = platform === "win32" ? constants.F_OK : constants.X_OK;
|
|
22
|
+
|
|
23
|
+
for (const rawDirectory of searchDirectories) {
|
|
24
|
+
const directory = platform === "win32" && rawDirectory.startsWith('"') && rawDirectory.endsWith('"')
|
|
25
|
+
? rawDirectory.slice(1, -1)
|
|
26
|
+
: rawDirectory;
|
|
27
|
+
for (const extension of extensions) {
|
|
28
|
+
try {
|
|
29
|
+
const candidate = join(directory || ".", `${cmd}${extension}`);
|
|
30
|
+
accessSync(candidate, accessMode);
|
|
31
|
+
if (statSync(candidate).isFile()) return true;
|
|
32
|
+
} catch {
|
|
33
|
+
// Continue searching PATH.
|
|
34
|
+
}
|
|
35
|
+
}
|
|
10
36
|
}
|
|
37
|
+
|
|
38
|
+
return false;
|
|
11
39
|
}
|
|
12
40
|
|
|
13
41
|
export function isUntrackedStatus(status?: string): boolean {
|
package/viewer.ts
CHANGED
|
@@ -501,7 +501,7 @@ export function createViewer(
|
|
|
501
501
|
jumpToNextMatch(1);
|
|
502
502
|
return { type: "none" };
|
|
503
503
|
}
|
|
504
|
-
if (matchesKey(data, "
|
|
504
|
+
if (matchesKey(data, "shift+n") && state.mode !== "select" && state.searchMatches.length > 0) {
|
|
505
505
|
jumpToNextMatch(-1);
|
|
506
506
|
return { type: "none" };
|
|
507
507
|
}
|
|
@@ -553,7 +553,7 @@ export function createViewer(
|
|
|
553
553
|
state.scroll = 0;
|
|
554
554
|
return { type: "none" };
|
|
555
555
|
}
|
|
556
|
-
if (matchesKey(data, "m") && state.mode !== "select"
|
|
556
|
+
if (matchesKey(data, "m") && state.mode !== "select") {
|
|
557
557
|
toggleMarkdownMode();
|
|
558
558
|
return { type: "none" };
|
|
559
559
|
}
|