Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,22 @@ jobs:
- name: Run tests
run: bun run test

- name: Type check
run: bun run type-check

- name: Build
run: bun run build
- name: Type check (strict - warnings are errors)
run: |
set -o pipefail
# Capture TypeScript output - any output indicates errors/warnings
output=$(bun run type-check 2>&1) || exit 1
if [ -n "$output" ] && echo "$output" | grep -qE "error TS|warning"; then
echo "$output"
exit 1
fi

- name: Build (strict - warnings are errors)
run: |
set -o pipefail
# Build and fail on any TypeScript errors/warnings
bun run build 2>&1 | tee build_output.txt
if grep -qE "error TS|warning" build_output.txt; then
echo "Build produced errors or warnings"
exit 1
fi
6 changes: 6 additions & 0 deletions apps/debugger-ios/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ PODS:
- Yoga
- ExpoAsset (12.0.10):
- ExpoModulesCore
- ExpoClipboard (8.0.8):
- ExpoModulesCore
- ExpoFileSystem (19.0.19):
- ExpoModulesCore
- ExpoFont (14.0.9):
Expand Down Expand Up @@ -1935,6 +1937,7 @@ DEPENDENCIES:
- EXConstants (from `../../../node_modules/expo-constants/ios`)
- Expo (from `../../../node_modules/expo`)
- ExpoAsset (from `../../../node_modules/expo-asset/ios`)
- ExpoClipboard (from `../../../node_modules/expo-clipboard/ios`)
- ExpoFileSystem (from `../../../node_modules/expo-file-system/ios`)
- ExpoFont (from `../../../node_modules/expo-font/ios`)
- ExpoHaptics (from `../../../node_modules/expo-haptics/ios`)
Expand Down Expand Up @@ -2022,6 +2025,8 @@ EXTERNAL SOURCES:
:path: "../../../node_modules/expo"
ExpoAsset:
:path: "../../../node_modules/expo-asset/ios"
ExpoClipboard:
:path: "../../../node_modules/expo-clipboard/ios"
ExpoFileSystem:
:path: "../../../node_modules/expo-file-system/ios"
ExpoFont:
Expand Down Expand Up @@ -2184,6 +2189,7 @@ SPEC CHECKSUMS:
EXConstants: fd688cef4e401dcf798a021cfb5d87c890c30ba3
Expo: 111394d38f32be09385d4c7f70cc96d2da438d0d
ExpoAsset: d839c8eae8124470332408427327e8f88beb2dfd
ExpoClipboard: b36b287d8356887844bb08ed5c84b5979bb4dd1e
ExpoFileSystem: 77157a101e03150a4ea4f854b4dd44883c93ae0a
ExpoFont: cf9d90ec1d3b97c4f513211905724c8171f82961
ExpoHaptics: 807476b0c39e9d82b7270349d6487928ce32df84
Expand Down
1 change: 1 addition & 0 deletions apps/debugger-ios/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@shopify/flash-list": "2.0.2",
"expo": "~54.0.25",
"expo-asset": "~12.0.10",
"expo-clipboard": "~8.0.8",
"expo-font": "~14.0.9",
"expo-haptics": "~15.0.7",
"expo-status-bar": "~3.0.8",
Expand Down
6 changes: 3 additions & 3 deletions apps/debugger-ios/src/components/Icon.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Lucide } from '@react-native-vector-icons/lucide';
import { Lucide, type LucideIconName } from '@react-native-vector-icons/lucide';

type IconProps = {
name: string;
Expand All @@ -10,12 +10,12 @@ type IconProps = {

/**
* Icon component for mobile (iOS/Android) - uses Lucide font icons
*
*
* Font icons are more performant on mobile than SVG rendering.
* Icon names should match Lucide icon names (e.g., "plus", "chevron-right").
*/
export function Icon({ name, size = 24, color = '#000', strokeWidth }: IconProps) {
// Font icons don't support strokeWidth, but we accept it for API consistency
return <Lucide name={name.toLowerCase()} size={size} color={color} />;
return <Lucide name={name.toLowerCase() as LucideIconName} size={size} color={color} />;
}

20 changes: 14 additions & 6 deletions apps/debugger-ios/src/components/Icon.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@ type IconProps = {
strokeWidth?: number;
};

// Type for lucide icon components
type LucideIconComponent = React.ComponentType<{
size?: number;
color?: string;
strokeWidth?: number;
}>;

/**
* Icon component for web - uses Lucide SVG icons
*
*
* Converts icon names to PascalCase and looks them up in lucide-react-native.
* Example: "plus" -> "Plus", "chevron-right" -> "ChevronRight"
*/
Expand All @@ -20,15 +27,16 @@ export function Icon({ name, size = 24, color = '#000', strokeWidth }: IconProps
.split('-')
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
.join('');

// Look up the icon component from lucide-react-native
const IconComponent = (LucideIcons as Record<string, React.ComponentType<any>>)[pascalName];

if (!IconComponent) {
// Use unknown first to avoid type comparison issues with mixed exports
const IconComponent = (LucideIcons as unknown as Record<string, LucideIconComponent>)[pascalName];

if (!IconComponent || typeof IconComponent !== 'function') {
console.warn(`Icon "${name}" (resolved to "${pascalName}") not found in lucide-react-native`);
return null;
}

return <IconComponent size={size} color={color} strokeWidth={strokeWidth} />;
}

75 changes: 75 additions & 0 deletions apps/debugger-ios/src/data/testMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,81 @@ The most important thing is to **start building** and iterate from there.

Don't let analysis paralysis hold you back!`;

// Streaming response for testing all custom renderers
export const STREAMING_ALL_ELEMENTS_RESPONSE = `[MSG #NEW] Here's a comprehensive test of all custom renderers:

# Heading Level 1

This is a paragraph with [a link](https://example.com) in it.

## Heading Level 2

> This is a blockquote.
> It can span multiple lines.
> And include **bold** and *italic* text.

### Heading Level 3

Here's an image:

![Sample Image](https://picsum.photos/seed/custom-renderer/400/200)

#### Heading Level 4

And a table:

| Feature | Supported | Notes |
| :--- | :---: | ---: |
| Images | Yes | With alt text |
| Links | Yes | With title |
| Tables | Yes | With alignment |
| Blockquotes | Yes | Nested too |

##### Heading Level 5

Finally, some code:

\`\`\`typescript
function greet(name: string): string {
return \`Hello, \${name}!\`;
}
\`\`\`

###### Heading Level 6

That's all the custom renderers!`;

// Streaming response with code block - for testing custom code block renderer
export const STREAMING_CODE_RESPONSE = `[MSG #NEW] Here's a code example:

\`\`\`typescript
function fibonacci(n: number): number {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}

// Usage
console.log(fibonacci(10)); // 55
\`\`\`

And here's another example in Python:

\`\`\`python
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)

# Example
print(quicksort([3, 6, 8, 10, 1, 2, 1]))
\`\`\`

That's the recursive approach for both!`;

// Helper to create a new message with proper numbering
export function createUserMessage(content: string, existingCount: number): Message {
const num = existingCount + 1;
Expand Down
Loading