From c69070a6e6eb9ecbaff3a9034cf893f178097905 Mon Sep 17 00:00:00 2001 From: Frederik Spirgi Date: Wed, 30 Sep 2026 11:05:13 +0200 Subject: [PATCH] make some overall QoL improvements --- README.md | 11 +++- eslint.config.js | 2 +- package.json | 2 +- public/chat.html | 14 +++-- public/js/market.js | 27 +++++---- public/js/script.js | 91 +++++++++++++++++++------------ public/js/settings.js | 19 +++++-- public/js/workspaceNavigation.js | 2 +- public/market.html | 4 +- public/settings.html | 2 +- src/app.js | 2 +- src/db/repositories.js | 7 ++- src/routes/chats.js | 82 +++++++++++++++++++++++++++- src/routes/personas.js | 6 +- src/services/attachmentService.js | 6 +- src/services/chatService.js | 2 +- test/app.test.js | 24 ++++++++ test/attachments.test.js | 31 +++++++++++ 18 files changed, 256 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index f77eaf5..514737d 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,15 @@ Outside production, the default directory is `data/uploads`; `UPLOAD_DIR` overri it. Startup creates the directory and checks write permission, failing clearly rather than falling back to another location. Files use `YYYY/MM/DD/.` keys. Do not publish this directory as a static directory. Back up **both the SQLite database -and uploads directory**. JSON workspace exports contain attachment references only; -imports reconnect existing images owned by the same account, not portable image bytes. +and uploads directory** for server recovery. The workspace's **Download workspace archive** +button saves a `.tar.gz` containing `workspace.json` and referenced images; import that +archive on another installation to restore chats with attachments. The importer also +accepts older JSON exports, which contain attachment references only and reconnect +images only when those IDs already belong to the importing account. Archives are +limited to 250 MB uncompressed, and each image must meet the destination's upload limit. + +`CHAT_LIMIT` defaults to 10 active chats per account. Archived chats remain available +without using an active slot; restoring one requires a free slot. Authenticated API endpoints: diff --git a/eslint.config.js b/eslint.config.js index 963962d..9851b1e 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -6,5 +6,5 @@ import globals from "globals"; import { defineConfig } from "eslint/config"; export default defineConfig([ - { files: ["**/*.{js,mjs,cjs}"], plugins: { js }, extends: ["js/recommended"], languageOptions: { globals: globals.browser } }, + { files: ["**/*.{js,mjs,cjs}"], plugins: { js }, extends: ["js/recommended"], languageOptions: { globals: {...globals.browser, ...globals.node} } }, ]); diff --git a/package.json b/package.json index 0851eaf..9ce6d02 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "scripts": { "start": "node server.js", "dev": "node --watch server.js", - "lint": "node scripts/lint.mjs", + "lint": "eslint .", "test": "node --test" }, "dependencies": { diff --git a/public/chat.html b/public/chat.html index c83b763..19ecd0a 100644 --- a/public/chat.html +++ b/public/chat.html @@ -221,12 +221,12 @@ data-chat-action="personaState">Roleplay state + type="button">Download workspace archive + accept="application/json,.json,.tar.gz,application/gzip" />
@@ -316,7 +316,7 @@