diff --git a/Makefile b/Makefile
index 0025ef4..2defcce 100644
--- a/Makefile
+++ b/Makefile
@@ -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)"
diff --git a/README.ja.md b/README.ja.md
index 33a8f19..48105ce 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -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** | 普通(アプリ認証情報) |
Telegram(推奨)
@@ -307,6 +309,73 @@ picoclaw gateway
+
+QQ
+
+**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
+```
+
+
+
+
+DingTalk
+
+**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
+```
+
+
+
## ⚙️ 設定
設定ファイル: `~/.picoclaw/config.json`
diff --git a/cmd/picoclaw/main.go b/cmd/picoclaw/main.go
index 694a011..b705a93 100644
--- a/cmd/picoclaw/main.go
+++ b/cmd/picoclaw/main.go
@@ -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 ")
- return
- }
- skillsRemoveCmd(installer, os.Args[3])
- case "search":
- skillsSearchCmd(installer)
- case "show":
- if len(os.Args) < 4 {
- fmt.Println("Usage: picoclaw skills show ")
- 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")