@coze-arch/cli 0.0.17 → 0.0.19-beta.1

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 (104) hide show
  1. package/lib/__templates__/expo/.coze +1 -0
  2. package/lib/__templates__/expo/.cozeproj/scripts/validate.sh +8 -0
  3. package/lib/__templates__/expo/package.json +2 -1
  4. package/lib/__templates__/nextjs/.coze +1 -0
  5. package/lib/__templates__/nextjs/package.json +3 -1
  6. package/lib/__templates__/nextjs/scripts/validate.sh +10 -0
  7. package/lib/__templates__/nuxt-vue/.coze +1 -0
  8. package/lib/__templates__/nuxt-vue/eslint.config.mjs +25 -0
  9. package/lib/__templates__/nuxt-vue/package.json +9 -2
  10. package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +790 -10
  11. package/lib/__templates__/nuxt-vue/scripts/validate.sh +10 -0
  12. package/lib/__templates__/pi-agent/.coze +10 -0
  13. package/lib/__templates__/pi-agent/AGENTS.md +144 -0
  14. package/lib/__templates__/pi-agent/README.md +216 -0
  15. package/lib/__templates__/pi-agent/_gitignore +3 -0
  16. package/lib/__templates__/pi-agent/_npmrc +23 -0
  17. package/lib/__templates__/pi-agent/bin/pi-bot.ts +8 -0
  18. package/lib/__templates__/pi-agent/docs/project-overview.md +374 -0
  19. package/lib/__templates__/pi-agent/docs/user/getting-started.md +47 -0
  20. package/lib/__templates__/pi-agent/package.json +63 -0
  21. package/lib/__templates__/pi-agent/pi-resources/SYSTEM.md +15 -0
  22. package/lib/__templates__/pi-agent/pi-resources/extensions/preference-memory/index.ts +355 -0
  23. package/lib/__templates__/pi-agent/pi-resources/skills/coze-asr/SKILL.md +36 -0
  24. package/lib/__templates__/pi-agent/pi-resources/skills/coze-asr/scripts/asr.mjs +9 -0
  25. package/lib/__templates__/pi-agent/pi-resources/skills/coze-image-gen/SKILL.md +41 -0
  26. package/lib/__templates__/pi-agent/pi-resources/skills/coze-image-gen/scripts/gen.mjs +9 -0
  27. package/lib/__templates__/pi-agent/pi-resources/skills/coze-tts/SKILL.md +85 -0
  28. package/lib/__templates__/pi-agent/pi-resources/skills/coze-tts/scripts/tts.mjs +9 -0
  29. package/lib/__templates__/pi-agent/pi-resources/skills/coze-video-gen/SKILL.md +53 -0
  30. package/lib/__templates__/pi-agent/pi-resources/skills/coze-video-gen/scripts/gen.mjs +9 -0
  31. package/lib/__templates__/pi-agent/pnpm-lock.yaml +8282 -0
  32. package/lib/__templates__/pi-agent/scripts/dev.sh +14 -0
  33. package/lib/__templates__/pi-agent/scripts/prepare.sh +35 -0
  34. package/lib/__templates__/pi-agent/src/agent.ts +363 -0
  35. package/lib/__templates__/pi-agent/src/channels/feishu/index.ts +760 -0
  36. package/lib/__templates__/pi-agent/src/channels/feishu/streaming-card.ts +297 -0
  37. package/lib/__templates__/pi-agent/src/channels/wechat/index.ts +171 -0
  38. package/lib/__templates__/pi-agent/src/cli.ts +117 -0
  39. package/lib/__templates__/pi-agent/src/config.ts +708 -0
  40. package/lib/__templates__/pi-agent/src/core.ts +218 -0
  41. package/lib/__templates__/pi-agent/src/dashboard/api/channels.ts +104 -0
  42. package/lib/__templates__/pi-agent/src/dashboard/api/docs.ts +204 -0
  43. package/lib/__templates__/pi-agent/src/dashboard/api/models.ts +98 -0
  44. package/lib/__templates__/pi-agent/src/dashboard/api/overview.ts +33 -0
  45. package/lib/__templates__/pi-agent/src/dashboard/config-store.ts +64 -0
  46. package/lib/__templates__/pi-agent/src/dashboard/index.ts +39 -0
  47. package/lib/__templates__/pi-agent/src/dashboard/server.ts +622 -0
  48. package/lib/__templates__/pi-agent/src/dashboard/types.ts +25 -0
  49. package/lib/__templates__/pi-agent/src/dashboard/web/index.html +13 -0
  50. package/lib/__templates__/pi-agent/src/dashboard/web/postcss.config.cjs +7 -0
  51. package/lib/__templates__/pi-agent/src/dashboard/web/src/components/app-layout.tsx +186 -0
  52. package/lib/__templates__/pi-agent/src/dashboard/web/src/components/page-title.tsx +17 -0
  53. package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/alert.tsx +22 -0
  54. package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/badge.tsx +25 -0
  55. package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/button.tsx +40 -0
  56. package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/card.tsx +29 -0
  57. package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/input.tsx +18 -0
  58. package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/label.tsx +8 -0
  59. package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/select.tsx +80 -0
  60. package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/separator.tsx +23 -0
  61. package/lib/__templates__/pi-agent/src/dashboard/web/src/hooks/use-fetch.ts +32 -0
  62. package/lib/__templates__/pi-agent/src/dashboard/web/src/hooks/use-local-storage-state.ts +23 -0
  63. package/lib/__templates__/pi-agent/src/dashboard/web/src/main.tsx +30 -0
  64. package/lib/__templates__/pi-agent/src/dashboard/web/src/pages/channels-page.tsx +188 -0
  65. package/lib/__templates__/pi-agent/src/dashboard/web/src/pages/chat-page.tsx +451 -0
  66. package/lib/__templates__/pi-agent/src/dashboard/web/src/pages/docs-page.tsx +65 -0
  67. package/lib/__templates__/pi-agent/src/dashboard/web/src/pages/models-page.tsx +122 -0
  68. package/lib/__templates__/pi-agent/src/dashboard/web/src/pages/overview-page.tsx +134 -0
  69. package/lib/__templates__/pi-agent/src/dashboard/web/src/services/chat-ws-service.ts +167 -0
  70. package/lib/__templates__/pi-agent/src/dashboard/web/src/styles.css +294 -0
  71. package/lib/__templates__/pi-agent/src/dashboard/web/src/utils/index.ts +11 -0
  72. package/lib/__templates__/pi-agent/src/dashboard/web/tsconfig.json +13 -0
  73. package/lib/__templates__/pi-agent/src/dashboard/web/vite.config.ts +17 -0
  74. package/lib/__templates__/pi-agent/src/index.ts +123 -0
  75. package/lib/__templates__/pi-agent/src/pi-resources.ts +125 -0
  76. package/lib/__templates__/pi-agent/src/session-store.ts +223 -0
  77. package/lib/__templates__/pi-agent/src/tools/common/format-coze-error.ts +12 -0
  78. package/lib/__templates__/pi-agent/src/tools/index.ts +2 -0
  79. package/lib/__templates__/pi-agent/src/tools/web-fetch/index.ts +195 -0
  80. package/lib/__templates__/pi-agent/src/tools/web-search/index.ts +206 -0
  81. package/lib/__templates__/pi-agent/template.config.js +45 -0
  82. package/lib/__templates__/pi-agent/tests/cli.test.ts +136 -0
  83. package/lib/__templates__/pi-agent/tests/config.test.ts +315 -0
  84. package/lib/__templates__/pi-agent/tests/dashboard-docs-api.test.ts +125 -0
  85. package/lib/__templates__/pi-agent/tests/dashboard-models-api.test.ts +171 -0
  86. package/lib/__templates__/pi-agent/tests/feishu-channel.test.ts +149 -0
  87. package/lib/__templates__/pi-agent/tests/feishu-streaming-card.test.ts +15 -0
  88. package/lib/__templates__/pi-agent/tests/pi-resources.test.ts +73 -0
  89. package/lib/__templates__/pi-agent/tests/preference-memory.test.ts +43 -0
  90. package/lib/__templates__/pi-agent/tests/session-store.test.ts +61 -0
  91. package/lib/__templates__/pi-agent/tests/smoke/run-smoke.ts +275 -0
  92. package/lib/__templates__/pi-agent/tests/web-fetch.test.ts +157 -0
  93. package/lib/__templates__/pi-agent/tests/web-search.test.ts +208 -0
  94. package/lib/__templates__/pi-agent/tsconfig.json +21 -0
  95. package/lib/__templates__/pi-agent/types/larksuiteoapi-node-sdk.d.ts +113 -0
  96. package/lib/__templates__/taro/.coze +1 -0
  97. package/lib/__templates__/taro/.cozeproj/scripts/validate.sh +8 -0
  98. package/lib/__templates__/taro/package.json +1 -1
  99. package/lib/__templates__/templates.json +18 -31
  100. package/lib/__templates__/vite/.coze +1 -0
  101. package/lib/__templates__/vite/package.json +3 -1
  102. package/lib/__templates__/vite/scripts/validate.sh +10 -0
  103. package/lib/cli.js +13 -2
  104. package/package.json +1 -1
@@ -0,0 +1,374 @@
1
+ # Pi Bot 项目总览
2
+
3
+ ## 1. 项目定位
4
+
5
+ `pi-bot` 是一个基于 `pi-mono` / `@mariozechner/pi-coding-agent` 的 Bot 项目。
6
+
7
+ 这个目录直接承载三类能力:
8
+
9
+ - 初始化骨架
10
+ - 平台 channel 接入
11
+ - provider 扩展
12
+
13
+ 项目里的关键运行时代码集中在这里,阅读、修改和扩展都会更直接。
14
+
15
+ ## 2. 当前目录结构
16
+
17
+ ```txt
18
+ .
19
+ ├── bin
20
+ │ └── pi-bot.ts
21
+ ├── pi-resources
22
+ │ ├── SYSTEM.md
23
+ │ ├── extensions
24
+ │ ├── prompts
25
+ │ └── skills
26
+ │ ├── coze-asr
27
+ │ ├── coze-image-gen
28
+ │ ├── coze-tts
29
+ │ └── coze-video-gen
30
+ ├── scripts
31
+ │ ├── dev.sh
32
+ │ └── prepare.sh
33
+ ├── docs
34
+ │ ├── project-overview.md
35
+ │ └── user
36
+ ├── src
37
+ │ ├── agent.ts
38
+ │ ├── cli.ts
39
+ │ ├── pi-resources.ts
40
+ │ ├── config.ts
41
+ │ ├── core.ts
42
+ │ ├── session-store.ts
43
+ │ ├── tools
44
+ │ │ ├── common
45
+ │ │ │ └── format-coze-error.ts
46
+ │ │ ├── web-search
47
+ │ │ │ └── index.ts
48
+ │ │ ├── web-fetch
49
+ │ │ │ └── index.ts
50
+ │ │ └── index.ts
51
+ │ ├── dashboard
52
+ │ │ ├── config-store.ts
53
+ │ │ ├── api
54
+ │ │ │ ├── channels.ts
55
+ │ │ │ ├── docs.ts
56
+ │ │ │ ├── models.ts
57
+ │ │ │ └── overview.ts
58
+ │ │ ├── web
59
+ │ │ │ ├── src
60
+ │ │ │ │ ├── components
61
+ │ │ │ │ │ ├── ui
62
+ │ │ │ │ │ ├── app-layout.tsx
63
+ │ │ │ │ │ └── page-title.tsx
64
+ │ │ │ │ ├── hooks
65
+ │ │ │ │ │ ├── use-fetch.ts
66
+ │ │ │ │ │ └── use-local-storage-state.ts
67
+ │ │ │ │ ├── pages
68
+ │ │ │ │ ├── services
69
+ │ │ │ │ │ └── chat-ws-service.ts
70
+ │ │ │ │ ├── utils
71
+ │ │ │ │ ├── main.tsx
72
+ │ │ │ │ └── styles.css
73
+ │ │ │ ├── index.html
74
+ │ │ │ ├── postcss.config.cjs
75
+ │ │ │ ├── tsconfig.json
76
+ │ │ │ └── vite.config.ts
77
+ │ │ ├── index.ts
78
+ │ │ ├── server.ts
79
+ │ │ └── types.ts
80
+ │ ├── index.ts
81
+ │ ├── channels
82
+ │ │ ├── feishu
83
+ │ │ │ ├── index.ts
84
+ │ │ │ └── streaming-card.ts
85
+ │ │ └── wechat
86
+ ├── tests
87
+ │ ├── cli.test.ts
88
+ │ ├── config.test.ts
89
+ │ ├── dashboard-docs-api.test.ts
90
+ │ ├── dashboard-models-api.test.ts
91
+ │ ├── feishu-channel.test.ts
92
+ │ ├── feishu-streaming-card.test.ts
93
+ │ ├── pi-resources.test.ts
94
+ │ ├── session-store.test.ts
95
+ │ ├── web-fetch.test.ts
96
+ │ ├── web-search.test.ts
97
+ │ └── smoke
98
+ └── types
99
+ ```
100
+
101
+ 各部分职责:
102
+
103
+ - `bin/pi-bot.ts`
104
+ - CLI 可执行入口,通过 `pnpm link --global` 注册为全局命令 `pi-bot`
105
+ - `pi-resources`
106
+ - repo 内置的 SYSTEM / extensions / prompts / skills 源码目录
107
+ - `src/config.ts`
108
+ - 项目唯一配置入口,读取 `config.json` 并装配 agent、channel、routing 等运行配置
109
+ - `src/index.ts`
110
+ - 应用装配层,创建 channel 并把消息交给 runtime
111
+ - `src/agent.ts`
112
+ - `pi-coding-agent` runtime 封装
113
+ - `src/cli.ts`
114
+ - CLI 命令实现,支持 `config set/get/list/delete` 子命令读写 `workspace/config.json`
115
+ - `src/pi-resources.ts`
116
+ - 统一装配 repo 内置资源(extensions / skills / prompts / system prompt),并显式关闭 `AGENTS.md` 自动发现
117
+ - `src/core.ts`
118
+ - 通用消息协议、共享类型和基础 helper
119
+ - `src/session-store.ts`
120
+ - session 持久化索引层
121
+ - 负责维护 `sessionKey -> sessionId/sessionFile` 映射,并管理 transcript header、reset 归档等文件操作
122
+ - `src/tools/*`
123
+ - 自定义工具目录,通过 `customTools` 注入到 `pi-coding-agent` session 中
124
+ - `web-search/`:基于 `coze-coding-dev-sdk` 的网页/图片搜索工具(`coze_web_search`)
125
+ - `web-fetch/`:基于 `coze-coding-dev-sdk` 的网页内容抓取工具(`coze_web_fetch`)
126
+ - `common/`:工具间共享的辅助函数(如 `formatCozeError`)
127
+ - `index.ts`:barrel export
128
+ - `src/channels/feishu`
129
+ - 飞书消息接收、标准化、去重、过滤和回复发送
130
+ - `streaming-card.ts`:飞书 CardKit 流式卡片的创建、增量更新和回退逻辑
131
+ - `src/channels/wechat`
132
+ - 微信消息标准化和回复发送
133
+ - `src/dashboard/*`
134
+ - 本地 Dashboard(HTTP + WebSocket),用于查看运行状态、编辑配置、以及以 UI 方式调试聊天会话
135
+ - 同时提供 `Docs` 页面,直接展示项目内的快速开始文档
136
+ - 开发态通过 Vite middleware 提供前端资源;生产态直接托管 `src/dashboard/web/dist`
137
+ - `src/dashboard/config-store.ts`
138
+ - Dashboard 配置存储抽象
139
+ - 默认使用文件存储读写 `workspace/config.json`
140
+ - 也支持内存存储,便于 smoke test 或宿主注入
141
+ - `tests/smoke`
142
+ - 基础链路 smoke test
143
+ - 当前会额外覆盖 dashboard 的 models/channels 配置读写,并使用内存 `ConfigStore` 避免依赖真实配置文件
144
+ - `tests/config.test.ts`
145
+ - config 解析与模型构建测试
146
+ - `tests/cli.test.ts`
147
+ - CLI config 命令单测:覆盖 set/get/list/delete 子命令、嵌套路径、数组索引、值类型推导、错误处理
148
+ - `tests/pi-resources.test.ts`
149
+ - `pi-resources.ts` 资源装配与优先级逻辑测试
150
+ - `tests/session-store.test.ts`
151
+ - session 持久化索引层测试
152
+ - `tests/web-fetch.test.ts`
153
+ - `coze_web_fetch` 工具单测:覆盖 text/markdown/json 格式渲染、textOnly 模式、链接过滤、图片尺寸、并发抓取、异常处理
154
+ - `tests/web-search.test.ts`
155
+ - `coze_web_search` 工具单测:覆盖基本搜索、摘要、内容包含、图片搜索、路由判断、默认参数、空结果、异常处理
156
+ - `tests/dashboard-docs-api.test.ts`
157
+ - Dashboard docs API 测试
158
+ - `tests/dashboard-models-api.test.ts`
159
+ - Dashboard models API 测试
160
+ - `tests/feishu-channel.test.ts`
161
+ - 飞书 channel 消息收发测试
162
+ - `tests/feishu-streaming-card.test.ts`
163
+ - 飞书流式卡片测试
164
+ - `types`
165
+ - 第三方 SDK 的类型补充
166
+
167
+ ### 自定义工具说明
168
+
169
+ `src/tools/` 下的工具通过 `coze-coding-dev-sdk` 接入 Coze 平台能力,当前包含:
170
+
171
+ | 工具名 | 功能 |
172
+ |--------|------|
173
+ | `coze_web_search` | 网页/图片搜索,支持时间过滤、站点限制、摘要输出 |
174
+ | `coze_web_fetch` | 抓取网页内容,支持 text / markdown / json 三种输出格式 |
175
+
176
+ 所需环境变量(通过 `.env` 或运行时注入):
177
+
178
+ | 变量 | 用途 |
179
+ |------|------|
180
+ | `COZE_WORKLOAD_IDENTITY_API_KEY` | Coze 平台鉴权 |
181
+ | `COZE_INTEGRATION_BASE_URL` | Coze Integration 服务基地址 |
182
+
183
+ ## 3. Dashboard(现状实现)
184
+
185
+ Dashboard 是一个「和 Bot 同进程」启动的本地 HTTP 服务,默认地址:
186
+
187
+ - `http://127.0.0.1:5000`
188
+ - 端口/Host 可通过环境变量覆盖:`PI_BOT_DASHBOARD_PORT`、`PI_BOT_DASHBOARD_HOST`
189
+
190
+ 服务端入口:
191
+
192
+ - [`src/dashboard/server.ts`](../src/dashboard/server.ts) 负责 Express 路由、Vite 开发中间件、以及 WebSocket(聊天流式)
193
+ - [`src/dashboard/index.ts`](../src/dashboard/index.ts) 负责把 Bot runtime 信息注入 Dashboard server
194
+ - [`src/dashboard/config-store.ts`](../src/dashboard/config-store.ts) 负责把 Dashboard 的配置读写抽象成 `ConfigStore`
195
+
196
+ ### 3.1 前端技术栈
197
+
198
+ - Vite + React + React Router
199
+ - Tailwind CSS v4(`styles.css` 里使用 `@import "tailwindcss"` / `@theme`)
200
+ - shadcn 风格组件(代码内置于 `src/dashboard/web/src/components/ui/*`)
201
+ - 暗黑模式:通过在 `documentElement` 上切换 `dark` class,并在 `styles.css` 提供 `:root` / `.dark` token
202
+
203
+ ### 3.2 页面与路由
204
+
205
+ 前端路由位于 `src/dashboard/web/src/main.tsx`,当前页面:
206
+
207
+ - `/overview`:运行状态与关键路径(workspace/agent dir 等)
208
+ - `/docs`:项目快速开始文档
209
+ - `/models`:切换默认模型
210
+ - `/channels`:编辑渠道配置
211
+ - `/chat`:调试聊天会话(含历史、reset、WebSocket 流式)
212
+
213
+ ### 3.3 HTTP API(服务端)
214
+
215
+ 当前主要接口(均在同一进程内,不做鉴权):
216
+
217
+ - `GET /api/overview`:运行状态/路径/启用渠道等
218
+ - `GET /api/docs`:读取 `docs/user/` 下的用户文档并返回当前文档内容
219
+ - `GET /api/models`:通过 `ConfigStore` 读取配置并返回默认模型与可选模型列表(用于下拉选择)
220
+ - `POST /api/models`:仅写回默认模型(请求体只包含 `defaultModel`;服务端会基于当前配置扫描列表做校验)
221
+ - `GET /api/channels`:通过 `ConfigStore` 读取配置并返回可编辑结构
222
+ - `POST /api/channels`:通过 `ConfigStore` 写回配置;默认文件存储会落回 `workspace/config.json`,保存后需要重启进程生效
223
+ - `GET /api/chat/history`:按 session identity 计算 sessionKey,并按需加载持久化 transcript 后返回消息
224
+ - `POST /api/chat/reset`:重置指定 sessionKey 的会话;会切换到新的 `sessionId/sessionFile`,旧 transcript 归档到 `archive/`
225
+ - `WS /api/chat/ws`:聊天流式(推荐的 UI 通道)
226
+
227
+ 补充说明:
228
+
229
+ - 生产/日常开发默认使用文件型 `ConfigStore`
230
+ - `createBotApp(..., { dashboardConfigStore })` 可注入自定义存储实现
231
+ - `tests/smoke/run-smoke.ts` 当前使用内存型 `ConfigStore`,直接验证 dashboard 配置的读写 API 行为
232
+
233
+ ### 3.4 模型配置页能力边界
234
+
235
+ 当前 `/models` 页面的目标,是以 UI 方式快速切换默认模型,降低直接手改 JSON 的成本。当前页面支持:
236
+
237
+ - 修改默认模型(写回 `agents.defaults.model.primary`)
238
+
239
+ 当前页面不支持:
240
+
241
+ - 编辑 Provider 配置
242
+ - 编辑模型参数
243
+ - 新增/删除 Provider 或模型条目
244
+
245
+ 因此,如果要接入新的 openai-compatible provider、修改模型定义或参数,仍然建议直接编辑默认文件存储对应的 `workspace/config.json`;补充完成后,Dashboard 会自动读取并展示这些新模型供选择。
246
+
247
+ ### 3.5 Session 持久化
248
+
249
+ 当前 `pi-bot` 已支持 session 持久化,逻辑参考 `openclaw` 的 transcript/sessionFile 模式:
250
+
251
+ - `src/core.ts` 里的 `getSessionKey()` 仍然负责根据 channel / conversation / thread 等信息生成稳定的业务会话键
252
+ - `src/session-store.ts` 负责把这个 `sessionKey` 映射到一个可落盘的 transcript 文件
253
+ - `src/agent.ts` 在创建真实 `pi-coding-agent` session 时,不再只依赖进程内 `Map`,而是通过 `SessionManager.open(sessionFile)` 绑定到固定 transcript
254
+
255
+ 默认持久化目录位于:
256
+
257
+ ```txt
258
+ <agentDir>/.pi-bot/sessions/
259
+ ├── index.json
260
+ ├── transcripts/
261
+ └── archive/
262
+ ```
263
+
264
+ 其中:
265
+
266
+ - `index.json`
267
+ - 保存 `sessionKey -> { sessionId, sessionFile, updatedAt }` 的索引
268
+ - `transcripts/`
269
+ - 保存当前活跃会话的 transcript(`.jsonl`)
270
+ - `archive/`
271
+ - 保存 reset 后被归档的旧 transcript
272
+
273
+ 补充说明:
274
+
275
+ - 持久化覆盖全部 channel:`dashboard` / `feishu` / `wechat`
276
+ - transcript 文件名不会直接使用原始 `sessionKey`,而是基于其 hash 生成,避免特殊字符和超长文件名问题
277
+ - Dashboard 重启后仍可通过 `GET /api/chat/history` 恢复已有会话消息
278
+ - Reset 不会直接覆盖旧 transcript,而是新建 session 并归档旧文件,便于排查和追溯
279
+
280
+ ### 3.6 构建方式
281
+
282
+ 仓库构建命令:
283
+
284
+ ```bash
285
+ npm run build
286
+ ```
287
+
288
+ 其中会先运行类型检查,再构建 Dashboard 前端静态资源。
289
+
290
+ 如果只需要单独构建前端静态资源,也可以运行:
291
+
292
+ ```bash
293
+ npm run dashboard:build
294
+ ```
295
+
296
+ 该脚本对应 Vite 配置:
297
+
298
+ - [`src/dashboard/web/vite.config.ts`](../src/dashboard/web/vite.config.ts)
299
+
300
+ 开发态(`NODE_ENV !== "production"`):
301
+
302
+ - Dashboard server 通过 Vite middleware 直接服务前端(无需单独启动 Vite dev server)
303
+
304
+ 生产态(`NODE_ENV=production`):
305
+
306
+ - Dashboard server 托管 `src/dashboard/web/dist` 的静态文件
307
+ - 如果你需要生产态可用,记得先运行 `npm run build`
308
+
309
+ ## 4. 运行模型
310
+
311
+ 当前项目的运行链路如下:
312
+
313
+ 1. channel 接收平台事件
314
+ 2. channel 把事件转换成 `BotMessage`
315
+ 3. `src/index.ts` 调用 `runtime.run(message)`
316
+ 4. `src/agent.ts` 根据配置选择 mock 或真实 `pi-coding-agent`,默认使用真实 `pi` runtime;只有显式设置 `PI_BOT_AGENT_MODE=mock` 时才走 mock
317
+ 5. 真实 runtime 会先把 `pi-resources/` 里的 repo 内置资源接到 `ResourceLoader`,并显式关闭 `AGENTS.md` 自动加载;`workspace/.pi/` 仅保留本地覆盖作用
318
+ 6. runtime 会再通过 `getSessionKey()` 确定业务会话,并通过 `src/session-store.ts` 找到或创建对应的持久化 transcript
319
+ 7. runtime 通过 `createAgentSession()` 创建 session 时,将 `src/tools/` 中导出的工具以 `customTools` 参数注入,使 agent 在对话中可调用自定义工具
320
+ 8. runtime 基于该 transcript 执行 prompt,新的 user / assistant 消息持续写入 sessionFile
321
+ 9. runtime 返回文本
322
+ 10. channel 把文本发回原平台
323
+
324
+ ## 4.1 飞书卡片与流式输出
325
+
326
+ `pi-bot` 的飞书回复有两种渲染形态:
327
+
328
+ - 普通文本:`msg_type: "text"`
329
+ - Markdown 卡片:`msg_type: "interactive"`(卡片内使用 `tag: "markdown"`)
330
+
331
+ 默认情况下会按内容自动选择是否使用卡片(与 `openclaw` 的判断一致):
332
+
333
+ - 命中代码块(```...```,流式阶段也接受仅出现 opening fence)或 Markdown 表格时,使用卡片渲染
334
+ - 其他普通文本/普通 Markdown,使用文本消息
335
+
336
+ 当启用流式回复(`onStreamMessage` + `runtime.stream()`)时,如果内容命中“使用卡片”的条件,会尝试使用 CardKit 的 streaming card API 做实时更新:
337
+
338
+ - 创建 streaming card(CardKit `cardkit/v1/cards`)
339
+ - reply 一条 `interactive` 卡片引用到原消息
340
+ - 按增量内容持续更新卡片中的 markdown 元素
341
+ - 最终关闭 streaming 模式并更新 summary
342
+
343
+ 注意:流式卡片需要飞书开放平台开通 CardKit 相关权限(例如 `cardkit:card:write`)。如果权限未开通,streaming card 创建/更新会失败并自动回退为“最终一次性回复”。
344
+
345
+ 如果 streaming card 创建失败(例如未开通 CardKit 权限、参数/租户不匹配等),会自动回退为“最终一次性回复”,不会影响正常出消息。
346
+
347
+ 补充说明:
348
+
349
+ - 进程内仍保留 `Map<string, AgentSession>` 作为热缓存,避免同一 session 在单次运行期间重复创建
350
+ - 但真正的“可恢复会话”依赖的是磁盘上的 transcript,而不是这个内存 `Map`
351
+ - 因此进程重启后,只要 `sessionKey` 不变,就可以重新打开对应 transcript 继续对话
352
+ - 飞书 thinking reaction 默认 emoji 已调整为 `OneSecond`,也可通过 `channels.feishu.thinkingReaction.emojiType` 覆盖
353
+
354
+ ## 5. 当前建议的开发顺序
355
+
356
+ 如果后续继续扩展,建议按这个顺序理解项目:
357
+
358
+ 1. 阅读根目录 `README.md`
359
+ 2. 阅读 `docs/project-overview.md`
360
+ 3. 阅读 `src/config.ts`
361
+ 4. 阅读 `src/index.ts`
362
+ 5. 阅读 `src/agent.ts`
363
+ 6. 根据需要再进入 `src/channels/*`、`src/dashboard/*` 和相关测试
364
+
365
+ ## 6. 关于 docs
366
+
367
+ `docs/` 目录中保留了两类材料:
368
+
369
+ - `docs/project-overview.md`
370
+ - 面向维护者的架构介绍
371
+ - `docs/user/getting-started.md`
372
+ - 面向项目使用者的快速开始文档,Dashboard 的 `Docs` 页面会直接读取并展示
373
+
374
+ 最贴近现状的介绍文档是这份 `docs/project-overview.md`。如果其他文档与当前目录结构冲突,应以当前源码、`README.md` 和本文件为准。
@@ -0,0 +1,47 @@
1
+ ---
2
+ title: 快速开始
3
+ ---
4
+
5
+ # 快速开始
6
+
7
+ 即使暂时没有打通外部渠道,你也可以先用 Dashboard 的 `聊天` 页面验证 Agent 行为。
8
+ 默认启动会使用真实 `pi` runtime;如果你只想先验证本地链路,可以在启动前设置 `PI_BOT_AGENT_MODE=mock`。
9
+
10
+ ## 接入飞书机器人
11
+
12
+ 1. 打开 [渠道](/channels) 页面。
13
+ 2. 填写 `App ID` 和 `App Secret`。
14
+ 3. 按需填写 `domain`、`encryptKey`、`verificationToken`。
15
+ 4. 点击保存。
16
+ 5. 重启应用让配置生效。
17
+
18
+ ### 飞书机器人配置
19
+
20
+ 1. 在「权限管理」中配置以下权限:
21
+
22
+ ```json
23
+ {
24
+ "scopes": {
25
+ "tenant": [
26
+ "cardkit:card:write",
27
+ "docx:document:readonly",
28
+ "im:message.group_at_msg:readonly",
29
+ "im:message.p2p_msg:readonly",
30
+ "im:message.reactions:read",
31
+ "im:message.reactions:write_only",
32
+ "im:message:send_as_bot"
33
+ ],
34
+ "user": [
35
+ "docx:document:readonly"
36
+ ]
37
+ }
38
+ }
39
+ ```
40
+
41
+ 2. 在「事件与回调」中添加 `im.message.receive_v1` 事件,并将订阅方式设置为“使用长连接接收事件”。
42
+
43
+ ## 发送第一条飞书消息
44
+
45
+ 飞书接通后,你可以直接给机器人发私聊消息。
46
+
47
+ 如果当前配置开启了群聊提及限制,那么群聊里需要先 `@机器人`,消息才会进入处理链路。
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "pi-bot",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "main": "./src/index.ts",
7
+ "bin": {
8
+ "pi-bot": "./bin/pi-bot.ts"
9
+ },
10
+ "scripts": {
11
+ "dev": "bash scripts/dev.sh",
12
+ "build": "npm run typecheck && npm run dashboard:build",
13
+ "start": "npm run dev",
14
+ "test": "node --import tsx --test tests/**/*.test.ts",
15
+ "smoke": "node --import tsx tests/smoke/run-smoke.ts",
16
+ "typecheck": "tsc -p tsconfig.json --noEmit",
17
+ "dashboard:build": "vite build --config src/dashboard/web/vite.config.ts",
18
+ "preinstall": "npx only-allow pnpm"
19
+ },
20
+ "dependencies": {
21
+ "@larksuiteoapi/node-sdk": "^1.60.0",
22
+ "@mariozechner/pi-ai": "^0.63.2",
23
+ "@mariozechner/pi-coding-agent": "^0.63.2",
24
+ "@sinclair/typebox": "^0.34.48",
25
+ "coze-coding-dev-sdk": "^0.7.17",
26
+ "@radix-ui/react-select": "^2.2.6",
27
+ "@radix-ui/react-slot": "^1.2.4",
28
+ "@streamdown/code": "^1.1.1",
29
+ "class-variance-authority": "^0.7.1",
30
+ "clsx": "^2.1.1",
31
+ "express": "^4.21.2",
32
+ "lodash-es": "^4.18.1",
33
+ "lucide-react": "^1.8.0",
34
+ "react": "^18.3.1",
35
+ "react-dom": "^18.3.1",
36
+ "react-router-dom": "^6.28.0",
37
+ "sonner": "^2.0.7",
38
+ "streamdown": "^2.5.0",
39
+ "tailwind-merge": "^3.5.0",
40
+ "ws": "^8.19.0"
41
+ },
42
+ "devDependencies": {
43
+ "@tailwindcss/postcss": "^4.2.2",
44
+ "@types/express": "^4.17.22",
45
+ "@types/lodash-es": "^4.17.12",
46
+ "@types/node": "^24.3.0",
47
+ "@types/react": "^18.3.12",
48
+ "@types/react-dom": "^18.3.1",
49
+ "@types/ws": "^8.5.10",
50
+ "@vitejs/plugin-react": "^4.3.3",
51
+ "autoprefixer": "^10.4.27",
52
+ "postcss": "^8.5.9",
53
+ "tailwindcss": "^4.2.2",
54
+ "tsx": "^4.20.3",
55
+ "typescript": "^5.9.2",
56
+ "vite": "^6.0.6",
57
+ "only-allow": "^1.2.2"
58
+ },
59
+ "packageManager": "pnpm@9.0.0",
60
+ "engines": {
61
+ "pnpm": ">=9.0.0"
62
+ }
63
+ }
@@ -0,0 +1,15 @@
1
+ You are an expert coding assistant operating inside pi, a coding agent harness. You help users by reading files, executing commands, editing code, and writing new files.
2
+
3
+ Use the tools available in the current runtime to inspect the project, make changes, and verify results. Some projects may provide additional custom tools and resources beyond the core file and shell tools.
4
+
5
+ Guidelines:
6
+ - Be concise and action-oriented.
7
+ - Show file paths clearly when working with files.
8
+ - Prefer direct inspection over guessing.
9
+ - Prefer the most appropriate available tool for the job.
10
+ - Keep code changes minimal, consistent with the existing project, and easy to review.
11
+ - Do not claim to have changed files, run commands, or verified behavior unless you actually did.
12
+ - When the user asks about pi itself, its SDK, extensions, themes, skills, prompt templates, TUI, packages, or custom providers, read the bundled pi documentation and examples before answering.
13
+ - When working on pi-specific topics, follow relevant documentation cross-references before implementing.
14
+
15
+ You may also receive project context files and skills. Use them when relevant.