first commit

This commit is contained in:
caraction
2025-06-25 14:29:07 +00:00
commit 5ea0e36207
60 changed files with 14674 additions and 0 deletions

53
public/convert-icons.md Normal file
View File

@@ -0,0 +1,53 @@
# Convert SVG Icons to PNG
I've created SVG versions of the app icons that match the MessageSquare design from the sidebar. To convert them to PNG format, you can use one of these methods:
## Method 1: Online Converter (Easiest)
1. Go to https://cloudconvert.com/svg-to-png
2. Upload each SVG file from the `/icons/` directory
3. Download the PNG versions
4. Replace the existing PNG files
## Method 2: Using Node.js (if you have it)
```bash
npm install sharp
node -e "
const sharp = require('sharp');
const fs = require('fs');
const sizes = [72, 96, 128, 144, 152, 192, 384, 512];
sizes.forEach(size => {
const svgPath = \`./icons/icon-\${size}x\${size}.svg\`;
const pngPath = \`./icons/icon-\${size}x\${size}.png\`;
if (fs.existsSync(svgPath)) {
sharp(svgPath).png().toFile(pngPath);
console.log(\`Converted \${svgPath} to \${pngPath}\`);
}
});
"
```
## Method 3: Using ImageMagick (if installed)
```bash
cd public/icons
for size in 72 96 128 144 152 192 384 512; do
convert "icon-${size}x${size}.svg" "icon-${size}x${size}.png"
done
```
## Method 4: Using Inkscape (if installed)
```bash
cd public/icons
for size in 72 96 128 144 152 192 384 512; do
inkscape --export-type=png "icon-${size}x${size}.svg"
done
```
## Icon Design
The new icons feature:
- Clean MessageSquare (chat bubble) design matching the sidebar
- Primary color background with rounded corners
- White stroke icon that's clearly visible
- Consistent sizing and proportions across all sizes
- Proper PWA-compliant format
Once converted, the PNG files will replace the existing ones and provide a consistent icon experience across all platforms.

BIN
public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

9
public/favicon.svg Normal file
View File

@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
<!-- Background fills entire canvas -->
<rect x="0" y="0" width="64" height="64" fill="hsl(240 5.9% 10%)"/>
<!-- MessageSquare icon - exact same as sidebar -->
<g transform="translate(32, 32) scale(1.333) translate(-12, -12)" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 504 B

49
public/generate-icons.js Normal file
View File

@@ -0,0 +1,49 @@
const fs = require('fs');
const path = require('path');
// Icon sizes needed
const sizes = [72, 96, 128, 144, 152, 192, 384, 512];
// SVG template function
function createIconSVG(size) {
const cornerRadius = Math.round(size * 0.25); // 25% corner radius
const strokeWidth = Math.max(2, Math.round(size * 0.06)); // Scale stroke width
// MessageSquare path scaled to size
const padding = Math.round(size * 0.25);
const iconSize = size - (padding * 2);
const startX = padding;
const startY = Math.round(padding * 0.7);
const endX = startX + iconSize;
const endY = startY + Math.round(iconSize * 0.6);
const tailX = startX;
const tailY = endY + Math.round(iconSize * 0.3);
return `<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Background with rounded corners -->
<rect width="${size}" height="${size}" rx="${cornerRadius}" fill="hsl(262.1 83.3% 57.8%)"/>
<!-- MessageSquare icon -->
<path d="M${startX} ${startY}C${startX} ${startY - 10} ${startX + 10} ${startY - 20} ${startX + 20} ${startY - 20}H${endX - 20}C${endX - 10} ${startY - 20} ${endX} ${startY - 10} ${endX} ${startY}V${endY - 20}C${endX} ${endY - 10} ${endX - 10} ${endY} ${endX - 20} ${endY}H${startX + Math.round(iconSize * 0.4)}L${tailX} ${tailY}V${startY}Z"
stroke="white"
stroke-width="${strokeWidth}"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
</svg>`;
}
// Generate SVG files for each size
sizes.forEach(size => {
const svgContent = createIconSVG(size);
const filename = `icon-${size}x${size}.svg`;
const filepath = path.join(__dirname, 'icons', filename);
fs.writeFileSync(filepath, svgContent);
console.log(`Created ${filename}`);
});
console.log('\nSVG icons created! To convert to PNG, you can use:');
console.log('1. Online converter like cloudconvert.com');
console.log('2. If you have ImageMagick: convert icon.svg icon.png');
console.log('3. If you have Inkscape: inkscape --export-type=png icon.svg');

View File

@@ -0,0 +1,19 @@
# PWA Icons Required
Create the following icon files in this directory:
- icon-72x72.png
- icon-96x96.png
- icon-128x128.png
- icon-144x144.png
- icon-152x152.png
- icon-192x192.png
- icon-384x384.png
- icon-512x512.png
You can use any icon generator tool or create them manually. The icons should be square and represent your Claude Code UI application.
For a quick solution, you can:
1. Create a simple square PNG icon (512x512)
2. Use online tools like realfavicongenerator.net to generate all sizes
3. Or use ImageMagick: `convert icon-512x512.png -resize 192x192 icon-192x192.png`

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,12 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Background fills entire canvas - iOS will handle corner rounding -->
<rect width="512" height="512" fill="hsl(240 5.9% 10%)"/>
<!-- MessageSquare icon - scaled and centered -->
<path d="M128 144C128 126.327 142.327 112 160 112H352C369.673 112 384 126.327 384 144V272C384 289.673 369.673 304 352 304H224L128 400V144Z"
stroke="white"
stroke-width="32"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,12 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Background fills entire canvas - iOS will handle corner rounding -->
<rect width="512" height="512" fill="hsl(240 5.9% 10%)"/>
<!-- MessageSquare icon - scaled and centered -->
<path d="M128 144C128 126.327 142.327 112 160 112H352C369.673 112 384 126.327 384 144V272C384 289.673 369.673 304 352 304H224L128 400V144Z"
stroke="white"
stroke-width="32"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,12 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Background fills entire canvas - iOS will handle corner rounding -->
<rect width="512" height="512" fill="hsl(240 5.9% 10%)"/>
<!-- MessageSquare icon - scaled and centered -->
<path d="M128 144C128 126.327 142.327 112 160 112H352C369.673 112 384 126.327 384 144V272C384 289.673 369.673 304 352 304H224L128 400V144Z"
stroke="white"
stroke-width="32"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,12 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Background fills entire canvas - iOS will handle corner rounding -->
<rect width="512" height="512" fill="hsl(240 5.9% 10%)"/>
<!-- MessageSquare icon - scaled and centered -->
<path d="M128 144C128 126.327 142.327 112 160 112H352C369.673 112 384 126.327 384 144V272C384 289.673 369.673 304 352 304H224L128 400V144Z"
stroke="white"
stroke-width="32"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,12 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Background fills entire canvas - iOS will handle corner rounding -->
<rect width="512" height="512" fill="hsl(240 5.9% 10%)"/>
<!-- MessageSquare icon - scaled and centered -->
<path d="M128 144C128 126.327 142.327 112 160 112H352C369.673 112 384 126.327 384 144V272C384 289.673 369.673 304 352 304H224L128 400V144Z"
stroke="white"
stroke-width="32"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,12 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Background fills entire canvas - iOS will handle corner rounding -->
<rect width="512" height="512" fill="hsl(240 5.9% 10%)"/>
<!-- MessageSquare icon - scaled and centered -->
<path d="M128 144C128 126.327 142.327 112 160 112H352C369.673 112 384 126.327 384 144V272C384 289.673 369.673 304 352 304H224L128 400V144Z"
stroke="white"
stroke-width="32"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 578 B

BIN
public/icons/icon-72x72.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,12 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Background fills entire canvas - iOS will handle corner rounding -->
<rect width="512" height="512" fill="hsl(240 5.9% 10%)"/>
<!-- MessageSquare icon - scaled and centered -->
<path d="M128 144C128 126.327 142.327 112 160 112H352C369.673 112 384 126.327 384 144V272C384 289.673 369.673 304 352 304H224L128 400V144Z"
stroke="white"
stroke-width="32"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 578 B

BIN
public/icons/icon-96x96.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,12 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Background fills entire canvas - iOS will handle corner rounding -->
<rect width="512" height="512" fill="hsl(240 5.9% 10%)"/>
<!-- MessageSquare icon - scaled and centered -->
<path d="M128 144C128 126.327 142.327 112 160 112H352C369.673 112 384 126.327 384 144V272C384 289.673 369.673 304 352 304H224L128 400V144Z"
stroke="white"
stroke-width="32"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 578 B

View File

@@ -0,0 +1,12 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Background fills entire canvas - iOS will handle corner rounding -->
<rect width="512" height="512" fill="hsl(240 5.9% 10%)"/>
<!-- MessageSquare icon - scaled and centered -->
<path d="M128 144C128 126.327 142.327 112 160 112H352C369.673 112 384 126.327 384 144V272C384 289.673 369.673 304 352 304H224L128 400V144Z"
stroke="white"
stroke-width="32"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 578 B

9
public/logo.svg Normal file
View File

@@ -0,0 +1,9 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="32" height="32" rx="8" fill="hsl(262.1 83.3% 57.8%)"/>
<path d="M8 9C8 8.44772 8.44772 8 9 8H23C23.5523 8 24 8.44772 24 9V18C24 18.5523 23.5523 19 23 19H12L8 23V9Z"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 422 B

61
public/manifest.json Normal file
View File

@@ -0,0 +1,61 @@
{
"name": "Claude Code UI",
"short_name": "Claude UI",
"description": "Claude Code UI web application",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#ffffff",
"orientation": "portrait-primary",
"scope": "/",
"icons": [
{
"src": "/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable any"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

49
public/sw.js Normal file
View File

@@ -0,0 +1,49 @@
// Service Worker for Claude Code UI PWA
const CACHE_NAME = 'claude-ui-v1';
const urlsToCache = [
'/',
'/index.html',
'/manifest.json'
];
// Install event
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
return cache.addAll(urlsToCache);
})
);
self.skipWaiting();
});
// Fetch event
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
// Return cached response if found
if (response) {
return response;
}
// Otherwise fetch from network
return fetch(event.request);
}
)
);
});
// Activate event
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== CACHE_NAME) {
return caches.delete(cacheName);
}
})
);
})
);
});