@pi-archimedes/image-paste 2.3.0 → 2.5.0
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/package.json +3 -3
- package/src/default-export.test.ts +41 -0
- package/src/index.ts +16 -0
- package/src/preview.ts +1 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-archimedes/image-paste",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package"
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"@earendil-works/pi-tui": ">=0.1.0"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@earendil-works/pi-coding-agent": "^0.84.
|
|
19
|
-
"@earendil-works/pi-tui": "^0.84.
|
|
18
|
+
"@earendil-works/pi-coding-agent": "^0.84.4",
|
|
19
|
+
"@earendil-works/pi-tui": "^0.84.4",
|
|
20
20
|
"typescript": "^6.0.0"
|
|
21
21
|
},
|
|
22
22
|
"pi": {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import defaultExport from "./index.js";
|
|
3
|
+
|
|
4
|
+
describe("image-paste default export (standalone factory)", () => {
|
|
5
|
+
it("is a function that registers paste + per-session lifecycle on the pi extension", () => {
|
|
6
|
+
expect(typeof defaultExport).toBe("function");
|
|
7
|
+
|
|
8
|
+
const on = vi.fn();
|
|
9
|
+
const registerShortcut = vi.fn();
|
|
10
|
+
const registerMessageRenderer = vi.fn();
|
|
11
|
+
|
|
12
|
+
const pi = { on, registerShortcut, registerMessageRenderer } as any;
|
|
13
|
+
|
|
14
|
+
defaultExport(pi);
|
|
15
|
+
|
|
16
|
+
// registerImagePaste wires the preview renderer + shortcuts
|
|
17
|
+
expect(registerMessageRenderer).toHaveBeenCalled();
|
|
18
|
+
expect(registerShortcut).toHaveBeenCalled();
|
|
19
|
+
|
|
20
|
+
// input handler (from registerImagePaste) + session lifecycle handlers
|
|
21
|
+
const events = on.mock.calls.map((c: Array<unknown>) => c[0]);
|
|
22
|
+
expect(events).toEqual(
|
|
23
|
+
expect.arrayContaining(["input", "session_start", "session_shutdown"]),
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("resets the per-session queue on session_start and clears it on shutdown", () => {
|
|
28
|
+
const on = vi.fn();
|
|
29
|
+
const pi = { on, registerShortcut: vi.fn(), registerMessageRenderer: vi.fn() } as any;
|
|
30
|
+
defaultExport(pi);
|
|
31
|
+
|
|
32
|
+
const startHandler = on.mock.calls.find((c: Array<unknown>) => c[0] === "session_start")?.[1];
|
|
33
|
+
const shutdownHandler = on.mock.calls.find((c: Array<unknown>) => c[0] === "session_shutdown")?.[1];
|
|
34
|
+
expect(typeof startHandler).toBe("function");
|
|
35
|
+
expect(typeof shutdownHandler).toBe("function");
|
|
36
|
+
|
|
37
|
+
// Must not throw when wired to a session context
|
|
38
|
+
expect(() => (startHandler as (...a: unknown[]) => unknown)({}, { hasUI: true })).not.toThrow();
|
|
39
|
+
expect(() => (shutdownHandler as (...a: unknown[]) => unknown)({}, {})).not.toThrow();
|
|
40
|
+
});
|
|
41
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -188,3 +188,19 @@ export function shutdownImagePaste(): void {
|
|
|
188
188
|
_queue = null;
|
|
189
189
|
_pasting = false;
|
|
190
190
|
}
|
|
191
|
+
|
|
192
|
+
// ── Default export (for standalone pi.extensions loading) ─────────────────
|
|
193
|
+
|
|
194
|
+
// Pi's standalone loader requires a default export functioning as the
|
|
195
|
+
// extension factory. Meta imports the named exports directly (register
|
|
196
|
+
// + session lifecycle), so this default export is standalone-only.
|
|
197
|
+
export default function (pi: ExtensionAPI): void {
|
|
198
|
+
registerImagePaste(pi);
|
|
199
|
+
// Session lifecycle: pi requires per-session ctx for image pasting.
|
|
200
|
+
pi.on("session_start", (_event, ctx) => {
|
|
201
|
+
initImagePasteSession(ctx);
|
|
202
|
+
});
|
|
203
|
+
pi.on("session_shutdown", (_event, _ctx) => {
|
|
204
|
+
shutdownImagePaste();
|
|
205
|
+
});
|
|
206
|
+
}
|
package/src/preview.ts
CHANGED
|
@@ -12,10 +12,6 @@ interface PreviewDetails {
|
|
|
12
12
|
export function registerImagePreview(pi: ExtensionAPI): void {
|
|
13
13
|
pi.registerMessageRenderer<PreviewDetails>(CUSTOM_TYPE, (message, _options, theme) => {
|
|
14
14
|
try {
|
|
15
|
-
// Theme.fg is runtime-available but not exposed in the Theme type definition
|
|
16
|
-
const fg = (theme as any).fg?.bind(theme) as ((color: string, text: string) => string) | undefined;
|
|
17
|
-
if (!fg) return undefined;
|
|
18
|
-
|
|
19
15
|
// Extract image data from content array
|
|
20
16
|
const content = message.content;
|
|
21
17
|
if (!Array.isArray(content) || content.length === 0) return undefined;
|
|
@@ -28,7 +24,7 @@ export function registerImagePreview(pi: ExtensionAPI): void {
|
|
|
28
24
|
container.addChild(new Spacer(1));
|
|
29
25
|
container.addChild(
|
|
30
26
|
new Image(item.data, item.mimeType, {
|
|
31
|
-
fallbackColor: (text: string) => fg("toolOutput", text),
|
|
27
|
+
fallbackColor: (text: string) => theme.fg("toolOutput", text),
|
|
32
28
|
}, {
|
|
33
29
|
maxWidthCells: 60,
|
|
34
30
|
}),
|