mirror of
https://github.com/samsonjs/Peekaboo.git
synced 2026-04-27 15:07:41 +00:00
fix: Trim whitespace from app_target parameter
- Add .trim() to app_target when passing to Swift CLI - Handles cases like " Spotify " correctly matching "Spotify" - Applies to all app name formats including window specifiers 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
979ae84f6b
commit
0301df2608
2 changed files with 91 additions and 4 deletions
|
|
@ -96,7 +96,7 @@ export function buildSwiftCliArgs(
|
||||||
const specifierType = parts[1];
|
const specifierType = parts[1];
|
||||||
const specifierValue = parts.slice(2).join(":"); // Handle colons in window titles
|
const specifierValue = parts.slice(2).join(":"); // Handle colons in window titles
|
||||||
|
|
||||||
args.push("--app", appName);
|
args.push("--app", appName.trim());
|
||||||
args.push("--mode", "window");
|
args.push("--mode", "window");
|
||||||
|
|
||||||
if (specifierType === "WINDOW_TITLE") {
|
if (specifierType === "WINDOW_TITLE") {
|
||||||
|
|
@ -115,12 +115,12 @@ export function buildSwiftCliArgs(
|
||||||
{ app_target: input.app_target },
|
{ app_target: input.app_target },
|
||||||
"Malformed window specifier, treating as app name",
|
"Malformed window specifier, treating as app name",
|
||||||
);
|
);
|
||||||
args.push("--app", input.app_target);
|
args.push("--app", input.app_target.trim());
|
||||||
args.push("--mode", "multi");
|
args.push("--mode", "multi");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 'AppName': All windows of that app
|
// 'AppName': All windows of that app
|
||||||
args.push("--app", input.app_target);
|
args.push("--app", input.app_target.trim());
|
||||||
args.push("--mode", "multi");
|
args.push("--mode", "multi");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -317,6 +317,64 @@ describe("Image Tool", () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should handle case-insensitive format values", async () => {
|
||||||
|
// Import schema to test preprocessing
|
||||||
|
const { imageToolSchema } = await import("../../../src/types/index.js");
|
||||||
|
|
||||||
|
// Mock resolveImagePath for minimal case
|
||||||
|
mockResolveImagePath.mockResolvedValue({
|
||||||
|
effectivePath: "/tmp/test.png",
|
||||||
|
tempDirUsed: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockResponse = mockSwiftCli.captureImage("screen", {
|
||||||
|
path: "/tmp/test.png",
|
||||||
|
format: "png",
|
||||||
|
});
|
||||||
|
mockExecuteSwiftCli.mockResolvedValue(mockResponse);
|
||||||
|
|
||||||
|
// Test uppercase PNG - parse through schema first
|
||||||
|
const parsedInput = imageToolSchema.parse({ format: "PNG", path: "/tmp/test.png" });
|
||||||
|
await imageToolHandler(
|
||||||
|
parsedInput,
|
||||||
|
mockContext,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(mockExecuteSwiftCli).toHaveBeenCalledWith(
|
||||||
|
expect.arrayContaining(["--format", "png"]),
|
||||||
|
mockLogger,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle jpeg alias for jpg format", async () => {
|
||||||
|
// Import schema to test preprocessing
|
||||||
|
const { imageToolSchema } = await import("../../../src/types/index.js");
|
||||||
|
|
||||||
|
// Mock resolveImagePath for minimal case
|
||||||
|
mockResolveImagePath.mockResolvedValue({
|
||||||
|
effectivePath: "/tmp/test.jpg",
|
||||||
|
tempDirUsed: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockResponse = mockSwiftCli.captureImage("screen", {
|
||||||
|
path: "/tmp/test.jpg",
|
||||||
|
format: "jpg",
|
||||||
|
});
|
||||||
|
mockExecuteSwiftCli.mockResolvedValue(mockResponse);
|
||||||
|
|
||||||
|
// Test jpeg alias - parse through schema first
|
||||||
|
const parsedInput = imageToolSchema.parse({ format: "jpeg", path: "/tmp/test.jpg" });
|
||||||
|
await imageToolHandler(
|
||||||
|
parsedInput,
|
||||||
|
mockContext,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(mockExecuteSwiftCli).toHaveBeenCalledWith(
|
||||||
|
expect.arrayContaining(["--format", "jpg"]),
|
||||||
|
mockLogger,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle app_target: 'frontmost' with warning", async () => {
|
it("should handle app_target: 'frontmost' with warning", async () => {
|
||||||
// Mock resolveImagePath for minimal case
|
// Mock resolveImagePath for minimal case
|
||||||
mockResolveImagePath.mockResolvedValue({
|
mockResolveImagePath.mockResolvedValue({
|
||||||
|
|
@ -1116,6 +1174,9 @@ describe("Image Tool", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fall back to PNG when format is an invalid value", async () => {
|
it("should fall back to PNG when format is an invalid value", async () => {
|
||||||
|
// Import schema to test preprocessing
|
||||||
|
const { imageToolSchema } = await import("../../../src/types/index.js");
|
||||||
|
|
||||||
// Mock resolveImagePath
|
// Mock resolveImagePath
|
||||||
mockResolveImagePath.mockResolvedValue({
|
mockResolveImagePath.mockResolvedValue({
|
||||||
effectivePath: MOCK_TEMP_IMAGE_DIR,
|
effectivePath: MOCK_TEMP_IMAGE_DIR,
|
||||||
|
|
@ -1129,8 +1190,9 @@ describe("Image Tool", () => {
|
||||||
mockExecuteSwiftCli.mockResolvedValue(mockResponse);
|
mockExecuteSwiftCli.mockResolvedValue(mockResponse);
|
||||||
|
|
||||||
// Test with invalid format - schema should preprocess to 'png'
|
// Test with invalid format - schema should preprocess to 'png'
|
||||||
|
const parsedInput = imageToolSchema.parse({ format: "invalid" });
|
||||||
const result = await imageToolHandler(
|
const result = await imageToolHandler(
|
||||||
{ format: "invalid" as any },
|
parsedInput,
|
||||||
mockContext,
|
mockContext,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1200,4 +1262,29 @@ describe("Image Tool", () => {
|
||||||
expect(result.content[0].text).toBe("Image capture failed: Application not found");
|
expect(result.content[0].text).toBe("Image capture failed: Application not found");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("imageToolHandler - Whitespace trimming", () => {
|
||||||
|
it("should trim leading and trailing whitespace from app_target", async () => {
|
||||||
|
mockResolveImagePath.mockResolvedValue({
|
||||||
|
effectivePath: MOCK_TEMP_IMAGE_DIR,
|
||||||
|
tempDirUsed: MOCK_TEMP_IMAGE_DIR,
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockResponse = mockSwiftCli.captureImage("Spotify", {
|
||||||
|
path: MOCK_SAVED_FILE_PATH,
|
||||||
|
format: "png",
|
||||||
|
});
|
||||||
|
mockExecuteSwiftCli.mockResolvedValue(mockResponse);
|
||||||
|
|
||||||
|
await imageToolHandler(
|
||||||
|
{ app_target: " Spotify " },
|
||||||
|
mockContext,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check that the Swift CLI was called with trimmed app name
|
||||||
|
const callArgs = mockExecuteSwiftCli.mock.calls[0][0];
|
||||||
|
const appIndex = callArgs.indexOf("--app");
|
||||||
|
expect(callArgs[appIndex + 1]).toBe("Spotify"); // Should be trimmed
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Loading…
Reference in a new issue