mirror of
https://github.com/samsonjs/Peekaboo.git
synced 2026-03-25 09:25:47 +00:00
feat: Enhanced error messages for ambiguous app identifiers
- Error messages now include the list of matching applications when multiple apps match an identifier
- Shows bundle IDs alongside app names to help users disambiguate (e.g., Calendar (com.apple.iCal))
- Applies to both image and list tools for consistent user experience
- Added comprehensive tests for error detail handling
This makes it much easier for users to understand which specific application to target when there are multiple matches.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
dbb68e4294
commit
2676decf51
5 changed files with 105 additions and 3 deletions
|
|
@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Invalid format values now automatically fall back to PNG instead of returning an error
|
||||
- Empty strings, null values, and unrecognized format values are converted to PNG
|
||||
- This provides a better user experience by gracefully handling invalid inputs
|
||||
- Enhanced error messages for ambiguous application identifiers
|
||||
- When multiple applications match an identifier (e.g., "C" matches Calendar, Console, and Cursor), the error message now lists all matching applications with their bundle IDs
|
||||
- This helps users quickly identify the correct application name to use
|
||||
- Applies to both `image` and `list` tools
|
||||
|
||||
## [1.0.0-beta.18] - 2025-06-08
|
||||
|
||||
|
|
|
|||
|
|
@ -63,11 +63,17 @@ export async function imageToolHandler(
|
|||
{ error: swiftResponse.error },
|
||||
"Swift CLI returned error for image capture",
|
||||
);
|
||||
const errorMessage = swiftResponse.error?.message || "Unknown error";
|
||||
const errorDetails = swiftResponse.error?.details;
|
||||
const fullErrorMessage = errorDetails
|
||||
? `${errorMessage}\n${errorDetails}`
|
||||
: errorMessage;
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `Image capture failed: ${swiftResponse.error?.message || "Unknown error"}`,
|
||||
text: `Image capture failed: ${fullErrorMessage}`,
|
||||
},
|
||||
],
|
||||
isError: true,
|
||||
|
|
|
|||
|
|
@ -119,11 +119,17 @@ export async function listToolHandler(
|
|||
|
||||
if (!swiftResponse.success) {
|
||||
logger.error({ error: swiftResponse.error }, "Swift CLI returned error");
|
||||
const errorMessage = swiftResponse.error?.message || "Unknown error";
|
||||
const errorDetails = swiftResponse.error?.details;
|
||||
const fullErrorMessage = errorDetails
|
||||
? `${errorMessage}\n${errorDetails}`
|
||||
: errorMessage;
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text" as const,
|
||||
text: `List operation failed: ${swiftResponse.error?.message || "Unknown error"}`,
|
||||
text: `List operation failed: ${fullErrorMessage}`,
|
||||
},
|
||||
],
|
||||
isError: true,
|
||||
|
|
|
|||
|
|
@ -1142,4 +1142,62 @@ describe("Image Tool", () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("imageToolHandler - Error message handling", () => {
|
||||
it("should include error details for ambiguous app identifier", async () => {
|
||||
// Mock resolveImagePath
|
||||
mockResolveImagePath.mockResolvedValue({
|
||||
effectivePath: MOCK_TEMP_IMAGE_DIR,
|
||||
tempDirUsed: MOCK_TEMP_IMAGE_DIR,
|
||||
});
|
||||
|
||||
// Mock Swift CLI returning ambiguous app error with details
|
||||
mockExecuteSwiftCli.mockResolvedValue({
|
||||
success: false,
|
||||
error: {
|
||||
message: "Multiple applications match identifier 'C'. Please be more specific.",
|
||||
code: "AMBIGUOUS_APP_IDENTIFIER",
|
||||
details: "Matches found: Calendar (com.apple.iCal), Console (com.apple.Console), Cursor (com.todesktop.230313mzl4w4u92)"
|
||||
}
|
||||
});
|
||||
|
||||
const result = await imageToolHandler(
|
||||
{ app_target: "C" },
|
||||
mockContext,
|
||||
);
|
||||
|
||||
expect(result.isError).toBe(true);
|
||||
expect(result.content[0].type).toBe("text");
|
||||
// Should include both the main message and the details
|
||||
expect(result.content[0].text).toContain("Multiple applications match identifier 'C'");
|
||||
expect(result.content[0].text).toContain("Matches found: Calendar (com.apple.iCal), Console (com.apple.Console), Cursor (com.todesktop.230313mzl4w4u92)");
|
||||
});
|
||||
|
||||
it("should handle errors without details gracefully", async () => {
|
||||
// Mock resolveImagePath
|
||||
mockResolveImagePath.mockResolvedValue({
|
||||
effectivePath: MOCK_TEMP_IMAGE_DIR,
|
||||
tempDirUsed: MOCK_TEMP_IMAGE_DIR,
|
||||
});
|
||||
|
||||
// Mock Swift CLI returning error without details
|
||||
mockExecuteSwiftCli.mockResolvedValue({
|
||||
success: false,
|
||||
error: {
|
||||
message: "Application not found",
|
||||
code: "APP_NOT_FOUND"
|
||||
}
|
||||
});
|
||||
|
||||
const result = await imageToolHandler(
|
||||
{ app_target: "NonExistent" },
|
||||
mockContext,
|
||||
);
|
||||
|
||||
expect(result.isError).toBe(true);
|
||||
expect(result.content[0].type).toBe("text");
|
||||
// Should only include the main message
|
||||
expect(result.content[0].text).toBe("Image capture failed: Application not found");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -288,7 +288,7 @@ describe("List Tool", () => {
|
|||
// Assert
|
||||
expect(result.isError).toBe(true);
|
||||
expect(result.content[0].text).toBe(
|
||||
"List operation failed: The specified application ('Ciursor') is not running or could not be found."
|
||||
"List operation failed: The specified application ('Ciursor') is not running or could not be found.\nError: Application with name 'Ciursor' not found."
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -865,4 +865,32 @@ describe("List Tool", () => {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("listToolHandler - Error message handling", () => {
|
||||
it("should include error details for ambiguous app identifier", async () => {
|
||||
// Mock Swift CLI returning ambiguous app error with details
|
||||
mockExecuteSwiftCli.mockResolvedValue({
|
||||
success: false,
|
||||
error: {
|
||||
message: "Multiple applications match identifier 'C'. Please be more specific.",
|
||||
code: "AMBIGUOUS_APP_IDENTIFIER",
|
||||
details: "Matches found: Calendar (com.apple.iCal), Console (com.apple.Console), Cursor (com.todesktop.230313mzl4w4u92)"
|
||||
}
|
||||
});
|
||||
|
||||
const result = await listToolHandler(
|
||||
{
|
||||
item_type: "application_windows",
|
||||
app: "C"
|
||||
},
|
||||
mockContext,
|
||||
);
|
||||
|
||||
expect(result.isError).toBe(true);
|
||||
expect(result.content[0].type).toBe("text");
|
||||
// Should include both the main message and the details
|
||||
expect(result.content[0].text).toContain("Multiple applications match identifier 'C'");
|
||||
expect(result.content[0].text).toContain("Matches found: Calendar (com.apple.iCal), Console (com.apple.Console), Cursor (com.todesktop.230313mzl4w4u92)");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue