Restructure: move Vite project into app/, deploy build output to repo root
The webserver serves the repo checkout directly as static files, so index.html at the repo root must be the production build (pointing at hashed /assets/*.js) rather than the dev template (/src/main.tsx), which was being served with an unrecognized application/octet-stream MIME type and blocked by the browser. - Move src/, public/, scripts/, server/, package.json, vite.config.ts, tsconfig.json, .env(.example), and the dev index.html into app/. - Add app/scripts/deploy.mjs: copies app/dist/* into the repo root after every `vite build`, cleaning up stale hashed filenames. - Wire it into `npm run build` (app/package.json). - Update run.sh to operate from app/, and .gitignore for the new layout. - Commit the current build output (index.html, assets/, manifest, sw.js, workbox-*.js, favicon.svg, icons/, LICENSE) to the repo root. - Update README with the new project layout and deployment model.
This commit is contained in:
1 parent
5245c0a856
commit
c7b653ff6a
54 files changed
+224
-34
No files matched your search
@@ -0,0 +1,97 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useStore } from "./state/store";
|
||||
import { isConfigured } from "./lib/config";
|
||||
import { useTts } from "./hooks/useTts";
|
||||
import { ConfigScreen } from "./components/ConfigScreen";
|
||||
import { DerezLogoLink } from "./components/DerezLogo";
|
||||
import { Sidebar } from "./components/Sidebar";
|
||||
import { ChatView } from "./components/ChatView";
|
||||
import { SettingsPanel } from "./components/SettingsPanel";
|
||||
import { Toast } from "./components/Toast";
|
||||
|
||||
function AutoSpeak() {
|
||||
const messages = useStore((s) => s.messages);
|
||||
const streaming = useStore((s) => s.streaming);
|
||||
const speakReplies = useStore((s) => s.config.speakReplies);
|
||||
const { speak } = useTts();
|
||||
const lastSpoken = useRef<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!speakReplies || streaming) return;
|
||||
const last = messages[messages.length - 1];
|
||||
if (!last || last.role !== "assistant") return;
|
||||
if (!last.id || last.id === lastSpoken.current) return;
|
||||
if (!last.content.trim()) return;
|
||||
lastSpoken.current = last.id;
|
||||
speak(last.content);
|
||||
}, [messages, streaming, speakReplies, speak]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function App() {
|
||||
const ready = useStore((s) => s.ready);
|
||||
const config = useStore((s) => s.config);
|
||||
const connectionError = useStore((s) => s.connectionError);
|
||||
const showSettings = useStore((s) => s.showSettings);
|
||||
const bootstrap = useStore((s) => s.bootstrap);
|
||||
const connect = useStore((s) => s.connect);
|
||||
|
||||
useEffect(() => {
|
||||
void bootstrap();
|
||||
}, [bootstrap]);
|
||||
|
||||
if (!ready) {
|
||||
return (
|
||||
<div className="screen">
|
||||
<div className="spinner" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isConfigured(config)) {
|
||||
return (
|
||||
<>
|
||||
<ConfigScreen />
|
||||
{showSettings && <SettingsPanel />}
|
||||
<Toast />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if (connectionError) {
|
||||
return (
|
||||
<div className="screen">
|
||||
<div className="card">
|
||||
<div style={{ marginBottom: 18 }}>
|
||||
<DerezLogoLink height={30} />
|
||||
</div>
|
||||
<h1>Can’t reach Hermes</h1>
|
||||
<p className="lead">{connectionError}</p>
|
||||
<div className="actions">
|
||||
<button className="btn" onClick={() => useStore.getState().setShowSettings(true)}>
|
||||
Settings
|
||||
</button>
|
||||
<button className="btn primary" onClick={() => connect()}>
|
||||
Retry
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{showSettings && <SettingsPanel />}
|
||||
<Toast />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="app">
|
||||
<Sidebar />
|
||||
<ChatView />
|
||||
</div>
|
||||
<AutoSpeak />
|
||||
{showSettings && <SettingsPanel />}
|
||||
<Toast />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user