pikiclaw 0.3.27 → 0.3.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -152
- package/dashboard/dist/assets/{AgentTab-BBtJfvrC.js → AgentTab-ZD_v6TZO.js} +1 -1
- package/dashboard/dist/assets/{BrandIcon-ebROfQ3W.js → BrandIcon-ycTnqyli.js} +1 -1
- package/dashboard/dist/assets/{DirBrowser-Ct2sOJlu.js → DirBrowser-D9MoNXRG.js} +1 -1
- package/dashboard/dist/assets/ExtensionsTab-BBzGOBuU.js +1 -0
- package/dashboard/dist/assets/{IMAccessTab-CLJie3vd.js → IMAccessTab-CjuZLN-A.js} +1 -1
- package/dashboard/dist/assets/{Modal-pohoM-qG.js → Modal-BDQJ_YdH.js} +1 -1
- package/dashboard/dist/assets/{Modals-C9P2Ve3h.js → Modals-DwhYomKl.js} +1 -1
- package/dashboard/dist/assets/{PermissionsTab-DKXVXQSO.js → PermissionsTab-B5fachdB.js} +1 -1
- package/dashboard/dist/assets/{Select-CFQy2awZ.js → Select-DGtM0D46.js} +1 -1
- package/dashboard/dist/assets/SessionPanel-w-IIanZE.js +1 -0
- package/dashboard/dist/assets/{SystemTab-DRuic4TT.js → SystemTab-Bkq9SWWJ.js} +1 -1
- package/dashboard/dist/assets/index-BmjHdHur.js +16 -0
- package/dashboard/dist/assets/{index-9UgAKpbU.css → index-CBm6tEZZ.css} +1 -1
- package/dashboard/dist/assets/{index-BWKI6cTh.js → index-CMSUNxje.js} +3 -3
- package/dashboard/dist/assets/{shared-ChIpDTvm.js → shared-S40jZ8aO.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dist/agent/auto-update.js +30 -2
- package/dist/agent/mcp/bridge.js +74 -20
- package/dist/agent/mcp/extensions.js +24 -0
- package/dist/agent/mcp/playwright-proxy.js +156 -51
- package/dist/bot/bot.js +118 -16
- package/dist/bot/command-ui.js +13 -7
- package/dist/bot/commands.js +1 -0
- package/dist/browser-supervisor.js +131 -0
- package/dist/catalog/skill-repos.js +95 -56
- package/dist/channels/feishu/bot.js +1 -1
- package/dist/channels/telegram/bot.js +1 -1
- package/dist/channels/weixin/bot.js +13 -6
- package/dist/cli/main.js +20 -1
- package/dist/core/config/runtime-config.js +1 -1
- package/dist/dashboard/routes/extensions.js +78 -8
- package/package.json +1 -1
- package/dashboard/dist/assets/ExtensionsTab-Ci2zL66a.js +0 -1
- package/dashboard/dist/assets/SessionPanel-BBtT_Oe8.js +0 -1
- package/dashboard/dist/assets/index-D-Mq1xQ_.js +0 -16
package/README.md
CHANGED
|
@@ -2,202 +2,235 @@
|
|
|
2
2
|
|
|
3
3
|
# pikiclaw
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Put the world's smartest AI agents in your pocket.
|
|
6
6
|
|
|
7
|
-
*
|
|
7
|
+
##### *The open Agent orchestrator for the era when creators no longer need to read code.*
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
*Plug in any agent (Claude · Codex · Gemini · Hermes · …), any model (Claude · GPT · Gemini · DeepSeek · 豆包 · MiMo · MiniMax · OpenRouter · or any third-party proxy), any tool (Skills · MCP · CLI). Drive them from any terminal — IM, Web, or future. Pikiclaw is built using pikiclaw.*
|
|
10
|
+
|
|
11
|
+
```bash
|
|
10
12
|
npx pikiclaw@latest
|
|
11
13
|
```
|
|
12
14
|
|
|
13
15
|
<p>
|
|
14
|
-
<a href="https://www.npmjs.com/package/pikiclaw"><img src="https://img.shields.io/npm/v/pikiclaw" alt="npm"></a>
|
|
15
|
-
<a href="
|
|
16
|
-
<a href="https://
|
|
16
|
+
<a href="https://www.npmjs.com/package/pikiclaw"><img src="https://img.shields.io/npm/v/pikiclaw?label=npm&color=cb3837" alt="npm"></a>
|
|
17
|
+
<a href="https://www.npmjs.com/package/pikiclaw"><img src="https://img.shields.io/npm/dm/pikiclaw?label=downloads&color=success" alt="npm downloads"></a>
|
|
18
|
+
<a href="https://github.com/xiaotonng/pikiclaw/stargazers"><img src="https://img.shields.io/github/stars/xiaotonng/pikiclaw?style=flat&color=yellow" alt="GitHub stars"></a>
|
|
19
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"></a>
|
|
20
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%E2%89%A518-green.svg" alt="Node 18+"></a>
|
|
17
21
|
</p>
|
|
18
22
|
|
|
19
|
-
<img src="docs/workspace.png" alt="Workspace" width="
|
|
23
|
+
<img src="docs/workspace.png" alt="Workspace" width="780">
|
|
20
24
|
|
|
21
25
|
</div>
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
---
|
|
24
28
|
|
|
25
|
-
|
|
29
|
+
## What is pikiclaw?
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
**Most "AI dev tool" projects pick one slice — one IDE, one agent, one model vendor — and stop there.** pikiclaw is built around a different bet: the next era of building does not happen inside a single editor. It happens through an **orchestrator** that lets a creator drive a *swarm* of agents — in parallel, from one console — on the best models, through whatever terminal is closest at hand. And never open a code file.
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
The product is the orchestrator. Everything else plugs in. **And the orchestrator is built using itself** — pikiclaw is what we use to build pikiclaw.
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
```
|
|
36
|
+
Terminal layer Telegram Feishu WeChat Web Dashboard ( …mobile · voice · future )
|
|
37
|
+
\__________________|__________________/
|
|
38
|
+
v
|
|
39
|
+
┌──────────────────────────────┐
|
|
40
|
+
│ pikiclaw orchestrator │
|
|
41
|
+
└──────────────────────────────┘
|
|
42
|
+
|
|
|
43
|
+
┌────────────────────────────────┼────────────────────────────────┐
|
|
44
|
+
v v v
|
|
45
|
+
Agent layer Model layer Tool layer
|
|
46
|
+
Claude Code · Codex · Gemini Claude · GPT · Gemini · DeepSeek Skills · MCP · CLI
|
|
47
|
+
Hermes · … (driver registry) 豆包 · MiMo · MiniMax · OpenRouter (global × workspace)
|
|
48
|
+
· any third-party proxy · …
|
|
49
|
+
|
|
|
50
|
+
v
|
|
51
|
+
Your computer
|
|
52
|
+
```
|
|
32
53
|
|
|
33
|
-
|
|
54
|
+
- **Terminal layer** — Telegram, Feishu, WeChat, and the Web Dashboard are co-equal entry points. New terminals plug in here.
|
|
55
|
+
- **Agent layer** — Official Claude Code / Codex / Gemini CLIs as drivers. Hermes is next; the registry takes any agent.
|
|
56
|
+
- **Model layer** — Claude / GPT / Gemini, the domestic Chinese series (DeepSeek, 豆包, MiMo, MiniMax), plus OpenRouter and any third-party proxy. Wrappers let an agent run on top of arbitrary models.
|
|
57
|
+
- **Tool layer** — Skills, MCP servers, and CLI tools merged across global and workspace scopes, injected into every session.
|
|
34
58
|
|
|
35
|
-
|
|
59
|
+
---
|
|
36
60
|
|
|
37
|
-
|
|
38
|
-
<summary>More dashboard pages</summary>
|
|
61
|
+
## Built with itself
|
|
39
62
|
|
|
40
|
-
|
|
63
|
+
> The most credible test of an Agent orchestrator is whether it can build itself. pikiclaw can. We use pikiclaw to develop, test, release, and operate pikiclaw — every commit, every release.
|
|
41
64
|
|
|
42
|
-
|
|
65
|
+
A typical day-of-development inside pikiclaw:
|
|
43
66
|
|
|
44
|
-
|
|
67
|
+
- A Claude Code session in window 1 implements a new dashboard route.
|
|
68
|
+
- A Codex session in window 2 writes the matching unit tests, against the same workspace.
|
|
69
|
+
- A Gemini session in window 3 reviews the diff and drafts the changelog.
|
|
70
|
+
- A skill (`/sk_promote`) sweeps GitHub for relevant issues and replies in a fourth thread.
|
|
71
|
+
- All four streams run in parallel; one human steers them from a phone in a coffee shop.
|
|
45
72
|
|
|
46
|
-
|
|
73
|
+
The orchestrator is the product. It also happens to be the IDE the orchestrator is built in.
|
|
47
74
|
|
|
48
|
-
|
|
75
|
+
---
|
|
49
76
|
|
|
50
|
-
|
|
77
|
+
## A swarm by default
|
|
51
78
|
|
|
52
|
-
|
|
79
|
+
Most "AI dev tools" assume one user, one agent, one task at a time. pikiclaw assumes the opposite: **N agents, N windows, one operator, one toolkit.**
|
|
53
80
|
|
|
54
|
-
|
|
81
|
+
- **N parallel sessions** — every dashboard pane is an independent agent stream against an independent session workspace; IM threads add even more.
|
|
82
|
+
- **Mix-and-match agents** — Claude Code in pane 1, Codex in pane 2, Gemini in pane 3, all on different repos / workspaces.
|
|
83
|
+
- **One toolkit** — global skills, global MCP servers, and per-workspace overrides apply uniformly. You configure once; every session inherits.
|
|
84
|
+
- **Steer anywhere** — interrupt any running stream, queue a follow-up, hand control to the next agent in line.
|
|
85
|
+
- **Group-mode** — drop the orchestrator into a Feishu / WeChat group; teammates share the same swarm.
|
|
55
86
|
|
|
56
|
-
|
|
87
|
+
This is the shape that matters: one creator, with a swarm at their fingertips.
|
|
57
88
|
|
|
58
|
-
|
|
89
|
+
---
|
|
59
90
|
|
|
60
|
-
|
|
91
|
+
## See it in action
|
|
61
92
|
|
|
62
|
-
|
|
93
|
+
> **Real task** — ask pikiclaw to gather and summarize today's AI news; the agent reads, writes, and ships the result back through Telegram, all from your phone.
|
|
63
94
|
|
|
64
|
-
|
|
95
|
+
<p align="center"><img src="docs/promo-demo.gif" alt="Demo: ask Telegram, agent works locally, result returns to chat" width="780"></p>
|
|
65
96
|
|
|
66
|
-
|
|
97
|
+
> **Web Dashboard** — multi-pane workspace with session list, conversation, tool-use traces, and input composer (1 / 2 / 3 / 6 pane layouts).
|
|
67
98
|
|
|
68
|
-
|
|
99
|
+
<p align="center"><img src="docs/promo-dashboard-workspace.png" alt="Web Dashboard workspace" width="780"></p>
|
|
69
100
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
- **Your existing IM** — Telegram, Feishu, or WeChat, no new app to learn
|
|
73
|
-
- **Community extensions** — install MCP servers and skills from the ecosystem with one click
|
|
101
|
+
<details>
|
|
102
|
+
<summary><b>More: basic ops · IM access · agent config · extensions · permissions · system info</b></summary>
|
|
74
103
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
v
|
|
85
|
-
Your Computer
|
|
86
|
-
```
|
|
104
|
+
> Send a message, watch the agent stream, receive files back.
|
|
105
|
+
|
|
106
|
+
<img src="docs/promo-basic-ops.gif" alt="Basic operations" width="780">
|
|
107
|
+
|
|
108
|
+
> **IM Access** — Telegram, Feishu, WeChat channel status and configuration
|
|
109
|
+
|
|
110
|
+
<img src="docs/promo-dashboard-im.png" alt="IM Access" width="780">
|
|
111
|
+
|
|
112
|
+
> **Agent Config** — default agent / model / reasoning effort, available agents overview
|
|
87
113
|
|
|
88
|
-
|
|
114
|
+
<img src="docs/promo-dashboard-agents.png" alt="Agent Config" width="780">
|
|
115
|
+
|
|
116
|
+
> **Extensions** — global MCP servers, community skills, browser & desktop automation
|
|
117
|
+
|
|
118
|
+
<img src="docs/promo-dashboard-extensions.png" alt="Extensions" width="780">
|
|
119
|
+
|
|
120
|
+
> **System Permissions** — macOS accessibility, screen recording, disk access
|
|
121
|
+
|
|
122
|
+
<img src="docs/promo-dashboard-permissions.png" alt="Permissions" width="780">
|
|
123
|
+
|
|
124
|
+
> **System Info** — working directory, CPU / memory / disk monitoring
|
|
125
|
+
|
|
126
|
+
<img src="docs/promo-dashboard-system.png" alt="System Info" width="780">
|
|
127
|
+
|
|
128
|
+
</details>
|
|
89
129
|
|
|
90
130
|
---
|
|
91
131
|
|
|
92
|
-
## Quick
|
|
132
|
+
## Quick start
|
|
93
133
|
|
|
94
|
-
|
|
134
|
+
**Prereqs:** Node.js 18+, plus at least one official Agent CLI logged in:
|
|
95
135
|
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
|
|
99
|
-
- [`codex`](https://github.com/openai/codex) (Codex CLI)
|
|
100
|
-
- [`gemini`](https://github.com/google-gemini/gemini-cli) (Gemini CLI)
|
|
101
|
-
- A bot token for your IM channel (Telegram Bot Token, Feishu app credentials, or WeChat account)
|
|
136
|
+
- [`claude`](https://docs.anthropic.com/en/docs/claude-code) (Claude Code)
|
|
137
|
+
- [`codex`](https://github.com/openai/codex) (Codex CLI)
|
|
138
|
+
- [`gemini`](https://github.com/google-gemini/gemini-cli) (Gemini CLI)
|
|
102
139
|
|
|
103
|
-
|
|
140
|
+
**Launch:**
|
|
104
141
|
|
|
105
142
|
```bash
|
|
106
143
|
cd your-workspace
|
|
107
144
|
npx pikiclaw@latest
|
|
108
145
|
```
|
|
109
146
|
|
|
110
|
-
<img src="docs/promo-install.gif" alt="
|
|
147
|
+
<p align="center"><img src="docs/promo-install.gif" alt="One-command install" width="780"></p>
|
|
111
148
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
- Drive agent sessions directly from the browser — full conversation, tool use, streaming
|
|
115
|
-
- Connect IM channels (Telegram / Feishu / WeChat)
|
|
116
|
-
- Configure agents, models, and reasoning effort
|
|
117
|
-
- Browse and install community MCP servers and skills
|
|
118
|
-
- Manage macOS system permissions and automation extensions
|
|
119
|
-
- Monitor sessions and system resources
|
|
149
|
+
That opens the **Web Dashboard** at `http://localhost:3939` — drive sessions in the browser, connect IM channels, configure agents/models, install MCP servers and skills, manage system permissions. Everything else is one click away.
|
|
120
150
|
|
|
121
151
|
<details>
|
|
122
|
-
<summary>
|
|
152
|
+
<summary><b>Prefer the terminal? There's a wizard.</b></summary>
|
|
123
153
|
|
|
124
154
|
```bash
|
|
125
|
-
npx pikiclaw@latest --setup
|
|
126
|
-
npx pikiclaw@latest --doctor
|
|
155
|
+
npx pikiclaw@latest --setup # interactive terminal wizard
|
|
156
|
+
npx pikiclaw@latest --doctor # environment check only
|
|
127
157
|
```
|
|
128
158
|
|
|
129
159
|
</details>
|
|
130
160
|
|
|
131
161
|
---
|
|
132
162
|
|
|
133
|
-
##
|
|
163
|
+
## What people do with it
|
|
134
164
|
|
|
135
|
-
|
|
165
|
+
- **Run a swarm in parallel** — open N sessions in N dashboard panes (or N IM threads), each a different agent on a different workspace, all working at the same time. One person, many agents, one cockpit. Steer any of them at any moment.
|
|
166
|
+
- **Self-hosted dev loop** — pikiclaw was built using pikiclaw. The dev workflow *is* the product: drive the orchestrator from your phone, write code, ship a release, iterate.
|
|
167
|
+
- **Walk-away coding** — kick off a long refactor, close the laptop, drive it from your phone over Telegram. The agent keeps running locally; results stream back to chat.
|
|
168
|
+
- **Multi-agent on one workspace** — let Claude Code draft an implementation, switch to Codex to review, then Gemini for a different perspective. Same files, same session history.
|
|
169
|
+
- **Domestic-model routing** — run Claude Code over DeepSeek or 豆包 via a wrapper driver when latency, cost, or compliance demands a non-frontier model.
|
|
170
|
+
- **Group-chat agent** — drop pikiclaw into a Feishu / WeChat work group; the team shares one orchestrator, one workspace, one set of skills.
|
|
171
|
+
- **Headless operator** — give the agent browser + macOS desktop control via the built-in MCP bridge, then steer it from anywhere — book a meeting, scrape a dashboard, run an end-to-end test.
|
|
172
|
+
- **Skill-driven workflows** — install community skills (`promote`, `snipe`, `review`, `security-review`, …) once and trigger them from any terminal with `/sk_<name>`.
|
|
136
173
|
|
|
137
|
-
|
|
138
|
-
- Claude Code, Codex CLI, and Gemini CLI via unified driver registry
|
|
139
|
-
- Model listing, session management, and usage tracking through a single interface
|
|
140
|
-
|
|
141
|
-
### Extensions & Community Plugins
|
|
142
|
-
|
|
143
|
-
pikiclaw has a two-layer extension system — **global** extensions apply to all projects, **workspace** extensions are project-scoped.
|
|
174
|
+
---
|
|
144
175
|
|
|
145
|
-
|
|
176
|
+
## Features
|
|
146
177
|
|
|
147
|
-
|
|
178
|
+
### Terminal layer
|
|
148
179
|
|
|
149
|
-
**
|
|
180
|
+
- **Telegram, Feishu, WeChat** — run one or all simultaneously. Each channel is physically isolated; adding a new one (WhatsApp, mobile app, …) doesn't touch the others.
|
|
181
|
+
- **Web Dashboard** — drive sessions directly from the browser with the same conversation, tool-use, and streaming surfaces as IM. Multi-pane workspace (1 / 2 / 3 / 6 panes), light / dark theme, EN / 中文 i18n.
|
|
182
|
+
- **Live streaming preview** — message updates in place as the agent thinks; long text auto-splits; images and files stream back in real time.
|
|
150
183
|
|
|
151
|
-
|
|
184
|
+
### Agent layer
|
|
152
185
|
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
186
|
+
- **Official CLIs as drivers** — Claude Code, Codex CLI, Gemini CLI. No home-grown agent rewrite. You get the upstream behavior, on day-zero updates.
|
|
187
|
+
- **Pluggable registry** — `agent-driver.ts` is the only contract. Hermes and future agents drop in.
|
|
188
|
+
- **Per-session agent switching** — same workspace, swap the brain.
|
|
189
|
+
- **Steer** — interrupt a running task and let a queued message jump ahead in the queue.
|
|
190
|
+
- **Codex human-in-the-loop** — when Codex pauses to ask, the question becomes an interactive IM prompt. Reply there; the task continues.
|
|
158
191
|
|
|
159
|
-
|
|
160
|
-
- Install skills from GitHub repos with one click (`owner/repo`)
|
|
161
|
-
- Browse recommended skill repos (Anthropic Official, Vercel Agent Skills, etc.)
|
|
162
|
-
- Search community skills via npm
|
|
163
|
-
- Skills can declare MCP dependencies via `mcp_requires`
|
|
164
|
-
- Global skills (`~/.pikiclaw/skills/`) and project skills (`.pikiclaw/skills/`)
|
|
192
|
+
### Model layer
|
|
165
193
|
|
|
166
|
-
|
|
194
|
+
- **Frontier + domestic + proxies** — Claude (4 family), GPT-5 / Codex, Gemini, DeepSeek, 豆包 (Doubao), MiMo, MiniMax, OpenRouter, and any third-party model proxy.
|
|
195
|
+
- **Per-session model + reasoning effort** — picked from the dashboard or `/models`.
|
|
196
|
+
- **Wrapper drivers** — run Claude Code or Codex on top of arbitrary models when the upstream client allows.
|
|
167
197
|
|
|
168
|
-
###
|
|
198
|
+
### Tool layer
|
|
169
199
|
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
- Trigger via `/skills` and `/sk_<name>` in chat
|
|
200
|
+
- **Skills** — project skills in `.pikiclaw/skills/*/SKILL.md`, compatible with `.claude/commands/*.md`. One-click install from GitHub repos (`owner/repo`) or browse recommended packs (Anthropic Official, Vercel Agent Skills, …). Trigger with `/skills` and `/sk_<name>`.
|
|
201
|
+
- **MCP servers** — browse the [MCP Registry](https://registry.modelcontextprotocol.io), add custom stdio / HTTP servers, health-check with a real handshake, enable per scope. Built-ins include GitHub, Filesystem, PostgreSQL, Slack, Brave Search, Memory, Fetch, SQLite, Git, Sentry.
|
|
202
|
+
- **CLI tools** — invoked through the agent's normal tool surface, augmented by pikiclaw's session-scoped MCP bridge.
|
|
203
|
+
- **Two-scope merge** — `global < workspace < built-in`, applied automatically to every session.
|
|
175
204
|
|
|
176
|
-
|
|
205
|
+
<p align="center"><img src="docs/promo-dashboard-extensions-add.png" alt="Add MCP server" width="780"></p>
|
|
177
206
|
|
|
178
|
-
|
|
179
|
-
- Session switching, resume, and multi-turn conversations
|
|
180
|
-
- Session classification (answer, proposal, implementation, blocked, etc.)
|
|
181
|
-
- Task queue with **Steer** — interrupt the running task and let a queued message jump ahead
|
|
182
|
-
- Working directory browsing and switching
|
|
183
|
-
- File attachments automatically enter the session workspace
|
|
184
|
-
- Long-task sleep prevention, watchdog, and auto-restart
|
|
185
|
-
- Long text auto-splitting; images and files sent back to IM directly
|
|
186
|
-
- Light / dark theme and i18n (Chinese & English)
|
|
207
|
+
### Runtime & DX
|
|
187
208
|
|
|
188
|
-
|
|
209
|
+
- **Session workspace** — every session owns a directory; file attachments land there automatically.
|
|
210
|
+
- **Resume, switch, classify** — multi-turn conversations, session classification (answer / proposal / implementation / blocked / …).
|
|
211
|
+
- **Session-scoped MCP bridge** — built-in `im_list_files` / `im_send_file` for streaming files back to chat.
|
|
212
|
+
- **GUI automation** (optional):
|
|
213
|
+
- **Browser** — managed Chrome profile via `@playwright/mcp`; log in once, reuse credentials across tasks.
|
|
214
|
+
- **Desktop (macOS)** — Appium Mac2 with `desktop_open_app`, `desktop_snapshot`, `desktop_click`, `desktop_type`, `desktop_screenshot`.
|
|
215
|
+
- **Long-task hardening** — sleep prevention, watchdog, auto-restart, daemon mode.
|
|
189
216
|
|
|
190
|
-
|
|
217
|
+
---
|
|
191
218
|
|
|
192
|
-
|
|
193
|
-
2. **User extensions** — all enabled MCP servers (global + workspace) are merged and registered
|
|
194
|
-
3. **GUI automation** (optional):
|
|
195
|
-
- **Browser** — managed Chrome profile via `@playwright/mcp`; log in once, reuse across tasks
|
|
196
|
-
- **Desktop** — Appium Mac2 with `desktop_open_app`, `desktop_snapshot`, `desktop_click`, `desktop_type`, `desktop_screenshot`
|
|
219
|
+
## How is this different?
|
|
197
220
|
|
|
198
|
-
|
|
221
|
+
| | pikiclaw | IDE assistants<br>(Cursor / Windsurf / Aider) | Cloud agents<br>(Devin / web Claude) | Single-agent IM bots |
|
|
222
|
+
|---|---|---|---|---|
|
|
223
|
+
| **Terminal** | IM + Web + future plug-ins | IDE only | Web app | One IM, one bot |
|
|
224
|
+
| **Where the agent runs** | Your machine | Your machine | Vendor sandbox | Often vendor |
|
|
225
|
+
| **Agent choice** | Claude Code · Codex · Gemini · Hermes · … | Bundled | Single | Single |
|
|
226
|
+
| **Model choice** | Frontier + domestic Chinese | Vendor-controlled | Vendor-controlled | Single |
|
|
227
|
+
| **Parallel agents** | **N agents × N windows × N workspaces** | One per IDE | Sequential | One |
|
|
228
|
+
| **Files / tools** | Your files, your MCP, your CLIs | Your files | Sandbox | None / limited |
|
|
229
|
+
| **Plug new terminal** | Add a `Channel` class | n/a | n/a | Fork |
|
|
230
|
+
| **Plug new agent** | Add an `AgentDriver` | n/a | n/a | Fork |
|
|
231
|
+
| **Self-bootstrapping** | **Yes — built with itself** | No | No | No |
|
|
199
232
|
|
|
200
|
-
|
|
233
|
+
The shape that matters: **you stay in your environment, you keep your choice of brain, you run a swarm in parallel, and the orchestrator is the same one we use to build the orchestrator.**
|
|
201
234
|
|
|
202
235
|
---
|
|
203
236
|
|
|
@@ -205,7 +238,7 @@ When Codex requests additional user input mid-task, pikiclaw surfaces the questi
|
|
|
205
238
|
|
|
206
239
|
| Command | Description |
|
|
207
240
|
|---|---|
|
|
208
|
-
| `/start` |
|
|
241
|
+
| `/start` | Entry info, current agent, working directory |
|
|
209
242
|
| `/sessions` | View, switch, or create sessions |
|
|
210
243
|
| `/agents` | Switch agent |
|
|
211
244
|
| `/models` | View and switch model / reasoning effort |
|
|
@@ -219,23 +252,23 @@ When Codex requests additional user input mid-task, pikiclaw surfaces the questi
|
|
|
219
252
|
| `/restart` | Restart and re-launch bot |
|
|
220
253
|
| `/sk_<name>` | Run a project skill |
|
|
221
254
|
|
|
222
|
-
Plain text
|
|
255
|
+
Plain text is forwarded to the current agent.
|
|
223
256
|
|
|
224
257
|
---
|
|
225
258
|
|
|
226
259
|
## Configuration
|
|
227
260
|
|
|
228
|
-
- Persistent config
|
|
229
|
-
- The Dashboard is the primary configuration
|
|
230
|
-
- Global MCP extensions
|
|
231
|
-
- Workspace MCP extensions
|
|
261
|
+
- Persistent config: `~/.pikiclaw/setting.json`
|
|
262
|
+
- The Dashboard is the primary configuration surface
|
|
263
|
+
- Global MCP extensions: `~/.pikiclaw/setting.json` → `extensions.mcp`
|
|
264
|
+
- Workspace MCP extensions: standard `.mcp.json`
|
|
232
265
|
|
|
233
266
|
<details>
|
|
234
|
-
<summary>GUI automation setup</summary>
|
|
267
|
+
<summary><b>GUI automation setup (browser + macOS desktop)</b></summary>
|
|
235
268
|
|
|
236
|
-
**Browser
|
|
269
|
+
**Browser** is fully managed by the dashboard — a dedicated Chrome profile is created and reused. Log in to the sites you need once, every future agent session reuses those credentials.
|
|
237
270
|
|
|
238
|
-
**macOS desktop
|
|
271
|
+
**macOS desktop** needs Appium Mac2:
|
|
239
272
|
|
|
240
273
|
```bash
|
|
241
274
|
npm install -g appium
|
|
@@ -245,9 +278,7 @@ appium
|
|
|
245
278
|
|
|
246
279
|
Then grant macOS Accessibility permission to your terminal app.
|
|
247
280
|
|
|
248
|
-
|
|
249
|
-
- `PIKICLAW_DESKTOP_GUI`
|
|
250
|
-
- `PIKICLAW_DESKTOP_APPIUM_URL`
|
|
281
|
+
Env vars: `PIKICLAW_DESKTOP_GUI`, `PIKICLAW_DESKTOP_APPIUM_URL`.
|
|
251
282
|
|
|
252
283
|
</details>
|
|
253
284
|
|
|
@@ -255,10 +286,12 @@ Relevant environment variables:
|
|
|
255
286
|
|
|
256
287
|
## Roadmap
|
|
257
288
|
|
|
258
|
-
- **
|
|
259
|
-
-
|
|
260
|
-
-
|
|
261
|
-
-
|
|
289
|
+
- **Hermes driver** — first-class plug-in for the Hermes agent
|
|
290
|
+
- **ACP (Agent Client Protocol)** — unified driver for any ACP-compatible agent, replacing per-agent CLI parsing — see [ACP Migration Plan](docs/acp-migration.md)
|
|
291
|
+
- **More terminals** — WhatsApp, dedicated mobile app, voice
|
|
292
|
+
- **Deeper model layer** — agent-on-arbitrary-model wrappers for more domestic series
|
|
293
|
+
- **Better tool ecosystem** — recommended MCP packs, skill templates, marketplace
|
|
294
|
+
- **GUI co-ordination** — tighter browser + desktop tool interplay
|
|
262
295
|
|
|
263
296
|
---
|
|
264
297
|
|
|
@@ -273,36 +306,42 @@ npm test
|
|
|
273
306
|
```
|
|
274
307
|
|
|
275
308
|
```bash
|
|
276
|
-
npm run dev
|
|
277
|
-
npm run build
|
|
278
|
-
npm test
|
|
279
|
-
npm run test:e2e
|
|
280
|
-
npx pikiclaw@latest --doctor
|
|
309
|
+
npm run dev # local dev (--no-daemon, logs to ~/.pikiclaw/dev/dev.log)
|
|
310
|
+
npm run build # production build
|
|
311
|
+
npm test # unit tests
|
|
312
|
+
npm run test:e2e # end-to-end tests
|
|
313
|
+
npx pikiclaw@latest --doctor # environment check
|
|
281
314
|
```
|
|
282
315
|
|
|
283
|
-
|
|
316
|
+
Architecture and integration deep dives: [ARCHITECTURE.md](ARCHITECTURE.md) · [INTEGRATION.md](INTEGRATION.md) · [TESTING.md](TESTING.md)
|
|
284
317
|
|
|
285
318
|
---
|
|
286
319
|
|
|
287
320
|
## Contributing
|
|
288
321
|
|
|
289
|
-
|
|
322
|
+
The project is built around layers that are *meant* to be extended. New terminals, new agents, new model wrappers, new MCP tools — all are first-class contributions.
|
|
290
323
|
|
|
291
324
|
- Read the **[Contributing Guide](CONTRIBUTING.md)** to get started
|
|
292
|
-
-
|
|
293
|
-
- Open an issue first for larger changes so we can
|
|
325
|
+
- Browse [`good first issue`](https://github.com/xiaotonng/pikiclaw/labels/good%20first%20issue) and [`help wanted`](https://github.com/xiaotonng/pikiclaw/labels/help%20wanted)
|
|
326
|
+
- Open an issue first for larger changes so we can align on approach
|
|
327
|
+
|
|
328
|
+
| Where | What you'd add |
|
|
329
|
+
|---|---|
|
|
330
|
+
| `src/agent/driver.ts`, `src/agent/drivers/*.ts` | A new agent driver |
|
|
331
|
+
| `src/channels/base.ts`, `src/channels/*/` | A new terminal / IM channel |
|
|
332
|
+
| `src/dashboard/routes/*.ts` | A new dashboard API surface |
|
|
333
|
+
| `src/agent/mcp/tools/*.ts`, `src/agent/mcp/bridge.ts` | New session-scoped MCP tools |
|
|
334
|
+
|
|
335
|
+
---
|
|
294
336
|
|
|
295
|
-
|
|
337
|
+
## Star history
|
|
296
338
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
| Add an IM channel | `src/channels/base.ts`, any `src/channels/*/` |
|
|
301
|
-
| Add a dashboard route | `src/dashboard/routes/*.ts` |
|
|
302
|
-
| Change MCP tools | `src/agent/mcp/tools/*.ts`, `src/agent/mcp/bridge.ts` |
|
|
339
|
+
<a href="https://www.star-history.com/#xiaotonng/pikiclaw&Date">
|
|
340
|
+
<img src="https://api.star-history.com/svg?repos=xiaotonng/pikiclaw&type=Date" alt="Star history" width="640">
|
|
341
|
+
</a>
|
|
303
342
|
|
|
304
343
|
---
|
|
305
344
|
|
|
306
345
|
## License
|
|
307
346
|
|
|
308
|
-
[MIT](LICENSE)
|
|
347
|
+
[MIT](LICENSE) — built in the open. Use it, fork it, plug your own layer in.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,j as e}from"./react-vendor-DTcmqLiz.js";import{u as I,b as xe,a as H,g as R,B as y,E as ge,S as q,k as Y,c as pe}from"./index-BWKI6cTh.js";import{B as he}from"./BrandIcon-ebROfQ3W.js";import{M as ve,a as be,L as P}from"./Modal-pohoM-qG.js";import{S as K}from"./Select-CFQy2awZ.js";import{S as Z}from"./shared-ChIpDTvm.js";import"./router-emLofBBH.js";const je=["claude","codex","gemini"];function Ne(t){return t==="zh-CN"?{defaultsTitle:"新会话默认值",defaultsHint:"新会话会默认采用这里的智能体、模型和推理强度。",defaultsEditTitle:"编辑新会话默认值",defaultsEditHint:"在弹窗中选择默认智能体、模型和推理强度,保存后对新会话生效。",defaultsSaved:"新会话默认值已保存",editDefaults:"修改默认值",agentsTitle:"可用智能体",defaultAgent:"默认智能体",defaultModel:"默认模型",defaultEffort:"推理强度",status:"状态",model:"模型",models:"模型",version:"版本",defaultBadge:"默认",installed:"已安装",notInstalled:"未安装",noModel:"暂无可选模型",currentModelPrefix:"当前模型",availableModelsSuffix:"个可选",availableModels:"可用模型",recommendedFor:"建议场景",currentConfig:"当前配置",effort:"推理强度",readyHint:"已安装,可直接作为新会话执行智能体。",installHint:"尚未安装,需要先完成本地 CLI 安装。",noVersion:"版本未知",moreModels:s=>`+${s}`,install:"安装",installing:"安装中...",noEffort:"不支持调整",loadFailed:"无法加载智能体状态",latestVersion:"最新版本",updateAvailable:"有新版本可用",updateSkipped:"自动更新已跳过",updateFailed:"自动更新失败",update:"手动升级",updating:"升级中...",checkUpdate:"检查更新",checking:"检查中...",upToDate:"已是最新"}:{defaultsTitle:"New Session Defaults",defaultsHint:"New sessions use this agent, model, and effort by default.",defaultsEditTitle:"Edit New Session Defaults",defaultsEditHint:"Choose the default agent, model, and effort in the modal, then save them for new sessions.",defaultsSaved:"New session defaults saved",editDefaults:"Edit Defaults",agentsTitle:"Available Agents",defaultAgent:"Default Agent",defaultModel:"Default Model",defaultEffort:"Effort",status:"Status",model:"Model",models:"Models",version:"Version",defaultBadge:"Default",installed:"Installed",notInstalled:"Not installed",noModel:"No selectable models",currentModelPrefix:"Current model",availableModelsSuffix:"available",availableModels:"Available models",recommendedFor:"Recommended for",currentConfig:"Current config",effort:"Effort",readyHint:"Installed and ready for new sessions.",installHint:"Not installed locally yet.",noVersion:"Version unavailable",moreModels:s=>`+${s}`,install:"Install",installing:"Installing...",noEffort:"Not supported",loadFailed:"Failed to load agent status",latestVersion:"Latest",updateAvailable:"Update available",updateSkipped:"Auto-update skipped",updateFailed:"Auto-update failed",update:"Update",updating:"Updating...",checkUpdate:"Check update",checking:"Checking...",upToDate:"Up to date"}}function Me(t,s){const n=t.filter(u=>u.installed);return(n.length?n:t).map(u=>({value:u.agent,label:`${R(u.agent).label} · ${u.installed?u.version||s.installed:s.notInstalled}`}))}function ke(t){if(!t)return[];const s=t.models.map(n=>({value:n.id,label:n.alias?`${n.alias} · ${n.id}`:n.id}));return t.selectedModel&&!s.some(n=>n.value===t.selectedModel)&&s.unshift({value:t.selectedModel,label:t.selectedModel}),s}function Ae(t){return t?ge[t.agent].map(s=>({value:s,label:s})):[]}function Ee(t,s){if(!t.models.length)return s.noModel;const n=t.selectedModel?t.models.find(u=>u.id===t.selectedModel):t.models[0],m=n?.alias||n?.id||s.noModel;return`${s.currentModelPrefix}: ${m} · ${t.models.length} ${s.availableModelsSuffix}`}function se(t){return t?t.alias||t.id:"—"}function le(t,s){if(!t.models.length)return s.noModel;const n=t.selectedModel?t.models.find(m=>m.id===t.selectedModel):t.models[0];return se(n)}function Se(t,s=4){const n=new Set;return t.models.map(u=>({key:u.id,label:se(u)})).filter(u=>n.has(u.key)?!1:(n.add(u.key),!0)).slice(0,s)}function ee(t,s){t({defaultAgent:s.defaultAgent,agents:s.agents})}function te(t,s){return{agent:t?.agent||s,model:t?.selectedModel||"",effort:t?.selectedEffort||""}}function G({label:t,value:s,hint:n,loading:m=!1}){return e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt px-3.5 py-2.5",children:[e.jsx("div",{className:"text-[10px] font-semibold uppercase tracking-[0.14em] text-fg-5",children:t}),e.jsxs("div",{className:"mt-1 flex items-center gap-2 text-[13px] font-semibold text-fg-2",children:[m&&e.jsx(q,{className:"h-3.5 w-3.5"}),e.jsx("span",{children:s})]}),n&&e.jsx("div",{className:"mt-0.5 text-[10px] leading-relaxed text-fg-5",children:n})]})}function we({agent:t,copy:s,t:n,installing:m,onInstall:u,updatingAgent:o,checkingAgent:d,onUpdate:A,onCheckUpdate:U,loading:c=!1}){const E=R(t.agent),V=Ee(t,s),O=le(t,s),j=E.advantageKey?n(E.advantageKey):"—",D=Se(t),F=Math.max(0,t.models.length-D.length),_=t.selectedEffort||s.noEffort,S=t.version||s.noVersion,N=c?n("status.loading"):t.installed?s.installed:s.notInstalled,i=c?"muted":t.installed?"ok":"warn",w=c?n("status.loading"):t.installed?s.readyHint:s.installHint,C=c?n("status.loading"):O,g=c?n("status.loading"):_,p=c?n("status.loading"):j,h=c?n("status.loading"):V;return e.jsx("div",{className:"glass rounded-md border border-edge px-4 py-3 shadow-[0_1px_0_rgba(255,255,255,0.02),0_4px_12px_rgba(15,23,42,0.05)]",children:e.jsxs("div",{className:"grid gap-x-5 gap-y-3 xl:grid-cols-[220px_130px_220px_minmax(0,1fr)_auto] xl:items-start",children:[e.jsx("div",{className:"min-w-0",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-md border border-edge bg-panel-alt",children:e.jsx(he,{brand:t.agent,size:22})}),e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"text-[15px] font-semibold text-fg",children:E.label}),t.isDefault&&e.jsx(Y,{variant:"accent",children:s.defaultBadge})]}),e.jsxs("div",{className:"mt-1 text-[12px] leading-relaxed text-fg-5",children:[s.version,": ",S,t.latestVersion&&t.updateAvailable&&e.jsxs("span",{className:"ml-1.5 text-amber-400",children:["→ ",t.latestVersion]}),t.latestVersion&&!t.updateAvailable&&t.installed&&e.jsx("span",{className:"ml-1.5 text-emerald-400",children:"✓"})]})]})]})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-[10px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:s.status}),e.jsx("div",{className:"mt-1.5",children:e.jsxs(Y,{variant:i,children:[c&&e.jsx(q,{className:"h-3 w-3"}),N]})}),e.jsx("div",{className:"mt-1.5 text-[12px] leading-relaxed text-fg-5",children:w})]}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-[10px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:s.currentConfig}),e.jsxs("div",{className:"mt-1.5 space-y-1.5 text-[13px] leading-relaxed text-fg-3",children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{className:"w-16 shrink-0 text-fg-5",children:s.model}),e.jsx("span",{className:"min-w-0 break-words text-fg-2",children:C})]}),e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{className:"w-16 shrink-0 text-fg-5",children:s.effort}),e.jsx("span",{className:"text-fg-2",children:g})]})]})]}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-[10px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:s.recommendedFor}),e.jsx("div",{className:"mt-1.5 text-[13px] leading-relaxed text-fg-3",children:p}),e.jsx("div",{className:"mt-2.5 text-[10px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:s.availableModels}),e.jsxs("div",{className:"mt-1.5 flex flex-wrap items-center gap-1.5",children:[!c&&D.length>0?D.map(v=>e.jsx("span",{className:"inline-flex h-6 max-w-full items-center rounded-md border border-edge bg-panel-alt px-2 text-[11px] text-fg-3",title:v.key,children:e.jsx("span",{className:"truncate",children:v.label})},v.key)):e.jsx("span",{className:"text-[12px] text-fg-5",children:c?n("status.loading"):s.noModel}),!c&&F>0&&e.jsx("span",{className:"inline-flex h-6 items-center rounded-md border border-edge bg-panel-alt px-2 text-[11px] text-fg-5",children:s.moreModels(F)})]}),e.jsx("div",{className:"mt-1.5 text-[12px] leading-relaxed text-fg-5",children:h})]}),e.jsxs("div",{className:pe("flex flex-col items-start gap-1.5 xl:items-end",t.installed&&"xl:self-start"),children:[c&&e.jsxs("div",{className:"inline-flex h-7 items-center gap-2 rounded-md border border-edge bg-transparent px-2.5 text-[11px] text-fg-5",children:[e.jsx(q,{className:"h-3 w-3"}),n("status.loading")]}),!c&&!t.installed&&e.jsx(y,{variant:"outline",size:"sm",disabled:m,onClick:()=>u(t),children:m?s.installing:s.install}),!c&&t.installed&&t.updateAvailable&&e.jsx(y,{variant:"primary",size:"sm",disabled:o,onClick:()=>A(t),children:o?s.updating:s.update}),!c&&t.installed&&!t.updateAvailable&&e.jsx(y,{variant:"ghost",size:"sm",disabled:d,onClick:()=>U(t),children:d?s.checking:s.checkUpdate}),!c&&t.installed&&t.updateAvailable&&t.updateStatus==="skipped"&&t.updateDetail&&e.jsxs("div",{className:"text-[11px] leading-relaxed text-amber-400",children:[s.updateSkipped,": ",t.updateDetail]}),!c&&t.installed&&t.updateStatus==="failed"&&t.updateDetail&&e.jsxs("div",{className:"text-[11px] leading-relaxed text-red-400",children:[s.updateFailed,": ",t.updateDetail]})]})]})})}function Ve(){const t=I(l=>l.locale),s=I(l=>l.toast),n=I(l=>l.agentStatus),m=I(l=>l.setAgentStatus),u=I(l=>l.refreshAgentStatus),o=r.useMemo(()=>xe(t),[t]),d=Ne(t),[A,U]=r.useState(n?{defaultAgent:n.defaultAgent,agents:n.agents}:null),[c,E]=r.useState(!n),[V,O]=r.useState(null),[j,D]=r.useState(!1),[F,_]=r.useState(null),[S,N]=r.useState(!1),[i,w]=r.useState({agent:"codex",model:"",effort:""}),C=r.useRef(!!n);r.useEffect(()=>{n&&(ee(U,n),C.current||(C.current=!0,E(!1)))},[n]);const g=r.useCallback(l=>{ee(U,l),m(l)},[m]),p=r.useCallback(async()=>{C.current||E(!0);try{const l=await H.getAgentStatus();return g(l),O(null),C.current=!0,l}catch(l){const a=l instanceof Error?l.message:d.loadFailed;return O(a),C.current||s(a,!1),null}finally{E(!1)}},[g,d.loadFailed,s]);r.useEffect(()=>{n?u():p()},[]);const h=r.useMemo(()=>{const l=A?.agents||[],a=new Map(l.map(f=>[f.agent,f]));return je.map(f=>{const T=a.get(f);if(T)return T;const b=R(f);return{agent:f,label:b.label,installed:!1,version:void 0,installCommand:void 0,selectedModel:null,selectedEffort:null,isDefault:A?.defaultAgent===f,models:[],usage:null}})},[A]),v=A?.defaultAgent||"codex",M=h.find(l=>l.agent===v)||null,J=h.filter(l=>l.installed).length>0,ae=Me(h,d),x=h.find(l=>l.agent===i.agent)||null,L=ke(x),$=Ae(x),Q=r.useCallback(async l=>{D(!0);try{const a=await H.updateRuntimeAgent(l);if(!a.ok)throw new Error(a.error||o("config.applyFailed"));return g(a),a}catch(a){const f=a instanceof Error?a.message:o("config.applyFailed");return s(f,!1),p(),null}finally{D(!1)}},[g,p,o,s]);r.useEffect(()=>{S&&w(te(M,v))},[v,M,S]),r.useEffect(()=>{if(!S||!x)return;const l=x.selectedModel||"",a=!i.model||L.some(b=>b.value===i.model),f=x.selectedEffort||"",T=!i.effort||$.some(b=>b.value===i.effort);a&&T||w(b=>({...b,model:a?b.model:l,effort:T?b.effort:f}))},[S,i.effort,i.model,x,$,L]);const ne=r.useCallback(l=>{const a=h.find(f=>f.agent===l);a?.installed&&w(te(a,a.agent))},[h]),de=r.useCallback(async()=>{if(!x?.installed)return;const l={};if(i.agent!==v&&(l.defaultAgent=i.agent),i.model&&i.model!==(x.selectedModel||"")&&(l.agent=i.agent,l.model=i.model),i.effort&&i.effort!==(x.selectedEffort||"")&&(l.agent=i.agent,l.effort=i.effort),Object.keys(l).length===0){N(!1);return}await Q(l)&&(s(d.defaultsSaved),N(!1))},[d.defaultsSaved,v,i.agent,i.effort,i.model,x,s,Q]),ie=r.useCallback(async l=>{if(!F){_(l.agent);try{const a=await H.installAgent(l.agent);if(!a.ok)throw new Error(a.error||o("config.agentInstallFailed"));g(a),s(o("config.agentInstalled"))}catch(a){const f=a instanceof Error?a.message:o("config.agentInstallFailed");s(f,!1),p()}finally{_(a=>a===l.agent?null:a)}}},[g,F,p,o,s]),[B,W]=r.useState(null),[z,X]=r.useState(null),re=r.useCallback(async l=>{if(!B){W(l.agent);try{const a=await H.updateAgent(l.agent);if(!a.ok)throw new Error(a.error||o("config.agentInstallFailed"));g(a),s(d.upToDate)}catch(a){const f=a instanceof Error?a.message:d.updateFailed;s(f,!1),p()}finally{W(a=>a===l.agent?null:a)}}},[g,d.updateFailed,d.upToDate,p,o,s,B]),oe=r.useCallback(async l=>{if(!z){X(l.agent);try{const a=await H.checkAgentUpdate(l.agent);if(!a.ok)throw new Error(a.error||d.loadFailed);g(a)}catch(a){const f=a instanceof Error?a.message:d.loadFailed;s(f,!1),p()}finally{X(a=>a===l.agent?null:a)}}},[g,z,d.loadFailed,p,s]),k=c&&!A,ce=k?o("status.loading"):M?R(M.agent).label:d.notInstalled,fe=k?o("status.loading"):M?.installed?d.installed:d.notInstalled,ue=k?o("status.loading"):M?le(M,d):d.noModel,me=k?o("status.loading"):M?.selectedEffort||d.noEffort;return e.jsxs("div",{className:"animate-in space-y-4",children:[e.jsx("section",{className:"space-y-3",children:e.jsxs(Z,{className:"space-y-3",children:[e.jsxs("div",{className:"flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-base font-semibold tracking-tight text-fg",children:d.defaultsTitle}),e.jsx("div",{className:"mt-0.5 text-[13px] leading-relaxed text-fg-4",children:d.defaultsHint})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx(y,{variant:"secondary",onClick:()=>N(!0),disabled:j||!J,children:d.editDefaults})})]}),e.jsxs("div",{className:"grid gap-2.5 lg:grid-cols-3",children:[e.jsx(G,{label:d.defaultAgent,value:ce,hint:fe,loading:k}),e.jsx(G,{label:d.defaultModel,value:ue,loading:k}),e.jsx(G,{label:d.defaultEffort,value:me,loading:k})]})]})}),e.jsxs("section",{className:"space-y-3",children:[e.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-[0.18em] text-fg-5",children:d.agentsTitle}),e.jsx("div",{className:"space-y-3",children:h.map(l=>e.jsx(we,{agent:l,copy:d,t:o,installing:F===l.agent,loading:k,onInstall:ie,updatingAgent:B===l.agent,checkingAgent:z===l.agent,onUpdate:re,onCheckUpdate:oe},l.agent))})]}),V&&e.jsx(Z,{className:"border-amber-500/20 bg-amber-500/5",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{className:"text-[13px] text-fg-2",children:V}),e.jsx(y,{variant:"outline",size:"sm",onClick:()=>{p()},children:o("sessions.retry")})]})}),e.jsxs(ve,{open:S,onClose:()=>N(!1),children:[e.jsx(be,{title:d.defaultsEditTitle,description:d.defaultsEditHint,onClose:()=>N(!1)}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(P,{children:d.defaultAgent}),e.jsx(K,{value:i.agent,options:ae,onChange:ne,disabled:j||!J,placeholder:d.notInstalled})]}),e.jsxs("div",{children:[e.jsx(P,{children:d.defaultModel}),e.jsx(K,{value:i.model,options:L,onChange:l=>w(a=>({...a,model:l})),disabled:j||!x?.installed||L.length===0,placeholder:d.noModel})]}),e.jsxs("div",{children:[e.jsx(P,{children:d.defaultEffort}),e.jsx(K,{value:i.effort,options:$,onChange:l=>w(a=>({...a,effort:l})),disabled:j||!x?.installed||$.length===0,placeholder:d.noEffort})]})]}),e.jsxs("div",{className:"mt-6 flex justify-end gap-2",children:[e.jsx(y,{variant:"ghost",onClick:()=>N(!1),children:o("modal.cancel")}),e.jsx(y,{variant:"primary",disabled:j||!x?.installed,onClick:()=>{de()},children:o(j?"config.validating":"modal.save")})]})]})]})}export{Ve as AgentTab,Ve as default};
|
|
1
|
+
import{r,j as e}from"./react-vendor-DTcmqLiz.js";import{u as I,b as xe,a as H,g as R,B as y,E as ge,S as q,k as Y,c as pe}from"./index-CMSUNxje.js";import{B as he}from"./BrandIcon-ycTnqyli.js";import{M as ve,a as be,L as P}from"./Modal-BDQJ_YdH.js";import{S as K}from"./Select-DGtM0D46.js";import{S as Z}from"./shared-S40jZ8aO.js";import"./router-emLofBBH.js";const je=["claude","codex","gemini"];function Ne(t){return t==="zh-CN"?{defaultsTitle:"新会话默认值",defaultsHint:"新会话会默认采用这里的智能体、模型和推理强度。",defaultsEditTitle:"编辑新会话默认值",defaultsEditHint:"在弹窗中选择默认智能体、模型和推理强度,保存后对新会话生效。",defaultsSaved:"新会话默认值已保存",editDefaults:"修改默认值",agentsTitle:"可用智能体",defaultAgent:"默认智能体",defaultModel:"默认模型",defaultEffort:"推理强度",status:"状态",model:"模型",models:"模型",version:"版本",defaultBadge:"默认",installed:"已安装",notInstalled:"未安装",noModel:"暂无可选模型",currentModelPrefix:"当前模型",availableModelsSuffix:"个可选",availableModels:"可用模型",recommendedFor:"建议场景",currentConfig:"当前配置",effort:"推理强度",readyHint:"已安装,可直接作为新会话执行智能体。",installHint:"尚未安装,需要先完成本地 CLI 安装。",noVersion:"版本未知",moreModels:s=>`+${s}`,install:"安装",installing:"安装中...",noEffort:"不支持调整",loadFailed:"无法加载智能体状态",latestVersion:"最新版本",updateAvailable:"有新版本可用",updateSkipped:"自动更新已跳过",updateFailed:"自动更新失败",update:"手动升级",updating:"升级中...",checkUpdate:"检查更新",checking:"检查中...",upToDate:"已是最新"}:{defaultsTitle:"New Session Defaults",defaultsHint:"New sessions use this agent, model, and effort by default.",defaultsEditTitle:"Edit New Session Defaults",defaultsEditHint:"Choose the default agent, model, and effort in the modal, then save them for new sessions.",defaultsSaved:"New session defaults saved",editDefaults:"Edit Defaults",agentsTitle:"Available Agents",defaultAgent:"Default Agent",defaultModel:"Default Model",defaultEffort:"Effort",status:"Status",model:"Model",models:"Models",version:"Version",defaultBadge:"Default",installed:"Installed",notInstalled:"Not installed",noModel:"No selectable models",currentModelPrefix:"Current model",availableModelsSuffix:"available",availableModels:"Available models",recommendedFor:"Recommended for",currentConfig:"Current config",effort:"Effort",readyHint:"Installed and ready for new sessions.",installHint:"Not installed locally yet.",noVersion:"Version unavailable",moreModels:s=>`+${s}`,install:"Install",installing:"Installing...",noEffort:"Not supported",loadFailed:"Failed to load agent status",latestVersion:"Latest",updateAvailable:"Update available",updateSkipped:"Auto-update skipped",updateFailed:"Auto-update failed",update:"Update",updating:"Updating...",checkUpdate:"Check update",checking:"Checking...",upToDate:"Up to date"}}function Me(t,s){const n=t.filter(u=>u.installed);return(n.length?n:t).map(u=>({value:u.agent,label:`${R(u.agent).label} · ${u.installed?u.version||s.installed:s.notInstalled}`}))}function ke(t){if(!t)return[];const s=t.models.map(n=>({value:n.id,label:n.alias?`${n.alias} · ${n.id}`:n.id}));return t.selectedModel&&!s.some(n=>n.value===t.selectedModel)&&s.unshift({value:t.selectedModel,label:t.selectedModel}),s}function Ae(t){return t?ge[t.agent].map(s=>({value:s,label:s})):[]}function Ee(t,s){if(!t.models.length)return s.noModel;const n=t.selectedModel?t.models.find(u=>u.id===t.selectedModel):t.models[0],m=n?.alias||n?.id||s.noModel;return`${s.currentModelPrefix}: ${m} · ${t.models.length} ${s.availableModelsSuffix}`}function se(t){return t?t.alias||t.id:"—"}function le(t,s){if(!t.models.length)return s.noModel;const n=t.selectedModel?t.models.find(m=>m.id===t.selectedModel):t.models[0];return se(n)}function Se(t,s=4){const n=new Set;return t.models.map(u=>({key:u.id,label:se(u)})).filter(u=>n.has(u.key)?!1:(n.add(u.key),!0)).slice(0,s)}function ee(t,s){t({defaultAgent:s.defaultAgent,agents:s.agents})}function te(t,s){return{agent:t?.agent||s,model:t?.selectedModel||"",effort:t?.selectedEffort||""}}function G({label:t,value:s,hint:n,loading:m=!1}){return e.jsxs("div",{className:"rounded-lg border border-edge bg-panel-alt px-3.5 py-2.5",children:[e.jsx("div",{className:"text-[10px] font-semibold uppercase tracking-[0.14em] text-fg-5",children:t}),e.jsxs("div",{className:"mt-1 flex items-center gap-2 text-[13px] font-semibold text-fg-2",children:[m&&e.jsx(q,{className:"h-3.5 w-3.5"}),e.jsx("span",{children:s})]}),n&&e.jsx("div",{className:"mt-0.5 text-[10px] leading-relaxed text-fg-5",children:n})]})}function we({agent:t,copy:s,t:n,installing:m,onInstall:u,updatingAgent:o,checkingAgent:d,onUpdate:A,onCheckUpdate:U,loading:c=!1}){const E=R(t.agent),V=Ee(t,s),O=le(t,s),j=E.advantageKey?n(E.advantageKey):"—",D=Se(t),F=Math.max(0,t.models.length-D.length),_=t.selectedEffort||s.noEffort,S=t.version||s.noVersion,N=c?n("status.loading"):t.installed?s.installed:s.notInstalled,i=c?"muted":t.installed?"ok":"warn",w=c?n("status.loading"):t.installed?s.readyHint:s.installHint,C=c?n("status.loading"):O,g=c?n("status.loading"):_,p=c?n("status.loading"):j,h=c?n("status.loading"):V;return e.jsx("div",{className:"glass rounded-md border border-edge px-4 py-3 shadow-[0_1px_0_rgba(255,255,255,0.02),0_4px_12px_rgba(15,23,42,0.05)]",children:e.jsxs("div",{className:"grid gap-x-5 gap-y-3 xl:grid-cols-[220px_130px_220px_minmax(0,1fr)_auto] xl:items-start",children:[e.jsx("div",{className:"min-w-0",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-md border border-edge bg-panel-alt",children:e.jsx(he,{brand:t.agent,size:22})}),e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"text-[15px] font-semibold text-fg",children:E.label}),t.isDefault&&e.jsx(Y,{variant:"accent",children:s.defaultBadge})]}),e.jsxs("div",{className:"mt-1 text-[12px] leading-relaxed text-fg-5",children:[s.version,": ",S,t.latestVersion&&t.updateAvailable&&e.jsxs("span",{className:"ml-1.5 text-amber-400",children:["→ ",t.latestVersion]}),t.latestVersion&&!t.updateAvailable&&t.installed&&e.jsx("span",{className:"ml-1.5 text-emerald-400",children:"✓"})]})]})]})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-[10px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:s.status}),e.jsx("div",{className:"mt-1.5",children:e.jsxs(Y,{variant:i,children:[c&&e.jsx(q,{className:"h-3 w-3"}),N]})}),e.jsx("div",{className:"mt-1.5 text-[12px] leading-relaxed text-fg-5",children:w})]}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-[10px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:s.currentConfig}),e.jsxs("div",{className:"mt-1.5 space-y-1.5 text-[13px] leading-relaxed text-fg-3",children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{className:"w-16 shrink-0 text-fg-5",children:s.model}),e.jsx("span",{className:"min-w-0 break-words text-fg-2",children:C})]}),e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{className:"w-16 shrink-0 text-fg-5",children:s.effort}),e.jsx("span",{className:"text-fg-2",children:g})]})]})]}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-[10px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:s.recommendedFor}),e.jsx("div",{className:"mt-1.5 text-[13px] leading-relaxed text-fg-3",children:p}),e.jsx("div",{className:"mt-2.5 text-[10px] font-semibold uppercase tracking-[0.16em] text-fg-5",children:s.availableModels}),e.jsxs("div",{className:"mt-1.5 flex flex-wrap items-center gap-1.5",children:[!c&&D.length>0?D.map(v=>e.jsx("span",{className:"inline-flex h-6 max-w-full items-center rounded-md border border-edge bg-panel-alt px-2 text-[11px] text-fg-3",title:v.key,children:e.jsx("span",{className:"truncate",children:v.label})},v.key)):e.jsx("span",{className:"text-[12px] text-fg-5",children:c?n("status.loading"):s.noModel}),!c&&F>0&&e.jsx("span",{className:"inline-flex h-6 items-center rounded-md border border-edge bg-panel-alt px-2 text-[11px] text-fg-5",children:s.moreModels(F)})]}),e.jsx("div",{className:"mt-1.5 text-[12px] leading-relaxed text-fg-5",children:h})]}),e.jsxs("div",{className:pe("flex flex-col items-start gap-1.5 xl:items-end",t.installed&&"xl:self-start"),children:[c&&e.jsxs("div",{className:"inline-flex h-7 items-center gap-2 rounded-md border border-edge bg-transparent px-2.5 text-[11px] text-fg-5",children:[e.jsx(q,{className:"h-3 w-3"}),n("status.loading")]}),!c&&!t.installed&&e.jsx(y,{variant:"outline",size:"sm",disabled:m,onClick:()=>u(t),children:m?s.installing:s.install}),!c&&t.installed&&t.updateAvailable&&e.jsx(y,{variant:"primary",size:"sm",disabled:o,onClick:()=>A(t),children:o?s.updating:s.update}),!c&&t.installed&&!t.updateAvailable&&e.jsx(y,{variant:"ghost",size:"sm",disabled:d,onClick:()=>U(t),children:d?s.checking:s.checkUpdate}),!c&&t.installed&&t.updateAvailable&&t.updateStatus==="skipped"&&t.updateDetail&&e.jsxs("div",{className:"text-[11px] leading-relaxed text-amber-400",children:[s.updateSkipped,": ",t.updateDetail]}),!c&&t.installed&&t.updateStatus==="failed"&&t.updateDetail&&e.jsxs("div",{className:"text-[11px] leading-relaxed text-red-400",children:[s.updateFailed,": ",t.updateDetail]})]})]})})}function Ve(){const t=I(l=>l.locale),s=I(l=>l.toast),n=I(l=>l.agentStatus),m=I(l=>l.setAgentStatus),u=I(l=>l.refreshAgentStatus),o=r.useMemo(()=>xe(t),[t]),d=Ne(t),[A,U]=r.useState(n?{defaultAgent:n.defaultAgent,agents:n.agents}:null),[c,E]=r.useState(!n),[V,O]=r.useState(null),[j,D]=r.useState(!1),[F,_]=r.useState(null),[S,N]=r.useState(!1),[i,w]=r.useState({agent:"codex",model:"",effort:""}),C=r.useRef(!!n);r.useEffect(()=>{n&&(ee(U,n),C.current||(C.current=!0,E(!1)))},[n]);const g=r.useCallback(l=>{ee(U,l),m(l)},[m]),p=r.useCallback(async()=>{C.current||E(!0);try{const l=await H.getAgentStatus();return g(l),O(null),C.current=!0,l}catch(l){const a=l instanceof Error?l.message:d.loadFailed;return O(a),C.current||s(a,!1),null}finally{E(!1)}},[g,d.loadFailed,s]);r.useEffect(()=>{n?u():p()},[]);const h=r.useMemo(()=>{const l=A?.agents||[],a=new Map(l.map(f=>[f.agent,f]));return je.map(f=>{const T=a.get(f);if(T)return T;const b=R(f);return{agent:f,label:b.label,installed:!1,version:void 0,installCommand:void 0,selectedModel:null,selectedEffort:null,isDefault:A?.defaultAgent===f,models:[],usage:null}})},[A]),v=A?.defaultAgent||"codex",M=h.find(l=>l.agent===v)||null,J=h.filter(l=>l.installed).length>0,ae=Me(h,d),x=h.find(l=>l.agent===i.agent)||null,L=ke(x),$=Ae(x),Q=r.useCallback(async l=>{D(!0);try{const a=await H.updateRuntimeAgent(l);if(!a.ok)throw new Error(a.error||o("config.applyFailed"));return g(a),a}catch(a){const f=a instanceof Error?a.message:o("config.applyFailed");return s(f,!1),p(),null}finally{D(!1)}},[g,p,o,s]);r.useEffect(()=>{S&&w(te(M,v))},[v,M,S]),r.useEffect(()=>{if(!S||!x)return;const l=x.selectedModel||"",a=!i.model||L.some(b=>b.value===i.model),f=x.selectedEffort||"",T=!i.effort||$.some(b=>b.value===i.effort);a&&T||w(b=>({...b,model:a?b.model:l,effort:T?b.effort:f}))},[S,i.effort,i.model,x,$,L]);const ne=r.useCallback(l=>{const a=h.find(f=>f.agent===l);a?.installed&&w(te(a,a.agent))},[h]),de=r.useCallback(async()=>{if(!x?.installed)return;const l={};if(i.agent!==v&&(l.defaultAgent=i.agent),i.model&&i.model!==(x.selectedModel||"")&&(l.agent=i.agent,l.model=i.model),i.effort&&i.effort!==(x.selectedEffort||"")&&(l.agent=i.agent,l.effort=i.effort),Object.keys(l).length===0){N(!1);return}await Q(l)&&(s(d.defaultsSaved),N(!1))},[d.defaultsSaved,v,i.agent,i.effort,i.model,x,s,Q]),ie=r.useCallback(async l=>{if(!F){_(l.agent);try{const a=await H.installAgent(l.agent);if(!a.ok)throw new Error(a.error||o("config.agentInstallFailed"));g(a),s(o("config.agentInstalled"))}catch(a){const f=a instanceof Error?a.message:o("config.agentInstallFailed");s(f,!1),p()}finally{_(a=>a===l.agent?null:a)}}},[g,F,p,o,s]),[B,W]=r.useState(null),[z,X]=r.useState(null),re=r.useCallback(async l=>{if(!B){W(l.agent);try{const a=await H.updateAgent(l.agent);if(!a.ok)throw new Error(a.error||o("config.agentInstallFailed"));g(a),s(d.upToDate)}catch(a){const f=a instanceof Error?a.message:d.updateFailed;s(f,!1),p()}finally{W(a=>a===l.agent?null:a)}}},[g,d.updateFailed,d.upToDate,p,o,s,B]),oe=r.useCallback(async l=>{if(!z){X(l.agent);try{const a=await H.checkAgentUpdate(l.agent);if(!a.ok)throw new Error(a.error||d.loadFailed);g(a)}catch(a){const f=a instanceof Error?a.message:d.loadFailed;s(f,!1),p()}finally{X(a=>a===l.agent?null:a)}}},[g,z,d.loadFailed,p,s]),k=c&&!A,ce=k?o("status.loading"):M?R(M.agent).label:d.notInstalled,fe=k?o("status.loading"):M?.installed?d.installed:d.notInstalled,ue=k?o("status.loading"):M?le(M,d):d.noModel,me=k?o("status.loading"):M?.selectedEffort||d.noEffort;return e.jsxs("div",{className:"animate-in space-y-4",children:[e.jsx("section",{className:"space-y-3",children:e.jsxs(Z,{className:"space-y-3",children:[e.jsxs("div",{className:"flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-base font-semibold tracking-tight text-fg",children:d.defaultsTitle}),e.jsx("div",{className:"mt-0.5 text-[13px] leading-relaxed text-fg-4",children:d.defaultsHint})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx(y,{variant:"secondary",onClick:()=>N(!0),disabled:j||!J,children:d.editDefaults})})]}),e.jsxs("div",{className:"grid gap-2.5 lg:grid-cols-3",children:[e.jsx(G,{label:d.defaultAgent,value:ce,hint:fe,loading:k}),e.jsx(G,{label:d.defaultModel,value:ue,loading:k}),e.jsx(G,{label:d.defaultEffort,value:me,loading:k})]})]})}),e.jsxs("section",{className:"space-y-3",children:[e.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-[0.18em] text-fg-5",children:d.agentsTitle}),e.jsx("div",{className:"space-y-3",children:h.map(l=>e.jsx(we,{agent:l,copy:d,t:o,installing:F===l.agent,loading:k,onInstall:ie,updatingAgent:B===l.agent,checkingAgent:z===l.agent,onUpdate:re,onCheckUpdate:oe},l.agent))})]}),V&&e.jsx(Z,{className:"border-amber-500/20 bg-amber-500/5",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{className:"text-[13px] text-fg-2",children:V}),e.jsx(y,{variant:"outline",size:"sm",onClick:()=>{p()},children:o("sessions.retry")})]})}),e.jsxs(ve,{open:S,onClose:()=>N(!1),children:[e.jsx(be,{title:d.defaultsEditTitle,description:d.defaultsEditHint,onClose:()=>N(!1)}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(P,{children:d.defaultAgent}),e.jsx(K,{value:i.agent,options:ae,onChange:ne,disabled:j||!J,placeholder:d.notInstalled})]}),e.jsxs("div",{children:[e.jsx(P,{children:d.defaultModel}),e.jsx(K,{value:i.model,options:L,onChange:l=>w(a=>({...a,model:l})),disabled:j||!x?.installed||L.length===0,placeholder:d.noModel})]}),e.jsxs("div",{children:[e.jsx(P,{children:d.defaultEffort}),e.jsx(K,{value:i.effort,options:$,onChange:l=>w(a=>({...a,effort:l})),disabled:j||!x?.installed||$.length===0,placeholder:d.noEffort})]})]}),e.jsxs("div",{className:"mt-6 flex justify-end gap-2",children:[e.jsx(y,{variant:"ghost",onClick:()=>N(!1),children:o("modal.cancel")}),e.jsx(y,{variant:"primary",disabled:j||!x?.installed,onClick:()=>{de()},children:o(j?"config.validating":"modal.save")})]})]})]})}export{Ve as AgentTab,Ve as default};
|