fluxy-bot 0.3.27 → 0.4.0
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/bin/cli.js +125 -6
- package/package.json +2 -3
- package/scripts/install +60 -25
- package/scripts/install.ps1 +85 -26
- package/scripts/install.sh +60 -25
- package/scripts/postinstall.js +21 -9
package/bin/cli.js
CHANGED
|
@@ -30,6 +30,8 @@ const c = {
|
|
|
30
30
|
yellow: '\x1b[33m',
|
|
31
31
|
red: '\x1b[31m',
|
|
32
32
|
white: '\x1b[97m',
|
|
33
|
+
blue: '\x1b[38;2;50;165;247m',
|
|
34
|
+
pink: '\x1b[38;2;219;54;163m',
|
|
33
35
|
};
|
|
34
36
|
|
|
35
37
|
const SPINNER = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
@@ -100,10 +102,11 @@ class Stepper {
|
|
|
100
102
|
|
|
101
103
|
function banner() {
|
|
102
104
|
console.log(`
|
|
103
|
-
${c.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
${c.
|
|
105
|
+
${c.blue}${c.bold} ___ __ ${c.reset}
|
|
106
|
+
${c.blue}${c.bold} / _/ / / __ __ __ __ __ ${c.reset}
|
|
107
|
+
${c.pink}${c.bold} / _/ / / / / / / \\ \\/ / / / ${c.reset}
|
|
108
|
+
${c.pink}${c.bold} /_/ /_/ \\_,_/ /_/\\_\\ /_/ ${c.reset}
|
|
109
|
+
${c.dim}v${pkg.version} · Self-hosted AI bot${c.reset}`);
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
function finalMessage(tunnelUrl, relayUrl) {
|
|
@@ -112,13 +115,13 @@ function finalMessage(tunnelUrl, relayUrl) {
|
|
|
112
115
|
|
|
113
116
|
${c.bold}${c.white}Open your dashboard to finish setup:${c.reset}
|
|
114
117
|
|
|
115
|
-
${c.
|
|
118
|
+
${c.blue}${c.bold}${tunnelUrl}${c.reset}`);
|
|
116
119
|
|
|
117
120
|
if (relayUrl) {
|
|
118
121
|
console.log(`
|
|
119
122
|
${c.bold}${c.white}Your permanent URL:${c.reset}
|
|
120
123
|
|
|
121
|
-
${c.
|
|
124
|
+
${c.blue}${c.bold}${relayUrl}${c.reset}`);
|
|
122
125
|
}
|
|
123
126
|
|
|
124
127
|
console.log(`
|
|
@@ -396,12 +399,128 @@ async function status() {
|
|
|
396
399
|
}
|
|
397
400
|
}
|
|
398
401
|
|
|
402
|
+
async function update() {
|
|
403
|
+
banner();
|
|
404
|
+
|
|
405
|
+
const currentVersion = pkg.version;
|
|
406
|
+
console.log(`\n ${c.dim}Current version: v${currentVersion}${c.reset}`);
|
|
407
|
+
console.log(` ${c.blue}⠋${c.reset} Checking for updates...\n`);
|
|
408
|
+
|
|
409
|
+
// Fetch latest package info from npm registry
|
|
410
|
+
let latest;
|
|
411
|
+
try {
|
|
412
|
+
const res = await fetch('https://registry.npmjs.org/fluxy-bot/latest');
|
|
413
|
+
if (!res.ok) throw new Error();
|
|
414
|
+
latest = await res.json();
|
|
415
|
+
} catch {
|
|
416
|
+
console.log(` ${c.red}✗${c.reset} Failed to check for updates\n`);
|
|
417
|
+
process.exit(1);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (currentVersion === latest.version) {
|
|
421
|
+
console.log(` ${c.green}✔${c.reset} Already up to date (v${currentVersion})\n`);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
console.log(` ${c.dim}v${currentVersion} → v${latest.version}${c.reset}\n`);
|
|
426
|
+
|
|
427
|
+
const steps = [
|
|
428
|
+
'Downloading update',
|
|
429
|
+
'Updating files',
|
|
430
|
+
'Installing dependencies',
|
|
431
|
+
'Building interface',
|
|
432
|
+
];
|
|
433
|
+
|
|
434
|
+
const stepper = new Stepper(steps);
|
|
435
|
+
stepper.start();
|
|
436
|
+
|
|
437
|
+
// Download tarball
|
|
438
|
+
const tarballUrl = latest.dist.tarball;
|
|
439
|
+
const tmpDir = path.join(os.tmpdir(), `fluxy-update-${Date.now()}`);
|
|
440
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
441
|
+
const tarball = path.join(tmpDir, 'fluxy.tgz');
|
|
442
|
+
|
|
443
|
+
try {
|
|
444
|
+
const res = await fetch(tarballUrl);
|
|
445
|
+
if (!res.ok) throw new Error();
|
|
446
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
447
|
+
fs.writeFileSync(tarball, buf);
|
|
448
|
+
execSync(`tar xzf "${tarball}" -C "${tmpDir}"`, { stdio: 'ignore' });
|
|
449
|
+
} catch {
|
|
450
|
+
stepper.finish();
|
|
451
|
+
console.log(`\n ${c.red}✗${c.reset} Download failed\n`);
|
|
452
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
453
|
+
process.exit(1);
|
|
454
|
+
}
|
|
455
|
+
stepper.advance();
|
|
456
|
+
|
|
457
|
+
const extracted = path.join(tmpDir, 'package');
|
|
458
|
+
|
|
459
|
+
// Update code directories (preserve workspace/ user data)
|
|
460
|
+
for (const dir of ['bin', 'supervisor', 'worker', 'shared', 'scripts']) {
|
|
461
|
+
const src = path.join(extracted, dir);
|
|
462
|
+
if (fs.existsSync(src)) {
|
|
463
|
+
fs.cpSync(src, path.join(DATA_DIR, dir), { recursive: true, force: true });
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// Copy workspace template only if it doesn't exist yet
|
|
468
|
+
if (!fs.existsSync(path.join(DATA_DIR, 'workspace'))) {
|
|
469
|
+
const wsSrc = path.join(extracted, 'workspace');
|
|
470
|
+
if (fs.existsSync(wsSrc)) {
|
|
471
|
+
fs.cpSync(wsSrc, path.join(DATA_DIR, 'workspace'), { recursive: true });
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// Update code files (never touches config.json, memory.db, etc.)
|
|
476
|
+
for (const file of ['package.json', 'vite.config.ts', 'vite.fluxy.config.ts', 'tsconfig.json', 'postcss.config.js', 'components.json']) {
|
|
477
|
+
const src = path.join(extracted, file);
|
|
478
|
+
if (fs.existsSync(src)) {
|
|
479
|
+
fs.copyFileSync(src, path.join(DATA_DIR, file));
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// Update pre-built UI from tarball
|
|
484
|
+
const distSrc = path.join(extracted, 'dist-fluxy');
|
|
485
|
+
const distDst = path.join(DATA_DIR, 'dist-fluxy');
|
|
486
|
+
if (fs.existsSync(distSrc)) {
|
|
487
|
+
if (fs.existsSync(distDst)) fs.rmSync(distDst, { recursive: true });
|
|
488
|
+
fs.cpSync(distSrc, distDst, { recursive: true });
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
stepper.advance();
|
|
492
|
+
|
|
493
|
+
// Install dependencies
|
|
494
|
+
try {
|
|
495
|
+
execSync('npm install --omit=dev', { cwd: DATA_DIR, stdio: 'ignore' });
|
|
496
|
+
} catch {}
|
|
497
|
+
stepper.advance();
|
|
498
|
+
|
|
499
|
+
// Rebuild UI if not in tarball
|
|
500
|
+
if (!fs.existsSync(path.join(distDst, 'onboard.html'))) {
|
|
501
|
+
try {
|
|
502
|
+
if (fs.existsSync(distDst)) fs.rmSync(distDst, { recursive: true });
|
|
503
|
+
execSync('npm run build:fluxy', { cwd: DATA_DIR, stdio: 'ignore' });
|
|
504
|
+
} catch {}
|
|
505
|
+
}
|
|
506
|
+
stepper.advance();
|
|
507
|
+
|
|
508
|
+
// Clean up
|
|
509
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
510
|
+
|
|
511
|
+
stepper.finish();
|
|
512
|
+
|
|
513
|
+
console.log(`\n ${c.green}${c.bold}✔ Updated to v${latest.version}${c.reset}\n`);
|
|
514
|
+
console.log(` ${c.dim}Run ${c.reset}${c.cyan}fluxy start${c.reset}${c.dim} to launch.${c.reset}\n`);
|
|
515
|
+
}
|
|
516
|
+
|
|
399
517
|
// ── Route ──
|
|
400
518
|
|
|
401
519
|
switch (command) {
|
|
402
520
|
case 'init': init(); break;
|
|
403
521
|
case 'start': start(); break;
|
|
404
522
|
case 'status': status(); break;
|
|
523
|
+
case 'update': update(); break;
|
|
405
524
|
default:
|
|
406
525
|
fs.existsSync(CONFIG_PATH) ? start() : init();
|
|
407
526
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fluxy-bot",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Self-hosted AI
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Self-hosted, self-evolving AI agent with its own dashboard.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
"tsconfig.json",
|
|
21
21
|
"postcss.config.js",
|
|
22
22
|
"components.json",
|
|
23
|
-
"install.sh",
|
|
24
23
|
"install.ps1"
|
|
25
24
|
],
|
|
26
25
|
"keywords": [
|
package/scripts/install
CHANGED
|
@@ -15,7 +15,9 @@ NODE_DIR="$TOOLS_DIR/node"
|
|
|
15
15
|
BIN_DIR="$FLUXY_HOME/bin"
|
|
16
16
|
USE_SYSTEM_NODE=false
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
# Brand colors: #32A5F7 (blue) and #DB36A3 (pink) via 256-color approximation
|
|
19
|
+
BLUE='\033[38;2;50;165;247m'
|
|
20
|
+
PINK='\033[38;2;219;54;163m'
|
|
19
21
|
GREEN='\033[32m'
|
|
20
22
|
YELLOW='\033[33m'
|
|
21
23
|
RED='\033[31m'
|
|
@@ -23,10 +25,14 @@ DIM='\033[2m'
|
|
|
23
25
|
BOLD='\033[1m'
|
|
24
26
|
RESET='\033[0m'
|
|
25
27
|
|
|
26
|
-
printf "\n
|
|
27
|
-
printf "${
|
|
28
|
-
printf "${
|
|
29
|
-
printf "${
|
|
28
|
+
printf "\n"
|
|
29
|
+
printf "${BLUE}${BOLD} ___ __ ${RESET}\n"
|
|
30
|
+
printf "${BLUE}${BOLD} / _/ / / __ __ __ __ __ ${RESET}\n"
|
|
31
|
+
printf "${PINK}${BOLD} / _/ / / / / / / \\ \\/ / / / ${RESET}\n"
|
|
32
|
+
printf "${PINK}${BOLD} /_/ /_/ \\_,_/ /_/\\_\\ /_/ ${RESET}\n"
|
|
33
|
+
printf "\n"
|
|
34
|
+
printf "${DIM} Self-hosted AI bot installer${RESET}\n"
|
|
35
|
+
printf "${DIM} ─────────────────────────────${RESET}\n\n"
|
|
30
36
|
|
|
31
37
|
# ─── Detect platform ────────────────────────────────────────────────────────
|
|
32
38
|
|
|
@@ -85,7 +91,7 @@ install_node() {
|
|
|
85
91
|
fi
|
|
86
92
|
fi
|
|
87
93
|
|
|
88
|
-
printf " ${
|
|
94
|
+
printf " ${BLUE}↓${RESET} Downloading Node.js v${NODE_VERSION}...\n"
|
|
89
95
|
|
|
90
96
|
NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-${PLATFORM}-${NODEARCH}.tar.xz"
|
|
91
97
|
TMPFILE=$(mktemp /tmp/node-XXXXXX.tar.xz)
|
|
@@ -128,9 +134,14 @@ install_fluxy() {
|
|
|
128
134
|
NODE="$NODE_DIR/bin/node"
|
|
129
135
|
fi
|
|
130
136
|
|
|
131
|
-
|
|
137
|
+
# Fetch version + tarball URL from npm registry
|
|
138
|
+
NPM_VERSION=$("$NPM" view fluxy-bot version 2>/dev/null || echo "")
|
|
139
|
+
if [ -n "$NPM_VERSION" ]; then
|
|
140
|
+
printf " ${DIM}Latest npm version: fluxy-bot@${NPM_VERSION}${RESET}\n"
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
printf " ${BLUE}↓${RESET} Installing fluxy...\n"
|
|
132
144
|
|
|
133
|
-
# Get tarball URL from npm registry
|
|
134
145
|
TARBALL_URL=$("$NPM" view fluxy-bot dist.tarball 2>/dev/null)
|
|
135
146
|
if [ -z "$TARBALL_URL" ]; then
|
|
136
147
|
printf " ${RED}✗${RESET} Failed to fetch package info from npm\n"
|
|
@@ -154,26 +165,42 @@ install_fluxy() {
|
|
|
154
165
|
exit 1
|
|
155
166
|
fi
|
|
156
167
|
|
|
157
|
-
# Copy
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
168
|
+
# Copy code directories (always safe to overwrite)
|
|
169
|
+
for dir in bin supervisor worker shared scripts; do
|
|
170
|
+
[ -d "$EXTRACTED/$dir" ] && cp -r "$EXTRACTED/$dir" "$FLUXY_HOME/"
|
|
171
|
+
done
|
|
161
172
|
|
|
162
|
-
#
|
|
163
|
-
|
|
173
|
+
# Copy workspace template only on first install (preserves user files)
|
|
174
|
+
if [ ! -d "$FLUXY_HOME/workspace" ]; then
|
|
175
|
+
[ -d "$EXTRACTED/workspace" ] && cp -r "$EXTRACTED/workspace" "$FLUXY_HOME/"
|
|
176
|
+
fi
|
|
164
177
|
|
|
165
|
-
#
|
|
166
|
-
|
|
178
|
+
# Copy code files (never touches config.json, memory.db, etc.)
|
|
179
|
+
for f in package.json vite.config.ts vite.fluxy.config.ts tsconfig.json postcss.config.js components.json; do
|
|
180
|
+
[ -f "$EXTRACTED/$f" ] && cp "$EXTRACTED/$f" "$FLUXY_HOME/"
|
|
181
|
+
done
|
|
182
|
+
|
|
183
|
+
# Copy pre-built UI from tarball, or build from source
|
|
184
|
+
if [ -d "$EXTRACTED/dist-fluxy" ]; then
|
|
185
|
+
rm -rf "$FLUXY_HOME/dist-fluxy"
|
|
186
|
+
cp -r "$EXTRACTED/dist-fluxy" "$FLUXY_HOME/"
|
|
167
187
|
printf " ${GREEN}✔${RESET} Chat interface ready\n"
|
|
168
|
-
|
|
169
|
-
printf " ${
|
|
188
|
+
elif [ ! -f "$FLUXY_HOME/dist-fluxy/onboard.html" ]; then
|
|
189
|
+
printf " ${BLUE}↓${RESET} Building chat interface...\n"
|
|
170
190
|
if (cd "$FLUXY_HOME" && "$NPM" run build:fluxy 2>/dev/null); then
|
|
171
191
|
printf " ${GREEN}✔${RESET} Chat interface built\n"
|
|
172
192
|
else
|
|
173
193
|
printf " ${YELLOW}!${RESET} Chat build skipped — will build on first start\n"
|
|
174
194
|
fi
|
|
195
|
+
else
|
|
196
|
+
printf " ${GREEN}✔${RESET} Chat interface ready\n"
|
|
175
197
|
fi
|
|
176
198
|
|
|
199
|
+
rm -rf "$TMPDIR"
|
|
200
|
+
|
|
201
|
+
# Install dependencies inside ~/.fluxy/
|
|
202
|
+
(cd "$FLUXY_HOME" && "$NPM" install --omit=dev 2>/dev/null)
|
|
203
|
+
|
|
177
204
|
# Verify
|
|
178
205
|
if [ ! -f "$FLUXY_HOME/bin/cli.js" ]; then
|
|
179
206
|
printf " ${RED}✗${RESET} Installation failed\n"
|
|
@@ -270,10 +297,18 @@ install_fluxy
|
|
|
270
297
|
create_wrapper
|
|
271
298
|
setup_path
|
|
272
299
|
|
|
273
|
-
printf "\n
|
|
274
|
-
printf "
|
|
275
|
-
printf "
|
|
276
|
-
printf "
|
|
277
|
-
printf "
|
|
278
|
-
printf "
|
|
279
|
-
printf "
|
|
300
|
+
printf "\n"
|
|
301
|
+
printf " ${GREEN}${BOLD}✔ Fluxy is ready!${RESET}\n"
|
|
302
|
+
printf "\n"
|
|
303
|
+
printf " ${DIM}─────────────────────────────${RESET}\n"
|
|
304
|
+
printf " ${BOLD}Get started:${RESET}\n"
|
|
305
|
+
printf "\n"
|
|
306
|
+
printf " ${BLUE}fluxy init${RESET} Set up your bot\n"
|
|
307
|
+
printf " ${BLUE}fluxy start${RESET} Start your bot\n"
|
|
308
|
+
printf " ${BLUE}fluxy status${RESET} Check if it's running\n"
|
|
309
|
+
printf "\n"
|
|
310
|
+
printf " ${PINK}>${RESET} Run ${BLUE}fluxy init${RESET} to begin.\n"
|
|
311
|
+
printf " ${DIM}(Open a new terminal if 'fluxy' isn't found yet)${RESET}\n"
|
|
312
|
+
printf "\n"
|
|
313
|
+
printf " ${DIM}https://fluxy.bot${RESET}\n"
|
|
314
|
+
printf "\n"
|
package/scripts/install.ps1
CHANGED
|
@@ -14,11 +14,33 @@ $NODE_DIR = Join-Path $TOOLS_DIR "node"
|
|
|
14
14
|
$BIN_DIR = Join-Path $FLUXY_HOME "bin"
|
|
15
15
|
$USE_SYSTEM_NODE = $false
|
|
16
16
|
|
|
17
|
+
# Ensure UTF-8 output for proper rendering
|
|
18
|
+
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
19
|
+
|
|
20
|
+
# Brand colors via ANSI escape sequences: #32A5F7 (blue) and #DB36A3 (pink)
|
|
21
|
+
$BLUE = "`e[38;2;50;165;247m"
|
|
22
|
+
$PINK = "`e[38;2;219;54;163m"
|
|
23
|
+
$BOLD = "`e[1m"
|
|
24
|
+
$RSET = "`e[0m"
|
|
25
|
+
|
|
26
|
+
# Use ANSI sequences for consistent rendering; fallback to plain if no VT support
|
|
27
|
+
$vtSupported = $null -ne $env:WT_SESSION -or $PSVersionTable.PSVersion.Major -ge 7 -or $host.UI.SupportsVirtualTerminal
|
|
28
|
+
|
|
17
29
|
Write-Host ""
|
|
18
|
-
|
|
19
|
-
Write-Host "
|
|
20
|
-
Write-Host "
|
|
21
|
-
Write-Host "
|
|
30
|
+
if ($vtSupported) {
|
|
31
|
+
Write-Host "${BLUE}${BOLD} ___ __ ${RSET}"
|
|
32
|
+
Write-Host "${BLUE}${BOLD} / _/ / / __ __ __ __ __ ${RSET}"
|
|
33
|
+
Write-Host "${PINK}${BOLD} / _/ / / / / / / \ \/ / / / ${RSET}"
|
|
34
|
+
Write-Host "${PINK}${BOLD} /_/ /_/ \_,_/ /_/\_\ /_/ ${RSET}"
|
|
35
|
+
} else {
|
|
36
|
+
Write-Host " ___ __ " -ForegroundColor Cyan
|
|
37
|
+
Write-Host " / _/ / / __ __ __ __ __ " -ForegroundColor Cyan
|
|
38
|
+
Write-Host " / _/ / / / / / / \ \/ / / / " -ForegroundColor Magenta
|
|
39
|
+
Write-Host " /_/ /_/ \_,_/ /_/\_\ /_/ " -ForegroundColor Magenta
|
|
40
|
+
}
|
|
41
|
+
Write-Host ""
|
|
42
|
+
Write-Host " Self-hosted AI bot installer" -ForegroundColor DarkGray
|
|
43
|
+
Write-Host " -----------------------------" -ForegroundColor DarkGray
|
|
22
44
|
Write-Host ""
|
|
23
45
|
|
|
24
46
|
# ─── Detect platform ────────────────────────────────────────────────────────
|
|
@@ -117,9 +139,15 @@ function Install-Fluxy {
|
|
|
117
139
|
$NODE_BIN = Join-Path $NODE_DIR "node.exe"
|
|
118
140
|
}
|
|
119
141
|
|
|
142
|
+
# Fetch version + tarball URL from npm registry
|
|
143
|
+
$npmVersion = ""
|
|
144
|
+
try { $npmVersion = (& $NPM view fluxy-bot version 2>$null).Trim() } catch {}
|
|
145
|
+
if ($npmVersion) {
|
|
146
|
+
Write-Host " Latest npm version: fluxy-bot@${npmVersion}" -ForegroundColor DarkGray
|
|
147
|
+
}
|
|
148
|
+
|
|
120
149
|
Write-Host " ↓ Installing fluxy..." -ForegroundColor Cyan
|
|
121
150
|
|
|
122
|
-
# Get tarball URL from npm registry
|
|
123
151
|
$tarballUrl = (& $NPM view fluxy-bot dist.tarball 2>$null).Trim()
|
|
124
152
|
if (-not $tarballUrl) {
|
|
125
153
|
Write-Host " ✗ Failed to fetch package info from npm" -ForegroundColor Red
|
|
@@ -142,10 +170,52 @@ function Install-Fluxy {
|
|
|
142
170
|
exit 1
|
|
143
171
|
}
|
|
144
172
|
|
|
145
|
-
# Copy source files to ~/.fluxy/ (preserves existing config.json, memory.db, etc.)
|
|
146
173
|
New-Item -ItemType Directory -Path $FLUXY_HOME -Force | Out-Null
|
|
147
|
-
|
|
148
|
-
|
|
174
|
+
|
|
175
|
+
# Copy code directories (always safe to overwrite)
|
|
176
|
+
foreach ($dir in @("bin", "supervisor", "worker", "shared", "scripts")) {
|
|
177
|
+
$src = Join-Path $extracted $dir
|
|
178
|
+
if (Test-Path $src) {
|
|
179
|
+
Copy-Item -Path $src -Destination $FLUXY_HOME -Recurse -Force
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
# Copy workspace template only on first install (preserves user files)
|
|
184
|
+
$wsDst = Join-Path $FLUXY_HOME "workspace"
|
|
185
|
+
if (-not (Test-Path $wsDst)) {
|
|
186
|
+
$wsSrc = Join-Path $extracted "workspace"
|
|
187
|
+
if (Test-Path $wsSrc) {
|
|
188
|
+
Copy-Item -Path $wsSrc -Destination $FLUXY_HOME -Recurse
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
# Copy code files (never touches config.json, memory.db, etc.)
|
|
193
|
+
foreach ($file in @("package.json", "vite.config.ts", "vite.fluxy.config.ts", "tsconfig.json", "postcss.config.js", "components.json")) {
|
|
194
|
+
$src = Join-Path $extracted $file
|
|
195
|
+
if (Test-Path $src) {
|
|
196
|
+
Copy-Item -Path $src -Destination (Join-Path $FLUXY_HOME $file) -Force
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
# Copy pre-built UI from tarball, or build from source
|
|
201
|
+
$distSrc = Join-Path $extracted "dist-fluxy"
|
|
202
|
+
$distDst = Join-Path $FLUXY_HOME "dist-fluxy"
|
|
203
|
+
if (Test-Path $distSrc) {
|
|
204
|
+
if (Test-Path $distDst) { Remove-Item $distDst -Recurse -Force }
|
|
205
|
+
Copy-Item -Path $distSrc -Destination $distDst -Recurse
|
|
206
|
+
Write-Host " ✔ Chat interface ready" -ForegroundColor Green
|
|
207
|
+
} elseif (-not (Test-Path (Join-Path $distDst "onboard.html"))) {
|
|
208
|
+
Write-Host " ↓ Building chat interface..." -ForegroundColor Cyan
|
|
209
|
+
Push-Location $FLUXY_HOME
|
|
210
|
+
try {
|
|
211
|
+
& $NPM run build:fluxy 2>$null
|
|
212
|
+
Write-Host " ✔ Chat interface built" -ForegroundColor Green
|
|
213
|
+
} catch {
|
|
214
|
+
Write-Host " ! Chat build failed — will build on first start" -ForegroundColor Yellow
|
|
215
|
+
}
|
|
216
|
+
Pop-Location
|
|
217
|
+
} else {
|
|
218
|
+
Write-Host " ✔ Chat interface ready" -ForegroundColor Green
|
|
149
219
|
}
|
|
150
220
|
} finally {
|
|
151
221
|
Remove-Item $tmpDir -Recurse -Force -ErrorAction SilentlyContinue
|
|
@@ -156,21 +226,6 @@ function Install-Fluxy {
|
|
|
156
226
|
try {
|
|
157
227
|
& $NPM install --omit=dev 2>$null
|
|
158
228
|
} catch {}
|
|
159
|
-
|
|
160
|
-
# Build fluxy chat + onboard (served as static files)
|
|
161
|
-
$distFluxy = Join-Path $FLUXY_HOME "dist-fluxy"
|
|
162
|
-
$onboardHtml = Join-Path $distFluxy "onboard.html"
|
|
163
|
-
if ((Test-Path $distFluxy) -and (Test-Path $onboardHtml)) {
|
|
164
|
-
Write-Host " ✔ Chat interface (pre-built)" -ForegroundColor Green
|
|
165
|
-
} else {
|
|
166
|
-
Write-Host " ↓ Building chat interface..." -ForegroundColor Cyan
|
|
167
|
-
try {
|
|
168
|
-
& $NPM run build:fluxy 2>$null
|
|
169
|
-
Write-Host " ✔ Chat interface built" -ForegroundColor Green
|
|
170
|
-
} catch {
|
|
171
|
-
Write-Host " ! Chat interface build failed — it will be built on first start" -ForegroundColor Yellow
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
229
|
Pop-Location
|
|
175
230
|
|
|
176
231
|
# Verify
|
|
@@ -240,14 +295,18 @@ Setup-Path
|
|
|
240
295
|
Write-Host ""
|
|
241
296
|
Write-Host " ✔ Fluxy is ready!" -ForegroundColor Green
|
|
242
297
|
Write-Host ""
|
|
243
|
-
Write-Host "
|
|
298
|
+
Write-Host " -----------------------------" -ForegroundColor DarkGray
|
|
299
|
+
Write-Host " Get started:" -NoNewline; Write-Host ""
|
|
244
300
|
Write-Host ""
|
|
245
301
|
Write-Host " fluxy init " -ForegroundColor Cyan -NoNewline; Write-Host "Set up your bot"
|
|
246
302
|
Write-Host " fluxy start " -ForegroundColor Cyan -NoNewline; Write-Host "Start your bot"
|
|
247
303
|
Write-Host " fluxy status " -ForegroundColor Cyan -NoNewline; Write-Host "Check if it's running"
|
|
248
304
|
Write-Host ""
|
|
249
|
-
Write-Host "
|
|
305
|
+
Write-Host " > " -ForegroundColor Magenta -NoNewline
|
|
306
|
+
Write-Host "Run " -NoNewline
|
|
250
307
|
Write-Host "fluxy init" -ForegroundColor Cyan -NoNewline
|
|
251
|
-
Write-Host " to begin."
|
|
308
|
+
Write-Host " to begin."
|
|
252
309
|
Write-Host " (Open a new terminal if 'fluxy' isn't found yet)" -ForegroundColor DarkGray
|
|
253
310
|
Write-Host ""
|
|
311
|
+
Write-Host " https://fluxy.bot" -ForegroundColor DarkGray
|
|
312
|
+
Write-Host ""
|
package/scripts/install.sh
CHANGED
|
@@ -15,7 +15,9 @@ NODE_DIR="$TOOLS_DIR/node"
|
|
|
15
15
|
BIN_DIR="$FLUXY_HOME/bin"
|
|
16
16
|
USE_SYSTEM_NODE=false
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
# Brand colors: #32A5F7 (blue) and #DB36A3 (pink) via 256-color approximation
|
|
19
|
+
BLUE='\033[38;2;50;165;247m'
|
|
20
|
+
PINK='\033[38;2;219;54;163m'
|
|
19
21
|
GREEN='\033[32m'
|
|
20
22
|
YELLOW='\033[33m'
|
|
21
23
|
RED='\033[31m'
|
|
@@ -23,10 +25,14 @@ DIM='\033[2m'
|
|
|
23
25
|
BOLD='\033[1m'
|
|
24
26
|
RESET='\033[0m'
|
|
25
27
|
|
|
26
|
-
printf "\n
|
|
27
|
-
printf "${
|
|
28
|
-
printf "${
|
|
29
|
-
printf "${
|
|
28
|
+
printf "\n"
|
|
29
|
+
printf "${BLUE}${BOLD} ___ __ ${RESET}\n"
|
|
30
|
+
printf "${BLUE}${BOLD} / _/ / / __ __ __ __ __ ${RESET}\n"
|
|
31
|
+
printf "${PINK}${BOLD} / _/ / / / / / / \\ \\/ / / / ${RESET}\n"
|
|
32
|
+
printf "${PINK}${BOLD} /_/ /_/ \\_,_/ /_/\\_\\ /_/ ${RESET}\n"
|
|
33
|
+
printf "\n"
|
|
34
|
+
printf "${DIM} Self-hosted AI bot installer${RESET}\n"
|
|
35
|
+
printf "${DIM} ─────────────────────────────${RESET}\n\n"
|
|
30
36
|
|
|
31
37
|
# ─── Detect platform ────────────────────────────────────────────────────────
|
|
32
38
|
|
|
@@ -85,7 +91,7 @@ install_node() {
|
|
|
85
91
|
fi
|
|
86
92
|
fi
|
|
87
93
|
|
|
88
|
-
printf " ${
|
|
94
|
+
printf " ${BLUE}↓${RESET} Downloading Node.js v${NODE_VERSION}...\n"
|
|
89
95
|
|
|
90
96
|
NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-${PLATFORM}-${NODEARCH}.tar.xz"
|
|
91
97
|
TMPFILE=$(mktemp /tmp/node-XXXXXX.tar.xz)
|
|
@@ -128,9 +134,14 @@ install_fluxy() {
|
|
|
128
134
|
NODE="$NODE_DIR/bin/node"
|
|
129
135
|
fi
|
|
130
136
|
|
|
131
|
-
|
|
137
|
+
# Fetch version + tarball URL from npm registry
|
|
138
|
+
NPM_VERSION=$("$NPM" view fluxy-bot version 2>/dev/null || echo "")
|
|
139
|
+
if [ -n "$NPM_VERSION" ]; then
|
|
140
|
+
printf " ${DIM}Latest npm version: fluxy-bot@${NPM_VERSION}${RESET}\n"
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
printf " ${BLUE}↓${RESET} Installing fluxy...\n"
|
|
132
144
|
|
|
133
|
-
# Get tarball URL from npm registry
|
|
134
145
|
TARBALL_URL=$("$NPM" view fluxy-bot dist.tarball 2>/dev/null)
|
|
135
146
|
if [ -z "$TARBALL_URL" ]; then
|
|
136
147
|
printf " ${RED}✗${RESET} Failed to fetch package info from npm\n"
|
|
@@ -154,26 +165,42 @@ install_fluxy() {
|
|
|
154
165
|
exit 1
|
|
155
166
|
fi
|
|
156
167
|
|
|
157
|
-
# Copy
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
168
|
+
# Copy code directories (always safe to overwrite)
|
|
169
|
+
for dir in bin supervisor worker shared scripts; do
|
|
170
|
+
[ -d "$EXTRACTED/$dir" ] && cp -r "$EXTRACTED/$dir" "$FLUXY_HOME/"
|
|
171
|
+
done
|
|
161
172
|
|
|
162
|
-
#
|
|
163
|
-
|
|
173
|
+
# Copy workspace template only on first install (preserves user files)
|
|
174
|
+
if [ ! -d "$FLUXY_HOME/workspace" ]; then
|
|
175
|
+
[ -d "$EXTRACTED/workspace" ] && cp -r "$EXTRACTED/workspace" "$FLUXY_HOME/"
|
|
176
|
+
fi
|
|
164
177
|
|
|
165
|
-
#
|
|
166
|
-
|
|
178
|
+
# Copy code files (never touches config.json, memory.db, etc.)
|
|
179
|
+
for f in package.json vite.config.ts vite.fluxy.config.ts tsconfig.json postcss.config.js components.json; do
|
|
180
|
+
[ -f "$EXTRACTED/$f" ] && cp "$EXTRACTED/$f" "$FLUXY_HOME/"
|
|
181
|
+
done
|
|
182
|
+
|
|
183
|
+
# Copy pre-built UI from tarball, or build from source
|
|
184
|
+
if [ -d "$EXTRACTED/dist-fluxy" ]; then
|
|
185
|
+
rm -rf "$FLUXY_HOME/dist-fluxy"
|
|
186
|
+
cp -r "$EXTRACTED/dist-fluxy" "$FLUXY_HOME/"
|
|
167
187
|
printf " ${GREEN}✔${RESET} Chat interface ready\n"
|
|
168
|
-
|
|
169
|
-
printf " ${
|
|
188
|
+
elif [ ! -f "$FLUXY_HOME/dist-fluxy/onboard.html" ]; then
|
|
189
|
+
printf " ${BLUE}↓${RESET} Building chat interface...\n"
|
|
170
190
|
if (cd "$FLUXY_HOME" && "$NPM" run build:fluxy 2>/dev/null); then
|
|
171
191
|
printf " ${GREEN}✔${RESET} Chat interface built\n"
|
|
172
192
|
else
|
|
173
193
|
printf " ${YELLOW}!${RESET} Chat build skipped — will build on first start\n"
|
|
174
194
|
fi
|
|
195
|
+
else
|
|
196
|
+
printf " ${GREEN}✔${RESET} Chat interface ready\n"
|
|
175
197
|
fi
|
|
176
198
|
|
|
199
|
+
rm -rf "$TMPDIR"
|
|
200
|
+
|
|
201
|
+
# Install dependencies inside ~/.fluxy/
|
|
202
|
+
(cd "$FLUXY_HOME" && "$NPM" install --omit=dev 2>/dev/null)
|
|
203
|
+
|
|
177
204
|
# Verify
|
|
178
205
|
if [ ! -f "$FLUXY_HOME/bin/cli.js" ]; then
|
|
179
206
|
printf " ${RED}✗${RESET} Installation failed\n"
|
|
@@ -270,10 +297,18 @@ install_fluxy
|
|
|
270
297
|
create_wrapper
|
|
271
298
|
setup_path
|
|
272
299
|
|
|
273
|
-
printf "\n
|
|
274
|
-
printf "
|
|
275
|
-
printf "
|
|
276
|
-
printf "
|
|
277
|
-
printf "
|
|
278
|
-
printf "
|
|
279
|
-
printf "
|
|
300
|
+
printf "\n"
|
|
301
|
+
printf " ${GREEN}${BOLD}✔ Fluxy is ready!${RESET}\n"
|
|
302
|
+
printf "\n"
|
|
303
|
+
printf " ${DIM}─────────────────────────────${RESET}\n"
|
|
304
|
+
printf " ${BOLD}Get started:${RESET}\n"
|
|
305
|
+
printf "\n"
|
|
306
|
+
printf " ${BLUE}fluxy init${RESET} Set up your bot\n"
|
|
307
|
+
printf " ${BLUE}fluxy start${RESET} Start your bot\n"
|
|
308
|
+
printf " ${BLUE}fluxy status${RESET} Check if it's running\n"
|
|
309
|
+
printf "\n"
|
|
310
|
+
printf " ${PINK}>${RESET} Run ${BLUE}fluxy init${RESET} to begin.\n"
|
|
311
|
+
printf " ${DIM}(Open a new terminal if 'fluxy' isn't found yet)${RESET}\n"
|
|
312
|
+
printf "\n"
|
|
313
|
+
printf " ${DIM}https://fluxy.bot${RESET}\n"
|
|
314
|
+
printf "\n"
|
package/scripts/postinstall.js
CHANGED
|
@@ -28,23 +28,30 @@ if (fs.existsSync(path.join(PKG_ROOT, '.git'))) {
|
|
|
28
28
|
|
|
29
29
|
fs.mkdirSync(FLUXY_HOME, { recursive: true });
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
];
|
|
31
|
+
// Code directories — always overwrite (these are application code)
|
|
32
|
+
const CODE_DIRS = ['bin', 'supervisor', 'worker', 'shared', 'scripts'];
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
// Code files — always overwrite
|
|
35
|
+
const CODE_FILES = [
|
|
36
36
|
'package.json', 'vite.config.ts', 'vite.fluxy.config.ts',
|
|
37
37
|
'tsconfig.json', 'postcss.config.js', 'components.json',
|
|
38
38
|
];
|
|
39
39
|
|
|
40
|
-
for (const dir of
|
|
40
|
+
for (const dir of CODE_DIRS) {
|
|
41
41
|
const src = path.join(PKG_ROOT, dir);
|
|
42
42
|
if (!fs.existsSync(src)) continue;
|
|
43
43
|
const dst = path.join(FLUXY_HOME, dir);
|
|
44
44
|
fs.cpSync(src, dst, { recursive: true, force: true });
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
// Workspace template — only on first install (preserves user files, uploads, etc.)
|
|
48
|
+
const wsSrc = path.join(PKG_ROOT, 'workspace');
|
|
49
|
+
const wsDst = path.join(FLUXY_HOME, 'workspace');
|
|
50
|
+
if (fs.existsSync(wsSrc) && !fs.existsSync(wsDst)) {
|
|
51
|
+
fs.cpSync(wsSrc, wsDst, { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
for (const file of CODE_FILES) {
|
|
48
55
|
const src = path.join(PKG_ROOT, file);
|
|
49
56
|
if (!fs.existsSync(src)) continue;
|
|
50
57
|
fs.copyFileSync(src, path.join(FLUXY_HOME, file));
|
|
@@ -61,10 +68,15 @@ try {
|
|
|
61
68
|
// Non-fatal: deps may already exist from a previous install
|
|
62
69
|
}
|
|
63
70
|
|
|
64
|
-
// ──
|
|
71
|
+
// ── Copy pre-built UI if available, otherwise build ──
|
|
65
72
|
|
|
66
|
-
const
|
|
67
|
-
|
|
73
|
+
const distSrc = path.join(PKG_ROOT, 'dist-fluxy');
|
|
74
|
+
const distDst = path.join(FLUXY_HOME, 'dist-fluxy');
|
|
75
|
+
if (fs.existsSync(distSrc)) {
|
|
76
|
+
// Always use the pre-built UI from the package (handles updates)
|
|
77
|
+
if (fs.existsSync(distDst)) fs.rmSync(distDst, { recursive: true });
|
|
78
|
+
fs.cpSync(distSrc, distDst, { recursive: true });
|
|
79
|
+
} else if (!fs.existsSync(path.join(distDst, 'onboard.html'))) {
|
|
68
80
|
try {
|
|
69
81
|
execSync('npm run build:fluxy', {
|
|
70
82
|
cwd: FLUXY_HOME,
|