2026-02-04 11:06:13 +00:00
|
|
|
.PHONY: all build install uninstall clean help test
|
|
|
|
|
|
|
|
|
|
# Build variables
|
|
|
|
|
BINARY_NAME=picoclaw
|
|
|
|
|
BUILD_DIR=build
|
|
|
|
|
CMD_DIR=cmd/$(BINARY_NAME)
|
|
|
|
|
MAIN_GO=$(CMD_DIR)/main.go
|
|
|
|
|
|
|
|
|
|
# Version
|
|
|
|
|
VERSION?=$(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
|
2026-02-13 11:56:31 +00:00
|
|
|
GIT_COMMIT=$(shell git rev-parse --short=8 HEAD 2>/dev/null || echo "dev")
|
2026-02-04 11:06:13 +00:00
|
|
|
BUILD_TIME=$(shell date +%FT%T%z)
|
2026-02-12 00:14:49 +00:00
|
|
|
GO_VERSION=$(shell $(GO) version | awk '{print $$3}')
|
2026-03-10 09:42:05 +00:00
|
|
|
CONFIG_PKG=github.com/sipeed/picoclaw/pkg/config
|
2026-03-17 06:12:32 +00:00
|
|
|
LDFLAGS=-X $(CONFIG_PKG).Version=$(VERSION) -X $(CONFIG_PKG).GitCommit=$(GIT_COMMIT) -X $(CONFIG_PKG).BuildTime=$(BUILD_TIME) -X $(CONFIG_PKG).GoVersion=$(GO_VERSION) -s -w
|
2026-02-04 11:06:13 +00:00
|
|
|
|
|
|
|
|
# Go variables
|
2026-02-24 09:19:18 +00:00
|
|
|
GO?=CGO_ENABLED=0 go
|
2026-03-17 07:23:49 +00:00
|
|
|
WEB_GO?=$(GO)
|
2026-03-20 15:24:46 +00:00
|
|
|
GOFLAGS?=-v -tags goolm,stdjson
|
2026-02-04 11:06:13 +00:00
|
|
|
|
2026-03-06 11:54:56 +00:00
|
|
|
# Patch MIPS LE ELF e_flags (offset 36) for NaN2008-only kernels (e.g. Ingenic X2600).
|
|
|
|
|
#
|
|
|
|
|
# Bytes (octal): \004 \024 \000 \160 → little-endian 0x70001404
|
|
|
|
|
# 0x70000000 EF_MIPS_ARCH_32R2 MIPS32 Release 2
|
|
|
|
|
# 0x00001000 EF_MIPS_ABI_O32 O32 ABI
|
|
|
|
|
# 0x00000400 EF_MIPS_NAN2008 IEEE 754-2008 NaN encoding
|
|
|
|
|
# 0x00000004 EF_MIPS_CPIC PIC calling sequence
|
|
|
|
|
#
|
|
|
|
|
# Go's GOMIPS=softfloat emits no FP instructions, so the NaN mode is irrelevant
|
|
|
|
|
# at runtime — this is purely an ELF metadata fix to satisfy the kernel's check.
|
|
|
|
|
# patchelf cannot modify e_flags; dd at a fixed offset is the most portable way.
|
|
|
|
|
#
|
|
|
|
|
# Ref: https://codebrowser.dev/linux/linux/arch/mips/include/asm/elf.h.html
|
|
|
|
|
define PATCH_MIPS_FLAGS
|
|
|
|
|
@if [ -f "$(1)" ]; then \
|
|
|
|
|
printf '\004\024\000\160' | dd of=$(1) bs=1 seek=36 count=4 conv=notrunc 2>/dev/null || \
|
|
|
|
|
{ echo "Error: failed to patch MIPS e_flags for $(1)"; exit 1; }; \
|
|
|
|
|
else \
|
|
|
|
|
echo "Error: $(1) not found, cannot patch MIPS e_flags"; exit 1; \
|
|
|
|
|
fi
|
|
|
|
|
endef
|
|
|
|
|
|
2026-02-18 19:48:23 +00:00
|
|
|
# Golangci-lint
|
|
|
|
|
GOLANGCI_LINT?=golangci-lint
|
|
|
|
|
|
2026-02-04 11:06:13 +00:00
|
|
|
# Installation
|
|
|
|
|
INSTALL_PREFIX?=$(HOME)/.local
|
|
|
|
|
INSTALL_BIN_DIR=$(INSTALL_PREFIX)/bin
|
|
|
|
|
INSTALL_MAN_DIR=$(INSTALL_PREFIX)/share/man/man1
|
2026-02-23 10:29:43 +00:00
|
|
|
INSTALL_TMP_SUFFIX=.new
|
2026-02-04 11:06:13 +00:00
|
|
|
|
|
|
|
|
# Workspace and Skills
|
|
|
|
|
PICOCLAW_HOME?=$(HOME)/.picoclaw
|
|
|
|
|
WORKSPACE_DIR?=$(PICOCLAW_HOME)/workspace
|
|
|
|
|
WORKSPACE_SKILLS_DIR=$(WORKSPACE_DIR)/skills
|
|
|
|
|
BUILTIN_SKILLS_DIR=$(CURDIR)/skills
|
|
|
|
|
|
|
|
|
|
# OS detection
|
|
|
|
|
UNAME_S:=$(shell uname -s)
|
|
|
|
|
UNAME_M:=$(shell uname -m)
|
|
|
|
|
|
|
|
|
|
# Platform-specific settings
|
|
|
|
|
ifeq ($(UNAME_S),Linux)
|
|
|
|
|
PLATFORM=linux
|
|
|
|
|
ifeq ($(UNAME_M),x86_64)
|
|
|
|
|
ARCH=amd64
|
|
|
|
|
else ifeq ($(UNAME_M),aarch64)
|
|
|
|
|
ARCH=arm64
|
2026-02-26 09:41:01 +00:00
|
|
|
else ifeq ($(UNAME_M),armv81)
|
|
|
|
|
ARCH=arm64
|
2026-02-17 13:31:54 +00:00
|
|
|
else ifeq ($(UNAME_M),loongarch64)
|
|
|
|
|
ARCH=loong64
|
2026-02-04 11:06:13 +00:00
|
|
|
else ifeq ($(UNAME_M),riscv64)
|
|
|
|
|
ARCH=riscv64
|
2026-03-06 11:54:56 +00:00
|
|
|
else ifeq ($(UNAME_M),mipsel)
|
|
|
|
|
ARCH=mipsle
|
2026-02-04 11:06:13 +00:00
|
|
|
else
|
|
|
|
|
ARCH=$(UNAME_M)
|
|
|
|
|
endif
|
|
|
|
|
else ifeq ($(UNAME_S),Darwin)
|
|
|
|
|
PLATFORM=darwin
|
2026-03-17 07:23:49 +00:00
|
|
|
WEB_GO=CGO_ENABLED=1 go
|
2026-02-04 11:06:13 +00:00
|
|
|
ifeq ($(UNAME_M),x86_64)
|
|
|
|
|
ARCH=amd64
|
|
|
|
|
else ifeq ($(UNAME_M),arm64)
|
|
|
|
|
ARCH=arm64
|
|
|
|
|
else
|
|
|
|
|
ARCH=$(UNAME_M)
|
|
|
|
|
endif
|
|
|
|
|
else
|
|
|
|
|
PLATFORM=$(UNAME_S)
|
|
|
|
|
ARCH=$(UNAME_M)
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
BINARY_PATH=$(BUILD_DIR)/$(BINARY_NAME)-$(PLATFORM)-$(ARCH)
|
|
|
|
|
|
|
|
|
|
# Default target
|
|
|
|
|
all: build
|
|
|
|
|
|
2026-02-14 23:43:46 +00:00
|
|
|
## generate: Run generate
|
|
|
|
|
generate:
|
|
|
|
|
@echo "Run generate..."
|
|
|
|
|
@rm -r ./$(CMD_DIR)/workspace 2>/dev/null || true
|
|
|
|
|
@$(GO) generate ./...
|
|
|
|
|
@echo "Run generate complete"
|
|
|
|
|
|
2026-02-04 11:06:13 +00:00
|
|
|
## build: Build the picoclaw binary for current platform
|
2026-02-14 23:43:46 +00:00
|
|
|
build: generate
|
2026-02-04 11:06:13 +00:00
|
|
|
@echo "Building $(BINARY_NAME) for $(PLATFORM)/$(ARCH)..."
|
|
|
|
|
@mkdir -p $(BUILD_DIR)
|
2026-03-17 06:12:32 +00:00
|
|
|
@$(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $(BINARY_PATH) ./$(CMD_DIR)
|
2026-02-04 11:06:13 +00:00
|
|
|
@echo "Build complete: $(BINARY_PATH)"
|
|
|
|
|
@ln -sf $(BINARY_NAME)-$(PLATFORM)-$(ARCH) $(BUILD_DIR)/$(BINARY_NAME)
|
|
|
|
|
|
feat(web): migrate launcher to modular web frontend/backend and improve management UX (#1275)
* refactor: remove the legacy picoclaw-launcher
* feat: create initial web frontend and backend structure
* feat(packaging): add desktop entry for PicoClaw Launcher (#1062)
- Add .desktop file with Terminal=true, named "PicoClaw Launcher"
- Install to /usr/share/applications/ for app menu visibility
- Add 512x512 PNG icon to /usr/share/icons/hicolor/
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* `make dev`: If you haven't built it before, you need to run `build` first.
* feat(web): comprehensive web UI and backend refactoring
This commit introduces a major overhaul of both the frontend web UI and the Go backend API, transitioning to a highly modular architecture and integrating new core features.
Backend:
- Refactored monolithic API endpoints into domain-specific modules (config, gateway, log, models, pico, session).
- Cleaned up obsolete files (`server.go`, `status.go`, WebSocket handlers) and outdated tests.
- Implemented Gateway process lifecycle management (start/stop/restart) and real-time log streaming.
Frontend:
- Integrated Shadcn UI components to establish a modern, consistent design system.
- Introduced a new application layout featuring a responsive sidebar (`app-sidebar`) and header.
- Implemented internationalization (i18n) with initial support for English and Chinese.
- Restructured API clients, hooks, and Zustand stores into logical domains.
- Added new management pages for Settings, Logs, Models, Providers, and Credentials.
- Upgraded the Pico chat interface with session history management and dynamic model selection.
Build & Config:
- Updated frontend dependencies, Vite configuration, and lockfiles.
- Refined routing setup and overarching application stylesheets.
* feat(web): enhance model management, sorting, and deletion logic
- Implement model sorting in UI (default > configured > unconfigured)
- Prevent deletion of default models in the frontend
- Update backend to clear default settings when a model is deleted
- Add existence validation when setting a default model via API
- Group models in chat UI by type (API Key, OAuth, Local)
- Conditionally display model selector in chat based on configuration status
* refactor(web): refactor chat page into modular components/hooks and update i18n
- split chat route into dedicated chat components (page, composer, empty state, messages, history, model selector)
- extract model/session logic into use-chat-models and use-session-history hooks
- update chat locale keys in en/zh and add empty-state/history-related translations
* refactor(models): refactor models page into modular components and improve UX
- split /models route into dedicated components (page, provider section, card, add/edit sheets, delete dialog)
- add provider grouping/sorting, provider labels/icons, and a no-default hint in the models page
- add "Set as default model" toggle to add/edit flows with safer defaults
- introduce shared form helpers and new UI primitives (field, label, switch)
- update i18n strings (en/zh) for models and gateway header text usage
- apply minor UI polish (models nav icon, separator client directive)
* fix(web): add SPA index fallback for embedded frontend routes
Serve existing static assets as-is, keep /api/* and missing asset paths returning 404, and add tests for SPA fallback behavior on refresh.
* fix(frontend/chat): normalize message timestamp units to prevent invalid far-future dates
* chore: delete TestSPARouteFallsBackToIndex
* feat: update build for web-based launcher (#1186)
- Makefile: add build-launcher target (builds frontend + Go backend)
- GoReleaser: point picoclaw-launcher build to web/backend, add frontend
build hook, restore winres hook with updated paths
- Restore icon.ico and winres config from main for Windows builds
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(credentials): add multi-provider OAuth credential management
- add backend `/api/oauth/*` endpoints for provider status, browser/device-code/token login, flow query/polling, and logout
- extend API handler with OAuth flow/state tracking and route registration, plus OAuth unit tests
- implement frontend credentials page/components for OpenAI, Anthropic, and Google Antigravity login/logout
- add OAuth API client and `useCredentialsPage` hook, with new EN/ZH i18n strings
* chore: remove placeholder index.html from dist (#1188)
The .gitkeep is sufficient for go:embed to find the dist directory.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(frontend): polish model and credential UX; remove Providers nav
- remove the Providers item from sidebar navigation and locale keys
- simplify chat composer by dropping attach/voice action buttons
- support ReactNode titles in credential cards and add provider brand icons
- refine sheet header/footer styling and device-code footer button hierarchy
- disable “Set default” when a model is unconfigured or already default
* feat(web): Update config page (#1173)
* feat(web): Update config page
* fix(web): useEffect resets editorValue whenever config changes
* fix(web): react-hooks/set-state-in-effect error & pnpm lint #1173
* feat(web): add channel management page for web console (#1190)
* feat(web): add channel management page for web console
Add a complete channel management UI that allows users to configure
messaging channels (Telegram, Discord, Slack, Feishu, etc.) directly
from the web console instead of manually editing config.json.
Backend: GET/PUT/PATCH API endpoints for listing, updating, and
toggling channels with secret field masking.
Frontend: Channel cards grid with enable/disable toggles, per-channel
configuration sheets with dedicated forms for major platforms and a
generic fallback for others.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(web/channels): move channels to own sidebar group and fix sheet padding
- Channels now has its own navigation group instead of being under Services
- Fix edit sheet form content padding (px-1 -> px-4) to match header/footer
- Fix naked return lint error in extractChannelInfo
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(web): harden channel config updates and resolve frontend lint issues
- validate channel PUT/PATCH updates before saving and return structured validation errors
- require `enabled` in toggle requests to avoid silent false defaults
- support editing `allow_origins` in the generic channel form and parse string/array inputs on backend
- replace channel form `any` usage with `ChannelConfig` (`Record<string, unknown>`) and add safe value helpers
- add i18n strings for allow-origins fields and apply related frontend formatting cleanups
* fix(frontend): prevent false "Invalid JSON" errors in config editor
* feat: add startup readiness checks and propagate start availability to UI
- add gateway precondition validation for default model and credentials
- auto-start gateway on backend boot when conditions are met
- include gateway_start_allowed and gateway_start_reason in status updates
- prevent frontend start actions when gateway cannot be started
* feat(web): revamp channel config UX with catalog-based routing
- replace legacy channel management endpoints with a backend channel catalog API
- switch frontend channel updates to PATCH /api/config and per-channel config pages
- add dynamic channel items in the sidebar with support for expand/collapse
- migrate /channels to nested routes (/channels/$name) and remove old card/sheet flow
- improve channel forms with clearer hints, required/error states, and reusable switch cards
- fix Discord mention-only toggle to read/write group_trigger.mention_only
* refactor(frontend): move shared-form to components and unify default-model switch with SwitchCardField
* fix(frontend): improve model form validation and unify secret placeholder handling
- block duplicate model aliases when adding a model (with localized error messages)
- share masked secret placeholder logic across model and channel forms
- refresh gateway state after setting the default model
- apply minor UI cleanup to provider icon rendering
* feat(web): add visual system config and launcher/autostart controls
- add launcher config model and persistence (`launcher-config.json`) for port/public/CIDR settings
- add system APIs for launch-at-login and launcher parameters
- apply CIDR-based access-control middleware to backend HTTP routes
- split config routing into visual config and raw JSON config pages
- add frontend system API client and visual config sections for runtime/devices/launcher
- expand i18n strings (en/zh) for new config UI
- improve sidebar active matching and session ID generation fallback
* refactor(frontend): remove i18n fallback strings and drop providers route
- Replace `t(key, defaultValue)` calls with key-only translations across UI pages
- Clean up locale files by pruning unused keys and adding missing shared keys
- Remove the obsolete `/providers` page and update generated route tree
* fix(backend): correct gateway status detection on Windows
* fix(repo): keep web backend dist placeholder tracked
---------
Co-authored-by: Guoguo <16666742+imguoguo@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Dihubopen <dihubcn@gmail.com>
Co-authored-by: Dihubopen <130813726+Dihubopen@users.noreply.github.com>
2026-03-09 11:42:03 +00:00
|
|
|
## build-launcher: Build the picoclaw-launcher (web console) binary
|
|
|
|
|
build-launcher:
|
|
|
|
|
@echo "Building picoclaw-launcher for $(PLATFORM)/$(ARCH)..."
|
|
|
|
|
@mkdir -p $(BUILD_DIR)
|
|
|
|
|
@if [ ! -f web/backend/dist/index.html ]; then \
|
|
|
|
|
echo "Building frontend..."; \
|
|
|
|
|
cd web/frontend && pnpm install && pnpm build:backend; \
|
|
|
|
|
fi
|
2026-03-17 07:23:49 +00:00
|
|
|
@$(WEB_GO) build $(GOFLAGS) -o $(BUILD_DIR)/picoclaw-launcher-$(PLATFORM)-$(ARCH) ./web/backend
|
feat(web): migrate launcher to modular web frontend/backend and improve management UX (#1275)
* refactor: remove the legacy picoclaw-launcher
* feat: create initial web frontend and backend structure
* feat(packaging): add desktop entry for PicoClaw Launcher (#1062)
- Add .desktop file with Terminal=true, named "PicoClaw Launcher"
- Install to /usr/share/applications/ for app menu visibility
- Add 512x512 PNG icon to /usr/share/icons/hicolor/
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* `make dev`: If you haven't built it before, you need to run `build` first.
* feat(web): comprehensive web UI and backend refactoring
This commit introduces a major overhaul of both the frontend web UI and the Go backend API, transitioning to a highly modular architecture and integrating new core features.
Backend:
- Refactored monolithic API endpoints into domain-specific modules (config, gateway, log, models, pico, session).
- Cleaned up obsolete files (`server.go`, `status.go`, WebSocket handlers) and outdated tests.
- Implemented Gateway process lifecycle management (start/stop/restart) and real-time log streaming.
Frontend:
- Integrated Shadcn UI components to establish a modern, consistent design system.
- Introduced a new application layout featuring a responsive sidebar (`app-sidebar`) and header.
- Implemented internationalization (i18n) with initial support for English and Chinese.
- Restructured API clients, hooks, and Zustand stores into logical domains.
- Added new management pages for Settings, Logs, Models, Providers, and Credentials.
- Upgraded the Pico chat interface with session history management and dynamic model selection.
Build & Config:
- Updated frontend dependencies, Vite configuration, and lockfiles.
- Refined routing setup and overarching application stylesheets.
* feat(web): enhance model management, sorting, and deletion logic
- Implement model sorting in UI (default > configured > unconfigured)
- Prevent deletion of default models in the frontend
- Update backend to clear default settings when a model is deleted
- Add existence validation when setting a default model via API
- Group models in chat UI by type (API Key, OAuth, Local)
- Conditionally display model selector in chat based on configuration status
* refactor(web): refactor chat page into modular components/hooks and update i18n
- split chat route into dedicated chat components (page, composer, empty state, messages, history, model selector)
- extract model/session logic into use-chat-models and use-session-history hooks
- update chat locale keys in en/zh and add empty-state/history-related translations
* refactor(models): refactor models page into modular components and improve UX
- split /models route into dedicated components (page, provider section, card, add/edit sheets, delete dialog)
- add provider grouping/sorting, provider labels/icons, and a no-default hint in the models page
- add "Set as default model" toggle to add/edit flows with safer defaults
- introduce shared form helpers and new UI primitives (field, label, switch)
- update i18n strings (en/zh) for models and gateway header text usage
- apply minor UI polish (models nav icon, separator client directive)
* fix(web): add SPA index fallback for embedded frontend routes
Serve existing static assets as-is, keep /api/* and missing asset paths returning 404, and add tests for SPA fallback behavior on refresh.
* fix(frontend/chat): normalize message timestamp units to prevent invalid far-future dates
* chore: delete TestSPARouteFallsBackToIndex
* feat: update build for web-based launcher (#1186)
- Makefile: add build-launcher target (builds frontend + Go backend)
- GoReleaser: point picoclaw-launcher build to web/backend, add frontend
build hook, restore winres hook with updated paths
- Restore icon.ico and winres config from main for Windows builds
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(credentials): add multi-provider OAuth credential management
- add backend `/api/oauth/*` endpoints for provider status, browser/device-code/token login, flow query/polling, and logout
- extend API handler with OAuth flow/state tracking and route registration, plus OAuth unit tests
- implement frontend credentials page/components for OpenAI, Anthropic, and Google Antigravity login/logout
- add OAuth API client and `useCredentialsPage` hook, with new EN/ZH i18n strings
* chore: remove placeholder index.html from dist (#1188)
The .gitkeep is sufficient for go:embed to find the dist directory.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(frontend): polish model and credential UX; remove Providers nav
- remove the Providers item from sidebar navigation and locale keys
- simplify chat composer by dropping attach/voice action buttons
- support ReactNode titles in credential cards and add provider brand icons
- refine sheet header/footer styling and device-code footer button hierarchy
- disable “Set default” when a model is unconfigured or already default
* feat(web): Update config page (#1173)
* feat(web): Update config page
* fix(web): useEffect resets editorValue whenever config changes
* fix(web): react-hooks/set-state-in-effect error & pnpm lint #1173
* feat(web): add channel management page for web console (#1190)
* feat(web): add channel management page for web console
Add a complete channel management UI that allows users to configure
messaging channels (Telegram, Discord, Slack, Feishu, etc.) directly
from the web console instead of manually editing config.json.
Backend: GET/PUT/PATCH API endpoints for listing, updating, and
toggling channels with secret field masking.
Frontend: Channel cards grid with enable/disable toggles, per-channel
configuration sheets with dedicated forms for major platforms and a
generic fallback for others.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(web/channels): move channels to own sidebar group and fix sheet padding
- Channels now has its own navigation group instead of being under Services
- Fix edit sheet form content padding (px-1 -> px-4) to match header/footer
- Fix naked return lint error in extractChannelInfo
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(web): harden channel config updates and resolve frontend lint issues
- validate channel PUT/PATCH updates before saving and return structured validation errors
- require `enabled` in toggle requests to avoid silent false defaults
- support editing `allow_origins` in the generic channel form and parse string/array inputs on backend
- replace channel form `any` usage with `ChannelConfig` (`Record<string, unknown>`) and add safe value helpers
- add i18n strings for allow-origins fields and apply related frontend formatting cleanups
* fix(frontend): prevent false "Invalid JSON" errors in config editor
* feat: add startup readiness checks and propagate start availability to UI
- add gateway precondition validation for default model and credentials
- auto-start gateway on backend boot when conditions are met
- include gateway_start_allowed and gateway_start_reason in status updates
- prevent frontend start actions when gateway cannot be started
* feat(web): revamp channel config UX with catalog-based routing
- replace legacy channel management endpoints with a backend channel catalog API
- switch frontend channel updates to PATCH /api/config and per-channel config pages
- add dynamic channel items in the sidebar with support for expand/collapse
- migrate /channels to nested routes (/channels/$name) and remove old card/sheet flow
- improve channel forms with clearer hints, required/error states, and reusable switch cards
- fix Discord mention-only toggle to read/write group_trigger.mention_only
* refactor(frontend): move shared-form to components and unify default-model switch with SwitchCardField
* fix(frontend): improve model form validation and unify secret placeholder handling
- block duplicate model aliases when adding a model (with localized error messages)
- share masked secret placeholder logic across model and channel forms
- refresh gateway state after setting the default model
- apply minor UI cleanup to provider icon rendering
* feat(web): add visual system config and launcher/autostart controls
- add launcher config model and persistence (`launcher-config.json`) for port/public/CIDR settings
- add system APIs for launch-at-login and launcher parameters
- apply CIDR-based access-control middleware to backend HTTP routes
- split config routing into visual config and raw JSON config pages
- add frontend system API client and visual config sections for runtime/devices/launcher
- expand i18n strings (en/zh) for new config UI
- improve sidebar active matching and session ID generation fallback
* refactor(frontend): remove i18n fallback strings and drop providers route
- Replace `t(key, defaultValue)` calls with key-only translations across UI pages
- Clean up locale files by pruning unused keys and adding missing shared keys
- Remove the obsolete `/providers` page and update generated route tree
* fix(backend): correct gateway status detection on Windows
* fix(repo): keep web backend dist placeholder tracked
---------
Co-authored-by: Guoguo <16666742+imguoguo@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Dihubopen <dihubcn@gmail.com>
Co-authored-by: Dihubopen <130813726+Dihubopen@users.noreply.github.com>
2026-03-09 11:42:03 +00:00
|
|
|
@ln -sf picoclaw-launcher-$(PLATFORM)-$(ARCH) $(BUILD_DIR)/picoclaw-launcher
|
|
|
|
|
@echo "Build complete: $(BUILD_DIR)/picoclaw-launcher"
|
|
|
|
|
|
2026-02-23 03:22:32 +00:00
|
|
|
## build-whatsapp-native: Build with WhatsApp native (whatsmeow) support; larger binary
|
|
|
|
|
build-whatsapp-native: generate
|
2026-02-23 04:58:59 +00:00
|
|
|
## @echo "Building $(BINARY_NAME) with WhatsApp native for $(PLATFORM)/$(ARCH)..."
|
|
|
|
|
@echo "Building for multiple platforms..."
|
2026-02-23 03:22:32 +00:00
|
|
|
@mkdir -p $(BUILD_DIR)
|
2026-03-17 06:12:32 +00:00
|
|
|
GOOS=linux GOARCH=amd64 $(GO) build -tags whatsapp_native -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-amd64 ./$(CMD_DIR)
|
|
|
|
|
GOOS=linux GOARCH=arm GOARM=7 $(GO) build -tags whatsapp_native -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-arm ./$(CMD_DIR)
|
|
|
|
|
GOOS=linux GOARCH=arm64 $(GO) build -tags whatsapp_native -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 ./$(CMD_DIR)
|
|
|
|
|
GOOS=linux GOARCH=loong64 $(GO) build -tags whatsapp_native -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-loong64 ./$(CMD_DIR)
|
|
|
|
|
GOOS=linux GOARCH=riscv64 $(GO) build -tags whatsapp_native -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-riscv64 ./$(CMD_DIR)
|
|
|
|
|
GOOS=linux GOARCH=mipsle GOMIPS=softfloat $(GO) build -tags whatsapp_native -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-mipsle ./$(CMD_DIR)
|
2026-03-06 11:54:56 +00:00
|
|
|
$(call PATCH_MIPS_FLAGS,$(BUILD_DIR)/$(BINARY_NAME)-linux-mipsle)
|
2026-03-17 06:12:32 +00:00
|
|
|
GOOS=darwin GOARCH=arm64 $(GO) build -tags whatsapp_native -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-arm64 ./$(CMD_DIR)
|
|
|
|
|
GOOS=windows GOARCH=amd64 $(GO) build -tags whatsapp_native -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-windows-amd64.exe ./$(CMD_DIR)
|
|
|
|
|
## @$(GO) build $(GOFLAGS) -tags whatsapp_native -ldflags "$(LDFLAGS)" -o $(BINARY_PATH) ./$(CMD_DIR)
|
2026-02-23 04:58:59 +00:00
|
|
|
@echo "Build complete"
|
|
|
|
|
## @ln -sf $(BINARY_NAME)-$(PLATFORM)-$(ARCH) $(BUILD_DIR)/$(BINARY_NAME)
|
2026-02-23 03:22:32 +00:00
|
|
|
|
2026-02-22 20:29:27 +00:00
|
|
|
## build-linux-arm: Build for Linux ARMv7 (e.g. Raspberry Pi Zero 2 W 32-bit)
|
|
|
|
|
build-linux-arm: generate
|
|
|
|
|
@echo "Building for linux/arm (GOARM=7)..."
|
|
|
|
|
@mkdir -p $(BUILD_DIR)
|
2026-03-17 06:12:32 +00:00
|
|
|
GOOS=linux GOARCH=arm GOARM=7 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-arm ./$(CMD_DIR)
|
2026-02-22 20:29:27 +00:00
|
|
|
@echo "Build complete: $(BUILD_DIR)/$(BINARY_NAME)-linux-arm"
|
|
|
|
|
|
|
|
|
|
## build-linux-arm64: Build for Linux ARM64 (e.g. Raspberry Pi Zero 2 W 64-bit)
|
|
|
|
|
build-linux-arm64: generate
|
|
|
|
|
@echo "Building for linux/arm64..."
|
|
|
|
|
@mkdir -p $(BUILD_DIR)
|
2026-03-17 06:12:32 +00:00
|
|
|
GOOS=linux GOARCH=arm64 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 ./$(CMD_DIR)
|
2026-02-22 20:29:27 +00:00
|
|
|
@echo "Build complete: $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64"
|
|
|
|
|
|
2026-03-06 11:54:56 +00:00
|
|
|
## build-linux-mipsle: Build for Linux MIPS32 LE
|
|
|
|
|
build-linux-mipsle: generate
|
|
|
|
|
@echo "Building for linux/mipsle (softfloat)..."
|
|
|
|
|
@mkdir -p $(BUILD_DIR)
|
2026-03-17 06:12:32 +00:00
|
|
|
GOOS=linux GOARCH=mipsle GOMIPS=softfloat $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-mipsle ./$(CMD_DIR)
|
2026-03-06 11:54:56 +00:00
|
|
|
$(call PATCH_MIPS_FLAGS,$(BUILD_DIR)/$(BINARY_NAME)-linux-mipsle)
|
|
|
|
|
@echo "Build complete: $(BUILD_DIR)/$(BINARY_NAME)-linux-mipsle"
|
|
|
|
|
|
2026-02-22 20:29:27 +00:00
|
|
|
## build-pi-zero: Build for Raspberry Pi Zero 2 W (32-bit and 64-bit)
|
|
|
|
|
build-pi-zero: build-linux-arm build-linux-arm64
|
|
|
|
|
@echo "Pi Zero 2 W builds: $(BUILD_DIR)/$(BINARY_NAME)-linux-arm (32-bit), $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 (64-bit)"
|
|
|
|
|
|
2026-02-04 11:06:13 +00:00
|
|
|
## build-all: Build picoclaw for all platforms
|
2026-02-14 23:43:46 +00:00
|
|
|
build-all: generate
|
2026-02-04 11:06:13 +00:00
|
|
|
@echo "Building for multiple platforms..."
|
|
|
|
|
@mkdir -p $(BUILD_DIR)
|
2026-03-17 06:12:32 +00:00
|
|
|
GOOS=linux GOARCH=amd64 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-amd64 ./$(CMD_DIR)
|
|
|
|
|
GOOS=linux GOARCH=arm GOARM=7 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-arm ./$(CMD_DIR)
|
|
|
|
|
GOOS=linux GOARCH=arm64 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 ./$(CMD_DIR)
|
|
|
|
|
GOOS=linux GOARCH=loong64 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-loong64 ./$(CMD_DIR)
|
|
|
|
|
GOOS=linux GOARCH=riscv64 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-riscv64 ./$(CMD_DIR)
|
|
|
|
|
GOOS=linux GOARCH=mipsle GOMIPS=softfloat $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-mipsle ./$(CMD_DIR)
|
2026-03-06 11:54:56 +00:00
|
|
|
$(call PATCH_MIPS_FLAGS,$(BUILD_DIR)/$(BINARY_NAME)-linux-mipsle)
|
2026-03-17 06:12:32 +00:00
|
|
|
GOOS=linux GOARCH=arm GOARM=7 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-linux-armv7 ./$(CMD_DIR)
|
|
|
|
|
GOOS=darwin GOARCH=arm64 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-arm64 ./$(CMD_DIR)
|
|
|
|
|
GOOS=windows GOARCH=amd64 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-windows-amd64.exe ./$(CMD_DIR)
|
|
|
|
|
GOOS=netbsd GOARCH=amd64 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-netbsd-amd64 ./$(CMD_DIR)
|
|
|
|
|
GOOS=netbsd GOARCH=arm64 $(GO) build -ldflags "$(LDFLAGS)" -o $(BUILD_DIR)/$(BINARY_NAME)-netbsd-arm64 ./$(CMD_DIR)
|
2026-02-04 11:06:13 +00:00
|
|
|
@echo "All builds complete"
|
|
|
|
|
|
|
|
|
|
## install: Install picoclaw to system and copy builtin skills
|
|
|
|
|
install: build
|
|
|
|
|
@echo "Installing $(BINARY_NAME)..."
|
|
|
|
|
@mkdir -p $(INSTALL_BIN_DIR)
|
2026-02-23 10:29:43 +00:00
|
|
|
# Copy binary with temporary suffix to ensure atomic update
|
|
|
|
|
@cp $(BUILD_DIR)/$(BINARY_NAME) $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX)
|
|
|
|
|
@chmod +x $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX)
|
|
|
|
|
@mv -f $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX) $(INSTALL_BIN_DIR)/$(BINARY_NAME)
|
2026-02-04 11:06:13 +00:00
|
|
|
@echo "Installed binary to $(INSTALL_BIN_DIR)/$(BINARY_NAME)"
|
|
|
|
|
@echo "Installation complete!"
|
|
|
|
|
|
|
|
|
|
## uninstall: Remove picoclaw from system
|
|
|
|
|
uninstall:
|
|
|
|
|
@echo "Uninstalling $(BINARY_NAME)..."
|
|
|
|
|
@rm -f $(INSTALL_BIN_DIR)/$(BINARY_NAME)
|
|
|
|
|
@echo "Removed binary from $(INSTALL_BIN_DIR)/$(BINARY_NAME)"
|
|
|
|
|
@echo "Note: Only the executable file has been deleted."
|
|
|
|
|
@echo "If you need to delete all configurations (config.json, workspace, etc.), run 'make uninstall-all'"
|
|
|
|
|
|
|
|
|
|
## uninstall-all: Remove picoclaw and all data
|
|
|
|
|
uninstall-all:
|
|
|
|
|
@echo "Removing workspace and skills..."
|
|
|
|
|
@rm -rf $(PICOCLAW_HOME)
|
|
|
|
|
@echo "Removed workspace: $(PICOCLAW_HOME)"
|
|
|
|
|
@echo "Complete uninstallation done!"
|
|
|
|
|
|
|
|
|
|
## clean: Remove build artifacts
|
|
|
|
|
clean:
|
|
|
|
|
@echo "Cleaning build artifacts..."
|
|
|
|
|
@rm -rf $(BUILD_DIR)
|
|
|
|
|
@echo "Clean complete"
|
|
|
|
|
|
2026-02-16 07:48:02 +00:00
|
|
|
## vet: Run go vet for static analysis
|
2026-02-23 12:45:04 +00:00
|
|
|
vet: generate
|
2026-03-17 07:23:49 +00:00
|
|
|
@packages="$$(go list ./...)" && \
|
|
|
|
|
$(GO) vet $$(printf '%s\n' "$$packages" | grep -v '^github.com/sipeed/picoclaw/web/')
|
|
|
|
|
@cd web/backend && $(WEB_GO) vet ./...
|
2026-02-14 23:43:46 +00:00
|
|
|
|
2026-02-18 19:48:23 +00:00
|
|
|
## test: Test Go code
|
2026-02-23 12:45:04 +00:00
|
|
|
test: generate
|
2026-03-17 06:12:32 +00:00
|
|
|
@$(GO) test $$(go list ./... | grep -v github.com/sipeed/picoclaw/web/)
|
|
|
|
|
@cd web && make test
|
2026-02-14 23:43:46 +00:00
|
|
|
|
2026-02-04 11:06:13 +00:00
|
|
|
## fmt: Format Go code
|
|
|
|
|
fmt:
|
2026-02-18 19:48:23 +00:00
|
|
|
@$(GOLANGCI_LINT) fmt
|
|
|
|
|
|
|
|
|
|
## lint: Run linters
|
|
|
|
|
lint:
|
|
|
|
|
@$(GOLANGCI_LINT) run
|
2026-02-04 11:06:13 +00:00
|
|
|
|
2026-02-24 11:04:23 +00:00
|
|
|
## fix: Fix linting issues
|
|
|
|
|
fix:
|
|
|
|
|
@$(GOLANGCI_LINT) run --fix
|
|
|
|
|
|
2026-02-16 07:48:02 +00:00
|
|
|
## deps: Download dependencies
|
2026-02-04 11:06:13 +00:00
|
|
|
deps:
|
2026-02-16 07:48:02 +00:00
|
|
|
@$(GO) mod download
|
|
|
|
|
@$(GO) mod verify
|
|
|
|
|
|
|
|
|
|
## update-deps: Update dependencies
|
|
|
|
|
update-deps:
|
2026-02-04 11:06:13 +00:00
|
|
|
@$(GO) get -u ./...
|
|
|
|
|
@$(GO) mod tidy
|
|
|
|
|
|
2026-02-16 07:48:02 +00:00
|
|
|
## check: Run vet, fmt, and verify dependencies
|
|
|
|
|
check: deps fmt vet test
|
|
|
|
|
|
2026-02-04 11:06:13 +00:00
|
|
|
## run: Build and run picoclaw
|
|
|
|
|
run: build
|
|
|
|
|
@$(BUILD_DIR)/$(BINARY_NAME) $(ARGS)
|
|
|
|
|
|
2026-02-16 06:48:40 +00:00
|
|
|
## docker-build: Build Docker image (minimal Alpine-based)
|
|
|
|
|
docker-build:
|
|
|
|
|
@echo "Building minimal Docker image (Alpine-based)..."
|
2026-03-01 02:56:02 +00:00
|
|
|
docker compose -f docker/docker-compose.yml build picoclaw-agent picoclaw-gateway
|
2026-02-16 06:48:40 +00:00
|
|
|
|
2026-02-16 07:40:07 +00:00
|
|
|
## docker-build-full: Build Docker image with full MCP support (Node.js 24)
|
2026-02-16 06:48:40 +00:00
|
|
|
docker-build-full:
|
2026-02-16 07:40:07 +00:00
|
|
|
@echo "Building full-featured Docker image (Node.js 24)..."
|
2026-03-01 02:56:02 +00:00
|
|
|
docker compose -f docker/docker-compose.full.yml build picoclaw-agent picoclaw-gateway
|
2026-02-16 06:48:40 +00:00
|
|
|
|
|
|
|
|
## docker-test: Test MCP tools in Docker container
|
|
|
|
|
docker-test:
|
|
|
|
|
@echo "Testing MCP tools in Docker..."
|
|
|
|
|
@chmod +x scripts/test-docker-mcp.sh
|
|
|
|
|
@./scripts/test-docker-mcp.sh
|
|
|
|
|
|
|
|
|
|
## docker-run: Run picoclaw gateway in Docker (Alpine-based)
|
|
|
|
|
docker-run:
|
2026-03-01 02:56:02 +00:00
|
|
|
docker compose -f docker/docker-compose.yml --profile gateway up
|
2026-02-16 06:48:40 +00:00
|
|
|
|
|
|
|
|
## docker-run-full: Run picoclaw gateway in Docker (full-featured)
|
|
|
|
|
docker-run-full:
|
2026-03-01 02:56:02 +00:00
|
|
|
docker compose -f docker/docker-compose.full.yml --profile gateway up
|
2026-02-16 06:48:40 +00:00
|
|
|
|
|
|
|
|
## docker-run-agent: Run picoclaw agent in Docker (interactive, Alpine-based)
|
|
|
|
|
docker-run-agent:
|
2026-03-01 02:56:02 +00:00
|
|
|
docker compose -f docker/docker-compose.yml run --rm picoclaw-agent
|
2026-02-16 06:48:40 +00:00
|
|
|
|
|
|
|
|
## docker-run-agent-full: Run picoclaw agent in Docker (interactive, full-featured)
|
|
|
|
|
docker-run-agent-full:
|
2026-03-01 02:56:02 +00:00
|
|
|
docker compose -f docker/docker-compose.full.yml run --rm picoclaw-agent
|
2026-02-16 06:48:40 +00:00
|
|
|
|
|
|
|
|
## docker-clean: Clean Docker images and volumes
|
|
|
|
|
docker-clean:
|
2026-03-01 02:56:02 +00:00
|
|
|
docker compose -f docker/docker-compose.yml down -v
|
|
|
|
|
docker compose -f docker/docker-compose.full.yml down -v
|
2026-02-16 06:48:40 +00:00
|
|
|
docker rmi picoclaw:latest picoclaw:full 2>/dev/null || true
|
|
|
|
|
|
2026-03-18 06:43:58 +00:00
|
|
|
|
|
|
|
|
## build-macos-app: Build PicoClaw macOS .app bundle (no terminal window)
|
|
|
|
|
build-macos-app:
|
|
|
|
|
@echo "Building macOS .app bundle..."
|
|
|
|
|
@if [ "$(UNAME_S)" != "Darwin" ]; then \
|
|
|
|
|
echo "Error: This target is only available on macOS"; \
|
|
|
|
|
exit 1; \
|
|
|
|
|
fi
|
|
|
|
|
@cd web && $(MAKE) build && cd ..
|
|
|
|
|
@./scripts/build-macos-app.sh $(BINARY_NAME)-$(PLATFORM)-$(ARCH)
|
|
|
|
|
@echo "macOS .app bundle created: $(BUILD_DIR)/PicoClaw.app"
|
|
|
|
|
|
2026-02-04 11:06:13 +00:00
|
|
|
## help: Show this help message
|
|
|
|
|
help:
|
|
|
|
|
@echo "picoclaw Makefile"
|
|
|
|
|
@echo ""
|
|
|
|
|
@echo "Usage:"
|
|
|
|
|
@echo " make [target]"
|
|
|
|
|
@echo ""
|
|
|
|
|
@echo "Targets:"
|
2026-02-24 11:04:23 +00:00
|
|
|
@grep -E '^## ' $(MAKEFILE_LIST) | sort | awk -F': ' '{printf " %-16s %s\n", substr($$1, 4), $$2}'
|
2026-02-04 11:06:13 +00:00
|
|
|
@echo ""
|
|
|
|
|
@echo "Examples:"
|
|
|
|
|
@echo " make build # Build for current platform"
|
2026-02-11 12:41:40 +00:00
|
|
|
@echo " make install # Install to ~/.local/bin"
|
2026-02-04 11:06:13 +00:00
|
|
|
@echo " make uninstall # Remove from /usr/local/bin"
|
|
|
|
|
@echo " make install-skills # Install skills to workspace"
|
2026-02-16 06:48:40 +00:00
|
|
|
@echo " make docker-build # Build minimal Docker image"
|
|
|
|
|
@echo " make docker-test # Test MCP tools in Docker"
|
2026-02-04 11:06:13 +00:00
|
|
|
@echo ""
|
|
|
|
|
@echo "Environment Variables:"
|
2026-02-11 12:41:40 +00:00
|
|
|
@echo " INSTALL_PREFIX # Installation prefix (default: ~/.local)"
|
2026-02-04 11:06:13 +00:00
|
|
|
@echo " WORKSPACE_DIR # Workspace directory (default: ~/.picoclaw/workspace)"
|
|
|
|
|
@echo " VERSION # Version string (default: git describe)"
|
|
|
|
|
@echo ""
|
|
|
|
|
@echo "Current Configuration:"
|
|
|
|
|
@echo " Platform: $(PLATFORM)/$(ARCH)"
|
|
|
|
|
@echo " Binary: $(BINARY_PATH)"
|
|
|
|
|
@echo " Install Prefix: $(INSTALL_PREFIX)"
|
|
|
|
|
@echo " Workspace: $(WORKSPACE_DIR)"
|