build(web): refactor launcher build flow and expand WebUI documentation (#2174)
- delegate root launcher builds to the web Makefile - add dedicated frontend and dev picoclaw build targets - document the WebUI architecture, runtime behavior, and build workflow
This commit is contained in:
parent
b67d3cfbd8
commit
edda02ce67
3 changed files with 406 additions and 45 deletions
13
Makefile
13
Makefile
|
|
@ -130,14 +130,17 @@ build: generate
|
||||||
build-launcher:
|
build-launcher:
|
||||||
@echo "Building picoclaw-launcher for $(PLATFORM)/$(ARCH)..."
|
@echo "Building picoclaw-launcher for $(PLATFORM)/$(ARCH)..."
|
||||||
@mkdir -p $(BUILD_DIR)
|
@mkdir -p $(BUILD_DIR)
|
||||||
@if [ ! -f web/backend/dist/index.html ]; then \
|
@$(MAKE) -C web build \
|
||||||
echo "Building frontend..."; \
|
OUTPUT="$(CURDIR)/$(BUILD_DIR)/picoclaw-launcher-$(PLATFORM)-$(ARCH)" \
|
||||||
cd web/frontend && pnpm install && pnpm build:backend; \
|
WEB_GO='$(WEB_GO)' \
|
||||||
fi
|
GO_BUILD_TAGS='$(GO_BUILD_TAGS)' \
|
||||||
@$(WEB_GO) build $(GOFLAGS) -o $(BUILD_DIR)/picoclaw-launcher-$(PLATFORM)-$(ARCH) ./web/backend
|
LDFLAGS='$(LDFLAGS)'
|
||||||
@ln -sf picoclaw-launcher-$(PLATFORM)-$(ARCH) $(BUILD_DIR)/picoclaw-launcher
|
@ln -sf picoclaw-launcher-$(PLATFORM)-$(ARCH) $(BUILD_DIR)/picoclaw-launcher
|
||||||
@echo "Build complete: $(BUILD_DIR)/picoclaw-launcher"
|
@echo "Build complete: $(BUILD_DIR)/picoclaw-launcher"
|
||||||
|
|
||||||
|
build-launcher-frontend:
|
||||||
|
@$(MAKE) -C web build-frontend
|
||||||
|
|
||||||
## build-launcher-tui: Build the picoclaw-launcher TUI binary
|
## build-launcher-tui: Build the picoclaw-launcher TUI binary
|
||||||
build-launcher-tui:
|
build-launcher-tui:
|
||||||
@echo "Building picoclaw-launcher-tui for $(PLATFORM)/$(ARCH)..."
|
@echo "Building picoclaw-launcher-tui for $(PLATFORM)/$(ARCH)..."
|
||||||
|
|
|
||||||
64
web/Makefile
64
web/Makefile
|
|
@ -1,12 +1,20 @@
|
||||||
.PHONY: dev dev-frontend dev-backend build test lint clean
|
.PHONY: dev dev-frontend dev-backend build build-frontend build-dev-picoclaw test lint clean
|
||||||
|
|
||||||
# Go variables
|
# Go variables
|
||||||
GO?=CGO_ENABLED=0 go
|
GO?=CGO_ENABLED=0 go
|
||||||
WEB_GO?=$(GO)
|
WEB_GO?=$(GO)
|
||||||
GOFLAGS?=-v -tags stdjson
|
GO_BUILD_TAGS?=goolm,stdjson
|
||||||
|
GOFLAGS?=-v -tags $(GO_BUILD_TAGS)
|
||||||
|
|
||||||
# Build variables
|
# Build variables
|
||||||
BUILD_DIR=build
|
BUILD_DIR=build
|
||||||
|
OUTPUT?=$(BUILD_DIR)/picoclaw-launcher
|
||||||
|
FRONTEND_DIR=frontend
|
||||||
|
BACKEND_DIR=backend
|
||||||
|
BACKEND_DIST=$(BACKEND_DIR)/dist
|
||||||
|
PICOCLAW_BINARY_NAME=picoclaw
|
||||||
|
PICOCLAW_BINARY?=$(abspath ../build/$(PICOCLAW_BINARY_NAME))
|
||||||
|
LAUNCHER_GUI_LDFLAG=
|
||||||
|
|
||||||
# Version
|
# Version
|
||||||
VERSION?=$(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
|
VERSION?=$(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
|
||||||
|
|
@ -52,45 +60,63 @@ else ifeq ($(UNAME_S),Darwin)
|
||||||
else ifeq ($(UNAME_S),Windows)
|
else ifeq ($(UNAME_S),Windows)
|
||||||
PLATFORM=windows
|
PLATFORM=windows
|
||||||
ARCH=$(UNAME_M)
|
ARCH=$(UNAME_M)
|
||||||
LDFLAGS=-H=windowsgui $(LDFLAGS)
|
PICOCLAW_BINARY_NAME=picoclaw.exe
|
||||||
|
LAUNCHER_GUI_LDFLAG=-H=windowsgui
|
||||||
else
|
else
|
||||||
PLATFORM=$(UNAME_S)
|
PLATFORM=$(UNAME_S)
|
||||||
ARCH=$(UNAME_M)
|
ARCH=$(UNAME_M)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
LAUNCHER_LDFLAGS=$(strip $(LAUNCHER_GUI_LDFLAG) $(LDFLAGS))
|
||||||
|
|
||||||
# Run both frontend and backend dev servers
|
# Run both frontend and backend dev servers
|
||||||
dev:
|
dev: build-dev-picoclaw
|
||||||
@if [ ! -f $(BUILD_DIR)/picoclaw-launcher ] || [ ! -d backend/dist ]; then \
|
@if [ ! -f "$(BACKEND_DIST)/index.html" ]; then \
|
||||||
echo "Build artifacts not found, building..."; \
|
echo "Embedded frontend not found, building..."; \
|
||||||
$(MAKE) build; \
|
$(MAKE) build-frontend; \
|
||||||
fi
|
fi
|
||||||
@echo "Starting backend and frontend dev servers..."
|
@echo "Starting backend and frontend dev servers..."
|
||||||
@$(MAKE) dev-backend & $(MAKE) dev-frontend
|
@$(MAKE) dev-backend BACKEND_ARGS='-no-browser' & $(MAKE) dev-frontend
|
||||||
|
|
||||||
# Start frontend dev server (Vite, with proxy to backend)
|
# Start frontend dev server (Vite, with proxy to backend)
|
||||||
dev-frontend:
|
dev-frontend:
|
||||||
cd frontend && pnpm dev
|
cd $(FRONTEND_DIR) && pnpm dev
|
||||||
|
|
||||||
# Start backend dev server
|
# Start backend dev server
|
||||||
dev-backend:
|
dev-backend:
|
||||||
cd backend && ${WEB_GO} run -ldflags "$(LDFLAGS)" .
|
cd $(BACKEND_DIR) && PICOCLAW_BINARY="$(PICOCLAW_BINARY)" ${WEB_GO} run -ldflags "$(LAUNCHER_LDFLAGS)" . $(BACKEND_ARGS)
|
||||||
|
|
||||||
# Build frontend and embed into Go binary
|
# Build frontend and embed into Go binary
|
||||||
build:
|
build: build-frontend
|
||||||
cd frontend && pnpm build:backend
|
@mkdir -p "$$(dirname "$(OUTPUT)")"
|
||||||
${WEB_GO} build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/picoclaw-launcher ./backend/
|
${WEB_GO} build $(GOFLAGS) -ldflags "$(LAUNCHER_LDFLAGS)" -o "$(OUTPUT)" ./$(BACKEND_DIR)/
|
||||||
|
|
||||||
|
build-frontend:
|
||||||
|
@if [ ! -d $(FRONTEND_DIR)/node_modules ] || \
|
||||||
|
[ $(FRONTEND_DIR)/package.json -nt $(FRONTEND_DIR)/node_modules ] || \
|
||||||
|
[ $(FRONTEND_DIR)/pnpm-lock.yaml -nt $(FRONTEND_DIR)/node_modules ]; then \
|
||||||
|
echo "Installing frontend dependencies..."; \
|
||||||
|
cd $(FRONTEND_DIR) && pnpm install --frozen-lockfile; \
|
||||||
|
fi
|
||||||
|
@echo "Building frontend..."
|
||||||
|
@cd $(FRONTEND_DIR) && pnpm build:backend
|
||||||
|
|
||||||
|
build-dev-picoclaw:
|
||||||
|
@echo "Building picoclaw for launcher development..."
|
||||||
|
@mkdir -p "$$(dirname "$(PICOCLAW_BINARY)")"
|
||||||
|
@$(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o "$(PICOCLAW_BINARY)" ../cmd/picoclaw
|
||||||
|
|
||||||
# Run all tests
|
# Run all tests
|
||||||
test:
|
test:
|
||||||
cd backend && ${WEB_GO} test ./...
|
cd $(BACKEND_DIR) && ${WEB_GO} test ./...
|
||||||
cd frontend && pnpm lint
|
cd $(FRONTEND_DIR) && pnpm lint
|
||||||
|
|
||||||
# Lint and format
|
# Lint and format
|
||||||
lint:
|
lint:
|
||||||
cd backend && ${WEB_GO} vet ./...
|
cd $(BACKEND_DIR) && ${WEB_GO} vet ./...
|
||||||
cd frontend && pnpm check
|
cd $(FRONTEND_DIR) && pnpm check
|
||||||
|
|
||||||
# Clean build artifacts
|
# Clean build artifacts
|
||||||
clean:
|
clean:
|
||||||
rm -rf frontend/dist backend/dist $(BUILD_DIR)
|
rm -rf $(FRONTEND_DIR)/dist $(BACKEND_DIST) $(BUILD_DIR)
|
||||||
mkdir -p backend/dist && touch backend/dist/.gitkeep
|
node $(FRONTEND_DIR)/scripts/ensure-backend-gitkeep.cjs
|
||||||
|
|
|
||||||
374
web/README.md
374
web/README.md
|
|
@ -1,51 +1,383 @@
|
||||||
# Picoclaw Web
|
# PicoClaw Web
|
||||||
|
|
||||||
This directory contains the standalone web service for `picoclaw`.
|
`web/` contains the standalone WebUI launcher for PicoClaw.
|
||||||
It provides a complete unified web interface, acting as a dashboard, configuration center, and interactive console (channel client) for the core `picoclaw` engine.
|
It is not just a frontend: it is a small launcher service that bundles a React dashboard, exposes a backend API, manages launcher authentication, and starts or attaches to the `picoclaw gateway` process.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## What This Directory Provides
|
||||||
|
|
||||||
|
- A browser-based chat UI backed by the Pico channel WebSocket proxy.
|
||||||
|
- A dashboard for models, credentials, channels, agent tools, skills, logs, and runtime settings.
|
||||||
|
- A launcher process that can auto-open the browser, show a system tray menu, and persist launcher-specific settings.
|
||||||
|
- A controlled way to start, stop, restart, and inspect the `picoclaw gateway` subprocess.
|
||||||
|
- A single-binary deployment target where the frontend is embedded into the Go backend.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
The service is structured as a monorepo containing both the backend and frontend code to ensure high cohesion and simplify deployment.
|
This directory is a small monorepo:
|
||||||
|
|
||||||
* **`backend/`**: The Go-based web server. It provides RESTful APIs, manages WebSocket connections for chat, and handles the lifecycle of the `picoclaw` process. It eventually embeds the compiled frontend assets into a single executable.
|
- `backend/`
|
||||||
* **`frontend/`**: The Vite + React + TanStack Router single-page application (SPA). It provides the interactive user interface.
|
- Go HTTP server and launcher runtime.
|
||||||
|
- Serves REST APIs, authentication endpoints, channel helper flows, and the Pico WebSocket reverse proxy.
|
||||||
|
- Embeds compiled frontend assets from `backend/dist`.
|
||||||
|
- `frontend/`
|
||||||
|
- Vite + React 19 + TanStack Router SPA.
|
||||||
|
- Provides the launcher dashboard and chat UI.
|
||||||
|
|
||||||
## Getting Started
|
At runtime the launcher and the main PicoClaw engine are separate processes:
|
||||||
|
|
||||||
|
1. The launcher starts the web backend on port `18800` by default.
|
||||||
|
2. The launcher serves the dashboard and handles dashboard authentication.
|
||||||
|
3. When allowed, it starts or attaches to `picoclaw gateway -E`.
|
||||||
|
4. The frontend talks only to the launcher backend.
|
||||||
|
5. The launcher proxies chat traffic to the gateway through `/pico/ws`.
|
||||||
|
|
||||||
|
## Dashboard Capabilities
|
||||||
|
|
||||||
|
The current frontend exposes these major pages and flows:
|
||||||
|
|
||||||
|
- `/`
|
||||||
|
- Chat UI with session history, default model selection, and Pico channel messaging.
|
||||||
|
- `/models`
|
||||||
|
- Add, edit, delete, and set the default model.
|
||||||
|
- Supports API-key models, OAuth-backed models, and local/CLI-backed models.
|
||||||
|
- `/credentials`
|
||||||
|
- Manage provider credentials.
|
||||||
|
- Current built-in flows: OpenAI, Anthropic, and Google Antigravity.
|
||||||
|
- `/channels/*`
|
||||||
|
- Configure supported channels from a shared catalog.
|
||||||
|
- Current catalog: `weixin`, `telegram`, `discord`, `slack`, `feishu`, `dingtalk`, `line`, `qq`, `onebot`, `wecom`, `whatsapp`, `whatsapp_native`, `pico`, `maixcam`, `matrix`, `irc`.
|
||||||
|
- Includes QR-based binding helpers for WeChat and WeCom.
|
||||||
|
- `/agent/skills`
|
||||||
|
- Browse built-in, global, and workspace skills.
|
||||||
|
- Import Markdown skills into the workspace and delete workspace-owned skills.
|
||||||
|
- `/agent/tools`
|
||||||
|
- View tool availability and enable or disable tool switches through config-backed APIs.
|
||||||
|
- `/config`
|
||||||
|
- Edit agent defaults, exec controls, cron controls, heartbeat, device monitoring, launcher networking, and launch-at-login settings.
|
||||||
|
- `/logs`
|
||||||
|
- View the in-memory gateway log buffer and clear it.
|
||||||
|
|
||||||
|
The UI currently supports English and Simplified Chinese, plus light and dark themes.
|
||||||
|
|
||||||
|
## Runtime Behavior
|
||||||
|
|
||||||
|
### Config Resolution
|
||||||
|
|
||||||
|
The launcher uses the same PicoClaw config file as the main binary.
|
||||||
|
|
||||||
|
- Default app config path: `~/.picoclaw/config.json`
|
||||||
|
- Override with environment variable: `PICOCLAW_CONFIG`
|
||||||
|
- Override with a positional CLI argument: `picoclaw-launcher /path/to/config.json`
|
||||||
|
|
||||||
|
Launcher-only settings are stored beside that app config:
|
||||||
|
|
||||||
|
- File name: `launcher-config.json`
|
||||||
|
- Default location: `~/.picoclaw/launcher-config.json`
|
||||||
|
|
||||||
|
That file currently stores:
|
||||||
|
|
||||||
|
- `port`
|
||||||
|
- `public`
|
||||||
|
- `allowed_cidrs`
|
||||||
|
|
||||||
|
If `-port` or `-public` are passed explicitly, the CLI flag wins for that run.
|
||||||
|
If they are omitted, stored launcher settings are used.
|
||||||
|
|
||||||
|
### First-Run Onboarding
|
||||||
|
|
||||||
|
If the target config file does not exist, the launcher tries to bootstrap it automatically by running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
picoclaw onboard
|
||||||
|
```
|
||||||
|
|
||||||
|
The launcher looks for the main PicoClaw binary in this order:
|
||||||
|
|
||||||
|
1. `PICOCLAW_BINARY`
|
||||||
|
2. A `picoclaw` binary in the same directory as the launcher
|
||||||
|
3. `picoclaw` from `PATH`
|
||||||
|
|
||||||
|
If onboarding or gateway startup cannot find the main binary, set `PICOCLAW_BINARY` explicitly.
|
||||||
|
|
||||||
|
### Gateway Management
|
||||||
|
|
||||||
|
The launcher manages `picoclaw gateway -E`.
|
||||||
|
|
||||||
|
On startup it tries to auto-start or attach to the gateway, but only when startup preconditions pass. In the current code, the main checks are:
|
||||||
|
|
||||||
|
- a default model is configured
|
||||||
|
- the default model entry is valid
|
||||||
|
- the default model has usable credentials
|
||||||
|
- local/runtime-probed models are reachable
|
||||||
|
|
||||||
|
When a gateway process is started by the launcher, the launcher:
|
||||||
|
|
||||||
|
- captures stdout and stderr into an in-memory ring buffer
|
||||||
|
- tracks transient states such as `starting`, `restarting`, and `stopping`
|
||||||
|
- marks restart-required when the default model or enabled tool set changed since boot
|
||||||
|
- ensures the Pico channel is configured before startup
|
||||||
|
|
||||||
|
### Launcher Authentication
|
||||||
|
|
||||||
|
The dashboard is protected by a launcher access token.
|
||||||
|
|
||||||
|
- If `PICOCLAW_LAUNCHER_TOKEN` is set, that token is used.
|
||||||
|
- Otherwise a random token is generated for each launcher process.
|
||||||
|
- The browser auto-open URL includes `?token=...` so local launches can sign in automatically.
|
||||||
|
- Manual login uses `/launcher-login`.
|
||||||
|
- API clients may also authenticate with `Authorization: Bearer <token>`.
|
||||||
|
|
||||||
|
Where users can retrieve the token depends on launch mode:
|
||||||
|
|
||||||
|
- Console mode: printed to stdout
|
||||||
|
- GUI mode: available through the tray menu on supported builds
|
||||||
|
- GUI mode without stdout:
|
||||||
|
- random per-run tokens are written to the launcher log
|
||||||
|
- default log path: `~/.picoclaw/logs/launcher.log`
|
||||||
|
- if `PICOCLAW_HOME` is set, use `$PICOCLAW_HOME/logs/launcher.log`
|
||||||
|
- env-pinned tokens are not reprinted there; the log only notes that `PICOCLAW_LAUNCHER_TOKEN` is in use
|
||||||
|
|
||||||
|
### Network Exposure
|
||||||
|
|
||||||
|
By default the launcher listens on:
|
||||||
|
|
||||||
|
```text
|
||||||
|
127.0.0.1:18800
|
||||||
|
```
|
||||||
|
|
||||||
|
With `-public` or `public: true`, it listens on all interfaces:
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.0.0:18800
|
||||||
|
```
|
||||||
|
|
||||||
|
When public access is enabled:
|
||||||
|
|
||||||
|
- the launcher can still protect the dashboard with the access token
|
||||||
|
- optional `allowed_cidrs` can restrict which client IP ranges may connect
|
||||||
|
- the gateway host is overridden so remote clients can still use the launcher-managed proxy paths
|
||||||
|
|
||||||
|
## Build And Run
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
* Go 1.25+
|
- Go `1.25+`
|
||||||
* Node.js 20+ with pnpm
|
- Node.js `20+`
|
||||||
|
- `pnpm`
|
||||||
|
|
||||||
### Development
|
On macOS, the `web` Makefile enables `CGO_ENABLED=1` so tray-enabled launcher builds work as expected.
|
||||||
|
On Darwin or FreeBSD without cgo, the launcher falls back to headless mode without a tray.
|
||||||
|
|
||||||
Run both the frontend dev server and the Go backend simultaneously:
|
If you want to prepare the frontend workspace manually, you can still install dependencies yourself:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Recommended Development Workflow
|
||||||
|
|
||||||
|
From the `web/` directory:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make dev
|
make dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Or run them separately:
|
This does three things:
|
||||||
|
|
||||||
|
1. Builds `../build/picoclaw` for launcher development.
|
||||||
|
2. Starts the Go backend with `PICOCLAW_BINARY` pointing at that binary.
|
||||||
|
3. Starts the Vite frontend dev server.
|
||||||
|
|
||||||
|
Use this when you want the full launcher flow during development.
|
||||||
|
|
||||||
|
### Run Frontend And Backend Separately
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make dev-frontend # Vite dev server
|
make dev-frontend
|
||||||
make dev-backend # Go backend
|
make dev-backend
|
||||||
```
|
```
|
||||||
|
|
||||||
### Build
|
Notes:
|
||||||
|
|
||||||
Build the frontend and embed it into a single Go binary:
|
- `dev-frontend` runs the Vite server.
|
||||||
|
- `dev-backend` runs the Go backend only.
|
||||||
|
- The Vite dev server proxies `/api` to `http://localhost:18800`.
|
||||||
|
- Chat WebSocket URLs are generated by the backend, so the frontend does not hardcode gateway addresses.
|
||||||
|
- Running `dev-backend` alone is mainly useful for backend work or when `backend/dist` already contains a built frontend.
|
||||||
|
|
||||||
|
### Build The Standalone Launcher Binary
|
||||||
|
|
||||||
|
From `web/`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make build
|
make build
|
||||||
```
|
```
|
||||||
|
|
||||||
The output binary is `backend/picoclaw-web`.
|
This:
|
||||||
|
|
||||||
### Other Commands
|
1. Installs frontend dependencies when needed.
|
||||||
|
2. Builds the frontend into `backend/dist`.
|
||||||
|
3. Embeds those assets into the Go backend.
|
||||||
|
4. Produces `build/picoclaw-launcher`.
|
||||||
|
|
||||||
|
Override the output path if needed:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make test # Run backend tests and frontend lint
|
make build OUTPUT=/tmp/picoclaw-launcher
|
||||||
make lint # Run go vet and prettier/eslint
|
|
||||||
make clean # Remove all build artifacts
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
From the repository root you can also use:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make build-launcher
|
||||||
|
```
|
||||||
|
|
||||||
|
That writes the platform-specific launcher to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
build/picoclaw-launcher-<platform>-<arch>
|
||||||
|
```
|
||||||
|
|
||||||
|
and refreshes the `build/picoclaw-launcher` symlink.
|
||||||
|
|
||||||
|
### Frontend-Only Builds
|
||||||
|
|
||||||
|
For frontend work there are two useful package scripts:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
pnpm build
|
||||||
|
pnpm build:backend
|
||||||
|
```
|
||||||
|
|
||||||
|
- `pnpm build` writes a normal Vite build to `frontend/dist`
|
||||||
|
- `pnpm build:backend` writes the embeddable build to `../backend/dist`
|
||||||
|
|
||||||
|
### Run The Built Launcher
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build/picoclaw-launcher
|
||||||
|
./build/picoclaw-launcher -console
|
||||||
|
./build/picoclaw-launcher -public
|
||||||
|
./build/picoclaw-launcher -port 19999 /path/to/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Current launcher flags:
|
||||||
|
|
||||||
|
- `-port`
|
||||||
|
- `-public`
|
||||||
|
- `-no-browser`
|
||||||
|
- `-lang`
|
||||||
|
- `-console`
|
||||||
|
|
||||||
|
## Make Targets
|
||||||
|
|
||||||
|
From `web/`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make dev
|
||||||
|
make dev-frontend
|
||||||
|
make dev-backend
|
||||||
|
make build
|
||||||
|
make build-frontend
|
||||||
|
make test
|
||||||
|
make lint
|
||||||
|
make clean
|
||||||
|
```
|
||||||
|
|
||||||
|
What they do today:
|
||||||
|
|
||||||
|
- `make build-frontend`
|
||||||
|
- Runs `pnpm install --frozen-lockfile` when dependencies are missing or stale.
|
||||||
|
- Builds the embeddable frontend into `backend/dist`.
|
||||||
|
- `make test`
|
||||||
|
- Runs backend Go tests.
|
||||||
|
- Runs frontend `pnpm lint`.
|
||||||
|
- `make lint`
|
||||||
|
- Runs backend `go vet`.
|
||||||
|
- Runs frontend `pnpm check`.
|
||||||
|
- `pnpm check` currently formats files with Prettier and fixes lint issues with ESLint, so this target can modify your working tree.
|
||||||
|
- `make clean`
|
||||||
|
- Removes `frontend/dist`, `backend/dist`, and `build/`, then recreates `backend/dist/.gitkeep`.
|
||||||
|
|
||||||
|
## Directory Layout
|
||||||
|
|
||||||
|
```text
|
||||||
|
web/
|
||||||
|
├── backend/
|
||||||
|
│ ├── api/ # REST API handlers and launcher runtime endpoints
|
||||||
|
│ ├── launcherconfig/ # launcher-config.json load/save/validation
|
||||||
|
│ ├── middleware/ # auth, content type, logging, CIDR allowlist
|
||||||
|
│ ├── model/ # Go data structures and logic wrappers
|
||||||
|
│ ├── utils/ # runtime helpers, onboarding, browser launch
|
||||||
|
│ ├── winres/ # Windows application resources
|
||||||
|
│ └── dist/ # embedded frontend build output
|
||||||
|
├── frontend/
|
||||||
|
│ ├── src/api/ # browser API clients
|
||||||
|
│ ├── src/components/ # UI pages and shared components
|
||||||
|
│ ├── src/features/ # feature-specific state, controllers, and protocol helpers
|
||||||
|
│ ├── src/hooks/ # shared React hooks
|
||||||
|
│ ├── src/i18n/ # internationalization language packs
|
||||||
|
│ ├── src/lib/ # generic library utilities
|
||||||
|
│ ├── src/routes/ # TanStack file routes
|
||||||
|
│ ├── src/store/ # global state management
|
||||||
|
│ └── vite.config.ts # dev server and build config
|
||||||
|
├── Makefile
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### You have to sign in again after the launcher restarts
|
||||||
|
|
||||||
|
Existing dashboard sessions do not survive launcher restarts.
|
||||||
|
That is expected: each launcher process generates a new signed session value, so old cookies become invalid.
|
||||||
|
|
||||||
|
To make re-login easier, set a stable token:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export PICOCLAW_LAUNCHER_TOKEN="replace-with-a-long-random-token"
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- a stable token does not preserve the old cookie-based session by itself
|
||||||
|
- when the launcher opens the browser automatically, it appends `?token=...` and signs in again automatically
|
||||||
|
- if you reopen the dashboard manually, use the same stable token on `/launcher-login`
|
||||||
|
|
||||||
|
### "Start Gateway" stays disabled
|
||||||
|
|
||||||
|
The launcher only allows gateway startup when the configured default model is usable.
|
||||||
|
Check these in the dashboard:
|
||||||
|
|
||||||
|
- a default model is selected
|
||||||
|
- the model has credentials or OAuth state
|
||||||
|
- local models such as Ollama or vLLM are reachable
|
||||||
|
|
||||||
|
### The launcher cannot find `picoclaw`
|
||||||
|
|
||||||
|
Set the main binary explicitly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export PICOCLAW_BINARY=/absolute/path/to/picoclaw
|
||||||
|
```
|
||||||
|
|
||||||
|
This affects onboarding and gateway subprocess startup.
|
||||||
|
|
||||||
|
### The backend starts but the UI is blank in development
|
||||||
|
|
||||||
|
Use `make dev` for the normal workflow.
|
||||||
|
If you run only `make dev-backend`, either run `make dev-frontend` alongside it or build the embedded frontend first with `make build-frontend`.
|
||||||
|
|
||||||
|
## Related Docs
|
||||||
|
|
||||||
|
- Main project overview: [`../README.md`](../README.md)
|
||||||
|
- Configuration guide: [`../docs/configuration.md`](../docs/configuration.md)
|
||||||
|
- Providers: [`../docs/providers.md`](../docs/providers.md)
|
||||||
|
- Troubleshooting: [`../docs/troubleshooting.md`](../docs/troubleshooting.md)
|
||||||
|
- Official docs site: [docs.picoclaw.io](https://docs.picoclaw.io)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue