refactor(version): extract version formatting helpers and improve build info display

Extract formatVersion() and formatBuildInfo() helper functions to reduce code duplication between printVersion() and statusCmd(). Update git commit default value to "dev" in Makefile for consistency with version handling. Update documentation for QQ and DingTalk chat integration in Japanese README.
This commit is contained in:
yinwm
2026-02-13 19:56:31 +08:00
parent 3c2e467324
commit 92490feff0
3 changed files with 96 additions and 63 deletions

View File

@@ -8,7 +8,7 @@ MAIN_GO=$(CMD_DIR)/main.go
# Version
VERSION?=$(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
GIT_COMMIT=$(shell git rev-parse --short=8 HEAD 2>/dev/null || echo "unknown")
GIT_COMMIT=$(shell git rev-parse --short=8 HEAD 2>/dev/null || echo "dev")
BUILD_TIME=$(shell date +%FT%T%z)
GO_VERSION=$(shell $(GO) version | awk '{print $$3}')
LDFLAGS=-ldflags "-X main.version=$(VERSION) -X main.gitCommit=$(GIT_COMMIT) -X main.buildTime=$(BUILD_TIME) -X main.goVersion=$(GO_VERSION)"

View File

@@ -186,7 +186,7 @@ picoclaw onboard
"providers": {
"openrouter": {
"api_key": "xxx",
"api_base": "https://open.bigmodel.cn/api/paas/v4"
"api_base": "https://openrouter.ai/api/v1"
}
},
"tools": {
@@ -223,12 +223,14 @@ picoclaw agent -m "What is 2+2?"
## 💬 チャットアプリ
Telegram で PicoClaw と会話できます
Telegram、Discord、QQ、DingTalk で PicoClaw と会話できます
| チャネル | セットアップ |
|---------|------------|
| **Telegram** | 簡単(トークンのみ) |
| **Discord** | 簡単Bot トークン + Intents |
| **QQ** | 簡単AppID + AppSecret |
| **DingTalk** | 普通(アプリ認証情報) |
<details>
<summary><b>Telegram</b>(推奨)</summary>
@@ -307,6 +309,73 @@ picoclaw gateway
</details>
<details>
<summary><b>QQ</b></summary>
**1. Bot を作成**
- [QQ オープンプラットフォーム](https://connect.qq.com/) にアクセス
- アプリケーションを作成 → **AppID****AppSecret** を取得
**2. 設定**
```json
{
"channels": {
"qq": {
"enabled": true,
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"allow_from": []
}
}
}
```
> `allow_from` を空にすると全ユーザーを許可、QQ番号を指定してアクセス制限可能。
**3. 起動**
```bash
picoclaw gateway
```
</details>
<details>
<summary><b>DingTalk</b></summary>
**1. Bot を作成**
- [オープンプラットフォーム](https://open.dingtalk.com/) にアクセス
- 内部アプリを作成
- Client ID と Client Secret をコピー
**2. 設定**
```json
{
"channels": {
"dingtalk": {
"enabled": true,
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"allow_from": []
}
}
}
```
> `allow_from` を空にすると全ユーザーを許可、ユーザーIDを指定してアクセス制限可能。
**3. 起動**
```bash
picoclaw gateway
```
</details>
## ⚙️ 設定
設定ファイル: `~/.picoclaw/config.json`

View File

@@ -43,19 +43,33 @@ var (
const logo = "🦞"
func printVersion() {
fmt.Printf("%s picoclaw %s", logo, version)
// formatVersion returns the version string with optional git commit
func formatVersion() string {
v := version
if gitCommit != "" {
fmt.Printf(" (git: %s)", gitCommit)
v += fmt.Sprintf(" (git: %s)", gitCommit)
}
fmt.Println()
return v
}
// formatBuildInfo returns build time and go version info
func formatBuildInfo() (build string, goVer string) {
if buildTime != "" {
fmt.Printf(" Build: %s\n", buildTime)
build = buildTime
}
goVer := goVersion
goVer = goVersion
if goVer == "" {
goVer = runtime.Version()
}
return
}
func printVersion() {
fmt.Printf("%s picoclaw %s\n", logo, formatVersion())
build, goVer := formatBuildInfo()
if build != "" {
fmt.Printf(" Build: %s\n", build)
}
if goVer != "" {
fmt.Printf(" Go: %s\n", goVer)
}
@@ -766,13 +780,10 @@ func statusCmd() {
configPath := getConfigPath()
fmt.Printf("%s picoclaw Status\n", logo)
fmt.Printf("Version: %s", version)
if gitCommit != "" {
fmt.Printf(" (git: %s)", gitCommit)
}
fmt.Println()
if buildTime != "" {
fmt.Printf("Build: %s\n", buildTime)
fmt.Printf("Version: %s\n", formatVersion())
build, _ := formatBuildInfo()
if build != "" {
fmt.Printf("Build: %s\n", build)
}
fmt.Println()
@@ -1295,53 +1306,6 @@ func cronEnableCmd(storePath string, disable bool) {
}
}
func skillsCmd() {
if len(os.Args) < 3 {
skillsHelp()
return
}
subcommand := os.Args[2]
cfg, err := loadConfig()
if err != nil {
fmt.Printf("Error loading config: %v\n", err)
os.Exit(1)
}
workspace := cfg.WorkspacePath()
installer := skills.NewSkillInstaller(workspace)
// 获取全局配置目录和内置 skills 目录
globalDir := filepath.Dir(getConfigPath())
globalSkillsDir := filepath.Join(globalDir, "skills")
builtinSkillsDir := filepath.Join(globalDir, "picoclaw", "skills")
skillsLoader := skills.NewSkillsLoader(workspace, globalSkillsDir, builtinSkillsDir)
switch subcommand {
case "list":
skillsListCmd(skillsLoader)
case "install":
skillsInstallCmd(installer)
case "remove", "uninstall":
if len(os.Args) < 4 {
fmt.Println("Usage: picoclaw skills remove <skill-name>")
return
}
skillsRemoveCmd(installer, os.Args[3])
case "search":
skillsSearchCmd(installer)
case "show":
if len(os.Args) < 4 {
fmt.Println("Usage: picoclaw skills show <skill-name>")
return
}
skillsShowCmd(skillsLoader, os.Args[3])
default:
fmt.Printf("Unknown skills command: %s\n", subcommand)
skillsHelp()
}
}
func skillsHelp() {
fmt.Println("\nSkills commands:")
fmt.Println(" list List installed skills")