Rework browser launch functionality (#4143) * Add browser selection to auto-launch * Update readmes * Update readme * Display browser name in a console

87f618d15cb03b2cf755e98d498295ceacc8283f

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
12 files changed, +407 -266Ignore whitespace
.github/readme-de_de.md+23 -23
@@ -320,29 +320,29 @@ Start.bat --port 8000 --listen false
320320
321321### Unterstützte Argumente
322322
323323| Option | Beschreibung | Typ |
324324|-------------------------|---------|--------------------------------------------------------------------------------------------------|----------|
325325| `--version` | Versionsnummer anzeigen | boolean |
326326| `--enableIPv6` | Aktiviert IPv6. | boolean |
327327| `--enableIPv4` | Aktiviert IPv4. | boolean |
328328| `--port` | Legt den Port fest, unter dem SillyTavern ausgeführt wird. Wenn nicht angegeben, wird auf YAML-Konfiguration „Port“ zurückgegriffen. | number |
329329| `--dnsPreferIPv6` | Bevorzugt IPv6 für DNS. Wenn nicht angegeben, wird auf YAML-Konfiguration „preferIPv6“ zurückgegriffen. | boolean |
330330| `--autorun“ browserLaunchEnabled` | Startet SillyTavern automatisch im Browser. Wenn nicht angegeben, wird auf YAML-Konfiguration „autorun“ zurückgegriffen. | boolean |
331331| `--autorunHostname“ browserLaunchHostname` | Der Autorun-Hostname, am besten auf „auto" belassen. | string |
332332| `--autorunPortOverride“ browserLaunchPort` | Überschreibt den Port für Autorun. | string |
333-| „--listen“ | SillyTavern lauscht auf allen Netzwerkschnittstellen. Wenn nicht angegeben, wird auf YAML-Konfiguration „listen“ zurückgegriffen.| boolean |
333+| `--browserLaunchAvoidLocalhost` | Vermeidet die Verwendung von „localhost" für Autorun im Auto-Modus. | boolean |
334-| „--corsProxy“ | Aktiviert CORS-Proxy. Wenn nicht angegeben, wird auf YAML-Konfiguration „enableCorsProxy“ zurückgegriffen. | boolean |
334+| `--listen` | SillyTavern lauscht auf allen Netzwerkschnittstellen. | boolean |
335335| `--disableCsrfcorsProxy` | DeaktiviertAktiviert CSRFCORS-SchutzProxy. Wenn nicht angegeben. | boolean |
336336| `--ssldisableCsrf` | Aktiviert SSLDeaktiviert CSRF-Schutz | boolean |
337337| `--certPathssl` | Pfad zu Ihrer Zertifikatsdatei.Aktiviert SSL | string boolean |
338338| `--keyPathcertPath` | Pfad zu Ihrer privaten SchlüsseldateiZertifikatsdatei. | string |
339339| `--whitelistkeyPath` | AktiviertPfad denzu Whitelist-ModusIhrer |privaten booleanSchlüsseldatei. | string |
340340| `--dataRootwhitelist` | Stammverzeichnis fürAktiviert Datenspeicherungden Whitelist-Modus | string boolean |
341-| `--avoidLocalhost` | Vermeidet die Verwendung von „localhost“ für Autorun im Auto-Modus. | boolean |
341+| `--dataRoot` | Stammverzeichnis für Datenspeicherung | string |
342342| `--basicAuthMode` | Aktiviert die grundlegende Authentifizierung | boolean |
343343| `--requestProxyEnabled` | Aktiviert die Verwendung eines Proxys für ausgehende Anfragen | boolean |
344344| `--requestProxyUrl` | Proxy-URL anfordern (HTTP- oder SOCKS-Protokolle) | string |
345345| `--requestProxyBypass` | Proxy-Bypass-Liste anfordern (durch Leerzeichen getrennte Liste von Hosts) | Array |
346346
347347## Remoteverbindungen
348348
.github/readme-ko_kr.md+23 -23
@@ -334,29 +334,29 @@ Start.bat --port 8000 --listen false
334334
335335### 지원되는 인수
336336
337337| 옵션 | 설명 | 타입 |
338338|-------------------------|----------------|--------------------------------------------------------------------------------------|----------|
339339| `--version` | 버전 표시 | boolean |
340340| `--enableIPv6` | IPv6 활성화 | boolean |
341341| `--enableIPv4` | IPv4 활성화 | boolean |
342342| `--port` | SillyTavern이 실행될 포트를 설정합니다. 설정되지 않은 경우 yaml config 'port'를 불러옵니다. | number |
343343| `--dnsPreferIPv6` | DNS에 IPv6를 우선으로 할당합니다. 설정되지 않은 경우 yaml config를 불러옵니다. | boolean |
344344| `--autorunbrowserLaunchEnabled` | 브라우저에서 SillyTavern을 자동으로 실행합니다. 설정되지 않은 경우 yaml config 'autorun'를 불러옵니다. | boolean |
345345| `--autorunHostnamebrowserLaunchHostname` | 자동 실행 호스트 이름, 'auto'가 최적의 설정일 것입니다. | string |
346346| `--autorunPortOverridebrowserLaunchPort` | 자동 실행 포트 덮어쓰기 | string |
347347| `--listenbrowserLaunchAvoidLocalhost` | SillyTavern이 모든 네트워크 인터페이스에서 수신 대기합니다. 설정되지자동 않은모드에서 경우자동 yaml실행 구성 'listenlocalhost' 불러옵니다. 사용 방지 | boolean |
348348| `--corsProxylisten` | CORS 프록시 활성화. 설정되지 않은SillyTavern이 경우모든 yaml네트워크 구성인터페이스에서 'enableCorsProxy'을수신 불러옵니다대기합니다. | boolean |
349349| `--disableCsrfcorsProxy` | CSRFCORS 보호프록시 비활성화 활성화. | boolean |
350350| `--ssldisableCsrf` | SSLCSRF 활성화 보호 비활성화 | boolean |
351351| `--certPathssl` | 인증서 파일SSL 경로 활성화 | string boolean |
352352| `--keyPathcertPath` | 프라이빗 키인증서 파일 경로 | string |
353353| `--whitelistkeyPath` | 화이트리스트프라이빗 모드 활성화 파일 경로 | boolean string |
354354| `--dataRootwhitelist` | 데이터 스토리지의화이트리스트 루트모드 디렉토리 활성화 | string boolean |
355355| `--avoidLocalhostdataRoot` | 자동 모드에서 자동 실행 시데이터 'localhost'스토리지의 사용루트 방지 디렉토리 | boolean string |
356356| `--basicAuthMode` | 기본 인증 활성화 | boolean |
357357| `--requestProxyEnabled` | 외부 리퀘스트 프록시 활성화 | boolean |
358358| `--requestProxyUrl` | 프록시 URL 리퀘스트 (HTTP 혹은 SOCKS 프로토콜) | string |
359359| `--requestProxyBypass` | 프록시 바이패스 리스트 리퀘스트 (공백으로 구분된 호스트 목록) | array |
360360
361361## 원격 연결
362362
.github/readme-ru_ru.md+23 -23
@@ -283,29 +283,29 @@ Start.bat --port 8000 --listen false
283283
284284### Поддерживаемые аргументы
285285
286286| Аргумент | Описание | Тип |
287287|-------------------------|-----|-----------------------------------------------------------------------------------------------------------|----------|
288288| `--version` | Показывает номер версии. | boolean |
289289| `--enableIPv6` | Включает IPv6. | boolean |
290290| `--enableIPv4` | Включает IPv4. | boolean |
291291| `--port` | Устанавливает порт, котрыйкоторый будет использовать SillyTavern. Если не указан, то используется yaml-конфиг 'port'. | number |
292292| `--dnsPreferIPv6` | Отдает предпочтение IPv6 для dns. Если не указан, то используется yaml-конфиг 'preferIPv6'. | boolean |
293293| `--autorunbrowserLaunchEnabled` | Автоматический запуск SillyTavern в браузере. Если не указан, то используется yaml-конфиг 'autorun'. | boolean |
294294| `--autorunHostnamebrowserLaunchHostname` | Имя хоста автозапуска, лучше оставить на 'auto'. | string |
295295| `--autorunPortOverridebrowserLaunchPort` | Переопределяет порт для автозапуска. | string |
296296| `--listenbrowserLaunchAvoidLocalhost` | SillyTavern будет прослушивать все сетевые интерфейсы.Избегает Еслииспользования не'localhost' указан,для тоавтозапуска используетсяв yaml-конфигрежиме 'listenauto'. | boolean |
297297| `--corsProxylisten` | Включает CORS-прокси. Если неSillyTavern указан,будет топрослушивать используетсявсе yaml-конфигсетевые 'enableCorsProxy'интерфейсы. | boolean |
298298| `--disableCsrfcorsProxy` | Отключает защиту отВключает CSRFCORS-прокси. | boolean |
299299| `--ssldisableCsrf` | ВключаетОтключает SSLзащиту от CSRF. | boolean |
300300| `--certPathssl` | Путь к файлу cВключает сертификатомSSL. | string boolean |
301301| `--keyPathcertPath` | Путь к файлу с закрытымc ключомсертификатом. | string |
302302| `--whitelistkeyPath` | ВключаетПуть режимк белогофайлу спискас закрытым ключом. | booleanstring |
303303| `--dataRootwhitelist` | Корневой каталогВключает длярежим хранениябелого данныхсписка. | string boolean |
304304| `--avoidLocalhostdataRoot` | Избегает использованияКорневой 'localhost'каталог для автозапуска в режимехранения 'auto'данных. | booleanstring |
305305| `--basicAuthMode` | Включает простую аутентификацию. | boolean |
306306| `--requestProxyEnabled` | Разрешает использование прокси для исходящих запросов. | boolean |
307307| `--requestProxyUrl` | URL-адрес прокси (протоколы HTTP или SOCKS). | string |
308308| `--requestProxyBypass` | Bypass список прокси (список хостов, разделенных пробелами). | array |
309309
310310## Удалённое подключение
311311
.github/readme-zh_cn.md+26 -26
@@ -336,32 +336,32 @@ Start.bat --port 8000 --listen false
336336> \[!TIP]
337337> 所有参数都不是必需的。如果您不提供它们,SillyTavern 将使用 `config.yaml` 中的设置。
338338
339339| 选项 | 描述 | 类型 |
340340| -------------------------------- | ---------------------------------------------- | ------- |
341341| `--version` | 显示版本号 | boolean |
342342| `--configPath` | 覆盖 config.yaml 文件的路径 | string |
343343| `--dataRoot` | 数据存储的根目录 | string |
344344| `--port` | 设置 SillyTavern 将在其下运行的端口 | number |
345345| `--listen` | SillyTavern 将侦听所有网络接口 | boolean |
346346| `--whitelist` | 启用白名单模式 | boolean |
347347| `--basicAuthMode` | 启用基本身份验证 | boolean |
348348| `--enableIPv4` | 启用 IPv4 协议 | boolean |
349349| `--enableIPv6` | 启用 IPv6 协议 | boolean |
350350| `--listenAddressIPv4` | 要侦听的特定 IPv4 地址 | string |
351351| `--listenAddressIPv6` | 要侦听的特定 IPv6 地址 | string |
352352| `--dnsPreferIPv6` | DNS 首选 IPv6 | boolean |
353353| `--ssl` | 启用 SSL | boolean |
354354| `--certPath` | 您的证书文件路径 | string |
355355| `--keyPath` | 您的私钥文件路径 | string |
356356| `--autorunbrowserLaunchEnabled` | 自动在浏览器中启动 SillyTavern | boolean |
357357| `--autorunHostnamebrowserLaunchHostname` | 自动运行主机名 | string |
358358| `--autorunPortOverridebrowserLaunchPort` | 覆盖自动运行的端口 | string |
359359| `--avoidLocalhostbrowserLaunchAvoidLocalhost` | 在自动模式下避免使用 'localhost' 进行自动运行 | boolean |
360360| `--corsProxy` | 启用 CORS 代理 | boolean |
361361| `--requestProxyEnabled` | 为传出请求启用代理 | boolean |
362362| `--requestProxyUrl` | 请求代理 URL(HTTP 或 SOCKS 协议) | string |
363363| `--requestProxyBypass` | 请求代理绕过列表(以空格分隔的主机列表) | array |
364364| `--disableCsrf` | 禁用 CSRF 保护(不推荐) | boolean |
365365
366366## 远程连接
367367
.github/readme-zh_tw.md+23 -23
@@ -319,29 +319,29 @@ Start.bat --port 8000 --listen false
319319
320320### Supported arguments
321321
322322| Option | Description | Type |
323323|-------------------------|---------------------------------------------------------|---------------------------------------------|----------|
324324| `--version` | 顯示版本序號 | boolean |
325325| `--enableIPv6` | 啟用 IPv6 | boolean |
326326| `--enableIPv4` | 啟用 IPv4 | boolean |
327327| `--port` | 設定 SillyTavern 運行的端口。若未提供,則預設使用 `config.yaml` 中的 'port' | number |
328328| `--dnsPreferIPv6` | 偏好使用 IPv6 解析 DNS。未提供則默認使用 `config.yaml` 中的 'preferIPv6' | boolean |
329329| `--autorunbrowserLaunchEnabled` | 自動在瀏覽器中啟動 SillyTavern。未提供則默認使用 `config.yaml` 中的 'autorun' | boolean |
330330| `--autorunHostnamebrowserLaunchHostname` | 自動啟動時的主機名稱,通常建議保持為 'auto' | string |
331331| `--autorunPortOverridebrowserLaunchPort` | 覆蓋自動啟動的端口設定 | string |
332332| `--listenbrowserLaunchAvoidLocalhost` | SillyTavern 是否可監聽所有網路接口。若未提供,則默認使用 `config.yaml` 中的在自動模式下避免使用 'listenlocalhost' | boolean |
333-| `--corsProxy` | 啟用 CORS 代理。若未提供,則默認使用 `config.yaml` 中的 'enableCorsProxy' | boolean |
333+| `--listen` | SillyTavern 是否可監聽所有網路接口。 | boolean |
334334| `--disableCsrfcorsProxy` | 停用啟用 CSRFCORS 保護 代理。 | boolean |
335335| `--ssldisableCsrf` | 啟用停用 SSL CSRF 保護 | boolean |
336336| `--certPathssl` | 設定您證書文件的路徑 啟用 SSL | string boolean |
337337| `--keyPathcertPath` | 設定您私人金鑰文件的路徑 設定您證書文件的路徑 | string |
338338| `--whitelistkeyPath` | 啟用白名單模式 設定您私人金鑰文件的路徑 | booleanstring |
339339| `--dataRootwhitelist` | 設定數據儲存的根目錄 啟用白名單模式 | string boolean |
340340| `--avoidLocalhostdataRoot` | 在自動模式下避免使用 'localhost' 設定數據儲存的根目錄 | booleanstring |
341341| `--basicAuthMode` | 啟用基本身份驗證模式 | boolean |
342342| `--requestProxyEnabled` | 啟用代理以處理外部請求 | boolean |
343343| `--requestProxyUrl` | 設定請求代理的 URL(支持 HTTP 或 SOCKS 協議) | string |
344344| `--requestProxyBypass` | 請求代理的例外主機清單(主機列表需以空格分隔) | array |
345345
346346## 遠端連線
347347
.github/readme.md+26 -26
@@ -333,32 +333,32 @@ Start.bat --port 8000 --listen false
333333> \[!TIP]
334334> None of the arguments are required. If you don't provide them, SillyTavern will use the settings in `config.yaml`.
335335
336336| Option | Description | Type |
337337|---------------------------------|----------------------------------------------------------------------|----------|
338338| `--version` | Show version number | boolean |
339339| `--configPath` | Override the path to the config.yaml file | string |
340340| `--dataRoot` | Root directory for data storage | string |
341341| `--port` | Sets the port under which SillyTavern will run | number |
342342| `--listen` | SillyTavern will listen on all network interfaces | boolean |
343343| `--whitelist` | Enables whitelist mode | boolean |
344344| `--basicAuthMode` | Enables basic authentication | boolean |
345345| `--enableIPv4` | Enables IPv4 protocol | boolean |
346346| `--enableIPv6` | Enables IPv6 protocol | boolean |
347347| `--listenAddressIPv4` | Specific IPv4 address to listen to | string |
348348| `--listenAddressIPv6` | Specific IPv6 address to listen to | string |
349349| `--dnsPreferIPv6` | Prefers IPv6 for DNS | boolean |
350350| `--ssl` | Enables SSL | boolean |
351351| `--certPath` | Path to your certificate file | string |
352352| `--keyPath` | Path to your private key file | string |
353353| `--autorunbrowserLaunchEnabled` | Automatically launch SillyTavern in the browser | boolean |
354354| `--autorunHostnamebrowserLaunchHostname` | AutorunBrowser launch hostname | string |
355355| `--autorunPortOverridebrowserLaunchPort` | Overrides the port for autorun browser launch | string |
356356| `--avoidLocalhostbrowserLaunchAvoidLocalhost` | Avoids using 'localhost' for autorunbrowser launch in auto mode | boolean |
357357| `--corsProxy` | Enables CORS proxy | boolean |
358358| `--requestProxyEnabled` | Enables a use of proxy for outgoing requests | boolean |
359359| `--requestProxyUrl` | Request proxy URL (HTTP or SOCKS protocols) | string |
360360| `--requestProxyBypass` | Request proxy bypass list (space separated list of hosts) | array |
361361| `--disableCsrf` | Disables CSRF protection (NOT RECOMMENDED) | boolean |
362362
363363## Remote connections
364364
default/config.yaml+19 -14
@@ -16,16 +16,27 @@ protocol:
1616 ipv6: false
1717# Prefers IPv6 for DNS. Enable this on ISPs that don't have issues with IPv6
1818dnsPreferIPv6: false
19-# The hostname that autorun opens.
19+# -- BROWSER LAUNCH CONFIGURATION --
20-# - Use "auto" to let the server decide
20+browserLaunch:
21-# - Use options like 'localhost', 'st.example.com'
21+ # Open the browser automatically on server startup.
22-autorunHostname: "auto"
22+ enabled: true
23+ # Browser to use for opening the URL.
24+ # - Use "default" to use the system default browser
25+ # - Use "firefox", "chrome", "edge"
26+ browser: 'default'
27+ # Overrides the hostname that opens in the browser.
28+ # - Use "auto" to let the server decide
29+ # - Use options like 'localhost', 'st.example.com'
30+ hostname: 'auto'
31+ # Overrides the port for run in the browser.
32+ # - Use -1 to use the server port.
33+ # - Specify a port to override the default.
34+ port: -1
35+ # Avoids using 'localhost' as the hostname in auto mode.
36+ # Use if you don't have 'localhost' in your hosts file
37+ avoidLocalhost: false
2338# Server port
2439port: 8000
25-# Overrides the port for autorun in browser.
26-# - Use -1 to use the server port.
27-# - Specify a port to override the default.
28-autorunPortOverride: -1
2940# -- SSL options --
3041ssl:
3142 enabled: false
@@ -98,12 +109,6 @@ rateLimiting:
98109 # Use X-Real-IP header instead of socket IP for rate limiting
99110 # Only enable this if you are using a properly configured reverse proxy (like Nginx/traefik/Caddy)
100111 preferRealIpHeader: false
101-# -- ADVANCED CONFIGURATION --
102-# Open the browser automatically
103-autorun: true
104-# Avoids using 'localhost' for autorun in auto mode.
105-# use if you don't have 'localhost' in your hosts file
106-avoidLocalhost: false
107112
108113## BACKUP CONFIGURATION
109114backups:
package-lock.json+94 -44
@@ -77,7 +77,7 @@
7777 "multer": "^2.0.1",
7878 "node-fetch": "^3.3.2",
7979 "node-persist": "^4.0.4",
8080 "open": "^810.41.2",
8181 "png-chunk-text": "^1.0.0",
8282 "png-chunks-extract": "^1.0.0",
8383 "proxy-agent": "^6.5.0",
@@ -2991,6 +2991,21 @@
29912991 "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
29922992 "license": "MIT"
29932993 },
2994+ "node_modules/bundle-name": {
2995+ "version": "4.1.0",
2996+ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
2997+ "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
2998+ "license": "MIT",
2999+ "dependencies": {
3000+ "run-applescript": "^7.0.0"
3001+ },
3002+ "engines": {
3003+ "node": ">=18"
3004+ },
3005+ "funding": {
3006+ "url": "https://github.com/sponsors/sindresorhus"
3007+ }
3008+ },
29943009 "node_modules/busboy": {
29953010 "version": "1.6.0",
29963011 "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -3764,6 +3779,34 @@
37643779 "dev": true,
37653780 "license": "MIT"
37663781 },
3782+ "node_modules/default-browser": {
3783+ "version": "5.2.1",
3784+ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
3785+ "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
3786+ "license": "MIT",
3787+ "dependencies": {
3788+ "bundle-name": "^4.1.0",
3789+ "default-browser-id": "^5.0.0"
3790+ },
3791+ "engines": {
3792+ "node": ">=18"
3793+ },
3794+ "funding": {
3795+ "url": "https://github.com/sponsors/sindresorhus"
3796+ }
3797+ },
3798+ "node_modules/default-browser-id": {
3799+ "version": "5.0.0",
3800+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz",
3801+ "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==",
3802+ "license": "MIT",
3803+ "engines": {
3804+ "node": ">=18"
3805+ },
3806+ "funding": {
3807+ "url": "https://github.com/sponsors/sindresorhus"
3808+ }
3809+ },
37673810 "node_modules/defer-to-connect": {
37683811 "version": "2.0.1",
37693812 "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
@@ -3791,12 +3834,15 @@
37913834 }
37923835 },
37933836 "node_modules/define-lazy-prop": {
37943837 "version": "23.0.0",
37953838 "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-23.0.0.tgz",
37963839 "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4OgN+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
37973840 "license": "MIT",
37983841 "engines": {
37993842 "node": ">=812"
3843+ },
3844+ "funding": {
3845+ "url": "https://github.com/sponsors/sindresorhus"
38003846 }
38013847 },
38023848 "node_modules/degenerator": {
@@ -5545,6 +5591,24 @@
55455591 "node": ">=0.10.0"
55465592 }
55475593 },
5594+ "node_modules/is-inside-container": {
5595+ "version": "1.0.0",
5596+ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
5597+ "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
5598+ "license": "MIT",
5599+ "dependencies": {
5600+ "is-docker": "^3.0.0"
5601+ },
5602+ "bin": {
5603+ "is-inside-container": "cli.js"
5604+ },
5605+ "engines": {
5606+ "node": ">=14.16"
5607+ },
5608+ "funding": {
5609+ "url": "https://github.com/sponsors/sindresorhus"
5610+ }
5611+ },
55485612 "node_modules/is-path-inside": {
55495613 "version": "3.0.3",
55505614 "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
@@ -5567,27 +5631,15 @@
55675631 }
55685632 },
55695633 "node_modules/is-wsl": {
55705634 "version": "23.21.0",
55715635 "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-23.21.0.tgz",
55725636 "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcnUcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7LwwzVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
55735637 "license": "MIT",
55745638 "dependencies": {
55755639 "is-dockerinside-container": "^21.0.0"
5576- },
5577- "engines": {
5578- "node": ">=8"
5579- }
5580- },
5581- "node_modules/is-wsl/node_modules/is-docker": {
5582- "version": "2.2.1",
5583- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
5584- "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
5585- "license": "MIT",
5586- "bin": {
5587- "is-docker": "cli.js"
55885640 },
55895641 "engines": {
55905642 "node": ">=816"
55915643 },
55925644 "funding": {
55935645 "url": "https://github.com/sponsors/sindresorhus"
@@ -6367,32 +6419,18 @@
63676419 }
63686420 },
63696421 "node_modules/open": {
63706422 "version": "810.41.2",
63716423 "resolved": "https://registry.npmjs.org/open/-/open-810.41.2.tgz",
63726424 "integrity": "sha512-7x81NCL719oNbsq/3mhcxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQBZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==",
63736425 "license": "MIT",
63746426 "dependencies": {
63756427 "define-lazydefault-propbrowser": "^25.02.01",
63766428 "isdefine-dockerlazy-prop": "^23.10.10",
63776429 "is-wslinside-container": "^21.20.0",
6430+ "is-wsl": "^3.1.0"
63786431 },
63796432 "engines": {
63806433 "node": ">=1218"
6381- },
6382- "funding": {
6383- "url": "https://github.com/sponsors/sindresorhus"
6384- }
6385- },
6386- "node_modules/open/node_modules/is-docker": {
6387- "version": "2.2.1",
6388- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
6389- "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
6390- "license": "MIT",
6391- "bin": {
6392- "is-docker": "cli.js"
6393- },
6394- "engines": {
6395- "node": ">=8"
63966434 },
63976435 "funding": {
63986436 "url": "https://github.com/sponsors/sindresorhus"
@@ -7219,6 +7257,18 @@
72197257 "url": "https://github.com/sponsors/isaacs"
72207258 }
72217259 },
7260+ "node_modules/run-applescript": {
7261+ "version": "7.0.0",
7262+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz",
7263+ "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==",
7264+ "license": "MIT",
7265+ "engines": {
7266+ "node": ">=18"
7267+ },
7268+ "funding": {
7269+ "url": "https://github.com/sponsors/sindresorhus"
7270+ }
7271+ },
72227272 "node_modules/run-parallel": {
72237273 "version": "1.2.0",
72247274 "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
package.json+1 -1
@@ -67,7 +67,7 @@
6767 "multer": "^2.0.1",
6868 "node-fetch": "^3.3.2",
6969 "node-persist": "^4.0.4",
7070 "open": "^810.41.2",
7171 "png-chunk-text": "^1.0.0",
7272 "png-chunks-extract": "^1.0.0",
7373 "proxy-agent": "^6.5.0",
src/command-line.js+97 -54
@@ -15,24 +15,24 @@ import { initConfig } from './config-init.js';
1515 * @property {boolean|string} enableIPv4 If enable IPv4 protocol ("auto" is also allowed)
1616 * @property {boolean|string} enableIPv6 If enable IPv6 protocol ("auto" is also allowed)
1717 * @property {boolean} dnsPreferIPv6 If prefer IPv6 for DNS
1818 * @property {boolean} autorunbrowserLaunchEnabled If automatically launch SillyTavern in the browser
1919 * @property {string} autorunHostnamebrowserLaunchHostname AutorunBrowser launch hostname
2020 * @property {number} autorunPortOverridebrowserLaunchPort AutorunBrowser launch port override (-1 is use server port)
21+ * @property {boolean} browserLaunchAvoidLocalhost If avoid using 'localhost' for browser launch in auto mode
2122 * @property {boolean} enableCorsProxy If enable CORS proxy
2223 * @property {boolean} disableCsrf If disable CSRF protection
2324 * @property {boolean} ssl If enable SSL
2425 * @property {string} certPath Path to certificate
2526 * @property {string} keyPath Path to private key
2627 * @property {boolean} whitelistMode If enable whitelist mode
27- * @property {boolean} avoidLocalhost If avoid using 'localhost' for autorun in auto mode
2828 * @property {boolean} basicAuthMode If enable basic authentication
2929 * @property {boolean} requestProxyEnabled If enable outgoing request proxy
3030 * @property {string} requestProxyUrl Request proxy URL
3131 * @property {string[]} requestProxyBypass Request proxy bypass list
3232 * @property {function(): URL} getIPv4ListenUrl Get IPv4 listen URL
3333 * @property {function(): URL} getIPv6ListenUrl Get IPv6 listen URL
3434 * @property {function(import('./server-startup.js').ServerStartupResult): Promise<string>} getAutorunHostnamegetBrowserLaunchHostname Get autorunbrowser launch hostname
3535 * @property {function(string): URL} getAutorunUrlgetBrowserLaunchUrl Get autorunbrowser launch URL
3636 */
3737
3838/**
@@ -51,16 +51,16 @@ export class CommandLineParser {
5151 enableIPv4: true,
5252 enableIPv6: false,
5353 dnsPreferIPv6: false,
5454 autorunbrowserLaunchEnabled: false,
5555 autorunHostnamebrowserLaunchHostname: 'auto',
5656 autorunPortOverridebrowserLaunchPort: -1,
57+ browserLaunchAvoidLocalhost: false,
5758 enableCorsProxy: false,
5859 disableCsrf: false,
5960 ssl: false,
6061 certPath: 'certs/cert.pem',
6162 keyPath: 'certs/privkey.pem',
6263 whitelistMode: true,
63- avoidLocalhost: false,
6464 basicAuthMode: false,
6565 requestProxyEnabled: false,
6666 requestProxyUrl: '',
@@ -71,11 +71,11 @@ export class CommandLineParser {
7171 getIPv6ListenUrl: function () {
7272 throw new Error('getIPv6ListenUrl is not implemented');
7373 },
7474 getAutorunHostnamegetBrowserLaunchHostname: async function () {
7575 throw new Error('getAutorunHostnamegetBrowserLaunchHostname is not implemented');
7676 },
7777 getAutorunUrlgetBrowserLaunchUrl: function () {
7878 throw new Error('getAutorunUrlgetBrowserLaunchUrl is not implemented');
7979 },
8080 });
8181
@@ -100,90 +100,133 @@ export class CommandLineParser {
100100 type: 'string',
101101 default: null,
102102 describe: 'Enables IPv6 protocol',
103- }).option('enableIPv4', {
103+ })
104+ .option('enableIPv4', {
104105 type: 'string',
105106 default: null,
106107 describe: 'Enables IPv4 protocol',
107- }).option('port', {
108+ })
109+ .option('port', {
108110 type: 'number',
109111 default: null,
110112 describe: 'Sets the server listening port',
111- }).option('dnsPreferIPv6', {
113+ })
114+ .option('dnsPreferIPv6', {
112115 type: 'boolean',
113116 default: null,
114117 describe: 'Prefers IPv6 for DNS\nYou should probably have the enabled if you\'re on an IPv6 only network',
115- }).option('autorun', {
118+ })
119+ .option('browserLaunchEnabled', {
116120 type: 'boolean',
117121 default: null,
118122 describe: 'Automatically launch SillyTavern in the browser',
119- }).option('autorunHostname', {
123+ })
124+ .option('browserLaunchHostname', {
120125 type: 'string',
121126 default: null,
122127 describe: 'Sets the autorunbrowser launch hostname, probably best left on \'auto\'.\nUse values like \'localhost\', \'st.example.com\'',
123- }).option('autorunPortOverride', {
128+ })
124- type: 'string',
129+ .option('browserLaunchPort', {
130+ type: 'number',
131+ default: null,
132+ describe: 'Overrides the port for browser launch with open your browser with this port and ignore what port the server is running on. -1 is use server port',
133+ })
134+ .option('browserLaunchAvoidLocalhost', {
135+ type: 'boolean',
125136 default: null,
126- describe: 'Overrides the port for autorun with open your browser with this port and ignore what port the server is running on. -1 is use server port',
137+ describe: 'Avoids using \'localhost\' for browser launch in auto mode.\nUse if you don\'t have \'localhost\' in your hosts file',
127- }).option('listen', {
138+ })
139+ .option('listen', {
128140 type: 'boolean',
129141 default: null,
130142 describe: 'Whether to listen on all network interfaces',
131- }).option('listenAddressIPv6', {
143+ })
144+ .option('listenAddressIPv6', {
132145 type: 'string',
133146 default: null,
134147 describe: 'Specific IPv6 address to listen to',
135- }).option('listenAddressIPv4', {
148+ })
149+ .option('listenAddressIPv4', {
136150 type: 'string',
137151 default: null,
138152 describe: 'Specific IPv4 address to listen to',
139- }).option('corsProxy', {
153+ })
154+ .option('corsProxy', {
140155 type: 'boolean',
141156 default: null,
142157 describe: 'Enables CORS proxy',
143- }).option('disableCsrf', {
158+ })
159+ .option('disableCsrf', {
144160 type: 'boolean',
145161 default: null,
146162 describe: 'Disables CSRF protection - NOT RECOMMENDED',
147- }).option('ssl', {
163+ })
164+ .option('ssl', {
148165 type: 'boolean',
149166 default: null,
150167 describe: 'Enables SSL',
151- }).option('certPath', {
168+ })
169+ .option('certPath', {
152170 type: 'string',
153171 default: null,
154172 describe: 'Path to SSL certificate file',
155- }).option('keyPath', {
173+ })
174+ .option('keyPath', {
156175 type: 'string',
157176 default: null,
158177 describe: 'Path to SSL private key file',
159- }).option('whitelist', {
178+ })
179+ .option('whitelist', {
160180 type: 'boolean',
161181 default: null,
162182 describe: 'Enables whitelist mode',
163- }).option('dataRoot', {
183+ })
184+ .option('dataRoot', {
164185 type: 'string',
165186 default: null,
166187 describe: 'Root directory for data storage',
167- }).option('avoidLocalhost', {
188+ })
168- type: 'boolean',
189+ .option('basicAuthMode', {
169- default: null,
170- describe: 'Avoids using \'localhost\' for autorun in auto mode.\nUse if you don\'t have \'localhost\' in your hosts file',
171- }).option('basicAuthMode', {
172190 type: 'boolean',
173191 default: null,
174192 describe: 'Enables basic authentication',
175- }).option('requestProxyEnabled', {
193+ })
194+ .option('requestProxyEnabled', {
176195 type: 'boolean',
177196 default: null,
178197 describe: 'Enables a use of proxy for outgoing requests',
179- }).option('requestProxyUrl', {
198+ })
199+ .option('requestProxyUrl', {
180200 type: 'string',
181201 default: null,
182202 describe: 'Request proxy URL (HTTP or SOCKS protocols)',
183- }).option('requestProxyBypass', {
203+ })
204+ .option('requestProxyBypass', {
184205 type: 'array',
185206 describe: 'Request proxy bypass list (space separated list of hosts)',
186207 }).parseSync();
208+ /* DEPRECATED options */
209+ .option('autorun', {
210+ type: 'boolean',
211+ default: null,
212+ describe: 'DEPRECATED: Use "browserLaunchEnabled" instead.',
213+ })
214+ .option('autorunHostname', {
215+ type: 'string',
216+ default: null,
217+ describe: 'DEPRECATED: Use "browserLaunchHostname" instead.',
218+ })
219+ .option('autorunPortOverride', {
220+ type: 'number',
221+ default: null,
222+ describe: 'DEPRECATED: Use "browserLaunchPort" instead.',
223+ })
224+ .option('avoidLocalhost', {
225+ type: 'boolean',
226+ default: null,
227+ describe: 'DEPRECATED: Use "browserLaunchAvoidLocalhost" instead.',
228+ })
229+ .parseSync();
187230
188231 const configPath = cliArguments.configPath ?? this.default.configPath;
189232 initConfig(configPath);
@@ -198,16 +241,16 @@ export class CommandLineParser {
198241 enableIPv4: stringToBool(cliArguments.enableIPv4) ?? stringToBool(getConfigValue('protocol.ipv4', this.default.enableIPv4)) ?? this.default.enableIPv4,
199242 enableIPv6: stringToBool(cliArguments.enableIPv6) ?? stringToBool(getConfigValue('protocol.ipv6', this.default.enableIPv6)) ?? this.default.enableIPv6,
200243 dnsPreferIPv6: cliArguments.dnsPreferIPv6 ?? getConfigValue('dnsPreferIPv6', this.default.dnsPreferIPv6, 'boolean'),
201244 autorunbrowserLaunchEnabled: cliArguments.browserLaunchEnabled ?? cliArguments.autorun ?? getConfigValue('autorunbrowserLaunch.enabled', this.default.autorunbrowserLaunchEnabled, 'boolean'),
202245 autorunHostnamebrowserLaunchHostname: cliArguments.browserLaunchHostname ?? cliArguments.autorunHostname ?? getConfigValue('autorunHostnamebrowserLaunch.hostname', this.default.autorunHostnamebrowserLaunchHostname),
203246 autorunPortOverridebrowserLaunchPort: cliArguments.browserLaunchPort ?? cliArguments.autorunPortOverride ?? getConfigValue('autorunPortOverridebrowserLaunch.port', this.default.autorunPortOverridebrowserLaunchPort, 'number'),
247+ browserLaunchAvoidLocalhost: cliArguments.browserLaunchAvoidLocalhost ?? cliArguments.avoidLocalhost ?? getConfigValue('browserLaunch.avoidLocalhost', this.default.browserLaunchAvoidLocalhost, 'boolean'),
204248 enableCorsProxy: cliArguments.corsProxy ?? getConfigValue('enableCorsProxy', this.default.enableCorsProxy, 'boolean'),
205249 disableCsrf: cliArguments.disableCsrf ?? getConfigValue('disableCsrfProtection', this.default.disableCsrf, 'boolean'),
206250 ssl: cliArguments.ssl ?? getConfigValue('ssl.enabled', this.default.ssl, 'boolean'),
207251 certPath: cliArguments.certPath ?? getConfigValue('ssl.certPath', this.default.certPath),
208252 keyPath: cliArguments.keyPath ?? getConfigValue('ssl.keyPath', this.default.keyPath),
209253 whitelistMode: cliArguments.whitelist ?? getConfigValue('whitelistMode', this.default.whitelistMode, 'boolean'),
210- avoidLocalhost: cliArguments.avoidLocalhost ?? getConfigValue('avoidLocalhost', this.default.avoidLocalhost, 'boolean'),
211254 basicAuthMode: cliArguments.basicAuthMode ?? getConfigValue('basicAuthMode', this.default.basicAuthMode, 'boolean'),
212255 requestProxyEnabled: cliArguments.requestProxyEnabled ?? getConfigValue('requestProxy.enabled', this.default.requestProxyEnabled, 'boolean'),
213256 requestProxyUrl: cliArguments.requestProxyUrl ?? getConfigValue('requestProxy.url', this.default.requestProxyUrl),
@@ -228,12 +271,12 @@ export class CommandLineParser {
228271 (':' + this.port),
229272 );
230273 },
231274 getAutorunHostnamegetBrowserLaunchHostname: async function ({ useIPv6, useIPv4 }) {
232275 if (this.autorunHostnamebrowserLaunchHostname === 'auto') {
233276 letconst localhostResolve = await canResolve('localhost', useIPv6, useIPv4);
234277
235278 if (useIPv6 && useIPv4) {
236279 return (this.avoidLocalhostbrowserLaunchAvoidLocalhost || !localhostResolve) ? '[::1]' : 'localhost';
237280 }
238281
239282 if (useIPv6) {
@@ -245,15 +288,15 @@ export class CommandLineParser {
245288 }
246289 }
247290
248291 return this.autorunHostnamebrowserLaunchHostname;
249292 },
250293 getAutorunUrlgetBrowserLaunchUrl: function (hostname) {
251294 const autorunPortbrowserLaunchPort = (this.autorunPortOverridebrowserLaunchPort >= 0) ? this.autorunPortOverridebrowserLaunchPort : this.port;
252295 return new URL(
253296 (this.ssl ? 'https://' : 'http://') +
254297 (hostname) +
255298 (':') +
256299 (autorunPortbrowserLaunchPort),
257300 );
258301 },
259302 };
src/config-init.js+33 -1
@@ -4,7 +4,7 @@ import yaml from 'yaml';
44import color from 'chalk';
55import _ from 'lodash';
66import { serverDirectory } from './server-directory.js';
77import { keyToEnv, setConfigFilePath } from './util.js';
88
99const keyMigrationMap = [
1010 {
@@ -98,6 +98,26 @@ const keyMigrationMap = [
9898 migrate: () => void 0,
9999 remove: true,
100100 },
101+ {
102+ oldKey: 'autorun',
103+ newKey: 'browserLaunch.enabled',
104+ migrate: (value) => value,
105+ },
106+ {
107+ oldKey: 'autorunHostname',
108+ newKey: 'browserLaunch.hostname',
109+ migrate: (value) => value,
110+ },
111+ {
112+ oldKey: 'autorunPortOverride',
113+ newKey: 'browserLaunch.port',
114+ migrate: (value) => value,
115+ },
116+ {
117+ oldKey: 'avoidLocalhost',
118+ newKey: 'browserLaunch.avoidLocalhost',
119+ migrate: (value) => value,
120+ },
101121];
102122
103123/**
@@ -133,6 +153,18 @@ export function addMissingConfigValues(configPath) {
133153 // Migrate old keys to new keys
134154 const migratedKeys = [];
135155 for (const { oldKey, newKey, migrate, remove } of keyMigrationMap) {
156+ // Migrate environment variables
157+ const oldEnvKey = keyToEnv(oldKey);
158+ const newEnvKey = keyToEnv(newKey);
159+ if (process.env[oldEnvKey] && !process.env[newEnvKey]) {
160+ const oldValue = process.env[oldEnvKey];
161+ const newValue = migrate(oldValue);
162+ process.env[newEnvKey] = newValue;
163+ delete process.env[oldEnvKey];
164+ console.warn(color.yellow(`Warning: Using a deprecated environment variable: ${oldEnvKey}. Please use ${newEnvKey} instead.`));
165+ console.log(`Redirecting ${color.blue(oldEnvKey)}=${oldValue} -> ${color.blue(newEnvKey)}=${newValue}`);
166+ }
167+
136168 if (_.has(config, oldKey)) {
137169 if (remove) {
138170 _.unset(config, oldKey);
src/server-main.js+19 -8
@@ -14,7 +14,7 @@ import multer from 'multer';
1414import responseTime from 'response-time';
1515import helmet from 'helmet';
1616import bodyParser from 'body-parser';
1717import open, { apps } from 'open';
1818
1919// local library imports
2020import './fetch-patch.js';
@@ -65,6 +65,7 @@ import {
6565 safeReadFileSync,
6666 setupLogLevel,
6767 setWindowTitle,
68+ getConfigValue,
6869} from './util.js';
6970import { UPLOADS_DIRECTORY } from './constants.js';
7071import { ensureThumbnailCache } from './endpoints/thumbnails.js';
@@ -83,6 +84,7 @@ util.inspect.defaultOptions.maxArrayLength = null;
8384util.inspect.defaultOptions.maxStringLength = null;
8485util.inspect.defaultOptions.depth = 4;
8586
87+/** @type {import('./command-line.js').CommandLineArguments} */
8688const cliArgs = globalThis.COMMAND_LINE_ARGS;
8789
8890if (!cliArgs.enableIPv6 && !cliArgs.enableIPv4) {
@@ -321,13 +323,22 @@ async function preSetupTasks() {
321323 * @returns {Promise<void>}
322324 */
323325async function postSetupTasks(result) {
324326 const autorunHostnamebrowserLaunchHostname = await cliArgs.getAutorunHostnamegetBrowserLaunchHostname(result);
325327 const autorunUrlbrowserLaunchUrl = cliArgs.getAutorunUrlgetBrowserLaunchUrl(autorunHostnamebrowserLaunchHostname);
328+ const browserLaunchApp = String(getConfigValue('browserLaunch.browser', 'default') ?? '');
326329
327330 if (cliArgs.autorunbrowserLaunchEnabled) {
328331 try {
329- console.log('Launching in a browser...');
332+ const validBrowsers = {
330- await open(autorunUrl.toString());
333+ 'firefox': apps.firefox,
334+ 'chrome': apps.chrome,
335+ 'edge': apps.edge,
336+ };
337+ const appName = validBrowsers[browserLaunchApp.trim().toLowerCase()];
338+ const openOptions = appName ? { app: { name: appName } } : {};
339+
340+ console.log(`Launching in a browser: ${browserLaunchApp}...`);
341+ await open(browserLaunchUrl.toString(), openOptions);
331342 } catch (error) {
332343 console.error('Failed to launch the browser. Open the URL manually.');
333344 }
@@ -349,7 +360,7 @@ async function postSetupTasks(result) {
349360 );
350361 }
351362
352363 const goToLog = '`Go to: ' + ${color.blue(autorunUrlbrowserLaunchUrl) + '} to open SillyTavern'`;
353364 const plainGoToLog = removeColorFormatting(goToLog);
354365
355366 console.log(logListen);
@@ -363,7 +374,7 @@ async function postSetupTasks(result) {
363374 console.log('\n' + getSeparator(plainGoToLog.length) + '\n');
364375
365376 setupLogLevel();
366377 serverEvents.emit(EVENT_NAMES.SERVER_STARTED, { url: autorunUrlbrowserLaunchUrl });
367378}
368379
369380/**