@aweeclaw/scenario-cli 1.0.0

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 ADDED
@@ -0,0 +1,488 @@
1
+ # @aweeclaw/scenario-cli
2
+
3
+ AweeClaw 场景开发 CLI 工具,用于初始化、构建、打包和校验 AweeClaw 场景包。
4
+
5
+ 场景开发者使用此工具将 TypeScript + React 代码预编译为 ESM Bundle,客户端运行时动态加载。共享依赖(React、zustand、lucide-react 等)由宿主应用注入,无需打包进场景包。
6
+
7
+ ## 安装
8
+
9
+ ```bash
10
+ # 全局安装
11
+ npm install -g @aweeclaw/scenario-cli
12
+
13
+ # 或使用 npx(无需安装)
14
+ npx @aweeclaw/scenario-cli init my-scenario
15
+ ```
16
+
17
+ 要求 Node.js >= 18.0.0。
18
+
19
+ ## 快速开始
20
+
21
+ ```bash
22
+ # 1. 初始化场景项目
23
+ npx aweeclaw-scenario init my-scenario --name-zh "我的场景" --category development
24
+
25
+ # 2. 进入项目并安装依赖
26
+ cd my-scenario
27
+ npm install
28
+
29
+ # 3. 启动开发服务器
30
+ npx aweeclaw-scenario dev
31
+
32
+ # 4. 构建场景包
33
+ npx aweeclaw-scenario build
34
+
35
+ # 5. 校验构建产物
36
+ npx aweeclaw-scenario validate
37
+
38
+ # 6. 打包为 tar.gz
39
+ npx aweeclaw-scenario pack
40
+ # → my-scenario-1.0.0.tar.gz
41
+ ```
42
+
43
+ ## 命令详解
44
+
45
+ ### `init` — 初始化场景项目
46
+
47
+ 创建场景脚手架,生成 `scenario.json`、TypeScript 配置、入口文件和组件模板。
48
+
49
+ ```bash
50
+ aweeclaw-scenario init <name> [options]
51
+ ```
52
+
53
+ **参数:**
54
+
55
+ | 参数 | 说明 |
56
+ |------|------|
57
+ | `<name>` | 场景名称,自动转为小写 kebab-case 作为 ID |
58
+
59
+ **选项:**
60
+
61
+ | 选项 | 默认值 | 说明 |
62
+ |------|--------|------|
63
+ | `--name-zh <nameZh>` | 同 name | 场景中文名称 |
64
+ | `--category <category>` | `custom` | 场景分类 |
65
+ | `--type <type>` | `programmatic` | 场景类型:`declarative` 或 `programmatic` |
66
+ | `--author <author>` | `unknown` | 作者名称 |
67
+
68
+ **分类可选值:** `productivity`、`development`、`education`、`business`、`creative`、`data`、`health`、`finance`、`legal`、`custom`
69
+
70
+ **示例:**
71
+
72
+ ```bash
73
+ # 编程式场景(默认)
74
+ aweeclaw-scenario init code-reviewer --name-zh "代码审查" --category development --author "zhangsan"
75
+
76
+ # 声明式场景
77
+ aweeclaw-scenario init legal-advisor --name-zh "法律顾问" --type declarative --category legal
78
+ ```
79
+
80
+ ---
81
+
82
+ ### `build` — 构建场景包
83
+
84
+ 编程式场景使用 Vite 构建 ESM Bundle,声明式场景直接复制文件。构建产物输出到 `dist/` 目录。
85
+
86
+ ```bash
87
+ aweeclaw-scenario build [options]
88
+ ```
89
+
90
+ **选项:**
91
+
92
+ | 选项 | 默认值 | 说明 |
93
+ |------|--------|------|
94
+ | `--out-dir <dir>` | `dist` | 输出目录 |
95
+ | `--minify` | `false` | 压缩输出 |
96
+ | `--no-sourcemap` | 启用 | 禁用 sourcemap |
97
+
98
+ **构建产物结构(编程式):**
99
+
100
+ ```
101
+ dist/
102
+ ├── manifest.json # 包清单(含 checksum)
103
+ ├── config/
104
+ │ └── scenario.json # 场景配置
105
+ ├── bundle/
106
+ │ ├── index.js # ESM 主入口
107
+ │ ├── DashboardPanel.js # 组件 chunk(按需加载)
108
+ │ ├── index.js.map # Sourcemap
109
+ │ └── *.css # 样式文件
110
+ ├── prompts/
111
+ │ └── system.md
112
+ └── assets/ # 静态资源(如有)
113
+ ```
114
+
115
+ **构建产物结构(声明式):**
116
+
117
+ ```
118
+ dist/
119
+ ├── manifest.json
120
+ ├── config/
121
+ │ └── scenario.json
122
+ ├── prompts/
123
+ │ ├── system.md
124
+ │ └── workflow.md
125
+ ├── scripts/
126
+ │ ├── onActivate.js
127
+ │ └── onDeactivate.js
128
+ └── assets/
129
+ ```
130
+
131
+ ---
132
+
133
+ ### `pack` — 打包发布
134
+
135
+ 将 `dist/` 目录打包为 `{id}-{version}.tar.gz`,用于上传到场景市场。
136
+
137
+ ```bash
138
+ aweeclaw-scenario pack [options]
139
+ ```
140
+
141
+ **选项:**
142
+
143
+ | 选项 | 默认值 | 说明 |
144
+ |------|--------|------|
145
+ | `--out-dir <dir>` | `.` | tar.gz 输出目录 |
146
+
147
+ 打包前会自动更新 `manifest.json` 中的 checksum。
148
+
149
+ **示例:**
150
+
151
+ ```bash
152
+ aweeclaw-scenario pack
153
+ # → my-scenario-1.0.0.tar.gz
154
+
155
+ aweeclaw-scenario pack --out-dir ./releases
156
+ # → releases/my-scenario-1.0.0.tar.gz
157
+ ```
158
+
159
+ ---
160
+
161
+ ### `dev` — 本地开发
162
+
163
+ 启动 Vite 开发服务器,支持热更新。
164
+
165
+ ```bash
166
+ aweeclaw-scenario dev [options]
167
+ ```
168
+
169
+ **选项:**
170
+
171
+ | 选项 | 默认值 | 说明 |
172
+ |------|--------|------|
173
+ | `--port <port>` | `3210` | 开发服务器端口 |
174
+
175
+ 声明式场景无需开发服务器,会提示直接编辑文件。
176
+
177
+ ---
178
+
179
+ ### `validate` — 校验场景包
180
+
181
+ 校验 `dist/` 目录中的构建产物,检查完整性和正确性。
182
+
183
+ ```bash
184
+ aweeclaw-scenario validate [options]
185
+ ```
186
+
187
+ **选项:**
188
+
189
+ | 选项 | 默认值 | 说明 |
190
+ |------|--------|------|
191
+ | `--strict` | `false` | 启用严格校验模式 |
192
+
193
+ **校验项:**
194
+
195
+ - `scenario.json` 格式和字段校验(Zod Schema)
196
+ - `manifest.json` 完整性
197
+ - 编程式场景的 `bundle/index.js` 是否存在
198
+ - 共享依赖是否正确外部化
199
+ - 声明式场景的文件引用完整性(identity / database / scripts)
200
+ - SHA-256 checksum 是否匹配
201
+ - 包大小是否超过 50 MB 限制
202
+
203
+ 严格模式下会额外检查 `__AWEECLAW_SHARED__` 引用。
204
+
205
+ ---
206
+
207
+ ## scenario.json 配置说明
208
+
209
+ 场景的核心配置文件,位于项目根目录。
210
+
211
+ ### 编程式场景配置
212
+
213
+ ```json
214
+ {
215
+ "id": "my-scenario",
216
+ "version": "1.0.0",
217
+ "name": "My Scenario",
218
+ "nameZh": "我的场景",
219
+ "description": "A brief description",
220
+ "descriptionZh": "简要描述",
221
+ "author": "author-name",
222
+ "icon": "Package",
223
+ "category": "development",
224
+ "tags": ["code", "review"],
225
+ "license": "MIT",
226
+ "type": "programmatic",
227
+ "entryPoint": "src/index.ts",
228
+ "permissions": [],
229
+ "sharedDeps": {
230
+ "react": "^18.3.0",
231
+ "react-dom": "^18.3.0",
232
+ "zustand": "^5.0.0",
233
+ "lucide-react": "^0.562.0"
234
+ },
235
+ "dependencies": []
236
+ }
237
+ ```
238
+
239
+ ### 声明式场景配置
240
+
241
+ ```json
242
+ {
243
+ "id": "travel-planner",
244
+ "version": "1.0.0",
245
+ "name": "Travel Planner",
246
+ "nameZh": "旅行规划师",
247
+ "description": "AI travel planning assistant",
248
+ "descriptionZh": "AI 旅行规划助手",
249
+ "author": "aweeclaw",
250
+ "icon": "Plane",
251
+ "category": "productivity",
252
+ "tags": ["travel", "planning"],
253
+ "type": "declarative",
254
+ "identity": {
255
+ "systemPromptFile": "prompts/system.md",
256
+ "workflowFile": "prompts/workflow.md"
257
+ },
258
+ "capabilities": {
259
+ "builtinTools": ["web_search", "ask_user", "remember"],
260
+ "customTools": [
261
+ {
262
+ "name": "search_flights",
263
+ "description": "Search for flights",
264
+ "parameters": {
265
+ "origin": { "type": "string", "description": "Departure city", "required": true },
266
+ "destination": { "type": "string", "description": "Arrival city", "required": true }
267
+ },
268
+ "executor": "web_search",
269
+ "template": "search flights from {origin} to {destination}"
270
+ }
271
+ ]
272
+ },
273
+ "ui": {
274
+ "layout": "chat-centric"
275
+ },
276
+ "database": {
277
+ "installScriptFiles": ["db/install.sql"],
278
+ "uninstallScriptFiles": ["db/uninstall.sql"]
279
+ },
280
+ "scripts": {
281
+ "onActivateFile": "scripts/onActivate.js",
282
+ "onDeactivateFile": "scripts/onDeactivate.js"
283
+ }
284
+ }
285
+ ```
286
+
287
+ ### 字段说明
288
+
289
+ | 字段 | 类型 | 必填 | 说明 |
290
+ |------|------|------|------|
291
+ | `id` | `string` | ✅ | 场景唯一标识,小写字母数字+连字符 |
292
+ | `version` | `string` | ✅ | 语义化版本号(如 `1.0.0`) |
293
+ | `name` | `string` | ✅ | 英文名称 |
294
+ | `nameZh` | `string` | ✅ | 中文名称 |
295
+ | `description` | `string` | | 英文描述 |
296
+ | `descriptionZh` | `string` | | 中文描述 |
297
+ | `author` | `string` | | 作者 |
298
+ | `icon` | `string` | | 图标名称(lucide-react 图标) |
299
+ | `category` | `enum` | | 分类 |
300
+ | `tags` | `string[]` | | 标签 |
301
+ | `license` | `string` | | 开源协议 |
302
+ | `type` | `enum` | ✅ | `declarative` 或 `programmatic` |
303
+ | `entryPoint` | `string` | | 编程式场景入口文件 |
304
+ | `permissions` | `string[]` | | 所需权限声明 |
305
+ | `sharedDeps` | `object` | | 编程式场景共享依赖及版本要求 |
306
+ | `dependencies` | `array` | | 场景间依赖 |
307
+ | `identity` | `object` | | 声明式场景身份配置 |
308
+ | `capabilities` | `object` | | 声明式场景能力声明 |
309
+ | `ui` | `object` | | 声明式场景 UI 配置 |
310
+ | `database` | `object` | | 声明式场景数据库脚本 |
311
+ | `scripts` | `object` | | 声明式场景生命周期脚本 |
312
+
313
+ ### category 可选值
314
+
315
+ | 值 | 说明 |
316
+ |----|------|
317
+ | `productivity` | 生产力 |
318
+ | `development` | 开发工具 |
319
+ | `education` | 教育 |
320
+ | `business` | 商业 |
321
+ | `creative` | 创意 |
322
+ | `data` | 数据 |
323
+ | `health` | 健康 |
324
+ | `finance` | 金融 |
325
+ | `legal` | 法律 |
326
+ | `custom` | 自定义 |
327
+
328
+ ---
329
+
330
+ ## 两种场景模式
331
+
332
+ ### 编程式(Programmatic)
333
+
334
+ 使用 TypeScript + React 开发,支持自定义 UI 组件、完整 JS 逻辑。构建时通过 Vite 编译为 ESM Bundle。
335
+
336
+ **适用场景:** 需要自定义面板、复杂交互、数据可视化等
337
+
338
+ **项目结构:**
339
+
340
+ ```
341
+ my-scenario/
342
+ ├── scenario.json
343
+ ├── package.json
344
+ ├── tsconfig.json
345
+ ├── src/
346
+ │ ├── index.ts # 入口,导出 ScenarioModule
347
+ │ └── components/
348
+ │ └── DashboardPanel.tsx
349
+ ├── prompts/
350
+ │ └── system.md
351
+ └── assets/
352
+ ```
353
+
354
+ **入口文件模板:**
355
+
356
+ ```typescript
357
+ import type { ScenarioModule, ScenarioModuleContext } from '@aweeclaw/scenario-sdk'
358
+ import { DashboardPanel } from './components/DashboardPanel.js'
359
+
360
+ export default {
361
+ id: 'my-scenario',
362
+ version: '1.0.0',
363
+
364
+ getManifest() { /* ... */ },
365
+ getPlugin() { /* ... */ },
366
+
367
+ getTools() { return [] },
368
+ getComponents() { return { DashboardPanel } },
369
+
370
+ async onActivate(context: ScenarioModuleContext) {
371
+ context.publishData('scenario:activated', { scenarioId: 'my-scenario' })
372
+ },
373
+ async onDeactivate(context: ScenarioModuleContext) {
374
+ context.publishData('scenario:deactivated', { scenarioId: 'my-scenario' })
375
+ },
376
+ } satisfies ScenarioModule
377
+ ```
378
+
379
+ ### 声明式(Declarative)
380
+
381
+ 使用 JSON 配置 + Markdown 提示词 + 沙箱脚本,无需编译。
382
+
383
+ **适用场景:** 简单对话场景、提示词模板、无自定义 UI
384
+
385
+ **项目结构:**
386
+
387
+ ```
388
+ my-scenario/
389
+ ├── scenario.json
390
+ ├── package.json
391
+ ├── prompts/
392
+ │ ├── system.md
393
+ │ └── workflow.md
394
+ ├── scripts/
395
+ │ ├── onActivate.js
396
+ │ └── onDeactivate.js
397
+ ├── db/
398
+ │ ├── install.sql
399
+ │ └── uninstall.sql
400
+ └── assets/
401
+ ```
402
+
403
+ ---
404
+
405
+ ## 共享依赖机制
406
+
407
+ 编程式场景的 React、zustand、lucide-react 等依赖**不打包**进场景包,而是由宿主应用通过全局变量 `__AWEECLAW_SHARED__` 注入。
408
+
409
+ **构建时行为:**
410
+
411
+ - 这些依赖被标记为 `external`,不会打包进 bundle
412
+ - import 语句被重写为全局变量引用(如 `react` → `__AWEECLAW_SHARED__.modules.react`)
413
+
414
+ **运行时行为:**
415
+
416
+ - 宿主应用启动时注入共享依赖到 `window.__AWEECLAW_SHARED__`
417
+ - 场景加载时直接从全局变量获取,避免版本冲突和 React hooks 崩溃
418
+
419
+ **当前共享依赖版本:**
420
+
421
+ | 依赖 | 版本 |
422
+ |------|------|
423
+ | react | ^18.3.0 |
424
+ | react-dom | ^18.3.0 |
425
+ | react/jsx-runtime | ^18.3.0 |
426
+ | zustand | ^5.0.0 |
427
+ | lucide-react | ^0.562.0 |
428
+
429
+ ---
430
+
431
+ ## 开发指南
432
+
433
+ ### 本地开发
434
+
435
+ ```bash
436
+ # 克隆仓库
437
+ git clone <repo-url>
438
+ cd aweeclaw-scenario-cli
439
+
440
+ # 安装依赖
441
+ npm install
442
+
443
+ # 构建
444
+ npm run build
445
+
446
+ # 开发模式(监听文件变化)
447
+ npm run dev
448
+
449
+ # 测试 CLI
450
+ node dist/bin.js --help
451
+ ```
452
+
453
+ ### 发布
454
+
455
+ ```bash
456
+ npm run build
457
+ npm publish --access public
458
+ ```
459
+
460
+ ---
461
+
462
+ ## 常见问题
463
+
464
+ ### Q: 场景中如何使用 React hooks?
465
+
466
+ 场景使用宿主应用提供的 React 实例,hooks 调用与宿主应用在同一上下文,不会出现 "Invalid hook call" 错误。只需正常编写 React 组件即可。
467
+
468
+ ### Q: 场景可以使用哪些 UI 库?
469
+
470
+ 场景可以使用宿主应用提供的共享依赖(React、zustand、lucide-react)。其他 UI 库需要自行打包进场景包,但需注意体积控制(建议 < 50 MB)。
471
+
472
+ ### Q: 如何调试场景?
473
+
474
+ 1. 使用 `aweeclaw-scenario dev` 启动本地开发服务器
475
+ 2. 在宿主应用中通过本地路径加载场景
476
+ 3. 使用浏览器 DevTools 调试
477
+
478
+ ### Q: 编程式和声明式如何选择?
479
+
480
+ - 需要自定义 UI 面板 → 编程式
481
+ - 只需对话提示词模板 → 声明式
482
+ - 不确定 → 先用声明式,后续可迁移为编程式
483
+
484
+ ---
485
+
486
+ ## License
487
+
488
+ MIT