Build & Push Frontend Docker Image / build-and-push (push) Canceled after 0s
Build Validation / validate (push) Canceled after 6s
Build & Push Backend Docker Image / build-and-push (push) Failing after 10m10s
Build & Push Gateway Docker Image / build-and-push (push) Failing after 10m9s
A professional workspace for AI coding agents with: - Real-time streaming chat with SSE - Session management (fork, clone, tree navigation) - MCP tools browser & metadata panel - Skills browser (global, project, package sources) - Voice input & STT provider configuration - Integrated terminal & file explorer - Model selector with capability metadata - Keyboard-first UI with command palette - 8 languages (en, pt-BR, es, ja, zh-CN, ar, bn, hi) - Tauri 2 desktop app - React 19 + TypeScript + Vite 8 + Tailwind CSS 4 - Pi Agent extension runtime Originally forked from OpenCodeUI, now an independent project. License: GPL-3.0-only
71 lines
1.9 KiB
JavaScript
71 lines
1.9 KiB
JavaScript
/**
|
|
* Copy only the material-icon-theme SVGs that are actually referenced
|
|
* by src/utils/materialIcons.ts to public/material-icons/.
|
|
*
|
|
* Runs automatically via postinstall hook.
|
|
*/
|
|
|
|
import { copyFileSync, mkdirSync, existsSync, readFileSync, rmSync } from 'fs'
|
|
import { resolve, dirname } from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
const root = resolve(__dirname, '..')
|
|
|
|
const srcDir = resolve(root, 'node_modules/material-icon-theme/icons')
|
|
const destDir = resolve(root, 'public/material-icons')
|
|
|
|
if (!existsSync(srcDir)) {
|
|
console.warn('[copy-material-icons] Source not found, skipping:', srcDir)
|
|
process.exit(0)
|
|
}
|
|
|
|
// Parse materialIcons.ts to extract every icon name referenced
|
|
const tsSource = readFileSync(resolve(root, 'src/utils/materialIcons.ts'), 'utf-8')
|
|
|
|
const icons = new Set()
|
|
|
|
// Icon values after colon: 'icon-name'
|
|
for (const m of tsSource.matchAll(/:\s*'([a-z0-9_-]+)'/g)) {
|
|
icons.add(m[1])
|
|
}
|
|
// Array items [ext, icon]
|
|
for (const m of tsSource.matchAll(/\[\s*'[^']+'\s*,\s*'([a-z0-9_-]+)'\s*\]/g)) {
|
|
icons.add(m[1])
|
|
}
|
|
// Defaults
|
|
icons.add('file')
|
|
icons.add('folder')
|
|
icons.add('folder-open')
|
|
|
|
// Folder icons need both base and -open variants
|
|
for (const icon of [...icons]) {
|
|
if (icon.startsWith('folder-') && !icon.endsWith('-open')) {
|
|
icons.add(icon + '-open')
|
|
}
|
|
}
|
|
|
|
// Clean destination and copy only needed files
|
|
if (existsSync(destDir)) {
|
|
rmSync(destDir, { recursive: true })
|
|
}
|
|
mkdirSync(destDir, { recursive: true })
|
|
|
|
let copied = 0
|
|
let missing = 0
|
|
for (const icon of icons) {
|
|
const srcPath = resolve(srcDir, icon + '.svg')
|
|
const destPath = resolve(destDir, icon + '.svg')
|
|
if (existsSync(srcPath)) {
|
|
copyFileSync(srcPath, destPath)
|
|
copied++
|
|
} else {
|
|
console.warn(` [WARN] Missing: ${icon}.svg`)
|
|
missing++
|
|
}
|
|
}
|
|
|
|
console.log(
|
|
`[copy-material-icons] Copied ${copied} icons to public/material-icons/` + (missing ? ` (${missing} missing)` : ''),
|
|
)
|