feat: Support installing built-in AGENT files and skills during picoclaw onboard

This commit is contained in:
lxowalle
2026-02-15 00:16:42 +08:00
parent 1cff7d4e37
commit a9557aa073
19 changed files with 190 additions and 199 deletions

1
.gitignore vendored
View File

@@ -10,6 +10,7 @@ build/
*.out
/picoclaw
/picoclaw-test
cmd/picoclaw/workspace
# Picoclaw specific

View File

@@ -25,12 +25,8 @@ RUN apk add --no-cache ca-certificates tzdata
# Copy binary
COPY --from=builder /src/build/picoclaw /usr/local/bin/picoclaw
# Copy builtin skills
COPY --from=builder /src/skills /opt/picoclaw/skills
# Create picoclaw home directory
RUN mkdir -p /root/.picoclaw/workspace/skills && \
cp -r /opt/picoclaw/skills/* /root/.picoclaw/workspace/skills/ 2>/dev/null || true
RUN /usr/local/bin/picoclaw onboard
ENTRYPOINT ["picoclaw"]
CMD ["gateway"]

View File

@@ -67,6 +67,8 @@ all: build
build:
@echo "Building $(BINARY_NAME) for $(PLATFORM)/$(ARCH)..."
@mkdir -p $(BUILD_DIR)
@rm -r ./$(CMD_DIR)/workspace 2>/dev/null || true
@cp -r workspace ./$(CMD_DIR)/workspace 2>/dev/null || true
$(GO) build $(GOFLAGS) $(LDFLAGS) -o $(BINARY_PATH) ./$(CMD_DIR)
@echo "Build complete: $(BINARY_PATH)"
@ln -sf $(BINARY_NAME)-$(PLATFORM)-$(ARCH) $(BUILD_DIR)/$(BINARY_NAME)
@@ -74,6 +76,8 @@ build:
## build-all: Build picoclaw for all platforms
build-all:
@echo "Building for multiple platforms..."
@rm -r ./$(CMD_DIR)/workspace 2>/dev/null || true
@cp -r workspace ./$(CMD_DIR)/workspace 2>/dev/null || true
@mkdir -p $(BUILD_DIR)
GOOS=linux GOARCH=amd64 $(GO) build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-linux-amd64 ./$(CMD_DIR)
GOOS=linux GOARCH=arm64 $(GO) build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 ./$(CMD_DIR)
@@ -89,35 +93,8 @@ install: build
@cp $(BUILD_DIR)/$(BINARY_NAME) $(INSTALL_BIN_DIR)/$(BINARY_NAME)
@chmod +x $(INSTALL_BIN_DIR)/$(BINARY_NAME)
@echo "Installed binary to $(INSTALL_BIN_DIR)/$(BINARY_NAME)"
@echo "Installing builtin skills to $(WORKSPACE_SKILLS_DIR)..."
@mkdir -p $(WORKSPACE_SKILLS_DIR)
@for skill in $(BUILTIN_SKILLS_DIR)/*/; do \
if [ -d "$$skill" ]; then \
skill_name=$$(basename "$$skill"); \
if [ -f "$$skill/SKILL.md" ]; then \
cp -r "$$skill" $(WORKSPACE_SKILLS_DIR); \
echo " ✓ Installed skill: $$skill_name"; \
fi; \
fi; \
done
@echo "Installation complete!"
## install-skills: Install builtin skills to workspace
install-skills:
@echo "Installing builtin skills to $(WORKSPACE_SKILLS_DIR)..."
@mkdir -p $(WORKSPACE_SKILLS_DIR)
@for skill in $(BUILTIN_SKILLS_DIR)/*/; do \
if [ -d "$$skill" ]; then \
skill_name=$$(basename "$$skill"); \
if [ -f "$$skill/SKILL.md" ]; then \
mkdir -p $(WORKSPACE_SKILLS_DIR)/$$skill_name; \
cp -r "$$skill" $(WORKSPACE_SKILLS_DIR); \
echo " ✓ Installed skill: $$skill_name"; \
fi; \
fi; \
done
@echo "Skills installation complete!"
## uninstall: Remove picoclaw from system
uninstall:
@echo "Uninstalling $(BINARY_NAME)..."

View File

@@ -11,12 +11,14 @@ import (
"context"
"fmt"
"io"
"io/fs"
"os"
"os/signal"
"path/filepath"
"runtime"
"strings"
"time"
"embed"
"github.com/chzyer/readline"
"github.com/sipeed/picoclaw/pkg/agent"
@@ -36,6 +38,10 @@ import (
"github.com/sipeed/picoclaw/pkg/voice"
)
//go:embed workspace
var embeddedFiles embed.FS
var (
version = "dev"
gitCommit string
@@ -208,6 +214,7 @@ func printHelp() {
fmt.Println(" version Show version information")
}
func onboard() {
configPath := getConfigPath()
@@ -229,10 +236,6 @@ func onboard() {
}
workspace := cfg.WorkspacePath()
os.MkdirAll(workspace, 0755)
os.MkdirAll(filepath.Join(workspace, "memory"), 0755)
os.MkdirAll(filepath.Join(workspace, "skills"), 0755)
createWorkspaceTemplates(workspace)
fmt.Printf("%s picoclaw is ready!\n", logo)
@@ -242,170 +245,57 @@ func onboard() {
fmt.Println(" 2. Chat: picoclaw agent -m \"Hello!\"")
}
func copyEmbeddedToTarget(targetDir string) error {
// Ensure target directory exists
if err := os.MkdirAll(targetDir, 0755); err != nil {
return fmt.Errorf("Failed to create target directory: %w", err)
}
// Walk through all files in embed.FS
err := fs.WalkDir(embeddedFiles, "workspace", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
// Skip directories
if d.IsDir() {
return nil
}
// Read embedded file
data, err := embeddedFiles.ReadFile(path)
if err != nil {
return fmt.Errorf("Failed to read embedded file %s: %w", path, err)
}
new_path, err := filepath.Rel("workspace", path)
if err != nil {
return fmt.Errorf("Failed to get relative path for %s: %v\n", path, err)
}
// Build target file path
targetPath := filepath.Join(targetDir, new_path)
// Ensure target file's directory exists
if err := os.MkdirAll(filepath.Dir(targetPath), 0755); err != nil {
return fmt.Errorf("Failed to create directory %s: %w", filepath.Dir(targetPath), err)
}
// Write file
if err := os.WriteFile(targetPath, data, 0644); err != nil {
return fmt.Errorf("Failed to write file %s: %w", targetPath, err)
}
return nil
})
return err
}
func createWorkspaceTemplates(workspace string) {
templates := map[string]string{
"AGENTS.md": `# Agent Instructions
You are a helpful AI assistant. Be concise, accurate, and friendly.
## Guidelines
- Always explain what you're doing before taking actions
- Ask for clarification when request is ambiguous
- Use tools to help accomplish tasks
- Remember important information in your memory files
- Be proactive and helpful
- Learn from user feedback
`,
"SOUL.md": `# Soul
I am picoclaw, a lightweight AI assistant powered by AI.
## Personality
- Helpful and friendly
- Concise and to the point
- Curious and eager to learn
- Honest and transparent
## Values
- Accuracy over speed
- User privacy and safety
- Transparency in actions
- Continuous improvement
`,
"USER.md": `# User
Information about user goes here.
## Preferences
- Communication style: (casual/formal)
- Timezone: (your timezone)
- Language: (your preferred language)
## Personal Information
- Name: (optional)
- Location: (optional)
- Occupation: (optional)
## Learning Goals
- What the user wants to learn from AI
- Preferred interaction style
- Areas of interest
`,
"IDENTITY.md": `# Identity
## Name
PicoClaw 🦞
## Description
Ultra-lightweight personal AI assistant written in Go, inspired by nanobot.
## Version
0.1.0
## Purpose
- Provide intelligent AI assistance with minimal resource usage
- Support multiple LLM providers (OpenAI, Anthropic, Zhipu, etc.)
- Enable easy customization through skills system
- Run on minimal hardware ($10 boards, <10MB RAM)
## Capabilities
- Web search and content fetching
- File system operations (read, write, edit)
- Shell command execution
- Multi-channel messaging (Telegram, WhatsApp, Feishu)
- Skill-based extensibility
- Memory and context management
## Philosophy
- Simplicity over complexity
- Performance over features
- User control and privacy
- Transparent operation
- Community-driven development
## Goals
- Provide a fast, lightweight AI assistant
- Support offline-first operation where possible
- Enable easy customization and extension
- Maintain high quality responses
- Run efficiently on constrained hardware
## License
MIT License - Free and open source
## Repository
https://github.com/sipeed/picoclaw
## Contact
Issues: https://github.com/sipeed/picoclaw/issues
Discussions: https://github.com/sipeed/picoclaw/discussions
---
"Every bit helps, every bit matters."
- Picoclaw
`,
}
for filename, content := range templates {
filePath := filepath.Join(workspace, filename)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
os.WriteFile(filePath, []byte(content), 0644)
fmt.Printf(" Created %s\n", filename)
}
}
memoryDir := filepath.Join(workspace, "memory")
os.MkdirAll(memoryDir, 0755)
memoryFile := filepath.Join(memoryDir, "MEMORY.md")
if _, err := os.Stat(memoryFile); os.IsNotExist(err) {
memoryContent := `# Long-term Memory
This file stores important information that should persist across sessions.
## User Information
(Important facts about user)
## Preferences
(User preferences learned over time)
## Important Notes
(Things to remember)
## Configuration
- Model preferences
- Channel settings
- Skills enabled
`
os.WriteFile(memoryFile, []byte(memoryContent), 0644)
fmt.Println(" Created memory/MEMORY.md")
skillsDir := filepath.Join(workspace, "skills")
if _, err := os.Stat(skillsDir); os.IsNotExist(err) {
os.MkdirAll(skillsDir, 0755)
fmt.Println(" Created skills/")
}
}
for filename, content := range templates {
filePath := filepath.Join(workspace, filename)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
os.WriteFile(filePath, []byte(content), 0644)
fmt.Printf(" Created %s\n", filename)
}
err := copyEmbeddedToTarget(workspace)
if err != nil {
fmt.Printf("Error copying workspace templates: %v\n", err)
}
}

12
workspace/AGENT.md Normal file
View File

@@ -0,0 +1,12 @@
# Agent Instructions
You are a helpful AI assistant. Be concise, accurate, and friendly.
## Guidelines
- Always explain what you're doing before taking actions
- Ask for clarification when request is ambiguous
- Use tools to help accomplish tasks
- Remember important information in your memory files
- Be proactive and helpful
- Learn from user feedback

56
workspace/IDENTITY.md Normal file
View File

@@ -0,0 +1,56 @@
# Identity
## Name
PicoClaw 🦞
## Description
Ultra-lightweight personal AI assistant written in Go, inspired by nanobot.
## Version
0.1.0
## Purpose
- Provide intelligent AI assistance with minimal resource usage
- Support multiple LLM providers (OpenAI, Anthropic, Zhipu, etc.)
- Enable easy customization through skills system
- Run on minimal hardware ($10 boards, <10MB RAM)
## Capabilities
- Web search and content fetching
- File system operations (read, write, edit)
- Shell command execution
- Multi-channel messaging (Telegram, WhatsApp, Feishu)
- Skill-based extensibility
- Memory and context management
## Philosophy
- Simplicity over complexity
- Performance over features
- User control and privacy
- Transparent operation
- Community-driven development
## Goals
- Provide a fast, lightweight AI assistant
- Support offline-first operation where possible
- Enable easy customization and extension
- Maintain high quality responses
- Run efficiently on constrained hardware
## License
MIT License - Free and open source
## Repository
https://github.com/sipeed/picoclaw
## Contact
Issues: https://github.com/sipeed/picoclaw/issues
Discussions: https://github.com/sipeed/picoclaw/discussions
---
"Every bit helps, every bit matters."
- Picoclaw

17
workspace/SOUL.md Normal file
View File

@@ -0,0 +1,17 @@
# Soul
I am picoclaw, a lightweight AI assistant powered by AI.
## Personality
- Helpful and friendly
- Concise and to the point
- Curious and eager to learn
- Honest and transparent
## Values
- Accuracy over speed
- User privacy and safety
- Transparency in actions
- Continuous improvement

21
workspace/USER.md Normal file
View File

@@ -0,0 +1,21 @@
# User
Information about user goes here.
## Preferences
- Communication style: (casual/formal)
- Timezone: (your timezone)
- Language: (your preferred language)
## Personal Information
- Name: (optional)
- Location: (optional)
- Occupation: (optional)
## Learning Goals
- What the user wants to learn from AI
- Preferred interaction style
- Areas of interest

View File

@@ -0,0 +1,21 @@
# Long-term Memory
This file stores important information that should persist across sessions.
## User Information
(Important facts about user)
## Preferences
(User preferences learned over time)
## Important Notes
(Things to remember)
## Configuration
- Model preferences
- Channel settings
- Skills enabled