style: fix formatting with Prettier

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
SuperComboGamer
2025-12-21 20:31:57 -05:00
parent 584f5a3426
commit 8d578558ff
295 changed files with 9088 additions and 10546 deletions

View File

@@ -31,6 +31,7 @@ Centralized utilities for processing image files, including MIME type detection,
Get MIME type for an image file based on its extension.
**Supported formats**:
- `.jpg`, `.jpeg``image/jpeg`
- `.png``image/png`
- `.gif``image/gif`
@@ -38,10 +39,11 @@ Get MIME type for an image file based on its extension.
- Default: `image/png`
**Example**:
```typescript
import { getMimeTypeForImage } from "../lib/image-handler.js";
const mimeType = getMimeTypeForImage("/path/to/image.jpg");
```typescript
import { getMimeTypeForImage } from '../lib/image-handler.js';
const mimeType = getMimeTypeForImage('/path/to/image.jpg');
// Returns: "image/jpeg"
```
@@ -52,21 +54,23 @@ const mimeType = getMimeTypeForImage("/path/to/image.jpg");
Read an image file and convert to base64 with metadata.
**Returns**: `ImageData`
```typescript
interface ImageData {
base64: string; // Base64-encoded image data
mimeType: string; // MIME type
filename: string; // File basename
originalPath: string; // Original file path
base64: string; // Base64-encoded image data
mimeType: string; // MIME type
filename: string; // File basename
originalPath: string; // Original file path
}
```
**Example**:
```typescript
const imageData = await readImageAsBase64("/path/to/photo.png");
console.log(imageData.base64); // "iVBORw0KG..."
console.log(imageData.mimeType); // "image/png"
console.log(imageData.filename); // "photo.png"
const imageData = await readImageAsBase64('/path/to/photo.png');
console.log(imageData.base64); // "iVBORw0KG..."
console.log(imageData.mimeType); // "image/png"
console.log(imageData.filename); // "photo.png"
```
---
@@ -76,15 +80,17 @@ console.log(imageData.filename); // "photo.png"
Convert image paths to content blocks in Claude SDK format. Handles both relative and absolute paths.
**Parameters**:
- `imagePaths` - Array of image file paths
- `workDir` - Optional working directory for resolving relative paths
**Returns**: Array of `ImageContentBlock`
```typescript
interface ImageContentBlock {
type: "image";
type: 'image';
source: {
type: "base64";
type: 'base64';
media_type: string;
data: string;
};
@@ -92,17 +98,15 @@ interface ImageContentBlock {
```
**Example**:
```typescript
const imageBlocks = await convertImagesToContentBlocks(
["./screenshot.png", "/absolute/path/diagram.jpg"],
"/project/root"
['./screenshot.png', '/absolute/path/diagram.jpg'],
'/project/root'
);
// Use in prompt content
const contentBlocks = [
{ type: "text", text: "Analyze these images:" },
...imageBlocks
];
const contentBlocks = [{ type: 'text', text: 'Analyze these images:' }, ...imageBlocks];
```
---
@@ -114,10 +118,11 @@ Format image paths as a bulleted list for inclusion in text prompts.
**Returns**: Formatted string with image paths, or empty string if no images.
**Example**:
```typescript
const pathsList = formatImagePathsForPrompt([
"/screenshots/login.png",
"/diagrams/architecture.png"
'/screenshots/login.png',
'/diagrams/architecture.png',
]);
// Returns:
@@ -139,39 +144,44 @@ Standardized prompt building that combines text prompts with image attachments.
Build a prompt with optional image attachments.
**Parameters**:
- `basePrompt` - The text prompt
- `imagePaths` - Optional array of image file paths
- `workDir` - Optional working directory for resolving relative paths
- `includeImagePaths` - Whether to append image paths to the text (default: false)
**Returns**: `PromptWithImages`
```typescript
interface PromptWithImages {
content: PromptContent; // string | Array<ContentBlock>
content: PromptContent; // string | Array<ContentBlock>
hasImages: boolean;
}
type PromptContent = string | Array<{
type: string;
text?: string;
source?: object;
}>;
type PromptContent =
| string
| Array<{
type: string;
text?: string;
source?: object;
}>;
```
**Example**:
```typescript
import { buildPromptWithImages } from "../lib/prompt-builder.js";
import { buildPromptWithImages } from '../lib/prompt-builder.js';
// Without images
const { content } = await buildPromptWithImages("What is 2+2?");
const { content } = await buildPromptWithImages('What is 2+2?');
// content: "What is 2+2?" (simple string)
// With images
const { content, hasImages } = await buildPromptWithImages(
"Analyze this screenshot",
["/path/to/screenshot.png"],
"/project/root",
true // include image paths in text
'Analyze this screenshot',
['/path/to/screenshot.png'],
'/project/root',
true // include image paths in text
);
// content: [
// { type: "text", text: "Analyze this screenshot\n\nAttached images:\n- /path/to/screenshot.png\n" },
@@ -181,6 +191,7 @@ const { content, hasImages } = await buildPromptWithImages(
```
**Use Cases**:
- **AgentService**: Set `includeImagePaths: true` to list paths for Read tool access
- **AutoModeService**: Set `includeImagePaths: false` to avoid duplication in feature descriptions
@@ -200,9 +211,9 @@ Model alias mapping for Claude models.
```typescript
export const CLAUDE_MODEL_MAP: Record<string, string> = {
haiku: "claude-haiku-4-5",
sonnet: "claude-sonnet-4-20250514",
opus: "claude-opus-4-5-20251101",
haiku: 'claude-haiku-4-5',
sonnet: 'claude-sonnet-4-20250514',
opus: 'claude-opus-4-5-20251101',
} as const;
```
@@ -212,8 +223,8 @@ Default models per provider.
```typescript
export const DEFAULT_MODELS = {
claude: "claude-opus-4-5-20251101",
openai: "gpt-5.2",
claude: 'claude-opus-4-5-20251101',
openai: 'gpt-5.2',
} as const;
```
@@ -224,6 +235,7 @@ export const DEFAULT_MODELS = {
Resolve a model key/alias to a full model string.
**Logic**:
1. If `modelKey` is undefined → return `defaultModel`
2. If starts with `"gpt-"` or `"o"` → pass through (OpenAI/Codex model)
3. If includes `"claude-"` → pass through (full Claude model string)
@@ -231,22 +243,23 @@ Resolve a model key/alias to a full model string.
5. Otherwise → return `defaultModel` with warning
**Example**:
```typescript
import { resolveModelString, DEFAULT_MODELS } from "../lib/model-resolver.js";
resolveModelString("opus");
```typescript
import { resolveModelString, DEFAULT_MODELS } from '../lib/model-resolver.js';
resolveModelString('opus');
// Returns: "claude-opus-4-5-20251101"
// Logs: "[ModelResolver] Resolved model alias: "opus" -> "claude-opus-4-5-20251101""
resolveModelString("gpt-5.2");
resolveModelString('gpt-5.2');
// Returns: "gpt-5.2"
// Logs: "[ModelResolver] Using OpenAI/Codex model: gpt-5.2"
resolveModelString("claude-sonnet-4-20250514");
resolveModelString('claude-sonnet-4-20250514');
// Returns: "claude-sonnet-4-20250514"
// Logs: "[ModelResolver] Using full Claude model string: claude-sonnet-4-20250514"
resolveModelString("invalid-model");
resolveModelString('invalid-model');
// Returns: "claude-opus-4-5-20251101"
// Logs: "[ModelResolver] Unknown model key "invalid-model", using default: "claude-opus-4-5-20251101""
```
@@ -260,19 +273,20 @@ Get the effective model from multiple sources with priority.
**Priority**: explicit model > session model > default model
**Example**:
```typescript
import { getEffectiveModel } from "../lib/model-resolver.js";
import { getEffectiveModel } from '../lib/model-resolver.js';
// Explicit model takes precedence
getEffectiveModel("sonnet", "opus");
getEffectiveModel('sonnet', 'opus');
// Returns: "claude-sonnet-4-20250514"
// Falls back to session model
getEffectiveModel(undefined, "haiku");
getEffectiveModel(undefined, 'haiku');
// Returns: "claude-haiku-4-5"
// Falls back to default
getEffectiveModel(undefined, undefined, "gpt-5.2");
getEffectiveModel(undefined, undefined, 'gpt-5.2');
// Returns: "gpt-5.2"
```
@@ -287,10 +301,10 @@ Standardized conversation history processing for both SDK-based and CLI-based pr
### Types
```typescript
import type { ConversationMessage } from "../providers/types.js";
import type { ConversationMessage } from '../providers/types.js';
interface ConversationMessage {
role: "user" | "assistant";
role: 'user' | 'assistant';
content: string | Array<{ type: string; text?: string; source?: object }>;
}
```
@@ -302,6 +316,7 @@ interface ConversationMessage {
Extract plain text from message content (handles both string and array formats).
**Example**:
```typescript
import { extractTextFromContent } from "../lib/conversation-utils.js";
@@ -325,13 +340,14 @@ extractTextFromContent([
Normalize message content to array format.
**Example**:
```typescript
// String → array
normalizeContentBlocks("Hello");
normalizeContentBlocks('Hello');
// Returns: [{ type: "text", text: "Hello" }]
// Array → pass through
normalizeContentBlocks([{ type: "text", text: "Hello" }]);
normalizeContentBlocks([{ type: 'text', text: 'Hello' }]);
// Returns: [{ type: "text", text: "Hello" }]
```
@@ -344,10 +360,11 @@ Format conversation history as plain text for CLI-based providers (e.g., Codex).
**Returns**: Formatted text with role labels, or empty string if no history.
**Example**:
```typescript
const history = [
{ role: "user", content: "What is 2+2?" },
{ role: "assistant", content: "2+2 equals 4." }
{ role: 'user', content: 'What is 2+2?' },
{ role: 'assistant', content: '2+2 equals 4.' },
];
const formatted = formatHistoryAsText(history);
@@ -372,10 +389,11 @@ Convert conversation history to Claude SDK message format.
**Returns**: Array of SDK-formatted messages ready to yield in async generator.
**Example**:
```typescript
const history = [
{ role: "user", content: "Hello" },
{ role: "assistant", content: "Hi there!" }
{ role: 'user', content: 'Hello' },
{ role: 'assistant', content: 'Hi there!' },
];
const messages = convertHistoryToMessages(history);
@@ -413,7 +431,7 @@ Standardized error classification and handling utilities.
### Types
```typescript
export type ErrorType = "authentication" | "abort" | "execution" | "unknown";
export type ErrorType = 'authentication' | 'abort' | 'execution' | 'unknown';
export interface ErrorInfo {
type: ErrorType;
@@ -431,14 +449,15 @@ export interface ErrorInfo {
Check if an error is an abort/cancellation error.
**Example**:
```typescript
import { isAbortError } from "../lib/error-handler.js";
import { isAbortError } from '../lib/error-handler.js';
try {
// ... operation
} catch (error) {
if (isAbortError(error)) {
console.log("Operation was cancelled");
console.log('Operation was cancelled');
return { success: false, aborted: true };
}
}
@@ -451,15 +470,17 @@ try {
Check if an error is an authentication/API key error.
**Detects**:
- "Authentication failed"
- "Invalid API key"
- "authentication_failed"
- "Fix external API key"
**Example**:
```typescript
if (isAuthenticationError(error.message)) {
console.error("Please check your API key configuration");
console.error('Please check your API key configuration');
}
```
@@ -470,8 +491,9 @@ if (isAuthenticationError(error.message)) {
Classify an error into a specific type.
**Example**:
```typescript
import { classifyError } from "../lib/error-handler.js";
import { classifyError } from '../lib/error-handler.js';
try {
// ... operation
@@ -479,13 +501,13 @@ try {
const errorInfo = classifyError(error);
switch (errorInfo.type) {
case "authentication":
case 'authentication':
// Handle auth errors
break;
case "abort":
case 'abort':
// Handle cancellation
break;
case "execution":
case 'execution':
// Handle other errors
break;
}
@@ -499,6 +521,7 @@ try {
Get a user-friendly error message.
**Example**:
```typescript
try {
// ... operation
@@ -527,7 +550,7 @@ export interface SubprocessOptions {
cwd: string;
env?: Record<string, string>;
abortController?: AbortController;
timeout?: number; // Milliseconds of no output before timeout
timeout?: number; // Milliseconds of no output before timeout
}
export interface SubprocessResult {
@@ -544,6 +567,7 @@ export interface SubprocessResult {
Spawns a subprocess and streams JSONL output line-by-line.
**Features**:
- Parses each line as JSON
- Handles abort signals
- 30-second timeout detection for hanging processes
@@ -551,20 +575,21 @@ Spawns a subprocess and streams JSONL output line-by-line.
- Continues processing other lines if one fails to parse
**Example**:
```typescript
import { spawnJSONLProcess } from "../lib/subprocess-manager.js";
import { spawnJSONLProcess } from '../lib/subprocess-manager.js';
const stream = spawnJSONLProcess({
command: "codex",
args: ["exec", "--model", "gpt-5.2", "--json", "--full-auto", "Fix the bug"],
cwd: "/project/path",
env: { OPENAI_API_KEY: "sk-..." },
command: 'codex',
args: ['exec', '--model', 'gpt-5.2', '--json', '--full-auto', 'Fix the bug'],
cwd: '/project/path',
env: { OPENAI_API_KEY: 'sk-...' },
abortController: new AbortController(),
timeout: 30000
timeout: 30000,
});
for await (const event of stream) {
console.log("Received event:", event);
console.log('Received event:', event);
// Process JSONL events
}
```
@@ -576,15 +601,16 @@ for await (const event of stream) {
Spawns a subprocess and collects all output.
**Example**:
```typescript
const result = await spawnProcess({
command: "git",
args: ["status"],
cwd: "/project/path"
command: 'git',
args: ['status'],
cwd: '/project/path',
});
console.log(result.stdout); // Git status output
console.log(result.exitCode); // 0 for success
console.log(result.stdout); // Git status output
console.log(result.exitCode); // 0 for success
```
---
@@ -645,10 +671,10 @@ Always use `.js` extension in imports for ESM compatibility:
```typescript
// ✅ Correct
import { buildPromptWithImages } from "../lib/prompt-builder.js";
import { buildPromptWithImages } from '../lib/prompt-builder.js';
// ❌ Incorrect
import { buildPromptWithImages } from "../lib/prompt-builder";
import { buildPromptWithImages } from '../lib/prompt-builder';
```
---
@@ -662,11 +688,12 @@ When writing tests for utilities:
3. **Mock external dependencies** - File system, child processes
Example:
```typescript
describe("image-handler", () => {
it("should detect MIME type correctly", () => {
expect(getMimeTypeForImage("photo.jpg")).toBe("image/jpeg");
expect(getMimeTypeForImage("diagram.png")).toBe("image/png");
describe('image-handler', () => {
it('should detect MIME type correctly', () => {
expect(getMimeTypeForImage('photo.jpg')).toBe('image/jpeg');
expect(getMimeTypeForImage('diagram.png')).toBe('image/png');
});
});
```