pikiclaw 0.3.28 → 0.3.30

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.
Files changed (41) hide show
  1. package/README.md +191 -152
  2. package/dashboard/dist/assets/{AgentTab-CtNbvg2T.js → AgentTab-CZD5gpYM.js} +1 -1
  3. package/dashboard/dist/assets/{BrandIcon-C-aE815y.js → BrandIcon-OQPfo-1d.js} +1 -1
  4. package/dashboard/dist/assets/{DirBrowser-vJss0x7d.js → DirBrowser-Cwjw5lcv.js} +1 -1
  5. package/dashboard/dist/assets/ExtensionsTab-BeYRY7w2.js +1 -0
  6. package/dashboard/dist/assets/{IMAccessTab-emw5qxk1.js → IMAccessTab-CI6pHR4T.js} +1 -1
  7. package/dashboard/dist/assets/{Modal-BLxBTu-V.js → Modal-BjmWI4rV.js} +1 -1
  8. package/dashboard/dist/assets/{Modals-B3HtmZgm.js → Modals-oCEkl5bg.js} +1 -1
  9. package/dashboard/dist/assets/{PermissionsTab-BfewCKoC.js → PermissionsTab-BCIWbHZ8.js} +1 -1
  10. package/dashboard/dist/assets/{Select-CrXZymnB.js → Select-DVfNRUsp.js} +1 -1
  11. package/dashboard/dist/assets/SessionPanel-QofmyhAM.js +1 -0
  12. package/dashboard/dist/assets/{SystemTab-iLxOYtia.js → SystemTab-D1pVZ7QQ.js} +1 -1
  13. package/dashboard/dist/assets/index-BK0TrLhz.css +1 -0
  14. package/dashboard/dist/assets/index-DiokcHDO.js +16 -0
  15. package/dashboard/dist/assets/index-REYJ4IMp.js +3 -0
  16. package/dashboard/dist/assets/{shared-BSx12aDa.js → shared-BCJjyDlo.js} +1 -1
  17. package/dashboard/dist/index.html +2 -2
  18. package/dist/agent/drivers/claude.js +286 -16
  19. package/dist/agent/drivers/gemini.js +146 -2
  20. package/dist/agent/mcp/extensions.js +24 -0
  21. package/dist/agent/stream.js +2 -0
  22. package/dist/agent/utils.js +4 -1
  23. package/dist/bot/bot.js +100 -13
  24. package/dist/bot/session-hub.js +50 -5
  25. package/dist/catalog/skill-repos.js +95 -56
  26. package/dist/channels/feishu/bot.js +1 -1
  27. package/dist/channels/telegram/bot.js +1 -1
  28. package/dist/channels/weixin/bot.js +1 -1
  29. package/dist/cli/main.js +11 -14
  30. package/dist/core/config/runtime-config.js +9 -4
  31. package/dist/core/config/user-config.js +3 -4
  32. package/dist/core/constants.js +1 -1
  33. package/dist/dashboard/routes/agents.js +40 -2
  34. package/dist/dashboard/routes/extensions.js +78 -8
  35. package/dist/dashboard/runtime.js +1 -3
  36. package/package.json +1 -1
  37. package/dashboard/dist/assets/ExtensionsTab-BIJUhVs_.js +0 -1
  38. package/dashboard/dist/assets/SessionPanel-D5onHBIe.js +0 -1
  39. package/dashboard/dist/assets/index-9UgAKpbU.css +0 -1
  40. package/dashboard/dist/assets/index-BOjiS988.js +0 -16
  41. package/dashboard/dist/assets/index-xNJkl-jN.js +0 -3
package/README.md CHANGED
@@ -2,202 +2,235 @@
2
2
 
3
3
  # pikiclaw
4
4
 
5
- **Put the world's smartest AI agents in your pocket. Command local Claude, Codex & Gemini via IM.**
5
+ ## Put the world's smartest AI agents in your pocket.
6
6
 
7
- *Turn Telegram, Feishu, or WeChat into a full-featured Agent console on your computer*
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="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
16
- <a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node.js-18+-green.svg" alt="Node.js 18+"></a>
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="700">
23
+ <img src="docs/workspace.png" alt="Workspace" width="780">
20
24
 
21
25
  </div>
22
26
 
23
- ## Demo
27
+ ---
24
28
 
25
- > Real task: ask pikiclaw to gather and summarize today's AI news — the agent reads, writes, and sends results back through Telegram, all from your phone.
29
+ ## What is pikiclaw?
26
30
 
27
- <img src="docs/promo-demo.gif" alt="Demo" width="700">
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
- > Basic operations: send a message, watch the agent stream, receive files back.
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
- <img src="docs/promo-basic-ops.gif" alt="Basic operations" width="700">
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
- > Web Dashboard: multi-panel workspace with session list, conversation view, tool-use traces, and input composer (1 / 2 / 3 / 6 pane layouts).
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
- <img src="docs/promo-dashboard-workspace.png" alt="Workspace" width="700">
59
+ ---
36
60
 
37
- <details>
38
- <summary>More dashboard pages</summary>
61
+ ## Built with itself
39
62
 
40
- **IM Access** Telegram, Feishu, WeChat channel status and configuration
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
- <img src="docs/promo-dashboard-im.png" alt="IM Access" width="700">
65
+ A typical day-of-development inside pikiclaw:
43
66
 
44
- **Agent Config** Default agent / model / reasoning effort, available agents overview
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
- <img src="docs/promo-dashboard-agents.png" alt="Agent Config" width="700">
73
+ The orchestrator is the product. It also happens to be the IDE the orchestrator is built in.
47
74
 
48
- **System Permissions** — macOS accessibility, screen recording, disk access
75
+ ---
49
76
 
50
- <img src="docs/promo-dashboard-permissions.png" alt="Permissions" width="700">
77
+ ## A swarm by default
51
78
 
52
- **Extensions** Global MCP servers, community skills, and built-in browser & desktop automation
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
- <img src="docs/promo-dashboard-extensions.png" alt="Extensions" width="700">
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
- **System Info** Working directory, CPU / memory / disk monitoring
87
+ This is the shape that matters: one creator, with a swarm at their fingertips.
57
88
 
58
- <img src="docs/promo-dashboard-system.png" alt="System Info" width="700">
89
+ ---
59
90
 
60
- </details>
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
- ## Why pikiclaw?
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
- Most "IM + Agent" solutions either reinvent the agent (worse than official CLIs), run in remote sandboxes (not your environment), or only support short conversations (unusable for real tasks).
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
- pikiclaw takes a different approach:
99
+ <p align="center"><img src="docs/promo-dashboard-workspace.png" alt="Web Dashboard workspace" width="780"></p>
69
100
 
70
- - **Official Agent CLIs** — Claude Code, Codex, Gemini CLI as-is, not a home-grown wrapper
71
- - **Your own machine** local files, local tools, local environment
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
- You (Telegram / Feishu / WeChat)
77
- |
78
- v
79
- pikiclaw <-- MCP servers & community skills
80
- |
81
- v
82
- Claude Code / Codex / Gemini CLI
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
- It's designed for the moment you walk away from your desk — the agent keeps working locally, and you stay in control from your phone.
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 Start
132
+ ## Quick start
93
133
 
94
- ### Prerequisites
134
+ **Prereqs:** Node.js 18+, plus at least one official Agent CLI logged in:
95
135
 
96
- - Node.js 18+
97
- - At least one Agent CLI installed and logged in:
98
- - [`claude`](https://docs.anthropic.com/en/docs/claude-code) (Claude Code)
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
- ### Install & Launch
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="Quick install" width="700">
147
+ <p align="center"><img src="docs/promo-install.gif" alt="One-command install" width="780"></p>
111
148
 
112
- This opens the **Web Dashboard** at `http://localhost:3939`, where you can:
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>Alternative: terminal setup wizard</summary>
152
+ <summary><b>Prefer the terminal? There's a wizard.</b></summary>
123
153
 
124
154
  ```bash
125
- npx pikiclaw@latest --setup # interactive terminal wizard
126
- npx pikiclaw@latest --doctor # check environment only
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
- ## Features
163
+ ## What people do with it
134
164
 
135
- ### Channels & Agents
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
- - Telegram, Feishu, and WeChat — run one or all simultaneously
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
- **MCP Servers** — browse recommended servers, search the [MCP Registry](https://registry.modelcontextprotocol.io), or add custom servers (stdio / HTTP):
176
+ ## Features
146
177
 
147
- <img src="docs/promo-dashboard-extensions-add.png" alt="Add MCP Server" width="700">
178
+ ### Terminal layer
148
179
 
149
- **Project Extensions** — each workspace has its own MCP servers (`.mcp.json`) and skills (`.pikiclaw/skills/`), managed from the workspace sidebar:
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
- <img src="docs/promo-workspace-extensions.png" alt="Project Extensions" width="700">
184
+ ### Agent layer
152
185
 
153
- - Browse recommended servers (GitHub, Filesystem, PostgreSQL, Slack, Brave Search, Memory, Fetch, SQLite, Git, Sentry)
154
- - Search the MCP Registry for community servers
155
- - Add custom servers with environment variable configuration
156
- - Health check with MCP protocol handshake and tool discovery
157
- - Enable / disable individual servers per scope
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
- **Community Skills**
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
- All extensions are merged with priority (global < workspace < built-in) and injected into agent sessions automatically.
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
- ### Skills
198
+ ### Tool layer
169
199
 
170
- - Project-level skills at `.pikiclaw/skills/*/SKILL.md`
171
- - Compatible with `.claude/commands/*.md`
172
- - Legacy `.claude/skills` / `.agents/skills` support with migration path
173
- - Install from GitHub or browse recommended repos via the dashboard
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
- ### Runtime
205
+ <p align="center"><img src="docs/promo-dashboard-extensions-add.png" alt="Add MCP server" width="780"></p>
177
206
 
178
- - Streaming preview with continuous message updates
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
- ### MCP Bridge & Automation
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
- Each agent stream launches a session-scoped MCP bridge that injects tools from three sources:
217
+ ---
191
218
 
192
- 1. **Built-in tools** `im_list_files`, `im_send_file` (send files back to IM in real time)
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
- ### Codex Human Loop
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
- When Codex requests additional user input mid-task, pikiclaw surfaces the question as an interactive prompt in your IM. Reply there and the task continues.
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` | Show entry info, current agent, working directory |
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 messages are forwarded directly to the current agent.
255
+ Plain text is forwarded to the current agent.
223
256
 
224
257
  ---
225
258
 
226
259
  ## Configuration
227
260
 
228
- - Persistent config lives in `~/.pikiclaw/setting.json`
229
- - The Dashboard is the primary configuration interface
230
- - Global MCP extensions are stored in `~/.pikiclaw/setting.json` under `extensions.mcp`
231
- - Workspace MCP extensions use the standard `.mcp.json` format
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 automation** is managed by the dashboard — a dedicated Chrome profile is created and reused automatically. Log in to the sites you need once in that browser and every future agent session can reuse those credentials.
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 automation** requires Appium Mac2:
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
- Relevant environment variables:
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
- - **ACP (Agent Client Protocol) adoption** — unified driver for any ACP-compatible agent, replacing per-agent CLI output parsing. See [ACP Migration Plan](docs/acp-migration.md)
259
- - Expand extension ecosystemmore recommended MCP servers, skill templates, and community tooling
260
- - Improve GUI automation, especially browser + desktop tool coordination
261
- - More IM channels (WhatsApp, etc.)
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 # local dev (--no-daemon, logs to ~/.pikiclaw/dev/dev.log)
277
- npm run build # production build
278
- npm test # unit tests
279
- npm run test:e2e # end-to-end tests
280
- npx pikiclaw@latest --doctor # environment check
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
- See also: [ARCHITECTURE.md](ARCHITECTURE.md) · [INTEGRATION.md](INTEGRATION.md) · [TESTING.md](TESTING.md)
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
- Contributions are welcome! Whether it's a bug fix, new feature, or documentation improvementwe appreciate your help.
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
- - Check out [`good first issue`](https://github.com/xiaotonng/pikiclaw/labels/good%20first%20issue) and [`help wanted`](https://github.com/xiaotonng/pikiclaw/labels/help%20wanted) labels for contribution ideas
293
- - Open an issue first for larger changes so we can discuss the approach
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
- Common contribution areas:
337
+ ## Star history
296
338
 
297
- | Task | Where to start |
298
- |------|----------------|
299
- | Add an agent driver | `src/agent/driver.ts`, `src/agent/drivers/*.ts` |
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-xNJkl-jN.js";import{B as he}from"./BrandIcon-C-aE815y.js";import{M as ve,a as be,L as P}from"./Modal-BLxBTu-V.js";import{S as K}from"./Select-CrXZymnB.js";import{S as Z}from"./shared-BSx12aDa.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-REYJ4IMp.js";import{B as he}from"./BrandIcon-OQPfo-1d.js";import{M as ve,a as be,L as P}from"./Modal-BjmWI4rV.js";import{S as K}from"./Select-DVfNRUsp.js";import{S as Z}from"./shared-BCJjyDlo.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};