Compare commits

..
4 Commits
Author SHA1 Message Date
westfarn 52cc2428ec Rename Android shell display name to Hesychia (#29)
Unit Tests / test (pull_request) Successful in 15s
Capacitor appName and Android string resources (plus docs) now show Hesychia
so the mobile shell matches the product rebrand when this wrap lands.
2026-07-26 19:12:19 -05:00
westfarn 0e86924daf Add android/ README with build and Play deploy steps
Document sync, debug/release Gradle builds, signing, and internal-testing
upload so the native project folder is self-contained for release work.
2026-07-26 19:12:19 -05:00
westfarn 0d90269c53 Ship Android app by wrapping CRA build with Capacitor (#20)
Add Capacitor 7 scaffolding (config, android/, npm scripts, .env.mobile),
native back-button/safe-area chrome, icons/splash, and signing docs so
llm-fe ships one codebase to web and Android.
2026-07-26 19:12:19 -05:00
westfarn b7f23eb16c Rebrand product to Hesychia (hesychia.ai) (#29) (#32)
Unit Tests / test (push) Successful in 10s
## Summary
- Closes #29
- Rename user-facing product from AIML Operations chat to **Hesychia** (headers, sidenav brand, footer, ToS welcome, sample page)
- Update page metadata (`title`, description, Open Graph, `manifest.json` app name)
- Point README / env comments at **hesychia.ai**; keep live API hosts and deploy webroots until infra cutover

## Android display name
Capacitor tree is not on `master` yet ([#28](#28)). Display name / `appName` → **Hesychia** pushed on `ship-android-capacitor-20` so it lands with that wrap. Package id stays `com.aimloperations.chat` (Play identity; rename later if desired).

## Out of scope (per issue)
- New logo artwork (#30)
- Backend system-prompt identity (`chat_backend` #20)

## Test plan
- [ ] Web UI shows **Hesychia** in header / sidenav / footer (no old product name)
- [ ] Browser tab title and PWA manifest name are Hesychia
- [ ] Footer still credits AI ML Operations, LLC as developer
- [ ] `npm run test:ci` (Footer test updated)
- [ ] After #28 merges: Android launcher / activity title shows HesychiaReviewed-on: #32
2026-07-26 17:07:26 -07:00
12 changed files with 47 additions and 24 deletions
+23 -8
View File
@@ -1,7 +1,9 @@
# Chat Web App (`chat_web_app`) # Hesychia (`chat_web_app`)
Frontend for [chat.aimloperations.com](https://chat.aimloperations.com) — a React + Frontend for **[Hesychia](https://hesychia.ai)** — a React + TypeScript single-page
TypeScript single-page app for the AI ML Operations chat product. app for a calm AI assistant experience (quiet, rest, stillness).
Public product domain: **hesychia.ai** (replacing `chat.aimloperations.com`).
Companion backend: [chat_backend](https://git.aimloperations.com/ai_ml_operations/chat_backend) Companion backend: [chat_backend](https://git.aimloperations.com/ai_ml_operations/chat_backend)
@@ -10,7 +12,20 @@ document root; the shared **web-static** nginx container from
[server-infra](https://git.aimloperations.com/ai_ml_operations/server-infra) serves [server-infra](https://git.aimloperations.com/ai_ml_operations/server-infra) serves
those assets. Same pattern as `dta_webapp`. those assets. Same pattern as `dta_webapp`.
Android ships the same CRA `build/` via **Capacitor** (see `llm-fe/ANDROID.md`). Android ships the same CRA `build/` via **Capacitor** (display name **Hesychia**;
see `llm-fe/ANDROID.md`).
## Domain migration
| Role | Current (still live) | Target |
|------|----------------------|--------|
| Web UI | `chat.aimloperations.com` | `hesychia.ai` |
| REST / WS API | `chatbackend.aimloperations.com` | TBD under hesychia.ai (infra cutover) |
| Deploy webroot | `/var/www/{env}.chat.aimloperations/html` | Keep until `server-infra` renames |
Committed `.env.production` / `.env.beta` still point at the **current**
`*.aimloperations.com` API hosts so builds keep working. Flip those URLs (and
deploy webroots / NPM) when DNS and `server-infra` cut over to hesychia.ai.
## Stack ## Stack
@@ -74,8 +89,8 @@ npm ci
CRA loads mode-specific env files. Variables must be prefixed with `REACT_APP_` CRA loads mode-specific env files. Variables must be prefixed with `REACT_APP_`
to be visible in the browser bundle. to be visible in the browser bundle.
| File | Used when | Backend | | File | Used when | Backend (current) |
|------|-----------|---------| |------|-----------|-------------------|
| `.env.development` | `npm start` | `http://127.0.0.1:8001` | | `.env.development` | `npm start` | `http://127.0.0.1:8001` |
| `.env.production` | `npm run build` / `build:prod` | `https://chatbackend.aimloperations.com` | | `.env.production` | `npm run build` / `build:prod` | `https://chatbackend.aimloperations.com` |
| `.env.beta` | `npm run build:beta` | `https://beta.chatbackend.aimloperations.com` | | `.env.beta` | `npm run build:beta` | `https://beta.chatbackend.aimloperations.com` |
@@ -141,7 +156,7 @@ Full signing / Play Store notes: [`llm-fe/ANDROID.md`](llm-fe/ANDROID.md).
`build:prod` / `build:beta` are intended for deploy hosts (or a machine that can `build:prod` / `build:beta` are intended for deploy hosts (or a machine that can
write those `/var/www/...` paths). Paths must match write those `/var/www/...` paths). Paths must match
`server-infra` `app_catalog.chat_web_app.webroot_pattern`: `server-infra` `app_catalog.chat_web_app.webroot_pattern` until renamed:
```text ```text
/var/www/{env}.chat.aimloperations/html /var/www/{env}.chat.aimloperations/html
@@ -179,7 +194,7 @@ Manual deploy from the control node:
--app chat_web_app --env prod --ref <sha> --app chat_web_app --env prod --ref <sha>
``` ```
NPM (not managed by Ansible) should balance public chat domains to: NPM (not managed by Ansible) should balance public Hesychia domains to:
- `adama:8082` + `roslin:8082` + `ai-server-4080:8082` (prod) - `adama:8082` + `roslin:8082` + `ai-server-4080:8082` (prod)
+2
View File
@@ -1,2 +1,4 @@
# Beta API hosts (current). Target public product domain: hesychia.ai
# Flip these to hesychia.ai API hosts when server-infra / DNS cut over.
REACT_APP_BACKEND_REST_API_BASE_URL=https://beta.chatbackend.aimloperations.com/api/ REACT_APP_BACKEND_REST_API_BASE_URL=https://beta.chatbackend.aimloperations.com/api/
REACT_APP_BACKEND_WS_API_BASE_URL=wss://beta.chatbackend.aimloperations.com/ws/chat_again/ REACT_APP_BACKEND_WS_API_BASE_URL=wss://beta.chatbackend.aimloperations.com/ws/chat_again/
+2
View File
@@ -1,2 +1,4 @@
# Production API hosts (current). Target public product domain: hesychia.ai
# Flip these to hesychia.ai API hosts when server-infra / DNS cut over.
REACT_APP_BACKEND_REST_API_BASE_URL=https://chatbackend.aimloperations.com/api/ REACT_APP_BACKEND_REST_API_BASE_URL=https://chatbackend.aimloperations.com/api/
REACT_APP_BACKEND_WS_API_BASE_URL=wss://chatbackend.aimloperations.com/ws/chat_again/ REACT_APP_BACKEND_WS_API_BASE_URL=wss://chatbackend.aimloperations.com/ws/chat_again/
+6 -2
View File
@@ -8,7 +8,11 @@
<link rel="icon" type="image/png" sizes="16x16" href="%PUBLIC_URL%/favicon-16x16.png" /> <link rel="icon" type="image/png" sizes="16x16" href="%PUBLIC_URL%/favicon-16x16.png" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta name="description" content="Chat app by AI ML Operations, LLC" /> <meta name="description" content="Hesychia — a calm AI assistant by AI ML Operations, LLC" />
<meta name="application-name" content="Hesychia" />
<meta property="og:title" content="Hesychia" />
<meta property="og:description" content="Hesychia — quiet, focused AI chat at hesychia.ai" />
<meta property="og:url" content="https://hesychia.ai" />
<link rel="apple-touch-icon" sizes="180x180" href="%PUBLIC_URL%/apple-touch-icon.png" /> <link rel="apple-touch-icon" sizes="180x180" href="%PUBLIC_URL%/apple-touch-icon.png" />
<!-- <!--
manifest.json provides metadata used when your web app is installed on a manifest.json provides metadata used when your web app is installed on a
@@ -24,7 +28,7 @@
work correctly both with client-side routing and a non-root public URL. work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<title>Chat by AI ML Operations. LCC</title> <title>Hesychia</title>
</head> </head>
<body> <body>
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"short_name": "Chat by AI ML Operations. LLC", "short_name": "Hesychia",
"name": "Chat by AI ML Operations, LLC", "name": "Hesychia",
"icons": [ "icons": [
{ {
"src": "favicon.ico", "src": "favicon.ico",
@@ -115,7 +115,7 @@ const DashboardWrapperLayout = ({ children }: DashboardWrapperLayoutProps): JSX.
<Sidenav <Sidenav
color={sidenavColor} color={sidenavColor}
brand={(transparentSidenav && !darkMode) || whiteSidenav ? brandDark : brandWhite} brand={(transparentSidenav && !darkMode) || whiteSidenav ? brandDark : brandWhite}
brandName="Chat by AI ML, Operations, LLC" brandName="Hesychia"
routes={[]} // {routes} routes={[]} // {routes}
onMouseEnter={handleOnMouseEnter} onMouseEnter={handleOnMouseEnter}
onMouseLeave={handleOnMouseLeave} onMouseLeave={handleOnMouseLeave}
@@ -136,7 +136,7 @@ const DashboardWrapperLayout = ({ children }: DashboardWrapperLayoutProps): JSX.
<Sidenav <Sidenav
color={sidenavColor} color={sidenavColor}
brand={(transparentSidenav && !darkMode) || whiteSidenav ? brandDark : brandWhite} brand={(transparentSidenav && !darkMode) || whiteSidenav ? brandDark : brandWhite}
brandName="AI ML, Operations, LLC" brandName="Hesychia"
routes={[]} // {routes} routes={[]} // {routes}
onMouseEnter={handleOnMouseEnter} onMouseEnter={handleOnMouseEnter}
onMouseLeave={handleOnMouseLeave} onMouseLeave={handleOnMouseLeave}
@@ -11,10 +11,10 @@ describe('Footer', () => {
it('renders copyright and developer credit', () => { it('renders copyright and developer credit', () => {
render(<Footer />); render(<Footer />);
expect(screen.getByText(/© 2025 Chat/i)).toBeInTheDocument(); expect(screen.getByText(/© 2026 Hesychia/i)).toBeInTheDocument();
expect(screen.getByRole('link', { name: /AI ML Operations, LLC/i })).toHaveAttribute( expect(screen.getByRole('link', { name: /AI ML Operations, LLC/i })).toHaveAttribute(
'href', 'href',
'www.aimloperations.com' 'https://www.aimloperations.com'
); );
}); });
}); });
@@ -5,7 +5,7 @@ const Footer = (): JSX.Element => {
return ( return (
<div className='continer-fluid'> <div className='continer-fluid'>
<MDTypography>&copy; 2025 Chat | Developed by <a href='www.aimloperations.com'>AI ML Operations, LLC</a></MDTypography> <MDTypography>&copy; 2026 Hesychia | Developed by <a href='https://www.aimloperations.com'>AI ML Operations, LLC</a></MDTypography>
</div> </div>
); );
@@ -67,7 +67,7 @@ const Header = ({drawerWidth=0, handleDrawerToggle}: HeaderProps): JSX.Element =
{isLargeScreen ? ( {isLargeScreen ? (
<> <>
<Typography variant="h6" style={{ flexGrow: 1 }} className='text-white font-weight-bold'> <Typography variant="h6" style={{ flexGrow: 1 }} className='text-white font-weight-bold'>
Chat | AI Ml Operations Hesychia
</Typography > </Typography >
<Button color="inherit" onClick={handleDashboardClick}> <Button color="inherit" onClick={handleDashboardClick}>
Dashboard</Button> Dashboard</Button>
@@ -81,7 +81,7 @@ const Header = ({drawerWidth=0, handleDrawerToggle}: HeaderProps): JSX.Element =
) : ( ) : (
<> <>
<Typography variant="h6" style={{ flexGrow: 1 }} className='text-white font-weight-bold'> <Typography variant="h6" style={{ flexGrow: 1 }} className='text-white font-weight-bold'>
Chat Hesychia
</Typography > </Typography >
<IconButton color="inherit" onClick={handleDashboardClick}> <IconButton color="inherit" onClick={handleDashboardClick}>
<Dashboard /> <Dashboard />
@@ -150,7 +150,7 @@ const Header2 = ({ absolute = false, light = false, isMini = false }: Header2Pro
return ( return (
<HeaderContainer> <HeaderContainer>
<Logo onClick={() => navigate('/')}> <Logo onClick={() => navigate('/')}>
<h4>Chat</h4> <h4>Hesychia</h4>
</Logo> </Logo>
+2 -2
View File
@@ -57,8 +57,8 @@ const SamplePage: React.FC = () => {
</Container> </Container>
<footer className="footer"> <footer className="footer">
<a href="https://aimloperations.com" target="_blank" rel="noopener noreferrer"> <a href="https://hesychia.ai" target="_blank" rel="noopener noreferrer">
Visit AIMLOperations.com Visit hesychia.ai
</a> </a>
</footer> </footer>
</div> </div>
@@ -36,7 +36,7 @@ const TermsOfService = (): JSX.Element => {
</CardContent> </CardContent>
<Divider /> <Divider />
<MDTypography> <MDTypography>
Welcome to chat.aimloperations.com! We're excited to have you on board. Before you start using our large language model, supplied by AI ML Operations, LLC, we need you to agree to our Terms of Service. Welcome to Hesychia (hesychia.ai)! We're excited to have you on board. Before you start using our large language model, supplied by AI ML Operations, LLC, we need you to agree to our Terms of Service.
</MDTypography> </MDTypography>
<MDTypography variant="h4"> <MDTypography variant="h4">
1. Acceptance of Terms 1. Acceptance of Terms