Compare commits

..
Author SHA1 Message Date
nathan 0aef410f60 fixed retarded prettier 'error'
CI / Build & Quality Checks (pull_request) Successful in 10m45s
CI / Trigger Desktop Build (pull_request) Skipped
2026-08-02 19:01:05 -04:00
nathan b2376513fd fixed retarded linter problem
CI / Build & Quality Checks (pull_request) Failing after 6m2s
CI / Trigger Desktop Build (pull_request) Skipped
2026-08-02 18:42:37 -04:00
nathan.vititoe 2bbd390a3b image path changes, for dev setup, needs testing on 'prod'
CI / Build & Quality Checks (pull_request) Failing after 6m0s
CI / Trigger Desktop Build (pull_request) Skipped
2026-08-02 16:35:11 -04:00
13 changed files with 55 additions and 103 deletions
+26 -30
View File
@@ -30,13 +30,8 @@ jobs:
uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
cache: npm
# No npm / node_modules cache: the act_runner's internal cache server is
# unreachable from job containers (`getCacheEntry failed: connect ETIMEDOUT
# 172.17.0.2`), so every cache restore hangs ~5 min and then fails — pure
# cost, zero benefit. `cache: npm` was removed from Setup Node above for the
# same reason. Re-enable both (setup-node `cache: npm` + an actions/cache
# node_modules step) once the runner's cache server is reachable from jobs.
- name: Install dependencies
# Harden against transient registry network failures (ECONNRESET etc.):
# raise npm's built-in fetch retries/timeouts and retry `npm ci` up to
@@ -57,36 +52,37 @@ jobs:
sleep $((attempt * 15))
done
# ── Quality gates run BEFORE the slow build so a format/lint/type/test
# error fails in seconds instead of after the ~minutes-long build. All are
# hard gates — any failure fails the job and blocks the deploy. The tree is
# held clean (prettier formatted, eslint 0 errors, typecheck 0), so these
# gate real regressions. NOTE: the lotus-build.sh upstream-merge path can
# deploy without CI; a later normal push surfaces any introduced issue here
# — fix forward (or briefly re-soften a gate) rather than deploy broken.
# eslint gates on errors only (existing no-explicit-any warnings stay
# informational — check:eslint has no --max-warnings).
- name: Prettier
run: npm run check:prettier
- name: ESLint
run: npm run check:eslint
- name: TypeScript
run: npm run typecheck
# Deterministic pure-logic tests on Node's built-in runner via tsx (no
# vitest — Vite 8 is ahead of vitest's range). A failure blocks the deploy.
- name: Unit tests
run: npm test
# ── Critical gate — if this fails, nothing deploys. Produces dist/. ──
# ── Critical gate — if this fails, nothing deploys ──────────────────
- name: Build
run: npm run build
env:
NODE_OPTIONS: '--max_old_space_size=4096'
VITE_APP_VERSION: ${{ github.sha }}
# Unit tests are a hard gate too — deterministic pure-logic tests on Node's
# built-in runner via tsx (no vitest — Vite 8 is ahead of vitest's range).
# A failure blocks the deploy.
- name: Unit tests
run: npm test
# ── Quality gates (hard — a failure fails the job and blocks deploy) ──
# The tree is held clean (typecheck 0, eslint 0 errors, prettier
# formatted), so these gate real regressions instead of relying on local
# runs. NOTE: an upstream-stable merge (the lotus-build.sh path) could
# introduce upstream type/lint/format issues; that path deploys without
# CI, but a subsequent normal push would surface the failure here — fix
# forward (or briefly re-soften a gate) rather than let it deploy broken.
# eslint gates on errors only (existing `no-explicit-any` warnings stay
# informational — `check:eslint` has no --max-warnings).
- name: TypeScript
run: npm run typecheck
- name: ESLint
run: npm run check:eslint
- name: Prettier
run: npm run check:prettier
# ── Security (informational — findings shouldn't block a deploy) ─────
- name: Audit (high/critical)
run: npm audit --audit-level=high --omit=dev
-27
View File
@@ -1,27 +0,0 @@
---
name: Bug Report
about: Report something that isn't working in Lotus Chat
title: ''
labels: bug
---
**Describe the bug**
A clear and concise description of what went wrong.
**Steps to reproduce**
1. Go to '...'
2. Click on '...'
3. See error
**Expected behavior**
What you expected to happen instead.
**Client info**
- Lotus Chat version (Settings → Help & About):
- Platform: Web / Desktop (Windows / macOS / Linux)
- Browser + version (if web):
**Screenshots / logs**
If applicable, add screenshots or the browser devtools console output.
+5 -1
View File
@@ -1 +1,5 @@
blank_issues_enabled: true
blank_issues_enabled: false
contact_links:
- name: Features, Bug Reports, Questions
url: https://github.com/cinnyapp/cinny/discussions/new/choose
about: Our preferred starting point if you have any questions or suggestions about features or behavior.
-15
View File
@@ -1,15 +0,0 @@
---
name: Feature Request
about: Suggest an idea or improvement for Lotus Chat
title: ''
labels: enhancement
---
**What would you like?**
A clear and concise description of the feature or change.
**Why / use case**
What problem does it solve, or what does it make better?
**Alternatives considered**
Any workarounds or other approaches you've thought about.
+9
View File
@@ -0,0 +1,9 @@
---
name: Pre-Discussed and Approved Topics
about: |-
Only for topics already discussed and approved in the GitHub Discussions section.
---
**DO NOT OPEN A NEW ISSUE. PLEASE USE THE DISCUSSIONS SECTION.**
**I DIDN'T READ THE ABOVE LINE. PLEASE CLOSE THIS ISSUE.**
+3 -1
View File
@@ -1 +1,3 @@
npx lint-staged
# These are commented until we enable lint and typecheck
# npx tsc -p tsconfig.json --noEmit
# npx lint-staged
-17
View File
@@ -167,23 +167,6 @@ The source code lives in `/root/code/cinny`. All changes should be made on the `
See [LOTUS_FEATURES.md](LOTUS_FEATURES.md) for the full feature changelog and [LOTUS_TODO.md](LOTUS_TODO.md) for the work backlog.
### Local Development
Lotus Chat is a **pure client — there is no backend of its own to run.** It talks directly to a Matrix homeserver (Synapse) over HTTPS, so the only thing you run locally is the Vite dev server; it connects to a real homeserver for all data. If you were looking for "the backend to pair with it," there isn't one — that's the homeserver.
**Prerequisites:** Node 20+ (CI builds on Node 24) and npm.
```bash
npm ci # deps; @lotusguild/* come from our Gitea npm registry (public read — no auth/token needed)
npm start # Vite dev server → http://localhost:8080
```
The dev server defaults to **port 8080** (`vite.config.js`); if 8080 is already in use it falls through to 8081+, so check the "Local:" URL Vite prints on startup. If it boots but the page renders blank, it's almost always a failed module/asset resolution, not a "missing backend" — open the devtools console and read the first error.
**Which homeserver / logging in:** `config.json` sets `defaultHomeserver: 0``matrix.lotusguild.org`, so you sign in with your normal `@you:matrix.lotusguild.org` account. That homeserver is **live production** — anything you send is real, so keep test traffic to a DM with yourself or a throwaway room. To develop fully isolated instead, point `config.json` at a throwaway `matrix.org` account (already in `homeserverList`) or a local Synapse.
- **SSO / OIDC works from localhost.** Login goes through Authelia via OIDC dynamic registration; the provider redirects back to `http://localhost:8080/…` and the client registers that redirect on the fly, so no server-side allow-listing is needed. After the callback you may see a `GET …/_matrix/media/v1/thumbnail/… 404` — that's just a missing avatar thumbnail, **not** a login failure.
### 🔱 Element Call fork ("Lotus Call") — LIVE
Voice/video channels embed **Element Call**, which is now our **self-built fork**
+2 -2
View File
@@ -4,12 +4,12 @@ import { Page, PageContent, PageHeader } from '../../../components/page';
import { SequenceCard } from '../../../components/sequence-card';
import { SequenceCardStyle } from '../styles.css';
import { SettingTile } from '../../../components/setting-tile';
import { getOriginBaseUrl, withOriginBaseUrl } from '../../../pages/pathUtils';
import pkg from '../../../../../package.json';
import { clearCacheAndReload } from '../../../../client/initMatrix';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { getOriginBaseUrl, withOriginBaseUrl } from '../../../pages/pathUtils';
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/public/res/Lotus.png');
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/Lotus.png');
type MSC1929Contact = {
matrix_id?: string;
+2 -2
View File
@@ -20,7 +20,6 @@ import {
} from '../../hooks/useClientConfig';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import { LOGIN_PATH, REGISTER_PATH, RESET_PASSWORD_PATH } from '../paths';
import { getOriginBaseUrl, withOriginBaseUrl } from '../pathUtils';
import { ServerPicker } from './ServerPicker';
import { AutoDiscoveryAction, autoDiscovery } from '../../cs-api';
import { SpecVersionsLoader } from '../../components/SpecVersionsLoader';
@@ -30,8 +29,9 @@ import { AuthFlowsLoader } from '../../components/AuthFlowsLoader';
import { AuthFlowsProvider } from '../../hooks/useAuthFlows';
import { AuthServerProvider } from '../../hooks/useAuthServer';
import { tryDecodeURIComponent } from '../../utils/dom';
import { getOriginBaseUrl, withOriginBaseUrl } from '../pathUtils';
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/public/res/Lotus.png');
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/Lotus.png');
const currentAuthPath = (pathname: string): string => {
if (matchPath(LOGIN_PATH, pathname)) {
+1 -1
View File
@@ -2,7 +2,7 @@ import type { OidcRegistrationClientMetadata } from 'matrix-js-sdk';
import { OIDC_CALLBACK_PATH } from '../../paths';
import { getOriginBaseUrl, withOriginBaseUrl } from '../../pathUtils';
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/public/res/Lotus.png');
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/Lotus.png');
/**
* Absolute URL the OIDC provider redirects back to after authorization.
+4 -4
View File
@@ -70,12 +70,12 @@ import {
THREAD_NOTIFICATIONS_FALLBACK_BEHAVIOR,
} from '../../utils/threadNotifications';
const LogoSVG = withOriginBaseUrl(getOriginBaseUrl(), '/lotus.png');
const LogoUnreadSVG = withOriginBaseUrl(getOriginBaseUrl(), '/lotus-unread.png');
const LogoHighlightSVG = withOriginBaseUrl(getOriginBaseUrl(), '/lotus-highlight.png');
// Grace period after the initial sync settles before invite notifications arm, so
// the async invite-atom population lands first and isn't mistaken for new invites.
const LogoSVG = withOriginBaseUrl(getOriginBaseUrl(), '/public/res/lotus.png');
const LogoUnreadSVG = withOriginBaseUrl(getOriginBaseUrl(), '/public/res/lotus-unread.png');
const LogoHighlightSVG = withOriginBaseUrl(getOriginBaseUrl(), '/public/res/lotus-highlight.png');
const INVITE_NOTIFY_ARM_DELAY_MS = 3000;
function SystemEmojiFeature() {
+2 -2
View File
@@ -1,10 +1,10 @@
import React from 'react';
import { Box, Button, Icon, Icons, Text, config, toRem } from 'folds';
import { Page, PageHero, PageHeroSection } from '../../components/page';
import { getOriginBaseUrl, withOriginBaseUrl } from '../pathUtils';
import pkg from '../../../../package.json';
import { getOriginBaseUrl, withOriginBaseUrl } from '../pathUtils';
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/public/res/Lotus.png');
const LotusLogo = withOriginBaseUrl(getOriginBaseUrl(), '/Lotus.png');
export function WelcomePage() {
return (
+1 -1
View File
@@ -246,7 +246,7 @@ const vendorChunks = (id) => {
export default defineConfig({
appType: 'spa',
publicDir: false,
publicDir: './public/res',
base: buildConfig.base,
server: {
port: 8080,