fluxy-bot 0.2.20 → 0.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/index.html +16 -0
- package/client/src/App.tsx +18 -7
- package/client/src/components/Dashboard/ConversationAnalytics.tsx +20 -6
- package/client/src/components/Layout/Sidebar.tsx +28 -2
- package/package.json +1 -1
- package/scripts/install.ps1 +238 -0
- package/{install.sh → scripts/install.sh} +1 -1
- package/supervisor/chat/src/styles/globals.css +110 -0
- package/supervisor/fluxy-agent.ts +1 -1
- package/supervisor/widget.js +8 -0
- package/vite.fluxy.config.ts +4 -4
- package/worker/prompts/fluxy-system-prompt.txt +3 -5
- package/client/src/hooks/useMobile.ts +0 -16
- package/client/src/lib/mock-data.ts +0 -104
- package/install.ps1 +0 -91
- /package/{client → supervisor/chat}/fluxy-main.tsx +0 -0
- /package/{client → supervisor/chat}/fluxy.html +0 -0
- /package/{client → supervisor/chat}/src/components/Chat/AudioBubble.tsx +0 -0
- /package/{client → supervisor/chat}/src/components/Chat/ChatView.tsx +0 -0
- /package/{client → supervisor/chat}/src/components/Chat/ImageLightbox.tsx +0 -0
- /package/{client → supervisor/chat}/src/components/Chat/InputBar.tsx +0 -0
- /package/{client → supervisor/chat}/src/components/Chat/MessageBubble.tsx +0 -0
- /package/{client → supervisor/chat}/src/components/Chat/MessageList.tsx +0 -0
- /package/{client → supervisor/chat}/src/components/Chat/TypingIndicator.tsx +0 -0
- /package/{client → supervisor/chat}/src/hooks/useChat.ts +0 -0
- /package/{client → supervisor/chat}/src/hooks/useFluxyChat.ts +0 -0
- /package/{client → supervisor/chat}/src/lib/ws-client.ts +0 -0
package/client/index.html
CHANGED
|
@@ -8,6 +8,22 @@
|
|
|
8
8
|
</head>
|
|
9
9
|
<body class="bg-background text-foreground">
|
|
10
10
|
<div id="root"></div>
|
|
11
|
+
<script>
|
|
12
|
+
// Global error handler — catches errors outside React's Error Boundary
|
|
13
|
+
// (e.g., Vite compilation errors, module loading failures)
|
|
14
|
+
window.addEventListener('error', function (e) {
|
|
15
|
+
// Only show if root is empty (React didn't mount or crashed before mounting)
|
|
16
|
+
var root = document.getElementById('root');
|
|
17
|
+
if (root && root.children.length === 0) {
|
|
18
|
+
root.innerHTML =
|
|
19
|
+
'<div style="background:#222122;color:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center;height:100dvh;width:100vw;position:fixed;inset:0;z-index:50;font-family:system-ui,-apple-system,sans-serif;text-align:center;padding:24px">' +
|
|
20
|
+
'<video src="/fluxy_say_hi.webm" autoplay loop muted playsinline style="height:120px;width:120px;border-radius:50%;object-fit:cover;margin-bottom:32px"></video>' +
|
|
21
|
+
'<h1 style="font-size:20px;font-weight:600;margin-bottom:8px">Your app crashed</h1>' +
|
|
22
|
+
'<p style="font-size:14px;color:rgba(255,255,255,0.5);max-width:320px;line-height:1.5">Ask the agent to fix it using the chat.</p>' +
|
|
23
|
+
'</div>';
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
</script>
|
|
11
27
|
<script type="module" src="/src/main.tsx"></script>
|
|
12
28
|
<script>if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then(r=>r.forEach(w=>w.unregister()))}</script>
|
|
13
29
|
<script src="/fluxy/widget.js"></script>
|
package/client/src/App.tsx
CHANGED
|
@@ -6,13 +6,19 @@ import OnboardWizard from './components/Onboard/OnboardWizard';
|
|
|
6
6
|
|
|
7
7
|
function DashboardError() {
|
|
8
8
|
return (
|
|
9
|
-
<div
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
<div style={{ background: '#222122', color: '#fff', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100dvh', width: '100vw', position: 'fixed', inset: 0, zIndex: 50, fontFamily: 'system-ui, -apple-system, sans-serif', textAlign: 'center', padding: '24px' }}>
|
|
10
|
+
<video
|
|
11
|
+
src="/fluxy_say_hi.webm"
|
|
12
|
+
autoPlay
|
|
13
|
+
loop
|
|
14
|
+
muted
|
|
15
|
+
playsInline
|
|
16
|
+
style={{ height: 120, width: 120, borderRadius: '50%', objectFit: 'cover', marginBottom: 32 }}
|
|
17
|
+
/>
|
|
18
|
+
<h1 style={{ fontSize: 20, fontWeight: 600, marginBottom: 8 }}>Your app crashed</h1>
|
|
19
|
+
<p style={{ fontSize: 14, color: 'rgba(255,255,255,0.5)', maxWidth: 320, lineHeight: 1.5 }}>
|
|
20
|
+
Ask the agent to fix it using the chat.
|
|
21
|
+
</p>
|
|
16
22
|
</div>
|
|
17
23
|
);
|
|
18
24
|
}
|
|
@@ -52,6 +58,11 @@ export default function App() {
|
|
|
52
58
|
setTimeout(() => setRebuildState('idle'), 5000);
|
|
53
59
|
} else if (e.data?.type === 'fluxy:hmr-update') {
|
|
54
60
|
console.log('[dashboard] File changed — reloading...');
|
|
61
|
+
// Preserve widget open state so chat isn't disrupted
|
|
62
|
+
const panel = document.getElementById('fluxy-widget-panel');
|
|
63
|
+
if (panel?.classList.contains('open')) {
|
|
64
|
+
sessionStorage.setItem('fluxy_widget_open', '1');
|
|
65
|
+
}
|
|
55
66
|
setTimeout(() => location.reload(), 800);
|
|
56
67
|
}
|
|
57
68
|
};
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import { ChevronDown, MoreHorizontal } from 'lucide-react';
|
|
2
2
|
import { Card, CardContent } from '@/components/ui/card';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
|
|
4
|
+
const weeklyActivity = [
|
|
5
|
+
{ model: 'GPT-4o', days: [3, 2, 4, 3, 1, 2, 0] },
|
|
6
|
+
{ model: 'Claude', days: [2, 4, 3, 4, 2, 1, 1] },
|
|
7
|
+
{ model: 'Local', days: [1, 1, 2, 1, 3, 4, 2] },
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
const dayLabels = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
|
|
11
|
+
|
|
12
|
+
const activityColors = [
|
|
13
|
+
'#2a2a2a', '#1e3a5f', '#2c5a8f', '#3578bf', '#3C8FFF',
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const activityLegend = [
|
|
17
|
+
{ label: '< 10', level: 1 },
|
|
18
|
+
{ label: '10–50', level: 2 },
|
|
19
|
+
{ label: '> 50', level: 3 },
|
|
20
|
+
{ label: '100+', level: 4 },
|
|
21
|
+
{ label: 'None', level: 0 },
|
|
22
|
+
];
|
|
9
23
|
|
|
10
24
|
export default function ConversationAnalytics() {
|
|
11
25
|
return (
|
|
@@ -1,7 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
ChevronDown,
|
|
3
|
+
LayoutDashboard,
|
|
4
|
+
MessageSquare,
|
|
5
|
+
Brain,
|
|
6
|
+
BookOpen,
|
|
7
|
+
ScrollText,
|
|
8
|
+
Settings,
|
|
9
|
+
} from 'lucide-react';
|
|
3
10
|
import { cn } from '@/lib/utils';
|
|
4
11
|
|
|
12
|
+
const navSections = [
|
|
13
|
+
{
|
|
14
|
+
label: 'HOME',
|
|
15
|
+
items: [
|
|
16
|
+
{ label: 'Overview', icon: LayoutDashboard, href: '#', active: true },
|
|
17
|
+
{ label: 'Conversations', icon: MessageSquare, href: '#' },
|
|
18
|
+
{ label: 'Models', icon: Brain, href: '#' },
|
|
19
|
+
{ label: 'Knowledge', icon: BookOpen, href: '#' },
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
label: 'SYSTEM',
|
|
24
|
+
items: [
|
|
25
|
+
{ label: 'Logs', icon: ScrollText, href: '#' },
|
|
26
|
+
{ label: 'Settings', icon: Settings, href: '#' },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
|
|
5
31
|
function getGreeting(): string {
|
|
6
32
|
const hour = new Date().getHours();
|
|
7
33
|
if (hour < 12) return 'Good\nMorning!';
|
package/package.json
CHANGED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# ─── Fluxy Installer ────────────────────────────────────────────────────────
|
|
2
|
+
# irm https://fluxy.bot/install.ps1 | iex
|
|
3
|
+
#
|
|
4
|
+
# Downloads Node.js + Fluxy into ~/.fluxy — no system dependencies needed.
|
|
5
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
$ErrorActionPreference = "Stop"
|
|
8
|
+
|
|
9
|
+
$MIN_NODE_MAJOR = 18
|
|
10
|
+
$NODE_VERSION = "22.14.0"
|
|
11
|
+
$FLUXY_HOME = Join-Path $env:USERPROFILE ".fluxy"
|
|
12
|
+
$TOOLS_DIR = Join-Path $FLUXY_HOME "tools"
|
|
13
|
+
$NODE_DIR = Join-Path $TOOLS_DIR "node"
|
|
14
|
+
$BIN_DIR = Join-Path $FLUXY_HOME "bin"
|
|
15
|
+
$USE_SYSTEM_NODE = $false
|
|
16
|
+
|
|
17
|
+
Write-Host ""
|
|
18
|
+
Write-Host " ╔═══════════════════════════════╗" -ForegroundColor Cyan
|
|
19
|
+
Write-Host " ║ FLUXY ║" -ForegroundColor Cyan
|
|
20
|
+
Write-Host " ╚═══════════════════════════════╝" -ForegroundColor Cyan
|
|
21
|
+
Write-Host " Self-hosted AI bot" -ForegroundColor DarkGray
|
|
22
|
+
Write-Host ""
|
|
23
|
+
|
|
24
|
+
# ─── Detect platform ────────────────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
function Detect-Platform {
|
|
27
|
+
$script:PLATFORM = "win"
|
|
28
|
+
|
|
29
|
+
if ([Environment]::Is64BitOperatingSystem) {
|
|
30
|
+
if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") {
|
|
31
|
+
$script:NODEARCH = "arm64"
|
|
32
|
+
} else {
|
|
33
|
+
$script:NODEARCH = "x64"
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
$script:NODEARCH = "x86"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
Write-Host " Platform: windows/$NODEARCH" -ForegroundColor DarkGray
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# ─── Check for system Node.js ─────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
function Check-SystemNode {
|
|
45
|
+
$nodeCmd = Get-Command node -ErrorAction SilentlyContinue
|
|
46
|
+
if ($nodeCmd) {
|
|
47
|
+
try {
|
|
48
|
+
$ver = (node -v 2>$null)
|
|
49
|
+
if ($ver -match '^v(\d+)') {
|
|
50
|
+
$major = [int]$Matches[1]
|
|
51
|
+
if ($major -ge $MIN_NODE_MAJOR) {
|
|
52
|
+
$script:USE_SYSTEM_NODE = $true
|
|
53
|
+
Write-Host " ✔ Node.js $ver (system)" -ForegroundColor Green
|
|
54
|
+
return $true
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} catch {}
|
|
58
|
+
}
|
|
59
|
+
return $false
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# ─── Download Node.js ───────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
function Install-Node {
|
|
65
|
+
$nodeBin = Join-Path $NODE_DIR "node.exe"
|
|
66
|
+
|
|
67
|
+
# Check if we already have a bundled node that works
|
|
68
|
+
if (Test-Path $nodeBin) {
|
|
69
|
+
try {
|
|
70
|
+
$existing = & $nodeBin -v 2>$null
|
|
71
|
+
if ($existing) {
|
|
72
|
+
Write-Host " ✔ Node.js $existing (bundled)" -ForegroundColor Green
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
} catch {}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
Write-Host " ↓ Downloading Node.js v${NODE_VERSION}..." -ForegroundColor Cyan
|
|
79
|
+
|
|
80
|
+
$nodeUrl = "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-win-${NODEARCH}.zip"
|
|
81
|
+
$tmpFile = Join-Path ([System.IO.Path]::GetTempPath()) "node-fluxy.zip"
|
|
82
|
+
|
|
83
|
+
Invoke-WebRequest -Uri $nodeUrl -OutFile $tmpFile -UseBasicParsing
|
|
84
|
+
|
|
85
|
+
# Extract
|
|
86
|
+
New-Item -ItemType Directory -Path $TOOLS_DIR -Force | Out-Null
|
|
87
|
+
if (Test-Path $NODE_DIR) { Remove-Item $NODE_DIR -Recurse -Force }
|
|
88
|
+
|
|
89
|
+
$tmpExtract = Join-Path ([System.IO.Path]::GetTempPath()) "node-fluxy-extract"
|
|
90
|
+
if (Test-Path $tmpExtract) { Remove-Item $tmpExtract -Recurse -Force }
|
|
91
|
+
|
|
92
|
+
Expand-Archive -Path $tmpFile -DestinationPath $tmpExtract -Force
|
|
93
|
+
$extracted = Get-ChildItem $tmpExtract | Select-Object -First 1
|
|
94
|
+
Move-Item -Path $extracted.FullName -Destination $NODE_DIR -Force
|
|
95
|
+
|
|
96
|
+
Remove-Item $tmpFile -Force -ErrorAction SilentlyContinue
|
|
97
|
+
Remove-Item $tmpExtract -Recurse -Force -ErrorAction SilentlyContinue
|
|
98
|
+
|
|
99
|
+
# Verify
|
|
100
|
+
$nodeBin = Join-Path $NODE_DIR "node.exe"
|
|
101
|
+
if (-not (Test-Path $nodeBin)) {
|
|
102
|
+
Write-Host " ✗ Node.js download failed" -ForegroundColor Red
|
|
103
|
+
exit 1
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Write-Host " ✔ Node.js v${NODE_VERSION} installed" -ForegroundColor Green
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
# ─── Install Fluxy ────────────────────────────────────────────────────────
|
|
110
|
+
|
|
111
|
+
function Install-Fluxy {
|
|
112
|
+
if ($USE_SYSTEM_NODE) {
|
|
113
|
+
$NPM = "npm"
|
|
114
|
+
$NODE_BIN = "node"
|
|
115
|
+
} else {
|
|
116
|
+
$NPM = Join-Path $NODE_DIR "npm.cmd"
|
|
117
|
+
$NODE_BIN = Join-Path $NODE_DIR "node.exe"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
Write-Host " ↓ Installing fluxy..." -ForegroundColor Cyan
|
|
121
|
+
|
|
122
|
+
# Get tarball URL from npm registry
|
|
123
|
+
$tarballUrl = (& $NPM view fluxy-bot dist.tarball 2>$null).Trim()
|
|
124
|
+
if (-not $tarballUrl) {
|
|
125
|
+
Write-Host " ✗ Failed to fetch package info from npm" -ForegroundColor Red
|
|
126
|
+
exit 1
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
# Download and extract tarball
|
|
130
|
+
$tmpDir = Join-Path ([System.IO.Path]::GetTempPath()) ("fluxy-install-" + [guid]::NewGuid().ToString("N").Substring(0,8))
|
|
131
|
+
New-Item -ItemType Directory -Path $tmpDir -Force | Out-Null
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
$tarball = Join-Path $tmpDir "fluxy.tgz"
|
|
135
|
+
Invoke-WebRequest -Uri $tarballUrl -OutFile $tarball -UseBasicParsing
|
|
136
|
+
|
|
137
|
+
tar xzf $tarball -C $tmpDir
|
|
138
|
+
|
|
139
|
+
$extracted = Join-Path $tmpDir "package"
|
|
140
|
+
if (-not (Test-Path $extracted)) {
|
|
141
|
+
Write-Host " ✗ Installation failed" -ForegroundColor Red
|
|
142
|
+
exit 1
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
# Copy source files to ~/.fluxy/ (preserves existing config.json, memory.db, etc.)
|
|
146
|
+
New-Item -ItemType Directory -Path $FLUXY_HOME -Force | Out-Null
|
|
147
|
+
Get-ChildItem -Path $extracted -Force | ForEach-Object {
|
|
148
|
+
Copy-Item -Path $_.FullName -Destination $FLUXY_HOME -Recurse -Force
|
|
149
|
+
}
|
|
150
|
+
} finally {
|
|
151
|
+
Remove-Item $tmpDir -Recurse -Force -ErrorAction SilentlyContinue
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
# Install dependencies inside ~/.fluxy/
|
|
155
|
+
Push-Location $FLUXY_HOME
|
|
156
|
+
try {
|
|
157
|
+
& $NPM install --omit=dev 2>$null
|
|
158
|
+
} catch {}
|
|
159
|
+
Pop-Location
|
|
160
|
+
|
|
161
|
+
# Verify
|
|
162
|
+
$cliPath = Join-Path $FLUXY_HOME "bin\cli.js"
|
|
163
|
+
if (-not (Test-Path $cliPath)) {
|
|
164
|
+
Write-Host " ✗ Installation failed" -ForegroundColor Red
|
|
165
|
+
exit 1
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
$script:VERSION = "unknown"
|
|
169
|
+
try {
|
|
170
|
+
$pkgJson = Get-Content (Join-Path $FLUXY_HOME "package.json") -Raw | ConvertFrom-Json
|
|
171
|
+
$script:VERSION = $pkgJson.version
|
|
172
|
+
} catch {}
|
|
173
|
+
|
|
174
|
+
Write-Host " ✔ Fluxy v${VERSION} installed" -ForegroundColor Green
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
# ─── Create wrapper script ──────────────────────────────────────────────────
|
|
178
|
+
|
|
179
|
+
function Create-Wrapper {
|
|
180
|
+
New-Item -ItemType Directory -Path $BIN_DIR -Force | Out-Null
|
|
181
|
+
|
|
182
|
+
# Remove any existing wrapper
|
|
183
|
+
$wrapperPath = Join-Path $BIN_DIR "fluxy.cmd"
|
|
184
|
+
Remove-Item $wrapperPath -Force -ErrorAction SilentlyContinue
|
|
185
|
+
|
|
186
|
+
if ($USE_SYSTEM_NODE) {
|
|
187
|
+
$wrapper = @"
|
|
188
|
+
@echo off
|
|
189
|
+
node "%USERPROFILE%\.fluxy\bin\cli.js" %*
|
|
190
|
+
"@
|
|
191
|
+
} else {
|
|
192
|
+
$wrapper = @"
|
|
193
|
+
@echo off
|
|
194
|
+
"%USERPROFILE%\.fluxy\tools\node\node.exe" "%USERPROFILE%\.fluxy\bin\cli.js" %*
|
|
195
|
+
"@
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
Set-Content -Path $wrapperPath -Value $wrapper -Encoding ASCII
|
|
199
|
+
Write-Host " ✔ Created ~/.fluxy/bin/fluxy.cmd" -ForegroundColor Green
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
# ─── Add to PATH ────────────────────────────────────────────────────────────
|
|
203
|
+
|
|
204
|
+
function Setup-Path {
|
|
205
|
+
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
|
206
|
+
if ($userPath -notlike "*$BIN_DIR*") {
|
|
207
|
+
[Environment]::SetEnvironmentVariable("Path", "$BIN_DIR;$userPath", "User")
|
|
208
|
+
$env:Path = "$BIN_DIR;$env:Path"
|
|
209
|
+
Write-Host " ✔ Added to PATH" -ForegroundColor Green
|
|
210
|
+
} else {
|
|
211
|
+
Write-Host " ✔ PATH already configured" -ForegroundColor Green
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
# ─── Main ────────────────────────────────────────────────────────────────────
|
|
216
|
+
|
|
217
|
+
New-Item -ItemType Directory -Path $FLUXY_HOME -Force | Out-Null
|
|
218
|
+
|
|
219
|
+
Detect-Platform
|
|
220
|
+
if (-not (Check-SystemNode)) { Install-Node }
|
|
221
|
+
Install-Fluxy
|
|
222
|
+
Create-Wrapper
|
|
223
|
+
Setup-Path
|
|
224
|
+
|
|
225
|
+
Write-Host ""
|
|
226
|
+
Write-Host " ✔ Fluxy is ready!" -ForegroundColor Green
|
|
227
|
+
Write-Host ""
|
|
228
|
+
Write-Host " Get started:"
|
|
229
|
+
Write-Host ""
|
|
230
|
+
Write-Host " fluxy init " -ForegroundColor Cyan -NoNewline; Write-Host "Set up your bot"
|
|
231
|
+
Write-Host " fluxy start " -ForegroundColor Cyan -NoNewline; Write-Host "Start your bot"
|
|
232
|
+
Write-Host " fluxy status " -ForegroundColor Cyan -NoNewline; Write-Host "Check if it's running"
|
|
233
|
+
Write-Host ""
|
|
234
|
+
Write-Host " Run " -ForegroundColor DarkGray -NoNewline
|
|
235
|
+
Write-Host "fluxy init" -ForegroundColor Cyan -NoNewline
|
|
236
|
+
Write-Host " to begin." -ForegroundColor DarkGray
|
|
237
|
+
Write-Host " (Open a new terminal if 'fluxy' isn't found yet)" -ForegroundColor DarkGray
|
|
238
|
+
Write-Host ""
|
|
@@ -69,7 +69,7 @@ ok "Files copied"
|
|
|
69
69
|
# ── Install dependencies ──
|
|
70
70
|
info "Installing dependencies (this may take a moment)..."
|
|
71
71
|
cd "$FLUXY_HOME"
|
|
72
|
-
npm install --omit=dev 2>/dev/null
|
|
72
|
+
npm install --omit=dev --ignore-scripts 2>/dev/null
|
|
73
73
|
ok "Dependencies installed"
|
|
74
74
|
|
|
75
75
|
# ── Create symlink ──
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
|
|
3
|
+
@custom-variant dark (&:is(.dark *));
|
|
4
|
+
|
|
5
|
+
@theme inline {
|
|
6
|
+
--color-background: #212121;
|
|
7
|
+
--color-foreground: #f5f5f5;
|
|
8
|
+
--color-card: #2a2a2a;
|
|
9
|
+
--color-card-foreground: #f5f5f5;
|
|
10
|
+
--color-popover: #2a2a2a;
|
|
11
|
+
--color-popover-foreground: #f5f5f5;
|
|
12
|
+
--color-primary: #3C8FFF;
|
|
13
|
+
--color-primary-foreground: #ffffff;
|
|
14
|
+
--color-secondary: #333333;
|
|
15
|
+
--color-secondary-foreground: #f5f5f5;
|
|
16
|
+
--color-muted: #333333;
|
|
17
|
+
--color-muted-foreground: #999999;
|
|
18
|
+
--color-accent: #333333;
|
|
19
|
+
--color-accent-foreground: #f5f5f5;
|
|
20
|
+
--color-destructive: #FD486B;
|
|
21
|
+
--color-destructive-foreground: #ffffff;
|
|
22
|
+
--color-border: #3a3a3a;
|
|
23
|
+
--color-input: #3a3a3a;
|
|
24
|
+
--color-ring: #3C8FFF;
|
|
25
|
+
--color-chart-1: #3C8FFF;
|
|
26
|
+
--color-chart-2: #FD486B;
|
|
27
|
+
--color-chart-3: #F59E0B;
|
|
28
|
+
--color-chart-4: #8B5CF6;
|
|
29
|
+
--color-chart-5: #10B981;
|
|
30
|
+
--color-sidebar: #1c1c1c;
|
|
31
|
+
--color-sidebar-foreground: #f5f5f5;
|
|
32
|
+
--color-sidebar-primary: #3C8FFF;
|
|
33
|
+
--color-sidebar-primary-foreground: #ffffff;
|
|
34
|
+
--color-sidebar-accent: #282828;
|
|
35
|
+
--color-sidebar-accent-foreground: #f5f5f5;
|
|
36
|
+
--color-sidebar-border: #3a3a3a;
|
|
37
|
+
--color-sidebar-ring: #3C8FFF;
|
|
38
|
+
--radius: 0.75rem;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
body {
|
|
42
|
+
background-color: var(--color-background);
|
|
43
|
+
color: var(--color-foreground);
|
|
44
|
+
-webkit-font-smoothing: antialiased;
|
|
45
|
+
-moz-osx-font-smoothing: grayscale;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
::selection {
|
|
49
|
+
background-color: rgba(175, 39, 227, 0.25);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
::-webkit-scrollbar { width: 6px; }
|
|
53
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
54
|
+
::-webkit-scrollbar-thumb { background: #3a3a3a; border-radius: 3px; }
|
|
55
|
+
::-webkit-scrollbar-thumb:hover { background: #4a4a4a; }
|
|
56
|
+
|
|
57
|
+
.text-gradient {
|
|
58
|
+
background-clip: text;
|
|
59
|
+
-webkit-background-clip: text;
|
|
60
|
+
color: transparent;
|
|
61
|
+
-webkit-text-fill-color: transparent;
|
|
62
|
+
background-image: linear-gradient(135deg, #04D1FE, #AF27E3, #FB4072);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.bg-gradient-brand {
|
|
66
|
+
background-image: linear-gradient(135deg, #04D1FE, #AF27E3, #FB4072);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.glow-border {
|
|
70
|
+
box-shadow: 0 0 0 1px rgba(175, 39, 227, 0.1),
|
|
71
|
+
0 0 20px -5px rgba(175, 39, 227, 0.15);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.animated-border {
|
|
75
|
+
position: relative;
|
|
76
|
+
overflow: hidden;
|
|
77
|
+
}
|
|
78
|
+
.animated-border::before {
|
|
79
|
+
content: '';
|
|
80
|
+
position: absolute;
|
|
81
|
+
inset: -150%;
|
|
82
|
+
background: conic-gradient(
|
|
83
|
+
from 0deg,
|
|
84
|
+
#04D1FE,
|
|
85
|
+
#AF27E3,
|
|
86
|
+
#FB4072,
|
|
87
|
+
#04D1FE
|
|
88
|
+
);
|
|
89
|
+
animation: border-spin 3s linear infinite;
|
|
90
|
+
}
|
|
91
|
+
.animated-border > * {
|
|
92
|
+
position: relative;
|
|
93
|
+
z-index: 1;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.animated-border-slow::before {
|
|
97
|
+
animation-duration: 5s;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.input-glow:focus {
|
|
101
|
+
border-color: rgba(175, 39, 227, 0.4);
|
|
102
|
+
box-shadow: 0 0 0 1px rgba(175, 39, 227, 0.15),
|
|
103
|
+
0 0 20px -5px rgba(175, 39, 227, 0.25),
|
|
104
|
+
0 0 4px -1px rgba(4, 209, 254, 0.1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@keyframes border-spin {
|
|
108
|
+
0% { transform: rotate(0deg); }
|
|
109
|
+
100% { transform: rotate(360deg); }
|
|
110
|
+
}
|
package/supervisor/widget.js
CHANGED
|
@@ -72,4 +72,12 @@
|
|
|
72
72
|
document.addEventListener('keydown', function (e) {
|
|
73
73
|
if (e.key === 'Escape' && isOpen) toggle();
|
|
74
74
|
});
|
|
75
|
+
|
|
76
|
+
// Restore open state after HMR reload (so chat isn't disrupted)
|
|
77
|
+
try {
|
|
78
|
+
if (sessionStorage.getItem('fluxy_widget_open') === '1') {
|
|
79
|
+
sessionStorage.removeItem('fluxy_widget_open');
|
|
80
|
+
toggle();
|
|
81
|
+
}
|
|
82
|
+
} catch (e) {}
|
|
75
83
|
})();
|
package/vite.fluxy.config.ts
CHANGED
|
@@ -4,16 +4,16 @@ import tailwindcss from '@tailwindcss/vite';
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
|
|
6
6
|
export default defineConfig({
|
|
7
|
-
root: '
|
|
7
|
+
root: 'supervisor/chat',
|
|
8
8
|
base: '/fluxy/',
|
|
9
9
|
resolve: {
|
|
10
|
-
alias: { '@': path.resolve(__dirname, '
|
|
10
|
+
alias: { '@': path.resolve(__dirname, 'supervisor/chat/src') },
|
|
11
11
|
},
|
|
12
12
|
build: {
|
|
13
|
-
outDir: '
|
|
13
|
+
outDir: '../../dist-fluxy',
|
|
14
14
|
emptyOutDir: true,
|
|
15
15
|
rollupOptions: {
|
|
16
|
-
input: path.resolve(__dirname, '
|
|
16
|
+
input: path.resolve(__dirname, 'supervisor/chat/fluxy.html'),
|
|
17
17
|
},
|
|
18
18
|
},
|
|
19
19
|
optimizeDeps: {
|
|
@@ -6,13 +6,11 @@ You are a Fluxy bot agent — a self-hosted AI assistant running on the user's o
|
|
|
6
6
|
- The dashboard and UI source code is in client/src/ (e.g. client/src/App.tsx, client/src/components/).
|
|
7
7
|
- NEVER look in dist/ or dist-fluxy/ — those are stale build artifacts. Always edit files in client/src/.
|
|
8
8
|
- You CAN read and modify your own source code to improve yourself — add features, fix bugs, change behavior.
|
|
9
|
-
- You MUST NEVER modify
|
|
10
|
-
-
|
|
11
|
-
- client/fluxy-main.tsx
|
|
12
|
-
- client/src/hooks/useFluxyChat.ts
|
|
9
|
+
- You MUST NEVER modify anything inside supervisor/ — this is the chat interface that connects you to the user. If you break it, the user loses the ability to talk to you. Off-limits files include:
|
|
10
|
+
- supervisor/chat/ (the entire chat UI)
|
|
13
11
|
- supervisor/widget.js
|
|
14
12
|
- supervisor/fluxy-agent.ts
|
|
15
|
-
- supervisor/index.ts
|
|
13
|
+
- supervisor/index.ts
|
|
16
14
|
|
|
17
15
|
# Rules
|
|
18
16
|
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
export function useMobile(breakpoint = 768) {
|
|
4
|
-
const [isMobile, setIsMobile] = useState(false);
|
|
5
|
-
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
const mql = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
|
|
8
|
-
const onChange = (e: MediaQueryListEvent | MediaQueryList) =>
|
|
9
|
-
setIsMobile(e.matches);
|
|
10
|
-
onChange(mql);
|
|
11
|
-
mql.addEventListener('change', onChange);
|
|
12
|
-
return () => mql.removeEventListener('change', onChange);
|
|
13
|
-
}, [breakpoint]);
|
|
14
|
-
|
|
15
|
-
return isMobile;
|
|
16
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
LayoutDashboard,
|
|
3
|
-
MessageSquare,
|
|
4
|
-
Brain,
|
|
5
|
-
BookOpen,
|
|
6
|
-
ScrollText,
|
|
7
|
-
Settings,
|
|
8
|
-
type LucideIcon,
|
|
9
|
-
} from 'lucide-react';
|
|
10
|
-
|
|
11
|
-
/* ── Navigation ─────────────────────────────── */
|
|
12
|
-
|
|
13
|
-
export interface NavItem {
|
|
14
|
-
label: string;
|
|
15
|
-
icon: LucideIcon;
|
|
16
|
-
href: string;
|
|
17
|
-
active?: boolean;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface NavSection {
|
|
21
|
-
label: string;
|
|
22
|
-
items: NavItem[];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const navSections: NavSection[] = [
|
|
26
|
-
{
|
|
27
|
-
label: 'HOME',
|
|
28
|
-
items: [
|
|
29
|
-
{ label: 'Overview', icon: LayoutDashboard, href: '#', active: true },
|
|
30
|
-
{ label: 'Conversations', icon: MessageSquare, href: '#' },
|
|
31
|
-
{ label: 'Models', icon: Brain, href: '#' },
|
|
32
|
-
{ label: 'Knowledge', icon: BookOpen, href: '#' },
|
|
33
|
-
],
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
label: 'SYSTEM',
|
|
37
|
-
items: [
|
|
38
|
-
{ label: 'Logs', icon: ScrollText, href: '#' },
|
|
39
|
-
{ label: 'Settings', icon: Settings, href: '#' },
|
|
40
|
-
],
|
|
41
|
-
},
|
|
42
|
-
];
|
|
43
|
-
|
|
44
|
-
/* ── Weekly activity grid ───────────────────── */
|
|
45
|
-
|
|
46
|
-
export interface WeeklyModelActivity {
|
|
47
|
-
model: string;
|
|
48
|
-
/** 0–4 intensity per day (Mon–Sun) */
|
|
49
|
-
days: number[];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const weeklyActivity: WeeklyModelActivity[] = [
|
|
53
|
-
{ model: 'GPT-4o', days: [3, 2, 4, 3, 1, 2, 0] },
|
|
54
|
-
{ model: 'Claude', days: [2, 4, 3, 4, 2, 1, 1] },
|
|
55
|
-
{ model: 'Local', days: [1, 1, 2, 1, 3, 4, 2] },
|
|
56
|
-
];
|
|
57
|
-
|
|
58
|
-
export const dayLabels = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
|
|
59
|
-
|
|
60
|
-
export const activityColors = [
|
|
61
|
-
'#2a2a2a', // 0 – none
|
|
62
|
-
'#1e3a5f', // 1 – low
|
|
63
|
-
'#2c5a8f', // 2 – medium-low
|
|
64
|
-
'#3578bf', // 3 – medium-high
|
|
65
|
-
'#3C8FFF', // 4 – high
|
|
66
|
-
];
|
|
67
|
-
|
|
68
|
-
export const activityLegend = [
|
|
69
|
-
{ label: '< 10', level: 1 },
|
|
70
|
-
{ label: '10–50', level: 2 },
|
|
71
|
-
{ label: '> 50', level: 3 },
|
|
72
|
-
{ label: '100+', level: 4 },
|
|
73
|
-
{ label: 'None', level: 0 },
|
|
74
|
-
];
|
|
75
|
-
|
|
76
|
-
/* ── Stats ──────────────────────────────────── */
|
|
77
|
-
|
|
78
|
-
export interface StatItem {
|
|
79
|
-
label: string;
|
|
80
|
-
value: string;
|
|
81
|
-
change: string;
|
|
82
|
-
trend: 'up' | 'down';
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export const stats: StatItem[] = [
|
|
86
|
-
{ label: 'Conversations', value: '1,284', change: '+12%', trend: 'up' },
|
|
87
|
-
{ label: 'Messages Today', value: '342', change: '+8%', trend: 'up' },
|
|
88
|
-
{ label: 'Avg Response', value: '1.2s', change: '-15%', trend: 'down' },
|
|
89
|
-
{ label: 'Uptime', value: '99.9%', change: '+0.1%', trend: 'up' },
|
|
90
|
-
];
|
|
91
|
-
|
|
92
|
-
/* ── System status ──────────────────────────── */
|
|
93
|
-
|
|
94
|
-
export interface SystemService {
|
|
95
|
-
name: string;
|
|
96
|
-
status: 'online' | 'offline' | 'degraded';
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export const systemStatus: SystemService[] = [
|
|
100
|
-
{ name: 'Worker', status: 'online' },
|
|
101
|
-
{ name: 'Tunnel', status: 'online' },
|
|
102
|
-
{ name: 'Database', status: 'online' },
|
|
103
|
-
{ name: 'AI Provider', status: 'online' },
|
|
104
|
-
];
|
package/install.ps1
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# ── Fluxy Installer for Windows ──
|
|
2
|
-
# Downloads the latest fluxy-bot from npm and installs to ~/.fluxy/
|
|
3
|
-
|
|
4
|
-
$ErrorActionPreference = "Stop"
|
|
5
|
-
|
|
6
|
-
$FLUXY_HOME = Join-Path $env:USERPROFILE ".fluxy"
|
|
7
|
-
|
|
8
|
-
function Write-Info($msg) { Write-Host " ▸ $msg" -ForegroundColor Cyan }
|
|
9
|
-
function Write-Ok($msg) { Write-Host " ✔ $msg" -ForegroundColor Green }
|
|
10
|
-
function Write-Err($msg) { Write-Host " ✘ $msg" -ForegroundColor Red }
|
|
11
|
-
|
|
12
|
-
Write-Host ""
|
|
13
|
-
Write-Host " Fluxy Installer" -ForegroundColor Cyan
|
|
14
|
-
Write-Host ""
|
|
15
|
-
|
|
16
|
-
# ── Check dependencies ──
|
|
17
|
-
foreach ($cmd in @("node", "npm")) {
|
|
18
|
-
if (-not (Get-Command $cmd -ErrorAction SilentlyContinue)) {
|
|
19
|
-
Write-Err "$cmd is required but not installed."
|
|
20
|
-
exit 1
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
# ── Get tarball URL ──
|
|
25
|
-
Write-Info "Fetching latest version..."
|
|
26
|
-
$TARBALL_URL = (npm view fluxy-bot dist.tarball 2>$null).Trim()
|
|
27
|
-
if (-not $TARBALL_URL) {
|
|
28
|
-
Write-Err "Failed to fetch tarball URL from npm."
|
|
29
|
-
exit 1
|
|
30
|
-
}
|
|
31
|
-
$VERSION = (npm view fluxy-bot version 2>$null).Trim()
|
|
32
|
-
Write-Ok "Found fluxy-bot@$VERSION"
|
|
33
|
-
|
|
34
|
-
# ── Download and extract ──
|
|
35
|
-
$TMPDIR = Join-Path ([System.IO.Path]::GetTempPath()) ("fluxy-install-" + [guid]::NewGuid().ToString("N").Substring(0,8))
|
|
36
|
-
New-Item -ItemType Directory -Path $TMPDIR -Force | Out-Null
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
Write-Info "Downloading..."
|
|
40
|
-
$tarball = Join-Path $TMPDIR "fluxy.tgz"
|
|
41
|
-
Invoke-WebRequest -Uri $TARBALL_URL -OutFile $tarball -UseBasicParsing
|
|
42
|
-
Write-Ok "Downloaded"
|
|
43
|
-
|
|
44
|
-
Write-Info "Extracting..."
|
|
45
|
-
tar xzf $tarball -C $TMPDIR
|
|
46
|
-
Write-Ok "Extracted"
|
|
47
|
-
|
|
48
|
-
$EXTRACTED = Join-Path $TMPDIR "package"
|
|
49
|
-
if (-not (Test-Path $EXTRACTED)) {
|
|
50
|
-
Write-Err "Unexpected tarball structure."
|
|
51
|
-
exit 1
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
# ── Copy to ~/.fluxy/ ──
|
|
55
|
-
Write-Info "Installing to $FLUXY_HOME..."
|
|
56
|
-
New-Item -ItemType Directory -Path $FLUXY_HOME -Force | Out-Null
|
|
57
|
-
|
|
58
|
-
# Copy-Item -Recurse -Force overwrites existing files but does NOT delete extras
|
|
59
|
-
Get-ChildItem -Path $EXTRACTED -Force | ForEach-Object {
|
|
60
|
-
Copy-Item -Path $_.FullName -Destination $FLUXY_HOME -Recurse -Force
|
|
61
|
-
}
|
|
62
|
-
Write-Ok "Files copied"
|
|
63
|
-
|
|
64
|
-
# ── Install dependencies ──
|
|
65
|
-
Write-Info "Installing dependencies (this may take a moment)..."
|
|
66
|
-
Push-Location $FLUXY_HOME
|
|
67
|
-
npm install --omit=dev 2>$null
|
|
68
|
-
Pop-Location
|
|
69
|
-
Write-Ok "Dependencies installed"
|
|
70
|
-
|
|
71
|
-
# ── Add to PATH ──
|
|
72
|
-
Write-Info "Configuring PATH..."
|
|
73
|
-
$binDir = Join-Path $FLUXY_HOME "bin"
|
|
74
|
-
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
|
75
|
-
if ($userPath -notlike "*$binDir*") {
|
|
76
|
-
[Environment]::SetEnvironmentVariable("Path", "$binDir;$userPath", "User")
|
|
77
|
-
$env:Path = "$binDir;$env:Path"
|
|
78
|
-
Write-Ok "Added $binDir to user PATH"
|
|
79
|
-
} else {
|
|
80
|
-
Write-Ok "PATH already configured"
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
Write-Host ""
|
|
84
|
-
Write-Host " Fluxy v$VERSION installed successfully!" -ForegroundColor Green
|
|
85
|
-
Write-Host " Run 'fluxy' to start your bot." -ForegroundColor DarkGray
|
|
86
|
-
Write-Host ""
|
|
87
|
-
}
|
|
88
|
-
finally {
|
|
89
|
-
# Clean up temp directory
|
|
90
|
-
Remove-Item -Path $TMPDIR -Recurse -Force -ErrorAction SilentlyContinue
|
|
91
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|