🎉 Initial commit: PiAgentUI — AI Agent Desktop & Web UI
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
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
This commit is contained in:
commit
b3489e1ede
983 files changed
+158475
No files matched your search
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 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)` : ''),
|
||||
)
|
||||
Reference in new issue
Block a user