cardbuddy 0.22.0 → 0.23.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.
Files changed (69) hide show
  1. package/README.md +11 -11
  2. package/dist/cli.js +2 -2
  3. package/dist/config.js +3 -3
  4. package/dist/init.js +13 -13
  5. package/dist/mcp.js +1 -1
  6. package/dist/preview-editor/assets/{index-CU8zVA2P.css → index-7RzNd7tf.css} +1 -1
  7. package/dist/preview-editor/assets/{index-CPpLZZyi.js → index-C7N5n_qW.js} +80 -80
  8. package/dist/preview-editor/index.html +2 -2
  9. package/dist/skills-upgrade.js +1 -1
  10. package/dist/standalone.js +2 -2
  11. package/dist/vendored/card-editor/runtime/adapter.js +10 -11
  12. package/dist/vendored/mcp/client.mjs +50 -13
  13. package/dist/vendored/mcp/tools.mjs +13 -7
  14. package/dist/vendored/server/core/ai-chat.js +540 -183
  15. package/dist/vendored/server/core/assetProxy.js +1 -1
  16. package/dist/vendored/server/core/browser.js +1 -1
  17. package/dist/vendored/server/core/cardDigest.js +324 -0
  18. package/dist/vendored/server/core/cardExport.js +5 -5
  19. package/dist/vendored/server/core/cardFiles.js +1 -1
  20. package/dist/vendored/server/core/cardHistoryRemote.js +1 -1
  21. package/dist/vendored/server/core/cardImportMeta.js +1 -1
  22. package/dist/vendored/server/core/cardListCache.js +92 -10
  23. package/dist/vendored/server/core/cardPublish.js +11 -6
  24. package/dist/vendored/server/core/cardPublishVersions.js +8 -8
  25. package/dist/vendored/server/core/cardSave.js +14 -10
  26. package/dist/vendored/server/core/cardSidecar.js +3 -3
  27. package/dist/vendored/server/core/cardSync.js +35 -23
  28. package/dist/vendored/server/core/cardVersion.js +1 -1
  29. package/dist/vendored/server/core/index.js +6 -6
  30. package/dist/vendored/server/core/logger.js +1 -1
  31. package/dist/vendored/server/core/remoteCard.js +5 -5
  32. package/dist/vendored/server/core/skillPaths.js +1 -1
  33. package/dist/vendored/server/core/sliceUpload.js +4 -4
  34. package/dist/vendored/skills/README.md +13 -13
  35. package/dist/vendored/skills/card-doctor/SKILL.md +2 -2
  36. package/dist/vendored/skills/dsl-card-ai/SKILL.md +4 -4
  37. package/dist/vendored/skills/dsl-card-generator/SKILL.md +2 -2
  38. package/dist/vendored/skills/dsl-card-generator/references/amount_formatting.md +1 -1
  39. package/dist/vendored/skills/dsl-card-generator/references/build_protocol.md +54 -0
  40. package/dist/vendored/skills/dsl-card-generator/references/component_rules.md +2 -2
  41. package/dist/vendored/skills/dsl-card-generator/references/converge_protocol.md +36 -0
  42. package/dist/vendored/skills/dsl-card-generator/references/event_patterns.md +1 -1
  43. package/dist/vendored/skills/dsl-card-generator/references/generation_pitfalls.md +1 -1
  44. package/dist/vendored/skills/dsl-card-generator/references/image_to_card.md +1 -1
  45. package/dist/vendored/skills/dsl-card-generator/references/quickref.md +1 -1
  46. package/dist/vendored/skills/dsl-card-generator/references/recipes.md +4 -4
  47. package/dist/vendored/skills/dsl-card-generator/references/rules.md +1 -1
  48. package/dist/vendored/skills/dsl-card-generator/references/slices_convention.md +6 -6
  49. package/dist/vendored/skills/dsl-card-generator/scripts/inventory_schemas.py +1 -1
  50. package/dist/vendored/skills/dsl-card-generator/scripts/lib/scaffold.mjs +1 -1
  51. package/dist/vendored/skills/dsl-card-generator/scripts/lib/slice_dedupe.mjs +2 -2
  52. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/standalone-CeVX_y-M.js +137 -0
  53. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/standalone-DiEiY59H.css +1 -0
  54. package/dist/vendored/skills/dsl-card-generator/vendor/preview/standalone.html +2 -2
  55. package/dist/vendored/skills/{finmall-card-sync → platform-card-sync}/SKILL.md +26 -26
  56. package/dist/vendored/skills/{finmall-card-sync → platform-card-sync}/scripts/api_batch_sync.mjs +184 -162
  57. package/dist/vendored/skills/{finmall-card-sync → platform-card-sync}/scripts/slice_upload.mjs +48 -29
  58. package/dist/vendored/skills/{finmall-session-navigator → platform-session-navigator}/SKILL.md +13 -13
  59. package/dist/vendored/skills/{finmall-session-navigator → platform-session-navigator}/scripts/package-lock.json +2 -2
  60. package/dist/vendored/skills/{finmall-session-navigator → platform-session-navigator}/scripts/package.json +2 -2
  61. package/dist/vendored/skills/{finmall-session-navigator/scripts/finmall_login.mjs → platform-session-navigator/scripts/platform_login.mjs} +41 -31
  62. package/dist/vendored/skills/{finmall-session-navigator → platform-session-navigator}/scripts/session-manager.mjs +17 -17
  63. package/dist/vendored/skills/shared/README.md +21 -21
  64. package/dist/vendored/skills/shared/auth-model.md +8 -10
  65. package/dist/vendored/skills/shared/{finmall-config.mjs → platform-config.mjs} +10 -10
  66. package/dist/vendored/tools/{finmall-env.mjs → platform-env.mjs} +13 -13
  67. package/package.json +1 -1
  68. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/standalone-BCLshIzC.css +0 -1
  69. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/standalone-pP5kTKiI.js +0 -88
@@ -8,8 +8,8 @@
8
8
  <link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16-Cg6Nrosk.png" />
9
9
  <link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32-B_1744sp.png" />
10
10
  <link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon-BQcES9QK.png" />
11
- <script type="module" crossorigin src="/assets/index-CPpLZZyi.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-CU8zVA2P.css">
11
+ <script type="module" crossorigin src="/assets/index-C7N5n_qW.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index-7RzNd7tf.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="app"></div>
@@ -5,7 +5,7 @@
5
5
  * 运行时 skillPaths 解析「项目 skills/ 优先于包内快照」(server/core/skillPaths.js),
6
6
  * 故只 `npm i cardbuddy@latest` 不会更新工程里的 skills 副本——必须显式拉一次。本命令
7
7
  * 就是为这个场景而生,且**只动 skills/**,绝不碰 .env.cb / package.json / README.md
8
- * (那是 `init --force` 的危险面,可能冲掉端口 / FinMall 配置 / AI 网关占位)。
8
+ * (那是 `init --force` 的危险面,可能冲掉端口 / 远端配置 / AI 网关占位)。
9
9
  *
10
10
  * 行为模型(upgrade = 显式要把新版带进来,「有差异 = 应当覆盖」,不做好坏判定):
11
11
  * ADDED 源有、目标无 → 复制(安全)
@@ -9,7 +9,7 @@
9
9
  * - /__events(SSE)实时推送 cards-changed(替代 Vite HMR)
10
10
  * - 内嵌 Vite middlewareMode 实例,仅为 render-status / node-models 提供 ssrLoadModule
11
11
  *
12
- * 仅绑定 127.0.0.1;FinMall 凭据只在本机,公网前端永不接触。
12
+ * 仅绑定 127.0.0.1;远端凭据只在本机,公网前端永不接触。
13
13
  */
14
14
  import http from 'node:http'
15
15
  import https from 'node:https'
@@ -494,7 +494,7 @@ export async function startServer(userConfig = {}) {
494
494
  // <pkg>/dist/vendored/skills/... 里,推出来的是包内快照目录,UI/ 产物会写进 node_modules
495
495
  // (0.14.1 的 route_input 事故)。技能层的 AI 工具与 skill_exec 子进程都继承本进程 env。
496
496
  if (!process.env.DSL_CARD_PROJECT_ROOT) process.env.DSL_CARD_PROJECT_ROOT = config.root
497
- // upstream(FINMALL_BASE_URL)透传给资源代理中间件,使其能回源 FinMall 取站内资源
497
+ // upstream(PLATFORM_BASE_URL)透传给资源代理中间件,使其能回源远端取站内资源
498
498
  mountCoreMiddlewares(app, {
499
499
  root: config.root,
500
500
  viteServer: vite,
@@ -7,7 +7,7 @@
7
7
  * 全局正则替换。别名表取自 /ubomp-h5-sub/js/main.js。
8
8
  */
9
9
 
10
- // 前后分离后,站内资源统一经「本地开发服务(8787)」的资源代理回源 FinMall。
10
+ // 前后分离后,站内资源统一经「本地开发服务(8787)」的资源代理回源远端。
11
11
  // 这里引入 resolveApiBase,把本地化出的站内路径改写为指向 8787 的绝对 URL,
12
12
  // 修复部署态(静态编辑器 + 本机 8787,无 Vite)资源缺失的问题。
13
13
  import { resolveApiBase } from '@/api.js'
@@ -25,16 +25,15 @@ const URL_PREFIX_ALIAS = {
25
25
  * 卡片 data.json 里有不少写死的完整 CDN 地址,直接请求会跨域也吃不到本地缓存。
26
26
  * 统一改写成同源路径,交给 vite 的资源代理中间件。
27
27
  *
28
- * 域名不硬编码:从 .env.cb 的 FINMALL_BASE_URL 读取(vite 以
29
- * envPrefix FINMALL_ 暴露到 import.meta.env),未配置时回退 UAT 域名。
28
+ * 域名不硬编码:从 .env.cb 的 PLATFORM_BASE_URL 读取(vite 以
29
+ * envPrefix PLATFORM_ 暴露到 import.meta.env)。未配置时不改写任何 host,
30
+ * 让这些绝对地址原样请求(资源代理仍会回源),避免误把相对路径截成空串。
30
31
  */
31
- const BASE_URL = import.meta.env.FINMALL_BASE_URL || 'https://uat-pkg.finmall.com'
32
- const BASE_HOST = BASE_URL.replace(/^https?:/, '') // '//uat-pkg.finmall.com'
33
- const ABSOLUTE_ASSET_HOSTS = [...new Set([
34
- BASE_URL,
35
- BASE_URL.replace(/^https:/, 'http:'),
36
- BASE_HOST,
37
- ])]
32
+ const BASE_URL = import.meta.env.PLATFORM_BASE_URL || ''
33
+ const BASE_HOST = BASE_URL ? BASE_URL.replace(/^https?:/, '') : ''
34
+ const ABSOLUTE_ASSET_HOSTS = BASE_URL
35
+ ? [...new Set([BASE_URL, BASE_URL.replace(/^https:/, 'http:'), BASE_HOST])]
36
+ : []
38
37
 
39
38
  function toLocalAssetUrl(url) {
40
39
  if (typeof url !== 'string' || !url) return url
@@ -82,7 +81,7 @@ export default class Adapter {
82
81
  * - `@` 开头的站内别名(如 `@filestore/x`):走 URL_PREFIX_ALIAS 替换 + 绝对 host 截取,
83
82
  * 转成同源站内路径,交给本地资源代理回源。
84
83
  *
85
- * 历史实现里 toLocalAssetUrl 对所有入参(含 http 图链)都截取 FinMall 等 host,导致
84
+ * 历史实现里 toLocalAssetUrl 对所有入参(含 http 图链)都截取远端等 host,导致
86
85
  * 背景图 / 图片一旦命中这些 host 就被剥掉域名、改走本地代理,与「远程地址原样直连」的预期不符。
87
86
  */
88
87
  doReplaceUrl(url) {
@@ -3,9 +3,10 @@ import path from 'node:path'
3
3
  import { fileURLToPath } from 'node:url'
4
4
  import { dirname, resolve } from 'node:path'
5
5
  import { listCards, readCardFiles, writeCardFiles, renameCard } from '../server/core/cardFiles.js'
6
+ import { findNodeByComponentId } from '../server/core/cardDigest.js'
6
7
  import { validateCard, resolvePython, scriptPath } from '../server/core/cardValidate.js'
7
8
  import { listSnapshots, saveSnapshot, HISTORY_DIR } from '../server/core/cardHistory.js'
8
- import { devApiBase } from '../tools/finmall-env.mjs'
9
+ import { devApiBase } from '../tools/platform-env.mjs'
9
10
 
10
11
  /**
11
12
  * MCP 薄 HTTP 客户端:只封装对 dev server(端口见 .env.cb 的 CARDBUDDY_DEV_PORT)的请求,不复制任何业务逻辑。
@@ -13,7 +14,7 @@ import { devApiBase } from '../tools/finmall-env.mjs'
13
14
  * 降级策略(与 tools/card-check.mjs 一致):
14
15
  * - list / read / write / validate:dev server 未启动(fetch 抛连接错误)时,
15
16
  * 降级为直接读盘 / 写盘 / 跑 Python —— 复用 server/* 导出的同一份实现,避免漂移。
16
- * - render_status / sync / save:依赖 dev server 与 FinMall 登录态,不支持离线降级;
17
+ * - render_status / sync / save:依赖 dev server 与远端登录态,不支持离线降级;
17
18
  * screenshot 在 dev server 未启动时降级到独立离线渲染器。
18
19
  */
19
20
 
@@ -101,13 +102,13 @@ async function httpPost(p, body) {
101
102
  return { status: res.status, buf, text, json, contentType: res.headers.get('content-type') || '' }
102
103
  }
103
104
 
104
- // 需要 FinMall 登录态的远端工具:提示语要额外说明「且已登录 FinMall」。
105
+ // 需要远端登录态的远端工具:提示语要额外说明「且已登录远端」。
105
106
  const REMOTE_TOOLS = new Set(['card_sync', 'card_save', 'card_slice_upload'])
106
107
 
107
108
  const DEV_REQUIRED = (tool) => ({
108
109
  source: null,
109
110
  error: 'dev-server-required',
110
- message: `${tool} 需要 dev server 已启动(npm run dev)${REMOTE_TOOLS.has(tool) ? ' 且已登录 FinMall' : ''}。本工具不支持离线降级。`,
111
+ message: `${tool} 需要 dev server 已启动(npm run dev)${REMOTE_TOOLS.has(tool) ? ' 且已登录远端' : ''}。本工具不支持离线降级。`,
111
112
  })
112
113
 
113
114
  // ---- card_list ----
@@ -122,16 +123,52 @@ export async function cardList() {
122
123
  }
123
124
 
124
125
  // ---- card_read ----
125
- export async function cardRead(id) {
126
+ /**
127
+ * 读单卡。
128
+ *
129
+ * `node` 给定 componentId 时**只返回该子树**(附带真实 JSON 路径与祖先链)——
130
+ * 大卡(实测最大 239KB / 167 节点)整份读一次就会吃满工具结果档位,
131
+ * 而「结构摘要 → 定向取一棵子树」才是正常读法(见 server/core/cardDigest.js)。
132
+ */
133
+ export async function cardRead(id, { node = '' } = {}) {
134
+ let payload = null
135
+ let source = 'local'
126
136
  try {
127
137
  const { status, json } = await httpGet(`/__card/${encodeURIComponent(id)}`)
128
- if (status === 200 && json) return { source: 'http', ...json }
138
+ if (status === 200 && json) {
139
+ payload = json
140
+ source = 'http'
141
+ }
129
142
  } catch {
130
143
  /* 降级 */
131
144
  }
132
- const r = readCardFiles(ROOT, id)
133
- if (!r) return { source: 'local', error: 'card not found', id }
134
- return { source: 'local', ...r }
145
+ if (!payload) {
146
+ const r = readCardFiles(ROOT, id)
147
+ if (!r) return { source: 'local', error: 'card not found', id }
148
+ payload = r
149
+ }
150
+ if (!node) return { source, ...payload }
151
+
152
+ const found = findNodeByComponentId(payload.schema, node)
153
+ if (!found) {
154
+ return {
155
+ source,
156
+ error: 'component not found',
157
+ id,
158
+ node,
159
+ hint: '先用 card_read 不带 node 看结构图(tree 段),或 card_grep 按文案/类名定位;节点树在 view.components[] / view.slots[].components[]',
160
+ }
161
+ }
162
+ return {
163
+ source,
164
+ mode: 'node',
165
+ id,
166
+ componentId: node,
167
+ path: found.path,
168
+ depth: found.depth,
169
+ ancestors: found.ancestors.map((a) => `${a.cid || a.cls}@${a.path}`),
170
+ node: found.node,
171
+ }
135
172
  }
136
173
 
137
174
  // ---- card_write(闭环收口:写前自动留历史快照,写完自动校验)----
@@ -458,7 +495,7 @@ export async function cardScreenshot(id, { format = 'json', width = 390 } = {})
458
495
  }
459
496
  }
460
497
 
461
- // ---- card_sync(需 dev server + FinMall 登录态)----
498
+ // ---- card_sync(需 dev server + 远端登录态)----
462
499
  export async function cardSync({ cardCode } = {}) {
463
500
  try {
464
501
  const { status, json } = await httpPost('/__sync', { cardCode })
@@ -470,7 +507,7 @@ export async function cardSync({ cardCode } = {}) {
470
507
  return DEV_REQUIRED('card_sync')
471
508
  }
472
509
 
473
- // ---- card_save(需 dev server + FinMall 登录态)----
510
+ // ---- card_save(需 dev server + 远端登录态)----
474
511
  export async function cardSave({ schema, code, skeletonScreen } = {}) {
475
512
  try {
476
513
  const { status, json } = await httpPost('/__save', { schema, code, skeletonScreen })
@@ -482,8 +519,8 @@ export async function cardSave({ schema, code, skeletonScreen } = {}) {
482
519
  return DEV_REQUIRED('card_save')
483
520
  }
484
521
 
485
- // ---- card_slice_upload(需 dev server + FinMall 登录态)----
486
- // 切图上传只按单卡范围执行:端点内部复用 finmall-card-sync 的 uploadSlices({ cardId }),
522
+ // ---- card_slice_upload(需 dev server + 远端登录态)----
523
+ // 切图上传只按单卡范围执行:端点内部复用 platform-card-sync 的 uploadSlices({ cardId }),
487
524
  // 上传 src/slices 里该卡引用的图并把 schema/data 的 /slices/ 引用改写为 @filestore/ 线上地址。
488
525
  export async function sliceUpload({ cardId, force } = {}) {
489
526
  try {
@@ -22,10 +22,16 @@ export const TOOLS = [
22
22
  {
23
23
  name: 'card_read',
24
24
  description:
25
- '读取单张卡片的 schema.json(组件树/属性/样式/事件)与 data.json(输入参数默认值)。优先走 GET /__card/:id;未启动 dev server 时降级为直接读盘。',
25
+ '读取单张卡片的 schema.json(组件树/属性/样式/事件)与 data.json(输入参数默认值)。优先走 GET /__card/:id;未启动 dev server 时降级为直接读盘。大卡(数百 KB)服务端会返回**结构图**(全部节点身份 + 主文本 + 参数表)而不是整份 JSON——据此定位后,用 node:"<componentId>" 定向读该子树(含完整 style/properties),比整卡小一个数量级。',
26
26
  inputSchema: {
27
27
  type: 'object',
28
- properties: { id: { type: 'string', description: '卡片 id,对应 src/cards/<id>' } },
28
+ properties: {
29
+ id: { type: 'string', description: '卡片 id,对应 src/cards/<id>' },
30
+ node: {
31
+ type: 'string',
32
+ description: '可选:只返回该 componentId 的子树(含真实 JSON 路径与祖先链)。配合结构图的 tree 段使用',
33
+ },
34
+ },
29
35
  required: ['id'],
30
36
  },
31
37
  },
@@ -84,7 +90,7 @@ export const TOOLS = [
84
90
  {
85
91
  name: 'card_node_models',
86
92
  description:
87
- '读取单卡的「可编辑字段结构树」(Task #5 暴露的 Property-tree 模型,对应 dev server 的 GET /__node-models/:id)。返回每个节点的 {componentId, className, properties, style, directives, eventactions, components},其中每个字段含 itemKey/itemName/itemType/itemValue/itemValueFrom/itemTypeRange/options(iParamList|iTypeList)/children——AI 无需解析 raw DSL + component-meta 即可知道「某节点有哪些可改字段、各自类型与枚举」。⚠️ 该模型是只读视图,改卡仍走 card_write(整体替换);必须 dev server 已启动(npm run dev),不支持离线降级。',
93
+ '读取单卡的「可编辑字段结构树」(Task #5 暴露的 Property-tree 模型,对应 dev server 的 GET /__node-models/:id)。返回每个节点的 {componentId, className, properties, style, directives, eventactions, components},其中每个字段含 itemKey/itemName/itemType/itemValue/itemValueFrom/itemTypeRange/options(iParamList|iTypeList)/children——AI 无需解析 raw DSL + component-meta 即可知道「某节点有哪些可改字段、各自类型与枚举」。⚠️ 该模型是只读视图;改卡走 card_patch(按 @componentId 点路径最小写),不要 card_write 整包重写。本工具适合「查某节点有哪些可改字段、枚举候选是什么」,定位节点本身用 card_read 的结构图更省。必须 dev server 已启动(npm run dev),不支持离线降级。',
88
94
  inputSchema: {
89
95
  type: 'object',
90
96
  properties: { id: { type: 'string', description: '卡片 id,对应 src/cards/<id>' } },
@@ -108,7 +114,7 @@ export const TOOLS = [
108
114
  {
109
115
  name: 'card_sync',
110
116
  description:
111
- '经已登录的 FinMall 浏览器会话从远端拉取最新卡片写回 src/cards(复用 finmall-card-sync)。必须 dev server 已启动且已登录 FinMall,不支持离线降级。',
117
+ '经已登录的远端浏览器会话从远端拉取最新卡片写回 src/cards(复用 platform-card-sync)。必须 dev server 已启动且已登录远端,不支持离线降级。',
112
118
  inputSchema: {
113
119
  type: 'object',
114
120
  properties: { cardCode: { type: 'string', description: '指定卡片 code;留空=同步全部' } },
@@ -118,7 +124,7 @@ export const TOOLS = [
118
124
  {
119
125
  name: 'card_save',
120
126
  description:
121
- '把当前卡片 schema 经已登录浏览器写回 FinMall(IDC10010.do)。必须 dev server 已启动且已登录 FinMall,不支持离线降级。',
127
+ '把当前卡片 schema 经已登录浏览器写回远端(IDC10010.do)。必须 dev server 已启动且已登录远端,不支持离线降级。',
122
128
  inputSchema: {
123
129
  type: 'object',
124
130
  properties: {
@@ -132,7 +138,7 @@ export const TOOLS = [
132
138
  {
133
139
  name: 'card_slice_upload',
134
140
  description:
135
- '把指定卡片引用的本地切图(src/slices)经已登录浏览器上传到 FinMall 图片库(CC0000.do),写「本地文件 ↔ 线上地址」映射 src/slices/manifest.json,并把该卡 schema.json / data.json 里的 "/slices/<name>" 引用改写为返回的 @filestore/… 线上地址。按 sha256 判重:内容未变的切图直接复用已有地址不重复上传;本地切图真源保留不动。**仅按需调用,不存在自动上传**——推送版本 / 出真机预览前,若卡片仍引用 /slices/ 就先跑本工具,否则线上卡片取不到图。必须 dev server 已启动且已登录 FinMall,不支持离线降级。',
141
+ '把指定卡片引用的本地切图(src/slices)经已登录浏览器上传到远端图片库(CC0000.do),写「本地文件 ↔ 线上地址」映射 src/slices/manifest.json,并把该卡 schema.json / data.json 里的 "/slices/<name>" 引用改写为返回的 @filestore/… 线上地址。按 sha256 判重:内容未变的切图直接复用已有地址不重复上传;本地切图真源保留不动。**仅按需调用,不存在自动上传**——推送版本 / 出真机预览前,若卡片仍引用 /slices/ 就先跑本工具,否则线上卡片取不到图。必须 dev server 已启动且已登录远端,不支持离线降级。',
136
142
  inputSchema: {
137
143
  type: 'object',
138
144
  properties: {
@@ -240,7 +246,7 @@ export async function dispatch(name, args = {}) {
240
246
  case 'card_list':
241
247
  return client.cardList()
242
248
  case 'card_read':
243
- return client.cardRead(args.id)
249
+ return client.cardRead(args.id, { node: args.node })
244
250
  case 'card_write':
245
251
  return client.cardWrite(args.id, { schema: args.schema, data: args.data }, { verify: args.verify !== false })
246
252
  case 'card_validate':