Fix TypeScript compilation errors

- Added missing imports for ToolResponse and z in index.ts
- Added missing imports for WindowInfo and TargetApplicationInfo in list.ts
- Fixed type casting for ImageCaptureData in image.ts
- Added proper return type annotations to handlers
- Fixed content array metadata type to Record<string, unknown>
- Added const assertions for all 'text' type literals
- Fixed return types for helper functions in list.ts
- Added minItems and maxItems to JSONSchema interface

All TypeScript compilation errors resolved

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Peter Steinberger 2025-05-27 01:10:35 +02:00
parent cbecd6181d
commit 4be8c69e77
5 changed files with 38 additions and 30 deletions

View file

@ -23,6 +23,8 @@ import {
import { generateServerStatusString } from "./utils/server-status.js"; import { generateServerStatusString } from "./utils/server-status.js";
import { initializeSwiftCliPath } from "./utils/peekaboo-cli.js"; import { initializeSwiftCliPath } from "./utils/peekaboo-cli.js";
import { zodToJsonSchema } from "./utils/zod-to-json-schema.js"; import { zodToJsonSchema } from "./utils/zod-to-json-schema.js";
import { ToolResponse } from "./types/index.js";
import { z } from "zod";
// Get package version and determine package root // Get package version and determine package root
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
@ -215,12 +217,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: `Invalid arguments: ${(error as z.ZodError).issues.map((issue) => issue.message).join(", ")}`, text: `Invalid arguments: ${(error as z.ZodError).issues.map((issue) => issue.message).join(", ")}`,
}, },
], ],
isError: true, isError: true,
}; } as ToolResponse;
} }
throw error; throw error;

View file

@ -1,6 +1,6 @@
import { z } from "zod"; import { z } from "zod";
import path from "path"; import path from "path";
import { ToolContext } from "../types/index.js"; import { ToolContext, ToolResponse } from "../types/index.js";
import { readImageAsBase64 } from "../utils/peekaboo-cli.js"; import { readImageAsBase64 } from "../utils/peekaboo-cli.js";
import { import {
parseAIProviders, parseAIProviders,
@ -43,7 +43,7 @@ export type AnalyzeToolInput = z.infer<typeof analyzeToolSchema>;
export async function analyzeToolHandler( export async function analyzeToolHandler(
input: AnalyzeToolInput, input: AnalyzeToolInput,
context: ToolContext, context: ToolContext,
) { ): Promise<ToolResponse> {
const { logger } = context; const { logger } = context;
try { try {
@ -58,7 +58,7 @@ export async function analyzeToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: `Unsupported image format: ${ext}. Supported formats: .png, .jpg, .jpeg, .webp`, text: `Unsupported image format: ${ext}. Supported formats: .png, .jpg, .jpeg, .webp`,
}, },
], ],
@ -73,7 +73,7 @@ export async function analyzeToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: "AI analysis not configured on this server. Set the PEEKABOO_AI_PROVIDERS environment variable.", text: "AI analysis not configured on this server. Set the PEEKABOO_AI_PROVIDERS environment variable.",
}, },
], ],
@ -87,7 +87,7 @@ export async function analyzeToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: "No valid AI providers found in PEEKABOO_AI_PROVIDERS configuration.", text: "No valid AI providers found in PEEKABOO_AI_PROVIDERS configuration.",
}, },
], ],
@ -106,7 +106,7 @@ export async function analyzeToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: "No configured AI providers are currently operational.", text: "No configured AI providers are currently operational.",
}, },
], ],
@ -126,7 +126,7 @@ export async function analyzeToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: `Failed to read image file: ${error instanceof Error ? error.message : "Unknown error"}`, text: `Failed to read image file: ${error instanceof Error ? error.message : "Unknown error"}`,
}, },
], ],
@ -150,7 +150,7 @@ export async function analyzeToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: `AI analysis failed: ${error instanceof Error ? error.message : "Unknown error"}`, text: `AI analysis failed: ${error instanceof Error ? error.message : "Unknown error"}`,
}, },
], ],
@ -170,11 +170,11 @@ export async function analyzeToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: analysisResult, text: analysisResult,
}, },
{ {
type: "text", type: "text" as const,
text: analysisTimeMessage, // Add the timing message text: analysisTimeMessage, // Add the timing message
}, },
], ],
@ -186,7 +186,7 @@ export async function analyzeToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: `Unexpected error: ${error instanceof Error ? error.message : "Unknown error"}`, text: `Unexpected error: ${error instanceof Error ? error.message : "Unknown error"}`,
}, },
], ],

View file

@ -73,10 +73,11 @@ export async function imageToolHandler(
}; };
} }
const imageData = swiftResponse.data as ImageCaptureData | undefined;
if ( if (
!swiftResponse.data || !imageData ||
!swiftResponse.data.saved_files || !imageData.saved_files ||
swiftResponse.data.saved_files.length === 0 imageData.saved_files.length === 0
) { ) {
logger.error( logger.error(
"Swift CLI reported success but no data/saved_files were returned.", "Swift CLI reported success but no data/saved_files were returned.",
@ -93,7 +94,7 @@ export async function imageToolHandler(
}; };
} }
const captureData = swiftResponse.data as ImageCaptureData; const captureData = imageData;
const imagePathForAnalysis = captureData.saved_files[0].path; const imagePathForAnalysis = captureData.saved_files[0].path;
// Determine which files to report as saved // Determine which files to report as saved
@ -150,7 +151,7 @@ export async function imageToolHandler(
} }
} }
const content: Array<{ type: "text" | "image"; text?: string; data?: string; mimeType?: string; metadata?: unknown }> = []; const content: Array<{ type: "text" | "image"; text?: string; data?: string; mimeType?: string; metadata?: Record<string, unknown> }> = [];
let summary = buildImageSummary(input, captureData, input.question); let summary = buildImageSummary(input, captureData, input.question);
if (analysisAttempted) { if (analysisAttempted) {
summary += `\nAnalysis ${analysisSucceeded ? "succeeded" : "failed/skipped"}.`; summary += `\nAnalysis ${analysisSucceeded ? "succeeded" : "failed/skipped"}.`;

View file

@ -4,7 +4,10 @@ import {
ApplicationListData, ApplicationListData,
WindowListData, WindowListData,
ApplicationInfo, ApplicationInfo,
WindowInfo,
TargetApplicationInfo,
SwiftCliResponse, SwiftCliResponse,
ToolResponse,
} from "../types/index.js"; } from "../types/index.js";
import { executeSwiftCli, execPeekaboo } from "../utils/peekaboo-cli.js"; import { executeSwiftCli, execPeekaboo } from "../utils/peekaboo-cli.js";
import { generateServerStatusString } from "../utils/server-status.js"; import { generateServerStatusString } from "../utils/server-status.js";
@ -83,7 +86,7 @@ export type ListToolInput = z.infer<typeof listToolSchema>;
export async function listToolHandler( export async function listToolHandler(
input: ListToolInput, input: ListToolInput,
context: ToolContext, context: ToolContext,
) { ): Promise<ToolResponse> {
const { logger } = context; const { logger } = context;
try { try {
@ -114,7 +117,7 @@ export async function listToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: `List operation failed: ${swiftResponse.error?.message || "Unknown error"}`, text: `List operation failed: ${swiftResponse.error?.message || "Unknown error"}`,
}, },
], ],
@ -131,7 +134,7 @@ export async function listToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: "List operation failed: Invalid response from list utility (no data).", text: "List operation failed: Invalid response from list utility (no data).",
}, },
], ],
@ -160,7 +163,7 @@ export async function listToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: "List operation completed with unknown item type.", text: "List operation completed with unknown item type.",
}, },
], ],
@ -170,7 +173,7 @@ export async function listToolHandler(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: `Unexpected error: ${error instanceof Error ? error.message : "Unknown error"}`, text: `Unexpected error: ${error instanceof Error ? error.message : "Unknown error"}`,
}, },
], ],
@ -183,7 +186,7 @@ async function handleServerStatus(
version: string, version: string,
packageRootDir: string, packageRootDir: string,
logger: Logger, logger: Logger,
): Promise<{ content: { type: string; text: string }[] }> { ): Promise<ToolResponse> {
const statusSections: string[] = []; const statusSections: string[] = [];
// 1. Server version and AI providers // 1. Server version and AI providers
@ -327,7 +330,7 @@ async function handleServerStatus(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: fullStatus, text: fullStatus,
}, },
], ],
@ -357,7 +360,7 @@ export function buildSwiftCliArgs(input: ListToolInput): string[] {
function handleApplicationsList( function handleApplicationsList(
data: ApplicationListData, data: ApplicationListData,
swiftResponse: SwiftCliResponse, swiftResponse: SwiftCliResponse,
): { content: { type: string; text: string }[]; application_list: ApplicationInfo[] } { ): ToolResponse & { application_list: ApplicationInfo[] } {
const apps = data.applications || []; const apps = data.applications || [];
let summary = `Found ${apps.length} running application${apps.length !== 1 ? "s" : ""}`; let summary = `Found ${apps.length} running application${apps.length !== 1 ? "s" : ""}`;
@ -385,7 +388,7 @@ function handleApplicationsList(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: summary, text: summary,
}, },
], ],
@ -399,7 +402,7 @@ function handleWindowsList(
swiftResponse: SwiftCliResponse, swiftResponse: SwiftCliResponse,
): ToolResponse & { ): ToolResponse & {
window_list?: WindowInfo[]; window_list?: WindowInfo[];
target_application_info?: ApplicationInfo; target_application_info?: TargetApplicationInfo;
} { } {
const windows = data.windows || []; const windows = data.windows || [];
const appInfo = data.target_application_info; const appInfo = data.target_application_info;
@ -409,7 +412,7 @@ function handleWindowsList(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: "List operation failed: Invalid response from list utility (missing application info).", text: "List operation failed: Invalid response from list utility (missing application info).",
}, },
], ],
@ -456,7 +459,7 @@ function handleWindowsList(
return { return {
content: [ content: [
{ {
type: "text", type: "text" as const,
text: summary, text: summary,
}, },
], ],

View file

@ -34,6 +34,8 @@ interface JSONSchema {
maximum?: number; maximum?: number;
minLength?: number; minLength?: number;
maxLength?: number; maxLength?: number;
minItems?: number;
maxItems?: number;
pattern?: string; pattern?: string;
format?: string; format?: string;
$ref?: string; $ref?: string;