Sync local changes
This commit is contained in:
parent
74bfcc218b
commit
577ef68dad
18 changed files with 1584 additions and 6 deletions
135
.github/workflows/desktop-release.yml
vendored
Normal file
135
.github/workflows/desktop-release.yml
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
name: Build Desktop App
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version to build (e.g., 0.1.0)'
|
||||
required: false
|
||||
default: ''
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build desktop renderer
|
||||
run: npm run build:desktop
|
||||
|
||||
- name: Build Windows installer
|
||||
run: npx electron-builder --win --config electron-builder.yml
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload Windows artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows-build
|
||||
path: dist/*.exe
|
||||
retention-days: 5
|
||||
|
||||
build-macos:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build desktop renderer
|
||||
run: npm run build:desktop
|
||||
|
||||
- name: Build macOS installer
|
||||
run: npx electron-builder --mac --config electron-builder.yml
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload macOS artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macos-build
|
||||
path: dist/*.dmg
|
||||
retention-days: 5
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build desktop renderer
|
||||
run: npm run build:desktop
|
||||
|
||||
- name: Build Linux installers
|
||||
run: npx electron-builder --linux --config electron-builder.yml
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload Linux artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: linux-build
|
||||
path: |
|
||||
dist/*.AppImage
|
||||
dist/*.deb
|
||||
retention-days: 5
|
||||
|
||||
release:
|
||||
needs: [build-windows, build-macos, build-linux]
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
steps:
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts
|
||||
|
||||
- name: Display downloaded files
|
||||
run: ls -R artifacts
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
draft: false
|
||||
prerelease: ${{ contains(github.ref_name, 'beta') || contains(github.ref_name, 'alpha') }}
|
||||
generate_release_notes: true
|
||||
files: |
|
||||
artifacts/windows-build/*.exe
|
||||
artifacts/macos-build/*.dmg
|
||||
artifacts/linux-build/*.AppImage
|
||||
artifacts/linux-build/*.deb
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
6
.replit
6
.replit
|
|
@ -5,6 +5,7 @@ integrations = ["javascript_gemini_ai_integrations:1.0.0"]
|
|||
|
||||
[nix]
|
||||
channel = "stable-25_05"
|
||||
packages = ["imagemagick"]
|
||||
|
||||
[workflows]
|
||||
runButton = "Project"
|
||||
|
|
@ -53,6 +54,10 @@ externalPort = 80
|
|||
localPort = 8044
|
||||
externalPort = 3003
|
||||
|
||||
[[ports]]
|
||||
localPort = 8080
|
||||
externalPort = 8080
|
||||
|
||||
[[ports]]
|
||||
localPort = 38557
|
||||
externalPort = 3000
|
||||
|
|
@ -70,3 +75,4 @@ build = ["npm", "run", "build"]
|
|||
|
||||
[userenv.shared]
|
||||
DISCORD_MAIN_CHAT_CHANNELS = "1425114041021497454"
|
||||
MAINTENANCE_MODE = "true"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
17s
|
||||
12s
|
||||
Run npx electron-builder --win --config electron-builder.yml
|
||||
|
||||
• electron-builder version=25.1.8 os=10.0.26100
|
||||
• artifacts will be published reason=tag is defined tag=v0.1.1
|
||||
• loaded configuration file=D:\a\aethex-forge\aethex-forge\electron-builder.yml
|
||||
• skipped dependencies rebuild reason=npmRebuild is set to false
|
||||
• packaging platform=win32 arch=x64 electron=32.3.3 appOutDir=dist\win-unpacked
|
||||
• downloading url=https://github.com/electron/electron/releases/download/v32.3.3/electron-v32.3.3-win32-x64.zip size=113 MB parts=8
|
||||
• downloaded url=https://github.com/electron/electron/releases/download/v32.3.3/electron-v32.3.3-win32-x64.zip duration=449ms
|
||||
• updating asar integrity executable resource executablePath=dist\win-unpacked\AeThex Desktop Terminal.exe
|
||||
⨯ icon directory D:\a\aethex-forge\aethex-forge\build\icons doesn't contain icons
|
||||
github.com/develar/app-builder/pkg/icons.CollectIcons
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/collect-icons.go:73
|
||||
github.com/develar/app-builder/pkg/icons.doConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:199
|
||||
github.com/develar/app-builder/pkg/icons.ConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:56
|
||||
github.com/develar/app-builder/pkg/icons.ConfigureCommand.func1
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:33
|
||||
github.com/alecthomas/kingpin.(*actionMixin).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/actions.go:28
|
||||
github.com/alecthomas/kingpin.(*Application).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:557
|
||||
github.com/alecthomas/kingpin.(*Application).execute
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:390
|
||||
github.com/alecthomas/kingpin.(*Application).Parse
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:222
|
||||
main.main
|
||||
/Users/runner/work/app-builder/app-builder/main.go:90
|
||||
runtime.main
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/proc.go:267
|
||||
runtime.goexit
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/asm_amd64.s:1650
|
||||
github.com/develar/app-builder/pkg/icons.doConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:201
|
||||
github.com/develar/app-builder/pkg/icons.ConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:56
|
||||
github.com/develar/app-builder/pkg/icons.ConfigureCommand.func1
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:33
|
||||
github.com/alecthomas/kingpin.(*actionMixin).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/actions.go:28
|
||||
github.com/alecthomas/kingpin.(*Application).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:557
|
||||
github.com/alecthomas/kingpin.(*Application).execute
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:390
|
||||
github.com/alecthomas/kingpin.(*Application).Parse
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:222
|
||||
main.main
|
||||
/Users/runner/work/app-builder/app-builder/main.go:90
|
||||
runtime.main
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/proc.go:267
|
||||
runtime.goexit
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/asm_amd64.s:1650
|
||||
⨯ D:\a\aethex-forge\aethex-forge\node_modules\app-builder-bin\win\x64\app-builder.exe process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
|
||||
Exit code:
|
||||
1 failedTask=build stackTrace=Error: D:\a\aethex-forge\aethex-forge\node_modules\app-builder-bin\win\x64\app-builder.exe process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
|
||||
Exit code:
|
||||
1
|
||||
at ChildProcess.<anonymous> (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\util.ts:255:14)
|
||||
at Object.onceWrapper (node:events:639:26)
|
||||
at ChildProcess.emit (node:events:524:28)
|
||||
at ChildProcess.cp.emit (D:\a\aethex-forge\aethex-forge\node_modules\cross-spawn\lib\enoent.js:34:29)
|
||||
at maybeClose (node:internal/child_process:1104:16)
|
||||
at Process.ChildProcess._handle.onexit (node:internal/child_process:304:5)
|
||||
From previous event:
|
||||
at processImmediate (node:internal/timers:483:21)
|
||||
From previous event:
|
||||
at WinPackager.signApp (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\winPackager.ts:270:27)
|
||||
at WinPackager.doSignAfterPack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:346:32)
|
||||
at WinPackager.doPack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:331:7)
|
||||
at WinPackager.pack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:138:5)
|
||||
at Packager.doBuild (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\packager.ts:459:9)
|
||||
at executeFinally (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\promise.ts:12:14)
|
||||
at Packager.build (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\packager.ts:393:31)
|
||||
at executeFinally (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\promise.ts:12:14)
|
||||
Error: Process completed with exit code 1.
|
||||
0s
|
||||
0s
|
||||
2s
|
||||
Post job cleanup.
|
||||
"C:\Program Files\Git\bin\git.exe" version
|
||||
git version 2.52.0.windows.1
|
||||
Temporarily overriding HOME='D:\a\_temp\4963c2ff-b212-40d1-906e-719e33666ab2' before making global git config changes
|
||||
Adding repository directory to the temporary git global config as a safe directory
|
||||
"C:\Program Files\Git\bin\git.exe" config --global --add safe.directory D:\a\aethex-forge\aethex-forge
|
||||
"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp core\.sshCommand
|
||||
"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :\""
|
||||
"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
|
||||
http.https://github.com/.extraheader
|
||||
"C:\Program Files\Git\bin\git.exe" config --local --unset-all http.https://github.com/.extraheader
|
||||
"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :\""
|
||||
"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp ^includeIf\.gitdir:
|
||||
"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "git config --local --show-origin --name-only --get-regexp remote.origin.url"
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
17s
|
||||
12s
|
||||
Run npx electron-builder --win --config electron-builder.yml
|
||||
|
||||
• electron-builder version=25.1.8 os=10.0.26100
|
||||
• artifacts will be published reason=tag is defined tag=v0.1.1
|
||||
• loaded configuration file=D:\a\aethex-forge\aethex-forge\electron-builder.yml
|
||||
• skipped dependencies rebuild reason=npmRebuild is set to false
|
||||
• packaging platform=win32 arch=x64 electron=32.3.3 appOutDir=dist\win-unpacked
|
||||
• downloading url=https://github.com/electron/electron/releases/download/v32.3.3/electron-v32.3.3-win32-x64.zip size=113 MB parts=8
|
||||
• downloaded url=https://github.com/electron/electron/releases/download/v32.3.3/electron-v32.3.3-win32-x64.zip duration=449ms
|
||||
• updating asar integrity executable resource executablePath=dist\win-unpacked\AeThex Desktop Terminal.exe
|
||||
⨯ icon directory D:\a\aethex-forge\aethex-forge\build\icons doesn't contain icons
|
||||
github.com/develar/app-builder/pkg/icons.CollectIcons
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/collect-icons.go:73
|
||||
github.com/develar/app-builder/pkg/icons.doConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:199
|
||||
github.com/develar/app-builder/pkg/icons.ConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:56
|
||||
github.com/develar/app-builder/pkg/icons.ConfigureCommand.func1
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:33
|
||||
github.com/alecthomas/kingpin.(*actionMixin).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/actions.go:28
|
||||
github.com/alecthomas/kingpin.(*Application).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:557
|
||||
github.com/alecthomas/kingpin.(*Application).execute
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:390
|
||||
github.com/alecthomas/kingpin.(*Application).Parse
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:222
|
||||
main.main
|
||||
/Users/runner/work/app-builder/app-builder/main.go:90
|
||||
runtime.main
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/proc.go:267
|
||||
runtime.goexit
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/asm_amd64.s:1650
|
||||
github.com/develar/app-builder/pkg/icons.doConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:201
|
||||
github.com/develar/app-builder/pkg/icons.ConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:56
|
||||
github.com/develar/app-builder/pkg/icons.ConfigureCommand.func1
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:33
|
||||
github.com/alecthomas/kingpin.(*actionMixin).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/actions.go:28
|
||||
github.com/alecthomas/kingpin.(*Application).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:557
|
||||
github.com/alecthomas/kingpin.(*Application).execute
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:390
|
||||
github.com/alecthomas/kingpin.(*Application).Parse
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:222
|
||||
main.main
|
||||
/Users/runner/work/app-builder/app-builder/main.go:90
|
||||
runtime.main
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/proc.go:267
|
||||
runtime.goexit
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/asm_amd64.s:1650
|
||||
⨯ D:\a\aethex-forge\aethex-forge\node_modules\app-builder-bin\win\x64\app-builder.exe process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
|
||||
Exit code:
|
||||
1 failedTask=build stackTrace=Error: D:\a\aethex-forge\aethex-forge\node_modules\app-builder-bin\win\x64\app-builder.exe process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
|
||||
Exit code:
|
||||
1
|
||||
at ChildProcess.<anonymous> (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\util.ts:255:14)
|
||||
at Object.onceWrapper (node:events:639:26)
|
||||
at ChildProcess.emit (node:events:524:28)
|
||||
at ChildProcess.cp.emit (D:\a\aethex-forge\aethex-forge\node_modules\cross-spawn\lib\enoent.js:34:29)
|
||||
at maybeClose (node:internal/child_process:1104:16)
|
||||
at Process.ChildProcess._handle.onexit (node:internal/child_process:304:5)
|
||||
From previous event:
|
||||
at processImmediate (node:internal/timers:483:21)
|
||||
From previous event:
|
||||
at WinPackager.signApp (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\winPackager.ts:270:27)
|
||||
at WinPackager.doSignAfterPack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:346:32)
|
||||
at WinPackager.doPack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:331:7)
|
||||
at WinPackager.pack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:138:5)
|
||||
at Packager.doBuild (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\packager.ts:459:9)
|
||||
at executeFinally (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\promise.ts:12:14)
|
||||
at Packager.build (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\packager.ts:393:31)
|
||||
at executeFinally (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\promise.ts:12:14)
|
||||
Error: Process completed with exit code 1.
|
||||
0s
|
||||
0s
|
||||
2s
|
||||
Post job cleanup.
|
||||
"C:\Program Files\Git\bin\git.exe" version
|
||||
git version 2.52.0.windows.1
|
||||
Temporarily overriding HOME='D:\a\_temp\4963c2ff-b212-40d1-906e-719e33666ab2' before making global git config changes
|
||||
Adding repository directory to the temporary git global config as a safe directory
|
||||
"C:\Program Files\Git\bin\git.exe" config --global --add safe.directory D:\a\aethex-forge\aethex-forge
|
||||
"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp core\.sshCommand
|
||||
"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :\""
|
||||
"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
|
||||
http.https://github.com/.extraheader
|
||||
"C:\Program Files\Git\bin\git.exe" config --local --unset-all http.https://github.com/.extraheader
|
||||
"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :\""
|
||||
"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp ^includeIf\.gitdir:
|
||||
"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "git config --local --show-origin --name-only --get-regexp remote.origin.url"
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
Run npx electron-builder --win --config electron-builder.yml
|
||||
• electron-builder version=25.1.8 os=10.0.26100
|
||||
• artifacts will be published reason=tag is defined tag=v0.1.0
|
||||
• loaded configuration file=D:\a\aethex-forge\aethex-forge\electron-builder.yml
|
||||
• skipped dependencies rebuild reason=npmRebuild is set to false
|
||||
• packaging platform=win32 arch=x64 electron=32.3.3 appOutDir=dist\win-unpacked
|
||||
• downloading url=https://github.com/electron/electron/releases/download/v32.3.3/electron-v32.3.3-win32-x64.zip size=113 MB parts=8
|
||||
• downloaded url=https://github.com/electron/electron/releases/download/v32.3.3/electron-v32.3.3-win32-x64.zip duration=592ms
|
||||
• updating asar integrity executable resource executablePath=dist\win-unpacked\AeThex Desktop Terminal.exe
|
||||
⨯ icon directory D:\a\aethex-forge\aethex-forge\build\icons doesn't contain icons
|
||||
github.com/develar/app-builder/pkg/icons.CollectIcons
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/collect-icons.go:73
|
||||
github.com/develar/app-builder/pkg/icons.doConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:199
|
||||
github.com/develar/app-builder/pkg/icons.ConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:56
|
||||
github.com/develar/app-builder/pkg/icons.ConfigureCommand.func1
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:33
|
||||
github.com/alecthomas/kingpin.(*actionMixin).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/actions.go:28
|
||||
github.com/alecthomas/kingpin.(*Application).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:557
|
||||
github.com/alecthomas/kingpin.(*Application).execute
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:390
|
||||
github.com/alecthomas/kingpin.(*Application).Parse
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:222
|
||||
main.main
|
||||
/Users/runner/work/app-builder/app-builder/main.go:90
|
||||
runtime.main
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/proc.go:267
|
||||
runtime.goexit
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/asm_amd64.s:1650
|
||||
github.com/develar/app-builder/pkg/icons.doConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:201
|
||||
github.com/develar/app-builder/pkg/icons.ConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:56
|
||||
github.com/develar/app-builder/pkg/icons.ConfigureCommand.func1
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:33
|
||||
github.com/alecthomas/kingpin.(*actionMixin).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/actions.go:28
|
||||
github.com/alecthomas/kingpin.(*Application).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:557
|
||||
github.com/alecthomas/kingpin.(*Application).execute
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:390
|
||||
github.com/alecthomas/kingpin.(*Application).Parse
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:222
|
||||
main.main
|
||||
/Users/runner/work/app-builder/app-builder/main.go:90
|
||||
runtime.main
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/proc.go:267
|
||||
runtime.goexit
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/asm_amd64.s:1650
|
||||
⨯ D:\a\aethex-forge\aethex-forge\node_modules\app-builder-bin\win\x64\app-builder.exe process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
|
||||
Exit code:
|
||||
1 failedTask=build stackTrace=Error: D:\a\aethex-forge\aethex-forge\node_modules\app-builder-bin\win\x64\app-builder.exe process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
|
||||
Exit code:
|
||||
1
|
||||
at ChildProcess.<anonymous> (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\util.ts:255:14)
|
||||
at Object.onceWrapper (node:events:639:26)
|
||||
at ChildProcess.emit (node:events:524:28)
|
||||
at ChildProcess.cp.emit (D:\a\aethex-forge\aethex-forge\node_modules\cross-spawn\lib\enoent.js:34:29)
|
||||
at maybeClose (node:internal/child_process:1104:16)
|
||||
at Process.ChildProcess._handle.onexit (node:internal/child_process:304:5)
|
||||
From previous event:
|
||||
at processImmediate (node:internal/timers:483:21)
|
||||
From previous event:
|
||||
at WinPackager.signApp (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\winPackager.ts:270:27)
|
||||
at WinPackager.doSignAfterPack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:346:32)
|
||||
at WinPackager.doPack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:331:7)
|
||||
at WinPackager.pack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:138:5)
|
||||
at Packager.doBuild (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\packager.ts:459:9)
|
||||
at executeFinally (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\promise.ts:12:14)
|
||||
at Packager.build (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\packager.ts:393:31)
|
||||
at executeFinally (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\promise.ts:12:14)
|
||||
Error: Process completed with exit code 1.
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
Run npx electron-builder --win --config electron-builder.yml
|
||||
• electron-builder version=25.1.8 os=10.0.26100
|
||||
• artifacts will be published reason=tag is defined tag=v0.1.2
|
||||
• loaded configuration file=D:\a\aethex-forge\aethex-forge\electron-builder.yml
|
||||
• skipped dependencies rebuild reason=npmRebuild is set to false
|
||||
• packaging platform=win32 arch=x64 electron=32.3.3 appOutDir=dist\win-unpacked
|
||||
• downloading url=https://github.com/electron/electron/releases/download/v32.3.3/electron-v32.3.3-win32-x64.zip size=113 MB parts=8
|
||||
• downloaded url=https://github.com/electron/electron/releases/download/v32.3.3/electron-v32.3.3-win32-x64.zip duration=732ms
|
||||
• updating asar integrity executable resource executablePath=dist\win-unpacked\AeThex Desktop Terminal.exe
|
||||
⨯ icon directory D:\a\aethex-forge\aethex-forge\build\icons doesn't contain icons
|
||||
github.com/develar/app-builder/pkg/icons.CollectIcons
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/collect-icons.go:73
|
||||
github.com/develar/app-builder/pkg/icons.doConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:199
|
||||
github.com/develar/app-builder/pkg/icons.ConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:56
|
||||
github.com/develar/app-builder/pkg/icons.ConfigureCommand.func1
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:33
|
||||
github.com/alecthomas/kingpin.(*actionMixin).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/actions.go:28
|
||||
github.com/alecthomas/kingpin.(*Application).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:557
|
||||
github.com/alecthomas/kingpin.(*Application).execute
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:390
|
||||
github.com/alecthomas/kingpin.(*Application).Parse
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:222
|
||||
main.main
|
||||
/Users/runner/work/app-builder/app-builder/main.go:90
|
||||
runtime.main
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/proc.go:267
|
||||
runtime.goexit
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/asm_amd64.s:1650
|
||||
github.com/develar/app-builder/pkg/icons.doConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:201
|
||||
github.com/develar/app-builder/pkg/icons.ConvertIcon
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:56
|
||||
github.com/develar/app-builder/pkg/icons.ConfigureCommand.func1
|
||||
/Users/runner/work/app-builder/app-builder/pkg/icons/icon-converter.go:33
|
||||
github.com/alecthomas/kingpin.(*actionMixin).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/actions.go:28
|
||||
github.com/alecthomas/kingpin.(*Application).applyActions
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:557
|
||||
github.com/alecthomas/kingpin.(*Application).execute
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:390
|
||||
github.com/alecthomas/kingpin.(*Application).Parse
|
||||
/Users/runner/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:222
|
||||
main.main
|
||||
/Users/runner/work/app-builder/app-builder/main.go:90
|
||||
runtime.main
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/proc.go:267
|
||||
runtime.goexit
|
||||
/Users/runner/hostedtoolcache/go/1.21.13/arm64/src/runtime/asm_amd64.s:1650
|
||||
⨯ D:\a\aethex-forge\aethex-forge\node_modules\app-builder-bin\win\x64\app-builder.exe process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
|
||||
Exit code:
|
||||
1 failedTask=build stackTrace=Error: D:\a\aethex-forge\aethex-forge\node_modules\app-builder-bin\win\x64\app-builder.exe process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
|
||||
Exit code:
|
||||
1
|
||||
at ChildProcess.<anonymous> (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\util.ts:255:14)
|
||||
at Object.onceWrapper (node:events:639:26)
|
||||
at ChildProcess.emit (node:events:524:28)
|
||||
at ChildProcess.cp.emit (D:\a\aethex-forge\aethex-forge\node_modules\cross-spawn\lib\enoent.js:34:29)
|
||||
at maybeClose (node:internal/child_process:1104:16)
|
||||
at Process.ChildProcess._handle.onexit (node:internal/child_process:304:5)
|
||||
From previous event:
|
||||
at processImmediate (node:internal/timers:483:21)
|
||||
From previous event:
|
||||
at WinPackager.signApp (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\winPackager.ts:270:27)
|
||||
at WinPackager.doSignAfterPack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:346:32)
|
||||
at WinPackager.doPack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:331:7)
|
||||
at WinPackager.pack (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\platformPackager.ts:138:5)
|
||||
at Packager.doBuild (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\packager.ts:459:9)
|
||||
at executeFinally (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\promise.ts:12:14)
|
||||
at Packager.build (D:\a\aethex-forge\aethex-forge\node_modules\app-builder-lib\src\packager.ts:393:31)
|
||||
at executeFinally (D:\a\aethex-forge\aethex-forge\node_modules\builder-util\src\promise.ts:12:14)
|
||||
Error: Process completed with exit code 1.
|
||||
BIN
attached_assets/image_1765005879621.png
Normal file
BIN
attached_assets/image_1765005879621.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
|
|
@ -10,6 +10,8 @@ import { AuthProvider } from "./contexts/AuthContext";
|
|||
import { Web3Provider } from "./contexts/Web3Context";
|
||||
import { DocsThemeProvider } from "./contexts/DocsThemeContext";
|
||||
import { ArmThemeProvider } from "./contexts/ArmThemeContext";
|
||||
import { MaintenanceProvider } from "./contexts/MaintenanceContext";
|
||||
import MaintenanceGuard from "./components/MaintenanceGuard";
|
||||
import PageTransition from "./components/PageTransition";
|
||||
import SkipAgentController from "./components/SkipAgentController";
|
||||
import Index from "./pages/Index";
|
||||
|
|
@ -182,6 +184,8 @@ const App = () => (
|
|||
<BrowserRouter>
|
||||
<SubdomainPassportProvider>
|
||||
<ArmThemeProvider>
|
||||
<MaintenanceProvider>
|
||||
<MaintenanceGuard>
|
||||
<SkipAgentController />
|
||||
<PageTransition>
|
||||
<Routes>
|
||||
|
|
@ -797,6 +801,8 @@ const App = () => (
|
|||
<Route path="*" element={<FourOhFourPage />} />
|
||||
</Routes>
|
||||
</PageTransition>
|
||||
</MaintenanceGuard>
|
||||
</MaintenanceProvider>
|
||||
</ArmThemeProvider>
|
||||
</SubdomainPassportProvider>
|
||||
</BrowserRouter>
|
||||
|
|
|
|||
33
client/components/MaintenanceGuard.tsx
Normal file
33
client/components/MaintenanceGuard.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import React from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { useMaintenance } from "@/contexts/MaintenanceContext";
|
||||
import MaintenancePage from "@/pages/Maintenance";
|
||||
|
||||
const ALLOWED_PATHS = ["/login", "/staff/login", "/reset-password", "/health"];
|
||||
|
||||
interface MaintenanceGuardProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function MaintenanceGuard({ children }: MaintenanceGuardProps) {
|
||||
const { isMaintenanceMode, canBypass, loading } = useMaintenance();
|
||||
const location = useLocation();
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-900 flex items-center justify-center">
|
||||
<div className="w-8 h-8 border-2 border-purple-500 border-t-transparent rounded-full animate-spin" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const isAllowedPath = ALLOWED_PATHS.some(path =>
|
||||
location.pathname === path || location.pathname.startsWith(path)
|
||||
);
|
||||
|
||||
if (isMaintenanceMode && !canBypass && !isAllowedPath) {
|
||||
return <MaintenancePage />;
|
||||
}
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
111
client/components/admin/MaintenanceToggle.tsx
Normal file
111
client/components/admin/MaintenanceToggle.tsx
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { useMaintenance } from "@/contexts/MaintenanceContext";
|
||||
import { Construction, AlertTriangle, Loader2 } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { aethexToast } from "@/lib/aethex-toast";
|
||||
|
||||
export default function MaintenanceToggle() {
|
||||
const { isMaintenanceMode, canBypass, toggleMaintenanceMode, loading } = useMaintenance();
|
||||
const [toggling, setToggling] = useState(false);
|
||||
|
||||
const handleToggle = async () => {
|
||||
if (!canBypass) {
|
||||
aethexToast.error("Only admins can toggle maintenance mode");
|
||||
return;
|
||||
}
|
||||
|
||||
setToggling(true);
|
||||
try {
|
||||
await toggleMaintenanceMode();
|
||||
aethexToast.success(
|
||||
isMaintenanceMode
|
||||
? "Maintenance mode disabled - site is now live"
|
||||
: "Maintenance mode enabled - visitors will see maintenance page"
|
||||
);
|
||||
} catch (error: any) {
|
||||
aethexToast.error(error?.message || "Failed to toggle maintenance mode");
|
||||
} finally {
|
||||
setToggling(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Card className="bg-card/60 border-border/40 backdrop-blur">
|
||||
<CardContent className="flex items-center justify-center py-8">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className={`bg-card/60 border-border/40 backdrop-blur ${isMaintenanceMode ? 'border-yellow-500/30' : ''}`}>
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`flex h-10 w-10 items-center justify-center rounded-full border ${
|
||||
isMaintenanceMode
|
||||
? 'border-yellow-500/30 bg-yellow-500/10'
|
||||
: 'border-emerald-500/30 bg-emerald-500/10'
|
||||
}`}>
|
||||
{isMaintenanceMode ? (
|
||||
<Construction className="h-5 w-5 text-yellow-400" />
|
||||
) : (
|
||||
<Construction className="h-5 w-5 text-emerald-400" />
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<CardTitle className="text-lg">Maintenance Mode</CardTitle>
|
||||
<CardDescription>
|
||||
{isMaintenanceMode
|
||||
? "Site is currently in maintenance mode"
|
||||
: "Site is live and accessible"}
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={isMaintenanceMode
|
||||
? "border-yellow-500/30 bg-yellow-500/10 text-yellow-200"
|
||||
: "border-emerald-500/30 bg-emerald-500/10 text-emerald-200"
|
||||
}
|
||||
>
|
||||
{isMaintenanceMode ? "Active" : "Off"}
|
||||
</Badge>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex items-center justify-between rounded-lg border border-border/30 bg-background/40 p-4">
|
||||
<div className="flex items-center gap-3">
|
||||
{isMaintenanceMode && (
|
||||
<AlertTriangle className="h-5 w-5 text-yellow-400" />
|
||||
)}
|
||||
<div>
|
||||
<p className="font-medium text-sm">
|
||||
{isMaintenanceMode
|
||||
? "Visitors see maintenance page"
|
||||
: "All visitors can access the site"}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground mt-1">
|
||||
{isMaintenanceMode
|
||||
? "Only admins can view the site. Toggle off to go live."
|
||||
: "Toggle on to show maintenance page to visitors."}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{toggling && <Loader2 className="h-4 w-4 animate-spin" />}
|
||||
<Switch
|
||||
checked={isMaintenanceMode}
|
||||
onCheckedChange={handleToggle}
|
||||
disabled={toggling || !canBypass}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
104
client/contexts/MaintenanceContext.tsx
Normal file
104
client/contexts/MaintenanceContext.tsx
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import React, { createContext, useContext, useState, useEffect, useCallback } from "react";
|
||||
import { useAuth } from "./AuthContext";
|
||||
import { supabase } from "@/lib/supabase";
|
||||
|
||||
interface MaintenanceContextType {
|
||||
isMaintenanceMode: boolean;
|
||||
canBypass: boolean;
|
||||
loading: boolean;
|
||||
toggleMaintenanceMode: () => Promise<void>;
|
||||
refreshStatus: () => Promise<void>;
|
||||
}
|
||||
|
||||
const MaintenanceContext = createContext<MaintenanceContextType | undefined>(undefined);
|
||||
|
||||
const ADMIN_ROLES = ["admin", "super_admin", "staff", "owner"];
|
||||
|
||||
export function MaintenanceProvider({ children }: { children: React.ReactNode }) {
|
||||
const { user, roles, session, loading: authLoading } = useAuth();
|
||||
const [isMaintenanceMode, setIsMaintenanceMode] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const isAdmin = roles.some(role => ADMIN_ROLES.includes(role.toLowerCase()));
|
||||
const canBypass = isAdmin && !!user;
|
||||
|
||||
const fetchMaintenanceStatus = useCallback(async () => {
|
||||
try {
|
||||
const response = await fetch("/api/admin/platform/maintenance");
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
setIsMaintenanceMode(data.maintenance_mode ?? false);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch maintenance status:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const toggleMaintenanceMode = useCallback(async () => {
|
||||
if (!canBypass) {
|
||||
throw new Error("Only admins can toggle maintenance mode");
|
||||
}
|
||||
|
||||
const { data: sessionData } = await supabase.auth.getSession();
|
||||
const token = sessionData?.session?.access_token;
|
||||
|
||||
if (!token) {
|
||||
throw new Error("No auth session");
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/admin/platform/maintenance", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({ maintenance_mode: !isMaintenanceMode }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error || "Failed to toggle maintenance mode");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
setIsMaintenanceMode(data.maintenance_mode);
|
||||
} catch (error) {
|
||||
console.error("Failed to toggle maintenance mode:", error);
|
||||
throw error;
|
||||
}
|
||||
}, [canBypass, isMaintenanceMode]);
|
||||
|
||||
const refreshStatus = useCallback(async () => {
|
||||
setLoading(true);
|
||||
await fetchMaintenanceStatus();
|
||||
}, [fetchMaintenanceStatus]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchMaintenanceStatus();
|
||||
}, [fetchMaintenanceStatus]);
|
||||
|
||||
return (
|
||||
<MaintenanceContext.Provider
|
||||
value={{
|
||||
isMaintenanceMode,
|
||||
canBypass,
|
||||
loading: loading || authLoading,
|
||||
toggleMaintenanceMode,
|
||||
refreshStatus,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</MaintenanceContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useMaintenance() {
|
||||
const context = useContext(MaintenanceContext);
|
||||
if (!context) {
|
||||
throw new Error("useMaintenance must be used within MaintenanceProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
|
@ -40,6 +40,7 @@ import AdminStaffChat from "@/components/admin/AdminStaffChat";
|
|||
import AdminStaffAdmin from "@/components/admin/AdminStaffAdmin";
|
||||
import AdminStaffDocs from "@/components/admin/AdminStaffDocs";
|
||||
import AdminStaffAchievements from "@/components/admin/AdminStaffAchievements";
|
||||
import MaintenanceToggle from "@/components/admin/MaintenanceToggle";
|
||||
import AdminSidebar from "@/components/admin/AdminSidebar";
|
||||
import AdminEthosVerification from "@/pages/admin/AdminEthosVerification";
|
||||
import AdminGameForgeStudio from "@/components/admin/AdminGameForgeStudio";
|
||||
|
|
@ -393,6 +394,8 @@ export default function Admin() {
|
|||
</TabsList>
|
||||
|
||||
<TabsContent value="overview" className="space-y-6">
|
||||
<MaintenanceToggle />
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<Card className="bg-card/60 border-border/40 backdrop-blur">
|
||||
<CardHeader className="pb-3">
|
||||
|
|
|
|||
159
client/pages/Maintenance.tsx
Normal file
159
client/pages/Maintenance.tsx
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { Shield, Mail, Wrench, Clock, Zap } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import AeThexOSLogo from "@/components/AeThexOSLogo";
|
||||
|
||||
export default function MaintenancePage() {
|
||||
const [currentMessage, setCurrentMessage] = useState(0);
|
||||
const [dots, setDots] = useState("");
|
||||
|
||||
const messages = [
|
||||
"Upgrading quantum processors...",
|
||||
"Optimizing neural networks...",
|
||||
"Synchronizing data streams...",
|
||||
"Calibrating system modules...",
|
||||
"Enhancing user experience...",
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
const messageInterval = setInterval(() => {
|
||||
setCurrentMessage((prev) => (prev + 1) % messages.length);
|
||||
}, 2500);
|
||||
|
||||
const dotsInterval = setInterval(() => {
|
||||
setDots((prev) => (prev.length >= 3 ? "" : prev + "."));
|
||||
}, 400);
|
||||
|
||||
return () => {
|
||||
clearInterval(messageInterval);
|
||||
clearInterval(dotsInterval);
|
||||
};
|
||||
}, [messages.length]);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background overflow-hidden relative">
|
||||
<div className="absolute inset-0 pointer-events-none overflow-hidden opacity-5">
|
||||
{[...Array(20)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="absolute text-blue-400 animate-float font-mono"
|
||||
style={{
|
||||
left: `${Math.random() * 100}%`,
|
||||
top: `${Math.random() * 100}%`,
|
||||
animationDelay: `${Math.random() * 3}s`,
|
||||
animationDuration: `${4 + Math.random() * 3}s`,
|
||||
fontSize: `${10 + Math.random() * 6}px`,
|
||||
}}
|
||||
>
|
||||
{["01", "10", "//", "{ }", "< >", "=>"][Math.floor(Math.random() * 6)]}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="absolute top-1/4 left-1/4 w-96 h-96 bg-blue-500/5 rounded-full blur-3xl" />
|
||||
<div className="absolute bottom-1/4 right-1/4 w-80 h-80 bg-cyan-500/5 rounded-full blur-3xl" />
|
||||
|
||||
<div className="relative z-10 flex items-center justify-center min-h-screen p-4">
|
||||
<div className="max-w-xl w-full text-center space-y-8">
|
||||
<div className="space-y-6">
|
||||
<div className="relative inline-block">
|
||||
<div className="absolute -inset-4 bg-gradient-to-r from-blue-500 to-cyan-500 opacity-20 blur-xl rounded-full animate-pulse" />
|
||||
<div className="relative w-24 h-24 mx-auto bg-gradient-to-br from-blue-500/20 to-cyan-500/20 border border-blue-500/40 rounded-xl flex items-center justify-center shadow-lg shadow-blue-500/10">
|
||||
<AeThexOSLogo size="lg" variant="default" animate />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<h1 className="text-4xl md:text-5xl font-bold bg-gradient-to-r from-blue-400 via-cyan-400 to-blue-400 bg-clip-text text-transparent">
|
||||
System Maintenance
|
||||
</h1>
|
||||
<p className="text-lg text-muted-foreground max-w-md mx-auto">
|
||||
We're upgrading AeThex to deliver a better experience.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center gap-3 flex-wrap">
|
||||
<Badge variant="outline" className="border-blue-500/50 text-blue-400 animate-pulse">
|
||||
<Wrench className="h-3 w-3 mr-1" />
|
||||
Maintenance Mode
|
||||
</Badge>
|
||||
<Badge variant="outline" className="border-cyan-500/50 text-cyan-400">
|
||||
<Clock className="h-3 w-3 mr-1" />
|
||||
Back Soon
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card className="bg-card/50 border-border/50 backdrop-blur-sm">
|
||||
<CardContent className="p-6 space-y-4">
|
||||
<div className="flex items-center justify-center gap-3">
|
||||
<div className="flex gap-1">
|
||||
{[...Array(5)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="w-1.5 bg-gradient-to-t from-blue-500 to-cyan-400 rounded-full animate-pulse"
|
||||
style={{
|
||||
height: `${12 + i * 4}px`,
|
||||
animationDelay: `${i * 0.15}s`,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<span className="text-sm text-muted-foreground font-mono">
|
||||
{messages[currentMessage]}{dots}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="h-px bg-border" />
|
||||
|
||||
<div className="grid grid-cols-3 gap-4 text-center text-xs">
|
||||
<div className="space-y-1">
|
||||
<div className="text-muted-foreground">STATUS</div>
|
||||
<div className="text-blue-400 font-semibold flex items-center justify-center gap-1">
|
||||
<Zap className="h-3 w-3" />
|
||||
ACTIVE
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<div className="text-muted-foreground">SYSTEM</div>
|
||||
<div className="text-foreground font-semibold">AeThex v2.0</div>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<div className="text-muted-foreground">ETA</div>
|
||||
<div className="text-cyan-400 font-semibold">~30 min</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-background/30 border-border/30">
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-center justify-center gap-2 text-sm">
|
||||
<Shield className="w-4 h-4 text-blue-400" />
|
||||
<span className="text-muted-foreground">Questions?</span>
|
||||
<Mail className="w-4 h-4 text-muted-foreground" />
|
||||
<a
|
||||
href="mailto:support@aethex.dev"
|
||||
className="text-blue-400 hover:text-blue-300 transition-colors"
|
||||
>
|
||||
support@aethex.dev
|
||||
</a>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
asChild
|
||||
className="text-muted-foreground hover:text-foreground hover:bg-blue-500/10"
|
||||
>
|
||||
<a href="/login">Staff Login</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -311,7 +311,7 @@ async function registerDiscordCommands() {
|
|||
}
|
||||
|
||||
// Start HTTP health check server
|
||||
const healthPort = process.env.HEALTH_PORT || 8044;
|
||||
const healthPort = process.env.HEALTH_PORT || 8080;
|
||||
const ADMIN_TOKEN = process.env.DISCORD_ADMIN_TOKEN || "aethex-bot-admin";
|
||||
|
||||
// Helper to check admin authentication
|
||||
|
|
|
|||
554
package-lock.json
generated
554
package-lock.json
generated
|
|
@ -19,6 +19,8 @@
|
|||
"ethers": "^6.13.0",
|
||||
"express": "^4.18.2",
|
||||
"nodemailer": "^7.0.10",
|
||||
"png-to-ico": "^3.0.1",
|
||||
"sharp": "^0.34.5",
|
||||
"stripe": "^15.12.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
|
|
@ -1737,6 +1739,23 @@
|
|||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz",
|
||||
"integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime/node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@emotion/cache": {
|
||||
"version": "10.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz",
|
||||
|
|
@ -2364,6 +2383,471 @@
|
|||
"react-hook-form": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/colour": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz",
|
||||
"integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-arm64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
|
||||
"integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-arm64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-x64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
|
||||
"integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-x64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-darwin-arm64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
|
||||
"integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-darwin-x64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
|
||||
"integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-arm": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
|
||||
"integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-arm64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
|
||||
"integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-ppc64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
|
||||
"integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-riscv64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
|
||||
"integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-s390x": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
|
||||
"integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-x64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
|
||||
"integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
|
||||
"integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
|
||||
"integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
|
||||
"integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
|
||||
"integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-ppc64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
|
||||
"integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-ppc64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-riscv64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
|
||||
"integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-riscv64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-s390x": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
|
||||
"integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-s390x": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-x64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
|
||||
"integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-x64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-arm64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
|
||||
"integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-x64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
|
||||
"integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-wasm32": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
|
||||
"integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/runtime": "^1.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-arm64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
|
||||
"integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-ia32": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
|
||||
"integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-x64": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
|
||||
"integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/balanced-match": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
|
||||
|
|
@ -13370,6 +13854,32 @@
|
|||
"node": ">=10.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/png-to-ico": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/png-to-ico/-/png-to-ico-3.0.1.tgz",
|
||||
"integrity": "sha512-S8BOAoaGd9gT5uaemQ62arIY3Jzco7Uc7LwUTqRyqJDTsKqOAiyfyN4dSdT0D+Zf8XvgztgpRbM5wnQd7EgYwg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "^22.10.3",
|
||||
"minimist": "^1.2.8",
|
||||
"pngjs": "^7.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"png-to-ico": "bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/pngjs": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
|
||||
"integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.6",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
|
||||
|
|
@ -14698,6 +15208,50 @@
|
|||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/sharp": {
|
||||
"version": "0.34.5",
|
||||
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
|
||||
"integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@img/colour": "^1.0.0",
|
||||
"detect-libc": "^2.1.2",
|
||||
"semver": "^7.7.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-darwin-arm64": "0.34.5",
|
||||
"@img/sharp-darwin-x64": "0.34.5",
|
||||
"@img/sharp-libvips-darwin-arm64": "1.2.4",
|
||||
"@img/sharp-libvips-darwin-x64": "1.2.4",
|
||||
"@img/sharp-libvips-linux-arm": "1.2.4",
|
||||
"@img/sharp-libvips-linux-arm64": "1.2.4",
|
||||
"@img/sharp-libvips-linux-ppc64": "1.2.4",
|
||||
"@img/sharp-libvips-linux-riscv64": "1.2.4",
|
||||
"@img/sharp-libvips-linux-s390x": "1.2.4",
|
||||
"@img/sharp-libvips-linux-x64": "1.2.4",
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.2.4",
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.2.4",
|
||||
"@img/sharp-linux-arm": "0.34.5",
|
||||
"@img/sharp-linux-arm64": "0.34.5",
|
||||
"@img/sharp-linux-ppc64": "0.34.5",
|
||||
"@img/sharp-linux-riscv64": "0.34.5",
|
||||
"@img/sharp-linux-s390x": "0.34.5",
|
||||
"@img/sharp-linux-x64": "0.34.5",
|
||||
"@img/sharp-linuxmusl-arm64": "0.34.5",
|
||||
"@img/sharp-linuxmusl-x64": "0.34.5",
|
||||
"@img/sharp-wasm32": "0.34.5",
|
||||
"@img/sharp-win32-arm64": "0.34.5",
|
||||
"@img/sharp-win32-ia32": "0.34.5",
|
||||
"@img/sharp-win32-x64": "0.34.5"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
"ethers": "^6.13.0",
|
||||
"express": "^4.18.2",
|
||||
"nodemailer": "^7.0.10",
|
||||
"png-to-ico": "^3.0.1",
|
||||
"sharp": "^0.34.5",
|
||||
"stripe": "^15.12.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ The monolith (`aethex.dev`) implements split routing to enforce legal separation
|
|||
This ensures the Foundation's user-facing URLs display `aethex.foundation` in the browser, demonstrating operational independence per the Axiom Model.
|
||||
|
||||
## Recent Changes (December 2025)
|
||||
- **Maintenance Mode**: Site-wide maintenance mode with admin bypass. Admins can toggle via Admin Dashboard overview tab. Uses MAINTENANCE_MODE env var for initial state. Allowed paths during maintenance: /login, /staff/login, /reset-password, /health
|
||||
- **Health Endpoint**: Added /health endpoint at aethex.dev/health that aggregates platform and Discord bot status
|
||||
- **Axiom Model Routing**: Foundation and GameForge routes redirect to `aethex.foundation` domain for legal entity separation
|
||||
- **AI Intelligent Agent Integration**: Added global AI chat with 10 specialized personas (Network Agent, Forge Master, Ethics Sentinel, SBS Architect, Curriculum Weaver, QuantumLeap, Vapor, Apex, Ethos Producer, AeThex Archivist)
|
||||
- **Tiered Access Control**: AI personas gated by user tier (Free/Architect/Council) based on roles
|
||||
|
|
|
|||
123
server/index.ts
123
server/index.ts
|
|
@ -457,6 +457,129 @@ export function createServer() {
|
|||
}
|
||||
});
|
||||
|
||||
// Health check endpoint - proxies to Discord bot health
|
||||
app.get("/health", async (_req, res) => {
|
||||
try {
|
||||
const botHealthPort = process.env.HEALTH_PORT || 8080;
|
||||
const response = await fetch(`http://localhost:${botHealthPort}/health`);
|
||||
const data = await response.json();
|
||||
res.json({
|
||||
status: "online",
|
||||
platform: "aethex.dev",
|
||||
bot: data,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
} catch (error: any) {
|
||||
res.json({
|
||||
status: "online",
|
||||
platform: "aethex.dev",
|
||||
bot: { status: "offline", error: error?.message || "Bot unreachable" },
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Maintenance Mode API endpoints
|
||||
const ADMIN_ROLES = ["admin", "super_admin", "staff", "owner"];
|
||||
|
||||
// In-memory maintenance state (fallback when DB table doesn't exist)
|
||||
let maintenanceModeCache: boolean | null = null;
|
||||
|
||||
// Get maintenance status (public)
|
||||
app.get("/api/admin/platform/maintenance", async (_req, res) => {
|
||||
try {
|
||||
// Try database first
|
||||
const { data, error } = await adminSupabase
|
||||
.from("platform_settings")
|
||||
.select("value")
|
||||
.eq("key", "maintenance_mode")
|
||||
.single();
|
||||
|
||||
if (error) {
|
||||
// If table doesn't exist, use env var or in-memory cache
|
||||
if (error.code === "42P01" || error.message?.includes("does not exist")) {
|
||||
const envMaintenance = process.env.MAINTENANCE_MODE === "true";
|
||||
res.json({ maintenance_mode: maintenanceModeCache ?? envMaintenance });
|
||||
return;
|
||||
}
|
||||
// Row not found is OK, means maintenance is off
|
||||
if (error.code !== "PGRST116") {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
const isActive = data?.value === "true" || data?.value === true;
|
||||
maintenanceModeCache = isActive;
|
||||
res.json({ maintenance_mode: isActive });
|
||||
} catch (e: any) {
|
||||
console.error("[Maintenance] Error fetching status:", e?.message);
|
||||
// Fall back to env var or cache
|
||||
const envMaintenance = process.env.MAINTENANCE_MODE === "true";
|
||||
res.json({ maintenance_mode: maintenanceModeCache ?? envMaintenance });
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle maintenance mode (admin only)
|
||||
app.post("/api/admin/platform/maintenance", async (req, res) => {
|
||||
try {
|
||||
const authHeader = req.headers.authorization;
|
||||
if (!authHeader?.startsWith("Bearer ")) {
|
||||
return res.status(401).json({ error: "Unauthorized" });
|
||||
}
|
||||
|
||||
const token = authHeader.substring(7);
|
||||
const { data: { user }, error: authError } = await adminSupabase.auth.getUser(token);
|
||||
|
||||
if (authError || !user) {
|
||||
return res.status(401).json({ error: "Invalid token" });
|
||||
}
|
||||
|
||||
// Check if user has admin role
|
||||
const { data: roles } = await adminSupabase
|
||||
.from("user_roles")
|
||||
.select("role")
|
||||
.eq("user_id", user.id);
|
||||
|
||||
const userRoles = roles?.map((r: any) => r.role?.toLowerCase()) || [];
|
||||
const isAdmin = userRoles.some((role: string) => ADMIN_ROLES.includes(role));
|
||||
|
||||
if (!isAdmin) {
|
||||
return res.status(403).json({ error: "Admin access required" });
|
||||
}
|
||||
|
||||
const rawValue = req.body?.maintenance_mode;
|
||||
const newMaintenanceMode = rawValue === true || rawValue === "true";
|
||||
|
||||
// Try to upsert in database
|
||||
const { error } = await adminSupabase
|
||||
.from("platform_settings")
|
||||
.upsert({
|
||||
key: "maintenance_mode",
|
||||
value: String(newMaintenanceMode),
|
||||
updated_at: new Date().toISOString(),
|
||||
updated_by: user.id,
|
||||
}, { onConflict: "key" });
|
||||
|
||||
if (error) {
|
||||
// If table doesn't exist, just use in-memory cache
|
||||
if (error.code === "42P01" || error.message?.includes("does not exist")) {
|
||||
maintenanceModeCache = newMaintenanceMode;
|
||||
console.log(`[Maintenance] Mode set to ${newMaintenanceMode} (in-memory) by ${user.email}`);
|
||||
return res.json({ maintenance_mode: newMaintenanceMode });
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
maintenanceModeCache = newMaintenanceMode;
|
||||
console.log(`[Maintenance] Mode set to ${newMaintenanceMode} by ${user.email}`);
|
||||
|
||||
res.json({ maintenance_mode: newMaintenanceMode });
|
||||
} catch (e: any) {
|
||||
console.error("[Maintenance] Error toggling:", e?.message);
|
||||
res.status(500).json({ error: e?.message || "Failed to toggle maintenance mode" });
|
||||
}
|
||||
});
|
||||
|
||||
// Example API routes
|
||||
app.get("/api/ping", (_req, res) => {
|
||||
const ping = process.env.PING_MESSAGE ?? "ping";
|
||||
|
|
|
|||
Loading…
Reference in a new issue