@oh-my-pi/pi-coding-agent 5.1.0 → 5.1.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/package.json +5 -5
- package/src/utils/clipboard.ts +46 -33
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.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": "5.1.
|
|
43
|
-
"@oh-my-pi/pi-ai": "5.1.
|
|
44
|
-
"@oh-my-pi/pi-git-tool": "5.1.
|
|
45
|
-
"@oh-my-pi/pi-tui": "5.1.
|
|
42
|
+
"@oh-my-pi/pi-agent-core": "5.1.1",
|
|
43
|
+
"@oh-my-pi/pi-ai": "5.1.1",
|
|
44
|
+
"@oh-my-pi/pi-git-tool": "5.1.1",
|
|
45
|
+
"@oh-my-pi/pi-tui": "5.1.1",
|
|
46
46
|
"@openai/agents": "^0.3.7",
|
|
47
47
|
"@silvia-odwyer/photon-node": "^0.3.4",
|
|
48
48
|
"@sinclair/typebox": "^0.34.46",
|
package/src/utils/clipboard.ts
CHANGED
|
@@ -151,19 +151,29 @@ export async function readImageFromClipboard(): Promise<ClipboardImage | null> {
|
|
|
151
151
|
return null;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
type ClipboardReadResult =
|
|
155
|
+
| { status: "found"; image: ClipboardImage }
|
|
156
|
+
| { status: "empty" } // Tools ran successfully, no image in clipboard
|
|
157
|
+
| { status: "unavailable" }; // Tools not found or failed to run
|
|
158
|
+
|
|
154
159
|
async function readImageLinux(timeout: number): Promise<ClipboardImage | null> {
|
|
155
160
|
const wayland = isWaylandSession();
|
|
156
161
|
if (wayland) {
|
|
157
|
-
const
|
|
158
|
-
if (
|
|
162
|
+
const result = await readImageWayland(timeout);
|
|
163
|
+
if (result.status === "found") return result.image;
|
|
164
|
+
if (result.status === "empty") return null; // Don't fall back to X11 if Wayland worked
|
|
159
165
|
}
|
|
160
166
|
|
|
161
|
-
|
|
167
|
+
const result = await readImageX11(timeout);
|
|
168
|
+
return result.status === "found" ? result.image : null;
|
|
162
169
|
}
|
|
163
170
|
|
|
164
|
-
async function readImageWayland(timeout: number): Promise<
|
|
165
|
-
const
|
|
166
|
-
if (!
|
|
171
|
+
async function readImageWayland(timeout: number): Promise<ClipboardReadResult> {
|
|
172
|
+
const wlPastePath = Bun.which("wl-paste");
|
|
173
|
+
if (!wlPastePath) return { status: "unavailable" };
|
|
174
|
+
|
|
175
|
+
const types = await spawnAndRead([wlPastePath, "--list-types"], timeout);
|
|
176
|
+
if (!types) return { status: "unavailable" }; // Command failed
|
|
167
177
|
|
|
168
178
|
const typeList = types
|
|
169
179
|
.toString("utf-8")
|
|
@@ -172,43 +182,46 @@ async function readImageWayland(timeout: number): Promise<ClipboardImage | null>
|
|
|
172
182
|
.filter(Boolean);
|
|
173
183
|
|
|
174
184
|
const selectedType = selectPreferredImageMimeType(typeList);
|
|
175
|
-
if (!selectedType) return
|
|
185
|
+
if (!selectedType) return { status: "empty" }; // No image types available
|
|
176
186
|
|
|
177
|
-
const imageData = await spawnAndRead([
|
|
178
|
-
if (!imageData || imageData.length === 0) return
|
|
187
|
+
const imageData = await spawnAndRead([wlPastePath, "--type", selectedType, "--no-newline"], timeout);
|
|
188
|
+
if (!imageData || imageData.length === 0) return { status: "empty" };
|
|
179
189
|
|
|
180
190
|
return {
|
|
181
|
-
|
|
182
|
-
|
|
191
|
+
status: "found",
|
|
192
|
+
image: {
|
|
193
|
+
data: imageData.toString("base64"),
|
|
194
|
+
mimeType: baseMimeType(selectedType),
|
|
195
|
+
},
|
|
183
196
|
};
|
|
184
197
|
}
|
|
185
198
|
|
|
186
|
-
async function readImageX11(timeout: number): Promise<
|
|
187
|
-
const
|
|
199
|
+
async function readImageX11(timeout: number): Promise<ClipboardReadResult> {
|
|
200
|
+
const xclipPath = Bun.which("xclip");
|
|
201
|
+
if (!xclipPath) return { status: "unavailable" };
|
|
188
202
|
|
|
189
|
-
|
|
190
|
-
if (targets) {
|
|
191
|
-
candidateTypes = targets
|
|
192
|
-
.toString("utf-8")
|
|
193
|
-
.split(/\r?\n/)
|
|
194
|
-
.map((t) => t.trim())
|
|
195
|
-
.filter(Boolean);
|
|
196
|
-
}
|
|
203
|
+
const targets = await spawnAndRead([xclipPath, "-selection", "clipboard", "-t", "TARGETS", "-o"], timeout);
|
|
204
|
+
if (!targets) return { status: "unavailable" }; // xclip failed (no X server?)
|
|
197
205
|
|
|
198
|
-
const
|
|
199
|
-
|
|
206
|
+
const candidateTypes = targets
|
|
207
|
+
.toString("utf-8")
|
|
208
|
+
.split(/\r?\n/)
|
|
209
|
+
.map((t) => t.trim())
|
|
210
|
+
.filter(Boolean);
|
|
200
211
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if (imageData && imageData.length > 0) {
|
|
204
|
-
return {
|
|
205
|
-
data: imageData.toString("base64"),
|
|
206
|
-
mimeType: baseMimeType(mimeType),
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
}
|
|
212
|
+
const selectedType = selectPreferredImageMimeType(candidateTypes);
|
|
213
|
+
if (!selectedType) return { status: "empty" }; // Clipboard has no image types
|
|
210
214
|
|
|
211
|
-
|
|
215
|
+
const imageData = await spawnAndRead([xclipPath, "-selection", "clipboard", "-t", selectedType, "-o"], timeout);
|
|
216
|
+
if (!imageData || imageData.length === 0) return { status: "empty" };
|
|
217
|
+
|
|
218
|
+
return {
|
|
219
|
+
status: "found",
|
|
220
|
+
image: {
|
|
221
|
+
data: imageData.toString("base64"),
|
|
222
|
+
mimeType: baseMimeType(selectedType),
|
|
223
|
+
},
|
|
224
|
+
};
|
|
212
225
|
}
|
|
213
226
|
|
|
214
227
|
async function readImageMacOS(timeout: number): Promise<ClipboardImage | null> {
|