version_0_1_0-alpha
This commit is contained in:
parent
1d2951478b
commit
42c159e42f
71
Makefile
71
Makefile
|
|
@ -1,7 +1,9 @@
|
||||||
# Local process control for LazyBoy.
|
# Local process control for LazyBoy.
|
||||||
# make start API :8787 + Vite :5173
|
# make build cargo + production web UI (web/dist)
|
||||||
|
# make box Docker computer image (lazyboy-box:local)
|
||||||
|
# make start rebuild, then API :8787 + Vite :5173
|
||||||
|
# make restart stop, build, start
|
||||||
# make stop
|
# make stop
|
||||||
# make restart
|
|
||||||
|
|
||||||
.DEFAULT_GOAL := help
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
|
|
@ -10,6 +12,7 @@ RUNDIR := $(ROOT)/.run
|
||||||
BIN := $(ROOT)/target/debug/lazyboy
|
BIN := $(ROOT)/target/debug/lazyboy
|
||||||
WEBDIR := $(ROOT)/web
|
WEBDIR := $(ROOT)/web
|
||||||
|
|
||||||
|
HOST ?= 0.0.0.0
|
||||||
PORT_API ?= 8787
|
PORT_API ?= 8787
|
||||||
PORT_WEB ?= 5173
|
PORT_WEB ?= 5173
|
||||||
|
|
||||||
|
|
@ -18,7 +21,7 @@ PID_WEB := $(RUNDIR)/web.pid
|
||||||
LOG_SERVE := $(RUNDIR)/serve.log
|
LOG_SERVE := $(RUNDIR)/serve.log
|
||||||
LOG_WEB := $(RUNDIR)/web.log
|
LOG_WEB := $(RUNDIR)/web.log
|
||||||
|
|
||||||
.PHONY: help start stop restart status logs prepare-ui start-serve start-web stop-serve stop-web
|
.PHONY: help build build-bin build-ui box start stop restart status logs prepare-ui start-serve start-web stop-serve stop-web
|
||||||
|
|
||||||
# Shared POSIX helpers. Sourced by each recipe.
|
# Shared POSIX helpers. Sourced by each recipe.
|
||||||
define CTL
|
define CTL
|
||||||
|
|
@ -153,17 +156,40 @@ endef
|
||||||
export CTL
|
export CTL
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "make start Start API (:$(PORT_API)) and frontend (:$(PORT_WEB))"
|
@echo "make build Compile API + production web UI (web/dist; phone uses :$(PORT_API))"
|
||||||
|
@echo "make box Build Docker computer image lazyboy-box:local (first time / after box/)"
|
||||||
|
@echo "make start Rebuild and start API (:$(PORT_API)) and frontend (:$(PORT_WEB))"
|
||||||
@echo "make stop Stop both"
|
@echo "make stop Stop both"
|
||||||
@echo "make restart Stop then start"
|
@echo "make restart Stop, rebuild, start"
|
||||||
@echo "make status Show PIDs and ports"
|
@echo "make status Show PIDs and ports"
|
||||||
@echo "make logs Tail both logs (Ctrl-C to leave)"
|
@echo "make logs Tail both logs (Ctrl-C to leave)"
|
||||||
|
|
||||||
start: prepare-ui start-serve start-web
|
build: build-bin build-ui
|
||||||
|
@echo "built $(BIN) and $(WEBDIR)/dist"
|
||||||
|
|
||||||
|
build-bin:
|
||||||
|
@echo "building lazyboy…"
|
||||||
|
@cargo build -p lazyboy
|
||||||
|
|
||||||
|
build-ui:
|
||||||
|
@if [ ! -d "$(WEBDIR)/node_modules" ]; then \
|
||||||
|
echo "npm install…"; \
|
||||||
|
(cd "$(WEBDIR)" && npm install) || exit 1; \
|
||||||
|
fi
|
||||||
|
@echo "building web UI…"
|
||||||
|
@(cd "$(WEBDIR)" && npm run build) || exit 1
|
||||||
|
|
||||||
|
box:
|
||||||
|
@echo "building computer image lazyboy-box:local…"
|
||||||
|
@bash "$(ROOT)/box/build.sh"
|
||||||
|
|
||||||
|
start: build
|
||||||
|
@$(MAKE) start-serve
|
||||||
|
@$(MAKE) start-web
|
||||||
@echo
|
@echo
|
||||||
@echo "API http://127.0.0.1:$(PORT_API)"
|
@echo "API http://127.0.0.1:$(PORT_API)"
|
||||||
@echo "UI http://127.0.0.1:$(PORT_WEB)"
|
@echo "UI http://127.0.0.1:$(PORT_WEB)"
|
||||||
@lan=$$(hostname -I 2>/dev/null | awk '{print $$1}'); \
|
@lan=$$(awk '/手機同一個 Wi-Fi:/ {sub("http://", "", $$NF); sub(/:[0-9]+$$/, "", $$NF); print $$NF; exit}' "$(LOG_SERVE)"); \
|
||||||
if [ -n "$$lan" ]; then \
|
if [ -n "$$lan" ]; then \
|
||||||
echo "Phone http://$$lan:$(PORT_API)"; \
|
echo "Phone http://$$lan:$(PORT_API)"; \
|
||||||
fi
|
fi
|
||||||
|
|
@ -186,32 +212,17 @@ logs:
|
||||||
@echo "=== web $(LOG_WEB) ==="
|
@echo "=== web $(LOG_WEB) ==="
|
||||||
@tail -f "$(LOG_SERVE)" "$(LOG_WEB)"
|
@tail -f "$(LOG_SERVE)" "$(LOG_WEB)"
|
||||||
|
|
||||||
prepare-ui:
|
prepare-ui: build-ui
|
||||||
@if [ ! -d "$(WEBDIR)/node_modules" ]; then \
|
|
||||||
echo "npm install…"; \
|
|
||||||
(cd "$(WEBDIR)" && npm install) || exit 1; \
|
|
||||||
fi
|
|
||||||
@if [ ! -f "$(WEBDIR)/dist/index.html" ]; then \
|
|
||||||
echo "building web UI (once, so :$(PORT_API) serves the app)…"; \
|
|
||||||
(cd "$(WEBDIR)" && npm run build) || exit 1; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
start-serve:
|
start-serve:
|
||||||
@mkdir -p "$(RUNDIR)"
|
@mkdir -p "$(RUNDIR)"
|
||||||
@eval "$$CTL"; \
|
@eval "$$CTL"; \
|
||||||
if alive "$(PID_SERVE)"; then \
|
if alive "$(PID_SERVE)"; then \
|
||||||
fmt=$$(cat "$$HOME/.lazyboy/certs/format" 2>/dev/null || true); \
|
echo "restarting serve with rebuilt binary"; \
|
||||||
if [ "$$fmt" = "2" ]; then \
|
|
||||||
echo "serve already running pid=$$(cat "$(PID_SERVE)")"; \
|
|
||||||
exit 0; \
|
|
||||||
fi; \
|
|
||||||
echo "TLS certs need reissue; restarting serve"; \
|
|
||||||
stop_one serve "$(PID_SERVE)" "$(PORT_API)"; \
|
stop_one serve "$(PID_SERVE)" "$(PORT_API)"; \
|
||||||
fi; \
|
fi; \
|
||||||
echo "building lazyboy…"; \
|
|
||||||
cargo build -p lazyboy || exit 1; \
|
|
||||||
load_env; \
|
load_env; \
|
||||||
LAZYBOY_WEB_PORT="$(PORT_API)" nohup "$(BIN)" serve > "$(LOG_SERVE)" 2>&1 & echo $$! > "$(PID_SERVE)"; \
|
LAZYBOY_WEB_HOST="$(HOST)" LAZYBOY_WEB_PORT="$(PORT_API)" nohup "$(BIN)" serve > "$(LOG_SERVE)" 2>&1 < /dev/null & echo $$! > "$(PID_SERVE)"; \
|
||||||
wait_alive "$(PID_SERVE)" serve "$(LOG_SERVE)" || exit 1; \
|
wait_alive "$(PID_SERVE)" serve "$(LOG_SERVE)" || exit 1; \
|
||||||
wait_listen "$(PID_SERVE)" "$(PORT_API)" serve "$(LOG_SERVE)" || exit 1; \
|
wait_listen "$(PID_SERVE)" "$(PORT_API)" serve "$(LOG_SERVE)" || exit 1; \
|
||||||
echo "started serve pid=$$(cat "$(PID_SERVE)") :$(PORT_API) log=$(LOG_SERVE)"
|
echo "started serve pid=$$(cat "$(PID_SERVE)") :$(PORT_API) log=$(LOG_SERVE)"
|
||||||
|
|
@ -220,19 +231,13 @@ start-web:
|
||||||
@mkdir -p "$(RUNDIR)"
|
@mkdir -p "$(RUNDIR)"
|
||||||
@eval "$$CTL"; \
|
@eval "$$CTL"; \
|
||||||
if alive "$(PID_WEB)"; then \
|
if alive "$(PID_WEB)"; then \
|
||||||
if lsof -nP -iTCP:"$(PORT_WEB)" -sTCP:LISTEN 2>/dev/null | grep -q '127.0.0.1:$(PORT_WEB)'; then \
|
stop_one web "$(PID_WEB)" "$(PORT_WEB)"; \
|
||||||
echo "web is localhost-only; restarting so the phone can connect"; \
|
|
||||||
stop_one web "$(PID_WEB)" "$(PORT_WEB)"; \
|
|
||||||
else \
|
|
||||||
echo "web already running pid=$$(cat "$(PID_WEB)")"; \
|
|
||||||
exit 0; \
|
|
||||||
fi; \
|
|
||||||
fi; \
|
fi; \
|
||||||
if [ ! -d "$(WEBDIR)/node_modules" ]; then \
|
if [ ! -d "$(WEBDIR)/node_modules" ]; then \
|
||||||
echo "npm install…"; \
|
echo "npm install…"; \
|
||||||
(cd "$(WEBDIR)" && npm install) || exit 1; \
|
(cd "$(WEBDIR)" && npm install) || exit 1; \
|
||||||
fi; \
|
fi; \
|
||||||
nohup npm --prefix "$(WEBDIR)" run dev -- --host 0.0.0.0 --port "$(PORT_WEB)" > "$(LOG_WEB)" 2>&1 & echo $$! > "$(PID_WEB)"; \
|
LAZYBOY_WEB_PORT="$(PORT_API)" nohup npm --prefix "$(WEBDIR)" run dev -- --host "$(HOST)" --port "$(PORT_WEB)" > "$(LOG_WEB)" 2>&1 < /dev/null & echo $$! > "$(PID_WEB)"; \
|
||||||
wait_alive "$(PID_WEB)" web "$(LOG_WEB)" || exit 1; \
|
wait_alive "$(PID_WEB)" web "$(LOG_WEB)" || exit 1; \
|
||||||
wait_listen "$(PID_WEB)" "$(PORT_WEB)" web "$(LOG_WEB)" || exit 1; \
|
wait_listen "$(PID_WEB)" "$(PORT_WEB)" web "$(LOG_WEB)" || exit 1; \
|
||||||
echo "started web pid=$$(cat "$(PID_WEB)") :$(PORT_WEB) log=$(LOG_WEB)"
|
echo "started web pid=$$(cat "$(PID_WEB)") :$(PORT_WEB) log=$(LOG_WEB)"
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,18 @@ For action tasks the agent briefly explains its approach, then starts. Multi-sta
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 可設項目與說明:複製 .env.example 成 .env 後填 LAZYBOY_API_KEY
|
# 可設項目與說明:複製 .env.example 成 .env 後填 LAZYBOY_API_KEY
|
||||||
# make start 會載入 .env
|
# make start / restart 會載入 .env
|
||||||
|
make build # API + 正式 UI(web/dist;手機走 :8787 需要這步)
|
||||||
|
make start # 每次重建 API + UI,再啟動;預設綁定 0.0.0.0
|
||||||
|
make restart # 停止後重建並啟動
|
||||||
|
make box # 第一次/改 box/ 之後:Docker 電腦映像 lazyboy-box:local
|
||||||
|
make stop
|
||||||
export LAZYBOY_API_KEY=your_key # or XAI_API_KEY
|
export LAZYBOY_API_KEY=your_key # or XAI_API_KEY
|
||||||
cargo run -p lazyboy -- agent
|
cargo run -p lazyboy -- agent
|
||||||
# API daemon (named Agents) + HTTP on :8787
|
# API daemon (named Agents) + HTTP on :8787
|
||||||
cargo run -p lazyboy -- serve
|
cargo run -p lazyboy -- serve
|
||||||
|
# 開發前端使用 HTTP,不會因本機殘留憑證自動切換 HTTPS。
|
||||||
|
# 本機:http://127.0.0.1:5173;其他裝置:http://本機區網IP:5173(或 :8787)。
|
||||||
# Independent frontend:
|
# Independent frontend:
|
||||||
cd web && npm install && npm run dev
|
cd web && npm install && npm run dev
|
||||||
# Production UI: npm run build then lazyboy serve hosts web/dist
|
# Production UI: npm run build then lazyboy serve hosts web/dist
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,26 @@
|
||||||
import { existsSync, readFileSync } from "node:fs";
|
import { dirname, resolve } from "node:path";
|
||||||
import { homedir } from "node:os";
|
|
||||||
import { dirname, join, resolve } from "node:path";
|
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
import { defineConfig, loadEnv, type ServerOptions } from "vite";
|
import { defineConfig, loadEnv, type ServerOptions } from "vite";
|
||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
|
|
||||||
const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
||||||
|
|
||||||
function localCerts(): { cert: Buffer; key: Buffer } | undefined {
|
|
||||||
const home = homedir();
|
|
||||||
for (const dir of [join(home, ".lazyboy", "certs"), join(home, ".grokboy", "certs")]) {
|
|
||||||
const cert = join(dir, "server.pem");
|
|
||||||
const key = join(dir, "server.key");
|
|
||||||
if (existsSync(cert) && existsSync(key)) {
|
|
||||||
return { cert: readFileSync(cert), key: readFileSync(key) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineConfig(({ mode }) => {
|
export default defineConfig(({ mode }) => {
|
||||||
const env = loadEnv(mode, rootDir, "");
|
const env = loadEnv(mode, rootDir, "");
|
||||||
const version = (process.env.LAZYBOY_VERSION || env.LAZYBOY_VERSION || "0.1.0").trim() || "0.1.0";
|
const version = (process.env.LAZYBOY_VERSION || env.LAZYBOY_VERSION || "0.1.0").trim() || "0.1.0";
|
||||||
const https = localCerts();
|
// The API accepts HTTP even when its optional TLS listener is enabled.
|
||||||
const backend = https ? "https://127.0.0.1:8787" : "http://127.0.0.1:8787";
|
const backendPort = process.env.LAZYBOY_WEB_PORT || env.LAZYBOY_WEB_PORT || "8787";
|
||||||
|
const backend = `http://127.0.0.1:${backendPort}`;
|
||||||
const server: ServerOptions = {
|
const server: ServerOptions = {
|
||||||
port: 5173,
|
port: 5173,
|
||||||
host: true,
|
host: "0.0.0.0",
|
||||||
|
strictPort: true,
|
||||||
proxy: {
|
proxy: {
|
||||||
"/api": { target: backend, secure: false },
|
"/api": { target: backend, secure: false },
|
||||||
"/novnc": { target: backend, ws: true, secure: false },
|
"/novnc": { target: backend, ws: true, secure: false },
|
||||||
"/lazyboy-ca.crt": { target: backend, secure: false },
|
"/lazyboy-ca.crt": { target: backend, secure: false },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if (https) server.https = https;
|
|
||||||
return {
|
return {
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
define: {
|
define: {
|
||||||
|
|
@ -42,6 +29,8 @@ export default defineConfig(({ mode }) => {
|
||||||
server,
|
server,
|
||||||
preview: {
|
preview: {
|
||||||
port: 4173,
|
port: 4173,
|
||||||
|
host: "0.0.0.0",
|
||||||
|
strictPort: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue