@tbox.cn/app-template-agent 0.10.19 → 0.10.20

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.
@@ -0,0 +1,3 @@
1
+ [
2
+ "@tbox.cn/app-module-ai-payment"
3
+ ]
@@ -0,0 +1,6 @@
1
+ [
2
+ {
3
+ "platform": "alipay",
4
+ "source": "@tbox.cn/app-miniapp-container-alipay@0.2.6"
5
+ }
6
+ ]
package/README.md CHANGED
@@ -1,18 +1,24 @@
1
1
  # template-agent
2
2
 
3
3
  tbox AI Agent 全栈模板(npm 包名 `@tbox.cn/app-template-agent`,唯一模板——W4 单一模板统一化),多包 pnpm workspace:`apps/` 薄组装端 + `packages/` 模块。
4
- 缺省出厂 = 空装配(chat 形态);**商圈形态经 `profiles/mall` 画像加装**(`tbox-app create --profile mall`:mall-core + 六业务模块 + 商圈配置叠加)。
4
+ 缺省出厂 = 带 AI 支付体验的 chat 形态;**商圈形态经 `profiles/mall` 画像加装**(`tbox-app create --profile mall`:mall-core + 七业务模块 + 商圈配置叠加)。
5
5
  客户端同时支持浏览器和支付宝小程序 web-view;平台能力(鉴权/会话/TTS/ASR/上传/反馈)经 `@tbox.cn/app-sdk` 统一提供(007 下沉)。
6
6
 
7
+ 创建应用时按 `.tbox/default-modules.json` 加装 AI 支付模块,源码落在 `packages/module-ai-payment`。
8
+
9
+ 创建应用时默认使用 `@tbox.cn/app-miniapp-container-alipay@0.2.5` 生成 `apps/miniapp-container-alipay`,容器计划见 `.tbox/miniapp-containers.json`。使用前配置小程序 AppId 和 H5 地址;重复创建保留已登记的容器。
10
+
11
+ `pnpm dev` 始终启动原有 H5/server;容器已安装且 PATH 中有 `minidev` 时同时启动容器,否则跳过。容器异常退出不影响 H5/server,Ctrl+C 统一停止本次启动的进程。
12
+
7
13
  ## 快速开始
8
14
 
9
15
  ```sh
10
16
  pnpm install
11
- pnpm dev # 单进程 http://localhost:8000(API + WS + 页面 + HMR)
17
+ pnpm dev # H5/server + 可选 minidev 小程序容器
12
18
  pnpm verify # typecheck + test + build
13
19
  ```
14
20
 
15
- **能力加装**(空装配起点,能力即模块;mall 全套可改用 `create --profile mall` 一步到位):
21
+ **能力加装**(已有 AI 支付体验,能力即模块;mall 全套可改用 `create --profile mall` 一步到位):
16
22
 
17
23
  ```sh
18
24
  tbox-app module add shopping-guide # 导购/找店/业态/客服(模块级 intents + LLM 工具 + 卡片)
@@ -28,7 +34,7 @@ tbox-app module doctor # 26 条结构校验
28
34
  > 环境变量:本地开发用 shell export 注入(见 `ENV.md`,含必需变量命令块;每次新终端需重新执行),
29
35
  > 生产建议在 tbox 平台页面上配置(平台托管 env,密钥不进代码仓库)。
30
36
 
31
- > 平台包消费(005 v0.4.0 发布态):生成应用初始通过 `@app/contracts-mall` shim 使用 `catalog:` 引用的发布包;添加依赖 contracts-mall 的 codegen 模块后,CLI 将 shim 替换为本地源码包——
37
+ > 平台包消费(005 v0.4.0 发布态):模板通过 `@app/contracts-mall` shim 使用 `catalog:` 引用的发布包;创建时默认安装 AI 支付模块,CLI 按依赖将 shim 替换为本地源码包——
32
38
  > 生产(registry 已发布)直接 `pnpm install`;平台包未发布 npm 时,由 `tbox-app create --local-deps <平台 tgz 目录>`
33
39
  > 注入 overrides(`file:` 本地发布态产物)后 install 离线可用。
34
40
  >
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tbox.cn/app-template-agent",
3
- "version": "0.10.19",
4
- "description": "tbox AI Agent 全栈模板(多包 pnpm workspace):apps/client + apps/server。唯一模板(W4 单一模板统一化:缺省空装配 chat 形态;mall 能力经 profiles/mall 加装),能力经 tbox-app module add 模块扩展(shopping-guide/member 等)。",
3
+ "version": "0.10.20",
4
+ "description": "tbox AI Agent 全栈模板(多包 pnpm workspace):apps/client + apps/server。唯一模板(W4 单一模板统一化:缺省带 AI 支付体验的 chat 形态;mall 能力经 profiles/mall 加装),能力经 tbox-app module add 模块扩展(shopping-guide/member 等)。",
5
5
  "engines": {
6
6
  "node": ">=24.0.0 <25.0.0"
7
7
  },
@@ -44,7 +44,7 @@
44
44
  "access": "public"
45
45
  },
46
46
  "scripts": {
47
- "dev": "pnpm --filter ./apps/server dev",
47
+ "dev": "node scripts/dev.mjs",
48
48
  "build": "pnpm check && pnpm --filter ./apps/server build && pnpm --filter ./apps/client build",
49
49
  "build:client": "pnpm check && pnpm --filter ./apps/client build",
50
50
  "typecheck": "pnpm -r --filter \"./{apps,packages}/*\" typecheck",
@@ -6,9 +6,6 @@ settings:
6
6
 
7
7
  catalogs:
8
8
  default:
9
- '@phosphor-icons/react':
10
- specifier: 2.1.10
11
- version: 2.1.10
12
9
  '@tbox-dev-js/sdk':
13
10
  specifier: 0.1.18
14
11
  version: 0.1.18
@@ -24,9 +21,9 @@ catalogs:
24
21
  '@tbox.cn/app-contracts':
25
22
  specifier: 0.13.1
26
23
  version: 0.13.1
27
- '@tbox.cn/app-contracts-mall':
28
- specifier: 0.13.1
29
- version: 0.13.1
24
+ '@tbox.cn/app-sdk-client':
25
+ specifier: 0.21.3
26
+ version: 0.21.3
30
27
  '@tbox.cn/app-sdk-server':
31
28
  specifier: 0.26.0
32
29
  version: 0.26.0
@@ -48,9 +45,6 @@ catalogs:
48
45
  '@vitejs/plugin-react':
49
46
  specifier: 4.7.0
50
47
  version: 4.7.0
51
- antd-mobile:
52
- specifier: 5.42.3
53
- version: 5.42.3
54
48
  eslint:
55
49
  specifier: 9.39.5
56
50
  version: 9.39.5
@@ -75,12 +69,6 @@ catalogs:
75
69
  react-dom:
76
70
  specifier: 18.3.1
77
71
  version: 18.3.1
78
- react-markdown:
79
- specifier: 9.1.0
80
- version: 9.1.0
81
- remark-gfm:
82
- specifier: 4.0.1
83
- version: 4.0.1
84
72
  tsup:
85
73
  specifier: 8.5.1
86
74
  version: 8.5.1
@@ -137,6 +125,9 @@ importers:
137
125
  '@app/contracts-mall':
138
126
  specifier: workspace:*
139
127
  version: link:../../packages/contracts-mall
128
+ '@app/module-ai-payment':
129
+ specifier: workspace:*
130
+ version: link:../../packages/module-ai-payment
140
131
  '@app/provider-custom':
141
132
  specifier: workspace:*
142
133
  version: link:../../packages/provider-custom
@@ -190,11 +181,32 @@ importers:
190
181
  specifier: 'catalog:'
191
182
  version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(happy-dom@20.11.2)(vite@6.4.3(@types/node@24.13.3)(less@4.8.1)(tsx@4.23.11))
192
183
 
184
+ apps/miniapp-container-alipay:
185
+ devDependencies:
186
+ '@mini-types/alipay':
187
+ specifier: ^3.0.14
188
+ version: 3.0.14
189
+ '@tbox.cn/app-sdk-client':
190
+ specifier: 'catalog:'
191
+ version: 0.21.3
192
+ '@tbox.cn/app-sdk-server':
193
+ specifier: 'catalog:'
194
+ version: 0.26.0
195
+ typescript:
196
+ specifier: 'catalog:'
197
+ version: 5.9.3
198
+ vitest:
199
+ specifier: 'catalog:'
200
+ version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(happy-dom@20.11.2)(vite@6.4.3(@types/node@24.13.3)(less@4.8.1)(tsx@4.23.11))
201
+
193
202
  apps/server:
194
203
  dependencies:
195
204
  '@app/contracts-mall':
196
205
  specifier: workspace:*
197
206
  version: link:../../packages/contracts-mall
207
+ '@app/module-ai-payment':
208
+ specifier: workspace:*
209
+ version: link:../../packages/module-ai-payment
198
210
  '@app/provider-custom':
199
211
  specifier: workspace:*
200
212
  version: link:../../packages/provider-custom
@@ -242,7 +254,7 @@ importers:
242
254
  packages/agent-ui-kit:
243
255
  dependencies:
244
256
  '@phosphor-icons/react':
245
- specifier: 'catalog:'
257
+ specifier: 2.1.10
246
258
  version: 2.1.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
247
259
  '@tbox.cn/app-agent-sdk-client':
248
260
  specifier: 'catalog:'
@@ -251,64 +263,119 @@ importers:
251
263
  specifier: 'catalog:'
252
264
  version: 0.13.1
253
265
  antd-mobile:
254
- specifier: 'catalog:'
266
+ specifier: 5.42.3
255
267
  version: 5.42.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
256
268
  react-markdown:
257
- specifier: 'catalog:'
269
+ specifier: 9.1.0
258
270
  version: 9.1.0(@types/react@18.3.31)(react@18.3.1)
259
271
  remark-gfm:
260
- specifier: 'catalog:'
272
+ specifier: 4.0.1
261
273
  version: 4.0.1
262
274
  zustand:
263
- specifier: 'catalog:'
275
+ specifier: 4.5.7
264
276
  version: 4.5.7(@types/react@18.3.31)(react@18.3.1)
265
277
  devDependencies:
266
278
  '@types/node':
267
- specifier: 'catalog:'
279
+ specifier: 24.13.3
268
280
  version: 24.13.3
269
281
  '@types/react':
270
- specifier: 'catalog:'
282
+ specifier: 18.3.31
271
283
  version: 18.3.31
272
284
  '@types/react-dom':
273
- specifier: 'catalog:'
285
+ specifier: 18.3.7
274
286
  version: 18.3.7(@types/react@18.3.31)
275
287
  happy-dom:
276
- specifier: 'catalog:'
288
+ specifier: 20.11.2
277
289
  version: 20.11.2
278
290
  less:
279
- specifier: 'catalog:'
291
+ specifier: 4.8.1
280
292
  version: 4.8.1
281
293
  react:
282
- specifier: 'catalog:'
294
+ specifier: 18.3.1
283
295
  version: 18.3.1
284
296
  react-dom:
285
- specifier: 'catalog:'
297
+ specifier: 18.3.1
286
298
  version: 18.3.1(react@18.3.1)
287
299
  typescript:
288
- specifier: 'catalog:'
300
+ specifier: 5.9.3
289
301
  version: 5.9.3
290
302
  vite:
291
- specifier: 'catalog:'
303
+ specifier: 6.4.3
292
304
  version: 6.4.3(@types/node@24.13.3)(less@4.8.1)(tsx@4.23.11)
293
305
  vitest:
294
- specifier: 'catalog:'
306
+ specifier: 4.1.10
295
307
  version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(happy-dom@20.11.2)(vite@6.4.3(@types/node@24.13.3)(less@4.8.1)(tsx@4.23.11))
296
308
 
297
309
  packages/contracts-mall:
298
310
  dependencies:
299
- '@tbox.cn/app-contracts-mall':
311
+ '@tbox.cn/app-contracts':
312
+ specifier: 'catalog:'
313
+ version: 0.13.1
314
+ zod:
315
+ specifier: 3.25.76
316
+ version: 3.25.76
317
+ devDependencies:
318
+ happy-dom:
319
+ specifier: 20.11.2
320
+ version: 20.11.2
321
+ tsup:
322
+ specifier: 8.5.1
323
+ version: 8.5.1(postcss@8.5.26)(tsx@4.23.11)(typescript@5.9.3)
324
+ typescript:
325
+ specifier: 5.9.3
326
+ version: 5.9.3
327
+ vitest:
328
+ specifier: 4.1.10
329
+ version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(happy-dom@20.11.2)(vite@6.4.3(@types/node@24.13.3)(less@4.8.1)(tsx@4.23.11))
330
+
331
+ packages/module-ai-payment:
332
+ dependencies:
333
+ '@app/contracts-mall':
334
+ specifier: workspace:*
335
+ version: link:../contracts-mall
336
+ '@phosphor-icons/react':
337
+ specifier: 2.1.10
338
+ version: 2.1.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
339
+ '@tbox.cn/app-agent-sdk-client':
340
+ specifier: 'catalog:'
341
+ version: 0.2.0(@types/react@18.3.31)
342
+ '@tbox.cn/app-agent-sdk-server':
343
+ specifier: 'catalog:'
344
+ version: 0.3.0(@tbox-dev-js/sdk@0.1.18)(rxjs@7.8.1)
345
+ '@tbox.cn/app-contracts':
300
346
  specifier: 'catalog:'
301
347
  version: 0.13.1
348
+ react:
349
+ specifier: 18.3.1
350
+ version: 18.3.1
302
351
  devDependencies:
303
352
  '@types/node':
304
353
  specifier: 24.13.3
305
354
  version: 24.13.3
355
+ '@types/react':
356
+ specifier: 18.3.31
357
+ version: 18.3.31
358
+ '@types/react-dom':
359
+ specifier: 18.3.7
360
+ version: 18.3.7(@types/react@18.3.31)
361
+ happy-dom:
362
+ specifier: 20.11.2
363
+ version: 20.11.2
364
+ react-dom:
365
+ specifier: 18.3.1
366
+ version: 18.3.1(react@18.3.1)
367
+ tsup:
368
+ specifier: 8.5.1
369
+ version: 8.5.1(postcss@8.5.26)(tsx@4.23.11)(typescript@5.9.3)
306
370
  typescript:
307
371
  specifier: 5.9.3
308
372
  version: 5.9.3
309
373
  vitest:
310
374
  specifier: 4.1.10
311
375
  version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@24.13.3)(happy-dom@20.11.2)(vite@6.4.3(@types/node@24.13.3)(less@4.8.1)(tsx@4.23.11))
376
+ zod:
377
+ specifier: 3.25.76
378
+ version: 3.25.76
312
379
 
313
380
  packages/provider-custom:
314
381
  dependencies:
@@ -1101,6 +1168,15 @@ packages:
1101
1168
  peerDependencies:
1102
1169
  zod: ^3.25.0 || ^4.0.0
1103
1170
 
1171
+ '@mini-types/alipay@3.0.14':
1172
+ resolution: {integrity: sha512-FakzSsKvybtWlEIVTIRlr89kuQFn+XY86Ho9VUFFaKLplhW6Wx8FUxTDE7IzV7B9rT8DP/Icy637vUHlXPsw1g==}
1173
+
1174
+ '@mini-types/global@3.0.14':
1175
+ resolution: {integrity: sha512-St2ucFRfKRskposOqV/9iNJTKn1MbyqDypQiy/0DaVJjEm2MFi82RJjX9sBz1uWhQIqzu741PgTjGSy7L/Qj9g==}
1176
+
1177
+ '@mini-types/my@3.0.14':
1178
+ resolution: {integrity: sha512-aEgmM+rbEvEzTvqltCFRAg/h6KKs14M1y+FrOkz+hn2EyNpOVPesUzTjbRhSiFFsE3WdfBh54lHNYBahAmHq7w==}
1179
+
1104
1180
  '@modelcontextprotocol/core@2.0.0':
1105
1181
  resolution: {integrity: sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==}
1106
1182
  engines: {node: '>=20'}
@@ -1343,10 +1419,6 @@ packages:
1343
1419
  resolution: {integrity: sha512-thnnPwA0Tkb3yf+HxmeIEDyji6myIJVKvyhzn0WWuVJN7mg9I6+juTimxwRNhqnpZBjue3kExMw75+MvTineYA==}
1344
1420
  engines: {node: '>=20.0.0'}
1345
1421
 
1346
- '@tbox.cn/app-contracts-mall@0.13.1':
1347
- resolution: {integrity: sha512-xylb7J5KxH3rmK8bA1AAJ/Qinn0zGsqO3HjXY8R4CrazHV+F0R2YJvD4J2vd/tazOm9rKRqDxfhdW208QQioFg==}
1348
- engines: {node: '>=20.0.0'}
1349
-
1350
1422
  '@tbox.cn/app-contracts@0.13.0':
1351
1423
  resolution: {integrity: sha512-8sqP/23MoUlbTX9enFNotP5bu7XKFfigDUJ6sEn1Ff2a0rRlSTWzLWmDv9lP70cfZMPjh4MHoLKFoukr8QPvMA==}
1352
1424
  engines: {node: '>=20.0.0'}
@@ -3911,6 +3983,15 @@ snapshots:
3911
3983
  zod: 3.25.76
3912
3984
  zod-from-json-schema: 0.5.6
3913
3985
 
3986
+ '@mini-types/alipay@3.0.14':
3987
+ dependencies:
3988
+ '@mini-types/global': 3.0.14
3989
+ '@mini-types/my': 3.0.14
3990
+
3991
+ '@mini-types/global@3.0.14': {}
3992
+
3993
+ '@mini-types/my@3.0.14': {}
3994
+
3914
3995
  '@modelcontextprotocol/core@2.0.0':
3915
3996
  dependencies:
3916
3997
  zod: 4.4.3
@@ -4114,11 +4195,6 @@ snapshots:
4114
4195
  - utf-8-validate
4115
4196
  - workflow
4116
4197
 
4117
- '@tbox.cn/app-contracts-mall@0.13.1':
4118
- dependencies:
4119
- '@tbox.cn/app-contracts': 0.13.1
4120
- zod: 3.25.76
4121
-
4122
4198
  '@tbox.cn/app-contracts@0.13.0':
4123
4199
  dependencies:
4124
4200
  '@ag-ui/core': 0.0.47
@@ -0,0 +1,91 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { accessSync, constants, existsSync, statSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ export function hasCommand(command, env = process.env) {
7
+ const extensions = process.platform === 'win32' ? (env.PATHEXT ?? '.EXE;.CMD;.BAT').split(';') : [''];
8
+ return (env.PATH ?? '').split(path.delimiter).some(dir => extensions.some(extension => {
9
+ try {
10
+ const executable = path.join(dir || '.', command + extension);
11
+ accessSync(executable, constants.X_OK);
12
+ return statSync(executable).isFile();
13
+ }
14
+ catch { return false; }
15
+ }));
16
+ }
17
+
18
+ function stopChild(child, signal) {
19
+ if (!child?.pid) return;
20
+ try {
21
+ if (process.platform === 'win32') child.kill(signal);
22
+ else process.kill(-child.pid, signal);
23
+ } catch (error) {
24
+ if (error.code !== 'ESRCH') throw error;
25
+ }
26
+ }
27
+
28
+ /** H5/server 为主进程;可选容器失败不终止主进程。 */
29
+ export function startDev({
30
+ projectDir,
31
+ spawnProcess = spawn,
32
+ commandExists = hasCommand,
33
+ stopProcess = stopChild,
34
+ signals = process,
35
+ log = console,
36
+ finish = code => { process.exitCode = code; },
37
+ }) {
38
+ const options = { cwd: projectDir, detached: process.platform !== 'win32', shell: process.platform === 'win32' };
39
+ const containerInstalled = existsSync(path.join(projectDir, 'apps/miniapp-container-alipay/package.json'));
40
+ const containerEnabled = containerInstalled && commandExists('minidev');
41
+ const server = spawnProcess('pnpm', ['--filter', './apps/server', 'dev'], {
42
+ ...options, stdio: containerEnabled ? ['ignore', 'inherit', 'inherit'] : 'inherit',
43
+ });
44
+ let container;
45
+ let stopping = false;
46
+ let requestedCode;
47
+ let completed = false;
48
+ const stop = code => {
49
+ if (stopping) return;
50
+ stopping = true;
51
+ requestedCode = code;
52
+ stopProcess(server, 'SIGTERM');
53
+ stopProcess(container, 'SIGTERM');
54
+ setTimeout(() => {
55
+ stopProcess(server, 'SIGKILL');
56
+ stopProcess(container, 'SIGKILL');
57
+ }, 2000);
58
+ };
59
+ const interrupt = () => stop(130);
60
+ const terminate = () => stop(143);
61
+ signals.on('SIGINT', interrupt);
62
+ signals.on('SIGTERM', terminate);
63
+ const complete = code => {
64
+ if (completed) return;
65
+ completed = true;
66
+ stop(code);
67
+ signals.removeListener('SIGINT', interrupt);
68
+ signals.removeListener('SIGTERM', terminate);
69
+ finish(requestedCode ?? code);
70
+ };
71
+ server.once('error', error => { log.error(`H5/server 启动失败:${error.message}`); complete(1); });
72
+ server.once('exit', (code, signal) => complete(code ?? (signal ? 1 : 0)));
73
+
74
+ if (!containerInstalled) {
75
+ log.info('未安装支付宝小程序容器,仅启动 H5/server。');
76
+ } else if (!containerEnabled) {
77
+ log.info('未找到 minidev,跳过小程序容器,H5/server 正常启动。');
78
+ } else {
79
+ log.info('同时启动支付宝小程序容器(minidev)。');
80
+ container = spawnProcess('pnpm', ['--filter', '@app/miniapp-container-alipay', 'dev'], { ...options, stdio: 'inherit' });
81
+ container.once('error', error => log.warn(`小程序容器启动失败,H5/server 继续运行:${error.message}`));
82
+ container.once('exit', code => {
83
+ if (!stopping) log.info(`小程序容器已退出(${code ?? 'signal'}),H5/server 继续运行。`);
84
+ });
85
+ }
86
+ return { server, get container() { return container; }, stop };
87
+ }
88
+
89
+ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
90
+ startDev({ projectDir: path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..') });
91
+ }
package/scripts/dev.sh CHANGED
@@ -12,4 +12,4 @@ pnpm install
12
12
  echo "Starting development server..."
13
13
  echo " - http://localhost:8000 (API + WS + 页面 + HMR)"
14
14
 
15
- pnpm --filter @app/server dev
15
+ pnpm dev